aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/aha
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2012-10-15 15:59:13 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2012-10-15 15:59:13 +0000
commit0e87317a92fadea0f89a23c963d52c40f9f506a6 (patch)
treec1d0d3b3d2226862567fd9564826ad386e062738 /sys/dev/aha
parenta25d65b0648f7ec24390e9867ebe73a0e536a1ed (diff)
downloadsrc-0e87317a92fadea0f89a23c963d52c40f9f506a6.tar.gz
src-0e87317a92fadea0f89a23c963d52c40f9f506a6.zip
Add locking to the aha(4) driver and mark it MPSAFE.
- Remove use of explicit bus space handles and tags. Tested by: no one
Notes
Notes: svn path=/head/; revision=241589
Diffstat (limited to 'sys/dev/aha')
-rw-r--r--sys/dev/aha/aha.c105
-rw-r--r--sys/dev/aha/aha_isa.c64
-rw-r--r--sys/dev/aha/aha_mca.c14
-rw-r--r--sys/dev/aha/ahareg.h14
4 files changed, 86 insertions, 111 deletions
diff --git a/sys/dev/aha/aha.c b/sys/dev/aha/aha.c
index ace7d257cb92..e84968aed39a 100644
--- a/sys/dev/aha/aha.c
+++ b/sys/dev/aha/aha.c
@@ -147,6 +147,7 @@ static void ahaallocccbs(struct aha_softc *aha);
static bus_dmamap_callback_t ahaexecuteccb;
static void ahadone(struct aha_softc *aha, struct aha_ccb *accb,
aha_mbi_comp_code_t comp_code);
+static void aha_intr_locked(struct aha_softc *aha);
/* Host adapter command functions */
static int ahareset(struct aha_softc* aha, int hard_reset);
@@ -168,7 +169,7 @@ static void ahaaction(struct cam_sim *sim, union ccb *ccb);
static void ahapoll(struct cam_sim *sim);
/* Our timeout handler */
-static timeout_t ahatimeout;
+static void ahatimeout(void *arg);
/* Exported functions */
void
@@ -179,11 +180,9 @@ aha_alloc(struct aha_softc *aha, int unit, bus_space_tag_t tag,
SLIST_INIT(&aha->free_aha_ccbs);
LIST_INIT(&aha->pending_ccbs);
SLIST_INIT(&aha->sg_maps);
- aha->unit = unit;
- aha->tag = tag;
- aha->bsh = bsh;
aha->ccb_sg_opcode = INITIATOR_SG_CCB_WRESID;
aha->ccb_ccb_opcode = INITIATOR_CCB_WRESID;
+ mtx_init(&aha->lock, "aha", NULL, MTX_DEF);
}
void
@@ -225,6 +224,7 @@ aha_free(struct aha_softc *aha)
case 0:
break;
}
+ mtx_destroy(&aha->lock);
}
/*
@@ -464,7 +464,7 @@ aha_init(struct aha_softc* aha)
/* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT,
/* flags */ BUS_DMA_ALLOCNOW,
/* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockarg */ &aha->lock,
&aha->buffer_dmat) != 0) {
goto error_exit;
}
@@ -484,8 +484,8 @@ aha_init(struct aha_softc* aha)
/* nsegments */ 1,
/* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&aha->mailbox_dmat) != 0) {
goto error_exit;
}
@@ -523,8 +523,8 @@ aha_init(struct aha_softc* aha)
/* nsegments */ 1,
/* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&aha->ccb_dmat) != 0) {
goto error_exit;
}
@@ -556,8 +556,8 @@ aha_init(struct aha_softc* aha)
/* nsegments */ 1,
/* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&aha->sg_dmat) != 0)
goto error_exit;
@@ -605,22 +605,27 @@ aha_attach(struct aha_softc *aha)
/*
* Construct our SIM entry
*/
- aha->sim = cam_sim_alloc(ahaaction, ahapoll, "aha", aha, aha->unit,
- &Giant, 2, tagged_dev_openings, devq);
+ aha->sim = cam_sim_alloc(ahaaction, ahapoll, "aha", aha,
+ device_get_unit(aha->dev), &aha->lock, 2, tagged_dev_openings,
+ devq);
if (aha->sim == NULL) {
cam_simq_free(devq);
return (ENOMEM);
}
+ mtx_lock(&aha->lock);
if (xpt_bus_register(aha->sim, aha->dev, 0) != CAM_SUCCESS) {
cam_sim_free(aha->sim, /*free_devq*/TRUE);
+ mtx_unlock(&aha->lock);
return (ENXIO);
}
if (xpt_create_path(&aha->path, /*periph*/NULL, cam_sim_path(aha->sim),
CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
xpt_bus_deregister(cam_sim_path(aha->sim));
cam_sim_free(aha->sim, /*free_devq*/TRUE);
+ mtx_unlock(&aha->lock);
return (ENXIO);
}
+ mtx_unlock(&aha->lock);
return (0);
}
@@ -664,6 +669,7 @@ ahaallocccbs(struct aha_softc *aha)
next_ccb->sg_list = segs;
next_ccb->sg_list_phys = physaddr;
next_ccb->flags = ACCB_FREE;
+ callout_init_mtx(&next_ccb->timer, &aha->lock, 0);
error = bus_dmamap_create(aha->buffer_dmat, /*flags*/0,
&next_ccb->dmamap);
if (error != 0)
@@ -685,9 +691,9 @@ ahaallocccbs(struct aha_softc *aha)
static __inline void
ahafreeccb(struct aha_softc *aha, struct aha_ccb *accb)
{
- int s;
- s = splcam();
+ if (!dumping)
+ mtx_assert(&aha->lock, MA_OWNED);
if ((accb->flags & ACCB_ACTIVE) != 0)
LIST_REMOVE(&accb->ccb->ccb_h, sim_links.le);
if (aha->resource_shortage != 0
@@ -698,16 +704,15 @@ ahafreeccb(struct aha_softc *aha, struct aha_ccb *accb)
accb->flags = ACCB_FREE;
SLIST_INSERT_HEAD(&aha->free_aha_ccbs, accb, links);
aha->active_ccbs--;
- splx(s);
}
static struct aha_ccb*
ahagetccb(struct aha_softc *aha)
{
struct aha_ccb* accb;
- int s;
- s = splcam();
+ if (!dumping)
+ mtx_assert(&aha->lock, MA_OWNED);
if ((accb = SLIST_FIRST(&aha->free_aha_ccbs)) != NULL) {
SLIST_REMOVE_HEAD(&aha->free_aha_ccbs, links);
aha->active_ccbs++;
@@ -721,7 +726,6 @@ ahagetccb(struct aha_softc *aha)
aha->active_ccbs++;
}
}
- splx(s);
return (accb);
}
@@ -730,11 +734,11 @@ static void
ahaaction(struct cam_sim *sim, union ccb *ccb)
{
struct aha_softc *aha;
- int s;
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahaaction\n"));
aha = (struct aha_softc *)cam_sim_softc(sim);
+ mtx_assert(&aha->lock, MA_OWNED);
switch (ccb->ccb_h.func_code) {
/* Common cases first */
@@ -747,9 +751,7 @@ ahaaction(struct cam_sim *sim, union ccb *ccb)
* Get an accb to use.
*/
if ((accb = ahagetccb(aha)) == NULL) {
- s = splcam();
aha->resource_shortage = TRUE;
- splx(s);
xpt_freeze_simq(aha->sim, /*count*/1);
ccb->ccb_h.status = CAM_REQUEUE_REQ;
xpt_done(ccb);
@@ -818,7 +820,6 @@ ahaaction(struct cam_sim *sim, union ccb *ccb)
if ((ccbh->flags & CAM_DATA_PHYS)==0) {
int error;
- s = splsoftvm();
error = bus_dmamap_load(
aha->buffer_dmat,
accb->dmamap,
@@ -840,7 +841,6 @@ ahaaction(struct cam_sim *sim, union ccb *ccb)
csio->ccb_h.status |=
CAM_RELEASE_SIMQ;
}
- splx(s);
} else {
struct bus_dma_segment seg;
@@ -1017,7 +1017,6 @@ ahaexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
struct aha_ccb *accb;
union ccb *ccb;
struct aha_softc *aha;
- int s;
uint32_t paddr;
accb = (struct aha_ccb *)arg;
@@ -1077,8 +1076,6 @@ ahaexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
ahautoa24(0, accb->hccb.data_addr);
}
- s = splcam();
-
/*
* Last time we need to check if this CCB needs to
* be aborted.
@@ -1088,7 +1085,6 @@ ahaexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
bus_dmamap_unload(aha->buffer_dmat, accb->dmamap);
ahafreeccb(aha, accb);
xpt_done(ccb);
- splx(s);
return;
}
@@ -1096,8 +1092,8 @@ ahaexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
ccb->ccb_h.status |= CAM_SIM_QUEUED;
LIST_INSERT_HEAD(&aha->pending_ccbs, &ccb->ccb_h, sim_links.le);
- ccb->ccb_h.timeout_ch = timeout(ahatimeout, (caddr_t)accb,
- (ccb->ccb_h.timeout * hz) / 1000);
+ callout_reset(&accb->timer, (ccb->ccb_h.timeout * hz) / 1000,
+ ahatimeout, accb);
/* Tell the adapter about this command */
if (aha->cur_outbox->action_code != AMBO_FREE) {
@@ -1111,7 +1107,7 @@ ahaexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
device_printf(aha->dev,
"Encountered busy mailbox with %d out of %d "
"commands active!!!", aha->active_ccbs, aha->max_ccbs);
- untimeout(ahatimeout, accb, ccb->ccb_h.timeout_ch);
+ callout_stop(&aacb->timer);
if (nseg != 0)
bus_dmamap_unload(aha->buffer_dmat, accb->dmamap);
ahafreeccb(aha, accb);
@@ -1127,17 +1123,25 @@ ahaexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
aha_outb(aha, COMMAND_REG, AOP_START_MBOX);
ahanextoutbox(aha);
- splx(s);
}
void
aha_intr(void *arg)
{
struct aha_softc *aha;
+
+ aha = arg;
+ mtx_lock(&aha->lock);
+ aha_intr_locked(aha);
+ mtx_unlock(&aha->lock);
+}
+
+void
+aha_intr_locked(struct aha_softc *aha)
+{
u_int intstat;
uint32_t paddr;
- aha = (struct aha_softc *)arg;
while (((intstat = aha_inb(aha, INTSTAT_REG)) & INTR_PENDING) != 0) {
if ((intstat & CMD_COMPLETE) != 0) {
aha->latched_status = aha_inb(aha, STATUS_REG);
@@ -1220,9 +1224,9 @@ ahadone(struct aha_softc *aha, struct aha_ccb *accb, aha_mbi_comp_code_t comp_co
ccb_h = LIST_NEXT(ccb_h, sim_links.le);
ahadone(aha, pending_accb, AMBI_ERROR);
} else {
- ccb_h->timeout_ch = timeout(ahatimeout,
- (caddr_t)pending_accb,
- (ccb_h->timeout * hz) / 1000);
+ callout_reset(&pending_accb->timer,
+ (ccb_h->timeout * hz) / 1000,
+ ahatimeout, pending_accb);
ccb_h = LIST_NEXT(ccb_h, sim_links.le);
}
}
@@ -1230,7 +1234,7 @@ ahadone(struct aha_softc *aha, struct aha_ccb *accb, aha_mbi_comp_code_t comp_co
return;
}
- untimeout(ahatimeout, accb, ccb->ccb_h.timeout_ch);
+ callout_stop(&accb->timer);
switch (comp_code) {
case AMBI_FREE:
@@ -1446,7 +1450,6 @@ aha_cmd(struct aha_softc *aha, aha_op_t opcode, uint8_t *params,
u_int saved_status;
u_int intstat;
u_int reply_buf_size;
- int s;
int cmd_complete;
int error;
@@ -1465,15 +1468,11 @@ aha_cmd(struct aha_softc *aha, aha_op_t opcode, uint8_t *params,
* and wait for all completions to occur if necessary.
*/
timeout = 10000;
- s = splcam();
while (LIST_FIRST(&aha->pending_ccbs) != NULL && --timeout) {
/* Fire the interrupt handler in case interrupts are blocked */
aha_intr(aha);
- splx(s);
DELAY(10);
- s = splcam();
}
- splx(s);
if (timeout == 0) {
device_printf(aha->dev,
@@ -1516,10 +1515,8 @@ aha_cmd(struct aha_softc *aha, aha_op_t opcode, uint8_t *params,
timeout = 10000;
while (param_len && --timeout) {
DELAY(100);
- s = splcam();
status = aha_inb(aha, STATUS_REG);
intstat = aha_inb(aha, INTSTAT_REG);
- splx(s);
if ((intstat & (INTR_PENDING|CMD_COMPLETE))
== (INTR_PENDING|CMD_COMPLETE)) {
@@ -1553,10 +1550,8 @@ aha_cmd(struct aha_softc *aha, aha_op_t opcode, uint8_t *params,
*/
while (cmd_complete == 0 && --cmd_timeout) {
- s = splcam();
status = aha_inb(aha, STATUS_REG);
intstat = aha_inb(aha, INTSTAT_REG);
- splx(s);
if (aha->command_cmp != 0) {
cmd_complete = 1;
@@ -1601,9 +1596,7 @@ aha_cmd(struct aha_softc *aha, aha_op_t opcode, uint8_t *params,
* Clear any pending interrupts. Block interrupts so our
* interrupt handler is not re-entered.
*/
- s = splcam();
aha_intr(aha);
- splx(s);
if (error != 0)
return (error);
@@ -1764,7 +1757,7 @@ ahamapsgs(void *arg, bus_dma_segment_t *segs, int nseg, int error)
static void
ahapoll(struct cam_sim *sim)
{
- aha_intr(cam_sim_softc(sim));
+ aha_intr_locked(cam_sim_softc(sim));
}
static void
@@ -1773,23 +1766,20 @@ ahatimeout(void *arg)
struct aha_ccb *accb;
union ccb *ccb;
struct aha_softc *aha;
- int s;
uint32_t paddr;
struct ccb_hdr *ccb_h;
accb = (struct aha_ccb *)arg;
ccb = accb->ccb;
aha = (struct aha_softc *)ccb->ccb_h.ccb_aha_ptr;
+ mtx_assert(&aha->lock, MA_OWNED);
xpt_print_path(ccb->ccb_h.path);
printf("CCB %p - timed out\n", (void *)accb);
- s = splcam();
-
if ((accb->flags & ACCB_ACTIVE) == 0) {
xpt_print_path(ccb->ccb_h.path);
printf("CCB %p - timed out CCB already completed\n",
(void *)accb);
- splx(s);
return;
}
@@ -1814,7 +1804,7 @@ ahatimeout(void *arg)
struct aha_ccb *pending_accb;
pending_accb = (struct aha_ccb *)ccb_h->ccb_accb_ptr;
- untimeout(ahatimeout, pending_accb, ccb_h->timeout_ch);
+ callout_stop(&pending_accb->timer);
ccb_h = LIST_NEXT(ccb_h, sim_links.le);
}
}
@@ -1843,7 +1833,7 @@ ahatimeout(void *arg)
* later which will attempt a bus reset.
*/
accb->flags |= ACCB_DEVICE_RESET;
- ccb->ccb_h.timeout_ch = timeout(ahatimeout, (caddr_t)accb, 2 * hz);
+ callout_reset(&aacb->timer, 2 * hz, ahatimeout, accb);
aha->recovery_accb->hccb.opcode = INITIATOR_BUS_DEV_RESET;
/* No Data Transfer */
@@ -1860,17 +1850,18 @@ ahatimeout(void *arg)
aha_outb(aha, COMMAND_REG, AOP_START_MBOX);
ahanextoutbox(aha);
}
-
- splx(s);
}
int
aha_detach(struct aha_softc *aha)
{
+ mtx_lock(&aha->lock);
xpt_async(AC_LOST_DEVICE, aha->path, NULL);
xpt_free_path(aha->path);
xpt_bus_deregister(cam_sim_path(aha->sim));
cam_sim_free(aha->sim, /*free_devq*/TRUE);
+ mtx_unlock(&aha->lock);
+ /* XXX: Drain all timers? */
return (0);
}
MODULE_DEPEND(aha, cam, 1, 1, 1);
diff --git a/sys/dev/aha/aha_isa.c b/sys/dev/aha/aha_isa.c
index 7485563ac68c..4a60cb6f797c 100644
--- a/sys/dev/aha/aha_isa.c
+++ b/sys/dev/aha/aha_isa.c
@@ -109,7 +109,6 @@ aha_isa_probe(device_t dev)
struct aha_softc *aha = device_get_softc(dev);
int error;
u_long port_start;
- struct resource *port_res;
int port_rid;
int drq;
int irq;
@@ -121,20 +120,19 @@ aha_isa_probe(device_t dev)
return (ENXIO);
port_rid = 0;
- port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &port_rid,
- 0, ~0, AHA_NREGS, RF_ACTIVE);
+ aha->port = bus_alloc_resource(dev, SYS_RES_IOPORT, &port_rid,
+ 0ul, ~0ul, AHA_NREGS, RF_ACTIVE);
- if (port_res == NULL)
+ if (aha->port == NULL)
return (ENXIO);
port_start = rman_get_start(port_res);
- aha_alloc(aha, device_get_unit(dev), rman_get_bustag(port_res),
- rman_get_bushandle(port_res));
+ aha_alloc(aha);
/* See if there is really a card present */
if (aha_probe(aha) || aha_fetch_adapter_info(aha)) {
aha_free(aha);
- bus_release_resource(dev, SYS_RES_IOPORT, port_rid, port_res);
+ bus_release_resource(dev, SYS_RES_IOPORT, port_rid, aha->port);
return (ENXIO);
}
@@ -151,11 +149,12 @@ aha_isa_probe(device_t dev)
(uintmax_t)port_start);
aha_free(aha);
bus_release_resource(dev, SYS_RES_IOPORT, port_rid,
- port_res);
+ aha->port);
return (ENXIO);
}
- bus_release_resource(dev, SYS_RES_IOPORT, port_rid, port_res);
+ bus_release_resource(dev, SYS_RES_IOPORT, port_rid, aha->port);
+ aha->port = NULL;
switch (config_data.dma_chan) {
case DMA_CHAN_5:
@@ -188,17 +187,12 @@ static int
aha_isa_attach(device_t dev)
{
struct aha_softc *aha = device_get_softc(dev);
- bus_dma_filter_t *filter;
- void *filter_arg;
- bus_addr_t lowaddr;
- void *ih;
int error = ENOMEM;
- int aha_free_needed = 0;
aha->dev = dev;
aha->portrid = 0;
aha->port = bus_alloc_resource(dev, SYS_RES_IOPORT, &aha->portrid,
- 0, ~0, AHA_NREGS, RF_ACTIVE);
+ 0ul, ~0ul, AHA_NREGS, RF_ACTIVE);
if (!aha->port) {
device_printf(dev, "Unable to allocate I/O ports\n");
goto fail;
@@ -227,23 +221,19 @@ aha_isa_attach(device_t dev)
isa_dmacascade(rman_get_start(aha->drq));
/* Allocate our parent dmatag */
- filter = NULL;
- filter_arg = NULL;
- lowaddr = BUS_SPACE_MAXADDR_24BIT;
-
if (bus_dma_tag_create( /* parent */ bus_get_dma_tag(dev),
/* alignemnt */ 1,
/* boundary */ 0,
- /* lowaddr */ lowaddr,
+ /* lowaddr */ BUS_SPACE_MAXADDR_24BIT,
/* highaddr */ BUS_SPACE_MAXADDR,
- /* filter */ filter,
- /* filterarg */ filter_arg,
+ /* filter */ NULL,
+ /* filterarg */ NULL,
/* maxsize */ BUS_SPACE_MAXSIZE_24BIT,
/* nsegments */ ~0,
/* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&aha->parent_dmat) != 0) {
device_printf(dev, "dma tag create failed.\n");
goto fail;
@@ -263,7 +253,6 @@ aha_isa_attach(device_t dev)
aha->ccb_sg_opcode = INITIATOR_SG_CCB;
aha->ccb_ccb_opcode = INITIATOR_CCB;
}
- aha_free_needed++;
error = aha_attach(aha);
if (error) {
@@ -271,20 +260,20 @@ aha_isa_attach(device_t dev)
goto fail;
}
- error = bus_setup_intr(dev, aha->irq, INTR_TYPE_CAM|INTR_ENTROPY,
- NULL, aha_intr, aha, &ih);
+ error = bus_setup_intr(dev, aha->irq, INTR_TYPE_CAM|INTR_ENTROPY|
+ INTR_MPSAFE, NULL, aha_intr, aha, &aha->ih);
if (error) {
device_printf(dev, "Unable to register interrupt handler\n");
+ aha_detach(aha);
goto fail;
}
return (0);
fail: ;
+ aha_free(aha);
bus_free_resource(dev, SYS_RES_IOPORT, aha->port);
bus_free_resource(dev, SYS_RES_IRQ, aha->irq);
bus_free_resource(dev, SYS_RES_DRQ, aha->drq);
- if (aha_free_needed)
- aha_free(aha);
return (error);
}
@@ -298,16 +287,15 @@ aha_isa_detach(device_t dev)
if (error)
device_printf(dev, "failed to unregister interrupt handler\n");
- bus_free_resource(dev, SYS_RES_IOPORT, aha->port);
- bus_free_resource(dev, SYS_RES_IRQ, aha->irq);
- bus_free_resource(dev, SYS_RES_DRQ, aha->drq);
-
error = aha_detach(aha);
if (error) {
device_printf(dev, "detach failed\n");
return (error);
}
aha_free(aha);
+ bus_free_resource(dev, SYS_RES_IOPORT, aha->port);
+ bus_free_resource(dev, SYS_RES_IRQ, aha->irq);
+ bus_free_resource(dev, SYS_RES_DRQ, aha->drq);
return (0);
}
@@ -319,7 +307,6 @@ aha_isa_identify(driver_t *driver, device_t parent)
bus_addr_t ioport;
struct aha_softc aha;
int rid;
- struct resource *res;
device_t child;
/* Attempt to find an adapter */
@@ -334,12 +321,11 @@ aha_isa_identify(driver_t *driver, device_t parent)
* XXX kldload/kldunload.
*/
rid = 0;
- res = bus_alloc_resource(parent, SYS_RES_IOPORT, &rid,
+ aha->port = bus_alloc_resource(parent, SYS_RES_IOPORT, &rid,
ioport, ioport, AHA_NREGS, RF_ACTIVE);
- if (res == NULL)
+ if (aha->port == NULL)
continue;
- aha_alloc(&aha, -1, rman_get_bustag(res),
- rman_get_bushandle(res));
+ aha_alloc(&aha);
/* See if there is really a card present */
if (aha_probe(&aha) || aha_fetch_adapter_info(&aha))
goto not_this_one;
@@ -350,7 +336,7 @@ aha_isa_identify(driver_t *driver, device_t parent)
* that.
*/
not_this_one:;
- bus_release_resource(parent, SYS_RES_IOPORT, rid, res);
+ bus_release_resource(parent, SYS_RES_IOPORT, rid, aha->port);
aha_free(&aha);
}
}
diff --git a/sys/dev/aha/aha_mca.c b/sys/dev/aha/aha_mca.c
index f09a7a46f5ef..0c50630dd68b 100644
--- a/sys/dev/aha/aha_mca.c
+++ b/sys/dev/aha/aha_mca.c
@@ -118,8 +118,6 @@ aha_mca_attach (device_t dev)
{
struct aha_softc * sc = device_get_softc(dev);
int error = ENOMEM;
- int unit = device_get_unit(dev);
- void * ih;
sc->portrid = 0;
sc->port = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->portrid,
@@ -145,8 +143,7 @@ aha_mca_attach (device_t dev)
goto bad;
}
- aha_alloc(sc, unit, rman_get_bustag(sc->port),
- rman_get_bushandle(sc->port));
+ aha_alloc(sc);
error = aha_probe(sc);
if (error) {
device_printf(dev, "aha_probe() failed!\n");
@@ -173,8 +170,8 @@ aha_mca_attach (device_t dev)
/* nsegments */ ~0,
/* maxsegsz */ BUS_SPACE_MAXSIZE_24BIT,
/* flags */ 0,
- /* lockfunc */ busdma_lock_mutex,
- /* lockarg */ &Giant,
+ /* lockfunc */ NULL,
+ /* lockarg */ NULL,
&sc->parent_dmat);
if (error) {
device_printf(dev, "bus_dma_tag_create() failed!\n");
@@ -193,10 +190,11 @@ aha_mca_attach (device_t dev)
goto bad;
}
- error = bus_setup_intr(dev, sc->irq, INTR_TYPE_CAM | INTR_ENTROPY,
- NULL, aha_intr, sc, &ih);
+ error = bus_setup_intr(dev, sc->irq, INTR_TYPE_CAM | INTR_ENTROPY |
+ INTR_MPSAFE, NULL, aha_intr, sc, &aha->ih);
if (error) {
device_printf(dev, "Unable to register interrupt handler\n");
+ aha_detach(sc);
goto bad;
}
diff --git a/sys/dev/aha/ahareg.h b/sys/dev/aha/ahareg.h
index 5dc21a3c35fd..771338666f2d 100644
--- a/sys/dev/aha/ahareg.h
+++ b/sys/dev/aha/ahareg.h
@@ -297,6 +297,7 @@ struct aha_ccb {
uint32_t flags;
union ccb *ccb;
bus_dmamap_t dmamap;
+ struct callout timer;
aha_sg_t *sg_list;
uint32_t sg_list_phys;
};
@@ -309,8 +310,6 @@ struct sg_map_node {
};
struct aha_softc {
- bus_space_tag_t tag;
- bus_space_handle_t bsh;
struct cam_sim *sim;
struct cam_path *path;
aha_mbox_out_t *cur_outbox;
@@ -368,11 +367,12 @@ struct aha_softc {
struct resource *irq;
struct resource *port;
struct resource *drq;
- int irqrid;
- int portrid;
- int drqrid;
+ int irqrid;
+ int portrid;
+ int drqrid;
void **ih;
device_t dev;
+ struct mtx lock;
};
void aha_alloc(struct aha_softc *, int, bus_space_tag_t, bus_space_handle_t);
@@ -390,10 +390,10 @@ int aha_probe(struct aha_softc *);
#define DEFAULT_CMD_TIMEOUT 10000 /* 1 sec */
#define aha_inb(aha, port) \
- bus_space_read_1((aha)->tag, (aha)->bsh, port)
+ bus_read_1((aha)->port, port)
#define aha_outb(aha, port, value) \
- bus_space_write_1((aha)->tag, (aha)->bsh, port, value)
+ bus_write_1((aha)->port, port, value)
#define ADP0100_PNP 0x00019004 /* ADP0100 */
#define AHA1540_PNP 0x40159004 /* ADP1540 */