Merge branch 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa
[powerpc.git] / drivers / ata / libata-scsi.c
index 664e137..836947d 100644 (file)
@@ -51,7 +51,7 @@
 
 #define SECTOR_SIZE    512
 
-typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd);
+typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc);
 
 static struct ata_device * __ata_scsi_find_dev(struct ata_port *ap,
                                        const struct scsi_device *scsidev);
@@ -935,7 +935,6 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
 /**
  *     ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
  *     @qc: Storage for translated ATA taskfile
- *     @scsicmd: SCSI command to translate
  *
  *     Sets up an ATA taskfile to issue STANDBY (to stop) or READ VERIFY
  *     (to start). Perhaps these commands should be preceded by
@@ -948,22 +947,25 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
  *     RETURNS:
  *     Zero on success, non-zero on error.
  */
-
-static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
-                                            const u8 *scsicmd)
+static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
 {
+       struct scsi_cmnd *scmd = qc->scsicmd;
        struct ata_taskfile *tf = &qc->tf;
+       const u8 *cdb = scmd->cmnd;
+
+       if (scmd->cmd_len < 5)
+               goto invalid_fld;
 
        tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
        tf->protocol = ATA_PROT_NODATA;
-       if (scsicmd[1] & 0x1) {
+       if (cdb[1] & 0x1) {
                ;       /* ignore IMMED bit, violates sat-r05 */
        }
-       if (scsicmd[4] & 0x2)
+       if (cdb[4] & 0x2)
                goto invalid_fld;       /* LOEJ bit set not supported */
-       if (((scsicmd[4] >> 4) & 0xf) != 0)
+       if (((cdb[4] >> 4) & 0xf) != 0)
                goto invalid_fld;       /* power conditions not supported */
-       if (scsicmd[4] & 0x1) {
+       if (cdb[4] & 0x1) {
                tf->nsect = 1;  /* 1 sector, lba=0 */
 
                if (qc->dev->flags & ATA_DFLAG_LBA) {
@@ -996,7 +998,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
        return 0;
 
 invalid_fld:
-       ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
+       ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
        /* "Invalid field in cbd" */
        return 1;
 }
@@ -1005,7 +1007,6 @@ invalid_fld:
 /**
  *     ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command
  *     @qc: Storage for translated ATA taskfile
- *     @scsicmd: SCSI command to translate (ignored)
  *
  *     Sets up an ATA taskfile to issue FLUSH CACHE or
  *     FLUSH CACHE EXT.
@@ -1016,8 +1017,7 @@ invalid_fld:
  *     RETURNS:
  *     Zero on success, non-zero on error.
  */
-
-static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc)
 {
        struct ata_taskfile *tf = &qc->tf;
 
@@ -1034,7 +1034,7 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scs
 
 /**
  *     scsi_6_lba_len - Get LBA and transfer length
- *     @scsicmd: SCSI command to translate
+ *     @cdb: SCSI command to translate
  *
  *     Calculate LBA and transfer length for 6-byte commands.
  *
@@ -1042,18 +1042,17 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scs
  *     @plba: the LBA
  *     @plen: the transfer length
  */
-
-static void scsi_6_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+static void scsi_6_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
 {
        u64 lba = 0;
        u32 len = 0;
 
        VPRINTK("six-byte command\n");
 
-       lba |= ((u64)scsicmd[2]) << 8;
-       lba |= ((u64)scsicmd[3]);
+       lba |= ((u64)cdb[2]) << 8;
+       lba |= ((u64)cdb[3]);
 
-       len |= ((u32)scsicmd[4]);
+       len |= ((u32)cdb[4]);
 
        *plba = lba;
        *plen = len;
@@ -1061,7 +1060,7 @@ static void scsi_6_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
 
 /**
  *     scsi_10_lba_len - Get LBA and transfer length
- *     @scsicmd: SCSI command to translate
+ *     @cdb: SCSI command to translate
  *
  *     Calculate LBA and transfer length for 10-byte commands.
  *
@@ -1069,21 +1068,20 @@ static void scsi_6_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
  *     @plba: the LBA
  *     @plen: the transfer length
  */
-
-static void scsi_10_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+static void scsi_10_lba_len(const u8 *cdb, 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]);
+       lba |= ((u64)cdb[2]) << 24;
+       lba |= ((u64)cdb[3]) << 16;
+       lba |= ((u64)cdb[4]) << 8;
+       lba |= ((u64)cdb[5]);
 
-       len |= ((u32)scsicmd[7]) << 8;
-       len |= ((u32)scsicmd[8]);
+       len |= ((u32)cdb[7]) << 8;
+       len |= ((u32)cdb[8]);
 
        *plba = lba;
        *plen = len;
@@ -1091,7 +1089,7 @@ static void scsi_10_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
 
 /**
  *     scsi_16_lba_len - Get LBA and transfer length
- *     @scsicmd: SCSI command to translate
+ *     @cdb: SCSI command to translate
  *
  *     Calculate LBA and transfer length for 16-byte commands.
  *
@@ -1099,27 +1097,26 @@ static void scsi_10_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
  *     @plba: the LBA
  *     @plen: the transfer length
  */
-
-static void scsi_16_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+static void scsi_16_lba_len(const u8 *cdb, 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]);
+       lba |= ((u64)cdb[2]) << 56;
+       lba |= ((u64)cdb[3]) << 48;
+       lba |= ((u64)cdb[4]) << 40;
+       lba |= ((u64)cdb[5]) << 32;
+       lba |= ((u64)cdb[6]) << 24;
+       lba |= ((u64)cdb[7]) << 16;
+       lba |= ((u64)cdb[8]) << 8;
+       lba |= ((u64)cdb[9]);
 
-       len |= ((u32)scsicmd[10]) << 24;
-       len |= ((u32)scsicmd[11]) << 16;
-       len |= ((u32)scsicmd[12]) << 8;
-       len |= ((u32)scsicmd[13]);
+       len |= ((u32)cdb[10]) << 24;
+       len |= ((u32)cdb[11]) << 16;
+       len |= ((u32)cdb[12]) << 8;
+       len |= ((u32)cdb[13]);
 
        *plba = lba;
        *plen = len;
@@ -1128,7 +1125,6 @@ static void scsi_16_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
 /**
  *     ata_scsi_verify_xlat - Translate SCSI VERIFY command into an ATA one
  *     @qc: Storage for translated ATA taskfile
- *     @scsicmd: SCSI command to translate
  *
  *     Converts SCSI VERIFY command to an ATA READ VERIFY command.
  *
@@ -1138,23 +1134,28 @@ static void scsi_16_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
  *     RETURNS:
  *     Zero on success, non-zero on error.
  */
-
-static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc)
 {
+       struct scsi_cmnd *scmd = qc->scsicmd;
        struct ata_taskfile *tf = &qc->tf;
        struct ata_device *dev = qc->dev;
        u64 dev_sectors = qc->dev->n_sectors;
+       const u8 *cdb = scmd->cmnd;
        u64 block;
        u32 n_block;
 
        tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
        tf->protocol = ATA_PROT_NODATA;
 
-       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
+       if (cdb[0] == VERIFY) {
+               if (scmd->cmd_len < 10)
+                       goto invalid_fld;
+               scsi_10_lba_len(cdb, &block, &n_block);
+       } else if (cdb[0] == VERIFY_16) {
+               if (scmd->cmd_len < 16)
+                       goto invalid_fld;
+               scsi_16_lba_len(cdb, &block, &n_block);
+       } else
                goto invalid_fld;
 
        if (!n_block)
@@ -1229,24 +1230,23 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc
        return 0;
 
 invalid_fld:
-       ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
+       ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
        /* "Invalid field in cbd" */
        return 1;
 
 out_of_range:
-       ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0);
+       ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x21, 0x0);
        /* "Logical Block Address out of range" */
        return 1;
 
 nothing_to_do:
-       qc->scsicmd->result = SAM_STAT_GOOD;
+       scmd->result = SAM_STAT_GOOD;
        return 1;
 }
 
 /**
  *     ata_scsi_rw_xlat - Translate SCSI r/w command into an ATA one
  *     @qc: Storage for translated ATA taskfile
- *     @scsicmd: SCSI command to translate
  *
  *     Converts any of six SCSI read/write commands into the
  *     ATA counterpart, including starting sector (LBA),
@@ -1262,29 +1262,33 @@ nothing_to_do:
  *     RETURNS:
  *     Zero on success, non-zero on error.
  */
