[PATCH] mark several libata datastructures const
[pandora-kernel.git] / drivers / scsi / libata-core.c
index ff18fa7..11ed6fa 100644 (file)
@@ -51,8 +51,8 @@
 #include <linux/jiffies.h>
 #include <linux/scatterlist.h>
 #include <scsi/scsi.h>
-#include "scsi.h"
 #include "scsi_priv.h"
+#include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
 #include <asm/io.h>
@@ -532,8 +532,7 @@ void ata_tf_to_fis(const struct ata_taskfile *tf, u8 *fis, u8 pmp)
  *     @fis: Buffer from which data will be input
  *     @tf: Taskfile to output
  *
- *     Converts a standard ATA taskfile to a Serial ATA
- *     FIS structure (Register - Host to Device).
+ *     Converts a serial ATA FIS structure to a standard ATA taskfile.
  *
  *     LOCKING:
  *     Inherited from caller.
@@ -606,7 +605,7 @@ void ata_rwcmd_protocol(struct ata_queued_cmd *qc)
        tf->command = ata_rw_cmds[index + lba48 + write];
 }
 
-static const char * xfer_mode_str[] = {
+static const char * const xfer_mode_str[] = {
        "UDMA/16",
        "UDMA/25",
        "UDMA/33",
@@ -1047,6 +1046,30 @@ static unsigned int ata_pio_modes(const struct ata_device *adev)
        return modes;
 }
 
+static int ata_qc_wait_err(struct ata_queued_cmd *qc,
+                          struct completion *wait)
+{
+       int rc = 0;
+
+       if (wait_for_completion_timeout(wait, 30 * HZ) < 1) {
+               /* timeout handling */
+               unsigned int err_mask = ac_err_mask(ata_chk_status(qc->ap));
+
+               if (!err_mask) {
+                       printk(KERN_WARNING "ata%u: slow completion (cmd %x)\n",
+                              qc->ap->id, qc->tf.command);
+               } else {
+                       printk(KERN_WARNING "ata%u: qc timeout (cmd %x)\n",
+                              qc->ap->id, qc->tf.command);
+                       rc = -EIO;
+               }
+
+               ata_qc_complete(qc, err_mask);
+       }
+
+       return rc;
+}
+
 /**
  *     ata_dev_identify - obtain IDENTIFY x DEVICE page
  *     @ap: port on which device we wish to probe resides
@@ -1126,7 +1149,7 @@ retry:
        if (rc)
                goto err_out;
        else
-               wait_for_completion(&wait);
+               ata_qc_wait_err(qc, &wait);
 
        spin_lock_irqsave(&ap->host_set->lock, flags);
        ap->ops->tf_read(ap, &qc->tf);
@@ -1144,7 +1167,7 @@ retry:
                 * ATA software reset (SRST, the default) does not appear
                 * to have this problem.
                 */
-               if ((using_edd) && (qc->tf.command == ATA_CMD_ID_ATA)) {
+               if ((using_edd) && (dev->class == ATA_DEV_ATA)) {
                        u8 err = qc->tf.feature;
                        if (err & ATA_ABORTED) {
                                dev->class = ATA_DEV_ATAPI;
@@ -1264,7 +1287,7 @@ retry:
        }
 
        /* ATAPI-specific feature tests */
-       else {
+       else if (dev->class == ATA_DEV_ATAPI) {
                if (ata_id_is_ata(dev->id))             /* sanity check */
                        goto err_out_nosup;
 
@@ -1421,11 +1444,23 @@ void __sata_phy_reset(struct ata_port *ap)
        } while (time_before(jiffies, timeout));
 
        /* TODO: phy layer with polling, timeouts, etc. */
-       if (sata_dev_present(ap))
+       sstatus = scr_read(ap, SCR_STATUS);
+       if (sata_dev_present(ap)) {
+               const char *speed;
+               u32 tmp;
+
+               tmp = (sstatus >> 4) & 0xf;
+               if (tmp & (1 << 0))
+                       speed = "1.5";
+               else if (tmp & (1 << 1))
+                       speed = "3.0";
+               else
+                       speed = "<unknown>";
+               printk(KERN_INFO "ata%u: SATA link up %s Gbps (SStatus %X)\n",
+                      ap->id, speed, sstatus);
                ata_port_probe(ap);
-       else {
-               sstatus = scr_read(ap, SCR_STATUS);
-               printk(KERN_INFO "ata%u: no device found (phy stat %08x)\n",
+       } else {
+               printk(KERN_INFO "ata%u: SATA link down (SStatus %X)\n",
                       ap->id, sstatus);
                ata_port_disable(ap);
        }
@@ -1571,11 +1606,13 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
 
        /*
         * Find the mode. 
-       */
+        */
 
        if (!(s = ata_timing_find_mode(speed)))
                return -EINVAL;
 
+       memcpy(t, s, sizeof(*s));
+
        /*
         * If the drive is an EIDE drive, it can tell us it needs extended
         * PIO/MW_DMA cycle timing.
@@ -1596,7 +1633,7 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
         * Convert the timing to bus clock counts.
         */
 
-       ata_timing_quantize(s, t, T, UT);
+       ata_timing_quantize(t, t, T, UT);
 
        /*
         * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, S.M.A.R.T
@@ -2046,7 +2083,7 @@ static void ata_pr_blacklisted(const struct ata_port *ap,
                ap->id, dev->devno);
 }
 
-static const char * ata_dma_blacklist [] = {
+static const char * const ata_dma_blacklist [] = {
        "WDC AC11000H",
        "WDC AC22100H",
        "WDC AC32500H",
@@ -2268,7 +2305,7 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
        if (rc)
                ata_port_disable(ap);
        else
-               wait_for_completion(&wait);
+               ata_qc_wait_err(qc, &wait);
 
        DPRINTK("EXIT\n");
 }
@@ -2316,7 +2353,7 @@ static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev)
        if (rc)
                goto err_out;
 
-       wait_for_completion(&wait);
+       ata_qc_wait_err(qc, &wait);
 
        swap_buf_le16(dev->id, ATA_ID_WORDS);
 
@@ -2372,7 +2409,7 @@ static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev)
        if (rc)
                ata_port_disable(ap);
        else
-               wait_for_completion(&wait);
+               ata_qc_wait_err(qc, &wait);
 
        DPRINTK("EXIT\n");
 }
@@ -2390,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);
@@ -2399,16 +2437,40 @@ static void ata_sg_clean(struct ata_queued_cmd *qc)
        if (qc->flags & ATA_QCFLAG_SINGLE)
                assert(qc->n_elem == 1);
 
-       DPRINTK("unmapping %u sg elements\n", qc->n_elem);
+       VPRINTK("unmapping %u sg elements\n", qc->n_elem);
 
-       if (qc->flags & ATA_QCFLAG_SG)
-               dma_unmap_sg(ap->host_set->dev, sg, qc->n_elem, dir);
-       else
-               dma_unmap_single(ap->host_set->dev, sg_dma_address(&sg[0]),
-                                sg_dma_len(&sg[0]), dir);
+       /* 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) {
+               if (qc->n_elem)
+                       dma_unmap_sg(ap->host_set->dev, sg, qc->n_elem, dir);
+               /* 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 {
+               if (sg_dma_len(&sg[0]) > 0)
+                       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;
 }
 
 /**
@@ -2424,15 +2486,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;
 
@@ -2518,12 +2580,18 @@ void ata_qc_prep(struct ata_queued_cmd *qc)
 
 void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
 {
+       struct scatterlist *sg;
+
        qc->flags |= ATA_QCFLAG_SINGLE;
 
-       qc->sg = &qc->sgent;
+       memset(&qc->sgent, 0, sizeof(qc->sgent));
+       qc->__sg = &qc->sgent;
        qc->n_elem = 1;
+       qc->orig_n_elem = 1;
        qc->buf_virt = buf;
-       sg_init_one(qc->sg, buf, buflen);
+
+       sg = qc->__sg;
+       sg_init_one(sg, buf, buflen);
 }
 
 /**
@@ -2544,8 +2612,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;
 }
 
 /**
@@ -2565,15 +2634,47 @@ 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);
+       }
+
+       if (!sg->length) {
+               sg_dma_address(sg) = 0;
+               goto skip_map;
+       }
+
        dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt,
                                     sg->length, dir);
-       if (dma_mapping_error(dma_address))
+       if (dma_mapping_error(dma_address)) {
+               /* restore sg */
+               sg->length += qc->pad_len;
                return -1;
+       }
 
        sg_dma_address(sg) = dma_address;
+skip_map:
        sg_dma_len(sg) = sg->length;
 
        DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg),
@@ -2599,19 +2700,69 @@ 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;
-       int n_elem, dir;
+       struct scatterlist *sg = qc->__sg;
+       struct scatterlist *lsg = &sg[qc->n_elem - 1];
+       int n_elem, pre_n_elem, dir, trim_sg = 0;
 
        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;
+               if (lsg->length == 0)
+                       trim_sg = 1;
+
+               DPRINTK("padding done, sg[%d].length=%u pad_len=%u\n",
+                       qc->n_elem - 1, lsg->length, qc->pad_len);
+       }
+
+       pre_n_elem = qc->n_elem;
+       if (trim_sg && pre_n_elem)
+               pre_n_elem--;
+
+       if (!pre_n_elem) {
+               n_elem = 0;
+               goto skip_map;
+       }
+
        dir = qc->dma_dir;
-       n_elem = dma_map_sg(ap->host_set->dev, sg, qc->n_elem, dir);
-       if (n_elem < 1)
+       n_elem = dma_map_sg(ap->host_set->dev, sg, pre_n_elem, dir);
+       if (n_elem < 1) {
+               /* restore last sg */
+               lsg->length += qc->pad_len;
                return -1;
+       }
 
        DPRINTK("%d sg elements mapped\n", n_elem);
 
+skip_map:
        qc->n_elem = n_elem;
 
        return 0;
@@ -2620,7 +2771,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
 /**
  *     ata_poll_qc_complete - turn irq back on and finish qc
  *     @qc: Command to complete
- *     @drv_stat: ATA status register content
+ *     @err_mask: ATA status register content
  *
  *     LOCKING:
  *     None.  (grabs host lock)
@@ -2654,7 +2805,6 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
        u8 status;
        unsigned int poll_state = HSM_ST_UNKNOWN;
        unsigned int reg_state = HSM_ST_UNKNOWN;
-       const unsigned int tmout_state = HSM_ST_TMOUT;
 
        switch (ap->hsm_task_state) {
        case HSM_ST:
@@ -2675,7 +2825,7 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
        status = ata_chk_status(ap);
        if (status & ATA_BUSY) {
                if (time_after(jiffies, ap->pio_task_timeout)) {
-                       ap->hsm_task_state = tmout_state;
+                       ap->hsm_task_state = HSM_ST_TMOUT;
                        return 0;
                }
                ap->hsm_task_state = poll_state;
@@ -2880,7 +3030,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;
@@ -2930,7 +3080,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;
@@ -2963,7 +3113,7 @@ next_sg:
                return;
        }
 
-       sg = &qc->sg[qc->cursg];
+       sg = &qc->__sg[qc->cursg];
 
        page = sg->page;
        offset = sg->offset + qc->cursg_ofs;
@@ -3172,32 +3322,11 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
        struct ata_host_set *host_set = ap->host_set;
-       struct ata_device *dev = qc->dev;
        u8 host_stat = 0, drv_stat;
        unsigned long flags;
 
        DPRINTK("ENTER\n");
 
-       /* FIXME: doesn't this conflict with timeout handling? */
-       if (qc->dev->class == ATA_DEV_ATAPI && qc->scsicmd) {
-               struct scsi_cmnd *cmd = qc->scsicmd;
-
-               if (!(cmd->eh_eflags & SCSI_EH_CANCEL_CMD)) {
-
-                       /* finish completing original command */
-                       spin_lock_irqsave(&host_set->lock, flags);
-                       __ata_qc_complete(qc);
-                       spin_unlock_irqrestore(&host_set->lock, flags);
-
-                       atapi_request_sense(ap, dev, cmd);
-
-                       cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16);
-                       scsi_finish_command(cmd);
-
-                       goto out;
-               }
-       }
-
        spin_lock_irqsave(&host_set->lock, flags);
 
        /* hack alert!  We cannot use the supplied completion
@@ -3236,7 +3365,6 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
 
        spin_unlock_irqrestore(&host_set->lock, flags);
 
-out:
        DPRINTK("EXIT\n");
 }
 
@@ -3320,16 +3448,11 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
 
        qc = ata_qc_new(ap);
        if (qc) {
-               qc->sg = NULL;
-               qc->flags = 0;
                qc->scsicmd = NULL;
                qc->ap = ap;
                qc->dev = dev;
-               qc->cursect = qc->cursg = qc->cursg_ofs = 0;
-               qc->nsect = 0;
-               qc->nbytes = qc->curbytes = 0;
 
-               ata_tf_init(ap, &qc->tf, dev->devno);
+               ata_qc_reinit(qc);
        }
 
        return qc;
@@ -3385,7 +3508,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
 /**
  *     ata_qc_complete - Complete an active ATA command
  *     @qc: Command to complete
- *     @drv_stat: ATA Status register contents
+ *     @err_mask: ATA Status register contents
  *
  *     Indicate to the mid and upper layers that an ATA
  *     command has completed, with either an ok or not-ok status.
@@ -4004,11 +4127,18 @@ err_out:
 int ata_port_start (struct ata_port *ap)
 {
        struct device *dev = ap->host_set->dev;
+       int rc;
 
        ap->prd = dma_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_KERNEL);
        if (!ap->prd)
                return -ENOMEM;
 
+       rc = ata_pad_alloc(ap, dev);
+       if (rc) {
+               dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
+               return rc;
+       }
+
        DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd, (unsigned long long) ap->prd_dma);
 
        return 0;
@@ -4032,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);
+       ata_pad_free(ap, dev);
 }
 
 void ata_host_stop (struct ata_host_set *host_set)
@@ -4463,6 +4594,7 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
 
        probe_ent->irq = pdev->irq;
        probe_ent->irq_flags = SA_SHIRQ;
+       probe_ent->private_data = port[0]->private_data;
 
        if (ports & ATA_PORT_PRIMARY) {
                probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0);
@@ -4499,6 +4631,7 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, stru
        probe_ent->legacy_mode = 1;
        probe_ent->n_ports = 1;
        probe_ent->hard_port_no = port_num;
+       probe_ent->private_data = port->private_data;
 
        switch(port_num)
        {