Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

Merge branch 'lba48-opt'

parents 8a6d498e 0825788f
Loading
Loading
Loading
Loading
+21 −27
Original line number Original line Diff line number Diff line
@@ -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
			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
		/* 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
	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,16 +1152,10 @@ 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 */

			/* The request -may- be too large for LBA28. */
			if ((block >> 28) || (n_block > 256))
			goto out_of_range;
			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
		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))
+12 −0
Original line number Original line Diff line number Diff line
@@ -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__ */