-
-static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
 {
+       struct scsi_cmnd *scmd = qc->scsicmd;
+       const u8 *cdb = scmd->cmnd;
        unsigned int tf_flags = 0;
        u64 block;
        u32 n_block;
        int rc;
 
-       if (scsicmd[0] == WRITE_10 || scsicmd[0] == WRITE_6 ||
-           scsicmd[0] == WRITE_16)
+       if (cdb[0] == WRITE_10 || cdb[0] == WRITE_6 || cdb[0] == WRITE_16)
                tf_flags |= ATA_TFLAG_WRITE;
 
        /* Calculate the SCSI LBA, transfer length and FUA. */
-       switch (scsicmd[0]) {
+       switch (cdb[0]) {
        case READ_10:
        case WRITE_10:
-               scsi_10_lba_len(scsicmd, &block, &n_block);
-               if (unlikely(scsicmd[1] & (1 << 3)))
+               if (unlikely(scmd->cmd_len < 10))
+                       goto invalid_fld;
+               scsi_10_lba_len(cdb, &block, &n_block);
+               if (unlikely(cdb[1] & (1 << 3)))
                        tf_flags |= ATA_TFLAG_FUA;
                break;
        case READ_6:
        case WRITE_6:
-               scsi_6_lba_len(scsicmd, &block, &n_block);
+               if (unlikely(scmd->cmd_len < 6))
+                       goto invalid_fld;
+               scsi_6_lba_len(cdb, &block, &n_block);
 
                /* for 6-byte r/w commands, transfer length 0
                 * means 256 blocks of data, not 0 block.
@@ -1294,8 +1298,10 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
                break;
        case READ_16:
        case WRITE_16:
-               scsi_16_lba_len(scsicmd, &block, &n_block);
-               if (unlikely(scsicmd[1] & (1 << 3)))
+               if (unlikely(scmd->cmd_len < 16))
+                       goto invalid_fld;
+               scsi_16_lba_len(cdb, &block, &n_block);
+               if (unlikely(cdb[1] & (1 << 3)))
                        tf_flags |= ATA_TFLAG_FUA;
                break;
        default:
@@ -1326,17 +1332,17 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
                goto out_of_range;
        /* treat all other errors as -EINVAL, fall through */
 invalid_fld:
-       ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
+       ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
        /* "Invalid field in cbd" */
        return 1;
 
 out_of_range:
-       ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0);
+       ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x21, 0x0);
        /* "Logical Block Address out of range" */
        return 1;
 
 nothing_to_do:
-       qc->scsicmd->result = SAM_STAT_GOOD;
+       scmd->result = SAM_STAT_GOOD;
        return 1;
 }
 
@@ -1456,7 +1462,6 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
                              ata_xlat_func_t xlat_func)
 {
        struct ata_queued_cmd *qc;
-       u8 *scsicmd = cmd->cmnd;
        int is_io = xlat_func == ata_scsi_rw_xlat;
 
        VPRINTK("ENTER\n");
@@ -1488,7 +1493,7 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
 
        qc->complete_fn = ata_scsi_qc_complete;
 
-       if (xlat_func(qc, scsicmd))
+       if (xlat_func(qc))
                goto early_finish;
 
        /* select device, send command to hardware */
@@ -1539,7 +1544,7 @@ static unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out)
                struct scatterlist *sg;
 
                sg = (struct scatterlist *) cmd->request_buffer;
-               buf = kmap_atomic(sg->page, KM_USER0) + sg->offset;
+               buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
                buflen = sg->length;
        } else {
                buf = cmd->request_buffer;
@@ -1567,7 +1572,7 @@ static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf)
                struct scatterlist *sg;
 
                sg = (struct scatterlist *) cmd->request_buffer;
-               kunmap_atomic(buf - sg->offset, KM_USER0);
+               kunmap_atomic(buf - sg->offset, KM_IRQ0);
        }
 }
 
@@ -2344,7 +2349,6 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
 /**
  *     atapi_xlat - Initialize PACKET taskfile
  *     @qc: command structure to be initialized
- *     @scsicmd: SCSI CDB associated with this PACKET command
  *
  *     LOCKING:
  *     spin_lock_irqsave(host lock)
@@ -2352,25 +2356,25 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
  *     RETURNS:
  *     Zero on success, non-zero on failure.
  */
