예제 #1
0
void
isf_detach(struct isf_softc *sc)
{

	/*
	 * Simulate a disk removal if one is present to deal with any pending
	 * or queued I/O.  This will occur as a result of a device driver
	 * detach -- the Intel StrataFlash has no notion of removal itself.
	 *
	 * XXXRW: Is the locking here right?
	 */
	ISF_LOCK(sc);
	isf_disk_remove(sc);
	bioq_flush(&sc->isf_bioq, NULL, ENXIO);
	KASSERT(bioq_first(&sc->isf_bioq) == NULL,
	    ("%s: non-empty bioq", __func__));
	ISF_UNLOCK(sc);
	ISF_LOCK_DESTROY(sc);
}
예제 #2
0
static void
ptoninvalidate(struct cam_periph *periph)
{
    struct pt_softc *softc;

    softc = (struct pt_softc *)periph->softc;

    /*
     * De-register any async callbacks.
     */
    xpt_register_async(0, ptasync, periph, periph->path);

    softc->flags |= PT_FLAG_DEVICE_INVALID;

    /*
     * 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);
}
예제 #3
0
static void
ptdone(struct cam_periph *periph, union ccb *done_ccb)
{
	struct pt_softc *softc;
	struct ccb_scsiio *csio;

	softc = (struct pt_softc *)periph->softc;
	csio = &done_ccb->csio;
	switch (csio->ccb_h.ccb_state) {
	case PT_CCB_BUFFER_IO:
	case PT_CCB_BUFFER_IO_UA:
	{
		struct bio *bp;

		bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
			int error;
			int sf;
			
			if ((csio->ccb_h.ccb_state & PT_CCB_RETRY_UA) != 0)
				sf = SF_RETRY_UA;
			else
				sf = 0;

			error = pterror(done_ccb, CAM_RETRY_SELTO, sf);
			if (error == ERESTART) {
				/*
				 * A retry was scheuled, so
				 * just return.
				 */
				return;
			}
			if (error != 0) {
				if (error == ENXIO) {
					/*
					 * Catastrophic error.  Mark our device
					 * as invalid.
					 */
					xpt_print(periph->path,
					    "Invalidating device\n");
					softc->flags |= PT_FLAG_DEVICE_INVALID;
				}

				/*
				 * return all queued I/O with EIO, so that
				 * the client can retry these I/Os in the
				 * proper order should it attempt to recover.
				 */
				bioq_flush(&softc->bio_queue, NULL, EIO);
				bp->bio_error = error;
				bp->bio_resid = bp->bio_bcount;
				bp->bio_flags |= BIO_ERROR;
			} else {
				bp->bio_resid = csio->resid;
				bp->bio_error = 0;
				if (bp->bio_resid != 0) {
					/* Short transfer ??? */
					bp->bio_flags |= BIO_ERROR;
				}
			}
			if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
				cam_release_devq(done_ccb->ccb_h.path,
						 /*relsim_flags*/0,
						 /*reduction*/0,
						 /*timeout*/0,
						 /*getcount_only*/0);
		} else {
			bp->bio_resid = csio->resid;
			if (bp->bio_resid != 0)
				bp->bio_flags |= BIO_ERROR;
		}

		/*
		 * Block out any asyncronous callbacks
		 * while we touch the pending ccb list.
		 */
		LIST_REMOVE(&done_ccb->ccb_h, periph_links.le);

		biofinish(bp, softc->device_stats, 0);
		break;
	}
	case PT_CCB_WAITING:
		/* Caller will release the CCB */
		wakeup(&done_ccb->ccb_h.cbfcnp);
		return;
	}
	xpt_release_ccb(done_ccb);
}