Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 25 Apr 2004 07:21:43 -0700 (PDT)
From:      Scott Long <scottl@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 51703 for review
Message-ID:  <200404251421.i3PELhan064473@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=51703

Change 51703 by scottl@scottl-junior-camlock on 2004/04/25 07:21:28

	Lock the request_ccb list in the probe softc.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/cam/cam_probe.c#8 edit

Differences ...

==== //depot/projects/scottl-camlock/src/sys/cam/cam_probe.c#8 (text+ko) ====

@@ -112,6 +112,7 @@
 
 typedef struct {
 	TAILQ_HEAD(, ccb_hdr) request_ccbs;
+	struct mtx	ccb_lock;
 	probe_action	action;
 	union ccb	saved_ccb;
 	probe_flags	flags;
@@ -237,7 +238,7 @@
 		return(CAM_REQ_CMP_ERR);
 	}
 
-	softc = (probe_softc *)malloc(sizeof(*softc), M_TEMP, M_NOWAIT);
+	softc = (probe_softc *)malloc(sizeof(*softc), M_TEMP, M_NOWAIT|M_ZERO);
 
 	if (softc == NULL) {
 		printf("proberegister: Unable to probe new device. "
@@ -255,6 +256,7 @@
 
 	softc->work = work;
 	TAILQ_INIT(&softc->request_ccbs);
+	mtx_init(&softc->ccb_lock, "Probe requst CCB lock", NULL, MTX_DEF);
 	TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h,
 			  periph_links.tqe);
 	softc->flags = 0;
@@ -277,9 +279,10 @@
 	struct ccb_pathinq cpi;
 	union ccb *ccb;
 	probe_softc *softc;
+	int need_renegotiate;
 
 	softc = (probe_softc *)periph->softc;
-	ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs);
+	need_renegotiate = 0;
 
 	xpt_setup_ccb(&cpi.ccb_h, periph->path, /*priority*/1);
 	cpi.ccb_h.func_code = XPT_PATH_INQ;
@@ -303,12 +306,14 @@
 	 * ensures that the device is not confused by transfer negotiation
 	 * settings left over by loader or BIOS action.
 	 */
+	mtx_lock(&softc->ccb_lock);
+	ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs);
 	if (((ccb->ccb_h.path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
 	 && (ccb->ccb_h.target_lun == 0)) {
 		softc->action = PROBE_TUR;
 	} else if ((cpi.hba_inquiry & (PI_WIDE_32|PI_WIDE_16|PI_SDTR_ABLE)) != 0
 	      && (cpi.hba_misc & PIM_NOBUSRESET) != 0) {
-		proberequestdefaultnegotiation(periph);
+		need_renegotiate = 1;
 		softc->action = PROBE_INQUIRY;
 	} else {
 		softc->action = PROBE_INQUIRY;
@@ -318,8 +323,14 @@
 		softc->flags |= PROBE_NO_ANNOUNCE;
 	else
 		softc->flags &= ~PROBE_NO_ANNOUNCE;
+	mtx_unlock(&softc->ccb_lock);
 
+	if (need_renegotiate)
+		proberequestdefaultnegotiation(periph);
+
+	mtx_lock(&Giant);
 	xpt_schedule(periph, ccb->ccb_h.pinfo.priority);
+	mtx_unlock(&Giant);
 }
 
 static void
@@ -758,10 +769,14 @@
 		xpt_release_ccb(done_ccb);
 		break;
 	}
+	mtx_lock(&softc->ccb_lock);
 	done_ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs);
 	TAILQ_REMOVE(&softc->request_ccbs, &done_ccb->ccb_h, periph_links.tqe);
+	mtx_unlock(&softc->ccb_lock);
 	done_ccb->ccb_h.status = CAM_REQ_CMP;
 	xpt_done(done_ccb);
+
+	/* XXX How to lock this? */
 	if (TAILQ_FIRST(&softc->request_ccbs) == NULL) {
 		cam_periph_invalidate(periph);
 		cam_periph_release(periph);
@@ -773,8 +788,12 @@
 static void
 probecleanup(struct cam_periph *periph)
 {
-	free(((probe_softc *)(periph->softc))->work, M_TEMP);
-	free(periph->softc, M_TEMP);
+	probe_softc *softc;
+
+	softc = (probe_softc *)periph->softc;
+	mtx_destroy(&softc->ccb_lock);
+	free(softc->work, M_TEMP);
+	free(softc, M_TEMP);
 }
 
 void
@@ -854,8 +873,10 @@
 		probe_softc *softc;
 
 		softc = (probe_softc *)old_periph->softc;
+		mtx_lock(&softc->ccb_lock);
 		TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h,
 				  periph_links.tqe);
+		mtx_unlock(&softc->ccb_lock);
 	} else {
 		status = cam_periph_alloc(proberegister, NULL, probecleanup,
 					  probestart, "probe",



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200404251421.i3PELhan064473>