Index: sys/dev/scsipi/sd.c =================================================================== RCS file: /cvsroot/src/sys/dev/scsipi/sd.c,v retrieving revision 1.345 diff -p -u -r1.345 sd.c --- sys/dev/scsipi/sd.c 13 Apr 2025 14:01:00 -0000 1.345 +++ sys/dev/scsipi/sd.c 11 Oct 2025 13:00:41 -0000 @@ -1422,9 +1422,7 @@ sd_read_capacity(struct sd_softc *sd, in sd->params.lbppbe = 0; sd->params.lalba = 0; - - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd.opcode = READ_CAPACITY_10; + sd->flags &= ~SDF_LBPME; /* * Don't allocate data buffer on stack; @@ -1436,54 +1434,50 @@ sd_read_capacity(struct sd_softc *sd, in if (datap == NULL) return 0; - if (periph->periph_version >= 5) /* SPC-3 */ - goto rc16; - - /* - * If the command works, interpret the result as a 4 byte - * number of blocks - */ rv = 0; - memset(datap, 0, sizeof(datap->data)); - if (scsipi_command(periph, (void *)&cmd.cmd, sizeof(cmd.cmd), - (void *)datap, sizeof(datap->data), SCSIPIRETRIES, 20000, NULL, - flags | XS_CTL_DATA_IN | XS_CTL_SILENT) != 0) - goto out; - - if (_4btol(datap->data.addr) != 0xffffffff) { - *blksize = _4btol(datap->data.length); - rv = _4btol(datap->data.addr) + 1; - goto out; - } /* - * Device is larger than can be reflected by READ CAPACITY (10). - * Try READ CAPACITY (16). + * When device announces SPC-3 conformance, + * try READ CAPACITY (16) to collect information + * about physical blocks and management capabilities. + * + * Fall back to READ CAPACITY (10). */ - rc16: memset(&cmd, 0, sizeof(cmd)); cmd.cmd16.opcode = READ_CAPACITY_16; cmd.cmd16.byte2 = SRC16_SERVICE_ACTION; _lto4b(sizeof(datap->data16), cmd.cmd16.len); memset(datap, 0, sizeof(datap->data16)); - if (scsipi_command(periph, (void *)&cmd.cmd16, sizeof(cmd.cmd16), - (void *)datap, sizeof(datap->data16), SCSIPIRETRIES, 20000, NULL, - flags | XS_CTL_DATA_IN | XS_CTL_SILENT) != 0) - goto out; - - *blksize = _4btol(datap->data16.length); - rv = _8btol(datap->data16.addr) + 1; - sd->params.lbppbe = datap->data16.byte14 & SRC16D_LBPPB_EXPONENT; - sd->params.lalba = _2btol(datap->data16.lowest_aligned) & SRC16D_LALBA; - if (_2btol(datap->data16.lowest_aligned) & SRC16D_LBPME) { - sd->flags |= SDF_LBPME; + if (periph->periph_version >= 5 && + scsipi_command(periph, (void *)&cmd.cmd16, sizeof(cmd.cmd16), + (void *)datap, sizeof(datap->data16), SCSIPIRETRIES, 20000, + NULL, flags | XS_CTL_DATA_IN | XS_CTL_SILENT) == 0) { + + *blksize = _4btol(datap->data16.length); + rv = _8btol(datap->data16.addr) + 1; + + sd->params.lbppbe = datap->data16.byte14 + & SRC16D_LBPPB_EXPONENT; + sd->params.lalba = _2btol(datap->data16.lowest_aligned) + & SRC16D_LALBA; + if (_2btol(datap->data16.lowest_aligned) & SRC16D_LBPME) + sd->flags |= SDF_LBPME; } else { - sd->flags &= ~SDF_LBPME; + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd.opcode = READ_CAPACITY_10; + + memset(datap, 0, sizeof(datap->data)); + if (scsipi_command(periph, (void *)&cmd.cmd, sizeof(cmd.cmd), + (void *)datap, sizeof(datap->data), SCSIPIRETRIES, 20000, + NULL, flags | XS_CTL_DATA_IN | XS_CTL_SILENT) == 0) { + + *blksize = _4btol(datap->data.length); + rv = _4btol(datap->data.addr) + 1; + } } - out: free(datap, M_TEMP); return rv; } @@ -1577,7 +1571,7 @@ sd_get_capacity(struct sd_softc *sd, str error = scsipi_command(sd->sc_periph, (void *)&cmd, sizeof(cmd), (void *)&data, sizeof(data), SDRETRIES, 20000, NULL, - flags | XS_CTL_DATA_IN); + flags | XS_CTL_DATA_IN | XS_CTL_SILENT); if (error == EFTYPE) { /* Medium Format Corrupted, handle as not formatted */ return (SDGP_RESULT_UNFORMATTED);