--- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c Thu May 13 11:41:40 2010 -0400
+++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c Thu May 13 17:30:30 2010 -0700
@@ -95,6 +95,7 @@
void sbd_handle_mode_select_xfer(scsi_task_t *task, uint8_t *buf,
uint32_t buflen);
void sbd_handle_mode_select(scsi_task_t *task, stmf_data_buf_t *dbuf);
+void sbd_handle_identifying_info(scsi_task_t *task, stmf_data_buf_t *dbuf);
extern void sbd_pgr_initialize_it(scsi_task_t *, sbd_it_data_t *);
extern int sbd_pgr_reservation_conflict(scsi_task_t *);
@@ -2111,6 +2112,73 @@
}
/*
+ * Command support added from SPC-4 r24
+ * Supports info type 0, 2, 127
+ */
+void
+sbd_handle_identifying_info(struct scsi_task *task,
+ stmf_data_buf_t *initial_dbuf)
+{
+ sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
+ uint8_t *cdb;
+ uint32_t cmd_size;
+ uint32_t param_len;
+ uint32_t xfer_size;
+ uint8_t info_type;
+ uint8_t *buf, *p;
+
+ cdb = &task->task_cdb[0];
+ cmd_size = READ_SCSI32(&cdb[6], uint32_t);
+ info_type = cdb[10]>>1;
+
+ /* Validate the command */
+ if (cmd_size < 4) {
+ stmf_scsilib_send_status(task, STATUS_CHECK,
+ STMF_SAA_INVALID_FIELD_IN_CDB);
+ return;
+ }
+
+ p = buf = kmem_zalloc(260, KM_SLEEP);
+
+ switch (info_type) {
+ case 0:
+ /*
+ * No value is supplied but this info type
+ * is mandatory.
+ */
+ xfer_size = 4;
+ break;
+ case 2:
+ mutex_enter(&sl->sl_lock);
+ param_len = strlcpy((char *)(p+4), sl->sl_alias, 256);
+ mutex_exit(&sl->sl_lock);
+ /* text info must be null terminated */
+ if (++param_len > 256)
+ param_len = 256;
+ SCSI_WRITE16(p+2, param_len);
+ xfer_size = param_len + 4;
+ break;
+ case 127:
+ /* 0 and 2 descriptor supported */
+ SCSI_WRITE16(p+2, 8); /* set param length */
+ p += 8;
+ *p = 4; /* set type to 2 (7 hi bits) */
+ p += 2;
+ SCSI_WRITE16(p, 256); /* 256 max length */
+ xfer_size = 12;
+ break;
+ default:
+ stmf_scsilib_send_status(task, STATUS_CHECK,
+ STMF_SAA_INVALID_FIELD_IN_CDB);
+ kmem_free(buf, 260);
+ return;
+ }
+ sbd_handle_short_read_transfers(task, initial_dbuf, buf,
+ cmd_size, xfer_size);
+ kmem_free(buf, 260);
+}
+
+/*
* This function parse through a string, passed to it as a pointer to a string,
* by adjusting the pointer to the first non-space character and returns
* the count/length of the first bunch of non-space characters. Multiple
@@ -2664,6 +2732,8 @@
!(cdb0 == SCMD_SVC_ACTION_IN_G4 &&
cdb1 == SSVC_ACTION_READ_CAPACITY_G4) &&
!(cdb0 == SCMD_MAINTENANCE_IN &&
+ (cdb1 & 0x1F) == 0x05) &&
+ !(cdb0 == SCMD_MAINTENANCE_IN &&
(cdb1 & 0x1F) == 0x0A)) {
stmf_scsilib_send_status(task, STATUS_CHECK,
STMF_SAA_LU_NO_ACCESS_STANDBY);
@@ -2800,6 +2870,13 @@
return;
}
+ /* Report Identifying Information */
+ if ((cdb0 == SCMD_MAINTENANCE_IN) &&
+ ((cdb1 & 0x1F) == 0x05)) {
+ sbd_handle_identifying_info(task, initial_dbuf);
+ return;
+ }
+
if (cdb0 == SCMD_START_STOP) { /* Start stop */
task->task_cmd_xfer_length = 0;
if (task->task_cdb[4] & 0xFC) {