Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 27 Mar 2007 16:00:47 GMT
From:      Scott Long <scottl@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 116663 for review
Message-ID:  <200703271600.l2RG0lHR054540@repoman.freebsd.org>

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

Change 116663 by scottl@scottl-x64 on 2007/03/27 16:00:44

	Lock the scsi_cd driver and remove spl markers.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_cd.c#12 edit

Differences ...

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

@@ -104,7 +104,8 @@
 	CD_FLAG_RETRY_UA	= 0x0200,
 	CD_FLAG_VALID_MEDIA	= 0x0400,
 	CD_FLAG_VALID_TOC	= 0x0800,
-	CD_FLAG_SCTX_INIT	= 0x1000
+	CD_FLAG_SCTX_INIT	= 0x1000,
+	CD_FLAG_OPEN		= 0x2000
 } cd_flags;
 
 typedef enum {
@@ -366,7 +367,6 @@
 static void
 cdoninvalidate(struct cam_periph *periph)
 {
-	int s;
 	struct cd_softc *softc;
 	struct ccb_setasync csa;
 
@@ -386,19 +386,11 @@
 	softc->flags |= CD_FLAG_INVALID;
 
 	/*
-	 * Although the oninvalidate() routines are always called at
-	 * splsoftcam, we need to be at splbio() here to keep the buffer
-	 * queue from being modified while we traverse it.
-	 */
-	s = splbio();
-
-	/*
 	 * Return all queued I/O with ENXIO.
 	 * XXX Handle any transactions queued to the card
 	 *     with XPT_ABORT_CCB.
 	 */
 	bioq_flush(&softc->bio_queue, NULL, ENXIO);
-	splx(s);
 
 	/*
 	 * If this device is part of a changer, and it was scheduled
@@ -417,7 +409,6 @@
 cdcleanup(struct cam_periph *periph)
 {
 	struct cd_softc *softc;
-	int s;
 
 	softc = (struct cd_softc *)periph->softc;
 
@@ -428,7 +419,6 @@
 		xpt_print(periph->path, "can't remove sysctl context\n");
 	}
 
-	s = splsoftcam();
 	/*
 	 * In the queued, non-active case, the device in question
 	 * has already been removed from the changer run queue.  Since this
@@ -498,7 +488,6 @@
 	}
 	disk_destroy(softc->disk);
 	free(softc, M_DEVBUF);
-	splx(s);
 }
 
 static void
@@ -545,10 +534,8 @@
 	{
 		struct cd_softc *softc;
 		struct ccb_hdr *ccbh;
-		int s;
 
 		softc = (struct cd_softc *)periph->softc;
-		s = splsoftcam();
 		/*
 		 * Don't fail on the expected unit attention
 		 * that will occur.
@@ -556,7 +543,6 @@
 		softc->flags |= CD_FLAG_RETRY_UA;
 		LIST_FOREACH(ccbh, &softc->pending_ccbs, periph_links.le)
 			ccbh->ccb_state |= CD_CCB_RETRY_UA;
-		splx(s);
 		/* FALLTHROUGH */
 	}
 	default:
@@ -1011,17 +997,22 @@
 
 	softc = (struct cd_softc *)periph->softc;
 
-	/*
-	 * Grab splsoftcam and hold it until we lock the peripheral.
-	 */
+	if (cam_periph_acquire(periph) != CAM_REQ_CMP)
+		return(ENXIO);
+
+	cam_periph_lock(periph);
+
 	if (softc->flags & CD_FLAG_INVALID) {
+		cam_periph_unlock(periph);
+		cam_periph_release(periph);
 		return(ENXIO);
 	}
 
-	if (cam_periph_acquire(periph) != CAM_REQ_CMP)
-		return(ENXIO);
-
-	cam_periph_lock(periph);
+	/* Closes aren't symmetrical with opens, so fix up the refcounting. */
+	if (softc->flags & CD_FLAG_OPEN)
+		cam_periph_release(periph);
+	else
+		softc->flags |= CD_FLAG_OPEN;
 
 	/*
 	 * Check for media, and set the appropriate flags.  We don't bail
@@ -1062,7 +1053,7 @@
 	/*
 	 * We'll check the media and toc again at the next open().
 	 */
-	softc->flags &= ~(CD_FLAG_VALID_MEDIA|CD_FLAG_VALID_TOC);
+	softc->flags &= ~(CD_FLAG_VALID_MEDIA|CD_FLAG_VALID_TOC|CD_FLAG_OPEN);
 
 	cam_periph_unlock(periph);
 	cam_periph_release(periph);
@@ -1074,10 +1065,7 @@
 cdshorttimeout(void *arg)
 {
 	struct cdchanger *changer;
-	int s;
 
-	s = splsoftcam();
-
 	changer = (struct cdchanger *)arg;
 
 	/* Always clear the short timeout flag, since that's what we're in */
@@ -1092,8 +1080,6 @@
 		changer->flags |= CHANGER_MANUAL_CALL;
 		cdrunchangerqueue(changer);
 	}
-
-	splx(s);
 }
 
 /*
@@ -1103,9 +1089,6 @@
 cdschedule(struct cam_periph *periph, int priority)
 {
 	struct cd_softc *softc;
-	int s;
-
-	s = splsoftcam();
 
 	softc = (struct cd_softc *)periph->softc;
 
@@ -1144,9 +1127,6 @@
 	} else if ((softc->flags & CD_FLAG_ACTIVE)
 		&& ((softc->flags & CD_FLAG_SCHED_ON_COMP) == 0))
 		xpt_schedule(periph, priority);
-
-	splx(s);
-
 }
 
 static void
@@ -1155,9 +1135,6 @@
 	struct cd_softc *softc;
 	struct cdchanger *changer;
 	int called_from_timeout;
-	int s;
-
-	s = splsoftcam();
 
 	changer = (struct cdchanger *)arg;
 
@@ -1177,7 +1154,6 @@
 
 	/* nothing to do if the queue is empty */
 	if (changer->devq.entries <= 0) {
-		splx(s);
 		return;
 	}
 
