aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>2015-03-26 10:41:26 -0400
committerJames Bottomley <JBottomley@Odin.com>2015-04-09 19:51:29 -0400
commit5d9106490c7f7533abc6b8e15ceab64f2c7f466a (patch)
tree32b532066ae0d6111f4d6b6187bda57b86c8aeaa
parent495c021767bd78c998a46cf8cdd7a4ebf3a9cfd1 (diff)
aacraid: vpd page code 0x83 support
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Murthy Bhat <Murthy.Bhat@pmcs.com> Signed-off-by: James Bottomley <JBottomley@Odin.com>
-rw-r--r--drivers/scsi/aacraid/aachba.c165
1 files changed, 153 insertions, 12 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index aee3eaa0bd5d..09027e9edfd5 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -163,6 +163,48 @@ struct inquiry_data {
163 u8 inqd_prl[4]; /* Product Revision Level */ 163 u8 inqd_prl[4]; /* Product Revision Level */
164}; 164};
165 165
166/* Added for VPD 0x83 */
167typedef struct {
168 u8 CodeSet:4; /* VPD_CODE_SET */
169 u8 Reserved:4;
170 u8 IdentifierType:4; /* VPD_IDENTIFIER_TYPE */
171 u8 Reserved2:4;
172 u8 Reserved3;
173 u8 IdentifierLength;
174 u8 VendId[8];
175 u8 ProductId[16];
176 u8 SerialNumber[8]; /* SN in ASCII */
177
178} TVPD_ID_Descriptor_Type_1;
179
180typedef struct {
181 u8 CodeSet:4; /* VPD_CODE_SET */
182 u8 Reserved:4;
183 u8 IdentifierType:4; /* VPD_IDENTIFIER_TYPE */
184 u8 Reserved2:4;
185 u8 Reserved3;
186 u8 IdentifierLength;
187 struct TEU64Id {
188 u32 Serial;
189 /* The serial number supposed to be 40 bits,
190 * bit we only support 32, so make the last byte zero. */
191 u8 Reserved;
192 u8 VendId[3];
193 } EU64Id;
194
195} TVPD_ID_Descriptor_Type_2;
196
197typedef struct {
198 u8 DeviceType:5;
199 u8 DeviceTypeQualifier:3;
200 u8 PageCode;
201 u8 Reserved;
202 u8 PageLength;
203 TVPD_ID_Descriptor_Type_1 IdDescriptorType1;
204 TVPD_ID_Descriptor_Type_2 IdDescriptorType2;
205
206} TVPD_Page83;
207
166/* 208/*
167 * M O D U L E G L O B A L S 209 * M O D U L E G L O B A L S
168 */ 210 */
@@ -890,14 +932,88 @@ static void get_container_serial_callback(void *context, struct fib * fibptr)
890 get_serial_reply = (struct aac_get_serial_resp *) fib_data(fibptr); 932 get_serial_reply = (struct aac_get_serial_resp *) fib_data(fibptr);
891 /* Failure is irrelevant, using default value instead */ 933 /* Failure is irrelevant, using default value instead */
892 if (le32_to_cpu(get_serial_reply->status) == CT_OK) { 934 if (le32_to_cpu(get_serial_reply->status) == CT_OK) {
893 char sp[13]; 935 /*Check to see if it's for VPD 0x83 or 0x80 */
894 /* EVPD bit set */ 936 if (scsicmd->cmnd[2] == 0x83) {
895 sp[0] = INQD_PDT_DA; 937 /* vpd page 0x83 - Device Identification Page */
896 sp[1] = scsicmd->cmnd[2]; 938 int i;
897 sp[2] = 0; 939 TVPD_Page83 VPDPage83Data;
898 sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X", 940
899 le32_to_cpu(get_serial_reply->uid)); 941 memset(((u8 *)&VPDPage83Data), 0,
900 scsi_sg_copy_from_buffer(scsicmd, sp, sizeof(sp)); 942 sizeof(VPDPage83Data));
943
944 /* DIRECT_ACCESS_DEVIC */
945 VPDPage83Data.DeviceType = 0;
946 /* DEVICE_CONNECTED */
947 VPDPage83Data.DeviceTypeQualifier = 0;
948 /* VPD_DEVICE_IDENTIFIERS */
949 VPDPage83Data.PageCode = 0x83;
950 VPDPage83Data.Reserved = 0;
951 VPDPage83Data.PageLength =
952 sizeof(VPDPage83Data.IdDescriptorType1) +
953 sizeof(VPDPage83Data.IdDescriptorType2);
954
955 /* T10 Vendor Identifier Field Format */
956 /* VpdCodeSetAscii */
957 VPDPage83Data.IdDescriptorType1.CodeSet = 2;
958 /* VpdIdentifierTypeVendorId */
959 VPDPage83Data.IdDescriptorType1.IdentifierType = 1;
960 VPDPage83Data.IdDescriptorType1.IdentifierLength =
961 sizeof(VPDPage83Data.IdDescriptorType1) - 4;
962
963 /* "ADAPTEC " for adaptec */
964 memcpy(VPDPage83Data.IdDescriptorType1.VendId,
965 "ADAPTEC ",
966 sizeof(VPDPage83Data.IdDescriptorType1.VendId));
967 memcpy(VPDPage83Data.IdDescriptorType1.ProductId,
968 "ARRAY ",
969 sizeof(
970 VPDPage83Data.IdDescriptorType1.ProductId));
971
972 /* Convert to ascii based serial number.
973 * The LSB is the the end.
974 */
975 for (i = 0; i < 8; i++) {
976 u8 temp =
977 (u8)((get_serial_reply->uid >> ((7 - i) * 4)) & 0xF);
978 if (temp > 0x9) {
979 VPDPage83Data.IdDescriptorType1.SerialNumber[i] =
980 'A' + (temp - 0xA);
981 } else {
982 VPDPage83Data.IdDescriptorType1.SerialNumber[i] =
983 '0' + temp;
984 }
985 }
986
987 /* VpdCodeSetBinary */
988 VPDPage83Data.IdDescriptorType2.CodeSet = 1;
989 /* VpdIdentifierTypeEUI64 */
990 VPDPage83Data.IdDescriptorType2.IdentifierType = 2;
991 VPDPage83Data.IdDescriptorType2.IdentifierLength =
992 sizeof(VPDPage83Data.IdDescriptorType2) - 4;
993
994 VPDPage83Data.IdDescriptorType2.EU64Id.VendId[0] = 0xD0;
995 VPDPage83Data.IdDescriptorType2.EU64Id.VendId[1] = 0;
996 VPDPage83Data.IdDescriptorType2.EU64Id.VendId[2] = 0;
997
998 VPDPage83Data.IdDescriptorType2.EU64Id.Serial =
999 get_serial_reply->uid;
1000 VPDPage83Data.IdDescriptorType2.EU64Id.Reserved = 0;
1001
1002 /* Move the inquiry data to the response buffer. */
1003 scsi_sg_copy_from_buffer(scsicmd, &VPDPage83Data,
1004 sizeof(VPDPage83Data));
1005 } else {
1006 /* It must be for VPD 0x80 */
1007 char sp[13];
1008 /* EVPD bit set */
1009 sp[0] = INQD_PDT_DA;
1010 sp[1] = scsicmd->cmnd[2];
1011 sp[2] = 0;
1012 sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X",
1013 le32_to_cpu(get_serial_reply->uid));
1014 scsi_sg_copy_from_buffer(scsicmd, sp,
1015 sizeof(sp));
1016 }
901 } 1017 }
902 1018
903 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; 1019 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
@@ -2309,9 +2425,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
2309 INQD_PDT_PROC : INQD_PDT_DA; 2425 INQD_PDT_PROC : INQD_PDT_DA;
2310 if (scsicmd->cmnd[2] == 0) { 2426 if (scsicmd->cmnd[2] == 0) {
2311 /* supported vital product data pages */ 2427 /* supported vital product data pages */
2312 arr[3] = 2; 2428 arr[3] = 3;
2313 arr[4] = 0x0; 2429 arr[4] = 0x0;
2314 arr[5] = 0x80; 2430 arr[5] = 0x80;
2431 arr[6] = 0x83;
2315 arr[1] = scsicmd->cmnd[2]; 2432 arr[1] = scsicmd->cmnd[2];
2316 scsi_sg_copy_from_buffer(scsicmd, &inq_data, 2433 scsi_sg_copy_from_buffer(scsicmd, &inq_data,
2317 sizeof(inq_data)); 2434 sizeof(inq_data));
@@ -2327,7 +2444,16 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
2327 if (aac_wwn != 2) 2444 if (aac_wwn != 2)
2328 return aac_get_container_serial( 2445 return aac_get_container_serial(
2329 scsicmd); 2446 scsicmd);
2330 /* SLES 10 SP1 special */ 2447 scsicmd->result = DID_OK << 16 |
2448 COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
2449 } else if (scsicmd->cmnd[2] == 0x83) {
2450 /* vpd page 0x83 - Device Identification Page */
2451 char *sno = (char *)&inq_data;
2452 sno[3] = setinqserial(dev, &sno[4],
2453 scmd_id(scsicmd));
2454 if (aac_wwn != 2)
2455 return aac_get_container_serial(
2456 scsicmd);
2331 scsicmd->result = DID_OK << 16 | 2457 scsicmd->result = DID_OK << 16 |
2332 COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; 2458 COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
2333 } else { 2459 } else {
@@ -2482,6 +2608,18 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
2482 (fsa_dev_ptr[cid].block_size >> 8) & 0xff; 2608 (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
2483 mpd.bd.block_length[2] = 2609 mpd.bd.block_length[2] =
2484 fsa_dev_ptr[cid].block_size & 0xff; 2610 fsa_dev_ptr[cid].block_size & 0xff;
2611
2612 mpd.mpc_buf[0] = scsicmd->cmnd[2];
2613 if (scsicmd->cmnd[2] == 0x1C) {
2614 /* page length */
2615 mpd.mpc_buf[1] = 0xa;
2616 /* Mode data length */
2617 mpd.hd.data_length = 23;
2618 } else {
2619 /* Mode data length */
2620 mpd.hd.data_length = 15;
2621 }
2622
2485 if (capacity > 0xffffff) { 2623 if (capacity > 0xffffff) {
2486 mpd.bd.block_count[0] = 0xff; 2624 mpd.bd.block_count[0] = 0xff;
2487 mpd.bd.block_count[1] = 0xff; 2625 mpd.bd.block_count[1] = 0xff;
@@ -2500,9 +2638,12 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
2500 mpd.mpc_buf[2] = ((aac_cache & 6) == 2) 2638 mpd.mpc_buf[2] = ((aac_cache & 6) == 2)
2501 ? 0 : 0x04; /* WCE */ 2639 ? 0 : 0x04; /* WCE */
2502 mode_buf_length = sizeof(mpd); 2640 mode_buf_length = sizeof(mpd);
2503 if (mode_buf_length > scsicmd->cmnd[4])
2504 mode_buf_length = scsicmd->cmnd[4];
2505 } 2641 }
2642
2643 if (mode_buf_length > scsicmd->cmnd[4])
2644 mode_buf_length = scsicmd->cmnd[4];
2645 else
2646 mode_buf_length = sizeof(mpd);
2506 scsi_sg_copy_from_buffer(scsicmd, 2647 scsi_sg_copy_from_buffer(scsicmd,
2507 (char *)&mpd, 2648 (char *)&mpd,
2508 mode_buf_length); 2649 mode_buf_length);