aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-04-17 10:44:07 -0400
committerJeff Garzik <jeff@garzik.org>2007-04-28 14:16:03 -0400
commit0f834de3ea61aacacf1fac59ba9e82680f83c846 (patch)
tree3b99ea99281e04ab6dd436f2954981f2cce889bb /drivers
parentf5cda257296fbd3683b1f568f2d94d3caaacf74d (diff)
libata: convert legacy PCI host handling to new init model
Convert legacy PCI host handling to alloc-init-register model. ata_init_legacy_host(), ata_request_legacy_irqs() and ata_pci_init_bmdma() are separated out and follow the new init model. The two legacy handling functions use separate ata_legacy_devres instead of generic devm_* resources. This reduces devres overhead for legacy hosts which was a bit high because it didn't use PCI/iomap merged resoruces. ata_pci_init_one() is rewritten in terms of the aboved functions but native mode handling is still using the old method. Conversion will be completed when native mode handling is updated. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/libata-sff.c404
1 files changed, 302 insertions, 102 deletions
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 93cc96782165..d48e1544a0bb 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -627,75 +627,266 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
627 return probe_ent; 627 return probe_ent;
628} 628}
629 629
630static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, 630/**
631 struct ata_port_info **port, int port_mask) 631 * ata_pci_init_bmdma - acquire PCI BMDMA resources and init ATA host
632 * @host: target ATA host
633 *
634 * Acquire PCI BMDMA resources and initialize @host accordingly.
635 *
636 * LOCKING:
637 * Inherited from calling layer (may sleep).
638 *
639 * RETURNS:
640 * 0 on success, -errno otherwise.
641 */
642static int ata_pci_init_bmdma(struct ata_host *host)
632{ 643{
633 struct ata_probe_ent *probe_ent; 644 struct device *gdev = host->dev;
634 void __iomem *iomap[5] = { }, *bmdma; 645 struct pci_dev *pdev = to_pci_dev(gdev);
646 int i, rc;
635 647
636 if (port_mask & ATA_PORT_PRIMARY) { 648 /* TODO: If we get no DMA mask we should fall back to PIO */
637 iomap[0] = devm_ioport_map(&pdev->dev, ATA_PRIMARY_CMD, 8); 649 rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
638 iomap[1] = devm_ioport_map(&pdev->dev, ATA_PRIMARY_CTL, 1); 650 if (rc)
639 if (!iomap[0] || !iomap[1]) 651 return rc;
640 return NULL; 652 rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
653 if (rc)
654 return rc;
655
656 /* request and iomap DMA region */
657 rc = pcim_iomap_regions(pdev, 1 << 4, DRV_NAME);
658 if (rc) {
659 dev_printk(KERN_ERR, gdev, "failed to request/iomap BAR4\n");
660 return -ENOMEM;
641 } 661 }
662 host->iomap = pcim_iomap_table(pdev);
642 663
643 if (port_mask & ATA_PORT_SECONDARY) { 664 for (i = 0; i < 2; i++) {
644 iomap[2] = devm_ioport_map(&pdev->dev, ATA_SECONDARY_CMD, 8); 665 struct ata_port *ap = host->ports[i];
645 iomap[3] = devm_ioport_map(&pdev->dev, ATA_SECONDARY_CTL, 1); 666 struct ata_ioports *ioaddr = &ap->ioaddr;
646 if (!iomap[2] || !iomap[3]) 667 void __iomem *bmdma = host->iomap[4] + 8 * i;
647 return NULL; 668
669 if (ata_port_is_dummy(ap))
670 continue;
671
672 ioaddr->bmdma_addr = bmdma;
673 if ((!(ap->flags & ATA_FLAG_IGN_SIMPLEX)) &&
674 (ioread8(bmdma + 2) & 0x80))
675 host->flags |= ATA_HOST_SIMPLEX;
648 } 676 }
649 677
650 bmdma = pcim_iomap(pdev, 4, 16); /* may fail */ 678 return 0;
679}
651 680
652 /* alloc and init probe_ent */ 681struct ata_legacy_devres {
653 probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); 682 unsigned int mask;
654 if (!probe_ent) 683 unsigned long cmd_port[2];
655 return NULL; 684 void __iomem * cmd_addr[2];
685 void __iomem * ctl_addr[2];
686 unsigned int irq[2];
687 void * irq_dev_id[2];
688};
656 689
657 probe_ent->n_ports = 2; 690static void ata_legacy_free_irqs(struct ata_legacy_devres *legacy_dr)
658 probe_ent->irq_flags = IRQF_SHARED; 691{
692 int i;
659 693
660 if (port_mask & ATA_PORT_PRIMARY) { 694 for (i = 0; i < 2; i++) {
661 probe_ent->irq = ATA_PRIMARY_IRQ(pdev); 695 if (!legacy_dr->irq[i])
662 probe_ent->port[0].cmd_addr = iomap[0]; 696 continue;
663 probe_ent->port[0].altstatus_addr = 697
664 probe_ent->port[0].ctl_addr = iomap[1]; 698 free_irq(legacy_dr->irq[i], legacy_dr->irq_dev_id[i]);
665 if (bmdma) { 699 legacy_dr->irq[i] = 0;
666 probe_ent->port[0].bmdma_addr = bmdma; 700 legacy_dr->irq_dev_id[i] = NULL;
667 if ((!(port[0]->flags & ATA_FLAG_IGN_SIMPLEX)) && 701 }
668 (ioread8(bmdma + 2) & 0x80)) 702}
669 probe_ent->_host_flags |= ATA_HOST_SIMPLEX; 703
670 } 704static void ata_legacy_release(struct device *gdev, void *res)
671 ata_std_ports(&probe_ent->port[0]); 705{
672 } else 706 struct ata_legacy_devres *this = res;
673 probe_ent->dummy_port_mask |= ATA_PORT_PRIMARY; 707 int i;
708
709 ata_legacy_free_irqs(this);
710
711 for (i = 0; i < 2; i++) {
712 if (this->cmd_addr[i])
713 ioport_unmap(this->cmd_addr[i]);
714 if (this->ctl_addr[i])
715 ioport_unmap(this->ctl_addr[i]);
716 if (this->cmd_port[i])
717 release_region(this->cmd_port[i], 8);
718 }
719}
720
721static int ata_init_legacy_port(struct ata_port *ap,
722 struct ata_legacy_devres *legacy_dr)
723{
724 struct ata_host *host = ap->host;
725 int port_no = ap->port_no;
726 unsigned long cmd_port, ctl_port;
727
728 if (port_no == 0) {
729 cmd_port = ATA_PRIMARY_CMD;
730 ctl_port = ATA_PRIMARY_CTL;
731 } else {
732 cmd_port = ATA_SECONDARY_CMD;
733 ctl_port = ATA_SECONDARY_CTL;
734 }
735
736 /* request cmd_port */
737 if (request_region(cmd_port, 8, "libata"))
738 legacy_dr->cmd_port[port_no] = cmd_port;
739 else {
740 dev_printk(KERN_WARNING, host->dev,
741 "0x%0lX IDE port busy\n", cmd_port);
742 return -EBUSY;
743 }
744
745 /* iomap cmd and ctl ports */
746 legacy_dr->cmd_addr[port_no] = ioport_map(cmd_port, 8);
747 legacy_dr->ctl_addr[port_no] = ioport_map(ctl_port, 1);
748 if (!legacy_dr->cmd_addr[port_no] || !legacy_dr->ctl_addr[port_no])
749 return -ENOMEM;
750
751 /* init IO addresses */
752 ap->ioaddr.cmd_addr = legacy_dr->cmd_addr[port_no];
753 ap->ioaddr.altstatus_addr = legacy_dr->ctl_addr[port_no];
754 ap->ioaddr.ctl_addr = legacy_dr->ctl_addr[port_no];
755 ata_std_ports(&ap->ioaddr);
756
757 return 0;
758}
759
760/**
761 * ata_init_legacy_host - acquire legacy ATA resources and init ATA host
762 * @host: target ATA host
763 * @legacy_mask: out parameter, mask indicating ports is in legacy mode
764 * @was_busy: out parameter, indicates whether any port was busy
765 *
766 * Acquire legacy ATA resources for ports.
767 *
768 * LOCKING:
769 * Inherited from calling layer (may sleep).
770 *
771 * RETURNS:
772 * 0 on success, -errno otherwise.
773 */
774static int ata_init_legacy_host(struct ata_host *host,
775 unsigned int *legacy_mask, int *was_busy)
776{
777 struct device *gdev = host->dev;
778 struct ata_legacy_devres *legacy_dr;
779 int i, rc;
780
781 if (!devres_open_group(gdev, NULL, GFP_KERNEL))
782 return -ENOMEM;
783
784 rc = -ENOMEM;
785 legacy_dr = devres_alloc(ata_legacy_release, sizeof(*legacy_dr),
786 GFP_KERNEL);
787 if (!legacy_dr)
788 goto err_out;
789 devres_add(gdev, legacy_dr);
790
791 for (i = 0; i < 2; i++) {
792 *legacy_mask &= ~(1 << i);
793 rc = ata_init_legacy_port(host->ports[i], legacy_dr);
794 if (rc == 0)
795 legacy_dr->mask |= 1 << i;
796 else if (rc == -EBUSY)
797 (*was_busy)++;
798 }
799
800 if (!legacy_dr->mask)
801 return -EBUSY;
802
803 for (i = 0; i < 2; i++)
804 if (!(legacy_dr->mask & (1 << i)))
805 host->ports[i]->ops = &ata_dummy_port_ops;
674 806
675 if (port_mask & ATA_PORT_SECONDARY) { 807 *legacy_mask |= legacy_dr->mask;
676 if (probe_ent->irq) 808
677 probe_ent->irq2 = ATA_SECONDARY_IRQ(pdev); 809 devres_remove_group(gdev, NULL);
810 return 0;
811
812 err_out:
813 devres_release_group(gdev, NULL);
814 return rc;
815}
816
817/**
818 * ata_request_legacy_irqs - request legacy ATA IRQs
819 * @host: target ATA host
820 * @handler: array of IRQ handlers
821 * @irq_flags: array of IRQ flags
822 * @dev_id: array of IRQ dev_ids
823 *
824 * Request legacy IRQs for non-dummy legacy ports in @host. All
825 * IRQ parameters are passed as array to allow ports to have
826 * separate IRQ handlers.
827 *
828 * LOCKING:
829 * Inherited from calling layer (may sleep).
830 *
831 * RETURNS:
832 * 0 on success, -errno otherwise.
833 */
834static int ata_request_legacy_irqs(struct ata_host *host,
835 irq_handler_t const *handler,
836 const unsigned int *irq_flags,
837 void * const *dev_id)
838{
839 struct device *gdev = host->dev;
840 struct ata_legacy_devres *legacy_dr;
841 int i, rc;
842
843 legacy_dr = devres_find(host->dev, ata_legacy_release, NULL, NULL);
844 BUG_ON(!legacy_dr);
845
846 for (i = 0; i < 2; i++) {
847 unsigned int irq;
848
849 /* FIXME: ATA_*_IRQ() should take generic device not pci_dev */
850 if (i == 0)
851 irq = ATA_PRIMARY_IRQ(to_pci_dev(gdev));
678 else 852 else
679 probe_ent->irq = ATA_SECONDARY_IRQ(pdev); 853 irq = ATA_SECONDARY_IRQ(to_pci_dev(gdev));
680 probe_ent->port[1].cmd_addr = iomap[2]; 854
681 probe_ent->port[1].altstatus_addr = 855 if (!(legacy_dr->mask & (1 << i)))
682 probe_ent->port[1].ctl_addr = iomap[3]; 856 continue;
683 if (bmdma) { 857
684 probe_ent->port[1].bmdma_addr = bmdma + 8; 858 if (!handler[i]) {
685 if ((!(port[1]->flags & ATA_FLAG_IGN_SIMPLEX)) && 859 dev_printk(KERN_ERR, gdev,
686 (ioread8(bmdma + 10) & 0x80)) 860 "NULL handler specified for port %d\n", i);
687 probe_ent->_host_flags |= ATA_HOST_SIMPLEX; 861 rc = -EINVAL;
862 goto err_out;
688 } 863 }
689 ata_std_ports(&probe_ent->port[1]);
690 864
691 /* FIXME: could be pointing to stack area; must copy */ 865 rc = request_irq(irq, handler[i], irq_flags[i], DRV_NAME,
692 probe_ent->pinfo2 = port[1]; 866 dev_id[i]);
693 } else 867 if (rc) {
694 probe_ent->dummy_port_mask |= ATA_PORT_SECONDARY; 868 dev_printk(KERN_ERR, gdev,
869 "irq %u request failed (errno=%d)\n", irq, rc);
870 goto err_out;
871 }
695 872
696 return probe_ent; 873 /* record irq allocation in legacy_dr */
697} 874 legacy_dr->irq[i] = irq;
875 legacy_dr->irq_dev_id[i] = dev_id[i];
876
877 /* only used to print info */
878 if (i == 0)
879 host->irq = irq;
880 else
881 host->irq2 = irq;
882 }
883
884 return 0;
698 885
886 err_out:
887 ata_legacy_free_irqs(legacy_dr);
888 return rc;
889}
699 890
700/** 891/**
701 * ata_pci_init_one - Initialize/register PCI IDE host controller 892 * ata_pci_init_one - Initialize/register PCI IDE host controller
@@ -727,7 +918,8 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
727{ 918{
728 struct device *dev = &pdev->dev; 919 struct device *dev = &pdev->dev;
729 struct ata_probe_ent *probe_ent = NULL; 920 struct ata_probe_ent *probe_ent = NULL;
730 struct ata_port_info *port[2]; 921 struct ata_host *host = NULL;
922 const struct ata_port_info *port[2];
731 u8 mask; 923 u8 mask;
732 unsigned int legacy_mode = 0; 924 unsigned int legacy_mode = 0;
733 int rc; 925 int rc;
@@ -783,66 +975,74 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
783 pcim_pin_device(pdev); 975 pcim_pin_device(pdev);
784 goto err_out; 976 goto err_out;
785 } 977 }
978
979 /* TODO: If we get no DMA mask we should fall back to PIO */
980 rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
981 if (rc)
982 goto err_out;
983 rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
984 if (rc)
985 goto err_out;
986
987 pci_set_master(pdev);
786 } else { 988 } else {
787 /* Deal with combined mode hack. This side of the logic all 989 int was_busy = 0;
788 goes away once the combined mode hack is killed in 2.6.21 */ 990
789 if (!devm_request_region(dev, ATA_PRIMARY_CMD, 8, "libata")) { 991 rc = -ENOMEM;
790 pcim_pin_device(pdev); 992 host = ata_host_alloc_pinfo(dev, port, 2);
791 printk(KERN_WARNING "ata: 0x%0X IDE port busy\n", 993 if (!host)
792 ATA_PRIMARY_CMD); 994 goto err_out;
793 } else
794 legacy_mode |= ATA_PORT_PRIMARY;
795 995
796 if (!devm_request_region(dev, ATA_SECONDARY_CMD, 8, "libata")) { 996 rc = ata_init_legacy_host(host, &legacy_mode, &was_busy);
997 if (was_busy)
797 pcim_pin_device(pdev); 998 pcim_pin_device(pdev);
798 printk(KERN_WARNING "ata: 0x%X IDE port busy\n", 999 if (rc)
799 ATA_SECONDARY_CMD); 1000 goto err_out;
800 } else
801 legacy_mode |= ATA_PORT_SECONDARY;
802
803 if (legacy_mode & ATA_PORT_PRIMARY)
804 pci_request_region(pdev, 1, DRV_NAME);
805 if (legacy_mode & ATA_PORT_SECONDARY)
806 pci_request_region(pdev, 3, DRV_NAME);
807 /* If there is a DMA resource, allocate it */
808 pci_request_region(pdev, 4, DRV_NAME);
809 }
810 1001
811 /* we have legacy mode, but all ports are unavailable */ 1002 /* request respective PCI regions, may fail */
812 if (legacy_mode == (1 << 3)) { 1003 rc = pci_request_region(pdev, 1, DRV_NAME);
813 rc = -EBUSY; 1004 rc = pci_request_region(pdev, 3, DRV_NAME);
814 goto err_out;
815 }
816 1005
817 /* TODO: If we get no DMA mask we should fall back to PIO */ 1006 /* init bmdma */
818 rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); 1007 ata_pci_init_bmdma(host);
819 if (rc) 1008 pci_set_master(pdev);
820 goto err_out; 1009 }
821 rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
822 if (rc)
823 goto err_out;
824 1010
825 if (legacy_mode) { 1011 if (legacy_mode) {
826 probe_ent = ata_pci_init_legacy_port(pdev, port, legacy_mode); 1012 irq_handler_t handler[2] = { host->ops->irq_handler,
1013 host->ops->irq_handler };
1014 unsigned int irq_flags[2] = { IRQF_SHARED, IRQF_SHARED };
1015 void *dev_id[2] = { host, host };
1016
1017 rc = ata_host_start(host);
1018 if (rc)
1019 goto err_out;
1020
1021 rc = ata_request_legacy_irqs(host, handler, irq_flags, dev_id);
1022 if (rc)
1023 goto err_out;
1024
1025 rc = ata_host_register(host, port_info[0]->sht);
1026 if (rc)
1027 goto err_out;
827 } else { 1028 } else {
828 if (n_ports == 2) 1029 if (n_ports == 2)
829 probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); 1030 probe_ent = ata_pci_init_native_mode(pdev, (struct ata_port_info **)port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
830 else 1031 else
831 probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY); 1032 probe_ent = ata_pci_init_native_mode(pdev, (struct ata_port_info **)port, ATA_PORT_PRIMARY);
832 }
833 if (!probe_ent) {
834 rc = -ENOMEM;
835 goto err_out;
836 }
837 1033
838 pci_set_master(pdev); 1034 if (!probe_ent) {
1035 rc = -ENOMEM;
1036 goto err_out;
1037 }
839 1038
840 if (!ata_device_add(probe_ent)) { 1039 if (!ata_device_add(probe_ent)) {
841 rc = -ENODEV; 1040 rc = -ENODEV;
842 goto err_out; 1041 goto err_out;
843 } 1042 }
844 1043
845 devm_kfree(dev, probe_ent); 1044 devm_kfree(dev, probe_ent);
1045 }
846 devres_remove_group(dev, NULL); 1046 devres_remove_group(dev, NULL);
847 return 0; 1047 return 0;
848 1048