aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/aac
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2007-11-01 20:45:29 +0000
committerEd Maste <emaste@FreeBSD.org>2007-11-01 20:45:29 +0000
commiteb5cbaa0207679e32e754aefd5697be8a6ea49ff (patch)
tree807e893d8bd66aaf92694c8adc1224c90e8357b4 /sys/dev/aac
parent3c2ff3b0a5acd5d15b61b775537addc201e86314 (diff)
Notes
Diffstat (limited to 'sys/dev/aac')
-rw-r--r--sys/dev/aac/aac.c7
-rw-r--r--sys/dev/aac/aac_cam.c34
2 files changed, 22 insertions, 19 deletions
diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c
index 01212eb18929..e62bd47064de 100644
--- a/sys/dev/aac/aac.c
+++ b/sys/dev/aac/aac.c
@@ -1310,9 +1310,12 @@ aac_release_command(struct aac_command *cm)
aac_enqueue_free(cm);
+ /*
+ * Dequeue all events so that there's no risk of events getting
+ * stranded.
+ */
sc = cm->cm_sc;
- event = TAILQ_FIRST(&sc->aac_ev_cmfree);
- if (event != NULL) {
+ while ((event = TAILQ_FIRST(&sc->aac_ev_cmfree)) != NULL) {
TAILQ_REMOVE(&sc->aac_ev_cmfree, event, ev_links);
event->ev_callback(sc, event, event->ev_arg);
}
diff --git a/sys/dev/aac/aac_cam.c b/sys/dev/aac/aac_cam.c
index c7e2f984b899..5ff03a557480 100644
--- a/sys/dev/aac/aac_cam.c
+++ b/sys/dev/aac/aac_cam.c
@@ -103,13 +103,17 @@ MALLOC_DEFINE(M_AACCAM, "aaccam", "AAC CAM info");
static void
aac_cam_event(struct aac_softc *sc, struct aac_event *event, void *arg)
{
+ union ccb *ccb;
struct aac_cam *camsc;
switch (event->ev_type) {
case AAC_EVENT_CMFREE:
- camsc = arg;
+ ccb = arg;
+ camsc = ccb->ccb_h.sim_priv.entries[0].ptr;
free(event, M_AACCAM);
xpt_release_simq(camsc->sim, 1);
+ ccb->ccb_h.status = CAM_REQUEUE_REQ;
+ xpt_done(ccb);
break;
default:
device_printf(sc->aac_dev, "unknown event %d in aac_cam\n",
@@ -131,19 +135,21 @@ aac_cam_probe(device_t dev)
static int
aac_cam_detach(device_t dev)
{
+ struct aac_softc *sc;
struct aac_cam *camsc;
debug_called(2);
camsc = (struct aac_cam *)device_get_softc(dev);
+ sc = camsc->inf->aac_sc;
- mtx_lock(&Giant);
+ mtx_lock(&sc->aac_io_lock);
xpt_async(AC_LOST_DEVICE, camsc->path, NULL);
xpt_free_path(camsc->path);
xpt_bus_deregister(cam_sim_path(camsc->sim));
cam_sim_free(camsc->sim, /*free_devq*/TRUE);
- mtx_unlock(&Giant);
+ mtx_unlock(&sc->aac_io_lock);
return (0);
}
@@ -171,15 +177,17 @@ aac_cam_attach(device_t dev)
return (EIO);
sim = cam_sim_alloc(aac_cam_action, aac_cam_poll, "aacp", camsc,
- device_get_unit(dev), &Giant, 1, 1, devq);
+ device_get_unit(dev), &inf->aac_sc->aac_io_lock, 1, 1, devq);
if (sim == NULL) {
cam_simq_free(devq);
return (EIO);
}
/* Since every bus has it's own sim, every bus 'appears' as bus 0 */
+ mtx_lock(&inf->aac_sc->aac_io_lock);
if (xpt_bus_register(sim, dev, 0) != CAM_SUCCESS) {
cam_sim_free(sim, TRUE);
+ mtx_unlock(&inf->aac_sc->aac_io_lock);
return (EIO);
}
@@ -187,8 +195,10 @@ aac_cam_attach(device_t dev)
CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
xpt_bus_deregister(cam_sim_path(sim));
cam_sim_free(sim, TRUE);
+ mtx_unlock(&inf->aac_sc->aac_io_lock);
return (EIO);
}
+ mtx_unlock(&inf->aac_sc->aac_io_lock);
camsc->sim = sim;
camsc->path = path;
@@ -321,27 +331,23 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
/* Async ops that require communcation with the controller */
- mtx_lock(&sc->aac_io_lock);
if (aac_alloc_command(sc, &cm)) {
struct aac_event *event;
xpt_freeze_simq(sim, 1);
- ccb->ccb_h.status = CAM_REQUEUE_REQ;
- xpt_done(ccb);
+ ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
+ ccb->ccb_h.sim_priv.entries[0].ptr = camsc;
event = malloc(sizeof(struct aac_event), M_AACCAM,
M_NOWAIT | M_ZERO);
if (event == NULL) {
device_printf(sc->aac_dev,
"Warning, out of memory for event\n");
- /* XXX Yuck, what to do here? */
- mtx_unlock(&sc->aac_io_lock);
return;
}
event->ev_callback = aac_cam_event;
- event->ev_arg = camsc;
+ event->ev_arg = ccb;
event->ev_type = AAC_EVENT_CMFREE;
aac_add_event(sc, event);
- mtx_unlock(&sc->aac_io_lock);
return;
}
@@ -429,7 +435,6 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
} else {
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
- mtx_unlock(&sc->aac_io_lock);
return;
}
default:
@@ -460,8 +465,6 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
aac_enqueue_ready(cm);
aac_startio(cm->cm_sc);
- mtx_unlock(&sc->aac_io_lock);
-
return;
}
@@ -565,7 +568,6 @@ aac_cam_reset_bus(struct cam_sim *sim, union ccb *ccb)
return (CAM_REQ_ABORTED);
}
- mtx_lock(&sc->aac_io_lock);
aac_alloc_sync_fib(sc, &fib);
vmi = (struct aac_vmioctl *)&fib->data[0];
@@ -586,12 +588,10 @@ aac_cam_reset_bus(struct cam_sim *sim, union ccb *ccb)
device_printf(sc->aac_dev,"Error %d sending ResetBus command\n",
e);
aac_release_sync_fib(sc);
- mtx_unlock(&sc->aac_io_lock);
return (CAM_REQ_ABORTED);
}
aac_release_sync_fib(sc);
- mtx_unlock(&sc->aac_io_lock);
return (CAM_REQ_CMP);
}