]> err.no Git - linux-2.6/blobdiff - drivers/ata/libata-scsi.c
libata: fix revalidation issuing after configuration commands
[linux-2.6] / drivers / ata / libata-scsi.c
index df2e05738f3b3806238e10d5cc78bdb222270217..d63c81ed084f7d016c70b55448804f0ad60d554e 100644 (file)
@@ -1363,6 +1363,7 @@ nothing_to_do:
 static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
+       struct ata_eh_info *ehi = &qc->dev->link->eh_info;
        struct scsi_cmnd *cmd = qc->scsicmd;
        u8 *cdb = cmd->cmnd;
        int need_sense = (qc->err_mask != 0);
@@ -1376,14 +1377,14 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
                case ATA_CMD_SET_FEATURES:
                        if ((qc->tf.feature == SETFEATURES_WC_ON) ||
                            (qc->tf.feature == SETFEATURES_WC_OFF)) {
-                               ap->link.eh_info.action |= ATA_EH_REVALIDATE;
+                               ehi->action |= ATA_EH_REVALIDATE;
                                ata_port_schedule_eh(ap);
                        }
                        break;
 
                case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */
                case ATA_CMD_SET_MULTI: /* multi_count changed */
-                       ap->link.eh_info.action |= ATA_EH_REVALIDATE;
+                       ehi->action |= ATA_EH_REVALIDATE;
                        ata_port_schedule_eh(ap);
                        break;
                }
@@ -2305,8 +2306,8 @@ static void atapi_request_sense(struct ata_queued_cmd *qc)
                qc->tf.feature |= ATAPI_PKT_DMA;
        } else {
                qc->tf.protocol = ATA_PROT_ATAPI;
-               qc->tf.lbam = (8 * 1024) & 0xff;
-               qc->tf.lbah = (8 * 1024) >> 8;
+               qc->tf.lbam = SCSI_SENSE_BUFFERSIZE;
+               qc->tf.lbah = 0;
        }
        qc->nbytes = SCSI_SENSE_BUFFERSIZE;
 
@@ -2415,6 +2416,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
        struct ata_device *dev = qc->dev;
        int using_pio = (dev->flags & ATA_DFLAG_PIO);
        int nodata = (scmd->sc_data_direction == DMA_NONE);
+       unsigned int nbytes;
 
        memset(qc->cdb, 0, dev->cdb_len);
        memcpy(qc->cdb, scmd->cmnd, scmd->cmd_len);
@@ -2434,14 +2436,20 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
        if (!using_pio && ata_check_atapi_dma(qc))
                using_pio = 1;
 
+       /* Some controller variants snoop this value for Packet transfers
+          to do state machine and FIFO management. Thus we want to set it
+          properly, and for DMA where it is effectively meaningless */
+       nbytes = min(qc->nbytes, (unsigned int)63 * 1024);
+
+       qc->tf.lbam = (nbytes & 0xFF);
+       qc->tf.lbah = (nbytes >> 8);
+
        if (using_pio || nodata) {
                /* no data, or PIO data xfer */
                if (nodata)
                        qc->tf.protocol = ATA_PROT_ATAPI_NODATA;
                else
                        qc->tf.protocol = ATA_PROT_ATAPI;
-               qc->tf.lbam = (8 * 1024) & 0xff;
-               qc->tf.lbah = (8 * 1024) >> 8;
        } else {
                /* DMA data xfer */
                qc->tf.protocol = ATA_PROT_ATAPI_DMA;
@@ -2452,6 +2460,9 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
                        qc->tf.feature |= ATAPI_DMADIR;
        }
 
+
+       /* FIXME: We need to translate 0x05 READ_BLOCK_LIMITS to a MODE_SENSE
+          as ATAPI tape drives don't get this right otherwise */
        return 0;
 }