|
@@ -985,9 +985,13 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc
|
|
if (dev->flags & ATA_DFLAG_LBA) {
|
|
if (dev->flags & ATA_DFLAG_LBA) {
|
|
tf->flags |= ATA_TFLAG_LBA;
|
|
tf->flags |= ATA_TFLAG_LBA;
|
|
|
|
|
|
- if (dev->flags & ATA_DFLAG_LBA48) {
|
|
|
|
- if (n_block > (64 * 1024))
|
|
|
|
- goto invalid_fld;
|
|
|
|
|
|
+ if (lba_28_ok(block, n_block)) {
|
|
|
|
+ /* use LBA28 */
|
|
|
|
+ tf->command = ATA_CMD_VERIFY;
|
|
|
|
+ tf->device |= (block >> 24) & 0xf;
|
|
|
|
+ } else if (lba_48_ok(block, n_block)) {
|
|
|
|
+ if (!(dev->flags & ATA_DFLAG_LBA48))
|
|
|
|
+ goto out_of_range;
|
|
|
|
|
|
/* use LBA48 */
|
|
/* use LBA48 */
|
|
tf->flags |= ATA_TFLAG_LBA48;
|
|
tf->flags |= ATA_TFLAG_LBA48;
|
|
@@ -998,15 +1002,9 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc
|
|
tf->hob_lbah = (block >> 40) & 0xff;
|
|
tf->hob_lbah = (block >> 40) & 0xff;
|
|
tf->hob_lbam = (block >> 32) & 0xff;
|
|
tf->hob_lbam = (block >> 32) & 0xff;
|
|
tf->hob_lbal = (block >> 24) & 0xff;
|
|
tf->hob_lbal = (block >> 24) & 0xff;
|
|
- } else {
|
|
|
|
- if (n_block > 256)
|
|
|
|
- goto invalid_fld;
|
|
|
|
-
|
|
|
|
- /* use LBA28 */
|
|
|
|
- tf->command = ATA_CMD_VERIFY;
|
|
|
|
-
|
|
|
|
- tf->device |= (block >> 24) & 0xf;
|
|
|
|
- }
|
|
|
|
|
|
+ } else
|
|
|
|
+ /* request too large even for LBA48 */
|
|
|
|
+ goto out_of_range;
|
|
|
|
|
|
tf->nsect = n_block & 0xff;
|
|
tf->nsect = n_block & 0xff;
|
|
|
|
|
|
@@ -1019,8 +1017,8 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc
|
|
/* CHS */
|
|
/* CHS */
|
|
u32 sect, head, cyl, track;
|
|
u32 sect, head, cyl, track;
|
|
|
|
|
|
- if (n_block > 256)
|
|
|
|
- goto invalid_fld;
|
|
|
|
|
|
+ if (!lba_28_ok(block, n_block))
|
|
|
|
+ goto out_of_range;
|
|
|
|
|
|
/* Convert LBA to CHS */
|
|
/* Convert LBA to CHS */
|
|
track = (u32)block / dev->sectors;
|
|
track = (u32)block / dev->sectors;
|
|
@@ -1139,9 +1137,11 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
|
|
if (dev->flags & ATA_DFLAG_LBA) {
|
|
if (dev->flags & ATA_DFLAG_LBA) {
|
|
tf->flags |= ATA_TFLAG_LBA;
|
|
tf->flags |= ATA_TFLAG_LBA;
|
|
|
|
|
|
- if (dev->flags & ATA_DFLAG_LBA48) {
|
|
|
|
- /* The request -may- be too large for LBA48. */
|
|
|
|
- if ((block >> 48) || (n_block > 65536))
|
|
|
|
|
|
+ if (lba_28_ok(block, n_block)) {
|
|
|
|
+ /* use LBA28 */
|
|
|
|
+ tf->device |= (block >> 24) & 0xf;
|
|
|
|
+ } else if (lba_48_ok(block, n_block)) {
|
|
|
|
+ if (!(dev->flags & ATA_DFLAG_LBA48))
|
|
goto out_of_range;
|
|
goto out_of_range;
|
|
|
|
|
|
/* use LBA48 */
|
|
/* use LBA48 */
|
|
@@ -1152,15 +1152,9 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
|
|
tf->hob_lbah = (block >> 40) & 0xff;
|
|
tf->hob_lbah = (block >> 40) & 0xff;
|
|
tf->hob_lbam = (block >> 32) & 0xff;
|
|
tf->hob_lbam = (block >> 32) & 0xff;
|
|
tf->hob_lbal = (block >> 24) & 0xff;
|
|
tf->hob_lbal = (block >> 24) & 0xff;
|
|
- } else {
|
|
|
|
- /* use LBA28 */
|
|
|
|
-
|
|
|
|
- /* The request -may- be too large for LBA28. */
|
|
|
|
- if ((block >> 28) || (n_block > 256))
|
|
|
|
- goto out_of_range;
|
|
|
|
-
|
|
|
|
- tf->device |= (block >> 24) & 0xf;
|
|
|
|
- }
|
|
|
|
|
|
+ } else
|
|
|
|
+ /* request too large even for LBA48 */
|
|
|
|
+ goto out_of_range;
|
|
|
|
|
|
if (unlikely(ata_rwcmd_protocol(qc) < 0))
|
|
if (unlikely(ata_rwcmd_protocol(qc) < 0))
|
|
goto invalid_fld;
|
|
goto invalid_fld;
|
|
@@ -1178,7 +1172,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
|
|
u32 sect, head, cyl, track;
|
|
u32 sect, head, cyl, track;
|
|
|
|
|
|
/* The request -may- be too large for CHS addressing. */
|
|
/* The request -may- be too large for CHS addressing. */
|
|
- if ((block >> 28) || (n_block > 256))
|
|
|
|
|
|
+ if (!lba_28_ok(block, n_block))
|
|
goto out_of_range;
|
|
goto out_of_range;
|
|
|
|
|
|
if (unlikely(ata_rwcmd_protocol(qc) < 0))
|
|
if (unlikely(ata_rwcmd_protocol(qc) < 0))
|