PERFORCE change 117938 for review

Scott Long scottl at FreeBSD.org
Thu Apr 12 04:17:24 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=117938

Change 117938 by scottl at scottl-y1 on 2007/04/12 04:17:03

	Lock the SG periph.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_sg.c#3 edit

Differences ...

==== //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_sg.c#3 (text+ko) ====

@@ -410,10 +410,6 @@
 	if (periph == NULL)
 		return (ENXIO);
 
-	softc = (struct sg_softc *)periph->softc;
-	if (softc->flags & SG_FLAG_INVALID)
-		return (ENXIO);
-
 	/*
 	 * Don't allow access when we're running at a high securelevel.
 	 */
@@ -421,13 +417,19 @@
 	if (error)
 		return (error);
 
-	if ((error = cam_periph_lock(periph, PRIBIO | PCATCH)) != 0)
-		return (error);
+	cam_periph_lock(periph);
+
+	softc = (struct sg_softc *)periph->softc;
+	if (softc->flags & SG_FLAG_INVALID) {
+		cam_periph_unlock(periph);
+		return (ENXIO);
+	}
 
 	if ((softc->flags & SG_FLAG_OPEN) == 0) {
-		if (cam_periph_acquire(periph) != CAM_REQ_CMP)
-			return (ENXIO);
 		softc->flags |= SG_FLAG_OPEN;
+	} else {
+		/* Device closes aren't symmetrical, fix up the refcount. */
+		cam_periph_release(periph);
 	}
 
 	cam_periph_unlock(periph);
@@ -440,17 +442,14 @@
 {
 	struct cam_periph *periph;
 	struct sg_softc *softc;
-	int error;
 
 	periph = (struct cam_periph *)dev->si_drv1;
 	if (periph == NULL)
 		return (ENXIO);
 
+	cam_periph_lock(periph);
+
 	softc = (struct sg_softc *)periph->softc;
-
-	if ((error = cam_periph_lock(periph, PRIBIO)) != 0)
-		return (error);
-
 	softc->flags &= ~SG_FLAG_OPEN;
 
 	cam_periph_unlock(periph);
@@ -473,6 +472,8 @@
 	if (periph == NULL)
 		return (ENXIO);
 
+	cam_periph_lock(periph);
+
 	softc = (struct sg_softc *)periph->softc;
 	error = 0;
 
@@ -669,6 +670,7 @@
 		break;
 	}
 
+	cam_periph_unlock(periph);
 	return (error);
 }
 
@@ -686,7 +688,6 @@
 	int error = 0, cdb_len, buf_len, dir;
 
 	periph = dev->si_drv1;
-	sc = periph->softc;
 	rdwr = malloc(sizeof(*rdwr), M_DEVBUF, M_WAITOK | M_ZERO);
 	hdr = &rdwr->hdr.hdr;
 
@@ -699,12 +700,11 @@
 	if (error)
 		goto out_hdr;
 
-	ccb = xpt_alloc_ccb();
+	ccb = xpt_alloc_ccb(periph->sim);
 	if (ccb == NULL) {
 		error = ENOMEM;
 		goto out_hdr;
 	}
-	xpt_setup_ccb(&ccb->ccb_h, periph->path, /*priority*/5);
 	csio = &ccb->csio;
 
 	/*
@@ -751,6 +751,9 @@
 		dir = CAM_DIR_NONE;
 	}
 
+	cam_periph_lock(periph);
+	sc = periph->softc;
+	xpt_setup_ccb(&ccb->ccb_h, periph->path, /*priority*/5);
 	cam_fill_csio(csio,
 		      /*retries*/1,
 		      sgdone,
@@ -774,7 +777,9 @@
 	ccb->ccb_h.ccb_rdwr = rdwr;
 	ccb->ccb_h.ccb_type = SG_CCB_RDWR_IO;
 	TAILQ_INSERT_TAIL(&sc->rdwr_done, rdwr, rdwr_link);
-	return (sgsendrdwr(periph, ccb));
+	error = sgsendrdwr(periph, ccb);
+	cam_periph_unlock(periph);
+	return (error);
 
 out_buf:
 	free(buf, M_DEVBUF);
@@ -797,7 +802,6 @@
 	int error, pack_len, reply_len, pack_id;
 
 	periph = dev->si_drv1;
-	sc = periph->softc;
 
 	/* XXX The pack len field needs to be updated and written out instead
 	 * of discarded.  Not sure how to do that.
@@ -811,17 +815,20 @@
 		return (error);
 	uio->uio_rw = UIO_READ;
 
+	cam_periph_lock(periph);
+	sc = periph->softc;
 search:
 	TAILQ_FOREACH(rdwr, &sc->rdwr_done, rdwr_link) {
 		if (rdwr->tag == pack_id)
 			break;
 	}
 	if ((rdwr == NULL) || (rdwr->state != SG_RDWR_DONE)) {
-		if (tsleep(rdwr, PCATCH, "sgread", 0) == ERESTART)
+		if (msleep(rdwr, periph->sim->mtx, PCATCH, "sgread", 0) == ERESTART)
 			return (EAGAIN);
 		goto search;
 	}
 	TAILQ_REMOVE(&sc->rdwr_done, rdwr, rdwr_link);
+	cam_periph_unlock(periph);
 
 	hdr = &rdwr->hdr.hdr;
 	csio = &rdwr->ccb->csio;
@@ -865,7 +872,9 @@
 	if ((error == 0) && (hdr->result == 0))
 		error = uiomove(rdwr->buf, rdwr->buf_len, uio);
 
+	cam_periph_lock(periph);
 	xpt_free_ccb(rdwr->ccb);
+	cam_periph_unlock(periph);
 	free(rdwr->buf, M_DEVBUF);
 	free(rdwr, M_DEVBUF);
 	return (error);


More information about the p4-projects mailing list