diff options
-rw-r--r-- | drivers/scsi/sd.c | 20 | ||||
-rw-r--r-- | drivers/scsi/sd.h | 1 |
2 files changed, 21 insertions, 0 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 7992635d405f..82910cc69ba3 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -142,6 +142,7 @@ sd_store_cache_type(struct device *dev, struct device_attribute *attr, | |||
142 | char *buffer_data; | 142 | char *buffer_data; |
143 | struct scsi_mode_data data; | 143 | struct scsi_mode_data data; |
144 | struct scsi_sense_hdr sshdr; | 144 | struct scsi_sense_hdr sshdr; |
145 | const char *temp = "temporary "; | ||
145 | int len; | 146 | int len; |
146 | 147 | ||
147 | if (sdp->type != TYPE_DISK) | 148 | if (sdp->type != TYPE_DISK) |
@@ -150,6 +151,13 @@ sd_store_cache_type(struct device *dev, struct device_attribute *attr, | |||
150 | * it's not worth the risk */ | 151 | * it's not worth the risk */ |
151 | return -EINVAL; | 152 | return -EINVAL; |
152 | 153 | ||
154 | if (strncmp(buf, temp, sizeof(temp) - 1) == 0) { | ||
155 | buf += sizeof(temp) - 1; | ||
156 | sdkp->cache_override = 1; | ||
157 | } else { | ||
158 | sdkp->cache_override = 0; | ||
159 | } | ||
160 | |||
153 | for (i = 0; i < ARRAY_SIZE(sd_cache_types); i++) { | 161 | for (i = 0; i < ARRAY_SIZE(sd_cache_types); i++) { |
154 | len = strlen(sd_cache_types[i]); | 162 | len = strlen(sd_cache_types[i]); |
155 | if (strncmp(sd_cache_types[i], buf, len) == 0 && | 163 | if (strncmp(sd_cache_types[i], buf, len) == 0 && |
@@ -162,6 +170,13 @@ sd_store_cache_type(struct device *dev, struct device_attribute *attr, | |||
162 | return -EINVAL; | 170 | return -EINVAL; |
163 | rcd = ct & 0x01 ? 1 : 0; | 171 | rcd = ct & 0x01 ? 1 : 0; |
164 | wce = ct & 0x02 ? 1 : 0; | 172 | wce = ct & 0x02 ? 1 : 0; |
173 | |||
174 | if (sdkp->cache_override) { | ||
175 | sdkp->WCE = wce; | ||
176 | sdkp->RCD = rcd; | ||
177 | return count; | ||
178 | } | ||
179 | |||
165 | if (scsi_mode_sense(sdp, 0x08, 8, buffer, sizeof(buffer), SD_TIMEOUT, | 180 | if (scsi_mode_sense(sdp, 0x08, 8, buffer, sizeof(buffer), SD_TIMEOUT, |
166 | SD_MAX_RETRIES, &data, NULL)) | 181 | SD_MAX_RETRIES, &data, NULL)) |
167 | return -EINVAL; | 182 | return -EINVAL; |
@@ -2319,6 +2334,10 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) | |||
2319 | int old_rcd = sdkp->RCD; | 2334 | int old_rcd = sdkp->RCD; |
2320 | int old_dpofua = sdkp->DPOFUA; | 2335 | int old_dpofua = sdkp->DPOFUA; |
2321 | 2336 | ||
2337 | |||
2338 | if (sdkp->cache_override) | ||
2339 | return; | ||
2340 | |||
2322 | first_len = 4; | 2341 | first_len = 4; |
2323 | if (sdp->skip_ms_page_8) { | 2342 | if (sdp->skip_ms_page_8) { |
2324 | if (sdp->type == TYPE_RBC) | 2343 | if (sdp->type == TYPE_RBC) |
@@ -2812,6 +2831,7 @@ static void sd_probe_async(void *data, async_cookie_t cookie) | |||
2812 | sdkp->capacity = 0; | 2831 | sdkp->capacity = 0; |
2813 | sdkp->media_present = 1; | 2832 | sdkp->media_present = 1; |
2814 | sdkp->write_prot = 0; | 2833 | sdkp->write_prot = 0; |
2834 | sdkp->cache_override = 0; | ||
2815 | sdkp->WCE = 0; | 2835 | sdkp->WCE = 0; |
2816 | sdkp->RCD = 0; | 2836 | sdkp->RCD = 0; |
2817 | sdkp->ATO = 0; | 2837 | sdkp->ATO = 0; |
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 74a1e4ca5401..2386aeb41fe8 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h | |||
@@ -73,6 +73,7 @@ struct scsi_disk { | |||
73 | u8 protection_type;/* Data Integrity Field */ | 73 | u8 protection_type;/* Data Integrity Field */ |
74 | u8 provisioning_mode; | 74 | u8 provisioning_mode; |
75 | unsigned ATO : 1; /* state of disk ATO bit */ | 75 | unsigned ATO : 1; /* state of disk ATO bit */ |
76 | unsigned cache_override : 1; /* temp override of WCE,RCD */ | ||
76 | unsigned WCE : 1; /* state of disk WCE bit */ | 77 | unsigned WCE : 1; /* state of disk WCE bit */ |
77 | unsigned RCD : 1; /* state of disk RCD bit, unused */ | 78 | unsigned RCD : 1; /* state of disk RCD bit, unused */ |
78 | unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ | 79 | unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ |