diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-10-18 18:30:58 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-10-18 18:30:58 -0400 |
commit | 77501f3cb648e18733509a951ed31eddd7ef2c0b (patch) | |
tree | 82624caa354394df2422562bf6dda56a2c088704 /drivers/scsi/libata-scsi.c | |
parent | 422fa08e538b649a9b80258950d2f8a202f45f19 (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 617534b7a25e..1ad75d58c30c 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -784,7 +784,7 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
784 | tf->flags |= ATA_TFLAG_DEVICE; | 784 | tf->flags |= ATA_TFLAG_DEVICE; |
785 | tf->protocol = ATA_PROT_NODATA; | 785 | tf->protocol = ATA_PROT_NODATA; |
786 | 786 | ||
787 | if ((tf->flags & ATA_TFLAG_LBA48) && | 787 | if ((qc->dev->flags & ATA_DFLAG_LBA48) && |
788 | (ata_id_has_flush_ext(qc->dev->id))) | 788 | (ata_id_has_flush_ext(qc->dev->id))) |
789 | tf->command = ATA_CMD_FLUSH_EXT; | 789 | tf->command = ATA_CMD_FLUSH_EXT; |
790 | else | 790 | else |
@@ -904,8 +904,6 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
904 | { | 904 | { |
905 | struct ata_taskfile *tf = &qc->tf; | 905 | struct ata_taskfile *tf = &qc->tf; |
906 | struct ata_device *dev = qc->dev; | 906 | struct ata_device *dev = qc->dev; |
907 | unsigned int lba = tf->flags & ATA_TFLAG_LBA; | ||
908 | unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48; | ||
909 | u64 dev_sectors = qc->dev->n_sectors; | 907 | u64 dev_sectors = qc->dev->n_sectors; |
910 | u64 block; | 908 | u64 block; |
911 | u32 n_block; | 909 | u32 n_block; |
@@ -926,16 +924,16 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
926 | goto out_of_range; | 924 | goto out_of_range; |
927 | if ((block + n_block) > dev_sectors) | 925 | if ((block + n_block) > dev_sectors) |
928 | goto out_of_range; | 926 | goto out_of_range; |
929 | if (lba48) { | ||
930 | if (n_block > (64 * 1024)) | ||
931 | goto invalid_fld; | ||
932 | } else { | ||
933 | if (n_block > 256) | ||
934 | goto invalid_fld; | ||
935 | } | ||
936 | 927 | ||
937 | if (lba) { | 928 | if (dev->flags & ATA_DFLAG_LBA) { |
938 | if (lba48) { | 929 | tf->flags |= ATA_TFLAG_LBA; |
930 | |||
931 | if (dev->flags & ATA_DFLAG_LBA48) { | ||
932 | if (n_block > (64 * 1024)) | ||
933 | goto invalid_fld; | ||
934 | |||
935 | /* use LBA48 */ | ||
936 | tf->flags |= ATA_TFLAG_LBA48; | ||
939 | tf->command = ATA_CMD_VERIFY_EXT; | 937 | tf->command = ATA_CMD_VERIFY_EXT; |
940 | 938 | ||
941 | tf->hob_nsect = (n_block >> 8) & 0xff; | 939 | tf->hob_nsect = (n_block >> 8) & 0xff; |
@@ -944,6 +942,10 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
944 | tf->hob_lbam = (block >> 32) & 0xff; | 942 | tf->hob_lbam = (block >> 32) & 0xff; |
945 | tf->hob_lbal = (block >> 24) & 0xff; | 943 | tf->hob_lbal = (block >> 24) & 0xff; |
946 | } else { | 944 | } else { |
945 | if (n_block > 256) | ||
946 | goto invalid_fld; | ||
947 | |||
948 | /* use LBA28 */ | ||
947 | tf->command = ATA_CMD_VERIFY; | 949 | tf->command = ATA_CMD_VERIFY; |
948 | 950 | ||
949 | tf->device |= (block >> 24) & 0xf; | 951 | tf->device |= (block >> 24) & 0xf; |
@@ -960,6 +962,9 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
960 | /* CHS */ | 962 | /* CHS */ |
961 | u32 sect, head, cyl, track; | 963 | u32 sect, head, cyl, track; |
962 | 964 | ||
965 | if (n_block > 256) | ||
966 | goto invalid_fld; | ||
967 | |||
963 | /* Convert LBA to CHS */ | 968 | /* Convert LBA to CHS */ |
964 | track = (u32)block / dev->sectors; | 969 | track = (u32)block / dev->sectors; |
965 | cyl = track / dev->heads; | 970 | cyl = track / dev->heads; |
@@ -1025,21 +1030,14 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
1025 | { | 1030 | { |
1026 | struct ata_taskfile *tf = &qc->tf; | 1031 | struct ata_taskfile *tf = &qc->tf; |
1027 | struct ata_device *dev = qc->dev; | 1032 | struct ata_device *dev = qc->dev; |
1028 | unsigned int lba = tf->flags & ATA_TFLAG_LBA; | ||
1029 | unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48; | ||
1030 | u64 block; | 1033 | u64 block; |
1031 | u32 n_block; | 1034 | u32 n_block; |
1032 | 1035 | ||
1033 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | 1036 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; |
1034 | tf->protocol = qc->dev->xfer_protocol; | ||
1035 | 1037 | ||
1036 | if (scsicmd[0] == READ_10 || scsicmd[0] == READ_6 || | 1038 | if (scsicmd[0] == WRITE_10 || scsicmd[0] == WRITE_6 || |
1037 | scsicmd[0] == READ_16) { | 1039 | scsicmd[0] == WRITE_16) |
1038 | tf->command = qc->dev->read_cmd; | ||
1039 | } else { | ||
1040 | tf->command = qc->dev->write_cmd; | ||
1041 | tf->flags |= ATA_TFLAG_WRITE; | 1040 | tf->flags |= ATA_TFLAG_WRITE; |
1042 | } | ||
1043 | 1041 | ||
1044 | /* Calculate the SCSI LBA and transfer length. */ | 1042 | /* Calculate the SCSI LBA and transfer length. */ |
1045 | switch (scsicmd[0]) { | 1043 | switch (scsicmd[0]) { |
@@ -1075,19 +1073,24 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
1075 | */ | 1073 | */ |
1076 | goto nothing_to_do; | 1074 | goto nothing_to_do; |
1077 | 1075 | ||
1078 | if (lba) { | 1076 | if (dev->flags & ATA_DFLAG_LBA) { |
1079 | if (lba48) { | 1077 | tf->flags |= ATA_TFLAG_LBA; |
1078 | |||
1079 | if (dev->flags & ATA_DFLAG_LBA48) { | ||
1080 | /* The request -may- be too large for LBA48. */ | 1080 | /* The request -may- be too large for LBA48. */ |
1081 | if ((block >> 48) || (n_block > 65536)) | 1081 | if ((block >> 48) || (n_block > 65536)) |
1082 | goto out_of_range; | 1082 | goto out_of_range; |
1083 | 1083 | ||
1084 | /* use LBA48 */ | ||
1085 | tf->flags |= ATA_TFLAG_LBA48; | ||
1086 | |||
1084 | tf->hob_nsect = (n_block >> 8) & 0xff; | 1087 | tf->hob_nsect = (n_block >> 8) & 0xff; |
1085 | 1088 | ||
1086 | tf->hob_lbah = (block >> 40) & 0xff; | 1089 | tf->hob_lbah = (block >> 40) & 0xff; |
1087 | tf->hob_lbam = (block >> 32) & 0xff; | 1090 | tf->hob_lbam = (block >> 32) & 0xff; |
1088 | tf->hob_lbal = (block >> 24) & 0xff; | 1091 | tf->hob_lbal = (block >> 24) & 0xff; |
1089 | } else { | 1092 | } else { |
1090 | /* LBA28 */ | 1093 | /* use LBA28 */ |
1091 | 1094 | ||
1092 | /* The request -may- be too large for LBA28. */ | 1095 | /* The request -may- be too large for LBA28. */ |
1093 | if ((block >> 28) || (n_block > 256)) | 1096 | if ((block >> 28) || (n_block > 256)) |
@@ -1096,6 +1099,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
1096 | tf->device |= (block >> 24) & 0xf; | 1099 | tf->device |= (block >> 24) & 0xf; |
1097 | } | 1100 | } |
1098 | 1101 | ||
1102 | ata_rwcmd_protocol(qc); | ||
1103 | |||
1099 | qc->nsect = n_block; | 1104 | qc->nsect = n_block; |
1100 | tf->nsect = n_block & 0xff; | 1105 | tf->nsect = n_block & 0xff; |
1101 | 1106 | ||
@@ -1112,6 +1117,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
1112 | if ((block >> 28) || (n_block > 256)) | 1117 | if ((block >> 28) || (n_block > 256)) |
1113 | goto out_of_range; | 1118 | goto out_of_range; |
1114 | 1119 | ||
1120 | ata_rwcmd_protocol(qc); | ||
1121 | |||
1115 | /* Convert LBA to CHS */ | 1122 | /* Convert LBA to CHS */ |
1116 | track = (u32)block / dev->sectors; | 1123 | track = (u32)block / dev->sectors; |
1117 | cyl = track / dev->heads; | 1124 | cyl = track / dev->heads; |