ppp: fix BUG on non-linear SKB (multilink receive)
[safe/jmp/linux-2.6] / drivers / ata / libata-sff.c
index c59ad76..bbbb1fa 100644 (file)
@@ -52,6 +52,7 @@ const struct ata_port_operations ata_sff_port_ops = {
        .softreset              = ata_sff_softreset,
        .hardreset              = sata_sff_hardreset,
        .postreset              = ata_sff_postreset,
+       .drain_fifo             = ata_sff_drain_fifo,
        .error_handler          = ata_sff_error_handler,
        .post_internal_cmd      = ata_sff_post_internal_cmd,
 
@@ -64,6 +65,8 @@ const struct ata_port_operations ata_sff_port_ops = {
        .sff_irq_on             = ata_sff_irq_on,
        .sff_irq_clear          = ata_sff_irq_clear,
 
+       .lost_interrupt         = ata_sff_lost_interrupt,
+
        .port_start             = ata_sff_port_start,
 };
 EXPORT_SYMBOL_GPL(ata_sff_port_ops);
@@ -84,6 +87,7 @@ const struct ata_port_operations ata_bmdma32_port_ops = {
        .inherits               = &ata_bmdma_port_ops,
 
        .sff_data_xfer          = ata_sff_data_xfer32,
+       .port_start             = ata_sff_port_start32,
 };
 EXPORT_SYMBOL_GPL(ata_bmdma32_port_ops);
 
@@ -578,7 +582,7 @@ void ata_sff_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
        }
 
        if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
-               WARN_ON(!ioaddr->ctl_addr);
+               WARN_ON_ONCE(!ioaddr->ctl_addr);
                iowrite8(tf->hob_feature, ioaddr->feature_addr);
                iowrite8(tf->hob_nsect, ioaddr->nsect_addr);
                iowrite8(tf->hob_lbal, ioaddr->lbal_addr);
@@ -651,7 +655,7 @@ void ata_sff_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
                        iowrite8(tf->ctl, ioaddr->ctl_addr);
                        ap->last_ctl = tf->ctl;
                } else
-                       WARN_ON(1);
+                       WARN_ON_ONCE(1);
        }
 }
 EXPORT_SYMBOL_GPL(ata_sff_tf_read);
@@ -723,17 +727,23 @@ unsigned int ata_sff_data_xfer(struct ata_device *dev, unsigned char *buf,
        else
                iowrite16_rep(data_addr, buf, words);
 
-       /* Transfer trailing byte, if any. */
+       /* Transfer trailing byte, if any. */
        if (unlikely(buflen & 0x01)) {
-               __le16 align_buf[1] = { 0 };
-               unsigned char *trailing_buf = buf + buflen - 1;
+               unsigned char pad[2];
+
+               /* Point buf to the tail of buffer */
+               buf += buflen - 1;
 
+               /*
+                * Use io*16_rep() accessors here as well to avoid pointlessly
+                * swapping bytes to and fro on the big endian machines...
+                */
                if (rw == READ) {
-                       align_buf[0] = cpu_to_le16(ioread16(data_addr));
-                       memcpy(trailing_buf, align_buf, 1);
+                       ioread16_rep(data_addr, pad, 1);
+                       *buf = pad[0];
                } else {
-                       memcpy(align_buf, trailing_buf, 1);
-                       iowrite16(le16_to_cpu(align_buf[0]), data_addr);
+                       pad[0] = *buf;
+                       iowrite16_rep(data_addr, pad, 1);
                }
                words++;
        }
@@ -766,6 +776,9 @@ unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf,
        void __iomem *data_addr = ap->ioaddr.data_addr;
        unsigned int words = buflen >> 2;
        int slop = buflen & 3;
+       
+       if (!(ap->pflags & ATA_PFLAG_PIO32))
+               return ata_sff_data_xfer(dev, buf, buflen, rw);
 
        /* Transfer multiple of 4 bytes */
        if (rw == READ)
@@ -773,18 +786,32 @@ unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf,
        else
                iowrite32_rep(data_addr, buf, words);
 
+       /* Transfer trailing bytes, if any */
        if (unlikely(slop)) {
-               __le32 pad;
+               unsigned char pad[4];
+
+               /* Point buf to the tail of buffer */
+               buf += buflen - slop;
+
+               /*
+                * Use io*_rep() accessors here as well to avoid pointlessly
+                * swapping bytes to and fro on the big endian machines...
+                */
                if (rw == READ) {
-                       pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
-                       memcpy(buf + buflen - slop, &pad, slop);
+                       if (slop < 3)
+                               ioread16_rep(data_addr, pad, 1);
+                       else
+                               ioread32_rep(data_addr, pad, 1);
+                       memcpy(buf, pad, slop);
                } else {
-                       memcpy(&pad, buf + buflen - slop, slop);
-                       iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
+                       memcpy(pad, buf, slop);
+                       if (slop < 3)
+                               iowrite16_rep(data_addr, pad, 1);
+                       else
+                               iowrite32_rep(data_addr, pad, 1);
                }
-               words++;
        }
-       return words << 2;
+       return (buflen + 1) & ~1;
 }
 EXPORT_SYMBOL_GPL(ata_sff_data_xfer32);
 
