]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ata/libata-core.c
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[linux-2.6-omap-h63xx.git] / drivers / ata / libata-core.c
index db760e2dc30b44525fa0d82ee5339a2ef5eaad22..629eadbd0ec09c17f538ace9ffd7921161679eac 100644 (file)
@@ -926,7 +926,7 @@ static int ata_read_native_max_address(struct ata_device *dev, u64 *max_sectors)
        tf.protocol |= ATA_PROT_NODATA;
        tf.device |= ATA_LBA;
 
-       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
        if (err_mask) {
                ata_dev_printk(dev, KERN_WARNING, "failed to read native "
                               "max address (err_mask=0x%x)\n", err_mask);
@@ -988,7 +988,7 @@ static int ata_set_max_sectors(struct ata_device *dev, u64 new_sectors)
        tf.lbam = (new_sectors >> 8) & 0xff;
        tf.lbah = (new_sectors >> 16) & 0xff;
 
-       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
        if (err_mask) {
                ata_dev_printk(dev, KERN_WARNING, "failed to set "
                               "max address (err_mask=0x%x)\n", err_mask);
@@ -1392,8 +1392,9 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
  *     @tf: Taskfile registers for the command and the result
  *     @cdb: CDB for packet command
  *     @dma_dir: Data tranfer direction of the command
- *     @sg: sg list for the data buffer of the command
+ *     @sgl: sg list for the data buffer of the command
  *     @n_elem: Number of sg entries
+ *     @timeout: Timeout in msecs (0 for default)
  *
  *     Executes libata internal command with timeout.  @tf contains
  *     command on entry and result on return.  Timeout and error
@@ -1409,8 +1410,8 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
  */
 unsigned ata_exec_internal_sg(struct ata_device *dev,
                              struct ata_taskfile *tf, const u8 *cdb,
-                             int dma_dir, struct scatterlist *sg,
-                             unsigned int n_elem)
+                             int dma_dir, struct scatterlist *sgl,
+                             unsigned int n_elem, unsigned long timeout)
 {
        struct ata_link *link = dev->link;
        struct ata_port *ap = link->ap;
@@ -1471,11 +1472,12 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
        qc->dma_dir = dma_dir;
        if (dma_dir != DMA_NONE) {
                unsigned int i, buflen = 0;
+               struct scatterlist *sg;
 
-               for (i = 0; i < n_elem; i++)
-                       buflen += sg[i].length;
+               for_each_sg(sgl, sg, n_elem, i)
+                       buflen += sg->length;
 
-               ata_sg_init(qc, sg, n_elem);
+               ata_sg_init(qc, sgl, n_elem);
                qc->nbytes = buflen;
        }
 
@@ -1486,7 +1488,10 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
 
        spin_unlock_irqrestore(ap->lock, flags);
 
-       rc = wait_for_completion_timeout(&wait, ata_probe_timeout);
+       if (!timeout)
+               timeout = ata_probe_timeout * 1000 / HZ;
+
+       rc = wait_for_completion_timeout(&wait, msecs_to_jiffies(timeout));
 
        ata_port_flush_task(ap);
 
@@ -1571,6 +1576,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
  *     @dma_dir: Data tranfer direction of the command
  *     @buf: Data buffer of the command
  *     @buflen: Length of data buffer
+ *     @timeout: Timeout in msecs (0 for default)
  *
  *     Wrapper around ata_exec_internal_sg() which takes simple
  *     buffer instead of sg list.
@@ -1583,7 +1589,8 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
  */
 unsigned ata_exec_internal(struct ata_device *dev,
                           struct ata_taskfile *tf, const u8 *cdb,
-                          int dma_dir, void *buf, unsigned int buflen)
+                          int dma_dir, void *buf, unsigned int buflen,
+                          unsigned long timeout)
 {
        struct scatterlist *psg = NULL, sg;
        unsigned int n_elem = 0;
@@ -1595,7 +1602,8 @@ unsigned ata_exec_internal(struct ata_device *dev,
                n_elem++;
        }
 
-       return ata_exec_internal_sg(dev, tf, cdb, dma_dir, psg, n_elem);
+       return ata_exec_internal_sg(dev, tf, cdb, dma_dir, psg, n_elem,
+                                   timeout);
 }
 
 /**
@@ -1622,7 +1630,7 @@ unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd)
        tf.flags |= ATA_TFLAG_DEVICE;
        tf.protocol = ATA_PROT_NODATA;
 
-       return ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+       return ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
 }
 
 /**
@@ -1737,7 +1745,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
        tf.flags |= ATA_TFLAG_POLLING;
 
        err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
-                                    id, sizeof(id[0]) * ATA_ID_WORDS);
+                                    id, sizeof(id[0]) * ATA_ID_WORDS, 0);
        if (err_mask) {
                if (err_mask & AC_ERR_NODEV_HINT) {
                        DPRINTK("ata%u.%d: NODEV after polling detection\n",
@@ -1796,7 +1804,8 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
                tf.feature = SETFEATURES_SPINUP;
                tf.protocol = ATA_PROT_NODATA;
                tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-               err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+               err_mask = ata_exec_internal(dev, &tf, NULL,
+                                            DMA_NONE, NULL, 0, 0);
                if (err_mask && id[2] != 0x738c) {
                        rc = -EIO;
                        reason = "SPINUP failed";
@@ -3976,6 +3985,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "ST9120822AS",        "3.CLF",        ATA_HORKAGE_NONCQ, },
        { "ST9160821AS",        "3.CLF",        ATA_HORKAGE_NONCQ, },
        { "ST9160821AS",        "3.ALD",        ATA_HORKAGE_NONCQ, },
+       { "ST9160821AS",        "3.CCD",        ATA_HORKAGE_NONCQ, },
        { "ST3160812AS",        "3.ADJ",        ATA_HORKAGE_NONCQ, },
        { "ST980813AS",         "3.ADB",        ATA_HORKAGE_NONCQ, },
        { "SAMSUNG HD401LJ",    "ZZ100-15",     ATA_HORKAGE_NONCQ, },
@@ -4005,8 +4015,14 @@ int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
        p = strchr(patt, wildchar);
        if (p && ((*(p + 1)) == 0))
                len = p - patt;
-       else
+       else {
                len = strlen(name);
+               if (!len) {
+                       if (!*patt)
+                               return 0;
+                       return -1;
+               }
+       }
 
        return strncmp(patt, name, len);
 }
@@ -4157,7 +4173,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev)
        tf.protocol = ATA_PROT_NODATA;
        tf.nsect = dev->xfer_mode;
 
-       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
 
        DPRINTK("EXIT, err_mask=%x\n", err_mask);
        return err_mask;
@@ -4193,7 +4209,7 @@ static unsigned int ata_dev_set_AN(struct ata_device *dev, u8 enable)
        tf.protocol = ATA_PROT_NODATA;
        tf.nsect = SATA_AN;
 
-       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
 
        DPRINTK("EXIT, err_mask=%x\n", err_mask);
        return err_mask;
@@ -4231,7 +4247,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev,
        tf.nsect = sectors;
        tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
 
-       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+       err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
        /* A clean abort indicates an original or just out of spec drive
           and we should continue as we issue the setup based on the
           drive reported working geometry */
@@ -4277,7 +4293,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
                if (qc->n_elem)
                        dma_unmap_sg(ap->dev, sg, qc->n_elem, dir);
                /* restore last sg */
-               sg[qc->orig_n_elem - 1].length += qc->pad_len;
+               sg_last(sg, qc->orig_n_elem)->length += qc->pad_len;
                if (pad_buf) {
                        struct scatterlist *psg = &qc->pad_sgent;
                        void *addr = kmap_atomic(psg->page, KM_IRQ0);
@@ -4532,6 +4548,7 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
        qc->orig_n_elem = 1;
        qc->buf_virt = buf;
        qc->nbytes = buflen;
+       qc->cursg = qc->__sg;
 
        sg_init_one(&qc->sgent, buf, buflen);
 }
@@ -4557,6 +4574,7 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
        qc->__sg = sg;
        qc->n_elem = n_elem;
        qc->orig_n_elem = n_elem;
+       qc->cursg = qc->__sg;
 }
 
 /**
@@ -4646,7 +4664,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
        struct scatterlist *sg = qc->__sg;
-       struct scatterlist *lsg = &sg[qc->n_elem - 1];
+       struct scatterlist *lsg = sg_last(qc->__sg, qc->n_elem);
        int n_elem, pre_n_elem, dir, trim_sg = 0;
 
        VPRINTK("ENTER, ata%u\n", ap->print_id);
@@ -4810,7 +4828,6 @@ void ata_data_xfer_noirq(struct ata_device *adev, 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 ata_port *ap = qc->ap;
        struct page *page;
        unsigned int offset;
@@ -4819,8 +4836,8 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
        if (qc->curbytes == qc->nbytes - qc->sect_size)
                ap->hsm_task_state = HSM_ST_LAST;
 
-       page = sg[qc->cursg].page;
-       offset = sg[qc->cursg].offset + qc->cursg_ofs;
+       page = qc->cursg->page;
+       offset = qc->cursg->offset + qc->cursg_ofs;
 
        /* get the current page and offset */
        page = nth_page(page, (offset >> PAGE_SHIFT));
