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>