Ever since the block layer expanded its command syntax beyond just
BIO_READ and BIO_WRITE, we've handled this expanded syntax poorly in drivers when the driver doesn't support a particular command. Do a sweep and fix that. Reported by: imp
This commit is contained in:
parent
a2abae8dc9
commit
d176b8039e
@ -2430,6 +2430,10 @@ adastart(struct cam_periph *periph, union ccb *start_ccb)
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
biofinish(bp, NULL, EOPNOTSUPP);
|
||||
xpt_release_ccb(start_ccb);
|
||||
return;
|
||||
}
|
||||
start_ccb->ccb_h.ccb_state = ADA_CCB_BUFFER_IO;
|
||||
start_ccb->ccb_h.flags |= CAM_UNLOCKED;
|
||||
|
@ -1834,6 +1834,10 @@ sddastart(struct cam_periph *periph, union ccb *start_ccb)
|
||||
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("BIO_DELETE\n"));
|
||||
sddaschedule(periph);
|
||||
break;
|
||||
default:
|
||||
biofinish(bp, NULL, EOPNOTSUPP);
|
||||
xpt_release_ccb(start_ccb);
|
||||
return;
|
||||
}
|
||||
start_ccb->ccb_h.ccb_bp = bp;
|
||||
softc->outstanding_cmds++;
|
||||
|
@ -994,6 +994,11 @@ ndastart(struct cam_periph *periph, union ccb *start_ccb)
|
||||
case BIO_FLUSH:
|
||||
nda_nvme_flush(softc, nvmeio);
|
||||
break;
|
||||
default:
|
||||
biofinish(bp, NULL, EOPNOTSUPP);
|
||||
xpt_release_ccb(start_ccb);
|
||||
ndaschedule(periph);
|
||||
return;
|
||||
}
|
||||
start_ccb->ccb_state = NDA_CCB_BUFFER_IO;
|
||||
start_ccb->ccb_bp = bp;
|
||||
|
@ -927,6 +927,13 @@ cdstart(struct cam_periph *periph, union ccb *start_ccb)
|
||||
}
|
||||
bioq_remove(&softc->bio_queue, bp);
|
||||
|
||||
if ((bp->bio_cmd != BIO_READ) &&
|
||||
(bp->bio_cmd != BIO_WRITE)) {
|
||||
biofinish(bp, NULL, EOPNOTSUPP);
|
||||
xpt_release_ccb(start_ccb);
|
||||
return;
|
||||
}
|
||||
|
||||
scsi_read_write(&start_ccb->csio,
|
||||
/*retries*/ cd_retry_count,
|
||||
/* cbfcnp */ cddone,
|
||||
|
@ -3381,6 +3381,10 @@ dastart(struct cam_periph *periph, union ccb *start_ccb)
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
biofinish(bp, NULL, EOPNOTSUPP);
|
||||
xpt_release_ccb(start_ccb);
|
||||
return;
|
||||
}
|
||||
start_ccb->ccb_h.ccb_state = DA_CCB_BUFFER_IO;
|
||||
start_ccb->ccb_h.flags |= CAM_UNLOCKED;
|
||||
|
@ -2683,6 +2683,12 @@ sastart(struct cam_periph *periph, union ccb *start_ccb)
|
||||
bioq_remove(&softc->bio_queue, bp);
|
||||
softc->queue_count--;
|
||||
|
||||
if ((bp->bio_cmd != BIO_READ) &&
|
||||
(bp->bio_cmd != BIO_WRITE)) {
|
||||
biofinish(bp, NULL, EOPNOTSUPP);
|
||||
xpt_release_ccb(start_ccb);
|
||||
return;
|
||||
}
|
||||
length = bp->bio_bcount;
|
||||
|
||||
if ((softc->flags & SA_FLAG_FIXED) != 0) {
|
||||
|
@ -163,6 +163,11 @@ aac_disk_strategy(struct bio *bp)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((bp->bio_cmd != BIO_READ) && (bp->bio_cmd != BIO_WRITE)) {
|
||||
biofinish(bp, NULL, EOPNOTSUPP);
|
||||
return;
|
||||
}
|
||||
|
||||
/* perform accounting */
|
||||
|
||||
/* pass the bio to the controller - it can work out who we are */
|
||||
|
@ -252,11 +252,13 @@ altera_avgen_disk_strategy(struct bio *bp)
|
||||
void *data;
|
||||
long bcount;
|
||||
daddr_t pblkno;
|
||||
int error;
|
||||
|
||||
sc = bp->bio_disk->d_drv1;
|
||||
data = bp->bio_data;
|
||||
bcount = bp->bio_bcount;
|
||||
pblkno = bp->bio_pblkno;
|
||||
error = 0;
|
||||
|
||||
/*
|
||||
* Serialize block reads / writes.
|
||||
@ -265,7 +267,7 @@ altera_avgen_disk_strategy(struct bio *bp)
|
||||
switch (bp->bio_cmd) {
|
||||
case BIO_READ:
|
||||
if (!(sc->avg_flags & ALTERA_AVALON_FLAG_GEOM_READ)) {
|
||||
biofinish(bp, NULL, EIO);
|
||||
error = EROFS;
|
||||
break;
|
||||
}
|
||||
switch (sc->avg_width) {
|
||||
@ -324,11 +326,11 @@ altera_avgen_disk_strategy(struct bio *bp)
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("%s: unsupported I/O operation %d", __func__,
|
||||
bp->bio_cmd);
|
||||
error = EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
mtx_unlock(&sc->avg_disk_mtx);
|
||||
biofinish(bp, NULL, 0);
|
||||
biofinish(bp, NULL, error);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -293,27 +293,27 @@ altera_sdcard_write_rxtx_buffer(struct altera_sdcard_softc *sc, void *data,
|
||||
}
|
||||
|
||||
static void
|
||||
altera_sdcard_io_start_internal(struct altera_sdcard_softc *sc, struct bio *bp)
|
||||
altera_sdcard_io_start_internal(struct altera_sdcard_softc *sc, struct bio **bp)
|
||||
{
|
||||
|
||||
switch (bp->bio_cmd) {
|
||||
switch (*bp->bio_cmd) {
|
||||
case BIO_READ:
|
||||
altera_sdcard_write_cmd_arg(sc, bp->bio_pblkno *
|
||||
altera_sdcard_write_cmd_arg(sc, *bp->bio_pblkno *
|
||||
ALTERA_SDCARD_SECTORSIZE);
|
||||
altera_sdcard_write_cmd(sc, ALTERA_SDCARD_CMD_READ_BLOCK);
|
||||
break;
|
||||
|
||||
case BIO_WRITE:
|
||||
altera_sdcard_write_rxtx_buffer(sc, bp->bio_data,
|
||||
bp->bio_bcount);
|
||||
altera_sdcard_write_cmd_arg(sc, bp->bio_pblkno *
|
||||
altera_sdcard_write_rxtx_buffer(sc, *bp->bio_data,
|
||||
*bp->bio_bcount);
|
||||
altera_sdcard_write_cmd_arg(sc, *bp->bio_pblkno *
|
||||
ALTERA_SDCARD_SECTORSIZE);
|
||||
altera_sdcard_write_cmd(sc, ALTERA_SDCARD_CMD_WRITE_BLOCK);
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("%s: unsupported I/O operation %d", __func__,
|
||||
bp->bio_cmd);
|
||||
biofinish(*bp, NULL, EOPNOTSUPP);
|
||||
*bp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -332,8 +332,8 @@ altera_sdcard_io_start(struct altera_sdcard_softc *sc, struct bio *bp)
|
||||
*/
|
||||
KASSERT(bp->bio_bcount == ALTERA_SDCARD_SECTORSIZE,
|
||||
("%s: I/O size not %d", __func__, ALTERA_SDCARD_SECTORSIZE));
|
||||
altera_sdcard_io_start_internal(sc, bp);
|
||||
sc->as_currentbio = bp;
|
||||
altera_sdcard_io_start_internal(sc, &bp);
|
||||
sc->as_currentbio = *bp;
|
||||
sc->as_retriesleft = ALTERA_SDCARD_RETRY_LIMIT;
|
||||
}
|
||||
|
||||
@ -406,7 +406,7 @@ altera_sdcard_io_complete(struct altera_sdcard_softc *sc, uint16_t asr)
|
||||
*/
|
||||
if (sc->as_retriesleft != 0) {
|
||||
sc->as_flags |= ALTERA_SDCARD_FLAG_IOERROR;
|
||||
altera_sdcard_io_start_internal(sc, bp);
|
||||
altera_sdcard_io_start_internal(sc, &bp);
|
||||
return (0);
|
||||
}
|
||||
sc->as_flags &= ~ALTERA_SDCARD_FLAG_IOERROR;
|
||||
|
@ -1315,6 +1315,10 @@ amr_bio_command(struct amr_softc *sc, struct amr_command **acp)
|
||||
ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
|
||||
cmd = AMR_CMD_FLUSH;
|
||||
break;
|
||||
default:
|
||||
biofinish(bio, NULL, EOPNOTSUPP);
|
||||
amr_releasecmd(ac);
|
||||
return (0);
|
||||
}
|
||||
amrd = (struct amrd_softc *)bio->bio_disk->d_drv1;
|
||||
driveno = amrd->amrd_drive - sc->amr_drive;
|
||||
|
@ -315,8 +315,10 @@ cfi_disk_strategy(struct bio *bp)
|
||||
{
|
||||
struct cfi_disk_softc *sc = bp->bio_disk->d_drv1;
|
||||
|
||||
if (sc == NULL)
|
||||
goto invalid;
|
||||
if (sc == NULL) {
|
||||
biofinish(bp, NULL, EINVAL);
|
||||
return;
|
||||
}
|
||||
if (bp->bio_bcount == 0) {
|
||||
bp->bio_resid = bp->bio_bcount;
|
||||
biodone(bp);
|
||||
@ -330,13 +332,11 @@ cfi_disk_strategy(struct bio *bp)
|
||||
bioq_insert_tail(&sc->bioq, bp);
|
||||
mtx_unlock(&sc->qlock);
|
||||
taskqueue_enqueue(sc->tq, &sc->iotask);
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
biofinish(bp, NULL, EOPNOTSUPP);
|
||||
break;
|
||||
}
|
||||
/* fall thru... */
|
||||
invalid:
|
||||
bp->bio_flags |= BIO_ERROR;
|
||||
bp->bio_error = EINVAL;
|
||||
biodone(bp);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -493,7 +493,7 @@ at45d_task(void *arg)
|
||||
len = sc->pagesize - offset;
|
||||
break;
|
||||
default:
|
||||
berr = EINVAL;
|
||||
berr = EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -658,7 +658,7 @@ mx25l_task(void *arg)
|
||||
bp->bio_data, bp->bio_bcount);
|
||||
break;
|
||||
default:
|
||||
bp->bio_error = EINVAL;
|
||||
bp->bio_error = EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
|
@ -462,7 +462,7 @@ n25q_task(void *arg)
|
||||
bp->bio_data, bp->bio_bcount);
|
||||
break;
|
||||
default:
|
||||
bp->bio_error = EINVAL;
|
||||
bp->bio_error = EOPNOTSUPP;
|
||||
}
|
||||
|
||||
biodone(bp);
|
||||
|
@ -106,6 +106,11 @@ idad_strategy(struct bio *bp)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if ((bp->bio_cmd != BIO_READ) && (bp->bio_cmd != BIO_WRITE)) {
|
||||
bp->bio_error = EOPNOTSUPP;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
bp->bio_driver1 = drv;
|
||||
ida_submit_buf(drv->controller, bp);
|
||||
return;
|
||||
|
@ -109,6 +109,13 @@ static void ipsd_strategy(struct bio *iobuf)
|
||||
dsc = iobuf->bio_disk->d_drv1;
|
||||
DEVICE_PRINTF(8,dsc->dev,"in strategy\n");
|
||||
iobuf->bio_driver1 = (void *)(uintptr_t)dsc->sc->drives[dsc->disk_number].drivenum;
|
||||
|
||||
if ((iobuf->bio_cmd != BIO_READ) &&
|
||||
(iobuf->bio_cmd != BIO_WRITE)) {
|
||||
biofinish(iobuf, NULL, EOPNOTSUPP);
|
||||
return;
|
||||
}
|
||||
|
||||
mtx_lock(&dsc->sc->queue_mtx);
|
||||
bioq_insert_tail(&dsc->sc->queue, iobuf);
|
||||
ips_start_io_request(dsc->sc);
|
||||
|
@ -2152,7 +2152,9 @@ mfi_build_syspdio(struct mfi_softc *sc, struct bio *bio)
|
||||
break;
|
||||
default:
|
||||
/* TODO: what about BIO_DELETE??? */
|
||||
panic("Unsupported bio command %x\n", bio->bio_cmd);
|
||||
biofinish(bio, NULL, EOPNOTSUPP);
|
||||
mfi_enqueue_free(cm);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Cheat with the sector length to avoid a non-constant division */
|
||||
@ -2211,7 +2213,9 @@ mfi_build_ldio(struct mfi_softc *sc, struct bio *bio)
|
||||
break;
|
||||
default:
|
||||
/* TODO: what about BIO_DELETE??? */
|
||||
panic("Unsupported bio command %x\n", bio->bio_cmd);
|
||||
biofinish(bio, NULL, EOPNOTSUPP);
|
||||
mfi_enqueue_free(cm);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Cheat with the sector length to avoid a non-constant division */
|
||||
|
@ -157,6 +157,11 @@ mlxd_strategy(struct bio *bp)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if ((bp->bio_cmd != BIO_READ) && (bp->bio_cmd != BIO_WRITE)) {
|
||||
bp->bio_error = EOPNOTSUPP;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* XXX may only be temporarily offline - sleep? */
|
||||
MLX_IO_LOCK(sc->mlxd_controller);
|
||||
if (sc->mlxd_drive->ms_state == MLX_SYSD_OFFLINE) {
|
||||
|
@ -1431,7 +1431,7 @@ mmcsd_task(void *arg)
|
||||
struct mmcsd_softc *sc;
|
||||
struct bio *bp;
|
||||
device_t dev, mmcbus;
|
||||
int err, sz;
|
||||
int bio_error, err, sz;
|
||||
|
||||
part = arg;
|
||||
sc = part->sc;
|
||||
@ -1482,11 +1482,14 @@ mmcsd_task(void *arg)
|
||||
block = mmcsd_rw(part, bp);
|
||||
} else if (bp->bio_cmd == BIO_DELETE) {
|
||||
block = mmcsd_delete(part, bp);
|
||||
} else {
|
||||
bio_error = EOPNOTSUPP;
|
||||
goto release;
|
||||
}
|
||||
release:
|
||||
MMCBUS_RELEASE_BUS(mmcbus, dev);
|
||||
if (block < end) {
|
||||
bp->bio_error = EIO;
|
||||
bp->bio_error = (bio_error == 0) ? EIO : bio_error;
|
||||
bp->bio_resid = (end - block) * sz;
|
||||
bp->bio_flags |= BIO_ERROR;
|
||||
} else {
|
||||
|
@ -488,7 +488,7 @@ nvme_ns_bio_process(struct nvme_namespace *ns, struct bio *bp,
|
||||
free(dsm_range, M_NVME);
|
||||
break;
|
||||
default:
|
||||
err = EIO;
|
||||
err = EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -214,6 +214,7 @@ pst_start(struct pst_softc *psc)
|
||||
struct pst_request *request;
|
||||
struct bio *bp;
|
||||
u_int32_t mfa;
|
||||
int error;
|
||||
|
||||
if (psc->iop->outstanding < (I2O_IOP_OUTBOUND_FRAME_COUNT - 1) &&
|
||||
(bp = bioq_first(&psc->queue))) {
|
||||
@ -231,8 +232,8 @@ pst_start(struct pst_softc *psc)
|
||||
request->psc = psc;
|
||||
request->mfa = mfa;
|
||||
request->bp = bp;
|
||||
if (pst_rw(request)) {
|
||||
biofinish(request->bp, NULL, EIO);
|
||||
if ((error = pst_rw(request)) != 0) {
|
||||
biofinish(request->bp, NULL, error);
|
||||
iop_free_mfa(request->psc->iop, request->mfa);
|
||||
psc->iop->outstanding--;
|
||||
free(request, M_PSTRAID);
|
||||
@ -286,7 +287,7 @@ pst_rw(struct pst_request *request)
|
||||
break;
|
||||
default:
|
||||
printf("pst: unknown command type 0x%02x\n", request->bp->bio_cmd);
|
||||
return -1;
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
msg->initiator_context = (u_int32_t)pst_done;
|
||||
msg->transaction_context = (u_int32_t)request;
|
||||
@ -296,7 +297,7 @@ pst_rw(struct pst_request *request)
|
||||
|
||||
if (!iop_create_sgl((struct i2o_basic_message *)msg, request->bp->bio_data,
|
||||
request->bp->bio_bcount, sgl_flag))
|
||||
return -1;
|
||||
return EIO;
|
||||
|
||||
request->psc->iop->reg->iqueue = request->mfa;
|
||||
|
||||
@ -309,6 +310,7 @@ static void
|
||||
pst_timeout(void *arg)
|
||||
{
|
||||
struct pst_request *request;
|
||||
int error;
|
||||
|
||||
request = arg;
|
||||
printf("pst: timeout mfa=0x%08x cmd=0x%02x\n",
|
||||
@ -321,9 +323,9 @@ pst_timeout(void *arg)
|
||||
request->psc->iop->outstanding--;
|
||||
return;
|
||||
}
|
||||
if (pst_rw(request)) {
|
||||
if ((error = pst_rw(request)) != 0) {
|
||||
iop_free_mfa(request->psc->iop, request->mfa);
|
||||
biofinish(request->bp, NULL, EIO);
|
||||
biofinish(request->bp, NULL, error);
|
||||
request->psc->iop->outstanding--;
|
||||
}
|
||||
}
|
||||
|
@ -439,9 +439,13 @@ twe_startio(struct twe_softc *sc)
|
||||
if (bp->bio_cmd == BIO_READ) {
|
||||
tr->tr_flags |= TWE_CMD_DATAIN;
|
||||
cmd->io.opcode = TWE_OP_READ;
|
||||
} else {
|
||||
} else if (bp->bio_cmd == BIO_WRITE) {
|
||||
tr->tr_flags |= TWE_CMD_DATAOUT;
|
||||
cmd->io.opcode = TWE_OP_WRITE;
|
||||
} else {
|
||||
twe_release_request(tr);
|
||||
biofinish(bp, NULL, EOPNOTSUPP);
|
||||
break;
|
||||
}
|
||||
|
||||
/* build a suitable I/O command (assumes 512-byte rounded transfers) */
|
||||
|
@ -549,6 +549,12 @@ vtblk_strategy(struct bio *bp)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((bp->bio_cmd != BIO_READ) && (bp->bio_cmd != BIO_WRITE) &&
|
||||
(bp->bio_cmd != BIO_FLUSH)) {
|
||||
vtblk_bio_done(sc, bp, EOPNOTSUPP);
|
||||
return;
|
||||
}
|
||||
|
||||
VTBLK_LOCK(sc);
|
||||
|
||||
if (sc->vtblk_flags & VTBLK_FLAG_DETACH) {
|
||||
|
@ -399,7 +399,9 @@ xbd_bio_command(struct xbd_softc *sc)
|
||||
panic("flush request, but no flush support available");
|
||||
break;
|
||||
default:
|
||||
panic("unknown bio command %d", bp->bio_cmd);
|
||||
biofinish(bp, NULL, EOPNOTSUPP);
|
||||
xbd_enqueue_cm(cm, XBD_Q_FREE);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (cm);
|
||||
|
Loading…
Reference in New Issue
Block a user