6945584 COMSTAR support for REPORT IDENTIFYING INFORMATION
authorJohn Forte <John.Forte@Sun.COM>
Thu, 13 May 2010 17:30:30 -0700
changeset 12397 5bbdc06df473
parent 12396 7b7b6660fa3d
child 12398 d1a36c3701ab
6945584 COMSTAR support for REPORT IDENTIFYING INFORMATION
usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c
--- 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) {