diff options
Diffstat (limited to 'sys/cam/scsi/scsi_sa.c')
-rw-r--r-- | sys/cam/scsi/scsi_sa.c | 118 |
1 files changed, 47 insertions, 71 deletions
diff --git a/sys/cam/scsi/scsi_sa.c b/sys/cam/scsi/scsi_sa.c index 013e421..170d35c 100644 --- a/sys/cam/scsi/scsi_sa.c +++ b/sys/cam/scsi/scsi_sa.c @@ -447,37 +447,33 @@ saopen(struct cdev *dev, int flags, int fmt, struct thread *td) struct sa_softc *softc; int unit; int error; - int s; unit = SAUNIT(dev); - s = splsoftcam(); periph = (struct cam_periph *)dev->si_drv1; - if (periph == NULL) { - (void) splx(s); - return (ENXIO); + if (cam_periph_acquire(periph) != CAM_REQ_CMP) { + return (ENXIO); } + + cam_periph_lock(periph); + softc = (struct sa_softc *)periph->softc; - if ((error = cam_periph_lock(periph, PRIBIO|PCATCH)) != 0) { - splx(s); - return (error); - } - splx(s); CAM_DEBUG(periph->path, CAM_DEBUG_TRACE|CAM_DEBUG_INFO, ("saopen(%d): dev=0x%x softc=0x%x\n", unit, unit, softc->flags)); - if (cam_periph_acquire(periph) != CAM_REQ_CMP) { - cam_periph_unlock(periph); - return (ENXIO); - } - if (SA_IS_CTRL(dev)) { softc->ctrl_mode = 1; cam_periph_unlock(periph); return (0); } + if ((error = cam_periph_hold(periph, PRIBIO|PCATCH)) != 0) { + cam_periph_unlock(periph); + cam_periph_release(periph); + return (error); + } + if (softc->flags & SA_FLAG_OPEN) { error = EBUSY; } else if (softc->flags & SA_FLAG_INVALID) { @@ -499,17 +495,23 @@ saopen(struct cdev *dev, int flags, int fmt, struct thread *td) if (error && (flags & O_NONBLOCK)) { softc->flags |= SA_FLAG_OPEN; softc->open_pending_mount = 1; + cam_periph_unhold(periph); cam_periph_unlock(periph); return (0); } } if (error) { + cam_periph_unhold(periph); + cam_periph_unlock(periph); cam_periph_release(periph); - } else { - saprevent(periph, PR_PREVENT); - softc->flags |= SA_FLAG_OPEN; + return (error); } + + saprevent(periph, PR_PREVENT); + softc->flags |= SA_FLAG_OPEN; + + cam_periph_unhold(periph); cam_periph_unlock(periph); return (error); } @@ -528,32 +530,35 @@ saclose(struct cdev *dev, int flag, int fmt, struct thread *td) if (periph == NULL) return (ENXIO); + cam_periph_lock(periph); + softc = (struct sa_softc *)periph->softc; CAM_DEBUG(periph->path, CAM_DEBUG_TRACE|CAM_DEBUG_INFO, ("saclose(%d): dev=0x%x softc=0x%x\n", unit, unit, softc->flags)); - if ((error = cam_periph_lock(periph, PRIBIO)) != 0) { - return (error); - } - softc->open_rdonly = 0; if (SA_IS_CTRL(dev)) { softc->ctrl_mode = 0; - cam_periph_release(periph); cam_periph_unlock(periph); + cam_periph_release(periph); return (0); } if (softc->open_pending_mount) { softc->flags &= ~SA_FLAG_OPEN; softc->open_pending_mount = 0; - cam_periph_release(periph); cam_periph_unlock(periph); + cam_periph_release(periph); return (0); } + if ((error = cam_periph_hold(periph, PRIBIO)) != 0) { + cam_periph_unlock(periph); + return (error); + } + /* * Were we writing the tape? */ @@ -661,6 +666,7 @@ saclose(struct cdev *dev, int flag, int fmt, struct thread *td) if ((softc->flags & SA_FLAG_TAPE_MOUNTED) == 0) sareservereleaseunit(periph, FALSE); + cam_periph_unhold(periph); cam_periph_unlock(periph); cam_periph_release(periph); @@ -677,7 +683,6 @@ sastrategy(struct bio *bp) { struct cam_periph *periph; struct sa_softc *softc; - int s; bp->bio_resid = bp->bio_bcount; if (SA_IS_CTRL(bp->bio_dev)) { @@ -689,18 +694,18 @@ sastrategy(struct bio *bp) biofinish(bp, NULL, ENXIO); return; } - softc = (struct sa_softc *)periph->softc; + cam_periph_lock(periph); - s = splsoftcam(); + softc = (struct sa_softc *)periph->softc; if (softc->flags & SA_FLAG_INVALID) { - splx(s); + cam_periph_unlock(periph); biofinish(bp, NULL, ENXIO); return; } if (softc->flags & SA_FLAG_TAPE_FROZEN) { - splx(s); + cam_periph_unlock(periph); biofinish(bp, NULL, EPERM); return; } @@ -711,16 +716,15 @@ sastrategy(struct bio *bp) * file descriptor. */ if (bp->bio_cmd == BIO_WRITE && softc->open_rdonly) { - splx(s); + cam_periph_unlock(periph); biofinish(bp, NULL, EBADF); return; } - splx(s); - if (softc->open_pending_mount) { int error = samount(periph, 0, bp->bio_dev); if (error) { + cam_periph_unlock(periph); biofinish(bp, NULL, ENXIO); return; } @@ -733,6 +737,7 @@ sastrategy(struct bio *bp) * If it's a null transfer, return immediately */ if (bp->bio_bcount == 0) { + cam_periph_unlock(periph); biodone(bp); return; } @@ -750,6 +755,7 @@ sastrategy(struct bio *bp) xpt_print(periph->path, "Invalid request. Fixed block " "device requests must be a multiple of %d bytes\n", softc->min_blk); + cam_periph_unlock(periph); biofinish(bp, NULL, EINVAL); return; } @@ -765,18 +771,12 @@ sastrategy(struct bio *bp) } printf("between %d and %d bytes\n", softc->min_blk, softc->max_blk); + cam_periph_unlock(periph); biofinish(bp, NULL, EINVAL); return; } /* - * Mask interrupts so that the device cannot be invalidated until - * after we are in the queue. Otherwise, we might not properly - * clean up one of the buffers. - */ - s = splbio(); - - /* * Place it at the end of the queue. */ bioq_insert_tail(&softc->bio_queue, bp); @@ -791,12 +791,12 @@ sastrategy(struct bio *bp) CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("sastrategy: queue count now %d\n", softc->queue_count)); } - splx(s); /* * Schedule ourselves for performing the work. */ xpt_schedule(periph, 1); + cam_periph_unlock(periph); return; } @@ -819,7 +819,6 @@ saioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) struct sa_softc *softc; scsi_space_code spaceop; int didlockperiph = 0; - int s; int mode; int error = 0; @@ -831,6 +830,7 @@ saioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) if (periph == NULL) return (ENXIO); + cam_periph_lock(periph); softc = (struct sa_softc *)periph->softc; /* @@ -856,13 +856,10 @@ saioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) * other thread that has this device open to do * an MTIOCERRSTAT that would clear latched status. */ - s = splsoftcam(); if ((periph->flags & CAM_PERIPH_LOCKED) == 0) { - error = cam_periph_lock(periph, PRIBIO|PCATCH); - if (error != 0) { - splx(s); + error = cam_periph_hold(periph, PRIBIO|PCATCH); + if (error != 0) return (error); - } didlockperiph = 1; } break; @@ -895,12 +892,9 @@ saioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) * than at open time because we are sharing writable * access to data structures. */ - s = splsoftcam(); - error = cam_periph_lock(periph, PRIBIO|PCATCH); - if (error != 0) { - splx(s); + error = cam_periph_hold(periph, PRIBIO|PCATCH); + if (error != 0) return (error); - } didlockperiph = 1; break; @@ -1327,8 +1321,9 @@ saioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) } } if (didlockperiph) { - cam_periph_unlock(periph); + cam_periph_unhold(periph); } + cam_periph_unlock(periph); return (error); } @@ -1371,7 +1366,6 @@ saoninvalidate(struct cam_periph *periph) { struct sa_softc *softc; struct ccb_setasync csa; - int s; softc = (struct sa_softc *)periph->softc; @@ -1389,20 +1383,12 @@ saoninvalidate(struct cam_periph *periph) softc->flags |= SA_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); softc->queue_count = 0; - splx(s); xpt_print(periph->path, "lost device\n"); @@ -1609,12 +1595,10 @@ sastart(struct cam_periph *periph, union ccb *start_ccb) { /* Pull a buffer from the queue and get going on it */ struct bio *bp; - int s; /* * See if there is a buf with work for us to do.. */ - s = splbio(); bp = bioq_first(&softc->bio_queue); if (periph->immediate_priority <= periph->pinfo.priority) { CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE, @@ -1623,10 +1607,8 @@ sastart(struct cam_periph *periph, union ccb *start_ccb) 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 if ((softc->flags & SA_FLAG_ERR_PENDING) != 0) { struct bio *done_bp; @@ -1669,7 +1651,6 @@ again: "%d more buffers queued up\n", (softc->flags & SA_FLAG_ERR_PENDING), (bp != NULL)? "not " : " ", softc->queue_count)); - splx(s); xpt_release_ccb(start_ccb); biodone(done_bp); } else { @@ -1689,7 +1670,6 @@ again: bp->bio_error = EIO; xpt_print(periph->path, "zero blocksize" " for FIXED length writes?\n"); - splx(s); biodone(bp); break; } @@ -1740,7 +1720,6 @@ again: Set_CCB_Type(start_ccb, SA_CCB_BUFFER_IO); start_ccb->ccb_h.ccb_bp = bp; bp = bioq_first(&softc->bio_queue); - splx(s); xpt_action(start_ccb); } @@ -1785,7 +1764,6 @@ sadone(struct cam_periph *periph, union ccb *done_ccb) } if (error == EIO) { - int s; /* * Catastrophic error. Mark the tape as frozen @@ -1798,10 +1776,8 @@ sadone(struct cam_periph *periph, union ccb *done_ccb) * */ - s = splbio(); softc->flags |= SA_FLAG_TAPE_FROZEN; bioq_flush(&softc->bio_queue, NULL, EIO); - splx(s); } if (error != 0) { bp->bio_resid = bp->bio_bcount; |