aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sd.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-26 00:06:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-26 00:06:13 -0400
commit9f34217c846a96dea03f4418e2f27423658d3542 (patch)
tree5b137af50db5758261700015911afb197ac8fc9f /drivers/scsi/sd.c
parent95e14ed7fc4b2db62eb597a70850a0fede48b78a (diff)
parent3703b2c5d041a68095cdd22380c23ce27d449ad7 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (55 commits) [SCSI] tcm_loop: Add multi-fabric Linux/SCSI LLD fabric module [SCSI] qla4xxx: Use polling mode for disable interrupt mailbox completion [SCSI] Revert "[SCSI] Retrieve the Caching mode page" [SCSI] bnx2fc: IO completion not processed due to missed wakeup [SCSI] qla4xxx: Update driver version to 5.02.00-k6 [SCSI] qla4xxx: masking required bits of add_fw_options during initialization [SCSI] qla4xxx: added new function qla4xxx_relogin_all_devices [SCSI] qla4xxx: add support for ql4xsess_recovery_tmo cmd line param [SCSI] qla4xxx: Add support for ql4xmaxqdepth command line parameter [SCSI] qla4xxx: cleanup function qla4xxx_process_ddb_changed [SCSI] qla4xxx: Prevent other port reinitialization during remove_adapter [SCSI] qla4xxx: remove unused ddb flag DF_NO_RELOGIN [SCSI] qla4xxx: cleanup DDB relogin logic during initialization [SCSI] qla4xxx: Do not retry ISP82XX initialization if H/W state is failed [SCSI] qla4xxx: Do not send mbox command if FW is in failed state [SCSI] qla4xxx: cleanup qla4xxx_initialize_ddb_list() [SCSI] ses: add subenclosure support [SCSI] bnx2fc: Bump version to 1.0.1 [SCSI] bnx2fc: Remove unnecessary module state checks [SCSI] bnx2fc: Fix MTU issue by using static MTU ...
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r--drivers/scsi/sd.c63
1 files changed, 16 insertions, 47 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 7ff61d76b4c5..b61ebec6bca7 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2027,14 +2027,10 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
2027 int old_rcd = sdkp->RCD; 2027 int old_rcd = sdkp->RCD;
2028 int old_dpofua = sdkp->DPOFUA; 2028 int old_dpofua = sdkp->DPOFUA;
2029 2029
2030 if (sdp->skip_ms_page_8) { 2030 if (sdp->skip_ms_page_8)
2031 if (sdp->type == TYPE_RBC) 2031 goto defaults;
2032 goto defaults; 2032
2033 else { 2033 if (sdp->type == TYPE_RBC) {
2034 modepage = 0x3F;
2035 dbd = 0;
2036 }
2037 } else if (sdp->type == TYPE_RBC) {
2038 modepage = 6; 2034 modepage = 6;
2039 dbd = 8; 2035 dbd = 8;
2040 } else { 2036 } else {
@@ -2062,11 +2058,13 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
2062 */ 2058 */
2063 if (len < 3) 2059 if (len < 3)
2064 goto bad_sense; 2060 goto bad_sense;
2065 else if (len > SD_BUF_SIZE) { 2061 if (len > 20)
2066 sd_printk(KERN_NOTICE, sdkp, "Truncating mode parameter " 2062 len = 20;
2067 "data from %d to %d bytes\n", len, SD_BUF_SIZE); 2063
2068 len = SD_BUF_SIZE; 2064 /* Take headers and block descriptors into account */
2069 } 2065 len += data.header_length + data.block_descriptor_length;
2066 if (len > SD_BUF_SIZE)
2067 goto bad_sense;
2070 2068
2071 /* Get the data */ 2069 /* Get the data */
2072 res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr); 2070 res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr);
@@ -2074,45 +2072,16 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
2074 if (scsi_status_is_good(res)) { 2072 if (scsi_status_is_good(res)) {
2075 int offset = data.header_length + data.block_descriptor_length; 2073 int offset = data.header_length + data.block_descriptor_length;
2076 2074
2077 while (offset < len) { 2075 if (offset >= SD_BUF_SIZE - 2) {
2078 u8 page_code = buffer[offset] & 0x3F; 2076 sd_printk(KERN_ERR, sdkp, "Malformed MODE SENSE response\n");
2079 u8 spf = buffer[offset] & 0x40; 2077 goto defaults;
2080
2081 if (page_code == 8 || page_code == 6) {
2082 /* We're interested only in the first 3 bytes.
2083 */
2084 if (len - offset <= 2) {
2085 sd_printk(KERN_ERR, sdkp, "Incomplete "
2086 "mode parameter data\n");
2087 goto defaults;
2088 } else {
2089 modepage = page_code;
2090 goto Page_found;
2091 }
2092 } else {
2093 /* Go to the next page */
2094 if (spf && len - offset > 3)
2095 offset += 4 + (buffer[offset+2] << 8) +
2096 buffer[offset+3];
2097 else if (!spf && len - offset > 1)
2098 offset += 2 + buffer[offset+1];
2099 else {
2100 sd_printk(KERN_ERR, sdkp, "Incomplete "
2101 "mode parameter data\n");
2102 goto defaults;
2103 }
2104 }
2105 } 2078 }
2106 2079
2107 if (modepage == 0x3F) { 2080 if ((buffer[offset] & 0x3f) != modepage) {
2108 sd_printk(KERN_ERR, sdkp, "No Caching mode page "
2109 "present\n");
2110 goto defaults;
2111 } else if ((buffer[offset] & 0x3f) != modepage) {
2112 sd_printk(KERN_ERR, sdkp, "Got wrong page\n"); 2081 sd_printk(KERN_ERR, sdkp, "Got wrong page\n");
2113 goto defaults; 2082 goto defaults;
2114 } 2083 }
2115 Page_found: 2084
2116 if (modepage == 8) { 2085 if (modepage == 8) {
2117 sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0); 2086 sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0);
2118 sdkp->RCD = ((buffer[offset + 2] & 0x01) != 0); 2087 sdkp->RCD = ((buffer[offset + 2] & 0x01) != 0);