static void
mfi_disk_strategy(struct bio *bio)
{
    struct mfi_disk *sc;
    struct mfi_softc *controller;

    sc = bio->bio_disk->d_drv1;

    if (sc == NULL) {
        bio->bio_error = EINVAL;
        bio->bio_flags |= BIO_ERROR;
        bio->bio_resid = bio->bio_bcount;
        biodone(bio);
        return;
    }

    controller = sc->ld_controller;
    bio->bio_driver1 = (void *)(uintptr_t)sc->ld_id;
    /* Mark it as LD IO */
    bio->bio_driver2 = (void *)MFI_LD_IO;
    mtx_lock(&controller->mfi_io_lock);
    mfi_enqueue_bio(controller, bio);
    mfi_startio(controller);
    mtx_unlock(&controller->mfi_io_lock);
    return;
}
Exemple #2
0
static int
mfi_disk_strategy(struct dev_strategy_args *ap)
{
	struct bio *bio = ap->a_bio;
	struct buf *bp = bio->bio_buf;
	struct mfi_disk *sc = ap->a_head.a_dev->si_drv1;
	struct mfi_softc *controller = sc->ld_controller;

	if (sc == NULL) {
		bp->b_error = EINVAL;
		bp->b_flags |= B_ERROR;
		bp->b_resid = bp->b_bcount;
		biodone(bio);
		return (0);
	}

	if (controller->hw_crit_error) {
		bp->b_error = EBUSY;
		return (0);
	}

	if (controller->issuepend_done == 0) {
		bp->b_error = EBUSY;
		return (0);
	}

	/*
	 * XXX swildner
	 *
	 * If it's a null transfer, do nothing. FreeBSD's original driver
	 * doesn't have this, but that caused hard error messages (even
	 * though everything else continued to work fine). Interestingly,
	 * only when HAMMER was used.
	 *
	 * Several others of our RAID drivers have this check, such as
	 * aac(4) and ida(4), so we insert it here, too.
	 *
	 * The cause of null transfers is yet unknown.
	 */
	if (bp->b_bcount == 0) {
		bp->b_resid = bp->b_bcount;
		biodone(bio);
		return (0);
	}

	bio->bio_driver_info = sc;
	lockmgr(&controller->mfi_io_lock, LK_EXCLUSIVE);
	mfi_enqueue_bio(controller, bio);
	devstat_start_transaction(&sc->ld_devstat);
	mfi_startio(controller);
	lockmgr(&controller->mfi_io_lock, LK_RELEASE);
	return (0);
}