PERFORCE change 51703 for review
Scott Long
scottl at FreeBSD.org
Sun Apr 25 07:21:45 PDT 2004
http://perforce.freebsd.org/chv.cgi?CH=51703
Change 51703 by scottl at 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",
More information about the p4-projects
mailing list