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

Commit 3aef5231 authored by Albert Lee's avatar Albert Lee Committed by Jeff Garzik
Browse files

[libata scsi] tidy up SCSI lba and xfer len calculations

move the redundant SCSI lba and transfer length calculation code from
ata_scsi_verify_xlat() and ata_scsi_rw_xlat() to common functions.
parent c187c4b5
Loading
Loading
Loading
Loading
+115 −64
Original line number Original line Diff line number Diff line
@@ -487,6 +487,99 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
	return 0;
	return 0;
}
}


/**
 *	scsi_6_lba_len - Get LBA and transfer length
 *	@scsicmd: SCSI command to translate
 *
 *	Calculate LBA and transfer length for 6-byte commands.
 *
 *	RETURNS:
 *	@plba: the LBA
 *	@plen: the transfer length
 */

static void scsi_6_lba_len(u8 *scsicmd, u64 *plba, u32 *plen)
{
	u64 lba = 0;
	u32 len = 0;

	VPRINTK("six-byte command\n");

	lba |= ((u64)scsicmd[2]) << 8;
	lba |= ((u64)scsicmd[3]);

	len |= ((u32)scsicmd[4]);

	*plba = lba;
	*plen = len;
}

/**
 *	scsi_10_lba_len - Get LBA and transfer length
 *	@scsicmd: SCSI command to translate
 *
 *	Calculate LBA and transfer length for 10-byte commands.
 *
 *	RETURNS:
 *	@plba: the LBA
 *	@plen: the transfer length
 */

static void scsi_10_lba_len(u8 *scsicmd, u64 *plba, u32 *plen)
{
	u64 lba = 0;
	u32 len = 0;

	VPRINTK("ten-byte command\n");

	lba |= ((u64)scsicmd[2]) << 24;
	lba |= ((u64)scsicmd[3]) << 16;
	lba |= ((u64)scsicmd[4]) << 8;
	lba |= ((u64)scsicmd[5]);

	len |= ((u32)scsicmd[7]) << 8;
	len |= ((u32)scsicmd[8]);

	*plba = lba;
	*plen = len;
}

/**
 *	scsi_16_lba_len - Get LBA and transfer length
 *	@scsicmd: SCSI command to translate
 *
 *	Calculate LBA and transfer length for 16-byte commands.
 *
 *	RETURNS:
 *	@plba: the LBA
 *	@plen: the transfer length
 */

static void scsi_16_lba_len(u8 *scsicmd, u64 *plba, u32 *plen)
{
	u64 lba = 0;
	u32 len = 0;

	VPRINTK("sixteen-byte command\n");

	lba |= ((u64)scsicmd[2]) << 56;
	lba |= ((u64)scsicmd[3]) << 48;
	lba |= ((u64)scsicmd[4]) << 40;
	lba |= ((u64)scsicmd[5]) << 32;
	lba |= ((u64)scsicmd[6]) << 24;
	lba |= ((u64)scsicmd[7]) << 16;
	lba |= ((u64)scsicmd[8]) << 8;
	lba |= ((u64)scsicmd[9]);

	len |= ((u32)scsicmd[10]) << 24;
	len |= ((u32)scsicmd[11]) << 16;
	len |= ((u32)scsicmd[12]) << 8;
	len |= ((u32)scsicmd[13]);

	*plba = lba;
	*plen = len;
}

