diff options
author | dwhite <dwhite@FreeBSD.org> | 2005-01-10 02:34:26 +0000 |
---|---|---|
committer | dwhite <dwhite@FreeBSD.org> | 2005-01-10 02:34:26 +0000 |
commit | 7935924a355b3fe0420fe1f78fbb698d2ad39aac (patch) | |
tree | 1fc28bd1c3d3d3ac3b79c06009ce5fe65d3ebe55 /sys | |
parent | 7f890bc8e0907d6c0388a07aeb174cd1ef0a5213 (diff) | |
download | FreeBSD-src-7935924a355b3fe0420fe1f78fbb698d2ad39aac.zip FreeBSD-src-7935924a355b3fe0420fe1f78fbb698d2ad39aac.tar.gz |
Free the shared devq last since CAM expects it to be there if
xpt_alloc_device() gets called, which can happen during detach in
certain situations. Fixes module unload.
MFC after: 3 days
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/amr/amr_cam.c | 15 | ||||
-rw-r--r-- | sys/dev/amr/amrvar.h | 1 |
2 files changed, 11 insertions, 5 deletions
diff --git a/sys/dev/amr/amr_cam.c b/sys/dev/amr/amr_cam.c index 17cd835..3c7aaf8 100644 --- a/sys/dev/amr/amr_cam.c +++ b/sys/dev/amr/amr_cam.c @@ -139,10 +139,12 @@ amr_cam_attach(struct amr_softc *sc) /* * Allocate a devq for all our channels combined. This should * allow for the maximum number of SCSI commands we will accept - * at one time. + * at one time. Save the pointer in the softc so we can find it later + * during detach. */ if ((devq = cam_simq_alloc(AMR_MAX_SCSI_CMDS)) == NULL) return(ENOMEM); + sc->amr_cam_devq = devq; /* * Iterate over our channels, registering them with CAM @@ -182,19 +184,22 @@ amr_cam_attach(struct amr_softc *sc) void amr_cam_detach(struct amr_softc *sc) { - int chn, first; + int chn; - for (chn = 0, first = 1; chn < sc->amr_maxchan; chn++) { + for (chn = 0; chn < sc->amr_maxchan; chn++) { /* * If a sim was allocated for this channel, free it */ if (sc->amr_cam_sim[chn] != NULL) { xpt_bus_deregister(cam_sim_path(sc->amr_cam_sim[chn])); - cam_sim_free(sc->amr_cam_sim[chn], first ? TRUE : FALSE); - first = 0; + cam_sim_free(sc->amr_cam_sim[chn], FALSE); } } + + /* Now free the devq */ + if (sc->amr_cam_devq != NULL) + cam_simq_free(sc->amr_cam_devq); } /******************************************************************************** diff --git a/sys/dev/amr/amrvar.h b/sys/dev/amr/amrvar.h index ee0a27c..6dc6838 100644 --- a/sys/dev/amr/amrvar.h +++ b/sys/dev/amr/amrvar.h @@ -202,6 +202,7 @@ struct amr_softc /* CAM attachments for passthrough */ struct cam_sim *amr_cam_sim[AMR_MAX_CHANNELS]; TAILQ_HEAD(, ccb_hdr) amr_cam_ccbq; + struct cam_devq *amr_cam_devq; /* control device */ struct cdev *amr_dev_t; |