Commit 5d910649 authored by Mahesh Rajashekhara's avatar Mahesh Rajashekhara Committed by James Bottomley

aacraid: vpd page code 0x83 support

Signed-off-by: default avatarMahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Reviewed-by: default avatarMurthy Bhat <Murthy.Bhat@pmcs.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Odin.com>
parent 495c0217
...@@ -163,6 +163,48 @@ struct inquiry_data { ...@@ -163,6 +163,48 @@ struct inquiry_data {
u8 inqd_prl[4]; /* Product Revision Level */ u8 inqd_prl[4]; /* Product Revision Level */
}; };
/* Added for VPD 0x83 */
typedef struct {
u8 CodeSet:4; /* VPD_CODE_SET */
u8 Reserved:4;
u8 IdentifierType:4; /* VPD_IDENTIFIER_TYPE */
u8 Reserved2:4;
u8 Reserved3;
u8 IdentifierLength;
u8 VendId[8];
u8 ProductId[16];
u8 SerialNumber[8]; /* SN in ASCII */
} TVPD_ID_Descriptor_Type_1;
typedef struct {
u8 CodeSet:4; /* VPD_CODE_SET */
u8 Reserved:4;
u8 IdentifierType:4; /* VPD_IDENTIFIER_TYPE */
u8 Reserved2:4;
u8 Reserved3;
u8 IdentifierLength;
struct TEU64Id {
u32 Serial;
/* The serial number supposed to be 40 bits,
* bit we only support 32, so make the last byte zero. */
u8 Reserved;
u8 VendId[3];
} EU64Id;
} TVPD_ID_Descriptor_Type_2;
typedef struct {
u8 DeviceType:5;
u8 DeviceTypeQualifier:3;
u8 PageCode;
u8 Reserved;
u8 PageLength;
TVPD_ID_Descriptor_Type_1 IdDescriptorType1;
TVPD_ID_Descriptor_Type_2 IdDescriptorType2;
} TVPD_Page83;
/* /*
* M O D U L E G L O B A L S * M O D U L E G L O B A L S
*/ */
...@@ -890,6 +932,78 @@ static void get_container_serial_callback(void *context, struct fib * fibptr) ...@@ -890,6 +932,78 @@ static void get_container_serial_callback(void *context, struct fib * fibptr)
get_serial_reply = (struct aac_get_serial_resp *) fib_data(fibptr); get_serial_reply = (struct aac_get_serial_resp *) fib_data(fibptr);
/* Failure is irrelevant, using default value instead */ /* Failure is irrelevant, using default value instead */
if (le32_to_cpu(get_serial_reply->status) == CT_OK) { if (le32_to_cpu(get_serial_reply->status) == CT_OK) {
/*Check to see if it's for VPD 0x83 or 0x80 */
if (scsicmd->cmnd[2] == 0x83) {
/* vpd page 0x83 - Device Identification Page */
int i;
TVPD_Page83 VPDPage83Data;
memset(((u8 *)&VPDPage83Data), 0,
sizeof(VPDPage83Data));
/* DIRECT_ACCESS_DEVIC */
VPDPage83Data.DeviceType = 0;
/* DEVICE_CONNECTED */
VPDPage83Data.DeviceTypeQualifier = 0;
/* VPD_DEVICE_IDENTIFIERS */
VPDPage83Data.PageCode = 0x83;
VPDPage83Data.Reserved = 0;
VPDPage83Data.PageLength =
sizeof(VPDPage83Data.IdDescriptorType1) +
sizeof(VPDPage83Data.IdDescriptorType2);
/* T10 Vendor Identifier Field Format */
/* VpdCodeSetAscii */
VPDPage83Data.IdDescriptorType1.CodeSet = 2;
/* VpdIdentifierTypeVendorId */
VPDPage83Data.IdDescriptorType1.IdentifierType = 1;
VPDPage83Data.IdDescriptorType1.IdentifierLength =
sizeof(VPDPage83Data.IdDescriptorType1) - 4;
/* "ADAPTEC " for adaptec */
memcpy(VPDPage83Data.IdDescriptorType1.VendId,
"ADAPTEC ",
sizeof(VPDPage83Data.IdDescriptorType1.VendId));
memcpy(VPDPage83Data.IdDescriptorType1.ProductId,
"ARRAY ",
sizeof(
VPDPage83Data.IdDescriptorType1.ProductId));
/* Convert to ascii based serial number.
* The LSB is the the end.
*/
for (i = 0; i < 8; i++) {
u8 temp =
(u8)((get_serial_reply->uid >> ((7 - i) * 4)) & 0xF);
if (temp > 0x9) {
VPDPage83Data.IdDescriptorType1.SerialNumber[i] =
'A' + (temp - 0xA);
} else {
VPDPage83Data.IdDescriptorType1.SerialNumber[i] =
'0' + temp;
}
}
/* VpdCodeSetBinary */
VPDPage83Data.IdDescriptorType2.CodeSet = 1;
/* VpdIdentifierTypeEUI64 */
VPDPage83Data.IdDescriptorType2.IdentifierType = 2;
VPDPage83Data.IdDescriptorType2.IdentifierLength =
sizeof(VPDPage83Data.IdDescriptorType2) - 4;
VPDPage83Data.IdDescriptorType2.EU64Id.VendId[0] = 0xD0;
VPDPage83Data.IdDescriptorType2.EU64Id.VendId[1] = 0;
VPDPage83Data.IdDescriptorType2.EU64Id.VendId[2] = 0;
VPDPage83Data.IdDescriptorType2.EU64Id.Serial =
get_serial_reply->uid;
VPDPage83Data.IdDescriptorType2.EU64Id.Reserved = 0;
/* Move the inquiry data to the response buffer. */
scsi_sg_copy_from_buffer(scsicmd, &VPDPage83Data,
sizeof(VPDPage83Data));
} else {
/* It must be for VPD 0x80 */
char sp[13]; char sp[13];
/* EVPD bit set */ /* EVPD bit set */
sp[0] = INQD_PDT_DA; sp[0] = INQD_PDT_DA;
...@@ -897,7 +1011,9 @@ static void get_container_serial_callback(void *context, struct fib * fibptr) ...@@ -897,7 +1011,9 @@ static void get_container_serial_callback(void *context, struct fib * fibptr)
sp[2] = 0; sp[2] = 0;
sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X", sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X",
le32_to_cpu(get_serial_reply->uid)); le32_to_cpu(get_serial_reply->uid));
scsi_sg_copy_from_buffer(scsicmd, sp, sizeof(sp)); scsi_sg_copy_from_buffer(scsicmd, sp,
sizeof(sp));
}
} }
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
...@@ -2309,9 +2425,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) ...@@ -2309,9 +2425,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
INQD_PDT_PROC : INQD_PDT_DA; INQD_PDT_PROC : INQD_PDT_DA;
if (scsicmd->cmnd[2] == 0) { if (scsicmd->cmnd[2] == 0) {
/* supported vital product data pages */ /* supported vital product data pages */
arr[3] = 2; arr[3] = 3;
arr[4] = 0x0; arr[4] = 0x0;
arr[5] = 0x80; arr[5] = 0x80;
arr[6] = 0x83;
arr[1] = scsicmd->cmnd[2]; arr[1] = scsicmd->cmnd[2];
scsi_sg_copy_from_buffer(scsicmd, &inq_data, scsi_sg_copy_from_buffer(scsicmd, &inq_data,
sizeof(inq_data)); sizeof(inq_data));
...@@ -2327,7 +2444,16 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) ...@@ -2327,7 +2444,16 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
if (aac_wwn != 2) if (aac_wwn != 2)
return aac_get_container_serial( return aac_get_container_serial(
scsicmd); scsicmd);
/* SLES 10 SP1 special */ scsicmd->result = DID_OK << 16 |
COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
} else if (scsicmd->cmnd[2] == 0x83) {
/* vpd page 0x83 - Device Identification Page */
char *sno = (char *)&inq_data;
sno[3] = setinqserial(dev, &sno[4],
scmd_id(scsicmd));
if (aac_wwn != 2)
return aac_get_container_serial(
scsicmd);
scsicmd->result = DID_OK << 16 | scsicmd->result = DID_OK << 16 |
COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
} else { } else {
...@@ -2482,6 +2608,18 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) ...@@ -2482,6 +2608,18 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
(fsa_dev_ptr[cid].block_size >> 8) & 0xff; (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
mpd.bd.block_length[2] = mpd.bd.block_length[2] =
fsa_dev_ptr[cid].block_size & 0xff; fsa_dev_ptr[cid].block_size & 0xff;
mpd.mpc_buf[0] = scsicmd->cmnd[2];
if (scsicmd->cmnd[2] == 0x1C) {
/* page length */
mpd.mpc_buf[1] = 0xa;
/* Mode data length */
mpd.hd.data_length = 23;
} else {
/* Mode data length */
mpd.hd.data_length = 15;
}
if (capacity > 0xffffff) { if (capacity > 0xffffff) {
mpd.bd.block_count[0] = 0xff; mpd.bd.block_count[0] = 0xff;
mpd.bd.block_count[1] = 0xff; mpd.bd.block_count[1] = 0xff;
...@@ -2500,9 +2638,12 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) ...@@ -2500,9 +2638,12 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
mpd.mpc_buf[2] = ((aac_cache & 6) == 2) mpd.mpc_buf[2] = ((aac_cache & 6) == 2)
? 0 : 0x04; /* WCE */ ? 0 : 0x04; /* WCE */
mode_buf_length = sizeof(mpd); mode_buf_length = sizeof(mpd);
}
if (mode_buf_length > scsicmd->cmnd[4]) if (mode_buf_length > scsicmd->cmnd[4])
mode_buf_length = scsicmd->cmnd[4]; mode_buf_length = scsicmd->cmnd[4];
} else
mode_buf_length = sizeof(mpd);
scsi_sg_copy_from_buffer(scsicmd, scsi_sg_copy_from_buffer(scsicmd,
(char *)&mpd, (char *)&mpd,
mode_buf_length); mode_buf_length);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment