aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-scsi.c
diff options
context:
space:
mode:
authorAlbert Lee <albertcc@tw.ibm.com>2005-10-12 03:12:26 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-10-18 17:18:16 -0400
commitc6a33e2464edd87f8c12cc2d11369a5b44c65b77 (patch)
treef15eb374fa98fb1f76bf3a7cffd9cb8ef7173091 /drivers/scsi/libata-scsi.c
parent59a10b172fccaea793352c00fd9065f0a5b4ef70 (diff)
[PATCH] libata CHS: LBA28/LBA48 optimization (revise #6)
- add lba_28_ok() and lba_48_ok() to ata.h. - check ending block number instead of staring block number. - use lba_28_ok() for CHS range check - LBA28/LBA48 optimization Suggested by Mark Lord and Alan Cox. Signed-off-by: Albert Lee <albertcc@tw.ibm.com> ===== Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/scsi/libata-scsi.c')
-rw-r--r--drivers/scsi/libata-scsi.c48
1 files changed, 21 insertions, 27 deletions
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 90bf22204668..efbe6fe65442 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -636,9 +636,13 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
636 if (dev->flags & ATA_DFLAG_LBA) { 636 if (dev->flags & ATA_DFLAG_LBA) {
637 tf->flags |= ATA_TFLAG_LBA; 637 tf->flags |= ATA_TFLAG_LBA;
638 638
639 if (dev->flags & ATA_DFLAG_LBA48) { 639 if (lba_28_ok(block, n_block)) {
640 if (n_block > (64 * 1024)) 640 /* use LBA28 */
641 goto invalid_fld; 641 tf->command = ATA_CMD_VERIFY;
642 tf->device |= (block >> 24) & 0xf;
643 } else if (lba_48_ok(block, n_block)) {
644 if (!(dev->flags & ATA_DFLAG_LBA48))
645 goto out_of_range;
642 646
643 /* use LBA48 */ 647 /* use LBA48 */
644 tf->flags |= ATA_TFLAG_LBA48; 648 tf->flags |= ATA_TFLAG_LBA48;
@@ -649,15 +653,9 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
649 tf->hob_lbah = (block >> 40) & 0xff; 653 tf->hob_lbah = (block >> 40) & 0xff;
650 tf->hob_lbam = (block >> 32) & 0xff; 654 tf->hob_lbam = (block >> 32) & 0xff;
651 tf->hob_lbal = (block >> 24) & 0xff; 655 tf->hob_lbal = (block >> 24) & 0xff;
652 } else { 656 } else
653 if (n_block > 256) 657 /* request too large even for LBA48 */
654 goto invalid_fld; 658 goto out_of_range;
655
656 /* use LBA28 */
657 tf->command = ATA_CMD_VERIFY;
658
659 tf->device |= (block >> 24) & 0xf;
660 }
661 659
662 tf->nsect = n_block & 0xff; 660 tf->nsect = n_block & 0xff;
663 661
@@ -670,8 +668,8 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
670 /* CHS */ 668 /* CHS */
671 u32 sect, head, cyl, track; 669 u32 sect, head, cyl, track;
672 670
673 if (n_block > 256) 671 if (!lba_28_ok(block, n_block))
674 goto invalid_fld; 672 goto out_of_range;
675 673
676 /* Convert LBA to CHS */ 674 /* Convert LBA to CHS */
677 track = (u32)block / dev->sectors; 675 track = (u32)block / dev->sectors;
@@ -784,9 +782,11 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
784 if (dev->flags & ATA_DFLAG_LBA) { 782 if (dev->flags & ATA_DFLAG_LBA) {
785 tf->flags |= ATA_TFLAG_LBA; 783 tf->flags |= ATA_TFLAG_LBA;
786 784
787 if (dev->flags & ATA_DFLAG_LBA48) { 785 if (lba_28_ok(block, n_block)) {
788 /* The request -may- be too large for LBA48. */ 786 /* use LBA28 */
789 if ((block >> 48) || (n_block > 65536)) 787 tf->device |= (block >> 24) & 0xf;
788 } else if (lba_48_ok(block, n_block)) {
789 if (!(dev->flags & ATA_DFLAG_LBA48))
790 goto out_of_range; 790 goto out_of_range;
791 791
792 /* use LBA48 */ 792 /* use LBA48 */
@@ -797,15 +797,9 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
797 tf->hob_lbah = (block >> 40) & 0xff; 797 tf->hob_lbah = (block >> 40) & 0xff;
798 tf->hob_lbam = (block >> 32) & 0xff; 798 tf->hob_lbam = (block >> 32) & 0xff;
799 tf->hob_lbal = (block >> 24) & 0xff; 799 tf->hob_lbal = (block >> 24) & 0xff;
800 } else { 800 } else
801 /* use LBA28 */ 801 /* request too large even for LBA48 */
802 802 goto out_of_range;
803 /* The request -may- be too large for LBA28. */
804 if ((block >> 28) || (n_block > 256))
805 goto out_of_range;
806
807 tf->device |= (block >> 24) & 0xf;
808 }
809 803
810 ata_rwcmd_protocol(qc); 804 ata_rwcmd_protocol(qc);
811 805
@@ -822,7 +816,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
822 u32 sect, head, cyl, track; 816 u32 sect, head, cyl, track;
823 817
824 /* The request -may- be too large for CHS addressing. */ 818 /* The request -may- be too large for CHS addressing. */
825 if ((block >> 28) || (n_block > 256)) 819 if (!lba_28_ok(block, n_block))
826 goto out_of_range; 820 goto out_of_range;
827 821
828 ata_rwcmd_protocol(qc); 822 ata_rwcmd_protocol(qc);