summaryrefslogtreecommitdiffstats
path: root/sys/dev/iir/iir_pci.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2014-11-13 22:00:18 +0000
committerjhb <jhb@FreeBSD.org>2014-11-13 22:00:18 +0000
commit1c95a6b2b42a794c0e10a916c8b3d6a2d852a9fe (patch)
tree57e3c7bdb3f074d155877b7cd7f6aa6d57f05716 /sys/dev/iir/iir_pci.c
parent484c1c2bfa2e6b4f999d8a0f3e4d3145c60dc361 (diff)
downloadFreeBSD-src-1c95a6b2b42a794c0e10a916c8b3d6a2d852a9fe.zip
FreeBSD-src-1c95a6b2b42a794c0e10a916c8b3d6a2d852a9fe.tar.gz
Lock iir(4) and mark it MPSAFE.
- Add a per-device mutex to the softc and use it for bus_dma tags, CAM SIMs, callouts, and interrupt handler. - Switch from timeout(9) to callout(9). - Add a separate global mutex to protect the global event buffer ring. - Return completed index from iir_intr_locked() and remove the global gdt_wait_* variables. - Remove global list of gdt softcs and replace its use with devclass_get_device(). - Use si_drv1 to store softc pointer in the SDEV_PER_HBA case instead of minor numbers. - Do math on osreldate instead of dubious char math on osrelease[] that didn't work on 10.0+. - Use bus_*() instead of bus_space_*(). - Use device_printf() instead of printf() with a unit number. Tested by: no one
Diffstat (limited to 'sys/dev/iir/iir_pci.c')
-rw-r--r--sys/dev/iir/iir_pci.c170
1 files changed, 72 insertions, 98 deletions
diff --git a/sys/dev/iir/iir_pci.c b/sys/dev/iir/iir_pci.c
index ec54d49..42e1c81 100644
--- a/sys/dev/iir/iir_pci.c
+++ b/sys/dev/iir/iir_pci.c
@@ -183,15 +183,18 @@ static int
iir_pci_attach(device_t dev)
{
struct gdt_softc *gdt;
- struct resource *io = NULL, *irq = NULL;
+ struct resource *irq = NULL;
int retries, rid, error = 0;
void *ih;
u_int8_t protocol;
-
+
+ gdt = device_get_softc(dev);
+ mtx_init(&gdt->sc_lock, "iir", NULL, MTX_DEF);
+
/* map DPMEM */
rid = PCI_DPMEM;
- io = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
- if (io == NULL) {
+ gdt->sc_dpmem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+ if (gdt->sc_dpmem == NULL) {
device_printf(dev, "can't allocate register resources\n");
error = ENOMEM;
goto err;
@@ -207,12 +210,8 @@ iir_pci_attach(device_t dev)
goto err;
}
- gdt = device_get_softc(dev);
gdt->sc_devnode = dev;
gdt->sc_init_level = 0;
- gdt->sc_dpmemt = rman_get_bustag(io);
- gdt->sc_dpmemh = rman_get_bushandle(io);
- gdt->sc_dpmembase = rman_get_start(io);
gdt->sc_hanum = device_get_unit(dev);
gdt->sc_bus = pci_get_bus(dev);
gdt->sc_slot = pci_get_slot(dev);
@@ -227,85 +226,70 @@ iir_pci_attach(device_t dev)
/* initialize RP controller */
/* check and reset interface area */
- bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC,
- htole32(GDT_MPR_MAGIC));
- if (bus_space_read_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC) !=
- htole32(GDT_MPR_MAGIC)) {
- printf("cannot access DPMEM at 0x%jx (shadowed?)\n",
- (uintmax_t)gdt->sc_dpmembase);
+ bus_write_4(gdt->sc_dpmem, GDT_MPR_IC, htole32(GDT_MPR_MAGIC));
+ if (bus_read_4(gdt->sc_dpmem, GDT_MPR_IC) != htole32(GDT_MPR_MAGIC)) {
+ device_printf(dev, "cannot access DPMEM at 0x%lx (shadowed?)\n",
+ rman_get_start(gdt->sc_dpmem));
error = ENXIO;
goto err;
}
- bus_space_set_region_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_I960_SZ, htole32(0),
- GDT_MPR_SZ >> 2);
+ bus_set_region_4(gdt->sc_dpmem, GDT_I960_SZ, htole32(0), GDT_MPR_SZ >> 2);
/* Disable everything */
- bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_EDOOR_EN,
- bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh,
- GDT_EDOOR_EN) | 4);
- bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_EDOOR, 0xff);
- bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_STATUS,
- 0);
- bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_CMD_INDEX,
- 0);
-
- bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_INFO,
- htole32(gdt->sc_dpmembase));
- bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_CMD_INDX,
- 0xff);
- bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_LDOOR, 1);
+ bus_write_1(gdt->sc_dpmem, GDT_EDOOR_EN,
+ bus_read_1(gdt->sc_dpmem, GDT_EDOOR_EN) | 4);
+ bus_write_1(gdt->sc_dpmem, GDT_MPR_EDOOR, 0xff);
+ bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS, 0);
+ bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_CMD_INDEX, 0);
+
+ bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO,
+ htole32(rman_get_start(gdt->sc_dpmem)));
+ bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_CMD_INDX, 0xff);
+ bus_write_1(gdt->sc_dpmem, GDT_MPR_LDOOR, 1);
DELAY(20);
retries = GDT_RETRIES;
- while (bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh,
- GDT_MPR_IC + GDT_S_STATUS) != 0xff) {
+ while (bus_read_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS) != 0xff) {
if (--retries == 0) {
- printf("DEINIT failed\n");
+ device_printf(dev, "DEINIT failed\n");
error = ENXIO;
goto err;
}
DELAY(1);
}
- protocol = (uint8_t)le32toh(bus_space_read_4(gdt->sc_dpmemt, gdt->sc_dpmemh,
- GDT_MPR_IC + GDT_S_INFO));
- bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_STATUS,
- 0);
+ protocol = (uint8_t)le32toh(bus_read_4(gdt->sc_dpmem,
+ GDT_MPR_IC + GDT_S_INFO));
+ bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS, 0);
if (protocol != GDT_PROTOCOL_VERSION) {
- printf("unsupported protocol %d\n", protocol);
+ device_printf(dev, "unsupported protocol %d\n", protocol);
error = ENXIO;
goto err;
}
- /* special commnd to controller BIOS */
- bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_INFO,
- htole32(0));
- bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh,
- GDT_MPR_IC + GDT_S_INFO + sizeof (u_int32_t), htole32(0));
- bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh,
- GDT_MPR_IC + GDT_S_INFO + 2 * sizeof (u_int32_t),
- htole32(1));
- bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh,
- GDT_MPR_IC + GDT_S_INFO + 3 * sizeof (u_int32_t),
- htole32(0));
- bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_CMD_INDX,
- 0xfe);
- bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_LDOOR, 1);
+ /* special command to controller BIOS */
+ bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO, htole32(0));
+ bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO + sizeof (u_int32_t),
+ htole32(0));
+ bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO + 2 * sizeof (u_int32_t),
+ htole32(1));
+ bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO + 3 * sizeof (u_int32_t),
+ htole32(0));
+ bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_CMD_INDX, 0xfe);
+ bus_write_1(gdt->sc_dpmem, GDT_MPR_LDOOR, 1);
DELAY(20);
retries = GDT_RETRIES;
- while (bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh,
- GDT_MPR_IC + GDT_S_STATUS) != 0xfe) {
+ while (bus_read_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS) != 0xfe) {
if (--retries == 0) {
- printf("initialization error\n");
+ device_printf(dev, "initialization error\n");
error = ENXIO;
goto err;
}
DELAY(1);
}
- bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_STATUS,
- 0);
+ bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS, 0);
gdt->sc_ic_all_size = GDT_MPR_SZ;
@@ -326,7 +310,7 @@ iir_pci_attach(device_t dev)
/*nsegments*/GDT_MAXSG,
/*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
/*flags*/0, /*lockfunc*/busdma_lock_mutex,
- /*lockarg*/&Giant, &gdt->sc_parent_dmat) != 0) {
+ /*lockarg*/&gdt->sc_lock, &gdt->sc_parent_dmat) != 0) {
error = ENXIO;
goto err;
}
@@ -342,7 +326,7 @@ iir_pci_attach(device_t dev)
iir_attach(gdt);
/* associate interrupt handler */
- if (bus_setup_intr( dev, irq, INTR_TYPE_CAM,
+ if (bus_setup_intr(dev, irq, INTR_TYPE_CAM | INTR_MPSAFE,
NULL, iir_intr, gdt, &ih )) {
device_printf(dev, "Unable to register interrupt handler\n");
error = ENXIO;
@@ -355,10 +339,11 @@ iir_pci_attach(device_t dev)
err:
if (irq)
bus_release_resource( dev, SYS_RES_IRQ, 0, irq );
-/*
- if (io)
- bus_release_resource( dev, SYS_RES_MEMORY, rid, io );
-*/
+
+ if (gdt->sc_dpmem)
+ bus_release_resource( dev, SYS_RES_MEMORY, rid, gdt->sc_dpmem );
+ mtx_destroy(&gdt->sc_lock);
+
return (error);
}
@@ -371,11 +356,9 @@ gdt_pci_enable_intr(struct gdt_softc *gdt)
switch(GDT_CLASS(gdt)) {
case GDT_MPR:
- bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh,
- GDT_MPR_EDOOR, 0xff);
- bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_EDOOR_EN,
- bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh,
- GDT_EDOOR_EN) & ~4);
+ bus_write_1(gdt->sc_dpmem, GDT_MPR_EDOOR, 0xff);
+ bus_write_1(gdt->sc_dpmem, GDT_EDOOR_EN,
+ bus_read_1(gdt->sc_dpmem, GDT_EDOOR_EN) & ~4);
break;
}
}
@@ -396,15 +379,14 @@ gdt_mpr_copy_cmd(struct gdt_softc *gdt, struct gdt_ccb *gccb)
gdt->sc_cmd_off += cp_count;
- bus_space_write_region_4(gdt->sc_dpmemt, gdt->sc_dpmemh,
- GDT_MPR_IC + GDT_DPR_CMD + dp_offset,
- (u_int32_t *)gccb->gc_cmd, cp_count >> 2);
- bus_space_write_2(gdt->sc_dpmemt, gdt->sc_dpmemh,
- GDT_MPR_IC + GDT_COMM_QUEUE + cmd_no * GDT_COMM_Q_SZ + GDT_OFFSET,
- htole16(GDT_DPMEM_COMMAND_OFFSET + dp_offset));
- bus_space_write_2(gdt->sc_dpmemt, gdt->sc_dpmemh,
- GDT_MPR_IC + GDT_COMM_QUEUE + cmd_no * GDT_COMM_Q_SZ + GDT_SERV_ID,
- htole16(gccb->gc_service));
+ bus_write_region_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_DPR_CMD + dp_offset,
+ (u_int32_t *)gccb->gc_cmd, cp_count >> 2);
+ bus_write_2(gdt->sc_dpmem,
+ GDT_MPR_IC + GDT_COMM_QUEUE + cmd_no * GDT_COMM_Q_SZ + GDT_OFFSET,
+ htole16(GDT_DPMEM_COMMAND_OFFSET + dp_offset));
+ bus_write_2(gdt->sc_dpmem,
+ GDT_MPR_IC + GDT_COMM_QUEUE + cmd_no * GDT_COMM_Q_SZ + GDT_SERV_ID,
+ htole16(gccb->gc_service));
}
u_int8_t
@@ -412,7 +394,7 @@ gdt_mpr_get_status(struct gdt_softc *gdt)
{
GDT_DPRINTF(GDT_D_MISC, ("gdt_mpr_get_status(%p) ", gdt));
- return bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_EDOOR);
+ return bus_read_1(gdt->sc_dpmem, GDT_MPR_EDOOR);
}
void
@@ -422,39 +404,32 @@ gdt_mpr_intr(struct gdt_softc *gdt, struct gdt_intr_ctx *ctx)
GDT_DPRINTF(GDT_D_INTR, ("gdt_mpr_intr(%p) ", gdt));
- bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_EDOOR, 0xff);
+ bus_write_1(gdt->sc_dpmem, GDT_MPR_EDOOR, 0xff);
if (ctx->istatus & 0x80) { /* error flag */
ctx->istatus &= ~0x80;
- ctx->cmd_status = bus_space_read_2(gdt->sc_dpmemt,
- gdt->sc_dpmemh, GDT_MPR_STATUS);
+ ctx->cmd_status = bus_read_2(gdt->sc_dpmem, GDT_MPR_STATUS);
} else /* no error */
ctx->cmd_status = GDT_S_OK;
- ctx->info =
- bus_space_read_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_INFO);
- ctx->service =
- bus_space_read_2(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_SERVICE);
- ctx->info2 =
- bus_space_read_4(gdt->sc_dpmemt, gdt->sc_dpmemh,
- GDT_MPR_INFO + sizeof (u_int32_t));
+ ctx->info = bus_read_4(gdt->sc_dpmem, GDT_MPR_INFO);
+ ctx->service = bus_read_2(gdt->sc_dpmem, GDT_MPR_SERVICE);
+ ctx->info2 = bus_read_4(gdt->sc_dpmem, GDT_MPR_INFO + sizeof (u_int32_t));
/* event string */
if (ctx->istatus == GDT_ASYNCINDEX) {
if (ctx->service != GDT_SCREENSERVICE &&
(gdt->sc_fw_vers & 0xff) >= 0x1a) {
- gdt->sc_dvr.severity =
- bus_space_read_1(gdt->sc_dpmemt,gdt->sc_dpmemh, GDT_SEVERITY);
+ gdt->sc_dvr.severity = bus_read_1(gdt->sc_dpmem, GDT_SEVERITY);
for (i = 0; i < 256; ++i) {
- gdt->sc_dvr.event_string[i] =
- bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh,
- GDT_EVT_BUF + i);
+ gdt->sc_dvr.event_string[i] = bus_read_1(gdt->sc_dpmem,
+ GDT_EVT_BUF + i);
if (gdt->sc_dvr.event_string[i] == 0)
break;
}
}
}
- bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_SEMA1, 0);
+ bus_write_1(gdt->sc_dpmem, GDT_MPR_SEMA1, 0);
}
void
@@ -462,7 +437,7 @@ gdt_mpr_release_event(struct gdt_softc *gdt)
{
GDT_DPRINTF(GDT_D_MISC, ("gdt_mpr_release_event(%p) ", gdt));
- bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_LDOOR, 1);
+ bus_write_1(gdt->sc_dpmem, GDT_MPR_LDOOR, 1);
}
void
@@ -470,7 +445,7 @@ gdt_mpr_set_sema0(struct gdt_softc *gdt)
{
GDT_DPRINTF(GDT_D_MISC, ("gdt_mpr_set_sema0(%p) ", gdt));
- bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_SEMA0, 1);
+ bus_write_1(gdt->sc_dpmem, GDT_MPR_SEMA0, 1);
}
int
@@ -478,6 +453,5 @@ gdt_mpr_test_busy(struct gdt_softc *gdt)
{
GDT_DPRINTF(GDT_D_MISC, ("gdt_mpr_test_busy(%p) ", gdt));
- return (bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh,
- GDT_MPR_SEMA0) & 1);
+ return (bus_read_1(gdt->sc_dpmem, GDT_MPR_SEMA0) & 1);
}
OpenPOWER on IntegriCloud