diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2010-07-02 23:57:47 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2010-07-02 23:57:47 +0000 |
commit | 9a8d40687e7af387d894c2b4fa066cb61ddc6bef (patch) | |
tree | eed72445a626fbcbb102c60d3e6793409da26306 /sys | |
parent | 597d8df7a74a0278a147433e716390cddbef765f (diff) |
Always try READ CAPACITY(16) on SCSI-3 devices. If it fails, return
the READ CAPACITY(10) values already retrieved. Creates the possibility
to look at other interesting READ CAPACITY(16) data for future
consideration.
ok matthew@ marco@ deraadt@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/scsi/scsi_base.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/sys/scsi/scsi_base.c b/sys/scsi/scsi_base.c index 0bbe0a8b931..7dec43e0cf0 100644 --- a/sys/scsi/scsi_base.c +++ b/sys/scsi/scsi_base.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scsi_base.c,v 1.180 2010/07/02 00:04:11 krw Exp $ */ +/* $OpenBSD: scsi_base.c,v 1.181 2010/07/02 23:57:46 krw Exp $ */ /* $NetBSD: scsi_base.c,v 1.43 1997/04/02 02:29:36 mycroft Exp $ */ /* @@ -637,18 +637,14 @@ scsi_size(struct scsi_link *sc_link, int flags, u_int32_t *blksize) *blksize = 0; /* - * make up a scsi command and ask the scsi driver to do it for you. + * Start with a READ CAPACITY(10). */ bzero(&rc, sizeof(rc)); bzero(&rdcap, sizeof(rdcap)); rc.opcode = READ_CAPACITY; - /* - * If the command works, interpret the result as a 4 byte - * number of blocks - */ - rdcap = malloc(sizeof(*rdcap), M_TEMP, ((flags & SCSI_NOSLEEP) ? M_NOWAIT : - M_WAITOK) | M_ZERO); + rdcap = malloc(sizeof(*rdcap), M_TEMP, ((flags & SCSI_NOSLEEP) ? + M_NOWAIT : M_WAITOK) | M_ZERO); if (rdcap == NULL) return (0); error = scsi_scsi_cmd(sc_link, (struct scsi_generic *)&rc, sizeof(rc), @@ -666,11 +662,12 @@ scsi_size(struct scsi_link *sc_link, int flags, u_int32_t *blksize) *blksize = _4btol(rdcap->length); free(rdcap, M_TEMP); - if (max_addr != 0xffffffff) - return (max_addr + 1); + if (SCSISPC(sc_link->inqdata.version) < 3 && max_addr != 0xffffffff) + goto exit; /* - * The device has more than 2^32-1 sectors. Use 16-byte READ CAPACITY. + * SCSI-3 devices, or devices reporting more than 2^32-1 sectors can try + * READ CAPACITY(16). */ bzero(&rc16, sizeof(rc16)); bzero(&rdcap16, sizeof(rdcap16)); @@ -681,7 +678,7 @@ scsi_size(struct scsi_link *sc_link, int flags, u_int32_t *blksize) rdcap16 = malloc(sizeof(*rdcap16), M_TEMP, ((flags & SCSI_NOSLEEP) ? M_NOWAIT : M_WAITOK) | M_ZERO); if (rdcap16 == NULL) - return (0); + goto exit; error = scsi_scsi_cmd(sc_link, (struct scsi_generic *)&rc16, sizeof(rc16), (u_char *)rdcap16, sizeof(*rdcap16), SCSI_RETRIES, 20000, NULL, flags | SCSI_DATA_IN); @@ -689,15 +686,24 @@ scsi_size(struct scsi_link *sc_link, int flags, u_int32_t *blksize) SC_DEBUG(sc_link, SDEV_DB1, ("READ CAPACITY 16 error (%#x)\n", error)); free(rdcap16, M_TEMP); - return (0); + goto exit; } max_addr = _8btol(rdcap16->addr); if (blksize != NULL) *blksize = _4btol(rdcap16->length); + /* XXX The other READ CAPACITY(16) info could be stored away somewhere. */ free(rdcap16, M_TEMP); return (max_addr + 1); + +exit: + /* Return READ CAPACITY 10 values. */ + if (max_addr != 0xffffffff) + return (max_addr + 1); + else if (blksize != NULL) + *blksize = 0; + return (0); } /* |