@@ -891,7 +918,7 @@ static void ata_pio_sectors(struct ata_queued_cmd *qc)
                /* READ/WRITE MULTIPLE */
                unsigned int nsect;
 
-               WARN_ON(qc->dev->multi_count == 0);
+               WARN_ON_ONCE(qc->dev->multi_count == 0);
 
                nsect = min((qc->nbytes - qc->curbytes) / qc->sect_size,
                            qc->dev->multi_count);
@@ -918,7 +945,7 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc)
 {
        /* send SCSI cdb */
        DPRINTK("send cdb\n");
-       WARN_ON(qc->dev->cdb_len < 12);
+       WARN_ON_ONCE(qc->dev->cdb_len < 12);
 
        ap->ops->sff_data_xfer(qc->dev, qc->cdb, qc->dev->cdb_len, 1);
        ata_sff_sync(ap);
@@ -1013,9 +1040,12 @@ next_sg:
                qc->cursg_ofs = 0;
        }
 
-       /* consumed can be larger than count only for the last transfer */
-       WARN_ON(qc->cursg && count != consumed);
-
+       /*
+        * There used to be a  WARN_ON_ONCE(qc->cursg && count != consumed);
+        * Unfortunately __atapi_pio_bytes doesn't know enough to do the WARN
+        * check correctly as it doesn't know if it is the last request being
+        * made. Somebody should implement a proper sanity check.
+        */
        if (bytes)
                goto next_sg;
        return 0;
@@ -1172,13 +1202,13 @@ int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
        unsigned long flags = 0;
        int poll_next;
 
-       WARN_ON((qc->flags & ATA_QCFLAG_ACTIVE) == 0);
+       WARN_ON_ONCE((qc->flags & ATA_QCFLAG_ACTIVE) == 0);
 
        /* Make sure ata_sff_qc_issue() does not throw things
         * like DMA polling into the workqueue. Notice that
         * in_wq is not equivalent to (qc->tf.flags & ATA_TFLAG_POLLING).
         */
-       WARN_ON(in_wq != ata_hsm_ok_in_wq(ap, qc));
+       WARN_ON_ONCE(in_wq != ata_hsm_ok_in_wq(ap, qc));
 
 fsm_start:
        DPRINTK("ata%u: protocol %d task_state %d (dev_stat 0x%X)\n",
@@ -1319,7 +1349,7 @@ fsm_start:
                                         * condition.  Mark hint.
                                         */
                                        ata_ehi_push_desc(ehi, "ST-ATA: "
-                                               "DRQ=1 with device error, "
+                                               "DRQ=0 without device error, "
                                                "dev_stat 0x%X", status);
                                        qc->err_mask |= AC_ERR_HSM |
                                                        AC_ERR_NODEV_HINT;
@@ -1355,6 +1385,16 @@ fsm_start:
                                        qc->err_mask |= AC_ERR_HSM;
                                }
 
