0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <linux/kernel.h>
0021 #include <linux/module.h>
0022 #include <linux/pci.h>
0023
0024 #include <pcmcia/ss.h>
0025 #include <pcmcia/cistpl.h>
0026
0027 #include "cs_internal.h"
0028
0029 static void cardbus_config_irq_and_cls(struct pci_bus *bus, int irq)
0030 {
0031 struct pci_dev *dev;
0032
0033 list_for_each_entry(dev, &bus->devices, bus_list) {
0034 u8 irq_pin;
0035
0036
0037
0038
0039
0040
0041 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
0042 if (irq_pin) {
0043 dev->irq = irq;
0044 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
0045 }
0046
0047
0048
0049
0050
0051
0052 pci_set_cacheline_size(dev);
0053
0054 if (dev->subordinate)
0055 cardbus_config_irq_and_cls(dev->subordinate, irq);
0056 }
0057 }
0058
0059
0060
0061
0062
0063
0064
0065
0066 int __ref cb_alloc(struct pcmcia_socket *s)
0067 {
0068 struct pci_bus *bus = s->cb_dev->subordinate;
0069 struct pci_dev *dev;
0070 unsigned int max, pass;
0071
0072 pci_lock_rescan_remove();
0073
0074 s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0));
0075 pci_fixup_cardbus(bus);
0076
0077 max = bus->busn_res.start;
0078 for (pass = 0; pass < 2; pass++)
0079 for_each_pci_bridge(dev, bus)
0080 max = pci_scan_bridge(bus, dev, max, pass);
0081
0082
0083
0084
0085 pci_bus_size_bridges(bus);
0086 pci_bus_assign_resources(bus);
0087 cardbus_config_irq_and_cls(bus, s->pci_irq);
0088
0089
0090 if (s->tune_bridge)
0091 s->tune_bridge(s, bus);
0092
0093 pci_bus_add_devices(bus);
0094
0095 pci_unlock_rescan_remove();
0096 return 0;
0097 }
0098
0099
0100
0101
0102
0103
0104
0105 void cb_free(struct pcmcia_socket *s)
0106 {
0107 struct pci_dev *bridge, *dev, *tmp;
0108 struct pci_bus *bus;
0109
0110 bridge = s->cb_dev;
0111 if (!bridge)
0112 return;
0113
0114 bus = bridge->subordinate;
0115 if (!bus)
0116 return;
0117
0118 pci_lock_rescan_remove();
0119
0120 list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list)
0121 pci_stop_and_remove_bus_device(dev);
0122
0123 pci_unlock_rescan_remove();
0124 }