aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi.c')
-rw-r--r--drivers/scsi/scsi.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index b2526ad7b9a1..1d98ac960887 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -1030,6 +1030,93 @@ int scsi_get_vpd_page(struct scsi_device *sdev, u8 page, unsigned char *buf,
1030EXPORT_SYMBOL_GPL(scsi_get_vpd_page); 1030EXPORT_SYMBOL_GPL(scsi_get_vpd_page);
1031 1031
1032/** 1032/**
1033 * scsi_attach_vpd - Attach Vital Product Data to a SCSI device structure
1034 * @sdev: The device to ask
1035 *
1036 * Attach the 'Device Identification' VPD page (0x83) and the
1037 * 'Unit Serial Number' VPD page (0x80) to a SCSI device
1038 * structure. This information can be used to identify the device
1039 * uniquely.
1040 */
1041void scsi_attach_vpd(struct scsi_device *sdev)
1042{
1043 int result, i;
1044 int vpd_len = SCSI_VPD_PG_LEN;
1045 int pg80_supported = 0;
1046 int pg83_supported = 0;
1047 unsigned char *vpd_buf;
1048
1049 if (sdev->skip_vpd_pages)
1050 return;
1051retry_pg0:
1052 vpd_buf = kmalloc(vpd_len, GFP_KERNEL);
1053 if (!vpd_buf)
1054 return;
1055
1056 /* Ask for all the pages supported by this device */
1057 result = scsi_vpd_inquiry(sdev, vpd_buf, 0, vpd_len);
1058 if (result < 0) {
1059 kfree(vpd_buf);
1060 return;
1061 }
1062 if (result > vpd_len) {
1063 vpd_len = result;
1064 kfree(vpd_buf);
1065 goto retry_pg0;
1066 }
1067
1068 for (i = 4; i < result; i++) {
1069 if (vpd_buf[i] == 0x80)
1070 pg80_supported = 1;
1071 if (vpd_buf[i] == 0x83)
1072 pg83_supported = 1;
1073 }
1074 kfree(vpd_buf);
1075 vpd_len = SCSI_VPD_PG_LEN;
1076
1077 if (pg80_supported) {
1078retry_pg80:
1079 vpd_buf = kmalloc(vpd_len, GFP_KERNEL);
1080 if (!vpd_buf)
1081 return;
1082
1083 result = scsi_vpd_inquiry(sdev, vpd_buf, 0x80, vpd_len);
1084 if (result < 0) {
1085 kfree(vpd_buf);
1086 return;
1087 }
1088 if (result > vpd_len) {
1089 vpd_len = result;
1090 kfree(vpd_buf);
1091 goto retry_pg80;
1092 }
1093 sdev->vpd_pg80_len = result;
1094 sdev->vpd_pg80 = vpd_buf;
1095 vpd_len = SCSI_VPD_PG_LEN;
1096 }
1097
1098 if (pg83_supported) {
1099retry_pg83:
1100 vpd_buf = kmalloc(vpd_len, GFP_KERNEL);
1101 if (!vpd_buf)
1102 return;
1103
1104 result = scsi_vpd_inquiry(sdev, vpd_buf, 0x83, vpd_len);
1105 if (result < 0) {
1106 kfree(vpd_buf);
1107 return;
1108 }
1109 if (result > vpd_len) {
1110 vpd_len = result;
1111 kfree(vpd_buf);
1112 goto retry_pg83;
1113 }
1114 sdev->vpd_pg83_len = result;
1115 sdev->vpd_pg83 = vpd_buf;
1116 }
1117}
1118
1119/**
1033 * scsi_report_opcode - Find out if a given command opcode is supported 1120 * scsi_report_opcode - Find out if a given command opcode is supported
1034 * @sdev: scsi device to query 1121 * @sdev: scsi device to query
1035 * @buffer: scratch buffer (must be at least 20 bytes long) 1122 * @buffer: scratch buffer (must be at least 20 bytes long)