aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/amr/amr_cam.c
diff options
context:
space:
mode:
authorScott Long <scottl@FreeBSD.org>2005-01-16 07:34:26 +0000
committerScott Long <scottl@FreeBSD.org>2005-01-16 07:34:26 +0000
commit5b4a781b96ffc9526a18dd0d5576dbda89bffa8a (patch)
treebfdf6effed4ced3ac3ccec00ef9ddd7f6c13681e /sys/dev/amr/amr_cam.c
parent835e0fa318d85113643e78fceff2f806f6c34fc4 (diff)
downloadsrc-5b4a781b96ffc9526a18dd0d5576dbda89bffa8a.tar.gz
src-5b4a781b96ffc9526a18dd0d5576dbda89bffa8a.zip
Lock the AMR driver:
- Introduce the amr_io_lock to control access to command queues, bio queues, and the hardware. - Eliminate the taskqueue and do all completion processing in the ithread. - Assign a static slot number to each command instead of doing a linear search for free slots each time a command is needed. - Modify the interrupt handler to more closely match what Linux does, for safety.
Notes
Notes: svn path=/head/; revision=140340
Diffstat (limited to 'sys/dev/amr/amr_cam.c')
-rw-r--r--sys/dev/amr/amr_cam.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/sys/dev/amr/amr_cam.c b/sys/dev/amr/amr_cam.c
index 3c7aaf889dec..a342699c6192 100644
--- a/sys/dev/amr/amr_cam.c
+++ b/sys/dev/amr/amr_cam.c
@@ -262,8 +262,10 @@ amr_cam_action(struct cam_sim *sim, union ccb *ccb)
/* save the channel number in the ccb */
csio->ccb_h.sim_priv.entries[0].field = cam_sim_bus(sim);
+ mtx_lock(&sc->amr_io_lock);
amr_enqueue_ccb(sc, ccb);
amr_startio(sc);
+ mtx_unlock(&sc->amr_io_lock);
return;
}
break;
@@ -491,7 +493,11 @@ out:
static void
amr_cam_poll(struct cam_sim *sim)
{
+ struct amr_softc *sc = cam_sim_softc(sim);
+
+ mtx_lock(&sc->amr_io_lock);
amr_done(cam_sim_softc(sim));
+ mtx_unlock(&sc->amr_io_lock);
}
/********************************************************************************
@@ -500,6 +506,7 @@ amr_cam_poll(struct cam_sim *sim)
static void
amr_cam_complete(struct amr_command *ac)
{
+ struct amr_softc *sc = ac->ac_sc;
struct amr_passthrough *ap = (struct amr_passthrough *)ac->ac_data;
struct ccb_scsiio *csio = (struct ccb_scsiio *)ac->ac_private;
struct scsi_inquiry_data *inq = (struct scsi_inquiry_data *)csio->data_ptr;
@@ -552,7 +559,11 @@ amr_cam_complete(struct amr_command *ac)
free(ap, M_DEVBUF);
if ((csio->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE)
debug(2, "%*D\n", imin(csio->dxfer_len, 16), csio->data_ptr, " ");
+ mtx_unlock(&sc->amr_io_lock);
+ mtx_lock(&Giant);
xpt_done((union ccb *)csio);
+ mtx_unlock(&Giant);
+ mtx_lock(&sc->amr_io_lock);
amr_releasecmd(ac);
}
@@ -563,6 +574,7 @@ amr_cam_complete(struct amr_command *ac)
static void
amr_cam_complete_extcdb(struct amr_command *ac)
{
+ struct amr_softc *sc = ac->ac_sc;
struct amr_ext_passthrough *aep = (struct amr_ext_passthrough *)ac->ac_data;
struct ccb_scsiio *csio = (struct ccb_scsiio *)ac->ac_private;
struct scsi_inquiry_data *inq = (struct scsi_inquiry_data *)csio->data_ptr;
@@ -615,6 +627,10 @@ amr_cam_complete_extcdb(struct amr_command *ac)
free(aep, M_DEVBUF);
if ((csio->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE)
debug(2, "%*D\n", imin(csio->dxfer_len, 16), csio->data_ptr, " ");
+ mtx_unlock(&sc->amr_io_lock);
+ mtx_lock(&Giant);
xpt_done((union ccb *)csio);
+ mtx_unlock(&Giant);
+ mtx_lock(&sc->amr_io_lock);
amr_releasecmd(ac);
}