Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 9600
b: refs/heads/master
c: 3aef523
h: refs/heads/master
v: v3
  • Loading branch information
Albert Lee authored and Jeff Garzik committed Oct 4, 2005
1 parent 686c8d6 commit fa22f82
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 65 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c187c4b58a9caff660a4c8ae39d0def88cc449af
refs/heads/master: 3aef52311bcb1f88aa5c786302f1ae14a787f61e
179 changes: 115 additions & 64 deletions trunk/drivers/scsi/libata-scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,99 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
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
* @qc: Storage for translated ATA taskfile
Expand All @@ -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 lba48 = tf->flags & ATA_TFLAG_LBA48;
u64 dev_sectors = qc->dev->n_sectors;
u64 block = 0;
u32 n_block = 0;
u64 block;
u32 n_block;

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

if (scsicmd[0] == VERIFY) {
block |= ((u64)scsicmd[2]) << 24;
block |= ((u64)scsicmd[3]) << 16;
block |= ((u64)scsicmd[4]) << 8;
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]);
}

if (scsicmd[0] == VERIFY)
scsi_10_lba_len(scsicmd, &block, &n_block);
else if (scsicmd[0] == VERIFY_16)
scsi_16_lba_len(scsicmd, &block, &n_block);
else
return 1;

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

tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf->protocol = qc->dev->xfer_protocol;
Expand All @@ -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. */
if (scsicmd[0] == READ_10 || scsicmd[0] == WRITE_10) {
block |= ((u64)scsicmd[2]) << 24;
block |= ((u64)scsicmd[3]) << 16;
block |= ((u64)scsicmd[4]) << 8;
block |= ((u64)scsicmd[5]);

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

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]);
switch (scsicmd[0]) {
case READ_10:
case WRITE_10:
scsi_10_lba_len(scsicmd, &block, &n_block);
break;
case READ_6:
case WRITE_6:
scsi_6_lba_len(scsicmd, &block, &n_block);

/* for 6-byte r/w commands, transfer length 0
* means 256 blocks of data, not 0 block.
*/
if (!n_block)
n_block = 256;

VPRINTK("six-byte command\n");
} else if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_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]);

VPRINTK("sixteen-byte command\n");
} else {
break;
case READ_16:
case WRITE_16:
scsi_16_lba_len(scsicmd, &block, &n_block);
break;
default:
DPRINTK("no-byte command\n");
return 1;
}
Expand Down

0 comments on commit fa22f82

Please sign in to comment.