+                               /* There are oddball controllers with
+                                * status register stuck at 0x7f and
+                                * lbal/m/h at zero which makes it
+                                * pass all other presence detection
+                                * mechanisms we have.  Set NODEV_HINT
+                                * for it.  Kernel bz#7241.
+                                */
+                               if (status == 0x7f)
+                                       qc->err_mask |= AC_ERR_NODEV_HINT;
+
                                /* ata_pio_sectors() might change the
                                 * state to HSM_ST_LAST. so, the state
                                 * is changed after ata_pio_sectors().
@@ -1387,7 +1427,7 @@ fsm_start:
                DPRINTK("ata%u: dev %u command complete, drv_stat 0x%x\n",
                        ap->print_id, qc->dev->devno, status);
 
-               WARN_ON(qc->err_mask & (AC_ERR_DEV | AC_ERR_HSM));
+               WARN_ON_ONCE(qc->err_mask & (AC_ERR_DEV | AC_ERR_HSM));
 
                ap->hsm_task_state = HSM_ST_IDLE;
 
@@ -1423,7 +1463,7 @@ void ata_pio_task(struct work_struct *work)
        int poll_next;
 
 fsm_start:
-       WARN_ON(ap->hsm_task_state == HSM_ST_IDLE);
+       WARN_ON_ONCE(ap->hsm_task_state == HSM_ST_IDLE);
 
        /*
         * This is purely heuristic.  This is a fast path.
@@ -1512,7 +1552,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
                break;
 
        case ATA_PROT_DMA:
-               WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
+               WARN_ON_ONCE(qc->tf.flags & ATA_TFLAG_POLLING);
 
                ap->ops->sff_tf_load(ap, &qc->tf);  /* load tf registers */
                ap->ops->bmdma_setup(qc);           /* set up bmdma */
@@ -1564,7 +1604,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
                break;
 
        case ATAPI_PROT_DMA:
-               WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
+               WARN_ON_ONCE(qc->tf.flags & ATA_TFLAG_POLLING);
 
                ap->ops->sff_tf_load(ap, &qc->tf);  /* load tf registers */
                ap->ops->bmdma_setup(qc);           /* set up bmdma */
@@ -1576,7 +1616,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
                break;
 
        default:
-               WARN_ON(1);
+               WARN_ON_ONCE(1);
                return AC_ERR_SYSTEM;
        }
 
@@ -1619,7 +1659,7 @@ EXPORT_SYMBOL_GPL(ata_sff_qc_fill_rtf);
  *     RETURNS:
  *     One if interrupt was handled, zero if not (shared irq).
  */
-inline unsigned int ata_sff_host_intr(struct ata_port *ap,
+unsigned int ata_sff_host_intr(struct ata_port *ap,
                                      struct ata_queued_cmd *qc)
 {
        struct ata_eh_info *ehi = &ap->link.eh_info;
@@ -1748,6 +1788,48 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
 EXPORT_SYMBOL_GPL(ata_sff_interrupt);
 
 /**
+ *     ata_sff_lost_interrupt  -       Check for an apparent lost interrupt
+ *     @ap: port that appears to have timed out
+ *
+ *     Called from the libata error handlers when the core code suspects
+ *     an interrupt has been lost. If it has complete anything we can and
+ *     then return. Interface must support altstatus for this faster
+ *     recovery to occur.
+ *
+ *     Locking:
+ *     Caller holds host lock
+ */
+
+void ata_sff_lost_interrupt(struct ata_port *ap)
+{
+       u8 status;
+       struct ata_queued_cmd *qc;
+
+       /* Only one outstanding command per SFF channel */
+       qc = ata_qc_from_tag(ap, ap->link.active_tag);
+       /* Check we have a live one.. */
+       if (qc == NULL ||  !(qc->flags & ATA_QCFLAG_ACTIVE))
+               return;
+       /* We cannot lose an interrupt on a polled command */
+       if (qc->tf.flags & ATA_TFLAG_POLLING)
+               return;
+       /* See if the controller thinks it is still busy - if so the command
+          isn't a lost IRQ but is still in progress */
+       status = ata_sff_altstatus(ap);
+       if (status & ATA_BUSY)
+               return;
+
+       /* There was a command running, we are no longer busy and we have
+          no interrupt. */
+       ata_port_printk(ap, KERN_WARNING, "lost interrupt (Status 0x%x)\n",
+                                                               status);
+       /* Run the host interrupt logic as if the interrupt had not been
+          lost */
+       ata_sff_host_intr(ap, qc);
+}
+EXPORT_SYMBOL_GPL(ata_sff_lost_interrupt);
+
+/**
  *     ata_sff_freeze - Freeze SFF controller port
  *     @ap: port to freeze
  *
@@ -2039,6 +2121,7 @@ static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,
        iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
        udelay(20);     /* FIXME: flush */
        iowrite8(ap->ctl, ioaddr->ctl_addr);
+       ap->last_ctl = ap->ctl;
 
        /* wait the port to become ready */
        return ata_sff_wait_after_reset(&ap->link, devmask, deadline);
@@ -2163,12 +2246,47 @@ void ata_sff_postreset(struct ata_link *link, unsigned int *classes)
        }
 
        /* set up device control */
-       if (ap->ioaddr.ctl_addr)
+       if (ap->ioaddr.ctl_addr) {
                iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
+               ap->last_ctl = ap->ctl;
+       }
 }
 EXPORT_SYMBOL_GPL(ata_sff_postreset);
 
 /**
+ *     ata_sff_drain_fifo - Stock FIFO drain logic for SFF controllers
+ *     @qc: command
+ *
+ *     Drain the FIFO and device of any stuck data following a command
+ *     failing to complete. In some cases this is neccessary before a
+ *     reset will recover the device.
+ *
+ */
+
+void ata_sff_drain_fifo(struct ata_queued_cmd *qc)
+{
+       int count;
+       struct ata_port *ap;
+
+       /* We only need to flush incoming data when a command was running */
+       if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE)
+               return;
+
+       ap = qc->ap;
+       /* Drain up to 64K of data before we give up this recovery method */
+       for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ)
+                                               && count < 32768; count++)
+               ioread16(ap->ioaddr.data_addr);
+
+       /* Can become DEBUG later */
+       if (count)
+               ata_port_printk(ap, KERN_DEBUG,
+                       "drained %d bytes to clear DRQ.\n", count);
+
+}
+EXPORT_SYMBOL_GPL(ata_sff_drain_fifo);
+
+/**
  *     ata_sff_error_handler - Stock error handler for BMDMA controller
  *     @ap: port to handle error for
  *
@@ -2209,7 +2327,8 @@ void ata_sff_error_handler(struct ata_port *ap)
                 * really a timeout event, adjust error mask and
                 * cancel frozen state.
                 */
