Merge branch 'upstream'
[pandora-kernel.git] / drivers / scsi / libata-core.c
index f53d7b8..6cab149 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/suspend.h>
 #include <linux/workqueue.h>
 #include <linux/jiffies.h>
+#include <linux/scatterlist.h>
 #include <scsi/scsi.h>
 #include "scsi.h"
 #include "scsi_priv.h"
@@ -370,6 +371,8 @@ static void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf)
 {
        struct ata_ioports *ioaddr = &ap->ioaddr;
 
+       tf->command = ata_check_status(ap);
+       tf->feature = inb(ioaddr->error_addr);
        tf->nsect = inb(ioaddr->nsect_addr);
        tf->lbal = inb(ioaddr->lbal_addr);
        tf->lbam = inb(ioaddr->lbam_addr);
@@ -402,6 +405,8 @@ static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf)
 {
        struct ata_ioports *ioaddr = &ap->ioaddr;
 
+       tf->command = ata_check_status(ap);
+       tf->feature = readb((void __iomem *)ioaddr->error_addr);
        tf->nsect = readb((void __iomem *)ioaddr->nsect_addr);
        tf->lbal = readb((void __iomem *)ioaddr->lbal_addr);
        tf->lbam = readb((void __iomem *)ioaddr->lbam_addr);
@@ -521,30 +526,6 @@ u8 ata_altstatus(struct ata_port *ap)
 }
 
 
-/**
- *     ata_chk_err - Read device error reg
- *     @ap: port where the device is
- *
- *     Reads ATA taskfile error register for
- *     currently-selected device and return its value.
- *
- *     Note: may NOT be used as the check_err() entry in
- *     ata_port_operations.
- *
- *     LOCKING:
- *     Inherited from caller.
- */
-u8 ata_chk_err(struct ata_port *ap)
-{
-       if (ap->ops->check_err)
-               return ap->ops->check_err(ap);
-
-       if (ap->flags & ATA_FLAG_MMIO) {
-               return readb((void __iomem *) ap->ioaddr.error_addr);
-       }
-       return inb(ap->ioaddr.error_addr);
-}
-
 /**
  *     ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure
  *     @tf: Taskfile to convert
@@ -897,8 +878,8 @@ static u8 ata_dev_try_classify(struct ata_port *ap, unsigned int device)
 
        memset(&tf, 0, sizeof(tf));
 
-       err = ata_chk_err(ap);
        ap->ops->tf_read(ap, &tf);
+       err = tf.feature;
 
        dev->class = ATA_DEV_NONE;
 
@@ -1135,7 +1116,6 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
        unsigned int major_version;
        u16 tmp;
        unsigned long xfer_modes;
-       u8 status;
        unsigned int using_edd;
        DECLARE_COMPLETION(wait);
        struct ata_queued_cmd *qc;
@@ -1189,8 +1169,11 @@ retry:
        else
                wait_for_completion(&wait);
 
-       status = ata_chk_status(ap);
-       if (status & ATA_ERR) {
+       spin_lock_irqsave(&ap->host_set->lock, flags);
+       ap->ops->tf_read(ap, &qc->tf);
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+       if (qc->tf.command & ATA_ERR) {
                /*
                 * arg!  EDD works for all test cases, but seems to return
                 * the ATA signature for some ATAPI devices.  Until the
@@ -1203,7 +1186,7 @@ retry:
                 * to have this problem.
                 */
                if ((using_edd) && (qc->tf.command == ATA_CMD_ID_ATA)) {
-                       u8 err = ata_chk_err(ap);
+                       u8 err = qc->tf.feature;
                        if (err & ATA_ABORTED) {
                                dev->class = ATA_DEV_ATAPI;
                                qc->cursg = 0;
@@ -2444,8 +2427,9 @@ static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev)
 static void ata_sg_clean(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
-       struct scatterlist *sg = qc->sg;
+       struct scatterlist *sg = qc->__sg;
        int dir = qc->dma_dir;
+       void *pad_buf = NULL;
 
        assert(qc->flags & ATA_QCFLAG_DMAMAP);
        assert(sg != NULL);
@@ -2455,14 +2439,35 @@ static void ata_sg_clean(struct ata_queued_cmd *qc)
 
        DPRINTK("unmapping %u sg elements\n", qc->n_elem);
 
-       if (qc->flags & ATA_QCFLAG_SG)
+       /* if we padded the buffer out to 32-bit bound, and data
+        * xfer direction is from-device, we must copy from the
+        * pad buffer back into the supplied buffer
+        */
+       if (qc->pad_len && !(qc->tf.flags & ATA_TFLAG_WRITE))
+               pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ);
+
+       if (qc->flags & ATA_QCFLAG_SG) {
                dma_unmap_sg(ap->host_set->dev, sg, qc->n_elem, dir);
-       else
+               /* restore last sg */
+               sg[qc->orig_n_elem - 1].length += qc->pad_len;
+               if (pad_buf) {
+                       struct scatterlist *psg = &qc->pad_sgent;
+                       void *addr = kmap_atomic(psg->page, KM_IRQ0);
+                       memcpy(addr + psg->offset, pad_buf, qc->pad_len);
+                       kunmap_atomic(psg->page, KM_IRQ0);
+               }
+       } else {
                dma_unmap_single(ap->host_set->dev, sg_dma_address(&sg[0]),
                                 sg_dma_len(&sg[0]), dir);
+               /* restore sg */
+               sg->length += qc->pad_len;
+               if (pad_buf)
+                       memcpy(qc->buf_virt + sg->length - qc->pad_len,
+                              pad_buf, qc->pad_len);
+       }
 
        qc->flags &= ~ATA_QCFLAG_DMAMAP;
-       qc->sg = NULL;
+       qc->__sg = NULL;
 }
 
 /**
@@ -2478,15 +2483,15 @@ static void ata_sg_clean(struct ata_queued_cmd *qc)
  */
 static void ata_fill_sg(struct ata_queued_cmd *qc)
 {
-       struct scatterlist *sg = qc->sg;
        struct ata_port *ap = qc->ap;
-       unsigned int idx, nelem;
+       struct scatterlist *sg;
+       unsigned int idx;
 
-       assert(sg != NULL);
+       assert(qc->__sg != NULL);
        assert(qc->n_elem > 0);
 
        idx = 0;
-       for (nelem = qc->n_elem; nelem; nelem--,sg++) {
+       ata_for_each_sg(sg, qc) {
                u32 addr, offset;
                u32 sg_len, len;
 
@@ -2577,14 +2582,13 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
        qc->flags |= ATA_QCFLAG_SINGLE;
 
        memset(&qc->sgent, 0, sizeof(qc->sgent));
-       qc->sg = &qc->sgent;
+       qc->__sg = &qc->sgent;
        qc->n_elem = 1;
+       qc->orig_n_elem = 1;
        qc->buf_virt = buf;
 
-       sg = qc->sg;
-       sg->page = virt_to_page(buf);
-       sg->offset = (unsigned long) buf & ~PAGE_MASK;
-       sg->length = buflen;
+       sg = qc->__sg;
+       sg_init_one(sg, buf, buflen);
 }
 
 /**
@@ -2605,8 +2609,9 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
                 unsigned int n_elem)
 {
        qc->flags |= ATA_QCFLAG_SG;
-       qc->sg = sg;
+       qc->__sg = sg;
        qc->n_elem = n_elem;
+       qc->orig_n_elem = n_elem;
 }
 
 /**
@@ -2626,9 +2631,32 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
        int dir = qc->dma_dir;
-       struct scatterlist *sg = qc->sg;
+       struct scatterlist *sg = qc->__sg;
        dma_addr_t dma_address;
 
+       /* we must lengthen transfers to end on a 32-bit boundary */
+       qc->pad_len = sg->length & 3;
+       if (qc->pad_len) {
+               void *pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ);
+               struct scatterlist *psg = &qc->pad_sgent;
+
+               assert(qc->dev->class == ATA_DEV_ATAPI);
+
+               memset(pad_buf, 0, ATA_DMA_PAD_SZ);
+
+               if (qc->tf.flags & ATA_TFLAG_WRITE)
+                       memcpy(pad_buf, qc->buf_virt + sg->length - qc->pad_len,
+                              qc->pad_len);
+
+               sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ);
+               sg_dma_len(psg) = ATA_DMA_PAD_SZ;
+               /* trim sg */
+               sg->length -= qc->pad_len;
+
+               DPRINTK("padding done, sg->length=%u pad_len=%u\n",
+                       sg->length, qc->pad_len);
+       }
+
        dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt,
                                     sg->length, dir);
        if (dma_mapping_error(dma_address))
@@ -2660,12 +2688,47 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
 static int ata_sg_setup(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
-       struct scatterlist *sg = qc->sg;
+       struct scatterlist *sg = qc->__sg;
+       struct scatterlist *lsg = &sg[qc->n_elem - 1];
        int n_elem, dir;
 
        VPRINTK("ENTER, ata%u\n", ap->id);
        assert(qc->flags & ATA_QCFLAG_SG);
 
+       /* we must lengthen transfers to end on a 32-bit boundary */
+       qc->pad_len = lsg->length & 3;
+       if (qc->pad_len) {
+               void *pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ);
+               struct scatterlist *psg = &qc->pad_sgent;
+               unsigned int offset;
+
+               assert(qc->dev->class == ATA_DEV_ATAPI);
+
+               memset(pad_buf, 0, ATA_DMA_PAD_SZ);
+
+               /*
+                * psg->page/offset are used to copy to-be-written
+                * data in this function or read data in ata_sg_clean.
+                */
+               offset = lsg->offset + lsg->length - qc->pad_len;
+               psg->page = nth_page(lsg->page, offset >> PAGE_SHIFT);
+               psg->offset = offset_in_page(offset);
+
+               if (qc->tf.flags & ATA_TFLAG_WRITE) {
+                       void *addr = kmap_atomic(psg->page, KM_IRQ0);
+                       memcpy(pad_buf, addr + psg->offset, qc->pad_len);
+                       kunmap_atomic(psg->page, KM_IRQ0);
+               }
+
+               sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ);
+               sg_dma_len(psg) = ATA_DMA_PAD_SZ;
+               /* trim last sg */
+               lsg->length -= qc->pad_len;
+
+               DPRINTK("padding done, sg[%d].length=%u pad_len=%u\n",
+                       qc->n_elem - 1, lsg->length, qc->pad_len);
+       }
+
        dir = qc->dma_dir;
        n_elem = dma_map_sg(ap->host_set->dev, sg, qc->n_elem, dir);
        if (n_elem < 1)
@@ -2687,7 +2750,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
  *     None.  (grabs host lock)
  */
 
-void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
+void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
 {
        struct ata_port *ap = qc->ap;
        unsigned long flags;
@@ -2695,7 +2758,7 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
        spin_lock_irqsave(&ap->host_set->lock, flags);
        ap->flags &= ~ATA_FLAG_NOINTR;
        ata_irq_on(ap);
-       ata_qc_complete(qc, drv_stat);
+       ata_qc_complete(qc, err_mask);
        spin_unlock_irqrestore(&ap->host_set->lock, flags);
 }
 
@@ -2792,7 +2855,7 @@ static int ata_pio_complete (struct ata_port *ap)
 
        ap->hsm_task_state = HSM_ST_IDLE;
 
-       ata_poll_qc_complete(qc, drv_stat);
+       ata_poll_qc_complete(qc, 0);
 
        /* another command may start at this point */
 
@@ -2941,7 +3004,7 @@ static void ata_data_xfer(struct ata_port *ap, unsigned char *buf,
 static void ata_pio_sector(struct ata_queued_cmd *qc)
 {
        int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
-       struct scatterlist *sg = qc->sg;
+       struct scatterlist *sg = qc->__sg;
        struct ata_port *ap = qc->ap;
        struct page *page;
        unsigned int offset;
@@ -2991,7 +3054,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
 static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
 {
        int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
-       struct scatterlist *sg = qc->sg;
+       struct scatterlist *sg = qc->__sg;
        struct ata_port *ap = qc->ap;
        struct page *page;
        unsigned char *buf;
@@ -3024,7 +3087,7 @@ next_sg:
                return;
        }
 
-       sg = &qc->sg[qc->cursg];
+       sg = &qc->__sg[qc->cursg];
 
        page = sg->page;
        offset = sg->offset + qc->cursg_ofs;
@@ -3160,18 +3223,15 @@ static void ata_pio_block(struct ata_port *ap)
 static void ata_pio_error(struct ata_port *ap)
 {
        struct ata_queued_cmd *qc;
-       u8 drv_stat;
+
+       printk(KERN_WARNING "ata%u: PIO error\n", ap->id);
 
        qc = ata_qc_from_tag(ap, ap->active_tag);
        assert(qc != NULL);
 
-       drv_stat = ata_chk_status(ap);
-       printk(KERN_WARNING "ata%u: PIO error, drv_stat 0x%x\n",
-              ap->id, drv_stat);
-
        ap->hsm_task_state = HSM_ST_IDLE;
 
-       ata_poll_qc_complete(qc, drv_stat | ATA_ERR);
+       ata_poll_qc_complete(qc, AC_ERR_ATA_BUS);
 }
 
 static void ata_pio_task(void *_data)
@@ -3294,7 +3354,7 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
                       ap->id, qc->tf.command, drv_stat, host_stat);
 
                /* complete taskfile transaction */
-               ata_qc_complete(qc, drv_stat);
+               ata_qc_complete(qc, ac_err_mask(drv_stat));
                break;
        }
 
