Exemplo n.º 1
0
void
idad_intr(struct bio *bio)
{
	struct idad_softc *drv = (struct idad_softc *)bio->bio_driver_info;
	struct buf *bp = bio->bio_buf;

	if (bp->b_flags & B_ERROR)
		bp->b_error = EIO;
	else
		bp->b_resid = 0;

	devstat_end_transaction_buf(&drv->stats, bp);
	biodone(bio);
}
Exemplo n.º 2
0
static void
ad_done(struct ata_request *request)
{
    struct ad_softc *adp = device_get_ivars(request->dev);
    struct bio *bp = request->bio;
    struct buf *bbp = bp->bio_buf;

    /* finish up transfer */
    if ((bbp->b_error = request->result))
	bbp->b_flags |= B_ERROR;
    bbp->b_resid = bbp->b_bcount - request->donecount;
    devstat_end_transaction_buf(&adp->stats, bbp);
    biodone(bp);
    ata_free_request(request);
}
Exemplo n.º 3
0
/* ipsd_finish is called to clean up and return a completed IO request */
void
ipsd_finish(struct bio *bio)
{
	struct buf *bp = bio->bio_buf;
	ipsdisk_softc_t *dsc;

	dsc = bio->bio_driver_info;
	if (bp->b_flags & B_ERROR) {
		device_printf(dsc->dev, "iobuf error %d\n", bp->b_error);
	} else {
		bp->b_resid = 0;
	}
	devstat_end_transaction_buf(&dsc->stats, bp);
	biodone(bio);
	ips_start_io_request(dsc->sc);
}
Exemplo n.º 4
0
void
mfi_disk_complete(struct bio *bio)
{
	struct mfi_system_pd *sc = bio->bio_driver_info;
	struct buf *bp = bio->bio_buf;

	devstat_end_transaction_buf(&sc->pd_devstat, bp);
	if (bio->b_flags & B_ERROR) {
		if (bp->b_error == 0)
			bp->b_error = EIO;
		diskerr(bio, sc->pd_disk.d_cdev, "hard error", -1, 1);
		kprintf("\n");
	} else {
		bp->b_resid = 0;
	}
	biodone(bio);
}
Exemplo n.º 5
0
static int 
ast_done(struct atapi_request *request)
{
    struct buf *bp = request->driver;
    struct ast_softc *stp = request->device->driver;

    if (request->error) {
	bp->b_error = request->error;
	bp->b_flags |= B_ERROR;
    }
    else {
	if (!(bp->b_flags & B_READ))
	    stp->flags |= F_DATA_WRITTEN;
	bp->b_resid = bp->b_bcount - request->donecount;
	ast_total += (bp->b_bcount - bp->b_resid);
    }
    devstat_end_transaction_buf(&stp->stats, bp);
    biodone(bp);
    return 0;
}
Exemplo n.º 6
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 buf *bp;
		struct bio *bio;

		bio = (struct bio *)done_ccb->ccb_h.ccb_bio;
		bp = bio->bio_buf;

		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) {
				struct buf *q_bp;
				struct bio *q_bio;

				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.
				 */
				while ((q_bio = bioq_takefirst(&softc->bio_queue)) != NULL) {
					q_bp = q_bio->bio_buf;
					q_bp->b_resid = q_bp->b_bcount;
					q_bp->b_error = EIO;
					q_bp->b_flags |= B_ERROR;
					biodone(q_bio);
				}
				bp->b_error = error;
				bp->b_resid = bp->b_bcount;
				bp->b_flags |= B_ERROR;
			} else {
				bp->b_resid = csio->resid;
				bp->b_error = 0;
				if (bp->b_resid != 0) {
					/* Short transfer ??? */
					bp->b_flags |= B_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->b_resid = csio->resid;
			if (bp->b_resid != 0)
				bp->b_flags |= B_ERROR;
		}

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

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