-               if (qc->err_mask == AC_ERR_TIMEOUT && (host_stat & ATA_DMA_ERR)) {
+               if (qc->err_mask == AC_ERR_TIMEOUT
+                                               && (host_stat & ATA_DMA_ERR)) {
                        qc->err_mask = AC_ERR_HOST_BUS;
                        thaw = 1;
                }
@@ -2220,6 +2339,13 @@ void ata_sff_error_handler(struct ata_port *ap)
        ata_sff_sync(ap);               /* FIXME: We don't need this */
        ap->ops->sff_check_status(ap);
        ap->ops->sff_irq_clear(ap);
+       /* We *MUST* do FIFO draining before we issue a reset as several
+        * devices helpfully clear their internal state and will lock solid
+        * if we touch the data port post reset. Pass qc in case anyone wants
+        *  to do different PIO/DMA recovery or has per command fixups
+        */
+       if (ap->ops->drain_fifo)
+               ap->ops->drain_fifo(qc);
 
        spin_unlock_irqrestore(ap->lock, flags);
 
@@ -2286,6 +2412,29 @@ int ata_sff_port_start(struct ata_port *ap)
 EXPORT_SYMBOL_GPL(ata_sff_port_start);
 
 /**
+ *     ata_sff_port_start32 - Set port up for dma.
+ *     @ap: Port to initialize
+ *
+ *     Called just after data structures for each port are
+ *     initialized.  Allocates space for PRD table if the device
+ *     is DMA capable SFF.
+ *
+ *     May be used as the port_start() entry in ata_port_operations for
+ *     devices that are capable of 32bit PIO.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+int ata_sff_port_start32(struct ata_port *ap)
+{
+       ap->pflags |= ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE;
+       if (ap->ioaddr.bmdma_addr)
+               return ata_port_start(ap);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ata_sff_port_start32);
+
+/**
  *     ata_sff_std_ports - initialize ioaddr with standard port offsets.
  *     @ioaddr: IO address structure to be initialized
  *
@@ -2507,6 +2656,7 @@ void ata_bus_reset(struct ata_port *ap)
        if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) {
                /* set up device control for ATA_FLAG_SATA_RESET */
                iowrite8(ap->ctl, ioaddr->ctl_addr);
+               ap->last_ctl = ap->ctl;
        }
 
        DPRINTK("EXIT\n");
@@ -2928,4 +3078,3 @@ out:
 EXPORT_SYMBOL_GPL(ata_pci_sff_init_one);
 
 #endif /* CONFIG_PCI */
-