summaryrefslogtreecommitdiffstats
path: root/sys/scsi/scsi_base.c
diff options
context:
space:
mode:
authorkrw <krw@openbsd.org>2019-11-25 17:02:56 +0000
committerkrw <krw@openbsd.org>2019-11-25 17:02:56 +0000
commit8568049220a4b82ecc1b469c8c63f615e467cbe1 (patch)
treef3fbad8f4fdf42321c74743764721a900152929a /sys/scsi/scsi_base.c
parentAdd p format modifier for padding to width. (diff)
downloadwireguard-openbsd-8568049220a4b82ecc1b469c8c63f615e467cbe1.tar.xz
wireguard-openbsd-8568049220a4b82ecc1b469c8c63f615e467cbe1.zip
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/scsi/scsi_base.c')
-rw-r--r--sys/scsi/scsi_base.c74
1 files changed, 73 insertions, 1 deletions
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
*/