diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2019-11-25 17:02:58 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2019-11-25 17:02:58 +0000 |
commit | a953a9c661f8233ff66d4438e89f2c37587b057d (patch) | |
tree | 2b36af4bbc32020b13c2336424fd491e0d592da3 /sys | |
parent | 05726ffdd317da21b9651c7f65e862e65fff315c (diff) |
Move struct scsi_read_cap_data and struct scsi_read_cap_data_16 to
scsi_all.h.
Add scsi_read_cap_10() and scsi_read_cap_16() functions to
scsi_base.c, i.e. move logic to do actual READ_CAPACITY commands out
of sd_read_cap() and sd_read_cap_16().
This will allow the READ_CAPACITY code to be reused by cd(4).
Return -1 for errors where the error code is just discarded, reducing
ENOMEM, ENXIO, EIO uses.
No intentional functional change.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/scsi/scsi_all.h | 31 | ||||
-rw-r--r-- | sys/scsi/scsi_base.c | 74 | ||||
-rw-r--r-- | sys/scsi/scsi_disk.h | 31 | ||||
-rw-r--r-- | sys/scsi/scsiconf.h | 5 | ||||
-rw-r--r-- | sys/scsi/sd.c | 88 |
5 files changed, 129 insertions, 100 deletions
diff --git a/sys/scsi/scsi_all.h b/sys/scsi/scsi_all.h index 7464ebe8f3e..cfd4170cf2b 100644 --- a/sys/scsi/scsi_all.h +++ b/sys/scsi/scsi_all.h @@ -1,4 +1,4 @@ -/* $OpenBSD: scsi_all.h,v 1.60 2019/09/27 23:07:42 krw Exp $ */ +/* $OpenBSD: scsi_all.h,v 1.61 2019/11/25 17:02:56 krw Exp $ */ /* $NetBSD: scsi_all.h,v 1.10 1996/09/12 01:57:17 thorpej Exp $ */ /* @@ -357,6 +357,35 @@ struct scsi_vpd_ata { u_int8_t identify[512]; }; +struct scsi_read_cap_data { + u_int8_t addr[4]; + u_int8_t length[4]; +}; + +struct scsi_read_cap_data_16 { + u_int8_t addr[8]; + u_int8_t length[4]; + u_int8_t p_type_prot; +#define RC16_PROT_EN 0x01 /* Protection type is 0 when 0 */ +#define RC16_PROT_P_TYPE 0x0e +#define RC16_P_TYPE_1 0x00 /* Protection type 1 */ +#define RC16_P_TYPE_2 0x02 /* Protection type 2 */ +#define RC16_P_TYPE_3 0x04 /* Protection type 3 */ +#define RC16_BASIS 0x30 /* Meaning of addr */ +#define RC16_BASIS_HIGH 0x00 /* highest LBA of zone */ +#define RC16_BASIS_LAST 0x10 /* last LBA on unit */ + u_int8_t logical_per_phys; /* Logical Blks Per Physical Blk Exp */ +#define RC16_LBPPB_EXPONENT 0x0f /* 2**N LB per PB, 0 means unknown */ +#define RC16_PIIPLB_EXPONENT 0xf0 /* 2**N Prot info intervals per LB */ + u_int8_t lowest_aligned[2]; +#define RC16_LALBA 0x3fff /* lowest aligned LBA */ +#define RC16_LBPRZ 0x4000 /* unmapped LBA returns all zeros */ +#define READ_CAP_16_TPRZ 0x4000 /* XXX old name used in driver(s) */ +#define RC16_LBPME 0x8000 /* LB provisioning management enabled */ +#define READ_CAP_16_TPE 0x8000 /* XXX old name used in driver(s) */ + u_int8_t reserved[16]; +}; + struct scsi_sense_data_unextended { /* 1*/ u_int8_t error_code; /* 4*/ u_int8_t block[3]; diff --git a/sys/scsi/scsi_base.c b/sys/scsi/scsi_base.c index 0e628f67026..6bc723ea526 100644 --- a/sys/scsi/scsi_base.c +++ b/sys/scsi/scsi_base.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scsi_base.c,v 1.243 2019/11/23 17:10:13 krw Exp $ */ +/* $OpenBSD: scsi_base.c,v 1.244 2019/11/25 17:02:56 krw Exp $ */ /* $NetBSD: scsi_base.c,v 1.43 1997/04/02 02:29:36 mycroft Exp $ */ /* @@ -918,6 +918,78 @@ scsi_inquire_vpd(struct scsi_link *link, void *buf, u_int buflen, return (error); } +int +scsi_read_cap_10(struct scsi_link *link, struct scsi_read_cap_data *rdcap, + int flags) +{ + struct scsi_read_capacity cdb; + struct scsi_xfer *xs; + int rv; + + xs = scsi_xs_get(link, flags | SCSI_DATA_IN | SCSI_SILENT); + if (xs == NULL) + return ENOMEM; + + memset(&cdb, 0, sizeof(cdb)); + cdb.opcode = READ_CAPACITY; + + memcpy(xs->cmd, &cdb, sizeof(cdb)); + xs->cmdlen = sizeof(cdb); + xs->data = (void *)rdcap; + xs->datalen = sizeof(*rdcap); + xs->timeout = 20000; + + rv = scsi_xs_sync(xs); + scsi_xs_put(xs); + +#ifdef SCSIDEBUG + if (rv == 0) { + sc_print_addr(link); + printf("read capacity 10 data:\n"); + scsi_show_mem((u_char *)rdcap, sizeof(*rdcap)); + } +#endif /* SCSIDEBUG */ + + return rv; +} + +int +scsi_read_cap_16(struct scsi_link *link, struct scsi_read_cap_data_16 *rdcap, + int flags) +{ + struct scsi_read_capacity_16 cdb; + struct scsi_xfer *xs; + int rv; + + xs = scsi_xs_get(link, flags | SCSI_DATA_IN | SCSI_SILENT); + if (xs == NULL) + return ENOMEM; + + memset(&cdb, 0, sizeof(cdb)); + cdb.opcode = READ_CAPACITY_16; + cdb.byte2 = SRC16_SERVICE_ACTION; + _lto4b(sizeof(*rdcap), cdb.length); + + memcpy(xs->cmd, &cdb, sizeof(cdb)); + xs->cmdlen = sizeof(cdb); + xs->data = (void *)rdcap; + xs->datalen = sizeof(*rdcap); + xs->timeout = 20000; + + rv = scsi_xs_sync(xs); + scsi_xs_put(xs); + +#ifdef SCSIDEBUG + if (rv == 0) { + sc_print_addr(link); + printf("read capacity 16 data:\n"); + scsi_show_mem((u_char *)rdcap, sizeof(*rdcap)); + } +#endif /* SCSIDEBUG */ + + return (rv); +} + /* * Prevent or allow the user to remove the media */ diff --git a/sys/scsi/scsi_disk.h b/sys/scsi/scsi_disk.h index 706217b3511..0f56fdd62d8 100644 --- a/sys/scsi/scsi_disk.h +++ b/sys/scsi/scsi_disk.h @@ -1,4 +1,4 @@ -/* $OpenBSD: scsi_disk.h,v 1.38 2019/09/27 23:07:42 krw Exp $ */ +/* $OpenBSD: scsi_disk.h,v 1.39 2019/11/25 17:02:57 krw Exp $ */ /* $NetBSD: scsi_disk.h,v 1.10 1996/07/05 16:19:05 christos Exp $ */ /* @@ -304,35 +304,6 @@ struct scsi_synchronize_cache { #define UNMAP 0x42 -struct scsi_read_cap_data { - u_int8_t addr[4]; - u_int8_t length[4]; -}; - -struct scsi_read_cap_data_16 { - u_int8_t addr[8]; - u_int8_t length[4]; - u_int8_t p_type_prot; -#define RC16_PROT_EN 0x01 /* Protection type is 0 when 0 */ -#define RC16_PROT_P_TYPE 0x0e -#define RC16_P_TYPE_1 0x00 /* Protection type 1 */ -#define RC16_P_TYPE_2 0x02 /* Protection type 2 */ -#define RC16_P_TYPE_3 0x04 /* Protection type 3 */ -#define RC16_BASIS 0x30 /* Meaning of addr */ -#define RC16_BASIS_HIGH 0x00 /* highest LBA of zone */ -#define RC16_BASIS_LAST 0x10 /* last LBA on unit */ - u_int8_t logical_per_phys; /* Logical Blks Per Physical Blk Exp */ -#define RC16_LBPPB_EXPONENT 0x0f /* 2**N LB per PB, 0 means unknown */ -#define RC16_PIIPLB_EXPONENT 0xf0 /* 2**N Prot info intervals per LB */ - u_int8_t lowest_aligned[2]; -#define RC16_LALBA 0x3fff /* lowest aligned LBA */ -#define RC16_LBPRZ 0x4000 /* unmapped LBA returns all zeros */ -#define READ_CAP_16_TPRZ 0x4000 /* XXX old name used in driver(s) */ -#define RC16_LBPME 0x8000 /* LB provisioning management enabled */ -#define READ_CAP_16_TPE 0x8000 /* XXX old name used in driver(s) */ - u_int8_t reserved[16]; -}; - struct scsi_reassign_blocks_data { u_int8_t reserved[2]; u_int8_t length[2]; diff --git a/sys/scsi/scsiconf.h b/sys/scsi/scsiconf.h index 189af7712fb..684539dc88f 100644 --- a/sys/scsi/scsiconf.h +++ b/sys/scsi/scsiconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: scsiconf.h,v 1.176 2019/09/27 23:07:42 krw Exp $ */ +/* $OpenBSD: scsiconf.h,v 1.177 2019/11/25 17:02:57 krw Exp $ */ /* $NetBSD: scsiconf.h,v 1.35 1997/04/02 02:29:38 mycroft Exp $ */ /* @@ -475,6 +475,9 @@ const void *scsi_inqmatch(struct scsi_inquiry_data *, const void *, int, void scsi_init(void); int scsi_test_unit_ready(struct scsi_link *, int, int); int scsi_inquire(struct scsi_link *, struct scsi_inquiry_data *, int); +int scsi_read_cap_10(struct scsi_link *, struct scsi_read_cap_data *, int); +int scsi_read_cap_16(struct scsi_link *, struct scsi_read_cap_data_16 *, + int); int scsi_inquire_vpd(struct scsi_link *, void *, u_int, u_int8_t, int); void scsi_init_inquiry(struct scsi_xfer *, u_int8_t, u_int8_t, void *, size_t); diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c index e9cd6600c26..870abfaa3b6 100644 --- a/sys/scsi/sd.c +++ b/sys/scsi/sd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sd.c,v 1.299 2019/11/23 17:10:13 krw Exp $ */ +/* $OpenBSD: sd.c,v 1.300 2019/11/25 17:02:57 krw Exp $ */ /* $NetBSD: sd.c,v 1.111 1997/04/02 02:29:41 mycroft Exp $ */ /*- @@ -1411,44 +1411,25 @@ viscpy(u_char *dst, u_char *src, int len) int sd_read_cap_10(struct sd_softc *sc, int flags) { - struct scsi_read_capacity cdb; - struct scsi_read_cap_data *rdcap; - struct scsi_xfer *xs; - int rv = ENOMEM; - - CLR(flags, SCSI_IGNORE_ILLEGAL_REQUEST); + struct scsi_read_cap_data *rdcap; + int rv; rdcap = dma_alloc(sizeof(*rdcap), (ISSET(flags, SCSI_NOSLEEP) ? PR_NOWAIT : PR_WAITOK) | PR_ZERO); if (rdcap == NULL) - return (ENOMEM); + return -1; if (ISSET(sc->flags, SDF_DYING)) { - rv = ENXIO; + rv = -1; goto done; } - xs = scsi_xs_get(sc->sc_link, flags | SCSI_DATA_IN | SCSI_SILENT); - if (xs == NULL) - goto done; - - bzero(&cdb, sizeof(cdb)); - cdb.opcode = READ_CAPACITY; - - memcpy(xs->cmd, &cdb, sizeof(cdb)); - xs->cmdlen = sizeof(cdb); - xs->data = (void *)rdcap; - xs->datalen = sizeof(*rdcap); - xs->timeout = 20000; - - rv = scsi_xs_sync(xs); - scsi_xs_put(xs); + rv = scsi_read_cap_10(sc->sc_link, rdcap, flags); if (rv == 0) { -#ifdef SCSIDEBUG - sc_print_addr(sc->sc_link); - printf("read capacity 10 data:\n"); - scsi_show_mem((u_char *)rdcap, sizeof(*rdcap)); -#endif /* SCSIDEBUG */ + if (_8btol(rdcap->addr) == 0) { + rv = -1; + goto done; + } sc->params.disksize = _4btol(rdcap->addr) + 1ll; sc->params.secsize = _4btol(rdcap->length); CLR(sc->flags, SDF_THIN); @@ -1456,58 +1437,32 @@ sd_read_cap_10(struct sd_softc *sc, int flags) done: dma_free(rdcap, sizeof(*rdcap)); - return (rv); + return rv; } int sd_read_cap_16(struct sd_softc *sc, int flags) { - struct scsi_read_capacity_16 cdb; - struct scsi_read_cap_data_16 *rdcap; - struct scsi_xfer *xs; - int rv = ENOMEM; - - CLR(flags, SCSI_IGNORE_ILLEGAL_REQUEST); + struct scsi_read_cap_data_16 *rdcap; + int rv; rdcap = dma_alloc(sizeof(*rdcap), (ISSET(flags, SCSI_NOSLEEP) ? PR_NOWAIT : PR_WAITOK) | PR_ZERO); if (rdcap == NULL) - return (ENOMEM); + return -1; if (ISSET(sc->flags, SDF_DYING)) { - rv = ENXIO; + rv = -1; goto done; } - xs = scsi_xs_get(sc->sc_link, flags | SCSI_DATA_IN | SCSI_SILENT); - if (xs == NULL) - goto done; - - bzero(&cdb, sizeof(cdb)); - cdb.opcode = READ_CAPACITY_16; - cdb.byte2 = SRC16_SERVICE_ACTION; - _lto4b(sizeof(*rdcap), cdb.length); - - memcpy(xs->cmd, &cdb, sizeof(cdb)); - xs->cmdlen = sizeof(cdb); - xs->data = (void *)rdcap; - xs->datalen = sizeof(*rdcap); - xs->timeout = 20000; - - rv = scsi_xs_sync(xs); - scsi_xs_put(xs); + rv = scsi_read_cap_16(sc->sc_link, rdcap, flags); if (rv == 0) { if (_8btol(rdcap->addr) == 0) { - rv = EIO; + rv = -1; goto done; } - -#ifdef SCSIDEBUG - sc_print_addr(sc->sc_link); - printf("read capacity 16 data:\n"); - scsi_show_mem((u_char *)rdcap, sizeof(*rdcap)); -#endif /* SCSIDEBUG */ - sc->params.disksize = _8btol(rdcap->addr) + 1; + sc->params.disksize = _8btol(rdcap->addr) + 1ll; sc->params.secsize = _4btol(rdcap->length); if (ISSET(_2btol(rdcap->lowest_aligned), READ_CAP_16_TPE)) SET(sc->flags, SDF_THIN); @@ -1517,7 +1472,7 @@ sd_read_cap_16(struct sd_softc *sc, int flags) done: dma_free(rdcap, sizeof(*rdcap)); - return (rv); + return rv; } int @@ -1525,8 +1480,7 @@ sd_read_cap(struct sd_softc *sc, int flags) { int rv; - if (ISSET(sc->flags, SDF_DYING)) - return (ENXIO); + CLR(flags, SCSI_IGNORE_ILLEGAL_REQUEST); /* * post-SPC2 (i.e. post-SCSI-3) devices can start with 16 byte @@ -1545,7 +1499,7 @@ sd_read_cap(struct sd_softc *sc, int flags) rv = sd_read_cap_16(sc, flags); } - return (rv); + return rv; } int |