diff options
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r-- | drivers/scsi/sd.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index ffa0689ee840..c52273c1327a 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -1153,6 +1153,12 @@ static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd) | |||
1153 | u64 end_lba = blk_rq_pos(scmd->request) + (scsi_bufflen(scmd) / 512); | 1153 | u64 end_lba = blk_rq_pos(scmd->request) + (scsi_bufflen(scmd) / 512); |
1154 | u64 bad_lba; | 1154 | u64 bad_lba; |
1155 | int info_valid; | 1155 | int info_valid; |
1156 | /* | ||
1157 | * resid is optional but mostly filled in. When it's unused, | ||
1158 | * its value is zero, so we assume the whole buffer transferred | ||
1159 | */ | ||
1160 | unsigned int transferred = scsi_bufflen(scmd) - scsi_get_resid(scmd); | ||
1161 | unsigned int good_bytes; | ||
1156 | 1162 | ||
1157 | if (scmd->request->cmd_type != REQ_TYPE_FS) | 1163 | if (scmd->request->cmd_type != REQ_TYPE_FS) |
1158 | return 0; | 1164 | return 0; |
@@ -1186,7 +1192,8 @@ static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd) | |||
1186 | /* This computation should always be done in terms of | 1192 | /* This computation should always be done in terms of |
1187 | * the resolution of the device's medium. | 1193 | * the resolution of the device's medium. |
1188 | */ | 1194 | */ |
1189 | return (bad_lba - start_lba) * scmd->device->sector_size; | 1195 | good_bytes = (bad_lba - start_lba) * scmd->device->sector_size; |
1196 | return min(good_bytes, transferred); | ||
1190 | } | 1197 | } |
1191 | 1198 | ||
1192 | /** | 1199 | /** |
@@ -2252,11 +2259,10 @@ static void sd_probe_async(void *data, async_cookie_t cookie) | |||
2252 | index = sdkp->index; | 2259 | index = sdkp->index; |
2253 | dev = &sdp->sdev_gendev; | 2260 | dev = &sdp->sdev_gendev; |
2254 | 2261 | ||
2255 | if (index < SD_MAX_DISKS) { | 2262 | gd->major = sd_major((index & 0xf0) >> 4); |
2256 | gd->major = sd_major((index & 0xf0) >> 4); | 2263 | gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); |
2257 | gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); | 2264 | gd->minors = SD_MINORS; |
2258 | gd->minors = SD_MINORS; | 2265 | |
2259 | } | ||
2260 | gd->fops = &sd_fops; | 2266 | gd->fops = &sd_fops; |
2261 | gd->private_data = &sdkp->driver; | 2267 | gd->private_data = &sdkp->driver; |
2262 | gd->queue = sdkp->device->request_queue; | 2268 | gd->queue = sdkp->device->request_queue; |
@@ -2346,6 +2352,12 @@ static int sd_probe(struct device *dev) | |||
2346 | if (error) | 2352 | if (error) |
2347 | goto out_put; | 2353 | goto out_put; |
2348 | 2354 | ||
2355 | if (index >= SD_MAX_DISKS) { | ||
2356 | error = -ENODEV; | ||
2357 | sdev_printk(KERN_WARNING, sdp, "SCSI disk (sd) name space exhausted.\n"); | ||
2358 | goto out_free_index; | ||
2359 | } | ||
2360 | |||
2349 | error = sd_format_disk_name("sd", index, gd->disk_name, DISK_NAME_LEN); | 2361 | error = sd_format_disk_name("sd", index, gd->disk_name, DISK_NAME_LEN); |
2350 | if (error) | 2362 | if (error) |
2351 | goto out_free_index; | 2363 | goto out_free_index; |