diff options
Diffstat (limited to 'drivers/ata/sata_qstor.c')
-rw-r--r-- | drivers/ata/sata_qstor.c | 138 |
1 files changed, 49 insertions, 89 deletions
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index 710909df4eaf..bfa35ede6551 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c | |||
@@ -37,13 +37,14 @@ | |||
37 | #include <linux/sched.h> | 37 | #include <linux/sched.h> |
38 | #include <linux/device.h> | 38 | #include <linux/device.h> |
39 | #include <scsi/scsi_host.h> | 39 | #include <scsi/scsi_host.h> |
40 | #include <asm/io.h> | ||
41 | #include <linux/libata.h> | 40 | #include <linux/libata.h> |
42 | 41 | ||
43 | #define DRV_NAME "sata_qstor" | 42 | #define DRV_NAME "sata_qstor" |
44 | #define DRV_VERSION "0.06" | 43 | #define DRV_VERSION "0.06" |
45 | 44 | ||
46 | enum { | 45 | enum { |
46 | QS_MMIO_BAR = 4, | ||
47 | |||
47 | QS_PORTS = 4, | 48 | QS_PORTS = 4, |
48 | QS_MAX_PRD = LIBATA_MAX_PRD, | 49 | QS_MAX_PRD = LIBATA_MAX_PRD, |
49 | QS_CPB_ORDER = 6, | 50 | QS_CPB_ORDER = 6, |
@@ -117,7 +118,6 @@ static int qs_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *en | |||
117 | static irqreturn_t qs_intr (int irq, void *dev_instance); | 118 | static irqreturn_t qs_intr (int irq, void *dev_instance); |
118 | static int qs_port_start(struct ata_port *ap); | 119 | static int qs_port_start(struct ata_port *ap); |
119 | static void qs_host_stop(struct ata_host *host); | 120 | static void qs_host_stop(struct ata_host *host); |
120 | static void qs_port_stop(struct ata_port *ap); | ||
121 | static void qs_phy_reset(struct ata_port *ap); | 121 | static void qs_phy_reset(struct ata_port *ap); |
122 | static void qs_qc_prep(struct ata_queued_cmd *qc); | 122 | static void qs_qc_prep(struct ata_queued_cmd *qc); |
123 | static unsigned int qs_qc_issue(struct ata_queued_cmd *qc); | 123 | static unsigned int qs_qc_issue(struct ata_queued_cmd *qc); |
@@ -157,14 +157,15 @@ static const struct ata_port_operations qs_ata_ops = { | |||
157 | .phy_reset = qs_phy_reset, | 157 | .phy_reset = qs_phy_reset, |
158 | .qc_prep = qs_qc_prep, | 158 | .qc_prep = qs_qc_prep, |
159 | .qc_issue = qs_qc_issue, | 159 | .qc_issue = qs_qc_issue, |
160 | .data_xfer = ata_mmio_data_xfer, | 160 | .data_xfer = ata_data_xfer, |
161 | .eng_timeout = qs_eng_timeout, | 161 | .eng_timeout = qs_eng_timeout, |
162 | .irq_handler = qs_intr, | 162 | .irq_handler = qs_intr, |
163 | .irq_clear = qs_irq_clear, | 163 | .irq_clear = qs_irq_clear, |
164 | .irq_on = ata_irq_on, | ||
165 | .irq_ack = ata_irq_ack, | ||
164 | .scr_read = qs_scr_read, | 166 | .scr_read = qs_scr_read, |
165 | .scr_write = qs_scr_write, | 167 | .scr_write = qs_scr_write, |
166 | .port_start = qs_port_start, | 168 | .port_start = qs_port_start, |
167 | .port_stop = qs_port_stop, | ||
168 | .host_stop = qs_host_stop, | 169 | .host_stop = qs_host_stop, |
169 | .bmdma_stop = qs_bmdma_stop, | 170 | .bmdma_stop = qs_bmdma_stop, |
170 | .bmdma_status = qs_bmdma_status, | 171 | .bmdma_status = qs_bmdma_status, |
@@ -197,6 +198,11 @@ static struct pci_driver qs_ata_pci_driver = { | |||
197 | .remove = ata_pci_remove_one, | 198 | .remove = ata_pci_remove_one, |
198 | }; | 199 | }; |
199 | 200 | ||
201 | static void __iomem *qs_mmio_base(struct ata_host *host) | ||
202 | { | ||
203 | return host->iomap[QS_MMIO_BAR]; | ||
204 | } | ||
205 | |||
200 | static int qs_check_atapi_dma(struct ata_queued_cmd *qc) | 206 | static int qs_check_atapi_dma(struct ata_queued_cmd *qc) |
201 | { | 207 | { |
202 | return 1; /* ATAPI DMA not supported */ | 208 | return 1; /* ATAPI DMA not supported */ |
@@ -219,7 +225,7 @@ static void qs_irq_clear(struct ata_port *ap) | |||
219 | 225 | ||
220 | static inline void qs_enter_reg_mode(struct ata_port *ap) | 226 | static inline void qs_enter_reg_mode(struct ata_port *ap) |
221 | { | 227 | { |
222 | u8 __iomem *chan = ap->host->mmio_base + (ap->port_no * 0x4000); | 228 | u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000); |
223 | 229 | ||
224 | writeb(QS_CTR0_REG, chan + QS_CCT_CTR0); | 230 | writeb(QS_CTR0_REG, chan + QS_CCT_CTR0); |
225 | readb(chan + QS_CCT_CTR0); /* flush */ | 231 | readb(chan + QS_CCT_CTR0); /* flush */ |
@@ -227,7 +233,7 @@ static inline void qs_enter_reg_mode(struct ata_port *ap) | |||
227 | 233 | ||
228 | static inline void qs_reset_channel_logic(struct ata_port *ap) | 234 | static inline void qs_reset_channel_logic(struct ata_port *ap) |
229 | { | 235 | { |
230 | u8 __iomem *chan = ap->host->mmio_base + (ap->port_no * 0x4000); | 236 | u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000); |
231 | 237 | ||
232 | writeb(QS_CTR1_RCHN, chan + QS_CCT_CTR1); | 238 | writeb(QS_CTR1_RCHN, chan + QS_CCT_CTR1); |
233 | readb(chan + QS_CCT_CTR0); /* flush */ | 239 | readb(chan + QS_CCT_CTR0); /* flush */ |
@@ -257,14 +263,14 @@ static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg) | |||
257 | { | 263 | { |
258 | if (sc_reg > SCR_CONTROL) | 264 | if (sc_reg > SCR_CONTROL) |
259 | return ~0U; | 265 | return ~0U; |
260 | return readl((void __iomem *)(ap->ioaddr.scr_addr + (sc_reg * 8))); | 266 | return readl(ap->ioaddr.scr_addr + (sc_reg * 8)); |
261 | } | 267 | } |
262 | 268 | ||
263 | static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) | 269 | static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) |
264 | { | 270 | { |
265 | if (sc_reg > SCR_CONTROL) | 271 | if (sc_reg > SCR_CONTROL) |
266 | return; | 272 | return; |
267 | writel(val, (void __iomem *)(ap->ioaddr.scr_addr + (sc_reg * 8))); | 273 | writel(val, ap->ioaddr.scr_addr + (sc_reg * 8)); |
268 | } | 274 | } |
269 | 275 | ||
270 | static unsigned int qs_fill_sg(struct ata_queued_cmd *qc) | 276 | static unsigned int qs_fill_sg(struct ata_queued_cmd *qc) |
@@ -325,7 +331,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc) | |||
325 | /* host control block (HCB) */ | 331 | /* host control block (HCB) */ |
326 | buf[ 0] = QS_HCB_HDR; | 332 | buf[ 0] = QS_HCB_HDR; |
327 | buf[ 1] = hflags; | 333 | buf[ 1] = hflags; |
328 | *(__le32 *)(&buf[ 4]) = cpu_to_le32(qc->nsect * ATA_SECT_SIZE); | 334 | *(__le32 *)(&buf[ 4]) = cpu_to_le32(qc->nbytes); |
329 | *(__le32 *)(&buf[ 8]) = cpu_to_le32(nelem); | 335 | *(__le32 *)(&buf[ 8]) = cpu_to_le32(nelem); |
330 | addr = ((u64)pp->pkt_dma) + QS_CPB_BYTES; | 336 | addr = ((u64)pp->pkt_dma) + QS_CPB_BYTES; |
331 | *(__le64 *)(&buf[16]) = cpu_to_le64(addr); | 337 | *(__le64 *)(&buf[16]) = cpu_to_le64(addr); |
@@ -341,7 +347,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc) | |||
341 | static inline void qs_packet_start(struct ata_queued_cmd *qc) | 347 | static inline void qs_packet_start(struct ata_queued_cmd *qc) |
342 | { | 348 | { |
343 | struct ata_port *ap = qc->ap; | 349 | struct ata_port *ap = qc->ap; |
344 | u8 __iomem *chan = ap->host->mmio_base + (ap->port_no * 0x4000); | 350 | u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000); |
345 | 351 | ||
346 | VPRINTK("ENTER, ap %p\n", ap); | 352 | VPRINTK("ENTER, ap %p\n", ap); |
347 | 353 | ||
@@ -378,7 +384,7 @@ static inline unsigned int qs_intr_pkt(struct ata_host *host) | |||
378 | { | 384 | { |
379 | unsigned int handled = 0; | 385 | unsigned int handled = 0; |
380 | u8 sFFE; | 386 | u8 sFFE; |
381 | u8 __iomem *mmio_base = host->mmio_base; | 387 | u8 __iomem *mmio_base = qs_mmio_base(host); |
382 | 388 | ||
383 | do { | 389 | do { |
384 | u32 sff0 = readl(mmio_base + QS_HST_SFF); | 390 | u32 sff0 = readl(mmio_base + QS_HST_SFF); |
@@ -470,7 +476,7 @@ static irqreturn_t qs_intr(int irq, void *dev_instance) | |||
470 | return IRQ_RETVAL(handled); | 476 | return IRQ_RETVAL(handled); |
471 | } | 477 | } |
472 | 478 | ||
473 | static void qs_ata_setup_port(struct ata_ioports *port, unsigned long base) | 479 | static void qs_ata_setup_port(struct ata_ioports *port, void __iomem *base) |
474 | { | 480 | { |
475 | port->cmd_addr = | 481 | port->cmd_addr = |
476 | port->data_addr = base + 0x400; | 482 | port->data_addr = base + 0x400; |
@@ -492,7 +498,7 @@ static int qs_port_start(struct ata_port *ap) | |||
492 | { | 498 | { |
493 | struct device *dev = ap->host->dev; | 499 | struct device *dev = ap->host->dev; |
494 | struct qs_port_priv *pp; | 500 | struct qs_port_priv *pp; |
495 | void __iomem *mmio_base = ap->host->mmio_base; | 501 | void __iomem *mmio_base = qs_mmio_base(ap->host); |
496 | void __iomem *chan = mmio_base + (ap->port_no * 0x4000); | 502 | void __iomem *chan = mmio_base + (ap->port_no * 0x4000); |
497 | u64 addr; | 503 | u64 addr; |
498 | int rc; | 504 | int rc; |
@@ -501,17 +507,13 @@ static int qs_port_start(struct ata_port *ap) | |||
501 | if (rc) | 507 | if (rc) |
502 | return rc; | 508 | return rc; |
503 | qs_enter_reg_mode(ap); | 509 | qs_enter_reg_mode(ap); |
504 | pp = kzalloc(sizeof(*pp), GFP_KERNEL); | 510 | pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); |
505 | if (!pp) { | 511 | if (!pp) |
506 | rc = -ENOMEM; | 512 | return -ENOMEM; |
507 | goto err_out; | 513 | pp->pkt = dmam_alloc_coherent(dev, QS_PKT_BYTES, &pp->pkt_dma, |
508 | } | 514 | GFP_KERNEL); |
509 | pp->pkt = dma_alloc_coherent(dev, QS_PKT_BYTES, &pp->pkt_dma, | 515 | if (!pp->pkt) |
510 | GFP_KERNEL); | 516 | return -ENOMEM; |
511 | if (!pp->pkt) { | ||
512 | rc = -ENOMEM; | ||
513 | goto err_out_kfree; | ||
514 | } | ||
515 | memset(pp->pkt, 0, QS_PKT_BYTES); | 517 | memset(pp->pkt, 0, QS_PKT_BYTES); |
516 | ap->private_data = pp; | 518 | ap->private_data = pp; |
517 | 519 | ||
@@ -519,43 +521,19 @@ static int qs_port_start(struct ata_port *ap) | |||
519 | writel((u32) addr, chan + QS_CCF_CPBA); | 521 | writel((u32) addr, chan + QS_CCF_CPBA); |
520 | writel((u32)(addr >> 32), chan + QS_CCF_CPBA + 4); | 522 | writel((u32)(addr >> 32), chan + QS_CCF_CPBA + 4); |
521 | return 0; | 523 | return 0; |
522 | |||
523 | err_out_kfree: | ||
524 | kfree(pp); | ||
525 | err_out: | ||
526 | ata_port_stop(ap); | ||
527 | return rc; | ||
528 | } | ||
529 | |||
530 | static void qs_port_stop(struct ata_port *ap) | ||
531 | { | ||
532 | struct device *dev = ap->host->dev; | ||
533 | struct qs_port_priv *pp = ap->private_data; | ||
534 | |||
535 | if (pp != NULL) { | ||
536 | ap->private_data = NULL; | ||
537 | if (pp->pkt != NULL) | ||
538 | dma_free_coherent(dev, QS_PKT_BYTES, pp->pkt, | ||
539 | pp->pkt_dma); | ||
540 | kfree(pp); | ||
541 | } | ||
542 | ata_port_stop(ap); | ||
543 | } | 524 | } |
544 | 525 | ||
545 | static void qs_host_stop(struct ata_host *host) | 526 | static void qs_host_stop(struct ata_host *host) |
546 | { | 527 | { |
547 | void __iomem *mmio_base = host->mmio_base; | 528 | void __iomem *mmio_base = qs_mmio_base(host); |
548 | struct pci_dev *pdev = to_pci_dev(host->dev); | ||
549 | 529 | ||
550 | writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */ | 530 | writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */ |
551 | writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */ | 531 | writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */ |
552 | |||
553 | pci_iounmap(pdev, mmio_base); | ||
554 | } | 532 | } |
555 | 533 | ||
556 | static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe) | 534 | static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe) |
557 | { | 535 | { |
558 | void __iomem *mmio_base = pe->mmio_base; | 536 | void __iomem *mmio_base = pe->iomap[QS_MMIO_BAR]; |
559 | unsigned int port_no; | 537 | unsigned int port_no; |
560 | 538 | ||
561 | writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */ | 539 | writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */ |
@@ -630,44 +608,34 @@ static int qs_ata_init_one(struct pci_dev *pdev, | |||
630 | const struct pci_device_id *ent) | 608 | const struct pci_device_id *ent) |
631 | { | 609 | { |
632 | static int printed_version; | 610 | static int printed_version; |
633 | struct ata_probe_ent *probe_ent = NULL; | 611 | struct ata_probe_ent *probe_ent; |
634 | void __iomem *mmio_base; | 612 | void __iomem * const *iomap; |
635 | unsigned int board_idx = (unsigned int) ent->driver_data; | 613 | unsigned int board_idx = (unsigned int) ent->driver_data; |
636 | int rc, port_no; | 614 | int rc, port_no; |
637 | 615 | ||
638 | if (!printed_version++) | 616 | if (!printed_version++) |
639 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); | 617 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); |
640 | 618 | ||
641 | rc = pci_enable_device(pdev); | 619 | rc = pcim_enable_device(pdev); |
642 | if (rc) | 620 | if (rc) |
643 | return rc; | 621 | return rc; |
644 | 622 | ||
645 | rc = pci_request_regions(pdev, DRV_NAME); | 623 | if ((pci_resource_flags(pdev, QS_MMIO_BAR) & IORESOURCE_MEM) == 0) |
646 | if (rc) | 624 | return -ENODEV; |
647 | goto err_out; | ||
648 | |||
649 | if ((pci_resource_flags(pdev, 4) & IORESOURCE_MEM) == 0) { | ||
650 | rc = -ENODEV; | ||
651 | goto err_out_regions; | ||
652 | } | ||
653 | 625 | ||
654 | mmio_base = pci_iomap(pdev, 4, 0); | 626 | rc = pcim_iomap_regions(pdev, 1 << QS_MMIO_BAR, DRV_NAME); |
655 | if (mmio_base == NULL) { | 627 | if (rc) |
656 | rc = -ENOMEM; | 628 | return rc; |
657 | goto err_out_regions; | 629 | iomap = pcim_iomap_table(pdev); |
658 | } | ||
659 | 630 | ||
660 | rc = qs_set_dma_masks(pdev, mmio_base); | 631 | rc = qs_set_dma_masks(pdev, iomap[QS_MMIO_BAR]); |
661 | if (rc) | 632 | if (rc) |
662 | goto err_out_iounmap; | 633 | return rc; |
663 | 634 | ||
664 | probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); | 635 | probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL); |
665 | if (probe_ent == NULL) { | 636 | if (probe_ent == NULL) |
666 | rc = -ENOMEM; | 637 | return -ENOMEM; |
667 | goto err_out_iounmap; | ||
668 | } | ||
669 | 638 | ||
670 | memset(probe_ent, 0, sizeof(*probe_ent)); | ||
671 | probe_ent->dev = pci_dev_to_dev(pdev); | 639 | probe_ent->dev = pci_dev_to_dev(pdev); |
672 | INIT_LIST_HEAD(&probe_ent->node); | 640 | INIT_LIST_HEAD(&probe_ent->node); |
673 | 641 | ||
@@ -680,12 +648,12 @@ static int qs_ata_init_one(struct pci_dev *pdev, | |||
680 | 648 | ||
681 | probe_ent->irq = pdev->irq; | 649 | probe_ent->irq = pdev->irq; |
682 | probe_ent->irq_flags = IRQF_SHARED; | 650 | probe_ent->irq_flags = IRQF_SHARED; |
683 | probe_ent->mmio_base = mmio_base; | 651 | probe_ent->iomap = iomap; |
684 | probe_ent->n_ports = QS_PORTS; | 652 | probe_ent->n_ports = QS_PORTS; |
685 | 653 | ||
686 | for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) { | 654 | for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) { |
687 | unsigned long chan = (unsigned long)mmio_base + | 655 | void __iomem *chan = |
688 | (port_no * 0x4000); | 656 | probe_ent->iomap[QS_MMIO_BAR] + (port_no * 0x4000); |
689 | qs_ata_setup_port(&probe_ent->port[port_no], chan); | 657 | qs_ata_setup_port(&probe_ent->port[port_no], chan); |
690 | } | 658 | } |
691 | 659 | ||
@@ -694,19 +662,11 @@ static int qs_ata_init_one(struct pci_dev *pdev, | |||
694 | /* initialize adapter */ | 662 | /* initialize adapter */ |
695 | qs_host_init(board_idx, probe_ent); | 663 | qs_host_init(board_idx, probe_ent); |
696 | 664 | ||
697 | rc = ata_device_add(probe_ent); | 665 | if (ata_device_add(probe_ent) != QS_PORTS) |
698 | kfree(probe_ent); | 666 | return -EIO; |
699 | if (rc != QS_PORTS) | ||
700 | goto err_out_iounmap; | ||
701 | return 0; | ||
702 | 667 | ||
703 | err_out_iounmap: | 668 | devm_kfree(&pdev->dev, probe_ent); |
704 | pci_iounmap(pdev, mmio_base); | 669 | return 0; |
705 | err_out_regions: | ||
706 | pci_release_regions(pdev); | ||
707 | err_out: | ||
708 | pci_disable_device(pdev); | ||
709 | return rc; | ||
710 | } | 670 | } |
711 | 671 | ||
712 | static int __init qs_ata_init(void) | 672 | static int __init qs_ata_init(void) |