Commit 35cfc45c authored by Jeff Garzik's avatar Jeff Garzik

Merge branch 'lba48-opt'

parents 8a6d498e 0825788f
...@@ -985,9 +985,13 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc ...@@ -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 (lba_28_ok(block, n_block)) {
if (n_block > (64 * 1024)) /* use LBA28 */
goto invalid_fld; 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 ...@@ -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 { } else
if (n_block > 256) /* request too large even for LBA48 */
goto invalid_fld; goto out_of_range;
/* use LBA28 */
tf->command = ATA_CMD_VERIFY;
tf->device |= (block >> 24) & 0xf;
}
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 ...@@ -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) if (!lba_28_ok(block, n_block))
goto invalid_fld; 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 ...@@ -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) { if (lba_28_ok(block, n_block)) {
/* The request -may- be too large for LBA48. */ /* use LBA28 */
if ((block >> 48) || (n_block > 65536)) 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 ...@@ -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 { } else
/* use LBA28 */ /* request too large even for LBA48 */
goto out_of_range;
/* The request -may- be too large for LBA28. */
if ((block >> 28) || (n_block > 256))
goto out_of_range;
tf->device |= (block >> 24) & 0xf;
}
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 ...@@ -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))
......
...@@ -302,4 +302,16 @@ static inline int ata_ok(u8 status) ...@@ -302,4 +302,16 @@ static inline int ata_ok(u8 status)
== ATA_DRDY); == ATA_DRDY);
} }
static inline int lba_28_ok(u64 block, u32 n_block)
{
/* check the ending block number */
return ((block + n_block - 1) < ((u64)1 << 28)) && (n_block <= 256);
}
static inline int lba_48_ok(u64 block, u32 n_block)
{
/* check the ending block number */
return ((block + n_block - 1) < ((u64)1 << 48)) && (n_block <= 65536);
}
#endif /* __LINUX_ATA_H__ */ #endif /* __LINUX_ATA_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment