Skip to contentSkip to conversation

Add VPD support to aacraid

PATCH In review Hannes Reinecke 2 participants 3 messages Jan 25, 2007

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Add VPD support to aacraid

Hi Mark,

I found to my surprise that the aacraid driver does not support VPD pages at all. I'm somewhat used to modern SCSI HBAs export SCSI-2 disks, but not supporting VPD pages at all is really a bit .. hmm .. SCSI-1-ish. And it makes it really impossible to assign a persistent device ID to those drives.

And it really made my eyes hurt. Now that I have the latest, top-of-the range SAS drives with a real HW RAID controller and the disks are exported as

SCSI-2.

Just as I thought we'd been finally past those days. Sigh.

Anyway, I don't think that it should be too hard to add proper VPD page support (ie page 0x83), but for that one would have some documentation how to ask the controller for it. I'll leave that to you :-) You can use the page 0x80 support as a template.

Cheers,

Hannes

Signature · 8 lines
Dr. Hannes Reinecke			[email protected]
SuSE Linux Products GmbH		S390 & zSeries
Maxfeldstraße 5				+49 911 74053 688
90409 Nürnberg				http://www.suse.de
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#1 lore raw
Quoted 8 lines · Hannes Reinecke

Hi Mark,

I found to my surprise that the aacraid driver does not support VPD pages at all. I'm somewhat used to modern SCSI HBAs export SCSI-2 disks, but not supporting VPD pages at all is really a bit .. hmm .. SCSI-1-ish. And it makes it really impossible to assign a persistent device ID to those drives.

[ .. ]

Quoted 6 lines

Anyway, I don't think that it should be too hard to add proper VPD page support (ie page 0x83), but for that one would have some documentation how to ask the controller for it. I'll leave that to you :-) You can use the page 0x80 support as a template.

And here is even the patch, based on scsi-misc.
Might help on reviewing.

Cheers,

Hannes

Signature · 4 lines
Dr. Hannes Reinecke			[email protected]
SuSE Linux Products GmbH		S390 & zSeries
Maxfeldstraße 5				+49 911 74053 688
90409 Nürnberg				http://www.suse.de
drivers/scsi/aacraid/aachba.c +61 -0
index 426cd6f..410a127 100644
@@ -666,6 +666,27 @@ static void setinqstr(struct aac_dev *de
 	inqstrcpy ("V1.0", str->prl);
 }
 
+/* Function: setinqserial
+ *
+ * Arguments: [1] pointer to void [1] int
+ *
+ * Purpose: Sets SCSI Unit Serial number.
+ *          This is a fake. We should read a proper
+ *          serial number from the container. But
+ *          without docs it's quite hard to do it :-)
+ *          So this will have to do in the meantime.
+ */
+
+static int setinqserial(struct aac_dev *dev, void *data, int cid)
+{
+	char *ep;
+
+	ep = (char *)(data);
+
+	return snprintf(ep, sizeof(struct scsi_inq) - 4, "%08X%02X",
+			le32_to_cpu(dev->adapter_info.serial[0]), cid);
+}
+
 static void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code,
 		      u8 a_sense_code, u8 incorrect_length,
 		      u8 bit_pointer, u16 field_pointer,
@@ -1580,6 +1601,46 @@ int aac_scsi_cmd(struct scsi_cmnd * scsi
 		dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scmd_id(scsicmd)));
 		memset(&inq_data, 0, sizeof (struct inquiry_data));
 
+		if (scsicmd->cmnd[1] & 0x1 ) {
+			char *arr = (char *)&inq_data;
+
+			/* EVPD bit set */
+			if (scmd_id(scsicmd) == host->this_id) {
+				arr[0] = INQD_PDT_PROC;
+			} else {
+				arr[0] = INQD_PDT_DA;
+			}
+			if (scsicmd->cmnd[2] == 0) {
+				int n;
+				/* supported vital product data pages */
+				arr[1] = scsicmd->cmnd[2];
+				n = 4;
+				arr[n++] = 0x0;;
+				arr[n++] = 0x80;
+				arr[3] = n - 4;
+				aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
+				scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
+			} else if (scsicmd->cmnd[2] == 0x80) {
+				/* unit serial number page */
+				arr[1] = scsicmd->cmnd[2];
+				arr[3] = setinqserial(dev, &arr[4], scmd_id(scsicmd));
+				aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
+				scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
+			} else {
+				/* vpd page not implemented */
+				scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
+				set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
+					  ILLEGAL_REQUEST,
+					  SENCODE_INVALID_CDB_FIELD,
+					  ASENCODE_NO_SENSE, 0, 7, 2, 0);
+				memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
+				       (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer))
+				       ? sizeof(scsicmd->sense_buffer)
+				       : sizeof(dev->fsa_dev[cid].sense_data));
+			}
+			scsicmd->scsi_done(scsicmd);
+			return 0;
+		}
 		inq_data.inqd_ver = 2;	/* claim compliance to SCSI-2 */
 		inq_data.inqd_rdf = 2;	/* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */
 		inq_data.inqd_len = 31;
#2 lore raw

On Thu, 25 Jan 2007 10:47:35 +0100 Hannes Reinecke wrote:

+/* Function: setinqserial
+ *
+ * Arguments: [1] pointer to void [1] int

Hi--
What does that notation mean? (I know, you copied it. :)

Parts of this source file use kernel-doc and parts don't. Would be nice to see it converted to all kernel-doc...

---
~Randy