And thus spake SBC-3:
If the number of logical blocks exceeds the maximum value that is able to be specified in the RETURNED LOGICAL BLOCK ADDRESS field, the device server shall set the RETURNED LOGICAL BLOCK ADDRESS field to FFFFFFFFh. The application client should then issue a READ CAPACITY (16) command (see 5.11) to retrieve the READ CAPACITY (16) parameter data. Implement this in scsipi_size(). First issue in kern/28514.
This commit is contained in:
parent
c89e858b2a
commit
e112950229
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: scsipi_base.c,v 1.121 2004/10/01 03:39:11 enami Exp $ */
|
||||
/* $NetBSD: scsipi_base.c,v 1.122 2004/12/03 20:20:32 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999, 2000, 2002, 2003, 2004 The NetBSD Foundation, Inc.
|
||||
|
@ -38,7 +38,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: scsipi_base.c,v 1.121 2004/10/01 03:39:11 enami Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: scsipi_base.c,v 1.122 2004/12/03 20:20:32 thorpej Exp $");
|
||||
|
||||
#include "opt_scsi.h"
|
||||
|
||||
|
@ -1026,22 +1026,47 @@ scsipi_interpret_sense(struct scsipi_xfer *xs)
|
|||
u_int64_t
|
||||
scsipi_size(struct scsipi_periph *periph, int flags)
|
||||
{
|
||||
struct scsipi_read_capacity cmd;
|
||||
struct scsipi_read_cap_data data;
|
||||
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.opcode = READ_CAPACITY;
|
||||
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,
|
||||
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);
|
||||
|
||||
return (_4btol(data.addr) + 1);
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: scsipi_disk.h,v 1.9 2003/09/17 23:33:43 mycroft Exp $ */
|
||||
/* $NetBSD: scsipi_disk.h,v 1.10 2004/12/03 20:20:32 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* SCSI and SCSI-like interfaces description
|
||||
|
@ -86,6 +86,28 @@ struct scsipi_read_cap_data {
|
|||
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;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: scsipiconf.h,v 1.90 2004/09/17 23:43:17 mycroft Exp $ */
|
||||
/* $NetBSD: scsipiconf.h,v 1.91 2004/12/03 20:20:32 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999, 2000, 2004 The NetBSD Foundation, Inc.
|
||||
|
@ -773,6 +773,22 @@ _5btol(const u_int8_t *bytes)
|
|||
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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue