diff options
author | Scott Long <scottl@FreeBSD.org> | 2005-01-16 07:34:26 +0000 |
---|---|---|
committer | Scott Long <scottl@FreeBSD.org> | 2005-01-16 07:34:26 +0000 |
commit | 5b4a781b96ffc9526a18dd0d5576dbda89bffa8a (patch) | |
tree | bfdf6effed4ced3ac3ccec00ef9ddd7f6c13681e /sys/dev/amr/amr_cam.c | |
parent | 835e0fa318d85113643e78fceff2f806f6c34fc4 (diff) | |
download | src-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.c | 16 |
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); } |