1- /* $NetBSD: sd.c,v 1.345 2025/04/13 14:01:00 jakllsch Exp $ */
1+ /* $NetBSD: sd.c,v 1.346 2025/10/11 13:58:08 mlelstv Exp $ */
22
33/*-
44 * Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc.
4848 */
4949
5050#include <sys/cdefs.h>
51- __KERNEL_RCSID (0 , "$NetBSD: sd.c,v 1.345 2025/04/13 14:01:00 jakllsch Exp $" );
51+ __KERNEL_RCSID (0 , "$NetBSD: sd.c,v 1.346 2025/10/11 13:58:08 mlelstv Exp $" );
5252
5353#ifdef _KERNEL_OPT
5454#include "opt_scsi.h"
@@ -1422,9 +1422,7 @@ sd_read_capacity(struct sd_softc *sd, int *blksize, int flags)
14221422
14231423 sd -> params .lbppbe = 0 ;
14241424 sd -> params .lalba = 0 ;
1425-
1426- memset (& cmd , 0 , sizeof (cmd ));
1427- cmd .cmd .opcode = READ_CAPACITY_10 ;
1425+ sd -> flags &= ~SDF_LBPME ;
14281426
14291427 /*
14301428 * Don't allocate data buffer on stack;
@@ -1436,54 +1434,50 @@ sd_read_capacity(struct sd_softc *sd, int *blksize, int flags)
14361434 if (datap == NULL )
14371435 return 0 ;
14381436
1439- if (periph -> periph_version >= 5 ) /* SPC-3 */
1440- goto rc16 ;
1441-
1442- /*
1443- * If the command works, interpret the result as a 4 byte
1444- * number of blocks
1445- */
14461437 rv = 0 ;
1447- memset (datap , 0 , sizeof (datap -> data ));
1448- if (scsipi_command (periph , (void * )& cmd .cmd , sizeof (cmd .cmd ),
1449- (void * )datap , sizeof (datap -> data ), SCSIPIRETRIES , 20000 , NULL ,
1450- flags | XS_CTL_DATA_IN | XS_CTL_SILENT ) != 0 )
1451- goto out ;
1452-
1453- if (_4btol (datap -> data .addr ) != 0xffffffff ) {
1454- * blksize = _4btol (datap -> data .length );
1455- rv = _4btol (datap -> data .addr ) + 1 ;
1456- goto out ;
1457- }
14581438
14591439 /*
1460- * Device is larger than can be reflected by READ CAPACITY (10).
1461- * Try READ CAPACITY (16).
1440+ * When device announces SPC-3 conformance,
1441+ * try READ CAPACITY (16) to collect information
1442+ * about physical blocks and management capabilities.
1443+ *
1444+ * Fall back to READ CAPACITY (10).
14621445 */
14631446
1464- rc16 :
14651447 memset (& cmd , 0 , sizeof (cmd ));
14661448 cmd .cmd16 .opcode = READ_CAPACITY_16 ;
14671449 cmd .cmd16 .byte2 = SRC16_SERVICE_ACTION ;
14681450 _lto4b (sizeof (datap -> data16 ), cmd .cmd16 .len );
14691451
14701452 memset (datap , 0 , sizeof (datap -> data16 ));
1471- if (scsipi_command (periph , (void * )& cmd .cmd16 , sizeof (cmd .cmd16 ),
1472- (void * )datap , sizeof (datap -> data16 ), SCSIPIRETRIES , 20000 , NULL ,
1473- flags | XS_CTL_DATA_IN | XS_CTL_SILENT ) != 0 )
1474- goto out ;
1475-
1476- * blksize = _4btol (datap -> data16 .length );
1477- rv = _8btol (datap -> data16 .addr ) + 1 ;
1478- sd -> params .lbppbe = datap -> data16 .byte14 & SRC16D_LBPPB_EXPONENT ;
1479- sd -> params .lalba = _2btol (datap -> data16 .lowest_aligned ) & SRC16D_LALBA ;
1480- if (_2btol (datap -> data16 .lowest_aligned ) & SRC16D_LBPME ) {
1481- sd -> flags |= SDF_LBPME ;
1453+ if (periph -> periph_version >= 5 &&
1454+ scsipi_command (periph , (void * )& cmd .cmd16 , sizeof (cmd .cmd16 ),
1455+ (void * )datap , sizeof (datap -> data16 ), SCSIPIRETRIES , 20000 ,
1456+ NULL , flags | XS_CTL_DATA_IN | XS_CTL_SILENT ) == 0 ) {
1457+
1458+ * blksize = _4btol (datap -> data16 .length );
1459+ rv = _8btol (datap -> data16 .addr ) + 1 ;
1460+
1461+ sd -> params .lbppbe = datap -> data16 .byte14
1462+ & SRC16D_LBPPB_EXPONENT ;
1463+ sd -> params .lalba = _2btol (datap -> data16 .lowest_aligned )
1464+ & SRC16D_LALBA ;
1465+ if (_2btol (datap -> data16 .lowest_aligned ) & SRC16D_LBPME )
1466+ sd -> flags |= SDF_LBPME ;
14821467 } else {
1483- sd -> flags &= ~SDF_LBPME ;
1468+ memset (& cmd , 0 , sizeof (cmd ));
1469+ cmd .cmd .opcode = READ_CAPACITY_10 ;
1470+
1471+ memset (datap , 0 , sizeof (datap -> data ));
1472+ if (scsipi_command (periph , (void * )& cmd .cmd , sizeof (cmd .cmd ),
1473+ (void * )datap , sizeof (datap -> data ), SCSIPIRETRIES , 20000 ,
1474+ NULL , flags | XS_CTL_DATA_IN | XS_CTL_SILENT ) == 0 ) {
1475+
1476+ * blksize = _4btol (datap -> data .length );
1477+ rv = _4btol (datap -> data .addr ) + 1 ;
1478+ }
14841479 }
14851480
1486- out :
14871481 free (datap , M_TEMP );
14881482 return rv ;
14891483}
0 commit comments