@@ -1197,7 +1173,6 @@
 				    cdrunchangerqueue, changer);
 				changer->flags |= CHANGER_TIMEOUT_SCHED;
 			}
-			splx(s);
 			return;
 		}
 
@@ -1254,17 +1229,12 @@
 	 * switch time.
 	 */
 	changer->flags |= CHANGER_NEED_TIMEOUT;
-
-	splx(s);
 }
 
 static void
 cdchangerschedule(struct cd_softc *softc)
 {
 	struct cdchanger *changer;
-	int s;
-
-	s = splsoftcam();
 
 	changer = softc->changer;
 
@@ -1334,7 +1304,6 @@
 		changer->flags &= ~CHANGER_NEED_TIMEOUT;
 
 	}
-	splx(s);
 }
 
 static int
@@ -1363,14 +1332,10 @@
 cdgetccb(struct cam_periph *periph, u_int32_t priority)
 {
 	struct cd_softc *softc;
-	int s;
 
 	softc = (struct cd_softc *)periph->softc;
 
 	if (softc->flags & CD_FLAG_CHANGER) {
-
-		s = splsoftcam();
-
 		/*
 		 * This should work the first time this device is woken up,
 		 * but just in case it doesn't, we use a while loop.
@@ -1395,7 +1360,6 @@
 			} else
 				tsleep(&softc->changer, PRIBIO, "cgticb", 0);
 		}
-		splx(s);
 	}
 	return(cam_periph_getccb(periph, priority));
 }
@@ -1411,7 +1375,6 @@
 {
 	struct cam_periph *periph;
 	struct cd_softc *softc;
-	int    s;
 
 	periph = (struct cam_periph *)bp->bio_disk->d_drv1;
 	if (periph == NULL) {
@@ -1419,22 +1382,16 @@
 		return;
 	}
 
+	cam_periph_lock(periph);
 	CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering cdstrategy\n"));
 
 	softc = (struct cd_softc *)periph->softc;
 
 	/*
-	 * Mask interrupts so that the pack cannot be invalidated until
-	 * after we are in the queue.  Otherwise, we might not properly
-	 * clean up one of the buffers.
-	 */
-	s = splbio();
-	
-	/*
 	 * If the device has been made invalid, error out
 	 */
 	if ((softc->flags & CD_FLAG_INVALID)) {
-		splx(s);
+		cam_periph_unlock(periph);
 		biofinish(bp, NULL, ENXIO);
 		return;
 	}
@@ -1448,7 +1405,7 @@
 
 		error = cdcheckmedia(periph);
 		if (error != 0) {
-			splx(s);
+			cam_periph_unlock(periph);
 			biofinish(bp, NULL, error);
 			return;
 		}
@@ -1459,8 +1416,6 @@
 	 */
 	bioq_disksort(&softc->bio_queue, bp);
 
-	splx(s);
-	
 	/*
 	 * Schedule ourselves for performing the work.  We do things
 	 * differently for changers.
@@ -1470,6 +1425,7 @@
 	else
 		cdschedule(periph, /* priority */ 1);
 
+	cam_periph_unlock(periph);
 	return;
 }
 
