Subject: Re: kern/28514: READ_FORMAT_CAPACITIES reply has 32-bit block count
To: None <jpk@panix.com>
From: Jason Thorpe <thorpej@shagadelic.org>
List: netbsd-bugs
Date: 12/02/2004 21:11:09
--Apple-Mail-24--810581729
Content-Type: multipart/mixed; boundary=Apple-Mail-23--810581759
--Apple-Mail-23--810581759
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
format=flowed
On Dec 2, 2004, at 1:21 PM, jpk@panix.com wrote:
> thorej suggested:
> It might require our sd driver to issue a different command to read the
> capacity, because the READ_FORMAT_CAPACITIES reply only has a 32-bit
> block count.
Can you please try the following patch?
-- Jason R. Thorpe <thorpej@shagadelic.org>
--Apple-Mail-23--810581759
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
x-unix-mode=0644;
name="src16-patch.txt"
Content-Disposition: attachment;
filename=src16-patch.txt
Index: scsipi_base.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/scsipi_base.c,v
retrieving revision 1.121
diff -c -p -r1.121 scsipi_base.c
*** scsipi_base.c 1 Oct 2004 03:39:11 -0000 1.121
--- scsipi_base.c 3 Dec 2004 05:09:47 -0000
*************** scsipi_interpret_sense(struct scsipi_xfe
*** 1026,1047 ****
u_int64_t
scsipi_size(struct scsipi_periph *periph, int flags)
{
! struct scsipi_read_capacity cmd;
! struct scsipi_read_cap_data data;
memset(&cmd, 0, sizeof(cmd));
! cmd.opcode = READ_CAPACITY;
/*
* If the command works, interpret the result as a 4 byte
* number of blocks
*/
! if (scsipi_command(periph, (void *)&cmd, sizeof(cmd),
! (void *)&data, sizeof(data), SCSIPIRETRIES, 20000, NULL,
flags | XS_CTL_DATA_IN | XS_CTL_DATA_ONSTACK | XS_CTL_SILENT) != 0)
return (0);
! return (_4btol(data.addr) + 1);
}
/*
--- 1026,1072 ----
u_int64_t
scsipi_size(struct scsipi_periph *periph, int flags)
{
! union {
! struct scsipi_read_capacity cmd;
! struct scsipi_read_capacity_16 cmd16;
! } cmd;
! union {
! struct scsipi_read_cap_data data;
! struct scsipi_read_capacity_16_data data16;
! } data;
memset(&cmd, 0, sizeof(cmd));
! cmd.cmd.opcode = READ_CAPACITY;
/*
* If the command works, interpret the result as a 4 byte
* number of blocks
*/
! if (scsipi_command(periph, (void *)&cmd.cmd, sizeof(cmd.cmd),
! (void *)&data.data, sizeof(data.data), SCSIPIRETRIES, 20000, NULL,
flags | XS_CTL_DATA_IN | XS_CTL_DATA_ONSTACK | XS_CTL_SILENT) != 0)
return (0);
! if (_4btol(data.data.addr) != 0xffffffff)
! return (_4btol(data.data.addr) + 1);
!
! /*
! * Device is larger than can be reflected by READ CAPACITY (10).
! * Try READ CAPACITY (16).
! */
!
! memset(&cmd, 0, sizeof(cmd));
! cmd.cmd16.opcode = READ_CAPACITY_16;
! cmd.cmd16.byte2 = SRC16_SERVICE_ACTION;
! _lto4b(sizeof(data.data16), cmd.cmd16.len);
!
! if (scsipi_command(periph, (void *)&cmd.cmd16, sizeof(cmd.cmd16),
! (void *)&data.data16, sizeof(data.data16), SCSIPIRETRIES, 20000,
! NULL,
! flags | XS_CTL_DATA_IN | XS_CTL_DATA_ONSTACK | XS_CTL_SILENT) != 0)
! return (0);
!
! return (_8btol(data.data16.addr) + 1);
}
/*
Index: scsipi_disk.h
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/scsipi_disk.h,v
retrieving revision 1.9
diff -c -p -r1.9 scsipi_disk.h
*** scsipi_disk.h 17 Sep 2003 23:33:43 -0000 1.9
--- scsipi_disk.h 3 Dec 2004 05:09:47 -0000
*************** struct scsipi_read_cap_data {
*** 86,91 ****
--- 86,113 ----
u_int8_t length[4];
} __attribute__((packed));
+ #define READ_CAPACITY_16 0x9e /* really SERVICE ACTION IN */
+ struct scsipi_read_capacity_16 {
+ u_int8_t opcode;
+ u_int8_t byte2;
+ #define SRC16_SERVICE_ACTION 0x10
+ u_int8_t addr[8];
+ u_int8_t len[4];
+ u_int8_t byte15;
+ #define SRC16_PMI 0x01
+ u_int8_t control;
+ };
+
+ struct scsipi_read_capacity_16_data {
+ u_int8_t addr[8];
+ u_int8_t length[4];
+ u_int8_t byte13;
+ #define SRC16D_PROT_EN 0x01
+ #define SRC16D_RTO_EN 0x02
+ u_int8_t reserved[19];
+ };
+
+ /* XXX SBC-2 says this is vendor-specific */
#define READ_FORMAT_CAPACITIES 0x23
struct scsipi_read_format_capacities {
u_int8_t opcode;
Index: scsipiconf.h
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/scsipiconf.h,v
retrieving revision 1.90
diff -c -p -r1.90 scsipiconf.h
*** scsipiconf.h 17 Sep 2004 23:43:17 -0000 1.90
--- scsipiconf.h 3 Dec 2004 05:09:48 -0000
*************** _5btol(const u_int8_t *bytes)
*** 773,778 ****
--- 773,794 ----
return (rv);
}
+ static __inline u_int64_t __unused
+ _8btol(const u_int8_t *bytes)
+ {
+ u_int64_t rv;
+
+ rv = ((u_int64_t)bytes[0] << 56) |
+ ((u_int64_t)bytes[1] << 48) |
+ ((u_int64_t)bytes[2] << 40) |
+ ((u_int64_t)bytes[3] << 32) |
+ ((u_int64_t)bytes[4] << 24) |
+ ((u_int64_t)bytes[5] << 16) |
+ ((u_int64_t)bytes[6] << 8) |
+ (u_int64_t)bytes[7];
+ return (rv);
+ }
+
static __inline void __unused
_lto2l(u_int32_t val, u_int8_t *bytes)
{
--Apple-Mail-23--810581759--
--Apple-Mail-24--810581729
content-type: application/pgp-signature; x-mac-type=70674453;
name=PGP.sig
content-description: This is a digitally signed message part
content-disposition: inline; filename=PGP.sig
content-transfer-encoding: 7bit
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (Darwin)
iD8DBQFBr/VuOpVKkaBm8XkRAmTbAKCpEW25nFe2gg8jC5H/dfafSQie2QCdF6my
ZZv5Ney8OXLnCKzGoF+HgyA=
=qb9+
-----END PGP SIGNATURE-----
--Apple-Mail-24--810581729--