aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-sff.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-05-04 06:43:58 -0400
committerJeff Garzik <jeff@garzik.org>2007-05-11 18:09:18 -0400
commit1626aeb881236c8cb022b5e4ca594146a951d669 (patch)
tree30f3457e4b5d76e62ee192fcc0d52b0ee8a829df /drivers/ata/libata-sff.c
parent920a4b1038e442700a1cfac77ea7e20bd615a2c3 (diff)
libata: clean up SFF init mess
The intention of using port_mask in SFF init helpers was to eventually support exoctic configurations such as combination of legacy and native port on the same controller. This never became actually necessary and the related code always has been subtly broken one way or the other. Now that new init model is in place, there is no reason to make common helpers capable of handling all corner cases. Exotic cases can simply dealt within LLDs as necessary. This patch removes port_mask handling in SFF init helpers. SFF init helpers don't take n_ports argument and interpret it into port_mask anymore. All information is carried via port_info. n_ports argument is dropped and always two ports are allocated. LLD can tell SFF to skip certain port by marking it dummy. Note that SFF code has been treating unuvailable ports this way for a long time until recent breakage fix from Linus and is consistent with how other drivers handle with unavailable ports. This fixes 1-port legacy host handling still broken after the recent native mode fix and simplifies SFF init logic. The following changes are made... * ata_pci_init_native_host() and ata_init_legacy_host() both now try to initialized whatever they can and mark failed ports dummy. They return 0 if any port is successfully initialized. * ata_pci_prepare_native_host() and ata_pci_init_one() now doesn't take n_ports argument. All info should be specified via port_info array. Always two ports are allocated. * ata_pci_init_bmdma() exported to be used by LLDs in exotic cases. * port_info handling in all LLDs are standardized - all port_info arrays are const stack variable named ppi. Unless the second port is different from the first, its port_info is specified as NULL (tells libata that it's identical to the last non-NULL port_info). * pata_hpt37x/hpt3x2n: don't modify static variable directly. Make an on-stack copy instead as ata_piix does. * pata_uli: It has 4 ports instead of 2. Don't use ata_pci_prepare_native_host(). Allocate the host explicitly and use init helpers. It's simple enough. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/libata-sff.c')
-rw-r--r--drivers/ata/libata-sff.c162
1 files changed, 83 insertions, 79 deletions
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index d211db6b35a2..e35d13466c69 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -544,7 +544,7 @@ static int ata_resources_present(struct pci_dev *pdev, int port)
544 * RETURNS: 544 * RETURNS:
545 * 0 on success, -errno otherwise. 545 * 0 on success, -errno otherwise.
546 */ 546 */
547static int ata_pci_init_bmdma(struct ata_host *host) 547int ata_pci_init_bmdma(struct ata_host *host)
548{ 548{
549 struct device *gdev = host->dev; 549 struct device *gdev = host->dev;
550 struct pci_dev *pdev = to_pci_dev(gdev); 550 struct pci_dev *pdev = to_pci_dev(gdev);
@@ -566,7 +566,7 @@ static int ata_pci_init_bmdma(struct ata_host *host)
566 } 566 }
567 host->iomap = pcim_iomap_table(pdev); 567 host->iomap = pcim_iomap_table(pdev);
568 568
569 for (i = 0; i < host->n_ports; i++) { 569 for (i = 0; i < 2; i++) {
570 struct ata_port *ap = host->ports[i]; 570 struct ata_port *ap = host->ports[i];
571 void __iomem *bmdma = host->iomap[4] + 8 * i; 571 void __iomem *bmdma = host->iomap[4] + 8 * i;
572 572
@@ -585,54 +585,52 @@ static int ata_pci_init_bmdma(struct ata_host *host)
585/** 585/**
586 * ata_pci_init_native_host - acquire native ATA resources and init host 586 * ata_pci_init_native_host - acquire native ATA resources and init host
587 * @host: target ATA host 587 * @host: target ATA host
588 * @port_mask: ports to consider
589 * 588 *
590 * Acquire native PCI ATA resources for @host and initialize 589 * Acquire native PCI ATA resources for @host and initialize the
591 * @host accordoingly. 590 * first two ports of @host accordingly. Ports marked dummy are
591 * skipped and allocation failure makes the port dummy.
592 * 592 *
593 * LOCKING: 593 * LOCKING:
594 * Inherited from calling layer (may sleep). 594 * Inherited from calling layer (may sleep).
595 * 595 *
596 * RETURNS: 596 * RETURNS:
597 * 0 on success, -errno otherwise. 597 * 0 if at least one port is initialized, -ENODEV if no port is
598 * available.
598 */ 599 */
599int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask) 600int ata_pci_init_native_host(struct ata_host *host)
600{ 601{
601 struct device *gdev = host->dev; 602 struct device *gdev = host->dev;
602 struct pci_dev *pdev = to_pci_dev(gdev); 603 struct pci_dev *pdev = to_pci_dev(gdev);
604 unsigned int mask = 0;
603 int i, rc; 605 int i, rc;
604 606
605 /* Discard disabled ports. Some controllers show their unused
606 * channels this way. Disabled ports are made dummy.
607 */
608 for (i = 0; i < 2; i++) {
609 if ((port_mask & (1 << i)) && !ata_resources_present(pdev, i)) {
610 host->ports[i]->ops = &ata_dummy_port_ops;
611 port_mask &= ~(1 << i);
612 }
613 }
614
615 if (!port_mask) {
616 dev_printk(KERN_ERR, gdev, "no available port\n");
617 return -ENODEV;
618 }
619
620 /* request, iomap BARs and init port addresses accordingly */ 607 /* request, iomap BARs and init port addresses accordingly */
621 for (i = 0; i < 2; i++) { 608 for (i = 0; i < 2; i++) {
622 struct ata_port *ap = host->ports[i]; 609 struct ata_port *ap = host->ports[i];
623 int base = i * 2; 610 int base = i * 2;
624 void __iomem * const *iomap; 611 void __iomem * const *iomap;
625 612
626 if (!(port_mask & (1 << i))) 613 if (ata_port_is_dummy(ap))
614 continue;
615
616 /* Discard disabled ports. Some controllers show
617 * their unused channels this way. Disabled ports are
618 * made dummy.
619 */
620 if (!ata_resources_present(pdev, i)) {
621 ap->ops = &ata_dummy_port_ops;
627 continue; 622 continue;
623 }
628 624
629 rc = pcim_iomap_regions(pdev, 0x3 << base, DRV_NAME); 625 rc = pcim_iomap_regions(pdev, 0x3 << base, DRV_NAME);
630 if (rc) { 626 if (rc) {
631 dev_printk(KERN_ERR, gdev, "failed to request/iomap " 627 dev_printk(KERN_WARNING, gdev,
632 "BARs for port %d (errno=%d)\n", i, rc); 628 "failed to request/iomap BARs for port %d "
629 "(errno=%d)\n", i, rc);
633 if (rc == -EBUSY) 630 if (rc == -EBUSY)
634 pcim_pin_device(pdev); 631 pcim_pin_device(pdev);
635 return rc; 632 ap->ops = &ata_dummy_port_ops;
633 continue;
636 } 634 }
637 host->iomap = iomap = pcim_iomap_table(pdev); 635 host->iomap = iomap = pcim_iomap_table(pdev);
638 636
@@ -641,6 +639,13 @@ int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask)
641 ap->ioaddr.ctl_addr = (void __iomem *) 639 ap->ioaddr.ctl_addr = (void __iomem *)
642 ((unsigned long)iomap[base + 1] | ATA_PCI_CTL_OFS); 640 ((unsigned long)iomap[base + 1] | ATA_PCI_CTL_OFS);
643 ata_std_ports(&ap->ioaddr); 641 ata_std_ports(&ap->ioaddr);
642
643 mask |= 1 << i;
644 }
645
646 if (!mask) {
647 dev_printk(KERN_ERR, gdev, "no available native port\n");
648 return -ENODEV;
644 } 649 }
645 650
646 return 0; 651 return 0;
@@ -649,8 +654,7 @@ int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask)
649/** 654/**
650 * ata_pci_prepare_native_host - helper to prepare native PCI ATA host 655 * ata_pci_prepare_native_host - helper to prepare native PCI ATA host
651 * @pdev: target PCI device 656 * @pdev: target PCI device
652 * @ppi: array of port_info 657 * @ppi: array of port_info, must be enough for two ports
653 * @n_ports: number of ports to allocate
654 * @r_host: out argument for the initialized ATA host 658 * @r_host: out argument for the initialized ATA host
655 * 659 *
656 * Helper to allocate ATA host for @pdev, acquire all native PCI 660 * Helper to allocate ATA host for @pdev, acquire all native PCI
@@ -664,10 +668,9 @@ int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask)
664 */ 668 */
665int ata_pci_prepare_native_host(struct pci_dev *pdev, 669int ata_pci_prepare_native_host(struct pci_dev *pdev,
666 const struct ata_port_info * const * ppi, 670 const struct ata_port_info * const * ppi,
667 int n_ports, struct ata_host **r_host) 671 struct ata_host **r_host)
668{ 672{
669 struct ata_host *host; 673 struct ata_host *host;
670 unsigned int port_mask;
671 int rc; 674 int rc;
672 675
673 if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) 676 if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL))
@@ -681,11 +684,7 @@ int ata_pci_prepare_native_host(struct pci_dev *pdev,
681 goto err_out; 684 goto err_out;
682 } 685 }
683 686
684 port_mask = ATA_PORT_PRIMARY; 687 rc = ata_pci_init_native_host(host);
685 if (n_ports > 1)
686 port_mask |= ATA_PORT_SECONDARY;
687
688 rc = ata_pci_init_native_host(host, port_mask);
689 if (rc) 688 if (rc)
690 goto err_out; 689 goto err_out;
691 690
@@ -777,8 +776,11 @@ static int ata_init_legacy_port(struct ata_port *ap,
777 /* iomap cmd and ctl ports */ 776 /* iomap cmd and ctl ports */
778 legacy_dr->cmd_addr[port_no] = ioport_map(cmd_port, 8); 777 legacy_dr->cmd_addr[port_no] = ioport_map(cmd_port, 8);
779 legacy_dr->ctl_addr[port_no] = ioport_map(ctl_port, 1); 778 legacy_dr->ctl_addr[port_no] = ioport_map(ctl_port, 1);
780 if (!legacy_dr->cmd_addr[port_no] || !legacy_dr->ctl_addr[port_no]) 779 if (!legacy_dr->cmd_addr[port_no] || !legacy_dr->ctl_addr[port_no]) {
780 dev_printk(KERN_WARNING, host->dev,
781 "failed to map cmd/ctl ports\n");
781 return -ENOMEM; 782 return -ENOMEM;
783 }
782 784
783 /* init IO addresses */ 785 /* init IO addresses */
784 ap->ioaddr.cmd_addr = legacy_dr->cmd_addr[port_no]; 786 ap->ioaddr.cmd_addr = legacy_dr->cmd_addr[port_no];
@@ -792,19 +794,20 @@ static int ata_init_legacy_port(struct ata_port *ap,
792/** 794/**
793 * ata_init_legacy_host - acquire legacy ATA resources and init ATA host 795 * ata_init_legacy_host - acquire legacy ATA resources and init ATA host
794 * @host: target ATA host 796 * @host: target ATA host
795 * @legacy_mask: out parameter, mask indicating ports is in legacy mode
796 * @was_busy: out parameter, indicates whether any port was busy 797 * @was_busy: out parameter, indicates whether any port was busy
797 * 798 *
798 * Acquire legacy ATA resources for ports. 799 * Acquire legacy ATA resources for the first two ports of @host
800 * and initialize it accordingly. Ports marked dummy are skipped
801 * and resource acquistion failure makes the port dummy.
799 * 802 *
800 * LOCKING: 803 * LOCKING:
801 * Inherited from calling layer (may sleep). 804 * Inherited from calling layer (may sleep).
802 * 805 *
803 * RETURNS: 806 * RETURNS:
804 * 0 on success, -errno otherwise. 807 * 0 if at least one port is initialized, -ENODEV if no port is
808 * available.
805 */ 809 */
806static int ata_init_legacy_host(struct ata_host *host, 810static int ata_init_legacy_host(struct ata_host *host, int *was_busy)
807 unsigned int *legacy_mask, int *was_busy)
808{ 811{
809 struct device *gdev = host->dev; 812 struct device *gdev = host->dev;
810 struct ata_legacy_devres *legacy_dr; 813 struct ata_legacy_devres *legacy_dr;
@@ -821,22 +824,23 @@ static int ata_init_legacy_host(struct ata_host *host,
821 devres_add(gdev, legacy_dr); 824 devres_add(gdev, legacy_dr);
822 825
823 for (i = 0; i < 2; i++) { 826 for (i = 0; i < 2; i++) {
824 *legacy_mask &= ~(1 << i); 827 if (ata_port_is_dummy(host->ports[i]))
828 continue;
829
825 rc = ata_init_legacy_port(host->ports[i], legacy_dr); 830 rc = ata_init_legacy_port(host->ports[i], legacy_dr);
826 if (rc == 0) 831 if (rc == 0)
827 legacy_dr->mask |= 1 << i; 832 legacy_dr->mask |= 1 << i;
828 else if (rc == -EBUSY) 833 else {
829 (*was_busy)++; 834 if (rc == -EBUSY)
830 } 835 (*was_busy)++;
831
832 if (!legacy_dr->mask)
833 return -EBUSY;
834
835 for (i = 0; i < 2; i++)
836 if (!(legacy_dr->mask & (1 << i)))
837 host->ports[i]->ops = &ata_dummy_port_ops; 836 host->ports[i]->ops = &ata_dummy_port_ops;
837 }
838 }
838 839
839 *legacy_mask |= legacy_dr->mask; 840 if (!legacy_dr->mask) {
841 dev_printk(KERN_ERR, gdev, "no available legacy port\n");
842 return -ENODEV;
843 }
840 844
841 devres_remove_group(gdev, NULL); 845 devres_remove_group(gdev, NULL);
842 return 0; 846 return 0;
@@ -875,7 +879,7 @@ static int ata_request_legacy_irqs(struct ata_host *host,
875 legacy_dr = devres_find(host->dev, ata_legacy_release, NULL, NULL); 879 legacy_dr = devres_find(host->dev, ata_legacy_release, NULL, NULL);
876 BUG_ON(!legacy_dr); 880 BUG_ON(!legacy_dr);
877 881
878 for (i = 0; i < host->n_ports; i++) { 882 for (i = 0; i < 2; i++) {
879 unsigned int irq; 883 unsigned int irq;
880 884
881 /* FIXME: ATA_*_IRQ() should take generic device not pci_dev */ 885 /* FIXME: ATA_*_IRQ() should take generic device not pci_dev */
@@ -923,8 +927,7 @@ static int ata_request_legacy_irqs(struct ata_host *host,
923/** 927/**
924 * ata_pci_init_one - Initialize/register PCI IDE host controller 928 * ata_pci_init_one - Initialize/register PCI IDE host controller
925 * @pdev: Controller to be initialized 929 * @pdev: Controller to be initialized
926 * @port_info: Information from low-level host driver 930 * @ppi: array of port_info, must be enough for two ports
927 * @n_ports: Number of ports attached to host controller
928 * 931 *
929 * This is a helper function which can be called from a driver's 932 * This is a helper function which can be called from a driver's
930 * xxx_init_one() probe function if the hardware uses traditional 933 * xxx_init_one() probe function if the hardware uses traditional
@@ -944,26 +947,34 @@ static int ata_request_legacy_irqs(struct ata_host *host,
944 * RETURNS: 947 * RETURNS:
945 * Zero on success, negative on errno-based value on error. 948 * Zero on success, negative on errno-based value on error.
946 */ 949 */
947 950int ata_pci_init_one(struct pci_dev *pdev,
948int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, 951 const struct ata_port_info * const * ppi)
949 unsigned int n_ports)
950{ 952{
951 struct device *dev = &pdev->dev; 953 struct device *dev = &pdev->dev;
954 const struct ata_port_info *pi = NULL;
952 struct ata_host *host = NULL; 955 struct ata_host *host = NULL;
953 const struct ata_port_info *port[2];
954 u8 mask; 956 u8 mask;
955 unsigned int legacy_mode = 0; 957 int legacy_mode = 0;
956 int rc; 958 int i, rc;
957 959
958 DPRINTK("ENTER\n"); 960 DPRINTK("ENTER\n");
959 961
960 if (!devres_open_group(dev, NULL, GFP_KERNEL)) 962 /* look up the first valid port_info */
961 return -ENOMEM; 963 for (i = 0; i < 2 && ppi[i]; i++) {
964 if (ppi[i]->port_ops != &ata_dummy_port_ops) {
965 pi = ppi[i];
966 break;
967 }
968 }
962 969
963 BUG_ON(n_ports < 1 || n_ports > 2); 970 if (!pi) {
971 dev_printk(KERN_ERR, &pdev->dev,
972 "no valid port_info specified\n");
973 return -EINVAL;
974 }
964 975
965 port[0] = port_info[0]; 976 if (!devres_open_group(dev, NULL, GFP_KERNEL))
966 port[1] = (n_ports > 1) ? port_info[1] : NULL; 977 return -ENOMEM;
967 978
968 /* FIXME: Really for ATA it isn't safe because the device may be 979 /* FIXME: Really for ATA it isn't safe because the device may be
969 multi-purpose and we want to leave it alone if it was already 980 multi-purpose and we want to leave it alone if it was already
@@ -984,7 +995,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
984 pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8); 995 pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8);
985 mask = (1 << 2) | (1 << 0); 996 mask = (1 << 2) | (1 << 0);
986 if ((tmp8 & mask) != mask) 997 if ((tmp8 & mask) != mask)
987 legacy_mode = (1 << 3); 998 legacy_mode = 1;
988#if defined(CONFIG_NO_ATA_LEGACY) 999#if defined(CONFIG_NO_ATA_LEGACY)
989 /* Some platforms with PCI limits cannot address compat 1000 /* Some platforms with PCI limits cannot address compat
990 port space. In that case we punt if their firmware has 1001 port space. In that case we punt if their firmware has
@@ -998,7 +1009,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
998 } 1009 }
999 1010
1000 /* alloc and init host */ 1011 /* alloc and init host */
1001 host = ata_host_alloc_pinfo(dev, port, n_ports); 1012 host = ata_host_alloc_pinfo(dev, ppi, 2);
1002 if (!host) { 1013 if (!host) {
1003 dev_printk(KERN_ERR, &pdev->dev, 1014 dev_printk(KERN_ERR, &pdev->dev,
1004 "failed to allocate ATA host\n"); 1015 "failed to allocate ATA host\n");
@@ -1007,19 +1018,13 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
1007 } 1018 }
1008 1019
1009 if (!legacy_mode) { 1020 if (!legacy_mode) {
1010 unsigned int port_mask; 1021 rc = ata_pci_init_native_host(host);
1011
1012 port_mask = ATA_PORT_PRIMARY;
1013 if (n_ports > 1)
1014 port_mask |= ATA_PORT_SECONDARY;
1015
1016 rc = ata_pci_init_native_host(host, port_mask);
1017 if (rc) 1022 if (rc)
1018 goto err_out; 1023 goto err_out;
1019 } else { 1024 } else {
1020 int was_busy = 0; 1025 int was_busy = 0;
1021 1026
1022 rc = ata_init_legacy_host(host, &legacy_mode, &was_busy); 1027 rc = ata_init_legacy_host(host, &was_busy);
1023 if (was_busy) 1028 if (was_busy)
1024 pcim_pin_device(pdev); 1029 pcim_pin_device(pdev);
1025 if (rc) 1030 if (rc)
@@ -1040,8 +1045,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
1040 goto err_out; 1045 goto err_out;
1041 1046
1042 if (!legacy_mode) 1047 if (!legacy_mode)
1043 rc = devm_request_irq(dev, pdev->irq, 1048 rc = devm_request_irq(dev, pdev->irq, pi->port_ops->irq_handler,
1044 port_info[0]->port_ops->irq_handler,
1045 IRQF_SHARED, DRV_NAME, host); 1049 IRQF_SHARED, DRV_NAME, host);
1046 else { 1050 else {
1047 irq_handler_t handler[2] = { host->ops->irq_handler, 1051 irq_handler_t handler[2] = { host->ops->irq_handler,
@@ -1055,7 +1059,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
1055 goto err_out; 1059 goto err_out;
1056 1060
1057 /* register */ 1061 /* register */
1058 rc = ata_host_register(host, port_info[0]->sht); 1062 rc = ata_host_register(host, pi->sht);
1059 if (rc) 1063 if (rc)
1060 goto err_out; 1064 goto err_out;
1061 1065