USB: rndis_host, various cleanups
[powerpc.git] / drivers / ata / sata_nv.c
index b564ff8..9d9670a 100644 (file)
@@ -230,7 +230,9 @@ struct nv_host_priv {
 
 static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
 static void nv_remove_one (struct pci_dev *pdev);
+#ifdef CONFIG_PM
 static int nv_pci_device_resume(struct pci_dev *pdev);
+#endif
 static void nv_ck804_host_stop(struct ata_host *host);
 static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance);
 static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance);
@@ -251,14 +253,13 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance);
 static void nv_adma_irq_clear(struct ata_port *ap);
 static int nv_adma_port_start(struct ata_port *ap);
 static void nv_adma_port_stop(struct ata_port *ap);
+#ifdef CONFIG_PM
 static int nv_adma_port_suspend(struct ata_port *ap, pm_message_t mesg);
 static int nv_adma_port_resume(struct ata_port *ap);
+#endif
 static void nv_adma_error_handler(struct ata_port *ap);
 static void nv_adma_host_stop(struct ata_host *host);
-static void nv_adma_bmdma_setup(struct ata_queued_cmd *qc);
-static void nv_adma_bmdma_start(struct ata_queued_cmd *qc);
-static void nv_adma_bmdma_stop(struct ata_queued_cmd *qc);
-static u8 nv_adma_bmdma_status(struct ata_port *ap);
+static void nv_adma_post_internal_cmd(struct ata_queued_cmd *qc);
 
 enum nv_host_type
 {
@@ -298,8 +299,10 @@ static struct pci_driver nv_pci_driver = {
        .name                   = DRV_NAME,
        .id_table               = nv_pci_tbl,
        .probe                  = nv_init_one,
+#ifdef CONFIG_PM
        .suspend                = ata_pci_device_suspend,
        .resume                 = nv_pci_device_resume,
+#endif
        .remove                 = nv_remove_one,
 };
 
@@ -319,8 +322,10 @@ static struct scsi_host_template nv_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
+#ifdef CONFIG_PM
        .suspend                = ata_scsi_device_suspend,
        .resume                 = ata_scsi_device_resume,
+#endif
 };
 
 static struct scsi_host_template nv_adma_sht = {
@@ -339,8 +344,10 @@ static struct scsi_host_template nv_adma_sht = {
        .slave_configure        = nv_adma_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
+#ifdef CONFIG_PM
        .suspend                = ata_scsi_device_suspend,
        .resume                 = ata_scsi_device_resume,
+#endif
 };
 
 static const struct ata_port_operations nv_generic_ops = {
@@ -433,16 +440,16 @@ static const struct ata_port_operations nv_adma_ops = {
        .exec_command           = ata_exec_command,
        .check_status           = ata_check_status,
        .dev_select             = ata_std_dev_select,
-       .bmdma_setup            = nv_adma_bmdma_setup,
-       .bmdma_start            = nv_adma_bmdma_start,
-       .bmdma_stop             = nv_adma_bmdma_stop,
-       .bmdma_status           = nv_adma_bmdma_status,
+       .bmdma_setup            = ata_bmdma_setup,
+       .bmdma_start            = ata_bmdma_start,
+       .bmdma_stop             = ata_bmdma_stop,
+       .bmdma_status           = ata_bmdma_status,
        .qc_prep                = nv_adma_qc_prep,
        .qc_issue               = nv_adma_qc_issue,
        .freeze                 = nv_ck804_freeze,
        .thaw                   = nv_ck804_thaw,
        .error_handler          = nv_adma_error_handler,
-       .post_internal_cmd      = nv_adma_bmdma_stop,
+       .post_internal_cmd      = nv_adma_post_internal_cmd,
        .data_xfer              = ata_data_xfer,
        .irq_handler            = nv_adma_interrupt,
        .irq_clear              = nv_adma_irq_clear,
@@ -452,8 +459,10 @@ static const struct ata_port_operations nv_adma_ops = {
        .scr_write              = nv_scr_write,
        .port_start             = nv_adma_port_start,
        .port_stop              = nv_adma_port_stop,
+#ifdef CONFIG_PM
        .port_suspend           = nv_adma_port_suspend,
        .port_resume            = nv_adma_port_resume,
+#endif
        .host_stop              = nv_adma_host_stop,
 };
 
@@ -672,18 +681,18 @@ static unsigned int nv_adma_tf_to_cpb(struct ata_taskfile *tf, __le16 *cpb)
                        cpb[idx++] = cpu_to_le16((ATA_REG_ERR    << 8) | tf->feature);
                } else
                        cpb[idx++] = cpu_to_le16((ATA_REG_ERR    << 8) | tf->feature | WNB);
-                       
+
                cpb[idx++] = cpu_to_le16((ATA_REG_NSECT  << 8) | tf->nsect);
                cpb[idx++] = cpu_to_le16((ATA_REG_LBAL   << 8) | tf->lbal);
                cpb[idx++] = cpu_to_le16((ATA_REG_LBAM   << 8) | tf->lbam);
                cpb[idx++] = cpu_to_le16((ATA_REG_LBAH   << 8) | tf->lbah);
        }
-       
+
        if(tf->flags & ATA_TFLAG_DEVICE)
                cpb[idx++] = cpu_to_le16((ATA_REG_DEVICE << 8) | tf->device);
 
        cpb[idx++] = cpu_to_le16((ATA_REG_CMD    << 8) | tf->command | CMDEND);
-       
+
        while(idx < 12)
                cpb[idx++] = cpu_to_le16(IGN);
 
@@ -743,6 +752,17 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
                        DPRINTK("Completing qc from tag %d with err_mask %u\n",cpb_num,
                                qc->err_mask);
                        ata_qc_complete(qc);
+               } else {
+                       struct ata_eh_info *ehi = &ap->eh_info;
+                       /* Notifier bits set without a command may indicate the drive
+                          is misbehaving. Raise host state machine violation on this
+                          condition. */
+                       ata_port_printk(ap, KERN_ERR, "notifier for tag %d with no command?\n",
+                               cpb_num);
+                       ehi->err_mask |= AC_ERR_HSM;
+                       ehi->action |= ATA_EH_SOFTRESET;
+                       ata_port_freeze(ap);
+                       return 1;
                }
        }
        return 0;
@@ -854,8 +874,14 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
 
                        if (status & (NV_ADMA_STAT_DONE |
                                      NV_ADMA_STAT_CPBERR)) {
-                               u32 check_commands = notifier | notifier_error;
+                               u32 check_commands;
                                int pos, error = 0;
+
+                               if(ata_tag_valid(ap->active_tag))
+                                       check_commands = 1 << ap->active_tag;
+                               else
+                                       check_commands = ap->sactive;
+
                                /** Check CPBs for completed commands */
                                while ((pos = ffs(check_commands)) && !error) {
                                        pos--;
@@ -899,73 +925,12 @@ static void nv_adma_irq_clear(struct ata_port *ap)
        iowrite8(ioread8(dma_stat_addr), dma_stat_addr);
 }
 
-static void nv_adma_bmdma_setup(struct ata_queued_cmd *qc)
+static void nv_adma_post_internal_cmd(struct ata_queued_cmd *qc)
 {
-       struct ata_port *ap = qc->ap;
-       unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
-       struct nv_adma_port_priv *pp = ap->private_data;
-       u8 dmactl;
-
-       if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) {
-               WARN_ON(1);
-               return;
-       }
-
-       /* load PRD table addr. */
-       iowrite32(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
-
-       /* specify data direction, triple-check start bit is clear */
-       dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-       dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
-       if (!rw)
-               dmactl |= ATA_DMA_WR;
-
-       iowrite8(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-
-       /* issue r/w command */
-       ata_exec_command(ap, &qc->tf);
-}
-
-static void nv_adma_bmdma_start(struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       struct nv_adma_port_priv *pp = ap->private_data;
-       u8 dmactl;
-
-       if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) {
-               WARN_ON(1);
-               return;
-       }
-
-       /* start host DMA transaction */
-       dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-       iowrite8(dmactl | ATA_DMA_START,
-                ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-}
-
-static void nv_adma_bmdma_stop(struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       struct nv_adma_port_priv *pp = ap->private_data;
-
-       if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE))
-               return;
-
-       /* clear start/stop bit */
-       iowrite8(ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
-                ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-
-       /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
-       ata_altstatus(ap);        /* dummy read */
-}
-
-static u8 nv_adma_bmdma_status(struct ata_port *ap)
-{
-       struct nv_adma_port_priv *pp = ap->private_data;
-
-       WARN_ON(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE));
+       struct nv_adma_port_priv *pp = qc->ap->private_data;
 
-       return ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+       if(pp->flags & NV_ADMA_PORT_REGISTER_MODE)
+               ata_bmdma_post_internal_cmd(qc);
 }
 
 static int nv_adma_port_start(struct ata_port *ap)
@@ -1056,6 +1021,7 @@ static void nv_adma_port_stop(struct ata_port *ap)
        writew(0, mmio + NV_ADMA_CTL);
 }
 
+#ifdef CONFIG_PM
 static int nv_adma_port_suspend(struct ata_port *ap, pm_message_t mesg)
 {
        struct nv_adma_port_priv *pp = ap->private_data;
@@ -1106,6 +1072,7 @@ static int nv_adma_port_resume(struct ata_port *ap)
 
        return 0;
 }
+#endif
 
 static void nv_adma_setup_port(struct ata_probe_ent *probe_ent, unsigned int port)
 {
@@ -1455,7 +1422,7 @@ static void nv_adma_error_handler(struct ata_port *ap)
                void __iomem *mmio = pp->ctl_block;
                int i;
                u16 tmp;
-               
+
                if(ata_tag_valid(ap->active_tag) || ap->sactive) {
                        u32 notifier = readl(mmio + NV_ADMA_NOTIFIER);
                        u32 notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR);
@@ -1608,6 +1575,7 @@ static void nv_remove_one (struct pci_dev *pdev)
        kfree(hpriv);
 }
 
+#ifdef CONFIG_PM
 static int nv_pci_device_resume(struct pci_dev *pdev)
 {
        struct ata_host *host = dev_get_drvdata(&pdev->dev);
@@ -1655,6 +1623,7 @@ static int nv_pci_device_resume(struct pci_dev *pdev)
 
        return 0;
 }
+#endif
 
 static void nv_ck804_host_stop(struct ata_host *host)
 {