/**
/**
 *	ata_scsi_verify_xlat - Translate SCSI VERIFY command into an ATA one
 *	ata_scsi_verify_xlat - Translate SCSI VERIFY command into an ATA one
 *	@qc: Storage for translated ATA taskfile
 *	@qc: Storage for translated ATA taskfile
@@ -508,38 +601,16 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
	unsigned int lba   = tf->flags & ATA_TFLAG_LBA;
	unsigned int lba   = tf->flags & ATA_TFLAG_LBA;
	unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
	unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
	u64 dev_sectors = qc->dev->n_sectors;
	u64 dev_sectors = qc->dev->n_sectors;
	u64 block = 0;
	u64 block;
	u32 n_block = 0;
	u32 n_block;


	tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
	tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
	tf->protocol = ATA_PROT_NODATA;
	tf->protocol = ATA_PROT_NODATA;


	if (scsicmd[0] == VERIFY) {
	if (scsicmd[0] == VERIFY)
		block |= ((u64)scsicmd[2]) << 24;
		scsi_10_lba_len(scsicmd, &block, &n_block);
		block |= ((u64)scsicmd[3]) << 16;
	else if (scsicmd[0] == VERIFY_16)
		block |= ((u64)scsicmd[4]) << 8;
		scsi_16_lba_len(scsicmd, &block, &n_block);
		block |= ((u64)scsicmd[5]);

		n_block |= ((u32)scsicmd[7]) << 8;
		n_block |= ((u32)scsicmd[8]);
	}

	else if (scsicmd[0] == VERIFY_16) {
		block |= ((u64)scsicmd[2]) << 56;
		block |= ((u64)scsicmd[3]) << 48;
		block |= ((u64)scsicmd[4]) << 40;
		block |= ((u64)scsicmd[5]) << 32;
		block |= ((u64)scsicmd[6]) << 24;
		block |= ((u64)scsicmd[7]) << 16;
		block |= ((u64)scsicmd[8]) << 8;
		block |= ((u64)scsicmd[9]);

		n_block |= ((u32)scsicmd[10]) << 24;
		n_block |= ((u32)scsicmd[11]) << 16;
		n_block |= ((u32)scsicmd[12]) << 8;
		n_block |= ((u32)scsicmd[13]);
	}

	else
	else
		return 1;
		return 1;


@@ -636,8 +707,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
	struct ata_device *dev = qc->dev;
	struct ata_device *dev = qc->dev;
	unsigned int lba   = tf->flags & ATA_TFLAG_LBA;
	unsigned int lba   = tf->flags & ATA_TFLAG_LBA;
	unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
	unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48;
	u64 block = 0;
	u64 block;
	u32 n_block = 0;
	u32 n_block;


	tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
	tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
	tf->protocol = qc->dev->xfer_protocol;
	tf->protocol = qc->dev->xfer_protocol;
@@ -651,46 +722,26 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
	}
	}


	/* Calculate the SCSI LBA and transfer length. */
	/* Calculate the SCSI LBA and transfer length. */
	if (scsicmd[0] == READ_10 || scsicmd[0] == WRITE_10) {
	switch (scsicmd[0]) {
		block |= ((u64)scsicmd[2]) << 24;
	case READ_10:
		block |= ((u64)scsicmd[3]) << 16;
	case WRITE_10:
		block |= ((u64)scsicmd[4]) << 8;
		scsi_10_lba_len(scsicmd, &block, &n_block);
		block |= ((u64)scsicmd[5]);
		break;

	case READ_6:
		n_block |= ((u32)scsicmd[7]) << 8;
	case WRITE_6:
		n_block |= ((u32)scsicmd[8]);
		scsi_6_lba_len(scsicmd, &block, &n_block);

		VPRINTK("ten-byte command\n");
	} else if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) {
		block |= ((u64)scsicmd[2]) << 8;
		block |= ((u64)scsicmd[3]);

		n_block |= ((u32)scsicmd[4]);


		/* for 6-byte r/w commands, transfer length 0
		/* for 6-byte r/w commands, transfer length 0
		 * means 256 blocks of data, not 0 block.
		 * means 256 blocks of data, not 0 block.
		 */
		 */
		if (!n_block)
		if (!n_block)
			n_block = 256;
			n_block = 256;
	
		break;
		VPRINTK("six-byte command\n");
	case READ_16:
	} else if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_16) {
	case WRITE_16:
		block |= ((u64)scsicmd[2]) << 56;
		scsi_16_lba_len(scsicmd, &block, &n_block);
		block |= ((u64)scsicmd[3]) << 48;
		break;
		block |= ((u64)scsicmd[4]) << 40;
	default:
		block |= ((u64)scsicmd[5]) << 32;
		block |= ((u64)scsicmd[6]) << 24;
		block |= ((u64)scsicmd[7]) << 16;
		block |= ((u64)scsicmd[8]) << 8;
		block |= ((u64)scsicmd[9]);

		n_block |= ((u32)scsicmd[10]) << 24;
		n_block |= ((u32)scsicmd[11]) << 16;
		n_block |= ((u32)scsicmd[12]) << 8;
		n_block |= ((u32)scsicmd[13]);

		VPRINTK("sixteen-byte command\n");
	} else {
		DPRINTK("no-byte command\n");
		DPRINTK("no-byte command\n");
		return 1;
		return 1;
	}
	}