]> err.no Git - linux-2.6/commitdiff
[libata scsi] tidy up SCSI lba and xfer len calculations
authorAlbert Lee <albertcc@tw.ibm.com>
Tue, 4 Oct 2005 12:47:43 +0000 (08:47 -0400)
committerJeff Garzik <jgarzik@pobox.com>
Tue, 4 Oct 2005 12:47:43 +0000 (08:47 -0400)
move the redundant SCSI lba and transfer length calculation code from
ata_scsi_verify_xlat() and ata_scsi_rw_xlat() to common functions.

drivers/scsi/libata-scsi.c

index d67c3fc98f7b392ba681c41c4dd592f4cc32e267..22434e0d4e758aaa05c63a099a95d4560f5a14ca 100644 (file)
@@ -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
@@ -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;
 
@@ -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;
@@ -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;
        }