diff options
Diffstat (limited to 'drivers/ata/pdc_adma.c')
-rw-r--r-- | drivers/ata/pdc_adma.c | 85 |
1 files changed, 33 insertions, 52 deletions
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c index 5dd3ca8b5f29..52b69530ab29 100644 --- a/drivers/ata/pdc_adma.c +++ b/drivers/ata/pdc_adma.c | |||
@@ -52,9 +52,9 @@ | |||
52 | /* macro to calculate base address for ADMA regs */ | 52 | /* macro to calculate base address for ADMA regs */ |
53 | #define ADMA_REGS(base,port_no) ((base) + 0x80 + ((port_no) * 0x20)) | 53 | #define ADMA_REGS(base,port_no) ((base) + 0x80 + ((port_no) * 0x20)) |
54 | 54 | ||
55 | /* macro to obtain addresses from ata_host */ | 55 | /* macro to obtain addresses from ata_port */ |
56 | #define ADMA_HOST_REGS(host,port_no) \ | 56 | #define ADMA_PORT_REGS(ap) \ |
57 | ADMA_REGS((host)->iomap[ADMA_MMIO_BAR], port_no) | 57 | ADMA_REGS((ap)->host->iomap[ADMA_MMIO_BAR], ap->port_no) |
58 | 58 | ||
59 | enum { | 59 | enum { |
60 | ADMA_MMIO_BAR = 4, | 60 | ADMA_MMIO_BAR = 4, |
@@ -128,7 +128,6 @@ struct adma_port_priv { | |||
128 | 128 | ||
129 | static int adma_ata_init_one (struct pci_dev *pdev, | 129 | static int adma_ata_init_one (struct pci_dev *pdev, |
130 | const struct pci_device_id *ent); | 130 | const struct pci_device_id *ent); |
131 | static irqreturn_t adma_intr (int irq, void *dev_instance); | ||
132 | static int adma_port_start(struct ata_port *ap); | 131 | static int adma_port_start(struct ata_port *ap); |
133 | static void adma_host_stop(struct ata_host *host); | 132 | static void adma_host_stop(struct ata_host *host); |
134 | static void adma_port_stop(struct ata_port *ap); | 133 | static void adma_port_stop(struct ata_port *ap); |
@@ -172,7 +171,6 @@ static const struct ata_port_operations adma_ata_ops = { | |||
172 | .qc_issue = adma_qc_issue, | 171 | .qc_issue = adma_qc_issue, |
173 | .eng_timeout = adma_eng_timeout, | 172 | .eng_timeout = adma_eng_timeout, |
174 | .data_xfer = ata_data_xfer, | 173 | .data_xfer = ata_data_xfer, |
175 | .irq_handler = adma_intr, | ||
176 | .irq_clear = adma_irq_clear, | 174 | .irq_clear = adma_irq_clear, |
177 | .irq_on = ata_irq_on, | 175 | .irq_on = ata_irq_on, |
178 | .irq_ack = ata_irq_ack, | 176 | .irq_ack = ata_irq_ack, |
@@ -186,7 +184,6 @@ static const struct ata_port_operations adma_ata_ops = { | |||
186 | static struct ata_port_info adma_port_info[] = { | 184 | static struct ata_port_info adma_port_info[] = { |
187 | /* board_1841_idx */ | 185 | /* board_1841_idx */ |
188 | { | 186 | { |
189 | .sht = &adma_ata_sht, | ||
190 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | | 187 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | |
191 | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | | 188 | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | |
192 | ATA_FLAG_PIO_POLLING, | 189 | ATA_FLAG_PIO_POLLING, |
@@ -229,8 +226,10 @@ static void adma_irq_clear(struct ata_port *ap) | |||
229 | /* nothing */ | 226 | /* nothing */ |
230 | } | 227 | } |
231 | 228 | ||
232 | static void adma_reset_engine(void __iomem *chan) | 229 | static void adma_reset_engine(struct ata_port *ap) |
233 | { | 230 | { |
231 | void __iomem *chan = ADMA_PORT_REGS(ap); | ||
232 | |||
234 | /* reset ADMA to idle state */ | 233 | /* reset ADMA to idle state */ |
235 | writew(aPIOMD4 | aNIEN | aRSTADM, chan + ADMA_CONTROL); | 234 | writew(aPIOMD4 | aNIEN | aRSTADM, chan + ADMA_CONTROL); |
236 | udelay(2); | 235 | udelay(2); |
@@ -241,14 +240,14 @@ static void adma_reset_engine(void __iomem *chan) | |||
241 | static void adma_reinit_engine(struct ata_port *ap) | 240 | static void adma_reinit_engine(struct ata_port *ap) |
242 | { | 241 | { |
243 | struct adma_port_priv *pp = ap->private_data; | 242 | struct adma_port_priv *pp = ap->private_data; |
244 | void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no); | 243 | void __iomem *chan = ADMA_PORT_REGS(ap); |
245 | 244 | ||
246 | /* mask/clear ATA interrupts */ | 245 | /* mask/clear ATA interrupts */ |
247 | writeb(ATA_NIEN, ap->ioaddr.ctl_addr); | 246 | writeb(ATA_NIEN, ap->ioaddr.ctl_addr); |
248 | ata_check_status(ap); | 247 | ata_check_status(ap); |
249 | 248 | ||
250 | /* reset the ADMA engine */ | 249 | /* reset the ADMA engine */ |
251 | adma_reset_engine(chan); | 250 | adma_reset_engine(ap); |
252 | 251 | ||
253 | /* set in-FIFO threshold to 0x100 */ | 252 | /* set in-FIFO threshold to 0x100 */ |
254 | writew(0x100, chan + ADMA_FIFO_IN); | 253 | writew(0x100, chan + ADMA_FIFO_IN); |
@@ -268,7 +267,7 @@ static void adma_reinit_engine(struct ata_port *ap) | |||
268 | 267 | ||
269 | static inline void adma_enter_reg_mode(struct ata_port *ap) | 268 | static inline void adma_enter_reg_mode(struct ata_port *ap) |
270 | { | 269 | { |
271 | void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no); | 270 | void __iomem *chan = ADMA_PORT_REGS(ap); |
272 | 271 | ||
273 | writew(aPIOMD4, chan + ADMA_CONTROL); | 272 | writew(aPIOMD4, chan + ADMA_CONTROL); |
274 | readb(chan + ADMA_STATUS); /* flush */ | 273 | readb(chan + ADMA_STATUS); /* flush */ |
@@ -415,7 +414,7 @@ static void adma_qc_prep(struct ata_queued_cmd *qc) | |||
415 | static inline void adma_packet_start(struct ata_queued_cmd *qc) | 414 | static inline void adma_packet_start(struct ata_queued_cmd *qc) |
416 | { | 415 | { |
417 | struct ata_port *ap = qc->ap; | 416 | struct ata_port *ap = qc->ap; |
418 | void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no); | 417 | void __iomem *chan = ADMA_PORT_REGS(ap); |
419 | 418 | ||
420 | VPRINTK("ENTER, ap %p\n", ap); | 419 | VPRINTK("ENTER, ap %p\n", ap); |
421 | 420 | ||
@@ -453,7 +452,7 @@ static inline unsigned int adma_intr_pkt(struct ata_host *host) | |||
453 | struct ata_port *ap = host->ports[port_no]; | 452 | struct ata_port *ap = host->ports[port_no]; |
454 | struct adma_port_priv *pp; | 453 | struct adma_port_priv *pp; |
455 | struct ata_queued_cmd *qc; | 454 | struct ata_queued_cmd *qc; |
456 | void __iomem *chan = ADMA_HOST_REGS(host, port_no); | 455 | void __iomem *chan = ADMA_PORT_REGS(ap); |
457 | u8 status = readb(chan + ADMA_STATUS); | 456 | u8 status = readb(chan + ADMA_STATUS); |
458 | 457 | ||
459 | if (status == 0) | 458 | if (status == 0) |
@@ -575,7 +574,7 @@ static int adma_port_start(struct ata_port *ap) | |||
575 | 574 | ||
576 | static void adma_port_stop(struct ata_port *ap) | 575 | static void adma_port_stop(struct ata_port *ap) |
577 | { | 576 | { |
578 | adma_reset_engine(ADMA_HOST_REGS(ap->host, ap->port_no)); | 577 | adma_reset_engine(ap); |
579 | } | 578 | } |
580 | 579 | ||
581 | static void adma_host_stop(struct ata_host *host) | 580 | static void adma_host_stop(struct ata_host *host) |
@@ -583,21 +582,19 @@ static void adma_host_stop(struct ata_host *host) | |||
583 | unsigned int port_no; | 582 | unsigned int port_no; |
584 | 583 | ||
585 | for (port_no = 0; port_no < ADMA_PORTS; ++port_no) | 584 | for (port_no = 0; port_no < ADMA_PORTS; ++port_no) |
586 | adma_reset_engine(ADMA_HOST_REGS(host, port_no)); | 585 | adma_reset_engine(host->ports[port_no]); |
587 | } | 586 | } |
588 | 587 | ||
589 | static void adma_host_init(unsigned int chip_id, | 588 | static void adma_host_init(struct ata_host *host, unsigned int chip_id) |
590 | struct ata_probe_ent *probe_ent) | ||
591 | { | 589 | { |
592 | unsigned int port_no; | 590 | unsigned int port_no; |
593 | void __iomem *mmio_base = probe_ent->iomap[ADMA_MMIO_BAR]; | ||
594 | 591 | ||
595 | /* enable/lock aGO operation */ | 592 | /* enable/lock aGO operation */ |
596 | writeb(7, mmio_base + ADMA_MODE_LOCK); | 593 | writeb(7, host->iomap[ADMA_MMIO_BAR] + ADMA_MODE_LOCK); |
597 | 594 | ||
598 | /* reset the ADMA logic */ | 595 | /* reset the ADMA logic */ |
599 | for (port_no = 0; port_no < ADMA_PORTS; ++port_no) | 596 | for (port_no = 0; port_no < ADMA_PORTS; ++port_no) |
600 | adma_reset_engine(ADMA_REGS(mmio_base, port_no)); | 597 | adma_reset_engine(host->ports[port_no]); |
601 | } | 598 | } |
602 | 599 | ||
603 | static int adma_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base) | 600 | static int adma_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base) |
@@ -623,14 +620,21 @@ static int adma_ata_init_one(struct pci_dev *pdev, | |||
623 | const struct pci_device_id *ent) | 620 | const struct pci_device_id *ent) |
624 | { | 621 | { |
625 | static int printed_version; | 622 | static int printed_version; |
626 | struct ata_probe_ent *probe_ent = NULL; | ||
627 | void __iomem *mmio_base; | ||
628 | unsigned int board_idx = (unsigned int) ent->driver_data; | 623 | unsigned int board_idx = (unsigned int) ent->driver_data; |
624 | const struct ata_port_info *ppi[] = { &adma_port_info[board_idx], NULL }; | ||
625 | struct ata_host *host; | ||
626 | void __iomem *mmio_base; | ||
629 | int rc, port_no; | 627 | int rc, port_no; |
630 | 628 | ||
631 | if (!printed_version++) | 629 | if (!printed_version++) |
632 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); | 630 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); |
633 | 631 | ||
632 | /* alloc host */ | ||
633 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, ADMA_PORTS); | ||
634 | if (!host) | ||
635 | return -ENOMEM; | ||
636 | |||
637 | /* acquire resources and fill host */ | ||
634 | rc = pcim_enable_device(pdev); | 638 | rc = pcim_enable_device(pdev); |
635 | if (rc) | 639 | if (rc) |
636 | return rc; | 640 | return rc; |
@@ -641,46 +645,23 @@ static int adma_ata_init_one(struct pci_dev *pdev, | |||
641 | rc = pcim_iomap_regions(pdev, 1 << ADMA_MMIO_BAR, DRV_NAME); | 645 | rc = pcim_iomap_regions(pdev, 1 << ADMA_MMIO_BAR, DRV_NAME); |
642 | if (rc) | 646 | if (rc) |
643 | return rc; | 647 | return rc; |
644 | mmio_base = pcim_iomap_table(pdev)[ADMA_MMIO_BAR]; | 648 | host->iomap = pcim_iomap_table(pdev); |
649 | mmio_base = host->iomap[ADMA_MMIO_BAR]; | ||
645 | 650 | ||
646 | rc = adma_set_dma_masks(pdev, mmio_base); | 651 | rc = adma_set_dma_masks(pdev, mmio_base); |
647 | if (rc) | 652 | if (rc) |
648 | return rc; | 653 | return rc; |
649 | 654 | ||
650 | probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL); | 655 | for (port_no = 0; port_no < ADMA_PORTS; ++port_no) |
651 | if (probe_ent == NULL) | 656 | adma_ata_setup_port(&host->ports[port_no]->ioaddr, |
652 | return -ENOMEM; | ||
653 | |||
654 | probe_ent->dev = pci_dev_to_dev(pdev); | ||
655 | INIT_LIST_HEAD(&probe_ent->node); | ||
656 | |||
657 | probe_ent->sht = adma_port_info[board_idx].sht; | ||
658 | probe_ent->port_flags = adma_port_info[board_idx].flags; | ||
659 | probe_ent->pio_mask = adma_port_info[board_idx].pio_mask; | ||
660 | probe_ent->mwdma_mask = adma_port_info[board_idx].mwdma_mask; | ||
661 | probe_ent->udma_mask = adma_port_info[board_idx].udma_mask; | ||
662 | probe_ent->port_ops = adma_port_info[board_idx].port_ops; | ||
663 | |||
664 | probe_ent->irq = pdev->irq; | ||
665 | probe_ent->irq_flags = IRQF_SHARED; | ||
666 | probe_ent->n_ports = ADMA_PORTS; | ||
667 | probe_ent->iomap = pcim_iomap_table(pdev); | ||
668 | |||
669 | for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) { | ||
670 | adma_ata_setup_port(&probe_ent->port[port_no], | ||
671 | ADMA_ATA_REGS(mmio_base, port_no)); | 657 | ADMA_ATA_REGS(mmio_base, port_no)); |
672 | } | ||
673 | |||
674 | pci_set_master(pdev); | ||
675 | 658 | ||
676 | /* initialize adapter */ | 659 | /* initialize adapter */ |
677 | adma_host_init(board_idx, probe_ent); | 660 | adma_host_init(host, board_idx); |
678 | 661 | ||
679 | if (!ata_device_add(probe_ent)) | 662 | pci_set_master(pdev); |
680 | return -ENODEV; | 663 | return ata_host_activate(host, pdev->irq, adma_intr, IRQF_SHARED, |
681 | 664 | &adma_ata_sht); | |
682 | devm_kfree(&pdev->dev, probe_ent); | ||
683 | return 0; | ||
684 | } | 665 | } |
685 | 666 | ||
686 | static int __init adma_ata_init(void) | 667 | static int __init adma_ata_init(void) |