@@ -4848,8 +4865,8 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
        qc->curbytes += qc->sect_size;
        qc->cursg_ofs += qc->sect_size;
 
-       if (qc->cursg_ofs == (&sg[qc->cursg])->length) {
-               qc->cursg++;
+       if (qc->cursg_ofs == qc->cursg->length) {
+               qc->cursg = sg_next(qc->cursg);
                qc->cursg_ofs = 0;
        }
 }
@@ -4935,16 +4952,18 @@ 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 *lsg = sg_last(qc->__sg, qc->n_elem);
        struct ata_port *ap = qc->ap;
        struct page *page;
        unsigned char *buf;
        unsigned int offset, count;
+       int no_more_sg = 0;
 
        if (qc->curbytes + bytes >= qc->nbytes)
                ap->hsm_task_state = HSM_ST_LAST;
 
 next_sg:
-       if (unlikely(qc->cursg >= qc->n_elem)) {
+       if (unlikely(no_more_sg)) {
                /*
                 * The end of qc->sg is reached and the device expects
                 * more data to transfer. In order not to overrun qc->sg
@@ -4967,7 +4986,7 @@ next_sg:
                return;
        }
 
-       sg = &qc->__sg[qc->cursg];
+       sg = qc->cursg;
 
        page = sg->page;
        offset = sg->offset + qc->cursg_ofs;
@@ -5006,7 +5025,10 @@ next_sg:
        qc->cursg_ofs += count;
 
        if (qc->cursg_ofs == sg->length) {
-               qc->cursg++;
+               if (qc->cursg == lsg)
+                       no_more_sg = 1;
+
+               qc->cursg = sg_next(qc->cursg);
                qc->cursg_ofs = 0;
        }
 
@@ -6999,7 +7021,7 @@ void ata_std_ports(struct ata_ioports *ioaddr)
  */
 void ata_pci_remove_one(struct pci_dev *pdev)
 {
-       struct device *dev = pci_dev_to_dev(pdev);
+       struct device *dev = &pdev->dev;
        struct ata_host *host = dev_get_drvdata(dev);
 
        ata_host_detach(host);
@@ -7346,9 +7368,6 @@ EXPORT_SYMBOL_GPL(ata_pci_clear_simplex);
 #endif /* CONFIG_PCI */
 
 EXPORT_SYMBOL_GPL(sata_pmp_qc_defer_cmd_switch);
-EXPORT_SYMBOL_GPL(sata_pmp_read_init_tf);
-EXPORT_SYMBOL_GPL(sata_pmp_read_val);
-EXPORT_SYMBOL_GPL(sata_pmp_write_init_tf);
 EXPORT_SYMBOL_GPL(sata_pmp_std_prereset);
 EXPORT_SYMBOL_GPL(sata_pmp_std_hardreset);
 EXPORT_SYMBOL_GPL(sata_pmp_std_postreset);