libata: kill unused ata_flush_cache()
[safe/jmp/linux-2.6] / drivers / ata / libata-scsi.c
index 3fd0820..798ba5e 100644 (file)
@@ -527,6 +527,14 @@ static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev,
        return qc;
 }
 
+static void ata_qc_set_pc_nbytes(struct ata_queued_cmd *qc)
+{
+       struct scsi_cmnd *scmd = qc->scsicmd;
+
+       qc->extrabytes = scmd->request->extra_len;
+       qc->nbytes = scsi_bufflen(scmd) + qc->extrabytes;
+}
+
 /**
  *     ata_dump_status - user friendly display of error info
  *     @id: id of the port in question
@@ -826,23 +834,62 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev)
        sdev->max_device_blocked = 1;
 }
 
-static void ata_scsi_dev_config(struct scsi_device *sdev,
-                               struct ata_device *dev)
+/**
+ *     atapi_drain_needed - Check whether data transfer may overflow
+ *     @rq: request to be checked
+ *
+ *     ATAPI commands which transfer variable length data to host
+ *     might overflow due to application error or hardare bug.  This
+ *     function checks whether overflow should be drained and ignored
+ *     for @request.
+ *
+ *     LOCKING:
+ *     None.
+ *
+ *     RETURNS:
+ *     1 if ; otherwise, 0.
+ */
+static int atapi_drain_needed(struct request *rq)
+{
+       if (likely(!blk_pc_request(rq)))
+               return 0;
+
+       if (!rq->data_len || (rq->cmd_flags & REQ_RW))
+               return 0;
+
+       return atapi_cmd_type(rq->cmd[0]) == ATAPI_MISC;
+}
+
+static int ata_scsi_dev_config(struct scsi_device *sdev,
+                              struct ata_device *dev)
 {
        /* configure max sectors */
        blk_queue_max_sectors(sdev->request_queue, dev->max_sectors);
 
-       /* SATA DMA transfers must be multiples of 4 byte, so
-        * we need to pad ATAPI transfers using an extra sg.
-        * Decrement max hw segments accordingly.
-        */
        if (dev->class == ATA_DEV_ATAPI) {
                struct request_queue *q = sdev->request_queue;
-               blk_queue_max_hw_segments(q, q->max_hw_segments - 1);
-       }
+               void *buf;
+
+               /* set the min alignment and padding */
+               blk_queue_update_dma_alignment(sdev->request_queue,
+                                              ATA_DMA_PAD_SZ - 1);
+               blk_queue_dma_pad(sdev->request_queue, ATA_DMA_PAD_SZ - 1);
+
+               /* configure draining */
+               buf = kmalloc(ATAPI_MAX_DRAIN, q->bounce_gfp | GFP_KERNEL);
+               if (!buf) {
+                       ata_dev_printk(dev, KERN_ERR,
+                                      "drain buffer allocation failed\n");
+                       return -ENOMEM;
+               }
 
-       if (dev->class == ATA_DEV_ATA)
+               blk_queue_dma_drain(q, atapi_drain_needed, buf, ATAPI_MAX_DRAIN);
+       } else {
+               /* ATA devices must be sector aligned */
+               blk_queue_update_dma_alignment(sdev->request_queue,
+                                              ATA_SECT_SIZE - 1);
                sdev->manage_start_stop = 1;
+       }
 
        if (dev->flags & ATA_DFLAG_AN)
                set_bit(SDEV_EVT_MEDIA_CHANGE, sdev->supported_events);
@@ -854,6 +901,8 @@ static void ata_scsi_dev_config(struct scsi_device *sdev,
                depth = min(ATA_MAX_QUEUE - 1, depth);
                scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth);
        }
+
+       return 0;
 }
 
 /**
@@ -872,13 +921,14 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
 {
        struct ata_port *ap = ata_shost_to_port(sdev->host);
        struct ata_device *dev = __ata_scsi_find_dev(ap, sdev);
+       int rc = 0;
 
        ata_scsi_sdev_config(sdev);
 
        if (dev)
-               ata_scsi_dev_config(sdev, dev);
+               rc = ata_scsi_dev_config(sdev, dev);
 
-       return 0;       /* scsi layer doesn't check return value, sigh */
+       return rc;
 }
 
 /**
@@ -898,6 +948,7 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
 void ata_scsi_slave_destroy(struct scsi_device *sdev)
 {
        struct ata_port *ap = ata_shost_to_port(sdev->host);
+       struct request_queue *q = sdev->request_queue;
        unsigned long flags;
        struct ata_device *dev;
 
@@ -913,6 +964,10 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev)
                ata_port_schedule_eh(ap);
        }
        spin_unlock_irqrestore(ap->lock, flags);
+
+       kfree(q->dma_drain_buffer);
+       q->dma_drain_buffer = NULL;
+       q->dma_drain_size = 0;
 }
 
 /**
@@ -1648,12 +1703,17 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
        u8 *rbuf;
        unsigned int buflen, rc;
        struct scsi_cmnd *cmd = args->cmd;
+       unsigned long flags;
+
+       local_irq_save(flags);
 
        buflen = ata_scsi_rbuf_get(cmd, &rbuf);
        memset(rbuf, 0, buflen);
        rc = actor(args, rbuf, buflen);
        ata_scsi_rbuf_put(cmd, rbuf);
 
+       local_irq_restore(flags);
+
        if (rc == 0)
                cmd->result = SAM_STAT_GOOD;
        args->done(cmd);
@@ -1855,7 +1915,7 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
  *     spin_lock_irqsave(host lock)
  */
 
-unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf,
+static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf,
                              unsigned int buflen)
 {
        u8 pbuf[60];
@@ -2427,6 +2487,9 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
                if ((scsicmd[0] == INQUIRY) && ((scsicmd[1] & 0x03) == 0)) {
                        u8 *buf = NULL;
                        unsigned int buflen;
+                       unsigned long flags;
+
+                       local_irq_save(flags);
 
                        buflen = ata_scsi_rbuf_get(cmd, &buf);
 
@@ -2444,6 +2507,8 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
                        }
 
                        ata_scsi_rbuf_put(cmd, buf);
+
+                       local_irq_restore(flags);
                }
 
                cmd->result = SAM_STAT_GOOD;
@@ -2482,7 +2547,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
        }
 
        qc->tf.command = ATA_CMD_PACKET;
-       qc->nbytes = scsi_bufflen(scmd);
+       ata_qc_set_pc_nbytes(qc);
 
        /* check whether ATAPI DMA is safe */
        if (!using_pio && ata_check_atapi_dma(qc))
@@ -2493,7 +2558,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
         * want to set it properly, and for DMA where it is
         * effectively meaningless.
         */
-       nbytes = min(qc->nbytes, (unsigned int)63 * 1024);
+       nbytes = min(ata_qc_raw_nbytes(qc), (unsigned int)63 * 1024);
 
        /* Most ATAPI devices which honor transfer chunk size don't
         * behave according to the spec when odd chunk size which
@@ -2536,7 +2601,8 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
                qc->tf.protocol = ATAPI_PROT_DMA;
                qc->tf.feature |= ATAPI_PKT_DMA;
 
-               if (atapi_dmadir && (scmd->sc_data_direction != DMA_TO_DEVICE))
+               if ((dev->flags & ATA_DFLAG_DMADIR) &&
+                   (scmd->sc_data_direction != DMA_TO_DEVICE))
                        /* some SATA bridges need us to indicate data xfer direction */
                        qc->tf.feature |= ATAPI_DMADIR;
        }
@@ -2818,7 +2884,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
         * TODO: find out if we need to do more here to
         *       cover scatter/gather case.
         */
-       qc->nbytes = scsi_bufflen(scmd);
+       ata_qc_set_pc_nbytes(qc);
 
        /* request result TF and be quiet about device error */
        qc->flags |= ATA_QCFLAG_RESULT_TF | ATA_QCFLAG_QUIET;
@@ -3441,8 +3507,8 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
 
                ata_port_for_each_link(link, ap) {
                        struct ata_eh_info *ehi = &link->eh_info;
-                       ehi->probe_mask |= (1 << ata_link_max_devices(link)) - 1;
-                       ehi->action |= ATA_EH_SOFTRESET;
+                       ehi->probe_mask |= ATA_ALL_DEVICES;
+                       ehi->action |= ATA_EH_RESET;
                }
        } else {
                struct ata_device *dev = ata_find_dev(ap, devno);
@@ -3450,8 +3516,7 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
                if (dev) {
                        struct ata_eh_info *ehi = &dev->link->eh_info;
                        ehi->probe_mask |= 1 << dev->devno;
-                       ehi->action |= ATA_EH_SOFTRESET;
-                       ehi->flags |= ATA_EHI_RESUME_LINK;
+                       ehi->action |= ATA_EH_RESET;
                } else
                        rc = -EINVAL;
        }
@@ -3548,7 +3613,7 @@ EXPORT_SYMBOL_GPL(ata_sas_port_alloc);
  *     @ap: Port to initialize
  *
  *     Called just after data structures for each port are
- *     initialized.  Allocates DMA pad.
+ *     initialized.
  *
  *     May be used as the port_start() entry in ata_port_operations.
  *
@@ -3557,7 +3622,7 @@ EXPORT_SYMBOL_GPL(ata_sas_port_alloc);
  */
 int ata_sas_port_start(struct ata_port *ap)
 {
-       return ata_pad_alloc(ap, ap->dev);
+       return 0;
 }
 EXPORT_SYMBOL_GPL(ata_sas_port_start);
 
@@ -3565,8 +3630,6 @@ EXPORT_SYMBOL_GPL(ata_sas_port_start);
  *     ata_port_stop - Undo ata_sas_port_start()
  *     @ap: Port to shut down
  *
- *     Frees the DMA pad.
- *
  *     May be used as the port_stop() entry in ata_port_operations.
  *
  *     LOCKING:
@@ -3575,7 +3638,6 @@ EXPORT_SYMBOL_GPL(ata_sas_port_start);
 
 void ata_sas_port_stop(struct ata_port *ap)
 {
-       ata_pad_free(ap, ap->dev);
 }
 EXPORT_SYMBOL_GPL(ata_sas_port_stop);