-
-static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
 {
-       struct scsi_cmnd *cmd = qc->scsicmd;
+       struct scsi_cmnd *scmd = qc->scsicmd;
        struct ata_device *dev = qc->dev;
        int using_pio = (dev->flags & ATA_DFLAG_PIO);
-       int nodata = (cmd->sc_data_direction == DMA_NONE);
+       int nodata = (scmd->sc_data_direction == DMA_NONE);
 
        if (!using_pio)
                /* Check whether ATAPI DMA is safe */
                if (ata_check_atapi_dma(qc))
                        using_pio = 1;
 
-       memcpy(&qc->cdb, scsicmd, dev->cdb_len);
+       memset(qc->cdb, 0, dev->cdb_len);
+       memcpy(qc->cdb, scmd->cmnd, scmd->cmd_len);
 
        qc->complete_fn = atapi_qc_complete;
 
        qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-       if (cmd->sc_data_direction == DMA_TO_DEVICE) {
+       if (scmd->sc_data_direction == DMA_TO_DEVICE) {
                qc->tf.flags |= ATA_TFLAG_WRITE;
                DPRINTK("direction: write\n");
        }
@@ -2392,12 +2396,12 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
                qc->tf.protocol = ATA_PROT_ATAPI_DMA;
                qc->tf.feature |= ATAPI_PKT_DMA;
 
-               if (atapi_dmadir && (cmd->sc_data_direction != DMA_TO_DEVICE))
+               if (atapi_dmadir && (scmd->sc_data_direction != DMA_TO_DEVICE))
                        /* some SATA bridges need us to indicate data xfer direction */
                        qc->tf.feature |= ATAPI_DMADIR;
        }
 
-       qc->nbytes = cmd->request_bufflen;
+       qc->nbytes = scmd->request_bufflen;
 
        return 0;
 }
@@ -2517,28 +2521,27 @@ ata_scsi_map_proto(u8 byte1)
 /**
  *     ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile
  *     @qc: command structure to be initialized
- *     @scsicmd: SCSI command to convert
  *
  *     Handles either 12 or 16-byte versions of the CDB.
  *
  *     RETURNS:
  *     Zero on success, non-zero on failure.
  */
-static unsigned int
-ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
 {
        struct ata_taskfile *tf = &(qc->tf);
-       struct scsi_cmnd *cmd = qc->scsicmd;
+       struct scsi_cmnd *scmd = qc->scsicmd;
        struct ata_device *dev = qc->dev;
+       const u8 *cdb = scmd->cmnd;
 
-       if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN)
+       if ((tf->protocol = ata_scsi_map_proto(cdb[1])) == ATA_PROT_UNKNOWN)
                goto invalid_fld;
 
        /* We may not issue DMA commands if no DMA mode is set */
        if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0)
                goto invalid_fld;
 
-       if (scsicmd[1] & 0xe0)
+       if (cdb[1] & 0xe0)
                /* PIO multi not supported yet */
                goto invalid_fld;
 
@@ -2546,18 +2549,18 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
         * 12 and 16 byte CDBs use different offsets to
         * provide the various register values.
         */
