aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/probe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r--drivers/pci/probe.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index a3b0a5eb5054..0eeac60042b3 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -679,6 +679,33 @@ static int pci_setup_device(struct pci_dev * dev)
679 pci_read_bases(dev, 6, PCI_ROM_ADDRESS); 679 pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
680 pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor); 680 pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor);
681 pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device); 681 pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device);
682
683 /*
684 * Do the ugly legacy mode stuff here rather than broken chip
685 * quirk code. Legacy mode ATA controllers have fixed
686 * addresses. These are not always echoed in BAR0-3, and
687 * BAR0-3 in a few cases contain junk!
688 */
689 if (class == PCI_CLASS_STORAGE_IDE) {
690 u8 progif;
691 pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
692 if ((progif & 1) == 0) {
693 dev->resource[0].start = 0x1F0;
694 dev->resource[0].end = 0x1F7;
695 dev->resource[0].flags = IORESOURCE_IO;
696 dev->resource[1].start = 0x3F6;
697 dev->resource[1].end = 0x3F6;
698 dev->resource[1].flags = IORESOURCE_IO;
699 }
700 if ((progif & 4) == 0) {
701 dev->resource[2].start = 0x170;
702 dev->resource[2].end = 0x177;
703 dev->resource[2].flags = IORESOURCE_IO;
704 dev->resource[3].start = 0x376;
705 dev->resource[3].end = 0x376;
706 dev->resource[3].flags = IORESOURCE_IO;
707 }
708 }
682 break; 709 break;
683 710
684 case PCI_HEADER_TYPE_BRIDGE: /* bridge header */ 711 case PCI_HEADER_TYPE_BRIDGE: /* bridge header */
@@ -1067,3 +1094,95 @@ EXPORT_SYMBOL(pci_scan_bridge);
1067EXPORT_SYMBOL(pci_scan_single_device); 1094EXPORT_SYMBOL(pci_scan_single_device);
1068EXPORT_SYMBOL_GPL(pci_scan_child_bus); 1095EXPORT_SYMBOL_GPL(pci_scan_child_bus);
1069#endif 1096#endif
1097
1098static int __init pci_sort_bf_cmp(const struct pci_dev *a, const struct pci_dev *b)
1099{
1100 if (pci_domain_nr(a->bus) < pci_domain_nr(b->bus)) return -1;
1101 else if (pci_domain_nr(a->bus) > pci_domain_nr(b->bus)) return 1;
1102
1103 if (a->bus->number < b->bus->number) return -1;
1104 else if (a->bus->number > b->bus->number) return 1;
1105
1106 if (a->devfn < b->devfn) return -1;
1107 else if (a->devfn > b->devfn) return 1;
1108
1109 return 0;
1110}
1111
1112/*
1113 * Yes, this forcably breaks the klist abstraction temporarily. It
1114 * just wants to sort the klist, not change reference counts and
1115 * take/drop locks rapidly in the process. It does all this while
1116 * holding the lock for the list, so objects can't otherwise be
1117 * added/removed while we're swizzling.
1118 */
1119static void __init pci_insertion_sort_klist(struct pci_dev *a, struct list_head *list)
1120{
1121 struct list_head *pos;
1122 struct klist_node *n;
1123 struct device *dev;
1124 struct pci_dev *b;
1125
1126 list_for_each(pos, list) {
1127 n = container_of(pos, struct klist_node, n_node);
1128 dev = container_of(n, struct device, knode_bus);
1129 b = to_pci_dev(dev);
1130 if (pci_sort_bf_cmp(a, b) <= 0) {
1131 list_move_tail(&a->dev.knode_bus.n_node, &b->dev.knode_bus.n_node);
1132 return;
1133 }
1134 }
1135 list_move_tail(&a->dev.knode_bus.n_node, list);
1136}
1137
1138static void __init pci_sort_breadthfirst_klist(void)
1139{
1140 LIST_HEAD(sorted_devices);
1141 struct list_head *pos, *tmp;
1142 struct klist_node *n;
1143 struct device *dev;
1144 struct pci_dev *pdev;
1145
1146 spin_lock(&pci_bus_type.klist_devices.k_lock);
1147 list_for_each_safe(pos, tmp, &pci_bus_type.klist_devices.k_list) {
1148 n = container_of(pos, struct klist_node, n_node);
1149 dev = container_of(n, struct device, knode_bus);
1150 pdev = to_pci_dev(dev);
1151 pci_insertion_sort_klist(pdev, &sorted_devices);
1152 }
1153 list_splice(&sorted_devices, &pci_bus_type.klist_devices.k_list);
1154 spin_unlock(&pci_bus_type.klist_devices.k_lock);
1155}
1156
1157static void __init pci_insertion_sort_devices(struct pci_dev *a, struct list_head *list)
1158{
1159 struct pci_dev *b;
1160
1161 list_for_each_entry(b, list, global_list) {
1162 if (pci_sort_bf_cmp(a, b) <= 0) {
1163 list_move_tail(&a->global_list, &b->global_list);
1164 return;
1165 }
1166 }
1167 list_move_tail(&a->global_list, list);
1168}
1169
1170static void __init pci_sort_breadthfirst_devices(void)
1171{
1172 LIST_HEAD(sorted_devices);
1173 struct pci_dev *dev, *tmp;
1174
1175 down_write(&pci_bus_sem);
1176 list_for_each_entry_safe(dev, tmp, &pci_devices, global_list) {
1177 pci_insertion_sort_devices(dev, &sorted_devices);
1178 }
1179 list_splice(&sorted_devices, &pci_devices);
1180 up_write(&pci_bus_sem);
1181}
1182
1183void __init pci_sort_breadthfirst(void)
1184{
1185 pci_sort_breadthfirst_devices();
1186 pci_sort_breadthfirst_klist();
1187}
1188