aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sd.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 12:01:25 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 12:01:25 -0500
commitd99cf9d679a520d67f81d805b7cb91c68e1847f0 (patch)
tree415aefe6d168df27c006fcc53b1ea5242eabaaea /drivers/scsi/sd.c
parent7ed40918a386afc2e14a6d3da563ea6d13686c25 (diff)
parente650c305ec3178818b317dad37a6d9c7fa8ba28d (diff)
Merge branch 'post-2.6.15' of git://brick.kernel.dk/data/git/linux-2.6-block
Manual fixup for merge with Jens' "Suspend support for libata", commit ID 9b847548663ef1039dd49f0eb4463d001e596bc3. Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r--drivers/scsi/sd.c85
1 files changed, 45 insertions, 40 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 3d3ad7d1b77..32d4d8d7b9f 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
107static DEFINE_IDR(sd_index_idr); 108static DEFINE_IDR(sd_index_idr);
@@ -121,8 +122,7 @@ static void sd_shutdown(struct device *dev);
121static void sd_rescan(struct device *); 122static void sd_rescan(struct device *);
122static int sd_init_command(struct scsi_cmnd *); 123static int sd_init_command(struct scsi_cmnd *);
123static int sd_issue_flush(struct device *, sector_t *); 124static int sd_issue_flush(struct device *, sector_t *);
124static void sd_end_flush(request_queue_t *, struct request *); 125static void sd_prepare_flush(request_queue_t *, struct request *);
125static int sd_prepare_flush(request_queue_t *, struct request *);
126static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname, 126static 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/*
@@ -346,6 +344,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
346 344
347 if (block > 0xffffffff) { 345 if (block > 0xffffffff) {
348 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;
349 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;
350 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;
351 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;
@@ -365,6 +364,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
365 this_count = 0xffff; 364 this_count = 0xffff;
366 365
367 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;
368 SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff; 368 SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff;
369 SCpnt->cmnd[3] = (unsigned char) (block >> 16) & 0xff; 369 SCpnt->cmnd[3] = (unsigned char) (block >> 16) & 0xff;
370 SCpnt->cmnd[4] = (unsigned char) (block >> 8) & 0xff; 370 SCpnt->cmnd[4] = (unsigned char) (block >> 8) & 0xff;
@@ -373,6 +373,17 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
373 SCpnt->cmnd[7] = (unsigned char) (this_count >> 8) & 0xff; 373 SCpnt->cmnd[7] = (unsigned char) (this_count >> 8) & 0xff;
374 SCpnt->cmnd[8] = (unsigned char) this_count & 0xff; 374 SCpnt->cmnd[8] = (unsigned char) this_count & 0xff;
375 } 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
376 SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f); 387 SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f);
377 SCpnt->cmnd[2] = (unsigned char) ((block >> 8) & 0xff); 388 SCpnt->cmnd[2] = (unsigned char) ((block >> 8) & 0xff);
378 SCpnt->cmnd[3] = (unsigned char) block & 0xff; 389 SCpnt->cmnd[3] = (unsigned char) block & 0xff;
@@ -729,42 +740,13 @@ static int sd_issue_flush(struct device *dev, sector_t *error_sector)
729 return ret; 740 return ret;
730} 741}
731 742
732static void sd_end_flush(request_queue_t *q, struct request *flush_rq) 743static void sd_prepare_flush(request_queue_t *q, struct request *rq)
733{
734 struct request *rq = flush_rq->end_io_data;
735 struct scsi_cmnd *cmd = rq->special;
736 unsigned int bytes = rq->hard_nr_sectors << 9;
737
738 if (!flush_rq->errors) {
739 spin_unlock(q->queue_lock);
740 scsi_io_completion(cmd, bytes, 0);
741 spin_lock(q->queue_lock);
742 } else if (blk_barrier_postflush(rq)) {
743 spin_unlock(q->queue_lock);
744 scsi_io_completion(cmd, 0, bytes);
745 spin_lock(q->queue_lock);
746 } else {
747 /*
748 * force journal abort of barriers
749 */
750 end_that_request_first(rq, -EOPNOTSUPP, rq->hard_nr_sectors);
751 end_that_request_last(rq);
752 }
753}
754
755static int sd_prepare_flush(request_queue_t *q, struct request *rq)
756{ 744{
757 struct scsi_device *sdev = q->queuedata;
758 struct scsi_disk *sdkp = dev_get_drvdata(&sdev->sdev_gendev);
759
760 if (!sdkp || !sdkp->WCE)
761 return 0;
762
763 memset(rq->cmd, 0, sizeof(rq->cmd)); 745 memset(rq->cmd, 0, sizeof(rq->cmd));
764 rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER; 746 rq->flags |= REQ_BLOCK_PC;
765 rq->timeout = SD_TIMEOUT; 747 rq->timeout = SD_TIMEOUT;
766 rq->cmd[0] = SYNCHRONIZE_CACHE; 748 rq->cmd[0] = SYNCHRONIZE_CACHE;
767 return 1; 749 rq->cmd_len = 10;
768} 750}
769 751
770static void sd_rescan(struct device *dev) 752static void sd_rescan(struct device *dev)
@@ -1427,10 +1409,18 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
1427 sdkp->RCD = 0; 1409 sdkp->RCD = 0;
1428 } 1410 }
1429 1411
1412 sdkp->DPOFUA = (data.device_specific & 0x10) != 0;
1413 if (sdkp->DPOFUA && !sdkp->device->use_10_for_rw) {
1414 printk(KERN_NOTICE "SCSI device %s: uses "
1415 "READ/WRITE(6), disabling FUA\n", diskname);
1416 sdkp->DPOFUA = 0;
1417 }
1418
1430 ct = sdkp->RCD + 2*sdkp->WCE; 1419 ct = sdkp->RCD + 2*sdkp->WCE;
1431 1420
1432 printk(KERN_NOTICE "SCSI device %s: drive cache: %s\n", 1421 printk(KERN_NOTICE "SCSI device %s: drive cache: %s%s\n",
1433 diskname, types[ct]); 1422 diskname, types[ct],
1423 sdkp->DPOFUA ? " w/ FUA" : "");
1434 1424
1435 return; 1425 return;
1436 } 1426 }
@@ -1462,6 +1452,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
1462 struct scsi_disk *sdkp = scsi_disk(disk); 1452 struct scsi_disk *sdkp = scsi_disk(disk);
1463 struct scsi_device *sdp = sdkp->device; 1453 struct scsi_device *sdp = sdkp->device;
1464 unsigned char *buffer; 1454 unsigned char *buffer;
1455 unsigned ordered;
1465 1456
1466 SCSI_LOG_HLQUEUE(3, printk("sd_revalidate_disk: disk=%s\n", disk->disk_name)); 1457 SCSI_LOG_HLQUEUE(3, printk("sd_revalidate_disk: disk=%s\n", disk->disk_name));
1467 1458
@@ -1498,7 +1489,21 @@ static int sd_revalidate_disk(struct gendisk *disk)
1498 sd_read_write_protect_flag(sdkp, disk->disk_name, buffer); 1489 sd_read_write_protect_flag(sdkp, disk->disk_name, buffer);
1499 sd_read_cache_type(sdkp, disk->disk_name, buffer); 1490 sd_read_cache_type(sdkp, disk->disk_name, buffer);
1500 } 1491 }
1501 1492
1493 /*
1494 * We now have all cache related info, determine how we deal
1495 * with ordered requests. Note that as the current SCSI
1496 * dispatch function can alter request order, we cannot use
1497 * QUEUE_ORDERED_TAG_* even when ordered tag is supported.
1498 */
1499 if (sdkp->WCE)
1500 ordered = sdkp->DPOFUA
1501 ? QUEUE_ORDERED_DRAIN_FUA : QUEUE_ORDERED_DRAIN_FLUSH;
1502 else
1503 ordered = QUEUE_ORDERED_DRAIN;
1504
1505 blk_queue_ordered(sdkp->disk->queue, ordered, sd_prepare_flush);
1506
1502 set_capacity(disk, sdkp->capacity); 1507 set_capacity(disk, sdkp->capacity);
1503 kfree(buffer); 1508 kfree(buffer);
1504 1509
@@ -1598,6 +1603,7 @@ static int sd_probe(struct device *dev)
1598 strcpy(gd->devfs_name, sdp->devfs_name); 1603 strcpy(gd->devfs_name, sdp->devfs_name);
1599 1604
1600 gd->private_data = &sdkp->driver; 1605 gd->private_data = &sdkp->driver;
1606 gd->queue = sdkp->device->request_queue;
1601 1607
1602 sd_revalidate_disk(gd); 1608 sd_revalidate_disk(gd);
1603 1609
@@ -1605,7 +1611,6 @@ static int sd_probe(struct device *dev)
1605 gd->flags = GENHD_FL_DRIVERFS; 1611 gd->flags = GENHD_FL_DRIVERFS;
1606 if (sdp->removable) 1612 if (sdp->removable)
1607 gd->flags |= GENHD_FL_REMOVABLE; 1613 gd->flags |= GENHD_FL_REMOVABLE;
1608 gd->queue = sdkp->device->request_queue;
1609 1614
1610 dev_set_drvdata(dev, sdkp); 1615 dev_set_drvdata(dev, sdkp);
1611 add_disk(gd); 1616 add_disk(gd);