@@ -1480,7 +1436,6 @@
 	struct bio *bp;
 	struct ccb_scsiio *csio;
 	struct scsi_read_capacity_data *rcap;
-	int s;
 
 	softc = (struct cd_softc *)periph->softc;
 
@@ -1489,9 +1444,6 @@
 	switch (softc->state) {
 	case CD_STATE_NORMAL:
 	{
-		int oldspl;
-
-		s = splbio();
 		bp = bioq_first(&softc->bio_queue);
 		if (periph->immediate_priority <= periph->pinfo.priority) {
 			start_ccb->ccb_h.ccb_state = CD_CCB_WAITING;
@@ -1499,10 +1451,8 @@
 			SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
 					  periph_links.sle);
 			periph->immediate_priority = CAM_PRIORITY_NONE;
-			splx(s);
 			wakeup(&periph->ccb_list);
 		} else if (bp == NULL) {
-			splx(s);
 			xpt_release_ccb(start_ccb);
 		} else {
 			bioq_remove(&softc->bio_queue, bp);
@@ -1526,15 +1476,9 @@
 			start_ccb->ccb_h.ccb_state = CD_CCB_BUFFER_IO;
 
 			
-			/*
-			 * Block out any asyncronous callbacks
-			 * while we touch the pending ccb list.
-			 */
-			oldspl = splcam();
 			LIST_INSERT_HEAD(&softc->pending_ccbs,
 					 &start_ccb->ccb_h, periph_links.le);
 			softc->outstanding_cmds++;
-			splx(oldspl);
 
 			/* We expect a unit attention from this device */
 			if ((softc->flags & CD_FLAG_RETRY_UA) != 0) {
@@ -1544,7 +1488,6 @@
 
 			start_ccb->ccb_h.ccb_bp = bp;
 			bp = bioq_first(&softc->bio_queue);
-			splx(s);
 
 			xpt_action(start_ccb);
 		}
@@ -1598,7 +1541,6 @@
 	{
 		struct bio	*bp;
 		int		error;
-		int		oldspl;
 
 		bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
 		error = 0;
@@ -1622,13 +1564,9 @@
 		}
 
 		if (error != 0) {
-			int s;
-
 			xpt_print(periph->path,
 			    "cddone: got error %#x back\n", error);
-			s = splbio();
 			bioq_flush(&softc->bio_queue, NULL, EIO);
-			splx(s);
 			bp->bio_resid = bp->bio_bcount;
 			bp->bio_error = error;
 			bp->bio_flags |= BIO_ERROR;
@@ -1651,14 +1589,8 @@
 			}
 		}
 
-		/*
-		 * Block out any asyncronous callbacks
-		 * while we touch the pending ccb list.
-		 */
-		oldspl = splcam();
 		LIST_REMOVE(&done_ccb->ccb_h, periph_links.le);
 		softc->outstanding_cmds--;
-		splx(oldspl);
 
 		if (softc->flags & CD_FLAG_CHANGER)
 			cdchangerschedule(softc);



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