summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2012-10-15 16:09:59 +0000
committerjhb <jhb@FreeBSD.org>2012-10-15 16:09:59 +0000
commitfcf1c6db5250deb9191312a95f978e557d091b14 (patch)
tree5829ecb29696b68ee5df08cafc2d610e3430d0bd
parent9ffe91c4a4d92a29e7f417b0cf3c9fb449aa5e0f (diff)
downloadFreeBSD-src-fcf1c6db5250deb9191312a95f978e557d091b14.zip
FreeBSD-src-fcf1c6db5250deb9191312a95f978e557d091b14.tar.gz
Add locking to the aic(4) driver and mark it MPSAFE.
- Move 'free_scbs' into the softc rather than having it be a global list and convert it to an SLIST instead of a hand-rolled linked-list. - Use device_printf() and device_get_unit() instead of storing the unit number in the softc. - Remove use of explicit bus space handles and tags. - Don't call device_set_desc() in the pccard attach routine, instead set a default description during the pccard probe if the matching product doesn't have a name. Tested by: no one
-rw-r--r--sys/dev/aic/aic.c106
-rw-r--r--sys/dev/aic/aic_cbus.c22
-rw-r--r--sys/dev/aic/aic_isa.c22
-rw-r--r--sys/dev/aic/aic_pccard.c26
-rw-r--r--sys/dev/aic/aicvar.h28
5 files changed, 110 insertions, 94 deletions
diff --git a/sys/dev/aic/aic.c b/sys/dev/aic/aic.c
index 4d5b5c3..d83df32 100644
--- a/sys/dev/aic/aic.c
+++ b/sys/dev/aic/aic.c
@@ -28,6 +28,7 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/conf.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/lock.h>
@@ -36,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <machine/bus.h>
+#include <sys/rman.h>
#include <cam/cam.h>
#include <cam/cam_ccb.h>
@@ -51,6 +53,7 @@ __FBSDID("$FreeBSD$");
static void aic_action(struct cam_sim *sim, union ccb *ccb);
static void aic_execute_scb(void *arg, bus_dma_segment_t *dm_segs,
int nseg, int error);
+static void aic_intr_locked(struct aic_softc *aic);
static void aic_start(struct aic_softc *aic);
static void aic_select(struct aic_softc *aic);
static void aic_selected(struct aic_softc *aic);
@@ -71,43 +74,42 @@ static void aic_reset(struct aic_softc *aic, int initiate_reset);
devclass_t aic_devclass;
-static struct aic_scb *free_scbs;
-
static struct aic_scb *
aic_get_scb(struct aic_softc *aic)
{
struct aic_scb *scb;
- int s = splcam();
- if ((scb = free_scbs) != NULL)
- free_scbs = (struct aic_scb *)free_scbs->ccb;
- splx(s);
+
+ if (!dumping)
+ mtx_assert(&aic->lock, MA_OWNED);
+ if ((scb = SLIST_FIRST(&aic->free_scbs)) != NULL)
+ SLIST_REMOVE_HEAD(&aic->free_scbs, link);
return (scb);
}
static void
aic_free_scb(struct aic_softc *aic, struct aic_scb *scb)
{
- int s = splcam();
+
+ if (!dumping)
+ mtx_assert(&aic->lock, MA_OWNED);
if ((aic->flags & AIC_RESOURCE_SHORTAGE) != 0 &&
(scb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) {
scb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
aic->flags &= ~AIC_RESOURCE_SHORTAGE;
}
scb->flags = 0;
- scb->ccb = (union ccb *)free_scbs;
- free_scbs = scb;
- splx(s);
+ SLIST_INSERT_HEAD(&aic->free_scbs, scb, link);
}
static void
aic_action(struct cam_sim *sim, union ccb *ccb)
{
struct aic_softc *aic;
- int s;
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("aic_action\n"));
aic = (struct aic_softc *)cam_sim_softc(sim);
+ mtx_assert(&aic->lock, MA_OWNED);
switch (ccb->ccb_h.func_code) {
case XPT_SCSI_IO: /* Execute the requested I/O operation */
@@ -116,9 +118,7 @@ aic_action(struct cam_sim *sim, union ccb *ccb)
struct aic_scb *scb;
if ((scb = aic_get_scb(aic)) == NULL) {
- s = splcam();
aic->flags |= AIC_RESOURCE_SHORTAGE;
- splx(s);
xpt_freeze_simq(aic->sim, /*count*/1);
ccb->ccb_h.status = CAM_REQUEUE_REQ;
xpt_done(ccb);
@@ -175,8 +175,6 @@ aic_action(struct cam_sim *sim, union ccb *ccb)
struct ccb_trans_settings_spi *spi =
&cts->xport_specific.spi;
- s = splcam();
-
if ((spi->valid & CTS_SPI_VALID_DISC) != 0 &&
(aic->flags & AIC_DISC_ENABLE) != 0) {
if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0)
@@ -214,7 +212,6 @@ aic_action(struct cam_sim *sim, union ccb *ccb)
|| (ti->goal.offset != ti->current.offset))
ti->flags |= TINFO_SDTR_NEGO;
- splx(s);
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
break;
@@ -235,7 +232,6 @@ aic_action(struct cam_sim *sim, union ccb *ccb)
scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
- s = splcam();
if ((ti->flags & TINFO_DISC_ENB) != 0)
spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
if ((ti->flags & TINFO_TAG_ENB) != 0)
@@ -248,7 +244,6 @@ aic_action(struct cam_sim *sim, union ccb *ccb)
spi->sync_period = ti->user.period;
spi->sync_offset = ti->user.offset;
}
- splx(s);
spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
spi->valid = CTS_SPI_VALID_SYNC_RATE
@@ -311,12 +306,10 @@ aic_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
struct aic_scb *scb = (struct aic_scb *)arg;
union ccb *ccb = scb->ccb;
struct aic_softc *aic = (struct aic_softc *)ccb->ccb_h.ccb_aic_ptr;
- int s;
-
- s = splcam();
+ if (!dumping)
+ mtx_assert(&aic->lock, MA_OWNED);
if (ccb->ccb_h.status != CAM_REQ_INPROG) {
- splx(s);
aic_free_scb(aic, scb);
xpt_done(ccb);
return;
@@ -326,11 +319,10 @@ aic_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
ccb->ccb_h.status |= CAM_SIM_QUEUED;
TAILQ_INSERT_TAIL(&aic->pending_ccbs, &ccb->ccb_h, sim_links.tqe);
- ccb->ccb_h.timeout_ch = timeout(aic_timeout, (caddr_t)scb,
- (ccb->ccb_h.timeout * hz) / 1000);
+ callout_reset(&scb->timer, (ccb->ccb_h.timeout * hz) / 1000,
+ aic_timeout, scb);
aic_start(aic);
- splx(s);
}
/*
@@ -1053,7 +1045,7 @@ aic_done(struct aic_softc *aic, struct aic_scb *scb)
("aic_done - ccb %p status %x resid %d\n",
ccb, ccb->ccb_h.status, ccb->csio.resid));
- untimeout(aic_timeout, (caddr_t)scb, ccb->ccb_h.timeout_ch);
+ callout_stop(&scb->timer);
if ((scb->flags & SCB_DEVICE_RESET) != 0 &&
ccb->ccb_h.func_code != XPT_RESET_DEV) {
@@ -1083,9 +1075,9 @@ aic_done(struct aic_softc *aic, struct aic_scb *scb)
&pending_scb->ccb->ccb_h, sim_links.tqe);
aic_done(aic, pending_scb);
} else {
- ccb_h->timeout_ch =
- timeout(aic_timeout, (caddr_t)pending_scb,
- (ccb_h->timeout * hz) / 1000);
+ callout_reset(&pending_scb->timer,
+ (ccb_h->timeout * hz) / 1000, aic_timeout,
+ pending_scb);
ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe);
}
}
@@ -1102,9 +1094,9 @@ aic_done(struct aic_softc *aic, struct aic_scb *scb)
&nexus_scb->ccb->ccb_h, sim_links.tqe);
aic_done(aic, nexus_scb);
} else {
- ccb_h->timeout_ch =
- timeout(aic_timeout, (caddr_t)nexus_scb,
- (ccb_h->timeout * hz) / 1000);
+ callout_reset(&nexus_scb->timer,
+ (ccb_h->timeout * hz) / 1000, aic_timeout,
+ nexus_scb);
ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe);
}
}
@@ -1123,7 +1115,7 @@ aic_done(struct aic_softc *aic, struct aic_scb *scb)
static void
aic_poll(struct cam_sim *sim)
{
- aic_intr(cam_sim_softc(sim));
+ aic_intr_locked(cam_sim_softc(sim));
}
static void
@@ -1132,18 +1124,15 @@ aic_timeout(void *arg)
struct aic_scb *scb = (struct aic_scb *)arg;
union ccb *ccb = scb->ccb;
struct aic_softc *aic = (struct aic_softc *)ccb->ccb_h.ccb_aic_ptr;
- int s;
+ mtx_assert(&aic->lock, MA_OWNED);
xpt_print_path(ccb->ccb_h.path);
printf("ccb %p - timed out", ccb);
if (aic->nexus && aic->nexus != scb)
printf(", nexus %p", aic->nexus->ccb);
printf(", phase 0x%x, state %d\n", aic_inb(aic, SCSISIGI), aic->state);
- s = splcam();
-
if ((scb->flags & SCB_ACTIVE) == 0) {
- splx(s);
xpt_print_path(ccb->ccb_h.path);
printf("ccb %p - timed out already completed\n", ccb);
return;
@@ -1151,6 +1140,7 @@ aic_timeout(void *arg)
if ((scb->flags & SCB_DEVICE_RESET) == 0 && aic->nexus == scb) {
struct ccb_hdr *ccb_h = &scb->ccb->ccb_h;
+ struct aic_scb *pending_scb;
if ((ccb_h->status & CAM_RELEASE_SIMQ) == 0) {
xpt_freeze_simq(aic->sim, /*count*/1);
@@ -1158,18 +1148,17 @@ aic_timeout(void *arg)
}
TAILQ_FOREACH(ccb_h, &aic->pending_ccbs, sim_links.tqe) {
- untimeout(aic_timeout, (caddr_t)ccb_h->ccb_scb_ptr,
- ccb_h->timeout_ch);
+ pending_scb = ccb_h->ccb_scb_ptr;
+ callout_stop(&pending_scb->timer);
}
TAILQ_FOREACH(ccb_h, &aic->nexus_ccbs, sim_links.tqe) {
- untimeout(aic_timeout, (caddr_t)ccb_h->ccb_scb_ptr,
- ccb_h->timeout_ch);
+ pending_scb = ccb_h->ccb_scb_ptr;
+ callout_stop(&pending_scb->timer);
}
scb->flags |= SCB_DEVICE_RESET;
- ccb->ccb_h.timeout_ch =
- timeout(aic_timeout, (caddr_t)scb, 5 * hz);
+ callout_reset(&scb->timer, 5 * hz, aic_timeout, scb);
aic_sched_msgout(aic, MSG_BUS_DEV_RESET);
} else {
if (aic->nexus == scb) {
@@ -1178,14 +1167,21 @@ aic_timeout(void *arg)
}
aic_reset(aic, /*initiate_reset*/TRUE);
}
-
- splx(s);
}
void
aic_intr(void *arg)
{
struct aic_softc *aic = (struct aic_softc *)arg;
+
+ mtx_lock(&aic->lock);
+ aic_intr_locked(aic);
+ mtx_unlock(&aic->lock);
+}
+
+void
+aic_intr_locked(struct aic_softc *aic)
+{
u_int8_t sstat0, sstat1;
union ccb *ccb;
struct aic_scb *scb;
@@ -1434,6 +1430,7 @@ aic_init(struct aic_softc *aic)
TAILQ_INIT(&aic->pending_ccbs);
TAILQ_INIT(&aic->nexus_ccbs);
+ SLIST_INIT(&aic->free_scbs);
aic->nexus = NULL;
aic->state = AIC_IDLE;
aic->prev_phase = -1;
@@ -1481,10 +1478,10 @@ aic_init(struct aic_softc *aic)
aic->max_period = AIC_SYNC_PERIOD;
aic->min_period = AIC_MIN_SYNC_PERIOD;
- free_scbs = NULL;
for (i = 255; i >= 0; i--) {
scb = &aic->scbs[i];
scb->tag = i;
+ callout_init_mtx(&scb->timer, &aic->lock, 0);
aic_free_scb(aic, scb);
}
@@ -1543,14 +1540,16 @@ aic_attach(struct aic_softc *aic)
* Construct our SIM entry
*/
aic->sim = cam_sim_alloc(aic_action, aic_poll, "aic", aic,
- aic->unit, &Giant, 2, 256, devq);
+ device_get_unit(aic->dev), &aic->lock, 2, 256, devq);
if (aic->sim == NULL) {
cam_simq_free(devq);
return (ENOMEM);
}
+ mtx_lock(&aic->lock);
if (xpt_bus_register(aic->sim, aic->dev, 0) != CAM_SUCCESS) {
cam_sim_free(aic->sim, /*free_devq*/TRUE);
+ mtx_unlock(&aic->lock);
return (ENXIO);
}
@@ -1559,12 +1558,13 @@ aic_attach(struct aic_softc *aic)
CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
xpt_bus_deregister(cam_sim_path(aic->sim));
cam_sim_free(aic->sim, /*free_devq*/TRUE);
+ mtx_unlock(&aic->lock);
return (ENXIO);
}
aic_init(aic);
- printf("aic%d: %s", aic->unit, aic_chip_names[aic->chip_type]);
+ device_printf(aic->dev, "%s", aic_chip_names[aic->chip_type]);
if (aic->flags & AIC_DMA_ENABLE)
printf(", dma");
if (aic->flags & AIC_DISC_ENABLE)
@@ -1574,15 +1574,25 @@ aic_attach(struct aic_softc *aic)
if (aic->flags & AIC_FAST_ENABLE)
printf(", fast SCSI");
printf("\n");
+ mtx_unlock(&aic->lock);
return (0);
}
int
aic_detach(struct aic_softc *aic)
{
+ struct aic_scb *scb;
+ int i;
+
+ mtx_lock(&aic->lock);
xpt_async(AC_LOST_DEVICE, aic->path, NULL);
xpt_free_path(aic->path);
xpt_bus_deregister(cam_sim_path(aic->sim));
cam_sim_free(aic->sim, /*free_devq*/TRUE);
+ mtx_unlock(&aic->lock);
+ for (i = 255; i >= 0; i--) {
+ scb = &aic->scbs[i];
+ callout_drain(&scb->timer);
+ }
return (0);
}
diff --git a/sys/dev/aic/aic_cbus.c b/sys/dev/aic/aic_cbus.c
index c641989..d2d2bc3 100644
--- a/sys/dev/aic/aic_cbus.c
+++ b/sys/dev/aic/aic_cbus.c
@@ -28,8 +28,11 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/callout.h>
#include <sys/kernel.h>
+#include <sys/lock.h>
#include <sys/module.h>
+#include <sys/mutex.h>
#include <sys/bus.h>
#include <machine/bus.h>
@@ -92,7 +95,7 @@ aic_isa_alloc_resources(device_t dev)
else
bs_iat = aicport_generic;
- sc->sc_port = sc->sc_irq = sc->sc_drq = 0;
+ sc->sc_port = sc->sc_irq = sc->sc_drq = NULL;
rid = 0;
sc->sc_port = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid,
@@ -102,6 +105,7 @@ aic_isa_alloc_resources(device_t dev)
return (ENOMEM);
}
isa_load_resourcev(sc->sc_port, bs_iat, AIC_ISA_PORTSIZE);
+ mtx_init(&sc->sc_aic.lock, "aic", NULL, MTX_DEF);
if (isa_get_irq(dev) != -1) {
rid = 0;
@@ -126,9 +130,7 @@ aic_isa_alloc_resources(device_t dev)
}
sc->sc_aic.dev = dev;
- sc->sc_aic.unit = device_get_unit(dev);
- sc->sc_aic.tag = rman_get_bustag(sc->sc_port);
- sc->sc_aic.bsh = rman_get_bushandle(sc->sc_port);
+ sc->sc_aic.res = sc->sc_port;
return (0);
}
@@ -143,7 +145,8 @@ aic_isa_release_resources(device_t dev)
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq);
if (sc->sc_drq)
bus_release_resource(dev, SYS_RES_DRQ, 0, sc->sc_drq);
- sc->sc_port = sc->sc_irq = sc->sc_drq = 0;
+ sc->sc_port = sc->sc_irq = sc->sc_drq = NULL;
+ mtx_destroy(&sc->sc_aic.lock);
}
static int
@@ -172,10 +175,8 @@ aic_isa_probe(device_t dev)
continue;
if (aic_isa_alloc_resources(dev))
continue;
- if (!aic_probe(aic)) {
- aic_isa_release_resources(dev);
+ if (aic_probe(aic) == 0)
break;
- }
aic_isa_release_resources(dev);
}
@@ -183,6 +184,7 @@ aic_isa_probe(device_t dev)
return (ENXIO);
porta = aic_inb(aic, PORTA);
+ aic_isa_release_resources(dev);
if (isa_get_irq(dev) == -1)
bus_set_resource(dev, SYS_RES_IRQ, 0, PORTA_IRQ(porta), 1);
if ((aic->flags & AIC_DMA_ENABLE) && isa_get_drq(dev) == -1)
@@ -211,8 +213,8 @@ aic_isa_attach(device_t dev)
return (error);
}
- error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM|INTR_ENTROPY,
- NULL, aic_intr, aic, &sc->sc_ih);
+ error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM | INTR_ENTROPY |
+ INTR_MPSAFE, NULL, aic_intr, aic, &sc->sc_ih);
if (error) {
device_printf(dev, "failed to register interrupt handler\n");
aic_isa_release_resources(dev);
diff --git a/sys/dev/aic/aic_isa.c b/sys/dev/aic/aic_isa.c
index b80b387..1671802 100644
--- a/sys/dev/aic/aic_isa.c
+++ b/sys/dev/aic/aic_isa.c
@@ -28,8 +28,11 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/callout.h>
#include <sys/kernel.h>
+#include <sys/lock.h>
#include <sys/module.h>
+#include <sys/mutex.h>
#include <sys/bus.h>
#include <machine/bus.h>
@@ -69,7 +72,7 @@ aic_isa_alloc_resources(device_t dev)
struct aic_isa_softc *sc = device_get_softc(dev);
int rid;
- sc->sc_port = sc->sc_irq = sc->sc_drq = 0;
+ sc->sc_port = sc->sc_irq = sc->sc_drq = NULL;
rid = 0;
sc->sc_port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
@@ -102,9 +105,8 @@ aic_isa_alloc_resources(device_t dev)
}
sc->sc_aic.dev = dev;
- sc->sc_aic.unit = device_get_unit(dev);
- sc->sc_aic.tag = rman_get_bustag(sc->sc_port);
- sc->sc_aic.bsh = rman_get_bushandle(sc->sc_port);
+ sc->sc_aic.res = sc->sc_port;
+ mtx_init(&sc->sc_aic.lock, "aic", NULL, MTX_DEF);
return (0);
}
@@ -119,7 +121,8 @@ aic_isa_release_resources(device_t dev)
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq);
if (sc->sc_drq)
bus_release_resource(dev, SYS_RES_DRQ, 0, sc->sc_drq);
- sc->sc_port = sc->sc_irq = sc->sc_drq = 0;
+ sc->sc_port = sc->sc_irq = sc->sc_drq = NULL;
+ mtx_destroy(&sc->sc_aic.lock);
}
static int
@@ -149,10 +152,8 @@ aic_isa_probe(device_t dev)
continue;
if (aic_isa_alloc_resources(dev))
continue;
- if (!aic_probe(aic)) {
- aic_isa_release_resources(dev);
+ if (aic_probe(aic) == 0)
break;
- }
aic_isa_release_resources(dev);
}
@@ -160,6 +161,7 @@ aic_isa_probe(device_t dev)
return (ENXIO);
porta = aic_inb(aic, PORTA);
+ aic_isa_release_resources(dev);
if (isa_get_irq(dev) == -1)
bus_set_resource(dev, SYS_RES_IRQ, 0, PORTA_IRQ(porta), 1);
if ((aic->flags & AIC_DMA_ENABLE) && isa_get_drq(dev) == -1)
@@ -188,8 +190,8 @@ aic_isa_attach(device_t dev)
return (error);
}
- error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM|INTR_ENTROPY,
- NULL, aic_intr, aic, &sc->sc_ih);
+ error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM | INTR_ENTROPY |
+ INTR_MPSAFE, NULL, aic_intr, aic, &sc->sc_ih);
if (error) {
device_printf(dev, "failed to register interrupt handler\n");
aic_isa_release_resources(dev);
diff --git a/sys/dev/aic/aic_pccard.c b/sys/dev/aic/aic_pccard.c
index 4000388..31ba257 100644
--- a/sys/dev/aic/aic_pccard.c
+++ b/sys/dev/aic/aic_pccard.c
@@ -28,8 +28,11 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/callout.h>
#include <sys/kernel.h>
+#include <sys/lock.h>
#include <sys/module.h>
+#include <sys/mutex.h>
#include <sys/bus.h>
#include <machine/bus.h>
@@ -71,7 +74,7 @@ aic_pccard_alloc_resources(device_t dev)
struct aic_pccard_softc *sc = device_get_softc(dev);
int rid;
- sc->sc_port = sc->sc_irq = 0;
+ sc->sc_port = sc->sc_irq = NULL;
rid = 0;
sc->sc_port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
@@ -87,9 +90,8 @@ aic_pccard_alloc_resources(device_t dev)
}
sc->sc_aic.dev = dev;
- sc->sc_aic.unit = device_get_unit(dev);
- sc->sc_aic.tag = rman_get_bustag(sc->sc_port);
- sc->sc_aic.bsh = rman_get_bushandle(sc->sc_port);
+ sc->sc_aic.res = sc->sc_port;
+ mtx_init(&sc->sc_aic.lock, "aic", NULL, MTX_DEF);
return (0);
}
@@ -102,7 +104,8 @@ aic_pccard_release_resources(device_t dev)
bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->sc_port);
if (sc->sc_irq)
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq);
- sc->sc_port = sc->sc_irq = 0;
+ sc->sc_port = sc->sc_irq = NULL;
+ mtx_destroy(&sc->sc_aic.lock);
}
static int
@@ -114,9 +117,12 @@ aic_pccard_probe(device_t dev)
sizeof(aic_pccard_products[0]), NULL)) != NULL) {
if (pp->pp_name != NULL)
device_set_desc(dev, pp->pp_name);
- return 0;
+ else
+ device_set_desc(dev,
+ "Adaptec 6260/6360 SCSI controller");
+ return (BUS_PROBE_DEFAULT);
}
- return EIO;
+ return (ENXIO);
}
static int
@@ -133,8 +139,6 @@ aic_pccard_attach(device_t dev)
return (ENXIO);
}
- device_set_desc(dev, "Adaptec 6260/6360 SCSI controller");
-
error = aic_attach(aic);
if (error) {
device_printf(dev, "attach failed\n");
@@ -142,8 +146,8 @@ aic_pccard_attach(device_t dev)
return (error);
}
- error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM|INTR_ENTROPY,
- NULL, aic_intr, aic, &sc->sc_ih);
+ error = bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_CAM | INTR_ENTROPY |
+ INTR_MPSAFE, NULL, aic_intr, aic, &sc->sc_ih);
if (error) {
device_printf(dev, "failed to register interrupt handler\n");
aic_pccard_release_resources(dev);
diff --git a/sys/dev/aic/aicvar.h b/sys/dev/aic/aicvar.h
index 3bce66c..078d748 100644
--- a/sys/dev/aic/aicvar.h
+++ b/sys/dev/aic/aicvar.h
@@ -47,6 +47,8 @@ struct aic_tinfo {
struct aic_scb {
union ccb *ccb;
+ SLIST_ENTRY(aic_scb) link;
+ struct callout timer;
u_int8_t flags;
u_int8_t tag;
u_int8_t target;
@@ -70,14 +72,14 @@ enum { AIC6260, AIC6360, AIC6370, GM82C700 };
struct aic_softc {
device_t dev;
- int unit;
- bus_space_tag_t tag;
- bus_space_handle_t bsh;
+ struct mtx lock;
+ struct resource *res;
bus_dma_tag_t dmat;
struct cam_sim *sim;
struct cam_path *path;
TAILQ_HEAD(,ccb_hdr) pending_ccbs, nexus_ccbs;
+ SLIST_HEAD(,aic_scb) free_scbs;
struct aic_scb *nexus;
u_int32_t flags;
@@ -127,32 +129,28 @@ struct aic_softc {
#define AIC_SYNC_OFFSET 8
#define aic_inb(aic, port) \
- bus_space_read_1((aic)->tag, (aic)->bsh, (port))
+ bus_read_1((aic)->res, (port))
#define aic_outb(aic, port, value) \
- bus_space_write_1((aic)->tag, (aic)->bsh, (port), (value))
+ bus_write_1((aic)->res, (port), (value))
#define aic_insb(aic, port, addr, count) \
- bus_space_read_multi_1((aic)->tag, (aic)->bsh, (port), (addr), (count))
+ bus_read_multi_1((aic)->res, (port), (addr), (count))
#define aic_outsb(aic, port, addr, count) \
- bus_space_write_multi_1((aic)->tag, (aic)->bsh, (port), (addr), (count))
+ bus_write_multi_1((aic)->res, (port), (addr), (count))
#define aic_insw(aic, port, addr, count) \
- bus_space_read_multi_2((aic)->tag, (aic)->bsh, (port), \
- (u_int16_t *)(addr), (count))
+ bus_read_multi_2((aic)->res, (port), (u_int16_t *)(addr), (count))
#define aic_outsw(aic, port, addr, count) \
- bus_space_write_multi_2((aic)->tag, (aic)->bsh, (port), \
- (u_int16_t *)(addr), (count))
+ bus_write_multi_2((aic)->res, (port), (u_int16_t *)(addr), (count))
#define aic_insl(aic, port, addr, count) \
- bus_space_read_multi_4((aic)->tag, (aic)->bsh, (port), \
- (u_int32_t *)(addr), (count))
+ bus_read_multi_4((aic)->res, (port), (u_int32_t *)(addr), (count))
#define aic_outsl(aic, port, addr, count) \
- bus_space_write_multi_4((aic)->tag, (aic)->bsh, (port), \
- (u_int32_t *)(addr), (count))
+ bus_write_multi_4((aic)->res, (port), (u_int32_t *)(addr), (count))
extern int aic_probe(struct aic_softc *);
extern int aic_attach(struct aic_softc *);
OpenPOWER on IntegriCloud