--- sys/bus/cam/scsi/scsi_sa.c.orig +++ sys/bus/cam/scsi/scsi_sa.c @@ -752,7 +752,7 @@ */ if (((softc->blk_mask != ~0) && ((bp->b_bcount & softc->blk_mask) != 0)) || - ((softc->blk_mask == ~0) && + ((softc->blk_mask == ~0) && softc->min_blk > 0 && ((bp->b_bcount % softc->min_blk) != 0))) { xpt_print(periph->path, "Invalid request. Fixed block " "device requests must be a multiple of %d bytes\n", @@ -1958,7 +1958,7 @@ * blocksize on tape is and don't expect to really * read a full record. */ - rblim = kmalloc(8192, M_SCSISA, M_INTWAIT); + rblim = kmalloc(8192, M_SCSISA, M_INTWAIT | M_ZERO); if ((softc->quirks & SA_QUIRK_NODREAD) == 0) { scsi_sa_read_write(&ccb->csio, 0, sadone, @@ -2021,6 +2021,14 @@ } /* + * DF-5285: a device that reports minimum == 0 (or a failed + * READ BLOCK LIMITS) must not leave min_blk == 0 around: + * sastrategy()'s fixed-block validation divides by it. + */ + if (softc->min_blk == 0) { + softc->min_blk = 1; + } + /* * Next, perform a mode sense to determine * current density, blocksize, compression etc. */ @@ -2754,7 +2762,7 @@ softc = (struct sa_softc *)periph->softc; - ccomp = kmalloc(sizeof (sa_comp_t), M_SCSISA, M_INTWAIT); + ccomp = kmalloc(sizeof (sa_comp_t), M_SCSISA, M_INTWAIT | M_ZERO); /* * Since it doesn't make sense to set the number of blocks, or