[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.
This commit is contained in:
Albert Lee 2005-10-04 08:47:43 -04:00 committed by Jeff Garzik
parent c187c4b58a
commit 3aef52311b
1 changed files with 115 additions and 64 deletions

View File

@ -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;
} }