X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fata%2Fahci.c;h=fd27227771b48a8038ec867c62f9804fc34aa9af;hb=97cb81c335565f3ce27cd26d71480dff0211797a;hp=48616c6fee9d6c30d36f206b60b98707020e0cc8;hpb=4285431fb658263e98942ce2320b0b26eddcc06d;p=linux-2.6-omap-h63xx.git diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 48616c6fee9..fd27227771b 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -39,16 +39,14 @@ #include #include #include -#include #include #include #include #include #include -#include #define DRV_NAME "ahci" -#define DRV_VERSION "2.0" +#define DRV_VERSION "2.1" enum { @@ -82,6 +80,7 @@ enum { board_ahci_pi = 1, board_ahci_vt8251 = 2, board_ahci_ign_iferr = 3, + board_ahci_sb600 = 4, /* global controller registers */ HOST_CAP = 0x00, /* host capabilities */ @@ -166,13 +165,11 @@ enum { PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */ PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */ - /* hpriv->flags bits */ - AHCI_FLAG_MSI = (1 << 0), - /* ap->flags bits */ AHCI_FLAG_NO_NCQ = (1 << 24), AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 25), /* ignore IRQ_IF_ERR */ AHCI_FLAG_HONOR_PI = (1 << 26), /* honor PORTS_IMPL */ + AHCI_FLAG_IGN_SERR_INTERNAL = (1 << 27), /* ignore SERR_INTERNAL */ }; struct ahci_cmd_hdr { @@ -191,7 +188,6 @@ struct ahci_sg { }; struct ahci_host_priv { - unsigned long flags; u32 cap; /* cache of HOST_CAP register */ u32 port_map; /* cache of HOST_PORTS_IMPL reg */ }; @@ -204,9 +200,9 @@ struct ahci_port_priv { void *rx_fis; dma_addr_t rx_fis_dma; /* for NCQ spurious interrupt analysis */ - int ncq_saw_spurious_sdb_cnt; unsigned int ncq_saw_d2h:1; unsigned int ncq_saw_dmas:1; + unsigned int ncq_saw_sdb:1; }; static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); @@ -225,11 +221,12 @@ static void ahci_thaw(struct ata_port *ap); static void ahci_error_handler(struct ata_port *ap); static void ahci_vt8251_error_handler(struct ata_port *ap); static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); +#ifdef CONFIG_PM static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg); static int ahci_port_resume(struct ata_port *ap); static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); static int ahci_pci_device_resume(struct pci_dev *pdev); -static void ahci_remove_one (struct pci_dev *pdev); +#endif static struct scsi_host_template ahci_sht = { .module = THIS_MODULE, @@ -248,8 +245,10 @@ static struct scsi_host_template ahci_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 const struct ata_port_operations ahci_ops = { @@ -266,6 +265,8 @@ static const struct ata_port_operations ahci_ops = { .irq_handler = ahci_interrupt, .irq_clear = ahci_irq_clear, + .irq_on = ata_dummy_irq_on, + .irq_ack = ata_dummy_irq_ack, .scr_read = ahci_scr_read, .scr_write = ahci_scr_write, @@ -276,8 +277,10 @@ static const struct ata_port_operations ahci_ops = { .error_handler = ahci_error_handler, .post_internal_cmd = ahci_post_internal_cmd, +#ifdef CONFIG_PM .port_suspend = ahci_port_suspend, .port_resume = ahci_port_resume, +#endif .port_start = ahci_port_start, .port_stop = ahci_port_stop, @@ -297,6 +300,8 @@ static const struct ata_port_operations ahci_vt8251_ops = { .irq_handler = ahci_interrupt, .irq_clear = ahci_irq_clear, + .irq_on = ata_dummy_irq_on, + .irq_ack = ata_dummy_irq_ack, .scr_read = ahci_scr_read, .scr_write = ahci_scr_write, @@ -307,8 +312,10 @@ static const struct ata_port_operations ahci_vt8251_ops = { .error_handler = ahci_vt8251_error_handler, .post_internal_cmd = ahci_post_internal_cmd, +#ifdef CONFIG_PM .port_suspend = ahci_port_suspend, .port_resume = ahci_port_resume, +#endif .port_start = ahci_port_start, .port_stop = ahci_port_stop, @@ -357,6 +364,18 @@ static const struct ata_port_info ahci_port_info[] = { .udma_mask = 0x7f, /* udma0-6 ; FIXME */ .port_ops = &ahci_ops, }, + /* board_ahci_sb600 */ + { + .sht = &ahci_sht, + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | + ATA_FLAG_SKIP_D2H_BSY | + AHCI_FLAG_IGN_SERR_INTERNAL, + .pio_mask = 0x1f, /* pio0-4 */ + .udma_mask = 0x7f, /* udma0-6 ; FIXME */ + .port_ops = &ahci_ops, + }, + }; static const struct pci_device_id ahci_pci_tbl[] = { @@ -384,19 +403,17 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x2929), board_ahci_pi }, /* ICH9M */ { PCI_VDEVICE(INTEL, 0x292a), board_ahci_pi }, /* ICH9M */ { PCI_VDEVICE(INTEL, 0x292b), board_ahci_pi }, /* ICH9M */ + { PCI_VDEVICE(INTEL, 0x292c), board_ahci_pi }, /* ICH9M */ { PCI_VDEVICE(INTEL, 0x292f), board_ahci_pi }, /* ICH9M */ { PCI_VDEVICE(INTEL, 0x294d), board_ahci_pi }, /* ICH9 */ { PCI_VDEVICE(INTEL, 0x294e), board_ahci_pi }, /* ICH9M */ - /* JMicron */ - { PCI_VDEVICE(JMICRON, 0x2360), board_ahci_ign_iferr }, /* JMB360 */ - { PCI_VDEVICE(JMICRON, 0x2361), board_ahci_ign_iferr }, /* JMB361 */ - { PCI_VDEVICE(JMICRON, 0x2363), board_ahci_ign_iferr }, /* JMB363 */ - { PCI_VDEVICE(JMICRON, 0x2365), board_ahci_ign_iferr }, /* JMB365 */ - { PCI_VDEVICE(JMICRON, 0x2366), board_ahci_ign_iferr }, /* JMB366 */ + /* JMicron 360/1/3/5/6, match class to avoid IDE function */ + { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr }, /* ATI */ - { PCI_VDEVICE(ATI, 0x4380), board_ahci }, /* ATI SB600 non-raid */ + { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 non-raid */ { PCI_VDEVICE(ATI, 0x4381), board_ahci }, /* ATI SB600 raid */ /* VIA */ @@ -431,7 +448,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { /* Generic, PCI class code for AHCI */ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, - 0x010601, 0xffffff, board_ahci }, + PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci }, { } /* terminate list */ }; @@ -441,9 +458,11 @@ static struct pci_driver ahci_pci_driver = { .name = DRV_NAME, .id_table = ahci_pci_tbl, .probe = ahci_init_one, + .remove = ata_pci_remove_one, +#ifdef CONFIG_PM .suspend = ahci_pci_device_suspend, .resume = ahci_pci_device_resume, - .remove = ahci_remove_one, +#endif }; @@ -452,16 +471,12 @@ static inline int ahci_nr_ports(u32 cap) return (cap & 0x1f) + 1; } -static inline unsigned long ahci_port_base_ul (unsigned long base, unsigned int port) +static inline void __iomem *ahci_port_base(void __iomem *base, + unsigned int port) { return base + 0x100 + (port * 0x80); } -static inline void __iomem *ahci_port_base (void __iomem *base, unsigned int port) -{ - return (void __iomem *) ahci_port_base_ul((unsigned long)base, port); -} - static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) { unsigned int sc_reg; @@ -475,7 +490,7 @@ static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) return 0xffffffffU; } - return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); + return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); } @@ -493,7 +508,7 @@ static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in, return; } - writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); + writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); } static void ahci_start_engine(void __iomem *port_mmio) @@ -587,6 +602,7 @@ static void ahci_power_up(void __iomem *port_mmio, u32 cap) writel(cmd | PORT_CMD_ICC_ACTIVE, port_mmio + PORT_CMD); } +#ifdef CONFIG_PM static void ahci_power_down(void __iomem *port_mmio, u32 cap) { u32 cmd, scontrol; @@ -604,6 +620,7 @@ static void ahci_power_down(void __iomem *port_mmio, u32 cap) cmd &= ~PORT_CMD_SPIN_UP; writel(cmd, port_mmio + PORT_CMD); } +#endif static void ahci_init_port(void __iomem *port_mmio, u32 cap, dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma) @@ -735,7 +752,7 @@ static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev, static unsigned int ahci_dev_classify(struct ata_port *ap) { - void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; + void __iomem *port_mmio = ap->ioaddr.cmd_addr; struct ata_taskfile tf; u32 tmp; @@ -763,7 +780,7 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, static int ahci_clo(struct ata_port *ap) { - void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; + void __iomem *port_mmio = ap->ioaddr.cmd_addr; struct ahci_host_priv *hpriv = ap->host->private_data; u32 tmp; @@ -785,7 +802,7 @@ static int ahci_clo(struct ata_port *ap) static int ahci_softreset(struct ata_port *ap, unsigned int *class) { struct ahci_port_priv *pp = ap->private_data; - void __iomem *mmio = ap->host->mmio_base; + void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); const u32 cmd_fis_len = 5; /* five dwords */ const char *reason = NULL; @@ -893,7 +910,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class) struct ahci_port_priv *pp = ap->private_data; u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; struct ata_taskfile tf; - void __iomem *mmio = ap->host->mmio_base; + void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); int rc; @@ -921,7 +938,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class) static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class) { - void __iomem *mmio = ap->host->mmio_base; + void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); int rc; @@ -946,7 +963,7 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class) static void ahci_postreset(struct ata_port *ap, unsigned int *class) { - void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; + void __iomem *port_mmio = ap->ioaddr.cmd_addr; u32 new_tmp, tmp; ata_std_postreset(ap, class); @@ -965,7 +982,7 @@ static void ahci_postreset(struct ata_port *ap, unsigned int *class) static u8 ahci_check_status(struct ata_port *ap) { - void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr; + void __iomem *mmio = ap->ioaddr.cmd_addr; return readl(mmio + PORT_TFDATA) & 0xFF; } @@ -1064,8 +1081,11 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) if (ap->flags & AHCI_FLAG_IGN_IRQ_IF_ERR) irq_stat &= ~PORT_IRQ_IF_ERR; - if (irq_stat & PORT_IRQ_TF_ERR) + if (irq_stat & PORT_IRQ_TF_ERR) { err_mask |= AC_ERR_DEV; + if (ap->flags & AHCI_FLAG_IGN_SERR_INTERNAL) + serror &= ~SERR_INTERNAL; + } if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) { err_mask |= AC_ERR_HOST_BUS; @@ -1111,7 +1131,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) static void ahci_host_intr(struct ata_port *ap) { - void __iomem *mmio = ap->host->mmio_base; + void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); struct ata_eh_info *ehi = &ap->eh_info; struct ahci_port_priv *pp = ap->private_data; @@ -1167,23 +1187,32 @@ static void ahci_host_intr(struct ata_port *ap) known_irq = 1; } - if (status & PORT_IRQ_SDB_FIS && - pp->ncq_saw_spurious_sdb_cnt < 10) { - /* SDB FIS containing spurious completions might be - * dangerous, we need to know more about them. Print - * more of it. - */ - const u32 *f = pp->rx_fis + RX_FIS_SDB; - - ata_port_printk(ap, KERN_INFO, "Spurious SDB FIS during NCQ " - "issue=0x%x SAct=0x%x FIS=%08x:%08x%s\n", + if (status & PORT_IRQ_SDB_FIS) { + const __le32 *f = pp->rx_fis + RX_FIS_SDB; + + if (le32_to_cpu(f[1])) { + /* SDB FIS containing spurious completions + * might be dangerous, whine and fail commands + * with HSM violation. EH will turn off NCQ + * after several such failures. + */ + ata_ehi_push_desc(ehi, + "spurious completions during NCQ " + "issue=0x%x SAct=0x%x FIS=%08x:%08x", readl(port_mmio + PORT_CMD_ISSUE), readl(port_mmio + PORT_SCR_ACT), - le32_to_cpu(f[0]), le32_to_cpu(f[1]), - pp->ncq_saw_spurious_sdb_cnt < 10 ? - "" : ", shutting up"); - - pp->ncq_saw_spurious_sdb_cnt++; + le32_to_cpu(f[0]), le32_to_cpu(f[1])); + ehi->err_mask |= AC_ERR_HSM; + ehi->action |= ATA_EH_SOFTRESET; + ata_port_freeze(ap); + } else { + if (!pp->ncq_saw_sdb) + ata_port_printk(ap, KERN_INFO, + "spurious SDB FIS %08x:%08x during NCQ, " + "this message won't be printed again\n", + le32_to_cpu(f[0]), le32_to_cpu(f[1])); + pp->ncq_saw_sdb = 1; + } known_irq = 1; } @@ -1209,7 +1238,7 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance) VPRINTK("ENTER\n"); hpriv = host->private_data; - mmio = host->mmio_base; + mmio = host->iomap[AHCI_PCI_BAR]; /* sigh. 0xffffffff is a valid return from h/w */ irq_stat = readl(mmio + HOST_IRQ_STAT); @@ -1254,7 +1283,7 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance) static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; + void __iomem *port_mmio = ap->ioaddr.cmd_addr; if (qc->tf.protocol == ATA_PROT_NCQ) writel(1 << qc->tag, port_mmio + PORT_SCR_ACT); @@ -1266,7 +1295,7 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) static void ahci_freeze(struct ata_port *ap) { - void __iomem *mmio = ap->host->mmio_base; + void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); /* turn IRQ off */ @@ -1275,7 +1304,7 @@ static void ahci_freeze(struct ata_port *ap) static void ahci_thaw(struct ata_port *ap) { - void __iomem *mmio = ap->host->mmio_base; + void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); u32 tmp; @@ -1290,7 +1319,7 @@ static void ahci_thaw(struct ata_port *ap) static void ahci_error_handler(struct ata_port *ap) { - void __iomem *mmio = ap->host->mmio_base; + void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); if (!(ap->pflags & ATA_PFLAG_FROZEN)) { @@ -1306,7 +1335,7 @@ static void ahci_error_handler(struct ata_port *ap) static void ahci_vt8251_error_handler(struct ata_port *ap) { - void __iomem *mmio = ap->host->mmio_base; + void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); if (!(ap->pflags & ATA_PFLAG_FROZEN)) { @@ -1323,7 +1352,7 @@ static void ahci_vt8251_error_handler(struct ata_port *ap) static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - void __iomem *mmio = ap->host->mmio_base; + void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); if (qc->flags & ATA_QCFLAG_FAILED) @@ -1336,11 +1365,12 @@ static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) } } +#ifdef CONFIG_PM static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) { struct ahci_host_priv *hpriv = ap->host->private_data; struct ahci_port_priv *pp = ap->private_data; - void __iomem *mmio = ap->host->mmio_base; + void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); const char *emsg = NULL; int rc; @@ -1361,7 +1391,7 @@ static int ahci_port_resume(struct ata_port *ap) { struct ahci_port_priv *pp = ap->private_data; struct ahci_host_priv *hpriv = ap->host->private_data; - void __iomem *mmio = ap->host->mmio_base; + void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); ahci_power_up(port_mmio, hpriv->cap); @@ -1373,7 +1403,7 @@ static int ahci_port_resume(struct ata_port *ap) static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) { struct ata_host *host = dev_get_drvdata(&pdev->dev); - void __iomem *mmio = host->mmio_base; + void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; u32 ctl; if (mesg.event == PM_EVENT_SUSPEND) { @@ -1394,10 +1424,12 @@ static int ahci_pci_device_resume(struct pci_dev *pdev) { struct ata_host *host = dev_get_drvdata(&pdev->dev); struct ahci_host_priv *hpriv = host->private_data; - void __iomem *mmio = host->mmio_base; + void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; int rc; - ata_pci_device_do_resume(pdev); + rc = ata_pci_device_do_resume(pdev); + if (rc) + return rc; if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { rc = ahci_reset_controller(mmio, pdev); @@ -1412,35 +1444,31 @@ static int ahci_pci_device_resume(struct pci_dev *pdev) return 0; } +#endif static int ahci_port_start(struct ata_port *ap) { struct device *dev = ap->host->dev; struct ahci_host_priv *hpriv = ap->host->private_data; struct ahci_port_priv *pp; - void __iomem *mmio = ap->host->mmio_base; + void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); void *mem; dma_addr_t mem_dma; int rc; - pp = kmalloc(sizeof(*pp), GFP_KERNEL); + pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); if (!pp) return -ENOMEM; - memset(pp, 0, sizeof(*pp)); rc = ata_pad_alloc(ap, dev); - if (rc) { - kfree(pp); + if (rc) return rc; - } - mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); - if (!mem) { - ata_pad_free(ap, dev); - kfree(pp); + mem = dmam_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, + GFP_KERNEL); + if (!mem) return -ENOMEM; - } memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ); /* @@ -1482,10 +1510,8 @@ static int ahci_port_start(struct ata_port *ap) static void ahci_port_stop(struct ata_port *ap) { - struct device *dev = ap->host->dev; struct ahci_host_priv *hpriv = ap->host->private_data; - struct ahci_port_priv *pp = ap->private_data; - void __iomem *mmio = ap->host->mmio_base; + void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); const char *emsg = NULL; int rc; @@ -1494,19 +1520,13 @@ static void ahci_port_stop(struct ata_port *ap) rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg); if (rc) ata_port_printk(ap, KERN_WARNING, "%s (%d)\n", emsg, rc); - - ap->private_data = NULL; - dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, - pp->cmd_slot, pp->cmd_slot_dma); - ata_pad_free(ap, dev); - kfree(pp); } -static void ahci_setup_port(struct ata_ioports *port, unsigned long base, +static void ahci_setup_port(struct ata_ioports *port, void __iomem *base, unsigned int port_idx) { VPRINTK("ENTER, base==0x%lx, port_idx %u\n", base, port_idx); - base = ahci_port_base_ul(base, port_idx); + base = ahci_port_base(base, port_idx); VPRINTK("base now==0x%lx\n", base); port->cmd_addr = base; @@ -1519,7 +1539,7 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent) { struct ahci_host_priv *hpriv = probe_ent->private_data; struct pci_dev *pdev = to_pci_dev(probe_ent->dev); - void __iomem *mmio = probe_ent->mmio_base; + void __iomem *mmio = probe_ent->iomap[AHCI_PCI_BAR]; unsigned int i, cap_n_ports, using_dac; int rc; @@ -1586,7 +1606,7 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent) } for (i = 0; i < probe_ent->n_ports; i++) - ahci_setup_port(&probe_ent->port[i], (unsigned long) mmio, i); + ahci_setup_port(&probe_ent->port[i], mmio, i); ahci_init_controller(mmio, pdev, probe_ent->n_ports, probe_ent->port_flags, hpriv); @@ -1600,7 +1620,7 @@ static void ahci_print_info(struct ata_probe_ent *probe_ent) { struct ahci_host_priv *hpriv = probe_ent->private_data; struct pci_dev *pdev = to_pci_dev(probe_ent->dev); - void __iomem *mmio = probe_ent->mmio_base; + void __iomem *mmio = probe_ent->iomap[AHCI_PCI_BAR]; u32 vers, cap, impl, speed; const char *speed_s; u16 cc; @@ -1619,11 +1639,11 @@ static void ahci_print_info(struct ata_probe_ent *probe_ent) speed_s = "?"; pci_read_config_word(pdev, 0x0a, &cc); - if (cc == 0x0101) + if (cc == PCI_CLASS_STORAGE_IDE) scc_s = "IDE"; - else if (cc == 0x0106) + else if (cc == PCI_CLASS_STORAGE_SATA) scc_s = "SATA"; - else if (cc == 0x0104) + else if (cc == PCI_CLASS_STORAGE_RAID) scc_s = "RAID"; else scc_s = "unknown"; @@ -1667,15 +1687,13 @@ static void ahci_print_info(struct ata_probe_ent *probe_ent) ); } -static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) +static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - struct ata_probe_ent *probe_ent = NULL; - struct ahci_host_priv *hpriv; - unsigned long base; - void __iomem *mmio_base; unsigned int board_idx = (unsigned int) ent->driver_data; - int have_msi, pci_dev_busy = 0; + struct device *dev = &pdev->dev; + struct ata_probe_ent *probe_ent; + struct ahci_host_priv *hpriv; int rc; VPRINTK("ENTER\n"); @@ -1685,57 +1703,29 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); - /* JMicron-specific fixup: make sure we're in AHCI mode */ - /* This is protected from races with ata_jmicron by the pci probe - locking */ - if (pdev->vendor == PCI_VENDOR_ID_JMICRON) { - /* AHCI enable, AHCI on function 0 */ - pci_write_config_byte(pdev, 0x41, 0xa1); - /* Function 1 is the PATA controller */ - if (PCI_FUNC(pdev->devfn)) - return -ENODEV; - } - - rc = pci_enable_device(pdev); + rc = pcim_enable_device(pdev); if (rc) return rc; - rc = pci_request_regions(pdev, DRV_NAME); - if (rc) { - pci_dev_busy = 1; - goto err_out; - } + rc = pcim_iomap_regions(pdev, 1 << AHCI_PCI_BAR, DRV_NAME); + if (rc == -EBUSY) + pcim_pin_device(pdev); + if (rc) + return rc; - if (pci_enable_msi(pdev) == 0) - have_msi = 1; - else { + if (pci_enable_msi(pdev)) pci_intx(pdev, 1); - have_msi = 0; - } - probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); - if (probe_ent == NULL) { - rc = -ENOMEM; - goto err_out_msi; - } + probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL); + if (probe_ent == NULL) + return -ENOMEM; - memset(probe_ent, 0, sizeof(*probe_ent)); probe_ent->dev = pci_dev_to_dev(pdev); INIT_LIST_HEAD(&probe_ent->node); - mmio_base = pci_iomap(pdev, AHCI_PCI_BAR, 0); - if (mmio_base == NULL) { - rc = -ENOMEM; - goto err_out_free_ent; - } - base = (unsigned long) mmio_base; - - hpriv = kmalloc(sizeof(*hpriv), GFP_KERNEL); - if (!hpriv) { - rc = -ENOMEM; - goto err_out_iounmap; - } - memset(hpriv, 0, sizeof(*hpriv)); + hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); + if (!hpriv) + return -ENOMEM; probe_ent->sht = ahci_port_info[board_idx].sht; probe_ent->port_flags = ahci_port_info[board_idx].flags; @@ -1745,16 +1735,13 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) probe_ent->irq = pdev->irq; probe_ent->irq_flags = IRQF_SHARED; - probe_ent->mmio_base = mmio_base; + probe_ent->iomap = pcim_iomap_table(pdev); probe_ent->private_data = hpriv; - if (have_msi) - hpriv->flags |= AHCI_FLAG_MSI; - /* initialize adapter */ rc = ahci_host_init(probe_ent); if (rc) - goto err_out_hpriv; + return rc; if (!(probe_ent->port_flags & AHCI_FLAG_NO_NCQ) && (hpriv->cap & HOST_CAP_NCQ)) @@ -1762,62 +1749,11 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ahci_print_info(probe_ent); - /* FIXME: check ata_device_add return value */ - ata_device_add(probe_ent); - kfree(probe_ent); + if (!ata_device_add(probe_ent)) + return -ENODEV; + devm_kfree(dev, probe_ent); return 0; - -err_out_hpriv: - kfree(hpriv); -err_out_iounmap: - pci_iounmap(pdev, mmio_base); -err_out_free_ent: - kfree(probe_ent); -err_out_msi: - if (have_msi) - pci_disable_msi(pdev); - else - pci_intx(pdev, 0); - pci_release_regions(pdev); -err_out: - if (!pci_dev_busy) - pci_disable_device(pdev); - return rc; -} - -static void ahci_remove_one (struct pci_dev *pdev) -{ - struct device *dev = pci_dev_to_dev(pdev); - struct ata_host *host = dev_get_drvdata(dev); - struct ahci_host_priv *hpriv = host->private_data; - unsigned int i; - int have_msi; - - for (i = 0; i < host->n_ports; i++) - ata_port_detach(host->ports[i]); - - have_msi = hpriv->flags & AHCI_FLAG_MSI; - free_irq(host->irq, host); - - for (i = 0; i < host->n_ports; i++) { - struct ata_port *ap = host->ports[i]; - - ata_scsi_release(ap->scsi_host); - scsi_host_put(ap->scsi_host); - } - - kfree(hpriv); - pci_iounmap(pdev, host->mmio_base); - kfree(host); - - if (have_msi) - pci_disable_msi(pdev); - else - pci_intx(pdev, 0); - pci_release_regions(pdev); - pci_disable_device(pdev); - dev_set_drvdata(dev, NULL); } static int __init ahci_init(void)