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>
This commit is contained in:
		
							parent
							
								
									495c021767
								
							
						
					
					
						commit
						5d9106490c
					
				| @ -163,6 +163,48 @@ struct inquiry_data { | ||||
| 	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 | ||||
|  */ | ||||
| @ -890,14 +932,88 @@ static void get_container_serial_callback(void *context, struct fib * fibptr) | ||||
| 	get_serial_reply = (struct aac_get_serial_resp *) fib_data(fibptr); | ||||
| 	/* Failure is irrelevant, using default value instead */ | ||||
| 	if (le32_to_cpu(get_serial_reply->status) == CT_OK) { | ||||
| 		char sp[13]; | ||||
| 		/* EVPD bit set */ | ||||
| 		sp[0] = INQD_PDT_DA; | ||||
| 		sp[1] = scsicmd->cmnd[2]; | ||||
| 		sp[2] = 0; | ||||
| 		sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X", | ||||
| 		  le32_to_cpu(get_serial_reply->uid)); | ||||
| 		scsi_sg_copy_from_buffer(scsicmd, sp, sizeof(sp)); | ||||
| 		/*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]; | ||||
| 			/* EVPD bit set */ | ||||
| 			sp[0] = INQD_PDT_DA; | ||||
| 			sp[1] = scsicmd->cmnd[2]; | ||||
| 			sp[2] = 0; | ||||
| 			sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X", | ||||
| 				le32_to_cpu(get_serial_reply->uid)); | ||||
| 			scsi_sg_copy_from_buffer(scsicmd, sp, | ||||
| 						 sizeof(sp)); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | ||||
| @ -2309,9 +2425,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | ||||
| 			  INQD_PDT_PROC : INQD_PDT_DA; | ||||
| 			if (scsicmd->cmnd[2] == 0) { | ||||
| 				/* supported vital product data pages */ | ||||
| 				arr[3] = 2; | ||||
| 				arr[3] = 3; | ||||
| 				arr[4] = 0x0; | ||||
| 				arr[5] = 0x80; | ||||
| 				arr[6] = 0x83; | ||||
| 				arr[1] = scsicmd->cmnd[2]; | ||||
| 				scsi_sg_copy_from_buffer(scsicmd, &inq_data, | ||||
| 							 sizeof(inq_data)); | ||||
| @ -2327,7 +2444,16 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | ||||
| 				if (aac_wwn != 2) | ||||
| 					return aac_get_container_serial( | ||||
| 						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 | | ||||
| 				  COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | ||||
| 			} else { | ||||
| @ -2482,6 +2608,18 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | ||||
| 				(fsa_dev_ptr[cid].block_size >> 8) &  0xff; | ||||
| 			mpd.bd.block_length[2] = | ||||
| 				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) { | ||||
| 				mpd.bd.block_count[0] = 0xff; | ||||
| 				mpd.bd.block_count[1] = 0xff; | ||||
| @ -2500,9 +2638,12 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | ||||
| 			mpd.mpc_buf[2] = ((aac_cache & 6) == 2) | ||||
| 				? 0 : 0x04; /* WCE */ | ||||
| 			mode_buf_length = sizeof(mpd); | ||||
| 			if (mode_buf_length > scsicmd->cmnd[4]) | ||||
| 				mode_buf_length = scsicmd->cmnd[4]; | ||||
| 		} | ||||
| 
 | ||||
| 		if (mode_buf_length > scsicmd->cmnd[4]) | ||||
| 			mode_buf_length = scsicmd->cmnd[4]; | ||||
| 		else | ||||
| 			mode_buf_length = sizeof(mpd); | ||||
| 		scsi_sg_copy_from_buffer(scsicmd, | ||||
| 					 (char *)&mpd, | ||||
| 					 mode_buf_length); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user