コード例 #1
0
ファイル: mlx_disk.c プロジェクト: cyrilmagsuci/freebsd
/*
 * Read/write routine for a buffer.  Finds the proper unit, range checks
 * arguments, and schedules the transfer.  Does not wait for the transfer
 * to complete.  Multi-page transfers are supported.  All I/O requests must
 * be a multiple of a sector in length.
 */
static void
mlxd_strategy(struct bio *bp)
{
    struct mlxd_softc	*sc = bp->bio_disk->d_drv1;

    debug_called(1);

    /* bogus disk? */
    if (sc == NULL) {
        bp->bio_error = EINVAL;
        bp->bio_flags |= BIO_ERROR;
        goto bad;
    }

    /* XXX may only be temporarily offline - sleep? */
    MLX_IO_LOCK(sc->mlxd_controller);
    if (sc->mlxd_drive->ms_state == MLX_SYSD_OFFLINE) {
        MLX_IO_UNLOCK(sc->mlxd_controller);
        bp->bio_error = ENXIO;
        bp->bio_flags |= BIO_ERROR;
        goto bad;
    }

    mlx_submit_buf(sc->mlxd_controller, bp);
    MLX_IO_UNLOCK(sc->mlxd_controller);
    return;

bad:
    /*
     * Correctly set the bio to indicate a failed tranfer.
     */
    bp->bio_resid = bp->bio_bcount;
    biodone(bp);
    return;
}
コード例 #2
0
/*
 * Read/write routine for a buffer.  Finds the proper unit, range checks
 * arguments, and schedules the transfer.  Does not wait for the transfer
 * to complete.  Multi-page transfers are supported.  All I/O requests must
 * be a multiple of a sector in length.
 */
static void
mlxd_strategy(mlx_bio *bp)
{
    struct mlxd_softc	*sc = (struct mlxd_softc *)MLX_BIO_SOFTC(bp);

    debug_called(1);

    /* bogus disk? */
    if (sc == NULL) {
	MLX_BIO_SET_ERROR(bp, EINVAL);
	goto bad;
    }

    /* XXX may only be temporarily offline - sleep? */
    if (sc->mlxd_drive->ms_state == MLX_SYSD_OFFLINE) {
	MLX_BIO_SET_ERROR(bp, ENXIO);
	goto bad;
    }

    MLX_BIO_STATS_START(bp);
    mlx_submit_buf(sc->mlxd_controller, bp);
    return;

 bad:
    /*
     * Correctly set the bio to indicate a failed tranfer.
     */
    MLX_BIO_RESID(bp) = MLX_BIO_LENGTH(bp);
    MLX_BIO_DONE(bp);
    return;
}