/* * 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; }
/* * 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; }