@@ -3384,7 +3444,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
 
        qc = ata_qc_new(ap);
        if (qc) {
-               qc->sg = NULL;
+               qc->__sg = NULL;
                qc->flags = 0;
                qc->scsicmd = NULL;
                qc->ap = ap;
@@ -3399,7 +3459,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
        return qc;
 }
 
-int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat)
+int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask)
 {
        return 0;
 }
@@ -3458,7 +3518,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
  *     spin_lock_irqsave(host_set lock)
  */
 
-void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
+void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
 {
        int rc;
 
@@ -3475,7 +3535,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
        qc->flags &= ~ATA_QCFLAG_ACTIVE;
 
        /* call completion callback */
-       rc = qc->complete_fn(qc, drv_stat);
+       rc = qc->complete_fn(qc, err_mask);
 
        /* if callback indicates not to complete command (non-zero),
         * return immediately
@@ -3913,7 +3973,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
                ap->ops->irq_clear(ap);
 
                /* complete taskfile transaction */
-               ata_qc_complete(qc, status);
+               ata_qc_complete(qc, ac_err_mask(status));
                break;
 
        default:
@@ -4008,7 +4068,7 @@ static void atapi_packet_task(void *_data)
        /* sleep-wait for BSY to clear */
        DPRINTK("busy wait\n");
        if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB))
-               goto err_out;
+               goto err_out_status;
 
        /* make sure DRQ is set */
        status = ata_chk_status(ap);
@@ -4045,8 +4105,10 @@ static void atapi_packet_task(void *_data)
 
        return;
 
+err_out_status:
+       status = ata_chk_status(ap);
 err_out:
-       ata_poll_qc_complete(qc, ATA_ERR);
+       ata_poll_qc_complete(qc, __ac_err_mask(status));
 }
 
 
@@ -4071,6 +4133,12 @@ int ata_port_start (struct ata_port *ap)
        if (!ap->prd)
                return -ENOMEM;
 
+       ap->pad = dma_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ, &ap->pad_dma, GFP_KERNEL);
+       if (!ap->pad) {
+               dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
+               return -ENOMEM;
+       }
+
        DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd, (unsigned long long) ap->prd_dma);
 
        return 0;
@@ -4094,6 +4162,7 @@ void ata_port_stop (struct ata_port *ap)
        struct device *dev = ap->host_set->dev;
 
        dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
+       dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma);
 }
 
 void ata_host_stop (struct ata_host_set *host_set)
@@ -4254,11 +4323,10 @@ int ata_device_add(const struct ata_probe_ent *ent)
 
        DPRINTK("ENTER\n");
        /* alloc a container for our list of ATA ports (buses) */
-       host_set = kmalloc(sizeof(struct ata_host_set) +
+       host_set = kzalloc(sizeof(struct ata_host_set) +
                           (ent->n_ports * sizeof(void *)), GFP_KERNEL);
        if (!host_set)
                return 0;
-       memset(host_set, 0, sizeof(struct ata_host_set) + (ent->n_ports * sizeof(void *)));
        spin_lock_init(&host_set->lock);
 
        host_set->dev = dev;
@@ -4298,10 +4366,8 @@ int ata_device_add(const struct ata_probe_ent *ent)
                count++;
        }
 
-       if (!count) {
-               kfree(host_set);
-               return 0;
-       }
+       if (!count)
+               goto err_free_ret;
 
        /* obtain irq, that is shared between channels */
        if (request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags,
@@ -4359,6 +4425,7 @@ err_out:
                ata_host_remove(host_set->ports[i], 1);
                scsi_host_put(host_set->ports[i]->host);
        }
+err_free_ret:
        kfree(host_set);
        VPRINTK("EXIT, returning 0\n");
        return 0;
@@ -4468,15 +4535,13 @@ ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port)
 {
        struct ata_probe_ent *probe_ent;
 
-       probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
+       probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
        if (!probe_ent) {
                printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
                       kobject_name(&(dev->kobj)));
                return NULL;
        }
 
-       memset(probe_ent, 0, sizeof(*probe_ent));
-
        INIT_LIST_HEAD(&probe_ent->node);
        probe_ent->dev = dev;
 
@@ -4873,7 +4938,6 @@ EXPORT_SYMBOL_GPL(ata_tf_to_fis);
 EXPORT_SYMBOL_GPL(ata_tf_from_fis);
 EXPORT_SYMBOL_GPL(ata_check_status);
 EXPORT_SYMBOL_GPL(ata_altstatus);
-EXPORT_SYMBOL_GPL(ata_chk_err);
 EXPORT_SYMBOL_GPL(ata_exec_command);
 EXPORT_SYMBOL_GPL(ata_port_start);
 EXPORT_SYMBOL_GPL(ata_port_stop);