-       if (scsicmd[0] == ATA_16) {
+       if (cdb[0] == ATA_16) {
                /*
                 * 16-byte CDB - may contain extended commands.
                 *
                 * If that is the case, copy the upper byte register values.
                 */
-               if (scsicmd[1] & 0x01) {
-                       tf->hob_feature = scsicmd[3];
-                       tf->hob_nsect = scsicmd[5];
-                       tf->hob_lbal = scsicmd[7];
-                       tf->hob_lbam = scsicmd[9];
-                       tf->hob_lbah = scsicmd[11];
+               if (cdb[1] & 0x01) {
+                       tf->hob_feature = cdb[3];
+                       tf->hob_nsect = cdb[5];
+                       tf->hob_lbal = cdb[7];
+                       tf->hob_lbam = cdb[9];
+                       tf->hob_lbah = cdb[11];
                        tf->flags |= ATA_TFLAG_LBA48;
                } else
                        tf->flags &= ~ATA_TFLAG_LBA48;
@@ -2565,26 +2568,26 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
                /*
                 * Always copy low byte, device and command registers.
                 */
-               tf->feature = scsicmd[4];
-               tf->nsect = scsicmd[6];
-               tf->lbal = scsicmd[8];
-               tf->lbam = scsicmd[10];
-               tf->lbah = scsicmd[12];
-               tf->device = scsicmd[13];
-               tf->command = scsicmd[14];
+               tf->feature = cdb[4];
+               tf->nsect = cdb[6];
+               tf->lbal = cdb[8];
+               tf->lbam = cdb[10];
+               tf->lbah = cdb[12];
+               tf->device = cdb[13];
+               tf->command = cdb[14];
        } else {
                /*
                 * 12-byte CDB - incapable of extended commands.
                 */
                tf->flags &= ~ATA_TFLAG_LBA48;
 
-               tf->feature = scsicmd[3];
-               tf->nsect = scsicmd[4];
-               tf->lbal = scsicmd[5];
-               tf->lbam = scsicmd[6];
-               tf->lbah = scsicmd[7];
-               tf->device = scsicmd[8];
-               tf->command = scsicmd[9];
+               tf->feature = cdb[3];
+               tf->nsect = cdb[4];
+               tf->lbal = cdb[5];
+               tf->lbam = cdb[6];
+               tf->lbah = cdb[7];
+               tf->device = cdb[8];
+               tf->command = cdb[9];
        }
        /*
         * If slave is possible, enforce correct master/slave bit
@@ -2611,7 +2614,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
         */
        tf->flags |= (ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE);
 
-       if (cmd->sc_data_direction == DMA_TO_DEVICE)
+       if (scmd->sc_data_direction == DMA_TO_DEVICE)
                tf->flags |= ATA_TFLAG_WRITE;
 
        /*
@@ -2620,7 +2623,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
         * TODO: find out if we need to do more here to
         *       cover scatter/gather case.
         */
-       qc->nsect = cmd->request_bufflen / ATA_SECT_SIZE;
+       qc->nsect = scmd->request_bufflen / ATA_SECT_SIZE;
 
        /* request result TF */
        qc->flags |= ATA_QCFLAG_RESULT_TF;
@@ -2628,7 +2631,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
        return 0;
 
  invalid_fld:
-       ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x00);
+       ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x00);
        /* "Invalid field in cdb" */
        return 1;
 }
@@ -2701,22 +2704,29 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap,
 #endif
 }
 
-static inline int __ata_scsi_queuecmd(struct scsi_cmnd *cmd,
+static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
                                      void (*done)(struct scsi_cmnd *),
                                      struct ata_device *dev)
 {
        int rc = 0;
 
+       if (unlikely(!scmd->cmd_len)) {
+               ata_dev_printk(dev, KERN_WARNING, "WARNING: zero len CDB\n");
+               scmd->result = DID_ERROR << 16;
+               done(scmd);
+               return 0;
+       }
+
        if (dev->class == ATA_DEV_ATA) {
                ata_xlat_func_t xlat_func = ata_get_xlat_func(dev,
-                                                             cmd->cmnd[0]);
+                                                             scmd->cmnd[0]);
 
                if (xlat_func)
-                       rc = ata_scsi_translate(dev, cmd, done, xlat_func);
+                       rc = ata_scsi_translate(dev, scmd, done, xlat_func);
                else
-                       ata_scsi_simulate(dev, cmd, done);
+                       ata_scsi_simulate(dev, scmd, done);
        } else
-               rc = ata_scsi_translate(dev, cmd, done, atapi_xlat);
+               rc = ata_scsi_translate(dev, scmd, done, atapi_xlat);
 
        return rc;
 }