summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2019-11-25 17:02:58 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2019-11-25 17:02:58 +0000
commita953a9c661f8233ff66d4438e89f2c37587b057d (patch)
tree2b36af4bbc32020b13c2336424fd491e0d592da3 /sys
parent05726ffdd317da21b9651c7f65e862e65fff315c (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.h31
-rw-r--r--sys/scsi/scsi_base.c74
-rw-r--r--sys/scsi/scsi_disk.h31
-rw-r--r--sys/scsi/scsiconf.h5
-rw-r--r--sys/scsi/sd.c88
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