diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-10-18 21:52:42 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-10-18 21:52:42 -0400 |
commit | b194b4250c2b7e9d762823ac6045316fcd4bf4f9 (patch) | |
tree | 8c54b5004822958ef0a7603e76a4868582e26d7f /drivers/scsi/libata-scsi.c | |
parent | c4052da6f0c01a0b059d125d72bb934d0980b798 (diff) | |
parent | 59a10b172fccaea793352c00fd9065f0a5b4ef70 (diff) |
Merge branch 'upstream'
Diffstat (limited to 'drivers/scsi/libata-scsi.c')
-rw-r--r-- | drivers/scsi/libata-scsi.c | 55 |
1 files changed, 31 insertions, 24 deletions
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 4cf43de4060e..9944adbe5a1d 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -502,7 +502,7 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
502 | tf->flags |= ATA_TFLAG_DEVICE; | 502 | tf->flags |= ATA_TFLAG_DEVICE; |
503 | tf->protocol = ATA_PROT_NODATA; | 503 | tf->protocol = ATA_PROT_NODATA; |
504 | 504 | ||
505 | if ((tf->flags & ATA_TFLAG_LBA48) && | 505 | if ((qc->dev->flags & ATA_DFLAG_LBA48) && |
506 | (ata_id_has_flush_ext(qc->dev->id))) | 506 | (ata_id_has_flush_ext(qc->dev->id))) |
507 | tf->command = ATA_CMD_FLUSH_EXT; | 507 | tf->command = ATA_CMD_FLUSH_EXT; |
508 | else | 508 | else |
@@ -622,8 +622,6 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
622 | { | 622 | { |
623 | struct ata_taskfile *tf = &qc->tf; | 623 | struct ata_taskfile *tf = &qc->tf; |
624 | struct ata_device *dev = qc->dev; | 624 | struct ata_device *dev = qc->dev; |
625 | unsigned int lba = tf->flags & ATA_TFLAG_LBA; | ||
626 | unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48; | ||
627 | u64 dev_sectors = qc->dev->n_sectors; | 625 | u64 dev_sectors = qc->dev->n_sectors; |
628 | u64 block; | 626 | u64 block; |
629 | u32 n_block; | 627 | u32 n_block; |
@@ -644,16 +642,16 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
644 | goto out_of_range; | 642 | goto out_of_range; |
645 | if ((block + n_block) > dev_sectors) | 643 | if ((block + n_block) > dev_sectors) |
646 | goto out_of_range; | 644 | goto out_of_range; |
647 | if (lba48) { | ||
648 | if (n_block > (64 * 1024)) | ||
649 | goto invalid_fld; | ||
650 | } else { | ||
651 | if (n_block > 256) | ||
652 | goto invalid_fld; | ||
653 | } | ||
654 | 645 | ||
655 | if (lba) { | 646 | if (dev->flags & ATA_DFLAG_LBA) { |
656 | if (lba48) { | 647 | tf->flags |= ATA_TFLAG_LBA; |
648 | |||
649 | if (dev->flags & ATA_DFLAG_LBA48) { | ||
650 | if (n_block > (64 * 1024)) | ||
651 | goto invalid_fld; | ||
652 | |||
653 | /* use LBA48 */ | ||
654 | tf->flags |= ATA_TFLAG_LBA48; | ||
657 | tf->command = ATA_CMD_VERIFY_EXT; | 655 | tf->command = ATA_CMD_VERIFY_EXT; |
658 | 656 | ||
659 | tf->hob_nsect = (n_block >> 8) & 0xff; | 657 | tf->hob_nsect = (n_block >> 8) & 0xff; |
@@ -662,6 +660,10 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
662 | tf->hob_lbam = (block >> 32) & 0xff; | 660 | tf->hob_lbam = (block >> 32) & 0xff; |
663 | tf->hob_lbal = (block >> 24) & 0xff; | 661 | tf->hob_lbal = (block >> 24) & 0xff; |
664 | } else { | 662 | } else { |
663 | if (n_block > 256) | ||
664 | goto invalid_fld; | ||
665 | |||
666 | /* use LBA28 */ | ||
665 | tf->command = ATA_CMD_VERIFY; | 667 | tf->command = ATA_CMD_VERIFY; |
666 | 668 | ||
667 | tf->device |= (block >> 24) & 0xf; | 669 | tf->device |= (block >> 24) & 0xf; |
@@ -678,6 +680,9 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
678 | /* CHS */ | 680 | /* CHS */ |
679 | u32 sect, head, cyl, track; | 681 | u32 sect, head, cyl, track; |
680 | 682 | ||
683 | if (n_block > 256) | ||
684 | goto invalid_fld; | ||
685 | |||
681 | /* Convert LBA to CHS */ | 686 | /* Convert LBA to CHS */ |
682 | track = (u32)block / dev->sectors; | 687 | track = (u32)block / dev->sectors; |
683 | cyl = track / dev->heads; | 688 | cyl = track / dev->heads; |
@@ -743,21 +748,14 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
743 | { | 748 | { |
744 | struct ata_taskfile *tf = &qc->tf; | 749 | struct ata_taskfile *tf = &qc->tf; |
745 | struct ata_device *dev = qc->dev; | 750 | struct ata_device *dev = qc->dev; |
746 | unsigned int lba = tf->flags & ATA_TFLAG_LBA; | ||
747 | unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48; | ||
748 | u64 block; | 751 | u64 block; |
749 | u32 n_block; | 752 | u32 n_block; |
750 | 753 | ||
751 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | 754 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; |
752 | tf->protocol = qc->dev->xfer_protocol; | ||
753 | 755 | ||
754 | if (scsicmd[0] == READ_10 || scsicmd[0] == READ_6 || | 756 | if (scsicmd[0] == WRITE_10 || scsicmd[0] == WRITE_6 || |
755 | scsicmd[0] == READ_16) { | 757 | scsicmd[0] == WRITE_16) |
756 | tf->command = qc->dev->read_cmd; | ||
757 | } else { | ||
758 | tf->command = qc->dev->write_cmd; | ||
759 | tf->flags |= ATA_TFLAG_WRITE; | 758 | tf->flags |= ATA_TFLAG_WRITE; |
760 | } | ||
761 | 759 | ||
762 | /* Calculate the SCSI LBA and transfer length. */ | 760 | /* Calculate the SCSI LBA and transfer length. */ |
763 | switch (scsicmd[0]) { | 761 | switch (scsicmd[0]) { |
@@ -793,19 +791,24 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
793 | */ | 791 | */ |
794 | goto nothing_to_do; | 792 | goto nothing_to_do; |
795 | 793 | ||
796 | if (lba) { | 794 | if (dev->flags & ATA_DFLAG_LBA) { |
797 | if (lba48) { | 795 | tf->flags |= ATA_TFLAG_LBA; |
796 | |||
797 | if (dev->flags & ATA_DFLAG_LBA48) { | ||
798 | /* The request -may- be too large for LBA48. */ | 798 | /* The request -may- be too large for LBA48. */ |
799 | if ((block >> 48) || (n_block > 65536)) | 799 | if ((block >> 48) || (n_block > 65536)) |
800 | goto out_of_range; | 800 | goto out_of_range; |
801 | 801 | ||
802 | /* use LBA48 */ | ||
803 | tf->flags |= ATA_TFLAG_LBA48; | ||
804 | |||
802 | tf->hob_nsect = (n_block >> 8) & 0xff; | 805 | tf->hob_nsect = (n_block >> 8) & 0xff; |
803 | 806 | ||
804 | tf->hob_lbah = (block >> 40) & 0xff; | 807 | tf->hob_lbah = (block >> 40) & 0xff; |
805 | tf->hob_lbam = (block >> 32) & 0xff; | 808 | tf->hob_lbam = (block >> 32) & 0xff; |
806 | tf->hob_lbal = (block >> 24) & 0xff; | 809 | tf->hob_lbal = (block >> 24) & 0xff; |
807 | } else { | 810 | } else { |
808 | /* LBA28 */ | 811 | /* use LBA28 */ |
809 | 812 | ||
810 | /* The request -may- be too large for LBA28. */ | 813 | /* The request -may- be too large for LBA28. */ |
811 | if ((block >> 28) || (n_block > 256)) | 814 | if ((block >> 28) || (n_block > 256)) |
@@ -814,6 +817,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
814 | tf->device |= (block >> 24) & 0xf; | 817 | tf->device |= (block >> 24) & 0xf; |
815 | } | 818 | } |
816 | 819 | ||
820 | ata_rwcmd_protocol(qc); | ||
821 | |||
817 | qc->nsect = n_block; | 822 | qc->nsect = n_block; |
818 | tf->nsect = n_block & 0xff; | 823 | tf->nsect = n_block & 0xff; |
819 | 824 | ||
@@ -830,6 +835,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
830 | if ((block >> 28) || (n_block > 256)) | 835 | if ((block >> 28) || (n_block > 256)) |
831 | goto out_of_range; | 836 | goto out_of_range; |
832 | 837 | ||
838 | ata_rwcmd_protocol(qc); | ||
839 | |||
833 | /* Convert LBA to CHS */ | 840 | /* Convert LBA to CHS */ |
834 | track = (u32)block / dev->sectors; | 841 | track = (u32)block / dev->sectors; |
835 | cyl = track / dev->heads; | 842 | cyl = track / dev->heads; |