aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/scsi/scsi.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/scsi/scsi.c')
-rw-r--r--drivers/scsi/scsi.c52
1 files changed, 22 insertions, 30 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index dd098cad337b..1c08f6164658 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -940,10 +940,16 @@ EXPORT_SYMBOL(scsi_adjust_queue_depth);
940 */ 940 */
941int scsi_track_queue_full(struct scsi_device *sdev, int depth) 941int scsi_track_queue_full(struct scsi_device *sdev, int depth)
942{ 942{
943 if ((jiffies >> 4) == sdev->last_queue_full_time) 943
944 /*
945 * Don't let QUEUE_FULLs on the same
946 * jiffies count, they could all be from
947 * same event.
948 */
949 if ((jiffies >> 4) == (sdev->last_queue_full_time >> 4))
944 return 0; 950 return 0;
945 951
946 sdev->last_queue_full_time = (jiffies >> 4); 952 sdev->last_queue_full_time = jiffies;
947 if (sdev->last_queue_full_depth != depth) { 953 if (sdev->last_queue_full_depth != depth) {
948 sdev->last_queue_full_count = 1; 954 sdev->last_queue_full_count = 1;
949 sdev->last_queue_full_depth = depth; 955 sdev->last_queue_full_depth = depth;
@@ -1012,6 +1018,8 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer,
1012 * scsi_get_vpd_page - Get Vital Product Data from a SCSI device 1018 * scsi_get_vpd_page - Get Vital Product Data from a SCSI device
1013 * @sdev: The device to ask 1019 * @sdev: The device to ask
1014 * @page: Which Vital Product Data to return 1020 * @page: Which Vital Product Data to return
1021 * @buf: where to store the VPD
1022 * @buf_len: number of bytes in the VPD buffer area
1015 * 1023 *
1016 * SCSI devices may optionally supply Vital Product Data. Each 'page' 1024 * SCSI devices may optionally supply Vital Product Data. Each 'page'
1017 * of VPD is defined in the appropriate SCSI document (eg SPC, SBC). 1025 * of VPD is defined in the appropriate SCSI document (eg SPC, SBC).
@@ -1020,55 +1028,39 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer,
1020 * responsible for calling kfree() on this pointer when it is no longer 1028 * responsible for calling kfree() on this pointer when it is no longer
1021 * needed. If we cannot retrieve the VPD page this routine returns %NULL. 1029 * needed. If we cannot retrieve the VPD page this routine returns %NULL.
1022 */ 1030 */
1023unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page) 1031int scsi_get_vpd_page(struct scsi_device *sdev, u8 page, unsigned char *buf,
1032 int buf_len)
1024{ 1033{
1025 int i, result; 1034 int i, result;
1026 unsigned int len;
1027 const unsigned int init_vpd_len = 255;
1028 unsigned char *buf = kmalloc(init_vpd_len, GFP_KERNEL);
1029
1030 if (!buf)
1031 return NULL;
1032 1035
1033 /* Ask for all the pages supported by this device */ 1036 /* Ask for all the pages supported by this device */
1034 result = scsi_vpd_inquiry(sdev, buf, 0, init_vpd_len); 1037 result = scsi_vpd_inquiry(sdev, buf, 0, buf_len);
1035 if (result) 1038 if (result)
1036 goto fail; 1039 goto fail;
1037 1040
1038 /* If the user actually wanted this page, we can skip the rest */ 1041 /* If the user actually wanted this page, we can skip the rest */
1039 if (page == 0) 1042 if (page == 0)
1040 return buf; 1043 return -EINVAL;
1041 1044
1042 for (i = 0; i < buf[3]; i++) 1045 for (i = 0; i < min((int)buf[3], buf_len - 4); i++)
1043 if (buf[i + 4] == page) 1046 if (buf[i + 4] == page)
1044 goto found; 1047 goto found;
1048
1049 if (i < buf[3] && i > buf_len)
1050 /* ran off the end of the buffer, give us benefit of doubt */
1051 goto found;
1045 /* The device claims it doesn't support the requested page */ 1052 /* The device claims it doesn't support the requested page */
1046 goto fail; 1053 goto fail;
1047 1054
1048 found: 1055 found:
1049 result = scsi_vpd_inquiry(sdev, buf, page, 255); 1056 result = scsi_vpd_inquiry(sdev, buf, page, buf_len);
1050 if (result)
1051 goto fail;
1052
1053 /*
1054 * Some pages are longer than 255 bytes. The actual length of
1055 * the page is returned in the header.
1056 */
1057 len = ((buf[2] << 8) | buf[3]) + 4;
1058 if (len <= init_vpd_len)
1059 return buf;
1060
1061 kfree(buf);
1062 buf = kmalloc(len, GFP_KERNEL);
1063 result = scsi_vpd_inquiry(sdev, buf, page, len);
1064 if (result) 1057 if (result)
1065 goto fail; 1058 goto fail;
1066 1059
1067 return buf; 1060 return 0;
1068 1061
1069 fail: 1062 fail:
1070 kfree(buf); 1063 return -EINVAL;
1071 return NULL;
1072} 1064}
1073EXPORT_SYMBOL_GPL(scsi_get_vpd_page); 1065EXPORT_SYMBOL_GPL(scsi_get_vpd_page);
1074 1066