summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordwhite <dwhite@FreeBSD.org>2005-01-10 02:34:26 +0000
committerdwhite <dwhite@FreeBSD.org>2005-01-10 02:34:26 +0000
commit7935924a355b3fe0420fe1f78fbb698d2ad39aac (patch)
tree1fc28bd1c3d3d3ac3b79c06009ce5fe65d3ebe55 /sys
parent7f890bc8e0907d6c0388a07aeb174cd1ef0a5213 (diff)
downloadFreeBSD-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.c15
-rw-r--r--sys/dev/amr/amrvar.h1
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;
OpenPOWER on IntegriCloud