From e1d9f9cea535d8545a3e405d1d358513f57837fc Mon Sep 17 00:00:00 2001 From: agc Date: Thu, 23 Mar 2006 00:01:48 +0000 Subject: [PATCH] First stab at implementing INQUIRY for Vital Product Data, aka Page 83 information in the Solaris initiator, with information taken from SPC3, T10/1416-D Revision 23, from www.t10.org. This is untested, work-in-progress. --- dist/iscsi/include/scsi_cmd_codes.h | 58 +++++++++++++++++++++++- dist/iscsi/src/disk.c | 68 ++++++++++++++++++----------- 2 files changed, 99 insertions(+), 27 deletions(-) diff --git a/dist/iscsi/include/scsi_cmd_codes.h b/dist/iscsi/include/scsi_cmd_codes.h index 2d302ae6aa4c..c6c288fa20f8 100644 --- a/dist/iscsi/include/scsi_cmd_codes.h +++ b/dist/iscsi/include/scsi_cmd_codes.h @@ -1,8 +1,41 @@ -/* taken from http://www.arkeia.com/resources/scsi_rsc.html */ +/* $NetBSD: scsi_cmd_codes.h,v 1.4 2006/03/23 00:01:48 agc Exp $ */ +/* + * Copyright © 2006 Alistair Crooks. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Alistair Crooks + * for the NetBSD project. + * 4. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef SCSI_CMD_CODES_H_ #define SCSI_CMD_CODES_H_ +/* information taken from SPC3, T10/1416-D Revision 23, from www.t10.org */ + enum { TEST_UNIT_READY = 0x00, WRITE_6 = 0x06, @@ -26,4 +59,27 @@ enum { #define ISCSI_MODE_SENSE_LEN 11 +/* miscellaneous definitions */ +enum { + DISK_PERIPHERAL_DEVICE = 0x0, + + INQUIRY_EVPD_BIT = 0x01, + + INQUIRY_DEVICE_IDENTIFICATION_VPD = 0x83, + INQUIRY_SUPPORTED_VPD_PAGES = 0x0, + + INQUIRY_DEVICE_ASSOCIATION_TARGET_PORT = 0x1, + INQUIRY_DEVICE_ASSOCIATION_TARGET_DEVICE = 0x2, + INQUIRY_DEVICE_CODESET_UTF8 = 0x3, + INQUIRY_DEVICE_ISCSI_PROTOCOL = 0x5, + INQUIRY_DEVICE_IDENTIFIER_SCSI_NAME = 0x8, + + WIDE_BUS_16 = 0x20, + WIDE_BUS_32 = 0x40, + + SCSI_VERSION_SPC = 0x03, + SCSI_VERSION_SPC2 = 0x04, + SCSI_VERSION_SPC3 = 0x05 +}; + #endif /* !SCSI_CMD_CODES_H_ */ diff --git a/dist/iscsi/src/disk.c b/dist/iscsi/src/disk.c index 29885f49fddb..5d3801f6e380 100644 --- a/dist/iscsi/src/disk.c +++ b/dist/iscsi/src/disk.c @@ -1,4 +1,4 @@ -/* $NetBSD: disk.c,v 1.9 2006/03/21 22:56:55 agc Exp $ */ +/* $NetBSD: disk.c,v 1.10 2006/03/23 00:01:48 agc Exp $ */ /* * Copyright © 2006 Alistair Crooks. All rights reserved. @@ -864,6 +864,7 @@ device_command(target_session_t * sess, target_cmd_t * cmd) uint8_t *cdb = args->cdb; uint8_t lun = (uint8_t) (args->lun >> 32); int mode_data_len; + int done; #if (CONFIG_DISK_INITIAL_CHECK_CONDITION==1) static int initialized = 0; @@ -891,7 +892,7 @@ device_command(target_session_t * sess, target_cmd_t * cmd) */ if (lun >= disks.v[sess->d].luns) { data = args->send_data; - memset(data, 0x0, (size_t) cdb[4]); + (void) memset(data, 0x0, (size_t) cdb[4]); /* * data[0] = 0x7F; * / no device @@ -914,28 +915,44 @@ device_command(target_session_t * sess, target_cmd_t * cmd) break; case INQUIRY: - iscsi_trace(TRACE_SCSI_CMD, "INQUIRY\n"); + iscsi_trace(TRACE_SCSI_CMD, "INQUIRY%s\n", (cdb[1] & INQUIRY_EVPD_BIT) ? " for Vital Product Data" : ""); data = args->send_data; (void) memset(data, 0x0, (unsigned) cdb[4]); /* Clear allocated buffer */ - data[0] = 0; /* Peripheral Device Type */ - /* data[1] |= 0x80; // Removable Bit */ - data[2] |= 0x02;/* ANSI-approved version */ - /* data[3] |= 0x80; // AENC */ - /* data[3] |= 0x40; // TrmIOP */ - /* data[3] |= 0x20; // NormACA */ - data[4] = cdb[4] - 4; /* Additional length */ - /* data[7] |= 0x80; // Relative addressing */ - data[7] |= 0x40;/* WBus32 */ - data[7] |= 0x20;/* WBus16 */ - /* data[7] |= 0x10; // Sync */ - /* data[7] |= 0x08; // Linked Commands */ - /* data[7] |= 0x04; // TransDis */ - /* data[7] |= 0x02; // Tagged Command Queueing */ - /* data[7] |= 0x01; // SftRe */ - (void) memset(data + 8, 0x0, 32); - (void) strlcpy((char *)&data[8], ISCSI_VENDOR, 8); /* Vendor */ - (void) strlcpy((char *)&data[16], ISCSI_PRODUCT, 16); /* Product ID */ - (void) snprintf((char *)&data[32], 8, "%d", ISCSI_VERSION); /* Product Revision */ + done = 0; + if (cdb[1] & INQUIRY_EVPD_BIT) { + switch(cdb[2]) { + case INQUIRY_DEVICE_IDENTIFICATION_VPD: + data[0] = DISK_PERIPHERAL_DEVICE; + data[1] = INQUIRY_DEVICE_IDENTIFICATION_VPD; + data[3] = cdb[4] - 7; + data[4] = (INQUIRY_DEVICE_ISCSI_PROTOCOL << 4) | INQUIRY_DEVICE_CODESET_UTF8; + data[5] = (INQUIRY_DEVICE_ASSOCIATION_TARGET_DEVICE << 4) | INQUIRY_DEVICE_IDENTIFIER_SCSI_NAME; + data[7] = snprintf((char *)&data[8], (unsigned) cdb[4] - 8, "%s", sess->globals->targetname); + done = 1; + break; + case INQUIRY_SUPPORTED_VPD_PAGES: + data[0] = DISK_PERIPHERAL_DEVICE; + data[1] = INQUIRY_SUPPORTED_VPD_PAGES; + data[3] = 2; + data[4] = INQUIRY_SUPPORTED_VPD_PAGES; + data[5] = INQUIRY_DEVICE_IDENTIFICATION_VPD; + done = 1; + break; + default: + iscsi_trace_error("Unsupported INQUIRY VPD page %x\n", cdb[2]); + break; + } + } + if (!done) { + data[0] = DISK_PERIPHERAL_DEVICE; + data[2] = SCSI_VERSION_SPC; + data[4] = cdb[4] - 4; /* Additional length */ + data[7] |= (WIDE_BUS_32 | WIDE_BUS_16); + (void) memset(data + 8, 0x0, 32); + (void) strlcpy((char *)&data[8], ISCSI_VENDOR, 8); /* Vendor */ + (void) strlcpy((char *)&data[16], ISCSI_PRODUCT, 16); /* Product ID */ + (void) snprintf((char *)&data[32], 8, "%d", ISCSI_VERSION); /* Product Revision */ + } args->input = 1; args->length = cdb[4] + 1; args->status = 0; @@ -962,8 +979,7 @@ device_command(target_session_t * sess, target_cmd_t * cmd) case WRITE_6: lba = ISCSI_NTOHL(*((uint32_t *) (void *)cdb)) & 0x001fffff; - len = cdb[4]; - if (!len) { + if ((len = cdb[4]) == 0) { len = 256; } iscsi_trace(TRACE_SCSI_CMD, "WRITE_6(lba %u, len %u blocks)\n", lba, len); @@ -978,9 +994,9 @@ device_command(target_session_t * sess, target_cmd_t * cmd) case READ_6: lba = ISCSI_NTOHL(*((uint32_t *) (void *)cdb)) & 0x001fffff; - len = cdb[4]; - if (!len) + if ((len = cdb[4]) == 0) { len = 256; + } iscsi_trace(TRACE_SCSI_CMD, "READ_6(lba %u, len %u blocks)\n", lba, len); if (disk_read(sess, args, lba, len, lun) != 0) { iscsi_trace_error("disk_read() failed\n");