diff options
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r-- | drivers/scsi/sd.c | 126 |
1 files changed, 52 insertions, 74 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 8613a1317712..4c5127ed379c 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -102,6 +102,7 @@ struct scsi_disk { | |||
102 | u8 write_prot; | 102 | u8 write_prot; |
103 | unsigned WCE : 1; /* state of disk WCE bit */ | 103 | unsigned WCE : 1; /* state of disk WCE bit */ |
104 | unsigned RCD : 1; /* state of disk RCD bit, unused */ | 104 | unsigned RCD : 1; /* state of disk RCD bit, unused */ |
105 | unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ | ||
105 | }; | 106 | }; |
106 | 107 | ||
107 | static DEFINE_IDR(sd_index_idr); | 108 | static DEFINE_IDR(sd_index_idr); |
@@ -121,8 +122,7 @@ static void sd_shutdown(struct device *dev); | |||
121 | static void sd_rescan(struct device *); | 122 | static void sd_rescan(struct device *); |
122 | static int sd_init_command(struct scsi_cmnd *); | 123 | static int sd_init_command(struct scsi_cmnd *); |
123 | static int sd_issue_flush(struct device *, sector_t *); | 124 | static int sd_issue_flush(struct device *, sector_t *); |
124 | static void sd_end_flush(request_queue_t *, struct request *); | 125 | static void sd_prepare_flush(request_queue_t *, struct request *); |
125 | static int sd_prepare_flush(request_queue_t *, struct request *); | ||
126 | static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname, | 126 | static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname, |
127 | unsigned char *buffer); | 127 | unsigned char *buffer); |
128 | 128 | ||
@@ -137,8 +137,6 @@ static struct scsi_driver sd_template = { | |||
137 | .rescan = sd_rescan, | 137 | .rescan = sd_rescan, |
138 | .init_command = sd_init_command, | 138 | .init_command = sd_init_command, |
139 | .issue_flush = sd_issue_flush, | 139 | .issue_flush = sd_issue_flush, |
140 | .prepare_flush = sd_prepare_flush, | ||
141 | .end_flush = sd_end_flush, | ||
142 | }; | 140 | }; |
143 | 141 | ||
144 | /* | 142 | /* |
@@ -245,24 +243,10 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
245 | * SG_IO from block layer already setup, just copy cdb basically | 243 | * SG_IO from block layer already setup, just copy cdb basically |
246 | */ | 244 | */ |
247 | if (blk_pc_request(rq)) { | 245 | if (blk_pc_request(rq)) { |
248 | if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd)) | 246 | scsi_setup_blk_pc_cmnd(SCpnt); |
249 | return 0; | ||
250 | |||
251 | memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd)); | ||
252 | SCpnt->cmd_len = rq->cmd_len; | ||
253 | if (rq_data_dir(rq) == WRITE) | ||
254 | SCpnt->sc_data_direction = DMA_TO_DEVICE; | ||
255 | else if (rq->data_len) | ||
256 | SCpnt->sc_data_direction = DMA_FROM_DEVICE; | ||
257 | else | ||
258 | SCpnt->sc_data_direction = DMA_NONE; | ||
259 | |||
260 | this_count = rq->data_len; | ||
261 | if (rq->timeout) | 247 | if (rq->timeout) |
262 | timeout = rq->timeout; | 248 | timeout = rq->timeout; |
263 | 249 | ||
264 | SCpnt->transfersize = rq->data_len; | ||
265 | SCpnt->allowed = SD_PASSTHROUGH_RETRIES; | ||
266 | goto queue; | 250 | goto queue; |
267 | } | 251 | } |
268 | 252 | ||
@@ -360,6 +344,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
360 | 344 | ||
361 | if (block > 0xffffffff) { | 345 | if (block > 0xffffffff) { |
362 | SCpnt->cmnd[0] += READ_16 - READ_6; | 346 | SCpnt->cmnd[0] += READ_16 - READ_6; |
347 | SCpnt->cmnd[1] |= blk_fua_rq(rq) ? 0x8 : 0; | ||
363 | SCpnt->cmnd[2] = sizeof(block) > 4 ? (unsigned char) (block >> 56) & 0xff : 0; | 348 | SCpnt->cmnd[2] = sizeof(block) > 4 ? (unsigned char) (block >> 56) & 0xff : 0; |
364 | SCpnt->cmnd[3] = sizeof(block) > 4 ? (unsigned char) (block >> 48) & 0xff : 0; | 349 | SCpnt->cmnd[3] = sizeof(block) > 4 ? (unsigned char) (block >> 48) & 0xff : 0; |
365 | SCpnt->cmnd[4] = sizeof(block) > 4 ? (unsigned char) (block >> 40) & 0xff : 0; | 350 | SCpnt->cmnd[4] = sizeof(block) > 4 ? (unsigned char) (block >> 40) & 0xff : 0; |
@@ -379,6 +364,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
379 | this_count = 0xffff; | 364 | this_count = 0xffff; |
380 | 365 | ||
381 | SCpnt->cmnd[0] += READ_10 - READ_6; | 366 | SCpnt->cmnd[0] += READ_10 - READ_6; |
367 | SCpnt->cmnd[1] |= blk_fua_rq(rq) ? 0x8 : 0; | ||
382 | SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff; | 368 | SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff; |
383 | SCpnt->cmnd[3] = (unsigned char) (block >> 16) & 0xff; | 369 | SCpnt->cmnd[3] = (unsigned char) (block >> 16) & 0xff; |
384 | SCpnt->cmnd[4] = (unsigned char) (block >> 8) & 0xff; | 370 | SCpnt->cmnd[4] = (unsigned char) (block >> 8) & 0xff; |
@@ -387,6 +373,17 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
387 | SCpnt->cmnd[7] = (unsigned char) (this_count >> 8) & 0xff; | 373 | SCpnt->cmnd[7] = (unsigned char) (this_count >> 8) & 0xff; |
388 | SCpnt->cmnd[8] = (unsigned char) this_count & 0xff; | 374 | SCpnt->cmnd[8] = (unsigned char) this_count & 0xff; |
389 | } else { | 375 | } else { |
376 | if (unlikely(blk_fua_rq(rq))) { | ||
377 | /* | ||
378 | * This happens only if this drive failed | ||
379 | * 10byte rw command with ILLEGAL_REQUEST | ||
380 | * during operation and thus turned off | ||
381 | * use_10_for_rw. | ||
382 | */ | ||
383 | printk(KERN_ERR "sd: FUA write on READ/WRITE(6) drive\n"); | ||
384 | return 0; | ||
385 | } | ||
386 | |||
390 | SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f); | 387 | SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f); |
391 | SCpnt->cmnd[2] = (unsigned char) ((block >> 8) & 0xff); | 388 | SCpnt->cmnd[2] = (unsigned char) ((block >> 8) & 0xff); |
392 | SCpnt->cmnd[3] = (unsigned char) block & 0xff; | 389 | SCpnt->cmnd[3] = (unsigned char) block & 0xff; |
@@ -530,7 +527,7 @@ static int sd_release(struct inode *inode, struct file *filp) | |||
530 | return 0; | 527 | return 0; |
531 | } | 528 | } |
532 | 529 | ||
533 | static int sd_hdio_getgeo(struct block_device *bdev, struct hd_geometry __user *loc) | 530 | static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo) |
534 | { | 531 | { |
535 | struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk); | 532 | struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk); |
536 | struct scsi_device *sdp = sdkp->device; | 533 | struct scsi_device *sdp = sdkp->device; |
@@ -548,15 +545,9 @@ static int sd_hdio_getgeo(struct block_device *bdev, struct hd_geometry __user * | |||
548 | else | 545 | else |
549 | scsicam_bios_param(bdev, sdkp->capacity, diskinfo); | 546 | scsicam_bios_param(bdev, sdkp->capacity, diskinfo); |
550 | 547 | ||
551 | if (put_user(diskinfo[0], &loc->heads)) | 548 | geo->heads = diskinfo[0]; |
552 | return -EFAULT; | 549 | geo->sectors = diskinfo[1]; |
553 | if (put_user(diskinfo[1], &loc->sectors)) | 550 | geo->cylinders = diskinfo[2]; |
554 | return -EFAULT; | ||
555 | if (put_user(diskinfo[2], &loc->cylinders)) | ||
556 | return -EFAULT; | ||
557 | if (put_user((unsigned)get_start_sect(bdev), | ||
558 | (unsigned long __user *)&loc->start)) | ||
559 | return -EFAULT; | ||
560 | return 0; | 551 | return 0; |
561 | } | 552 | } |
562 | 553 | ||
@@ -596,12 +587,6 @@ static int sd_ioctl(struct inode * inode, struct file * filp, | |||
596 | if (!scsi_block_when_processing_errors(sdp) || !error) | 587 | if (!scsi_block_when_processing_errors(sdp) || !error) |
597 | return error; | 588 | return error; |
598 | 589 | ||
599 | if (cmd == HDIO_GETGEO) { | ||
600 | if (!arg) | ||
601 | return -EINVAL; | ||
602 | return sd_hdio_getgeo(bdev, p); | ||
603 | } | ||
604 | |||
605 | /* | 590 | /* |
606 | * Send SCSI addressing ioctls directly to mid level, send other | 591 | * Send SCSI addressing ioctls directly to mid level, send other |
607 | * ioctls to block level and then onto mid level if they can't be | 592 | * ioctls to block level and then onto mid level if they can't be |
@@ -743,42 +728,13 @@ static int sd_issue_flush(struct device *dev, sector_t *error_sector) | |||
743 | return ret; | 728 | return ret; |
744 | } | 729 | } |
745 | 730 | ||
746 | static void sd_end_flush(request_queue_t *q, struct request *flush_rq) | 731 | static void sd_prepare_flush(request_queue_t *q, struct request *rq) |
747 | { | ||
748 | struct request *rq = flush_rq->end_io_data; | ||
749 | struct scsi_cmnd *cmd = rq->special; | ||
750 | unsigned int bytes = rq->hard_nr_sectors << 9; | ||
751 | |||
752 | if (!flush_rq->errors) { | ||
753 | spin_unlock(q->queue_lock); | ||
754 | scsi_io_completion(cmd, bytes, 0); | ||
755 | spin_lock(q->queue_lock); | ||
756 | } else if (blk_barrier_postflush(rq)) { | ||
757 | spin_unlock(q->queue_lock); | ||
758 | scsi_io_completion(cmd, 0, bytes); | ||
759 | spin_lock(q->queue_lock); | ||
760 | } else { | ||
761 | /* | ||
762 | * force journal abort of barriers | ||
763 | */ | ||
764 | end_that_request_first(rq, -EOPNOTSUPP, rq->hard_nr_sectors); | ||
765 | end_that_request_last(rq); | ||
766 | } | ||
767 | } | ||
768 | |||
769 | static int sd_prepare_flush(request_queue_t *q, struct request *rq) | ||
770 | { | 732 | { |
771 | struct scsi_device *sdev = q->queuedata; | ||
772 | struct scsi_disk *sdkp = dev_get_drvdata(&sdev->sdev_gendev); | ||
773 | |||
774 | if (!sdkp || !sdkp->WCE) | ||
775 | return 0; | ||
776 | |||
777 | memset(rq->cmd, 0, sizeof(rq->cmd)); | 733 | memset(rq->cmd, 0, sizeof(rq->cmd)); |
778 | rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER; | 734 | rq->flags |= REQ_BLOCK_PC; |
779 | rq->timeout = SD_TIMEOUT; | 735 | rq->timeout = SD_TIMEOUT; |
780 | rq->cmd[0] = SYNCHRONIZE_CACHE; | 736 | rq->cmd[0] = SYNCHRONIZE_CACHE; |
781 | return 1; | 737 | rq->cmd_len = 10; |
782 | } | 738 | } |
783 | 739 | ||
784 | static void sd_rescan(struct device *dev) | 740 | static void sd_rescan(struct device *dev) |
@@ -832,6 +788,7 @@ static struct block_device_operations sd_fops = { | |||
832 | .open = sd_open, | 788 | .open = sd_open, |
833 | .release = sd_release, | 789 | .release = sd_release, |
834 | .ioctl = sd_ioctl, | 790 | .ioctl = sd_ioctl, |
791 | .getgeo = sd_getgeo, | ||
835 | #ifdef CONFIG_COMPAT | 792 | #ifdef CONFIG_COMPAT |
836 | .compat_ioctl = sd_compat_ioctl, | 793 | .compat_ioctl = sd_compat_ioctl, |
837 | #endif | 794 | #endif |
@@ -1441,10 +1398,18 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, | |||
1441 | sdkp->RCD = 0; | 1398 | sdkp->RCD = 0; |
1442 | } | 1399 | } |
1443 | 1400 | ||
1401 | sdkp->DPOFUA = (data.device_specific & 0x10) != 0; | ||
1402 | if (sdkp->DPOFUA && !sdkp->device->use_10_for_rw) { | ||
1403 | printk(KERN_NOTICE "SCSI device %s: uses " | ||
1404 | "READ/WRITE(6), disabling FUA\n", diskname); | ||
1405 | sdkp->DPOFUA = 0; | ||
1406 | } | ||
1407 | |||
1444 | ct = sdkp->RCD + 2*sdkp->WCE; | 1408 | ct = sdkp->RCD + 2*sdkp->WCE; |
1445 | 1409 | ||
1446 | printk(KERN_NOTICE "SCSI device %s: drive cache: %s\n", | 1410 | printk(KERN_NOTICE "SCSI device %s: drive cache: %s%s\n", |
1447 | diskname, types[ct]); | 1411 | diskname, types[ct], |
1412 | sdkp->DPOFUA ? " w/ FUA" : ""); | ||
1448 | 1413 | ||
1449 | return; | 1414 | return; |
1450 | } | 1415 | } |
@@ -1476,6 +1441,7 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
1476 | struct scsi_disk *sdkp = scsi_disk(disk); | 1441 | struct scsi_disk *sdkp = scsi_disk(disk); |
1477 | struct scsi_device *sdp = sdkp->device; | 1442 | struct scsi_device *sdp = sdkp->device; |
1478 | unsigned char *buffer; | 1443 | unsigned char *buffer; |
1444 | unsigned ordered; | ||
1479 | 1445 | ||
1480 | SCSI_LOG_HLQUEUE(3, printk("sd_revalidate_disk: disk=%s\n", disk->disk_name)); | 1446 | SCSI_LOG_HLQUEUE(3, printk("sd_revalidate_disk: disk=%s\n", disk->disk_name)); |
1481 | 1447 | ||
@@ -1509,12 +1475,24 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
1509 | */ | 1475 | */ |
1510 | if (sdkp->media_present) { | 1476 | if (sdkp->media_present) { |
1511 | sd_read_capacity(sdkp, disk->disk_name, buffer); | 1477 | sd_read_capacity(sdkp, disk->disk_name, buffer); |
1512 | if (sdp->removable) | 1478 | sd_read_write_protect_flag(sdkp, disk->disk_name, buffer); |
1513 | sd_read_write_protect_flag(sdkp, disk->disk_name, | ||
1514 | buffer); | ||
1515 | sd_read_cache_type(sdkp, disk->disk_name, buffer); | 1479 | sd_read_cache_type(sdkp, disk->disk_name, buffer); |
1516 | } | 1480 | } |
1517 | 1481 | ||
1482 | /* | ||
1483 | * We now have all cache related info, determine how we deal | ||
1484 | * with ordered requests. Note that as the current SCSI | ||
1485 | * dispatch function can alter request order, we cannot use | ||
1486 | * QUEUE_ORDERED_TAG_* even when ordered tag is supported. | ||
1487 | */ | ||
1488 | if (sdkp->WCE) | ||
1489 | ordered = sdkp->DPOFUA | ||
1490 | ? QUEUE_ORDERED_DRAIN_FUA : QUEUE_ORDERED_DRAIN_FLUSH; | ||
1491 | else | ||
1492 | ordered = QUEUE_ORDERED_DRAIN; | ||
1493 | |||
1494 | blk_queue_ordered(sdkp->disk->queue, ordered, sd_prepare_flush); | ||
1495 | |||
1518 | set_capacity(disk, sdkp->capacity); | 1496 | set_capacity(disk, sdkp->capacity); |
1519 | kfree(buffer); | 1497 | kfree(buffer); |
1520 | 1498 | ||
@@ -1614,6 +1592,7 @@ static int sd_probe(struct device *dev) | |||
1614 | strcpy(gd->devfs_name, sdp->devfs_name); | 1592 | strcpy(gd->devfs_name, sdp->devfs_name); |
1615 | 1593 | ||
1616 | gd->private_data = &sdkp->driver; | 1594 | gd->private_data = &sdkp->driver; |
1595 | gd->queue = sdkp->device->request_queue; | ||
1617 | 1596 | ||
1618 | sd_revalidate_disk(gd); | 1597 | sd_revalidate_disk(gd); |
1619 | 1598 | ||
@@ -1621,7 +1600,6 @@ static int sd_probe(struct device *dev) | |||
1621 | gd->flags = GENHD_FL_DRIVERFS; | 1600 | gd->flags = GENHD_FL_DRIVERFS; |
1622 | if (sdp->removable) | 1601 | if (sdp->removable) |
1623 | gd->flags |= GENHD_FL_REMOVABLE; | 1602 | gd->flags |= GENHD_FL_REMOVABLE; |
1624 | gd->queue = sdkp->device->request_queue; | ||
1625 | 1603 | ||
1626 | dev_set_drvdata(dev, sdkp); | 1604 | dev_set_drvdata(dev, sdkp); |
1627 | add_disk(gd); | 1605 | add_disk(gd); |