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.
This commit is contained in:
agc 2006-03-23 00:01:48 +00:00
parent 504a2dd02c
commit e1d9f9cea5
2 changed files with 99 additions and 27 deletions

View File

@ -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_ */

68
dist/iscsi/src/disk.c vendored
View File

@ -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");