diff options
| -rw-r--r-- | drivers/ata/libata-core.c | 1 | ||||
| -rw-r--r-- | drivers/ata/libata-sff.c | 151 | ||||
| -rw-r--r-- | include/linux/libata.h | 2 |
3 files changed, 104 insertions, 50 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index ab189d3b84d3..8d3ae66572e9 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -6726,6 +6726,7 @@ EXPORT_SYMBOL_GPL(ata_timing_merge); | |||
| 6726 | #ifdef CONFIG_PCI | 6726 | #ifdef CONFIG_PCI |
| 6727 | EXPORT_SYMBOL_GPL(pci_test_config_bits); | 6727 | EXPORT_SYMBOL_GPL(pci_test_config_bits); |
| 6728 | EXPORT_SYMBOL_GPL(ata_pci_init_native_mode); | 6728 | EXPORT_SYMBOL_GPL(ata_pci_init_native_mode); |
| 6729 | EXPORT_SYMBOL_GPL(ata_pci_init_native_host); | ||
| 6729 | EXPORT_SYMBOL_GPL(ata_pci_init_one); | 6730 | EXPORT_SYMBOL_GPL(ata_pci_init_one); |
| 6730 | EXPORT_SYMBOL_GPL(ata_pci_remove_one); | 6731 | EXPORT_SYMBOL_GPL(ata_pci_remove_one); |
| 6731 | #ifdef CONFIG_PM | 6732 | #ifdef CONFIG_PM |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index d48e1544a0bb..d551fa1cb104 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
| @@ -678,6 +678,70 @@ static int ata_pci_init_bmdma(struct ata_host *host) | |||
| 678 | return 0; | 678 | return 0; |
| 679 | } | 679 | } |
| 680 | 680 | ||
| 681 | /** | ||
| 682 | * ata_pci_init_native_host - acquire native ATA resources and init host | ||
| 683 | * @host: target ATA host | ||
| 684 | * @port_mask: ports to consider | ||
| 685 | * | ||
| 686 | * Acquire native PCI ATA resources for @host and initialize | ||
| 687 | * @host accordoingly. | ||
| 688 | * | ||
| 689 | * LOCKING: | ||
| 690 | * Inherited from calling layer (may sleep). | ||
| 691 | * | ||
| 692 | * RETURNS: | ||
| 693 | * 0 on success, -errno otherwise. | ||
| 694 | */ | ||
| 695 | int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask) | ||
| 696 | { | ||
| 697 | struct device *gdev = host->dev; | ||
| 698 | struct pci_dev *pdev = to_pci_dev(gdev); | ||
| 699 | int i, rc; | ||
| 700 | |||
| 701 | /* Discard disabled ports. Some controllers show their unused | ||
| 702 | * channels this way. Disabled ports are made dummy. | ||
| 703 | */ | ||
| 704 | for (i = 0; i < 2; i++) { | ||
| 705 | if ((port_mask & (1 << i)) && !ata_resources_present(pdev, i)) { | ||
| 706 | host->ports[i]->ops = &ata_dummy_port_ops; | ||
| 707 | port_mask &= ~(1 << i); | ||
| 708 | } | ||
| 709 | } | ||
| 710 | |||
| 711 | if (!port_mask) { | ||
| 712 | dev_printk(KERN_ERR, gdev, "no available port\n"); | ||
| 713 | return -ENODEV; | ||
| 714 | } | ||
| 715 | |||
| 716 | /* request, iomap BARs and init port addresses accordingly */ | ||
| 717 | for (i = 0; i < 2; i++) { | ||
| 718 | struct ata_port *ap = host->ports[i]; | ||
| 719 | int base = i * 2; | ||
| 720 | void __iomem * const *iomap; | ||
| 721 | |||
| 722 | if (!(port_mask & (1 << i))) | ||
| 723 | continue; | ||
| 724 | |||
| 725 | rc = pcim_iomap_regions(pdev, 0x3 << base, DRV_NAME); | ||
| 726 | if (rc) { | ||
| 727 | dev_printk(KERN_ERR, gdev, "failed to request/iomap " | ||
| 728 | "BARs for port %d (errno=%d)\n", i, rc); | ||
| 729 | if (rc == -EBUSY) | ||
| 730 | pcim_pin_device(pdev); | ||
| 731 | return rc; | ||
| 732 | } | ||
| 733 | host->iomap = iomap = pcim_iomap_table(pdev); | ||
| 734 | |||
| 735 | ap->ioaddr.cmd_addr = iomap[base]; | ||
| 736 | ap->ioaddr.altstatus_addr = | ||
| 737 | ap->ioaddr.ctl_addr = (void __iomem *) | ||
| 738 | ((unsigned long)iomap[base + 1] | ATA_PCI_CTL_OFS); | ||
| 739 | ata_std_ports(&ap->ioaddr); | ||
| 740 | } | ||
| 741 | |||
| 742 | return 0; | ||
| 743 | } | ||
| 744 | |||
| 681 | struct ata_legacy_devres { | 745 | struct ata_legacy_devres { |
| 682 | unsigned int mask; | 746 | unsigned int mask; |
| 683 | unsigned long cmd_port[2]; | 747 | unsigned long cmd_port[2]; |
| @@ -917,7 +981,6 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
| 917 | unsigned int n_ports) | 981 | unsigned int n_ports) |
| 918 | { | 982 | { |
| 919 | struct device *dev = &pdev->dev; | 983 | struct device *dev = &pdev->dev; |
| 920 | struct ata_probe_ent *probe_ent = NULL; | ||
| 921 | struct ata_host *host = NULL; | 984 | struct ata_host *host = NULL; |
| 922 | const struct ata_port_info *port[2]; | 985 | const struct ata_port_info *port[2]; |
| 923 | u8 mask; | 986 | u8 mask; |
| @@ -943,7 +1006,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
| 943 | 1006 | ||
| 944 | Checking dev->is_enabled is insufficient as this is not set at | 1007 | Checking dev->is_enabled is insufficient as this is not set at |
| 945 | boot for the primary video which is BIOS enabled | 1008 | boot for the primary video which is BIOS enabled |
| 946 | */ | 1009 | */ |
| 947 | 1010 | ||
| 948 | rc = pcim_enable_device(pdev); | 1011 | rc = pcim_enable_device(pdev); |
| 949 | if (rc) | 1012 | if (rc) |
| @@ -969,30 +1032,28 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
| 969 | #endif | 1032 | #endif |
| 970 | } | 1033 | } |
| 971 | 1034 | ||
| 1035 | /* alloc and init host */ | ||
| 1036 | host = ata_host_alloc_pinfo(dev, port, 2); | ||
| 1037 | if (!host) { | ||
| 1038 | dev_printk(KERN_ERR, &pdev->dev, | ||
| 1039 | "failed to allocate ATA host\n"); | ||
| 1040 | rc = -ENOMEM; | ||
| 1041 | goto err_out; | ||
| 1042 | } | ||
| 1043 | |||
| 972 | if (!legacy_mode) { | 1044 | if (!legacy_mode) { |
| 973 | rc = pci_request_regions(pdev, DRV_NAME); | 1045 | unsigned int port_mask; |
| 974 | if (rc) { | ||
| 975 | pcim_pin_device(pdev); | ||
| 976 | goto err_out; | ||
| 977 | } | ||
| 978 | 1046 | ||
| 979 | /* TODO: If we get no DMA mask we should fall back to PIO */ | 1047 | port_mask = ATA_PORT_PRIMARY; |
| 980 | rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); | 1048 | if (n_ports > 1) |
| 981 | if (rc) | 1049 | port_mask |= ATA_PORT_SECONDARY; |
| 982 | goto err_out; | 1050 | |
| 983 | rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); | 1051 | rc = ata_pci_init_native_host(host, port_mask); |
| 984 | if (rc) | 1052 | if (rc) |
| 985 | goto err_out; | 1053 | goto err_out; |
| 986 | |||
| 987 | pci_set_master(pdev); | ||
| 988 | } else { | 1054 | } else { |
| 989 | int was_busy = 0; | 1055 | int was_busy = 0; |
| 990 | 1056 | ||
| 991 | rc = -ENOMEM; | ||
| 992 | host = ata_host_alloc_pinfo(dev, port, 2); | ||
| 993 | if (!host) | ||
| 994 | goto err_out; | ||
| 995 | |||
| 996 | rc = ata_init_legacy_host(host, &legacy_mode, &was_busy); | 1057 | rc = ata_init_legacy_host(host, &legacy_mode, &was_busy); |
| 997 | if (was_busy) | 1058 | if (was_busy) |
| 998 | pcim_pin_device(pdev); | 1059 | pcim_pin_device(pdev); |
| @@ -1002,47 +1063,37 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
| 1002 | /* request respective PCI regions, may fail */ | 1063 | /* request respective PCI regions, may fail */ |
| 1003 | rc = pci_request_region(pdev, 1, DRV_NAME); | 1064 | rc = pci_request_region(pdev, 1, DRV_NAME); |
| 1004 | rc = pci_request_region(pdev, 3, DRV_NAME); | 1065 | rc = pci_request_region(pdev, 3, DRV_NAME); |
| 1005 | |||
| 1006 | /* init bmdma */ | ||
| 1007 | ata_pci_init_bmdma(host); | ||
| 1008 | pci_set_master(pdev); | ||
| 1009 | } | 1066 | } |
| 1010 | 1067 | ||
| 1011 | if (legacy_mode) { | 1068 | /* init BMDMA, may fail */ |
| 1069 | ata_pci_init_bmdma(host); | ||
| 1070 | pci_set_master(pdev); | ||
| 1071 | |||
| 1072 | /* start host and request IRQ */ | ||
| 1073 | rc = ata_host_start(host); | ||
| 1074 | if (rc) | ||
| 1075 | goto err_out; | ||
| 1076 | |||
| 1077 | if (!legacy_mode) | ||
| 1078 | rc = devm_request_irq(dev, pdev->irq, | ||
| 1079 | port_info[0]->port_ops->irq_handler, | ||
| 1080 | IRQF_SHARED, DRV_NAME, host); | ||
| 1081 | else { | ||
| 1012 | irq_handler_t handler[2] = { host->ops->irq_handler, | 1082 | irq_handler_t handler[2] = { host->ops->irq_handler, |
| 1013 | host->ops->irq_handler }; | 1083 | host->ops->irq_handler }; |
| 1014 | unsigned int irq_flags[2] = { IRQF_SHARED, IRQF_SHARED }; | 1084 | unsigned int irq_flags[2] = { IRQF_SHARED, IRQF_SHARED }; |
| 1015 | void *dev_id[2] = { host, host }; | 1085 | void *dev_id[2] = { host, host }; |
| 1016 | 1086 | ||
| 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); | 1087 | rc = ata_request_legacy_irqs(host, handler, irq_flags, dev_id); |
| 1022 | if (rc) | 1088 | } |
| 1023 | goto err_out; | 1089 | if (rc) |
| 1024 | 1090 | goto err_out; | |
| 1025 | rc = ata_host_register(host, port_info[0]->sht); | ||
| 1026 | if (rc) | ||
| 1027 | goto err_out; | ||
| 1028 | } else { | ||
| 1029 | if (n_ports == 2) | ||
| 1030 | probe_ent = ata_pci_init_native_mode(pdev, (struct ata_port_info **)port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); | ||
| 1031 | else | ||
| 1032 | probe_ent = ata_pci_init_native_mode(pdev, (struct ata_port_info **)port, ATA_PORT_PRIMARY); | ||
| 1033 | |||
| 1034 | if (!probe_ent) { | ||
| 1035 | rc = -ENOMEM; | ||
| 1036 | goto err_out; | ||
| 1037 | } | ||
| 1038 | 1091 | ||
| 1039 | if (!ata_device_add(probe_ent)) { | 1092 | /* register */ |
| 1040 | rc = -ENODEV; | 1093 | rc = ata_host_register(host, port_info[0]->sht); |
| 1041 | goto err_out; | 1094 | if (rc) |
| 1042 | } | 1095 | goto err_out; |
| 1043 | 1096 | ||
| 1044 | devm_kfree(dev, probe_ent); | ||
| 1045 | } | ||
| 1046 | devres_remove_group(dev, NULL); | 1097 | devres_remove_group(dev, NULL); |
| 1047 | return 0; | 1098 | return 0; |
| 1048 | 1099 | ||
diff --git a/include/linux/libata.h b/include/linux/libata.h index 300daf6c50d0..400429f9cd9d 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
| @@ -892,6 +892,8 @@ struct pci_bits { | |||
| 892 | 892 | ||
| 893 | extern struct ata_probe_ent * | 893 | extern struct ata_probe_ent * |
| 894 | ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int portmask); | 894 | ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int portmask); |
| 895 | extern int ata_pci_init_native_host(struct ata_host *host, | ||
| 896 | unsigned int port_mask); | ||
| 895 | extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits); | 897 | extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits); |
| 896 | extern unsigned long ata_pci_default_filter(struct ata_device *, unsigned long); | 898 | extern unsigned long ata_pci_default_filter(struct ata_device *, unsigned long); |
| 897 | #endif /* CONFIG_PCI */ | 899 | #endif /* CONFIG_PCI */ |
