aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/pci
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/Kconfig59
-rw-r--r--drivers/pci/Makefile65
-rw-r--r--drivers/pci/access.c62
-rw-r--r--drivers/pci/bus.c151
-rw-r--r--drivers/pci/gen-devlist.c132
-rw-r--r--drivers/pci/hotplug.c163
-rw-r--r--drivers/pci/hotplug/Kconfig197
-rw-r--r--drivers/pci/hotplug/Makefile74
-rw-r--r--drivers/pci/hotplug/acpiphp.h268
-rw-r--r--drivers/pci/hotplug/acpiphp_core.c453
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c1344
-rw-r--r--drivers/pci/hotplug/acpiphp_ibm.c499
-rw-r--r--drivers/pci/hotplug/acpiphp_pci.c449
-rw-r--r--drivers/pci/hotplug/acpiphp_res.c700
-rw-r--r--drivers/pci/hotplug/cpci_hotplug.h96
-rw-r--r--drivers/pci/hotplug/cpci_hotplug_core.c792
-rw-r--r--drivers/pci/hotplug/cpci_hotplug_pci.c661
-rw-r--r--drivers/pci/hotplug/cpcihp_generic.c223
-rw-r--r--drivers/pci/hotplug/cpcihp_zt5550.c305
-rw-r--r--drivers/pci/hotplug/cpcihp_zt5550.h79
-rw-r--r--drivers/pci/hotplug/cpqphp.h721
-rw-r--r--drivers/pci/hotplug/cpqphp_core.c1509
-rw-r--r--drivers/pci/hotplug/cpqphp_ctrl.c3096
-rw-r--r--drivers/pci/hotplug/cpqphp_nvram.c666
-rw-r--r--drivers/pci/hotplug/cpqphp_nvram.h57
-rw-r--r--drivers/pci/hotplug/cpqphp_pci.c1569
-rw-r--r--drivers/pci/hotplug/cpqphp_sysfs.c143
-rw-r--r--drivers/pci/hotplug/fakephp.c358
-rw-r--r--drivers/pci/hotplug/ibmphp.h763
-rw-r--r--drivers/pci/hotplug/ibmphp_core.c1422
-rw-r--r--drivers/pci/hotplug/ibmphp_ebda.c1275
-rw-r--r--drivers/pci/hotplug/ibmphp_hpc.c1161
-rw-r--r--drivers/pci/hotplug/ibmphp_pci.c1747
-rw-r--r--drivers/pci/hotplug/ibmphp_res.c2156
-rw-r--r--drivers/pci/hotplug/pci_hotplug.h180
-rw-r--r--drivers/pci/hotplug/pci_hotplug_core.c715
-rw-r--r--drivers/pci/hotplug/pciehp.h352
-rw-r--r--drivers/pci/hotplug/pciehp_core.c662
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c2706
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c1501
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c827
-rw-r--r--drivers/pci/hotplug/pciehprm.h52
-rw-r--r--drivers/pci/hotplug/pciehprm_acpi.c1737
-rw-r--r--drivers/pci/hotplug/pciehprm_nonacpi.c501
-rw-r--r--drivers/pci/hotplug/pciehprm_nonacpi.h56
-rw-r--r--drivers/pci/hotplug/pcihp_skeleton.c375
-rw-r--r--drivers/pci/hotplug/rpadlpar.h24
-rw-r--r--drivers/pci/hotplug/rpadlpar_core.c503
-rw-r--r--drivers/pci/hotplug/rpadlpar_sysfs.c151
-rw-r--r--drivers/pci/hotplug/rpaphp.h138
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c536
-rw-r--r--drivers/pci/hotplug/rpaphp_pci.c538
-rw-r--r--drivers/pci/hotplug/rpaphp_slot.c267
-rw-r--r--drivers/pci/hotplug/rpaphp_vio.c129
-rw-r--r--drivers/pci/hotplug/shpchp.h463
-rw-r--r--drivers/pci/hotplug/shpchp_core.c630
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c2848
-rw-r--r--drivers/pci/hotplug/shpchp_hpc.c1620
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c810
-rw-r--r--drivers/pci/hotplug/shpchp_sysfs.c143
-rw-r--r--drivers/pci/hotplug/shpchprm.h55
-rw-r--r--drivers/pci/hotplug/shpchprm_acpi.c1713
-rw-r--r--drivers/pci/hotplug/shpchprm_legacy.c439
-rw-r--r--drivers/pci/hotplug/shpchprm_legacy.h113
-rw-r--r--drivers/pci/hotplug/shpchprm_nonacpi.c434
-rw-r--r--drivers/pci/hotplug/shpchprm_nonacpi.h56
-rw-r--r--drivers/pci/msi.c1151
-rw-r--r--drivers/pci/msi.h159
-rw-r--r--drivers/pci/names.c137
-rw-r--r--drivers/pci/pci-acpi.c209
-rw-r--r--drivers/pci/pci-driver.c531
-rw-r--r--drivers/pci/pci-sysfs.c490
-rw-r--r--drivers/pci/pci.c837
-rw-r--r--drivers/pci/pci.h96
-rw-r--r--drivers/pci/pci.ids10179
-rw-r--r--drivers/pci/pcie/Kconfig36
-rw-r--r--drivers/pci/pcie/Makefile7
-rw-r--r--drivers/pci/pcie/portdrv.h41
-rw-r--r--drivers/pci/pcie/portdrv_bus.c77
-rw-r--r--drivers/pci/pcie/portdrv_core.c434
-rw-r--r--drivers/pci/pcie/portdrv_pci.c122
-rw-r--r--drivers/pci/probe.c939
-rw-r--r--drivers/pci/proc.c619
-rw-r--r--drivers/pci/quirks.c1352
-rw-r--r--drivers/pci/remove.c118
-rw-r--r--drivers/pci/rom.c227
-rw-r--r--drivers/pci/search.c388
-rw-r--r--drivers/pci/setup-bus.c552
-rw-r--r--drivers/pci/setup-irq.c64
-rw-r--r--drivers/pci/setup-res.c200
-rw-r--r--drivers/pci/syscall.c145
91 files changed, 63799 insertions, 0 deletions
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
new file mode 100644
index 000000000000..7f31991772ea
--- /dev/null
+++ b/drivers/pci/Kconfig
@@ -0,0 +1,59 @@
1#
2# PCI configuration
3#
4config PCI_MSI
5 bool "Message Signaled Interrupts (MSI and MSI-X)"
6 depends on PCI
7 depends on (X86_LOCAL_APIC && X86_IO_APIC) || IA64
8 help
9 This allows device drivers to enable MSI (Message Signaled
10 Interrupts). Message Signaled Interrupts enable a device to
11 generate an interrupt using an inbound Memory Write on its
12 PCI bus instead of asserting a device IRQ pin.
13
14 If you don't know what to do here, say N.
15
16config PCI_LEGACY_PROC
17 bool "Legacy /proc/pci interface"
18 depends on PCI
19 ---help---
20 This feature enables a procfs file -- /proc/pci -- that provides a
21 summary of PCI devices in the system.
22
23 This feature has been deprecated as of v2.5.53, in favor of using the
24 tool lspci(8). This feature may be removed at a future date.
25
26 lspci can provide the same data, as well as much more. lspci is a part of
27 the pci-utils package, which should be installed by your distribution.
28 See <file:Documentation/Changes> for information on where to get the latest
29 version.
30
31 When in doubt, say N.
32
33config PCI_NAMES
34 bool "PCI device name database"
35 depends on PCI
36 ---help---
37 By default, the kernel contains a database of all known PCI device
38 names to make the information in /proc/pci, /proc/ioports and
39 similar files comprehensible to the user.
40
41 This database increases size of the kernel image by about 80KB. This
42 memory is freed after the system boots up if CONFIG_HOTPLUG is not set.
43
44 Anyway, if you are building an installation floppy or kernel for an
45 embedded system where kernel image size really matters, you can disable
46 this feature and you'll get device ID numbers instead of names.
47
48 When in doubt, say Y.
49
50config PCI_DEBUG
51 bool "PCI Debugging"
52 depends on PCI && DEBUG_KERNEL
53 help
54 Say Y here if you want the PCI core to produce a bunch of debug
55 messages to the system log. Select this if you are having a
56 problem with PCI support and want to see more of what is going on.
57
58 When in doubt, say N.
59
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
new file mode 100644
index 000000000000..7dea494c0d7b
--- /dev/null
+++ b/drivers/pci/Makefile
@@ -0,0 +1,65 @@
1#
2# Makefile for the PCI bus specific drivers.
3#
4
5obj-y += access.o bus.o probe.o remove.o pci.o quirks.o \
6 names.o pci-driver.o search.o pci-sysfs.o \
7 rom.o
8obj-$(CONFIG_PROC_FS) += proc.o
9
10ifndef CONFIG_SPARC64
11obj-y += setup-res.o
12endif
13
14obj-$(CONFIG_HOTPLUG) += hotplug.o
15
16# Build the PCI Hotplug drivers if we were asked to
17obj-$(CONFIG_HOTPLUG_PCI) += hotplug/
18
19#
20# Some architectures use the generic PCI setup functions
21#
22obj-$(CONFIG_ALPHA) += setup-bus.o setup-irq.o
23obj-$(CONFIG_ARM) += setup-bus.o setup-irq.o
24obj-$(CONFIG_PARISC) += setup-bus.o
25obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o
26obj-$(CONFIG_PPC32) += setup-irq.o
27obj-$(CONFIG_PPC64) += setup-bus.o
28obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o
29obj-$(CONFIG_X86_VISWS) += setup-irq.o
30obj-$(CONFIG_PCI_MSI) += msi.o
31
32#
33# ACPI Related PCI FW Functions
34#
35obj-$(CONFIG_ACPI) += pci-acpi.o
36
37# Cardbus & CompactPCI use setup-bus
38obj-$(CONFIG_HOTPLUG) += setup-bus.o
39
40ifndef CONFIG_X86
41obj-y += syscall.o
42endif
43
44ifeq ($(CONFIG_PCI_DEBUG),y)
45EXTRA_CFLAGS += -DDEBUG
46endif
47
48hostprogs-y := gen-devlist
49
50# Dependencies on generated files need to be listed explicitly
51$(obj)/names.o: $(obj)/devlist.h $(obj)/classlist.h
52$(obj)/classlist.h: $(obj)/devlist.h
53
54# And that's how to generate them
55quiet_cmd_devlist = DEVLIST $@
56 cmd_devlist = ( cd $(obj); ./gen-devlist ) < $<
57$(obj)/devlist.h: $(src)/pci.ids $(obj)/gen-devlist
58 $(call cmd,devlist)
59
60# Files generated that shall be removed upon make clean
61clean-files := devlist.h classlist.h
62
63# Build PCI Express stuff if needed
64obj-$(CONFIG_PCIEPORTBUS) += pcie/
65
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
new file mode 100644
index 000000000000..24a76de49f41
--- /dev/null
+++ b/drivers/pci/access.c
@@ -0,0 +1,62 @@
1#include <linux/pci.h>
2#include <linux/module.h>
3#include <linux/ioport.h>
4
5/*
6 * This interrupt-safe spinlock protects all accesses to PCI
7 * configuration space.
8 */
9
10static DEFINE_SPINLOCK(pci_lock);
11
12/*
13 * Wrappers for all PCI configuration access functions. They just check
14 * alignment, do locking and call the low-level functions pointed to
15 * by pci_dev->ops.
16 */
17
18#define PCI_byte_BAD 0
19#define PCI_word_BAD (pos & 1)
20#define PCI_dword_BAD (pos & 3)
21
22#define PCI_OP_READ(size,type,len) \
23int pci_bus_read_config_##size \
24 (struct pci_bus *bus, unsigned int devfn, int pos, type *value) \
25{ \
26 int res; \
27 unsigned long flags; \
28 u32 data = 0; \
29 if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
30 spin_lock_irqsave(&pci_lock, flags); \
31 res = bus->ops->read(bus, devfn, pos, len, &data); \
32 *value = (type)data; \
33 spin_unlock_irqrestore(&pci_lock, flags); \
34 return res; \
35}
36
37#define PCI_OP_WRITE(size,type,len) \
38int pci_bus_write_config_##size \
39 (struct pci_bus *bus, unsigned int devfn, int pos, type value) \
40{ \
41 int res; \
42 unsigned long flags; \
43 if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
44 spin_lock_irqsave(&pci_lock, flags); \
45 res = bus->ops->write(bus, devfn, pos, len, value); \
46 spin_unlock_irqrestore(&pci_lock, flags); \
47 return res; \
48}
49
50PCI_OP_READ(byte, u8, 1)
51PCI_OP_READ(word, u16, 2)
52PCI_OP_READ(dword, u32, 4)
53PCI_OP_WRITE(byte, u8, 1)
54PCI_OP_WRITE(word, u16, 2)
55PCI_OP_WRITE(dword, u32, 4)
56
57EXPORT_SYMBOL(pci_bus_read_config_byte);
58EXPORT_SYMBOL(pci_bus_read_config_word);
59EXPORT_SYMBOL(pci_bus_read_config_dword);
60EXPORT_SYMBOL(pci_bus_write_config_byte);
61EXPORT_SYMBOL(pci_bus_write_config_word);
62EXPORT_SYMBOL(pci_bus_write_config_dword);
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
new file mode 100644
index 000000000000..dbd33605cc10
--- /dev/null
+++ b/drivers/pci/bus.c
@@ -0,0 +1,151 @@
1/*
2 * drivers/pci/bus.c
3 *
4 * From setup-res.c, by:
5 * Dave Rusling (david.rusling@reo.mts.dec.com)
6 * David Mosberger (davidm@cs.arizona.edu)
7 * David Miller (davem@redhat.com)
8 * Ivan Kokshaysky (ink@jurassic.park.msu.ru)
9 */
10#include <linux/module.h>
11#include <linux/kernel.h>
12#include <linux/pci.h>
13#include <linux/errno.h>
14#include <linux/ioport.h>
15#include <linux/proc_fs.h>
16#include <linux/init.h>
17
18#include "pci.h"
19
20/**
21 * pci_bus_alloc_resource - allocate a resource from a parent bus
22 * @bus: PCI bus
23 * @res: resource to allocate
24 * @size: size of resource to allocate
25 * @align: alignment of resource to allocate
26 * @min: minimum /proc/iomem address to allocate
27 * @type_mask: IORESOURCE_* type flags
28 * @alignf: resource alignment function
29 * @alignf_data: data argument for resource alignment function
30 *
31 * Given the PCI bus a device resides on, the size, minimum address,
32 * alignment and type, try to find an acceptable resource allocation
33 * for a specific device resource.
34 */
35int
36pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
37 unsigned long size, unsigned long align, unsigned long min,
38 unsigned int type_mask,
39 void (*alignf)(void *, struct resource *,
40 unsigned long, unsigned long),
41 void *alignf_data)
42{
43 int i, ret = -ENOMEM;
44
45 type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
46
47 for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
48 struct resource *r = bus->resource[i];
49 if (!r)
50 continue;
51
52 /* type_mask must match */
53 if ((res->flags ^ r->flags) & type_mask)
54 continue;
55
56 /* We cannot allocate a non-prefetching resource
57 from a pre-fetching area */
58 if ((r->flags & IORESOURCE_PREFETCH) &&
59 !(res->flags & IORESOURCE_PREFETCH))
60 continue;
61
62 /* Ok, try it out.. */
63 ret = allocate_resource(r, res, size, min, -1, align,
64 alignf, alignf_data);
65 if (ret == 0)
66 break;
67 }
68 return ret;
69}
70
71/**
72 * add a single device
73 * @dev: device to add
74 *
75 * This adds a single pci device to the global
76 * device list and adds sysfs and procfs entries
77 */
78void __devinit pci_bus_add_device(struct pci_dev *dev)
79{
80 device_add(&dev->dev);
81
82 spin_lock(&pci_bus_lock);
83 list_add_tail(&dev->global_list, &pci_devices);
84 spin_unlock(&pci_bus_lock);
85
86 pci_proc_attach_device(dev);
87 pci_create_sysfs_dev_files(dev);
88}
89
90/**
91 * pci_bus_add_devices - insert newly discovered PCI devices
92 * @bus: bus to check for new devices
93 *
94 * Add newly discovered PCI devices (which are on the bus->devices
95 * list) to the global PCI device list, add the sysfs and procfs
96 * entries. Where a bridge is found, add the discovered bus to
97 * the parents list of child buses, and recurse (breadth-first
98 * to be compatible with 2.4)
99 *
100 * Call hotplug for each new devices.
101 */
102void __devinit pci_bus_add_devices(struct pci_bus *bus)
103{
104 struct pci_dev *dev;
105
106 list_for_each_entry(dev, &bus->devices, bus_list) {
107 /*
108 * Skip already-present devices (which are on the
109 * global device list.)
110 */
111 if (!list_empty(&dev->global_list))
112 continue;
113 pci_bus_add_device(dev);
114 }
115
116 list_for_each_entry(dev, &bus->devices, bus_list) {
117
118 BUG_ON(list_empty(&dev->global_list));
119
120 /*
121 * If there is an unattached subordinate bus, attach
122 * it and then scan for unattached PCI devices.
123 */
124 if (dev->subordinate && list_empty(&dev->subordinate->node)) {
125 spin_lock(&pci_bus_lock);
126 list_add_tail(&dev->subordinate->node, &dev->bus->children);
127 spin_unlock(&pci_bus_lock);
128 pci_bus_add_devices(dev->subordinate);
129
130 sysfs_create_link(&dev->subordinate->class_dev.kobj, &dev->dev.kobj, "bridge");
131 }
132 }
133}
134
135void pci_enable_bridges(struct pci_bus *bus)
136{
137 struct pci_dev *dev;
138
139 list_for_each_entry(dev, &bus->devices, bus_list) {
140 if (dev->subordinate) {
141 pci_enable_device(dev);
142 pci_set_master(dev);
143 pci_enable_bridges(dev->subordinate);
144 }
145 }
146}
147
148EXPORT_SYMBOL(pci_bus_alloc_resource);
149EXPORT_SYMBOL_GPL(pci_bus_add_device);
150EXPORT_SYMBOL(pci_bus_add_devices);
151EXPORT_SYMBOL(pci_enable_bridges);
diff --git a/drivers/pci/gen-devlist.c b/drivers/pci/gen-devlist.c
new file mode 100644
index 000000000000..8abfc499fdef
--- /dev/null
+++ b/drivers/pci/gen-devlist.c
@@ -0,0 +1,132 @@
1/*
2 * Generate devlist.h and classlist.h from the PCI ID file.
3 *
4 * (c) 1999--2002 Martin Mares <mj@ucw.cz>
5 */
6
7#include <stdio.h>
8#include <string.h>
9
10#define MAX_NAME_SIZE 200
11
12static void
13pq(FILE *f, const char *c, int len)
14{
15 int i = 1;
16 while (*c && i != len) {
17 if (*c == '"')
18 fprintf(f, "\\\"");
19 else {
20 fputc(*c, f);
21 if (*c == '?' && c[1] == '?') {
22 /* Avoid trigraphs */
23 fprintf(f, "\" \"");
24 }
25 }
26 c++;
27 i++;
28 }
29}
30
31int
32main(void)
33{
34 char line[1024], *c, *bra, vend[8];
35 int vendors = 0;
36 int mode = 0;
37 int lino = 0;
38 int vendor_len = 0;
39 FILE *devf, *clsf;
40
41 devf = fopen("devlist.h", "w");
42 clsf = fopen("classlist.h", "w");
43 if (!devf || !clsf) {
44 fprintf(stderr, "Cannot create output file!\n");
45 return 1;
46 }
47
48 while (fgets(line, sizeof(line)-1, stdin)) {
49 lino++;
50 if ((c = strchr(line, '\n')))
51 *c = 0;
52 if (!line[0] || line[0] == '#')
53 continue;
54 if (line[1] == ' ') {
55 if (line[0] == 'C' && strlen(line) > 4 && line[4] == ' ') {
56 vend[0] = line[2];
57 vend[1] = line[3];
58 vend[2] = 0;
59 mode = 2;
60 } else goto err;
61 }
62 else if (line[0] == '\t') {
63 if (line[1] == '\t')
64 continue;
65 switch (mode) {
66 case 1:
67 if (strlen(line) > 5 && line[5] == ' ') {
68 c = line + 5;
69 while (*c == ' ')
70 *c++ = 0;
71 if (vendor_len + strlen(c) + 1 > MAX_NAME_SIZE) {
72 /* Too long, try cutting off long description */
73 bra = strchr(c, '[');
74 if (bra && bra > c && bra[-1] == ' ')
75 bra[-1] = 0;
76 if (vendor_len + strlen(c) + 1 > MAX_NAME_SIZE) {
77 fprintf(stderr, "Line %d: Device name too long. Name truncated.\n", lino);
78 fprintf(stderr, "%s\n", c);
79 /*return 1;*/
80 }
81 }
82 fprintf(devf, "\tDEVICE(%s,%s,\"", vend, line+1);
83 pq(devf, c, MAX_NAME_SIZE - vendor_len - 1);
84 fputs("\")\n", devf);
85 } else goto err;
86 break;
87 case 2:
88 if (strlen(line) > 3 && line[3] == ' ') {
89 c = line + 3;
90 while (*c == ' ')
91 *c++ = 0;
92 fprintf(clsf, "CLASS(%s%s, \"%s\")\n", vend, line+1, c);
93 } else goto err;
94 break;
95 default:
96 goto err;
97 }
98 } else if (strlen(line) > 4 && line[4] == ' ') {
99 c = line + 4;
100 while (*c == ' ')
101 *c++ = 0;
102 if (vendors)
103 fputs("ENDVENDOR()\n\n", devf);
104 vendors++;
105 strcpy(vend, line);
106 vendor_len = strlen(c);
107 if (vendor_len + 24 > MAX_NAME_SIZE) {
108 fprintf(stderr, "Line %d: Vendor name too long\n", lino);
109 return 1;
110 }
111 fprintf(devf, "VENDOR(%s,\"", vend);
112 pq(devf, c, 0);
113 fputs("\")\n", devf);
114 mode = 1;
115 } else {
116 err:
117 fprintf(stderr, "Line %d: Syntax error in mode %d: %s\n", lino, mode, line);
118 return 1;
119 }
120 }
121 fputs("ENDVENDOR()\n\
122\n\
123#undef VENDOR\n\
124#undef DEVICE\n\
125#undef ENDVENDOR\n", devf);
126 fputs("\n#undef CLASS\n", clsf);
127
128 fclose(devf);
129 fclose(clsf);
130
131 return 0;
132}
diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c
new file mode 100644
index 000000000000..d471b3ea5d12
--- /dev/null
+++ b/drivers/pci/hotplug.c
@@ -0,0 +1,163 @@
1#include <linux/kernel.h>
2#include <linux/pci.h>
3#include <linux/module.h>
4#include "pci.h"
5
6int pci_hotplug (struct device *dev, char **envp, int num_envp,
7 char *buffer, int buffer_size)
8{
9 struct pci_dev *pdev;
10 char *scratch;
11 int i = 0;
12 int length = 0;
13
14 if (!dev)
15 return -ENODEV;
16
17 pdev = to_pci_dev(dev);
18 if (!pdev)
19 return -ENODEV;
20
21 scratch = buffer;
22
23 /* stuff we want to pass to /sbin/hotplug */
24 envp[i++] = scratch;
25 length += scnprintf (scratch, buffer_size - length, "PCI_CLASS=%04X",
26 pdev->class);
27 if ((buffer_size - length <= 0) || (i >= num_envp))
28 return -ENOMEM;
29 ++length;
30 scratch += length;
31
32 envp[i++] = scratch;
33 length += scnprintf (scratch, buffer_size - length, "PCI_ID=%04X:%04X",
34 pdev->vendor, pdev->device);
35 if ((buffer_size - length <= 0) || (i >= num_envp))
36 return -ENOMEM;
37 ++length;
38 scratch += length;
39
40 envp[i++] = scratch;
41 length += scnprintf (scratch, buffer_size - length,
42 "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
43 pdev->subsystem_device);
44 if ((buffer_size - length <= 0) || (i >= num_envp))
45 return -ENOMEM;
46 ++length;
47 scratch += length;
48
49 envp[i++] = scratch;
50 length += scnprintf (scratch, buffer_size - length, "PCI_SLOT_NAME=%s",
51 pci_name(pdev));
52 if ((buffer_size - length <= 0) || (i >= num_envp))
53 return -ENOMEM;
54
55 envp[i] = NULL;
56
57 return 0;
58}
59
60static int pci_visit_bus (struct pci_visit * fn, struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_parent)
61{
62 struct list_head *ln;
63 struct pci_dev *dev;
64 struct pci_dev_wrapped wrapped_dev;
65 int result = 0;
66
67 pr_debug("PCI: Scanning bus %04x:%02x\n", pci_domain_nr(wrapped_bus->bus),
68 wrapped_bus->bus->number);
69
70 if (fn->pre_visit_pci_bus) {
71 result = fn->pre_visit_pci_bus(wrapped_bus, wrapped_parent);
72 if (result)
73 return result;
74 }
75
76 ln = wrapped_bus->bus->devices.next;
77 while (ln != &wrapped_bus->bus->devices) {
78 dev = pci_dev_b(ln);
79 ln = ln->next;
80
81 memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
82 wrapped_dev.dev = dev;
83
84 result = pci_visit_dev(fn, &wrapped_dev, wrapped_bus);
85 if (result)
86 return result;
87 }
88
89 if (fn->post_visit_pci_bus)
90 result = fn->post_visit_pci_bus(wrapped_bus, wrapped_parent);
91
92 return result;
93}
94
95static int pci_visit_bridge (struct pci_visit * fn,
96 struct pci_dev_wrapped *wrapped_dev,
97 struct pci_bus_wrapped *wrapped_parent)
98{
99 struct pci_bus *bus;
100 struct pci_bus_wrapped wrapped_bus;
101 int result = 0;
102
103 pr_debug("PCI: Scanning bridge %s\n", pci_name(wrapped_dev->dev));
104
105 if (fn->visit_pci_dev) {
106 result = fn->visit_pci_dev(wrapped_dev, wrapped_parent);
107 if (result)
108 return result;
109 }
110
111 bus = wrapped_dev->dev->subordinate;
112 if (bus) {
113 memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
114 wrapped_bus.bus = bus;
115
116 result = pci_visit_bus(fn, &wrapped_bus, wrapped_dev);
117 }
118 return result;
119}
120
121/**
122 * pci_visit_dev - scans the pci buses.
123 * Every bus and every function is presented to a custom
124 * function that can act upon it.
125 */
126int pci_visit_dev(struct pci_visit *fn, struct pci_dev_wrapped *wrapped_dev,
127 struct pci_bus_wrapped *wrapped_parent)
128{
129 struct pci_dev* dev = wrapped_dev ? wrapped_dev->dev : NULL;
130 int result = 0;
131
132 if (!dev)
133 return 0;
134
135 if (fn->pre_visit_pci_dev) {
136 result = fn->pre_visit_pci_dev(wrapped_dev, wrapped_parent);
137 if (result)
138 return result;
139 }
140
141 switch (dev->class >> 8) {
142 case PCI_CLASS_BRIDGE_PCI:
143 result = pci_visit_bridge(fn, wrapped_dev,
144 wrapped_parent);
145 if (result)
146 return result;
147 break;
148 default:
149 pr_debug("PCI: Scanning device %s\n", pci_name(dev));
150 if (fn->visit_pci_dev) {
151 result = fn->visit_pci_dev (wrapped_dev,
152 wrapped_parent);
153 if (result)
154 return result;
155 }
156 }
157
158 if (fn->post_visit_pci_dev)
159 result = fn->post_visit_pci_dev(wrapped_dev, wrapped_parent);
160
161 return result;
162}
163EXPORT_SYMBOL(pci_visit_dev);
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
new file mode 100644
index 000000000000..1a4d4ca2a4dc
--- /dev/null
+++ b/drivers/pci/hotplug/Kconfig
@@ -0,0 +1,197 @@
1#
2# PCI Hotplug support
3#
4
5menu "PCI Hotplug Support"
6
7config HOTPLUG_PCI
8 tristate "Support for PCI Hotplug (EXPERIMENTAL)"
9 depends on PCI && EXPERIMENTAL
10 select HOTPLUG
11 ---help---
12 Say Y here if you have a motherboard with a PCI Hotplug controller.
13 This allows you to add and remove PCI cards while the machine is
14 powered up and running. The file system pcihpfs must be mounted
15 in order to interact with any PCI Hotplug controllers.
16
17 To compile this driver as a module, choose M here: the
18 module will be called pci_hotplug.
19
20 When in doubt, say N.
21
22config HOTPLUG_PCI_FAKE
23 tristate "Fake PCI Hotplug driver"
24 depends on HOTPLUG_PCI
25 help
26 Say Y here if you want to use the fake PCI hotplug driver. It can
27 be used to simulate PCI hotplug events if even if your system is
28 not PCI hotplug capable.
29
30 This driver will "emulate" removing PCI devices from the system.
31 If the "power" file is written to with "0" then the specified PCI
32 device will be completely removed from the kernel.
33
34 WARNING, this does NOT turn off the power to the PCI device.
35 This is a "logical" removal, not a physical or electrical
36 removal.
37
38 Use this module at your own risk. You have been warned!
39
40 To compile this driver as a module, choose M here: the
41 module will be called fakephp.
42
43 When in doubt, say N.
44
45config HOTPLUG_PCI_COMPAQ
46 tristate "Compaq PCI Hotplug driver"
47 depends on HOTPLUG_PCI && X86 && PCI_BIOS
48 help
49 Say Y here if you have a motherboard with a Compaq PCI Hotplug
50 controller.
51
52 To compile this driver as a module, choose M here: the
53 module will be called cpqphp.
54
55 When in doubt, say N.
56
57config HOTPLUG_PCI_COMPAQ_NVRAM
58 bool "Save configuration into NVRAM on Compaq servers"
59 depends on HOTPLUG_PCI_COMPAQ
60 help
61 Say Y here if you have a Compaq server that has a PCI Hotplug
62 controller. This will allow the PCI Hotplug driver to store the PCI
63 system configuration options in NVRAM.
64
65 When in doubt, say N.
66
67config HOTPLUG_PCI_IBM
68 tristate "IBM PCI Hotplug driver"
69 depends on HOTPLUG_PCI && X86_IO_APIC && X86 && PCI_BIOS
70 help
71 Say Y here if you have a motherboard with a IBM PCI Hotplug
72 controller.
73
74 To compile this driver as a module, choose M here: the
75 module will be called ibmphp.
76
77 When in doubt, say N.
78
79config HOTPLUG_PCI_ACPI
80 tristate "ACPI PCI Hotplug driver"
81 depends on ACPI_BUS && HOTPLUG_PCI
82 help
83 Say Y here if you have a system that supports PCI Hotplug using
84 ACPI.
85
86 To compile this driver as a module, choose M here: the
87 module will be called acpiphp.
88
89 When in doubt, say N.
90
91config HOTPLUG_PCI_ACPI_IBM
92 tristate "ACPI PCI Hotplug driver IBM extensions"
93 depends on HOTPLUG_PCI_ACPI
94 help
95 Say Y here if you have an IBM system that supports PCI Hotplug using
96 ACPI.
97
98 To compile this driver as a module, choose M here: the
99 module will be called acpiphp_ibm.
100
101 When in doubt, say N.
102
103config HOTPLUG_PCI_CPCI
104 bool "CompactPCI Hotplug driver"
105 depends on HOTPLUG_PCI
106 help
107 Say Y here if you have a CompactPCI system card with CompactPCI
108 hotswap support per the PICMG 2.1 specification.
109
110 When in doubt, say N.
111
112config HOTPLUG_PCI_CPCI_ZT5550
113 tristate "Ziatech ZT5550 CompactPCI Hotplug driver"
114 depends on HOTPLUG_PCI && HOTPLUG_PCI_CPCI && X86
115 help
116 Say Y here if you have an Performance Technologies (formerly Intel,
117 formerly just Ziatech) Ziatech ZT5550 CompactPCI system card.
118
119 To compile this driver as a module, choose M here: the
120 module will be called cpcihp_zt5550.
121
122 When in doubt, say N.
123
124config HOTPLUG_PCI_CPCI_GENERIC
125 tristate "Generic port I/O CompactPCI Hotplug driver"
126 depends on HOTPLUG_PCI && HOTPLUG_PCI_CPCI && X86
127 help
128 Say Y here if you have a CompactPCI system card that exposes the #ENUM
129 hotswap signal as a bit in a system register that can be read through
130 standard port I/O.
131
132 To compile this driver as a module, choose M here: the
133 module will be called cpcihp_generic.
134
135 When in doubt, say N.
136
137config HOTPLUG_PCI_SHPC
138 tristate "SHPC PCI Hotplug driver"
139 depends on HOTPLUG_PCI
140 help
141 Say Y here if you have a motherboard with a SHPC PCI Hotplug
142 controller.
143
144 To compile this driver as a module, choose M here: the
145 module will be called shpchp.
146
147 When in doubt, say N.
148
149config HOTPLUG_PCI_SHPC_POLL_EVENT_MODE
150 bool "Use polling mechanism for hot-plug events (for testing purpose)"
151 depends on HOTPLUG_PCI_SHPC
152 help
153 Say Y here if you want to use the polling mechanism for hot-plug
154 events for early platform testing.
155
156 When in doubt, say N.
157
158config HOTPLUG_PCI_SHPC_PHPRM_LEGACY
159 bool "For AMD SHPC only: Use $HRT for resource/configuration"
160 depends on HOTPLUG_PCI_SHPC && !ACPI_BUS
161 help
162 Say Y here for AMD SHPC. You have to select this option if you are
163 using this driver on platform with AMD SHPC.
164
165config HOTPLUG_PCI_RPA
166 tristate "RPA PCI Hotplug driver"
167 depends on HOTPLUG_PCI && PPC_PSERIES && PPC64 && !HOTPLUG_PCI_FAKE
168 help
169 Say Y here if you have a a RPA system that supports PCI Hotplug.
170
171 To compile this driver as a module, choose M here: the
172 module will be called rpaphp.
173
174 When in doubt, say N.
175
176config HOTPLUG_PCI_RPA_DLPAR
177 tristate "RPA Dynamic Logical Partitioning for I/O slots"
178 depends on HOTPLUG_PCI_RPA
179 help
180 Say Y here if your system supports Dynamic Logical Partitioning
181 for I/O slots.
182
183 To compile this driver as a module, choose M here: the
184 module will be called rpadlpar_io.
185
186 When in doubt, say N.
187
188config HOTPLUG_PCI_SGI
189 tristate "SGI PCI Hotplug Support"
190 depends on HOTPLUG_PCI && IA64_SGI_SN2
191 help
192 Say Y here if you have an SGI IA64 Altix system.
193
194 When in doubt, say N.
195
196endmenu
197
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
new file mode 100644
index 000000000000..93c120ddbd39
--- /dev/null
+++ b/drivers/pci/hotplug/Makefile
@@ -0,0 +1,74 @@
1#
2# Makefile for the Linux kernel pci hotplug controller drivers.
3#
4
5obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o
6obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o
7obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o
8obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o
9obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o
10obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o
11obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550) += cpcihp_zt5550.o
12obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC) += cpcihp_generic.o
13obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o
14obj-$(CONFIG_HOTPLUG_PCI_SHPC) += shpchp.o
15obj-$(CONFIG_HOTPLUG_PCI_RPA) += rpaphp.o
16obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o
17
18pci_hotplug-objs := pci_hotplug_core.o
19
20ifdef CONFIG_HOTPLUG_PCI_CPCI
21pci_hotplug-objs += cpci_hotplug_core.o \
22 cpci_hotplug_pci.o
23endif
24
25cpqphp-objs := cpqphp_core.o \
26 cpqphp_ctrl.o \
27 cpqphp_sysfs.o \
28 cpqphp_pci.o
29cpqphp-$(CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM) += cpqphp_nvram.o
30cpqphp-objs += $(cpqphp-y)
31
32ibmphp-objs := ibmphp_core.o \
33 ibmphp_ebda.o \
34 ibmphp_pci.o \
35 ibmphp_res.o \
36 ibmphp_hpc.o
37
38acpiphp-objs := acpiphp_core.o \
39 acpiphp_glue.o \
40 acpiphp_pci.o \
41 acpiphp_res.o
42
43rpaphp-objs := rpaphp_core.o \
44 rpaphp_pci.o \
45 rpaphp_slot.o \
46 rpaphp_vio.o
47
48rpadlpar_io-objs := rpadlpar_core.o \
49 rpadlpar_sysfs.o
50
51pciehp-objs := pciehp_core.o \
52 pciehp_ctrl.o \
53 pciehp_pci.o \
54 pciehp_hpc.o
55ifdef CONFIG_ACPI_BUS
56 pciehp-objs += pciehprm_acpi.o
57else
58 pciehp-objs += pciehprm_nonacpi.o
59endif
60
61shpchp-objs := shpchp_core.o \
62 shpchp_ctrl.o \
63 shpchp_pci.o \
64 shpchp_sysfs.o \
65 shpchp_hpc.o
66ifdef CONFIG_ACPI_BUS
67 shpchp-objs += shpchprm_acpi.o
68else
69 ifdef CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY
70 shpchp-objs += shpchprm_legacy.o
71 else
72 shpchp-objs += shpchprm_nonacpi.o
73 endif
74endif
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
new file mode 100644
index 000000000000..d9499874c8a9
--- /dev/null
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -0,0 +1,268 @@
1/*
2 * ACPI PCI Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
8 * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
9 * Copyright (C) 2002,2003 NEC Corporation
10 *
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or (at
16 * your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
21 * NON INFRINGEMENT. See the GNU General Public License for more
22 * details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 * Send feedback to <gregkh@us.ibm.com>,
29 * <t-kochi@bq.jp.nec.com>
30 *
31 */
32
33#ifndef _ACPIPHP_H
34#define _ACPIPHP_H
35
36#include <linux/acpi.h>
37#include <linux/kobject.h> /* for KOBJ_NAME_LEN */
38#include "pci_hotplug.h"
39
40#define dbg(format, arg...) \
41 do { \
42 if (acpiphp_debug) \
43 printk(KERN_DEBUG "%s: " format, \
44 MY_NAME , ## arg); \
45 } while (0)
46#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
47#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
48#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
49
50/* name size which is used for entries in pcihpfs */
51#define SLOT_NAME_SIZE KOBJ_NAME_LEN /* {_SUN} */
52
53struct acpiphp_bridge;
54struct acpiphp_slot;
55struct pci_resource;
56
57/*
58 * struct slot - slot information for each *physical* slot
59 */
60struct slot {
61 u8 number;
62 struct hotplug_slot *hotplug_slot;
63 struct list_head slot_list;
64
65 struct acpiphp_slot *acpi_slot;
66};
67
68/*
69 * struct pci_resource - describes pci resource (mem, pfmem, io, bus)
70 */
71struct pci_resource {
72 struct pci_resource * next;
73 u64 base;
74 u32 length;
75};
76
77/**
78 * struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters
79 * @cache_line_size in DWORD
80 * @latency_timer in PCI clock
81 * @enable_SERR 0 or 1
82 * @enable_PERR 0 or 1
83 */
84struct hpp_param {
85 u8 cache_line_size;
86 u8 latency_timer;
87 u8 enable_SERR;
88 u8 enable_PERR;
89};
90
91
92/**
93 * struct acpiphp_bridge - PCI bridge information
94 *
95 * for each bridge device in ACPI namespace
96 */
97struct acpiphp_bridge {
98 struct list_head list;
99 acpi_handle handle;
100 struct acpiphp_slot *slots;
101 int type;
102 int nr_slots;
103
104 u8 seg;
105 u8 bus;
106 u8 sub;
107
108 u32 flags;
109
110 /* This bus (host bridge) or Secondary bus (PCI-to-PCI bridge) */
111 struct pci_bus *pci_bus;
112
113 /* PCI-to-PCI bridge device */
114 struct pci_dev *pci_dev;
115
116 /* ACPI 2.0 _HPP parameters */
117 struct hpp_param hpp;
118
119 spinlock_t res_lock;
120
121 /* available resources on this bus */
122 struct pci_resource *mem_head;
123 struct pci_resource *p_mem_head;
124 struct pci_resource *io_head;
125 struct pci_resource *bus_head;
126};
127
128
129/**
130 * struct acpiphp_slot - PCI slot information
131 *
132 * PCI slot information for each *physical* PCI slot
133 */
134struct acpiphp_slot {
135 struct acpiphp_slot *next;
136 struct acpiphp_bridge *bridge; /* parent */
137 struct list_head funcs; /* one slot may have different
138 objects (i.e. for each function) */
139 struct semaphore crit_sect;
140
141 u32 id; /* slot id (serial #) for hotplug core */
142 u8 device; /* pci device# */
143
144 u32 sun; /* ACPI _SUN (slot unique number) */
145 u32 slotno; /* slot number relative to bridge */
146 u32 flags; /* see below */
147};
148
149
150/**
151 * struct acpiphp_func - PCI function information
152 *
153 * PCI function information for each object in ACPI namespace
154 * typically 8 objects per slot (i.e. for each PCI function)
155 */
156struct acpiphp_func {
157 struct acpiphp_slot *slot; /* parent */
158
159 struct list_head sibling;
160 struct pci_dev *pci_dev;
161
162 acpi_handle handle;
163
164 u8 function; /* pci function# */
165 u32 flags; /* see below */
166
167 /* resources used for this function */
168 struct pci_resource *mem_head;
169 struct pci_resource *p_mem_head;
170 struct pci_resource *io_head;
171 struct pci_resource *bus_head;
172};
173
174/**
175 * struct acpiphp_attention_info - device specific attention registration
176 *
177 * ACPI has no generic method of setting/getting attention status
178 * this allows for device specific driver registration
179 */
180struct acpiphp_attention_info
181{
182 int (*set_attn)(struct hotplug_slot *slot, u8 status);
183 int (*get_attn)(struct hotplug_slot *slot, u8 *status);
184 struct module *owner;
185};
186
187/* PCI bus bridge HID */
188#define ACPI_PCI_HOST_HID "PNP0A03"
189
190/* PCI BRIDGE type */
191#define BRIDGE_TYPE_HOST 0
192#define BRIDGE_TYPE_P2P 1
193
194/* ACPI _STA method value (ignore bit 4; battery present) */
195#define ACPI_STA_PRESENT (0x00000001)
196#define ACPI_STA_ENABLED (0x00000002)
197#define ACPI_STA_SHOW_IN_UI (0x00000004)
198#define ACPI_STA_FUNCTIONING (0x00000008)
199#define ACPI_STA_ALL (0x0000000f)
200
201/* bridge flags */
202#define BRIDGE_HAS_STA (0x00000001)
203#define BRIDGE_HAS_EJ0 (0x00000002)
204#define BRIDGE_HAS_HPP (0x00000004)
205#define BRIDGE_HAS_PS0 (0x00000010)
206#define BRIDGE_HAS_PS1 (0x00000020)
207#define BRIDGE_HAS_PS2 (0x00000040)
208#define BRIDGE_HAS_PS3 (0x00000080)
209
210/* slot flags */
211
212#define SLOT_POWEREDON (0x00000001)
213#define SLOT_ENABLED (0x00000002)
214#define SLOT_MULTIFUNCTION (0x00000004)
215
216/* function flags */
217
218#define FUNC_HAS_STA (0x00000001)
219#define FUNC_HAS_EJ0 (0x00000002)
220#define FUNC_HAS_PS0 (0x00000010)
221#define FUNC_HAS_PS1 (0x00000020)
222#define FUNC_HAS_PS2 (0x00000040)
223#define FUNC_HAS_PS3 (0x00000080)
224
225/* function prototypes */
226
227/* acpiphp_core.c */
228extern int acpiphp_register_attention(struct acpiphp_attention_info*info);
229extern int acpiphp_unregister_attention(struct acpiphp_attention_info *info);
230
231/* acpiphp_glue.c */
232extern int acpiphp_glue_init (void);
233extern void acpiphp_glue_exit (void);
234extern int acpiphp_get_num_slots (void);
235extern struct acpiphp_slot *get_slot_from_id (int id);
236typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data);
237
238extern int acpiphp_enable_slot (struct acpiphp_slot *slot);
239extern int acpiphp_disable_slot (struct acpiphp_slot *slot);
240extern u8 acpiphp_get_power_status (struct acpiphp_slot *slot);
241extern u8 acpiphp_get_attention_status (struct acpiphp_slot *slot);
242extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot);
243extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot);
244extern u32 acpiphp_get_address (struct acpiphp_slot *slot);
245
246/* acpiphp_pci.c */
247extern struct pci_dev *acpiphp_allocate_pcidev (struct pci_bus *pbus, int dev, int fn);
248extern int acpiphp_configure_slot (struct acpiphp_slot *slot);
249extern int acpiphp_configure_function (struct acpiphp_func *func);
250extern void acpiphp_unconfigure_function (struct acpiphp_func *func);
251extern int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge);
252extern int acpiphp_init_func_resource (struct acpiphp_func *func);
253
254/* acpiphp_res.c */
255extern struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size);
256extern struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size);
257extern struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size);
258extern int acpiphp_resource_sort_and_combine (struct pci_resource **head);
259extern struct pci_resource *acpiphp_make_resource (u64 base, u32 length);
260extern void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to);
261extern void acpiphp_free_resource (struct pci_resource **res);
262extern void acpiphp_dump_resource (struct acpiphp_bridge *bridge); /* debug */
263extern void acpiphp_dump_func_resource (struct acpiphp_func *func); /* debug */
264
265/* variables */
266extern int acpiphp_debug;
267
268#endif /* _ACPIPHP_H */
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
new file mode 100644
index 000000000000..4539e61a3dc1
--- /dev/null
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -0,0 +1,453 @@
1/*
2 * ACPI PCI Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
8 * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
9 * Copyright (C) 2002,2003 NEC Corporation
10 *
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or (at
16 * your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
21 * NON INFRINGEMENT. See the GNU General Public License for more
22 * details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 * Send feedback to <gregkh@us.ibm.com>,
29 * <t-kochi@bq.jp.nec.com>
30 *
31 */
32
33#include <linux/init.h>
34#include <linux/module.h>
35#include <linux/moduleparam.h>
36
37#include <linux/kernel.h>
38#include <linux/pci.h>
39#include <linux/slab.h>
40#include <linux/smp.h>
41#include <linux/smp_lock.h>
42#include "pci_hotplug.h"
43#include "acpiphp.h"
44
45static LIST_HEAD(slot_list);
46
47#define MY_NAME "acpiphp"
48
49static int debug;
50int acpiphp_debug;
51
52/* local variables */
53static int num_slots;
54static struct acpiphp_attention_info *attention_info;
55
56#define DRIVER_VERSION "0.4"
57#define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kochi@bq.jp.nec.com>"
58#define DRIVER_DESC "ACPI Hot Plug PCI Controller Driver"
59
60MODULE_AUTHOR(DRIVER_AUTHOR);
61MODULE_DESCRIPTION(DRIVER_DESC);
62MODULE_LICENSE("GPL");
63MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
64module_param(debug, bool, 0644);
65
66/* export the attention callback registration methods */
67EXPORT_SYMBOL_GPL(acpiphp_register_attention);
68EXPORT_SYMBOL_GPL(acpiphp_unregister_attention);
69
70static int enable_slot (struct hotplug_slot *slot);
71static int disable_slot (struct hotplug_slot *slot);
72static int set_attention_status (struct hotplug_slot *slot, u8 value);
73static int get_power_status (struct hotplug_slot *slot, u8 *value);
74static int get_attention_status (struct hotplug_slot *slot, u8 *value);
75static int get_address (struct hotplug_slot *slot, u32 *value);
76static int get_latch_status (struct hotplug_slot *slot, u8 *value);
77static int get_adapter_status (struct hotplug_slot *slot, u8 *value);
78
79static struct hotplug_slot_ops acpi_hotplug_slot_ops = {
80 .owner = THIS_MODULE,
81 .enable_slot = enable_slot,
82 .disable_slot = disable_slot,
83 .set_attention_status = set_attention_status,
84 .get_power_status = get_power_status,
85 .get_attention_status = get_attention_status,
86 .get_latch_status = get_latch_status,
87 .get_adapter_status = get_adapter_status,
88 .get_address = get_address,
89};
90
91
92/**
93 * acpiphp_register_attention - set attention LED callback
94 * @info: must be completely filled with LED callbacks
95 *
96 * Description: this is used to register a hardware specific ACPI
97 * driver that manipulates the attention LED. All the fields in
98 * info must be set.
99 **/
100int acpiphp_register_attention(struct acpiphp_attention_info *info)
101{
102 int retval = -EINVAL;
103
104 if (info && info->owner && info->set_attn &&
105 info->get_attn && !attention_info) {
106 retval = 0;
107 attention_info = info;
108 }
109 return retval;
110}
111
112
113/**
114 * acpiphp_unregister_attention - unset attention LED callback
115 * @info: must match the pointer used to register
116 *
117 * Description: this is used to un-register a hardware specific acpi
118 * driver that manipulates the attention LED. The pointer to the
119 * info struct must be the same as the one used to set it.
120 **/
121int acpiphp_unregister_attention(struct acpiphp_attention_info *info)
122{
123 int retval = -EINVAL;
124
125 if (info && attention_info == info) {
126 attention_info = NULL;
127 retval = 0;
128 }
129 return retval;
130}
131
132
133/**
134 * enable_slot - power on and enable a slot
135 * @hotplug_slot: slot to enable
136 *
137 * Actual tasks are done in acpiphp_enable_slot()
138 *
139 */
140static int enable_slot(struct hotplug_slot *hotplug_slot)
141{
142 struct slot *slot = hotplug_slot->private;
143
144 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
145
146 /* enable the specified slot */
147 return acpiphp_enable_slot(slot->acpi_slot);
148}
149
150
151/**
152 * disable_slot - disable and power off a slot
153 * @hotplug_slot: slot to disable
154 *
155 * Actual tasks are done in acpiphp_disable_slot()
156 *
157 */
158static int disable_slot(struct hotplug_slot *hotplug_slot)
159{
160 struct slot *slot = hotplug_slot->private;
161
162 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
163
164 /* disable the specified slot */
165 return acpiphp_disable_slot(slot->acpi_slot);
166}
167
168
169 /**
170 * set_attention_status - set attention LED
171 * @hotplug_slot: slot to set attention LED on
172 * @status: value to set attention LED to (0 or 1)
173 *
174 * attention status LED, so we use a callback that
175 * was registered with us. This allows hardware specific
176 * ACPI implementations to blink the light for us.
177 **/
178 static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
179 {
180 int retval = -ENODEV;
181
182 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
183
184 if (attention_info && try_module_get(attention_info->owner)) {
185 retval = attention_info->set_attn(hotplug_slot, status);
186 module_put(attention_info->owner);
187 } else
188 attention_info = NULL;
189 return retval;
190 }
191
192
193/**
194 * get_power_status - get power status of a slot
195 * @hotplug_slot: slot to get status
196 * @value: pointer to store status
197 *
198 * Some platforms may not implement _STA method properly.
199 * In that case, the value returned may not be reliable.
200 *
201 */
202static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
203{
204 struct slot *slot = hotplug_slot->private;
205
206 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
207
208 *value = acpiphp_get_power_status(slot->acpi_slot);
209
210 return 0;
211}
212
213
214 /**
215 * get_attention_status - get attention LED status
216 * @hotplug_slot: slot to get status from
217 * @value: returns with value of attention LED
218 *
219 * ACPI doesn't have known method to determine the state
220 * of the attention status LED, so we use a callback that
221 * was registered with us. This allows hardware specific
222 * ACPI implementations to determine its state
223 **/
224static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
225{
226 int retval = -EINVAL;
227
228 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
229
230 if (attention_info && try_module_get(attention_info->owner)) {
231 retval = attention_info->get_attn(hotplug_slot, value);
232 module_put(attention_info->owner);
233 } else
234 attention_info = NULL;
235 return retval;
236}
237
238
239/**
240 * get_latch_status - get latch status of a slot
241 * @hotplug_slot: slot to get status
242 * @value: pointer to store status
243 *
244 * ACPI doesn't provide any formal means to access latch status.
245 * Instead, we fake latch status from _STA
246 *
247 */
248static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
249{
250 struct slot *slot = hotplug_slot->private;
251
252 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
253
254 *value = acpiphp_get_latch_status(slot->acpi_slot);
255
256 return 0;
257}
258
259
260/**
261 * get_adapter_status - get adapter status of a slot
262 * @hotplug_slot: slot to get status
263 * @value: pointer to store status
264 *
265 * ACPI doesn't provide any formal means to access adapter status.
266 * Instead, we fake adapter status from _STA
267 *
268 */
269static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
270{
271 struct slot *slot = hotplug_slot->private;
272
273 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
274
275 *value = acpiphp_get_adapter_status(slot->acpi_slot);
276
277 return 0;
278}
279
280
281/**
282 * get_address - get pci address of a slot
283 * @hotplug_slot: slot to get status
284 * @busdev: pointer to struct pci_busdev (seg, bus, dev)
285 *
286 */
287static int get_address(struct hotplug_slot *hotplug_slot, u32 *value)
288{
289 struct slot *slot = hotplug_slot->private;
290
291 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
292
293 *value = acpiphp_get_address(slot->acpi_slot);
294
295 return 0;
296}
297
298static int __init init_acpi(void)
299{
300 int retval;
301
302 /* initialize internal data structure etc. */
303 retval = acpiphp_glue_init();
304
305 /* read initial number of slots */
306 if (!retval) {
307 num_slots = acpiphp_get_num_slots();
308 if (num_slots == 0)
309 retval = -ENODEV;
310 }
311
312 return retval;
313}
314
315
316/**
317 * make_slot_name - make a slot name that appears in pcihpfs
318 * @slot: slot to name
319 *
320 */
321static void make_slot_name(struct slot *slot)
322{
323 snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%u",
324 slot->acpi_slot->sun);
325}
326
327/**
328 * release_slot - free up the memory used by a slot
329 * @hotplug_slot: slot to free
330 */
331static void release_slot(struct hotplug_slot *hotplug_slot)
332{
333 struct slot *slot = hotplug_slot->private;
334
335 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
336
337 kfree(slot->hotplug_slot->info);
338 kfree(slot->hotplug_slot->name);
339 kfree(slot->hotplug_slot);
340 kfree(slot);
341}
342
343/**
344 * init_slots - initialize 'struct slot' structures for each slot
345 *
346 */
347static int __init init_slots(void)
348{
349 struct slot *slot;
350 int retval = -ENOMEM;
351 int i;
352
353 for (i = 0; i < num_slots; ++i) {
354 slot = kmalloc(sizeof(struct slot), GFP_KERNEL);
355 if (!slot)
356 goto error;
357 memset(slot, 0, sizeof(struct slot));
358
359 slot->hotplug_slot = kmalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
360 if (!slot->hotplug_slot)
361 goto error_slot;
362 memset(slot->hotplug_slot, 0, sizeof(struct hotplug_slot));
363
364 slot->hotplug_slot->info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
365 if (!slot->hotplug_slot->info)
366 goto error_hpslot;
367 memset(slot->hotplug_slot->info, 0, sizeof(struct hotplug_slot_info));
368
369 slot->hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
370 if (!slot->hotplug_slot->name)
371 goto error_info;
372
373 slot->number = i;
374
375 slot->hotplug_slot->private = slot;
376 slot->hotplug_slot->release = &release_slot;
377 slot->hotplug_slot->ops = &acpi_hotplug_slot_ops;
378
379 slot->acpi_slot = get_slot_from_id(i);
380 slot->hotplug_slot->info->power_status = acpiphp_get_power_status(slot->acpi_slot);
381 slot->hotplug_slot->info->attention_status = 0;
382 slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot);
383 slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot);
384 slot->hotplug_slot->info->max_bus_speed = PCI_SPEED_UNKNOWN;
385 slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN;
386
387 make_slot_name(slot);
388
389 retval = pci_hp_register(slot->hotplug_slot);
390 if (retval) {
391 err("pci_hp_register failed with error %d\n", retval);
392 goto error_name;
393 }
394
395 /* add slot to our internal list */
396 list_add(&slot->slot_list, &slot_list);
397 info("Slot [%s] registered\n", slot->hotplug_slot->name);
398 }
399
400 return 0;
401error_name:
402 kfree(slot->hotplug_slot->name);
403error_info:
404 kfree(slot->hotplug_slot->info);
405error_hpslot:
406 kfree(slot->hotplug_slot);
407error_slot:
408 kfree(slot);
409error:
410 return retval;
411}
412
413
414static void __exit cleanup_slots (void)
415{
416 struct list_head *tmp, *n;
417 struct slot *slot;
418
419 list_for_each_safe (tmp, n, &slot_list) {
420 /* memory will be freed in release_slot callback */
421 slot = list_entry(tmp, struct slot, slot_list);
422 list_del(&slot->slot_list);
423 pci_hp_deregister(slot->hotplug_slot);
424 }
425}
426
427
428static int __init acpiphp_init(void)
429{
430 int retval;
431
432 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
433
434 acpiphp_debug = debug;
435
436 /* read all the ACPI info from the system */
437 retval = init_acpi();
438 if (retval)
439 return retval;
440
441 return init_slots();
442}
443
444
445static void __exit acpiphp_exit(void)
446{
447 cleanup_slots();
448 /* deallocate internal data structures etc. */
449 acpiphp_glue_exit();
450}
451
452module_init(acpiphp_init);
453module_exit(acpiphp_exit);
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
new file mode 100644
index 000000000000..e7f41294f811
--- /dev/null
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -0,0 +1,1344 @@
1/*
2 * ACPI PCI HotPlug glue functions to ACPI CA subsystem
3 *
4 * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
5 * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
6 * Copyright (C) 2002,2003 NEC Corporation
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <t-kochi@bq.jp.nec.com>
26 *
27 */
28
29#include <linux/init.h>
30#include <linux/module.h>
31
32#include <linux/kernel.h>
33#include <linux/pci.h>
34#include <linux/smp_lock.h>
35#include <asm/semaphore.h>
36
37#include "../pci.h"
38#include "pci_hotplug.h"
39#include "acpiphp.h"
40
41static LIST_HEAD(bridge_list);
42
43#define MY_NAME "acpiphp_glue"
44
45static void handle_hotplug_event_bridge (acpi_handle, u32, void *);
46static void handle_hotplug_event_func (acpi_handle, u32, void *);
47
48/*
49 * initialization & terminatation routines
50 */
51
52/**
53 * is_ejectable - determine if a slot is ejectable
54 * @handle: handle to acpi namespace
55 *
56 * Ejectable slot should satisfy at least these conditions:
57 *
58 * 1. has _ADR method
59 * 2. has _EJ0 method
60 *
61 * optionally
62 *
63 * 1. has _STA method
64 * 2. has _PS0 method
65 * 3. has _PS3 method
66 * 4. ..
67 *
68 */
69static int is_ejectable(acpi_handle handle)
70{
71 acpi_status status;
72 acpi_handle tmp;
73
74 status = acpi_get_handle(handle, "_ADR", &tmp);
75 if (ACPI_FAILURE(status)) {
76 return 0;
77 }
78
79 status = acpi_get_handle(handle, "_EJ0", &tmp);
80 if (ACPI_FAILURE(status)) {
81 return 0;
82 }
83
84 return 1;
85}
86
87
88/* callback routine to check the existence of ejectable slots */
89static acpi_status
90is_ejectable_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
91{
92 int *count = (int *)context;
93
94 if (is_ejectable(handle)) {
95 (*count)++;
96 /* only one ejectable slot is enough */
97 return AE_CTRL_TERMINATE;
98 } else {
99 return AE_OK;
100 }
101}
102
103
104/* callback routine to register each ACPI PCI slot object */
105static acpi_status
106register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
107{
108 struct acpiphp_bridge *bridge = (struct acpiphp_bridge *)context;
109 struct acpiphp_slot *slot;
110 struct acpiphp_func *newfunc;
111 acpi_handle tmp;
112 acpi_status status = AE_OK;
113 unsigned long adr, sun;
114 int device, function;
115 static int num_slots = 0; /* XXX if we support I/O node hotplug... */
116
117 status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
118
119 if (ACPI_FAILURE(status))
120 return AE_OK;
121
122 status = acpi_get_handle(handle, "_EJ0", &tmp);
123
124 if (ACPI_FAILURE(status))
125 return AE_OK;
126
127 device = (adr >> 16) & 0xffff;
128 function = adr & 0xffff;
129
130 newfunc = kmalloc(sizeof(struct acpiphp_func), GFP_KERNEL);
131 if (!newfunc)
132 return AE_NO_MEMORY;
133 memset(newfunc, 0, sizeof(struct acpiphp_func));
134
135 INIT_LIST_HEAD(&newfunc->sibling);
136 newfunc->handle = handle;
137 newfunc->function = function;
138 newfunc->flags = FUNC_HAS_EJ0;
139
140 if (ACPI_SUCCESS(acpi_get_handle(handle, "_STA", &tmp)))
141 newfunc->flags |= FUNC_HAS_STA;
142
143 if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS0", &tmp)))
144 newfunc->flags |= FUNC_HAS_PS0;
145
146 if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &tmp)))
147 newfunc->flags |= FUNC_HAS_PS3;
148
149 status = acpi_evaluate_integer(handle, "_SUN", NULL, &sun);
150 if (ACPI_FAILURE(status))
151 sun = -1;
152
153 /* search for objects that share the same slot */
154 for (slot = bridge->slots; slot; slot = slot->next)
155 if (slot->device == device) {
156 if (slot->sun != sun)
157 warn("sibling found, but _SUN doesn't match!\n");
158 break;
159 }
160
161 if (!slot) {
162 slot = kmalloc(sizeof(struct acpiphp_slot), GFP_KERNEL);
163 if (!slot) {
164 kfree(newfunc);
165 return AE_NO_MEMORY;
166 }
167
168 memset(slot, 0, sizeof(struct acpiphp_slot));
169 slot->bridge = bridge;
170 slot->id = num_slots++;
171 slot->device = device;
172 slot->sun = sun;
173 INIT_LIST_HEAD(&slot->funcs);
174 init_MUTEX(&slot->crit_sect);
175
176 slot->next = bridge->slots;
177 bridge->slots = slot;
178
179 bridge->nr_slots++;
180
181 dbg("found ACPI PCI Hotplug slot at PCI %02x:%02x Slot:%d\n",
182 slot->bridge->bus, slot->device, slot->sun);
183 }
184
185 newfunc->slot = slot;
186 list_add_tail(&newfunc->sibling, &slot->funcs);
187
188 /* associate corresponding pci_dev */
189 newfunc->pci_dev = pci_find_slot(bridge->bus,
190 PCI_DEVFN(device, function));
191 if (newfunc->pci_dev) {
192 if (acpiphp_init_func_resource(newfunc) < 0) {
193 kfree(newfunc);
194 return AE_ERROR;
195 }
196 slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);
197 }
198
199 /* install notify handler */
200 status = acpi_install_notify_handler(handle,
201 ACPI_SYSTEM_NOTIFY,
202 handle_hotplug_event_func,
203 newfunc);
204
205 if (ACPI_FAILURE(status)) {
206 err("failed to register interrupt notify handler\n");
207 return status;
208 }
209
210 return AE_OK;
211}
212
213
214/* see if it's worth looking at this bridge */
215static int detect_ejectable_slots(acpi_handle *bridge_handle)
216{
217 acpi_status status;
218 int count;
219
220 count = 0;
221
222 /* only check slots defined directly below bridge object */
223 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle, (u32)1,
224 is_ejectable_slot, (void *)&count, NULL);
225
226 return count;
227}
228
229
230/* decode ACPI _CRS data and convert into our internal resource list
231 * TBD: _TRA, etc.
232 */
233static acpi_status
234decode_acpi_resource(struct acpi_resource *resource, void *context)
235{
236 struct acpiphp_bridge *bridge = (struct acpiphp_bridge *) context;
237 struct acpi_resource_address64 address;
238 struct pci_resource *res;
239
240 if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
241 resource->id != ACPI_RSTYPE_ADDRESS32 &&
242 resource->id != ACPI_RSTYPE_ADDRESS64)
243 return AE_OK;
244
245 acpi_resource_to_address64(resource, &address);
246
247 if (address.producer_consumer == ACPI_PRODUCER && address.address_length > 0) {
248 dbg("resource type: %d: 0x%llx - 0x%llx\n", address.resource_type,
249 (unsigned long long)address.min_address_range,
250 (unsigned long long)address.max_address_range);
251 res = acpiphp_make_resource(address.min_address_range,
252 address.address_length);
253 if (!res) {
254 err("out of memory\n");
255 return AE_OK;
256 }
257
258 switch (address.resource_type) {
259 case ACPI_MEMORY_RANGE:
260 if (address.attribute.memory.cache_attribute == ACPI_PREFETCHABLE_MEMORY) {
261 res->next = bridge->p_mem_head;
262 bridge->p_mem_head = res;
263 } else {
264 res->next = bridge->mem_head;
265 bridge->mem_head = res;
266 }
267 break;
268 case ACPI_IO_RANGE:
269 res->next = bridge->io_head;
270 bridge->io_head = res;
271 break;
272 case ACPI_BUS_NUMBER_RANGE:
273 res->next = bridge->bus_head;
274 bridge->bus_head = res;
275 break;
276 default:
277 /* invalid type */
278 kfree(res);
279 break;
280 }
281 }
282
283 return AE_OK;
284}
285
286/* decode ACPI 2.0 _HPP hot plug parameters */
287static void decode_hpp(struct acpiphp_bridge *bridge)
288{
289 acpi_status status;
290 struct acpi_buffer buffer = { .length = ACPI_ALLOCATE_BUFFER,
291 .pointer = NULL};
292 union acpi_object *package;
293 int i;
294
295 /* default numbers */
296 bridge->hpp.cache_line_size = 0x10;
297 bridge->hpp.latency_timer = 0x40;
298 bridge->hpp.enable_SERR = 0;
299 bridge->hpp.enable_PERR = 0;
300
301 status = acpi_evaluate_object(bridge->handle, "_HPP", NULL, &buffer);
302
303 if (ACPI_FAILURE(status)) {
304 dbg("_HPP evaluation failed\n");
305 return;
306 }
307
308 package = (union acpi_object *) buffer.pointer;
309
310 if (!package || package->type != ACPI_TYPE_PACKAGE ||
311 package->package.count != 4 || !package->package.elements) {
312 err("invalid _HPP object; ignoring\n");
313 goto err_exit;
314 }
315
316 for (i = 0; i < 4; i++) {
317 if (package->package.elements[i].type != ACPI_TYPE_INTEGER) {
318 err("invalid _HPP parameter type; ignoring\n");
319 goto err_exit;
320 }
321 }
322
323 bridge->hpp.cache_line_size = package->package.elements[0].integer.value;
324 bridge->hpp.latency_timer = package->package.elements[1].integer.value;
325 bridge->hpp.enable_SERR = package->package.elements[2].integer.value;
326 bridge->hpp.enable_PERR = package->package.elements[3].integer.value;
327
328 dbg("_HPP parameter = (%02x, %02x, %02x, %02x)\n",
329 bridge->hpp.cache_line_size,
330 bridge->hpp.latency_timer,
331 bridge->hpp.enable_SERR,
332 bridge->hpp.enable_PERR);
333
334 bridge->flags |= BRIDGE_HAS_HPP;
335
336 err_exit:
337 kfree(buffer.pointer);
338}
339
340
341/* initialize miscellaneous stuff for both root and PCI-to-PCI bridge */
342static void init_bridge_misc(struct acpiphp_bridge *bridge)
343{
344 acpi_status status;
345
346 /* decode ACPI 2.0 _HPP (hot plug parameters) */
347 decode_hpp(bridge);
348
349 /* subtract all resources already allocated */
350 acpiphp_detect_pci_resource(bridge);
351
352 /* register all slot objects under this bridge */
353 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1,
354 register_slot, bridge, NULL);
355
356 /* install notify handler */
357 status = acpi_install_notify_handler(bridge->handle,
358 ACPI_SYSTEM_NOTIFY,
359 handle_hotplug_event_bridge,
360 bridge);
361
362 if (ACPI_FAILURE(status)) {
363 err("failed to register interrupt notify handler\n");
364 }
365
366 list_add(&bridge->list, &bridge_list);
367
368 dbg("Bridge resource:\n");
369 acpiphp_dump_resource(bridge);
370}
371
372
373/* allocate and initialize host bridge data structure */
374static void add_host_bridge(acpi_handle *handle, int seg, int bus)
375{
376 acpi_status status;
377 struct acpiphp_bridge *bridge;
378
379 bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
380 if (bridge == NULL)
381 return;
382
383 memset(bridge, 0, sizeof(struct acpiphp_bridge));
384
385 bridge->type = BRIDGE_TYPE_HOST;
386 bridge->handle = handle;
387 bridge->seg = seg;
388 bridge->bus = bus;
389
390 bridge->pci_bus = pci_find_bus(seg, bus);
391
392 spin_lock_init(&bridge->res_lock);
393
394 /* to be overridden when we decode _CRS */
395 bridge->sub = bridge->bus;
396
397 /* decode resources */
398
399 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
400 decode_acpi_resource, bridge);
401
402 if (ACPI_FAILURE(status)) {
403 err("failed to decode bridge resources\n");
404 kfree(bridge);
405 return;
406 }
407
408 acpiphp_resource_sort_and_combine(&bridge->io_head);
409 acpiphp_resource_sort_and_combine(&bridge->mem_head);
410 acpiphp_resource_sort_and_combine(&bridge->p_mem_head);
411 acpiphp_resource_sort_and_combine(&bridge->bus_head);
412
413 dbg("ACPI _CRS resource:\n");
414 acpiphp_dump_resource(bridge);
415
416 if (bridge->bus_head) {
417 bridge->bus = bridge->bus_head->base;
418 bridge->sub = bridge->bus_head->base + bridge->bus_head->length - 1;
419 }
420
421 init_bridge_misc(bridge);
422}
423
424
425/* allocate and initialize PCI-to-PCI bridge data structure */
426static void add_p2p_bridge(acpi_handle *handle, int seg, int bus, int dev, int fn)
427{
428 struct acpiphp_bridge *bridge;
429 u8 tmp8;
430 u16 tmp16;
431 u64 base64, limit64;
432 u32 base, limit, base32u, limit32u;
433
434 bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
435 if (bridge == NULL) {
436 err("out of memory\n");
437 return;
438 }
439
440 memset(bridge, 0, sizeof(struct acpiphp_bridge));
441
442 bridge->type = BRIDGE_TYPE_P2P;
443 bridge->handle = handle;
444 bridge->seg = seg;
445
446 bridge->pci_dev = pci_find_slot(bus, PCI_DEVFN(dev, fn));
447 if (!bridge->pci_dev) {
448 err("Can't get pci_dev\n");
449 kfree(bridge);
450 return;
451 }
452
453 bridge->pci_bus = bridge->pci_dev->subordinate;
454 if (!bridge->pci_bus) {
455 err("This is not a PCI-to-PCI bridge!\n");
456 kfree(bridge);
457 return;
458 }
459
460 spin_lock_init(&bridge->res_lock);
461
462 bridge->bus = bridge->pci_bus->number;
463 bridge->sub = bridge->pci_bus->subordinate;
464
465 /*
466 * decode resources under this P2P bridge
467 */
468
469 /* I/O resources */
470 pci_read_config_byte(bridge->pci_dev, PCI_IO_BASE, &tmp8);
471 base = tmp8;
472 pci_read_config_byte(bridge->pci_dev, PCI_IO_LIMIT, &tmp8);
473 limit = tmp8;
474
475 switch (base & PCI_IO_RANGE_TYPE_MASK) {
476 case PCI_IO_RANGE_TYPE_16:
477 base = (base << 8) & 0xf000;
478 limit = ((limit << 8) & 0xf000) + 0xfff;
479 bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
480 if (!bridge->io_head) {
481 err("out of memory\n");
482 kfree(bridge);
483 return;
484 }
485 dbg("16bit I/O range: %04x-%04x\n",
486 (u32)bridge->io_head->base,
487 (u32)(bridge->io_head->base + bridge->io_head->length - 1));
488 break;
489 case PCI_IO_RANGE_TYPE_32:
490 pci_read_config_word(bridge->pci_dev, PCI_IO_BASE_UPPER16, &tmp16);
491 base = ((u32)tmp16 << 16) | ((base << 8) & 0xf000);
492 pci_read_config_word(bridge->pci_dev, PCI_IO_LIMIT_UPPER16, &tmp16);
493 limit = (((u32)tmp16 << 16) | ((limit << 8) & 0xf000)) + 0xfff;
494 bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
495 if (!bridge->io_head) {
496 err("out of memory\n");
497 kfree(bridge);
498 return;
499 }
500 dbg("32bit I/O range: %08x-%08x\n",
501 (u32)bridge->io_head->base,
502 (u32)(bridge->io_head->base + bridge->io_head->length - 1));
503 break;
504 case 0x0f:
505 dbg("I/O space unsupported\n");
506 break;
507 default:
508 warn("Unknown I/O range type\n");
509 }
510
511 /* Memory resources (mandatory for P2P bridge) */
512 pci_read_config_word(bridge->pci_dev, PCI_MEMORY_BASE, &tmp16);
513 base = (tmp16 & 0xfff0) << 16;
514 pci_read_config_word(bridge->pci_dev, PCI_MEMORY_LIMIT, &tmp16);
515 limit = ((tmp16 & 0xfff0) << 16) | 0xfffff;
516 bridge->mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
517 if (!bridge->mem_head) {
518 err("out of memory\n");
519 kfree(bridge);
520 return;
521 }
522 dbg("32bit Memory range: %08x-%08x\n",
523 (u32)bridge->mem_head->base,
524 (u32)(bridge->mem_head->base + bridge->mem_head->length-1));
525
526 /* Prefetchable Memory resources (optional) */
527 pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_BASE, &tmp16);
528 base = tmp16;
529 pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_LIMIT, &tmp16);
530 limit = tmp16;
531
532 switch (base & PCI_MEMORY_RANGE_TYPE_MASK) {
533 case PCI_PREF_RANGE_TYPE_32:
534 base = (base & 0xfff0) << 16;
535 limit = ((limit & 0xfff0) << 16) | 0xfffff;
536 bridge->p_mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
537 if (!bridge->p_mem_head) {
538 err("out of memory\n");
539 kfree(bridge);
540 return;
541 }
542 dbg("32bit Prefetchable memory range: %08x-%08x\n",
543 (u32)bridge->p_mem_head->base,
544 (u32)(bridge->p_mem_head->base + bridge->p_mem_head->length - 1));
545 break;
546 case PCI_PREF_RANGE_TYPE_64:
547 pci_read_config_dword(bridge->pci_dev, PCI_PREF_BASE_UPPER32, &base32u);
548 pci_read_config_dword(bridge->pci_dev, PCI_PREF_LIMIT_UPPER32, &limit32u);
549 base64 = ((u64)base32u << 32) | ((base & 0xfff0) << 16);
550 limit64 = (((u64)limit32u << 32) | ((limit & 0xfff0) << 16)) + 0xfffff;
551
552 bridge->p_mem_head = acpiphp_make_resource(base64, limit64 - base64 + 1);
553 if (!bridge->p_mem_head) {
554 err("out of memory\n");
555 kfree(bridge);
556 return;
557 }
558 dbg("64bit Prefetchable memory range: %08x%08x-%08x%08x\n",
559 (u32)(bridge->p_mem_head->base >> 32),
560 (u32)(bridge->p_mem_head->base & 0xffffffff),
561 (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) >> 32),
562 (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) & 0xffffffff));
563 break;
564 case 0x0f:
565 break;
566 default:
567 warn("Unknown prefetchale memory type\n");
568 }
569
570 init_bridge_misc(bridge);
571}
572
573
574/* callback routine to find P2P bridges */
575static acpi_status
576find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
577{
578 acpi_status status;
579 acpi_handle dummy_handle;
580 unsigned long *segbus = context;
581 unsigned long tmp;
582 int seg, bus, device, function;
583 struct pci_dev *dev;
584
585 /* get PCI address */
586 seg = (*segbus >> 8) & 0xff;
587 bus = *segbus & 0xff;
588
589 status = acpi_get_handle(handle, "_ADR", &dummy_handle);
590 if (ACPI_FAILURE(status))
591 return AE_OK; /* continue */
592
593 status = acpi_evaluate_integer(handle, "_ADR", NULL, &tmp);
594 if (ACPI_FAILURE(status)) {
595 dbg("%s: _ADR evaluation failure\n", __FUNCTION__);
596 return AE_OK;
597 }
598
599 device = (tmp >> 16) & 0xffff;
600 function = tmp & 0xffff;
601
602 dev = pci_find_slot(bus, PCI_DEVFN(device, function));
603
604 if (!dev)
605 return AE_OK;
606
607 if (!dev->subordinate)
608 return AE_OK;
609
610 /* check if this bridge has ejectable slots */
611 if (detect_ejectable_slots(handle) > 0) {
612 dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev));
613 add_p2p_bridge(handle, seg, bus, device, function);
614 }
615
616 return AE_OK;
617}
618
619
620/* find hot-pluggable slots, and then find P2P bridge */
621static int add_bridge(acpi_handle handle)
622{
623 acpi_status status;
624 unsigned long tmp;
625 int seg, bus;
626 acpi_handle dummy_handle;
627
628 /* if the bridge doesn't have _STA, we assume it is always there */
629 status = acpi_get_handle(handle, "_STA", &dummy_handle);
630 if (ACPI_SUCCESS(status)) {
631 status = acpi_evaluate_integer(handle, "_STA", NULL, &tmp);
632 if (ACPI_FAILURE(status)) {
633 dbg("%s: _STA evaluation failure\n", __FUNCTION__);
634 return 0;
635 }
636 if ((tmp & ACPI_STA_FUNCTIONING) == 0)
637 /* don't register this object */
638 return 0;
639 }
640
641 /* get PCI segment number */
642 status = acpi_evaluate_integer(handle, "_SEG", NULL, &tmp);
643
644 seg = ACPI_SUCCESS(status) ? tmp : 0;
645
646 /* get PCI bus number */
647 status = acpi_evaluate_integer(handle, "_BBN", NULL, &tmp);
648
649 if (ACPI_SUCCESS(status)) {
650 bus = tmp;
651 } else {
652 warn("can't get bus number, assuming 0\n");
653 bus = 0;
654 }
655
656 /* check if this bridge has ejectable slots */
657 if (detect_ejectable_slots(handle) > 0) {
658 dbg("found PCI host-bus bridge with hot-pluggable slots\n");
659 add_host_bridge(handle, seg, bus);
660 return 0;
661 }
662
663 tmp = seg << 8 | bus;
664
665 /* search P2P bridges under this host bridge */
666 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
667 find_p2p_bridge, &tmp, NULL);
668
669 if (ACPI_FAILURE(status))
670 warn("find_p2p_bridge faied (error code = 0x%x)\n",status);
671
672 return 0;
673}
674
675
676static void remove_bridge(acpi_handle handle)
677{
678 /* No-op for now .. */
679}
680
681
682static int power_on_slot(struct acpiphp_slot *slot)
683{
684 acpi_status status;
685 struct acpiphp_func *func;
686 struct list_head *l;
687 int retval = 0;
688
689 /* if already enabled, just skip */
690 if (slot->flags & SLOT_POWEREDON)
691 goto err_exit;
692
693 list_for_each (l, &slot->funcs) {
694 func = list_entry(l, struct acpiphp_func, sibling);
695
696 if (func->flags & FUNC_HAS_PS0) {
697 dbg("%s: executing _PS0\n", __FUNCTION__);
698 status = acpi_evaluate_object(func->handle, "_PS0", NULL, NULL);
699 if (ACPI_FAILURE(status)) {
700 warn("%s: _PS0 failed\n", __FUNCTION__);
701 retval = -1;
702 goto err_exit;
703 } else
704 break;
705 }
706 }
707
708 /* TBD: evaluate _STA to check if the slot is enabled */
709
710 slot->flags |= SLOT_POWEREDON;
711
712 err_exit:
713 return retval;
714}
715
716
717static int power_off_slot(struct acpiphp_slot *slot)
718{
719 acpi_status status;
720 struct acpiphp_func *func;
721 struct list_head *l;
722 struct acpi_object_list arg_list;
723 union acpi_object arg;
724
725 int retval = 0;
726
727 /* if already disabled, just skip */
728 if ((slot->flags & SLOT_POWEREDON) == 0)
729 goto err_exit;
730
731 list_for_each (l, &slot->funcs) {
732 func = list_entry(l, struct acpiphp_func, sibling);
733
734 if (func->pci_dev && (func->flags & FUNC_HAS_PS3)) {
735 status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL);
736 if (ACPI_FAILURE(status)) {
737 warn("%s: _PS3 failed\n", __FUNCTION__);
738 retval = -1;
739 goto err_exit;
740 } else
741 break;
742 }
743 }
744
745 list_for_each (l, &slot->funcs) {
746 func = list_entry(l, struct acpiphp_func, sibling);
747
748 /* We don't want to call _EJ0 on non-existing functions. */
749 if (func->pci_dev && (func->flags & FUNC_HAS_EJ0)) {
750 /* _EJ0 method take one argument */
751 arg_list.count = 1;
752 arg_list.pointer = &arg;
753 arg.type = ACPI_TYPE_INTEGER;
754 arg.integer.value = 1;
755
756 status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL);
757 if (ACPI_FAILURE(status)) {
758 warn("%s: _EJ0 failed\n", __FUNCTION__);
759 retval = -1;
760 goto err_exit;
761 } else
762 break;
763 }
764 }
765
766 /* TBD: evaluate _STA to check if the slot is disabled */
767
768 slot->flags &= (~SLOT_POWEREDON);
769
770 err_exit:
771 return retval;
772}
773
774
775/**
776 * enable_device - enable, configure a slot
777 * @slot: slot to be enabled
778 *
779 * This function should be called per *physical slot*,
780 * not per each slot object in ACPI namespace.
781 *
782 */
783static int enable_device(struct acpiphp_slot *slot)
784{
785 u8 bus;
786 struct pci_dev *dev;
787 struct pci_bus *child;
788 struct list_head *l;
789 struct acpiphp_func *func;
790 int retval = 0;
791 int num;
792
793 if (slot->flags & SLOT_ENABLED)
794 goto err_exit;
795
796 /* sanity check: dev should be NULL when hot-plugged in */
797 dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));
798 if (dev) {
799 /* This case shouldn't happen */
800 err("pci_dev structure already exists.\n");
801 retval = -1;
802 goto err_exit;
803 }
804
805 /* allocate resources to device */
806 retval = acpiphp_configure_slot(slot);
807 if (retval)
808 goto err_exit;
809
810 /* returned `dev' is the *first function* only! */
811 num = pci_scan_slot(slot->bridge->pci_bus, PCI_DEVFN(slot->device, 0));
812 if (num)
813 pci_bus_add_devices(slot->bridge->pci_bus);
814 dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));
815
816 if (!dev) {
817 err("No new device found\n");
818 retval = -1;
819 goto err_exit;
820 }
821
822 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
823 pci_read_config_byte(dev, PCI_SECONDARY_BUS, &bus);
824 child = (struct pci_bus*) pci_add_new_bus(dev->bus, dev, bus);
825 pci_do_scan_bus(child);
826 }
827
828 /* associate pci_dev to our representation */
829 list_for_each (l, &slot->funcs) {
830 func = list_entry(l, struct acpiphp_func, sibling);
831
832 func->pci_dev = pci_find_slot(slot->bridge->bus,
833 PCI_DEVFN(slot->device,
834 func->function));
835 if (!func->pci_dev)
836 continue;
837
838 /* configure device */
839 retval = acpiphp_configure_function(func);
840 if (retval)
841 goto err_exit;
842 }
843
844 slot->flags |= SLOT_ENABLED;
845
846 dbg("Available resources:\n");
847 acpiphp_dump_resource(slot->bridge);
848
849 err_exit:
850 return retval;
851}
852
853
854/**
855 * disable_device - disable a slot
856 */
857static int disable_device(struct acpiphp_slot *slot)
858{
859 int retval = 0;
860 struct acpiphp_func *func;
861 struct list_head *l;
862
863 /* is this slot already disabled? */
864 if (!(slot->flags & SLOT_ENABLED))
865 goto err_exit;
866
867 list_for_each (l, &slot->funcs) {
868 func = list_entry(l, struct acpiphp_func, sibling);
869
870 if (func->pci_dev)
871 acpiphp_unconfigure_function(func);
872 }
873
874 slot->flags &= (~SLOT_ENABLED);
875
876 err_exit:
877 return retval;
878}
879
880
881/**
882 * get_slot_status - get ACPI slot status
883 *
884 * if a slot has _STA for each function and if any one of them
885 * returned non-zero status, return it
886 *
887 * if a slot doesn't have _STA and if any one of its functions'
888 * configuration space is configured, return 0x0f as a _STA
889 *
890 * otherwise return 0
891 */
892static unsigned int get_slot_status(struct acpiphp_slot *slot)
893{
894 acpi_status status;
895 unsigned long sta = 0;
896 u32 dvid;
897 struct list_head *l;
898 struct acpiphp_func *func;
899
900 list_for_each (l, &slot->funcs) {
901 func = list_entry(l, struct acpiphp_func, sibling);
902
903 if (func->flags & FUNC_HAS_STA) {
904 status = acpi_evaluate_integer(func->handle, "_STA", NULL, &sta);
905 if (ACPI_SUCCESS(status) && sta)
906 break;
907 } else {
908 pci_bus_read_config_dword(slot->bridge->pci_bus,
909 PCI_DEVFN(slot->device,
910 func->function),
911 PCI_VENDOR_ID, &dvid);
912 if (dvid != 0xffffffff) {
913 sta = ACPI_STA_ALL;
914 break;
915 }
916 }
917 }
918
919 return (unsigned int)sta;
920}
921
922/**
923 * acpiphp_check_bridge - re-enumerate devices
924 *
925 * Iterate over all slots under this bridge and make sure that if a
926 * card is present they are enabled, and if not they are disabled.
927 */
928static int acpiphp_check_bridge(struct acpiphp_bridge *bridge)
929{
930 struct acpiphp_slot *slot;
931 int retval = 0;
932 int enabled, disabled;
933
934 enabled = disabled = 0;
935
936 for (slot = bridge->slots; slot; slot = slot->next) {
937 unsigned int status = get_slot_status(slot);
938 if (slot->flags & SLOT_ENABLED) {
939 if (status == ACPI_STA_ALL)
940 continue;
941 retval = acpiphp_disable_slot(slot);
942 if (retval) {
943 err("Error occurred in disabling\n");
944 goto err_exit;
945 }
946 disabled++;
947 } else {
948 if (status != ACPI_STA_ALL)
949 continue;
950 retval = acpiphp_enable_slot(slot);
951 if (retval) {
952 err("Error occurred in enabling\n");
953 goto err_exit;
954 }
955 enabled++;
956 }
957 }
958
959 dbg("%s: %d enabled, %d disabled\n", __FUNCTION__, enabled, disabled);
960
961 err_exit:
962 return retval;
963}
964
965/*
966 * ACPI event handlers
967 */
968
969/**
970 * handle_hotplug_event_bridge - handle ACPI event on bridges
971 *
972 * @handle: Notify()'ed acpi_handle
973 * @type: Notify code
974 * @context: pointer to acpiphp_bridge structure
975 *
976 * handles ACPI event notification on {host,p2p} bridges
977 *
978 */
979static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *context)
980{
981 struct acpiphp_bridge *bridge;
982 char objname[64];
983 struct acpi_buffer buffer = { .length = sizeof(objname),
984 .pointer = objname };
985
986 bridge = (struct acpiphp_bridge *)context;
987
988 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
989
990 switch (type) {
991 case ACPI_NOTIFY_BUS_CHECK:
992 /* bus re-enumerate */
993 dbg("%s: Bus check notify on %s\n", __FUNCTION__, objname);
994 acpiphp_check_bridge(bridge);
995 break;
996
997 case ACPI_NOTIFY_DEVICE_CHECK:
998 /* device check */
999 dbg("%s: Device check notify on %s\n", __FUNCTION__, objname);
1000 acpiphp_check_bridge(bridge);
1001 break;
1002
1003 case ACPI_NOTIFY_DEVICE_WAKE:
1004 /* wake event */
1005 dbg("%s: Device wake notify on %s\n", __FUNCTION__, objname);
1006 break;
1007
1008 case ACPI_NOTIFY_EJECT_REQUEST:
1009 /* request device eject */
1010 dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname);
1011 break;
1012
1013 case ACPI_NOTIFY_FREQUENCY_MISMATCH:
1014 printk(KERN_ERR "Device %s cannot be configured due"
1015 " to a frequency mismatch\n", objname);
1016 break;
1017
1018 case ACPI_NOTIFY_BUS_MODE_MISMATCH:
1019 printk(KERN_ERR "Device %s cannot be configured due"
1020 " to a bus mode mismatch\n", objname);
1021 break;
1022
1023 case ACPI_NOTIFY_POWER_FAULT:
1024 printk(KERN_ERR "Device %s has suffered a power fault\n",
1025 objname);
1026 break;
1027
1028 default:
1029 warn("notify_handler: unknown event type 0x%x for %s\n", type, objname);
1030 break;
1031 }
1032}
1033
1034
1035/**
1036 * handle_hotplug_event_func - handle ACPI event on functions (i.e. slots)
1037 *
1038 * @handle: Notify()'ed acpi_handle
1039 * @type: Notify code
1040 * @context: pointer to acpiphp_func structure
1041 *
1042 * handles ACPI event notification on slots
1043 *
1044 */
1045static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context)
1046{
1047 struct acpiphp_func *func;
1048 char objname[64];
1049 struct acpi_buffer buffer = { .length = sizeof(objname),
1050 .pointer = objname };
1051
1052 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
1053
1054 func = (struct acpiphp_func *)context;
1055
1056 switch (type) {
1057 case ACPI_NOTIFY_BUS_CHECK:
1058 /* bus re-enumerate */
1059 dbg("%s: Bus check notify on %s\n", __FUNCTION__, objname);
1060 acpiphp_enable_slot(func->slot);
1061 break;
1062
1063 case ACPI_NOTIFY_DEVICE_CHECK:
1064 /* device check : re-enumerate from parent bus */
1065 dbg("%s: Device check notify on %s\n", __FUNCTION__, objname);
1066 acpiphp_check_bridge(func->slot->bridge);
1067 break;
1068
1069 case ACPI_NOTIFY_DEVICE_WAKE:
1070 /* wake event */
1071 dbg("%s: Device wake notify on %s\n", __FUNCTION__, objname);
1072 break;
1073
1074 case ACPI_NOTIFY_EJECT_REQUEST:
1075 /* request device eject */
1076 dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname);
1077 acpiphp_disable_slot(func->slot);
1078 break;
1079
1080 default:
1081 warn("notify_handler: unknown event type 0x%x for %s\n", type, objname);
1082 break;
1083 }
1084}
1085
1086
1087static struct acpi_pci_driver acpi_pci_hp_driver = {
1088 .add = add_bridge,
1089 .remove = remove_bridge,
1090};
1091
1092/**
1093 * acpiphp_glue_init - initializes all PCI hotplug - ACPI glue data structures
1094 *
1095 */
1096int __init acpiphp_glue_init(void)
1097{
1098 int num;
1099
1100 if (list_empty(&pci_root_buses))
1101 return -1;
1102
1103 num = acpi_pci_register_driver(&acpi_pci_hp_driver);
1104
1105 if (num <= 0)
1106 return -1;
1107
1108 return 0;
1109}
1110
1111
1112/**
1113 * acpiphp_glue_exit - terminates all PCI hotplug - ACPI glue data structures
1114 *
1115 * This function frees all data allocated in acpiphp_glue_init()
1116 */
1117void __exit acpiphp_glue_exit(void)
1118{
1119 struct list_head *l1, *l2, *n1, *n2;
1120 struct acpiphp_bridge *bridge;
1121 struct acpiphp_slot *slot, *next;
1122 struct acpiphp_func *func;
1123 acpi_status status;
1124
1125 list_for_each_safe (l1, n1, &bridge_list) {
1126 bridge = (struct acpiphp_bridge *)l1;
1127 slot = bridge->slots;
1128 while (slot) {
1129 next = slot->next;
1130 list_for_each_safe (l2, n2, &slot->funcs) {
1131 func = list_entry(l2, struct acpiphp_func, sibling);
1132 acpiphp_free_resource(&func->io_head);
1133 acpiphp_free_resource(&func->mem_head);
1134 acpiphp_free_resource(&func->p_mem_head);
1135 acpiphp_free_resource(&func->bus_head);
1136 status = acpi_remove_notify_handler(func->handle,
1137 ACPI_SYSTEM_NOTIFY,
1138 handle_hotplug_event_func);
1139 if (ACPI_FAILURE(status))
1140 err("failed to remove notify handler\n");
1141 kfree(func);
1142 }
1143 kfree(slot);
1144 slot = next;
1145 }
1146 status = acpi_remove_notify_handler(bridge->handle, ACPI_SYSTEM_NOTIFY,
1147 handle_hotplug_event_bridge);
1148 if (ACPI_FAILURE(status))
1149 err("failed to remove notify handler\n");
1150
1151 acpiphp_free_resource(&bridge->io_head);
1152 acpiphp_free_resource(&bridge->mem_head);
1153 acpiphp_free_resource(&bridge->p_mem_head);
1154 acpiphp_free_resource(&bridge->bus_head);
1155
1156 kfree(bridge);
1157 }
1158
1159 acpi_pci_unregister_driver(&acpi_pci_hp_driver);
1160}
1161
1162
1163/**
1164 * acpiphp_get_num_slots - count number of slots in a system
1165 */
1166int __init acpiphp_get_num_slots(void)
1167{
1168 struct list_head *node;
1169 struct acpiphp_bridge *bridge;
1170 int num_slots;
1171
1172 num_slots = 0;
1173
1174 list_for_each (node, &bridge_list) {
1175 bridge = (struct acpiphp_bridge *)node;
1176 dbg("Bus%d %dslot(s)\n", bridge->bus, bridge->nr_slots);
1177 num_slots += bridge->nr_slots;
1178 }
1179
1180 dbg("Total %dslots\n", num_slots);
1181 return num_slots;
1182}
1183
1184
1185#if 0
1186/**
1187 * acpiphp_for_each_slot - call function for each slot
1188 * @fn: callback function
1189 * @data: context to be passed to callback function
1190 *
1191 */
1192static int acpiphp_for_each_slot(acpiphp_callback fn, void *data)
1193{
1194 struct list_head *node;
1195 struct acpiphp_bridge *bridge;
1196 struct acpiphp_slot *slot;
1197 int retval = 0;
1198
1199 list_for_each (node, &bridge_list) {
1200 bridge = (struct acpiphp_bridge *)node;
1201 for (slot = bridge->slots; slot; slot = slot->next) {
1202 retval = fn(slot, data);
1203 if (!retval)
1204 goto err_exit;
1205 }
1206 }
1207
1208 err_exit:
1209 return retval;
1210}
1211#endif
1212
1213/* search matching slot from id */
1214struct acpiphp_slot *get_slot_from_id(int id)
1215{
1216 struct list_head *node;
1217 struct acpiphp_bridge *bridge;
1218 struct acpiphp_slot *slot;
1219
1220 list_for_each (node, &bridge_list) {
1221 bridge = (struct acpiphp_bridge *)node;
1222 for (slot = bridge->slots; slot; slot = slot->next)
1223 if (slot->id == id)
1224 return slot;
1225 }
1226
1227 /* should never happen! */
1228 err("%s: no object for id %d\n", __FUNCTION__, id);
1229 WARN_ON(1);
1230 return NULL;
1231}
1232
1233
1234/**
1235 * acpiphp_enable_slot - power on slot
1236 */
1237int acpiphp_enable_slot(struct acpiphp_slot *slot)
1238{
1239 int retval;
1240
1241 down(&slot->crit_sect);
1242
1243 /* wake up all functions */
1244 retval = power_on_slot(slot);
1245 if (retval)
1246 goto err_exit;
1247
1248 if (get_slot_status(slot) == ACPI_STA_ALL)
1249 /* configure all functions */
1250 retval = enable_device(slot);
1251
1252 err_exit:
1253 up(&slot->crit_sect);
1254 return retval;
1255}
1256
1257
1258/**
1259 * acpiphp_disable_slot - power off slot
1260 */
1261int acpiphp_disable_slot(struct acpiphp_slot *slot)
1262{
1263 int retval = 0;
1264
1265 down(&slot->crit_sect);
1266
1267 /* unconfigure all functions */
1268 retval = disable_device(slot);
1269 if (retval)
1270 goto err_exit;
1271
1272 /* power off all functions */
1273 retval = power_off_slot(slot);
1274 if (retval)
1275 goto err_exit;
1276
1277 acpiphp_resource_sort_and_combine(&slot->bridge->io_head);
1278 acpiphp_resource_sort_and_combine(&slot->bridge->mem_head);
1279 acpiphp_resource_sort_and_combine(&slot->bridge->p_mem_head);
1280 acpiphp_resource_sort_and_combine(&slot->bridge->bus_head);
1281 dbg("Available resources:\n");
1282 acpiphp_dump_resource(slot->bridge);
1283
1284 err_exit:
1285 up(&slot->crit_sect);
1286 return retval;
1287}
1288
1289
1290/*
1291 * slot enabled: 1
1292 * slot disabled: 0
1293 */
1294u8 acpiphp_get_power_status(struct acpiphp_slot *slot)
1295{
1296 unsigned int sta;
1297
1298 sta = get_slot_status(slot);
1299
1300 return (sta & ACPI_STA_ENABLED) ? 1 : 0;
1301}
1302
1303
1304/*
1305 * latch closed: 1
1306 * latch open: 0
1307 */
1308u8 acpiphp_get_latch_status(struct acpiphp_slot *slot)
1309{
1310 unsigned int sta;
1311
1312 sta = get_slot_status(slot);
1313
1314 return (sta & ACPI_STA_SHOW_IN_UI) ? 1 : 0;
1315}
1316
1317
1318/*
1319 * adapter presence : 1
1320 * absence : 0
1321 */
1322u8 acpiphp_get_adapter_status(struct acpiphp_slot *slot)
1323{
1324 unsigned int sta;
1325
1326 sta = get_slot_status(slot);
1327
1328 return (sta == 0) ? 0 : 1;
1329}
1330
1331
1332/*
1333 * pci address (seg/bus/dev)
1334 */
1335u32 acpiphp_get_address(struct acpiphp_slot *slot)
1336{
1337 u32 address;
1338
1339 address = ((slot->bridge->seg) << 16) |
1340 ((slot->bridge->bus) << 8) |
1341 slot->device;
1342
1343 return address;
1344}
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c
new file mode 100644
index 000000000000..7e7f913ba7b9
--- /dev/null
+++ b/drivers/pci/hotplug/acpiphp_ibm.c
@@ -0,0 +1,499 @@
1/*
2 * ACPI PCI Hot Plug IBM Extension
3 *
4 * Copyright (C) 2004 Vernon Mauery <vernux@us.ibm.com>
5 * Copyright (C) 2004 IBM Corp.
6 *
7 * All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
17 * NON INFRINGEMENT. See the GNU General Public License for more
18 * details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * Send feedback to <vernux@us.ibm.com>
25 *
26 */
27
28#include <linux/init.h>
29#include <linux/module.h>
30#include <linux/kernel.h>
31#include <acpi/acpi_bus.h>
32#include <linux/sysfs.h>
33#include <linux/kobject.h>
34#include <asm/uaccess.h>
35#include <linux/moduleparam.h>
36
37#include "acpiphp.h"
38#include "pci_hotplug.h"
39
40#define DRIVER_VERSION "1.0.1"
41#define DRIVER_AUTHOR "Irene Zubarev <zubarev@us.ibm.com>, Vernon Mauery <vernux@us.ibm.com>"
42#define DRIVER_DESC "ACPI Hot Plug PCI Controller Driver IBM extension"
43
44static int debug;
45
46MODULE_AUTHOR(DRIVER_AUTHOR);
47MODULE_DESCRIPTION(DRIVER_DESC);
48MODULE_LICENSE("GPL");
49MODULE_VERSION(DRIVER_VERSION);
50module_param(debug, bool, 0644);
51MODULE_PARM_DESC(debug, " Debugging mode enabled or not");
52#define MY_NAME "acpiphp_ibm"
53
54#undef dbg
55#define dbg(format, arg...) \
56do { \
57 if (debug) \
58 printk(KERN_DEBUG "%s: " format, \
59 MY_NAME , ## arg); \
60} while (0)
61
62#define FOUND_APCI 0x61504349
63/* these are the names for the IBM ACPI pseudo-device */
64#define IBM_HARDWARE_ID1 "IBM37D0"
65#define IBM_HARDWARE_ID2 "IBM37D4"
66
67#define hpslot_to_sun(A) (((struct slot *)((A)->private))->acpi_slot->sun)
68
69/* union apci_descriptor - allows access to the
70 * various device descriptors that are embedded in the
71 * aPCI table
72 */
73union apci_descriptor {
74 struct {
75 char sig[4];
76 u8 len;
77 } header;
78 struct {
79 u8 type;
80 u8 len;
81 u16 slot_id;
82 u8 bus_id;
83 u8 dev_num;
84 u8 slot_num;
85 u8 slot_attr[2];
86 u8 attn;
87 u8 status[2];
88 u8 sun;
89 u8 res[3];
90 } slot;
91 struct {
92 u8 type;
93 u8 len;
94 } generic;
95};
96
97/* struct notification - keeps info about the device
98 * that cause the ACPI notification event
99 */
100struct notification {
101 struct acpi_device *device;
102 u8 event;
103};
104
105static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status);
106static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status);
107static void ibm_handle_events(acpi_handle handle, u32 event, void *context);
108static int ibm_get_table_from_acpi(char **bufp);
109static ssize_t ibm_read_apci_table(struct kobject *kobj,
110 char *buffer, loff_t pos, size_t size);
111static acpi_status __init ibm_find_acpi_device(acpi_handle handle,
112 u32 lvl, void *context, void **rv);
113static int __init ibm_acpiphp_init(void);
114static void __exit ibm_acpiphp_exit(void);
115
116static acpi_handle ibm_acpi_handle;
117static struct notification ibm_note;
118static struct bin_attribute ibm_apci_table_attr = {
119 .attr = {
120 .name = "apci_table",
121 .owner = THIS_MODULE,
122 .mode = S_IRUGO,
123 },
124 .read = ibm_read_apci_table,
125 .write = NULL,
126};
127static struct acpiphp_attention_info ibm_attention_info =
128{
129 .set_attn = ibm_set_attention_status,
130 .get_attn = ibm_get_attention_status,
131 .owner = THIS_MODULE,
132};
133
134/**
135 * ibm_slot_from_id - workaround for bad ibm hardware
136 * @id: the slot number that linux refers to the slot by
137 *
138 * Description: this method returns the aCPI slot descriptor
139 * corresponding to the Linux slot number. This descriptor
140 * has info about the aPCI slot id and attention status.
141 * This descriptor must be freed using kfree when done.
142 **/
143static union apci_descriptor *ibm_slot_from_id(int id)
144{
145 int ind = 0, size;
146 union apci_descriptor *ret = NULL, *des;
147 char *table;
148
149 size = ibm_get_table_from_acpi(&table);
150 des = (union apci_descriptor *)table;
151 if (memcmp(des->header.sig, "aPCI", 4) != 0)
152 goto ibm_slot_done;
153
154 des = (union apci_descriptor *)&table[ind += des->header.len];
155 while (ind < size && (des->generic.type != 0x82 ||
156 des->slot.slot_num != id)) {
157 des = (union apci_descriptor *)&table[ind += des->generic.len];
158 }
159
160 if (ind < size && des->slot.slot_num == id)
161 ret = des;
162
163ibm_slot_done:
164 if (ret) {
165 ret = kmalloc(sizeof(union apci_descriptor), GFP_KERNEL);
166 memcpy(ret, des, sizeof(union apci_descriptor));
167 }
168 kfree(table);
169 return ret;
170}
171
172/**
173 * ibm_set_attention_status - callback method to set the attention LED
174 * @slot: the hotplug_slot to work with
175 * @status: what to set the LED to (0 or 1)
176 *
177 * Description: this method is registered with the acpiphp module as a
178 * callback to do the device specific task of setting the LED status
179 **/
180static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status)
181{
182 union acpi_object args[2];
183 struct acpi_object_list params = { .pointer = args, .count = 2 };
184 acpi_status stat;
185 unsigned long rc;
186 union apci_descriptor *ibm_slot;
187
188 ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot));
189
190 dbg("%s: set slot %d (%d) attention status to %d\n", __FUNCTION__,
191 ibm_slot->slot.slot_num, ibm_slot->slot.slot_id,
192 (status ? 1 : 0));
193
194 args[0].type = ACPI_TYPE_INTEGER;
195 args[0].integer.value = ibm_slot->slot.slot_id;
196 args[1].type = ACPI_TYPE_INTEGER;
197 args[1].integer.value = (status) ? 1 : 0;
198
199 kfree(ibm_slot);
200
201 stat = acpi_evaluate_integer(ibm_acpi_handle, "APLS", &params, &rc);
202 if (ACPI_FAILURE(stat)) {
203 err("APLS evaluation failed: 0x%08x\n", stat);
204 return -ENODEV;
205 } else if (!rc) {
206 err("APLS method failed: 0x%08lx\n", rc);
207 return -ERANGE;
208 }
209 return 0;
210}
211
212/**
213 * ibm_get_attention_status - callback method to get attention LED status
214 * @slot: the hotplug_slot to work with
215 * @status: returns what the LED is set to (0 or 1)
216 *
217 * Description: this method is registered with the acpiphp module as a
218 * callback to do the device specific task of getting the LED status
219 *
220 * Because there is no direct method of getting the LED status directly
221 * from an ACPI call, we read the aPCI table and parse out our
222 * slot descriptor to read the status from that.
223 **/
224static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status)
225{
226 union apci_descriptor *ibm_slot;
227
228 ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot));
229
230 if (ibm_slot->slot.attn & 0xa0 || ibm_slot->slot.status[1] & 0x08)
231 *status = 1;
232 else
233 *status = 0;
234
235 dbg("%s: get slot %d (%d) attention status is %d\n", __FUNCTION__,
236 ibm_slot->slot.slot_num, ibm_slot->slot.slot_id,
237 *status);
238
239 kfree(ibm_slot);
240 return 0;
241}
242
243/**
244 * ibm_handle_events - listens for ACPI events for the IBM37D0 device
245 * @handle: an ACPI handle to the device that caused the event
246 * @event: the event info (device specific)
247 * @context: passed context (our notification struct)
248 *
249 * Description: this method is registered as a callback with the ACPI
250 * subsystem it is called when this device has an event to notify the OS of
251 *
252 * The events actually come from the device as two events that get
253 * synthesized into one event with data by this function. The event
254 * ID comes first and then the slot number that caused it. We report
255 * this as one event to the OS.
256 *
257 * From section 5.6.2.2 of the ACPI 2.0 spec, I understand that the OSPM will
258 * only re-enable the interrupt that causes this event AFTER this method
259 * has returned, thereby enforcing serial access for the notification struct.
260 **/
261static void ibm_handle_events(acpi_handle handle, u32 event, void *context)
262{
263 u8 detail = event & 0x0f;
264 u8 subevent = event & 0xf0;
265 struct notification *note = context;
266
267 dbg("%s: Received notification %02x\n", __FUNCTION__, event);
268
269 if (subevent == 0x80) {
270 dbg("%s: generationg bus event\n", __FUNCTION__);
271 acpi_bus_generate_event(note->device, note->event, detail);
272 } else
273 note->event = event;
274}
275
276/**
277 * ibm_get_table_from_acpi - reads the APLS buffer from ACPI
278 * @bufp: address to pointer to allocate for the table
279 *
280 * Description: this method reads the APLS buffer in from ACPI and
281 * stores the "stripped" table into a single buffer
282 * it allocates and passes the address back in bufp
283 *
284 * If NULL is passed in as buffer, this method only calculates
285 * the size of the table and returns that without filling
286 * in the buffer
287 *
288 * returns < 0 on error or the size of the table on success
289 **/
290static int ibm_get_table_from_acpi(char **bufp)
291{
292 union acpi_object *package;
293 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
294 acpi_status status;
295 char *lbuf = NULL;
296 int i, size = -EIO;
297
298 status = acpi_evaluate_object(ibm_acpi_handle, "APCI", NULL, &buffer);
299 if (ACPI_FAILURE(status)) {
300 err("%s: APCI evaluation failed\n", __FUNCTION__);
301 return -ENODEV;
302 }
303
304 package = (union acpi_object *) buffer.pointer;
305 if(!(package) ||
306 (package->type != ACPI_TYPE_PACKAGE) ||
307 !(package->package.elements)) {
308 err("%s: Invalid APCI object\n", __FUNCTION__);
309 goto read_table_done;
310 }
311
312 for(size = 0, i = 0; i < package->package.count; i++) {
313 if (package->package.elements[i].type != ACPI_TYPE_BUFFER) {
314 err("%s: Invalid APCI element %d\n", __FUNCTION__, i);
315 goto read_table_done;
316 }
317 size += package->package.elements[i].buffer.length;
318 }
319
320 if (bufp == NULL)
321 goto read_table_done;
322
323 lbuf = kmalloc(size, GFP_KERNEL);
324 dbg("%s: element count: %i, ASL table size: %i, &table = 0x%p\n",
325 __FUNCTION__, package->package.count, size, lbuf);
326
327 if (lbuf) {
328 *bufp = lbuf;
329 memset(lbuf, 0, size);
330 } else {
331 size = -ENOMEM;
332 goto read_table_done;
333 }
334
335 size = 0;
336 for (i=0; i<package->package.count; i++) {
337 memcpy(&lbuf[size],
338 package->package.elements[i].buffer.pointer,
339 package->package.elements[i].buffer.length);
340 size += package->package.elements[i].buffer.length;
341 }
342
343read_table_done:
344 kfree(buffer.pointer);
345 return size;
346}
347
348/**
349 * ibm_read_apci_table - callback for the sysfs apci_table file
350 * @kobj: the kobject this binary attribute is a part of
351 * @buffer: the kernel space buffer to fill
352 * @pos: the offset into the file
353 * @size: the number of bytes requested
354 *
355 * Description: gets registered with sysfs as the reader callback
356 * to be executed when /sys/bus/pci/slots/apci_table gets read
357 *
358 * Since we don't get notified on open and close for this file,
359 * things get really tricky here...
360 * our solution is to only allow reading the table in all at once
361 **/
362static ssize_t ibm_read_apci_table(struct kobject *kobj,
363 char *buffer, loff_t pos, size_t size)
364{
365 int bytes_read = -EINVAL;
366 char *table = NULL;
367
368 dbg("%s: pos = %d, size = %zd\n", __FUNCTION__, (int)pos, size);
369
370 if (pos == 0) {
371 bytes_read = ibm_get_table_from_acpi(&table);
372 if (bytes_read > 0 && bytes_read <= size)
373 memcpy(buffer, table, bytes_read);
374 kfree(table);
375 }
376 return bytes_read;
377}
378
379/**
380 * ibm_find_acpi_device - callback to find our ACPI device
381 * @handle: the ACPI handle of the device we are inspecting
382 * @lvl: depth into the namespace tree
383 * @context: a pointer to our handle to fill when we find the device
384 * @rv: a return value to fill if desired
385 *
386 * Description: used as a callback when calling acpi_walk_namespace
387 * to find our device. When this method returns non-zero
388 * acpi_walk_namespace quits its search and returns our value
389 **/
390static acpi_status __init ibm_find_acpi_device(acpi_handle handle,
391 u32 lvl, void *context, void **rv)
392{
393 acpi_handle *phandle = (acpi_handle *)context;
394 acpi_status status;
395 struct acpi_device_info info;
396 struct acpi_buffer info_buffer = {
397 .length = sizeof(struct acpi_device_info),
398 .pointer = &info,
399 };
400
401 status = acpi_get_object_info(handle, &info_buffer);
402 if (ACPI_FAILURE(status)) {
403 err("%s: Failed to get device information", __FUNCTION__);
404 return 0;
405 }
406 info.hardware_id.value[sizeof(info.hardware_id.value) - 1] = '\0';
407
408 if(info.current_status && (info.valid & ACPI_VALID_HID) &&
409 (!strcmp(info.hardware_id.value, IBM_HARDWARE_ID1) ||
410 !strcmp(info.hardware_id.value, IBM_HARDWARE_ID2))) {
411 dbg("found hardware: %s, handle: %p\n", info.hardware_id.value,
412 handle);
413 *phandle = handle;
414 /* returning non-zero causes the search to stop
415 * and returns this value to the caller of
416 * acpi_walk_namespace, but it also causes some warnings
417 * in the acpi debug code to print...
418 */
419 return FOUND_APCI;
420 }
421 return 0;
422}
423
424static int __init ibm_acpiphp_init(void)
425{
426 int retval = 0;
427 acpi_status status;
428 struct acpi_device *device;
429 struct kobject *sysdir = &pci_hotplug_slots_subsys.kset.kobj;
430
431 dbg("%s\n", __FUNCTION__);
432
433 if (acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
434 ACPI_UINT32_MAX, ibm_find_acpi_device,
435 &ibm_acpi_handle, NULL) != FOUND_APCI) {
436 err("%s: acpi_walk_namespace failed\n", __FUNCTION__);
437 retval = -ENODEV;
438 goto init_return;
439 }
440 dbg("%s: found IBM aPCI device\n", __FUNCTION__);
441 if (acpi_bus_get_device(ibm_acpi_handle, &device)) {
442 err("%s: acpi_bus_get_device failed\n", __FUNCTION__);
443 retval = -ENODEV;
444 goto init_return;
445 }
446 if (acpiphp_register_attention(&ibm_attention_info)) {
447 retval = -ENODEV;
448 goto init_return;
449 }
450
451 ibm_note.device = device;
452 status = acpi_install_notify_handler(
453 ibm_acpi_handle,
454 ACPI_DEVICE_NOTIFY,
455 ibm_handle_events,
456 &ibm_note);
457 if (ACPI_FAILURE(status)) {
458 err("%s: Failed to register notification handler\n",
459 __FUNCTION__);
460 retval = -EBUSY;
461 goto init_cleanup;
462 }
463
464 ibm_apci_table_attr.size = ibm_get_table_from_acpi(NULL);
465 retval = sysfs_create_bin_file(sysdir, &ibm_apci_table_attr);
466
467 return retval;
468
469init_cleanup:
470 acpiphp_unregister_attention(&ibm_attention_info);
471init_return:
472 return retval;
473}
474
475static void __exit ibm_acpiphp_exit(void)
476{
477 acpi_status status;
478 struct kobject *sysdir = &pci_hotplug_slots_subsys.kset.kobj;
479
480 dbg("%s\n", __FUNCTION__);
481
482 if (acpiphp_unregister_attention(&ibm_attention_info))
483 err("%s: attention info deregistration failed", __FUNCTION__);
484
485 status = acpi_remove_notify_handler(
486 ibm_acpi_handle,
487 ACPI_DEVICE_NOTIFY,
488 ibm_handle_events);
489 if (ACPI_FAILURE(status))
490 err("%s: Notification handler removal failed\n",
491 __FUNCTION__);
492 // remove the /sys entries
493 if (sysfs_remove_bin_file(sysdir, &ibm_apci_table_attr))
494 err("%s: removal of sysfs file apci_table failed\n",
495 __FUNCTION__);
496}
497
498module_init(ibm_acpiphp_init);
499module_exit(ibm_acpiphp_exit);
diff --git a/drivers/pci/hotplug/acpiphp_pci.c b/drivers/pci/hotplug/acpiphp_pci.c
new file mode 100644
index 000000000000..54d97c9d1dff
--- /dev/null
+++ b/drivers/pci/hotplug/acpiphp_pci.c
@@ -0,0 +1,449 @@
1/*
2 * ACPI PCI HotPlug PCI configuration space management
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001,2002 IBM Corp.
7 * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
8 * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
9 * Copyright (C) 2002 NEC Corporation
10 *
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or (at
16 * your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
21 * NON INFRINGEMENT. See the GNU General Public License for more
22 * details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 * Send feedback to <t-kochi@bq.jp.nec.com>
29 *
30 */
31
32#include <linux/init.h>
33#include <linux/module.h>
34
35#include <linux/kernel.h>
36#include <linux/pci.h>
37#include <linux/acpi.h>
38#include "../pci.h"
39#include "pci_hotplug.h"
40#include "acpiphp.h"
41
42#define MY_NAME "acpiphp_pci"
43
44
45/* allocate mem/pmem/io resource to a new function */
46static int init_config_space (struct acpiphp_func *func)
47{
48 u32 bar, len;
49 u32 address[] = {
50 PCI_BASE_ADDRESS_0,
51 PCI_BASE_ADDRESS_1,
52 PCI_BASE_ADDRESS_2,
53 PCI_BASE_ADDRESS_3,
54 PCI_BASE_ADDRESS_4,
55 PCI_BASE_ADDRESS_5,
56 0
57 };
58 int count;
59 struct acpiphp_bridge *bridge;
60 struct pci_resource *res;
61 struct pci_bus *pbus;
62 int bus, device, function;
63 unsigned int devfn;
64 u16 tmp;
65
66 bridge = func->slot->bridge;
67 pbus = bridge->pci_bus;
68 bus = bridge->bus;
69 device = func->slot->device;
70 function = func->function;
71 devfn = PCI_DEVFN(device, function);
72
73 for (count = 0; address[count]; count++) { /* for 6 BARs */
74 pci_bus_write_config_dword(pbus, devfn,
75 address[count], 0xFFFFFFFF);
76 pci_bus_read_config_dword(pbus, devfn, address[count], &bar);
77
78 if (!bar) /* This BAR is not implemented */
79 continue;
80
81 dbg("Device %02x.%02x BAR %d wants %x\n", device, function, count, bar);
82
83 if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
84 /* This is IO */
85
86 len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
87 len = len & ~(len - 1);
88
89 dbg("len in IO %x, BAR %d\n", len, count);
90
91 spin_lock(&bridge->res_lock);
92 res = acpiphp_get_io_resource(&bridge->io_head, len);
93 spin_unlock(&bridge->res_lock);
94
95 if (!res) {
96 err("cannot allocate requested io for %02x:%02x.%d len %x\n",
97 bus, device, function, len);
98 return -1;
99 }
100 pci_bus_write_config_dword(pbus, devfn,
101 address[count],
102 (u32)res->base);
103 res->next = func->io_head;
104 func->io_head = res;
105
106 } else {
107 /* This is Memory */
108 if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH) {
109 /* pfmem */
110
111 len = bar & 0xFFFFFFF0;
112 len = ~len + 1;
113
114 dbg("len in PFMEM %x, BAR %d\n", len, count);
115
116 spin_lock(&bridge->res_lock);
117 res = acpiphp_get_resource(&bridge->p_mem_head, len);
118 spin_unlock(&bridge->res_lock);
119
120 if (!res) {
121 err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n",
122 bus, device, function, len);
123 return -1;
124 }
125
126 pci_bus_write_config_dword(pbus, devfn,
127 address[count],
128 (u32)res->base);
129
130 if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) { /* takes up another dword */
131 dbg("inside the pfmem 64 case, count %d\n", count);
132 count += 1;
133 pci_bus_write_config_dword(pbus, devfn,
134 address[count],
135 (u32)(res->base >> 32));
136 }
137
138 res->next = func->p_mem_head;
139 func->p_mem_head = res;
140
141 } else {
142 /* regular memory */
143
144 len = bar & 0xFFFFFFF0;
145 len = ~len + 1;
146
147 dbg("len in MEM %x, BAR %d\n", len, count);
148
149 spin_lock(&bridge->res_lock);
150 res = acpiphp_get_resource(&bridge->mem_head, len);
151 spin_unlock(&bridge->res_lock);
152
153 if (!res) {
154 err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n",
155 bus, device, function, len);
156 return -1;
157 }
158
159 pci_bus_write_config_dword(pbus, devfn,
160 address[count],
161 (u32)res->base);
162
163 if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) {
164 /* takes up another dword */
165 dbg("inside mem 64 case, reg. mem, count %d\n", count);
166 count += 1;
167 pci_bus_write_config_dword(pbus, devfn,
168 address[count],
169 (u32)(res->base >> 32));
170 }
171
172 res->next = func->mem_head;
173 func->mem_head = res;
174
175 }
176 }
177 }
178
179 /* disable expansion rom */
180 pci_bus_write_config_dword(pbus, devfn, PCI_ROM_ADDRESS, 0x00000000);
181
182 /* set PCI parameters from _HPP */
183 pci_bus_write_config_byte(pbus, devfn, PCI_CACHE_LINE_SIZE,
184 bridge->hpp.cache_line_size);
185 pci_bus_write_config_byte(pbus, devfn, PCI_LATENCY_TIMER,
186 bridge->hpp.latency_timer);
187
188 pci_bus_read_config_word(pbus, devfn, PCI_COMMAND, &tmp);
189 if (bridge->hpp.enable_SERR)
190 tmp |= PCI_COMMAND_SERR;
191 if (bridge->hpp.enable_PERR)
192 tmp |= PCI_COMMAND_PARITY;
193 pci_bus_write_config_word(pbus, devfn, PCI_COMMAND, tmp);
194
195 return 0;
196}
197
198/* detect_used_resource - subtract resource under dev from bridge */
199static int detect_used_resource (struct acpiphp_bridge *bridge, struct pci_dev *dev)
200{
201 int count;
202
203 dbg("Device %s\n", pci_name(dev));
204
205 for (count = 0; count < DEVICE_COUNT_RESOURCE; count++) {
206 struct pci_resource *res;
207 struct pci_resource **head;
208 unsigned long base = dev->resource[count].start;
209 unsigned long len = dev->resource[count].end - base + 1;
210 unsigned long flags = dev->resource[count].flags;
211
212 if (!flags)
213 continue;
214
215 dbg("BAR[%d] 0x%lx - 0x%lx (0x%lx)\n", count, base,
216 base + len - 1, flags);
217
218 if (flags & IORESOURCE_IO) {
219 head = &bridge->io_head;
220 } else if (flags & IORESOURCE_PREFETCH) {
221 head = &bridge->p_mem_head;
222 } else {
223 head = &bridge->mem_head;
224 }
225
226 spin_lock(&bridge->res_lock);
227 res = acpiphp_get_resource_with_base(head, base, len);
228 spin_unlock(&bridge->res_lock);
229 if (res)
230 kfree(res);
231 }
232
233 return 0;
234}
235
236
237/**
238 * acpiphp_detect_pci_resource - detect resources under bridge
239 * @bridge: detect all resources already used under this bridge
240 *
241 * collect all resources already allocated for all devices under a bridge.
242 */
243int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge)
244{
245 struct list_head *l;
246 struct pci_dev *dev;
247
248 list_for_each (l, &bridge->pci_bus->devices) {
249 dev = pci_dev_b(l);
250 detect_used_resource(bridge, dev);
251 }
252
253 return 0;
254}
255
256
257/**
258 * acpiphp_init_slot_resource - gather resource usage information of a slot
259 * @slot: ACPI slot object to be checked, should have valid pci_dev member
260 *
261 * TBD: PCI-to-PCI bridge case
262 * use pci_dev->resource[]
263 */
264int acpiphp_init_func_resource (struct acpiphp_func *func)
265{
266 u64 base;
267 u32 bar, len;
268 u32 address[] = {
269 PCI_BASE_ADDRESS_0,
270 PCI_BASE_ADDRESS_1,
271 PCI_BASE_ADDRESS_2,
272 PCI_BASE_ADDRESS_3,
273 PCI_BASE_ADDRESS_4,
274 PCI_BASE_ADDRESS_5,
275 0
276 };
277 int count;
278 struct pci_resource *res;
279 struct pci_dev *dev;
280
281 dev = func->pci_dev;
282 dbg("Hot-pluggable device %s\n", pci_name(dev));
283
284 for (count = 0; address[count]; count++) { /* for 6 BARs */
285 pci_read_config_dword(dev, address[count], &bar);
286
287 if (!bar) /* This BAR is not implemented */
288 continue;
289
290 pci_write_config_dword(dev, address[count], 0xFFFFFFFF);
291 pci_read_config_dword(dev, address[count], &len);
292
293 if (len & PCI_BASE_ADDRESS_SPACE_IO) {
294 /* This is IO */
295 base = bar & 0xFFFFFFFC;
296 len = len & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
297 len = len & ~(len - 1);
298
299 dbg("BAR[%d] %08x - %08x (IO)\n", count, (u32)base, (u32)base + len - 1);
300
301 res = acpiphp_make_resource(base, len);
302 if (!res)
303 goto no_memory;
304
305 res->next = func->io_head;
306 func->io_head = res;
307
308 } else {
309 /* This is Memory */
310 base = bar & 0xFFFFFFF0;
311 if (len & PCI_BASE_ADDRESS_MEM_PREFETCH) {
312 /* pfmem */
313
314 len &= 0xFFFFFFF0;
315 len = ~len + 1;
316
317 if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) { /* takes up another dword */
318 dbg("prefetch mem 64\n");
319 count += 1;
320 }
321 dbg("BAR[%d] %08x - %08x (PMEM)\n", count, (u32)base, (u32)base + len - 1);
322 res = acpiphp_make_resource(base, len);
323 if (!res)
324 goto no_memory;
325
326 res->next = func->p_mem_head;
327 func->p_mem_head = res;
328
329 } else {
330 /* regular memory */
331
332 len &= 0xFFFFFFF0;
333 len = ~len + 1;
334
335 if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {
336 /* takes up another dword */
337 dbg("mem 64\n");
338 count += 1;
339 }
340 dbg("BAR[%d] %08x - %08x (MEM)\n", count, (u32)base, (u32)base + len - 1);
341 res = acpiphp_make_resource(base, len);
342 if (!res)
343 goto no_memory;
344
345 res->next = func->mem_head;
346 func->mem_head = res;
347
348 }
349 }
350
351 pci_write_config_dword(dev, address[count], bar);
352 }
353#if 1
354 acpiphp_dump_func_resource(func);
355#endif
356
357 return 0;
358
359 no_memory:
360 err("out of memory\n");
361 acpiphp_free_resource(&func->io_head);
362 acpiphp_free_resource(&func->mem_head);
363 acpiphp_free_resource(&func->p_mem_head);
364
365 return -1;
366}
367
368
369/**
370 * acpiphp_configure_slot - allocate PCI resources
371 * @slot: slot to be configured
372 *
373 * initializes a PCI functions on a device inserted
374 * into the slot
375 *
376 */
377int acpiphp_configure_slot (struct acpiphp_slot *slot)
378{
379 struct acpiphp_func *func;
380 struct list_head *l;
381 u8 hdr;
382 u32 dvid;
383 int retval = 0;
384 int is_multi = 0;
385
386 pci_bus_read_config_byte(slot->bridge->pci_bus,
387 PCI_DEVFN(slot->device, 0),
388 PCI_HEADER_TYPE, &hdr);
389
390 if (hdr & 0x80)
391 is_multi = 1;
392
393 list_for_each (l, &slot->funcs) {
394 func = list_entry(l, struct acpiphp_func, sibling);
395 if (is_multi || func->function == 0) {
396 pci_bus_read_config_dword(slot->bridge->pci_bus,
397 PCI_DEVFN(slot->device,
398 func->function),
399 PCI_VENDOR_ID, &dvid);
400 if (dvid != 0xffffffff) {
401 retval = init_config_space(func);
402 if (retval)
403 break;
404 }
405 }
406 }
407
408 return retval;
409}
410
411/**
412 * acpiphp_configure_function - configure PCI function
413 * @func: function to be configured
414 *
415 * initializes a PCI functions on a device inserted
416 * into the slot
417 *
418 */
419int acpiphp_configure_function (struct acpiphp_func *func)
420{
421 /* all handled by the pci core now */
422 return 0;
423}
424
425/**
426 * acpiphp_unconfigure_function - unconfigure PCI function
427 * @func: function to be unconfigured
428 *
429 */
430void acpiphp_unconfigure_function (struct acpiphp_func *func)
431{
432 struct acpiphp_bridge *bridge;
433
434 /* if pci_dev is NULL, ignore it */
435 if (!func->pci_dev)
436 return;
437
438 pci_remove_bus_device(func->pci_dev);
439
440 /* free all resources */
441 bridge = func->slot->bridge;
442
443 spin_lock(&bridge->res_lock);
444 acpiphp_move_resource(&func->io_head, &bridge->io_head);
445 acpiphp_move_resource(&func->mem_head, &bridge->mem_head);
446 acpiphp_move_resource(&func->p_mem_head, &bridge->p_mem_head);
447 acpiphp_move_resource(&func->bus_head, &bridge->bus_head);
448 spin_unlock(&bridge->res_lock);
449}
diff --git a/drivers/pci/hotplug/acpiphp_res.c b/drivers/pci/hotplug/acpiphp_res.c
new file mode 100644
index 000000000000..f54b1fa7b75a
--- /dev/null
+++ b/drivers/pci/hotplug/acpiphp_res.c
@@ -0,0 +1,700 @@
1/*
2 * ACPI PCI HotPlug Utility functions
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
8 * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
9 * Copyright (C) 2002 NEC Corporation
10 *
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or (at
16 * your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
21 * NON INFRINGEMENT. See the GNU General Public License for more
22 * details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 * Send feedback to <gregkh@us.ibm.com>, <t-kochi@bq.jp.nec.com>
29 *
30 */
31
32#include <linux/init.h>
33#include <linux/module.h>
34
35#include <linux/kernel.h>
36#include <linux/types.h>
37#include <linux/proc_fs.h>
38#include <linux/sysctl.h>
39#include <linux/pci.h>
40#include <linux/smp.h>
41#include <linux/smp_lock.h>
42
43#include <linux/string.h>
44#include <linux/mm.h>
45#include <linux/errno.h>
46#include <linux/ioport.h>
47#include <linux/slab.h>
48#include <linux/interrupt.h>
49#include <linux/timer.h>
50
51#include <linux/ioctl.h>
52#include <linux/fcntl.h>
53
54#include <linux/list.h>
55
56#include "pci_hotplug.h"
57#include "acpiphp.h"
58
59#define MY_NAME "acpiphp_res"
60
61
62/*
63 * sort_by_size - sort nodes by their length, smallest first
64 */
65static int sort_by_size(struct pci_resource **head)
66{
67 struct pci_resource *current_res;
68 struct pci_resource *next_res;
69 int out_of_order = 1;
70
71 if (!(*head))
72 return 1;
73
74 if (!((*head)->next))
75 return 0;
76
77 while (out_of_order) {
78 out_of_order = 0;
79
80 /* Special case for swapping list head */
81 if (((*head)->next) &&
82 ((*head)->length > (*head)->next->length)) {
83 out_of_order++;
84 current_res = *head;
85 *head = (*head)->next;
86 current_res->next = (*head)->next;
87 (*head)->next = current_res;
88 }
89
90 current_res = *head;
91
92 while (current_res->next && current_res->next->next) {
93 if (current_res->next->length > current_res->next->next->length) {
94 out_of_order++;
95 next_res = current_res->next;
96 current_res->next = current_res->next->next;
97 current_res = current_res->next;
98 next_res->next = current_res->next;
99 current_res->next = next_res;
100 } else
101 current_res = current_res->next;
102 }
103 } /* End of out_of_order loop */
104
105 return 0;
106}
107
108#if 0
109/*
110 * sort_by_max_size - sort nodes by their length, largest first
111 */
112static int sort_by_max_size(struct pci_resource **head)
113{
114 struct pci_resource *current_res;
115 struct pci_resource *next_res;
116 int out_of_order = 1;
117
118 if (!(*head))
119 return 1;
120
121 if (!((*head)->next))
122 return 0;
123
124 while (out_of_order) {
125 out_of_order = 0;
126
127 /* Special case for swapping list head */
128 if (((*head)->next) &&
129 ((*head)->length < (*head)->next->length)) {
130 out_of_order++;
131 current_res = *head;
132 *head = (*head)->next;
133 current_res->next = (*head)->next;
134 (*head)->next = current_res;
135 }
136
137 current_res = *head;
138
139 while (current_res->next && current_res->next->next) {
140 if (current_res->next->length < current_res->next->next->length) {
141 out_of_order++;
142 next_res = current_res->next;
143 current_res->next = current_res->next->next;
144 current_res = current_res->next;
145 next_res->next = current_res->next;
146 current_res->next = next_res;
147 } else
148 current_res = current_res->next;
149 }
150 } /* End of out_of_order loop */
151
152 return 0;
153}
154#endif
155
156/**
157 * get_io_resource - get resource for I/O ports
158 *
159 * this function sorts the resource list by size and then
160 * returns the first node of "size" length that is not in the
161 * ISA aliasing window. If it finds a node larger than "size"
162 * it will split it up.
163 *
164 * size must be a power of two.
165 *
166 * difference from get_resource is handling of ISA aliasing space.
167 *
168 */
169struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size)
170{
171 struct pci_resource *prevnode;
172 struct pci_resource *node;
173 struct pci_resource *split_node;
174 u64 temp_qword;
175
176 if (!(*head))
177 return NULL;
178
179 if (acpiphp_resource_sort_and_combine(head))
180 return NULL;
181
182 if (sort_by_size(head))
183 return NULL;
184
185 for (node = *head; node; node = node->next) {
186 if (node->length < size)
187 continue;
188
189 if (node->base & (size - 1)) {
190 /* this one isn't base aligned properly
191 so we'll make a new entry and split it up */
192 temp_qword = (node->base | (size-1)) + 1;
193
194 /* Short circuit if adjusted size is too small */
195 if ((node->length - (temp_qword - node->base)) < size)
196 continue;
197
198 split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
199
200 if (!split_node)
201 return NULL;
202
203 node->base = temp_qword;
204 node->length -= split_node->length;
205
206 /* Put it in the list */
207 split_node->next = node->next;
208 node->next = split_node;
209 } /* End of non-aligned base */
210
211 /* Don't need to check if too small since we already did */
212 if (node->length > size) {
213 /* this one is longer than we need
214 so we'll make a new entry and split it up */
215 split_node = acpiphp_make_resource(node->base + size, node->length - size);
216
217 if (!split_node)
218 return NULL;
219
220 node->length = size;
221
222 /* Put it in the list */
223 split_node->next = node->next;
224 node->next = split_node;
225 } /* End of too big on top end */
226
227 /* For IO make sure it's not in the ISA aliasing space */
228 if ((node->base & 0x300L) && !(node->base & 0xfffff000))
229 continue;
230
231 /* If we got here, then it is the right size
232 Now take it out of the list */
233 if (*head == node) {
234 *head = node->next;
235 } else {
236 prevnode = *head;
237 while (prevnode->next != node)
238 prevnode = prevnode->next;
239
240 prevnode->next = node->next;
241 }
242 node->next = NULL;
243 /* Stop looping */
244 break;
245 }
246
247 return node;
248}
249
250
251#if 0
252/**
253 * get_max_resource - get the largest resource
254 *
255 * Gets the largest node that is at least "size" big from the
256 * list pointed to by head. It aligns the node on top and bottom
257 * to "size" alignment before returning it.
258 */
259static struct pci_resource *acpiphp_get_max_resource (struct pci_resource **head, u32 size)
260{
261 struct pci_resource *max;
262 struct pci_resource *temp;
263 struct pci_resource *split_node;
264 u64 temp_qword;
265
266 if (!(*head))
267 return NULL;
268
269 if (acpiphp_resource_sort_and_combine(head))
270 return NULL;
271
272 if (sort_by_max_size(head))
273 return NULL;
274
275 for (max = *head;max; max = max->next) {
276
277 /* If not big enough we could probably just bail,
278 instead we'll continue to the next. */
279 if (max->length < size)
280 continue;
281
282 if (max->base & (size - 1)) {
283 /* this one isn't base aligned properly
284 so we'll make a new entry and split it up */
285 temp_qword = (max->base | (size-1)) + 1;
286
287 /* Short circuit if adjusted size is too small */
288 if ((max->length - (temp_qword - max->base)) < size)
289 continue;
290
291 split_node = acpiphp_make_resource(max->base, temp_qword - max->base);
292
293 if (!split_node)
294 return NULL;
295
296 max->base = temp_qword;
297 max->length -= split_node->length;
298
299 /* Put it next in the list */
300 split_node->next = max->next;
301 max->next = split_node;
302 }
303
304 if ((max->base + max->length) & (size - 1)) {
305 /* this one isn't end aligned properly at the top
306 so we'll make a new entry and split it up */
307 temp_qword = ((max->base + max->length) & ~(size - 1));
308
309 split_node = acpiphp_make_resource(temp_qword,
310 max->length + max->base - temp_qword);
311
312 if (!split_node)
313 return NULL;
314
315 max->length -= split_node->length;
316
317 /* Put it in the list */
318 split_node->next = max->next;
319 max->next = split_node;
320 }
321
322 /* Make sure it didn't shrink too much when we aligned it */
323 if (max->length < size)
324 continue;
325
326 /* Now take it out of the list */
327 temp = (struct pci_resource*) *head;
328 if (temp == max) {
329 *head = max->next;
330 } else {
331 while (temp && temp->next != max) {
332 temp = temp->next;
333 }
334
335 temp->next = max->next;
336 }
337
338 max->next = NULL;
339 return max;
340 }
341
342 /* If we get here, we couldn't find one */
343 return NULL;
344}
345#endif
346
347/**
348 * get_resource - get resource (mem, pfmem)
349 *
350 * this function sorts the resource list by size and then
351 * returns the first node of "size" length. If it finds a node
352 * larger than "size" it will split it up.
353 *
354 * size must be a power of two.
355 *
356 */
357struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size)
358{
359 struct pci_resource *prevnode;
360 struct pci_resource *node;
361 struct pci_resource *split_node;
362 u64 temp_qword;
363
364 if (!(*head))
365 return NULL;
366
367 if (acpiphp_resource_sort_and_combine(head))
368 return NULL;
369
370 if (sort_by_size(head))
371 return NULL;
372
373 for (node = *head; node; node = node->next) {
374 dbg("%s: req_size =%x node=%p, base=%x, length=%x\n",
375 __FUNCTION__, size, node, (u32)node->base, node->length);
376 if (node->length < size)
377 continue;
378
379 if (node->base & (size - 1)) {
380 dbg("%s: not aligned\n", __FUNCTION__);
381 /* this one isn't base aligned properly
382 so we'll make a new entry and split it up */
383 temp_qword = (node->base | (size-1)) + 1;
384
385 /* Short circuit if adjusted size is too small */
386 if ((node->length - (temp_qword - node->base)) < size)
387 continue;
388
389 split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
390
391 if (!split_node)
392 return NULL;
393
394 node->base = temp_qword;
395 node->length -= split_node->length;
396
397 /* Put it in the list */
398 split_node->next = node->next;
399 node->next = split_node;
400 } /* End of non-aligned base */
401
402 /* Don't need to check if too small since we already did */
403 if (node->length > size) {
404 dbg("%s: too big\n", __FUNCTION__);
405 /* this one is longer than we need
406 so we'll make a new entry and split it up */
407 split_node = acpiphp_make_resource(node->base + size, node->length - size);
408
409 if (!split_node)
410 return NULL;
411
412 node->length = size;
413
414 /* Put it in the list */
415 split_node->next = node->next;
416 node->next = split_node;
417 } /* End of too big on top end */
418
419 dbg("%s: got one!!!\n", __FUNCTION__);
420 /* If we got here, then it is the right size
421 Now take it out of the list */
422 if (*head == node) {
423 *head = node->next;
424 } else {
425 prevnode = *head;
426 while (prevnode->next != node)
427 prevnode = prevnode->next;
428
429 prevnode->next = node->next;
430 }
431 node->next = NULL;
432 /* Stop looping */
433 break;
434 }
435 return node;
436}
437
438/**
439 * get_resource_with_base - get resource with specific base address
440 *
441 * this function
442 * returns the first node of "size" length located at specified base address.
443 * If it finds a node larger than "size" it will split it up.
444 *
445 * size must be a power of two.
446 *
447 */
448struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size)
449{
450 struct pci_resource *prevnode;
451 struct pci_resource *node;
452 struct pci_resource *split_node;
453 u64 temp_qword;
454
455 if (!(*head))
456 return NULL;
457
458 if (acpiphp_resource_sort_and_combine(head))
459 return NULL;
460
461 for (node = *head; node; node = node->next) {
462 dbg(": 1st req_base=%x req_size =%x node=%p, base=%x, length=%x\n",
463 (u32)base, size, node, (u32)node->base, node->length);
464 if (node->base > base)
465 continue;
466
467 if ((node->base + node->length) < (base + size))
468 continue;
469
470 if (node->base < base) {
471 dbg(": split 1\n");
472 /* this one isn't base aligned properly
473 so we'll make a new entry and split it up */
474 temp_qword = base;
475
476 /* Short circuit if adjusted size is too small */
477 if ((node->length - (temp_qword - node->base)) < size)
478 continue;
479
480 split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
481
482 if (!split_node)
483 return NULL;
484
485 node->base = temp_qword;
486 node->length -= split_node->length;
487
488 /* Put it in the list */
489 split_node->next = node->next;
490 node->next = split_node;
491 }
492
493 dbg(": 2nd req_base=%x req_size =%x node=%p, base=%x, length=%x\n",
494 (u32)base, size, node, (u32)node->base, node->length);
495
496 /* Don't need to check if too small since we already did */
497 if (node->length > size) {
498 dbg(": split 2\n");
499 /* this one is longer than we need
500 so we'll make a new entry and split it up */
501 split_node = acpiphp_make_resource(node->base + size, node->length - size);
502
503 if (!split_node)
504 return NULL;
505
506 node->length = size;
507
508 /* Put it in the list */
509 split_node->next = node->next;
510 node->next = split_node;
511 } /* End of too big on top end */
512
513 dbg(": got one!!!\n");
514 /* If we got here, then it is the right size
515 Now take it out of the list */
516 if (*head == node) {
517 *head = node->next;
518 } else {
519 prevnode = *head;
520 while (prevnode->next != node)
521 prevnode = prevnode->next;
522
523 prevnode->next = node->next;
524 }
525 node->next = NULL;
526 /* Stop looping */
527 break;
528 }
529 return node;
530}
531
532
533/**
534 * acpiphp_resource_sort_and_combine
535 *
536 * Sorts all of the nodes in the list in ascending order by
537 * their base addresses. Also does garbage collection by
538 * combining adjacent nodes.
539 *
540 * returns 0 if success
541 */
542int acpiphp_resource_sort_and_combine (struct pci_resource **head)
543{
544 struct pci_resource *node1;
545 struct pci_resource *node2;
546 int out_of_order = 1;
547
548 if (!(*head))
549 return 1;
550
551 dbg("*head->next = %p\n",(*head)->next);
552
553 if (!(*head)->next)
554 return 0; /* only one item on the list, already sorted! */
555
556 dbg("*head->base = 0x%x\n",(u32)(*head)->base);
557 dbg("*head->next->base = 0x%x\n", (u32)(*head)->next->base);
558 while (out_of_order) {
559 out_of_order = 0;
560
561 /* Special case for swapping list head */
562 if (((*head)->next) &&
563 ((*head)->base > (*head)->next->base)) {
564 node1 = *head;
565 (*head) = (*head)->next;
566 node1->next = (*head)->next;
567 (*head)->next = node1;
568 out_of_order++;
569 }
570
571 node1 = (*head);
572
573 while (node1->next && node1->next->next) {
574 if (node1->next->base > node1->next->next->base) {
575 out_of_order++;
576 node2 = node1->next;
577 node1->next = node1->next->next;
578 node1 = node1->next;
579 node2->next = node1->next;
580 node1->next = node2;
581 } else
582 node1 = node1->next;
583 }
584 } /* End of out_of_order loop */
585
586 node1 = *head;
587
588 while (node1 && node1->next) {
589 if ((node1->base + node1->length) == node1->next->base) {
590 /* Combine */
591 dbg("8..\n");
592 node1->length += node1->next->length;
593 node2 = node1->next;
594 node1->next = node1->next->next;
595 kfree(node2);
596 } else
597 node1 = node1->next;
598 }
599
600 return 0;
601}
602
603
604/**
605 * acpiphp_make_resource - make resource structure
606 * @base: base address of a resource
607 * @length: length of a resource
608 */
609struct pci_resource *acpiphp_make_resource (u64 base, u32 length)
610{
611 struct pci_resource *res;
612
613 res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
614 if (res) {
615 memset(res, 0, sizeof(struct pci_resource));
616 res->base = base;
617 res->length = length;
618 }
619
620 return res;
621}
622
623
624/**
625 * acpiphp_move_resource - move linked resources from one to another
626 * @from: head of linked resource list
627 * @to: head of linked resource list
628 */
629void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to)
630{
631 struct pci_resource *tmp;
632
633 while (*from) {
634 tmp = (*from)->next;
635 (*from)->next = *to;
636 *to = *from;
637 *from = tmp;
638 }
639
640 /* *from = NULL is guaranteed */
641}
642
643
644/**
645 * acpiphp_free_resource - free all linked resources
646 * @res: head of linked resource list
647 */
648void acpiphp_free_resource (struct pci_resource **res)
649{
650 struct pci_resource *tmp;
651
652 while (*res) {
653 tmp = (*res)->next;
654 kfree(*res);
655 *res = tmp;
656 }
657
658 /* *res = NULL is guaranteed */
659}
660
661
662/* debug support functions; will go away sometime :) */
663static void dump_resource(struct pci_resource *head)
664{
665 struct pci_resource *p;
666 int cnt;
667
668 p = head;
669 cnt = 0;
670
671 while (p) {
672 dbg("[%02d] %08x - %08x\n",
673 cnt++, (u32)p->base, (u32)p->base + p->length - 1);
674 p = p->next;
675 }
676}
677
678void acpiphp_dump_resource(struct acpiphp_bridge *bridge)
679{
680 dbg("I/O resource:\n");
681 dump_resource(bridge->io_head);
682 dbg("MEM resource:\n");
683 dump_resource(bridge->mem_head);
684 dbg("PMEM resource:\n");
685 dump_resource(bridge->p_mem_head);
686 dbg("BUS resource:\n");
687 dump_resource(bridge->bus_head);
688}
689
690void acpiphp_dump_func_resource(struct acpiphp_func *func)
691{
692 dbg("I/O resource:\n");
693 dump_resource(func->io_head);
694 dbg("MEM resource:\n");
695 dump_resource(func->mem_head);
696 dbg("PMEM resource:\n");
697 dump_resource(func->p_mem_head);
698 dbg("BUS resource:\n");
699 dump_resource(func->bus_head);
700}
diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h
new file mode 100644
index 000000000000..3ddd75937a40
--- /dev/null
+++ b/drivers/pci/hotplug/cpci_hotplug.h
@@ -0,0 +1,96 @@
1/*
2 * CompactPCI Hot Plug Core Functions
3 *
4 * Copyright (C) 2002 SOMA Networks, Inc.
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <scottm@somanetworks.com>
26 */
27
28#ifndef _CPCI_HOTPLUG_H
29#define _CPCI_HOTPLUG_H
30
31#include <linux/types.h>
32#include <linux/pci.h>
33
34/* PICMG 2.12 R2.0 HS CSR bits: */
35#define HS_CSR_INS 0x0080
36#define HS_CSR_EXT 0x0040
37#define HS_CSR_PI 0x0030
38#define HS_CSR_LOO 0x0008
39#define HS_CSR_PIE 0x0004
40#define HS_CSR_EIM 0x0002
41#define HS_CSR_DHA 0x0001
42
43struct slot {
44 u8 number;
45 unsigned int devfn;
46 struct pci_bus *bus;
47 struct pci_dev *dev;
48 unsigned int extracting;
49 struct hotplug_slot *hotplug_slot;
50 struct list_head slot_list;
51};
52
53struct cpci_hp_controller_ops {
54 int (*query_enum) (void);
55 int (*enable_irq) (void);
56 int (*disable_irq) (void);
57 int (*check_irq) (void *dev_id);
58 int (*hardware_test) (struct slot* slot, u32 value);
59 u8 (*get_power) (struct slot* slot);
60 int (*set_power) (struct slot* slot, int value);
61};
62
63struct cpci_hp_controller {
64 unsigned int irq;
65 unsigned long irq_flags;
66 char *devname;
67 void *dev_id;
68 char *name;
69 struct cpci_hp_controller_ops *ops;
70};
71
72extern int cpci_hp_register_controller(struct cpci_hp_controller *controller);
73extern int cpci_hp_unregister_controller(struct cpci_hp_controller *controller);
74extern int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last);
75extern int cpci_hp_unregister_bus(struct pci_bus *bus);
76extern int cpci_hp_start(void);
77extern int cpci_hp_stop(void);
78
79/*
80 * Internal function prototypes, these functions should not be used by
81 * board/chassis drivers.
82 */
83extern u8 cpci_get_attention_status(struct slot *slot);
84extern u8 cpci_get_latch_status(struct slot *slot);
85extern u8 cpci_get_adapter_status(struct slot *slot);
86extern u16 cpci_get_hs_csr(struct slot * slot);
87extern int cpci_set_attention_status(struct slot *slot, int status);
88extern int cpci_check_and_clear_ins(struct slot * slot);
89extern int cpci_check_ext(struct slot * slot);
90extern int cpci_clear_ext(struct slot * slot);
91extern int cpci_led_on(struct slot * slot);
92extern int cpci_led_off(struct slot * slot);
93extern int cpci_configure_slot(struct slot *slot);
94extern int cpci_unconfigure_slot(struct slot *slot);
95
96#endif /* _CPCI_HOTPLUG_H */
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c
new file mode 100644
index 000000000000..ed243605dc7b
--- /dev/null
+++ b/drivers/pci/hotplug/cpci_hotplug_core.c
@@ -0,0 +1,792 @@
1/*
2 * CompactPCI Hot Plug Driver
3 *
4 * Copyright (C) 2002 SOMA Networks, Inc.
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <scottm@somanetworks.com>
26 */
27
28#include <linux/config.h>
29#include <linux/module.h>
30#include <linux/kernel.h>
31#include <linux/slab.h>
32#include <linux/pci.h>
33#include <linux/init.h>
34#include <linux/interrupt.h>
35#include <linux/smp_lock.h>
36#include <linux/delay.h>
37#include "pci_hotplug.h"
38#include "cpci_hotplug.h"
39
40#define DRIVER_VERSION "0.2"
41#define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>"
42#define DRIVER_DESC "CompactPCI Hot Plug Core"
43
44#define MY_NAME "cpci_hotplug"
45
46#define dbg(format, arg...) \
47 do { \
48 if(cpci_debug) \
49 printk (KERN_DEBUG "%s: " format "\n", \
50 MY_NAME , ## arg); \
51 } while(0)
52#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
53#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
54#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
55
56/* local variables */
57static spinlock_t list_lock;
58static LIST_HEAD(slot_list);
59static int slots;
60int cpci_debug;
61static struct cpci_hp_controller *controller;
62static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */
63static struct semaphore thread_exit; /* guard ensure thread has exited before calling it quits */
64static int thread_finished = 1;
65
66static int enable_slot(struct hotplug_slot *slot);
67static int disable_slot(struct hotplug_slot *slot);
68static int set_attention_status(struct hotplug_slot *slot, u8 value);
69static int get_power_status(struct hotplug_slot *slot, u8 * value);
70static int get_attention_status(struct hotplug_slot *slot, u8 * value);
71
72static struct hotplug_slot_ops cpci_hotplug_slot_ops = {
73 .owner = THIS_MODULE,
74 .enable_slot = enable_slot,
75 .disable_slot = disable_slot,
76 .set_attention_status = set_attention_status,
77 .get_power_status = get_power_status,
78 .get_attention_status = get_attention_status,
79};
80
81static int
82update_latch_status(struct hotplug_slot *hotplug_slot, u8 value)
83{
84 struct hotplug_slot_info info;
85
86 memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
87 info.latch_status = value;
88 return pci_hp_change_slot_info(hotplug_slot, &info);
89}
90
91static int
92update_adapter_status(struct hotplug_slot *hotplug_slot, u8 value)
93{
94 struct hotplug_slot_info info;
95
96 memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
97 info.adapter_status = value;
98 return pci_hp_change_slot_info(hotplug_slot, &info);
99}
100
101static int
102enable_slot(struct hotplug_slot *hotplug_slot)
103{
104 struct slot *slot = hotplug_slot->private;
105 int retval = 0;
106
107 dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
108
109 if(controller->ops->set_power) {
110 retval = controller->ops->set_power(slot, 1);
111 }
112
113 return retval;
114}
115
116static int
117disable_slot(struct hotplug_slot *hotplug_slot)
118{
119 struct slot *slot = hotplug_slot->private;
120 int retval = 0;
121
122 dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
123
124 /* Unconfigure device */
125 dbg("%s - unconfiguring slot %s",
126 __FUNCTION__, slot->hotplug_slot->name);
127 if((retval = cpci_unconfigure_slot(slot))) {
128 err("%s - could not unconfigure slot %s",
129 __FUNCTION__, slot->hotplug_slot->name);
130 return retval;
131 }
132 dbg("%s - finished unconfiguring slot %s",
133 __FUNCTION__, slot->hotplug_slot->name);
134
135 /* Clear EXT (by setting it) */
136 if(cpci_clear_ext(slot)) {
137 err("%s - could not clear EXT for slot %s",
138 __FUNCTION__, slot->hotplug_slot->name);
139 retval = -ENODEV;
140 }
141 cpci_led_on(slot);
142
143 if(controller->ops->set_power) {
144 retval = controller->ops->set_power(slot, 0);
145 }
146
147 if(update_adapter_status(slot->hotplug_slot, 0)) {
148 warn("failure to update adapter file");
149 }
150
151 slot->extracting = 0;
152
153 return retval;
154}
155
156static u8
157cpci_get_power_status(struct slot *slot)
158{
159 u8 power = 1;
160
161 if(controller->ops->get_power) {
162 power = controller->ops->get_power(slot);
163 }
164 return power;
165}
166
167static int
168get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)
169{
170 struct slot *slot = hotplug_slot->private;
171
172 *value = cpci_get_power_status(slot);
173 return 0;
174}
175
176static int
177get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)
178{
179 struct slot *slot = hotplug_slot->private;
180
181 *value = cpci_get_attention_status(slot);
182 return 0;
183}
184
185static int
186set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
187{
188 return cpci_set_attention_status(hotplug_slot->private, status);
189}
190
191static void release_slot(struct hotplug_slot *hotplug_slot)
192{
193 struct slot *slot = hotplug_slot->private;
194
195 kfree(slot->hotplug_slot->info);
196 kfree(slot->hotplug_slot->name);
197 kfree(slot->hotplug_slot);
198 kfree(slot);
199}
200
201#define SLOT_NAME_SIZE 6
202static void
203make_slot_name(struct slot *slot)
204{
205 snprintf(slot->hotplug_slot->name,
206 SLOT_NAME_SIZE, "%02x:%02x", slot->bus->number, slot->number);
207}
208
209int
210cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
211{
212 struct slot *slot;
213 struct hotplug_slot *hotplug_slot;
214 struct hotplug_slot_info *info;
215 char *name;
216 int status = -ENOMEM;
217 int i;
218
219 if(!(controller && bus)) {
220 return -ENODEV;
221 }
222
223 /*
224 * Create a structure for each slot, and register that slot
225 * with the pci_hotplug subsystem.
226 */
227 for (i = first; i <= last; ++i) {
228 slot = kmalloc(sizeof (struct slot), GFP_KERNEL);
229 if (!slot)
230 goto error;
231 memset(slot, 0, sizeof (struct slot));
232
233 hotplug_slot =
234 kmalloc(sizeof (struct hotplug_slot), GFP_KERNEL);
235 if (!hotplug_slot)
236 goto error_slot;
237 memset(hotplug_slot, 0, sizeof (struct hotplug_slot));
238 slot->hotplug_slot = hotplug_slot;
239
240 info = kmalloc(sizeof (struct hotplug_slot_info), GFP_KERNEL);
241 if (!info)
242 goto error_hpslot;
243 memset(info, 0, sizeof (struct hotplug_slot_info));
244 hotplug_slot->info = info;
245
246 name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
247 if (!name)
248 goto error_info;
249 hotplug_slot->name = name;
250
251 slot->bus = bus;
252 slot->number = i;
253 slot->devfn = PCI_DEVFN(i, 0);
254
255 hotplug_slot->private = slot;
256 hotplug_slot->release = &release_slot;
257 make_slot_name(slot);
258 hotplug_slot->ops = &cpci_hotplug_slot_ops;
259
260 /*
261 * Initialize the slot info structure with some known
262 * good values.
263 */
264 dbg("initializing slot %s", slot->hotplug_slot->name);
265 info->power_status = cpci_get_power_status(slot);
266 info->attention_status = cpci_get_attention_status(slot);
267
268 dbg("registering slot %s", slot->hotplug_slot->name);
269 status = pci_hp_register(slot->hotplug_slot);
270 if (status) {
271 err("pci_hp_register failed with error %d", status);
272 goto error_name;
273 }
274
275 /* Add slot to our internal list */
276 spin_lock(&list_lock);
277 list_add(&slot->slot_list, &slot_list);
278 slots++;
279 spin_unlock(&list_lock);
280 }
281 return 0;
282error_name:
283 kfree(name);
284error_info:
285 kfree(info);
286error_hpslot:
287 kfree(hotplug_slot);
288error_slot:
289 kfree(slot);
290error:
291 return status;
292}
293
294int
295cpci_hp_unregister_bus(struct pci_bus *bus)
296{
297 struct slot *slot;
298 struct list_head *tmp;
299 struct list_head *next;
300 int status;
301
302 spin_lock(&list_lock);
303 if(!slots) {
304 spin_unlock(&list_lock);
305 return -1;
306 }
307 list_for_each_safe(tmp, next, &slot_list) {
308 slot = list_entry(tmp, struct slot, slot_list);
309 if(slot->bus == bus) {
310 dbg("deregistering slot %s", slot->hotplug_slot->name);
311 status = pci_hp_deregister(slot->hotplug_slot);
312 if(status) {
313 err("pci_hp_deregister failed with error %d",
314 status);
315 return status;
316 }
317
318 list_del(&slot->slot_list);
319 slots--;
320 }
321 }
322 spin_unlock(&list_lock);
323 return 0;
324}
325
326/* This is the interrupt mode interrupt handler */
327static irqreturn_t
328cpci_hp_intr(int irq, void *data, struct pt_regs *regs)
329{
330 dbg("entered cpci_hp_intr");
331
332 /* Check to see if it was our interrupt */
333 if((controller->irq_flags & SA_SHIRQ) &&
334 !controller->ops->check_irq(controller->dev_id)) {
335 dbg("exited cpci_hp_intr, not our interrupt");
336 return IRQ_NONE;
337 }
338
339 /* Disable ENUM interrupt */
340 controller->ops->disable_irq();
341
342 /* Trigger processing by the event thread */
343 dbg("Signal event_semaphore");
344 up(&event_semaphore);
345 dbg("exited cpci_hp_intr");
346 return IRQ_HANDLED;
347}
348
349/*
350 * According to PICMG 2.12 R2.0, section 6.3.2, upon
351 * initialization, the system driver shall clear the
352 * INS bits of the cold-inserted devices.
353 */
354static int
355init_slots(void)
356{
357 struct slot *slot;
358 struct list_head *tmp;
359 struct pci_dev* dev;
360
361 dbg("%s - enter", __FUNCTION__);
362 spin_lock(&list_lock);
363 if(!slots) {
364 spin_unlock(&list_lock);
365 return -1;
366 }
367 list_for_each(tmp, &slot_list) {
368 slot = list_entry(tmp, struct slot, slot_list);
369 dbg("%s - looking at slot %s",
370 __FUNCTION__, slot->hotplug_slot->name);
371 if(cpci_check_and_clear_ins(slot)) {
372 dbg("%s - cleared INS for slot %s",
373 __FUNCTION__, slot->hotplug_slot->name);
374 dev = pci_find_slot(slot->bus->number, PCI_DEVFN(slot->number, 0));
375 if(dev) {
376 if(update_adapter_status(slot->hotplug_slot, 1)) {
377 warn("failure to update adapter file");
378 }
379 if(update_latch_status(slot->hotplug_slot, 1)) {
380 warn("failure to update latch file");
381 }
382 slot->dev = dev;
383 } else {
384 err("%s - no driver attached to device in slot %s",
385 __FUNCTION__, slot->hotplug_slot->name);
386 }
387 }
388 }
389 spin_unlock(&list_lock);
390 dbg("%s - exit", __FUNCTION__);
391 return 0;
392}
393
394static int
395check_slots(void)
396{
397 struct slot *slot;
398 struct list_head *tmp;
399 int extracted;
400 int inserted;
401
402 spin_lock(&list_lock);
403 if(!slots) {
404 spin_unlock(&list_lock);
405 err("no slots registered, shutting down");
406 return -1;
407 }
408 extracted = inserted = 0;
409 list_for_each(tmp, &slot_list) {
410 slot = list_entry(tmp, struct slot, slot_list);
411 dbg("%s - looking at slot %s",
412 __FUNCTION__, slot->hotplug_slot->name);
413 if(cpci_check_and_clear_ins(slot)) {
414 u16 hs_csr;
415
416 /* Some broken hardware (e.g. PLX 9054AB) asserts ENUM# twice... */
417 if(slot->dev) {
418 warn("slot %s already inserted", slot->hotplug_slot->name);
419 inserted++;
420 continue;
421 }
422
423 /* Process insertion */
424 dbg("%s - slot %s inserted",
425 __FUNCTION__, slot->hotplug_slot->name);
426
427 /* GSM, debug */
428 hs_csr = cpci_get_hs_csr(slot);
429 dbg("%s - slot %s HS_CSR (1) = %04x",
430 __FUNCTION__, slot->hotplug_slot->name, hs_csr);
431
432 /* Configure device */
433 dbg("%s - configuring slot %s",
434 __FUNCTION__, slot->hotplug_slot->name);
435 if(cpci_configure_slot(slot)) {
436 err("%s - could not configure slot %s",
437 __FUNCTION__, slot->hotplug_slot->name);
438 continue;
439 }
440 dbg("%s - finished configuring slot %s",
441 __FUNCTION__, slot->hotplug_slot->name);
442
443 /* GSM, debug */
444 hs_csr = cpci_get_hs_csr(slot);
445 dbg("%s - slot %s HS_CSR (2) = %04x",
446 __FUNCTION__, slot->hotplug_slot->name, hs_csr);
447
448 if(update_latch_status(slot->hotplug_slot, 1)) {
449 warn("failure to update latch file");
450 }
451
452 if(update_adapter_status(slot->hotplug_slot, 1)) {
453 warn("failure to update adapter file");
454 }
455
456 cpci_led_off(slot);
457
458 /* GSM, debug */
459 hs_csr = cpci_get_hs_csr(slot);
460 dbg("%s - slot %s HS_CSR (3) = %04x",
461 __FUNCTION__, slot->hotplug_slot->name, hs_csr);
462
463 inserted++;
464 } else if(cpci_check_ext(slot)) {
465 u16 hs_csr;
466
467 /* Process extraction request */
468 dbg("%s - slot %s extracted",
469 __FUNCTION__, slot->hotplug_slot->name);
470
471 /* GSM, debug */
472 hs_csr = cpci_get_hs_csr(slot);
473 dbg("%s - slot %s HS_CSR = %04x",
474 __FUNCTION__, slot->hotplug_slot->name, hs_csr);
475
476 if(!slot->extracting) {
477 if(update_latch_status(slot->hotplug_slot, 0)) {
478 warn("failure to update latch file");
479 }
480 slot->extracting = 1;
481 }
482 extracted++;
483 }
484 }
485 spin_unlock(&list_lock);
486 if(inserted || extracted) {
487 return extracted;
488 }
489 else {
490 err("cannot find ENUM# source, shutting down");
491 return -1;
492 }
493}
494
495/* This is the interrupt mode worker thread body */
496static int
497event_thread(void *data)
498{
499 int rc;
500 struct slot *slot;
501 struct list_head *tmp;
502
503 lock_kernel();
504 daemonize("cpci_hp_eventd");
505 unlock_kernel();
506
507 dbg("%s - event thread started", __FUNCTION__);
508 while(1) {
509 dbg("event thread sleeping");
510 down_interruptible(&event_semaphore);
511 dbg("event thread woken, thread_finished = %d",
512 thread_finished);
513 if(thread_finished || signal_pending(current))
514 break;
515 while(controller->ops->query_enum()) {
516 rc = check_slots();
517 if (rc > 0)
518 /* Give userspace a chance to handle extraction */
519 msleep(500);
520 else if (rc < 0) {
521 dbg("%s - error checking slots", __FUNCTION__);
522 thread_finished = 1;
523 break;
524 }
525 }
526 /* Check for someone yanking out a board */
527 list_for_each(tmp, &slot_list) {
528 slot = list_entry(tmp, struct slot, slot_list);
529 if(slot->extracting) {
530 /*
531 * Hmmm, we're likely hosed at this point, should we
532 * bother trying to tell the driver or not?
533 */
534 err("card in slot %s was improperly removed",
535 slot->hotplug_slot->name);
536 if(update_adapter_status(slot->hotplug_slot, 0)) {
537 warn("failure to update adapter file");
538 }
539 slot->extracting = 0;
540 }
541 }
542
543 /* Re-enable ENUM# interrupt */
544 dbg("%s - re-enabling irq", __FUNCTION__);
545 controller->ops->enable_irq();
546 }
547
548 dbg("%s - event thread signals exit", __FUNCTION__);
549 up(&thread_exit);
550 return 0;
551}
552
553/* This is the polling mode worker thread body */
554static int
555poll_thread(void *data)
556{
557 int rc;
558 struct slot *slot;
559 struct list_head *tmp;
560
561 lock_kernel();
562 daemonize("cpci_hp_polld");
563 unlock_kernel();
564
565 while(1) {
566 if(thread_finished || signal_pending(current))
567 break;
568
569 while(controller->ops->query_enum()) {
570 rc = check_slots();
571 if(rc > 0)
572 /* Give userspace a chance to handle extraction */
573 msleep(500);
574 else if (rc < 0) {
575 dbg("%s - error checking slots", __FUNCTION__);
576 thread_finished = 1;
577 break;
578 }
579 }
580 /* Check for someone yanking out a board */
581 list_for_each(tmp, &slot_list) {
582 slot = list_entry(tmp, struct slot, slot_list);
583 if(slot->extracting) {
584 /*
585 * Hmmm, we're likely hosed at this point, should we
586 * bother trying to tell the driver or not?
587 */
588 err("card in slot %s was improperly removed",
589 slot->hotplug_slot->name);
590 if(update_adapter_status(slot->hotplug_slot, 0)) {
591 warn("failure to update adapter file");
592 }
593 slot->extracting = 0;
594 }
595 }
596
597 msleep(100);
598 }
599 dbg("poll thread signals exit");
600 up(&thread_exit);
601 return 0;
602}
603
604static int
605cpci_start_thread(void)
606{
607 int pid;
608
609 /* initialize our semaphores */
610 init_MUTEX_LOCKED(&event_semaphore);
611 init_MUTEX_LOCKED(&thread_exit);
612 thread_finished = 0;
613
614 if(controller->irq) {
615 pid = kernel_thread(event_thread, NULL, 0);
616 } else {
617 pid = kernel_thread(poll_thread, NULL, 0);
618 }
619 if(pid < 0) {
620 err("Can't start up our thread");
621 return -1;
622 }
623 dbg("Our thread pid = %d", pid);
624 return 0;
625}
626
627static void
628cpci_stop_thread(void)
629{
630 thread_finished = 1;
631 dbg("thread finish command given");
632 if(controller->irq) {
633 up(&event_semaphore);
634 }
635 dbg("wait for thread to exit");
636 down(&thread_exit);
637}
638
639int
640cpci_hp_register_controller(struct cpci_hp_controller *new_controller)
641{
642 int status = 0;
643
644 if(!controller) {
645 controller = new_controller;
646 if(controller->irq) {
647 if(request_irq(controller->irq,
648 cpci_hp_intr,
649 controller->irq_flags,
650 MY_NAME, controller->dev_id)) {
651 err("Can't get irq %d for the hotplug cPCI controller", controller->irq);
652 status = -ENODEV;
653 }
654 dbg("%s - acquired controller irq %d", __FUNCTION__,
655 controller->irq);
656 }
657 } else {
658 err("cPCI hotplug controller already registered");
659 status = -1;
660 }
661 return status;
662}
663
664int
665cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller)
666{
667 int status = 0;
668
669 if(controller) {
670 if(!thread_finished) {
671 cpci_stop_thread();
672 }
673 if(controller->irq) {
674 free_irq(controller->irq, controller->dev_id);
675 }
676 controller = NULL;
677 } else {
678 status = -ENODEV;
679 }
680 return status;
681}
682
683int
684cpci_hp_start(void)
685{
686 static int first = 1;
687 int status;
688
689 dbg("%s - enter", __FUNCTION__);
690 if(!controller) {
691 return -ENODEV;
692 }
693
694 spin_lock(&list_lock);
695 if(!slots) {
696 spin_unlock(&list_lock);
697 return -ENODEV;
698 }
699 spin_unlock(&list_lock);
700
701 if(first) {
702 status = init_slots();
703 if(status) {
704 return status;
705 }
706 first = 0;
707 }
708
709 status = cpci_start_thread();
710 if(status) {
711 return status;
712 }
713 dbg("%s - thread started", __FUNCTION__);
714
715 if(controller->irq) {
716 /* Start enum interrupt processing */
717 dbg("%s - enabling irq", __FUNCTION__);
718 controller->ops->enable_irq();
719 }
720 dbg("%s - exit", __FUNCTION__);
721 return 0;
722}
723
724int
725cpci_hp_stop(void)
726{
727 if(!controller) {
728 return -ENODEV;
729 }
730
731 if(controller->irq) {
732 /* Stop enum interrupt processing */
733 dbg("%s - disabling irq", __FUNCTION__);
734 controller->ops->disable_irq();
735 }
736 cpci_stop_thread();
737 return 0;
738}
739
740static void __exit
741cleanup_slots(void)
742{
743 struct list_head *tmp;
744 struct slot *slot;
745
746 /*
747 * Unregister all of our slots with the pci_hotplug subsystem,
748 * and free up all memory that we had allocated.
749 */
750 spin_lock(&list_lock);
751 if(!slots) {
752 goto null_cleanup;
753 }
754 list_for_each(tmp, &slot_list) {
755 slot = list_entry(tmp, struct slot, slot_list);
756 list_del(&slot->slot_list);
757 pci_hp_deregister(slot->hotplug_slot);
758 kfree(slot->hotplug_slot->info);
759 kfree(slot->hotplug_slot->name);
760 kfree(slot->hotplug_slot);
761 kfree(slot);
762 }
763 null_cleanup:
764 spin_unlock(&list_lock);
765 return;
766}
767
768int __init
769cpci_hotplug_init(int debug)
770{
771 spin_lock_init(&list_lock);
772 cpci_debug = debug;
773
774 info(DRIVER_DESC " version: " DRIVER_VERSION);
775 return 0;
776}
777
778void __exit
779cpci_hotplug_exit(void)
780{
781 /*
782 * Clean everything up.
783 */
784 cleanup_slots();
785}
786
787EXPORT_SYMBOL_GPL(cpci_hp_register_controller);
788EXPORT_SYMBOL_GPL(cpci_hp_unregister_controller);
789EXPORT_SYMBOL_GPL(cpci_hp_register_bus);
790EXPORT_SYMBOL_GPL(cpci_hp_unregister_bus);
791EXPORT_SYMBOL_GPL(cpci_hp_start);
792EXPORT_SYMBOL_GPL(cpci_hp_stop);
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c
new file mode 100644
index 000000000000..2e969616f298
--- /dev/null
+++ b/drivers/pci/hotplug/cpci_hotplug_pci.c
@@ -0,0 +1,661 @@
1/*
2 * CompactPCI Hot Plug Driver PCI functions
3 *
4 * Copyright (C) 2002 by SOMA Networks, Inc.
5 *
6 * All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
16 * NON INFRINGEMENT. See the GNU General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 * Send feedback to <scottm@somanetworks.com>
24 */
25
26#include <linux/config.h>
27#include <linux/module.h>
28#include <linux/kernel.h>
29#include <linux/pci.h>
30#include <linux/proc_fs.h>
31#include "../pci.h"
32#include "pci_hotplug.h"
33#include "cpci_hotplug.h"
34
35#if !defined(MODULE)
36#define MY_NAME "cpci_hotplug"
37#else
38#define MY_NAME THIS_MODULE->name
39#endif
40
41extern int cpci_debug;
42
43#define dbg(format, arg...) \
44 do { \
45 if(cpci_debug) \
46 printk (KERN_DEBUG "%s: " format "\n", \
47 MY_NAME , ## arg); \
48 } while(0)
49#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
50#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
51#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
52
53#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1))
54
55
56u8 cpci_get_attention_status(struct slot* slot)
57{
58 int hs_cap;
59 u16 hs_csr;
60
61 hs_cap = pci_bus_find_capability(slot->bus,
62 slot->devfn,
63 PCI_CAP_ID_CHSWP);
64 if(!hs_cap) {
65 return 0;
66 }
67
68 if(pci_bus_read_config_word(slot->bus,
69 slot->devfn,
70 hs_cap + 2,
71 &hs_csr)) {
72 return 0;
73 }
74 return hs_csr & 0x0008 ? 1 : 0;
75}
76
77int cpci_set_attention_status(struct slot* slot, int status)
78{
79 int hs_cap;
80 u16 hs_csr;
81
82 hs_cap = pci_bus_find_capability(slot->bus,
83 slot->devfn,
84 PCI_CAP_ID_CHSWP);
85 if(!hs_cap) {
86 return 0;
87 }
88
89 if(pci_bus_read_config_word(slot->bus,
90 slot->devfn,
91 hs_cap + 2,
92 &hs_csr)) {
93 return 0;
94 }
95 if(status) {
96 hs_csr |= HS_CSR_LOO;
97 } else {
98 hs_csr &= ~HS_CSR_LOO;
99 }
100 if(pci_bus_write_config_word(slot->bus,
101 slot->devfn,
102 hs_cap + 2,
103 hs_csr)) {
104 return 0;
105 }
106 return 1;
107}
108
109u16 cpci_get_hs_csr(struct slot* slot)
110{
111 int hs_cap;
112 u16 hs_csr;
113
114 hs_cap = pci_bus_find_capability(slot->bus,
115 slot->devfn,
116 PCI_CAP_ID_CHSWP);
117 if(!hs_cap) {
118 return 0xFFFF;
119 }
120
121 if(pci_bus_read_config_word(slot->bus,
122 slot->devfn,
123 hs_cap + 2,
124 &hs_csr)) {
125 return 0xFFFF;
126 }
127 return hs_csr;
128}
129
130#if 0
131u16 cpci_set_hs_csr(struct slot* slot, u16 hs_csr)
132{
133 int hs_cap;
134 u16 new_hs_csr;
135
136 hs_cap = pci_bus_find_capability(slot->bus,
137 slot->devfn,
138 PCI_CAP_ID_CHSWP);
139 if(!hs_cap) {
140 return 0xFFFF;
141 }
142
143 /* Write out the new value */
144 if(pci_bus_write_config_word(slot->bus,
145 slot->devfn,
146 hs_cap + 2,
147 hs_csr)) {
148 return 0xFFFF;
149 }
150
151 /* Read back what we just wrote out */
152 if(pci_bus_read_config_word(slot->bus,
153 slot->devfn,
154 hs_cap + 2,
155 &new_hs_csr)) {
156 return 0xFFFF;
157 }
158 return new_hs_csr;
159}
160#endif
161
162int cpci_check_and_clear_ins(struct slot* slot)
163{
164 int hs_cap;
165 u16 hs_csr;
166 int ins = 0;
167
168 hs_cap = pci_bus_find_capability(slot->bus,
169 slot->devfn,
170 PCI_CAP_ID_CHSWP);
171 if(!hs_cap) {
172 return 0;
173 }
174 if(pci_bus_read_config_word(slot->bus,
175 slot->devfn,
176 hs_cap + 2,
177 &hs_csr)) {
178 return 0;
179 }
180 if(hs_csr & HS_CSR_INS) {
181 /* Clear INS (by setting it) */
182 if(pci_bus_write_config_word(slot->bus,
183 slot->devfn,
184 hs_cap + 2,
185 hs_csr)) {
186 ins = 0;
187 }
188 ins = 1;
189 }
190 return ins;
191}
192
193int cpci_check_ext(struct slot* slot)
194{
195 int hs_cap;
196 u16 hs_csr;
197 int ext = 0;
198
199 hs_cap = pci_bus_find_capability(slot->bus,
200 slot->devfn,
201 PCI_CAP_ID_CHSWP);
202 if(!hs_cap) {
203 return 0;
204 }
205 if(pci_bus_read_config_word(slot->bus,
206 slot->devfn,
207 hs_cap + 2,
208 &hs_csr)) {
209 return 0;
210 }
211 if(hs_csr & HS_CSR_EXT) {
212 ext = 1;
213 }
214 return ext;
215}
216
217int cpci_clear_ext(struct slot* slot)
218{
219 int hs_cap;
220 u16 hs_csr;
221
222 hs_cap = pci_bus_find_capability(slot->bus,
223 slot->devfn,
224 PCI_CAP_ID_CHSWP);
225 if(!hs_cap) {
226 return -ENODEV;
227 }
228 if(pci_bus_read_config_word(slot->bus,
229 slot->devfn,
230 hs_cap + 2,
231 &hs_csr)) {
232 return -ENODEV;
233 }
234 if(hs_csr & HS_CSR_EXT) {
235 /* Clear EXT (by setting it) */
236 if(pci_bus_write_config_word(slot->bus,
237 slot->devfn,
238 hs_cap + 2,
239 hs_csr)) {
240 return -ENODEV;
241 }
242 }
243 return 0;
244}
245
246int cpci_led_on(struct slot* slot)
247{
248 int hs_cap;
249 u16 hs_csr;
250
251 hs_cap = pci_bus_find_capability(slot->bus,
252 slot->devfn,
253 PCI_CAP_ID_CHSWP);
254 if(!hs_cap) {
255 return -ENODEV;
256 }
257 if(pci_bus_read_config_word(slot->bus,
258 slot->devfn,
259 hs_cap + 2,
260 &hs_csr)) {
261 return -ENODEV;
262 }
263 if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) {
264 /* Set LOO */
265 hs_csr |= HS_CSR_LOO;
266 if(pci_bus_write_config_word(slot->bus,
267 slot->devfn,
268 hs_cap + 2,
269 hs_csr)) {
270 err("Could not set LOO for slot %s",
271 slot->hotplug_slot->name);
272 return -ENODEV;
273 }
274 }
275 return 0;
276}
277
278int cpci_led_off(struct slot* slot)
279{
280 int hs_cap;
281 u16 hs_csr;
282
283 hs_cap = pci_bus_find_capability(slot->bus,
284 slot->devfn,
285 PCI_CAP_ID_CHSWP);
286 if(!hs_cap) {
287 return -ENODEV;
288 }
289 if(pci_bus_read_config_word(slot->bus,
290 slot->devfn,
291 hs_cap + 2,
292 &hs_csr)) {
293 return -ENODEV;
294 }
295 if(hs_csr & HS_CSR_LOO) {
296 /* Clear LOO */
297 hs_csr &= ~HS_CSR_LOO;
298 if(pci_bus_write_config_word(slot->bus,
299 slot->devfn,
300 hs_cap + 2,
301 hs_csr)) {
302 err("Could not clear LOO for slot %s",
303 slot->hotplug_slot->name);
304 return -ENODEV;
305 }
306 }
307 return 0;
308}
309
310
311/*
312 * Device configuration functions
313 */
314
315static int cpci_configure_dev(struct pci_bus *bus, struct pci_dev *dev)
316{
317 u8 irq_pin;
318 int r;
319
320 dbg("%s - enter", __FUNCTION__);
321
322 /* NOTE: device already setup from prior scan */
323
324 /* FIXME: How would we know if we need to enable the expansion ROM? */
325 pci_write_config_word(dev, PCI_ROM_ADDRESS, 0x00L);
326
327 /* Assign resources */
328 dbg("assigning resources for %02x:%02x.%x",
329 dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
330 for (r = 0; r < 6; r++) {
331 struct resource *res = dev->resource + r;
332 if(res->flags)
333 pci_assign_resource(dev, r);
334 }
335 dbg("finished assigning resources for %02x:%02x.%x",
336 dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
337
338 /* Does this function have an interrupt at all? */
339 dbg("checking for function interrupt");
340 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
341 if(irq_pin) {
342 dbg("function uses interrupt pin %d", irq_pin);
343 }
344
345 /*
346 * Need to explicitly set irq field to 0 so that it'll get assigned
347 * by the pcibios platform dependent code called by pci_enable_device.
348 */
349 dev->irq = 0;
350
351 dbg("enabling device");
352 pci_enable_device(dev); /* XXX check return */
353 dbg("now dev->irq = %d", dev->irq);
354 if(irq_pin && dev->irq) {
355 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
356 }
357
358 /* Can't use pci_insert_device at the moment, do it manually for now */
359 pci_proc_attach_device(dev);
360 dbg("notifying drivers");
361 //pci_announce_device_to_drivers(dev);
362 dbg("%s - exit", __FUNCTION__);
363 return 0;
364}
365
366static int cpci_configure_bridge(struct pci_bus* bus, struct pci_dev* dev)
367{
368 int rc;
369 struct pci_bus* child;
370 struct resource* r;
371 u8 max, n;
372 u16 command;
373
374 dbg("%s - enter", __FUNCTION__);
375
376 /* Do basic bridge initialization */
377 rc = pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40);
378 if(rc) {
379 printk(KERN_ERR "%s - write of PCI_LATENCY_TIMER failed\n", __FUNCTION__);
380 }
381 rc = pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 0x40);
382 if(rc) {
383 printk(KERN_ERR "%s - write of PCI_SEC_LATENCY_TIMER failed\n", __FUNCTION__);
384 }
385 rc = pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4);
386 if(rc) {
387 printk(KERN_ERR "%s - write of PCI_CACHE_LINE_SIZE failed\n", __FUNCTION__);
388 }
389
390 /*
391 * Set parent bridge's subordinate field so that configuration space
392 * access will work in pci_scan_bridge and friends.
393 */
394 max = pci_max_busnr();
395 bus->subordinate = max + 1;
396 pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, max + 1);
397
398 /* Scan behind bridge */
399 n = pci_scan_bridge(bus, dev, max, 2);
400 child = pci_find_bus(0, max + 1);
401 if (!child)
402 return -ENODEV;
403 pci_proc_attach_bus(child);
404
405 /*
406 * Update parent bridge's subordinate field if there were more bridges
407 * behind the bridge that was scanned.
408 */
409 if(n > max) {
410 bus->subordinate = n;
411 pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, n);
412 }
413
414 /*
415 * Update the bridge resources of the bridge to accommodate devices
416 * behind it.
417 */
418 pci_bus_size_bridges(child);
419 pci_bus_assign_resources(child);
420
421 /* Enable resource mapping via command register */
422 command = PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
423 r = child->resource[0];
424 if(r && r->start) {
425 command |= PCI_COMMAND_IO;
426 }
427 r = child->resource[1];
428 if(r && r->start) {
429 command |= PCI_COMMAND_MEMORY;
430 }
431 r = child->resource[2];
432 if(r && r->start) {
433 command |= PCI_COMMAND_MEMORY;
434 }
435 rc = pci_write_config_word(dev, PCI_COMMAND, command);
436 if(rc) {
437 err("Error setting command register");
438 return rc;
439 }
440
441 /* Set bridge control register */
442 command = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA;
443 rc = pci_write_config_word(dev, PCI_BRIDGE_CONTROL, command);
444 if(rc) {
445 err("Error setting bridge control register");
446 return rc;
447 }
448 dbg("%s - exit", __FUNCTION__);
449 return 0;
450}
451
452static int configure_visit_pci_dev(struct pci_dev_wrapped *wrapped_dev,
453 struct pci_bus_wrapped *wrapped_bus)
454{
455 int rc;
456 struct pci_dev *dev = wrapped_dev->dev;
457 struct pci_bus *bus = wrapped_bus->bus;
458 struct slot* slot;
459
460 dbg("%s - enter", __FUNCTION__);
461
462 /*
463 * We need to fix up the hotplug representation with the Linux
464 * representation.
465 */
466 if(wrapped_dev->data) {
467 slot = (struct slot*) wrapped_dev->data;
468 slot->dev = dev;
469 }
470
471 /* If it's a bridge, scan behind it for devices */
472 if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
473 rc = cpci_configure_bridge(bus, dev);
474 if(rc)
475 return rc;
476 }
477
478 /* Actually configure device */
479 if(dev) {
480 rc = cpci_configure_dev(bus, dev);
481 if(rc)
482 return rc;
483 }
484 dbg("%s - exit", __FUNCTION__);
485 return 0;
486}
487
488static int unconfigure_visit_pci_dev_phase2(struct pci_dev_wrapped *wrapped_dev,
489 struct pci_bus_wrapped *wrapped_bus)
490{
491 struct pci_dev *dev = wrapped_dev->dev;
492 struct slot* slot;
493
494 dbg("%s - enter", __FUNCTION__);
495 if(!dev)
496 return -ENODEV;
497
498 /* Remove the Linux representation */
499 if(pci_remove_device_safe(dev)) {
500 err("Could not remove device\n");
501 return -1;
502 }
503
504 /*
505 * Now remove the hotplug representation.
506 */
507 if(wrapped_dev->data) {
508 slot = (struct slot*) wrapped_dev->data;
509 slot->dev = NULL;
510 } else {
511 dbg("No hotplug representation for %02x:%02x.%x",
512 dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
513 }
514 dbg("%s - exit", __FUNCTION__);
515 return 0;
516}
517
518static int unconfigure_visit_pci_bus_phase2(struct pci_bus_wrapped *wrapped_bus,
519 struct pci_dev_wrapped *wrapped_dev)
520{
521 struct pci_bus *bus = wrapped_bus->bus;
522 struct pci_bus *parent = bus->self->bus;
523
524 dbg("%s - enter", __FUNCTION__);
525
526 /* The cleanup code for proc entries regarding buses should be in the kernel... */
527 if(bus->procdir)
528 dbg("detach_pci_bus %s", bus->procdir->name);
529 pci_proc_detach_bus(bus);
530
531 /* The cleanup code should live in the kernel... */
532 bus->self->subordinate = NULL;
533
534 /* unlink from parent bus */
535 list_del(&bus->node);
536
537 /* Now, remove */
538 if(bus)
539 kfree(bus);
540
541 /* Update parent's subordinate field */
542 if(parent) {
543 u8 n = pci_bus_max_busnr(parent);
544 if(n < parent->subordinate) {
545 parent->subordinate = n;
546 pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, n);
547 }
548 }
549 dbg("%s - exit", __FUNCTION__);
550 return 0;
551}
552
553static struct pci_visit configure_functions = {
554 .visit_pci_dev = configure_visit_pci_dev,
555};
556
557static struct pci_visit unconfigure_functions_phase2 = {
558 .post_visit_pci_bus = unconfigure_visit_pci_bus_phase2,
559 .post_visit_pci_dev = unconfigure_visit_pci_dev_phase2
560};
561
562
563int cpci_configure_slot(struct slot* slot)
564{
565 int rc = 0;
566
567 dbg("%s - enter", __FUNCTION__);
568
569 if(slot->dev == NULL) {
570 dbg("pci_dev null, finding %02x:%02x:%x",
571 slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn));
572 slot->dev = pci_find_slot(slot->bus->number, slot->devfn);
573 }
574
575 /* Still NULL? Well then scan for it! */
576 if(slot->dev == NULL) {
577 int n;
578 dbg("pci_dev still null");
579
580 /*
581 * This will generate pci_dev structures for all functions, but
582 * we will only call this case when lookup fails.
583 */
584 n = pci_scan_slot(slot->bus, slot->devfn);
585 dbg("%s: pci_scan_slot returned %d", __FUNCTION__, n);
586 if(n > 0)
587 pci_bus_add_devices(slot->bus);
588 slot->dev = pci_find_slot(slot->bus->number, slot->devfn);
589 if(slot->dev == NULL) {
590 err("Could not find PCI device for slot %02x", slot->number);
591 return 0;
592 }
593 }
594 dbg("slot->dev = %p", slot->dev);
595 if(slot->dev) {
596 struct pci_dev *dev;
597 struct pci_dev_wrapped wrapped_dev;
598 struct pci_bus_wrapped wrapped_bus;
599 int i;
600
601 memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
602 memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
603
604 for (i = 0; i < 8; i++) {
605 dev = pci_find_slot(slot->bus->number,
606 PCI_DEVFN(PCI_SLOT(slot->dev->devfn), i));
607 if(!dev)
608 continue;
609 wrapped_dev.dev = dev;
610 wrapped_bus.bus = slot->dev->bus;
611 if(i)
612 wrapped_dev.data = NULL;
613 else
614 wrapped_dev.data = (void*) slot;
615 rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
616 }
617 }
618
619 dbg("%s - exit, rc = %d", __FUNCTION__, rc);
620 return rc;
621}
622
623int cpci_unconfigure_slot(struct slot* slot)
624{
625 int rc = 0;
626 int i;
627 struct pci_dev_wrapped wrapped_dev;
628 struct pci_bus_wrapped wrapped_bus;
629 struct pci_dev *dev;
630
631 dbg("%s - enter", __FUNCTION__);
632
633 if(!slot->dev) {
634 err("No device for slot %02x\n", slot->number);
635 return -ENODEV;
636 }
637
638 memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
639 memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
640
641 for (i = 0; i < 8; i++) {
642 dev = pci_find_slot(slot->bus->number,
643 PCI_DEVFN(PCI_SLOT(slot->devfn), i));
644 if(dev) {
645 wrapped_dev.dev = dev;
646 wrapped_bus.bus = dev->bus;
647 if(i)
648 wrapped_dev.data = NULL;
649 else
650 wrapped_dev.data = (void*) slot;
651 dbg("%s - unconfigure phase 2", __FUNCTION__);
652 rc = pci_visit_dev(&unconfigure_functions_phase2,
653 &wrapped_dev,
654 &wrapped_bus);
655 if(rc)
656 break;
657 }
658 }
659 dbg("%s - exit, rc = %d", __FUNCTION__, rc);
660 return rc;
661}
diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c
new file mode 100644
index 000000000000..a62a4345b466
--- /dev/null
+++ b/drivers/pci/hotplug/cpcihp_generic.c
@@ -0,0 +1,223 @@
1/*
2 * cpcihp_generic.c
3 *
4 * Generic port I/O CompactPCI driver
5 *
6 * Copyright 2002 SOMA Networks, Inc.
7 * Copyright 2001 Intel San Luis Obispo
8 * Copyright 2000,2001 MontaVista Software Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
16 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 *
30 * This generic CompactPCI hotplug driver should allow using the PCI hotplug
31 * mechanism on any CompactPCI board that exposes the #ENUM signal as a bit
32 * in a system register that can be read through standard port I/O.
33 *
34 * Send feedback to <scottm@somanetworks.com>
35 */
36
37#include <linux/config.h>
38#include <linux/module.h>
39#include <linux/init.h>
40#include <linux/errno.h>
41#include <linux/pci.h>
42#include "cpci_hotplug.h"
43
44#define DRIVER_VERSION "0.1"
45#define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>"
46#define DRIVER_DESC "Generic port I/O CompactPCI Hot Plug Driver"
47
48#if !defined(MODULE)
49#define MY_NAME "cpcihp_generic"
50#else
51#define MY_NAME THIS_MODULE->name
52#endif
53
54#define dbg(format, arg...) \
55 do { \
56 if(debug) \
57 printk (KERN_DEBUG "%s: " format "\n", \
58 MY_NAME , ## arg); \
59 } while(0)
60#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
61#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
62#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
63
64/* local variables */
65static int debug;
66static char *bridge;
67static u8 bridge_busnr;
68static u8 bridge_slot;
69static struct pci_bus *bus;
70static u8 first_slot;
71static u8 last_slot;
72static u16 port;
73static unsigned int enum_bit;
74static u8 enum_mask;
75
76static struct cpci_hp_controller_ops generic_hpc_ops;
77static struct cpci_hp_controller generic_hpc;
78
79static int __init validate_parameters(void)
80{
81 char* str;
82 char* p;
83 unsigned long tmp;
84
85 if(!bridge) {
86 info("not configured, disabling.");
87 return 1;
88 }
89 str = bridge;
90 if(!*str)
91 return -EINVAL;
92
93 tmp = simple_strtoul(str, &p, 16);
94 if(p == str || tmp > 0xff) {
95 err("Invalid hotplug bus bridge device bus number");
96 return -EINVAL;
97 }
98 bridge_busnr = (u8) tmp;
99 dbg("bridge_busnr = 0x%02x", bridge_busnr);
100 if(*p != ':') {
101 err("Invalid hotplug bus bridge device");
102 return -EINVAL;
103 }
104 str = p + 1;
105 tmp = simple_strtoul(str, &p, 16);
106 if(p == str || tmp > 0x1f) {
107 err("Invalid hotplug bus bridge device slot number");
108 return -EINVAL;
109 }
110 bridge_slot = (u8) tmp;
111 dbg("bridge_slot = 0x%02x", bridge_slot);
112
113 dbg("first_slot = 0x%02x", first_slot);
114 dbg("last_slot = 0x%02x", last_slot);
115 if(!(first_slot && last_slot)) {
116 err("Need to specify first_slot and last_slot");
117 return -EINVAL;
118 }
119 if(last_slot < first_slot) {
120 err("first_slot must be less than last_slot");
121 return -EINVAL;
122 }
123
124 dbg("port = 0x%04x", port);
125 dbg("enum_bit = 0x%02x", enum_bit);
126 if(enum_bit > 7) {
127 err("Invalid #ENUM bit");
128 return -EINVAL;
129 }
130 enum_mask = 1 << enum_bit;
131 return 0;
132}
133
134static int query_enum(void)
135{
136 u8 value;
137
138 value = inb_p(port);
139 return ((value & enum_mask) == enum_mask);
140}
141
142static int __init cpcihp_generic_init(void)
143{
144 int status;
145 struct resource* r;
146 struct pci_dev* dev;
147
148 info(DRIVER_DESC " version: " DRIVER_VERSION);
149 status = validate_parameters();
150 if(status != 0)
151 return status;
152
153 r = request_region(port, 1, "#ENUM hotswap signal register");
154 if(!r)
155 return -EBUSY;
156
157 dev = pci_find_slot(bridge_busnr, PCI_DEVFN(bridge_slot, 0));
158 if(!dev || dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
159 err("Invalid bridge device %s", bridge);
160 return -EINVAL;
161 }
162 bus = dev->subordinate;
163
164 memset(&generic_hpc, 0, sizeof (struct cpci_hp_controller));
165 generic_hpc_ops.query_enum = query_enum;
166 generic_hpc.ops = &generic_hpc_ops;
167
168 status = cpci_hp_register_controller(&generic_hpc);
169 if(status != 0) {
170 err("Could not register cPCI hotplug controller");
171 return -ENODEV;
172 }
173 dbg("registered controller");
174
175 status = cpci_hp_register_bus(bus, first_slot, last_slot);
176 if(status != 0) {
177 err("Could not register cPCI hotplug bus");
178 goto init_bus_register_error;
179 }
180 dbg("registered bus");
181
182 status = cpci_hp_start();
183 if(status != 0) {
184 err("Could not started cPCI hotplug system");
185 goto init_start_error;
186 }
187 dbg("started cpci hp system");
188 return 0;
189init_start_error:
190 cpci_hp_unregister_bus(bus);
191init_bus_register_error:
192 cpci_hp_unregister_controller(&generic_hpc);
193 err("status = %d", status);
194 return status;
195
196}
197
198static void __exit cpcihp_generic_exit(void)
199{
200 cpci_hp_stop();
201 cpci_hp_unregister_bus(bus);
202 cpci_hp_unregister_controller(&generic_hpc);
203 release_region(port, 1);
204}
205
206module_init(cpcihp_generic_init);
207module_exit(cpcihp_generic_exit);
208
209MODULE_AUTHOR(DRIVER_AUTHOR);
210MODULE_DESCRIPTION(DRIVER_DESC);
211MODULE_LICENSE("GPL");
212module_param(debug, bool, S_IRUGO | S_IWUSR);
213MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
214module_param(bridge, charp, 0);
215MODULE_PARM_DESC(bridge, "Hotswap bus bridge device, <bus>:<slot> (bus and slot are in hexadecimal)");
216module_param(first_slot, byte, 0);
217MODULE_PARM_DESC(first_slot, "Hotswap bus first slot number");
218module_param(last_slot, byte, 0);
219MODULE_PARM_DESC(last_slot, "Hotswap bus last slot number");
220module_param(port, ushort, 0);
221MODULE_PARM_DESC(port, "#ENUM signal I/O port");
222module_param(enum_bit, uint, 0);
223MODULE_PARM_DESC(enum_bit, "#ENUM signal bit (0-7)");
diff --git a/drivers/pci/hotplug/cpcihp_zt5550.c b/drivers/pci/hotplug/cpcihp_zt5550.c
new file mode 100644
index 000000000000..e9928024be78
--- /dev/null
+++ b/drivers/pci/hotplug/cpcihp_zt5550.c
@@ -0,0 +1,305 @@
1/*
2 * cpcihp_zt5550.c
3 *
4 * Intel/Ziatech ZT5550 CompactPCI Host Controller driver
5 *
6 * Copyright 2002 SOMA Networks, Inc.
7 * Copyright 2001 Intel San Luis Obispo
8 * Copyright 2000,2001 MontaVista Software Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
16 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 *
30 * Send feedback to <scottm@somanetworks.com>
31 */
32
33#include <linux/config.h>
34#include <linux/module.h>
35#include <linux/moduleparam.h>
36#include <linux/init.h>
37#include <linux/errno.h>
38#include <linux/pci.h>
39#include "cpci_hotplug.h"
40#include "cpcihp_zt5550.h"
41
42#define DRIVER_VERSION "0.2"
43#define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>"
44#define DRIVER_DESC "ZT5550 CompactPCI Hot Plug Driver"
45
46#define MY_NAME "cpcihp_zt5550"
47
48#define dbg(format, arg...) \
49 do { \
50 if(debug) \
51 printk (KERN_DEBUG "%s: " format "\n", \
52 MY_NAME , ## arg); \
53 } while(0)
54#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
55#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
56#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
57
58/* local variables */
59static int debug;
60static int poll;
61static struct cpci_hp_controller_ops zt5550_hpc_ops;
62static struct cpci_hp_controller zt5550_hpc;
63
64/* Primary cPCI bus bridge device */
65static struct pci_dev *bus0_dev;
66static struct pci_bus *bus0;
67
68/* Host controller device */
69static struct pci_dev *hc_dev;
70
71/* Host controller register addresses */
72static void __iomem *hc_registers;
73static void __iomem *csr_hc_index;
74static void __iomem *csr_hc_data;
75static void __iomem *csr_int_status;
76static void __iomem *csr_int_mask;
77
78
79static int zt5550_hc_config(struct pci_dev *pdev)
80{
81 /* Since we know that no boards exist with two HC chips, treat it as an error */
82 if(hc_dev) {
83 err("too many host controller devices?");
84 return -EBUSY;
85 }
86 hc_dev = pdev;
87 dbg("hc_dev = %p", hc_dev);
88 dbg("pci resource start %lx", pci_resource_start(hc_dev, 1));
89 dbg("pci resource len %lx", pci_resource_len(hc_dev, 1));
90
91 if(!request_mem_region(pci_resource_start(hc_dev, 1),
92 pci_resource_len(hc_dev, 1), MY_NAME)) {
93 err("cannot reserve MMIO region");
94 return -ENOMEM;
95 }
96
97 hc_registers =
98 ioremap(pci_resource_start(hc_dev, 1), pci_resource_len(hc_dev, 1));
99 if(!hc_registers) {
100 err("cannot remap MMIO region %lx @ %lx",
101 pci_resource_len(hc_dev, 1), pci_resource_start(hc_dev, 1));
102 release_mem_region(pci_resource_start(hc_dev, 1),
103 pci_resource_len(hc_dev, 1));
104 return -ENODEV;
105 }
106
107 csr_hc_index = hc_registers + CSR_HCINDEX;
108 csr_hc_data = hc_registers + CSR_HCDATA;
109 csr_int_status = hc_registers + CSR_INTSTAT;
110 csr_int_mask = hc_registers + CSR_INTMASK;
111
112 /*
113 * Disable host control, fault and serial interrupts
114 */
115 dbg("disabling host control, fault and serial interrupts");
116 writeb((u8) HC_INT_MASK_REG, csr_hc_index);
117 writeb((u8) ALL_INDEXED_INTS_MASK, csr_hc_data);
118 dbg("disabled host control, fault and serial interrupts");
119
120 /*
121 * Disable timer0, timer1 and ENUM interrupts
122 */
123 dbg("disabling timer0, timer1 and ENUM interrupts");
124 writeb((u8) ALL_DIRECT_INTS_MASK, csr_int_mask);
125 dbg("disabled timer0, timer1 and ENUM interrupts");
126 return 0;
127}
128
129static int zt5550_hc_cleanup(void)
130{
131 if(!hc_dev)
132 return -ENODEV;
133
134 iounmap(hc_registers);
135 release_mem_region(pci_resource_start(hc_dev, 1),
136 pci_resource_len(hc_dev, 1));
137 return 0;
138}
139
140static int zt5550_hc_query_enum(void)
141{
142 u8 value;
143
144 value = inb_p(ENUM_PORT);
145 return ((value & ENUM_MASK) == ENUM_MASK);
146}
147
148static int zt5550_hc_check_irq(void *dev_id)
149{
150 int ret;
151 u8 reg;
152
153 ret = 0;
154 if(dev_id == zt5550_hpc.dev_id) {
155 reg = readb(csr_int_status);
156 if(reg)
157 ret = 1;
158 }
159 return ret;
160}
161
162static int zt5550_hc_enable_irq(void)
163{
164 u8 reg;
165
166 if(hc_dev == NULL) {
167 return -ENODEV;
168 }
169 reg = readb(csr_int_mask);
170 reg = reg & ~ENUM_INT_MASK;
171 writeb(reg, csr_int_mask);
172 return 0;
173}
174
175static int zt5550_hc_disable_irq(void)
176{
177 u8 reg;
178
179 if(hc_dev == NULL) {
180 return -ENODEV;
181 }
182
183 reg = readb(csr_int_mask);
184 reg = reg | ENUM_INT_MASK;
185 writeb(reg, csr_int_mask);
186 return 0;
187}
188
189static int zt5550_hc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
190{
191 int status;
192
193 status = zt5550_hc_config(pdev);
194 if(status != 0) {
195 return status;
196 }
197 dbg("returned from zt5550_hc_config");
198
199 memset(&zt5550_hpc, 0, sizeof (struct cpci_hp_controller));
200 zt5550_hpc_ops.query_enum = zt5550_hc_query_enum;
201 zt5550_hpc.ops = &zt5550_hpc_ops;
202 if(!poll) {
203 zt5550_hpc.irq = hc_dev->irq;
204 zt5550_hpc.irq_flags = SA_SHIRQ;
205 zt5550_hpc.dev_id = hc_dev;
206
207 zt5550_hpc_ops.enable_irq = zt5550_hc_enable_irq;
208 zt5550_hpc_ops.disable_irq = zt5550_hc_disable_irq;
209 zt5550_hpc_ops.check_irq = zt5550_hc_check_irq;
210 } else {
211 info("using ENUM# polling mode");
212 }
213
214 status = cpci_hp_register_controller(&zt5550_hpc);
215 if(status != 0) {
216 err("could not register cPCI hotplug controller");
217 goto init_hc_error;
218 }
219 dbg("registered controller");
220
221 /* Look for first device matching cPCI bus's bridge vendor and device IDs */
222 if(!(bus0_dev = pci_get_device(PCI_VENDOR_ID_DEC,
223 PCI_DEVICE_ID_DEC_21154, NULL))) {
224 status = -ENODEV;
225 goto init_register_error;
226 }
227 bus0 = bus0_dev->subordinate;
228 pci_dev_put(bus0_dev);
229
230 status = cpci_hp_register_bus(bus0, 0x0a, 0x0f);
231 if(status != 0) {
232 err("could not register cPCI hotplug bus");
233 goto init_register_error;
234 }
235 dbg("registered bus");
236
237 status = cpci_hp_start();
238 if(status != 0) {
239 err("could not started cPCI hotplug system");
240 cpci_hp_unregister_bus(bus0);
241 goto init_register_error;
242 }
243 dbg("started cpci hp system");
244
245 return 0;
246init_register_error:
247 cpci_hp_unregister_controller(&zt5550_hpc);
248init_hc_error:
249 err("status = %d", status);
250 zt5550_hc_cleanup();
251 return status;
252
253}
254
255static void __devexit zt5550_hc_remove_one(struct pci_dev *pdev)
256{
257 cpci_hp_stop();
258 cpci_hp_unregister_bus(bus0);
259 cpci_hp_unregister_controller(&zt5550_hpc);
260 zt5550_hc_cleanup();
261}
262
263
264static struct pci_device_id zt5550_hc_pci_tbl[] = {
265 { PCI_VENDOR_ID_ZIATECH, PCI_DEVICE_ID_ZIATECH_5550_HC, PCI_ANY_ID, PCI_ANY_ID, },
266 { 0, }
267};
268MODULE_DEVICE_TABLE(pci, zt5550_hc_pci_tbl);
269
270static struct pci_driver zt5550_hc_driver = {
271 .name = "zt5550_hc",
272 .id_table = zt5550_hc_pci_tbl,
273 .probe = zt5550_hc_init_one,
274 .remove = __devexit_p(zt5550_hc_remove_one),
275};
276
277static int __init zt5550_init(void)
278{
279 struct resource* r;
280
281 info(DRIVER_DESC " version: " DRIVER_VERSION);
282 r = request_region(ENUM_PORT, 1, "#ENUM hotswap signal register");
283 if(!r)
284 return -EBUSY;
285
286 return pci_register_driver(&zt5550_hc_driver);
287}
288
289static void __exit
290zt5550_exit(void)
291{
292 pci_unregister_driver(&zt5550_hc_driver);
293 release_region(ENUM_PORT, 1);
294}
295
296module_init(zt5550_init);
297module_exit(zt5550_exit);
298
299MODULE_AUTHOR(DRIVER_AUTHOR);
300MODULE_DESCRIPTION(DRIVER_DESC);
301MODULE_LICENSE("GPL");
302module_param(debug, bool, 0644);
303MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
304module_param(poll, bool, 0644);
305MODULE_PARM_DESC(poll, "#ENUM polling mode enabled or not");
diff --git a/drivers/pci/hotplug/cpcihp_zt5550.h b/drivers/pci/hotplug/cpcihp_zt5550.h
new file mode 100644
index 000000000000..bebc6060a558
--- /dev/null
+++ b/drivers/pci/hotplug/cpcihp_zt5550.h
@@ -0,0 +1,79 @@
1/*
2 * cpcihp_zt5550.h
3 *
4 * Intel/Ziatech ZT5550 CompactPCI Host Controller driver definitions
5 *
6 * Copyright 2002 SOMA Networks, Inc.
7 * Copyright 2001 Intel San Luis Obispo
8 * Copyright 2000,2001 MontaVista Software Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
16 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 *
30 * Send feedback to <scottm@somanetworks.com>
31 */
32
33#ifndef _CPCIHP_ZT5550_H
34#define _CPCIHP_ZT5550_H
35
36/* Direct registers */
37#define CSR_HCINDEX 0x00
38#define CSR_HCDATA 0x04
39#define CSR_INTSTAT 0x08
40#define CSR_INTMASK 0x09
41#define CSR_CNT0CMD 0x0C
42#define CSR_CNT1CMD 0x0E
43#define CSR_CNT0 0x10
44#define CSR_CNT1 0x14
45
46/* Masks for interrupt bits in CSR_INTMASK direct register */
47#define CNT0_INT_MASK 0x01
48#define CNT1_INT_MASK 0x02
49#define ENUM_INT_MASK 0x04
50#define ALL_DIRECT_INTS_MASK 0x07
51
52/* Indexed registers (through CSR_INDEX, CSR_DATA) */
53#define HC_INT_MASK_REG 0x04
54#define HC_STATUS_REG 0x08
55#define HC_CMD_REG 0x0C
56#define ARB_CONFIG_GNT_REG 0x10
57#define ARB_CONFIG_CFG_REG 0x12
58#define ARB_CONFIG_REG 0x10
59#define ISOL_CONFIG_REG 0x18
60#define FAULT_STATUS_REG 0x20
61#define FAULT_CONFIG_REG 0x24
62#define WD_CONFIG_REG 0x2C
63#define HC_DIAG_REG 0x30
64#define SERIAL_COMM_REG 0x34
65#define SERIAL_OUT_REG 0x38
66#define SERIAL_IN_REG 0x3C
67
68/* Masks for interrupt bits in HC_INT_MASK_REG indexed register */
69#define SERIAL_INT_MASK 0x01
70#define FAULT_INT_MASK 0x02
71#define HCF_INT_MASK 0x04
72#define ALL_INDEXED_INTS_MASK 0x07
73
74/* Digital I/O port storing ENUM# */
75#define ENUM_PORT 0xE1
76/* Mask to get to the ENUM# bit on the bus */
77#define ENUM_MASK 0x40
78
79#endif /* _CPCIHP_ZT5550_H */
diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h
new file mode 100644
index 000000000000..092491e25ef2
--- /dev/null
+++ b/drivers/pci/hotplug/cpqphp.h
@@ -0,0 +1,721 @@
1/*
2 * Compaq Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <greg@kroah.com>
26 *
27 */
28#ifndef _CPQPHP_H
29#define _CPQPHP_H
30
31#include "pci_hotplug.h"
32#include <linux/interrupt.h>
33#include <asm/io.h> /* for read? and write? functions */
34#include <linux/delay.h> /* for delays */
35
36#define MY_NAME "cpqphp"
37
38#define dbg(fmt, arg...) do { if (cpqhp_debug) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
39#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
40#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
41#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
42
43
44
45struct smbios_system_slot {
46 u8 type;
47 u8 length;
48 u16 handle;
49 u8 name_string_num;
50 u8 slot_type;
51 u8 slot_width;
52 u8 slot_current_usage;
53 u8 slot_length;
54 u16 slot_number;
55 u8 properties1;
56 u8 properties2;
57} __attribute__ ((packed));
58
59/* offsets to the smbios generic type based on the above structure layout */
60enum smbios_system_slot_offsets {
61 SMBIOS_SLOT_GENERIC_TYPE = offsetof(struct smbios_system_slot, type),
62 SMBIOS_SLOT_GENERIC_LENGTH = offsetof(struct smbios_system_slot, length),
63 SMBIOS_SLOT_GENERIC_HANDLE = offsetof(struct smbios_system_slot, handle),
64 SMBIOS_SLOT_NAME_STRING_NUM = offsetof(struct smbios_system_slot, name_string_num),
65 SMBIOS_SLOT_TYPE = offsetof(struct smbios_system_slot, slot_type),
66 SMBIOS_SLOT_WIDTH = offsetof(struct smbios_system_slot, slot_width),
67 SMBIOS_SLOT_CURRENT_USAGE = offsetof(struct smbios_system_slot, slot_current_usage),
68 SMBIOS_SLOT_LENGTH = offsetof(struct smbios_system_slot, slot_length),
69 SMBIOS_SLOT_NUMBER = offsetof(struct smbios_system_slot, slot_number),
70 SMBIOS_SLOT_PROPERTIES1 = offsetof(struct smbios_system_slot, properties1),
71 SMBIOS_SLOT_PROPERTIES2 = offsetof(struct smbios_system_slot, properties2),
72};
73
74struct smbios_generic {
75 u8 type;
76 u8 length;
77 u16 handle;
78} __attribute__ ((packed));
79
80/* offsets to the smbios generic type based on the above structure layout */
81enum smbios_generic_offsets {
82 SMBIOS_GENERIC_TYPE = offsetof(struct smbios_generic, type),
83 SMBIOS_GENERIC_LENGTH = offsetof(struct smbios_generic, length),
84 SMBIOS_GENERIC_HANDLE = offsetof(struct smbios_generic, handle),
85};
86
87struct smbios_entry_point {
88 char anchor[4];
89 u8 ep_checksum;
90 u8 ep_length;
91 u8 major_version;
92 u8 minor_version;
93 u16 max_size_entry;
94 u8 ep_rev;
95 u8 reserved[5];
96 char int_anchor[5];
97 u8 int_checksum;
98 u16 st_length;
99 u32 st_address;
100 u16 number_of_entrys;
101 u8 bcd_rev;
102} __attribute__ ((packed));
103
104/* offsets to the smbios entry point based on the above structure layout */
105enum smbios_entry_point_offsets {
106 ANCHOR = offsetof(struct smbios_entry_point, anchor[0]),
107 EP_CHECKSUM = offsetof(struct smbios_entry_point, ep_checksum),
108 EP_LENGTH = offsetof(struct smbios_entry_point, ep_length),
109 MAJOR_VERSION = offsetof(struct smbios_entry_point, major_version),
110 MINOR_VERSION = offsetof(struct smbios_entry_point, minor_version),
111 MAX_SIZE_ENTRY = offsetof(struct smbios_entry_point, max_size_entry),
112 EP_REV = offsetof(struct smbios_entry_point, ep_rev),
113 INT_ANCHOR = offsetof(struct smbios_entry_point, int_anchor[0]),
114 INT_CHECKSUM = offsetof(struct smbios_entry_point, int_checksum),
115 ST_LENGTH = offsetof(struct smbios_entry_point, st_length),
116 ST_ADDRESS = offsetof(struct smbios_entry_point, st_address),
117 NUMBER_OF_ENTRYS = offsetof(struct smbios_entry_point, number_of_entrys),
118 BCD_REV = offsetof(struct smbios_entry_point, bcd_rev),
119};
120
121struct ctrl_reg { /* offset */
122 u8 slot_RST; /* 0x00 */
123 u8 slot_enable; /* 0x01 */
124 u16 misc; /* 0x02 */
125 u32 led_control; /* 0x04 */
126 u32 int_input_clear; /* 0x08 */
127 u32 int_mask; /* 0x0a */
128 u8 reserved0; /* 0x10 */
129 u8 reserved1; /* 0x11 */
130 u8 reserved2; /* 0x12 */
131 u8 gen_output_AB; /* 0x13 */
132 u32 non_int_input; /* 0x14 */
133 u32 reserved3; /* 0x18 */
134 u32 reserved4; /* 0x1a */
135 u32 reserved5; /* 0x20 */
136 u8 reserved6; /* 0x24 */
137 u8 reserved7; /* 0x25 */
138 u16 reserved8; /* 0x26 */
139 u8 slot_mask; /* 0x28 */
140 u8 reserved9; /* 0x29 */
141 u8 reserved10; /* 0x2a */
142 u8 reserved11; /* 0x2b */
143 u8 slot_SERR; /* 0x2c */
144 u8 slot_power; /* 0x2d */
145 u8 reserved12; /* 0x2e */
146 u8 reserved13; /* 0x2f */
147 u8 next_curr_freq; /* 0x30 */
148 u8 reset_freq_mode; /* 0x31 */
149} __attribute__ ((packed));
150
151/* offsets to the controller registers based on the above structure layout */
152enum ctrl_offsets {
153 SLOT_RST = offsetof(struct ctrl_reg, slot_RST),
154 SLOT_ENABLE = offsetof(struct ctrl_reg, slot_enable),
155 MISC = offsetof(struct ctrl_reg, misc),
156 LED_CONTROL = offsetof(struct ctrl_reg, led_control),
157 INT_INPUT_CLEAR = offsetof(struct ctrl_reg, int_input_clear),
158 INT_MASK = offsetof(struct ctrl_reg, int_mask),
159 CTRL_RESERVED0 = offsetof(struct ctrl_reg, reserved0),
160 CTRL_RESERVED1 = offsetof(struct ctrl_reg, reserved1),
161 CTRL_RESERVED2 = offsetof(struct ctrl_reg, reserved1),
162 GEN_OUTPUT_AB = offsetof(struct ctrl_reg, gen_output_AB),
163 NON_INT_INPUT = offsetof(struct ctrl_reg, non_int_input),
164 CTRL_RESERVED3 = offsetof(struct ctrl_reg, reserved3),
165 CTRL_RESERVED4 = offsetof(struct ctrl_reg, reserved4),
166 CTRL_RESERVED5 = offsetof(struct ctrl_reg, reserved5),
167 CTRL_RESERVED6 = offsetof(struct ctrl_reg, reserved6),
168 CTRL_RESERVED7 = offsetof(struct ctrl_reg, reserved7),
169 CTRL_RESERVED8 = offsetof(struct ctrl_reg, reserved8),
170 SLOT_MASK = offsetof(struct ctrl_reg, slot_mask),
171 CTRL_RESERVED9 = offsetof(struct ctrl_reg, reserved9),
172 CTRL_RESERVED10 = offsetof(struct ctrl_reg, reserved10),
173 CTRL_RESERVED11 = offsetof(struct ctrl_reg, reserved11),
174 SLOT_SERR = offsetof(struct ctrl_reg, slot_SERR),
175 SLOT_POWER = offsetof(struct ctrl_reg, slot_power),
176 NEXT_CURR_FREQ = offsetof(struct ctrl_reg, next_curr_freq),
177 RESET_FREQ_MODE = offsetof(struct ctrl_reg, reset_freq_mode),
178};
179
180struct hrt {
181 char sig0;
182 char sig1;
183 char sig2;
184 char sig3;
185 u16 unused_IRQ;
186 u16 PCIIRQ;
187 u8 number_of_entries;
188 u8 revision;
189 u16 reserved1;
190 u32 reserved2;
191} __attribute__ ((packed));
192
193/* offsets to the hotplug resource table registers based on the above structure layout */
194enum hrt_offsets {
195 SIG0 = offsetof(struct hrt, sig0),
196 SIG1 = offsetof(struct hrt, sig1),
197 SIG2 = offsetof(struct hrt, sig2),
198 SIG3 = offsetof(struct hrt, sig3),
199 UNUSED_IRQ = offsetof(struct hrt, unused_IRQ),
200 PCIIRQ = offsetof(struct hrt, PCIIRQ),
201 NUMBER_OF_ENTRIES = offsetof(struct hrt, number_of_entries),
202 REVISION = offsetof(struct hrt, revision),
203 HRT_RESERVED1 = offsetof(struct hrt, reserved1),
204 HRT_RESERVED2 = offsetof(struct hrt, reserved2),
205};
206
207struct slot_rt {
208 u8 dev_func;
209 u8 primary_bus;
210 u8 secondary_bus;
211 u8 max_bus;
212 u16 io_base;
213 u16 io_length;
214 u16 mem_base;
215 u16 mem_length;
216 u16 pre_mem_base;
217 u16 pre_mem_length;
218} __attribute__ ((packed));
219
220/* offsets to the hotplug slot resource table registers based on the above structure layout */
221enum slot_rt_offsets {
222 DEV_FUNC = offsetof(struct slot_rt, dev_func),
223 PRIMARY_BUS = offsetof(struct slot_rt, primary_bus),
224 SECONDARY_BUS = offsetof(struct slot_rt, secondary_bus),
225 MAX_BUS = offsetof(struct slot_rt, max_bus),
226 IO_BASE = offsetof(struct slot_rt, io_base),
227 IO_LENGTH = offsetof(struct slot_rt, io_length),
228 MEM_BASE = offsetof(struct slot_rt, mem_base),
229 MEM_LENGTH = offsetof(struct slot_rt, mem_length),
230 PRE_MEM_BASE = offsetof(struct slot_rt, pre_mem_base),
231 PRE_MEM_LENGTH = offsetof(struct slot_rt, pre_mem_length),
232};
233
234struct pci_func {
235 struct pci_func *next;
236 u8 bus;
237 u8 device;
238 u8 function;
239 u8 is_a_board;
240 u16 status;
241 u8 configured;
242 u8 switch_save;
243 u8 presence_save;
244 u32 base_length[0x06];
245 u8 base_type[0x06];
246 u16 reserved2;
247 u32 config_space[0x20];
248 struct pci_resource *mem_head;
249 struct pci_resource *p_mem_head;
250 struct pci_resource *io_head;
251 struct pci_resource *bus_head;
252 struct timer_list *p_task_event;
253 struct pci_dev* pci_dev;
254};
255
256struct slot {
257 struct slot *next;
258 u8 bus;
259 u8 device;
260 u8 number;
261 u8 is_a_board;
262 u8 configured;
263 u8 state;
264 u8 switch_save;
265 u8 presence_save;
266 u32 capabilities;
267 u16 reserved2;
268 struct timer_list task_event;
269 u8 hp_slot;
270 struct controller *ctrl;
271 void __iomem *p_sm_slot;
272 struct hotplug_slot *hotplug_slot;
273};
274
275struct pci_resource {
276 struct pci_resource * next;
277 u32 base;
278 u32 length;
279};
280
281struct event_info {
282 u32 event_type;
283 u8 hp_slot;
284};
285
286struct controller {
287 struct controller *next;
288 u32 ctrl_int_comp;
289 struct semaphore crit_sect; /* critical section semaphore */
290 void __iomem *hpc_reg; /* cookie for our pci controller location */
291 struct pci_resource *mem_head;
292 struct pci_resource *p_mem_head;
293 struct pci_resource *io_head;
294 struct pci_resource *bus_head;
295 struct pci_dev *pci_dev;
296 struct pci_bus *pci_bus;
297 struct event_info event_queue[10];
298 struct slot *slot;
299 u8 next_event;
300 u8 interrupt;
301 u8 cfgspc_irq;
302 u8 bus; /* bus number for the pci hotplug controller */
303 u8 rev;
304 u8 slot_device_offset;
305 u8 first_slot;
306 u8 add_support;
307 u8 push_flag;
308 enum pci_bus_speed speed;
309 enum pci_bus_speed speed_capability;
310 u8 push_button; /* 0 = no pushbutton, 1 = pushbutton present */
311 u8 slot_switch_type; /* 0 = no switch, 1 = switch present */
312 u8 defeature_PHP; /* 0 = PHP not supported, 1 = PHP supported */
313 u8 alternate_base_address; /* 0 = not supported, 1 = supported */
314 u8 pci_config_space; /* Index/data access to working registers 0 = not supported, 1 = supported */
315 u8 pcix_speed_capability; /* PCI-X */
316 u8 pcix_support; /* PCI-X */
317 u16 vendor_id;
318 struct work_struct int_task_event;
319 wait_queue_head_t queue; /* sleep & wake process */
320};
321
322struct irq_mapping {
323 u8 barber_pole;
324 u8 valid_INT;
325 u8 interrupt[4];
326};
327
328struct resource_lists {
329 struct pci_resource *mem_head;
330 struct pci_resource *p_mem_head;
331 struct pci_resource *io_head;
332 struct pci_resource *bus_head;
333 struct irq_mapping *irqs;
334};
335
336#define ROM_PHY_ADDR 0x0F0000
337#define ROM_PHY_LEN 0x00ffff
338
339#define PCI_HPC_ID 0xA0F7
340#define PCI_SUB_HPC_ID 0xA2F7
341#define PCI_SUB_HPC_ID2 0xA2F8
342#define PCI_SUB_HPC_ID3 0xA2F9
343#define PCI_SUB_HPC_ID_INTC 0xA2FA
344#define PCI_SUB_HPC_ID4 0xA2FD
345
346#define INT_BUTTON_IGNORE 0
347#define INT_PRESENCE_ON 1
348#define INT_PRESENCE_OFF 2
349#define INT_SWITCH_CLOSE 3
350#define INT_SWITCH_OPEN 4
351#define INT_POWER_FAULT 5
352#define INT_POWER_FAULT_CLEAR 6
353#define INT_BUTTON_PRESS 7
354#define INT_BUTTON_RELEASE 8
355#define INT_BUTTON_CANCEL 9
356
357#define STATIC_STATE 0
358#define BLINKINGON_STATE 1
359#define BLINKINGOFF_STATE 2
360#define POWERON_STATE 3
361#define POWEROFF_STATE 4
362
363#define PCISLOT_INTERLOCK_CLOSED 0x00000001
364#define PCISLOT_ADAPTER_PRESENT 0x00000002
365#define PCISLOT_POWERED 0x00000004
366#define PCISLOT_66_MHZ_OPERATION 0x00000008
367#define PCISLOT_64_BIT_OPERATION 0x00000010
368#define PCISLOT_REPLACE_SUPPORTED 0x00000020
369#define PCISLOT_ADD_SUPPORTED 0x00000040
370#define PCISLOT_INTERLOCK_SUPPORTED 0x00000080
371#define PCISLOT_66_MHZ_SUPPORTED 0x00000100
372#define PCISLOT_64_BIT_SUPPORTED 0x00000200
373
374#define PCI_TO_PCI_BRIDGE_CLASS 0x00060400
375
376#define INTERLOCK_OPEN 0x00000002
377#define ADD_NOT_SUPPORTED 0x00000003
378#define CARD_FUNCTIONING 0x00000005
379#define ADAPTER_NOT_SAME 0x00000006
380#define NO_ADAPTER_PRESENT 0x00000009
381#define NOT_ENOUGH_RESOURCES 0x0000000B
382#define DEVICE_TYPE_NOT_SUPPORTED 0x0000000C
383#define POWER_FAILURE 0x0000000E
384
385#define REMOVE_NOT_SUPPORTED 0x00000003
386
387
388/*
389 * error Messages
390 */
391#define msg_initialization_err "Initialization failure, error=%d\n"
392#define msg_HPC_rev_error "Unsupported revision of the PCI hot plug controller found.\n"
393#define msg_HPC_non_compaq_or_intel "The PCI hot plug controller is not supported by this driver.\n"
394#define msg_HPC_not_supported "this system is not supported by this version of cpqphpd. Upgrade to a newer version of cpqphpd\n"
395#define msg_unable_to_save "unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n"
396#define msg_button_on "PCI slot #%d - powering on due to button press.\n"
397#define msg_button_off "PCI slot #%d - powering off due to button press.\n"
398#define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n"
399#define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n"
400
401
402/* sysfs functions for the hotplug controller info */
403extern void cpqhp_create_ctrl_files (struct controller *ctrl);
404
405/* controller functions */
406extern void cpqhp_pushbutton_thread (unsigned long event_pointer);
407extern irqreturn_t cpqhp_ctrl_intr (int IRQ, void *data, struct pt_regs *regs);
408extern int cpqhp_find_available_resources (struct controller *ctrl, void __iomem *rom_start);
409extern int cpqhp_event_start_thread (void);
410extern void cpqhp_event_stop_thread (void);
411extern struct pci_func *cpqhp_slot_create (unsigned char busnumber);
412extern struct pci_func *cpqhp_slot_find (unsigned char bus, unsigned char device, unsigned char index);
413extern int cpqhp_process_SI (struct controller *ctrl, struct pci_func *func);
414extern int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func);
415extern int cpqhp_hardware_test (struct controller *ctrl, int test_num);
416
417/* resource functions */
418extern int cpqhp_resource_sort_and_combine (struct pci_resource **head);
419
420/* pci functions */
421extern int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);
422extern int cpqhp_get_bus_dev (struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot);
423extern int cpqhp_save_config (struct controller *ctrl, int busnumber, int is_hot_plug);
424extern int cpqhp_save_base_addr_length (struct controller *ctrl, struct pci_func * func);
425extern int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func);
426extern int cpqhp_configure_board (struct controller *ctrl, struct pci_func * func);
427extern int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot);
428extern int cpqhp_valid_replace (struct controller *ctrl, struct pci_func * func);
429extern void cpqhp_destroy_board_resources (struct pci_func * func);
430extern int cpqhp_return_board_resources (struct pci_func * func, struct resource_lists * resources);
431extern void cpqhp_destroy_resource_list (struct resource_lists * resources);
432extern int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func);
433extern int cpqhp_unconfigure_device (struct pci_func* func);
434
435/* Global variables */
436extern int cpqhp_debug;
437extern int cpqhp_legacy_mode;
438extern struct controller *cpqhp_ctrl_list;
439extern struct pci_func *cpqhp_slot_list[256];
440
441/* these can be gotten rid of, but for debugging they are purty */
442extern u8 cpqhp_nic_irq;
443extern u8 cpqhp_disk_irq;
444
445
446/* inline functions */
447
448/*
449 * return_resource
450 *
451 * Puts node back in the resource list pointed to by head
452 *
453 */
454static inline void return_resource(struct pci_resource **head, struct pci_resource *node)
455{
456 if (!node || !head)
457 return;
458 node->next = *head;
459 *head = node;
460}
461
462static inline void set_SOGO(struct controller *ctrl)
463{
464 u16 misc;
465
466 misc = readw(ctrl->hpc_reg + MISC);
467 misc = (misc | 0x0001) & 0xFFFB;
468 writew(misc, ctrl->hpc_reg + MISC);
469}
470
471
472static inline void amber_LED_on(struct controller *ctrl, u8 slot)
473{
474 u32 led_control;
475
476 led_control = readl(ctrl->hpc_reg + LED_CONTROL);
477 led_control |= (0x01010000L << slot);
478 writel(led_control, ctrl->hpc_reg + LED_CONTROL);
479}
480
481
482static inline void amber_LED_off(struct controller *ctrl, u8 slot)
483{
484 u32 led_control;
485
486 led_control = readl(ctrl->hpc_reg + LED_CONTROL);
487 led_control &= ~(0x01010000L << slot);
488 writel(led_control, ctrl->hpc_reg + LED_CONTROL);
489}
490
491
492static inline int read_amber_LED(struct controller *ctrl, u8 slot)
493{
494 u32 led_control;
495
496 led_control = readl(ctrl->hpc_reg + LED_CONTROL);
497 led_control &= (0x01010000L << slot);
498
499 return led_control ? 1 : 0;
500}
501
502
503static inline void green_LED_on(struct controller *ctrl, u8 slot)
504{
505 u32 led_control;
506
507 led_control = readl(ctrl->hpc_reg + LED_CONTROL);
508 led_control |= 0x0101L << slot;
509 writel(led_control, ctrl->hpc_reg + LED_CONTROL);
510}
511
512static inline void green_LED_off(struct controller *ctrl, u8 slot)
513{
514 u32 led_control;
515
516 led_control = readl(ctrl->hpc_reg + LED_CONTROL);
517 led_control &= ~(0x0101L << slot);
518 writel(led_control, ctrl->hpc_reg + LED_CONTROL);
519}
520
521
522static inline void green_LED_blink(struct controller *ctrl, u8 slot)
523{
524 u32 led_control;
525
526 led_control = readl(ctrl->hpc_reg + LED_CONTROL);
527 led_control &= ~(0x0101L << slot);
528 led_control |= (0x0001L << slot);
529 writel(led_control, ctrl->hpc_reg + LED_CONTROL);
530}
531
532
533static inline void slot_disable(struct controller *ctrl, u8 slot)
534{
535 u8 slot_enable;
536
537 slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
538 slot_enable &= ~(0x01 << slot);
539 writeb(slot_enable, ctrl->hpc_reg + SLOT_ENABLE);
540}
541
542
543static inline void slot_enable(struct controller *ctrl, u8 slot)
544{
545 u8 slot_enable;
546
547 slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
548 slot_enable |= (0x01 << slot);
549 writeb(slot_enable, ctrl->hpc_reg + SLOT_ENABLE);
550}
551
552
553static inline u8 is_slot_enabled(struct controller *ctrl, u8 slot)
554{
555 u8 slot_enable;
556
557 slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
558 slot_enable &= (0x01 << slot);
559 return slot_enable ? 1 : 0;
560}
561
562
563static inline u8 read_slot_enable(struct controller *ctrl)
564{
565 return readb(ctrl->hpc_reg + SLOT_ENABLE);
566}
567
568
569/*
570 * get_controller_speed - find the current frequency/mode of controller.
571 *
572 * @ctrl: controller to get frequency/mode for.
573 *
574 * Returns controller speed.
575 *
576 */
577static inline u8 get_controller_speed(struct controller *ctrl)
578{
579 u8 curr_freq;
580 u16 misc;
581
582 if (ctrl->pcix_support) {
583 curr_freq = readb(ctrl->hpc_reg + NEXT_CURR_FREQ);
584 if ((curr_freq & 0xB0) == 0xB0)
585 return PCI_SPEED_133MHz_PCIX;
586 if ((curr_freq & 0xA0) == 0xA0)
587 return PCI_SPEED_100MHz_PCIX;
588 if ((curr_freq & 0x90) == 0x90)
589 return PCI_SPEED_66MHz_PCIX;
590 if (curr_freq & 0x10)
591 return PCI_SPEED_66MHz;
592
593 return PCI_SPEED_33MHz;
594 }
595
596 misc = readw(ctrl->hpc_reg + MISC);
597 return (misc & 0x0800) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
598}
599
600
601/*
602 * get_adapter_speed - find the max supported frequency/mode of adapter.
603 *
604 * @ctrl: hotplug controller.
605 * @hp_slot: hotplug slot where adapter is installed.
606 *
607 * Returns adapter speed.
608 *
609 */
610static inline u8 get_adapter_speed(struct controller *ctrl, u8 hp_slot)
611{
612 u32 temp_dword = readl(ctrl->hpc_reg + NON_INT_INPUT);
613 dbg("slot: %d, PCIXCAP: %8x\n", hp_slot, temp_dword);
614 if (ctrl->pcix_support) {
615 if (temp_dword & (0x10000 << hp_slot))
616 return PCI_SPEED_133MHz_PCIX;
617 if (temp_dword & (0x100 << hp_slot))
618 return PCI_SPEED_66MHz_PCIX;
619 }
620
621 if (temp_dword & (0x01 << hp_slot))
622 return PCI_SPEED_66MHz;
623
624 return PCI_SPEED_33MHz;
625}
626
627static inline void enable_slot_power(struct controller *ctrl, u8 slot)
628{
629 u8 slot_power;
630
631 slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
632 slot_power |= (0x01 << slot);
633 writeb(slot_power, ctrl->hpc_reg + SLOT_POWER);
634}
635
636static inline void disable_slot_power(struct controller *ctrl, u8 slot)
637{
638 u8 slot_power;
639
640 slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
641 slot_power &= ~(0x01 << slot);
642 writeb(slot_power, ctrl->hpc_reg + SLOT_POWER);
643}
644
645
646static inline int cpq_get_attention_status(struct controller *ctrl, struct slot *slot)
647{
648 u8 hp_slot;
649
650 hp_slot = slot->device - ctrl->slot_device_offset;
651
652 return read_amber_LED(ctrl, hp_slot);
653}
654
655
656static inline int get_slot_enabled(struct controller *ctrl, struct slot *slot)
657{
658 u8 hp_slot;
659
660 hp_slot = slot->device - ctrl->slot_device_offset;
661
662 return is_slot_enabled(ctrl, hp_slot);
663}
664
665
666static inline int cpq_get_latch_status(struct controller *ctrl, struct slot *slot)
667{
668 u32 status;
669 u8 hp_slot;
670
671 hp_slot = slot->device - ctrl->slot_device_offset;
672 dbg("%s: slot->device = %d, ctrl->slot_device_offset = %d \n",
673 __FUNCTION__, slot->device, ctrl->slot_device_offset);
674
675 status = (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot));
676
677 return(status == 0) ? 1 : 0;
678}
679
680
681static inline int get_presence_status(struct controller *ctrl, struct slot *slot)
682{
683 int presence_save = 0;
684 u8 hp_slot;
685 u32 tempdword;
686
687 hp_slot = slot->device - ctrl->slot_device_offset;
688
689 tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
690 presence_save = (int) ((((~tempdword) >> 23) | ((~tempdword) >> 15)) >> hp_slot) & 0x02;
691
692 return presence_save;
693}
694
695#define SLOT_NAME_SIZE 10
696
697static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
698{
699 snprintf(buffer, buffer_size, "%d", slot->number);
700}
701
702
703static inline int wait_for_ctrl_irq(struct controller *ctrl)
704{
705 DECLARE_WAITQUEUE(wait, current);
706 int retval = 0;
707
708 dbg("%s - start\n", __FUNCTION__);
709 add_wait_queue(&ctrl->queue, &wait);
710 /* Sleep for up to 1 second to wait for the LED to change. */
711 msleep_interruptible(1000);
712 remove_wait_queue(&ctrl->queue, &wait);
713 if (signal_pending(current))
714 retval = -EINTR;
715
716 dbg("%s - end\n", __FUNCTION__);
717 return retval;
718}
719
720#endif
721
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
new file mode 100644
index 000000000000..afbccfa5217d
--- /dev/null
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -0,0 +1,1509 @@
1/*
2 * Compaq Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman <greg@kroah.com>
6 * Copyright (C) 2001 IBM Corp.
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <greg@kroah.com>
26 *
27 * Jan 12, 2003 - Added 66/100/133MHz PCI-X support,
28 * Torben Mathiasen <torben.mathiasen@hp.com>
29 *
30 */
31
32#include <linux/config.h>
33#include <linux/module.h>
34#include <linux/moduleparam.h>
35#include <linux/kernel.h>
36#include <linux/types.h>
37#include <linux/proc_fs.h>
38#include <linux/slab.h>
39#include <linux/workqueue.h>
40#include <linux/pci.h>
41#include <linux/init.h>
42#include <linux/interrupt.h>
43
44#include <asm/uaccess.h>
45
46#include "cpqphp.h"
47#include "cpqphp_nvram.h"
48#include "../../../arch/i386/pci/pci.h" /* horrible hack showing how processor dependent we are... */
49
50
51/* Global variables */
52int cpqhp_debug;
53int cpqhp_legacy_mode;
54struct controller *cpqhp_ctrl_list; /* = NULL */
55struct pci_func *cpqhp_slot_list[256];
56
57/* local variables */
58static void __iomem *smbios_table;
59static void __iomem *smbios_start;
60static void __iomem *cpqhp_rom_start;
61static int power_mode;
62static int debug;
63
64#define DRIVER_VERSION "0.9.8"
65#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>"
66#define DRIVER_DESC "Compaq Hot Plug PCI Controller Driver"
67
68MODULE_AUTHOR(DRIVER_AUTHOR);
69MODULE_DESCRIPTION(DRIVER_DESC);
70MODULE_LICENSE("GPL");
71
72module_param(power_mode, bool, 0644);
73MODULE_PARM_DESC(power_mode, "Power mode enabled or not");
74
75module_param(debug, bool, 0644);
76MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
77
78#define CPQHPC_MODULE_MINOR 208
79
80static int one_time_init (void);
81static int set_attention_status (struct hotplug_slot *slot, u8 value);
82static int process_SI (struct hotplug_slot *slot);
83static int process_SS (struct hotplug_slot *slot);
84static int hardware_test (struct hotplug_slot *slot, u32 value);
85static int get_power_status (struct hotplug_slot *slot, u8 *value);
86static int get_attention_status (struct hotplug_slot *slot, u8 *value);
87static int get_latch_status (struct hotplug_slot *slot, u8 *value);
88static int get_adapter_status (struct hotplug_slot *slot, u8 *value);
89static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
90static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
91
92static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = {
93 .owner = THIS_MODULE,
94 .set_attention_status = set_attention_status,
95 .enable_slot = process_SI,
96 .disable_slot = process_SS,
97 .hardware_test = hardware_test,
98 .get_power_status = get_power_status,
99 .get_attention_status = get_attention_status,
100 .get_latch_status = get_latch_status,
101 .get_adapter_status = get_adapter_status,
102 .get_max_bus_speed = get_max_bus_speed,
103 .get_cur_bus_speed = get_cur_bus_speed,
104};
105
106
107static inline int is_slot64bit(struct slot *slot)
108{
109 return (readb(slot->p_sm_slot + SMBIOS_SLOT_WIDTH) == 0x06) ? 1 : 0;
110}
111
112static inline int is_slot66mhz(struct slot *slot)
113{
114 return (readb(slot->p_sm_slot + SMBIOS_SLOT_TYPE) == 0x0E) ? 1 : 0;
115}
116
117/**
118 * detect_SMBIOS_pointer - find the System Management BIOS Table in mem region.
119 *
120 * @begin: begin pointer for region to be scanned.
121 * @end: end pointer for region to be scanned.
122 *
123 * Returns pointer to the head of the SMBIOS tables (or NULL)
124 *
125 */
126static void __iomem * detect_SMBIOS_pointer(void __iomem *begin, void __iomem *end)
127{
128 void __iomem *fp;
129 void __iomem *endp;
130 u8 temp1, temp2, temp3, temp4;
131 int status = 0;
132
133 endp = (end - sizeof(u32) + 1);
134
135 for (fp = begin; fp <= endp; fp += 16) {
136 temp1 = readb(fp);
137 temp2 = readb(fp+1);
138 temp3 = readb(fp+2);
139 temp4 = readb(fp+3);
140 if (temp1 == '_' &&
141 temp2 == 'S' &&
142 temp3 == 'M' &&
143 temp4 == '_') {
144 status = 1;
145 break;
146 }
147 }
148
149 if (!status)
150 fp = NULL;
151
152 dbg("Discovered SMBIOS Entry point at %p\n", fp);
153
154 return fp;
155}
156
157/**
158 * init_SERR - Initializes the per slot SERR generation.
159 *
160 * For unexpected switch opens
161 *
162 */
163static int init_SERR(struct controller * ctrl)
164{
165 u32 tempdword;
166 u32 number_of_slots;
167 u8 physical_slot;
168
169 if (!ctrl)
170 return 1;
171
172 tempdword = ctrl->first_slot;
173
174 number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
175 // Loop through slots
176 while (number_of_slots) {
177 physical_slot = tempdword;
178 writeb(0, ctrl->hpc_reg + SLOT_SERR);
179 tempdword++;
180 number_of_slots--;
181 }
182
183 return 0;
184}
185
186
187/* nice debugging output */
188static int pci_print_IRQ_route (void)
189{
190 struct irq_routing_table *routing_table;
191 int len;
192 int loop;
193
194 u8 tbus, tdevice, tslot;
195
196 routing_table = pcibios_get_irq_routing_table();
197 if (routing_table == NULL) {
198 err("No BIOS Routing Table??? Not good\n");
199 return -ENOMEM;
200 }
201
202 len = (routing_table->size - sizeof(struct irq_routing_table)) /
203 sizeof(struct irq_info);
204 // Make sure I got at least one entry
205 if (len == 0) {
206 kfree(routing_table);
207 return -1;
208 }
209
210 dbg("bus dev func slot\n");
211
212 for (loop = 0; loop < len; ++loop) {
213 tbus = routing_table->slots[loop].bus;
214 tdevice = routing_table->slots[loop].devfn;
215 tslot = routing_table->slots[loop].slot;
216 dbg("%d %d %d %d\n", tbus, tdevice >> 3, tdevice & 0x7, tslot);
217
218 }
219 kfree(routing_table);
220 return 0;
221}
222
223
224/**
225 * get_subsequent_smbios_entry: get the next entry from bios table.
226 *
227 * Gets the first entry if previous == NULL
228 * Otherwise, returns the next entry
229 * Uses global SMBIOS Table pointer
230 *
231 * @curr: %NULL or pointer to previously returned structure
232 *
233 * returns a pointer to an SMBIOS structure or NULL if none found
234 */
235static void __iomem *get_subsequent_smbios_entry(void __iomem *smbios_start,
236 void __iomem *smbios_table,
237 void __iomem *curr)
238{
239 u8 bail = 0;
240 u8 previous_byte = 1;
241 void __iomem *p_temp;
242 void __iomem *p_max;
243
244 if (!smbios_table || !curr)
245 return(NULL);
246
247 // set p_max to the end of the table
248 p_max = smbios_start + readw(smbios_table + ST_LENGTH);
249
250 p_temp = curr;
251 p_temp += readb(curr + SMBIOS_GENERIC_LENGTH);
252
253 while ((p_temp < p_max) && !bail) {
254 /* Look for the double NULL terminator
255 * The first condition is the previous byte
256 * and the second is the curr */
257 if (!previous_byte && !(readb(p_temp))) {
258 bail = 1;
259 }
260
261 previous_byte = readb(p_temp);
262 p_temp++;
263 }
264
265 if (p_temp < p_max) {
266 return p_temp;
267 } else {
268 return NULL;
269 }
270}
271
272
273/**
274 * get_SMBIOS_entry
275 *
276 * @type:SMBIOS structure type to be returned
277 * @previous: %NULL or pointer to previously returned structure
278 *
279 * Gets the first entry of the specified type if previous == NULL
280 * Otherwise, returns the next entry of the given type.
281 * Uses global SMBIOS Table pointer
282 * Uses get_subsequent_smbios_entry
283 *
284 * returns a pointer to an SMBIOS structure or %NULL if none found
285 */
286static void __iomem *get_SMBIOS_entry(void __iomem *smbios_start,
287 void __iomem *smbios_table,
288 u8 type,
289 void __iomem *previous)
290{
291 if (!smbios_table)
292 return NULL;
293
294 if (!previous) {
295 previous = smbios_start;
296 } else {
297 previous = get_subsequent_smbios_entry(smbios_start,
298 smbios_table, previous);
299 }
300
301 while (previous) {
302 if (readb(previous + SMBIOS_GENERIC_TYPE) != type) {
303 previous = get_subsequent_smbios_entry(smbios_start,
304 smbios_table, previous);
305 } else {
306 break;
307 }
308 }
309
310 return previous;
311}
312
313static void release_slot(struct hotplug_slot *hotplug_slot)
314{
315 struct slot *slot = hotplug_slot->private;
316
317 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
318
319 kfree(slot->hotplug_slot->info);
320 kfree(slot->hotplug_slot->name);
321 kfree(slot->hotplug_slot);
322 kfree(slot);
323}
324
325static int ctrl_slot_setup(struct controller *ctrl,
326 void __iomem *smbios_start,
327 void __iomem *smbios_table)
328{
329 struct slot *new_slot;
330 u8 number_of_slots;
331 u8 slot_device;
332 u8 slot_number;
333 u8 ctrl_slot;
334 u32 tempdword;
335 void __iomem *slot_entry= NULL;
336 int result = -ENOMEM;
337
338 dbg("%s\n", __FUNCTION__);
339
340 tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
341
342 number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
343 slot_device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
344 slot_number = ctrl->first_slot;
345
346 while (number_of_slots) {
347 new_slot = kmalloc(sizeof(*new_slot), GFP_KERNEL);
348 if (!new_slot)
349 goto error;
350
351 memset(new_slot, 0, sizeof(struct slot));
352 new_slot->hotplug_slot = kmalloc(sizeof(*(new_slot->hotplug_slot)),
353 GFP_KERNEL);
354 if (!new_slot->hotplug_slot)
355 goto error_slot;
356 memset(new_slot->hotplug_slot, 0, sizeof(struct hotplug_slot));
357
358 new_slot->hotplug_slot->info =
359 kmalloc(sizeof(*(new_slot->hotplug_slot->info)),
360 GFP_KERNEL);
361 if (!new_slot->hotplug_slot->info)
362 goto error_hpslot;
363 memset(new_slot->hotplug_slot->info, 0,
364 sizeof(struct hotplug_slot_info));
365 new_slot->hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
366 if (!new_slot->hotplug_slot->name)
367 goto error_info;
368
369 new_slot->ctrl = ctrl;
370 new_slot->bus = ctrl->bus;
371 new_slot->device = slot_device;
372 new_slot->number = slot_number;
373 dbg("slot->number = %d\n",new_slot->number);
374
375 slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9,
376 slot_entry);
377
378 while (slot_entry && (readw(slot_entry + SMBIOS_SLOT_NUMBER) != new_slot->number)) {
379 slot_entry = get_SMBIOS_entry(smbios_start,
380 smbios_table, 9, slot_entry);
381 }
382
383 new_slot->p_sm_slot = slot_entry;
384
385 init_timer(&new_slot->task_event);
386 new_slot->task_event.expires = jiffies + 5 * HZ;
387 new_slot->task_event.function = cpqhp_pushbutton_thread;
388
389 //FIXME: these capabilities aren't used but if they are
390 // they need to be correctly implemented
391 new_slot->capabilities |= PCISLOT_REPLACE_SUPPORTED;
392 new_slot->capabilities |= PCISLOT_INTERLOCK_SUPPORTED;
393
394 if (is_slot64bit(new_slot))
395 new_slot->capabilities |= PCISLOT_64_BIT_SUPPORTED;
396 if (is_slot66mhz(new_slot))
397 new_slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED;
398 if (ctrl->speed == PCI_SPEED_66MHz)
399 new_slot->capabilities |= PCISLOT_66_MHZ_OPERATION;
400
401 ctrl_slot = slot_device - (readb(ctrl->hpc_reg + SLOT_MASK) >> 4);
402
403 // Check presence
404 new_slot->capabilities |= ((((~tempdword) >> 23) | ((~tempdword) >> 15)) >> ctrl_slot) & 0x02;
405 // Check the switch state
406 new_slot->capabilities |= ((~tempdword & 0xFF) >> ctrl_slot) & 0x01;
407 // Check the slot enable
408 new_slot->capabilities |= ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04;
409
410 /* register this slot with the hotplug pci core */
411 new_slot->hotplug_slot->release = &release_slot;
412 new_slot->hotplug_slot->private = new_slot;
413 make_slot_name(new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot);
414 new_slot->hotplug_slot->ops = &cpqphp_hotplug_slot_ops;
415
416 new_slot->hotplug_slot->info->power_status = get_slot_enabled(ctrl, new_slot);
417 new_slot->hotplug_slot->info->attention_status = cpq_get_attention_status(ctrl, new_slot);
418 new_slot->hotplug_slot->info->latch_status = cpq_get_latch_status(ctrl, new_slot);
419 new_slot->hotplug_slot->info->adapter_status = get_presence_status(ctrl, new_slot);
420
421 dbg ("registering bus %d, dev %d, number %d, "
422 "ctrl->slot_device_offset %d, slot %d\n",
423 new_slot->bus, new_slot->device,
424 new_slot->number, ctrl->slot_device_offset,
425 slot_number);
426 result = pci_hp_register (new_slot->hotplug_slot);
427 if (result) {
428 err ("pci_hp_register failed with error %d\n", result);
429 goto error_name;
430 }
431
432 new_slot->next = ctrl->slot;
433 ctrl->slot = new_slot;
434
435 number_of_slots--;
436 slot_device++;
437 slot_number++;
438 }
439
440 return 0;
441
442error_name:
443 kfree(new_slot->hotplug_slot->name);
444error_info:
445 kfree(new_slot->hotplug_slot->info);
446error_hpslot:
447 kfree(new_slot->hotplug_slot);
448error_slot:
449 kfree(new_slot);
450error:
451 return result;
452}
453
454static int ctrl_slot_cleanup (struct controller * ctrl)
455{
456 struct slot *old_slot, *next_slot;
457
458 old_slot = ctrl->slot;
459 ctrl->slot = NULL;
460
461 while (old_slot) {
462 /* memory will be freed by the release_slot callback */
463 next_slot = old_slot->next;
464 pci_hp_deregister (old_slot->hotplug_slot);
465 old_slot = next_slot;
466 }
467
468 //Free IRQ associated with hot plug device
469 free_irq(ctrl->interrupt, ctrl);
470 //Unmap the memory
471 iounmap(ctrl->hpc_reg);
472 //Finally reclaim PCI mem
473 release_mem_region(pci_resource_start(ctrl->pci_dev, 0),
474 pci_resource_len(ctrl->pci_dev, 0));
475
476 return(0);
477}
478
479
480//============================================================================
481// function: get_slot_mapping
482//
483// Description: Attempts to determine a logical slot mapping for a PCI
484// device. Won't work for more than one PCI-PCI bridge
485// in a slot.
486//
487// Input: u8 bus_num - bus number of PCI device
488// u8 dev_num - device number of PCI device
489// u8 *slot - Pointer to u8 where slot number will
490// be returned
491//
492// Output: SUCCESS or FAILURE
493//=============================================================================
494static int
495get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
496{
497 struct irq_routing_table *PCIIRQRoutingInfoLength;
498 u32 work;
499 long len;
500 long loop;
501
502 u8 tbus, tdevice, tslot, bridgeSlot;
503
504 dbg("%s: %p, %d, %d, %p\n", __FUNCTION__, bus, bus_num, dev_num, slot);
505
506 bridgeSlot = 0xFF;
507
508 PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
509 if (!PCIIRQRoutingInfoLength)
510 return -1;
511
512 len = (PCIIRQRoutingInfoLength->size -
513 sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
514 // Make sure I got at least one entry
515 if (len == 0) {
516 kfree(PCIIRQRoutingInfoLength);
517 return -1;
518 }
519
520 for (loop = 0; loop < len; ++loop) {
521 tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
522 tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn >> 3;
523 tslot = PCIIRQRoutingInfoLength->slots[loop].slot;
524
525 if ((tbus == bus_num) && (tdevice == dev_num)) {
526 *slot = tslot;
527 kfree(PCIIRQRoutingInfoLength);
528 return 0;
529 } else {
530 /* Did not get a match on the target PCI device. Check
531 * if the current IRQ table entry is a PCI-to-PCI bridge
532 * device. If so, and it's secondary bus matches the
533 * bus number for the target device, I need to save the
534 * bridge's slot number. If I can not find an entry for
535 * the target device, I will have to assume it's on the
536 * other side of the bridge, and assign it the bridge's
537 * slot. */
538 bus->number = tbus;
539 pci_bus_read_config_dword(bus, PCI_DEVFN(tdevice, 0),
540 PCI_REVISION_ID, &work);
541
542 if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
543 pci_bus_read_config_dword(bus,
544 PCI_DEVFN(tdevice, 0),
545 PCI_PRIMARY_BUS, &work);
546 // See if bridge's secondary bus matches target bus.
547 if (((work >> 8) & 0x000000FF) == (long) bus_num) {
548 bridgeSlot = tslot;
549 }
550 }
551 }
552
553 }
554
555 // If we got here, we didn't find an entry in the IRQ mapping table
556 // for the target PCI device. If we did determine that the target
557 // device is on the other side of a PCI-to-PCI bridge, return the
558 // slot number for the bridge.
559 if (bridgeSlot != 0xFF) {
560 *slot = bridgeSlot;
561 kfree(PCIIRQRoutingInfoLength);
562 return 0;
563 }
564 kfree(PCIIRQRoutingInfoLength);
565 // Couldn't find an entry in the routing table for this PCI device
566 return -1;
567}
568
569
570/**
571 * cpqhp_set_attention_status - Turns the Amber LED for a slot on or off
572 *
573 */
574static int
575cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func,
576 u32 status)
577{
578 u8 hp_slot;
579
580 if (func == NULL)
581 return(1);
582
583 hp_slot = func->device - ctrl->slot_device_offset;
584
585 // Wait for exclusive access to hardware
586 down(&ctrl->crit_sect);
587
588 if (status == 1) {
589 amber_LED_on (ctrl, hp_slot);
590 } else if (status == 0) {
591 amber_LED_off (ctrl, hp_slot);
592 } else {
593 // Done with exclusive hardware access
594 up(&ctrl->crit_sect);
595 return(1);
596 }
597
598 set_SOGO(ctrl);
599
600 // Wait for SOBS to be unset
601 wait_for_ctrl_irq (ctrl);
602
603 // Done with exclusive hardware access
604 up(&ctrl->crit_sect);
605
606 return(0);
607}
608
609
610/**
611 * set_attention_status - Turns the Amber LED for a slot on or off
612 *
613 */
614static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
615{
616 struct pci_func *slot_func;
617 struct slot *slot = hotplug_slot->private;
618 struct controller *ctrl = slot->ctrl;
619 u8 bus;
620 u8 devfn;
621 u8 device;
622 u8 function;
623
624 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
625
626 if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
627 return -ENODEV;
628
629 device = devfn >> 3;
630 function = devfn & 0x7;
631 dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
632
633 slot_func = cpqhp_slot_find(bus, device, function);
634 if (!slot_func)
635 return -ENODEV;
636
637 return cpqhp_set_attention_status(ctrl, slot_func, status);
638}
639
640
641static int process_SI(struct hotplug_slot *hotplug_slot)
642{
643 struct pci_func *slot_func;
644 struct slot *slot = hotplug_slot->private;
645 struct controller *ctrl = slot->ctrl;
646 u8 bus;
647 u8 devfn;
648 u8 device;
649 u8 function;
650
651 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
652
653 if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
654 return -ENODEV;
655
656 device = devfn >> 3;
657 function = devfn & 0x7;
658 dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
659
660 slot_func = cpqhp_slot_find(bus, device, function);
661 if (!slot_func)
662 return -ENODEV;
663
664 slot_func->bus = bus;
665 slot_func->device = device;
666 slot_func->function = function;
667 slot_func->configured = 0;
668 dbg("board_added(%p, %p)\n", slot_func, ctrl);
669 return cpqhp_process_SI(ctrl, slot_func);
670}
671
672
673static int process_SS(struct hotplug_slot *hotplug_slot)
674{
675 struct pci_func *slot_func;
676 struct slot *slot = hotplug_slot->private;
677 struct controller *ctrl = slot->ctrl;
678 u8 bus;
679 u8 devfn;
680 u8 device;
681 u8 function;
682
683 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
684
685 if (cpqhp_get_bus_dev(ctrl, &bus, &devfn, slot->number) == -1)
686 return -ENODEV;
687
688 device = devfn >> 3;
689 function = devfn & 0x7;
690 dbg("bus, dev, fn = %d, %d, %d\n", bus, device, function);
691
692 slot_func = cpqhp_slot_find(bus, device, function);
693 if (!slot_func)
694 return -ENODEV;
695
696 dbg("In %s, slot_func = %p, ctrl = %p\n", __FUNCTION__, slot_func, ctrl);
697 return cpqhp_process_SS(ctrl, slot_func);
698}
699
700
701static int hardware_test(struct hotplug_slot *hotplug_slot, u32 value)
702{
703 struct slot *slot = hotplug_slot->private;
704 struct controller *ctrl = slot->ctrl;
705
706 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
707
708 return cpqhp_hardware_test(ctrl, value);
709}
710
711
712static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
713{
714 struct slot *slot = hotplug_slot->private;
715 struct controller *ctrl = slot->ctrl;
716
717 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
718
719 *value = get_slot_enabled(ctrl, slot);
720 return 0;
721}
722
723static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
724{
725 struct slot *slot = hotplug_slot->private;
726 struct controller *ctrl = slot->ctrl;
727
728 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
729
730 *value = cpq_get_attention_status(ctrl, slot);
731 return 0;
732}
733
734static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
735{
736 struct slot *slot = hotplug_slot->private;
737 struct controller *ctrl = slot->ctrl;
738
739 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
740
741 *value = cpq_get_latch_status(ctrl, slot);
742
743 return 0;
744}
745
746static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
747{
748 struct slot *slot = hotplug_slot->private;
749 struct controller *ctrl = slot->ctrl;
750
751 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
752
753 *value = get_presence_status(ctrl, slot);
754
755 return 0;
756}
757
758static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
759{
760 struct slot *slot = hotplug_slot->private;
761 struct controller *ctrl = slot->ctrl;
762
763 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
764
765 *value = ctrl->speed_capability;
766
767 return 0;
768}
769
770static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
771{
772 struct slot *slot = hotplug_slot->private;
773 struct controller *ctrl = slot->ctrl;
774
775 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
776
777 *value = ctrl->speed;
778
779 return 0;
780}
781
782static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
783{
784 u8 num_of_slots = 0;
785 u8 hp_slot = 0;
786 u8 device;
787 u8 rev;
788 u8 bus_cap;
789 u16 temp_word;
790 u16 vendor_id;
791 u16 subsystem_vid;
792 u16 subsystem_deviceid;
793 u32 rc;
794 struct controller *ctrl;
795 struct pci_func *func;
796
797 // Need to read VID early b/c it's used to differentiate CPQ and INTC discovery
798 rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id);
799 if (rc || ((vendor_id != PCI_VENDOR_ID_COMPAQ) && (vendor_id != PCI_VENDOR_ID_INTEL))) {
800 err(msg_HPC_non_compaq_or_intel);
801 return -ENODEV;
802 }
803 dbg("Vendor ID: %x\n", vendor_id);
804
805 rc = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
806 dbg("revision: %d\n", rev);
807 if (rc || ((vendor_id == PCI_VENDOR_ID_COMPAQ) && (!rev))) {
808 err(msg_HPC_rev_error);
809 return -ENODEV;
810 }
811
812 /* Check for the proper subsytem ID's
813 * Intel uses a different SSID programming model than Compaq.
814 * For Intel, each SSID bit identifies a PHP capability.
815 * Also Intel HPC's may have RID=0.
816 */
817 if ((rev > 2) || (vendor_id == PCI_VENDOR_ID_INTEL)) {
818 // TODO: This code can be made to support non-Compaq or Intel subsystem IDs
819 rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid);
820 if (rc) {
821 err("%s : pci_read_config_word failed\n", __FUNCTION__);
822 return rc;
823 }
824 dbg("Subsystem Vendor ID: %x\n", subsystem_vid);
825 if ((subsystem_vid != PCI_VENDOR_ID_COMPAQ) && (subsystem_vid != PCI_VENDOR_ID_INTEL)) {
826 err(msg_HPC_non_compaq_or_intel);
827 return -ENODEV;
828 }
829
830 ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
831 if (!ctrl) {
832 err("%s : out of memory\n", __FUNCTION__);
833 return -ENOMEM;
834 }
835 memset(ctrl, 0, sizeof(struct controller));
836
837 rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid);
838 if (rc) {
839 err("%s : pci_read_config_word failed\n", __FUNCTION__);
840 goto err_free_ctrl;
841 }
842
843 info("Hot Plug Subsystem Device ID: %x\n", subsystem_deviceid);
844
845 /* Set Vendor ID, so it can be accessed later from other functions */
846 ctrl->vendor_id = vendor_id;
847
848 switch (subsystem_vid) {
849 case PCI_VENDOR_ID_COMPAQ:
850 if (rev >= 0x13) { /* CIOBX */
851 ctrl->push_flag = 1;
852 ctrl->slot_switch_type = 1;
853 ctrl->push_button = 1;
854 ctrl->pci_config_space = 1;
855 ctrl->defeature_PHP = 1;
856 ctrl->pcix_support = 1;
857 ctrl->pcix_speed_capability = 1;
858 pci_read_config_byte(pdev, 0x41, &bus_cap);
859 if (bus_cap & 0x80) {
860 dbg("bus max supports 133MHz PCI-X\n");
861 ctrl->speed_capability = PCI_SPEED_133MHz_PCIX;
862 break;
863 }
864 if (bus_cap & 0x40) {
865 dbg("bus max supports 100MHz PCI-X\n");
866 ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
867 break;
868 }
869 if (bus_cap & 20) {
870 dbg("bus max supports 66MHz PCI-X\n");
871 ctrl->speed_capability = PCI_SPEED_66MHz_PCIX;
872 break;
873 }
874 if (bus_cap & 10) {
875 dbg("bus max supports 66MHz PCI\n");
876 ctrl->speed_capability = PCI_SPEED_66MHz;
877 break;
878 }
879
880 break;
881 }
882
883 switch (subsystem_deviceid) {
884 case PCI_SUB_HPC_ID:
885 /* Original 6500/7000 implementation */
886 ctrl->slot_switch_type = 1;
887 ctrl->speed_capability = PCI_SPEED_33MHz;
888 ctrl->push_button = 0;
889 ctrl->pci_config_space = 1;
890 ctrl->defeature_PHP = 1;
891 ctrl->pcix_support = 0;
892 ctrl->pcix_speed_capability = 0;
893 break;
894 case PCI_SUB_HPC_ID2:
895 /* First Pushbutton implementation */
896 ctrl->push_flag = 1;
897 ctrl->slot_switch_type = 1;
898 ctrl->speed_capability = PCI_SPEED_33MHz;
899 ctrl->push_button = 1;
900 ctrl->pci_config_space = 1;
901 ctrl->defeature_PHP = 1;
902 ctrl->pcix_support = 0;
903 ctrl->pcix_speed_capability = 0;
904 break;
905 case PCI_SUB_HPC_ID_INTC:
906 /* Third party (6500/7000) */
907 ctrl->slot_switch_type = 1;
908 ctrl->speed_capability = PCI_SPEED_33MHz;
909 ctrl->push_button = 0;
910 ctrl->pci_config_space = 1;
911 ctrl->defeature_PHP = 1;
912 ctrl->pcix_support = 0;
913 ctrl->pcix_speed_capability = 0;
914 break;
915 case PCI_SUB_HPC_ID3:
916 /* First 66 Mhz implementation */
917 ctrl->push_flag = 1;
918 ctrl->slot_switch_type = 1;
919 ctrl->speed_capability = PCI_SPEED_66MHz;
920 ctrl->push_button = 1;
921 ctrl->pci_config_space = 1;
922 ctrl->defeature_PHP = 1;
923 ctrl->pcix_support = 0;
924 ctrl->pcix_speed_capability = 0;
925 break;
926 case PCI_SUB_HPC_ID4:
927 /* First PCI-X implementation, 100MHz */
928 ctrl->push_flag = 1;
929 ctrl->slot_switch_type = 1;
930 ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
931 ctrl->push_button = 1;
932 ctrl->pci_config_space = 1;
933 ctrl->defeature_PHP = 1;
934 ctrl->pcix_support = 1;
935 ctrl->pcix_speed_capability = 0;
936 break;
937 default:
938 err(msg_HPC_not_supported);
939 rc = -ENODEV;
940 goto err_free_ctrl;
941 }
942 break;
943
944 case PCI_VENDOR_ID_INTEL:
945 /* Check for speed capability (0=33, 1=66) */
946 if (subsystem_deviceid & 0x0001) {
947 ctrl->speed_capability = PCI_SPEED_66MHz;
948 } else {
949 ctrl->speed_capability = PCI_SPEED_33MHz;
950 }
951
952 /* Check for push button */
953 if (subsystem_deviceid & 0x0002) {
954 /* no push button */
955 ctrl->push_button = 0;
956 } else {
957 /* push button supported */
958 ctrl->push_button = 1;
959 }
960
961 /* Check for slot switch type (0=mechanical, 1=not mechanical) */
962 if (subsystem_deviceid & 0x0004) {
963 /* no switch */
964 ctrl->slot_switch_type = 0;
965 } else {
966 /* switch */
967 ctrl->slot_switch_type = 1;
968 }
969
970 /* PHP Status (0=De-feature PHP, 1=Normal operation) */
971 if (subsystem_deviceid & 0x0008) {
972 ctrl->defeature_PHP = 1; // PHP supported
973 } else {
974 ctrl->defeature_PHP = 0; // PHP not supported
975 }
976
977 /* Alternate Base Address Register Interface (0=not supported, 1=supported) */
978 if (subsystem_deviceid & 0x0010) {
979 ctrl->alternate_base_address = 1; // supported
980 } else {
981 ctrl->alternate_base_address = 0; // not supported
982 }
983
984 /* PCI Config Space Index (0=not supported, 1=supported) */
985 if (subsystem_deviceid & 0x0020) {
986 ctrl->pci_config_space = 1; // supported
987 } else {
988 ctrl->pci_config_space = 0; // not supported
989 }
990
991 /* PCI-X support */
992 if (subsystem_deviceid & 0x0080) {
993 /* PCI-X capable */
994 ctrl->pcix_support = 1;
995 /* Frequency of operation in PCI-X mode */
996 if (subsystem_deviceid & 0x0040) {
997 /* 133MHz PCI-X if bit 7 is 1 */
998 ctrl->pcix_speed_capability = 1;
999 } else {
1000 /* 100MHz PCI-X if bit 7 is 1 and bit 0 is 0, */
1001 /* 66MHz PCI-X if bit 7 is 1 and bit 0 is 1 */
1002 ctrl->pcix_speed_capability = 0;
1003 }
1004 } else {
1005 /* Conventional PCI */
1006 ctrl->pcix_support = 0;
1007 ctrl->pcix_speed_capability = 0;
1008 }
1009 break;
1010
1011 default:
1012 err(msg_HPC_not_supported);
1013 rc = -ENODEV;
1014 goto err_free_ctrl;
1015 }
1016
1017 } else {
1018 err(msg_HPC_not_supported);
1019 return -ENODEV;
1020 }
1021
1022 // Tell the user that we found one.
1023 info("Initializing the PCI hot plug controller residing on PCI bus %d\n",
1024 pdev->bus->number);
1025
1026 dbg("Hotplug controller capabilities:\n");
1027 dbg(" speed_capability %d\n", ctrl->speed_capability);
1028 dbg(" slot_switch_type %s\n", ctrl->slot_switch_type ?
1029 "switch present" : "no switch");
1030 dbg(" defeature_PHP %s\n", ctrl->defeature_PHP ?
1031 "PHP supported" : "PHP not supported");
1032 dbg(" alternate_base_address %s\n", ctrl->alternate_base_address ?
1033 "supported" : "not supported");
1034 dbg(" pci_config_space %s\n", ctrl->pci_config_space ?
1035 "supported" : "not supported");
1036 dbg(" pcix_speed_capability %s\n", ctrl->pcix_speed_capability ?
1037 "supported" : "not supported");
1038 dbg(" pcix_support %s\n", ctrl->pcix_support ?
1039 "supported" : "not supported");
1040
1041 ctrl->pci_dev = pdev;
1042 pci_set_drvdata(pdev, ctrl);
1043
1044 /* make our own copy of the pci bus structure,
1045 * as we like tweaking it a lot */
1046 ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL);
1047 if (!ctrl->pci_bus) {
1048 err("out of memory\n");
1049 rc = -ENOMEM;
1050 goto err_free_ctrl;
1051 }
1052 memcpy(ctrl->pci_bus, pdev->bus, sizeof(*ctrl->pci_bus));
1053
1054 ctrl->bus = pdev->bus->number;
1055 ctrl->rev = rev;
1056 dbg("bus device function rev: %d %d %d %d\n", ctrl->bus,
1057 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), ctrl->rev);
1058
1059 init_MUTEX(&ctrl->crit_sect);
1060 init_waitqueue_head(&ctrl->queue);
1061
1062 /* initialize our threads if they haven't already been started up */
1063 rc = one_time_init();
1064 if (rc) {
1065 goto err_free_bus;
1066 }
1067
1068 dbg("pdev = %p\n", pdev);
1069 dbg("pci resource start %lx\n", pci_resource_start(pdev, 0));
1070 dbg("pci resource len %lx\n", pci_resource_len(pdev, 0));
1071
1072 if (!request_mem_region(pci_resource_start(pdev, 0),
1073 pci_resource_len(pdev, 0), MY_NAME)) {
1074 err("cannot reserve MMIO region\n");
1075 rc = -ENOMEM;
1076 goto err_free_bus;
1077 }
1078
1079 ctrl->hpc_reg = ioremap(pci_resource_start(pdev, 0),
1080 pci_resource_len(pdev, 0));
1081 if (!ctrl->hpc_reg) {
1082 err("cannot remap MMIO region %lx @ %lx\n",
1083 pci_resource_len(pdev, 0),
1084 pci_resource_start(pdev, 0));
1085 rc = -ENODEV;
1086 goto err_free_mem_region;
1087 }
1088
1089 // Check for 66Mhz operation
1090 ctrl->speed = get_controller_speed(ctrl);
1091
1092
1093 /********************************************************
1094 *
1095 * Save configuration headers for this and
1096 * subordinate PCI buses
1097 *
1098 ********************************************************/
1099
1100 // find the physical slot number of the first hot plug slot
1101
1102 /* Get slot won't work for devices behind bridges, but
1103 * in this case it will always be called for the "base"
1104 * bus/dev/func of a slot.
1105 * CS: this is leveraging the PCIIRQ routing code from the kernel
1106 * (pci-pc.c: get_irq_routing_table) */
1107 rc = get_slot_mapping(ctrl->pci_bus, pdev->bus->number,
1108 (readb(ctrl->hpc_reg + SLOT_MASK) >> 4),
1109 &(ctrl->first_slot));
1110 dbg("get_slot_mapping: first_slot = %d, returned = %d\n",
1111 ctrl->first_slot, rc);
1112 if (rc) {
1113 err(msg_initialization_err, rc);
1114 goto err_iounmap;
1115 }
1116
1117 // Store PCI Config Space for all devices on this bus
1118 rc = cpqhp_save_config(ctrl, ctrl->bus, readb(ctrl->hpc_reg + SLOT_MASK));
1119 if (rc) {
1120 err("%s: unable to save PCI configuration data, error %d\n",
1121 __FUNCTION__, rc);
1122 goto err_iounmap;
1123 }
1124
1125 /*
1126 * Get IO, memory, and IRQ resources for new devices
1127 */
1128 // The next line is required for cpqhp_find_available_resources
1129 ctrl->interrupt = pdev->irq;
1130 if (ctrl->interrupt < 0x10) {
1131 cpqhp_legacy_mode = 1;
1132 dbg("System seems to be configured for Full Table Mapped MPS mode\n");
1133 }
1134
1135 ctrl->cfgspc_irq = 0;
1136 pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &ctrl->cfgspc_irq);
1137
1138 rc = cpqhp_find_available_resources(ctrl, cpqhp_rom_start);
1139 ctrl->add_support = !rc;
1140 if (rc) {
1141 dbg("cpqhp_find_available_resources = 0x%x\n", rc);
1142 err("unable to locate PCI configuration resources for hot plug add.\n");
1143 goto err_iounmap;
1144 }
1145
1146 /*
1147 * Finish setting up the hot plug ctrl device
1148 */
1149 ctrl->slot_device_offset = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
1150 dbg("NumSlots %d \n", ctrl->slot_device_offset);
1151
1152 ctrl->next_event = 0;
1153
1154 /* Setup the slot information structures */
1155 rc = ctrl_slot_setup(ctrl, smbios_start, smbios_table);
1156 if (rc) {
1157 err(msg_initialization_err, 6);
1158 err("%s: unable to save PCI configuration data, error %d\n",
1159 __FUNCTION__, rc);
1160 goto err_iounmap;
1161 }
1162
1163 /* Mask all general input interrupts */
1164 writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_MASK);
1165
1166 /* set up the interrupt */
1167 dbg("HPC interrupt = %d \n", ctrl->interrupt);
1168 if (request_irq(ctrl->interrupt, cpqhp_ctrl_intr,
1169 SA_SHIRQ, MY_NAME, ctrl)) {
1170 err("Can't get irq %d for the hotplug pci controller\n",
1171 ctrl->interrupt);
1172 rc = -ENODEV;
1173 goto err_iounmap;
1174 }
1175
1176 /* Enable Shift Out interrupt and clear it, also enable SERR on power fault */
1177 temp_word = readw(ctrl->hpc_reg + MISC);
1178 temp_word |= 0x4006;
1179 writew(temp_word, ctrl->hpc_reg + MISC);
1180
1181 // Changed 05/05/97 to clear all interrupts at start
1182 writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_INPUT_CLEAR);
1183
1184 ctrl->ctrl_int_comp = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
1185
1186 writel(0x0L, ctrl->hpc_reg + INT_MASK);
1187
1188 if (!cpqhp_ctrl_list) {
1189 cpqhp_ctrl_list = ctrl;
1190 ctrl->next = NULL;
1191 } else {
1192 ctrl->next = cpqhp_ctrl_list;
1193 cpqhp_ctrl_list = ctrl;
1194 }
1195
1196 // turn off empty slots here unless command line option "ON" set
1197 // Wait for exclusive access to hardware
1198 down(&ctrl->crit_sect);
1199
1200 num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
1201
1202 // find first device number for the ctrl
1203 device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
1204
1205 while (num_of_slots) {
1206 dbg("num_of_slots: %d\n", num_of_slots);
1207 func = cpqhp_slot_find(ctrl->bus, device, 0);
1208 if (!func)
1209 break;
1210
1211 hp_slot = func->device - ctrl->slot_device_offset;
1212 dbg("hp_slot: %d\n", hp_slot);
1213
1214 // We have to save the presence info for these slots
1215 temp_word = ctrl->ctrl_int_comp >> 16;
1216 func->presence_save = (temp_word >> hp_slot) & 0x01;
1217 func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
1218
1219 if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
1220 func->switch_save = 0;
1221 } else {
1222 func->switch_save = 0x10;
1223 }
1224
1225 if (!power_mode) {
1226 if (!func->is_a_board) {
1227 green_LED_off(ctrl, hp_slot);
1228 slot_disable(ctrl, hp_slot);
1229 }
1230 }
1231
1232 device++;
1233 num_of_slots--;
1234 }
1235
1236 if (!power_mode) {
1237 set_SOGO(ctrl);
1238 // Wait for SOBS to be unset
1239 wait_for_ctrl_irq(ctrl);
1240 }
1241
1242 rc = init_SERR(ctrl);
1243 if (rc) {
1244 err("init_SERR failed\n");
1245 up(&ctrl->crit_sect);
1246 goto err_free_irq;
1247 }
1248
1249 // Done with exclusive hardware access
1250 up(&ctrl->crit_sect);
1251
1252 cpqhp_create_ctrl_files(ctrl);
1253
1254 return 0;
1255
1256err_free_irq:
1257 free_irq(ctrl->interrupt, ctrl);
1258err_iounmap:
1259 iounmap(ctrl->hpc_reg);
1260err_free_mem_region:
1261 release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
1262err_free_bus:
1263 kfree(ctrl->pci_bus);
1264err_free_ctrl:
1265 kfree(ctrl);
1266 return rc;
1267}
1268
1269
1270static int one_time_init(void)
1271{
1272 int loop;
1273 int retval = 0;
1274 static int initialized = 0;
1275
1276 if (initialized)
1277 return 0;
1278
1279 power_mode = 0;
1280
1281 retval = pci_print_IRQ_route();
1282 if (retval)
1283 goto error;
1284
1285 dbg("Initialize + Start the notification mechanism \n");
1286
1287 retval = cpqhp_event_start_thread();
1288 if (retval)
1289 goto error;
1290
1291 dbg("Initialize slot lists\n");
1292 for (loop = 0; loop < 256; loop++) {
1293 cpqhp_slot_list[loop] = NULL;
1294 }
1295
1296 // FIXME: We also need to hook the NMI handler eventually.
1297 // this also needs to be worked with Christoph
1298 // register_NMI_handler();
1299
1300 // Map rom address
1301 cpqhp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN);
1302 if (!cpqhp_rom_start) {
1303 err ("Could not ioremap memory region for ROM\n");
1304 retval = -EIO;
1305 goto error;
1306 }
1307
1308 /* Now, map the int15 entry point if we are on compaq specific hardware */
1309 compaq_nvram_init(cpqhp_rom_start);
1310
1311 /* Map smbios table entry point structure */
1312 smbios_table = detect_SMBIOS_pointer(cpqhp_rom_start,
1313 cpqhp_rom_start + ROM_PHY_LEN);
1314 if (!smbios_table) {
1315 err ("Could not find the SMBIOS pointer in memory\n");
1316 retval = -EIO;
1317 goto error_rom_start;
1318 }
1319
1320 smbios_start = ioremap(readl(smbios_table + ST_ADDRESS),
1321 readw(smbios_table + ST_LENGTH));
1322 if (!smbios_start) {
1323 err ("Could not ioremap memory region taken from SMBIOS values\n");
1324 retval = -EIO;
1325 goto error_smbios_start;
1326 }
1327
1328 initialized = 1;
1329
1330 return retval;
1331
1332error_smbios_start:
1333 iounmap(smbios_start);
1334error_rom_start:
1335 iounmap(cpqhp_rom_start);
1336error:
1337 return retval;
1338}
1339
1340
1341static void __exit unload_cpqphpd(void)
1342{
1343 struct pci_func *next;
1344 struct pci_func *TempSlot;
1345 int loop;
1346 u32 rc;
1347 struct controller *ctrl;
1348 struct controller *tctrl;
1349 struct pci_resource *res;
1350 struct pci_resource *tres;
1351
1352 rc = compaq_nvram_store(cpqhp_rom_start);
1353
1354 ctrl = cpqhp_ctrl_list;
1355
1356 while (ctrl) {
1357 if (ctrl->hpc_reg) {
1358 u16 misc;
1359 rc = read_slot_enable (ctrl);
1360
1361 writeb(0, ctrl->hpc_reg + SLOT_SERR);
1362 writel(0xFFFFFFC0L | ~rc, ctrl->hpc_reg + INT_MASK);
1363
1364 misc = readw(ctrl->hpc_reg + MISC);
1365 misc &= 0xFFFD;
1366 writew(misc, ctrl->hpc_reg + MISC);
1367 }
1368
1369 ctrl_slot_cleanup(ctrl);
1370
1371 res = ctrl->io_head;
1372 while (res) {
1373 tres = res;
1374 res = res->next;
1375 kfree(tres);
1376 }
1377
1378 res = ctrl->mem_head;
1379 while (res) {
1380 tres = res;
1381 res = res->next;
1382 kfree(tres);
1383 }
1384
1385 res = ctrl->p_mem_head;
1386 while (res) {
1387 tres = res;
1388 res = res->next;
1389 kfree(tres);
1390 }
1391
1392 res = ctrl->bus_head;
1393 while (res) {
1394 tres = res;
1395 res = res->next;
1396 kfree(tres);
1397 }
1398
1399 kfree (ctrl->pci_bus);
1400
1401 tctrl = ctrl;
1402 ctrl = ctrl->next;
1403 kfree(tctrl);
1404 }
1405
1406 for (loop = 0; loop < 256; loop++) {
1407 next = cpqhp_slot_list[loop];
1408 while (next != NULL) {
1409 res = next->io_head;
1410 while (res) {
1411 tres = res;
1412 res = res->next;
1413 kfree(tres);
1414 }
1415
1416 res = next->mem_head;
1417 while (res) {
1418 tres = res;
1419 res = res->next;
1420 kfree(tres);
1421 }
1422
1423 res = next->p_mem_head;
1424 while (res) {
1425 tres = res;
1426 res = res->next;
1427 kfree(tres);
1428 }
1429
1430 res = next->bus_head;
1431 while (res) {
1432 tres = res;
1433 res = res->next;
1434 kfree(tres);
1435 }
1436
1437 TempSlot = next;
1438 next = next->next;
1439 kfree(TempSlot);
1440 }
1441 }
1442
1443 // Stop the notification mechanism
1444 cpqhp_event_stop_thread();
1445
1446 //unmap the rom address
1447 if (cpqhp_rom_start)
1448 iounmap(cpqhp_rom_start);
1449 if (smbios_start)
1450 iounmap(smbios_start);
1451}
1452
1453
1454
1455static struct pci_device_id hpcd_pci_tbl[] = {
1456 {
1457 /* handle any PCI Hotplug controller */
1458 .class = ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
1459 .class_mask = ~0,
1460
1461 /* no matter who makes it */
1462 .vendor = PCI_ANY_ID,
1463 .device = PCI_ANY_ID,
1464 .subvendor = PCI_ANY_ID,
1465 .subdevice = PCI_ANY_ID,
1466
1467 }, { /* end: all zeroes */ }
1468};
1469
1470MODULE_DEVICE_TABLE(pci, hpcd_pci_tbl);
1471
1472
1473
1474static struct pci_driver cpqhpc_driver = {
1475 .name = "compaq_pci_hotplug",
1476 .id_table = hpcd_pci_tbl,
1477 .probe = cpqhpc_probe,
1478 /* remove: cpqhpc_remove_one, */
1479};
1480
1481
1482
1483static int __init cpqhpc_init(void)
1484{
1485 int result;
1486
1487 cpqhp_debug = debug;
1488
1489 info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
1490 result = pci_register_driver(&cpqhpc_driver);
1491 dbg("pci_register_driver = %d\n", result);
1492 return result;
1493}
1494
1495
1496static void __exit cpqhpc_cleanup(void)
1497{
1498 dbg("unload_cpqphpd()\n");
1499 unload_cpqphpd();
1500
1501 dbg("pci_unregister_driver\n");
1502 pci_unregister_driver(&cpqhpc_driver);
1503}
1504
1505
1506module_init(cpqhpc_init);
1507module_exit(cpqhpc_cleanup);
1508
1509
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c
new file mode 100644
index 000000000000..10a5a7674a8a
--- /dev/null
+++ b/drivers/pci/hotplug/cpqphp_ctrl.c
@@ -0,0 +1,3096 @@
1/*
2 * Compaq Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <greg@kroah.com>
26 *
27 */
28
29#include <linux/config.h>
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/types.h>
33#include <linux/slab.h>
34#include <linux/workqueue.h>
35#include <linux/interrupt.h>
36#include <linux/delay.h>
37#include <linux/wait.h>
38#include <linux/smp_lock.h>
39#include <linux/pci.h>
40#include "cpqphp.h"
41
42static u32 configure_new_device(struct controller* ctrl, struct pci_func *func,
43 u8 behind_bridge, struct resource_lists *resources);
44static int configure_new_function(struct controller* ctrl, struct pci_func *func,
45 u8 behind_bridge, struct resource_lists *resources);
46static void interrupt_event_handler(struct controller *ctrl);
47
48static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */
49static struct semaphore event_exit; /* guard ensure thread has exited before calling it quits */
50static int event_finished;
51static unsigned long pushbutton_pending; /* = 0 */
52
53/* things needed for the long_delay function */
54static struct semaphore delay_sem;
55static wait_queue_head_t delay_wait;
56
57/* delay is in jiffies to wait for */
58static void long_delay(int delay)
59{
60 DECLARE_WAITQUEUE(wait, current);
61
62 /* only allow 1 customer into the delay queue at once
63 * yes this makes some people wait even longer, but who really cares?
64 * this is for _huge_ delays to make the hardware happy as the
65 * signals bounce around
66 */
67 down (&delay_sem);
68
69 init_waitqueue_head(&delay_wait);
70
71 add_wait_queue(&delay_wait, &wait);
72 msleep_interruptible(jiffies_to_msecs(delay));
73 remove_wait_queue(&delay_wait, &wait);
74
75 up(&delay_sem);
76}
77
78
79/* FIXME: The following line needs to be somewhere else... */
80#define WRONG_BUS_FREQUENCY 0x07
81static u8 handle_switch_change(u8 change, struct controller * ctrl)
82{
83 int hp_slot;
84 u8 rc = 0;
85 u16 temp_word;
86 struct pci_func *func;
87 struct event_info *taskInfo;
88
89 if (!change)
90 return 0;
91
92 /* Switch Change */
93 dbg("cpqsbd: Switch interrupt received.\n");
94
95 for (hp_slot = 0; hp_slot < 6; hp_slot++) {
96 if (change & (0x1L << hp_slot)) {
97 /**********************************
98 * this one changed.
99 **********************************/
100 func = cpqhp_slot_find(ctrl->bus,
101 (hp_slot + ctrl->slot_device_offset), 0);
102
103 /* this is the structure that tells the worker thread
104 *what to do */
105 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
106 ctrl->next_event = (ctrl->next_event + 1) % 10;
107 taskInfo->hp_slot = hp_slot;
108
109 rc++;
110
111 temp_word = ctrl->ctrl_int_comp >> 16;
112 func->presence_save = (temp_word >> hp_slot) & 0x01;
113 func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
114
115 if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
116 /**********************************
117 * Switch opened
118 **********************************/
119
120 func->switch_save = 0;
121
122 taskInfo->event_type = INT_SWITCH_OPEN;
123 } else {
124 /**********************************
125 * Switch closed
126 **********************************/
127
128 func->switch_save = 0x10;
129
130 taskInfo->event_type = INT_SWITCH_CLOSE;
131 }
132 }
133 }
134
135 return rc;
136}
137
138/**
139 * cpqhp_find_slot: find the struct slot of given device
140 * @ctrl: scan lots of this controller
141 * @device: the device id to find
142 */
143static struct slot *cpqhp_find_slot(struct controller *ctrl, u8 device)
144{
145 struct slot *slot = ctrl->slot;
146
147 while (slot && (slot->device != device)) {
148 slot = slot->next;
149 }
150
151 return slot;
152}
153
154
155static u8 handle_presence_change(u16 change, struct controller * ctrl)
156{
157 int hp_slot;
158 u8 rc = 0;
159 u8 temp_byte;
160 u16 temp_word;
161 struct pci_func *func;
162 struct event_info *taskInfo;
163 struct slot *p_slot;
164
165 if (!change)
166 return 0;
167
168 /**********************************
169 * Presence Change
170 **********************************/
171 dbg("cpqsbd: Presence/Notify input change.\n");
172 dbg(" Changed bits are 0x%4.4x\n", change );
173
174 for (hp_slot = 0; hp_slot < 6; hp_slot++) {
175 if (change & (0x0101 << hp_slot)) {
176 /**********************************
177 * this one changed.
178 **********************************/
179 func = cpqhp_slot_find(ctrl->bus,
180 (hp_slot + ctrl->slot_device_offset), 0);
181
182 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
183 ctrl->next_event = (ctrl->next_event + 1) % 10;
184 taskInfo->hp_slot = hp_slot;
185
186 rc++;
187
188 p_slot = cpqhp_find_slot(ctrl, hp_slot + (readb(ctrl->hpc_reg + SLOT_MASK) >> 4));
189 if (!p_slot)
190 return 0;
191
192 /* If the switch closed, must be a button
193 * If not in button mode, nevermind */
194 if (func->switch_save && (ctrl->push_button == 1)) {
195 temp_word = ctrl->ctrl_int_comp >> 16;
196 temp_byte = (temp_word >> hp_slot) & 0x01;
197 temp_byte |= (temp_word >> (hp_slot + 7)) & 0x02;
198
199 if (temp_byte != func->presence_save) {
200 /**************************************
201 * button Pressed (doesn't do anything)
202 **************************************/
203 dbg("hp_slot %d button pressed\n", hp_slot);
204 taskInfo->event_type = INT_BUTTON_PRESS;
205 } else {
206 /**********************************
207 * button Released - TAKE ACTION!!!!
208 **********************************/
209 dbg("hp_slot %d button released\n", hp_slot);
210 taskInfo->event_type = INT_BUTTON_RELEASE;
211
212 /* Cancel if we are still blinking */
213 if ((p_slot->state == BLINKINGON_STATE)
214 || (p_slot->state == BLINKINGOFF_STATE)) {
215 taskInfo->event_type = INT_BUTTON_CANCEL;
216 dbg("hp_slot %d button cancel\n", hp_slot);
217 } else if ((p_slot->state == POWERON_STATE)
218 || (p_slot->state == POWEROFF_STATE)) {
219 /* info(msg_button_ignore, p_slot->number); */
220 taskInfo->event_type = INT_BUTTON_IGNORE;
221 dbg("hp_slot %d button ignore\n", hp_slot);
222 }
223 }
224 } else {
225 /* Switch is open, assume a presence change
226 * Save the presence state */
227 temp_word = ctrl->ctrl_int_comp >> 16;
228 func->presence_save = (temp_word >> hp_slot) & 0x01;
229 func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
230
231 if ((!(ctrl->ctrl_int_comp & (0x010000 << hp_slot))) ||
232 (!(ctrl->ctrl_int_comp & (0x01000000 << hp_slot)))) {
233 /* Present */
234 taskInfo->event_type = INT_PRESENCE_ON;
235 } else {
236 /* Not Present */
237 taskInfo->event_type = INT_PRESENCE_OFF;
238 }
239 }
240 }
241 }
242
243 return rc;
244}
245
246
247static u8 handle_power_fault(u8 change, struct controller * ctrl)
248{
249 int hp_slot;
250 u8 rc = 0;
251 struct pci_func *func;
252 struct event_info *taskInfo;
253
254 if (!change)
255 return 0;
256
257 /**********************************
258 * power fault
259 **********************************/
260
261 info("power fault interrupt\n");
262
263 for (hp_slot = 0; hp_slot < 6; hp_slot++) {
264 if (change & (0x01 << hp_slot)) {
265 /**********************************
266 * this one changed.
267 **********************************/
268 func = cpqhp_slot_find(ctrl->bus,
269 (hp_slot + ctrl->slot_device_offset), 0);
270
271 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
272 ctrl->next_event = (ctrl->next_event + 1) % 10;
273 taskInfo->hp_slot = hp_slot;
274
275 rc++;
276
277 if (ctrl->ctrl_int_comp & (0x00000100 << hp_slot)) {
278 /**********************************
279 * power fault Cleared
280 **********************************/
281 func->status = 0x00;
282
283 taskInfo->event_type = INT_POWER_FAULT_CLEAR;
284 } else {
285 /**********************************
286 * power fault
287 **********************************/
288 taskInfo->event_type = INT_POWER_FAULT;
289
290 if (ctrl->rev < 4) {
291 amber_LED_on (ctrl, hp_slot);
292 green_LED_off (ctrl, hp_slot);
293 set_SOGO (ctrl);
294
295 /* this is a fatal condition, we want
296 * to crash the machine to protect from
297 * data corruption. simulated_NMI
298 * shouldn't ever return */
299 /* FIXME
300 simulated_NMI(hp_slot, ctrl); */
301
302 /* The following code causes a software
303 * crash just in case simulated_NMI did
304 * return */
305 /*FIXME
306 panic(msg_power_fault); */
307 } else {
308 /* set power fault status for this board */
309 func->status = 0xFF;
310 info("power fault bit %x set\n", hp_slot);
311 }
312 }
313 }
314 }
315
316 return rc;
317}
318
319
320/**
321 * sort_by_size: sort nodes on the list by their length, smallest first.
322 * @head: list to sort
323 *
324 */
325static int sort_by_size(struct pci_resource **head)
326{
327 struct pci_resource *current_res;
328 struct pci_resource *next_res;
329 int out_of_order = 1;
330
331 if (!(*head))
332 return 1;
333
334 if (!((*head)->next))
335 return 0;
336
337 while (out_of_order) {
338 out_of_order = 0;
339
340 /* Special case for swapping list head */
341 if (((*head)->next) &&
342 ((*head)->length > (*head)->next->length)) {
343 out_of_order++;
344 current_res = *head;
345 *head = (*head)->next;
346 current_res->next = (*head)->next;
347 (*head)->next = current_res;
348 }
349
350 current_res = *head;
351
352 while (current_res->next && current_res->next->next) {
353 if (current_res->next->length > current_res->next->next->length) {
354 out_of_order++;
355 next_res = current_res->next;
356 current_res->next = current_res->next->next;
357 current_res = current_res->next;
358 next_res->next = current_res->next;
359 current_res->next = next_res;
360 } else
361 current_res = current_res->next;
362 }
363 } /* End of out_of_order loop */
364
365 return 0;
366}
367
368
369/**
370 * sort_by_max_size: sort nodes on the list by their length, largest first.
371 * @head: list to sort
372 *
373 */
374static int sort_by_max_size(struct pci_resource **head)
375{
376 struct pci_resource *current_res;
377 struct pci_resource *next_res;
378 int out_of_order = 1;
379
380 if (!(*head))
381 return 1;
382
383 if (!((*head)->next))
384 return 0;
385
386 while (out_of_order) {
387 out_of_order = 0;
388
389 /* Special case for swapping list head */
390 if (((*head)->next) &&
391 ((*head)->length < (*head)->next->length)) {
392 out_of_order++;
393 current_res = *head;
394 *head = (*head)->next;
395 current_res->next = (*head)->next;
396 (*head)->next = current_res;
397 }
398
399 current_res = *head;
400
401 while (current_res->next && current_res->next->next) {
402 if (current_res->next->length < current_res->next->next->length) {
403 out_of_order++;
404 next_res = current_res->next;
405 current_res->next = current_res->next->next;
406 current_res = current_res->next;
407 next_res->next = current_res->next;
408 current_res->next = next_res;
409 } else
410 current_res = current_res->next;
411 }
412 } /* End of out_of_order loop */
413
414 return 0;
415}
416
417
418/**
419 * do_pre_bridge_resource_split: find node of resources that are unused
420 *
421 */
422static struct pci_resource *do_pre_bridge_resource_split(struct pci_resource **head,
423 struct pci_resource **orig_head, u32 alignment)
424{
425 struct pci_resource *prevnode = NULL;
426 struct pci_resource *node;
427 struct pci_resource *split_node;
428 u32 rc;
429 u32 temp_dword;
430 dbg("do_pre_bridge_resource_split\n");
431
432 if (!(*head) || !(*orig_head))
433 return NULL;
434
435 rc = cpqhp_resource_sort_and_combine(head);
436
437 if (rc)
438 return NULL;
439
440 if ((*head)->base != (*orig_head)->base)
441 return NULL;
442
443 if ((*head)->length == (*orig_head)->length)
444 return NULL;
445
446
447 /* If we got here, there the bridge requires some of the resource, but
448 * we may be able to split some off of the front */
449
450 node = *head;
451
452 if (node->length & (alignment -1)) {
453 /* this one isn't an aligned length, so we'll make a new entry
454 * and split it up. */
455 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
456
457 if (!split_node)
458 return NULL;
459
460 temp_dword = (node->length | (alignment-1)) + 1 - alignment;
461
462 split_node->base = node->base;
463 split_node->length = temp_dword;
464
465 node->length -= temp_dword;
466 node->base += split_node->length;
467
468 /* Put it in the list */
469 *head = split_node;
470 split_node->next = node;
471 }
472
473 if (node->length < alignment)
474 return NULL;
475
476 /* Now unlink it */
477 if (*head == node) {
478 *head = node->next;
479 } else {
480 prevnode = *head;
481 while (prevnode->next != node)
482 prevnode = prevnode->next;
483
484 prevnode->next = node->next;
485 }
486 node->next = NULL;
487
488 return node;
489}
490
491
492/**
493 * do_bridge_resource_split: find one node of resources that aren't in use
494 *
495 */
496static struct pci_resource *do_bridge_resource_split(struct pci_resource **head, u32 alignment)
497{
498 struct pci_resource *prevnode = NULL;
499 struct pci_resource *node;
500 u32 rc;
501 u32 temp_dword;
502
503 rc = cpqhp_resource_sort_and_combine(head);
504
505 if (rc)
506 return NULL;
507
508 node = *head;
509
510 while (node->next) {
511 prevnode = node;
512 node = node->next;
513 kfree(prevnode);
514 }
515
516 if (node->length < alignment)
517 goto error;
518
519 if (node->base & (alignment - 1)) {
520 /* Short circuit if adjusted size is too small */
521 temp_dword = (node->base | (alignment-1)) + 1;
522 if ((node->length - (temp_dword - node->base)) < alignment)
523 goto error;
524
525 node->length -= (temp_dword - node->base);
526 node->base = temp_dword;
527 }
528
529 if (node->length & (alignment - 1))
530 /* There's stuff in use after this node */
531 goto error;
532
533 return node;
534error:
535 kfree(node);
536 return NULL;
537}
538
539
540/**
541 * get_io_resource: find first node of given size not in ISA aliasing window.
542 * @head: list to search
543 * @size: size of node to find, must be a power of two.
544 *
545 * Description: this function sorts the resource list by size and then returns
546 * returns the first node of "size" length that is not in the ISA aliasing
547 * window. If it finds a node larger than "size" it will split it up.
548 *
549 */
550static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size)
551{
552 struct pci_resource *prevnode;
553 struct pci_resource *node;
554 struct pci_resource *split_node;
555 u32 temp_dword;
556
557 if (!(*head))
558 return NULL;
559
560 if ( cpqhp_resource_sort_and_combine(head) )
561 return NULL;
562
563 if ( sort_by_size(head) )
564 return NULL;
565
566 for (node = *head; node; node = node->next) {
567 if (node->length < size)
568 continue;
569
570 if (node->base & (size - 1)) {
571 /* this one isn't base aligned properly
572 * so we'll make a new entry and split it up */
573 temp_dword = (node->base | (size-1)) + 1;
574
575 /* Short circuit if adjusted size is too small */
576 if ((node->length - (temp_dword - node->base)) < size)
577 continue;
578
579 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
580
581 if (!split_node)
582 return NULL;
583
584 split_node->base = node->base;
585 split_node->length = temp_dword - node->base;
586 node->base = temp_dword;
587 node->length -= split_node->length;
588
589 /* Put it in the list */
590 split_node->next = node->next;
591 node->next = split_node;
592 } /* End of non-aligned base */
593
594 /* Don't need to check if too small since we already did */
595 if (node->length > size) {
596 /* this one is longer than we need
597 * so we'll make a new entry and split it up */
598 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
599
600 if (!split_node)
601 return NULL;
602
603 split_node->base = node->base + size;
604 split_node->length = node->length - size;
605 node->length = size;
606
607 /* Put it in the list */
608 split_node->next = node->next;
609 node->next = split_node;
610 } /* End of too big on top end */
611
612 /* For IO make sure it's not in the ISA aliasing space */
613 if (node->base & 0x300L)
614 continue;
615
616 /* If we got here, then it is the right size
617 * Now take it out of the list and break */
618 if (*head == node) {
619 *head = node->next;
620 } else {
621 prevnode = *head;
622 while (prevnode->next != node)
623 prevnode = prevnode->next;
624
625 prevnode->next = node->next;
626 }
627 node->next = NULL;
628 break;
629 }
630
631 return node;
632}
633
634
635/**
636 * get_max_resource: get largest node which has at least the given size.
637 * @head: the list to search the node in
638 * @size: the minimum size of the node to find
639 *
640 * Description: Gets the largest node that is at least "size" big from the
641 * list pointed to by head. It aligns the node on top and bottom
642 * to "size" alignment before returning it.
643 */
644static struct pci_resource *get_max_resource(struct pci_resource **head, u32 size)
645{
646 struct pci_resource *max;
647 struct pci_resource *temp;
648 struct pci_resource *split_node;
649 u32 temp_dword;
650
651 if (cpqhp_resource_sort_and_combine(head))
652 return NULL;
653
654 if (sort_by_max_size(head))
655 return NULL;
656
657 for (max = *head; max; max = max->next) {
658 /* If not big enough we could probably just bail,
659 * instead we'll continue to the next. */
660 if (max->length < size)
661 continue;
662
663 if (max->base & (size - 1)) {
664 /* this one isn't base aligned properly
665 * so we'll make a new entry and split it up */
666 temp_dword = (max->base | (size-1)) + 1;
667
668 /* Short circuit if adjusted size is too small */
669 if ((max->length - (temp_dword - max->base)) < size)
670 continue;
671
672 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
673
674 if (!split_node)
675 return NULL;
676
677 split_node->base = max->base;
678 split_node->length = temp_dword - max->base;
679 max->base = temp_dword;
680 max->length -= split_node->length;
681
682 split_node->next = max->next;
683 max->next = split_node;
684 }
685
686 if ((max->base + max->length) & (size - 1)) {
687 /* this one isn't end aligned properly at the top
688 * so we'll make a new entry and split it up */
689 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
690
691 if (!split_node)
692 return NULL;
693 temp_dword = ((max->base + max->length) & ~(size - 1));
694 split_node->base = temp_dword;
695 split_node->length = max->length + max->base
696 - split_node->base;
697 max->length -= split_node->length;
698
699 split_node->next = max->next;
700 max->next = split_node;
701 }
702
703 /* Make sure it didn't shrink too much when we aligned it */
704 if (max->length < size)
705 continue;
706
707 /* Now take it out of the list */
708 temp = *head;
709 if (temp == max) {
710 *head = max->next;
711 } else {
712 while (temp && temp->next != max) {
713 temp = temp->next;
714 }
715
716 temp->next = max->next;
717 }
718
719 max->next = NULL;
720 break;
721 }
722
723 return max;
724}
725
726
727/**
728 * get_resource: find resource of given size and split up larger ones.
729 * @head: the list to search for resources
730 * @size: the size limit to use
731 *
732 * Description: This function sorts the resource list by size and then
733 * returns the first node of "size" length. If it finds a node
734 * larger than "size" it will split it up.
735 *
736 * size must be a power of two.
737 */
738static struct pci_resource *get_resource(struct pci_resource **head, u32 size)
739{
740 struct pci_resource *prevnode;
741 struct pci_resource *node;
742 struct pci_resource *split_node;
743 u32 temp_dword;
744
745 if (cpqhp_resource_sort_and_combine(head))
746 return NULL;
747
748 if (sort_by_size(head))
749 return NULL;
750
751 for (node = *head; node; node = node->next) {
752 dbg("%s: req_size =%x node=%p, base=%x, length=%x\n",
753 __FUNCTION__, size, node, node->base, node->length);
754 if (node->length < size)
755 continue;
756
757 if (node->base & (size - 1)) {
758 dbg("%s: not aligned\n", __FUNCTION__);
759 /* this one isn't base aligned properly
760 * so we'll make a new entry and split it up */
761 temp_dword = (node->base | (size-1)) + 1;
762
763 /* Short circuit if adjusted size is too small */
764 if ((node->length - (temp_dword - node->base)) < size)
765 continue;
766
767 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
768
769 if (!split_node)
770 return NULL;
771
772 split_node->base = node->base;
773 split_node->length = temp_dword - node->base;
774 node->base = temp_dword;
775 node->length -= split_node->length;
776
777 split_node->next = node->next;
778 node->next = split_node;
779 } /* End of non-aligned base */
780
781 /* Don't need to check if too small since we already did */
782 if (node->length > size) {
783 dbg("%s: too big\n", __FUNCTION__);
784 /* this one is longer than we need
785 * so we'll make a new entry and split it up */
786 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
787
788 if (!split_node)
789 return NULL;
790
791 split_node->base = node->base + size;
792 split_node->length = node->length - size;
793 node->length = size;
794
795 /* Put it in the list */
796 split_node->next = node->next;
797 node->next = split_node;
798 } /* End of too big on top end */
799
800 dbg("%s: got one!!!\n", __FUNCTION__);
801 /* If we got here, then it is the right size
802 * Now take it out of the list */
803 if (*head == node) {
804 *head = node->next;
805 } else {
806 prevnode = *head;
807 while (prevnode->next != node)
808 prevnode = prevnode->next;
809
810 prevnode->next = node->next;
811 }
812 node->next = NULL;
813 break;
814 }
815 return node;
816}
817
818
819/**
820 * cpqhp_resource_sort_and_combine: sort nodes by base addresses and clean up.
821 * @head: the list to sort and clean up
822 *
823 * Description: Sorts all of the nodes in the list in ascending order by
824 * their base addresses. Also does garbage collection by
825 * combining adjacent nodes.
826 *
827 * returns 0 if success
828 */
829int cpqhp_resource_sort_and_combine(struct pci_resource **head)
830{
831 struct pci_resource *node1;
832 struct pci_resource *node2;
833 int out_of_order = 1;
834
835 dbg("%s: head = %p, *head = %p\n", __FUNCTION__, head, *head);
836
837 if (!(*head))
838 return 1;
839
840 dbg("*head->next = %p\n",(*head)->next);
841
842 if (!(*head)->next)
843 return 0; /* only one item on the list, already sorted! */
844
845 dbg("*head->base = 0x%x\n",(*head)->base);
846 dbg("*head->next->base = 0x%x\n",(*head)->next->base);
847 while (out_of_order) {
848 out_of_order = 0;
849
850 /* Special case for swapping list head */
851 if (((*head)->next) &&
852 ((*head)->base > (*head)->next->base)) {
853 node1 = *head;
854 (*head) = (*head)->next;
855 node1->next = (*head)->next;
856 (*head)->next = node1;
857 out_of_order++;
858 }
859
860 node1 = (*head);
861
862 while (node1->next && node1->next->next) {
863 if (node1->next->base > node1->next->next->base) {
864 out_of_order++;
865 node2 = node1->next;
866 node1->next = node1->next->next;
867 node1 = node1->next;
868 node2->next = node1->next;
869 node1->next = node2;
870 } else
871 node1 = node1->next;
872 }
873 } /* End of out_of_order loop */
874
875 node1 = *head;
876
877 while (node1 && node1->next) {
878 if ((node1->base + node1->length) == node1->next->base) {
879 /* Combine */
880 dbg("8..\n");
881 node1->length += node1->next->length;
882 node2 = node1->next;
883 node1->next = node1->next->next;
884 kfree(node2);
885 } else
886 node1 = node1->next;
887 }
888
889 return 0;
890}
891
892
893irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data, struct pt_regs *regs)
894{
895 struct controller *ctrl = data;
896 u8 schedule_flag = 0;
897 u8 reset;
898 u16 misc;
899 u32 Diff;
900 u32 temp_dword;
901
902
903 misc = readw(ctrl->hpc_reg + MISC);
904 /***************************************
905 * Check to see if it was our interrupt
906 ***************************************/
907 if (!(misc & 0x000C)) {
908 return IRQ_NONE;
909 }
910
911 if (misc & 0x0004) {
912 /**********************************
913 * Serial Output interrupt Pending
914 **********************************/
915
916 /* Clear the interrupt */
917 misc |= 0x0004;
918 writew(misc, ctrl->hpc_reg + MISC);
919
920 /* Read to clear posted writes */
921 misc = readw(ctrl->hpc_reg + MISC);
922
923 dbg ("%s - waking up\n", __FUNCTION__);
924 wake_up_interruptible(&ctrl->queue);
925 }
926
927 if (misc & 0x0008) {
928 /* General-interrupt-input interrupt Pending */
929 Diff = readl(ctrl->hpc_reg + INT_INPUT_CLEAR) ^ ctrl->ctrl_int_comp;
930
931 ctrl->ctrl_int_comp = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
932
933 /* Clear the interrupt */
934 writel(Diff, ctrl->hpc_reg + INT_INPUT_CLEAR);
935
936 /* Read it back to clear any posted writes */
937 temp_dword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
938
939 if (!Diff)
940 /* Clear all interrupts */
941 writel(0xFFFFFFFF, ctrl->hpc_reg + INT_INPUT_CLEAR);
942
943 schedule_flag += handle_switch_change((u8)(Diff & 0xFFL), ctrl);
944 schedule_flag += handle_presence_change((u16)((Diff & 0xFFFF0000L) >> 16), ctrl);
945 schedule_flag += handle_power_fault((u8)((Diff & 0xFF00L) >> 8), ctrl);
946 }
947
948 reset = readb(ctrl->hpc_reg + RESET_FREQ_MODE);
949 if (reset & 0x40) {
950 /* Bus reset has completed */
951 reset &= 0xCF;
952 writeb(reset, ctrl->hpc_reg + RESET_FREQ_MODE);
953 reset = readb(ctrl->hpc_reg + RESET_FREQ_MODE);
954 wake_up_interruptible(&ctrl->queue);
955 }
956
957 if (schedule_flag) {
958 up(&event_semaphore);
959 dbg("Signal event_semaphore\n");
960 }
961 return IRQ_HANDLED;
962}
963
964
965/**
966 * cpqhp_slot_create - Creates a node and adds it to the proper bus.
967 * @busnumber - bus where new node is to be located
968 *
969 * Returns pointer to the new node or NULL if unsuccessful
970 */
971struct pci_func *cpqhp_slot_create(u8 busnumber)
972{
973 struct pci_func *new_slot;
974 struct pci_func *next;
975
976 new_slot = kmalloc(sizeof(*new_slot), GFP_KERNEL);
977
978 if (new_slot == NULL) {
979 /* I'm not dead yet!
980 * You will be. */
981 return new_slot;
982 }
983
984 memset(new_slot, 0, sizeof(struct pci_func));
985
986 new_slot->next = NULL;
987 new_slot->configured = 1;
988
989 if (cpqhp_slot_list[busnumber] == NULL) {
990 cpqhp_slot_list[busnumber] = new_slot;
991 } else {
992 next = cpqhp_slot_list[busnumber];
993 while (next->next != NULL)
994 next = next->next;
995 next->next = new_slot;
996 }
997 return new_slot;
998}
999
1000
1001/**
1002 * slot_remove - Removes a node from the linked list of slots.
1003 * @old_slot: slot to remove
1004 *
1005 * Returns 0 if successful, !0 otherwise.
1006 */
1007static int slot_remove(struct pci_func * old_slot)
1008{
1009 struct pci_func *next;
1010
1011 if (old_slot == NULL)
1012 return 1;
1013
1014 next = cpqhp_slot_list[old_slot->bus];
1015
1016 if (next == NULL) {
1017 return 1;
1018 }
1019
1020 if (next == old_slot) {
1021 cpqhp_slot_list[old_slot->bus] = old_slot->next;
1022 cpqhp_destroy_board_resources(old_slot);
1023 kfree(old_slot);
1024 return 0;
1025 }
1026
1027 while ((next->next != old_slot) && (next->next != NULL)) {
1028 next = next->next;
1029 }
1030
1031 if (next->next == old_slot) {
1032 next->next = old_slot->next;
1033 cpqhp_destroy_board_resources(old_slot);
1034 kfree(old_slot);
1035 return 0;
1036 } else
1037 return 2;
1038}
1039
1040
1041/**
1042 * bridge_slot_remove - Removes a node from the linked list of slots.
1043 * @bridge: bridge to remove
1044 *
1045 * Returns 0 if successful, !0 otherwise.
1046 */
1047static int bridge_slot_remove(struct pci_func *bridge)
1048{
1049 u8 subordinateBus, secondaryBus;
1050 u8 tempBus;
1051 struct pci_func *next;
1052
1053 secondaryBus = (bridge->config_space[0x06] >> 8) & 0xFF;
1054 subordinateBus = (bridge->config_space[0x06] >> 16) & 0xFF;
1055
1056 for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {
1057 next = cpqhp_slot_list[tempBus];
1058
1059 while (!slot_remove(next)) {
1060 next = cpqhp_slot_list[tempBus];
1061 }
1062 }
1063
1064 next = cpqhp_slot_list[bridge->bus];
1065
1066 if (next == NULL)
1067 return 1;
1068
1069 if (next == bridge) {
1070 cpqhp_slot_list[bridge->bus] = bridge->next;
1071 goto out;
1072 }
1073
1074 while ((next->next != bridge) && (next->next != NULL))
1075 next = next->next;
1076
1077 if (next->next != bridge)
1078 return 2;
1079 next->next = bridge->next;
1080out:
1081 kfree(bridge);
1082 return 0;
1083}
1084
1085
1086/**
1087 * cpqhp_slot_find - Looks for a node by bus, and device, multiple functions accessed
1088 * @bus: bus to find
1089 * @device: device to find
1090 * @index: is 0 for first function found, 1 for the second...
1091 *
1092 * Returns pointer to the node if successful, %NULL otherwise.
1093 */
1094struct pci_func *cpqhp_slot_find(u8 bus, u8 device, u8 index)
1095{
1096 int found = -1;
1097 struct pci_func *func;
1098
1099 func = cpqhp_slot_list[bus];
1100
1101 if ((func == NULL) || ((func->device == device) && (index == 0)))
1102 return func;
1103
1104 if (func->device == device)
1105 found++;
1106
1107 while (func->next != NULL) {
1108 func = func->next;
1109
1110 if (func->device == device)
1111 found++;
1112
1113 if (found == index)
1114 return func;
1115 }
1116
1117 return NULL;
1118}
1119
1120
1121/* DJZ: I don't think is_bridge will work as is.
1122 * FIXME */
1123static int is_bridge(struct pci_func * func)
1124{
1125 /* Check the header type */
1126 if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01)
1127 return 1;
1128 else
1129 return 0;
1130}
1131
1132
1133/**
1134 * set_controller_speed - set the frequency and/or mode of a specific
1135 * controller segment.
1136 *
1137 * @ctrl: controller to change frequency/mode for.
1138 * @adapter_speed: the speed of the adapter we want to match.
1139 * @hp_slot: the slot number where the adapter is installed.
1140 *
1141 * Returns 0 if we successfully change frequency and/or mode to match the
1142 * adapter speed.
1143 *
1144 */
1145static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_slot)
1146{
1147 struct slot *slot;
1148 u8 reg;
1149 u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
1150 u16 reg16;
1151 u32 leds = readl(ctrl->hpc_reg + LED_CONTROL);
1152
1153 if (ctrl->speed == adapter_speed)
1154 return 0;
1155
1156 /* We don't allow freq/mode changes if we find another adapter running
1157 * in another slot on this controller */
1158 for(slot = ctrl->slot; slot; slot = slot->next) {
1159 if (slot->device == (hp_slot + ctrl->slot_device_offset))
1160 continue;
1161 if (!slot->hotplug_slot && !slot->hotplug_slot->info)
1162 continue;
1163 if (slot->hotplug_slot->info->adapter_status == 0)
1164 continue;
1165 /* If another adapter is running on the same segment but at a
1166 * lower speed/mode, we allow the new adapter to function at
1167 * this rate if supported */
1168 if (ctrl->speed < adapter_speed)
1169 return 0;
1170
1171 return 1;
1172 }
1173
1174 /* If the controller doesn't support freq/mode changes and the
1175 * controller is running at a higher mode, we bail */
1176 if ((ctrl->speed > adapter_speed) && (!ctrl->pcix_speed_capability))
1177 return 1;
1178
1179 /* But we allow the adapter to run at a lower rate if possible */
1180 if ((ctrl->speed < adapter_speed) && (!ctrl->pcix_speed_capability))
1181 return 0;
1182
1183 /* We try to set the max speed supported by both the adapter and
1184 * controller */
1185 if (ctrl->speed_capability < adapter_speed) {
1186 if (ctrl->speed == ctrl->speed_capability)
1187 return 0;
1188 adapter_speed = ctrl->speed_capability;
1189 }
1190
1191 writel(0x0L, ctrl->hpc_reg + LED_CONTROL);
1192 writeb(0x00, ctrl->hpc_reg + SLOT_ENABLE);
1193
1194 set_SOGO(ctrl);
1195 wait_for_ctrl_irq(ctrl);
1196
1197 if (adapter_speed != PCI_SPEED_133MHz_PCIX)
1198 reg = 0xF5;
1199 else
1200 reg = 0xF4;
1201 pci_write_config_byte(ctrl->pci_dev, 0x41, reg);
1202
1203 reg16 = readw(ctrl->hpc_reg + NEXT_CURR_FREQ);
1204 reg16 &= ~0x000F;
1205 switch(adapter_speed) {
1206 case(PCI_SPEED_133MHz_PCIX):
1207 reg = 0x75;
1208 reg16 |= 0xB;
1209 break;
1210 case(PCI_SPEED_100MHz_PCIX):
1211 reg = 0x74;
1212 reg16 |= 0xA;
1213 break;
1214 case(PCI_SPEED_66MHz_PCIX):
1215 reg = 0x73;
1216 reg16 |= 0x9;
1217 break;
1218 case(PCI_SPEED_66MHz):
1219 reg = 0x73;
1220 reg16 |= 0x1;
1221 break;
1222 default: /* 33MHz PCI 2.2 */
1223 reg = 0x71;
1224 break;
1225
1226 }
1227 reg16 |= 0xB << 12;
1228 writew(reg16, ctrl->hpc_reg + NEXT_CURR_FREQ);
1229
1230 mdelay(5);
1231
1232 /* Reenable interrupts */
1233 writel(0, ctrl->hpc_reg + INT_MASK);
1234
1235 pci_write_config_byte(ctrl->pci_dev, 0x41, reg);
1236
1237 /* Restart state machine */
1238 reg = ~0xF;
1239 pci_read_config_byte(ctrl->pci_dev, 0x43, &reg);
1240 pci_write_config_byte(ctrl->pci_dev, 0x43, reg);
1241
1242 /* Only if mode change...*/
1243 if (((ctrl->speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) ||
1244 ((ctrl->speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz)))
1245 set_SOGO(ctrl);
1246
1247 wait_for_ctrl_irq(ctrl);
1248 mdelay(1100);
1249
1250 /* Restore LED/Slot state */
1251 writel(leds, ctrl->hpc_reg + LED_CONTROL);
1252 writeb(slot_power, ctrl->hpc_reg + SLOT_ENABLE);
1253
1254 set_SOGO(ctrl);
1255 wait_for_ctrl_irq(ctrl);
1256
1257 ctrl->speed = adapter_speed;
1258 slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1259
1260 info("Successfully changed frequency/mode for adapter in slot %d\n",
1261 slot->number);
1262 return 0;
1263}
1264
1265/* the following routines constitute the bulk of the
1266 hotplug controller logic
1267 */
1268
1269
1270/**
1271 * board_replaced - Called after a board has been replaced in the system.
1272 *
1273 * This is only used if we don't have resources for hot add
1274 * Turns power on for the board
1275 * Checks to see if board is the same
1276 * If board is same, reconfigures it
1277 * If board isn't same, turns it back off.
1278 *
1279 */
1280static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
1281{
1282 u8 hp_slot;
1283 u8 temp_byte;
1284 u8 adapter_speed;
1285 u32 index;
1286 u32 rc = 0;
1287 u32 src = 8;
1288
1289 hp_slot = func->device - ctrl->slot_device_offset;
1290
1291 if (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot)) {
1292 /**********************************
1293 * The switch is open.
1294 **********************************/
1295 rc = INTERLOCK_OPEN;
1296 } else if (is_slot_enabled (ctrl, hp_slot)) {
1297 /**********************************
1298 * The board is already on
1299 **********************************/
1300 rc = CARD_FUNCTIONING;
1301 } else {
1302 down(&ctrl->crit_sect);
1303
1304 /* turn on board without attaching to the bus */
1305 enable_slot_power (ctrl, hp_slot);
1306
1307 set_SOGO(ctrl);
1308
1309 /* Wait for SOBS to be unset */
1310 wait_for_ctrl_irq (ctrl);
1311
1312 /* Change bits in slot power register to force another shift out
1313 * NOTE: this is to work around the timer bug */
1314 temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);
1315 writeb(0x00, ctrl->hpc_reg + SLOT_POWER);
1316 writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);
1317
1318 set_SOGO(ctrl);
1319
1320 /* Wait for SOBS to be unset */
1321 wait_for_ctrl_irq (ctrl);
1322
1323 adapter_speed = get_adapter_speed(ctrl, hp_slot);
1324 if (ctrl->speed != adapter_speed)
1325 if (set_controller_speed(ctrl, adapter_speed, hp_slot))
1326 rc = WRONG_BUS_FREQUENCY;
1327
1328 /* turn off board without attaching to the bus */
1329 disable_slot_power (ctrl, hp_slot);
1330
1331 set_SOGO(ctrl);
1332
1333 /* Wait for SOBS to be unset */
1334 wait_for_ctrl_irq (ctrl);
1335
1336 up(&ctrl->crit_sect);
1337
1338 if (rc)
1339 return rc;
1340
1341 down(&ctrl->crit_sect);
1342
1343 slot_enable (ctrl, hp_slot);
1344 green_LED_blink (ctrl, hp_slot);
1345
1346 amber_LED_off (ctrl, hp_slot);
1347
1348 set_SOGO(ctrl);
1349
1350 /* Wait for SOBS to be unset */
1351 wait_for_ctrl_irq (ctrl);
1352
1353 up(&ctrl->crit_sect);
1354
1355 /* Wait for ~1 second because of hot plug spec */
1356 long_delay(1*HZ);
1357
1358 /* Check for a power fault */
1359 if (func->status == 0xFF) {
1360 /* power fault occurred, but it was benign */
1361 rc = POWER_FAILURE;
1362 func->status = 0;
1363 } else
1364 rc = cpqhp_valid_replace(ctrl, func);
1365
1366 if (!rc) {
1367 /* It must be the same board */
1368
1369 rc = cpqhp_configure_board(ctrl, func);
1370
1371 if (rc || src) {
1372 /* If configuration fails, turn it off
1373 * Get slot won't work for devices behind
1374 * bridges, but in this case it will always be
1375 * called for the "base" bus/dev/func of an
1376 * adapter. */
1377
1378 down(&ctrl->crit_sect);
1379
1380 amber_LED_on (ctrl, hp_slot);
1381 green_LED_off (ctrl, hp_slot);
1382 slot_disable (ctrl, hp_slot);
1383
1384 set_SOGO(ctrl);
1385
1386 /* Wait for SOBS to be unset */
1387 wait_for_ctrl_irq (ctrl);
1388
1389 up(&ctrl->crit_sect);
1390
1391 if (rc)
1392 return rc;
1393 else
1394 return 1;
1395 }
1396
1397 func->status = 0;
1398 func->switch_save = 0x10;
1399
1400 index = 1;
1401 while (((func = cpqhp_slot_find(func->bus, func->device, index)) != NULL) && !rc) {
1402 rc |= cpqhp_configure_board(ctrl, func);
1403 index++;
1404 }
1405
1406 if (rc) {
1407 /* If configuration fails, turn it off
1408 * Get slot won't work for devices behind
1409 * bridges, but in this case it will always be
1410 * called for the "base" bus/dev/func of an
1411 * adapter. */
1412
1413 down(&ctrl->crit_sect);
1414
1415 amber_LED_on (ctrl, hp_slot);
1416 green_LED_off (ctrl, hp_slot);
1417 slot_disable (ctrl, hp_slot);
1418
1419 set_SOGO(ctrl);
1420
1421 /* Wait for SOBS to be unset */
1422 wait_for_ctrl_irq (ctrl);
1423
1424 up(&ctrl->crit_sect);
1425
1426 return rc;
1427 }
1428 /* Done configuring so turn LED on full time */
1429
1430 down(&ctrl->crit_sect);
1431
1432 green_LED_on (ctrl, hp_slot);
1433
1434 set_SOGO(ctrl);
1435
1436 /* Wait for SOBS to be unset */
1437 wait_for_ctrl_irq (ctrl);
1438
1439 up(&ctrl->crit_sect);
1440 rc = 0;
1441 } else {
1442 /* Something is wrong
1443
1444 * Get slot won't work for devices behind bridges, but
1445 * in this case it will always be called for the "base"
1446 * bus/dev/func of an adapter. */
1447
1448 down(&ctrl->crit_sect);
1449
1450 amber_LED_on (ctrl, hp_slot);
1451 green_LED_off (ctrl, hp_slot);
1452 slot_disable (ctrl, hp_slot);
1453
1454 set_SOGO(ctrl);
1455
1456 /* Wait for SOBS to be unset */
1457 wait_for_ctrl_irq (ctrl);
1458
1459 up(&ctrl->crit_sect);
1460 }
1461
1462 }
1463 return rc;
1464
1465}
1466
1467
1468/**
1469 * board_added - Called after a board has been added to the system.
1470 *
1471 * Turns power on for the board
1472 * Configures board
1473 *
1474 */
1475static u32 board_added(struct pci_func *func, struct controller *ctrl)
1476{
1477 u8 hp_slot;
1478 u8 temp_byte;
1479 u8 adapter_speed;
1480 int index;
1481 u32 temp_register = 0xFFFFFFFF;
1482 u32 rc = 0;
1483 struct pci_func *new_slot = NULL;
1484 struct slot *p_slot;
1485 struct resource_lists res_lists;
1486
1487 hp_slot = func->device - ctrl->slot_device_offset;
1488 dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n",
1489 __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
1490
1491 down(&ctrl->crit_sect);
1492
1493 /* turn on board without attaching to the bus */
1494 enable_slot_power(ctrl, hp_slot);
1495
1496 set_SOGO(ctrl);
1497
1498 /* Wait for SOBS to be unset */
1499 wait_for_ctrl_irq (ctrl);
1500
1501 /* Change bits in slot power register to force another shift out
1502 * NOTE: this is to work around the timer bug */
1503 temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);
1504 writeb(0x00, ctrl->hpc_reg + SLOT_POWER);
1505 writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);
1506
1507 set_SOGO(ctrl);
1508
1509 /* Wait for SOBS to be unset */
1510 wait_for_ctrl_irq (ctrl);
1511
1512 adapter_speed = get_adapter_speed(ctrl, hp_slot);
1513 if (ctrl->speed != adapter_speed)
1514 if (set_controller_speed(ctrl, adapter_speed, hp_slot))
1515 rc = WRONG_BUS_FREQUENCY;
1516
1517 /* turn off board without attaching to the bus */
1518 disable_slot_power (ctrl, hp_slot);
1519
1520 set_SOGO(ctrl);
1521
1522 /* Wait for SOBS to be unset */
1523 wait_for_ctrl_irq(ctrl);
1524
1525 up(&ctrl->crit_sect);
1526
1527 if (rc)
1528 return rc;
1529
1530 p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1531
1532 /* turn on board and blink green LED */
1533
1534 dbg("%s: before down\n", __FUNCTION__);
1535 down(&ctrl->crit_sect);
1536 dbg("%s: after down\n", __FUNCTION__);
1537
1538 dbg("%s: before slot_enable\n", __FUNCTION__);
1539 slot_enable (ctrl, hp_slot);
1540
1541 dbg("%s: before green_LED_blink\n", __FUNCTION__);
1542 green_LED_blink (ctrl, hp_slot);
1543
1544 dbg("%s: before amber_LED_blink\n", __FUNCTION__);
1545 amber_LED_off (ctrl, hp_slot);
1546
1547 dbg("%s: before set_SOGO\n", __FUNCTION__);
1548 set_SOGO(ctrl);
1549
1550 /* Wait for SOBS to be unset */
1551 dbg("%s: before wait_for_ctrl_irq\n", __FUNCTION__);
1552 wait_for_ctrl_irq (ctrl);
1553 dbg("%s: after wait_for_ctrl_irq\n", __FUNCTION__);
1554
1555 dbg("%s: before up\n", __FUNCTION__);
1556 up(&ctrl->crit_sect);
1557 dbg("%s: after up\n", __FUNCTION__);
1558
1559 /* Wait for ~1 second because of hot plug spec */
1560 dbg("%s: before long_delay\n", __FUNCTION__);
1561 long_delay(1*HZ);
1562 dbg("%s: after long_delay\n", __FUNCTION__);
1563
1564 dbg("%s: func status = %x\n", __FUNCTION__, func->status);
1565 /* Check for a power fault */
1566 if (func->status == 0xFF) {
1567 /* power fault occurred, but it was benign */
1568 temp_register = 0xFFFFFFFF;
1569 dbg("%s: temp register set to %x by power fault\n", __FUNCTION__, temp_register);
1570 rc = POWER_FAILURE;
1571 func->status = 0;
1572 } else {
1573 /* Get vendor/device ID u32 */
1574 ctrl->pci_bus->number = func->bus;
1575 rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, func->function), PCI_VENDOR_ID, &temp_register);
1576 dbg("%s: pci_read_config_dword returns %d\n", __FUNCTION__, rc);
1577 dbg("%s: temp_register is %x\n", __FUNCTION__, temp_register);
1578
1579 if (rc != 0) {
1580 /* Something's wrong here */
1581 temp_register = 0xFFFFFFFF;
1582 dbg("%s: temp register set to %x by error\n", __FUNCTION__, temp_register);
1583 }
1584 /* Preset return code. It will be changed later if things go okay. */
1585 rc = NO_ADAPTER_PRESENT;
1586 }
1587
1588 /* All F's is an empty slot or an invalid board */
1589 if (temp_register != 0xFFFFFFFF) { /* Check for a board in the slot */
1590 res_lists.io_head = ctrl->io_head;
1591 res_lists.mem_head = ctrl->mem_head;
1592 res_lists.p_mem_head = ctrl->p_mem_head;
1593 res_lists.bus_head = ctrl->bus_head;
1594 res_lists.irqs = NULL;
1595
1596 rc = configure_new_device(ctrl, func, 0, &res_lists);
1597
1598 dbg("%s: back from configure_new_device\n", __FUNCTION__);
1599 ctrl->io_head = res_lists.io_head;
1600 ctrl->mem_head = res_lists.mem_head;
1601 ctrl->p_mem_head = res_lists.p_mem_head;
1602 ctrl->bus_head = res_lists.bus_head;
1603
1604 cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
1605 cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
1606 cpqhp_resource_sort_and_combine(&(ctrl->io_head));
1607 cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
1608
1609 if (rc) {
1610 down(&ctrl->crit_sect);
1611
1612 amber_LED_on (ctrl, hp_slot);
1613 green_LED_off (ctrl, hp_slot);
1614 slot_disable (ctrl, hp_slot);
1615
1616 set_SOGO(ctrl);
1617
1618 /* Wait for SOBS to be unset */
1619 wait_for_ctrl_irq (ctrl);
1620
1621 up(&ctrl->crit_sect);
1622 return rc;
1623 } else {
1624 cpqhp_save_slot_config(ctrl, func);
1625 }
1626
1627
1628 func->status = 0;
1629 func->switch_save = 0x10;
1630 func->is_a_board = 0x01;
1631
1632 /* next, we will instantiate the linux pci_dev structures (with
1633 * appropriate driver notification, if already present) */
1634 dbg("%s: configure linux pci_dev structure\n", __FUNCTION__);
1635 index = 0;
1636 do {
1637 new_slot = cpqhp_slot_find(ctrl->bus, func->device, index++);
1638 if (new_slot && !new_slot->pci_dev) {
1639 cpqhp_configure_device(ctrl, new_slot);
1640 }
1641 } while (new_slot);
1642
1643 down(&ctrl->crit_sect);
1644
1645 green_LED_on (ctrl, hp_slot);
1646
1647 set_SOGO(ctrl);
1648
1649 /* Wait for SOBS to be unset */
1650 wait_for_ctrl_irq (ctrl);
1651
1652 up(&ctrl->crit_sect);
1653 } else {
1654 down(&ctrl->crit_sect);
1655
1656 amber_LED_on (ctrl, hp_slot);
1657 green_LED_off (ctrl, hp_slot);
1658 slot_disable (ctrl, hp_slot);
1659
1660 set_SOGO(ctrl);
1661
1662 /* Wait for SOBS to be unset */
1663 wait_for_ctrl_irq (ctrl);
1664
1665 up(&ctrl->crit_sect);
1666
1667 return rc;
1668 }
1669 return 0;
1670}
1671
1672
1673/**
1674 * remove_board - Turns off slot and LED's
1675 *
1676 */
1677static u32 remove_board(struct pci_func * func, u32 replace_flag, struct controller * ctrl)
1678{
1679 int index;
1680 u8 skip = 0;
1681 u8 device;
1682 u8 hp_slot;
1683 u8 temp_byte;
1684 u32 rc;
1685 struct resource_lists res_lists;
1686 struct pci_func *temp_func;
1687
1688 if (cpqhp_unconfigure_device(func))
1689 return 1;
1690
1691 device = func->device;
1692
1693 hp_slot = func->device - ctrl->slot_device_offset;
1694 dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
1695
1696 /* When we get here, it is safe to change base address registers.
1697 * We will attempt to save the base address register lengths */
1698 if (replace_flag || !ctrl->add_support)
1699 rc = cpqhp_save_base_addr_length(ctrl, func);
1700 else if (!func->bus_head && !func->mem_head &&
1701 !func->p_mem_head && !func->io_head) {
1702 /* Here we check to see if we've saved any of the board's
1703 * resources already. If so, we'll skip the attempt to
1704 * determine what's being used. */
1705 index = 0;
1706 temp_func = cpqhp_slot_find(func->bus, func->device, index++);
1707 while (temp_func) {
1708 if (temp_func->bus_head || temp_func->mem_head
1709 || temp_func->p_mem_head || temp_func->io_head) {
1710 skip = 1;
1711 break;
1712 }
1713 temp_func = cpqhp_slot_find(temp_func->bus, temp_func->device, index++);
1714 }
1715
1716 if (!skip)
1717 rc = cpqhp_save_used_resources(ctrl, func);
1718 }
1719 /* Change status to shutdown */
1720 if (func->is_a_board)
1721 func->status = 0x01;
1722 func->configured = 0;
1723
1724 down(&ctrl->crit_sect);
1725
1726 green_LED_off (ctrl, hp_slot);
1727 slot_disable (ctrl, hp_slot);
1728
1729 set_SOGO(ctrl);
1730
1731 /* turn off SERR for slot */
1732 temp_byte = readb(ctrl->hpc_reg + SLOT_SERR);
1733 temp_byte &= ~(0x01 << hp_slot);
1734 writeb(temp_byte, ctrl->hpc_reg + SLOT_SERR);
1735
1736 /* Wait for SOBS to be unset */
1737 wait_for_ctrl_irq (ctrl);
1738
1739 up(&ctrl->crit_sect);
1740
1741 if (!replace_flag && ctrl->add_support) {
1742 while (func) {
1743 res_lists.io_head = ctrl->io_head;
1744 res_lists.mem_head = ctrl->mem_head;
1745 res_lists.p_mem_head = ctrl->p_mem_head;
1746 res_lists.bus_head = ctrl->bus_head;
1747
1748 cpqhp_return_board_resources(func, &res_lists);
1749
1750 ctrl->io_head = res_lists.io_head;
1751 ctrl->mem_head = res_lists.mem_head;
1752 ctrl->p_mem_head = res_lists.p_mem_head;
1753 ctrl->bus_head = res_lists.bus_head;
1754
1755 cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
1756 cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
1757 cpqhp_resource_sort_and_combine(&(ctrl->io_head));
1758 cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
1759
1760 if (is_bridge(func)) {
1761 bridge_slot_remove(func);
1762 } else
1763 slot_remove(func);
1764
1765 func = cpqhp_slot_find(ctrl->bus, device, 0);
1766 }
1767
1768 /* Setup slot structure with entry for empty slot */
1769 func = cpqhp_slot_create(ctrl->bus);
1770
1771 if (func == NULL)
1772 return 1;
1773
1774 func->bus = ctrl->bus;
1775 func->device = device;
1776 func->function = 0;
1777 func->configured = 0;
1778 func->switch_save = 0x10;
1779 func->is_a_board = 0;
1780 func->p_task_event = NULL;
1781 }
1782
1783 return 0;
1784}
1785
1786static void pushbutton_helper_thread(unsigned long data)
1787{
1788 pushbutton_pending = data;
1789 up(&event_semaphore);
1790}
1791
1792
1793/* this is the main worker thread */
1794static int event_thread(void* data)
1795{
1796 struct controller *ctrl;
1797 lock_kernel();
1798 daemonize("phpd_event");
1799
1800 unlock_kernel();
1801
1802 while (1) {
1803 dbg("!!!!event_thread sleeping\n");
1804 down_interruptible (&event_semaphore);
1805 dbg("event_thread woken finished = %d\n", event_finished);
1806 if (event_finished) break;
1807 /* Do stuff here */
1808 if (pushbutton_pending)
1809 cpqhp_pushbutton_thread(pushbutton_pending);
1810 else
1811 for (ctrl = cpqhp_ctrl_list; ctrl; ctrl=ctrl->next)
1812 interrupt_event_handler(ctrl);
1813 }
1814 dbg("event_thread signals exit\n");
1815 up(&event_exit);
1816 return 0;
1817}
1818
1819
1820int cpqhp_event_start_thread(void)
1821{
1822 int pid;
1823
1824 /* initialize our semaphores */
1825 init_MUTEX(&delay_sem);
1826 init_MUTEX_LOCKED(&event_semaphore);
1827 init_MUTEX_LOCKED(&event_exit);
1828 event_finished=0;
1829
1830 pid = kernel_thread(event_thread, NULL, 0);
1831 if (pid < 0) {
1832 err ("Can't start up our event thread\n");
1833 return -1;
1834 }
1835 dbg("Our event thread pid = %d\n", pid);
1836 return 0;
1837}
1838
1839
1840void cpqhp_event_stop_thread(void)
1841{
1842 event_finished = 1;
1843 dbg("event_thread finish command given\n");
1844 up(&event_semaphore);
1845 dbg("wait for event_thread to exit\n");
1846 down(&event_exit);
1847}
1848
1849
1850static int update_slot_info(struct controller *ctrl, struct slot *slot)
1851{
1852 struct hotplug_slot_info *info;
1853 int result;
1854
1855 info = kmalloc(sizeof(*info), GFP_KERNEL);
1856 if (!info)
1857 return -ENOMEM;
1858
1859 info->power_status = get_slot_enabled(ctrl, slot);
1860 info->attention_status = cpq_get_attention_status(ctrl, slot);
1861 info->latch_status = cpq_get_latch_status(ctrl, slot);
1862 info->adapter_status = get_presence_status(ctrl, slot);
1863 result = pci_hp_change_slot_info(slot->hotplug_slot, info);
1864 kfree (info);
1865 return result;
1866}
1867
1868static void interrupt_event_handler(struct controller *ctrl)
1869{
1870 int loop = 0;
1871 int change = 1;
1872 struct pci_func *func;
1873 u8 hp_slot;
1874 struct slot *p_slot;
1875
1876 while (change) {
1877 change = 0;
1878
1879 for (loop = 0; loop < 10; loop++) {
1880 /* dbg("loop %d\n", loop); */
1881 if (ctrl->event_queue[loop].event_type != 0) {
1882 hp_slot = ctrl->event_queue[loop].hp_slot;
1883
1884 func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);
1885 if (!func)
1886 return;
1887
1888 p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1889 if (!p_slot)
1890 return;
1891
1892 dbg("hp_slot %d, func %p, p_slot %p\n",
1893 hp_slot, func, p_slot);
1894
1895 if (ctrl->event_queue[loop].event_type == INT_BUTTON_PRESS) {
1896 dbg("button pressed\n");
1897 } else if (ctrl->event_queue[loop].event_type ==
1898 INT_BUTTON_CANCEL) {
1899 dbg("button cancel\n");
1900 del_timer(&p_slot->task_event);
1901
1902 down(&ctrl->crit_sect);
1903
1904 if (p_slot->state == BLINKINGOFF_STATE) {
1905 /* slot is on */
1906 dbg("turn on green LED\n");
1907 green_LED_on (ctrl, hp_slot);
1908 } else if (p_slot->state == BLINKINGON_STATE) {
1909 /* slot is off */
1910 dbg("turn off green LED\n");
1911 green_LED_off (ctrl, hp_slot);
1912 }
1913
1914 info(msg_button_cancel, p_slot->number);
1915
1916 p_slot->state = STATIC_STATE;
1917
1918 amber_LED_off (ctrl, hp_slot);
1919
1920 set_SOGO(ctrl);
1921
1922 /* Wait for SOBS to be unset */
1923 wait_for_ctrl_irq (ctrl);
1924
1925 up(&ctrl->crit_sect);
1926 }
1927 /*** button Released (No action on press...) */
1928 else if (ctrl->event_queue[loop].event_type == INT_BUTTON_RELEASE) {
1929 dbg("button release\n");
1930
1931 if (is_slot_enabled (ctrl, hp_slot)) {
1932 dbg("slot is on\n");
1933 p_slot->state = BLINKINGOFF_STATE;
1934 info(msg_button_off, p_slot->number);
1935 } else {
1936 dbg("slot is off\n");
1937 p_slot->state = BLINKINGON_STATE;
1938 info(msg_button_on, p_slot->number);
1939 }
1940 down(&ctrl->crit_sect);
1941
1942 dbg("blink green LED and turn off amber\n");
1943
1944 amber_LED_off (ctrl, hp_slot);
1945 green_LED_blink (ctrl, hp_slot);
1946
1947 set_SOGO(ctrl);
1948
1949 /* Wait for SOBS to be unset */
1950 wait_for_ctrl_irq (ctrl);
1951
1952 up(&ctrl->crit_sect);
1953 init_timer(&p_slot->task_event);
1954 p_slot->hp_slot = hp_slot;
1955 p_slot->ctrl = ctrl;
1956/* p_slot->physical_slot = physical_slot; */
1957 p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */
1958 p_slot->task_event.function = pushbutton_helper_thread;
1959 p_slot->task_event.data = (u32) p_slot;
1960
1961 dbg("add_timer p_slot = %p\n", p_slot);
1962 add_timer(&p_slot->task_event);
1963 }
1964 /***********POWER FAULT */
1965 else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
1966 dbg("power fault\n");
1967 } else {
1968 /* refresh notification */
1969 if (p_slot)
1970 update_slot_info(ctrl, p_slot);
1971 }
1972
1973 ctrl->event_queue[loop].event_type = 0;
1974
1975 change = 1;
1976 }
1977 } /* End of FOR loop */
1978 }
1979
1980 return;
1981}
1982
1983
1984/**
1985 * cpqhp_pushbutton_thread
1986 *
1987 * Scheduled procedure to handle blocking stuff for the pushbuttons
1988 * Handles all pending events and exits.
1989 *
1990 */
1991void cpqhp_pushbutton_thread(unsigned long slot)
1992{
1993 u8 hp_slot;
1994 u8 device;
1995 struct pci_func *func;
1996 struct slot *p_slot = (struct slot *) slot;
1997 struct controller *ctrl = (struct controller *) p_slot->ctrl;
1998
1999 pushbutton_pending = 0;
2000 hp_slot = p_slot->hp_slot;
2001
2002 device = p_slot->device;
2003
2004 if (is_slot_enabled(ctrl, hp_slot)) {
2005 p_slot->state = POWEROFF_STATE;
2006 /* power Down board */
2007 func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
2008 dbg("In power_down_board, func = %p, ctrl = %p\n", func, ctrl);
2009 if (!func) {
2010 dbg("Error! func NULL in %s\n", __FUNCTION__);
2011 return ;
2012 }
2013
2014 if (func != NULL && ctrl != NULL) {
2015 if (cpqhp_process_SS(ctrl, func) != 0) {
2016 amber_LED_on (ctrl, hp_slot);
2017 green_LED_on (ctrl, hp_slot);
2018
2019 set_SOGO(ctrl);
2020
2021 /* Wait for SOBS to be unset */
2022 wait_for_ctrl_irq (ctrl);
2023 }
2024 }
2025
2026 p_slot->state = STATIC_STATE;
2027 } else {
2028 p_slot->state = POWERON_STATE;
2029 /* slot is off */
2030
2031 func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
2032 dbg("In add_board, func = %p, ctrl = %p\n", func, ctrl);
2033 if (!func) {
2034 dbg("Error! func NULL in %s\n", __FUNCTION__);
2035 return ;
2036 }
2037
2038 if (func != NULL && ctrl != NULL) {
2039 if (cpqhp_process_SI(ctrl, func) != 0) {
2040 amber_LED_on(ctrl, hp_slot);
2041 green_LED_off(ctrl, hp_slot);
2042
2043 set_SOGO(ctrl);
2044
2045 /* Wait for SOBS to be unset */
2046 wait_for_ctrl_irq (ctrl);
2047 }
2048 }
2049
2050 p_slot->state = STATIC_STATE;
2051 }
2052
2053 return;
2054}
2055
2056
2057int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func)
2058{
2059 u8 device, hp_slot;
2060 u16 temp_word;
2061 u32 tempdword;
2062 int rc;
2063 struct slot* p_slot;
2064 int physical_slot = 0;
2065
2066 tempdword = 0;
2067
2068 device = func->device;
2069 hp_slot = device - ctrl->slot_device_offset;
2070 p_slot = cpqhp_find_slot(ctrl, device);
2071 if (p_slot)
2072 physical_slot = p_slot->number;
2073
2074 /* Check to see if the interlock is closed */
2075 tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
2076
2077 if (tempdword & (0x01 << hp_slot)) {
2078 return 1;
2079 }
2080
2081 if (func->is_a_board) {
2082 rc = board_replaced(func, ctrl);
2083 } else {
2084 /* add board */
2085 slot_remove(func);
2086
2087 func = cpqhp_slot_create(ctrl->bus);
2088 if (func == NULL)
2089 return 1;
2090
2091 func->bus = ctrl->bus;
2092 func->device = device;
2093 func->function = 0;
2094 func->configured = 0;
2095 func->is_a_board = 1;
2096
2097 /* We have to save the presence info for these slots */
2098 temp_word = ctrl->ctrl_int_comp >> 16;
2099 func->presence_save = (temp_word >> hp_slot) & 0x01;
2100 func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
2101
2102 if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
2103 func->switch_save = 0;
2104 } else {
2105 func->switch_save = 0x10;
2106 }
2107
2108 rc = board_added(func, ctrl);
2109 if (rc) {
2110 if (is_bridge(func)) {
2111 bridge_slot_remove(func);
2112 } else
2113 slot_remove(func);
2114
2115 /* Setup slot structure with entry for empty slot */
2116 func = cpqhp_slot_create(ctrl->bus);
2117
2118 if (func == NULL)
2119 return 1;
2120
2121 func->bus = ctrl->bus;
2122 func->device = device;
2123 func->function = 0;
2124 func->configured = 0;
2125 func->is_a_board = 0;
2126
2127 /* We have to save the presence info for these slots */
2128 temp_word = ctrl->ctrl_int_comp >> 16;
2129 func->presence_save = (temp_word >> hp_slot) & 0x01;
2130 func->presence_save |=
2131 (temp_word >> (hp_slot + 7)) & 0x02;
2132
2133 if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
2134 func->switch_save = 0;
2135 } else {
2136 func->switch_save = 0x10;
2137 }
2138 }
2139 }
2140
2141 if (rc) {
2142 dbg("%s: rc = %d\n", __FUNCTION__, rc);
2143 }
2144
2145 if (p_slot)
2146 update_slot_info(ctrl, p_slot);
2147
2148 return rc;
2149}
2150
2151
2152int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func)
2153{
2154 u8 device, class_code, header_type, BCR;
2155 u8 index = 0;
2156 u8 replace_flag;
2157 u32 rc = 0;
2158 unsigned int devfn;
2159 struct slot* p_slot;
2160 struct pci_bus *pci_bus = ctrl->pci_bus;
2161 int physical_slot=0;
2162
2163 device = func->device;
2164 func = cpqhp_slot_find(ctrl->bus, device, index++);
2165 p_slot = cpqhp_find_slot(ctrl, device);
2166 if (p_slot) {
2167 physical_slot = p_slot->number;
2168 }
2169
2170 /* Make sure there are no video controllers here */
2171 while (func && !rc) {
2172 pci_bus->number = func->bus;
2173 devfn = PCI_DEVFN(func->device, func->function);
2174
2175 /* Check the Class Code */
2176 rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
2177 if (rc)
2178 return rc;
2179
2180 if (class_code == PCI_BASE_CLASS_DISPLAY) {
2181 /* Display/Video adapter (not supported) */
2182 rc = REMOVE_NOT_SUPPORTED;
2183 } else {
2184 /* See if it's a bridge */
2185 rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
2186 if (rc)
2187 return rc;
2188
2189 /* If it's a bridge, check the VGA Enable bit */
2190 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
2191 rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
2192 if (rc)
2193 return rc;
2194
2195 /* If the VGA Enable bit is set, remove isn't
2196 * supported */
2197 if (BCR & PCI_BRIDGE_CTL_VGA) {
2198 rc = REMOVE_NOT_SUPPORTED;
2199 }
2200 }
2201 }
2202
2203 func = cpqhp_slot_find(ctrl->bus, device, index++);
2204 }
2205
2206 func = cpqhp_slot_find(ctrl->bus, device, 0);
2207 if ((func != NULL) && !rc) {
2208 /* FIXME: Replace flag should be passed into process_SS */
2209 replace_flag = !(ctrl->add_support);
2210 rc = remove_board(func, replace_flag, ctrl);
2211 } else if (!rc) {
2212 rc = 1;
2213 }
2214
2215 if (p_slot)
2216 update_slot_info(ctrl, p_slot);
2217
2218 return rc;
2219}
2220
2221/**
2222 * switch_leds: switch the leds, go from one site to the other.
2223 * @ctrl: controller to use
2224 * @num_of_slots: number of slots to use
2225 * @direction: 1 to start from the left side, 0 to start right.
2226 */
2227static void switch_leds(struct controller *ctrl, const int num_of_slots,
2228 u32 *work_LED, const int direction)
2229{
2230 int loop;
2231
2232 for (loop = 0; loop < num_of_slots; loop++) {
2233 if (direction)
2234 *work_LED = *work_LED >> 1;
2235 else
2236 *work_LED = *work_LED << 1;
2237 writel(*work_LED, ctrl->hpc_reg + LED_CONTROL);
2238
2239 set_SOGO(ctrl);
2240
2241 /* Wait for SOGO interrupt */
2242 wait_for_ctrl_irq(ctrl);
2243
2244 /* Get ready for next iteration */
2245 long_delay((2*HZ)/10);
2246 }
2247}
2248
2249/**
2250 * hardware_test - runs hardware tests
2251 *
2252 * For hot plug ctrl folks to play with.
2253 * test_num is the number written to the "test" file in sysfs
2254 *
2255 */
2256int cpqhp_hardware_test(struct controller *ctrl, int test_num)
2257{
2258 u32 save_LED;
2259 u32 work_LED;
2260 int loop;
2261 int num_of_slots;
2262
2263 num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0f;
2264
2265 switch (test_num) {
2266 case 1:
2267 /* Do stuff here! */
2268
2269 /* Do that funky LED thing */
2270 /* so we can restore them later */
2271 save_LED = readl(ctrl->hpc_reg + LED_CONTROL);
2272 work_LED = 0x01010101;
2273 switch_leds(ctrl, num_of_slots, &work_LED, 0);
2274 switch_leds(ctrl, num_of_slots, &work_LED, 1);
2275 switch_leds(ctrl, num_of_slots, &work_LED, 0);
2276 switch_leds(ctrl, num_of_slots, &work_LED, 1);
2277
2278 work_LED = 0x01010000;
2279 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2280 switch_leds(ctrl, num_of_slots, &work_LED, 0);
2281 switch_leds(ctrl, num_of_slots, &work_LED, 1);
2282 work_LED = 0x00000101;
2283 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2284 switch_leds(ctrl, num_of_slots, &work_LED, 0);
2285 switch_leds(ctrl, num_of_slots, &work_LED, 1);
2286
2287 work_LED = 0x01010000;
2288 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2289 for (loop = 0; loop < num_of_slots; loop++) {
2290 set_SOGO(ctrl);
2291
2292 /* Wait for SOGO interrupt */
2293 wait_for_ctrl_irq (ctrl);
2294
2295 /* Get ready for next iteration */
2296 long_delay((3*HZ)/10);
2297 work_LED = work_LED >> 16;
2298 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2299
2300 set_SOGO(ctrl);
2301
2302 /* Wait for SOGO interrupt */
2303 wait_for_ctrl_irq (ctrl);
2304
2305 /* Get ready for next iteration */
2306 long_delay((3*HZ)/10);
2307 work_LED = work_LED << 16;
2308 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2309 work_LED = work_LED << 1;
2310 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2311 }
2312
2313 /* put it back the way it was */
2314 writel(save_LED, ctrl->hpc_reg + LED_CONTROL);
2315
2316 set_SOGO(ctrl);
2317
2318 /* Wait for SOBS to be unset */
2319 wait_for_ctrl_irq (ctrl);
2320 break;
2321 case 2:
2322 /* Do other stuff here! */
2323 break;
2324 case 3:
2325 /* and more... */
2326 break;
2327 }
2328 return 0;
2329}
2330
2331
2332/**
2333 * configure_new_device - Configures the PCI header information of one board.
2334 *
2335 * @ctrl: pointer to controller structure
2336 * @func: pointer to function structure
2337 * @behind_bridge: 1 if this is a recursive call, 0 if not
2338 * @resources: pointer to set of resource lists
2339 *
2340 * Returns 0 if success
2341 *
2342 */
2343static u32 configure_new_device(struct controller * ctrl, struct pci_func * func,
2344 u8 behind_bridge, struct resource_lists * resources)
2345{
2346 u8 temp_byte, function, max_functions, stop_it;
2347 int rc;
2348 u32 ID;
2349 struct pci_func *new_slot;
2350 int index;
2351
2352 new_slot = func;
2353
2354 dbg("%s\n", __FUNCTION__);
2355 /* Check for Multi-function device */
2356 ctrl->pci_bus->number = func->bus;
2357 rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);
2358 if (rc) {
2359 dbg("%s: rc = %d\n", __FUNCTION__, rc);
2360 return rc;
2361 }
2362
2363 if (temp_byte & 0x80) /* Multi-function device */
2364 max_functions = 8;
2365 else
2366 max_functions = 1;
2367
2368 function = 0;
2369
2370 do {
2371 rc = configure_new_function(ctrl, new_slot, behind_bridge, resources);
2372
2373 if (rc) {
2374 dbg("configure_new_function failed %d\n",rc);
2375 index = 0;
2376
2377 while (new_slot) {
2378 new_slot = cpqhp_slot_find(new_slot->bus, new_slot->device, index++);
2379
2380 if (new_slot)
2381 cpqhp_return_board_resources(new_slot, resources);
2382 }
2383
2384 return rc;
2385 }
2386
2387 function++;
2388
2389 stop_it = 0;
2390
2391 /* The following loop skips to the next present function
2392 * and creates a board structure */
2393
2394 while ((function < max_functions) && (!stop_it)) {
2395 pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
2396
2397 if (ID == 0xFFFFFFFF) { /* There's nothing there. */
2398 function++;
2399 } else { /* There's something there */
2400 /* Setup slot structure. */
2401 new_slot = cpqhp_slot_create(func->bus);
2402
2403 if (new_slot == NULL)
2404 return 1;
2405
2406 new_slot->bus = func->bus;
2407 new_slot->device = func->device;
2408 new_slot->function = function;
2409 new_slot->is_a_board = 1;
2410 new_slot->status = 0;
2411
2412 stop_it++;
2413 }
2414 }
2415
2416 } while (function < max_functions);
2417 dbg("returning from configure_new_device\n");
2418
2419 return 0;
2420}
2421
2422
2423/*
2424 Configuration logic that involves the hotplug data structures and
2425 their bookkeeping
2426 */
2427
2428
2429/**
2430 * configure_new_function - Configures the PCI header information of one device
2431 *
2432 * @ctrl: pointer to controller structure
2433 * @func: pointer to function structure
2434 * @behind_bridge: 1 if this is a recursive call, 0 if not
2435 * @resources: pointer to set of resource lists
2436 *
2437 * Calls itself recursively for bridged devices.
2438 * Returns 0 if success
2439 *
2440 */
2441static int configure_new_function(struct controller *ctrl, struct pci_func *func,
2442 u8 behind_bridge,
2443 struct resource_lists *resources)
2444{
2445 int cloop;
2446 u8 IRQ = 0;
2447 u8 temp_byte;
2448 u8 device;
2449 u8 class_code;
2450 u16 command;
2451 u16 temp_word;
2452 u32 temp_dword;
2453 u32 rc;
2454 u32 temp_register;
2455 u32 base;
2456 u32 ID;
2457 unsigned int devfn;
2458 struct pci_resource *mem_node;
2459 struct pci_resource *p_mem_node;
2460 struct pci_resource *io_node;
2461 struct pci_resource *bus_node;
2462 struct pci_resource *hold_mem_node;
2463 struct pci_resource *hold_p_mem_node;
2464 struct pci_resource *hold_IO_node;
2465 struct pci_resource *hold_bus_node;
2466 struct irq_mapping irqs;
2467 struct pci_func *new_slot;
2468 struct pci_bus *pci_bus;
2469 struct resource_lists temp_resources;
2470
2471 pci_bus = ctrl->pci_bus;
2472 pci_bus->number = func->bus;
2473 devfn = PCI_DEVFN(func->device, func->function);
2474
2475 /* Check for Bridge */
2476 rc = pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &temp_byte);
2477 if (rc)
2478 return rc;
2479
2480 if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
2481 /* set Primary bus */
2482 dbg("set Primary bus = %d\n", func->bus);
2483 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
2484 if (rc)
2485 return rc;
2486
2487 /* find range of busses to use */
2488 dbg("find ranges of buses to use\n");
2489 bus_node = get_max_resource(&(resources->bus_head), 1);
2490
2491 /* If we don't have any busses to allocate, we can't continue */
2492 if (!bus_node)
2493 return -ENOMEM;
2494
2495 /* set Secondary bus */
2496 temp_byte = bus_node->base;
2497 dbg("set Secondary bus = %d\n", bus_node->base);
2498 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, temp_byte);
2499 if (rc)
2500 return rc;
2501
2502 /* set subordinate bus */
2503 temp_byte = bus_node->base + bus_node->length - 1;
2504 dbg("set subordinate bus = %d\n", bus_node->base + bus_node->length - 1);
2505 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
2506 if (rc)
2507 return rc;
2508
2509 /* set subordinate Latency Timer and base Latency Timer */
2510 temp_byte = 0x40;
2511 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
2512 if (rc)
2513 return rc;
2514 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
2515 if (rc)
2516 return rc;
2517
2518 /* set Cache Line size */
2519 temp_byte = 0x08;
2520 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
2521 if (rc)
2522 return rc;
2523
2524 /* Setup the IO, memory, and prefetchable windows */
2525 io_node = get_max_resource(&(resources->io_head), 0x1000);
2526 if (!io_node)
2527 return -ENOMEM;
2528 mem_node = get_max_resource(&(resources->mem_head), 0x100000);
2529 if (!mem_node)
2530 return -ENOMEM;
2531 p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000);
2532 if (!p_mem_node)
2533 return -ENOMEM;
2534 dbg("Setup the IO, memory, and prefetchable windows\n");
2535 dbg("io_node\n");
2536 dbg("(base, len, next) (%x, %x, %p)\n", io_node->base,
2537 io_node->length, io_node->next);
2538 dbg("mem_node\n");
2539 dbg("(base, len, next) (%x, %x, %p)\n", mem_node->base,
2540 mem_node->length, mem_node->next);
2541 dbg("p_mem_node\n");
2542 dbg("(base, len, next) (%x, %x, %p)\n", p_mem_node->base,
2543 p_mem_node->length, p_mem_node->next);
2544
2545 /* set up the IRQ info */
2546 if (!resources->irqs) {
2547 irqs.barber_pole = 0;
2548 irqs.interrupt[0] = 0;
2549 irqs.interrupt[1] = 0;
2550 irqs.interrupt[2] = 0;
2551 irqs.interrupt[3] = 0;
2552 irqs.valid_INT = 0;
2553 } else {
2554 irqs.barber_pole = resources->irqs->barber_pole;
2555 irqs.interrupt[0] = resources->irqs->interrupt[0];
2556 irqs.interrupt[1] = resources->irqs->interrupt[1];
2557 irqs.interrupt[2] = resources->irqs->interrupt[2];
2558 irqs.interrupt[3] = resources->irqs->interrupt[3];
2559 irqs.valid_INT = resources->irqs->valid_INT;
2560 }
2561
2562 /* set up resource lists that are now aligned on top and bottom
2563 * for anything behind the bridge. */
2564 temp_resources.bus_head = bus_node;
2565 temp_resources.io_head = io_node;
2566 temp_resources.mem_head = mem_node;
2567 temp_resources.p_mem_head = p_mem_node;
2568 temp_resources.irqs = &irqs;
2569
2570 /* Make copies of the nodes we are going to pass down so that
2571 * if there is a problem,we can just use these to free resources */
2572 hold_bus_node = kmalloc(sizeof(*hold_bus_node), GFP_KERNEL);
2573 hold_IO_node = kmalloc(sizeof(*hold_IO_node), GFP_KERNEL);
2574 hold_mem_node = kmalloc(sizeof(*hold_mem_node), GFP_KERNEL);
2575 hold_p_mem_node = kmalloc(sizeof(*hold_p_mem_node), GFP_KERNEL);
2576
2577 if (!hold_bus_node || !hold_IO_node || !hold_mem_node || !hold_p_mem_node) {
2578 kfree(hold_bus_node);
2579 kfree(hold_IO_node);
2580 kfree(hold_mem_node);
2581 kfree(hold_p_mem_node);
2582
2583 return 1;
2584 }
2585
2586 memcpy(hold_bus_node, bus_node, sizeof(struct pci_resource));
2587
2588 bus_node->base += 1;
2589 bus_node->length -= 1;
2590 bus_node->next = NULL;
2591
2592 /* If we have IO resources copy them and fill in the bridge's
2593 * IO range registers */
2594 if (io_node) {
2595 memcpy(hold_IO_node, io_node, sizeof(struct pci_resource));
2596 io_node->next = NULL;
2597
2598 /* set IO base and Limit registers */
2599 temp_byte = io_node->base >> 8;
2600 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_BASE, temp_byte);
2601
2602 temp_byte = (io_node->base + io_node->length - 1) >> 8;
2603 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2604 } else {
2605 kfree(hold_IO_node);
2606 hold_IO_node = NULL;
2607 }
2608
2609 /* If we have memory resources copy them and fill in the
2610 * bridge's memory range registers. Otherwise, fill in the
2611 * range registers with values that disable them. */
2612 if (mem_node) {
2613 memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource));
2614 mem_node->next = NULL;
2615
2616 /* set Mem base and Limit registers */
2617 temp_word = mem_node->base >> 16;
2618 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
2619
2620 temp_word = (mem_node->base + mem_node->length - 1) >> 16;
2621 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2622 } else {
2623 temp_word = 0xFFFF;
2624 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
2625
2626 temp_word = 0x0000;
2627 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2628
2629 kfree(hold_mem_node);
2630 hold_mem_node = NULL;
2631 }
2632
2633 /* If we have prefetchable memory resources copy them and
2634 * fill in the bridge's memory range registers. Otherwise,
2635 * fill in the range registers with values that disable them. */
2636 if (p_mem_node) {
2637 memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource));
2638 p_mem_node->next = NULL;
2639
2640 /* set Pre Mem base and Limit registers */
2641 temp_word = p_mem_node->base >> 16;
2642 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
2643
2644 temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16;
2645 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2646 } else {
2647 temp_word = 0xFFFF;
2648 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
2649
2650 temp_word = 0x0000;
2651 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2652
2653 kfree(hold_p_mem_node);
2654 hold_p_mem_node = NULL;
2655 }
2656
2657 /* Adjust this to compensate for extra adjustment in first loop */
2658 irqs.barber_pole--;
2659
2660 rc = 0;
2661
2662 /* Here we actually find the devices and configure them */
2663 for (device = 0; (device <= 0x1F) && !rc; device++) {
2664 irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;
2665
2666 ID = 0xFFFFFFFF;
2667 pci_bus->number = hold_bus_node->base;
2668 pci_bus_read_config_dword (pci_bus, PCI_DEVFN(device, 0), 0x00, &ID);
2669 pci_bus->number = func->bus;
2670
2671 if (ID != 0xFFFFFFFF) { /* device present */
2672 /* Setup slot structure. */
2673 new_slot = cpqhp_slot_create(hold_bus_node->base);
2674
2675 if (new_slot == NULL) {
2676 rc = -ENOMEM;
2677 continue;
2678 }
2679
2680 new_slot->bus = hold_bus_node->base;
2681 new_slot->device = device;
2682 new_slot->function = 0;
2683 new_slot->is_a_board = 1;
2684 new_slot->status = 0;
2685
2686 rc = configure_new_device(ctrl, new_slot, 1, &temp_resources);
2687 dbg("configure_new_device rc=0x%x\n",rc);
2688 } /* End of IF (device in slot?) */
2689 } /* End of FOR loop */
2690
2691 if (rc)
2692 goto free_and_out;
2693 /* save the interrupt routing information */
2694 if (resources->irqs) {
2695 resources->irqs->interrupt[0] = irqs.interrupt[0];
2696 resources->irqs->interrupt[1] = irqs.interrupt[1];
2697 resources->irqs->interrupt[2] = irqs.interrupt[2];
2698 resources->irqs->interrupt[3] = irqs.interrupt[3];
2699 resources->irqs->valid_INT = irqs.valid_INT;
2700 } else if (!behind_bridge) {
2701 /* We need to hook up the interrupts here */
2702 for (cloop = 0; cloop < 4; cloop++) {
2703 if (irqs.valid_INT & (0x01 << cloop)) {
2704 rc = cpqhp_set_irq(func->bus, func->device,
2705 0x0A + cloop, irqs.interrupt[cloop]);
2706 if (rc)
2707 goto free_and_out;
2708 }
2709 } /* end of for loop */
2710 }
2711 /* Return unused bus resources
2712 * First use the temporary node to store information for
2713 * the board */
2714 if (hold_bus_node && bus_node && temp_resources.bus_head) {
2715 hold_bus_node->length = bus_node->base - hold_bus_node->base;
2716
2717 hold_bus_node->next = func->bus_head;
2718 func->bus_head = hold_bus_node;
2719
2720 temp_byte = temp_resources.bus_head->base - 1;
2721
2722 /* set subordinate bus */
2723 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
2724
2725 if (temp_resources.bus_head->length == 0) {
2726 kfree(temp_resources.bus_head);
2727 temp_resources.bus_head = NULL;
2728 } else {
2729 return_resource(&(resources->bus_head), temp_resources.bus_head);
2730 }
2731 }
2732
2733 /* If we have IO space available and there is some left,
2734 * return the unused portion */
2735 if (hold_IO_node && temp_resources.io_head) {
2736 io_node = do_pre_bridge_resource_split(&(temp_resources.io_head),
2737 &hold_IO_node, 0x1000);
2738
2739 /* Check if we were able to split something off */
2740 if (io_node) {
2741 hold_IO_node->base = io_node->base + io_node->length;
2742
2743 temp_byte = (hold_IO_node->base) >> 8;
2744 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_IO_BASE, temp_byte);
2745
2746 return_resource(&(resources->io_head), io_node);
2747 }
2748
2749 io_node = do_bridge_resource_split(&(temp_resources.io_head), 0x1000);
2750
2751 /* Check if we were able to split something off */
2752 if (io_node) {
2753 /* First use the temporary node to store
2754 * information for the board */
2755 hold_IO_node->length = io_node->base - hold_IO_node->base;
2756
2757 /* If we used any, add it to the board's list */
2758 if (hold_IO_node->length) {
2759 hold_IO_node->next = func->io_head;
2760 func->io_head = hold_IO_node;
2761
2762 temp_byte = (io_node->base - 1) >> 8;
2763 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2764
2765 return_resource(&(resources->io_head), io_node);
2766 } else {
2767 /* it doesn't need any IO */
2768 temp_word = 0x0000;
2769 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_IO_LIMIT, temp_word);
2770
2771 return_resource(&(resources->io_head), io_node);
2772 kfree(hold_IO_node);
2773 }
2774 } else {
2775 /* it used most of the range */
2776 hold_IO_node->next = func->io_head;
2777 func->io_head = hold_IO_node;
2778 }
2779 } else if (hold_IO_node) {
2780 /* it used the whole range */
2781 hold_IO_node->next = func->io_head;
2782 func->io_head = hold_IO_node;
2783 }
2784 /* If we have memory space available and there is some left,
2785 * return the unused portion */
2786 if (hold_mem_node && temp_resources.mem_head) {
2787 mem_node = do_pre_bridge_resource_split(&(temp_resources. mem_head),
2788 &hold_mem_node, 0x100000);
2789
2790 /* Check if we were able to split something off */
2791 if (mem_node) {
2792 hold_mem_node->base = mem_node->base + mem_node->length;
2793
2794 temp_word = (hold_mem_node->base) >> 16;
2795 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
2796
2797 return_resource(&(resources->mem_head), mem_node);
2798 }
2799
2800 mem_node = do_bridge_resource_split(&(temp_resources.mem_head), 0x100000);
2801
2802 /* Check if we were able to split something off */
2803 if (mem_node) {
2804 /* First use the temporary node to store
2805 * information for the board */
2806 hold_mem_node->length = mem_node->base - hold_mem_node->base;
2807
2808 if (hold_mem_node->length) {
2809 hold_mem_node->next = func->mem_head;
2810 func->mem_head = hold_mem_node;
2811
2812 /* configure end address */
2813 temp_word = (mem_node->base - 1) >> 16;
2814 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2815
2816 /* Return unused resources to the pool */
2817 return_resource(&(resources->mem_head), mem_node);
2818 } else {
2819 /* it doesn't need any Mem */
2820 temp_word = 0x0000;
2821 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2822
2823 return_resource(&(resources->mem_head), mem_node);
2824 kfree(hold_mem_node);
2825 }
2826 } else {
2827 /* it used most of the range */
2828 hold_mem_node->next = func->mem_head;
2829 func->mem_head = hold_mem_node;
2830 }
2831 } else if (hold_mem_node) {
2832 /* it used the whole range */
2833 hold_mem_node->next = func->mem_head;
2834 func->mem_head = hold_mem_node;
2835 }
2836 /* If we have prefetchable memory space available and there
2837 * is some left at the end, return the unused portion */
2838 if (hold_p_mem_node && temp_resources.p_mem_head) {
2839 p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head),
2840 &hold_p_mem_node, 0x100000);
2841
2842 /* Check if we were able to split something off */
2843 if (p_mem_node) {
2844 hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;
2845
2846 temp_word = (hold_p_mem_node->base) >> 16;
2847 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
2848
2849 return_resource(&(resources->p_mem_head), p_mem_node);
2850 }
2851
2852 p_mem_node = do_bridge_resource_split(&(temp_resources.p_mem_head), 0x100000);
2853
2854 /* Check if we were able to split something off */
2855 if (p_mem_node) {
2856 /* First use the temporary node to store
2857 * information for the board */
2858 hold_p_mem_node->length = p_mem_node->base - hold_p_mem_node->base;
2859
2860 /* If we used any, add it to the board's list */
2861 if (hold_p_mem_node->length) {
2862 hold_p_mem_node->next = func->p_mem_head;
2863 func->p_mem_head = hold_p_mem_node;
2864
2865 temp_word = (p_mem_node->base - 1) >> 16;
2866 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2867
2868 return_resource(&(resources->p_mem_head), p_mem_node);
2869 } else {
2870 /* it doesn't need any PMem */
2871 temp_word = 0x0000;
2872 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2873
2874 return_resource(&(resources->p_mem_head), p_mem_node);
2875 kfree(hold_p_mem_node);
2876 }
2877 } else {
2878 /* it used the most of the range */
2879 hold_p_mem_node->next = func->p_mem_head;
2880 func->p_mem_head = hold_p_mem_node;
2881 }
2882 } else if (hold_p_mem_node) {
2883 /* it used the whole range */
2884 hold_p_mem_node->next = func->p_mem_head;
2885 func->p_mem_head = hold_p_mem_node;
2886 }
2887 /* We should be configuring an IRQ and the bridge's base address
2888 * registers if it needs them. Although we have never seen such
2889 * a device */
2890
2891 /* enable card */
2892 command = 0x0157; /* = PCI_COMMAND_IO |
2893 * PCI_COMMAND_MEMORY |
2894 * PCI_COMMAND_MASTER |
2895 * PCI_COMMAND_INVALIDATE |
2896 * PCI_COMMAND_PARITY |
2897 * PCI_COMMAND_SERR */
2898 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_COMMAND, command);
2899
2900 /* set Bridge Control Register */
2901 command = 0x07; /* = PCI_BRIDGE_CTL_PARITY |
2902 * PCI_BRIDGE_CTL_SERR |
2903 * PCI_BRIDGE_CTL_NO_ISA */
2904 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
2905 } else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
2906 /* Standard device */
2907 rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
2908
2909 if (class_code == PCI_BASE_CLASS_DISPLAY) {
2910 /* Display (video) adapter (not supported) */
2911 return DEVICE_TYPE_NOT_SUPPORTED;
2912 }
2913 /* Figure out IO and memory needs */
2914 for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
2915 temp_register = 0xFFFFFFFF;
2916
2917 dbg("CND: bus=%d, devfn=%d, offset=%d\n", pci_bus->number, devfn, cloop);
2918 rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
2919
2920 rc = pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp_register);
2921 dbg("CND: base = 0x%x\n", temp_register);
2922
2923 if (temp_register) { /* If this register is implemented */
2924 if ((temp_register & 0x03L) == 0x01) {
2925 /* Map IO */
2926
2927 /* set base = amount of IO space */
2928 base = temp_register & 0xFFFFFFFC;
2929 base = ~base + 1;
2930
2931 dbg("CND: length = 0x%x\n", base);
2932 io_node = get_io_resource(&(resources->io_head), base);
2933 dbg("Got io_node start = %8.8x, length = %8.8x next (%p)\n",
2934 io_node->base, io_node->length, io_node->next);
2935 dbg("func (%p) io_head (%p)\n", func, func->io_head);
2936
2937 /* allocate the resource to the board */
2938 if (io_node) {
2939 base = io_node->base;
2940
2941 io_node->next = func->io_head;
2942 func->io_head = io_node;
2943 } else
2944 return -ENOMEM;
2945 } else if ((temp_register & 0x0BL) == 0x08) {
2946 /* Map prefetchable memory */
2947 base = temp_register & 0xFFFFFFF0;
2948 base = ~base + 1;
2949
2950 dbg("CND: length = 0x%x\n", base);
2951 p_mem_node = get_resource(&(resources->p_mem_head), base);
2952
2953 /* allocate the resource to the board */
2954 if (p_mem_node) {
2955 base = p_mem_node->base;
2956
2957 p_mem_node->next = func->p_mem_head;
2958 func->p_mem_head = p_mem_node;
2959 } else
2960 return -ENOMEM;
2961 } else if ((temp_register & 0x0BL) == 0x00) {
2962 /* Map memory */
2963 base = temp_register & 0xFFFFFFF0;
2964 base = ~base + 1;
2965
2966 dbg("CND: length = 0x%x\n", base);
2967 mem_node = get_resource(&(resources->mem_head), base);
2968
2969 /* allocate the resource to the board */
2970 if (mem_node) {
2971 base = mem_node->base;
2972
2973 mem_node->next = func->mem_head;
2974 func->mem_head = mem_node;
2975 } else
2976 return -ENOMEM;
2977 } else if ((temp_register & 0x0BL) == 0x04) {
2978 /* Map memory */
2979 base = temp_register & 0xFFFFFFF0;
2980 base = ~base + 1;
2981
2982 dbg("CND: length = 0x%x\n", base);
2983 mem_node = get_resource(&(resources->mem_head), base);
2984
2985 /* allocate the resource to the board */
2986 if (mem_node) {
2987 base = mem_node->base;
2988
2989 mem_node->next = func->mem_head;
2990 func->mem_head = mem_node;
2991 } else
2992 return -ENOMEM;
2993 } else if ((temp_register & 0x0BL) == 0x06) {
2994 /* Those bits are reserved, we can't handle this */
2995 return 1;
2996 } else {
2997 /* Requesting space below 1M */
2998 return NOT_ENOUGH_RESOURCES;
2999 }
3000
3001 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, base);
3002
3003 /* Check for 64-bit base */
3004 if ((temp_register & 0x07L) == 0x04) {
3005 cloop += 4;
3006
3007 /* Upper 32 bits of address always zero
3008 * on today's systems */
3009 /* FIXME this is probably not true on
3010 * Alpha and ia64??? */
3011 base = 0;
3012 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, base);
3013 }
3014 }
3015 } /* End of base register loop */
3016 if (cpqhp_legacy_mode) {
3017 /* Figure out which interrupt pin this function uses */
3018 rc = pci_bus_read_config_byte (pci_bus, devfn,
3019 PCI_INTERRUPT_PIN, &temp_byte);
3020
3021 /* If this function needs an interrupt and we are behind
3022 * a bridge and the pin is tied to something that's
3023 * alread mapped, set this one the same */
3024 if (temp_byte && resources->irqs &&
3025 (resources->irqs->valid_INT &
3026 (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) {
3027 /* We have to share with something already set up */
3028 IRQ = resources->irqs->interrupt[(temp_byte +
3029 resources->irqs->barber_pole - 1) & 0x03];
3030 } else {
3031 /* Program IRQ based on card type */
3032 rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
3033
3034 if (class_code == PCI_BASE_CLASS_STORAGE) {
3035 IRQ = cpqhp_disk_irq;
3036 } else {
3037 IRQ = cpqhp_nic_irq;
3038 }
3039 }
3040
3041 /* IRQ Line */
3042 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_INTERRUPT_LINE, IRQ);
3043 }
3044
3045 if (!behind_bridge) {
3046 rc = cpqhp_set_irq(func->bus, func->device, temp_byte + 0x09, IRQ);
3047 if (rc)
3048 return 1;
3049 } else {
3050 /* TBD - this code may also belong in the other clause
3051 * of this If statement */
3052 resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03] = IRQ;
3053 resources->irqs->valid_INT |= 0x01 << (temp_byte + resources->irqs->barber_pole - 1) & 0x03;
3054 }
3055
3056 /* Latency Timer */
3057 temp_byte = 0x40;
3058 rc = pci_bus_write_config_byte(pci_bus, devfn,
3059 PCI_LATENCY_TIMER, temp_byte);
3060
3061 /* Cache Line size */
3062 temp_byte = 0x08;
3063 rc = pci_bus_write_config_byte(pci_bus, devfn,
3064 PCI_CACHE_LINE_SIZE, temp_byte);
3065
3066 /* disable ROM base Address */
3067 temp_dword = 0x00L;
3068 rc = pci_bus_write_config_word(pci_bus, devfn,
3069 PCI_ROM_ADDRESS, temp_dword);
3070
3071 /* enable card */
3072 temp_word = 0x0157; /* = PCI_COMMAND_IO |
3073 * PCI_COMMAND_MEMORY |
3074 * PCI_COMMAND_MASTER |
3075 * PCI_COMMAND_INVALIDATE |
3076 * PCI_COMMAND_PARITY |
3077 * PCI_COMMAND_SERR */
3078 rc = pci_bus_write_config_word (pci_bus, devfn,
3079 PCI_COMMAND, temp_word);
3080 } else { /* End of Not-A-Bridge else */
3081 /* It's some strange type of PCI adapter (Cardbus?) */
3082 return DEVICE_TYPE_NOT_SUPPORTED;
3083 }
3084
3085 func->configured = 1;
3086
3087 return 0;
3088free_and_out:
3089 cpqhp_destroy_resource_list (&temp_resources);
3090
3091 return_resource(&(resources-> bus_head), hold_bus_node);
3092 return_resource(&(resources-> io_head), hold_IO_node);
3093 return_resource(&(resources-> mem_head), hold_mem_node);
3094 return_resource(&(resources-> p_mem_head), hold_p_mem_node);
3095 return rc;
3096}
diff --git a/drivers/pci/hotplug/cpqphp_nvram.c b/drivers/pci/hotplug/cpqphp_nvram.c
new file mode 100644
index 000000000000..ac98a11bd1eb
--- /dev/null
+++ b/drivers/pci/hotplug/cpqphp_nvram.c
@@ -0,0 +1,666 @@
1/*
2 * Compaq Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <greg@kroah.com>
26 *
27 */
28
29#include <linux/config.h>
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/types.h>
33#include <linux/proc_fs.h>
34#include <linux/slab.h>
35#include <linux/workqueue.h>
36#include <linux/pci.h>
37#include <linux/init.h>
38#include <asm/uaccess.h>
39#include "cpqphp.h"
40#include "cpqphp_nvram.h"
41
42
43#define ROM_INT15_PHY_ADDR 0x0FF859
44#define READ_EV 0xD8A4
45#define WRITE_EV 0xD8A5
46
47struct register_foo {
48 union {
49 unsigned long lword; /* eax */
50 unsigned short word; /* ax */
51
52 struct {
53 unsigned char low; /* al */
54 unsigned char high; /* ah */
55 } byte;
56 } data;
57
58 unsigned char opcode; /* see below */
59 unsigned long length; /* if the reg. is a pointer, how much data */
60} __attribute__ ((packed));
61
62struct all_reg {
63 struct register_foo eax_reg;
64 struct register_foo ebx_reg;
65 struct register_foo ecx_reg;
66 struct register_foo edx_reg;
67 struct register_foo edi_reg;
68 struct register_foo esi_reg;
69 struct register_foo eflags_reg;
70} __attribute__ ((packed));
71
72
73struct ev_hrt_header {
74 u8 Version;
75 u8 num_of_ctrl;
76 u8 next;
77};
78
79struct ev_hrt_ctrl {
80 u8 bus;
81 u8 device;
82 u8 function;
83 u8 mem_avail;
84 u8 p_mem_avail;
85 u8 io_avail;
86 u8 bus_avail;
87 u8 next;
88};
89
90
91static u8 evbuffer_init;
92static u8 evbuffer_length;
93static u8 evbuffer[1024];
94
95static void __iomem *compaq_int15_entry_point;
96
97static spinlock_t int15_lock; /* lock for ordering int15_bios_call() */
98
99
100/* This is a series of function that deals with
101 setting & getting the hotplug resource table in some environment variable.
102*/
103
104/*
105 * We really shouldn't be doing this unless there is a _very_ good reason to!!!
106 * greg k-h
107 */
108
109
110static u32 add_byte( u32 **p_buffer, u8 value, u32 *used, u32 *avail)
111{
112 u8 **tByte;
113
114 if ((*used + 1) > *avail)
115 return(1);
116
117 *((u8*)*p_buffer) = value;
118 tByte = (u8**)p_buffer;
119 (*tByte)++;
120 *used+=1;
121 return(0);
122}
123
124
125static u32 add_dword( u32 **p_buffer, u32 value, u32 *used, u32 *avail)
126{
127 if ((*used + 4) > *avail)
128 return(1);
129
130 **p_buffer = value;
131 (*p_buffer)++;
132 *used+=4;
133 return(0);
134}
135
136
137/*
138 * check_for_compaq_ROM
139 *
140 * this routine verifies that the ROM OEM string is 'COMPAQ'
141 *
142 * returns 0 for non-Compaq ROM, 1 for Compaq ROM
143 */
144static int check_for_compaq_ROM (void __iomem *rom_start)
145{
146 u8 temp1, temp2, temp3, temp4, temp5, temp6;
147 int result = 0;
148
149 temp1 = readb(rom_start + 0xffea + 0);
150 temp2 = readb(rom_start + 0xffea + 1);
151 temp3 = readb(rom_start + 0xffea + 2);
152 temp4 = readb(rom_start + 0xffea + 3);
153 temp5 = readb(rom_start + 0xffea + 4);
154 temp6 = readb(rom_start + 0xffea + 5);
155 if ((temp1 == 'C') &&
156 (temp2 == 'O') &&
157 (temp3 == 'M') &&
158 (temp4 == 'P') &&
159 (temp5 == 'A') &&
160 (temp6 == 'Q')) {
161 result = 1;
162 }
163 dbg ("%s - returned %d\n", __FUNCTION__, result);
164 return result;
165}
166
167
168static u32 access_EV (u16 operation, u8 *ev_name, u8 *buffer, u32 *buf_size)
169{
170 unsigned long flags;
171 int op = operation;
172 int ret_val;
173
174 if (!compaq_int15_entry_point)
175 return -ENODEV;
176
177 spin_lock_irqsave(&int15_lock, flags);
178 __asm__ (
179 "xorl %%ebx,%%ebx\n" \
180 "xorl %%edx,%%edx\n" \
181 "pushf\n" \
182 "push %%cs\n" \
183 "cli\n" \
184 "call *%6\n"
185 : "=c" (*buf_size), "=a" (ret_val)
186 : "a" (op), "c" (*buf_size), "S" (ev_name),
187 "D" (buffer), "m" (compaq_int15_entry_point)
188 : "%ebx", "%edx");
189 spin_unlock_irqrestore(&int15_lock, flags);
190
191 return((ret_val & 0xFF00) >> 8);
192}
193
194
195/*
196 * load_HRT
197 *
198 * Read the hot plug Resource Table from NVRAM
199 */
200static int load_HRT (void __iomem *rom_start)
201{
202 u32 available;
203 u32 temp_dword;
204 u8 temp_byte = 0xFF;
205 u32 rc;
206
207 if (!check_for_compaq_ROM(rom_start)) {
208 return -ENODEV;
209 }
210
211 available = 1024;
212
213 // Now load the EV
214 temp_dword = available;
215
216 rc = access_EV(READ_EV, "CQTHPS", evbuffer, &temp_dword);
217
218 evbuffer_length = temp_dword;
219
220 // We're maintaining the resource lists so write FF to invalidate old info
221 temp_dword = 1;
222
223 rc = access_EV(WRITE_EV, "CQTHPS", &temp_byte, &temp_dword);
224
225 return rc;
226}
227
228
229/*
230 * store_HRT
231 *
232 * Save the hot plug Resource Table in NVRAM
233 */
234static u32 store_HRT (void __iomem *rom_start)
235{
236 u32 *buffer;
237 u32 *pFill;
238 u32 usedbytes;
239 u32 available;
240 u32 temp_dword;
241 u32 rc;
242 u8 loop;
243 u8 numCtrl = 0;
244 struct controller *ctrl;
245 struct pci_resource *resNode;
246 struct ev_hrt_header *p_EV_header;
247 struct ev_hrt_ctrl *p_ev_ctrl;
248
249 available = 1024;
250
251 if (!check_for_compaq_ROM(rom_start)) {
252 return(1);
253 }
254
255 buffer = (u32*) evbuffer;
256
257 if (!buffer)
258 return(1);
259
260 pFill = buffer;
261 usedbytes = 0;
262
263 p_EV_header = (struct ev_hrt_header *) pFill;
264
265 ctrl = cpqhp_ctrl_list;
266
267 // The revision of this structure
268 rc = add_byte( &pFill, 1 + ctrl->push_flag, &usedbytes, &available);
269 if (rc)
270 return(rc);
271
272 // The number of controllers
273 rc = add_byte( &pFill, 1, &usedbytes, &available);
274 if (rc)
275 return(rc);
276
277 while (ctrl) {
278 p_ev_ctrl = (struct ev_hrt_ctrl *) pFill;
279
280 numCtrl++;
281
282 // The bus number
283 rc = add_byte( &pFill, ctrl->bus, &usedbytes, &available);
284 if (rc)
285 return(rc);
286
287 // The device Number
288 rc = add_byte( &pFill, PCI_SLOT(ctrl->pci_dev->devfn), &usedbytes, &available);
289 if (rc)
290 return(rc);
291
292 // The function Number
293 rc = add_byte( &pFill, PCI_FUNC(ctrl->pci_dev->devfn), &usedbytes, &available);
294 if (rc)
295 return(rc);
296
297 // Skip the number of available entries
298 rc = add_dword( &pFill, 0, &usedbytes, &available);
299 if (rc)
300 return(rc);
301
302 // Figure out memory Available
303
304 resNode = ctrl->mem_head;
305
306 loop = 0;
307
308 while (resNode) {
309 loop ++;
310
311 // base
312 rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
313 if (rc)
314 return(rc);
315
316 // length
317 rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
318 if (rc)
319 return(rc);
320
321 resNode = resNode->next;
322 }
323
324 // Fill in the number of entries
325 p_ev_ctrl->mem_avail = loop;
326
327 // Figure out prefetchable memory Available
328
329 resNode = ctrl->p_mem_head;
330
331 loop = 0;
332
333 while (resNode) {
334 loop ++;
335
336 // base
337 rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
338 if (rc)
339 return(rc);
340
341 // length
342 rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
343 if (rc)
344 return(rc);
345
346 resNode = resNode->next;
347 }
348
349 // Fill in the number of entries
350 p_ev_ctrl->p_mem_avail = loop;
351
352 // Figure out IO Available
353
354 resNode = ctrl->io_head;
355
356 loop = 0;
357
358 while (resNode) {
359 loop ++;
360
361 // base
362 rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
363 if (rc)
364 return(rc);
365
366 // length
367 rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
368 if (rc)
369 return(rc);
370
371 resNode = resNode->next;
372 }
373
374 // Fill in the number of entries
375 p_ev_ctrl->io_avail = loop;
376
377 // Figure out bus Available
378
379 resNode = ctrl->bus_head;
380
381 loop = 0;
382
383 while (resNode) {
384 loop ++;
385
386 // base
387 rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
388 if (rc)
389 return(rc);
390
391 // length
392 rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
393 if (rc)
394 return(rc);
395
396 resNode = resNode->next;
397 }
398
399 // Fill in the number of entries
400 p_ev_ctrl->bus_avail = loop;
401
402 ctrl = ctrl->next;
403 }
404
405 p_EV_header->num_of_ctrl = numCtrl;
406
407 // Now store the EV
408
409 temp_dword = usedbytes;
410
411 rc = access_EV(WRITE_EV, "CQTHPS", (u8*) buffer, &temp_dword);
412
413 dbg("usedbytes = 0x%x, length = 0x%x\n", usedbytes, temp_dword);
414
415 evbuffer_length = temp_dword;
416
417 if (rc) {
418 err(msg_unable_to_save);
419 return(1);
420 }
421
422 return(0);
423}
424
425
426void compaq_nvram_init (void __iomem *rom_start)
427{
428 if (rom_start) {
429 compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
430 }
431 dbg("int15 entry = %p\n", compaq_int15_entry_point);
432
433 /* initialize our int15 lock */
434 spin_lock_init(&int15_lock);
435}
436
437
438int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
439{
440 u8 bus, device, function;
441 u8 nummem, numpmem, numio, numbus;
442 u32 rc;
443 u8 *p_byte;
444 struct pci_resource *mem_node;
445 struct pci_resource *p_mem_node;
446 struct pci_resource *io_node;
447 struct pci_resource *bus_node;
448 struct ev_hrt_ctrl *p_ev_ctrl;
449 struct ev_hrt_header *p_EV_header;
450
451 if (!evbuffer_init) {
452 // Read the resource list information in from NVRAM
453 if (load_HRT(rom_start))
454 memset (evbuffer, 0, 1024);
455
456 evbuffer_init = 1;
457 }
458
459 // If we saved information in NVRAM, use it now
460 p_EV_header = (struct ev_hrt_header *) evbuffer;
461
462 // The following code is for systems where version 1.0 of this
463 // driver has been loaded, but doesn't support the hardware.
464 // In that case, the driver would incorrectly store something
465 // in NVRAM.
466 if ((p_EV_header->Version == 2) ||
467 ((p_EV_header->Version == 1) && !ctrl->push_flag)) {
468 p_byte = &(p_EV_header->next);
469
470 p_ev_ctrl = (struct ev_hrt_ctrl *) &(p_EV_header->next);
471
472 p_byte += 3;
473
474 if (p_byte > ((u8*)p_EV_header + evbuffer_length))
475 return 2;
476
477 bus = p_ev_ctrl->bus;
478 device = p_ev_ctrl->device;
479 function = p_ev_ctrl->function;
480
481 while ((bus != ctrl->bus) ||
482 (device != PCI_SLOT(ctrl->pci_dev->devfn)) ||
483 (function != PCI_FUNC(ctrl->pci_dev->devfn))) {
484 nummem = p_ev_ctrl->mem_avail;
485 numpmem = p_ev_ctrl->p_mem_avail;
486 numio = p_ev_ctrl->io_avail;
487 numbus = p_ev_ctrl->bus_avail;
488
489 p_byte += 4;
490
491 if (p_byte > ((u8*)p_EV_header + evbuffer_length))
492 return 2;
493
494 // Skip forward to the next entry
495 p_byte += (nummem + numpmem + numio + numbus) * 8;
496
497 if (p_byte > ((u8*)p_EV_header + evbuffer_length))
498 return 2;
499
500 p_ev_ctrl = (struct ev_hrt_ctrl *) p_byte;
501
502 p_byte += 3;
503
504 if (p_byte > ((u8*)p_EV_header + evbuffer_length))
505 return 2;
506
507 bus = p_ev_ctrl->bus;
508 device = p_ev_ctrl->device;
509 function = p_ev_ctrl->function;
510 }
511
512 nummem = p_ev_ctrl->mem_avail;
513 numpmem = p_ev_ctrl->p_mem_avail;
514 numio = p_ev_ctrl->io_avail;
515 numbus = p_ev_ctrl->bus_avail;
516
517 p_byte += 4;
518
519 if (p_byte > ((u8*)p_EV_header + evbuffer_length))
520 return 2;
521
522 while (nummem--) {
523 mem_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
524
525 if (!mem_node)
526 break;
527
528 mem_node->base = *(u32*)p_byte;
529 dbg("mem base = %8.8x\n",mem_node->base);
530 p_byte += 4;
531
532 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
533 kfree(mem_node);
534 return 2;
535 }
536
537 mem_node->length = *(u32*)p_byte;
538 dbg("mem length = %8.8x\n",mem_node->length);
539 p_byte += 4;
540
541 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
542 kfree(mem_node);
543 return 2;
544 }
545
546 mem_node->next = ctrl->mem_head;
547 ctrl->mem_head = mem_node;
548 }
549
550 while (numpmem--) {
551 p_mem_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
552
553 if (!p_mem_node)
554 break;
555
556 p_mem_node->base = *(u32*)p_byte;
557 dbg("pre-mem base = %8.8x\n",p_mem_node->base);
558 p_byte += 4;
559
560 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
561 kfree(p_mem_node);
562 return 2;
563 }
564
565 p_mem_node->length = *(u32*)p_byte;
566 dbg("pre-mem length = %8.8x\n",p_mem_node->length);
567 p_byte += 4;
568
569 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
570 kfree(p_mem_node);
571 return 2;
572 }
573
574 p_mem_node->next = ctrl->p_mem_head;
575 ctrl->p_mem_head = p_mem_node;
576 }
577
578 while (numio--) {
579 io_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
580
581 if (!io_node)
582 break;
583
584 io_node->base = *(u32*)p_byte;
585 dbg("io base = %8.8x\n",io_node->base);
586 p_byte += 4;
587
588 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
589 kfree(io_node);
590 return 2;
591 }
592
593 io_node->length = *(u32*)p_byte;
594 dbg("io length = %8.8x\n",io_node->length);
595 p_byte += 4;
596
597 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
598 kfree(io_node);
599 return 2;
600 }
601
602 io_node->next = ctrl->io_head;
603 ctrl->io_head = io_node;
604 }
605
606 while (numbus--) {
607 bus_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
608
609 if (!bus_node)
610 break;
611
612 bus_node->base = *(u32*)p_byte;
613 p_byte += 4;
614
615 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
616 kfree(bus_node);
617 return 2;
618 }
619
620 bus_node->length = *(u32*)p_byte;
621 p_byte += 4;
622
623 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
624 kfree(bus_node);
625 return 2;
626 }
627
628 bus_node->next = ctrl->bus_head;
629 ctrl->bus_head = bus_node;
630 }
631
632 // If all of the following fail, we don't have any resources for
633 // hot plug add
634 rc = 1;
635 rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
636 rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
637 rc &= cpqhp_resource_sort_and_combine(&(ctrl->io_head));
638 rc &= cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
639
640 if (rc)
641 return(rc);
642 } else {
643 if ((evbuffer[0] != 0) && (!ctrl->push_flag))
644 return 1;
645 }
646
647 return 0;
648}
649
650
651int compaq_nvram_store (void __iomem *rom_start)
652{
653 int rc = 1;
654
655 if (rom_start == NULL)
656 return -ENODEV;
657
658 if (evbuffer_init) {
659 rc = store_HRT(rom_start);
660 if (rc) {
661 err(msg_unable_to_save);
662 }
663 }
664 return rc;
665}
666
diff --git a/drivers/pci/hotplug/cpqphp_nvram.h b/drivers/pci/hotplug/cpqphp_nvram.h
new file mode 100644
index 000000000000..e89c0702119d
--- /dev/null
+++ b/drivers/pci/hotplug/cpqphp_nvram.h
@@ -0,0 +1,57 @@
1/*
2 * Compaq Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 *
7 * All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
17 * NON INFRINGEMENT. See the GNU General Public License for more
18 * details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * Send feedback to <greg@kroah.com>
25 *
26 */
27
28#ifndef _CPQPHP_NVRAM_H
29#define _CPQPHP_NVRAM_H
30
31#ifndef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM
32
33static inline void compaq_nvram_init (void __iomem *rom_start)
34{
35 return;
36}
37
38static inline int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
39{
40 return 0;
41}
42
43static inline int compaq_nvram_store (void __iomem *rom_start)
44{
45 return 0;
46}
47
48#else
49
50extern void compaq_nvram_init (void __iomem *rom_start);
51extern int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl);
52extern int compaq_nvram_store (void __iomem *rom_start);
53
54#endif
55
56#endif
57
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
new file mode 100644
index 000000000000..93e39c4096a9
--- /dev/null
+++ b/drivers/pci/hotplug/cpqphp_pci.c
@@ -0,0 +1,1569 @@
1/*
2 * Compaq Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <greg@kroah.com>
26 *
27 */
28
29#include <linux/config.h>
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/types.h>
33#include <linux/slab.h>
34#include <linux/workqueue.h>
35#include <linux/proc_fs.h>
36#include <linux/pci.h>
37#include "../pci.h"
38#include "cpqphp.h"
39#include "cpqphp_nvram.h"
40#include "../../../arch/i386/pci/pci.h" /* horrible hack showing how processor dependent we are... */
41
42
43u8 cpqhp_nic_irq;
44u8 cpqhp_disk_irq;
45
46static u16 unused_IRQ;
47
48/*
49 * detect_HRT_floating_pointer
50 *
51 * find the Hot Plug Resource Table in the specified region of memory.
52 *
53 */
54static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iomem *end)
55{
56 void __iomem *fp;
57 void __iomem *endp;
58 u8 temp1, temp2, temp3, temp4;
59 int status = 0;
60
61 endp = (end - sizeof(struct hrt) + 1);
62
63 for (fp = begin; fp <= endp; fp += 16) {
64 temp1 = readb(fp + SIG0);
65 temp2 = readb(fp + SIG1);
66 temp3 = readb(fp + SIG2);
67 temp4 = readb(fp + SIG3);
68 if (temp1 == '$' &&
69 temp2 == 'H' &&
70 temp3 == 'R' &&
71 temp4 == 'T') {
72 status = 1;
73 break;
74 }
75 }
76
77 if (!status)
78 fp = NULL;
79
80 dbg("Discovered Hotplug Resource Table at %p\n", fp);
81 return fp;
82}
83
84
85int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)
86{
87 unsigned char bus;
88 struct pci_bus *child;
89 int num;
90
91 if (func->pci_dev == NULL)
92 func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
93
94 /* No pci device, we need to create it then */
95 if (func->pci_dev == NULL) {
96 dbg("INFO: pci_dev still null\n");
97
98 num = pci_scan_slot(ctrl->pci_dev->bus, PCI_DEVFN(func->device, func->function));
99 if (num)
100 pci_bus_add_devices(ctrl->pci_dev->bus);
101
102 func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
103 if (func->pci_dev == NULL) {
104 dbg("ERROR: pci_dev still null\n");
105 return 0;
106 }
107 }
108
109 if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
110 pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus);
111 child = (struct pci_bus*) pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus);
112 pci_do_scan_bus(child);
113 }
114
115 return 0;
116}
117
118
119int cpqhp_unconfigure_device(struct pci_func* func)
120{
121 int j;
122
123 dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus, func->device, func->function);
124
125 for (j=0; j<8 ; j++) {
126 struct pci_dev* temp = pci_find_slot(func->bus, PCI_DEVFN(func->device, j));
127 if (temp)
128 pci_remove_bus_device(temp);
129 }
130 return 0;
131}
132
133static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 offset, u32 *value)
134{
135 u32 vendID = 0;
136
137 if (pci_bus_read_config_dword (bus, devfn, PCI_VENDOR_ID, &vendID) == -1)
138 return -1;
139 if (vendID == 0xffffffff)
140 return -1;
141 return pci_bus_read_config_dword (bus, devfn, offset, value);
142}
143
144
145/*
146 * cpqhp_set_irq
147 *
148 * @bus_num: bus number of PCI device
149 * @dev_num: device number of PCI device
150 * @slot: pointer to u8 where slot number will be returned
151 */
152int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
153{
154 int rc = 0;
155
156 if (cpqhp_legacy_mode) {
157 struct pci_dev *fakedev;
158 struct pci_bus *fakebus;
159 u16 temp_word;
160
161 fakedev = kmalloc(sizeof(*fakedev), GFP_KERNEL);
162 fakebus = kmalloc(sizeof(*fakebus), GFP_KERNEL);
163 if (!fakedev || !fakebus) {
164 kfree(fakedev);
165 kfree(fakebus);
166 return -ENOMEM;
167 }
168
169 fakedev->devfn = dev_num << 3;
170 fakedev->bus = fakebus;
171 fakebus->number = bus_num;
172 dbg("%s: dev %d, bus %d, pin %d, num %d\n",
173 __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
174 rc = pcibios_set_irq_routing(fakedev, int_pin - 0x0a, irq_num);
175 kfree(fakedev);
176 kfree(fakebus);
177 dbg("%s: rc %d\n", __FUNCTION__, rc);
178 if (!rc)
179 return !rc;
180
181 // set the Edge Level Control Register (ELCR)
182 temp_word = inb(0x4d0);
183 temp_word |= inb(0x4d1) << 8;
184
185 temp_word |= 0x01 << irq_num;
186
187 // This should only be for x86 as it sets the Edge Level Control Register
188 outb((u8) (temp_word & 0xFF), 0x4d0);
189 outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1);
190 rc = 0;
191 }
192
193 return rc;
194}
195
196
197/*
198 * WTF??? This function isn't in the code, yet a function calls it, but the
199 * compiler optimizes it away? strange. Here as a placeholder to keep the
200 * compiler happy.
201 */
202static int PCI_ScanBusNonBridge (u8 bus, u8 device)
203{
204 return 0;
205}
206
207static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev_num)
208{
209 u16 tdevice;
210 u32 work;
211 u8 tbus;
212
213 ctrl->pci_bus->number = bus_num;
214
215 for (tdevice = 0; tdevice < 0xFF; tdevice++) {
216 //Scan for access first
217 if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
218 continue;
219 dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice);
220 //Yep we got one. Not a bridge ?
221 if ((work >> 8) != PCI_TO_PCI_BRIDGE_CLASS) {
222 *dev_num = tdevice;
223 dbg("found it !\n");
224 return 0;
225 }
226 }
227 for (tdevice = 0; tdevice < 0xFF; tdevice++) {
228 //Scan for access first
229 if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
230 continue;
231 dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice);
232 //Yep we got one. bridge ?
233 if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
234 pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(tdevice, 0), PCI_SECONDARY_BUS, &tbus);
235 dbg("Recurse on bus_num %d tdevice %d\n", tbus, tdevice);
236 if (PCI_ScanBusNonBridge(tbus, tdevice) == 0)
237 return 0;
238 }
239 }
240
241 return -1;
242}
243
244
245static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot, u8 nobridge)
246{
247 struct irq_routing_table *PCIIRQRoutingInfoLength;
248 long len;
249 long loop;
250 u32 work;
251
252 u8 tbus, tdevice, tslot;
253
254 PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
255 if (!PCIIRQRoutingInfoLength)
256 return -1;
257
258 len = (PCIIRQRoutingInfoLength->size -
259 sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
260 // Make sure I got at least one entry
261 if (len == 0) {
262 if (PCIIRQRoutingInfoLength != NULL)
263 kfree(PCIIRQRoutingInfoLength );
264 return -1;
265 }
266
267 for (loop = 0; loop < len; ++loop) {
268 tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
269 tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn;
270 tslot = PCIIRQRoutingInfoLength->slots[loop].slot;
271
272 if (tslot == slot) {
273 *bus_num = tbus;
274 *dev_num = tdevice;
275 ctrl->pci_bus->number = tbus;
276 pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
277 if (!nobridge || (work == 0xffffffff)) {
278 if (PCIIRQRoutingInfoLength != NULL)
279 kfree(PCIIRQRoutingInfoLength );
280 return 0;
281 }
282
283 dbg("bus_num %d devfn %d\n", *bus_num, *dev_num);
284 pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_CLASS_REVISION, &work);
285 dbg("work >> 8 (%x) = BRIDGE (%x)\n", work >> 8, PCI_TO_PCI_BRIDGE_CLASS);
286
287 if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
288 pci_bus_read_config_byte (ctrl->pci_bus, *dev_num, PCI_SECONDARY_BUS, &tbus);
289 dbg("Scan bus for Non Bridge: bus %d\n", tbus);
290 if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) {
291 *bus_num = tbus;
292 if (PCIIRQRoutingInfoLength != NULL)
293 kfree(PCIIRQRoutingInfoLength );
294 return 0;
295 }
296 } else {
297 if (PCIIRQRoutingInfoLength != NULL)
298 kfree(PCIIRQRoutingInfoLength );
299 return 0;
300 }
301
302 }
303 }
304 if (PCIIRQRoutingInfoLength != NULL)
305 kfree(PCIIRQRoutingInfoLength );
306 return -1;
307}
308
309
310int cpqhp_get_bus_dev (struct controller *ctrl, u8 * bus_num, u8 * dev_num, u8 slot)
311{
312 return PCI_GetBusDevHelper(ctrl, bus_num, dev_num, slot, 0); //plain (bridges allowed)
313}
314
315
316/* More PCI configuration routines; this time centered around hotplug controller */
317
318
319/*
320 * cpqhp_save_config
321 *
322 * Reads configuration for all slots in a PCI bus and saves info.
323 *
324 * Note: For non-hot plug busses, the slot # saved is the device #
325 *
326 * returns 0 if success
327 */
328int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
329{
330 long rc;
331 u8 class_code;
332 u8 header_type;
333 u32 ID;
334 u8 secondary_bus;
335 struct pci_func *new_slot;
336 int sub_bus;
337 int FirstSupported;
338 int LastSupported;
339 int max_functions;
340 int function;
341 u8 DevError;
342 int device = 0;
343 int cloop = 0;
344 int stop_it;
345 int index;
346
347 // Decide which slots are supported
348
349 if (is_hot_plug) {
350 //*********************************
351 // is_hot_plug is the slot mask
352 //*********************************
353 FirstSupported = is_hot_plug >> 4;
354 LastSupported = FirstSupported + (is_hot_plug & 0x0F) - 1;
355 } else {
356 FirstSupported = 0;
357 LastSupported = 0x1F;
358 }
359
360 // Save PCI configuration space for all devices in supported slots
361 ctrl->pci_bus->number = busnumber;
362 for (device = FirstSupported; device <= LastSupported; device++) {
363 ID = 0xFFFFFFFF;
364 rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
365
366 if (ID != 0xFFFFFFFF) { // device in slot
367 rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, 0), 0x0B, &class_code);
368 if (rc)
369 return rc;
370
371 rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_HEADER_TYPE, &header_type);
372 if (rc)
373 return rc;
374
375 // If multi-function device, set max_functions to 8
376 if (header_type & 0x80)
377 max_functions = 8;
378 else
379 max_functions = 1;
380
381 function = 0;
382
383 do {
384 DevError = 0;
385
386 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // P-P Bridge
387 // Recurse the subordinate bus
388 // get the subordinate bus number
389 rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_SECONDARY_BUS, &secondary_bus);
390 if (rc) {
391 return rc;
392 } else {
393 sub_bus = (int) secondary_bus;
394
395 // Save secondary bus cfg spc
396 // with this recursive call.
397 rc = cpqhp_save_config(ctrl, sub_bus, 0);
398 if (rc)
399 return rc;
400 ctrl->pci_bus->number = busnumber;
401 }
402 }
403
404 index = 0;
405 new_slot = cpqhp_slot_find(busnumber, device, index++);
406 while (new_slot &&
407 (new_slot->function != (u8) function))
408 new_slot = cpqhp_slot_find(busnumber, device, index++);
409
410 if (!new_slot) {
411 // Setup slot structure.
412 new_slot = cpqhp_slot_create(busnumber);
413
414 if (new_slot == NULL)
415 return(1);
416 }
417
418 new_slot->bus = (u8) busnumber;
419 new_slot->device = (u8) device;
420 new_slot->function = (u8) function;
421 new_slot->is_a_board = 1;
422 new_slot->switch_save = 0x10;
423 // In case of unsupported board
424 new_slot->status = DevError;
425 new_slot->pci_dev = pci_find_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function);
426
427 for (cloop = 0; cloop < 0x20; cloop++) {
428 rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
429 if (rc)
430 return rc;
431 }
432
433 function++;
434
435 stop_it = 0;
436
437 // this loop skips to the next present function
438 // reading in Class Code and Header type.
439
440 while ((function < max_functions)&&(!stop_it)) {
441 rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_VENDOR_ID, &ID);
442 if (ID == 0xFFFFFFFF) { // nothing there.
443 function++;
444 } else { // Something there
445 rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), 0x0B, &class_code);
446 if (rc)
447 return rc;
448
449 rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_HEADER_TYPE, &header_type);
450 if (rc)
451 return rc;
452
453 stop_it++;
454 }
455 }
456
457 } while (function < max_functions);
458 } // End of IF (device in slot?)
459 else if (is_hot_plug) {
460 // Setup slot structure with entry for empty slot
461 new_slot = cpqhp_slot_create(busnumber);
462
463 if (new_slot == NULL) {
464 return(1);
465 }
466
467 new_slot->bus = (u8) busnumber;
468 new_slot->device = (u8) device;
469 new_slot->function = 0;
470 new_slot->is_a_board = 0;
471 new_slot->presence_save = 0;
472 new_slot->switch_save = 0;
473 }
474 } // End of FOR loop
475
476 return(0);
477}
478
479
480/*
481 * cpqhp_save_slot_config
482 *
483 * Saves configuration info for all PCI devices in a given slot
484 * including subordinate busses.
485 *
486 * returns 0 if success
487 */
488int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot)
489{
490 long rc;
491 u8 class_code;
492 u8 header_type;
493 u32 ID;
494 u8 secondary_bus;
495 int sub_bus;
496 int max_functions;
497 int function;
498 int cloop = 0;
499 int stop_it;
500
501 ID = 0xFFFFFFFF;
502
503 ctrl->pci_bus->number = new_slot->bus;
504 pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_VENDOR_ID, &ID);
505
506 if (ID != 0xFFFFFFFF) { // device in slot
507 pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), 0x0B, &class_code);
508 pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_HEADER_TYPE, &header_type);
509
510 if (header_type & 0x80) // Multi-function device
511 max_functions = 8;
512 else
513 max_functions = 1;
514
515 function = 0;
516
517 do {
518 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
519 // Recurse the subordinate bus
520 pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_SECONDARY_BUS, &secondary_bus);
521
522 sub_bus = (int) secondary_bus;
523
524 // Save the config headers for the secondary bus.
525 rc = cpqhp_save_config(ctrl, sub_bus, 0);
526 if (rc)
527 return(rc);
528 ctrl->pci_bus->number = new_slot->bus;
529
530 } // End of IF
531
532 new_slot->status = 0;
533
534 for (cloop = 0; cloop < 0x20; cloop++) {
535 pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
536 }
537
538 function++;
539
540 stop_it = 0;
541
542 // this loop skips to the next present function
543 // reading in the Class Code and the Header type.
544
545 while ((function < max_functions) && (!stop_it)) {
546 pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_VENDOR_ID, &ID);
547
548 if (ID == 0xFFFFFFFF) { // nothing there.
549 function++;
550 } else { // Something there
551 pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), 0x0B, &class_code);
552
553 pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_HEADER_TYPE, &header_type);
554
555 stop_it++;
556 }
557 }
558
559 } while (function < max_functions);
560 } // End of IF (device in slot?)
561 else {
562 return 2;
563 }
564
565 return 0;
566}
567
568
569/*
570 * cpqhp_save_base_addr_length
571 *
572 * Saves the length of all base address registers for the
573 * specified slot. this is for hot plug REPLACE
574 *
575 * returns 0 if success
576 */
577int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
578{
579 u8 cloop;
580 u8 header_type;
581 u8 secondary_bus;
582 u8 type;
583 int sub_bus;
584 u32 temp_register;
585 u32 base;
586 u32 rc;
587 struct pci_func *next;
588 int index = 0;
589 struct pci_bus *pci_bus = ctrl->pci_bus;
590 unsigned int devfn;
591
592 func = cpqhp_slot_find(func->bus, func->device, index++);
593
594 while (func != NULL) {
595 pci_bus->number = func->bus;
596 devfn = PCI_DEVFN(func->device, func->function);
597
598 // Check for Bridge
599 pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
600
601 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
602 // PCI-PCI Bridge
603 pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
604
605 sub_bus = (int) secondary_bus;
606
607 next = cpqhp_slot_list[sub_bus];
608
609 while (next != NULL) {
610 rc = cpqhp_save_base_addr_length(ctrl, next);
611 if (rc)
612 return rc;
613
614 next = next->next;
615 }
616 pci_bus->number = func->bus;
617
618 //FIXME: this loop is duplicated in the non-bridge case. The two could be rolled together
619 // Figure out IO and memory base lengths
620 for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
621 temp_register = 0xFFFFFFFF;
622 pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
623 pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
624
625 if (base) { // If this register is implemented
626 if (base & 0x01L) {
627 // IO base
628 // set base = amount of IO space requested
629 base = base & 0xFFFFFFFE;
630 base = (~base) + 1;
631
632 type = 1;
633 } else {
634 // memory base
635 base = base & 0xFFFFFFF0;
636 base = (~base) + 1;
637
638 type = 0;
639 }
640 } else {
641 base = 0x0L;
642 type = 0;
643 }
644
645 // Save information in slot structure
646 func->base_length[(cloop - 0x10) >> 2] =
647 base;
648 func->base_type[(cloop - 0x10) >> 2] = type;
649
650 } // End of base register loop
651
652
653 } else if ((header_type & 0x7F) == 0x00) { // PCI-PCI Bridge
654 // Figure out IO and memory base lengths
655 for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
656 temp_register = 0xFFFFFFFF;
657 pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
658 pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
659
660 if (base) { // If this register is implemented
661 if (base & 0x01L) {
662 // IO base
663 // base = amount of IO space requested
664 base = base & 0xFFFFFFFE;
665 base = (~base) + 1;
666
667 type = 1;
668 } else {
669 // memory base
670 // base = amount of memory space requested
671 base = base & 0xFFFFFFF0;
672 base = (~base) + 1;
673
674 type = 0;
675 }
676 } else {
677 base = 0x0L;
678 type = 0;
679 }
680
681 // Save information in slot structure
682 func->base_length[(cloop - 0x10) >> 2] = base;
683 func->base_type[(cloop - 0x10) >> 2] = type;
684
685 } // End of base register loop
686
687 } else { // Some other unknown header type
688 }
689
690 // find the next device in this slot
691 func = cpqhp_slot_find(func->bus, func->device, index++);
692 }
693
694 return(0);
695}
696
697
698/*
699 * cpqhp_save_used_resources
700 *
701 * Stores used resource information for existing boards. this is
702 * for boards that were in the system when this driver was loaded.
703 * this function is for hot plug ADD
704 *
705 * returns 0 if success
706 */
707int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
708{
709 u8 cloop;
710 u8 header_type;
711 u8 secondary_bus;
712 u8 temp_byte;
713 u8 b_base;
714 u8 b_length;
715 u16 command;
716 u16 save_command;
717 u16 w_base;
718 u16 w_length;
719 u32 temp_register;
720 u32 save_base;
721 u32 base;
722 int index = 0;
723 struct pci_resource *mem_node;
724 struct pci_resource *p_mem_node;
725 struct pci_resource *io_node;
726 struct pci_resource *bus_node;
727 struct pci_bus *pci_bus = ctrl->pci_bus;
728 unsigned int devfn;
729
730 func = cpqhp_slot_find(func->bus, func->device, index++);
731
732 while ((func != NULL) && func->is_a_board) {
733 pci_bus->number = func->bus;
734 devfn = PCI_DEVFN(func->device, func->function);
735
736 // Save the command register
737 pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command);
738
739 // disable card
740 command = 0x00;
741 pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
742
743 // Check for Bridge
744 pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
745
746 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
747 // Clear Bridge Control Register
748 command = 0x00;
749 pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
750 pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
751 pci_bus_read_config_byte(pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte);
752
753 bus_node = kmalloc(sizeof(*bus_node), GFP_KERNEL);
754 if (!bus_node)
755 return -ENOMEM;
756
757 bus_node->base = secondary_bus;
758 bus_node->length = temp_byte - secondary_bus + 1;
759
760 bus_node->next = func->bus_head;
761 func->bus_head = bus_node;
762
763 // Save IO base and Limit registers
764 pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &b_base);
765 pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &b_length);
766
767 if ((b_base <= b_length) && (save_command & 0x01)) {
768 io_node = kmalloc(sizeof(*io_node), GFP_KERNEL);
769 if (!io_node)
770 return -ENOMEM;
771
772 io_node->base = (b_base & 0xF0) << 8;
773 io_node->length = (b_length - b_base + 0x10) << 8;
774
775 io_node->next = func->io_head;
776 func->io_head = io_node;
777 }
778
779 // Save memory base and Limit registers
780 pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_BASE, &w_base);
781 pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length);
782
783 if ((w_base <= w_length) && (save_command & 0x02)) {
784 mem_node = kmalloc(sizeof(*mem_node), GFP_KERNEL);
785 if (!mem_node)
786 return -ENOMEM;
787
788 mem_node->base = w_base << 16;
789 mem_node->length = (w_length - w_base + 0x10) << 16;
790
791 mem_node->next = func->mem_head;
792 func->mem_head = mem_node;
793 }
794
795 // Save prefetchable memory base and Limit registers
796 pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base);
797 pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length);
798
799 if ((w_base <= w_length) && (save_command & 0x02)) {
800 p_mem_node = kmalloc(sizeof(*p_mem_node), GFP_KERNEL);
801 if (!p_mem_node)
802 return -ENOMEM;
803
804 p_mem_node->base = w_base << 16;
805 p_mem_node->length = (w_length - w_base + 0x10) << 16;
806
807 p_mem_node->next = func->p_mem_head;
808 func->p_mem_head = p_mem_node;
809 }
810 // Figure out IO and memory base lengths
811 for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
812 pci_bus_read_config_dword (pci_bus, devfn, cloop, &save_base);
813
814 temp_register = 0xFFFFFFFF;
815 pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
816 pci_bus_read_config_dword(pci_bus, devfn, cloop, &base);
817
818 temp_register = base;
819
820 if (base) { // If this register is implemented
821 if (((base & 0x03L) == 0x01)
822 && (save_command & 0x01)) {
823 // IO base
824 // set temp_register = amount of IO space requested
825 temp_register = base & 0xFFFFFFFE;
826 temp_register = (~temp_register) + 1;
827
828 io_node = kmalloc(sizeof(*io_node),
829 GFP_KERNEL);
830 if (!io_node)
831 return -ENOMEM;
832
833 io_node->base =
834 save_base & (~0x03L);
835 io_node->length = temp_register;
836
837 io_node->next = func->io_head;
838 func->io_head = io_node;
839 } else
840 if (((base & 0x0BL) == 0x08)
841 && (save_command & 0x02)) {
842 // prefetchable memory base
843 temp_register = base & 0xFFFFFFF0;
844 temp_register = (~temp_register) + 1;
845
846 p_mem_node = kmalloc(sizeof(*p_mem_node),
847 GFP_KERNEL);
848 if (!p_mem_node)
849 return -ENOMEM;
850
851 p_mem_node->base = save_base & (~0x0FL);
852 p_mem_node->length = temp_register;
853
854 p_mem_node->next = func->p_mem_head;
855 func->p_mem_head = p_mem_node;
856 } else
857 if (((base & 0x0BL) == 0x00)
858 && (save_command & 0x02)) {
859 // prefetchable memory base
860 temp_register = base & 0xFFFFFFF0;
861 temp_register = (~temp_register) + 1;
862
863 mem_node = kmalloc(sizeof(*mem_node),
864 GFP_KERNEL);
865 if (!mem_node)
866 return -ENOMEM;
867
868 mem_node->base = save_base & (~0x0FL);
869 mem_node->length = temp_register;
870
871 mem_node->next = func->mem_head;
872 func->mem_head = mem_node;
873 } else
874 return(1);
875 }
876 } // End of base register loop
877 } else if ((header_type & 0x7F) == 0x00) { // Standard header
878 // Figure out IO and memory base lengths
879 for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
880 pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base);
881
882 temp_register = 0xFFFFFFFF;
883 pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
884 pci_bus_read_config_dword(pci_bus, devfn, cloop, &base);
885
886 temp_register = base;
887
888 if (base) { // If this register is implemented
889 if (((base & 0x03L) == 0x01)
890 && (save_command & 0x01)) {
891 // IO base
892 // set temp_register = amount of IO space requested
893 temp_register = base & 0xFFFFFFFE;
894 temp_register = (~temp_register) + 1;
895
896 io_node = kmalloc(sizeof(*io_node),
897 GFP_KERNEL);
898 if (!io_node)
899 return -ENOMEM;
900
901 io_node->base = save_base & (~0x01L);
902 io_node->length = temp_register;
903
904 io_node->next = func->io_head;
905 func->io_head = io_node;
906 } else
907 if (((base & 0x0BL) == 0x08)
908 && (save_command & 0x02)) {
909 // prefetchable memory base
910 temp_register = base & 0xFFFFFFF0;
911 temp_register = (~temp_register) + 1;
912
913 p_mem_node = kmalloc(sizeof(*p_mem_node),
914 GFP_KERNEL);
915 if (!p_mem_node)
916 return -ENOMEM;
917
918 p_mem_node->base = save_base & (~0x0FL);
919 p_mem_node->length = temp_register;
920
921 p_mem_node->next = func->p_mem_head;
922 func->p_mem_head = p_mem_node;
923 } else
924 if (((base & 0x0BL) == 0x00)
925 && (save_command & 0x02)) {
926 // prefetchable memory base
927 temp_register = base & 0xFFFFFFF0;
928 temp_register = (~temp_register) + 1;
929
930 mem_node = kmalloc(sizeof(*mem_node),
931 GFP_KERNEL);
932 if (!mem_node)
933 return -ENOMEM;
934
935 mem_node->base = save_base & (~0x0FL);
936 mem_node->length = temp_register;
937
938 mem_node->next = func->mem_head;
939 func->mem_head = mem_node;
940 } else
941 return(1);
942 }
943 } // End of base register loop
944 } else { // Some other unknown header type
945 }
946
947 // find the next device in this slot
948 func = cpqhp_slot_find(func->bus, func->device, index++);
949 }
950
951 return(0);
952}
953
954
955/*
956 * cpqhp_configure_board
957 *
958 * Copies saved configuration information to one slot.
959 * this is called recursively for bridge devices.
960 * this is for hot plug REPLACE!
961 *
962 * returns 0 if success
963 */
964int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func)
965{
966 int cloop;
967 u8 header_type;
968 u8 secondary_bus;
969 int sub_bus;
970 struct pci_func *next;
971 u32 temp;
972 u32 rc;
973 int index = 0;
974 struct pci_bus *pci_bus = ctrl->pci_bus;
975 unsigned int devfn;
976
977 func = cpqhp_slot_find(func->bus, func->device, index++);
978
979 while (func != NULL) {
980 pci_bus->number = func->bus;
981 devfn = PCI_DEVFN(func->device, func->function);
982
983 // Start at the top of config space so that the control
984 // registers are programmed last
985 for (cloop = 0x3C; cloop > 0; cloop -= 4) {
986 pci_bus_write_config_dword (pci_bus, devfn, cloop, func->config_space[cloop >> 2]);
987 }
988
989 pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
990
991 // If this is a bridge device, restore subordinate devices
992 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
993 pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
994
995 sub_bus = (int) secondary_bus;
996
997 next = cpqhp_slot_list[sub_bus];
998
999 while (next != NULL) {
1000 rc = cpqhp_configure_board(ctrl, next);
1001 if (rc)
1002 return rc;
1003
1004 next = next->next;
1005 }
1006 } else {
1007
1008 // Check all the base Address Registers to make sure
1009 // they are the same. If not, the board is different.
1010
1011 for (cloop = 16; cloop < 40; cloop += 4) {
1012 pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp);
1013
1014 if (temp != func->config_space[cloop >> 2]) {
1015 dbg("Config space compare failure!!! offset = %x\n", cloop);
1016 dbg("bus = %x, device = %x, function = %x\n", func->bus, func->device, func->function);
1017 dbg("temp = %x, config space = %x\n\n", temp, func->config_space[cloop >> 2]);
1018 return 1;
1019 }
1020 }
1021 }
1022
1023 func->configured = 1;
1024
1025 func = cpqhp_slot_find(func->bus, func->device, index++);
1026 }
1027
1028 return 0;
1029}
1030
1031
1032/*
1033 * cpqhp_valid_replace
1034 *
1035 * this function checks to see if a board is the same as the
1036 * one it is replacing. this check will detect if the device's
1037 * vendor or device id's are the same
1038 *
1039 * returns 0 if the board is the same nonzero otherwise
1040 */
1041int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
1042{
1043 u8 cloop;
1044 u8 header_type;
1045 u8 secondary_bus;
1046 u8 type;
1047 u32 temp_register = 0;
1048 u32 base;
1049 u32 rc;
1050 struct pci_func *next;
1051 int index = 0;
1052 struct pci_bus *pci_bus = ctrl->pci_bus;
1053 unsigned int devfn;
1054
1055 if (!func->is_a_board)
1056 return(ADD_NOT_SUPPORTED);
1057
1058 func = cpqhp_slot_find(func->bus, func->device, index++);
1059
1060 while (func != NULL) {
1061 pci_bus->number = func->bus;
1062 devfn = PCI_DEVFN(func->device, func->function);
1063
1064 pci_bus_read_config_dword (pci_bus, devfn, PCI_VENDOR_ID, &temp_register);
1065
1066 // No adapter present
1067 if (temp_register == 0xFFFFFFFF)
1068 return(NO_ADAPTER_PRESENT);
1069
1070 if (temp_register != func->config_space[0])
1071 return(ADAPTER_NOT_SAME);
1072
1073 // Check for same revision number and class code
1074 pci_bus_read_config_dword (pci_bus, devfn, PCI_CLASS_REVISION, &temp_register);
1075
1076 // Adapter not the same
1077 if (temp_register != func->config_space[0x08 >> 2])
1078 return(ADAPTER_NOT_SAME);
1079
1080 // Check for Bridge
1081 pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
1082
1083 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
1084 // In order to continue checking, we must program the
1085 // bus registers in the bridge to respond to accesses
1086 // for it's subordinate bus(es)
1087
1088 temp_register = func->config_space[0x18 >> 2];
1089 pci_bus_write_config_dword (pci_bus, devfn, PCI_PRIMARY_BUS, temp_register);
1090
1091 secondary_bus = (temp_register >> 8) & 0xFF;
1092
1093 next = cpqhp_slot_list[secondary_bus];
1094
1095 while (next != NULL) {
1096 rc = cpqhp_valid_replace(ctrl, next);
1097 if (rc)
1098 return rc;
1099
1100 next = next->next;
1101 }
1102
1103 }
1104 // Check to see if it is a standard config header
1105 else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
1106 // Check subsystem vendor and ID
1107 pci_bus_read_config_dword (pci_bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &temp_register);
1108
1109 if (temp_register != func->config_space[0x2C >> 2]) {
1110 // If it's a SMART-2 and the register isn't filled
1111 // in, ignore the difference because
1112 // they just have an old rev of the firmware
1113
1114 if (!((func->config_space[0] == 0xAE100E11)
1115 && (temp_register == 0x00L)))
1116 return(ADAPTER_NOT_SAME);
1117 }
1118 // Figure out IO and memory base lengths
1119 for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
1120 temp_register = 0xFFFFFFFF;
1121 pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
1122 pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
1123 if (base) { // If this register is implemented
1124 if (base & 0x01L) {
1125 // IO base
1126 // set base = amount of IO space requested
1127 base = base & 0xFFFFFFFE;
1128 base = (~base) + 1;
1129
1130 type = 1;
1131 } else {
1132 // memory base
1133 base = base & 0xFFFFFFF0;
1134 base = (~base) + 1;
1135
1136 type = 0;
1137 }
1138 } else {
1139 base = 0x0L;
1140 type = 0;
1141 }
1142
1143 // Check information in slot structure
1144 if (func->base_length[(cloop - 0x10) >> 2] != base)
1145 return(ADAPTER_NOT_SAME);
1146
1147 if (func->base_type[(cloop - 0x10) >> 2] != type)
1148 return(ADAPTER_NOT_SAME);
1149
1150 } // End of base register loop
1151
1152 } // End of (type 0 config space) else
1153 else {
1154 // this is not a type 0 or 1 config space header so
1155 // we don't know how to do it
1156 return(DEVICE_TYPE_NOT_SUPPORTED);
1157 }
1158
1159 // Get the next function
1160 func = cpqhp_slot_find(func->bus, func->device, index++);
1161 }
1162
1163
1164 return 0;
1165}
1166
1167
1168/*
1169 * cpqhp_find_available_resources
1170 *
1171 * Finds available memory, IO, and IRQ resources for programming
1172 * devices which may be added to the system
1173 * this function is for hot plug ADD!
1174 *
1175 * returns 0 if success
1176 */
1177int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_start)
1178{
1179 u8 temp;
1180 u8 populated_slot;
1181 u8 bridged_slot;
1182 void __iomem *one_slot;
1183 void __iomem *rom_resource_table;
1184 struct pci_func *func = NULL;
1185 int i = 10, index;
1186 u32 temp_dword, rc;
1187 struct pci_resource *mem_node;
1188 struct pci_resource *p_mem_node;
1189 struct pci_resource *io_node;
1190 struct pci_resource *bus_node;
1191
1192 rom_resource_table = detect_HRT_floating_pointer(rom_start, rom_start+0xffff);
1193 dbg("rom_resource_table = %p\n", rom_resource_table);
1194
1195 if (rom_resource_table == NULL) {
1196 return -ENODEV;
1197 }
1198 // Sum all resources and setup resource maps
1199 unused_IRQ = readl(rom_resource_table + UNUSED_IRQ);
1200 dbg("unused_IRQ = %x\n", unused_IRQ);
1201
1202 temp = 0;
1203 while (unused_IRQ) {
1204 if (unused_IRQ & 1) {
1205 cpqhp_disk_irq = temp;
1206 break;
1207 }
1208 unused_IRQ = unused_IRQ >> 1;
1209 temp++;
1210 }
1211
1212 dbg("cpqhp_disk_irq= %d\n", cpqhp_disk_irq);
1213 unused_IRQ = unused_IRQ >> 1;
1214 temp++;
1215
1216 while (unused_IRQ) {
1217 if (unused_IRQ & 1) {
1218 cpqhp_nic_irq = temp;
1219 break;
1220 }
1221 unused_IRQ = unused_IRQ >> 1;
1222 temp++;
1223 }
1224
1225 dbg("cpqhp_nic_irq= %d\n", cpqhp_nic_irq);
1226 unused_IRQ = readl(rom_resource_table + PCIIRQ);
1227
1228 temp = 0;
1229
1230 if (!cpqhp_nic_irq) {
1231 cpqhp_nic_irq = ctrl->cfgspc_irq;
1232 }
1233
1234 if (!cpqhp_disk_irq) {
1235 cpqhp_disk_irq = ctrl->cfgspc_irq;
1236 }
1237
1238 dbg("cpqhp_disk_irq, cpqhp_nic_irq= %d, %d\n", cpqhp_disk_irq, cpqhp_nic_irq);
1239
1240 rc = compaq_nvram_load(rom_start, ctrl);
1241 if (rc)
1242 return rc;
1243
1244 one_slot = rom_resource_table + sizeof (struct hrt);
1245
1246 i = readb(rom_resource_table + NUMBER_OF_ENTRIES);
1247 dbg("number_of_entries = %d\n", i);
1248
1249 if (!readb(one_slot + SECONDARY_BUS))
1250 return 1;
1251
1252 dbg("dev|IO base|length|Mem base|length|Pre base|length|PB SB MB\n");
1253
1254 while (i && readb(one_slot + SECONDARY_BUS)) {
1255 u8 dev_func = readb(one_slot + DEV_FUNC);
1256 u8 primary_bus = readb(one_slot + PRIMARY_BUS);
1257 u8 secondary_bus = readb(one_slot + SECONDARY_BUS);
1258 u8 max_bus = readb(one_slot + MAX_BUS);
1259 u16 io_base = readw(one_slot + IO_BASE);
1260 u16 io_length = readw(one_slot + IO_LENGTH);
1261 u16 mem_base = readw(one_slot + MEM_BASE);
1262 u16 mem_length = readw(one_slot + MEM_LENGTH);
1263 u16 pre_mem_base = readw(one_slot + PRE_MEM_BASE);
1264 u16 pre_mem_length = readw(one_slot + PRE_MEM_LENGTH);
1265
1266 dbg("%2.2x | %4.4x | %4.4x | %4.4x | %4.4x | %4.4x | %4.4x |%2.2x %2.2x %2.2x\n",
1267 dev_func, io_base, io_length, mem_base, mem_length, pre_mem_base, pre_mem_length,
1268 primary_bus, secondary_bus, max_bus);
1269
1270 // If this entry isn't for our controller's bus, ignore it
1271 if (primary_bus != ctrl->bus) {
1272 i--;
1273 one_slot += sizeof (struct slot_rt);
1274 continue;
1275 }
1276 // find out if this entry is for an occupied slot
1277 ctrl->pci_bus->number = primary_bus;
1278 pci_bus_read_config_dword (ctrl->pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword);
1279 dbg("temp_D_word = %x\n", temp_dword);
1280
1281 if (temp_dword != 0xFFFFFFFF) {
1282 index = 0;
1283 func = cpqhp_slot_find(primary_bus, dev_func >> 3, 0);
1284
1285 while (func && (func->function != (dev_func & 0x07))) {
1286 dbg("func = %p (bus, dev, fun) = (%d, %d, %d)\n", func, primary_bus, dev_func >> 3, index);
1287 func = cpqhp_slot_find(primary_bus, dev_func >> 3, index++);
1288 }
1289
1290 // If we can't find a match, skip this table entry
1291 if (!func) {
1292 i--;
1293 one_slot += sizeof (struct slot_rt);
1294 continue;
1295 }
1296 // this may not work and shouldn't be used
1297 if (secondary_bus != primary_bus)
1298 bridged_slot = 1;
1299 else
1300 bridged_slot = 0;
1301
1302 populated_slot = 1;
1303 } else {
1304 populated_slot = 0;
1305 bridged_slot = 0;
1306 }
1307
1308
1309 // If we've got a valid IO base, use it
1310
1311 temp_dword = io_base + io_length;
1312
1313 if ((io_base) && (temp_dword < 0x10000)) {
1314 io_node = kmalloc(sizeof(*io_node), GFP_KERNEL);
1315 if (!io_node)
1316 return -ENOMEM;
1317
1318 io_node->base = io_base;
1319 io_node->length = io_length;
1320
1321 dbg("found io_node(base, length) = %x, %x\n",
1322 io_node->base, io_node->length);
1323 dbg("populated slot =%d \n", populated_slot);
1324 if (!populated_slot) {
1325 io_node->next = ctrl->io_head;
1326 ctrl->io_head = io_node;
1327 } else {
1328 io_node->next = func->io_head;
1329 func->io_head = io_node;
1330 }
1331 }
1332
1333 // If we've got a valid memory base, use it
1334 temp_dword = mem_base + mem_length;
1335 if ((mem_base) && (temp_dword < 0x10000)) {
1336 mem_node = kmalloc(sizeof(*mem_node), GFP_KERNEL);
1337 if (!mem_node)
1338 return -ENOMEM;
1339
1340 mem_node->base = mem_base << 16;
1341
1342 mem_node->length = mem_length << 16;
1343
1344 dbg("found mem_node(base, length) = %x, %x\n",
1345 mem_node->base, mem_node->length);
1346 dbg("populated slot =%d \n", populated_slot);
1347 if (!populated_slot) {
1348 mem_node->next = ctrl->mem_head;
1349 ctrl->mem_head = mem_node;
1350 } else {
1351 mem_node->next = func->mem_head;
1352 func->mem_head = mem_node;
1353 }
1354 }
1355
1356 // If we've got a valid prefetchable memory base, and
1357 // the base + length isn't greater than 0xFFFF
1358 temp_dword = pre_mem_base + pre_mem_length;
1359 if ((pre_mem_base) && (temp_dword < 0x10000)) {
1360 p_mem_node = kmalloc(sizeof(*p_mem_node), GFP_KERNEL);
1361 if (!p_mem_node)
1362 return -ENOMEM;
1363
1364 p_mem_node->base = pre_mem_base << 16;
1365
1366 p_mem_node->length = pre_mem_length << 16;
1367 dbg("found p_mem_node(base, length) = %x, %x\n",
1368 p_mem_node->base, p_mem_node->length);
1369 dbg("populated slot =%d \n", populated_slot);
1370
1371 if (!populated_slot) {
1372 p_mem_node->next = ctrl->p_mem_head;
1373 ctrl->p_mem_head = p_mem_node;
1374 } else {
1375 p_mem_node->next = func->p_mem_head;
1376 func->p_mem_head = p_mem_node;
1377 }
1378 }
1379
1380 // If we've got a valid bus number, use it
1381 // The second condition is to ignore bus numbers on
1382 // populated slots that don't have PCI-PCI bridges
1383 if (secondary_bus && (secondary_bus != primary_bus)) {
1384 bus_node = kmalloc(sizeof(*bus_node), GFP_KERNEL);
1385 if (!bus_node)
1386 return -ENOMEM;
1387
1388 bus_node->base = secondary_bus;
1389 bus_node->length = max_bus - secondary_bus + 1;
1390 dbg("found bus_node(base, length) = %x, %x\n",
1391 bus_node->base, bus_node->length);
1392 dbg("populated slot =%d \n", populated_slot);
1393 if (!populated_slot) {
1394 bus_node->next = ctrl->bus_head;
1395 ctrl->bus_head = bus_node;
1396 } else {
1397 bus_node->next = func->bus_head;
1398 func->bus_head = bus_node;
1399 }
1400 }
1401
1402 i--;
1403 one_slot += sizeof (struct slot_rt);
1404 }
1405
1406 // If all of the following fail, we don't have any resources for
1407 // hot plug add
1408 rc = 1;
1409 rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
1410 rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
1411 rc &= cpqhp_resource_sort_and_combine(&(ctrl->io_head));
1412 rc &= cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
1413
1414 return rc;
1415}
1416
1417
1418/*
1419 * cpqhp_return_board_resources
1420 *
1421 * this routine returns all resources allocated to a board to
1422 * the available pool.
1423 *
1424 * returns 0 if success
1425 */
1426int cpqhp_return_board_resources(struct pci_func * func, struct resource_lists * resources)
1427{
1428 int rc = 0;
1429 struct pci_resource *node;
1430 struct pci_resource *t_node;
1431 dbg("%s\n", __FUNCTION__);
1432
1433 if (!func)
1434 return 1;
1435
1436 node = func->io_head;
1437 func->io_head = NULL;
1438 while (node) {
1439 t_node = node->next;
1440 return_resource(&(resources->io_head), node);
1441 node = t_node;
1442 }
1443
1444 node = func->mem_head;
1445 func->mem_head = NULL;
1446 while (node) {
1447 t_node = node->next;
1448 return_resource(&(resources->mem_head), node);
1449 node = t_node;
1450 }
1451
1452 node = func->p_mem_head;
1453 func->p_mem_head = NULL;
1454 while (node) {
1455 t_node = node->next;
1456 return_resource(&(resources->p_mem_head), node);
1457 node = t_node;
1458 }
1459
1460 node = func->bus_head;
1461 func->bus_head = NULL;
1462 while (node) {
1463 t_node = node->next;
1464 return_resource(&(resources->bus_head), node);
1465 node = t_node;
1466 }
1467
1468 rc |= cpqhp_resource_sort_and_combine(&(resources->mem_head));
1469 rc |= cpqhp_resource_sort_and_combine(&(resources->p_mem_head));
1470 rc |= cpqhp_resource_sort_and_combine(&(resources->io_head));
1471 rc |= cpqhp_resource_sort_and_combine(&(resources->bus_head));
1472
1473 return rc;
1474}
1475
1476
1477/*
1478 * cpqhp_destroy_resource_list
1479 *
1480 * Puts node back in the resource list pointed to by head
1481 */
1482void cpqhp_destroy_resource_list (struct resource_lists * resources)
1483{
1484 struct pci_resource *res, *tres;
1485
1486 res = resources->io_head;
1487 resources->io_head = NULL;
1488
1489 while (res) {
1490 tres = res;
1491 res = res->next;
1492 kfree(tres);
1493 }
1494
1495 res = resources->mem_head;
1496 resources->mem_head = NULL;
1497
1498 while (res) {
1499 tres = res;
1500 res = res->next;
1501 kfree(tres);
1502 }
1503
1504 res = resources->p_mem_head;
1505 resources->p_mem_head = NULL;
1506
1507 while (res) {
1508 tres = res;
1509 res = res->next;
1510 kfree(tres);
1511 }
1512
1513 res = resources->bus_head;
1514 resources->bus_head = NULL;
1515
1516 while (res) {
1517 tres = res;
1518 res = res->next;
1519 kfree(tres);
1520 }
1521}
1522
1523
1524/*
1525 * cpqhp_destroy_board_resources
1526 *
1527 * Puts node back in the resource list pointed to by head
1528 */
1529void cpqhp_destroy_board_resources (struct pci_func * func)
1530{
1531 struct pci_resource *res, *tres;
1532
1533 res = func->io_head;
1534 func->io_head = NULL;
1535
1536 while (res) {
1537 tres = res;
1538 res = res->next;
1539 kfree(tres);
1540 }
1541
1542 res = func->mem_head;
1543 func->mem_head = NULL;
1544
1545 while (res) {
1546 tres = res;
1547 res = res->next;
1548 kfree(tres);
1549 }
1550
1551 res = func->p_mem_head;
1552 func->p_mem_head = NULL;
1553
1554 while (res) {
1555 tres = res;
1556 res = res->next;
1557 kfree(tres);
1558 }
1559
1560 res = func->bus_head;
1561 func->bus_head = NULL;
1562
1563 while (res) {
1564 tres = res;
1565 res = res->next;
1566 kfree(tres);
1567 }
1568}
1569
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c
new file mode 100644
index 000000000000..41c7971d06c5
--- /dev/null
+++ b/drivers/pci/hotplug/cpqphp_sysfs.c
@@ -0,0 +1,143 @@
1/*
2 * Compaq Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <greg@kroah.com>
26 *
27 */
28
29#include <linux/config.h>
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/types.h>
33#include <linux/proc_fs.h>
34#include <linux/workqueue.h>
35#include <linux/pci.h>
36#include "cpqphp.h"
37
38
39/* A few routines that create sysfs entries for the hot plug controller */
40
41static ssize_t show_ctrl (struct device *dev, char *buf)
42{
43 struct pci_dev *pci_dev;
44 struct controller *ctrl;
45 char * out = buf;
46 int index;
47 struct pci_resource *res;
48
49 pci_dev = container_of (dev, struct pci_dev, dev);
50 ctrl = pci_get_drvdata(pci_dev);
51
52 out += sprintf(buf, "Free resources: memory\n");
53 index = 11;
54 res = ctrl->mem_head;
55 while (res && index--) {
56 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
57 res = res->next;
58 }
59 out += sprintf(out, "Free resources: prefetchable memory\n");
60 index = 11;
61 res = ctrl->p_mem_head;
62 while (res && index--) {
63 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
64 res = res->next;
65 }
66 out += sprintf(out, "Free resources: IO\n");
67 index = 11;
68 res = ctrl->io_head;
69 while (res && index--) {
70 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
71 res = res->next;
72 }
73 out += sprintf(out, "Free resources: bus numbers\n");
74 index = 11;
75 res = ctrl->bus_head;
76 while (res && index--) {
77 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
78 res = res->next;
79 }
80
81 return out - buf;
82}
83static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL);
84
85static ssize_t show_dev (struct device *dev, char *buf)
86{
87 struct pci_dev *pci_dev;
88 struct controller *ctrl;
89 char * out = buf;
90 int index;
91 struct pci_resource *res;
92 struct pci_func *new_slot;
93 struct slot *slot;
94
95 pci_dev = container_of (dev, struct pci_dev, dev);
96 ctrl = pci_get_drvdata(pci_dev);
97
98 slot=ctrl->slot;
99
100 while (slot) {
101 new_slot = cpqhp_slot_find(slot->bus, slot->device, 0);
102 if (!new_slot)
103 break;
104 out += sprintf(out, "assigned resources: memory\n");
105 index = 11;
106 res = new_slot->mem_head;
107 while (res && index--) {
108 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
109 res = res->next;
110 }
111 out += sprintf(out, "assigned resources: prefetchable memory\n");
112 index = 11;
113 res = new_slot->p_mem_head;
114 while (res && index--) {
115 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
116 res = res->next;
117 }
118 out += sprintf(out, "assigned resources: IO\n");
119 index = 11;
120 res = new_slot->io_head;
121 while (res && index--) {
122 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
123 res = res->next;
124 }
125 out += sprintf(out, "assigned resources: bus numbers\n");
126 index = 11;
127 res = new_slot->bus_head;
128 while (res && index--) {
129 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
130 res = res->next;
131 }
132 slot=slot->next;
133 }
134
135 return out - buf;
136}
137static DEVICE_ATTR (dev, S_IRUGO, show_dev, NULL);
138
139void cpqhp_create_ctrl_files (struct controller *ctrl)
140{
141 device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl);
142 device_create_file (&ctrl->pci_dev->dev, &dev_attr_dev);
143}
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
new file mode 100644
index 000000000000..8e47fa66e25e
--- /dev/null
+++ b/drivers/pci/hotplug/fakephp.c
@@ -0,0 +1,358 @@
1/*
2 * Fake PCI Hot Plug Controller Driver
3 *
4 * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
5 * Copyright (C) 2003 IBM Corp.
6 * Copyright (C) 2003 Rolf Eike Beer <eike-kernel@sf-tec.de>
7 *
8 * Based on ideas and code from:
9 * Vladimir Kondratiev <vladimir.kondratiev@intel.com>
10 * Rolf Eike Beer <eike-kernel@sf-tec.de>
11 *
12 * All rights reserved.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, version 2 of the License.
17 *
18 * Send feedback to <greg@kroah.com>
19 */
20
21/*
22 *
23 * This driver will "emulate" removing PCI devices from the system. If
24 * the "power" file is written to with "0" then the specified PCI device
25 * will be completely removed from the kernel.
26 *
27 * WARNING, this does NOT turn off the power to the PCI device. This is
28 * a "logical" removal, not a physical or electrical removal.
29 *
30 * Use this module at your own risk, you have been warned!
31 *
32 * Enabling PCI devices is left as an exercise for the reader...
33 *
34 */
35#include <linux/config.h>
36#include <linux/kernel.h>
37#include <linux/module.h>
38#include <linux/pci.h>
39#include <linux/init.h>
40#include "pci_hotplug.h"
41#include "../pci.h"
42
43#if !defined(MODULE)
44 #define MY_NAME "fakephp"
45#else
46 #define MY_NAME THIS_MODULE->name
47#endif
48
49#define dbg(format, arg...) \
50 do { \
51 if (debug) \
52 printk(KERN_DEBUG "%s: " format, \
53 MY_NAME , ## arg); \
54 } while (0)
55#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
56#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
57
58#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
59#define DRIVER_DESC "Fake PCI Hot Plug Controller Driver"
60
61struct dummy_slot {
62 struct list_head node;
63 struct hotplug_slot *slot;
64 struct pci_dev *dev;
65};
66
67static int debug;
68static LIST_HEAD(slot_list);
69
70static int enable_slot (struct hotplug_slot *slot);
71static int disable_slot (struct hotplug_slot *slot);
72
73static struct hotplug_slot_ops dummy_hotplug_slot_ops = {
74 .owner = THIS_MODULE,
75 .enable_slot = enable_slot,
76 .disable_slot = disable_slot,
77};
78
79static void dummy_release(struct hotplug_slot *slot)
80{
81 struct dummy_slot *dslot = slot->private;
82
83 list_del(&dslot->node);
84 kfree(dslot->slot->info);
85 kfree(dslot->slot);
86 pci_dev_put(dslot->dev);
87 kfree(dslot);
88}
89
90static int add_slot(struct pci_dev *dev)
91{
92 struct dummy_slot *dslot;
93 struct hotplug_slot *slot;
94 int retval = -ENOMEM;
95
96 slot = kmalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
97 if (!slot)
98 goto error;
99 memset(slot, 0, sizeof(*slot));
100
101 slot->info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
102 if (!slot->info)
103 goto error_slot;
104 memset(slot->info, 0, sizeof(struct hotplug_slot_info));
105
106 slot->info->power_status = 1;
107 slot->info->max_bus_speed = PCI_SPEED_UNKNOWN;
108 slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN;
109
110 slot->name = &dev->dev.bus_id[0];
111 dbg("slot->name = %s\n", slot->name);
112
113 dslot = kmalloc(sizeof(struct dummy_slot), GFP_KERNEL);
114 if (!dslot)
115 goto error_info;
116
117 slot->ops = &dummy_hotplug_slot_ops;
118 slot->release = &dummy_release;
119 slot->private = dslot;
120
121 retval = pci_hp_register(slot);
122 if (retval) {
123 err("pci_hp_register failed with error %d\n", retval);
124 goto error_dslot;
125 }
126
127 dslot->slot = slot;
128 dslot->dev = pci_dev_get(dev);
129 list_add (&dslot->node, &slot_list);
130 return retval;
131
132error_dslot:
133 kfree(dslot);
134error_info:
135 kfree(slot->info);
136error_slot:
137 kfree(slot);
138error:
139 return retval;
140}
141
142static int __init pci_scan_buses(void)
143{
144 struct pci_dev *dev = NULL;
145 int retval = 0;
146
147 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
148 retval = add_slot(dev);
149 if (retval) {
150 pci_dev_put(dev);
151 break;
152 }
153 }
154
155 return retval;
156}
157
158static void remove_slot(struct dummy_slot *dslot)
159{
160 int retval;
161
162 dbg("removing slot %s\n", dslot->slot->name);
163 retval = pci_hp_deregister(dslot->slot);
164 if (retval)
165 err("Problem unregistering a slot %s\n", dslot->slot->name);
166}
167
168/**
169 * Rescan slot.
170 * Tries hard not to re-enable already existing devices
171 * also handles scanning of subfunctions
172 *
173 * @param temp Device template. Should be set: bus and devfn.
174 */
175static void pci_rescan_slot(struct pci_dev *temp)
176{
177 struct pci_bus *bus = temp->bus;
178 struct pci_dev *dev;
179 int func;
180 u8 hdr_type;
181 if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) {
182 temp->hdr_type = hdr_type & 0x7f;
183 if (!pci_find_slot(bus->number, temp->devfn)) {
184 dev = pci_scan_single_device(bus, temp->devfn);
185 if (dev) {
186 dbg("New device on %s function %x:%x\n",
187 bus->name, temp->devfn >> 3,
188 temp->devfn & 7);
189 pci_bus_add_device(dev);
190 add_slot(dev);
191 }
192 }
193 /* multifunction device? */
194 if (!(hdr_type & 0x80))
195 return;
196
197 /* continue scanning for other functions */
198 for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) {
199 if (pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type))
200 continue;
201 temp->hdr_type = hdr_type & 0x7f;
202
203 if (!pci_find_slot(bus->number, temp->devfn)) {
204 dev = pci_scan_single_device(bus, temp->devfn);
205 if (dev) {
206 dbg("New device on %s function %x:%x\n",
207 bus->name, temp->devfn >> 3,
208 temp->devfn & 7);
209 pci_bus_add_device(dev);
210 add_slot(dev);
211 }
212 }
213 }
214 }
215}
216
217
218/**
219 * Rescan PCI bus.
220 * call pci_rescan_slot for each possible function of the bus
221 *
222 * @param bus
223 */
224static void pci_rescan_bus(const struct pci_bus *bus)
225{
226 unsigned int devfn;
227 struct pci_dev *dev;
228 dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
229 if (!dev)
230 return;
231
232 memset(dev, 0, sizeof(dev));
233 dev->bus = (struct pci_bus*)bus;
234 dev->sysdata = bus->sysdata;
235 for (devfn = 0; devfn < 0x100; devfn += 8) {
236 dev->devfn = devfn;
237 pci_rescan_slot(dev);
238 }
239 kfree(dev);
240}
241
242/* recursively scan all buses */
243static void pci_rescan_buses(const struct list_head *list)
244{
245 const struct list_head *l;
246 list_for_each(l,list) {
247 const struct pci_bus *b = pci_bus_b(l);
248 pci_rescan_bus(b);
249 pci_rescan_buses(&b->children);
250 }
251}
252
253/* initiate rescan of all pci buses */
254static inline void pci_rescan(void) {
255 pci_rescan_buses(&pci_root_buses);
256}
257
258
259static int enable_slot(struct hotplug_slot *hotplug_slot)
260{
261 /* mis-use enable_slot for rescanning of the pci bus */
262 pci_rescan();
263 return -ENODEV;
264}
265
266/* find the hotplug_slot for the pci_dev */
267static struct hotplug_slot *get_slot_from_dev(struct pci_dev *dev)
268{
269 struct dummy_slot *dslot;
270
271 list_for_each_entry(dslot, &slot_list, node) {
272 if (dslot->dev == dev)
273 return dslot->slot;
274 }
275 return NULL;
276}
277
278
279static int disable_slot(struct hotplug_slot *slot)
280{
281 struct dummy_slot *dslot;
282 struct hotplug_slot *hslot;
283 struct pci_dev *dev;
284 int func;
285
286 if (!slot)
287 return -ENODEV;
288 dslot = slot->private;
289
290 dbg("%s - physical_slot = %s\n", __FUNCTION__, slot->name);
291
292 /* don't disable bridged devices just yet, we can't handle them easily... */
293 if (dslot->dev->subordinate) {
294 err("Can't remove PCI devices with other PCI devices behind it yet.\n");
295 return -ENODEV;
296 }
297 /* search for subfunctions and disable them first */
298 if (!(dslot->dev->devfn & 7)) {
299 for (func = 1; func < 8; func++) {
300 dev = pci_find_slot(dslot->dev->bus->number,
301 dslot->dev->devfn + func);
302 if (dev) {
303 hslot = get_slot_from_dev(dev);
304 if (hslot)
305 disable_slot(hslot);
306 else {
307 err("Hotplug slot not found for subfunction of PCI device\n");
308 return -ENODEV;
309 }
310 } else
311 dbg("No device in slot found\n");
312 }
313 }
314
315 /* remove the device from the pci core */
316 pci_remove_bus_device(dslot->dev);
317
318 /* blow away this sysfs entry and other parts. */
319 remove_slot(dslot);
320
321 return 0;
322}
323
324static void cleanup_slots (void)
325{
326 struct list_head *tmp;
327 struct list_head *next;
328 struct dummy_slot *dslot;
329
330 list_for_each_safe (tmp, next, &slot_list) {
331 dslot = list_entry (tmp, struct dummy_slot, node);
332 remove_slot(dslot);
333 }
334
335}
336
337static int __init dummyphp_init(void)
338{
339 info(DRIVER_DESC "\n");
340
341 return pci_scan_buses();
342}
343
344
345static void __exit dummyphp_exit(void)
346{
347 cleanup_slots();
348}
349
350module_init(dummyphp_init);
351module_exit(dummyphp_exit);
352
353MODULE_AUTHOR(DRIVER_AUTHOR);
354MODULE_DESCRIPTION(DRIVER_DESC);
355MODULE_LICENSE("GPL");
356module_param(debug, bool, S_IRUGO | S_IWUSR);
357MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
358
diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h
new file mode 100644
index 000000000000..5bc039da647f
--- /dev/null
+++ b/drivers/pci/hotplug/ibmphp.h
@@ -0,0 +1,763 @@
1#ifndef __IBMPHP_H
2#define __IBMPHP_H
3
4/*
5 * IBM Hot Plug Controller Driver
6 *
7 * Written By: Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation
8 *
9 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
10 * Copyright (C) 2001-2003 IBM Corp.
11 *
12 * All rights reserved.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or (at
17 * your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
22 * NON INFRINGEMENT. See the GNU General Public License for more
23 * details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 *
29 * Send feedback to <gregkh@us.ibm.com>
30 *
31 */
32
33#include "pci_hotplug.h"
34
35extern int ibmphp_debug;
36
37#if !defined(MODULE)
38 #define MY_NAME "ibmphpd"
39#else
40 #define MY_NAME THIS_MODULE->name
41#endif
42#define debug(fmt, arg...) do { if (ibmphp_debug == 1) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
43#define debug_pci(fmt, arg...) do { if (ibmphp_debug) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
44#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
45#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
46#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
47
48
49/* EBDA stuff */
50
51/***********************************************************
52* SLOT CAPABILITY *
53***********************************************************/
54
55#define EBDA_SLOT_133_MAX 0x20
56#define EBDA_SLOT_100_MAX 0x10
57#define EBDA_SLOT_66_MAX 0x02
58#define EBDA_SLOT_PCIX_CAP 0x08
59
60
61/************************************************************
62* RESOURE TYPE *
63************************************************************/
64
65#define EBDA_RSRC_TYPE_MASK 0x03
66#define EBDA_IO_RSRC_TYPE 0x00
67#define EBDA_MEM_RSRC_TYPE 0x01
68#define EBDA_PFM_RSRC_TYPE 0x03
69#define EBDA_RES_RSRC_TYPE 0x02
70
71
72/*************************************************************
73* IO RESTRICTION TYPE *
74*************************************************************/
75
76#define EBDA_IO_RESTRI_MASK 0x0c
77#define EBDA_NO_RESTRI 0x00
78#define EBDA_AVO_VGA_ADDR 0x04
79#define EBDA_AVO_VGA_ADDR_AND_ALIA 0x08
80#define EBDA_AVO_ISA_ADDR 0x0c
81
82
83/**************************************************************
84* DEVICE TYPE DEF *
85**************************************************************/
86
87#define EBDA_DEV_TYPE_MASK 0x10
88#define EBDA_PCI_DEV 0x10
89#define EBDA_NON_PCI_DEV 0x00
90
91
92/***************************************************************
93* PRIMARY DEF DEFINITION *
94***************************************************************/
95
96#define EBDA_PRI_DEF_MASK 0x20
97#define EBDA_PRI_PCI_BUS_INFO 0x20
98#define EBDA_NORM_DEV_RSRC_INFO 0x00
99
100
101//--------------------------------------------------------------
102// RIO TABLE DATA STRUCTURE
103//--------------------------------------------------------------
104
105struct rio_table_hdr {
106 u8 ver_num;
107 u8 scal_count;
108 u8 riodev_count;
109 u16 offset;
110};
111
112//-------------------------------------------------------------
113// SCALABILITY DETAIL
114//-------------------------------------------------------------
115
116struct scal_detail {
117 u8 node_id;
118 u32 cbar;
119 u8 port0_node_connect;
120 u8 port0_port_connect;
121 u8 port1_node_connect;
122 u8 port1_port_connect;
123 u8 port2_node_connect;
124 u8 port2_port_connect;
125 u8 chassis_num;
126// struct list_head scal_detail_list;
127};
128
129//--------------------------------------------------------------
130// RIO DETAIL
131//--------------------------------------------------------------
132
133struct rio_detail {
134 u8 rio_node_id;
135 u32 bbar;
136 u8 rio_type;
137 u8 owner_id;
138 u8 port0_node_connect;
139 u8 port0_port_connect;
140 u8 port1_node_connect;
141 u8 port1_port_connect;
142 u8 first_slot_num;
143 u8 status;
144 u8 wpindex;
145 u8 chassis_num;
146 struct list_head rio_detail_list;
147};
148
149struct opt_rio {
150 u8 rio_type;
151 u8 chassis_num;
152 u8 first_slot_num;
153 u8 middle_num;
154 struct list_head opt_rio_list;
155};
156
157struct opt_rio_lo {
158 u8 rio_type;
159 u8 chassis_num;
160 u8 first_slot_num;
161 u8 middle_num;
162 u8 pack_count;
163 struct list_head opt_rio_lo_list;
164};
165
166/****************************************************************
167* HPC DESCRIPTOR NODE *
168****************************************************************/
169
170struct ebda_hpc_list {
171 u8 format;
172 u16 num_ctlrs;
173 short phys_addr;
174// struct list_head ebda_hpc_list;
175};
176/*****************************************************************
177* IN HPC DATA STRUCTURE, THE ASSOCIATED SLOT AND BUS *
178* STRUCTURE *
179*****************************************************************/
180
181struct ebda_hpc_slot {
182 u8 slot_num;
183 u32 slot_bus_num;
184 u8 ctl_index;
185 u8 slot_cap;
186};
187
188struct ebda_hpc_bus {
189 u32 bus_num;
190 u8 slots_at_33_conv;
191 u8 slots_at_66_conv;
192 u8 slots_at_66_pcix;
193 u8 slots_at_100_pcix;
194 u8 slots_at_133_pcix;
195};
196
197
198/********************************************************************
199* THREE TYPE OF HOT PLUG CONTROLER *
200********************************************************************/
201
202struct isa_ctlr_access {
203 u16 io_start;
204 u16 io_end;
205};
206
207struct pci_ctlr_access {
208 u8 bus;
209 u8 dev_fun;
210};
211
212struct wpeg_i2c_ctlr_access {
213 ulong wpegbbar;
214 u8 i2c_addr;
215};
216
217#define HPC_DEVICE_ID 0x0246
218#define HPC_SUBSYSTEM_ID 0x0247
219#define HPC_PCI_OFFSET 0x40
220/*************************************************************************
221* RSTC DESCRIPTOR NODE *
222*************************************************************************/
223
224struct ebda_rsrc_list {
225 u8 format;
226 u16 num_entries;
227 u16 phys_addr;
228 struct ebda_rsrc_list *next;
229};
230
231
232/***************************************************************************
233* PCI RSRC NODE *
234***************************************************************************/
235
236struct ebda_pci_rsrc {
237 u8 rsrc_type;
238 u8 bus_num;
239 u8 dev_fun;
240 u32 start_addr;
241 u32 end_addr;
242 u8 marked; /* for NVRAM */
243 struct list_head ebda_pci_rsrc_list;
244};
245
246
247/***********************************************************
248* BUS_INFO DATE STRUCTURE *
249***********************************************************/
250
251struct bus_info {
252 u8 slot_min;
253 u8 slot_max;
254 u8 slot_count;
255 u8 busno;
256 u8 controller_id;
257 u8 current_speed;
258 u8 current_bus_mode;
259 u8 index;
260 u8 slots_at_33_conv;
261 u8 slots_at_66_conv;
262 u8 slots_at_66_pcix;
263 u8 slots_at_100_pcix;
264 u8 slots_at_133_pcix;
265 struct list_head bus_info_list;
266};
267
268
269/***********************************************************
270* GLOBAL VARIABLES *
271***********************************************************/
272extern struct list_head ibmphp_ebda_pci_rsrc_head;
273extern struct list_head ibmphp_slot_head;
274/***********************************************************
275* FUNCTION PROTOTYPES *
276***********************************************************/
277
278extern void ibmphp_free_ebda_hpc_queue (void);
279extern int ibmphp_access_ebda (void);
280extern struct slot *ibmphp_get_slot_from_physical_num (u8);
281extern int ibmphp_get_total_hp_slots (void);
282extern void ibmphp_free_ibm_slot (struct slot *);
283extern void ibmphp_free_bus_info_queue (void);
284extern void ibmphp_free_ebda_pci_rsrc_queue (void);
285extern struct bus_info *ibmphp_find_same_bus_num (u32);
286extern int ibmphp_get_bus_index (u8);
287extern u16 ibmphp_get_total_controllers (void);
288extern int ibmphp_register_pci (void);
289
290/* passed parameters */
291#define MEM 0
292#define IO 1
293#define PFMEM 2
294
295/* bit masks */
296#define RESTYPE 0x03
297#define IOMASK 0x00 /* will need to take its complement */
298#define MMASK 0x01
299#define PFMASK 0x03
300#define PCIDEVMASK 0x10 /* we should always have PCI devices */
301#define PRIMARYBUSMASK 0x20
302
303/* pci specific defines */
304#define PCI_VENDOR_ID_NOTVALID 0xFFFF
305#define PCI_HEADER_TYPE_MULTIDEVICE 0x80
306#define PCI_HEADER_TYPE_MULTIBRIDGE 0x81
307
308#define LATENCY 0x64
309#define CACHE 64
310#define DEVICEENABLE 0x015F /* CPQ has 0x0157 */
311
312#define IOBRIDGE 0x1000 /* 4k */
313#define MEMBRIDGE 0x100000 /* 1M */
314
315/* irqs */
316#define SCSI_IRQ 0x09
317#define LAN_IRQ 0x0A
318#define OTHER_IRQ 0x0B
319
320/* Data Structures */
321
322/* type is of the form x x xx xx
323 * | | | |_ 00 - I/O, 01 - Memory, 11 - PFMemory
324 * | | - 00 - No Restrictions, 01 - Avoid VGA, 10 - Avoid
325 * | | VGA and their aliases, 11 - Avoid ISA
326 * | - 1 - PCI device, 0 - non pci device
327 * - 1 - Primary PCI Bus Information (0 if Normal device)
328 * the IO restrictions [2:3] are only for primary buses
329 */
330
331
332/* we need this struct because there could be several resource blocks
333 * allocated per primary bus in the EBDA
334 */
335struct range_node {
336 int rangeno;
337 u32 start;
338 u32 end;
339 struct range_node *next;
340};
341
342struct bus_node {
343 u8 busno;
344 int noIORanges;
345 struct range_node *rangeIO;
346 int noMemRanges;
347 struct range_node *rangeMem;
348 int noPFMemRanges;
349 struct range_node *rangePFMem;
350 int needIOUpdate;
351 int needMemUpdate;
352 int needPFMemUpdate;
353 struct resource_node *firstIO; /* first IO resource on the Bus */
354 struct resource_node *firstMem; /* first memory resource on the Bus */
355 struct resource_node *firstPFMem; /* first prefetchable memory resource on the Bus */
356 struct resource_node *firstPFMemFromMem; /* when run out of pfmem available, taking from Mem */
357 struct list_head bus_list;
358};
359
360struct resource_node {
361 int rangeno;
362 u8 busno;
363 u8 devfunc;
364 u32 start;
365 u32 end;
366 u32 len;
367 int type; /* MEM, IO, PFMEM */
368 u8 fromMem; /* this is to indicate that the range is from
369 * from the Memory bucket rather than from PFMem */
370 struct resource_node *next;
371 struct resource_node *nextRange; /* for the other mem range on bus */
372};
373
374struct res_needed {
375 u32 mem;
376 u32 pfmem;
377 u32 io;
378 u8 not_correct; /* needed for return */
379 int devices[32]; /* for device numbers behind this bridge */
380};
381
382/* functions */
383
384extern int ibmphp_rsrc_init (void);
385extern int ibmphp_add_resource (struct resource_node *);
386extern int ibmphp_remove_resource (struct resource_node *);
387extern int ibmphp_find_resource (struct bus_node *, u32, struct resource_node **, int);
388extern int ibmphp_check_resource (struct resource_node *, u8);
389extern int ibmphp_remove_bus (struct bus_node *, u8);
390extern void ibmphp_free_resources (void);
391extern int ibmphp_add_pfmem_from_mem (struct resource_node *);
392extern struct bus_node *ibmphp_find_res_bus (u8);
393extern void ibmphp_print_test (void); /* for debugging purposes */
394
395extern void ibmphp_hpc_initvars (void);
396extern int ibmphp_hpc_readslot (struct slot *, u8, u8 *);
397extern int ibmphp_hpc_writeslot (struct slot *, u8);
398extern void ibmphp_lock_operations (void);
399extern void ibmphp_unlock_operations (void);
400extern int ibmphp_hpc_start_poll_thread (void);
401extern void ibmphp_hpc_stop_poll_thread (void);
402
403//----------------------------------------------------------------------------
404
405
406//----------------------------------------------------------------------------
407// HPC return codes
408//----------------------------------------------------------------------------
409#define FALSE 0x00
410#define TRUE 0x01
411#define HPC_ERROR 0xFF
412
413//-----------------------------------------------------------------------------
414// BUS INFO
415//-----------------------------------------------------------------------------
416#define BUS_SPEED 0x30
417#define BUS_MODE 0x40
418#define BUS_MODE_PCIX 0x01
419#define BUS_MODE_PCI 0x00
420#define BUS_SPEED_2 0x20
421#define BUS_SPEED_1 0x10
422#define BUS_SPEED_33 0x00
423#define BUS_SPEED_66 0x01
424#define BUS_SPEED_100 0x02
425#define BUS_SPEED_133 0x03
426#define BUS_SPEED_66PCIX 0x04
427#define BUS_SPEED_66UNKNOWN 0x05
428#define BUS_STATUS_AVAILABLE 0x01
429#define BUS_CONTROL_AVAILABLE 0x02
430#define SLOT_LATCH_REGS_SUPPORTED 0x10
431
432#define PRGM_MODEL_REV_LEVEL 0xF0
433#define MAX_ADAPTER_NONE 0x09
434
435//----------------------------------------------------------------------------
436// HPC 'write' operations/commands
437//----------------------------------------------------------------------------
438// Command Code State Write to reg
439// Machine at index
440//------------------------- ---- ------- ------------
441#define HPC_CTLR_ENABLEIRQ 0x00 // N 15
442#define HPC_CTLR_DISABLEIRQ 0x01 // N 15
443#define HPC_SLOT_OFF 0x02 // Y 0-14
444#define HPC_SLOT_ON 0x03 // Y 0-14
445#define HPC_SLOT_ATTNOFF 0x04 // N 0-14
446#define HPC_SLOT_ATTNON 0x05 // N 0-14
447#define HPC_CTLR_CLEARIRQ 0x06 // N 15
448#define HPC_CTLR_RESET 0x07 // Y 15
449#define HPC_CTLR_IRQSTEER 0x08 // N 15
450#define HPC_BUS_33CONVMODE 0x09 // Y 31-34
451#define HPC_BUS_66CONVMODE 0x0A // Y 31-34
452#define HPC_BUS_66PCIXMODE 0x0B // Y 31-34
453#define HPC_BUS_100PCIXMODE 0x0C // Y 31-34
454#define HPC_BUS_133PCIXMODE 0x0D // Y 31-34
455#define HPC_ALLSLOT_OFF 0x11 // Y 15
456#define HPC_ALLSLOT_ON 0x12 // Y 15
457#define HPC_SLOT_BLINKLED 0x13 // N 0-14
458
459//----------------------------------------------------------------------------
460// read commands
461//----------------------------------------------------------------------------
462#define READ_SLOTSTATUS 0x01
463#define READ_EXTSLOTSTATUS 0x02
464#define READ_BUSSTATUS 0x03
465#define READ_CTLRSTATUS 0x04
466#define READ_ALLSTAT 0x05
467#define READ_ALLSLOT 0x06
468#define READ_SLOTLATCHLOWREG 0x07
469#define READ_REVLEVEL 0x08
470#define READ_HPCOPTIONS 0x09
471//----------------------------------------------------------------------------
472// slot status
473//----------------------------------------------------------------------------
474#define HPC_SLOT_POWER 0x01
475#define HPC_SLOT_CONNECT 0x02
476#define HPC_SLOT_ATTN 0x04
477#define HPC_SLOT_PRSNT2 0x08
478#define HPC_SLOT_PRSNT1 0x10
479#define HPC_SLOT_PWRGD 0x20
480#define HPC_SLOT_BUS_SPEED 0x40
481#define HPC_SLOT_LATCH 0x80
482
483//----------------------------------------------------------------------------
484// HPC_SLOT_POWER status return codes
485//----------------------------------------------------------------------------
486#define HPC_SLOT_POWER_OFF 0x00
487#define HPC_SLOT_POWER_ON 0x01
488
489//----------------------------------------------------------------------------
490// HPC_SLOT_CONNECT status return codes
491//----------------------------------------------------------------------------
492#define HPC_SLOT_CONNECTED 0x00
493#define HPC_SLOT_DISCONNECTED 0x01
494
495//----------------------------------------------------------------------------
496// HPC_SLOT_ATTN status return codes
497//----------------------------------------------------------------------------
498#define HPC_SLOT_ATTN_OFF 0x00
499#define HPC_SLOT_ATTN_ON 0x01
500#define HPC_SLOT_ATTN_BLINK 0x02
501
502//----------------------------------------------------------------------------
503// HPC_SLOT_PRSNT status return codes
504//----------------------------------------------------------------------------
505#define HPC_SLOT_EMPTY 0x00
506#define HPC_SLOT_PRSNT_7 0x01
507#define HPC_SLOT_PRSNT_15 0x02
508#define HPC_SLOT_PRSNT_25 0x03
509
510//----------------------------------------------------------------------------
511// HPC_SLOT_PWRGD status return codes
512//----------------------------------------------------------------------------
513#define HPC_SLOT_PWRGD_FAULT_NONE 0x00
514#define HPC_SLOT_PWRGD_GOOD 0x01
515
516//----------------------------------------------------------------------------
517// HPC_SLOT_BUS_SPEED status return codes
518//----------------------------------------------------------------------------
519#define HPC_SLOT_BUS_SPEED_OK 0x00
520#define HPC_SLOT_BUS_SPEED_MISM 0x01
521
522//----------------------------------------------------------------------------
523// HPC_SLOT_LATCH status return codes
524//----------------------------------------------------------------------------
525#define HPC_SLOT_LATCH_OPEN 0x01 // NOTE : in PCI spec bit off = open
526#define HPC_SLOT_LATCH_CLOSED 0x00 // NOTE : in PCI spec bit on = closed
527
528
529//----------------------------------------------------------------------------
530// extended slot status
531//----------------------------------------------------------------------------
532#define HPC_SLOT_PCIX 0x01
533#define HPC_SLOT_SPEED1 0x02
534#define HPC_SLOT_SPEED2 0x04
535#define HPC_SLOT_BLINK_ATTN 0x08
536#define HPC_SLOT_RSRVD1 0x10
537#define HPC_SLOT_RSRVD2 0x20
538#define HPC_SLOT_BUS_MODE 0x40
539#define HPC_SLOT_RSRVD3 0x80
540
541//----------------------------------------------------------------------------
542// HPC_XSLOT_PCIX_CAP status return codes
543//----------------------------------------------------------------------------
544#define HPC_SLOT_PCIX_NO 0x00
545#define HPC_SLOT_PCIX_YES 0x01
546
547//----------------------------------------------------------------------------
548// HPC_XSLOT_SPEED status return codes
549//----------------------------------------------------------------------------
550#define HPC_SLOT_SPEED_33 0x00
551#define HPC_SLOT_SPEED_66 0x01
552#define HPC_SLOT_SPEED_133 0x02
553
554//----------------------------------------------------------------------------
555// HPC_XSLOT_ATTN_BLINK status return codes
556//----------------------------------------------------------------------------
557#define HPC_SLOT_ATTN_BLINK_OFF 0x00
558#define HPC_SLOT_ATTN_BLINK_ON 0x01
559
560//----------------------------------------------------------------------------
561// HPC_XSLOT_BUS_MODE status return codes
562//----------------------------------------------------------------------------
563#define HPC_SLOT_BUS_MODE_OK 0x00
564#define HPC_SLOT_BUS_MODE_MISM 0x01
565
566//----------------------------------------------------------------------------
567// Controller status
568//----------------------------------------------------------------------------
569#define HPC_CTLR_WORKING 0x01
570#define HPC_CTLR_FINISHED 0x02
571#define HPC_CTLR_RESULT0 0x04
572#define HPC_CTLR_RESULT1 0x08
573#define HPC_CTLR_RESULE2 0x10
574#define HPC_CTLR_RESULT3 0x20
575#define HPC_CTLR_IRQ_ROUTG 0x40
576#define HPC_CTLR_IRQ_PENDG 0x80
577
578//----------------------------------------------------------------------------
579// HPC_CTLR_WROKING status return codes
580//----------------------------------------------------------------------------
581#define HPC_CTLR_WORKING_NO 0x00
582#define HPC_CTLR_WORKING_YES 0x01
583
584//----------------------------------------------------------------------------
585// HPC_CTLR_FINISHED status return codes
586//----------------------------------------------------------------------------
587#define HPC_CTLR_FINISHED_NO 0x00
588#define HPC_CTLR_FINISHED_YES 0x01
589
590//----------------------------------------------------------------------------
591// HPC_CTLR_RESULT status return codes
592//----------------------------------------------------------------------------
593#define HPC_CTLR_RESULT_SUCCESS 0x00
594#define HPC_CTLR_RESULT_FAILED 0x01
595#define HPC_CTLR_RESULT_RSVD 0x02
596#define HPC_CTLR_RESULT_NORESP 0x03
597
598
599//----------------------------------------------------------------------------
600// macro for slot info
601//----------------------------------------------------------------------------
602#define SLOT_POWER(s) ((u8) ((s & HPC_SLOT_POWER) \
603 ? HPC_SLOT_POWER_ON : HPC_SLOT_POWER_OFF))
604
605#define SLOT_CONNECT(s) ((u8) ((s & HPC_SLOT_CONNECT) \
606 ? HPC_SLOT_DISCONNECTED : HPC_SLOT_CONNECTED))
607
608#define SLOT_ATTN(s,es) ((u8) ((es & HPC_SLOT_BLINK_ATTN) \
609 ? HPC_SLOT_ATTN_BLINK \
610 : ((s & HPC_SLOT_ATTN) ? HPC_SLOT_ATTN_ON : HPC_SLOT_ATTN_OFF)))
611
612#define SLOT_PRESENT(s) ((u8) ((s & HPC_SLOT_PRSNT1) \
613 ? ((s & HPC_SLOT_PRSNT2) ? HPC_SLOT_EMPTY : HPC_SLOT_PRSNT_15) \
614 : ((s & HPC_SLOT_PRSNT2) ? HPC_SLOT_PRSNT_25 : HPC_SLOT_PRSNT_7)))
615
616#define SLOT_PWRGD(s) ((u8) ((s & HPC_SLOT_PWRGD) \
617 ? HPC_SLOT_PWRGD_GOOD : HPC_SLOT_PWRGD_FAULT_NONE))
618
619#define SLOT_BUS_SPEED(s) ((u8) ((s & HPC_SLOT_BUS_SPEED) \
620 ? HPC_SLOT_BUS_SPEED_MISM : HPC_SLOT_BUS_SPEED_OK))
621
622#define SLOT_LATCH(s) ((u8) ((s & HPC_SLOT_LATCH) \
623 ? HPC_SLOT_LATCH_CLOSED : HPC_SLOT_LATCH_OPEN))
624
625#define SLOT_PCIX(es) ((u8) ((es & HPC_SLOT_PCIX) \
626 ? HPC_SLOT_PCIX_YES : HPC_SLOT_PCIX_NO))
627
628#define SLOT_SPEED(es) ((u8) ((es & HPC_SLOT_SPEED2) \
629 ? ((es & HPC_SLOT_SPEED1) ? HPC_SLOT_SPEED_133 \
630 : HPC_SLOT_SPEED_66) \
631 : HPC_SLOT_SPEED_33))
632
633#define SLOT_BUS_MODE(es) ((u8) ((es & HPC_SLOT_BUS_MODE) \
634 ? HPC_SLOT_BUS_MODE_MISM : HPC_SLOT_BUS_MODE_OK))
635
636//--------------------------------------------------------------------------
637// macro for bus info
638//---------------------------------------------------------------------------
639#define CURRENT_BUS_SPEED(s) ((u8) (s & BUS_SPEED_2) \
640 ? ((s & BUS_SPEED_1) ? BUS_SPEED_133 : BUS_SPEED_100) \
641 : ((s & BUS_SPEED_1) ? BUS_SPEED_66 : BUS_SPEED_33))
642
643#define CURRENT_BUS_MODE(s) ((u8) (s & BUS_MODE) ? BUS_MODE_PCIX : BUS_MODE_PCI)
644
645#define READ_BUS_STATUS(s) ((u8) (s->options & BUS_STATUS_AVAILABLE))
646
647#define READ_BUS_MODE(s) ((s->revision & PRGM_MODEL_REV_LEVEL) >= 0x20)
648
649#define SET_BUS_STATUS(s) ((u8) (s->options & BUS_CONTROL_AVAILABLE))
650
651#define READ_SLOT_LATCH(s) ((u8) (s->options & SLOT_LATCH_REGS_SUPPORTED))
652
653//----------------------------------------------------------------------------
654// macro for controller info
655//----------------------------------------------------------------------------
656#define CTLR_WORKING(c) ((u8) ((c & HPC_CTLR_WORKING) \
657 ? HPC_CTLR_WORKING_YES : HPC_CTLR_WORKING_NO))
658#define CTLR_FINISHED(c) ((u8) ((c & HPC_CTLR_FINISHED) \
659 ? HPC_CTLR_FINISHED_YES : HPC_CTLR_FINISHED_NO))
660#define CTLR_RESULT(c) ((u8) ((c & HPC_CTLR_RESULT1) \
661 ? ((c & HPC_CTLR_RESULT0) ? HPC_CTLR_RESULT_NORESP \
662 : HPC_CTLR_RESULT_RSVD) \
663 : ((c & HPC_CTLR_RESULT0) ? HPC_CTLR_RESULT_FAILED \
664 : HPC_CTLR_RESULT_SUCCESS)))
665
666// command that affect the state machine of HPC
667#define NEEDTOCHECK_CMDSTATUS(c) ((c == HPC_SLOT_OFF) || \
668 (c == HPC_SLOT_ON) || \
669 (c == HPC_CTLR_RESET) || \
670 (c == HPC_BUS_33CONVMODE) || \
671 (c == HPC_BUS_66CONVMODE) || \
672 (c == HPC_BUS_66PCIXMODE) || \
673 (c == HPC_BUS_100PCIXMODE) || \
674 (c == HPC_BUS_133PCIXMODE) || \
675 (c == HPC_ALLSLOT_OFF) || \
676 (c == HPC_ALLSLOT_ON))
677
678
679/* Core part of the driver */
680
681#define ENABLE 1
682#define DISABLE 0
683
684#define CARD_INFO 0x07
685#define PCIX133 0x07
686#define PCIX66 0x05
687#define PCI66 0x04
688
689extern struct pci_bus *ibmphp_pci_bus;
690
691/* Variables */
692
693struct pci_func {
694 struct pci_dev *dev; /* from the OS */
695 u8 busno;
696 u8 device;
697 u8 function;
698 struct resource_node *io[6];
699 struct resource_node *mem[6];
700 struct resource_node *pfmem[6];
701 struct pci_func *next;
702 int devices[32]; /* for bridge config */
703 u8 irq[4]; /* for interrupt config */
704 u8 bus; /* flag for unconfiguring, to say if PPB */
705};
706
707struct slot {
708 u8 bus;
709 u8 device;
710 u8 number;
711 u8 real_physical_slot_num;
712 char name[100];
713 u32 capabilities;
714 u8 supported_speed;
715 u8 supported_bus_mode;
716 struct hotplug_slot *hotplug_slot;
717 struct controller *ctrl;
718 struct pci_func *func;
719 u8 irq[4];
720 u8 flag; /* this is for disable slot and polling */
721 int bit_mode; /* 0 = 32, 1 = 64 */
722 u8 ctlr_index;
723 struct bus_info *bus_on;
724 struct list_head ibm_slot_list;
725 u8 status;
726 u8 ext_status;
727 u8 busstatus;
728};
729
730struct controller {
731 struct ebda_hpc_slot *slots;
732 struct ebda_hpc_bus *buses;
733 struct pci_dev *ctrl_dev; /* in case where controller is PCI */
734 u8 starting_slot_num; /* starting and ending slot #'s this ctrl controls*/
735 u8 ending_slot_num;
736 u8 revision;
737 u8 options; /* which options HPC supports */
738 u8 status;
739 u8 ctlr_id;
740 u8 slot_count;
741 u8 bus_count;
742 u8 ctlr_relative_id;
743 u32 irq;
744 union {
745 struct isa_ctlr_access isa_ctlr;
746 struct pci_ctlr_access pci_ctlr;
747 struct wpeg_i2c_ctlr_access wpeg_ctlr;
748 } u;
749 u8 ctlr_type;
750 struct list_head ebda_hpc_list;
751};
752
753/* Functions */
754
755extern int ibmphp_init_devno (struct slot **); /* This function is called from EBDA, so we need it not be static */
756extern int ibmphp_do_disable_slot (struct slot *slot_cur);
757extern int ibmphp_update_slot_info (struct slot *); /* This function is called from HPC, so we need it to not be be static */
758extern int ibmphp_configure_card (struct pci_func *, u8);
759extern int ibmphp_unconfigure_card (struct slot **, int);
760extern struct hotplug_slot_ops ibmphp_hotplug_slot_ops;
761
762#endif //__IBMPHP_H
763
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
new file mode 100644
index 000000000000..0392e004258f
--- /dev/null
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -0,0 +1,1422 @@
1/*
2 * IBM Hot Plug Controller Driver
3 *
4 * Written By: Chuck Cole, Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation
5 *
6 * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
7 * Copyright (C) 2001-2003 IBM Corp.
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <gregkh@us.ibm.com>
27 *
28 */
29
30#include <linux/init.h>
31#include <linux/module.h>
32#include <linux/slab.h>
33#include <linux/pci.h>
34#include <linux/interrupt.h>
35#include <linux/delay.h>
36#include <linux/wait.h>
37#include <linux/smp_lock.h>
38#include "../pci.h"
39#include "../../../arch/i386/pci/pci.h" /* for struct irq_routing_table */
40#include "ibmphp.h"
41
42#define attn_on(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNON)
43#define attn_off(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNOFF)
44#define attn_LED_blink(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_BLINKLED)
45#define get_ctrl_revision(sl, rev) ibmphp_hpc_readslot (sl, READ_REVLEVEL, rev)
46#define get_hpc_options(sl, opt) ibmphp_hpc_readslot (sl, READ_HPCOPTIONS, opt)
47
48#define DRIVER_VERSION "0.6"
49#define DRIVER_DESC "IBM Hot Plug PCI Controller Driver"
50
51int ibmphp_debug;
52
53static int debug;
54module_param(debug, bool, S_IRUGO | S_IWUSR);
55MODULE_PARM_DESC (debug, "Debugging mode enabled or not");
56MODULE_LICENSE ("GPL");
57MODULE_DESCRIPTION (DRIVER_DESC);
58
59struct pci_bus *ibmphp_pci_bus;
60static int max_slots;
61
62static int irqs[16]; /* PIC mode IRQ's we're using so far (in case MPS
63 * tables don't provide default info for empty slots */
64
65static int init_flag;
66
67/*
68static int get_max_adapter_speed_1 (struct hotplug_slot *, u8 *, u8);
69
70static inline int get_max_adapter_speed (struct hotplug_slot *hs, u8 *value)
71{
72 return get_max_adapter_speed_1 (hs, value, 1);
73}
74*/
75static inline int get_cur_bus_info(struct slot **sl)
76{
77 int rc = 1;
78 struct slot * slot_cur = *sl;
79
80 debug("options = %x\n", slot_cur->ctrl->options);
81 debug("revision = %x\n", slot_cur->ctrl->revision);
82
83 if (READ_BUS_STATUS(slot_cur->ctrl))
84 rc = ibmphp_hpc_readslot(slot_cur, READ_BUSSTATUS, NULL);
85
86 if (rc)
87 return rc;
88
89 slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED(slot_cur->busstatus);
90 if (READ_BUS_MODE(slot_cur->ctrl))
91 slot_cur->bus_on->current_bus_mode =
92 CURRENT_BUS_MODE(slot_cur->busstatus);
93 else
94 slot_cur->bus_on->current_bus_mode = 0xFF;
95
96 debug("busstatus = %x, bus_speed = %x, bus_mode = %x\n",
97 slot_cur->busstatus,
98 slot_cur->bus_on->current_speed,
99 slot_cur->bus_on->current_bus_mode);
100
101 *sl = slot_cur;
102 return 0;
103}
104
105static inline int slot_update(struct slot **sl)
106{
107 int rc;
108 rc = ibmphp_hpc_readslot(*sl, READ_ALLSTAT, NULL);
109 if (rc)
110 return rc;
111 if (!init_flag)
112 rc = get_cur_bus_info(sl);
113 return rc;
114}
115
116static int __init get_max_slots (void)
117{
118 struct slot * slot_cur;
119 struct list_head * tmp;
120 u8 slot_count = 0;
121
122 list_for_each(tmp, &ibmphp_slot_head) {
123 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
124 /* sometimes the hot-pluggable slots start with 4 (not always from 1) */
125 slot_count = max(slot_count, slot_cur->number);
126 }
127 return slot_count;
128}
129
130/* This routine will put the correct slot->device information per slot. It's
131 * called from initialization of the slot structures. It will also assign
132 * interrupt numbers per each slot.
133 * Parameters: struct slot
134 * Returns 0 or errors
135 */
136int ibmphp_init_devno(struct slot **cur_slot)
137{
138 struct irq_routing_table *rtable;
139 int len;
140 int loop;
141 int i;
142
143 rtable = pcibios_get_irq_routing_table();
144 if (!rtable) {
145 err("no BIOS routing table...\n");
146 return -ENOMEM;
147 }
148
149 len = (rtable->size - sizeof(struct irq_routing_table)) /
150 sizeof(struct irq_info);
151
152 if (!len)
153 return -1;
154 for (loop = 0; loop < len; loop++) {
155 if ((*cur_slot)->number == rtable->slots[loop].slot) {
156 if ((*cur_slot)->bus == rtable->slots[loop].bus) {
157 (*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn);
158 for (i = 0; i < 4; i++)
159 (*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus,
160 (int) (*cur_slot)->device, i);
161
162 debug("(*cur_slot)->irq[0] = %x\n",
163 (*cur_slot)->irq[0]);
164 debug("(*cur_slot)->irq[1] = %x\n",
165 (*cur_slot)->irq[1]);
166 debug("(*cur_slot)->irq[2] = %x\n",
167 (*cur_slot)->irq[2]);
168 debug("(*cur_slot)->irq[3] = %x\n",
169 (*cur_slot)->irq[3]);
170
171 debug("rtable->exlusive_irqs = %x\n",
172 rtable->exclusive_irqs);
173 debug("rtable->slots[loop].irq[0].bitmap = %x\n",
174 rtable->slots[loop].irq[0].bitmap);
175 debug("rtable->slots[loop].irq[1].bitmap = %x\n",
176 rtable->slots[loop].irq[1].bitmap);
177 debug("rtable->slots[loop].irq[2].bitmap = %x\n",
178 rtable->slots[loop].irq[2].bitmap);
179 debug("rtable->slots[loop].irq[3].bitmap = %x\n",
180 rtable->slots[loop].irq[3].bitmap);
181
182 debug("rtable->slots[loop].irq[0].link = %x\n",
183 rtable->slots[loop].irq[0].link);
184 debug("rtable->slots[loop].irq[1].link = %x\n",
185 rtable->slots[loop].irq[1].link);
186 debug("rtable->slots[loop].irq[2].link = %x\n",
187 rtable->slots[loop].irq[2].link);
188 debug("rtable->slots[loop].irq[3].link = %x\n",
189 rtable->slots[loop].irq[3].link);
190 debug("end of init_devno\n");
191 return 0;
192 }
193 }
194 }
195
196 return -1;
197}
198
199static inline int power_on(struct slot *slot_cur)
200{
201 u8 cmd = HPC_SLOT_ON;
202 int retval;
203
204 retval = ibmphp_hpc_writeslot(slot_cur, cmd);
205 if (retval) {
206 err("power on failed\n");
207 return retval;
208 }
209 if (CTLR_RESULT(slot_cur->ctrl->status)) {
210 err("command not completed successfully in power_on\n");
211 return -EIO;
212 }
213 msleep(3000); /* For ServeRAID cards, and some 66 PCI */
214 return 0;
215}
216
217static inline int power_off(struct slot *slot_cur)
218{
219 u8 cmd = HPC_SLOT_OFF;
220 int retval;
221
222 retval = ibmphp_hpc_writeslot(slot_cur, cmd);
223 if (retval) {
224 err("power off failed\n");
225 return retval;
226 }
227 if (CTLR_RESULT(slot_cur->ctrl->status)) {
228 err("command not completed successfully in power_off\n");
229 retval = -EIO;
230 }
231 return retval;
232}
233
234static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)
235{
236 int rc = 0;
237 struct slot *pslot;
238 u8 cmd;
239
240 debug("set_attention_status - Entry hotplug_slot[%lx] value[%x]\n",
241 (ulong) hotplug_slot, value);
242 ibmphp_lock_operations();
243 cmd = 0x00; // avoid compiler warning
244
245 if (hotplug_slot) {
246 switch (value) {
247 case HPC_SLOT_ATTN_OFF:
248 cmd = HPC_SLOT_ATTNOFF;
249 break;
250 case HPC_SLOT_ATTN_ON:
251 cmd = HPC_SLOT_ATTNON;
252 break;
253 case HPC_SLOT_ATTN_BLINK:
254 cmd = HPC_SLOT_BLINKLED;
255 break;
256 default:
257 rc = -ENODEV;
258 err("set_attention_status - Error : invalid input [%x]\n",
259 value);
260 break;
261 }
262 if (rc == 0) {
263 pslot = hotplug_slot->private;
264 if (pslot)
265 rc = ibmphp_hpc_writeslot(pslot, cmd);
266 else
267 rc = -ENODEV;
268 }
269 } else
270 rc = -ENODEV;
271
272 ibmphp_unlock_operations();
273
274 debug("set_attention_status - Exit rc[%d]\n", rc);
275 return rc;
276}
277
278static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)
279{
280 int rc = -ENODEV;
281 struct slot *pslot;
282 struct slot myslot;
283
284 debug("get_attention_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
285 (ulong) hotplug_slot, (ulong) value);
286
287 ibmphp_lock_operations();
288 if (hotplug_slot && value) {
289 pslot = hotplug_slot->private;
290 if (pslot) {
291 memcpy(&myslot, pslot, sizeof(struct slot));
292 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
293 &(myslot.status));
294 if (!rc)
295 rc = ibmphp_hpc_readslot(pslot,
296 READ_EXTSLOTSTATUS,
297 &(myslot.ext_status));
298 if (!rc)
299 *value = SLOT_ATTN(myslot.status,
300 myslot.ext_status);
301 }
302 }
303
304 ibmphp_unlock_operations();
305 debug("get_attention_status - Exit rc[%d] value[%x]\n", rc, *value);
306 return rc;
307}
308
309static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value)
310{
311 int rc = -ENODEV;
312 struct slot *pslot;
313 struct slot myslot;
314
315 debug("get_latch_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
316 (ulong) hotplug_slot, (ulong) value);
317 ibmphp_lock_operations();
318 if (hotplug_slot && value) {
319 pslot = hotplug_slot->private;
320 if (pslot) {
321 memcpy(&myslot, pslot, sizeof(struct slot));
322 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
323 &(myslot.status));
324 if (!rc)
325 *value = SLOT_LATCH(myslot.status);
326 }
327 }
328
329 ibmphp_unlock_operations();
330 debug("get_latch_status - Exit rc[%d] rc[%x] value[%x]\n",
331 rc, rc, *value);
332 return rc;
333}
334
335
336static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)
337{
338 int rc = -ENODEV;
339 struct slot *pslot;
340 struct slot myslot;
341
342 debug("get_power_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
343 (ulong) hotplug_slot, (ulong) value);
344 ibmphp_lock_operations();
345 if (hotplug_slot && value) {
346 pslot = hotplug_slot->private;
347 if (pslot) {
348 memcpy(&myslot, pslot, sizeof(struct slot));
349 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
350 &(myslot.status));
351 if (!rc)
352 *value = SLOT_PWRGD(myslot.status);
353 }
354 }
355
356 ibmphp_unlock_operations();
357 debug("get_power_status - Exit rc[%d] rc[%x] value[%x]\n",
358 rc, rc, *value);
359 return rc;
360}
361
362static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 * value)
363{
364 int rc = -ENODEV;
365 struct slot *pslot;
366 u8 present;
367 struct slot myslot;
368
369 debug("get_adapter_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
370 (ulong) hotplug_slot, (ulong) value);
371 ibmphp_lock_operations();
372 if (hotplug_slot && value) {
373 pslot = hotplug_slot->private;
374 if (pslot) {
375 memcpy(&myslot, pslot, sizeof(struct slot));
376 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
377 &(myslot.status));
378 if (!rc) {
379 present = SLOT_PRESENT(myslot.status);
380 if (present == HPC_SLOT_EMPTY)
381 *value = 0;
382 else
383 *value = 1;
384 }
385 }
386 }
387
388 ibmphp_unlock_operations();
389 debug("get_adapter_present - Exit rc[%d] value[%x]\n", rc, *value);
390 return rc;
391}
392
393static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
394{
395 int rc = -ENODEV;
396 struct slot *pslot;
397 u8 mode = 0;
398
399 debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__,
400 hotplug_slot, value);
401
402 ibmphp_lock_operations();
403
404 if (hotplug_slot && value) {
405 pslot = hotplug_slot->private;
406 if (pslot) {
407 rc = 0;
408 mode = pslot->supported_bus_mode;
409 *value = pslot->supported_speed;
410 switch (*value) {
411 case BUS_SPEED_33:
412 break;
413 case BUS_SPEED_66:
414 if (mode == BUS_MODE_PCIX)
415 *value += 0x01;
416 break;
417 case BUS_SPEED_100:
418 case BUS_SPEED_133:
419 *value = pslot->supported_speed + 0x01;
420 break;
421 default:
422 /* Note (will need to change): there would be soon 256, 512 also */
423 rc = -ENODEV;
424 }
425 }
426 }
427
428 ibmphp_unlock_operations();
429 debug("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value);
430 return rc;
431}
432
433static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
434{
435 int rc = -ENODEV;
436 struct slot *pslot;
437 u8 mode = 0;
438
439 debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__,
440 hotplug_slot, value);
441
442 ibmphp_lock_operations();
443
444 if (hotplug_slot && value) {
445 pslot = hotplug_slot->private;
446 if (pslot) {
447 rc = get_cur_bus_info(&pslot);
448 if (!rc) {
449 mode = pslot->bus_on->current_bus_mode;
450 *value = pslot->bus_on->current_speed;
451 switch (*value) {
452 case BUS_SPEED_33:
453 break;
454 case BUS_SPEED_66:
455 if (mode == BUS_MODE_PCIX)
456 *value += 0x01;
457 else if (mode == BUS_MODE_PCI)
458 ;
459 else
460 *value = PCI_SPEED_UNKNOWN;
461 break;
462 case BUS_SPEED_100:
463 case BUS_SPEED_133:
464 *value += 0x01;
465 break;
466 default:
467 /* Note of change: there would also be 256, 512 soon */
468 rc = -ENODEV;
469 }
470 }
471 }
472 }
473
474 ibmphp_unlock_operations();
475 debug("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value);
476 return rc;
477}
478
479/*
480static int get_max_adapter_speed_1(struct hotplug_slot *hotplug_slot, u8 * value, u8 flag)
481{
482 int rc = -ENODEV;
483 struct slot *pslot;
484 struct slot myslot;
485
486 debug("get_max_adapter_speed_1 - Entry hotplug_slot[%lx] pvalue[%lx]\n",
487 (ulong)hotplug_slot, (ulong) value);
488
489 if (flag)
490 ibmphp_lock_operations();
491
492 if (hotplug_slot && value) {
493 pslot = hotplug_slot->private;
494 if (pslot) {
495 memcpy(&myslot, pslot, sizeof(struct slot));
496 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
497 &(myslot.status));
498
499 if (!(SLOT_LATCH (myslot.status)) &&
500 (SLOT_PRESENT (myslot.status))) {
501 rc = ibmphp_hpc_readslot(pslot,
502 READ_EXTSLOTSTATUS,
503 &(myslot.ext_status));
504 if (!rc)
505 *value = SLOT_SPEED(myslot.ext_status);
506 } else
507 *value = MAX_ADAPTER_NONE;
508 }
509 }
510
511 if (flag)
512 ibmphp_unlock_operations();
513
514 debug("get_max_adapter_speed_1 - Exit rc[%d] value[%x]\n", rc, *value);
515 return rc;
516}
517
518static int get_bus_name(struct hotplug_slot *hotplug_slot, char * value)
519{
520 int rc = -ENODEV;
521 struct slot *pslot = NULL;
522
523 debug("get_bus_name - Entry hotplug_slot[%lx]\n", (ulong)hotplug_slot);
524
525 ibmphp_lock_operations();
526
527 if (hotplug_slot) {
528 pslot = hotplug_slot->private;
529 if (pslot) {
530 rc = 0;
531 snprintf(value, 100, "Bus %x", pslot->bus);
532 }
533 } else
534 rc = -ENODEV;
535
536 ibmphp_unlock_operations();
537 debug("get_bus_name - Exit rc[%d] value[%x]\n", rc, *value);
538 return rc;
539}
540*/
541
542/****************************************************************************
543 * This routine will initialize the ops data structure used in the validate
544 * function. It will also power off empty slots that are powered on since BIOS
545 * leaves those on, albeit disconnected
546 ****************************************************************************/
547static int __init init_ops(void)
548{
549 struct slot *slot_cur;
550 struct list_head *tmp;
551 int retval;
552 int rc;
553
554 list_for_each(tmp, &ibmphp_slot_head) {
555 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
556
557 if (!slot_cur)
558 return -ENODEV;
559
560 debug("BEFORE GETTING SLOT STATUS, slot # %x\n",
561 slot_cur->number);
562 if (slot_cur->ctrl->revision == 0xFF)
563 if (get_ctrl_revision(slot_cur,
564 &slot_cur->ctrl->revision))
565 return -1;
566
567 if (slot_cur->bus_on->current_speed == 0xFF)
568 if (get_cur_bus_info(&slot_cur))
569 return -1;
570
571 if (slot_cur->ctrl->options == 0xFF)
572 if (get_hpc_options(slot_cur, &slot_cur->ctrl->options))
573 return -1;
574
575 retval = slot_update(&slot_cur);
576 if (retval)
577 return retval;
578
579 debug("status = %x\n", slot_cur->status);
580 debug("ext_status = %x\n", slot_cur->ext_status);
581 debug("SLOT_POWER = %x\n", SLOT_POWER(slot_cur->status));
582 debug("SLOT_PRESENT = %x\n", SLOT_PRESENT(slot_cur->status));
583 debug("SLOT_LATCH = %x\n", SLOT_LATCH(slot_cur->status));
584
585 if ((SLOT_PWRGD(slot_cur->status)) &&
586 !(SLOT_PRESENT(slot_cur->status)) &&
587 !(SLOT_LATCH(slot_cur->status))) {
588 debug("BEFORE POWER OFF COMMAND\n");
589 rc = power_off(slot_cur);
590 if (rc)
591 return rc;
592
593 /* retval = slot_update(&slot_cur);
594 * if (retval)
595 * return retval;
596 * ibmphp_update_slot_info(slot_cur);
597 */
598 }
599 }
600 init_flag = 0;
601 return 0;
602}
603
604/* This operation will check whether the slot is within the bounds and
605 * the operation is valid to perform on that slot
606 * Parameters: slot, operation
607 * Returns: 0 or error codes
608 */
609static int validate(struct slot *slot_cur, int opn)
610{
611 int number;
612 int retval;
613
614 if (!slot_cur)
615 return -ENODEV;
616 number = slot_cur->number;
617 if ((number > max_slots) || (number < 0))
618 return -EBADSLT;
619 debug("slot_number in validate is %d\n", slot_cur->number);
620
621 retval = slot_update(&slot_cur);
622 if (retval)
623 return retval;
624
625 switch (opn) {
626 case ENABLE:
627 if (!(SLOT_PWRGD(slot_cur->status)) &&
628 (SLOT_PRESENT(slot_cur->status)) &&
629 !(SLOT_LATCH(slot_cur->status)))
630 return 0;
631 break;
632 case DISABLE:
633 if ((SLOT_PWRGD(slot_cur->status)) &&
634 (SLOT_PRESENT(slot_cur->status)) &&
635 !(SLOT_LATCH(slot_cur->status)))
636 return 0;
637 break;
638 default:
639 break;
640 }
641 err("validate failed....\n");
642 return -EINVAL;
643}
644
645/****************************************************************************
646 * This routine is for updating the data structures in the hotplug core
647 * Parameters: struct slot
648 * Returns: 0 or error
649 ****************************************************************************/
650int ibmphp_update_slot_info(struct slot *slot_cur)
651{
652 struct hotplug_slot_info *info;
653 int rc;
654 u8 bus_speed;
655 u8 mode;
656
657 info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
658 if (!info) {
659 err("out of system memory\n");
660 return -ENOMEM;
661 }
662
663 info->power_status = SLOT_PWRGD(slot_cur->status);
664 info->attention_status = SLOT_ATTN(slot_cur->status,
665 slot_cur->ext_status);
666 info->latch_status = SLOT_LATCH(slot_cur->status);
667 if (!SLOT_PRESENT(slot_cur->status)) {
668 info->adapter_status = 0;
669/* info->max_adapter_speed_status = MAX_ADAPTER_NONE; */
670 } else {
671 info->adapter_status = 1;
672/* get_max_adapter_speed_1(slot_cur->hotplug_slot,
673 &info->max_adapter_speed_status, 0); */
674 }
675
676 bus_speed = slot_cur->bus_on->current_speed;
677 mode = slot_cur->bus_on->current_bus_mode;
678
679 switch (bus_speed) {
680 case BUS_SPEED_33:
681 break;
682 case BUS_SPEED_66:
683 if (mode == BUS_MODE_PCIX)
684 bus_speed += 0x01;
685 else if (mode == BUS_MODE_PCI)
686 ;
687 else
688 bus_speed = PCI_SPEED_UNKNOWN;
689 break;
690 case BUS_SPEED_100:
691 case BUS_SPEED_133:
692 bus_speed += 0x01;
693 break;
694 default:
695 bus_speed = PCI_SPEED_UNKNOWN;
696 }
697
698 info->cur_bus_speed = bus_speed;
699 info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed;
700 // To do: bus_names
701
702 rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info);
703 kfree(info);
704 return rc;
705}
706
707
708/******************************************************************************
709 * This function will return the pci_func, given bus and devfunc, or NULL. It
710 * is called from visit routines
711 ******************************************************************************/
712
713static struct pci_func *ibm_slot_find(u8 busno, u8 device, u8 function)
714{
715 struct pci_func *func_cur;
716 struct slot *slot_cur;
717 struct list_head * tmp;
718 list_for_each(tmp, &ibmphp_slot_head) {
719 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
720 if (slot_cur->func) {
721 func_cur = slot_cur->func;
722 while (func_cur) {
723 if ((func_cur->busno == busno) &&
724 (func_cur->device == device) &&
725 (func_cur->function == function))
726 return func_cur;
727 func_cur = func_cur->next;
728 }
729 }
730 }
731 return NULL;
732}
733
734/*************************************************************
735 * This routine frees up memory used by struct slot, including
736 * the pointers to pci_func, bus, hotplug_slot, controller,
737 * and deregistering from the hotplug core
738 *************************************************************/
739static void free_slots(void)
740{
741 struct slot *slot_cur;
742 struct list_head * tmp;
743 struct list_head * next;
744
745 debug("%s -- enter\n", __FUNCTION__);
746
747 list_for_each_safe(tmp, next, &ibmphp_slot_head) {
748 slot_cur = list_entry(tmp, struct slot, ibm_slot_list);
749 pci_hp_deregister(slot_cur->hotplug_slot);
750 }
751 debug("%s -- exit\n", __FUNCTION__);
752}
753
754static void ibm_unconfigure_device(struct pci_func *func)
755{
756 struct pci_dev *temp;
757 u8 j;
758
759 debug("inside %s\n", __FUNCTION__);
760 debug("func->device = %x, func->function = %x\n",
761 func->device, func->function);
762 debug("func->device << 3 | 0x0 = %x\n", func->device << 3 | 0x0);
763
764 for (j = 0; j < 0x08; j++) {
765 temp = pci_find_slot(func->busno, (func->device << 3) | j);
766 if (temp)
767 pci_remove_bus_device(temp);
768 }
769}
770
771/*
772 * The following function is to fix kernel bug regarding
773 * getting bus entries, here we manually add those primary
774 * bus entries to kernel bus structure whenever apply
775 */
776static u8 bus_structure_fixup(u8 busno)
777{
778 struct pci_bus *bus;
779 struct pci_dev *dev;
780 u16 l;
781
782 if (pci_find_bus(0, busno) || !(ibmphp_find_same_bus_num(busno)))
783 return 1;
784
785 bus = kmalloc(sizeof(*bus), GFP_KERNEL);
786 if (!bus) {
787 err("%s - out of memory\n", __FUNCTION__);
788 return 1;
789 }
790 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
791 if (!dev) {
792 kfree(bus);
793 err("%s - out of memory\n", __FUNCTION__);
794 return 1;
795 }
796
797 bus->number = busno;
798 bus->ops = ibmphp_pci_bus->ops;
799 dev->bus = bus;
800 for (dev->devfn = 0; dev->devfn < 256; dev->devfn += 8) {
801 if (!pci_read_config_word(dev, PCI_VENDOR_ID, &l) &&
802 (l != 0x0000) && (l != 0xffff)) {
803 debug("%s - Inside bus_struture_fixup()\n",
804 __FUNCTION__);
805 pci_scan_bus(busno, ibmphp_pci_bus->ops, NULL);
806 break;
807 }
808 }
809
810 kfree(dev);
811 kfree(bus);
812
813 return 0;
814}
815
816static int ibm_configure_device(struct pci_func *func)
817{
818 unsigned char bus;
819 struct pci_bus *child;
820 int num;
821 int flag = 0; /* this is to make sure we don't double scan the bus,
822 for bridged devices primarily */
823
824 if (!(bus_structure_fixup(func->busno)))
825 flag = 1;
826 if (func->dev == NULL)
827 func->dev = pci_find_slot(func->busno,
828 PCI_DEVFN(func->device, func->function));
829
830 if (func->dev == NULL) {
831 struct pci_bus *bus = pci_find_bus(0, func->busno);
832 if (!bus)
833 return 0;
834
835 num = pci_scan_slot(bus,
836 PCI_DEVFN(func->device, func->function));
837 if (num)
838 pci_bus_add_devices(bus);
839
840 func->dev = pci_find_slot(func->busno,
841 PCI_DEVFN(func->device, func->function));
842 if (func->dev == NULL) {
843 err("ERROR... : pci_dev still NULL\n");
844 return 0;
845 }
846 }
847 if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
848 pci_read_config_byte(func->dev, PCI_SECONDARY_BUS, &bus);
849 child = pci_add_new_bus(func->dev->bus, func->dev, bus);
850 pci_do_scan_bus(child);
851 }
852
853 return 0;
854}
855
856/*******************************************************
857 * Returns whether the bus is empty or not
858 *******************************************************/
859static int is_bus_empty(struct slot * slot_cur)
860{
861 int rc;
862 struct slot * tmp_slot;
863 u8 i = slot_cur->bus_on->slot_min;
864
865 while (i <= slot_cur->bus_on->slot_max) {
866 if (i == slot_cur->number) {
867 i++;
868 continue;
869 }
870 tmp_slot = ibmphp_get_slot_from_physical_num(i);
871 if (!tmp_slot)
872 return 0;
873 rc = slot_update(&tmp_slot);
874 if (rc)
875 return 0;
876 if (SLOT_PRESENT(tmp_slot->status) &&
877 SLOT_PWRGD(tmp_slot->status))
878 return 0;
879 i++;
880 }
881 return 1;
882}
883
884/***********************************************************
885 * If the HPC permits and the bus currently empty, tries to set the
886 * bus speed and mode at the maximum card and bus capability
887 * Parameters: slot
888 * Returns: bus is set (0) or error code
889 ***********************************************************/
890static int set_bus(struct slot * slot_cur)
891{
892 int rc;
893 u8 speed;
894 u8 cmd = 0x0;
895 int retval;
896 static struct pci_device_id ciobx[] = {
897 { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 0x0101) },
898 { },
899 };
900
901 debug("%s - entry slot # %d\n", __FUNCTION__, slot_cur->number);
902 if (SET_BUS_STATUS(slot_cur->ctrl) && is_bus_empty(slot_cur)) {
903 rc = slot_update(&slot_cur);
904 if (rc)
905 return rc;
906 speed = SLOT_SPEED(slot_cur->ext_status);
907 debug("ext_status = %x, speed = %x\n", slot_cur->ext_status, speed);
908 switch (speed) {
909 case HPC_SLOT_SPEED_33:
910 cmd = HPC_BUS_33CONVMODE;
911 break;
912 case HPC_SLOT_SPEED_66:
913 if (SLOT_PCIX(slot_cur->ext_status)) {
914 if ((slot_cur->supported_speed >= BUS_SPEED_66) &&
915 (slot_cur->supported_bus_mode == BUS_MODE_PCIX))
916 cmd = HPC_BUS_66PCIXMODE;
917 else if (!SLOT_BUS_MODE(slot_cur->ext_status))
918 /* if max slot/bus capability is 66 pci
919 and there's no bus mode mismatch, then
920 the adapter supports 66 pci */
921 cmd = HPC_BUS_66CONVMODE;
922 else
923 cmd = HPC_BUS_33CONVMODE;
924 } else {
925 if (slot_cur->supported_speed >= BUS_SPEED_66)
926 cmd = HPC_BUS_66CONVMODE;
927 else
928 cmd = HPC_BUS_33CONVMODE;
929 }
930 break;
931 case HPC_SLOT_SPEED_133:
932 switch (slot_cur->supported_speed) {
933 case BUS_SPEED_33:
934 cmd = HPC_BUS_33CONVMODE;
935 break;
936 case BUS_SPEED_66:
937 if (slot_cur->supported_bus_mode == BUS_MODE_PCIX)
938 cmd = HPC_BUS_66PCIXMODE;
939 else
940 cmd = HPC_BUS_66CONVMODE;
941 break;
942 case BUS_SPEED_100:
943 cmd = HPC_BUS_100PCIXMODE;
944 break;
945 case BUS_SPEED_133:
946 /* This is to take care of the bug in CIOBX chip */
947 if (pci_dev_present(ciobx))
948 ibmphp_hpc_writeslot(slot_cur,
949 HPC_BUS_100PCIXMODE);
950 cmd = HPC_BUS_133PCIXMODE;
951 break;
952 default:
953 err("Wrong bus speed\n");
954 return -ENODEV;
955 }
956 break;
957 default:
958 err("wrong slot speed\n");
959 return -ENODEV;
960 }
961 debug("setting bus speed for slot %d, cmd %x\n",
962 slot_cur->number, cmd);
963 retval = ibmphp_hpc_writeslot(slot_cur, cmd);
964 if (retval) {
965 err("setting bus speed failed\n");
966 return retval;
967 }
968 if (CTLR_RESULT(slot_cur->ctrl->status)) {
969 err("command not completed successfully in set_bus\n");
970 return -EIO;
971 }
972 }
973 /* This is for x440, once Brandon fixes the firmware,
974 will not need this delay */
975 msleep(1000);
976 debug("%s -Exit\n", __FUNCTION__);
977 return 0;
978}
979
980/* This routine checks the bus limitations that the slot is on from the BIOS.
981 * This is used in deciding whether or not to power up the slot.
982 * (electrical/spec limitations. For example, >1 133 MHz or >2 66 PCI cards on
983 * same bus)
984 * Parameters: slot
985 * Returns: 0 = no limitations, -EINVAL = exceeded limitations on the bus
986 */
987static int check_limitations(struct slot *slot_cur)
988{
989 u8 i;
990 struct slot * tmp_slot;
991 u8 count = 0;
992 u8 limitation = 0;
993
994 for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
995 tmp_slot = ibmphp_get_slot_from_physical_num(i);
996 if (!tmp_slot)
997 return -ENODEV;
998 if ((SLOT_PWRGD(tmp_slot->status)) &&
999 !(SLOT_CONNECT(tmp_slot->status)))
1000 count++;
1001 }
1002 get_cur_bus_info(&slot_cur);
1003 switch (slot_cur->bus_on->current_speed) {
1004 case BUS_SPEED_33:
1005 limitation = slot_cur->bus_on->slots_at_33_conv;
1006 break;
1007 case BUS_SPEED_66:
1008 if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
1009 limitation = slot_cur->bus_on->slots_at_66_pcix;
1010 else
1011 limitation = slot_cur->bus_on->slots_at_66_conv;
1012 break;
1013 case BUS_SPEED_100:
1014 limitation = slot_cur->bus_on->slots_at_100_pcix;
1015 break;
1016 case BUS_SPEED_133:
1017 limitation = slot_cur->bus_on->slots_at_133_pcix;
1018 break;
1019 }
1020
1021 if ((count + 1) > limitation)
1022 return -EINVAL;
1023 return 0;
1024}
1025
1026static inline void print_card_capability(struct slot *slot_cur)
1027{
1028 info("capability of the card is ");
1029 if ((slot_cur->ext_status & CARD_INFO) == PCIX133)
1030 info(" 133 MHz PCI-X\n");
1031 else if ((slot_cur->ext_status & CARD_INFO) == PCIX66)
1032 info(" 66 MHz PCI-X\n");
1033 else if ((slot_cur->ext_status & CARD_INFO) == PCI66)
1034 info(" 66 MHz PCI\n");
1035 else
1036 info(" 33 MHz PCI\n");
1037
1038}
1039
1040/* This routine will power on the slot, configure the device(s) and find the
1041 * drivers for them.
1042 * Parameters: hotplug_slot
1043 * Returns: 0 or failure codes
1044 */
1045static int enable_slot(struct hotplug_slot *hs)
1046{
1047 int rc, i, rcpr;
1048 struct slot *slot_cur;
1049 u8 function;
1050 struct pci_func *tmp_func;
1051
1052 ibmphp_lock_operations();
1053
1054 debug("ENABLING SLOT........\n");
1055 slot_cur = hs->private;
1056
1057 if ((rc = validate(slot_cur, ENABLE))) {
1058 err("validate function failed\n");
1059 goto error_nopower;
1060 }
1061
1062 attn_LED_blink(slot_cur);
1063
1064 rc = set_bus(slot_cur);
1065 if (rc) {
1066 err("was not able to set the bus\n");
1067 goto error_nopower;
1068 }
1069
1070 /*-----------------debugging------------------------------*/
1071 get_cur_bus_info(&slot_cur);
1072 debug("the current bus speed right after set_bus = %x\n",
1073 slot_cur->bus_on->current_speed);
1074 /*----------------------------------------------------------*/
1075
1076 rc = check_limitations(slot_cur);
1077 if (rc) {
1078 err("Adding this card exceeds the limitations of this bus.\n");
1079 err("(i.e., >1 133MHz cards running on same bus, or "
1080 ">2 66 PCI cards running on same bus\n.");
1081 err("Try hot-adding into another bus\n");
1082 rc = -EINVAL;
1083 goto error_nopower;
1084 }
1085
1086 rc = power_on(slot_cur);
1087
1088 if (rc) {
1089 err("something wrong when powering up... please see below for details\n");
1090 /* need to turn off before on, otherwise, blinking overwrites */
1091 attn_off(slot_cur);
1092 attn_on(slot_cur);
1093 if (slot_update(&slot_cur)) {
1094 attn_off(slot_cur);
1095 attn_on(slot_cur);
1096 rc = -ENODEV;
1097 goto exit;
1098 }
1099 /* Check to see the error of why it failed */
1100 if ((SLOT_POWER(slot_cur->status)) &&
1101 !(SLOT_PWRGD(slot_cur->status)))
1102 err("power fault occurred trying to power up\n");
1103 else if (SLOT_BUS_SPEED(slot_cur->status)) {
1104 err("bus speed mismatch occurred. please check "
1105 "current bus speed and card capability\n");
1106 print_card_capability(slot_cur);
1107 } else if (SLOT_BUS_MODE(slot_cur->ext_status)) {
1108 err("bus mode mismatch occurred. please check "
1109 "current bus mode and card capability\n");
1110 print_card_capability(slot_cur);
1111 }
1112 ibmphp_update_slot_info(slot_cur);
1113 goto exit;
1114 }
1115 debug("after power_on\n");
1116 /*-----------------------debugging---------------------------*/
1117 get_cur_bus_info(&slot_cur);
1118 debug("the current bus speed right after power_on = %x\n",
1119 slot_cur->bus_on->current_speed);
1120 /*----------------------------------------------------------*/
1121
1122 rc = slot_update(&slot_cur);
1123 if (rc)
1124 goto error_power;
1125
1126 rc = -EINVAL;
1127 if (SLOT_POWER(slot_cur->status) && !(SLOT_PWRGD(slot_cur->status))) {
1128 err("power fault occurred trying to power up...\n");
1129 goto error_power;
1130 }
1131 if (SLOT_POWER(slot_cur->status) && (SLOT_BUS_SPEED(slot_cur->status))) {
1132 err("bus speed mismatch occurred. please check current bus "
1133 "speed and card capability\n");
1134 print_card_capability(slot_cur);
1135 goto error_power;
1136 }
1137 /* Don't think this case will happen after above checks...
1138 * but just in case, for paranoia sake */
1139 if (!(SLOT_POWER(slot_cur->status))) {
1140 err("power on failed...\n");
1141 goto error_power;
1142 }
1143
1144 slot_cur->func = kmalloc(sizeof(struct pci_func), GFP_KERNEL);
1145 if (!slot_cur->func) {
1146 /* We cannot do update_slot_info here, since no memory for
1147 * kmalloc n.e.ways, and update_slot_info allocates some */
1148 err("out of system memory\n");
1149 rc = -ENOMEM;
1150 goto error_power;
1151 }
1152 memset(slot_cur->func, 0, sizeof(struct pci_func));
1153 slot_cur->func->busno = slot_cur->bus;
1154 slot_cur->func->device = slot_cur->device;
1155 for (i = 0; i < 4; i++)
1156 slot_cur->func->irq[i] = slot_cur->irq[i];
1157
1158 debug("b4 configure_card, slot_cur->bus = %x, slot_cur->device = %x\n",
1159 slot_cur->bus, slot_cur->device);
1160
1161 if (ibmphp_configure_card(slot_cur->func, slot_cur->number)) {
1162 err("configure_card was unsuccessful...\n");
1163 /* true because don't need to actually deallocate resources,
1164 * just remove references */
1165 ibmphp_unconfigure_card(&slot_cur, 1);
1166 debug("after unconfigure_card\n");
1167 slot_cur->func = NULL;
1168 rc = -ENOMEM;
1169 goto error_power;
1170 }
1171
1172 function = 0x00;
1173 do {
1174 tmp_func = ibm_slot_find(slot_cur->bus, slot_cur->func->device,
1175 function++);
1176 if (tmp_func && !(tmp_func->dev))
1177 ibm_configure_device(tmp_func);
1178 } while (tmp_func);
1179
1180 attn_off(slot_cur);
1181 if (slot_update(&slot_cur)) {
1182 rc = -EFAULT;
1183 goto exit;
1184 }
1185 ibmphp_print_test();
1186 rc = ibmphp_update_slot_info(slot_cur);
1187exit:
1188 ibmphp_unlock_operations();
1189 return rc;
1190
1191error_nopower:
1192 attn_off(slot_cur); /* need to turn off if was blinking b4 */
1193 attn_on(slot_cur);
1194error_cont:
1195 rcpr = slot_update(&slot_cur);
1196 if (rcpr) {
1197 rc = rcpr;
1198 goto exit;
1199 }
1200 ibmphp_update_slot_info(slot_cur);
1201 goto exit;
1202
1203error_power:
1204 attn_off(slot_cur); /* need to turn off if was blinking b4 */
1205 attn_on(slot_cur);
1206 rcpr = power_off(slot_cur);
1207 if (rcpr) {
1208 rc = rcpr;
1209 goto exit;
1210 }
1211 goto error_cont;
1212}
1213
1214/**************************************************************
1215* HOT REMOVING ADAPTER CARD *
1216* INPUT: POINTER TO THE HOTPLUG SLOT STRUCTURE *
1217* OUTPUT: SUCCESS 0 ; FAILURE: UNCONFIGURE , VALIDATE *
1218 DISABLE POWER , *
1219**************************************************************/
1220static int ibmphp_disable_slot(struct hotplug_slot *hotplug_slot)
1221{
1222 struct slot *slot = hotplug_slot->private;
1223 int rc;
1224
1225 ibmphp_lock_operations();
1226 rc = ibmphp_do_disable_slot(slot);
1227 ibmphp_unlock_operations();
1228 return rc;
1229}
1230
1231int ibmphp_do_disable_slot(struct slot *slot_cur)
1232{
1233 int rc;
1234 u8 flag;
1235
1236 debug("DISABLING SLOT...\n");
1237
1238 if ((slot_cur == NULL) || (slot_cur->ctrl == NULL)) {
1239 return -ENODEV;
1240 }
1241
1242 flag = slot_cur->flag;
1243 slot_cur->flag = TRUE;
1244
1245 if (flag == TRUE) {
1246 rc = validate(slot_cur, DISABLE);
1247 /* checking if powered off already & valid slot # */
1248 if (rc)
1249 goto error;
1250 }
1251 attn_LED_blink(slot_cur);
1252
1253 if (slot_cur->func == NULL) {
1254 /* We need this for fncs's that were there on bootup */
1255 slot_cur->func = kmalloc(sizeof(struct pci_func), GFP_KERNEL);
1256 if (!slot_cur->func) {
1257 err("out of system memory\n");
1258 rc = -ENOMEM;
1259 goto error;
1260 }
1261 memset(slot_cur->func, 0, sizeof(struct pci_func));
1262 slot_cur->func->busno = slot_cur->bus;
1263 slot_cur->func->device = slot_cur->device;
1264 }
1265
1266 ibm_unconfigure_device(slot_cur->func);
1267
1268 /* If we got here from latch suddenly opening on operating card or
1269 a power fault, there's no power to the card, so cannot
1270 read from it to determine what resources it occupied. This operation
1271 is forbidden anyhow. The best we can do is remove it from kernel
1272 lists at least */
1273
1274 if (!flag) {
1275 attn_off(slot_cur);
1276 return 0;
1277 }
1278
1279 rc = ibmphp_unconfigure_card(&slot_cur, 0);
1280 slot_cur->func = NULL;
1281 debug("in disable_slot. after unconfigure_card\n");
1282 if (rc) {
1283 err("could not unconfigure card.\n");
1284 goto error;
1285 }
1286
1287 rc = ibmphp_hpc_writeslot(slot_cur, HPC_SLOT_OFF);
1288 if (rc)
1289 goto error;
1290
1291 attn_off(slot_cur);
1292 rc = slot_update(&slot_cur);
1293 if (rc)
1294 goto exit;
1295
1296 rc = ibmphp_update_slot_info(slot_cur);
1297 ibmphp_print_test();
1298exit:
1299 return rc;
1300
1301error:
1302 /* Need to turn off if was blinking b4 */
1303 attn_off(slot_cur);
1304 attn_on(slot_cur);
1305 if (slot_update(&slot_cur)) {
1306 rc = -EFAULT;
1307 goto exit;
1308 }
1309 if (flag)
1310 ibmphp_update_slot_info(slot_cur);
1311 goto exit;
1312}
1313
1314struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
1315 .owner = THIS_MODULE,
1316 .set_attention_status = set_attention_status,
1317 .enable_slot = enable_slot,
1318 .disable_slot = ibmphp_disable_slot,
1319 .hardware_test = NULL,
1320 .get_power_status = get_power_status,
1321 .get_attention_status = get_attention_status,
1322 .get_latch_status = get_latch_status,
1323 .get_adapter_status = get_adapter_present,
1324 .get_max_bus_speed = get_max_bus_speed,
1325 .get_cur_bus_speed = get_cur_bus_speed,
1326/* .get_max_adapter_speed = get_max_adapter_speed,
1327 .get_bus_name_status = get_bus_name,
1328*/
1329};
1330
1331static void ibmphp_unload(void)
1332{
1333 free_slots();
1334 debug("after slots\n");
1335 ibmphp_free_resources();
1336 debug("after resources\n");
1337 ibmphp_free_bus_info_queue();
1338 debug("after bus info\n");
1339 ibmphp_free_ebda_hpc_queue();
1340 debug("after ebda hpc\n");
1341 ibmphp_free_ebda_pci_rsrc_queue();
1342 debug("after ebda pci rsrc\n");
1343 kfree(ibmphp_pci_bus);
1344}
1345
1346static int __init ibmphp_init(void)
1347{
1348 struct pci_bus *bus;
1349 int i = 0;
1350 int rc = 0;
1351
1352 init_flag = 1;
1353
1354 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
1355
1356 ibmphp_pci_bus = kmalloc(sizeof(*ibmphp_pci_bus), GFP_KERNEL);
1357 if (!ibmphp_pci_bus) {
1358 err("out of memory\n");
1359 rc = -ENOMEM;
1360 goto exit;
1361 }
1362
1363 bus = pci_find_bus(0, 0);
1364 if (!bus) {
1365 err("Can't find the root pci bus, can not continue\n");
1366 rc = -ENODEV;
1367 goto error;
1368 }
1369 memcpy(ibmphp_pci_bus, bus, sizeof(*ibmphp_pci_bus));
1370
1371 ibmphp_debug = debug;
1372
1373 ibmphp_hpc_initvars();
1374
1375 for (i = 0; i < 16; i++)
1376 irqs[i] = 0;
1377
1378 if ((rc = ibmphp_access_ebda()))
1379 goto error;
1380 debug("after ibmphp_access_ebda()\n");
1381
1382 if ((rc = ibmphp_rsrc_init()))
1383 goto error;
1384 debug("AFTER Resource & EBDA INITIALIZATIONS\n");
1385
1386 max_slots = get_max_slots();
1387
1388 if ((rc = ibmphp_register_pci()))
1389 goto error;
1390
1391 if (init_ops()) {
1392 rc = -ENODEV;
1393 goto error;
1394 }
1395
1396 ibmphp_print_test();
1397 if ((rc = ibmphp_hpc_start_poll_thread())) {
1398 goto error;
1399 }
1400
1401 /* lock ourselves into memory with a module
1402 * count of -1 so that no one can unload us. */
1403 module_put(THIS_MODULE);
1404
1405exit:
1406 return rc;
1407
1408error:
1409 ibmphp_unload();
1410 goto exit;
1411}
1412
1413static void __exit ibmphp_exit(void)
1414{
1415 ibmphp_hpc_stop_poll_thread();
1416 debug("after polling\n");
1417 ibmphp_unload();
1418 debug("done\n");
1419}
1420
1421module_init(ibmphp_init);
1422module_exit(ibmphp_exit);
diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c
new file mode 100644
index 000000000000..aea1187c73ad
--- /dev/null
+++ b/drivers/pci/hotplug/ibmphp_ebda.c
@@ -0,0 +1,1275 @@
1/*
2 * IBM Hot Plug Controller Driver
3 *
4 * Written By: Tong Yu, IBM Corporation
5 *
6 * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
7 * Copyright (C) 2001-2003 IBM Corp.
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <gregkh@us.ibm.com>
27 *
28 */
29
30#include <linux/module.h>
31#include <linux/sched.h>
32#include <linux/errno.h>
33#include <linux/mm.h>
34#include <linux/slab.h>
35#include <linux/pci.h>
36#include <linux/list.h>
37#include <linux/init.h>
38#include "ibmphp.h"
39
40/*
41 * POST builds data blocks(in this data block definition, a char-1
42 * byte, short(or word)-2 byte, long(dword)-4 byte) in the Extended
43 * BIOS Data Area which describe the configuration of the hot-plug
44 * controllers and resources used by the PCI Hot-Plug devices.
45 *
46 * This file walks EBDA, maps data block from physical addr,
47 * reconstruct linked lists about all system resource(MEM, PFM, IO)
48 * already assigned by POST, as well as linked lists about hot plug
49 * controllers (ctlr#, slot#, bus&slot features...)
50 */
51
52/* Global lists */
53LIST_HEAD (ibmphp_ebda_pci_rsrc_head);
54LIST_HEAD (ibmphp_slot_head);
55
56/* Local variables */
57static struct ebda_hpc_list *hpc_list_ptr;
58static struct ebda_rsrc_list *rsrc_list_ptr;
59static struct rio_table_hdr *rio_table_ptr = NULL;
60static LIST_HEAD (ebda_hpc_head);
61static LIST_HEAD (bus_info_head);
62static LIST_HEAD (rio_vg_head);
63static LIST_HEAD (rio_lo_head);
64static LIST_HEAD (opt_vg_head);
65static LIST_HEAD (opt_lo_head);
66static void __iomem *io_mem;
67
68/* Local functions */
69static int ebda_rsrc_controller (void);
70static int ebda_rsrc_rsrc (void);
71static int ebda_rio_table (void);
72
73static struct ebda_hpc_list * __init alloc_ebda_hpc_list (void)
74{
75 struct ebda_hpc_list *list;
76
77 list = kmalloc (sizeof (struct ebda_hpc_list), GFP_KERNEL);
78 if (!list)
79 return NULL;
80 memset (list, 0, sizeof (*list));
81 return list;
82}
83
84static struct controller *alloc_ebda_hpc (u32 slot_count, u32 bus_count)
85{
86 struct controller *controller;
87 struct ebda_hpc_slot *slots;
88 struct ebda_hpc_bus *buses;
89
90 controller = kmalloc (sizeof (struct controller), GFP_KERNEL);
91 if (!controller)
92 goto error;
93 memset (controller, 0, sizeof (*controller));
94
95 slots = kmalloc (sizeof (struct ebda_hpc_slot) * slot_count, GFP_KERNEL);
96 if (!slots)
97 goto error_contr;
98 memset (slots, 0, sizeof (*slots) * slot_count);
99 controller->slots = slots;
100
101 buses = kmalloc (sizeof (struct ebda_hpc_bus) * bus_count, GFP_KERNEL);
102 if (!buses)
103 goto error_slots;
104 memset (buses, 0, sizeof (*buses) * bus_count);
105 controller->buses = buses;
106
107 return controller;
108error_slots:
109 kfree(controller->slots);
110error_contr:
111 kfree(controller);
112error:
113 return NULL;
114}
115
116static void free_ebda_hpc (struct controller *controller)
117{
118 kfree (controller->slots);
119 kfree (controller->buses);
120 kfree (controller);
121}
122
123static struct ebda_rsrc_list * __init alloc_ebda_rsrc_list (void)
124{
125 struct ebda_rsrc_list *list;
126
127 list = kmalloc (sizeof (struct ebda_rsrc_list), GFP_KERNEL);
128 if (!list)
129 return NULL;
130 memset (list, 0, sizeof (*list));
131 return list;
132}
133
134static struct ebda_pci_rsrc *alloc_ebda_pci_rsrc (void)
135{
136 struct ebda_pci_rsrc *resource;
137
138 resource = kmalloc (sizeof (struct ebda_pci_rsrc), GFP_KERNEL);
139 if (!resource)
140 return NULL;
141 memset (resource, 0, sizeof (*resource));
142 return resource;
143}
144
145static void __init print_bus_info (void)
146{
147 struct bus_info *ptr;
148 struct list_head *ptr1;
149
150 list_for_each (ptr1, &bus_info_head) {
151 ptr = list_entry (ptr1, struct bus_info, bus_info_list);
152 debug ("%s - slot_min = %x\n", __FUNCTION__, ptr->slot_min);
153 debug ("%s - slot_max = %x\n", __FUNCTION__, ptr->slot_max);
154 debug ("%s - slot_count = %x\n", __FUNCTION__, ptr->slot_count);
155 debug ("%s - bus# = %x\n", __FUNCTION__, ptr->busno);
156 debug ("%s - current_speed = %x\n", __FUNCTION__, ptr->current_speed);
157 debug ("%s - controller_id = %x\n", __FUNCTION__, ptr->controller_id);
158
159 debug ("%s - slots_at_33_conv = %x\n", __FUNCTION__, ptr->slots_at_33_conv);
160 debug ("%s - slots_at_66_conv = %x\n", __FUNCTION__, ptr->slots_at_66_conv);
161 debug ("%s - slots_at_66_pcix = %x\n", __FUNCTION__, ptr->slots_at_66_pcix);
162 debug ("%s - slots_at_100_pcix = %x\n", __FUNCTION__, ptr->slots_at_100_pcix);
163 debug ("%s - slots_at_133_pcix = %x\n", __FUNCTION__, ptr->slots_at_133_pcix);
164
165 }
166}
167
168static void print_lo_info (void)
169{
170 struct rio_detail *ptr;
171 struct list_head *ptr1;
172 debug ("print_lo_info ----\n");
173 list_for_each (ptr1, &rio_lo_head) {
174 ptr = list_entry (ptr1, struct rio_detail, rio_detail_list);
175 debug ("%s - rio_node_id = %x\n", __FUNCTION__, ptr->rio_node_id);
176 debug ("%s - rio_type = %x\n", __FUNCTION__, ptr->rio_type);
177 debug ("%s - owner_id = %x\n", __FUNCTION__, ptr->owner_id);
178 debug ("%s - first_slot_num = %x\n", __FUNCTION__, ptr->first_slot_num);
179 debug ("%s - wpindex = %x\n", __FUNCTION__, ptr->wpindex);
180 debug ("%s - chassis_num = %x\n", __FUNCTION__, ptr->chassis_num);
181
182 }
183}
184
185static void print_vg_info (void)
186{
187 struct rio_detail *ptr;
188 struct list_head *ptr1;
189 debug ("%s ---\n", __FUNCTION__);
190 list_for_each (ptr1, &rio_vg_head) {
191 ptr = list_entry (ptr1, struct rio_detail, rio_detail_list);
192 debug ("%s - rio_node_id = %x\n", __FUNCTION__, ptr->rio_node_id);
193 debug ("%s - rio_type = %x\n", __FUNCTION__, ptr->rio_type);
194 debug ("%s - owner_id = %x\n", __FUNCTION__, ptr->owner_id);
195 debug ("%s - first_slot_num = %x\n", __FUNCTION__, ptr->first_slot_num);
196 debug ("%s - wpindex = %x\n", __FUNCTION__, ptr->wpindex);
197 debug ("%s - chassis_num = %x\n", __FUNCTION__, ptr->chassis_num);
198
199 }
200}
201
202static void __init print_ebda_pci_rsrc (void)
203{
204 struct ebda_pci_rsrc *ptr;
205 struct list_head *ptr1;
206
207 list_for_each (ptr1, &ibmphp_ebda_pci_rsrc_head) {
208 ptr = list_entry (ptr1, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
209 debug ("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
210 __FUNCTION__, ptr->rsrc_type ,ptr->bus_num, ptr->dev_fun,ptr->start_addr, ptr->end_addr);
211 }
212}
213
214static void __init print_ibm_slot (void)
215{
216 struct slot *ptr;
217 struct list_head *ptr1;
218
219 list_for_each (ptr1, &ibmphp_slot_head) {
220 ptr = list_entry (ptr1, struct slot, ibm_slot_list);
221 debug ("%s - slot_number: %x\n", __FUNCTION__, ptr->number);
222 }
223}
224
225static void __init print_opt_vg (void)
226{
227 struct opt_rio *ptr;
228 struct list_head *ptr1;
229 debug ("%s ---\n", __FUNCTION__);
230 list_for_each (ptr1, &opt_vg_head) {
231 ptr = list_entry (ptr1, struct opt_rio, opt_rio_list);
232 debug ("%s - rio_type %x\n", __FUNCTION__, ptr->rio_type);
233 debug ("%s - chassis_num: %x\n", __FUNCTION__, ptr->chassis_num);
234 debug ("%s - first_slot_num: %x\n", __FUNCTION__, ptr->first_slot_num);
235 debug ("%s - middle_num: %x\n", __FUNCTION__, ptr->middle_num);
236 }
237}
238
239static void __init print_ebda_hpc (void)
240{
241 struct controller *hpc_ptr;
242 struct list_head *ptr1;
243 u16 index;
244
245 list_for_each (ptr1, &ebda_hpc_head) {
246
247 hpc_ptr = list_entry (ptr1, struct controller, ebda_hpc_list);
248
249 for (index = 0; index < hpc_ptr->slot_count; index++) {
250 debug ("%s - physical slot#: %x\n", __FUNCTION__, hpc_ptr->slots[index].slot_num);
251 debug ("%s - pci bus# of the slot: %x\n", __FUNCTION__, hpc_ptr->slots[index].slot_bus_num);
252 debug ("%s - index into ctlr addr: %x\n", __FUNCTION__, hpc_ptr->slots[index].ctl_index);
253 debug ("%s - cap of the slot: %x\n", __FUNCTION__, hpc_ptr->slots[index].slot_cap);
254 }
255
256 for (index = 0; index < hpc_ptr->bus_count; index++) {
257 debug ("%s - bus# of each bus controlled by this ctlr: %x\n", __FUNCTION__, hpc_ptr->buses[index].bus_num);
258 }
259
260 debug ("%s - type of hpc: %x\n", __FUNCTION__, hpc_ptr->ctlr_type);
261 switch (hpc_ptr->ctlr_type) {
262 case 1:
263 debug ("%s - bus: %x\n", __FUNCTION__, hpc_ptr->u.pci_ctlr.bus);
264 debug ("%s - dev_fun: %x\n", __FUNCTION__, hpc_ptr->u.pci_ctlr.dev_fun);
265 debug ("%s - irq: %x\n", __FUNCTION__, hpc_ptr->irq);
266 break;
267
268 case 0:
269 debug ("%s - io_start: %x\n", __FUNCTION__, hpc_ptr->u.isa_ctlr.io_start);
270 debug ("%s - io_end: %x\n", __FUNCTION__, hpc_ptr->u.isa_ctlr.io_end);
271 debug ("%s - irq: %x\n", __FUNCTION__, hpc_ptr->irq);
272 break;
273
274 case 2:
275 case 4:
276 debug ("%s - wpegbbar: %lx\n", __FUNCTION__, hpc_ptr->u.wpeg_ctlr.wpegbbar);
277 debug ("%s - i2c_addr: %x\n", __FUNCTION__, hpc_ptr->u.wpeg_ctlr.i2c_addr);
278 debug ("%s - irq: %x\n", __FUNCTION__, hpc_ptr->irq);
279 break;
280 }
281 }
282}
283
284int __init ibmphp_access_ebda (void)
285{
286 u8 format, num_ctlrs, rio_complete, hs_complete;
287 u16 ebda_seg, num_entries, next_offset, offset, blk_id, sub_addr, re, rc_id, re_id, base;
288 int rc = 0;
289
290
291 rio_complete = 0;
292 hs_complete = 0;
293
294 io_mem = ioremap ((0x40 << 4) + 0x0e, 2);
295 if (!io_mem )
296 return -ENOMEM;
297 ebda_seg = readw (io_mem);
298 iounmap (io_mem);
299 debug ("returned ebda segment: %x\n", ebda_seg);
300
301 io_mem = ioremap (ebda_seg<<4, 65000);
302 if (!io_mem )
303 return -ENOMEM;
304 next_offset = 0x180;
305
306 for (;;) {
307 offset = next_offset;
308 next_offset = readw (io_mem + offset); /* offset of next blk */
309
310 offset += 2;
311 if (next_offset == 0) /* 0 indicate it's last blk */
312 break;
313 blk_id = readw (io_mem + offset); /* this blk id */
314
315 offset += 2;
316 /* check if it is hot swap block or rio block */
317 if (blk_id != 0x4853 && blk_id != 0x4752)
318 continue;
319 /* found hs table */
320 if (blk_id == 0x4853) {
321 debug ("now enter hot swap block---\n");
322 debug ("hot blk id: %x\n", blk_id);
323 format = readb (io_mem + offset);
324
325 offset += 1;
326 if (format != 4)
327 goto error_nodev;
328 debug ("hot blk format: %x\n", format);
329 /* hot swap sub blk */
330 base = offset;
331
332 sub_addr = base;
333 re = readw (io_mem + sub_addr); /* next sub blk */
334
335 sub_addr += 2;
336 rc_id = readw (io_mem + sub_addr); /* sub blk id */
337
338 sub_addr += 2;
339 if (rc_id != 0x5243)
340 goto error_nodev;
341 /* rc sub blk signature */
342 num_ctlrs = readb (io_mem + sub_addr);
343
344 sub_addr += 1;
345 hpc_list_ptr = alloc_ebda_hpc_list ();
346 if (!hpc_list_ptr) {
347 rc = -ENOMEM;
348 goto out;
349 }
350 hpc_list_ptr->format = format;
351 hpc_list_ptr->num_ctlrs = num_ctlrs;
352 hpc_list_ptr->phys_addr = sub_addr; /* offset of RSRC_CONTROLLER blk */
353 debug ("info about hpc descriptor---\n");
354 debug ("hot blk format: %x\n", format);
355 debug ("num of controller: %x\n", num_ctlrs);
356 debug ("offset of hpc data structure enteries: %x\n ", sub_addr);
357
358 sub_addr = base + re; /* re sub blk */
359 /* FIXME: rc is never used/checked */
360 rc = readw (io_mem + sub_addr); /* next sub blk */
361
362 sub_addr += 2;
363 re_id = readw (io_mem + sub_addr); /* sub blk id */
364
365 sub_addr += 2;
366 if (re_id != 0x5245)
367 goto error_nodev;
368
369 /* signature of re */
370 num_entries = readw (io_mem + sub_addr);
371
372 sub_addr += 2; /* offset of RSRC_ENTRIES blk */
373 rsrc_list_ptr = alloc_ebda_rsrc_list ();
374 if (!rsrc_list_ptr ) {
375 rc = -ENOMEM;
376 goto out;
377 }
378 rsrc_list_ptr->format = format;
379 rsrc_list_ptr->num_entries = num_entries;
380 rsrc_list_ptr->phys_addr = sub_addr;
381
382 debug ("info about rsrc descriptor---\n");
383 debug ("format: %x\n", format);
384 debug ("num of rsrc: %x\n", num_entries);
385 debug ("offset of rsrc data structure enteries: %x\n ", sub_addr);
386
387 hs_complete = 1;
388 } else {
389 /* found rio table, blk_id == 0x4752 */
390 debug ("now enter io table ---\n");
391 debug ("rio blk id: %x\n", blk_id);
392
393 rio_table_ptr = kmalloc (sizeof (struct rio_table_hdr), GFP_KERNEL);
394 if (!rio_table_ptr)
395 return -ENOMEM;
396 memset (rio_table_ptr, 0, sizeof (struct rio_table_hdr) );
397 rio_table_ptr->ver_num = readb (io_mem + offset);
398 rio_table_ptr->scal_count = readb (io_mem + offset + 1);
399 rio_table_ptr->riodev_count = readb (io_mem + offset + 2);
400 rio_table_ptr->offset = offset +3 ;
401
402 debug("info about rio table hdr ---\n");
403 debug("ver_num: %x\nscal_count: %x\nriodev_count: %x\noffset of rio table: %x\n ",
404 rio_table_ptr->ver_num, rio_table_ptr->scal_count,
405 rio_table_ptr->riodev_count, rio_table_ptr->offset);
406
407 rio_complete = 1;
408 }
409 }
410
411 if (!hs_complete && !rio_complete)
412 goto error_nodev;
413
414 if (rio_table_ptr) {
415 if (rio_complete && rio_table_ptr->ver_num == 3) {
416 rc = ebda_rio_table ();
417 if (rc)
418 goto out;
419 }
420 }
421 rc = ebda_rsrc_controller ();
422 if (rc)
423 goto out;
424
425 rc = ebda_rsrc_rsrc ();
426 goto out;
427error_nodev:
428 rc = -ENODEV;
429out:
430 iounmap (io_mem);
431 return rc;
432}
433
434/*
435 * map info of scalability details and rio details from physical address
436 */
437static int __init ebda_rio_table (void)
438{
439 u16 offset;
440 u8 i;
441 struct rio_detail *rio_detail_ptr;
442
443 offset = rio_table_ptr->offset;
444 offset += 12 * rio_table_ptr->scal_count;
445
446 // we do concern about rio details
447 for (i = 0; i < rio_table_ptr->riodev_count; i++) {
448 rio_detail_ptr = kmalloc (sizeof (struct rio_detail), GFP_KERNEL);
449 if (!rio_detail_ptr)
450 return -ENOMEM;
451 memset (rio_detail_ptr, 0, sizeof (struct rio_detail));
452 rio_detail_ptr->rio_node_id = readb (io_mem + offset);
453 rio_detail_ptr->bbar = readl (io_mem + offset + 1);
454 rio_detail_ptr->rio_type = readb (io_mem + offset + 5);
455 rio_detail_ptr->owner_id = readb (io_mem + offset + 6);
456 rio_detail_ptr->port0_node_connect = readb (io_mem + offset + 7);
457 rio_detail_ptr->port0_port_connect = readb (io_mem + offset + 8);
458 rio_detail_ptr->port1_node_connect = readb (io_mem + offset + 9);
459 rio_detail_ptr->port1_port_connect = readb (io_mem + offset + 10);
460 rio_detail_ptr->first_slot_num = readb (io_mem + offset + 11);
461 rio_detail_ptr->status = readb (io_mem + offset + 12);
462 rio_detail_ptr->wpindex = readb (io_mem + offset + 13);
463 rio_detail_ptr->chassis_num = readb (io_mem + offset + 14);
464// debug ("rio_node_id: %x\nbbar: %x\nrio_type: %x\nowner_id: %x\nport0_node: %x\nport0_port: %x\nport1_node: %x\nport1_port: %x\nfirst_slot_num: %x\nstatus: %x\n", rio_detail_ptr->rio_node_id, rio_detail_ptr->bbar, rio_detail_ptr->rio_type, rio_detail_ptr->owner_id, rio_detail_ptr->port0_node_connect, rio_detail_ptr->port0_port_connect, rio_detail_ptr->port1_node_connect, rio_detail_ptr->port1_port_connect, rio_detail_ptr->first_slot_num, rio_detail_ptr->status);
465 //create linked list of chassis
466 if (rio_detail_ptr->rio_type == 4 || rio_detail_ptr->rio_type == 5)
467 list_add (&rio_detail_ptr->rio_detail_list, &rio_vg_head);
468 //create linked list of expansion box
469 else if (rio_detail_ptr->rio_type == 6 || rio_detail_ptr->rio_type == 7)
470 list_add (&rio_detail_ptr->rio_detail_list, &rio_lo_head);
471 else
472 // not in my concern
473 kfree (rio_detail_ptr);
474 offset += 15;
475 }
476 print_lo_info ();
477 print_vg_info ();
478 return 0;
479}
480
481/*
482 * reorganizing linked list of chassis
483 */
484static struct opt_rio *search_opt_vg (u8 chassis_num)
485{
486 struct opt_rio *ptr;
487 struct list_head *ptr1;
488 list_for_each (ptr1, &opt_vg_head) {
489 ptr = list_entry (ptr1, struct opt_rio, opt_rio_list);
490 if (ptr->chassis_num == chassis_num)
491 return ptr;
492 }
493 return NULL;
494}
495
496static int __init combine_wpg_for_chassis (void)
497{
498 struct opt_rio *opt_rio_ptr = NULL;
499 struct rio_detail *rio_detail_ptr = NULL;
500 struct list_head *list_head_ptr = NULL;
501
502 list_for_each (list_head_ptr, &rio_vg_head) {
503 rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
504 opt_rio_ptr = search_opt_vg (rio_detail_ptr->chassis_num);
505 if (!opt_rio_ptr) {
506 opt_rio_ptr = (struct opt_rio *) kmalloc (sizeof (struct opt_rio), GFP_KERNEL);
507 if (!opt_rio_ptr)
508 return -ENOMEM;
509 memset (opt_rio_ptr, 0, sizeof (struct opt_rio));
510 opt_rio_ptr->rio_type = rio_detail_ptr->rio_type;
511 opt_rio_ptr->chassis_num = rio_detail_ptr->chassis_num;
512 opt_rio_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
513 opt_rio_ptr->middle_num = rio_detail_ptr->first_slot_num;
514 list_add (&opt_rio_ptr->opt_rio_list, &opt_vg_head);
515 } else {
516 opt_rio_ptr->first_slot_num = min (opt_rio_ptr->first_slot_num, rio_detail_ptr->first_slot_num);
517 opt_rio_ptr->middle_num = max (opt_rio_ptr->middle_num, rio_detail_ptr->first_slot_num);
518 }
519 }
520 print_opt_vg ();
521 return 0;
522}
523
524/*
525 * reorgnizing linked list of expansion box
526 */
527static struct opt_rio_lo *search_opt_lo (u8 chassis_num)
528{
529 struct opt_rio_lo *ptr;
530 struct list_head *ptr1;
531 list_for_each (ptr1, &opt_lo_head) {
532 ptr = list_entry (ptr1, struct opt_rio_lo, opt_rio_lo_list);
533 if (ptr->chassis_num == chassis_num)
534 return ptr;
535 }
536 return NULL;
537}
538
539static int combine_wpg_for_expansion (void)
540{
541 struct opt_rio_lo *opt_rio_lo_ptr = NULL;
542 struct rio_detail *rio_detail_ptr = NULL;
543 struct list_head *list_head_ptr = NULL;
544
545 list_for_each (list_head_ptr, &rio_lo_head) {
546 rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
547 opt_rio_lo_ptr = search_opt_lo (rio_detail_ptr->chassis_num);
548 if (!opt_rio_lo_ptr) {
549 opt_rio_lo_ptr = (struct opt_rio_lo *) kmalloc (sizeof (struct opt_rio_lo), GFP_KERNEL);
550 if (!opt_rio_lo_ptr)
551 return -ENOMEM;
552 memset (opt_rio_lo_ptr, 0, sizeof (struct opt_rio_lo));
553 opt_rio_lo_ptr->rio_type = rio_detail_ptr->rio_type;
554 opt_rio_lo_ptr->chassis_num = rio_detail_ptr->chassis_num;
555 opt_rio_lo_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
556 opt_rio_lo_ptr->middle_num = rio_detail_ptr->first_slot_num;
557 opt_rio_lo_ptr->pack_count = 1;
558
559 list_add (&opt_rio_lo_ptr->opt_rio_lo_list, &opt_lo_head);
560 } else {
561 opt_rio_lo_ptr->first_slot_num = min (opt_rio_lo_ptr->first_slot_num, rio_detail_ptr->first_slot_num);
562 opt_rio_lo_ptr->middle_num = max (opt_rio_lo_ptr->middle_num, rio_detail_ptr->first_slot_num);
563 opt_rio_lo_ptr->pack_count = 2;
564 }
565 }
566 return 0;
567}
568
569
570/* Since we don't know the max slot number per each chassis, hence go
571 * through the list of all chassis to find out the range
572 * Arguments: slot_num, 1st slot number of the chassis we think we are on,
573 * var (0 = chassis, 1 = expansion box)
574 */
575static int first_slot_num (u8 slot_num, u8 first_slot, u8 var)
576{
577 struct opt_rio *opt_vg_ptr = NULL;
578 struct opt_rio_lo *opt_lo_ptr = NULL;
579 struct list_head *ptr = NULL;
580 int rc = 0;
581
582 if (!var) {
583 list_for_each (ptr, &opt_vg_head) {
584 opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list);
585 if ((first_slot < opt_vg_ptr->first_slot_num) && (slot_num >= opt_vg_ptr->first_slot_num)) {
586 rc = -ENODEV;
587 break;
588 }
589 }
590 } else {
591 list_for_each (ptr, &opt_lo_head) {
592 opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list);
593 if ((first_slot < opt_lo_ptr->first_slot_num) && (slot_num >= opt_lo_ptr->first_slot_num)) {
594 rc = -ENODEV;
595 break;
596 }
597 }
598 }
599 return rc;
600}
601
602static struct opt_rio_lo * find_rxe_num (u8 slot_num)
603{
604 struct opt_rio_lo *opt_lo_ptr;
605 struct list_head *ptr;
606
607 list_for_each (ptr, &opt_lo_head) {
608 opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list);
609 //check to see if this slot_num belongs to expansion box
610 if ((slot_num >= opt_lo_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_lo_ptr->first_slot_num, 1)))
611 return opt_lo_ptr;
612 }
613 return NULL;
614}
615
616static struct opt_rio * find_chassis_num (u8 slot_num)
617{
618 struct opt_rio *opt_vg_ptr;
619 struct list_head *ptr;
620
621 list_for_each (ptr, &opt_vg_head) {
622 opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list);
623 //check to see if this slot_num belongs to chassis
624 if ((slot_num >= opt_vg_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_vg_ptr->first_slot_num, 0)))
625 return opt_vg_ptr;
626 }
627 return NULL;
628}
629
630/* This routine will find out how many slots are in the chassis, so that
631 * the slot numbers for rxe100 would start from 1, and not from 7, or 6 etc
632 */
633static u8 calculate_first_slot (u8 slot_num)
634{
635 u8 first_slot = 1;
636 struct list_head * list;
637 struct slot * slot_cur;
638
639 list_for_each (list, &ibmphp_slot_head) {
640 slot_cur = list_entry (list, struct slot, ibm_slot_list);
641 if (slot_cur->ctrl) {
642 if ((slot_cur->ctrl->ctlr_type != 4) && (slot_cur->ctrl->ending_slot_num > first_slot) && (slot_num > slot_cur->ctrl->ending_slot_num))
643 first_slot = slot_cur->ctrl->ending_slot_num;
644 }
645 }
646 return first_slot + 1;
647
648}
649static char *create_file_name (struct slot * slot_cur)
650{
651 struct opt_rio *opt_vg_ptr = NULL;
652 struct opt_rio_lo *opt_lo_ptr = NULL;
653 static char str[30];
654 int which = 0; /* rxe = 1, chassis = 0 */
655 u8 number = 1; /* either chassis or rxe # */
656 u8 first_slot = 1;
657 u8 slot_num;
658 u8 flag = 0;
659
660 if (!slot_cur) {
661 err ("Structure passed is empty\n");
662 return NULL;
663 }
664
665 slot_num = slot_cur->number;
666
667 memset (str, 0, sizeof(str));
668
669 if (rio_table_ptr) {
670 if (rio_table_ptr->ver_num == 3) {
671 opt_vg_ptr = find_chassis_num (slot_num);
672 opt_lo_ptr = find_rxe_num (slot_num);
673 }
674 }
675 if (opt_vg_ptr) {
676 if (opt_lo_ptr) {
677 if ((slot_num - opt_vg_ptr->first_slot_num) > (slot_num - opt_lo_ptr->first_slot_num)) {
678 number = opt_lo_ptr->chassis_num;
679 first_slot = opt_lo_ptr->first_slot_num;
680 which = 1; /* it is RXE */
681 } else {
682 first_slot = opt_vg_ptr->first_slot_num;
683 number = opt_vg_ptr->chassis_num;
684 which = 0;
685 }
686 } else {
687 first_slot = opt_vg_ptr->first_slot_num;
688 number = opt_vg_ptr->chassis_num;
689 which = 0;
690 }
691 ++flag;
692 } else if (opt_lo_ptr) {
693 number = opt_lo_ptr->chassis_num;
694 first_slot = opt_lo_ptr->first_slot_num;
695 which = 1;
696 ++flag;
697 } else if (rio_table_ptr) {
698 if (rio_table_ptr->ver_num == 3) {
699 /* if both NULL and we DO have correct RIO table in BIOS */
700 return NULL;
701 }
702 }
703 if (!flag) {
704 if (slot_cur->ctrl->ctlr_type == 4) {
705 first_slot = calculate_first_slot (slot_num);
706 which = 1;
707 } else {
708 which = 0;
709 }
710 }
711
712 sprintf(str, "%s%dslot%d",
713 which == 0 ? "chassis" : "rxe",
714 number, slot_num - first_slot + 1);
715 return str;
716}
717
718static int fillslotinfo(struct hotplug_slot *hotplug_slot)
719{
720 struct slot *slot;
721 int rc = 0;
722
723 if (!hotplug_slot || !hotplug_slot->private)
724 return -EINVAL;
725
726 slot = hotplug_slot->private;
727 rc = ibmphp_hpc_readslot(slot, READ_ALLSTAT, NULL);
728 if (rc)
729 return rc;
730
731 // power - enabled:1 not:0
732 hotplug_slot->info->power_status = SLOT_POWER(slot->status);
733
734 // attention - off:0, on:1, blinking:2
735 hotplug_slot->info->attention_status = SLOT_ATTN(slot->status, slot->ext_status);
736
737 // latch - open:1 closed:0
738 hotplug_slot->info->latch_status = SLOT_LATCH(slot->status);
739
740 // pci board - present:1 not:0
741 if (SLOT_PRESENT (slot->status))
742 hotplug_slot->info->adapter_status = 1;
743 else
744 hotplug_slot->info->adapter_status = 0;
745/*
746 if (slot->bus_on->supported_bus_mode
747 && (slot->bus_on->supported_speed == BUS_SPEED_66))
748 hotplug_slot->info->max_bus_speed_status = BUS_SPEED_66PCIX;
749 else
750 hotplug_slot->info->max_bus_speed_status = slot->bus_on->supported_speed;
751*/
752
753 return rc;
754}
755
756static void release_slot(struct hotplug_slot *hotplug_slot)
757{
758 struct slot *slot;
759
760 if (!hotplug_slot || !hotplug_slot->private)
761 return;
762
763 slot = hotplug_slot->private;
764 kfree(slot->hotplug_slot->info);
765 kfree(slot->hotplug_slot->name);
766 kfree(slot->hotplug_slot);
767 slot->ctrl = NULL;
768 slot->bus_on = NULL;
769
770 /* we don't want to actually remove the resources, since free_resources will do just that */
771 ibmphp_unconfigure_card(&slot, -1);
772
773 kfree (slot);
774}
775
776static struct pci_driver ibmphp_driver;
777
778/*
779 * map info (ctlr-id, slot count, slot#.. bus count, bus#, ctlr type...) of
780 * each hpc from physical address to a list of hot plug controllers based on
781 * hpc descriptors.
782 */
783static int __init ebda_rsrc_controller (void)
784{
785 u16 addr, addr_slot, addr_bus;
786 u8 ctlr_id, temp, bus_index;
787 u16 ctlr, slot, bus;
788 u16 slot_num, bus_num, index;
789 struct hotplug_slot *hp_slot_ptr;
790 struct controller *hpc_ptr;
791 struct ebda_hpc_bus *bus_ptr;
792 struct ebda_hpc_slot *slot_ptr;
793 struct bus_info *bus_info_ptr1, *bus_info_ptr2;
794 int rc;
795 struct slot *tmp_slot;
796 struct list_head *list;
797
798 addr = hpc_list_ptr->phys_addr;
799 for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) {
800 bus_index = 1;
801 ctlr_id = readb (io_mem + addr);
802 addr += 1;
803 slot_num = readb (io_mem + addr);
804
805 addr += 1;
806 addr_slot = addr; /* offset of slot structure */
807 addr += (slot_num * 4);
808
809 bus_num = readb (io_mem + addr);
810
811 addr += 1;
812 addr_bus = addr; /* offset of bus */
813 addr += (bus_num * 9); /* offset of ctlr_type */
814 temp = readb (io_mem + addr);
815
816 addr += 1;
817 /* init hpc structure */
818 hpc_ptr = alloc_ebda_hpc (slot_num, bus_num);
819 if (!hpc_ptr ) {
820 rc = -ENOMEM;
821 goto error_no_hpc;
822 }
823 hpc_ptr->ctlr_id = ctlr_id;
824 hpc_ptr->ctlr_relative_id = ctlr;
825 hpc_ptr->slot_count = slot_num;
826 hpc_ptr->bus_count = bus_num;
827 debug ("now enter ctlr data struture ---\n");
828 debug ("ctlr id: %x\n", ctlr_id);
829 debug ("ctlr_relative_id: %x\n", hpc_ptr->ctlr_relative_id);
830 debug ("count of slots controlled by this ctlr: %x\n", slot_num);
831 debug ("count of buses controlled by this ctlr: %x\n", bus_num);
832
833 /* init slot structure, fetch slot, bus, cap... */
834 slot_ptr = hpc_ptr->slots;
835 for (slot = 0; slot < slot_num; slot++) {
836 slot_ptr->slot_num = readb (io_mem + addr_slot);
837 slot_ptr->slot_bus_num = readb (io_mem + addr_slot + slot_num);
838 slot_ptr->ctl_index = readb (io_mem + addr_slot + 2*slot_num);
839 slot_ptr->slot_cap = readb (io_mem + addr_slot + 3*slot_num);
840
841 // create bus_info lined list --- if only one slot per bus: slot_min = slot_max
842
843 bus_info_ptr2 = ibmphp_find_same_bus_num (slot_ptr->slot_bus_num);
844 if (!bus_info_ptr2) {
845 bus_info_ptr1 = (struct bus_info *) kmalloc (sizeof (struct bus_info), GFP_KERNEL);
846 if (!bus_info_ptr1) {
847 rc = -ENOMEM;
848 goto error_no_hp_slot;
849 }
850 memset (bus_info_ptr1, 0, sizeof (struct bus_info));
851 bus_info_ptr1->slot_min = slot_ptr->slot_num;
852 bus_info_ptr1->slot_max = slot_ptr->slot_num;
853 bus_info_ptr1->slot_count += 1;
854 bus_info_ptr1->busno = slot_ptr->slot_bus_num;
855 bus_info_ptr1->index = bus_index++;
856 bus_info_ptr1->current_speed = 0xff;
857 bus_info_ptr1->current_bus_mode = 0xff;
858
859 bus_info_ptr1->controller_id = hpc_ptr->ctlr_id;
860
861 list_add_tail (&bus_info_ptr1->bus_info_list, &bus_info_head);
862
863 } else {
864 bus_info_ptr2->slot_min = min (bus_info_ptr2->slot_min, slot_ptr->slot_num);
865 bus_info_ptr2->slot_max = max (bus_info_ptr2->slot_max, slot_ptr->slot_num);
866 bus_info_ptr2->slot_count += 1;
867
868 }
869
870 // end of creating the bus_info linked list
871
872 slot_ptr++;
873 addr_slot += 1;
874 }
875
876 /* init bus structure */
877 bus_ptr = hpc_ptr->buses;
878 for (bus = 0; bus < bus_num; bus++) {
879 bus_ptr->bus_num = readb (io_mem + addr_bus + bus);
880 bus_ptr->slots_at_33_conv = readb (io_mem + addr_bus + bus_num + 8 * bus);
881 bus_ptr->slots_at_66_conv = readb (io_mem + addr_bus + bus_num + 8 * bus + 1);
882
883 bus_ptr->slots_at_66_pcix = readb (io_mem + addr_bus + bus_num + 8 * bus + 2);
884
885 bus_ptr->slots_at_100_pcix = readb (io_mem + addr_bus + bus_num + 8 * bus + 3);
886
887 bus_ptr->slots_at_133_pcix = readb (io_mem + addr_bus + bus_num + 8 * bus + 4);
888
889 bus_info_ptr2 = ibmphp_find_same_bus_num (bus_ptr->bus_num);
890 if (bus_info_ptr2) {
891 bus_info_ptr2->slots_at_33_conv = bus_ptr->slots_at_33_conv;
892 bus_info_ptr2->slots_at_66_conv = bus_ptr->slots_at_66_conv;
893 bus_info_ptr2->slots_at_66_pcix = bus_ptr->slots_at_66_pcix;
894 bus_info_ptr2->slots_at_100_pcix = bus_ptr->slots_at_100_pcix;
895 bus_info_ptr2->slots_at_133_pcix = bus_ptr->slots_at_133_pcix;
896 }
897 bus_ptr++;
898 }
899
900 hpc_ptr->ctlr_type = temp;
901
902 switch (hpc_ptr->ctlr_type) {
903 case 1:
904 hpc_ptr->u.pci_ctlr.bus = readb (io_mem + addr);
905 hpc_ptr->u.pci_ctlr.dev_fun = readb (io_mem + addr + 1);
906 hpc_ptr->irq = readb (io_mem + addr + 2);
907 addr += 3;
908 debug ("ctrl bus = %x, ctlr devfun = %x, irq = %x\n",
909 hpc_ptr->u.pci_ctlr.bus,
910 hpc_ptr->u.pci_ctlr.dev_fun, hpc_ptr->irq);
911 break;
912
913 case 0:
914 hpc_ptr->u.isa_ctlr.io_start = readw (io_mem + addr);
915 hpc_ptr->u.isa_ctlr.io_end = readw (io_mem + addr + 2);
916 if (!request_region (hpc_ptr->u.isa_ctlr.io_start,
917 (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1),
918 "ibmphp")) {
919 rc = -ENODEV;
920 goto error_no_hp_slot;
921 }
922 hpc_ptr->irq = readb (io_mem + addr + 4);
923 addr += 5;
924 break;
925
926 case 2:
927 case 4:
928 hpc_ptr->u.wpeg_ctlr.wpegbbar = readl (io_mem + addr);
929 hpc_ptr->u.wpeg_ctlr.i2c_addr = readb (io_mem + addr + 4);
930 hpc_ptr->irq = readb (io_mem + addr + 5);
931 addr += 6;
932 break;
933 default:
934 rc = -ENODEV;
935 goto error_no_hp_slot;
936 }
937
938 //reorganize chassis' linked list
939 combine_wpg_for_chassis ();
940 combine_wpg_for_expansion ();
941 hpc_ptr->revision = 0xff;
942 hpc_ptr->options = 0xff;
943 hpc_ptr->starting_slot_num = hpc_ptr->slots[0].slot_num;
944 hpc_ptr->ending_slot_num = hpc_ptr->slots[slot_num-1].slot_num;
945
946 // register slots with hpc core as well as create linked list of ibm slot
947 for (index = 0; index < hpc_ptr->slot_count; index++) {
948
949 hp_slot_ptr = kmalloc(sizeof(*hp_slot_ptr), GFP_KERNEL);
950 if (!hp_slot_ptr) {
951 rc = -ENOMEM;
952 goto error_no_hp_slot;
953 }
954 memset(hp_slot_ptr, 0, sizeof(*hp_slot_ptr));
955
956 hp_slot_ptr->info = kmalloc (sizeof(struct hotplug_slot_info), GFP_KERNEL);
957 if (!hp_slot_ptr->info) {
958 rc = -ENOMEM;
959 goto error_no_hp_info;
960 }
961 memset(hp_slot_ptr->info, 0, sizeof(struct hotplug_slot_info));
962
963 hp_slot_ptr->name = kmalloc(30, GFP_KERNEL);
964 if (!hp_slot_ptr->name) {
965 rc = -ENOMEM;
966 goto error_no_hp_name;
967 }
968
969 tmp_slot = kmalloc(sizeof(*tmp_slot), GFP_KERNEL);
970 if (!tmp_slot) {
971 rc = -ENOMEM;
972 goto error_no_slot;
973 }
974 memset(tmp_slot, 0, sizeof(*tmp_slot));
975
976 tmp_slot->flag = TRUE;
977
978 tmp_slot->capabilities = hpc_ptr->slots[index].slot_cap;
979 if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_133_MAX) == EBDA_SLOT_133_MAX)
980 tmp_slot->supported_speed = 3;
981 else if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_100_MAX) == EBDA_SLOT_100_MAX)
982 tmp_slot->supported_speed = 2;
983 else if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_66_MAX) == EBDA_SLOT_66_MAX)
984 tmp_slot->supported_speed = 1;
985
986 if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_PCIX_CAP) == EBDA_SLOT_PCIX_CAP)
987 tmp_slot->supported_bus_mode = 1;
988 else
989 tmp_slot->supported_bus_mode = 0;
990
991
992 tmp_slot->bus = hpc_ptr->slots[index].slot_bus_num;
993
994 bus_info_ptr1 = ibmphp_find_same_bus_num (hpc_ptr->slots[index].slot_bus_num);
995 if (!bus_info_ptr1) {
996 rc = -ENODEV;
997 goto error;
998 }
999 tmp_slot->bus_on = bus_info_ptr1;
1000 bus_info_ptr1 = NULL;
1001 tmp_slot->ctrl = hpc_ptr;
1002
1003 tmp_slot->ctlr_index = hpc_ptr->slots[index].ctl_index;
1004 tmp_slot->number = hpc_ptr->slots[index].slot_num;
1005 tmp_slot->hotplug_slot = hp_slot_ptr;
1006
1007 hp_slot_ptr->private = tmp_slot;
1008 hp_slot_ptr->release = release_slot;
1009
1010 rc = fillslotinfo(hp_slot_ptr);
1011 if (rc)
1012 goto error;
1013
1014 rc = ibmphp_init_devno ((struct slot **) &hp_slot_ptr->private);
1015 if (rc)
1016 goto error;
1017 hp_slot_ptr->ops = &ibmphp_hotplug_slot_ops;
1018
1019 // end of registering ibm slot with hotplug core
1020
1021 list_add (& ((struct slot *)(hp_slot_ptr->private))->ibm_slot_list, &ibmphp_slot_head);
1022 }
1023
1024 print_bus_info ();
1025 list_add (&hpc_ptr->ebda_hpc_list, &ebda_hpc_head );
1026
1027 } /* each hpc */
1028
1029 list_for_each (list, &ibmphp_slot_head) {
1030 tmp_slot = list_entry (list, struct slot, ibm_slot_list);
1031
1032 snprintf (tmp_slot->hotplug_slot->name, 30, "%s", create_file_name (tmp_slot));
1033 pci_hp_register (tmp_slot->hotplug_slot);
1034 }
1035
1036 print_ebda_hpc ();
1037 print_ibm_slot ();
1038 return 0;
1039
1040error:
1041 kfree (hp_slot_ptr->private);
1042error_no_slot:
1043 kfree (hp_slot_ptr->name);
1044error_no_hp_name:
1045 kfree (hp_slot_ptr->info);
1046error_no_hp_info:
1047 kfree (hp_slot_ptr);
1048error_no_hp_slot:
1049 free_ebda_hpc (hpc_ptr);
1050error_no_hpc:
1051 iounmap (io_mem);
1052 return rc;
1053}
1054
1055/*
1056 * map info (bus, devfun, start addr, end addr..) of i/o, memory,
1057 * pfm from the physical addr to a list of resource.
1058 */
1059static int __init ebda_rsrc_rsrc (void)
1060{
1061 u16 addr;
1062 short rsrc;
1063 u8 type, rsrc_type;
1064 struct ebda_pci_rsrc *rsrc_ptr;
1065
1066 addr = rsrc_list_ptr->phys_addr;
1067 debug ("now entering rsrc land\n");
1068 debug ("offset of rsrc: %x\n", rsrc_list_ptr->phys_addr);
1069
1070 for (rsrc = 0; rsrc < rsrc_list_ptr->num_entries; rsrc++) {
1071 type = readb (io_mem + addr);
1072
1073 addr += 1;
1074 rsrc_type = type & EBDA_RSRC_TYPE_MASK;
1075
1076 if (rsrc_type == EBDA_IO_RSRC_TYPE) {
1077 rsrc_ptr = alloc_ebda_pci_rsrc ();
1078 if (!rsrc_ptr) {
1079 iounmap (io_mem);
1080 return -ENOMEM;
1081 }
1082 rsrc_ptr->rsrc_type = type;
1083
1084 rsrc_ptr->bus_num = readb (io_mem + addr);
1085 rsrc_ptr->dev_fun = readb (io_mem + addr + 1);
1086 rsrc_ptr->start_addr = readw (io_mem + addr + 2);
1087 rsrc_ptr->end_addr = readw (io_mem + addr + 4);
1088 addr += 6;
1089
1090 debug ("rsrc from io type ----\n");
1091 debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
1092 rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);
1093
1094 list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
1095 }
1096
1097 if (rsrc_type == EBDA_MEM_RSRC_TYPE || rsrc_type == EBDA_PFM_RSRC_TYPE) {
1098 rsrc_ptr = alloc_ebda_pci_rsrc ();
1099 if (!rsrc_ptr ) {
1100 iounmap (io_mem);
1101 return -ENOMEM;
1102 }
1103 rsrc_ptr->rsrc_type = type;
1104
1105 rsrc_ptr->bus_num = readb (io_mem + addr);
1106 rsrc_ptr->dev_fun = readb (io_mem + addr + 1);
1107 rsrc_ptr->start_addr = readl (io_mem + addr + 2);
1108 rsrc_ptr->end_addr = readl (io_mem + addr + 6);
1109 addr += 10;
1110
1111 debug ("rsrc from mem or pfm ---\n");
1112 debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
1113 rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);
1114
1115 list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
1116 }
1117 }
1118 kfree (rsrc_list_ptr);
1119 rsrc_list_ptr = NULL;
1120 print_ebda_pci_rsrc ();
1121 return 0;
1122}
1123
1124u16 ibmphp_get_total_controllers (void)
1125{
1126 return hpc_list_ptr->num_ctlrs;
1127}
1128
1129struct slot *ibmphp_get_slot_from_physical_num (u8 physical_num)
1130{
1131 struct slot *slot;
1132 struct list_head *list;
1133
1134 list_for_each (list, &ibmphp_slot_head) {
1135 slot = list_entry (list, struct slot, ibm_slot_list);
1136 if (slot->number == physical_num)
1137 return slot;
1138 }
1139 return NULL;
1140}
1141
1142/* To find:
1143 * - the smallest slot number
1144 * - the largest slot number
1145 * - the total number of the slots based on each bus
1146 * (if only one slot per bus slot_min = slot_max )
1147 */
1148struct bus_info *ibmphp_find_same_bus_num (u32 num)
1149{
1150 struct bus_info *ptr;
1151 struct list_head *ptr1;
1152
1153 list_for_each (ptr1, &bus_info_head) {
1154 ptr = list_entry (ptr1, struct bus_info, bus_info_list);
1155 if (ptr->busno == num)
1156 return ptr;
1157 }
1158 return NULL;
1159}
1160
1161/* Finding relative bus number, in order to map corresponding
1162 * bus register
1163 */
1164int ibmphp_get_bus_index (u8 num)
1165{
1166 struct bus_info *ptr;
1167 struct list_head *ptr1;
1168
1169 list_for_each (ptr1, &bus_info_head) {
1170 ptr = list_entry (ptr1, struct bus_info, bus_info_list);
1171 if (ptr->busno == num)
1172 return ptr->index;
1173 }
1174 return -ENODEV;
1175}
1176
1177void ibmphp_free_bus_info_queue (void)
1178{
1179 struct bus_info *bus_info;
1180 struct list_head *list;
1181 struct list_head *next;
1182
1183 list_for_each_safe (list, next, &bus_info_head ) {
1184 bus_info = list_entry (list, struct bus_info, bus_info_list);
1185 kfree (bus_info);
1186 }
1187}
1188
1189void ibmphp_free_ebda_hpc_queue (void)
1190{
1191 struct controller *controller = NULL;
1192 struct list_head *list;
1193 struct list_head *next;
1194 int pci_flag = 0;
1195
1196 list_for_each_safe (list, next, &ebda_hpc_head) {
1197 controller = list_entry (list, struct controller, ebda_hpc_list);
1198 if (controller->ctlr_type == 0)
1199 release_region (controller->u.isa_ctlr.io_start, (controller->u.isa_ctlr.io_end - controller->u.isa_ctlr.io_start + 1));
1200 else if ((controller->ctlr_type == 1) && (!pci_flag)) {
1201 ++pci_flag;
1202 pci_unregister_driver (&ibmphp_driver);
1203 }
1204 free_ebda_hpc (controller);
1205 }
1206}
1207
1208void ibmphp_free_ebda_pci_rsrc_queue (void)
1209{
1210 struct ebda_pci_rsrc *resource;
1211 struct list_head *list;
1212 struct list_head *next;
1213
1214 list_for_each_safe (list, next, &ibmphp_ebda_pci_rsrc_head) {
1215 resource = list_entry (list, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
1216 kfree (resource);
1217 resource = NULL;
1218 }
1219}
1220
1221static struct pci_device_id id_table[] = {
1222 {
1223 .vendor = PCI_VENDOR_ID_IBM,
1224 .device = HPC_DEVICE_ID,
1225 .subvendor = PCI_VENDOR_ID_IBM,
1226 .subdevice = HPC_SUBSYSTEM_ID,
1227 .class = ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
1228 }, {}
1229};
1230
1231MODULE_DEVICE_TABLE(pci, id_table);
1232
1233static int ibmphp_probe (struct pci_dev *, const struct pci_device_id *);
1234static struct pci_driver ibmphp_driver = {
1235 .name = "ibmphp",
1236 .id_table = id_table,
1237 .probe = ibmphp_probe,
1238};
1239
1240int ibmphp_register_pci (void)
1241{
1242 struct controller *ctrl;
1243 struct list_head *tmp;
1244 int rc = 0;
1245
1246 list_for_each (tmp, &ebda_hpc_head) {
1247 ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
1248 if (ctrl->ctlr_type == 1) {
1249 rc = pci_register_driver(&ibmphp_driver);
1250 break;
1251 }
1252 }
1253 return rc;
1254}
1255static int ibmphp_probe (struct pci_dev * dev, const struct pci_device_id *ids)
1256{
1257 struct controller *ctrl;
1258 struct list_head *tmp;
1259
1260 debug ("inside ibmphp_probe\n");
1261
1262 list_for_each (tmp, &ebda_hpc_head) {
1263 ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
1264 if (ctrl->ctlr_type == 1) {
1265 if ((dev->devfn == ctrl->u.pci_ctlr.dev_fun) && (dev->bus->number == ctrl->u.pci_ctlr.bus)) {
1266 ctrl->ctrl_dev = dev;
1267 debug ("found device!!!\n");
1268 debug ("dev->device = %x, dev->subsystem_device = %x\n", dev->device, dev->subsystem_device);
1269 return 0;
1270 }
1271 }
1272 }
1273 return -ENODEV;
1274}
1275
diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c
new file mode 100644
index 000000000000..6894b548c8ca
--- /dev/null
+++ b/drivers/pci/hotplug/ibmphp_hpc.c
@@ -0,0 +1,1161 @@
1/*
2 * IBM Hot Plug Controller Driver
3 *
4 * Written By: Jyoti Shah, IBM Corporation
5 *
6 * Copyright (C) 2001-2003 IBM Corp.
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <gregkh@us.ibm.com>
26 * <jshah@us.ibm.com>
27 *
28 */
29
30#include <linux/wait.h>
31#include <linux/time.h>
32#include <linux/delay.h>
33#include <linux/module.h>
34#include <linux/pci.h>
35#include <linux/smp_lock.h>
36#include <linux/init.h>
37#include "ibmphp.h"
38
39static int to_debug = FALSE;
40#define debug_polling(fmt, arg...) do { if (to_debug) debug (fmt, arg); } while (0)
41
42//----------------------------------------------------------------------------
43// timeout values
44//----------------------------------------------------------------------------
45#define CMD_COMPLETE_TOUT_SEC 60 // give HPC 60 sec to finish cmd
46#define HPC_CTLR_WORKING_TOUT 60 // give HPC 60 sec to finish cmd
47#define HPC_GETACCESS_TIMEOUT 60 // seconds
48#define POLL_INTERVAL_SEC 2 // poll HPC every 2 seconds
49#define POLL_LATCH_CNT 5 // poll latch 5 times, then poll slots
50
51//----------------------------------------------------------------------------
52// Winnipeg Architected Register Offsets
53//----------------------------------------------------------------------------
54#define WPG_I2CMBUFL_OFFSET 0x08 // I2C Message Buffer Low
55#define WPG_I2CMOSUP_OFFSET 0x10 // I2C Master Operation Setup Reg
56#define WPG_I2CMCNTL_OFFSET 0x20 // I2C Master Control Register
57#define WPG_I2CPARM_OFFSET 0x40 // I2C Parameter Register
58#define WPG_I2CSTAT_OFFSET 0x70 // I2C Status Register
59
60//----------------------------------------------------------------------------
61// Winnipeg Store Type commands (Add this commands to the register offset)
62//----------------------------------------------------------------------------
63#define WPG_I2C_AND 0x1000 // I2C AND operation
64#define WPG_I2C_OR 0x2000 // I2C OR operation
65
66//----------------------------------------------------------------------------
67// Command set for I2C Master Operation Setup Regisetr
68//----------------------------------------------------------------------------
69#define WPG_READATADDR_MASK 0x00010000 // read,bytes,I2C shifted,index
70#define WPG_WRITEATADDR_MASK 0x40010000 // write,bytes,I2C shifted,index
71#define WPG_READDIRECT_MASK 0x10010000
72#define WPG_WRITEDIRECT_MASK 0x60010000
73
74
75//----------------------------------------------------------------------------
76// bit masks for I2C Master Control Register
77//----------------------------------------------------------------------------
78#define WPG_I2CMCNTL_STARTOP_MASK 0x00000002 // Start the Operation
79
80//----------------------------------------------------------------------------
81//
82//----------------------------------------------------------------------------
83#define WPG_I2C_IOREMAP_SIZE 0x2044 // size of linear address interval
84
85//----------------------------------------------------------------------------
86// command index
87//----------------------------------------------------------------------------
88#define WPG_1ST_SLOT_INDEX 0x01 // index - 1st slot for ctlr
89#define WPG_CTLR_INDEX 0x0F // index - ctlr
90#define WPG_1ST_EXTSLOT_INDEX 0x10 // index - 1st ext slot for ctlr
91#define WPG_1ST_BUS_INDEX 0x1F // index - 1st bus for ctlr
92
93//----------------------------------------------------------------------------
94// macro utilities
95//----------------------------------------------------------------------------
96// if bits 20,22,25,26,27,29,30 are OFF return TRUE
97#define HPC_I2CSTATUS_CHECK(s) ((u8)((s & 0x00000A76) ? FALSE : TRUE))
98
99//----------------------------------------------------------------------------
100// global variables
101//----------------------------------------------------------------------------
102static int ibmphp_shutdown;
103static int tid_poll;
104static struct semaphore sem_hpcaccess; // lock access to HPC
105static struct semaphore semOperations; // lock all operations and
106 // access to data structures
107static struct semaphore sem_exit; // make sure polling thread goes away
108//----------------------------------------------------------------------------
109// local function prototypes
110//----------------------------------------------------------------------------
111static u8 i2c_ctrl_read (struct controller *, void __iomem *, u8);
112static u8 i2c_ctrl_write (struct controller *, void __iomem *, u8, u8);
113static u8 hpc_writecmdtoindex (u8, u8);
114static u8 hpc_readcmdtoindex (u8, u8);
115static void get_hpc_access (void);
116static void free_hpc_access (void);
117static void poll_hpc (void);
118static int process_changeinstatus (struct slot *, struct slot *);
119static int process_changeinlatch (u8, u8, struct controller *);
120static int hpc_poll_thread (void *);
121static int hpc_wait_ctlr_notworking (int, struct controller *, void __iomem *, u8 *);
122//----------------------------------------------------------------------------
123
124
125/*----------------------------------------------------------------------
126* Name: ibmphp_hpc_initvars
127*
128* Action: initialize semaphores and variables
129*---------------------------------------------------------------------*/
130void __init ibmphp_hpc_initvars (void)
131{
132 debug ("%s - Entry\n", __FUNCTION__);
133
134 init_MUTEX (&sem_hpcaccess);
135 init_MUTEX (&semOperations);
136 init_MUTEX_LOCKED (&sem_exit);
137 to_debug = FALSE;
138 ibmphp_shutdown = FALSE;
139 tid_poll = 0;
140
141 debug ("%s - Exit\n", __FUNCTION__);
142}
143
144/*----------------------------------------------------------------------
145* Name: i2c_ctrl_read
146*
147* Action: read from HPC over I2C
148*
149*---------------------------------------------------------------------*/
150static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index)
151{
152 u8 status;
153 int i;
154 void __iomem *wpg_addr; // base addr + offset
155 unsigned long wpg_data; // data to/from WPG LOHI format
156 unsigned long ultemp;
157 unsigned long data; // actual data HILO format
158
159 debug_polling ("%s - Entry WPGBbar[%p] index[%x] \n", __FUNCTION__, WPGBbar, index);
160
161 //--------------------------------------------------------------------
162 // READ - step 1
163 // read at address, byte length, I2C address (shifted), index
164 // or read direct, byte length, index
165 if (ctlr_ptr->ctlr_type == 0x02) {
166 data = WPG_READATADDR_MASK;
167 // fill in I2C address
168 ultemp = (unsigned long)ctlr_ptr->u.wpeg_ctlr.i2c_addr;
169 ultemp = ultemp >> 1;
170 data |= (ultemp << 8);
171
172 // fill in index
173 data |= (unsigned long)index;
174 } else if (ctlr_ptr->ctlr_type == 0x04) {
175 data = WPG_READDIRECT_MASK;
176
177 // fill in index
178 ultemp = (unsigned long)index;
179 ultemp = ultemp << 8;
180 data |= ultemp;
181 } else {
182 err ("this controller type is not supported \n");
183 return HPC_ERROR;
184 }
185
186 wpg_data = swab32 (data); // swap data before writing
187 wpg_addr = WPGBbar + WPG_I2CMOSUP_OFFSET;
188 writel (wpg_data, wpg_addr);
189
190 //--------------------------------------------------------------------
191 // READ - step 2 : clear the message buffer
192 data = 0x00000000;
193 wpg_data = swab32 (data);
194 wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;
195 writel (wpg_data, wpg_addr);
196
197 //--------------------------------------------------------------------
198 // READ - step 3 : issue start operation, I2C master control bit 30:ON
199 // 2020 : [20] OR operation at [20] offset 0x20
200 data = WPG_I2CMCNTL_STARTOP_MASK;
201 wpg_data = swab32 (data);
202 wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET + WPG_I2C_OR;
203 writel (wpg_data, wpg_addr);
204
205 //--------------------------------------------------------------------
206 // READ - step 4 : wait until start operation bit clears
207 i = CMD_COMPLETE_TOUT_SEC;
208 while (i) {
209 msleep(10);
210 wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET;
211 wpg_data = readl (wpg_addr);
212 data = swab32 (wpg_data);
213 if (!(data & WPG_I2CMCNTL_STARTOP_MASK))
214 break;
215 i--;
216 }
217 if (i == 0) {
218 debug ("%s - Error : WPG timeout\n", __FUNCTION__);
219 return HPC_ERROR;
220 }
221 //--------------------------------------------------------------------
222 // READ - step 5 : read I2C status register
223 i = CMD_COMPLETE_TOUT_SEC;
224 while (i) {
225 msleep(10);
226 wpg_addr = WPGBbar + WPG_I2CSTAT_OFFSET;
227 wpg_data = readl (wpg_addr);
228 data = swab32 (wpg_data);
229 if (HPC_I2CSTATUS_CHECK (data))
230 break;
231 i--;
232 }
233 if (i == 0) {
234 debug ("ctrl_read - Exit Error:I2C timeout\n");
235 return HPC_ERROR;
236 }
237
238 //--------------------------------------------------------------------
239 // READ - step 6 : get DATA
240 wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;
241 wpg_data = readl (wpg_addr);
242 data = swab32 (wpg_data);
243
244 status = (u8) data;
245
246 debug_polling ("%s - Exit index[%x] status[%x]\n", __FUNCTION__, index, status);
247
248 return (status);
249}
250
251/*----------------------------------------------------------------------
252* Name: i2c_ctrl_write
253*
254* Action: write to HPC over I2C
255*
256* Return 0 or error codes
257*---------------------------------------------------------------------*/
258static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index, u8 cmd)
259{
260 u8 rc;
261 void __iomem *wpg_addr; // base addr + offset
262 unsigned long wpg_data; // data to/from WPG LOHI format
263 unsigned long ultemp;
264 unsigned long data; // actual data HILO format
265 int i;
266
267 debug_polling ("%s - Entry WPGBbar[%p] index[%x] cmd[%x]\n", __FUNCTION__, WPGBbar, index, cmd);
268
269 rc = 0;
270 //--------------------------------------------------------------------
271 // WRITE - step 1
272 // write at address, byte length, I2C address (shifted), index
273 // or write direct, byte length, index
274 data = 0x00000000;
275
276 if (ctlr_ptr->ctlr_type == 0x02) {
277 data = WPG_WRITEATADDR_MASK;
278 // fill in I2C address
279 ultemp = (unsigned long)ctlr_ptr->u.wpeg_ctlr.i2c_addr;
280 ultemp = ultemp >> 1;
281 data |= (ultemp << 8);
282
283 // fill in index
284 data |= (unsigned long)index;
285 } else if (ctlr_ptr->ctlr_type == 0x04) {
286 data = WPG_WRITEDIRECT_MASK;
287
288 // fill in index
289 ultemp = (unsigned long)index;
290 ultemp = ultemp << 8;
291 data |= ultemp;
292 } else {
293 err ("this controller type is not supported \n");
294 return HPC_ERROR;
295 }
296
297 wpg_data = swab32 (data); // swap data before writing
298 wpg_addr = WPGBbar + WPG_I2CMOSUP_OFFSET;
299 writel (wpg_data, wpg_addr);
300
301 //--------------------------------------------------------------------
302 // WRITE - step 2 : clear the message buffer
303 data = 0x00000000 | (unsigned long)cmd;
304 wpg_data = swab32 (data);
305 wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;
306 writel (wpg_data, wpg_addr);
307
308 //--------------------------------------------------------------------
309 // WRITE - step 3 : issue start operation,I2C master control bit 30:ON
310 // 2020 : [20] OR operation at [20] offset 0x20
311 data = WPG_I2CMCNTL_STARTOP_MASK;
312 wpg_data = swab32 (data);
313 wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET + WPG_I2C_OR;
314 writel (wpg_data, wpg_addr);
315
316 //--------------------------------------------------------------------
317 // WRITE - step 4 : wait until start operation bit clears
318 i = CMD_COMPLETE_TOUT_SEC;
319 while (i) {
320 msleep(10);
321 wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET;
322 wpg_data = readl (wpg_addr);
323 data = swab32 (wpg_data);
324 if (!(data & WPG_I2CMCNTL_STARTOP_MASK))
325 break;
326 i--;
327 }
328 if (i == 0) {
329 debug ("%s - Exit Error:WPG timeout\n", __FUNCTION__);
330 rc = HPC_ERROR;
331 }
332
333 //--------------------------------------------------------------------
334 // WRITE - step 5 : read I2C status register
335 i = CMD_COMPLETE_TOUT_SEC;
336 while (i) {
337 msleep(10);
338 wpg_addr = WPGBbar + WPG_I2CSTAT_OFFSET;
339 wpg_data = readl (wpg_addr);
340 data = swab32 (wpg_data);
341 if (HPC_I2CSTATUS_CHECK (data))
342 break;
343 i--;
344 }
345 if (i == 0) {
346 debug ("ctrl_read - Error : I2C timeout\n");
347 rc = HPC_ERROR;
348 }
349
350 debug_polling ("%s Exit rc[%x]\n", __FUNCTION__, rc);
351 return (rc);
352}
353
354//------------------------------------------------------------
355// Read from ISA type HPC
356//------------------------------------------------------------
357static u8 isa_ctrl_read (struct controller *ctlr_ptr, u8 offset)
358{
359 u16 start_address;
360 u16 end_address;
361 u8 data;
362
363 start_address = ctlr_ptr->u.isa_ctlr.io_start;
364 end_address = ctlr_ptr->u.isa_ctlr.io_end;
365 data = inb (start_address + offset);
366 return data;
367}
368
369//--------------------------------------------------------------
370// Write to ISA type HPC
371//--------------------------------------------------------------
372static void isa_ctrl_write (struct controller *ctlr_ptr, u8 offset, u8 data)
373{
374 u16 start_address;
375 u16 port_address;
376
377 start_address = ctlr_ptr->u.isa_ctlr.io_start;
378 port_address = start_address + (u16) offset;
379 outb (data, port_address);
380}
381
382static u8 pci_ctrl_read (struct controller *ctrl, u8 offset)
383{
384 u8 data = 0x00;
385 debug ("inside pci_ctrl_read\n");
386 if (ctrl->ctrl_dev)
387 pci_read_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, &data);
388 return data;
389}
390
391static u8 pci_ctrl_write (struct controller *ctrl, u8 offset, u8 data)
392{
393 u8 rc = -ENODEV;
394 debug ("inside pci_ctrl_write\n");
395 if (ctrl->ctrl_dev) {
396 pci_write_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, data);
397 rc = 0;
398 }
399 return rc;
400}
401
402static u8 ctrl_read (struct controller *ctlr, void __iomem *base, u8 offset)
403{
404 u8 rc;
405 switch (ctlr->ctlr_type) {
406 case 0:
407 rc = isa_ctrl_read (ctlr, offset);
408 break;
409 case 1:
410 rc = pci_ctrl_read (ctlr, offset);
411 break;
412 case 2:
413 case 4:
414 rc = i2c_ctrl_read (ctlr, base, offset);
415 break;
416 default:
417 return -ENODEV;
418 }
419 return rc;
420}
421
422static u8 ctrl_write (struct controller *ctlr, void __iomem *base, u8 offset, u8 data)
423{
424 u8 rc = 0;
425 switch (ctlr->ctlr_type) {
426 case 0:
427 isa_ctrl_write(ctlr, offset, data);
428 break;
429 case 1:
430 rc = pci_ctrl_write (ctlr, offset, data);
431 break;
432 case 2:
433 case 4:
434 rc = i2c_ctrl_write(ctlr, base, offset, data);
435 break;
436 default:
437 return -ENODEV;
438 }
439 return rc;
440}
441/*----------------------------------------------------------------------
442* Name: hpc_writecmdtoindex()
443*
444* Action: convert a write command to proper index within a controller
445*
446* Return index, HPC_ERROR
447*---------------------------------------------------------------------*/
448static u8 hpc_writecmdtoindex (u8 cmd, u8 index)
449{
450 u8 rc;
451
452 switch (cmd) {
453 case HPC_CTLR_ENABLEIRQ: // 0x00.N.15
454 case HPC_CTLR_CLEARIRQ: // 0x06.N.15
455 case HPC_CTLR_RESET: // 0x07.N.15
456 case HPC_CTLR_IRQSTEER: // 0x08.N.15
457 case HPC_CTLR_DISABLEIRQ: // 0x01.N.15
458 case HPC_ALLSLOT_ON: // 0x11.N.15
459 case HPC_ALLSLOT_OFF: // 0x12.N.15
460 rc = 0x0F;
461 break;
462
463 case HPC_SLOT_OFF: // 0x02.Y.0-14
464 case HPC_SLOT_ON: // 0x03.Y.0-14
465 case HPC_SLOT_ATTNOFF: // 0x04.N.0-14
466 case HPC_SLOT_ATTNON: // 0x05.N.0-14
467 case HPC_SLOT_BLINKLED: // 0x13.N.0-14
468 rc = index;
469 break;
470
471 case HPC_BUS_33CONVMODE:
472 case HPC_BUS_66CONVMODE:
473 case HPC_BUS_66PCIXMODE:
474 case HPC_BUS_100PCIXMODE:
475 case HPC_BUS_133PCIXMODE:
476 rc = index + WPG_1ST_BUS_INDEX - 1;
477 break;
478
479 default:
480 err ("hpc_writecmdtoindex - Error invalid cmd[%x]\n", cmd);
481 rc = HPC_ERROR;
482 }
483
484 return rc;
485}
486
487/*----------------------------------------------------------------------
488* Name: hpc_readcmdtoindex()
489*
490* Action: convert a read command to proper index within a controller
491*
492* Return index, HPC_ERROR
493*---------------------------------------------------------------------*/
494static u8 hpc_readcmdtoindex (u8 cmd, u8 index)
495{
496 u8 rc;
497
498 switch (cmd) {
499 case READ_CTLRSTATUS:
500 rc = 0x0F;
501 break;
502 case READ_SLOTSTATUS:
503 case READ_ALLSTAT:
504 rc = index;
505 break;
506 case READ_EXTSLOTSTATUS:
507 rc = index + WPG_1ST_EXTSLOT_INDEX;
508 break;
509 case READ_BUSSTATUS:
510 rc = index + WPG_1ST_BUS_INDEX - 1;
511 break;
512 case READ_SLOTLATCHLOWREG:
513 rc = 0x28;
514 break;
515 case READ_REVLEVEL:
516 rc = 0x25;
517 break;
518 case READ_HPCOPTIONS:
519 rc = 0x27;
520 break;
521 default:
522 rc = HPC_ERROR;
523 }
524 return rc;
525}
526
527/*----------------------------------------------------------------------
528* Name: HPCreadslot()
529*
530* Action: issue a READ command to HPC
531*
532* Input: pslot - can not be NULL for READ_ALLSTAT
533* pstatus - can be NULL for READ_ALLSTAT
534*
535* Return 0 or error codes
536*---------------------------------------------------------------------*/
537int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
538{
539 void __iomem *wpg_bbar = NULL;
540 struct controller *ctlr_ptr;
541 struct list_head *pslotlist;
542 u8 index, status;
543 int rc = 0;
544 int busindex;
545
546 debug_polling ("%s - Entry pslot[%p] cmd[%x] pstatus[%p]\n", __FUNCTION__, pslot, cmd, pstatus);
547
548 if ((pslot == NULL)
549 || ((pstatus == NULL) && (cmd != READ_ALLSTAT) && (cmd != READ_BUSSTATUS))) {
550 rc = -EINVAL;
551 err ("%s - Error invalid pointer, rc[%d]\n", __FUNCTION__, rc);
552 return rc;
553 }
554
555 if (cmd == READ_BUSSTATUS) {
556 busindex = ibmphp_get_bus_index (pslot->bus);
557 if (busindex < 0) {
558 rc = -EINVAL;
559 err ("%s - Exit Error:invalid bus, rc[%d]\n", __FUNCTION__, rc);
560 return rc;
561 } else
562 index = (u8) busindex;
563 } else
564 index = pslot->ctlr_index;
565
566 index = hpc_readcmdtoindex (cmd, index);
567
568 if (index == HPC_ERROR) {
569 rc = -EINVAL;
570 err ("%s - Exit Error:invalid index, rc[%d]\n", __FUNCTION__, rc);
571 return rc;
572 }
573
574 ctlr_ptr = pslot->ctrl;
575
576 get_hpc_access ();
577
578 //--------------------------------------------------------------------
579 // map physical address to logical address
580 //--------------------------------------------------------------------
581 if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
582 wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
583
584 //--------------------------------------------------------------------
585 // check controller status before reading
586 //--------------------------------------------------------------------
587 rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
588 if (!rc) {
589 switch (cmd) {
590 case READ_ALLSTAT:
591 // update the slot structure
592 pslot->ctrl->status = status;
593 pslot->status = ctrl_read (ctlr_ptr, wpg_bbar, index);
594 rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
595 &status);
596 if (!rc)
597 pslot->ext_status = ctrl_read (ctlr_ptr, wpg_bbar, index + WPG_1ST_EXTSLOT_INDEX);
598
599 break;
600
601 case READ_SLOTSTATUS:
602 // DO NOT update the slot structure
603 *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
604 break;
605
606 case READ_EXTSLOTSTATUS:
607 // DO NOT update the slot structure
608 *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
609 break;
610
611 case READ_CTLRSTATUS:
612 // DO NOT update the slot structure
613 *pstatus = status;
614 break;
615
616 case READ_BUSSTATUS:
617 pslot->busstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
618 break;
619 case READ_REVLEVEL:
620 *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
621 break;
622 case READ_HPCOPTIONS:
623 *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
624 break;
625 case READ_SLOTLATCHLOWREG:
626 // DO NOT update the slot structure
627 *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
628 break;
629
630 // Not used
631 case READ_ALLSLOT:
632 list_for_each (pslotlist, &ibmphp_slot_head) {
633 pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
634 index = pslot->ctlr_index;
635 rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr,
636 wpg_bbar, &status);
637 if (!rc) {
638 pslot->status = ctrl_read (ctlr_ptr, wpg_bbar, index);
639 rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT,
640 ctlr_ptr, wpg_bbar, &status);
641 if (!rc)
642 pslot->ext_status =
643 ctrl_read (ctlr_ptr, wpg_bbar,
644 index + WPG_1ST_EXTSLOT_INDEX);
645 } else {
646 err ("%s - Error ctrl_read failed\n", __FUNCTION__);
647 rc = -EINVAL;
648 break;
649 }
650 }
651 break;
652 default:
653 rc = -EINVAL;
654 break;
655 }
656 }
657 //--------------------------------------------------------------------
658 // cleanup
659 //--------------------------------------------------------------------
660
661 // remove physical to logical address mapping
662 if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
663 iounmap (wpg_bbar);
664
665 free_hpc_access ();
666
667 debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
668 return rc;
669}
670
671/*----------------------------------------------------------------------
672* Name: ibmphp_hpc_writeslot()
673*
674* Action: issue a WRITE command to HPC
675*---------------------------------------------------------------------*/
676int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
677{
678 void __iomem *wpg_bbar = NULL;
679 struct controller *ctlr_ptr;
680 u8 index, status;
681 int busindex;
682 u8 done;
683 int rc = 0;
684 int timeout;
685
686 debug_polling ("%s - Entry pslot[%p] cmd[%x]\n", __FUNCTION__, pslot, cmd);
687 if (pslot == NULL) {
688 rc = -EINVAL;
689 err ("%s - Error Exit rc[%d]\n", __FUNCTION__, rc);
690 return rc;
691 }
692
693 if ((cmd == HPC_BUS_33CONVMODE) || (cmd == HPC_BUS_66CONVMODE) ||
694 (cmd == HPC_BUS_66PCIXMODE) || (cmd == HPC_BUS_100PCIXMODE) ||
695 (cmd == HPC_BUS_133PCIXMODE)) {
696 busindex = ibmphp_get_bus_index (pslot->bus);
697 if (busindex < 0) {
698 rc = -EINVAL;
699 err ("%s - Exit Error:invalid bus, rc[%d]\n", __FUNCTION__, rc);
700 return rc;
701 } else
702 index = (u8) busindex;
703 } else
704 index = pslot->ctlr_index;
705
706 index = hpc_writecmdtoindex (cmd, index);
707
708 if (index == HPC_ERROR) {
709 rc = -EINVAL;
710 err ("%s - Error Exit rc[%d]\n", __FUNCTION__, rc);
711 return rc;
712 }
713
714 ctlr_ptr = pslot->ctrl;
715
716 get_hpc_access ();
717
718 //--------------------------------------------------------------------
719 // map physical address to logical address
720 //--------------------------------------------------------------------
721 if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) {
722 wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
723
724 debug ("%s - ctlr id[%x] physical[%lx] logical[%lx] i2c[%x]\n", __FUNCTION__,
725 ctlr_ptr->ctlr_id, (ulong) (ctlr_ptr->u.wpeg_ctlr.wpegbbar), (ulong) wpg_bbar,
726 ctlr_ptr->u.wpeg_ctlr.i2c_addr);
727 }
728 //--------------------------------------------------------------------
729 // check controller status before writing
730 //--------------------------------------------------------------------
731 rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
732 if (!rc) {
733
734 ctrl_write (ctlr_ptr, wpg_bbar, index, cmd);
735
736 //--------------------------------------------------------------------
737 // check controller is still not working on the command
738 //--------------------------------------------------------------------
739 timeout = CMD_COMPLETE_TOUT_SEC;
740 done = FALSE;
741 while (!done) {
742 rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
743 &status);
744 if (!rc) {
745 if (NEEDTOCHECK_CMDSTATUS (cmd)) {
746 if (CTLR_FINISHED (status) == HPC_CTLR_FINISHED_YES)
747 done = TRUE;
748 } else
749 done = TRUE;
750 }
751 if (!done) {
752 msleep(1000);
753 if (timeout < 1) {
754 done = TRUE;
755 err ("%s - Error command complete timeout\n", __FUNCTION__);
756 rc = -EFAULT;
757 } else
758 timeout--;
759 }
760 }
761 ctlr_ptr->status = status;
762 }
763 // cleanup
764
765 // remove physical to logical address mapping
766 if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
767 iounmap (wpg_bbar);
768 free_hpc_access ();
769
770 debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
771 return rc;
772}
773
774/*----------------------------------------------------------------------
775* Name: get_hpc_access()
776*
777* Action: make sure only one process can access HPC at one time
778*---------------------------------------------------------------------*/
779static void get_hpc_access (void)
780{
781 down (&sem_hpcaccess);
782}
783
784/*----------------------------------------------------------------------
785* Name: free_hpc_access()
786*---------------------------------------------------------------------*/
787void free_hpc_access (void)
788{
789 up (&sem_hpcaccess);
790}
791
792/*----------------------------------------------------------------------
793* Name: ibmphp_lock_operations()
794*
795* Action: make sure only one process can change the data structure
796*---------------------------------------------------------------------*/
797void ibmphp_lock_operations (void)
798{
799 down (&semOperations);
800 to_debug = TRUE;
801}
802
803/*----------------------------------------------------------------------
804* Name: ibmphp_unlock_operations()
805*---------------------------------------------------------------------*/
806void ibmphp_unlock_operations (void)
807{
808 debug ("%s - Entry\n", __FUNCTION__);
809 up (&semOperations);
810 to_debug = FALSE;
811 debug ("%s - Exit\n", __FUNCTION__);
812}
813
814/*----------------------------------------------------------------------
815* Name: poll_hpc()
816*---------------------------------------------------------------------*/
817#define POLL_LATCH_REGISTER 0
818#define POLL_SLOTS 1
819#define POLL_SLEEP 2
820static void poll_hpc (void)
821{
822 struct slot myslot;
823 struct slot *pslot = NULL;
824 struct list_head *pslotlist;
825 int rc;
826 int poll_state = POLL_LATCH_REGISTER;
827 u8 oldlatchlow = 0x00;
828 u8 curlatchlow = 0x00;
829 int poll_count = 0;
830 u8 ctrl_count = 0x00;
831
832 debug ("%s - Entry\n", __FUNCTION__);
833
834 while (!ibmphp_shutdown) {
835 if (ibmphp_shutdown)
836 break;
837
838 /* try to get the lock to do some kind of harware access */
839 down (&semOperations);
840
841 switch (poll_state) {
842 case POLL_LATCH_REGISTER:
843 oldlatchlow = curlatchlow;
844 ctrl_count = 0x00;
845 list_for_each (pslotlist, &ibmphp_slot_head) {
846 if (ctrl_count >= ibmphp_get_total_controllers())
847 break;
848 pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
849 if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
850 ctrl_count++;
851 if (READ_SLOT_LATCH (pslot->ctrl)) {
852 rc = ibmphp_hpc_readslot (pslot,
853 READ_SLOTLATCHLOWREG,
854 &curlatchlow);
855 if (oldlatchlow != curlatchlow)
856 process_changeinlatch (oldlatchlow,
857 curlatchlow,
858 pslot->ctrl);
859 }
860 }
861 }
862 ++poll_count;
863 poll_state = POLL_SLEEP;
864 break;
865 case POLL_SLOTS:
866 list_for_each (pslotlist, &ibmphp_slot_head) {
867 pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
868 // make a copy of the old status
869 memcpy ((void *) &myslot, (void *) pslot,
870 sizeof (struct slot));
871 rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
872 if ((myslot.status != pslot->status)
873 || (myslot.ext_status != pslot->ext_status))
874 process_changeinstatus (pslot, &myslot);
875 }
876 ctrl_count = 0x00;
877 list_for_each (pslotlist, &ibmphp_slot_head) {
878 if (ctrl_count >= ibmphp_get_total_controllers())
879 break;
880 pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
881 if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
882 ctrl_count++;
883 if (READ_SLOT_LATCH (pslot->ctrl))
884 rc = ibmphp_hpc_readslot (pslot,
885 READ_SLOTLATCHLOWREG,
886 &curlatchlow);
887 }
888 }
889 ++poll_count;
890 poll_state = POLL_SLEEP;
891 break;
892 case POLL_SLEEP:
893 /* don't sleep with a lock on the hardware */
894 up (&semOperations);
895 msleep(POLL_INTERVAL_SEC * 1000);
896
897 if (ibmphp_shutdown)
898 break;
899
900 down (&semOperations);
901
902 if (poll_count >= POLL_LATCH_CNT) {
903 poll_count = 0;
904 poll_state = POLL_SLOTS;
905 } else
906 poll_state = POLL_LATCH_REGISTER;
907 break;
908 }
909 /* give up the harware semaphore */
910 up (&semOperations);
911 /* sleep for a short time just for good measure */
912 msleep(100);
913 }
914 up (&sem_exit);
915 debug ("%s - Exit\n", __FUNCTION__);
916}
917
918
919/*----------------------------------------------------------------------
920* Name: process_changeinstatus
921*
922* Action: compare old and new slot status, process the change in status
923*
924* Input: pointer to slot struct, old slot struct
925*
926* Return 0 or error codes
927* Value:
928*
929* Side
930* Effects: None.
931*
932* Notes:
933*---------------------------------------------------------------------*/
934static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)
935{
936 u8 status;
937 int rc = 0;
938 u8 disable = FALSE;
939 u8 update = FALSE;
940
941 debug ("process_changeinstatus - Entry pslot[%p], poldslot[%p]\n", pslot, poldslot);
942
943 // bit 0 - HPC_SLOT_POWER
944 if ((pslot->status & 0x01) != (poldslot->status & 0x01))
945 update = TRUE;
946
947 // bit 1 - HPC_SLOT_CONNECT
948 // ignore
949
950 // bit 2 - HPC_SLOT_ATTN
951 if ((pslot->status & 0x04) != (poldslot->status & 0x04))
952 update = TRUE;
953
954 // bit 3 - HPC_SLOT_PRSNT2
955 // bit 4 - HPC_SLOT_PRSNT1
956 if (((pslot->status & 0x08) != (poldslot->status & 0x08))
957 || ((pslot->status & 0x10) != (poldslot->status & 0x10)))
958 update = TRUE;
959
960 // bit 5 - HPC_SLOT_PWRGD
961 if ((pslot->status & 0x20) != (poldslot->status & 0x20))
962 // OFF -> ON: ignore, ON -> OFF: disable slot
963 if ((poldslot->status & 0x20) && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status)))
964 disable = TRUE;
965
966 // bit 6 - HPC_SLOT_BUS_SPEED
967 // ignore
968
969 // bit 7 - HPC_SLOT_LATCH
970 if ((pslot->status & 0x80) != (poldslot->status & 0x80)) {
971 update = TRUE;
972 // OPEN -> CLOSE
973 if (pslot->status & 0x80) {
974 if (SLOT_PWRGD (pslot->status)) {
975 // power goes on and off after closing latch
976 // check again to make sure power is still ON
977 msleep(1000);
978 rc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &status);
979 if (SLOT_PWRGD (status))
980 update = TRUE;
981 else // overwrite power in pslot to OFF
982 pslot->status &= ~HPC_SLOT_POWER;
983 }
984 }
985 // CLOSE -> OPEN
986 else if ((SLOT_PWRGD (poldslot->status) == HPC_SLOT_PWRGD_GOOD)
987 && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status))) {
988 disable = TRUE;
989 }
990 // else - ignore
991 }
992 // bit 4 - HPC_SLOT_BLINK_ATTN
993 if ((pslot->ext_status & 0x08) != (poldslot->ext_status & 0x08))
994 update = TRUE;
995
996 if (disable) {
997 debug ("process_changeinstatus - disable slot\n");
998 pslot->flag = FALSE;
999 rc = ibmphp_do_disable_slot (pslot);
1000 }
1001
1002 if (update || disable) {
1003 ibmphp_update_slot_info (pslot);
1004 }
1005
1006 debug ("%s - Exit rc[%d] disable[%x] update[%x]\n", __FUNCTION__, rc, disable, update);
1007
1008 return rc;
1009}
1010
1011/*----------------------------------------------------------------------
1012* Name: process_changeinlatch
1013*
1014* Action: compare old and new latch reg status, process the change
1015*
1016* Input: old and current latch register status
1017*
1018* Return 0 or error codes
1019* Value:
1020*---------------------------------------------------------------------*/
1021static int process_changeinlatch (u8 old, u8 new, struct controller *ctrl)
1022{
1023 struct slot myslot, *pslot;
1024 u8 i;
1025 u8 mask;
1026 int rc = 0;
1027
1028 debug ("%s - Entry old[%x], new[%x]\n", __FUNCTION__, old, new);
1029 // bit 0 reserved, 0 is LSB, check bit 1-6 for 6 slots
1030
1031 for (i = ctrl->starting_slot_num; i <= ctrl->ending_slot_num; i++) {
1032 mask = 0x01 << i;
1033 if ((mask & old) != (mask & new)) {
1034 pslot = ibmphp_get_slot_from_physical_num (i);
1035 if (pslot) {
1036 memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
1037 rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
1038 debug ("%s - call process_changeinstatus for slot[%d]\n", __FUNCTION__, i);
1039 process_changeinstatus (pslot, &myslot);
1040 } else {
1041 rc = -EINVAL;
1042 err ("%s - Error bad pointer for slot[%d]\n", __FUNCTION__, i);
1043 }
1044 }
1045 }
1046 debug ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
1047 return rc;
1048}
1049
1050/*----------------------------------------------------------------------
1051* Name: hpc_poll_thread
1052*
1053* Action: polling
1054*
1055* Return 0
1056* Value:
1057*---------------------------------------------------------------------*/
1058static int hpc_poll_thread (void *data)
1059{
1060 debug ("%s - Entry\n", __FUNCTION__);
1061
1062 daemonize("hpc_poll");
1063 allow_signal(SIGKILL);
1064
1065 poll_hpc ();
1066
1067 tid_poll = 0;
1068 debug ("%s - Exit\n", __FUNCTION__);
1069 return 0;
1070}
1071
1072
1073/*----------------------------------------------------------------------
1074* Name: ibmphp_hpc_start_poll_thread
1075*
1076* Action: start polling thread
1077*---------------------------------------------------------------------*/
1078int __init ibmphp_hpc_start_poll_thread (void)
1079{
1080 int rc = 0;
1081
1082 debug ("%s - Entry\n", __FUNCTION__);
1083
1084 tid_poll = kernel_thread (hpc_poll_thread, NULL, 0);
1085 if (tid_poll < 0) {
1086 err ("%s - Error, thread not started\n", __FUNCTION__);
1087 rc = -1;
1088 }
1089
1090 debug ("%s - Exit tid_poll[%d] rc[%d]\n", __FUNCTION__, tid_poll, rc);
1091 return rc;
1092}
1093
1094/*----------------------------------------------------------------------
1095* Name: ibmphp_hpc_stop_poll_thread
1096*
1097* Action: stop polling thread and cleanup
1098*---------------------------------------------------------------------*/
1099void __exit ibmphp_hpc_stop_poll_thread (void)
1100{
1101 debug ("%s - Entry\n", __FUNCTION__);
1102
1103 ibmphp_shutdown = TRUE;
1104 debug ("before locking operations \n");
1105 ibmphp_lock_operations ();
1106 debug ("after locking operations \n");
1107
1108 // wait for poll thread to exit
1109 debug ("before sem_exit down \n");
1110 down (&sem_exit);
1111 debug ("after sem_exit down \n");
1112
1113 // cleanup
1114 debug ("before free_hpc_access \n");
1115 free_hpc_access ();
1116 debug ("after free_hpc_access \n");
1117 ibmphp_unlock_operations ();
1118 debug ("after unlock operations \n");
1119 up (&sem_exit);
1120 debug ("after sem exit up\n");
1121
1122 debug ("%s - Exit\n", __FUNCTION__);
1123}
1124
1125/*----------------------------------------------------------------------
1126* Name: hpc_wait_ctlr_notworking
1127*
1128* Action: wait until the controller is in a not working state
1129*
1130* Return 0, HPC_ERROR
1131* Value:
1132*---------------------------------------------------------------------*/
1133static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, void __iomem *wpg_bbar,
1134 u8 * pstatus)
1135{
1136 int rc = 0;
1137 u8 done = FALSE;
1138
1139 debug_polling ("hpc_wait_ctlr_notworking - Entry timeout[%d]\n", timeout);
1140
1141 while (!done) {
1142 *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, WPG_CTLR_INDEX);
1143 if (*pstatus == HPC_ERROR) {
1144 rc = HPC_ERROR;
1145 done = TRUE;
1146 }
1147 if (CTLR_WORKING (*pstatus) == HPC_CTLR_WORKING_NO)
1148 done = TRUE;
1149 if (!done) {
1150 msleep(1000);
1151 if (timeout < 1) {
1152 done = TRUE;
1153 err ("HPCreadslot - Error ctlr timeout\n");
1154 rc = HPC_ERROR;
1155 } else
1156 timeout--;
1157 }
1158 }
1159 debug_polling ("hpc_wait_ctlr_notworking - Exit rc[%x] status[%x]\n", rc, *pstatus);
1160 return rc;
1161}
diff --git a/drivers/pci/hotplug/ibmphp_pci.c b/drivers/pci/hotplug/ibmphp_pci.c
new file mode 100644
index 000000000000..2335fac65fb4
--- /dev/null
+++ b/drivers/pci/hotplug/ibmphp_pci.c
@@ -0,0 +1,1747 @@
1/*
2 * IBM Hot Plug Controller Driver
3 *
4 * Written By: Irene Zubarev, IBM Corporation
5 *
6 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
7 * Copyright (C) 2001,2002 IBM Corp.
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <gregkh@us.ibm.com>
27 *
28 */
29
30#include <linux/module.h>
31#include <linux/slab.h>
32#include <linux/pci.h>
33#include <linux/list.h>
34#include "ibmphp.h"
35
36
37static int configure_device(struct pci_func *);
38static int configure_bridge(struct pci_func **, u8);
39static struct res_needed *scan_behind_bridge(struct pci_func *, u8);
40static int add_new_bus (struct bus_node *, struct resource_node *, struct resource_node *, struct resource_node *, u8);
41static u8 find_sec_number (u8 primary_busno, u8 slotno);
42
43/*
44 * NOTE..... If BIOS doesn't provide default routing, we assign:
45 * 9 for SCSI, 10 for LAN adapters, and 11 for everything else.
46 * If adapter is bridged, then we assign 11 to it and devices behind it.
47 * We also assign the same irq numbers for multi function devices.
48 * These are PIC mode, so shouldn't matter n.e.ways (hopefully)
49 */
50static void assign_alt_irq (struct pci_func * cur_func, u8 class_code)
51{
52 int j;
53 for (j = 0; j < 4; j++) {
54 if (cur_func->irq[j] == 0xff) {
55 switch (class_code) {
56 case PCI_BASE_CLASS_STORAGE:
57 cur_func->irq[j] = SCSI_IRQ;
58 break;
59 case PCI_BASE_CLASS_NETWORK:
60 cur_func->irq[j] = LAN_IRQ;
61 break;
62 default:
63 cur_func->irq[j] = OTHER_IRQ;
64 break;
65 }
66 }
67 }
68}
69
70/*
71 * Configures the device to be added (will allocate needed resources if it
72 * can), the device can be a bridge or a regular pci device, can also be
73 * multi-functional
74 *
75 * Input: function to be added
76 *
77 * TO DO: The error case with Multifunction device or multi function bridge,
78 * if there is an error, will need to go through all previous functions and
79 * unconfigure....or can add some code into unconfigure_card....
80 */
81int ibmphp_configure_card (struct pci_func *func, u8 slotno)
82{
83 u16 vendor_id;
84 u32 class;
85 u8 class_code;
86 u8 hdr_type, device, sec_number;
87 u8 function;
88 struct pci_func *newfunc; /* for multi devices */
89 struct pci_func *cur_func, *prev_func;
90 int rc, i, j;
91 int cleanup_count;
92 u8 flag;
93 u8 valid_device = 0x00; /* to see if we are able to read from card any device info at all */
94
95 debug ("inside configure_card, func->busno = %x\n", func->busno);
96
97 device = func->device;
98 cur_func = func;
99
100 /* We only get bus and device from IRQ routing table. So at this point,
101 * func->busno is correct, and func->device contains only device (at the 5
102 * highest bits)
103 */
104
105 /* For every function on the card */
106 for (function = 0x00; function < 0x08; function++) {
107 unsigned int devfn = PCI_DEVFN(device, function);
108 ibmphp_pci_bus->number = cur_func->busno;
109
110 cur_func->function = function;
111
112 debug ("inside the loop, cur_func->busno = %x, cur_func->device = %x, cur_func->funcion = %x\n",
113 cur_func->busno, cur_func->device, cur_func->function);
114
115 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
116
117 debug ("vendor_id is %x\n", vendor_id);
118 if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
119 /* found correct device!!! */
120 debug ("found valid device, vendor_id = %x\n", vendor_id);
121
122 ++valid_device;
123
124 /* header: x x x x x x x x
125 * | |___________|=> 1=PPB bridge, 0=normal device, 2=CardBus Bridge
126 * |_=> 0 = single function device, 1 = multi-function device
127 */
128
129 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
130 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
131
132 class_code = class >> 24;
133 debug ("hrd_type = %x, class = %x, class_code %x\n", hdr_type, class, class_code);
134 class >>= 8; /* to take revision out, class = class.subclass.prog i/f */
135 if (class == PCI_CLASS_NOT_DEFINED_VGA) {
136 err ("The device %x is VGA compatible and as is not supported for hot plugging. "
137 "Please choose another device.\n", cur_func->device);
138 return -ENODEV;
139 } else if (class == PCI_CLASS_DISPLAY_VGA) {
140 err ("The device %x is not supported for hot plugging. "
141 "Please choose another device.\n", cur_func->device);
142 return -ENODEV;
143 }
144 switch (hdr_type) {
145 case PCI_HEADER_TYPE_NORMAL:
146 debug ("single device case.... vendor id = %x, hdr_type = %x, class = %x\n", vendor_id, hdr_type, class);
147 assign_alt_irq (cur_func, class_code);
148 if ((rc = configure_device (cur_func)) < 0) {
149 /* We need to do this in case some other BARs were properly inserted */
150 err ("was not able to configure devfunc %x on bus %x.\n",
151 cur_func->device, cur_func->busno);
152 cleanup_count = 6;
153 goto error;
154 }
155 cur_func->next = NULL;
156 function = 0x8;
157 break;
158 case PCI_HEADER_TYPE_MULTIDEVICE:
159 assign_alt_irq (cur_func, class_code);
160 if ((rc = configure_device (cur_func)) < 0) {
161 /* We need to do this in case some other BARs were properly inserted */
162 err ("was not able to configure devfunc %x on bus %x...bailing out\n",
163 cur_func->device, cur_func->busno);
164 cleanup_count = 6;
165 goto error;
166 }
167 newfunc = kmalloc(sizeof(*newfunc), GFP_KERNEL);
168 if (!newfunc) {
169 err ("out of system memory\n");
170 return -ENOMEM;
171 }
172 memset (newfunc, 0, sizeof (struct pci_func));
173 newfunc->busno = cur_func->busno;
174 newfunc->device = device;
175 cur_func->next = newfunc;
176 cur_func = newfunc;
177 for (j = 0; j < 4; j++)
178 newfunc->irq[j] = cur_func->irq[j];
179 break;
180 case PCI_HEADER_TYPE_MULTIBRIDGE:
181 class >>= 8;
182 if (class != PCI_CLASS_BRIDGE_PCI) {
183 err ("This %x is not PCI-to-PCI bridge, and as is not supported for hot-plugging. "
184 "Please insert another card.\n", cur_func->device);
185 return -ENODEV;
186 }
187 assign_alt_irq (cur_func, class_code);
188 rc = configure_bridge (&cur_func, slotno);
189 if (rc == -ENODEV) {
190 err ("You chose to insert Single Bridge, or nested bridges, this is not supported...\n");
191 err ("Bus %x, devfunc %x\n", cur_func->busno, cur_func->device);
192 return rc;
193 }
194 if (rc) {
195 /* We need to do this in case some other BARs were properly inserted */
196 err ("was not able to hot-add PPB properly.\n");
197 func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
198 cleanup_count = 2;
199 goto error;
200 }
201
202 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
203 flag = FALSE;
204 for (i = 0; i < 32; i++) {
205 if (func->devices[i]) {
206 newfunc = kmalloc(sizeof(*newfunc), GFP_KERNEL);
207 if (!newfunc) {
208 err ("out of system memory\n");
209 return -ENOMEM;
210 }
211 memset (newfunc, 0, sizeof (struct pci_func));
212 newfunc->busno = sec_number;
213 newfunc->device = (u8) i;
214 for (j = 0; j < 4; j++)
215 newfunc->irq[j] = cur_func->irq[j];
216
217 if (flag) {
218 for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next) ;
219 prev_func->next = newfunc;
220 } else
221 cur_func->next = newfunc;
222
223 rc = ibmphp_configure_card (newfunc, slotno);
224 /* This could only happen if kmalloc failed */
225 if (rc) {
226 /* We need to do this in case bridge itself got configured properly, but devices behind it failed */
227 func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
228 cleanup_count = 2;
229 goto error;
230 }
231 flag = TRUE;
232 }
233 }
234
235 newfunc = kmalloc(sizeof(*newfunc), GFP_KERNEL);
236 if (!newfunc) {
237 err ("out of system memory\n");
238 return -ENOMEM;
239 }
240 memset (newfunc, 0, sizeof (struct pci_func));
241 newfunc->busno = cur_func->busno;
242 newfunc->device = device;
243 for (j = 0; j < 4; j++)
244 newfunc->irq[j] = cur_func->irq[j];
245 for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next) ;
246 prev_func->next = newfunc;
247 cur_func = newfunc;
248 break;
249 case PCI_HEADER_TYPE_BRIDGE:
250 class >>= 8;
251 debug ("class now is %x\n", class);
252 if (class != PCI_CLASS_BRIDGE_PCI) {
253 err ("This %x is not PCI-to-PCI bridge, and as is not supported for hot-plugging. "
254 "Please insert another card.\n", cur_func->device);
255 return -ENODEV;
256 }
257
258 assign_alt_irq (cur_func, class_code);
259
260 debug ("cur_func->busno b4 configure_bridge is %x\n", cur_func->busno);
261 rc = configure_bridge (&cur_func, slotno);
262 if (rc == -ENODEV) {
263 err ("You chose to insert Single Bridge, or nested bridges, this is not supported...\n");
264 err ("Bus %x, devfunc %x\n", cur_func->busno, cur_func->device);
265 return rc;
266 }
267 if (rc) {
268 /* We need to do this in case some other BARs were properly inserted */
269 func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
270 err ("was not able to hot-add PPB properly.\n");
271 cleanup_count = 2;
272 goto error;
273 }
274 debug ("cur_func->busno = %x, device = %x, function = %x\n",
275 cur_func->busno, device, function);
276 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
277 debug ("after configuring bridge..., sec_number = %x\n", sec_number);
278 flag = FALSE;
279 for (i = 0; i < 32; i++) {
280 if (func->devices[i]) {
281 debug ("inside for loop, device is %x\n", i);
282 newfunc = kmalloc(sizeof(*newfunc), GFP_KERNEL);
283 if (!newfunc) {
284 err (" out of system memory\n");
285 return -ENOMEM;
286 }
287 memset (newfunc, 0, sizeof (struct pci_func));
288 newfunc->busno = sec_number;
289 newfunc->device = (u8) i;
290 for (j = 0; j < 4; j++)
291 newfunc->irq[j] = cur_func->irq[j];
292
293 if (flag) {
294 for (prev_func = cur_func; prev_func->next; prev_func = prev_func->next) ;
295 prev_func->next = newfunc;
296 } else
297 cur_func->next = newfunc;
298
299 rc = ibmphp_configure_card (newfunc, slotno);
300
301 /* Again, this case should not happen... For complete paranoia, will need to call remove_bus */
302 if (rc) {
303 /* We need to do this in case some other BARs were properly inserted */
304 func->bus = 1; /* To indicate to the unconfigure function that this is a PPB */
305 cleanup_count = 2;
306 goto error;
307 }
308 flag = TRUE;
309 }
310 }
311
312 function = 0x8;
313 break;
314 default:
315 err ("MAJOR PROBLEM!!!!, header type not supported? %x\n", hdr_type);
316 return -ENXIO;
317 break;
318 } /* end of switch */
319 } /* end of valid device */
320 } /* end of for */
321
322 if (!valid_device) {
323 err ("Cannot find any valid devices on the card. Or unable to read from card.\n");
324 return -ENODEV;
325 }
326
327 return 0;
328
329error:
330 for (i = 0; i < cleanup_count; i++) {
331 if (cur_func->io[i]) {
332 ibmphp_remove_resource (cur_func->io[i]);
333 cur_func->io[i] = NULL;
334 } else if (cur_func->pfmem[i]) {
335 ibmphp_remove_resource (cur_func->pfmem[i]);
336 cur_func->pfmem[i] = NULL;
337 } else if (cur_func->mem[i]) {
338 ibmphp_remove_resource (cur_func->mem[i]);
339 cur_func->mem[i] = NULL;
340 }
341 }
342 return rc;
343}
344
345/*
346 * This function configures the pci BARs of a single device.
347 * Input: pointer to the pci_func
348 * Output: configured PCI, 0, or error
349 */
350static int configure_device (struct pci_func *func)
351{
352 u32 bar[6];
353 u32 address[] = {
354 PCI_BASE_ADDRESS_0,
355 PCI_BASE_ADDRESS_1,
356 PCI_BASE_ADDRESS_2,
357 PCI_BASE_ADDRESS_3,
358 PCI_BASE_ADDRESS_4,
359 PCI_BASE_ADDRESS_5,
360 0
361 };
362 u8 irq;
363 int count;
364 int len[6];
365 struct resource_node *io[6];
366 struct resource_node *mem[6];
367 struct resource_node *mem_tmp;
368 struct resource_node *pfmem[6];
369 unsigned int devfn;
370
371 debug ("%s - inside\n", __FUNCTION__);
372
373 devfn = PCI_DEVFN(func->device, func->function);
374 ibmphp_pci_bus->number = func->busno;
375
376 for (count = 0; address[count]; count++) { /* for 6 BARs */
377
378 /* not sure if i need this. per scott, said maybe need smth like this
379 if devices don't adhere 100% to the spec, so don't want to write
380 to the reserved bits
381
382 pcibios_read_config_byte(cur_func->busno, cur_func->device,
383 PCI_BASE_ADDRESS_0 + 4 * count, &tmp);
384 if (tmp & 0x01) // IO
385 pcibios_write_config_dword(cur_func->busno, cur_func->device,
386 PCI_BASE_ADDRESS_0 + 4 * count, 0xFFFFFFFD);
387 else // Memory
388 pcibios_write_config_dword(cur_func->busno, cur_func->device,
389 PCI_BASE_ADDRESS_0 + 4 * count, 0xFFFFFFFF);
390 */
391 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
392 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
393
394 if (!bar[count]) /* This BAR is not implemented */
395 continue;
396
397 debug ("Device %x BAR %d wants %x\n", func->device, count, bar[count]);
398
399 if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
400 /* This is IO */
401 debug ("inside IO SPACE\n");
402
403 len[count] = bar[count] & 0xFFFFFFFC;
404 len[count] = ~len[count] + 1;
405
406 debug ("len[count] in IO %x, count %d\n", len[count], count);
407
408 io[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
409
410 if (!io[count]) {
411 err ("out of system memory\n");
412 return -ENOMEM;
413 }
414 memset (io[count], 0, sizeof (struct resource_node));
415 io[count]->type = IO;
416 io[count]->busno = func->busno;
417 io[count]->devfunc = PCI_DEVFN(func->device, func->function);
418 io[count]->len = len[count];
419 if (ibmphp_check_resource(io[count], 0) == 0) {
420 ibmphp_add_resource (io[count]);
421 func->io[count] = io[count];
422 } else {
423 err ("cannot allocate requested io for bus %x device %x function %x len %x\n",
424 func->busno, func->device, func->function, len[count]);
425 kfree (io[count]);
426 return -EIO;
427 }
428 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->io[count]->start);
429
430 /* _______________This is for debugging purposes only_____________________ */
431 debug ("b4 writing, the IO address is %x\n", func->io[count]->start);
432 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
433 debug ("after writing.... the start address is %x\n", bar[count]);
434 /* _________________________________________________________________________*/
435
436 } else {
437 /* This is Memory */
438 if (bar[count] & PCI_BASE_ADDRESS_MEM_PREFETCH) {
439 /* pfmem */
440 debug ("PFMEM SPACE\n");
441
442 len[count] = bar[count] & 0xFFFFFFF0;
443 len[count] = ~len[count] + 1;
444
445 debug ("len[count] in PFMEM %x, count %d\n", len[count], count);
446
447 pfmem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
448 if (!pfmem[count]) {
449 err ("out of system memory\n");
450 return -ENOMEM;
451 }
452 memset (pfmem[count], 0, sizeof (struct resource_node));
453 pfmem[count]->type = PFMEM;
454 pfmem[count]->busno = func->busno;
455 pfmem[count]->devfunc = PCI_DEVFN(func->device,
456 func->function);
457 pfmem[count]->len = len[count];
458 pfmem[count]->fromMem = FALSE;
459 if (ibmphp_check_resource (pfmem[count], 0) == 0) {
460 ibmphp_add_resource (pfmem[count]);
461 func->pfmem[count] = pfmem[count];
462 } else {
463 mem_tmp = kmalloc(sizeof(*mem_tmp), GFP_KERNEL);
464 if (!mem_tmp) {
465 err ("out of system memory\n");
466 kfree (pfmem[count]);
467 return -ENOMEM;
468 }
469 memset (mem_tmp, 0, sizeof (struct resource_node));
470 mem_tmp->type = MEM;
471 mem_tmp->busno = pfmem[count]->busno;
472 mem_tmp->devfunc = pfmem[count]->devfunc;
473 mem_tmp->len = pfmem[count]->len;
474 debug ("there's no pfmem... going into mem.\n");
475 if (ibmphp_check_resource (mem_tmp, 0) == 0) {
476 ibmphp_add_resource (mem_tmp);
477 pfmem[count]->fromMem = TRUE;
478 pfmem[count]->rangeno = mem_tmp->rangeno;
479 pfmem[count]->start = mem_tmp->start;
480 pfmem[count]->end = mem_tmp->end;
481 ibmphp_add_pfmem_from_mem (pfmem[count]);
482 func->pfmem[count] = pfmem[count];
483 } else {
484 err ("cannot allocate requested pfmem for bus %x, device %x, len %x\n",
485 func->busno, func->device, len[count]);
486 kfree (mem_tmp);
487 kfree (pfmem[count]);
488 return -EIO;
489 }
490 }
491
492 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start);
493
494 /*_______________This is for debugging purposes only______________________________*/
495 debug ("b4 writing, start address is %x\n", func->pfmem[count]->start);
496 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
497 debug ("after writing, start address is %x\n", bar[count]);
498 /*_________________________________________________________________________________*/
499
500 if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) { /* takes up another dword */
501 debug ("inside the mem 64 case, count %d\n", count);
502 count += 1;
503 /* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
504 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
505 }
506 } else {
507 /* regular memory */
508 debug ("REGULAR MEM SPACE\n");
509
510 len[count] = bar[count] & 0xFFFFFFF0;
511 len[count] = ~len[count] + 1;
512
513 debug ("len[count] in Mem %x, count %d\n", len[count], count);
514
515 mem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
516 if (!mem[count]) {
517 err ("out of system memory\n");
518 return -ENOMEM;
519 }
520 memset (mem[count], 0, sizeof (struct resource_node));
521 mem[count]->type = MEM;
522 mem[count]->busno = func->busno;
523 mem[count]->devfunc = PCI_DEVFN(func->device,
524 func->function);
525 mem[count]->len = len[count];
526 if (ibmphp_check_resource (mem[count], 0) == 0) {
527 ibmphp_add_resource (mem[count]);
528 func->mem[count] = mem[count];
529 } else {
530 err ("cannot allocate requested mem for bus %x, device %x, len %x\n",
531 func->busno, func->device, len[count]);
532 kfree (mem[count]);
533 return -EIO;
534 }
535 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->mem[count]->start);
536 /* _______________________This is for debugging purposes only _______________________*/
537 debug ("b4 writing, start address is %x\n", func->mem[count]->start);
538 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
539 debug ("after writing, the address is %x\n", bar[count]);
540 /* __________________________________________________________________________________*/
541
542 if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
543 /* takes up another dword */
544 debug ("inside mem 64 case, reg. mem, count %d\n", count);
545 count += 1;
546 /* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
547 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
548 }
549 }
550 } /* end of mem */
551 } /* end of for */
552
553 func->bus = 0; /* To indicate that this is not a PPB */
554 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_PIN, &irq);
555 if ((irq > 0x00) && (irq < 0x05))
556 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_LINE, func->irq[irq - 1]);
557
558 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);
559 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);
560
561 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_ROM_ADDRESS, 0x00L);
562 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);
563
564 return 0;
565}
566
567/******************************************************************************
568 * This routine configures a PCI-2-PCI bridge and the functions behind it
569 * Parameters: pci_func
570 * Returns:
571 ******************************************************************************/
572static int configure_bridge (struct pci_func **func_passed, u8 slotno)
573{
574 int count;
575 int i;
576 int rc;
577 u8 sec_number;
578 u8 io_base;
579 u16 pfmem_base;
580 u32 bar[2];
581 u32 len[2];
582 u8 flag_io = FALSE;
583 u8 flag_mem = FALSE;
584 u8 flag_pfmem = FALSE;
585 u8 need_io_upper = FALSE;
586 u8 need_pfmem_upper = FALSE;
587 struct res_needed *amount_needed = NULL;
588 struct resource_node *io = NULL;
589 struct resource_node *bus_io[2] = {NULL, NULL};
590 struct resource_node *mem = NULL;
591 struct resource_node *bus_mem[2] = {NULL, NULL};
592 struct resource_node *mem_tmp = NULL;
593 struct resource_node *pfmem = NULL;
594 struct resource_node *bus_pfmem[2] = {NULL, NULL};
595 struct bus_node *bus;
596 u32 address[] = {
597 PCI_BASE_ADDRESS_0,
598 PCI_BASE_ADDRESS_1,
599 0
600 };
601 struct pci_func *func = *func_passed;
602 unsigned int devfn;
603 u8 irq;
604 int retval;
605
606 debug ("%s - enter\n", __FUNCTION__);
607
608 devfn = PCI_DEVFN(func->function, func->device);
609 ibmphp_pci_bus->number = func->busno;
610
611 /* Configuring necessary info for the bridge so that we could see the devices
612 * behind it
613 */
614
615 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, func->busno);
616
617 /* _____________________For debugging purposes only __________________________
618 pci_bus_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, &pri_number);
619 debug ("primary # written into the bridge is %x\n", pri_number);
620 ___________________________________________________________________________*/
621
622 /* in EBDA, only get allocated 1 additional bus # per slot */
623 sec_number = find_sec_number (func->busno, slotno);
624 if (sec_number == 0xff) {
625 err ("cannot allocate secondary bus number for the bridged device\n");
626 return -EINVAL;
627 }
628
629 debug ("after find_sec_number, the number we got is %x\n", sec_number);
630 debug ("AFTER FIND_SEC_NUMBER, func->busno IS %x\n", func->busno);
631
632 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, sec_number);
633
634 /* __________________For debugging purposes only __________________________________
635 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
636 debug ("sec_number after write/read is %x\n", sec_number);
637 ________________________________________________________________________________*/
638
639 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, sec_number);
640
641 /* __________________For debugging purposes only ____________________________________
642 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, &sec_number);
643 debug ("subordinate number after write/read is %x\n", sec_number);
644 __________________________________________________________________________________*/
645
646 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);
647 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);
648 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SEC_LATENCY_TIMER, LATENCY);
649
650 debug ("func->busno is %x\n", func->busno);
651 debug ("sec_number after writing is %x\n", sec_number);
652
653
654 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
655 !!!!!!!!!!!!!!!NEED TO ADD!!! FAST BACK-TO-BACK ENABLE!!!!!!!!!!!!!!!!!!!!
656 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
657
658
659 /* First we need to allocate mem/io for the bridge itself in case it needs it */
660 for (count = 0; address[count]; count++) { /* for 2 BARs */
661 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
662 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
663
664 if (!bar[count]) {
665 /* This BAR is not implemented */
666 debug ("so we come here then, eh?, count = %d\n", count);
667 continue;
668 }
669 // tmp_bar = bar[count];
670
671 debug ("Bar %d wants %x\n", count, bar[count]);
672
673 if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
674 /* This is IO */
675 len[count] = bar[count] & 0xFFFFFFFC;
676 len[count] = ~len[count] + 1;
677
678 debug ("len[count] in IO = %x\n", len[count]);
679
680 bus_io[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
681
682 if (!bus_io[count]) {
683 err ("out of system memory\n");
684 retval = -ENOMEM;
685 goto error;
686 }
687 memset (bus_io[count], 0, sizeof (struct resource_node));
688 bus_io[count]->type = IO;
689 bus_io[count]->busno = func->busno;
690 bus_io[count]->devfunc = PCI_DEVFN(func->device,
691 func->function);
692 bus_io[count]->len = len[count];
693 if (ibmphp_check_resource (bus_io[count], 0) == 0) {
694 ibmphp_add_resource (bus_io[count]);
695 func->io[count] = bus_io[count];
696 } else {
697 err ("cannot allocate requested io for bus %x, device %x, len %x\n",
698 func->busno, func->device, len[count]);
699 kfree (bus_io[count]);
700 return -EIO;
701 }
702
703 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->io[count]->start);
704
705 } else {
706 /* This is Memory */
707 if (bar[count] & PCI_BASE_ADDRESS_MEM_PREFETCH) {
708 /* pfmem */
709 len[count] = bar[count] & 0xFFFFFFF0;
710 len[count] = ~len[count] + 1;
711
712 debug ("len[count] in PFMEM = %x\n", len[count]);
713
714 bus_pfmem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
715 if (!bus_pfmem[count]) {
716 err ("out of system memory\n");
717 retval = -ENOMEM;
718 goto error;
719 }
720 memset (bus_pfmem[count], 0, sizeof (struct resource_node));
721 bus_pfmem[count]->type = PFMEM;
722 bus_pfmem[count]->busno = func->busno;
723 bus_pfmem[count]->devfunc = PCI_DEVFN(func->device,
724 func->function);
725 bus_pfmem[count]->len = len[count];
726 bus_pfmem[count]->fromMem = FALSE;
727 if (ibmphp_check_resource (bus_pfmem[count], 0) == 0) {
728 ibmphp_add_resource (bus_pfmem[count]);
729 func->pfmem[count] = bus_pfmem[count];
730 } else {
731 mem_tmp = kmalloc(sizeof(*mem_tmp), GFP_KERNEL);
732 if (!mem_tmp) {
733 err ("out of system memory\n");
734 retval = -ENOMEM;
735 goto error;
736 }
737 memset (mem_tmp, 0, sizeof (struct resource_node));
738 mem_tmp->type = MEM;
739 mem_tmp->busno = bus_pfmem[count]->busno;
740 mem_tmp->devfunc = bus_pfmem[count]->devfunc;
741 mem_tmp->len = bus_pfmem[count]->len;
742 if (ibmphp_check_resource (mem_tmp, 0) == 0) {
743 ibmphp_add_resource (mem_tmp);
744 bus_pfmem[count]->fromMem = TRUE;
745 bus_pfmem[count]->rangeno = mem_tmp->rangeno;
746 ibmphp_add_pfmem_from_mem (bus_pfmem[count]);
747 func->pfmem[count] = bus_pfmem[count];
748 } else {
749 err ("cannot allocate requested pfmem for bus %x, device %x, len %x\n",
750 func->busno, func->device, len[count]);
751 kfree (mem_tmp);
752 kfree (bus_pfmem[count]);
753 return -EIO;
754 }
755 }
756
757 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start);
758
759 if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
760 /* takes up another dword */
761 count += 1;
762 /* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
763 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
764
765 }
766 } else {
767 /* regular memory */
768 len[count] = bar[count] & 0xFFFFFFF0;
769 len[count] = ~len[count] + 1;
770
771 debug ("len[count] in Memory is %x\n", len[count]);
772
773 bus_mem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
774 if (!bus_mem[count]) {
775 err ("out of system memory\n");
776 retval = -ENOMEM;
777 goto error;
778 }
779 memset (bus_mem[count], 0, sizeof (struct resource_node));
780 bus_mem[count]->type = MEM;
781 bus_mem[count]->busno = func->busno;
782 bus_mem[count]->devfunc = PCI_DEVFN(func->device,
783 func->function);
784 bus_mem[count]->len = len[count];
785 if (ibmphp_check_resource (bus_mem[count], 0) == 0) {
786 ibmphp_add_resource (bus_mem[count]);
787 func->mem[count] = bus_mem[count];
788 } else {
789 err ("cannot allocate requested mem for bus %x, device %x, len %x\n",
790 func->busno, func->device, len[count]);
791 kfree (bus_mem[count]);
792 return -EIO;
793 }
794
795 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->mem[count]->start);
796
797 if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
798 /* takes up another dword */
799 count += 1;
800 /* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
801 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
802
803 }
804 }
805 } /* end of mem */
806 } /* end of for */
807
808 /* Now need to see how much space the devices behind the bridge needed */
809 amount_needed = scan_behind_bridge (func, sec_number);
810 if (amount_needed == NULL)
811 return -ENOMEM;
812
813 ibmphp_pci_bus->number = func->busno;
814 debug ("after coming back from scan_behind_bridge\n");
815 debug ("amount_needed->not_correct = %x\n", amount_needed->not_correct);
816 debug ("amount_needed->io = %x\n", amount_needed->io);
817 debug ("amount_needed->mem = %x\n", amount_needed->mem);
818 debug ("amount_needed->pfmem = %x\n", amount_needed->pfmem);
819
820 if (amount_needed->not_correct) {
821 debug ("amount_needed is not correct\n");
822 for (count = 0; address[count]; count++) {
823 /* for 2 BARs */
824 if (bus_io[count]) {
825 ibmphp_remove_resource (bus_io[count]);
826 func->io[count] = NULL;
827 } else if (bus_pfmem[count]) {
828 ibmphp_remove_resource (bus_pfmem[count]);
829 func->pfmem[count] = NULL;
830 } else if (bus_mem[count]) {
831 ibmphp_remove_resource (bus_mem[count]);
832 func->mem[count] = NULL;
833 }
834 }
835 kfree (amount_needed);
836 return -ENODEV;
837 }
838
839 if (!amount_needed->io) {
840 debug ("it doesn't want IO?\n");
841 flag_io = TRUE;
842 } else {
843 debug ("it wants %x IO behind the bridge\n", amount_needed->io);
844 io = kmalloc(sizeof(*io), GFP_KERNEL);
845
846 if (!io) {
847 err ("out of system memory\n");
848 retval = -ENOMEM;
849 goto error;
850 }
851 memset (io, 0, sizeof (struct resource_node));
852 io->type = IO;
853 io->busno = func->busno;
854 io->devfunc = PCI_DEVFN(func->device, func->function);
855 io->len = amount_needed->io;
856 if (ibmphp_check_resource (io, 1) == 0) {
857 debug ("were we able to add io\n");
858 ibmphp_add_resource (io);
859 flag_io = TRUE;
860 }
861 }
862
863 if (!amount_needed->mem) {
864 debug ("it doesn't want n.e.memory?\n");
865 flag_mem = TRUE;
866 } else {
867 debug ("it wants %x memory behind the bridge\n", amount_needed->mem);
868 mem = kmalloc(sizeof(*mem), GFP_KERNEL);
869 if (!mem) {
870 err ("out of system memory\n");
871 retval = -ENOMEM;
872 goto error;
873 }
874 memset (mem, 0, sizeof (struct resource_node));
875 mem->type = MEM;
876 mem->busno = func->busno;
877 mem->devfunc = PCI_DEVFN(func->device, func->function);
878 mem->len = amount_needed->mem;
879 if (ibmphp_check_resource (mem, 1) == 0) {
880 ibmphp_add_resource (mem);
881 flag_mem = TRUE;
882 debug ("were we able to add mem\n");
883 }
884 }
885
886 if (!amount_needed->pfmem) {
887 debug ("it doesn't want n.e.pfmem mem?\n");
888 flag_pfmem = TRUE;
889 } else {
890 debug ("it wants %x pfmemory behind the bridge\n", amount_needed->pfmem);
891 pfmem = kmalloc(sizeof(*pfmem), GFP_KERNEL);
892 if (!pfmem) {
893 err ("out of system memory\n");
894 retval = -ENOMEM;
895 goto error;
896 }
897 memset (pfmem, 0, sizeof (struct resource_node));
898 pfmem->type = PFMEM;
899 pfmem->busno = func->busno;
900 pfmem->devfunc = PCI_DEVFN(func->device, func->function);
901 pfmem->len = amount_needed->pfmem;
902 pfmem->fromMem = FALSE;
903 if (ibmphp_check_resource (pfmem, 1) == 0) {
904 ibmphp_add_resource (pfmem);
905 flag_pfmem = TRUE;
906 } else {
907 mem_tmp = kmalloc(sizeof(*mem_tmp), GFP_KERNEL);
908 if (!mem_tmp) {
909 err ("out of system memory\n");
910 retval = -ENOMEM;
911 goto error;
912 }
913 memset (mem_tmp, 0, sizeof (struct resource_node));
914 mem_tmp->type = MEM;
915 mem_tmp->busno = pfmem->busno;
916 mem_tmp->devfunc = pfmem->devfunc;
917 mem_tmp->len = pfmem->len;
918 if (ibmphp_check_resource (mem_tmp, 1) == 0) {
919 ibmphp_add_resource (mem_tmp);
920 pfmem->fromMem = TRUE;
921 pfmem->rangeno = mem_tmp->rangeno;
922 ibmphp_add_pfmem_from_mem (pfmem);
923 flag_pfmem = TRUE;
924 }
925 }
926 }
927
928 debug ("b4 if (flag_io && flag_mem && flag_pfmem)\n");
929 debug ("flag_io = %x, flag_mem = %x, flag_pfmem = %x\n", flag_io, flag_mem, flag_pfmem);
930
931 if (flag_io && flag_mem && flag_pfmem) {
932 /* If on bootup, there was a bridged card in this slot,
933 * then card was removed and ibmphp got unloaded and loaded
934 * back again, there's no way for us to remove the bus
935 * struct, so no need to kmalloc, can use existing node
936 */
937 bus = ibmphp_find_res_bus (sec_number);
938 if (!bus) {
939 bus = kmalloc(sizeof(*bus), GFP_KERNEL);
940 if (!bus) {
941 err ("out of system memory\n");
942 retval = -ENOMEM;
943 goto error;
944 }
945 memset (bus, 0, sizeof (struct bus_node));
946 bus->busno = sec_number;
947 debug ("b4 adding new bus\n");
948 rc = add_new_bus (bus, io, mem, pfmem, func->busno);
949 } else if (!(bus->rangeIO) && !(bus->rangeMem) && !(bus->rangePFMem))
950 rc = add_new_bus (bus, io, mem, pfmem, 0xFF);
951 else {
952 err ("expected bus structure not empty?\n");
953 retval = -EIO;
954 goto error;
955 }
956 if (rc) {
957 if (rc == -ENOMEM) {
958 ibmphp_remove_bus (bus, func->busno);
959 kfree (amount_needed);
960 return rc;
961 }
962 retval = rc;
963 goto error;
964 }
965 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &io_base);
966 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &pfmem_base);
967
968 if ((io_base & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
969 debug ("io 32\n");
970 need_io_upper = TRUE;
971 }
972 if ((io_base & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) {
973 debug ("pfmem 64\n");
974 need_pfmem_upper = TRUE;
975 }
976
977 if (bus->noIORanges) {
978 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, 0x00 | bus->rangeIO->start >> 8);
979 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00 | bus->rangeIO->end >> 8);
980
981 /* _______________This is for debugging purposes only ____________________
982 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &temp);
983 debug ("io_base = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8);
984 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, &temp);
985 debug ("io_limit = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8);
986 ________________________________________________________________________*/
987
988 if (need_io_upper) { /* since can't support n.e.ways */
989 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_IO_BASE_UPPER16, 0x0000);
990 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_IO_LIMIT_UPPER16, 0x0000);
991 }
992 } else {
993 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, 0x00);
994 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00);
995 }
996
997 if (bus->noMemRanges) {
998 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, 0x0000 | bus->rangeMem->start >> 16);
999 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000 | bus->rangeMem->end >> 16);
1000
1001 /* ____________________This is for debugging purposes only ________________________
1002 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, &temp);
1003 debug ("mem_base = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
1004 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, &temp);
1005 debug ("mem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
1006 __________________________________________________________________________________*/
1007
1008 } else {
1009 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, 0xffff);
1010 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000);
1011 }
1012 if (bus->noPFMemRanges) {
1013 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, 0x0000 | bus->rangePFMem->start >> 16);
1014 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, 0x0000 | bus->rangePFMem->end >> 16);
1015
1016 /* __________________________This is for debugging purposes only _______________________
1017 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &temp);
1018 debug ("pfmem_base = %x", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
1019 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &temp);
1020 debug ("pfmem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
1021 ______________________________________________________________________________________*/
1022
1023 if (need_pfmem_upper) { /* since can't support n.e.ways */
1024 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_BASE_UPPER32, 0x00000000);
1025 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_LIMIT_UPPER32, 0x00000000);
1026 }
1027 } else {
1028 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, 0xffff);
1029 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, 0x0000);
1030 }
1031
1032 debug ("b4 writing control information\n");
1033
1034 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_PIN, &irq);
1035 if ((irq > 0x00) && (irq < 0x05))
1036 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_LINE, func->irq[irq - 1]);
1037 /*
1038 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, ctrl);
1039 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_PARITY);
1040 pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_SERR);
1041 */
1042
1043 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);
1044 pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, 0x07);
1045 for (i = 0; i < 32; i++) {
1046 if (amount_needed->devices[i]) {
1047 debug ("device where devices[i] is 1 = %x\n", i);
1048 func->devices[i] = 1;
1049 }
1050 }
1051 func->bus = 1; /* For unconfiguring, to indicate it's PPB */
1052 func_passed = &func;
1053 debug ("func->busno b4 returning is %x\n", func->busno);
1054 debug ("func->busno b4 returning in the other structure is %x\n", (*func_passed)->busno);
1055 kfree (amount_needed);
1056 return 0;
1057 } else {
1058 err ("Configuring bridge was unsuccessful...\n");
1059 mem_tmp = NULL;
1060 retval = -EIO;
1061 goto error;
1062 }
1063
1064error:
1065 kfree(amount_needed);
1066 if (pfmem)
1067 ibmphp_remove_resource (pfmem);
1068 if (io)
1069 ibmphp_remove_resource (io);
1070 if (mem)
1071 ibmphp_remove_resource (mem);
1072 for (i = 0; i < 2; i++) { /* for 2 BARs */
1073 if (bus_io[i]) {
1074 ibmphp_remove_resource (bus_io[i]);
1075 func->io[i] = NULL;
1076 } else if (bus_pfmem[i]) {
1077 ibmphp_remove_resource (bus_pfmem[i]);
1078 func->pfmem[i] = NULL;
1079 } else if (bus_mem[i]) {
1080 ibmphp_remove_resource (bus_mem[i]);
1081 func->mem[i] = NULL;
1082 }
1083 }
1084 return retval;
1085}
1086
1087/*****************************************************************************
1088 * This function adds up the amount of resources needed behind the PPB bridge
1089 * and passes it to the configure_bridge function
1090 * Input: bridge function
1091 * Ouput: amount of resources needed
1092 *****************************************************************************/
1093static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno)
1094{
1095 int count, len[6];
1096 u16 vendor_id;
1097 u8 hdr_type;
1098 u8 device, function;
1099 unsigned int devfn;
1100 int howmany = 0; /*this is to see if there are any devices behind the bridge */
1101
1102 u32 bar[6], class;
1103 u32 address[] = {
1104 PCI_BASE_ADDRESS_0,
1105 PCI_BASE_ADDRESS_1,
1106 PCI_BASE_ADDRESS_2,
1107 PCI_BASE_ADDRESS_3,
1108 PCI_BASE_ADDRESS_4,
1109 PCI_BASE_ADDRESS_5,
1110 0
1111 };
1112 struct res_needed *amount;
1113
1114 amount = kmalloc(sizeof(*amount), GFP_KERNEL);
1115 if (amount == NULL)
1116 return NULL;
1117 memset (amount, 0, sizeof (struct res_needed));
1118
1119 ibmphp_pci_bus->number = busno;
1120
1121 debug ("the bus_no behind the bridge is %x\n", busno);
1122 debug ("scanning devices behind the bridge...\n");
1123 for (device = 0; device < 32; device++) {
1124 amount->devices[device] = 0;
1125 for (function = 0; function < 8; function++) {
1126 devfn = PCI_DEVFN(device, function);
1127
1128 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
1129
1130 if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
1131 /* found correct device!!! */
1132 howmany++;
1133
1134 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
1135 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
1136
1137 debug ("hdr_type behind the bridge is %x\n", hdr_type);
1138 if (hdr_type & PCI_HEADER_TYPE_BRIDGE) {
1139 err ("embedded bridges not supported for hot-plugging.\n");
1140 amount->not_correct = TRUE;
1141 return amount;
1142 }
1143
1144 class >>= 8; /* to take revision out, class = class.subclass.prog i/f */
1145 if (class == PCI_CLASS_NOT_DEFINED_VGA) {
1146 err ("The device %x is VGA compatible and as is not supported for hot plugging. "
1147 "Please choose another device.\n", device);
1148 amount->not_correct = TRUE;
1149 return amount;
1150 } else if (class == PCI_CLASS_DISPLAY_VGA) {
1151 err ("The device %x is not supported for hot plugging. "
1152 "Please choose another device.\n", device);
1153 amount->not_correct = TRUE;
1154 return amount;
1155 }
1156
1157 amount->devices[device] = 1;
1158
1159 for (count = 0; address[count]; count++) {
1160 /* for 6 BARs */
1161 /*
1162 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, address[count], &tmp);
1163 if (tmp & 0x01) // IO
1164 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFD);
1165 else // MEMORY
1166 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
1167 */
1168 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
1169 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
1170
1171 debug ("what is bar[count]? %x, count = %d\n", bar[count], count);
1172
1173 if (!bar[count]) /* This BAR is not implemented */
1174 continue;
1175
1176 //tmp_bar = bar[count];
1177
1178 debug ("count %d device %x function %x wants %x resources\n", count, device, function, bar[count]);
1179
1180 if (bar[count] & PCI_BASE_ADDRESS_SPACE_IO) {
1181 /* This is IO */
1182 len[count] = bar[count] & 0xFFFFFFFC;
1183 len[count] = ~len[count] + 1;
1184 amount->io += len[count];
1185 } else {
1186 /* This is Memory */
1187 if (bar[count] & PCI_BASE_ADDRESS_MEM_PREFETCH) {
1188 /* pfmem */
1189 len[count] = bar[count] & 0xFFFFFFF0;
1190 len[count] = ~len[count] + 1;
1191 amount->pfmem += len[count];
1192 if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64)
1193 /* takes up another dword */
1194 count += 1;
1195
1196 } else {
1197 /* regular memory */
1198 len[count] = bar[count] & 0xFFFFFFF0;
1199 len[count] = ~len[count] + 1;
1200 amount->mem += len[count];
1201 if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
1202 /* takes up another dword */
1203 count += 1;
1204 }
1205 }
1206 }
1207 } /* end for */
1208 } /* end if (valid) */
1209 } /* end for */
1210 } /* end for */
1211
1212 if (!howmany)
1213 amount->not_correct = TRUE;
1214 else
1215 amount->not_correct = FALSE;
1216 if ((amount->io) && (amount->io < IOBRIDGE))
1217 amount->io = IOBRIDGE;
1218 if ((amount->mem) && (amount->mem < MEMBRIDGE))
1219 amount->mem = MEMBRIDGE;
1220 if ((amount->pfmem) && (amount->pfmem < MEMBRIDGE))
1221 amount->pfmem = MEMBRIDGE;
1222 return amount;
1223}
1224
1225/* The following 3 unconfigure_boot_ routines deal with the case when we had the card
1226 * upon bootup in the system, since we don't allocate func to such case, we need to read
1227 * the start addresses from pci config space and then find the corresponding entries in
1228 * our resource lists. The functions return either 0, -ENODEV, or -1 (general failure)
1229 * Change: we also call these functions even if we configured the card ourselves (i.e., not
1230 * the bootup case), since it should work same way
1231 */
1232static int unconfigure_boot_device (u8 busno, u8 device, u8 function)
1233{
1234 u32 start_address;
1235 u32 address[] = {
1236 PCI_BASE_ADDRESS_0,
1237 PCI_BASE_ADDRESS_1,
1238 PCI_BASE_ADDRESS_2,
1239 PCI_BASE_ADDRESS_3,
1240 PCI_BASE_ADDRESS_4,
1241 PCI_BASE_ADDRESS_5,
1242 0
1243 };
1244 int count;
1245 struct resource_node *io;
1246 struct resource_node *mem;
1247 struct resource_node *pfmem;
1248 struct bus_node *bus;
1249 u32 end_address;
1250 u32 temp_end;
1251 u32 size;
1252 u32 tmp_address;
1253 unsigned int devfn;
1254
1255 debug ("%s - enter\n", __FUNCTION__);
1256
1257 bus = ibmphp_find_res_bus (busno);
1258 if (!bus) {
1259 debug ("cannot find corresponding bus.\n");
1260 return -EINVAL;
1261 }
1262
1263 devfn = PCI_DEVFN(device, function);
1264 ibmphp_pci_bus->number = busno;
1265 for (count = 0; address[count]; count++) { /* for 6 BARs */
1266 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &start_address);
1267
1268 /* We can do this here, b/c by that time the device driver of the card has been stopped */
1269
1270 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
1271 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &size);
1272 pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], start_address);
1273
1274 debug ("start_address is %x\n", start_address);
1275 debug ("busno, device, function %x %x %x\n", busno, device, function);
1276 if (!size) {
1277 /* This BAR is not implemented */
1278 debug ("is this bar no implemented?, count = %d\n", count);
1279 continue;
1280 }
1281 tmp_address = start_address;
1282 if (start_address & PCI_BASE_ADDRESS_SPACE_IO) {
1283 /* This is IO */
1284 start_address &= PCI_BASE_ADDRESS_IO_MASK;
1285 size = size & 0xFFFFFFFC;
1286 size = ~size + 1;
1287 end_address = start_address + size - 1;
1288 if (ibmphp_find_resource (bus, start_address, &io, IO) < 0) {
1289 err ("cannot find corresponding IO resource to remove\n");
1290 return -EIO;
1291 }
1292 debug ("io->start = %x\n", io->start);
1293 temp_end = io->end;
1294 start_address = io->end + 1;
1295 ibmphp_remove_resource (io);
1296 /* This is needed b/c of the old I/O restrictions in the BIOS */
1297 while (temp_end < end_address) {
1298 if (ibmphp_find_resource (bus, start_address, &io, IO) < 0) {
1299 err ("cannot find corresponding IO resource to remove\n");
1300 return -EIO;
1301 }
1302 debug ("io->start = %x\n", io->start);
1303 temp_end = io->end;
1304 start_address = io->end + 1;
1305 ibmphp_remove_resource (io);
1306 }
1307
1308 /* ????????? DO WE NEED TO WRITE ANYTHING INTO THE PCI CONFIG SPACE BACK ?????????? */
1309 } else {
1310 /* This is Memory */
1311 start_address &= PCI_BASE_ADDRESS_MEM_MASK;
1312 if (start_address & PCI_BASE_ADDRESS_MEM_PREFETCH) {
1313 /* pfmem */
1314 debug ("start address of pfmem is %x\n", start_address);
1315
1316 if (ibmphp_find_resource (bus, start_address, &pfmem, PFMEM) < 0) {
1317 err ("cannot find corresponding PFMEM resource to remove\n");
1318 return -EIO;
1319 }
1320 if (pfmem) {
1321 debug ("pfmem->start = %x\n", pfmem->start);
1322
1323 ibmphp_remove_resource(pfmem);
1324 }
1325 } else {
1326 /* regular memory */
1327 debug ("start address of mem is %x\n", start_address);
1328 if (ibmphp_find_resource (bus, start_address, &mem, MEM) < 0) {
1329 err ("cannot find corresponding MEM resource to remove\n");
1330 return -EIO;
1331 }
1332 if (mem) {
1333 debug ("mem->start = %x\n", mem->start);
1334
1335 ibmphp_remove_resource(mem);
1336 }
1337 }
1338 if (tmp_address & PCI_BASE_ADDRESS_MEM_TYPE_64) {
1339 /* takes up another dword */
1340 count += 1;
1341 }
1342 } /* end of mem */
1343 } /* end of for */
1344
1345 return 0;
1346}
1347
1348static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
1349{
1350 int count;
1351 int bus_no, pri_no, sub_no, sec_no = 0;
1352 u32 start_address, tmp_address;
1353 u8 sec_number, sub_number, pri_number;
1354 struct resource_node *io = NULL;
1355 struct resource_node *mem = NULL;
1356 struct resource_node *pfmem = NULL;
1357 struct bus_node *bus;
1358 u32 address[] = {
1359 PCI_BASE_ADDRESS_0,
1360 PCI_BASE_ADDRESS_1,
1361 0
1362 };
1363 unsigned int devfn;
1364
1365 devfn = PCI_DEVFN(device, function);
1366 ibmphp_pci_bus->number = busno;
1367 bus_no = (int) busno;
1368 debug ("busno is %x\n", busno);
1369 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, &pri_number);
1370 debug ("%s - busno = %x, primary_number = %x\n", __FUNCTION__, busno, pri_number);
1371
1372 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
1373 debug ("sec_number is %x\n", sec_number);
1374 sec_no = (int) sec_number;
1375 pri_no = (int) pri_number;
1376 if (pri_no != bus_no) {
1377 err ("primary numbers in our structures and pci config space don't match.\n");
1378 return -EINVAL;
1379 }
1380
1381 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, &sub_number);
1382 sub_no = (int) sub_number;
1383 debug ("sub_no is %d, sec_no is %d\n", sub_no, sec_no);
1384 if (sec_no != sub_number) {
1385 err ("there're more buses behind this bridge. Hot removal is not supported. Please choose another card\n");
1386 return -ENODEV;
1387 }
1388
1389 bus = ibmphp_find_res_bus (sec_number);
1390 debug ("bus->busno is %x\n", bus->busno);
1391 debug ("sec_number is %x\n", sec_number);
1392 if (!bus) {
1393 err ("cannot find Bus structure for the bridged device\n");
1394 return -EINVAL;
1395 }
1396
1397 ibmphp_remove_bus (bus, busno);
1398
1399 for (count = 0; address[count]; count++) {
1400 /* for 2 BARs */
1401 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &start_address);
1402
1403 if (!start_address) {
1404 /* This BAR is not implemented */
1405 continue;
1406 }
1407
1408 tmp_address = start_address;
1409
1410 if (start_address & PCI_BASE_ADDRESS_SPACE_IO) {
1411 /* This is IO */
1412 start_address &= PCI_BASE_ADDRESS_IO_MASK;
1413 if (ibmphp_find_resource (bus, start_address, &io, IO) < 0) {
1414 err ("cannot find corresponding IO resource to remove\n");
1415 return -EIO;
1416 }
1417 if (io)
1418 debug ("io->start = %x\n", io->start);
1419
1420 ibmphp_remove_resource (io);
1421
1422 /* ????????? DO WE NEED TO WRITE ANYTHING INTO THE PCI CONFIG SPACE BACK ?????????? */
1423 } else {
1424 /* This is Memory */
1425 start_address &= PCI_BASE_ADDRESS_MEM_MASK;
1426 if (start_address & PCI_BASE_ADDRESS_MEM_PREFETCH) {
1427 /* pfmem */
1428 if (ibmphp_find_resource (bus, start_address, &pfmem, PFMEM) < 0) {
1429 err ("cannot find corresponding PFMEM resource to remove\n");
1430 return -EINVAL;
1431 }
1432 if (pfmem) {
1433 debug ("pfmem->start = %x\n", pfmem->start);
1434
1435 ibmphp_remove_resource(pfmem);
1436 }
1437 } else {
1438 /* regular memory */
1439 if (ibmphp_find_resource (bus, start_address, &mem, MEM) < 0) {
1440 err ("cannot find corresponding MEM resource to remove\n");
1441 return -EINVAL;
1442 }
1443 if (mem) {
1444 debug ("mem->start = %x\n", mem->start);
1445
1446 ibmphp_remove_resource(mem);
1447 }
1448 }
1449 if (tmp_address & PCI_BASE_ADDRESS_MEM_TYPE_64) {
1450 /* takes up another dword */
1451 count += 1;
1452 }
1453 } /* end of mem */
1454 } /* end of for */
1455 debug ("%s - exiting, returning success\n", __FUNCTION__);
1456 return 0;
1457}
1458
1459static int unconfigure_boot_card (struct slot *slot_cur)
1460{
1461 u16 vendor_id;
1462 u32 class;
1463 u8 hdr_type;
1464 u8 device;
1465 u8 busno;
1466 u8 function;
1467 int rc;
1468 unsigned int devfn;
1469 u8 valid_device = 0x00; /* To see if we are ever able to find valid device and read it */
1470
1471 debug ("%s - enter\n", __FUNCTION__);
1472
1473 device = slot_cur->device;
1474 busno = slot_cur->bus;
1475
1476 debug ("b4 for loop, device is %x\n", device);
1477 /* For every function on the card */
1478 for (function = 0x0; function < 0x08; function++) {
1479 devfn = PCI_DEVFN(device, function);
1480 ibmphp_pci_bus->number = busno;
1481
1482 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
1483
1484 if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
1485 /* found correct device!!! */
1486 ++valid_device;
1487
1488 debug ("%s - found correct device\n", __FUNCTION__);
1489
1490 /* header: x x x x x x x x
1491 * | |___________|=> 1=PPB bridge, 0=normal device, 2=CardBus Bridge
1492 * |_=> 0 = single function device, 1 = multi-function device
1493 */
1494
1495 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
1496 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
1497
1498 debug ("hdr_type %x, class %x\n", hdr_type, class);
1499 class >>= 8; /* to take revision out, class = class.subclass.prog i/f */
1500 if (class == PCI_CLASS_NOT_DEFINED_VGA) {
1501 err ("The device %x function %x is VGA compatible and is not supported for hot removing. "
1502 "Please choose another device.\n", device, function);
1503 return -ENODEV;
1504 } else if (class == PCI_CLASS_DISPLAY_VGA) {
1505 err ("The device %x function %x is not supported for hot removing. "
1506 "Please choose another device.\n", device, function);
1507 return -ENODEV;
1508 }
1509
1510 switch (hdr_type) {
1511 case PCI_HEADER_TYPE_NORMAL:
1512 rc = unconfigure_boot_device (busno, device, function);
1513 if (rc) {
1514 err ("was not able to unconfigure device %x func %x on bus %x. bailing out...\n",
1515 device, function, busno);
1516 return rc;
1517 }
1518 function = 0x8;
1519 break;
1520 case PCI_HEADER_TYPE_MULTIDEVICE:
1521 rc = unconfigure_boot_device (busno, device, function);
1522 if (rc) {
1523 err ("was not able to unconfigure device %x func %x on bus %x. bailing out...\n",
1524 device, function, busno);
1525 return rc;
1526 }
1527 break;
1528 case PCI_HEADER_TYPE_BRIDGE:
1529 class >>= 8;
1530 if (class != PCI_CLASS_BRIDGE_PCI) {
1531 err ("This device %x function %x is not PCI-to-PCI bridge, "
1532 "and is not supported for hot-removing. "
1533 "Please try another card.\n", device, function);
1534 return -ENODEV;
1535 }
1536 rc = unconfigure_boot_bridge (busno, device, function);
1537 if (rc != 0) {
1538 err ("was not able to hot-remove PPB properly.\n");
1539 return rc;
1540 }
1541
1542 function = 0x8;
1543 break;
1544 case PCI_HEADER_TYPE_MULTIBRIDGE:
1545 class >>= 8;
1546 if (class != PCI_CLASS_BRIDGE_PCI) {
1547 err ("This device %x function %x is not PCI-to-PCI bridge, "
1548 "and is not supported for hot-removing. "
1549 "Please try another card.\n", device, function);
1550 return -ENODEV;
1551 }
1552 rc = unconfigure_boot_bridge (busno, device, function);
1553 if (rc != 0) {
1554 err ("was not able to hot-remove PPB properly.\n");
1555 return rc;
1556 }
1557 break;
1558 default:
1559 err ("MAJOR PROBLEM!!!! Cannot read device's header\n");
1560 return -1;
1561 break;
1562 } /* end of switch */
1563 } /* end of valid device */
1564 } /* end of for */
1565
1566 if (!valid_device) {
1567 err ("Could not find device to unconfigure. Or could not read the card.\n");
1568 return -1;
1569 }
1570 return 0;
1571}
1572
1573/*
1574 * free the resources of the card (multi, single, or bridged)
1575 * Parameters: slot, flag to say if this is for removing entire module or just
1576 * unconfiguring the device
1577 * TO DO: will probably need to add some code in case there was some resource,
1578 * to remove it... this is from when we have errors in the configure_card...
1579 * !!!!!!!!!!!!!!!!!!!!!!!!!FOR BUSES!!!!!!!!!!!!
1580 * Returns: 0, -1, -ENODEV
1581 */
1582int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end)
1583{
1584 int i;
1585 int count;
1586 int rc;
1587 struct slot *sl = *slot_cur;
1588 struct pci_func *cur_func = NULL;
1589 struct pci_func *temp_func;
1590
1591 debug ("%s - enter\n", __FUNCTION__);
1592
1593 if (!the_end) {
1594 /* Need to unconfigure the card */
1595 rc = unconfigure_boot_card (sl);
1596 if ((rc == -ENODEV) || (rc == -EIO) || (rc == -EINVAL)) {
1597 /* In all other cases, will still need to get rid of func structure if it exists */
1598 return rc;
1599 }
1600 }
1601
1602 if (sl->func) {
1603 cur_func = sl->func;
1604 while (cur_func) {
1605 /* TO DO: WILL MOST LIKELY NEED TO GET RID OF THE BUS STRUCTURE FROM RESOURCES AS WELL */
1606 if (cur_func->bus) {
1607 /* in other words, it's a PPB */
1608 count = 2;
1609 } else {
1610 count = 6;
1611 }
1612
1613 for (i = 0; i < count; i++) {
1614 if (cur_func->io[i]) {
1615 debug ("io[%d] exists\n", i);
1616 if (the_end > 0)
1617 ibmphp_remove_resource (cur_func->io[i]);
1618 cur_func->io[i] = NULL;
1619 }
1620 if (cur_func->mem[i]) {
1621 debug ("mem[%d] exists\n", i);
1622 if (the_end > 0)
1623 ibmphp_remove_resource (cur_func->mem[i]);
1624 cur_func->mem[i] = NULL;
1625 }
1626 if (cur_func->pfmem[i]) {
1627 debug ("pfmem[%d] exists\n", i);
1628 if (the_end > 0)
1629 ibmphp_remove_resource (cur_func->pfmem[i]);
1630 cur_func->pfmem[i] = NULL;
1631 }
1632 }
1633
1634 temp_func = cur_func->next;
1635 kfree (cur_func);
1636 cur_func = temp_func;
1637 }
1638 }
1639
1640 sl->func = NULL;
1641 *slot_cur = sl;
1642 debug ("%s - exit\n", __FUNCTION__);
1643 return 0;
1644}
1645
1646/*
1647 * add a new bus resulting from hot-plugging a PPB bridge with devices
1648 *
1649 * Input: bus and the amount of resources needed (we know we can assign those,
1650 * since they've been checked already
1651 * Output: bus added to the correct spot
1652 * 0, -1, error
1653 */
1654static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct resource_node *mem, struct resource_node *pfmem, u8 parent_busno)
1655{
1656 struct range_node *io_range = NULL;
1657 struct range_node *mem_range = NULL;
1658 struct range_node *pfmem_range = NULL;
1659 struct bus_node *cur_bus = NULL;
1660
1661 /* Trying to find the parent bus number */
1662 if (parent_busno != 0xFF) {
1663 cur_bus = ibmphp_find_res_bus (parent_busno);
1664 if (!cur_bus) {
1665 err ("strange, cannot find bus which is supposed to be at the system... something is terribly wrong...\n");
1666 return -ENODEV;
1667 }
1668
1669 list_add (&bus->bus_list, &cur_bus->bus_list);
1670 }
1671 if (io) {
1672 io_range = kmalloc(sizeof(*io_range), GFP_KERNEL);
1673 if (!io_range) {
1674 err ("out of system memory\n");
1675 return -ENOMEM;
1676 }
1677 memset (io_range, 0, sizeof (struct range_node));
1678 io_range->start = io->start;
1679 io_range->end = io->end;
1680 io_range->rangeno = 1;
1681 bus->noIORanges = 1;
1682 bus->rangeIO = io_range;
1683 }
1684 if (mem) {
1685 mem_range = kmalloc(sizeof(*mem_range), GFP_KERNEL);
1686 if (!mem_range) {
1687 err ("out of system memory\n");
1688 return -ENOMEM;
1689 }
1690 memset (mem_range, 0, sizeof (struct range_node));
1691 mem_range->start = mem->start;
1692 mem_range->end = mem->end;
1693 mem_range->rangeno = 1;
1694 bus->noMemRanges = 1;
1695 bus->rangeMem = mem_range;
1696 }
1697 if (pfmem) {
1698 pfmem_range = kmalloc(sizeof(*pfmem_range), GFP_KERNEL);
1699 if (!pfmem_range) {
1700 err ("out of system memory\n");
1701 return -ENOMEM;
1702 }
1703 memset (pfmem_range, 0, sizeof (struct range_node));
1704 pfmem_range->start = pfmem->start;
1705 pfmem_range->end = pfmem->end;
1706 pfmem_range->rangeno = 1;
1707 bus->noPFMemRanges = 1;
1708 bus->rangePFMem = pfmem_range;
1709 }
1710 return 0;
1711}
1712
1713/*
1714 * find the 1st available bus number for PPB to set as its secondary bus
1715 * Parameters: bus_number of the primary bus
1716 * Returns: bus_number of the secondary bus or 0xff in case of failure
1717 */
1718static u8 find_sec_number (u8 primary_busno, u8 slotno)
1719{
1720 int min, max;
1721 u8 busno;
1722 struct bus_info *bus;
1723 struct bus_node *bus_cur;
1724
1725 bus = ibmphp_find_same_bus_num (primary_busno);
1726 if (!bus) {
1727 err ("cannot get slot range of the bus from the BIOS\n");
1728 return 0xff;
1729 }
1730 max = bus->slot_max;
1731 min = bus->slot_min;
1732 if ((slotno > max) || (slotno < min)) {
1733 err ("got the wrong range\n");
1734 return 0xff;
1735 }
1736 busno = (u8) (slotno - (u8) min);
1737 busno += primary_busno + 0x01;
1738 bus_cur = ibmphp_find_res_bus (busno);
1739 /* either there is no such bus number, or there are no ranges, which
1740 * can only happen if we removed the bridged device in previous load
1741 * of the driver, and now only have the skeleton bus struct
1742 */
1743 if ((!bus_cur) || (!(bus_cur->rangeIO) && !(bus_cur->rangeMem) && !(bus_cur->rangePFMem)))
1744 return busno;
1745 return 0xff;
1746}
1747
diff --git a/drivers/pci/hotplug/ibmphp_res.c b/drivers/pci/hotplug/ibmphp_res.c
new file mode 100644
index 000000000000..9c224c94d698
--- /dev/null
+++ b/drivers/pci/hotplug/ibmphp_res.c
@@ -0,0 +1,2156 @@
1/*
2 * IBM Hot Plug Controller Driver
3 *
4 * Written By: Irene Zubarev, IBM Corporation
5 *
6 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
7 * Copyright (C) 2001,2002 IBM Corp.
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <gregkh@us.ibm.com>
27 *
28 */
29
30#include <linux/module.h>
31#include <linux/slab.h>
32#include <linux/pci.h>
33#include <linux/list.h>
34#include <linux/init.h>
35#include "ibmphp.h"
36
37static int flags = 0; /* for testing */
38
39static void update_resources (struct bus_node *bus_cur, int type, int rangeno);
40static int once_over (void);
41static int remove_ranges (struct bus_node *, struct bus_node *);
42static int update_bridge_ranges (struct bus_node **);
43static int add_range (int type, struct range_node *, struct bus_node *);
44static void fix_resources (struct bus_node *);
45static struct bus_node *find_bus_wprev (u8, struct bus_node **, u8);
46
47static LIST_HEAD(gbuses);
48
49static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc * curr, u8 busno, int flag)
50{
51 struct bus_node * newbus;
52
53 if (!(curr) && !(flag)) {
54 err ("NULL pointer passed\n");
55 return NULL;
56 }
57
58 newbus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
59 if (!newbus) {
60 err ("out of system memory\n");
61 return NULL;
62 }
63
64 memset (newbus, 0, sizeof (struct bus_node));
65 if (flag)
66 newbus->busno = busno;
67 else
68 newbus->busno = curr->bus_num;
69 list_add_tail (&newbus->bus_list, &gbuses);
70 return newbus;
71}
72
73static struct resource_node * __init alloc_resources (struct ebda_pci_rsrc * curr)
74{
75 struct resource_node *rs;
76
77 if (!curr) {
78 err ("NULL passed to allocate\n");
79 return NULL;
80 }
81
82 rs = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
83 if (!rs) {
84 err ("out of system memory\n");
85 return NULL;
86 }
87 memset (rs, 0, sizeof (struct resource_node));
88 rs->busno = curr->bus_num;
89 rs->devfunc = curr->dev_fun;
90 rs->start = curr->start_addr;
91 rs->end = curr->end_addr;
92 rs->len = curr->end_addr - curr->start_addr + 1;
93 return rs;
94}
95
96static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node **new_range, struct ebda_pci_rsrc *curr, int flag, u8 first_bus)
97{
98 struct bus_node * newbus;
99 struct range_node *newrange;
100 u8 num_ranges = 0;
101
102 if (first_bus) {
103 newbus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
104 if (!newbus) {
105 err ("out of system memory.\n");
106 return -ENOMEM;
107 }
108 memset (newbus, 0, sizeof (struct bus_node));
109 newbus->busno = curr->bus_num;
110 } else {
111 newbus = *new_bus;
112 switch (flag) {
113 case MEM:
114 num_ranges = newbus->noMemRanges;
115 break;
116 case PFMEM:
117 num_ranges = newbus->noPFMemRanges;
118 break;
119 case IO:
120 num_ranges = newbus->noIORanges;
121 break;
122 }
123 }
124
125 newrange = kmalloc (sizeof (struct range_node), GFP_KERNEL);
126 if (!newrange) {
127 if (first_bus)
128 kfree (newbus);
129 err ("out of system memory\n");
130 return -ENOMEM;
131 }
132 memset (newrange, 0, sizeof (struct range_node));
133 newrange->start = curr->start_addr;
134 newrange->end = curr->end_addr;
135
136 if (first_bus || (!num_ranges))
137 newrange->rangeno = 1;
138 else {
139 /* need to insert our range */
140 add_range (flag, newrange, newbus);
141 debug ("%d resource Primary Bus inserted on bus %x [%x - %x]\n", flag, newbus->busno, newrange->start, newrange->end);
142 }
143
144 switch (flag) {
145 case MEM:
146 newbus->rangeMem = newrange;
147 if (first_bus)
148 newbus->noMemRanges = 1;
149 else {
150 debug ("First Memory Primary on bus %x, [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
151 ++newbus->noMemRanges;
152 fix_resources (newbus);
153 }
154 break;
155 case IO:
156 newbus->rangeIO = newrange;
157 if (first_bus)
158 newbus->noIORanges = 1;
159 else {
160 debug ("First IO Primary on bus %x, [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
161 ++newbus->noIORanges;
162 fix_resources (newbus);
163 }
164 break;
165 case PFMEM:
166 newbus->rangePFMem = newrange;
167 if (first_bus)
168 newbus->noPFMemRanges = 1;
169 else {
170 debug ("1st PFMemory Primary on Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
171 ++newbus->noPFMemRanges;
172 fix_resources (newbus);
173 }
174
175 break;
176 }
177
178 *new_bus = newbus;
179 *new_range = newrange;
180 return 0;
181}
182
183
184/* Notes:
185 * 1. The ranges are ordered. The buses are not ordered. (First come)
186 *
187 * 2. If cannot allocate out of PFMem range, allocate from Mem ranges. PFmemFromMem
188 * are not sorted. (no need since use mem node). To not change the entire code, we
189 * also add mem node whenever this case happens so as not to change
190 * ibmphp_check_mem_resource etc (and since it really is taking Mem resource)
191 */
192
193/*****************************************************************************
194 * This is the Resource Management initialization function. It will go through
195 * the Resource list taken from EBDA and fill in this module's data structures
196 *
197 * THIS IS NOT TAKING INTO CONSIDERATION IO RESTRICTIONS OF PRIMARY BUSES,
198 * SINCE WE'RE GOING TO ASSUME FOR NOW WE DON'T HAVE THOSE ON OUR BUSES FOR NOW
199 *
200 * Input: ptr to the head of the resource list from EBDA
201 * Output: 0, -1 or error codes
202 ***************************************************************************/
203int __init ibmphp_rsrc_init (void)
204{
205 struct ebda_pci_rsrc *curr;
206 struct range_node *newrange = NULL;
207 struct bus_node *newbus = NULL;
208 struct bus_node *bus_cur;
209 struct bus_node *bus_prev;
210 struct list_head *tmp;
211 struct resource_node *new_io = NULL;
212 struct resource_node *new_mem = NULL;
213 struct resource_node *new_pfmem = NULL;
214 int rc;
215 struct list_head *tmp_ebda;
216
217 list_for_each (tmp_ebda, &ibmphp_ebda_pci_rsrc_head) {
218 curr = list_entry (tmp_ebda, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
219 if (!(curr->rsrc_type & PCIDEVMASK)) {
220 /* EBDA still lists non PCI devices, so ignore... */
221 debug ("this is not a PCI DEVICE in rsrc_init, please take care\n");
222 // continue;
223 }
224
225 /* this is a primary bus resource */
226 if (curr->rsrc_type & PRIMARYBUSMASK) {
227 /* memory */
228 if ((curr->rsrc_type & RESTYPE) == MMASK) {
229 /* no bus structure exists in place yet */
230 if (list_empty (&gbuses)) {
231 if ((rc = alloc_bus_range (&newbus, &newrange, curr, MEM, 1)))
232 return rc;
233 list_add_tail (&newbus->bus_list, &gbuses);
234 debug ("gbuses = NULL, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
235 } else {
236 bus_cur = find_bus_wprev (curr->bus_num, &bus_prev, 1);
237 /* found our bus */
238 if (bus_cur) {
239 rc = alloc_bus_range (&bus_cur, &newrange, curr, MEM, 0);
240 if (rc)
241 return rc;
242 } else {
243 /* went through all the buses and didn't find ours, need to create a new bus node */
244 if ((rc = alloc_bus_range (&newbus, &newrange, curr, MEM, 1)))
245 return rc;
246
247 list_add_tail (&newbus->bus_list, &gbuses);
248 debug ("New Bus, Memory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
249 }
250 }
251 } else if ((curr->rsrc_type & RESTYPE) == PFMASK) {
252 /* prefetchable memory */
253 if (list_empty (&gbuses)) {
254 /* no bus structure exists in place yet */
255 if ((rc = alloc_bus_range (&newbus, &newrange, curr, PFMEM, 1)))
256 return rc;
257 list_add_tail (&newbus->bus_list, &gbuses);
258 debug ("gbuses = NULL, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
259 } else {
260 bus_cur = find_bus_wprev (curr->bus_num, &bus_prev, 1);
261 if (bus_cur) {
262 /* found our bus */
263 rc = alloc_bus_range (&bus_cur, &newrange, curr, PFMEM, 0);
264 if (rc)
265 return rc;
266 } else {
267 /* went through all the buses and didn't find ours, need to create a new bus node */
268 if ((rc = alloc_bus_range (&newbus, &newrange, curr, PFMEM, 1)))
269 return rc;
270 list_add_tail (&newbus->bus_list, &gbuses);
271 debug ("1st Bus, PFMemory Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
272 }
273 }
274 } else if ((curr->rsrc_type & RESTYPE) == IOMASK) {
275 /* IO */
276 if (list_empty (&gbuses)) {
277 /* no bus structure exists in place yet */
278 if ((rc = alloc_bus_range (&newbus, &newrange, curr, IO, 1)))
279 return rc;
280 list_add_tail (&newbus->bus_list, &gbuses);
281 debug ("gbuses = NULL, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
282 } else {
283 bus_cur = find_bus_wprev (curr->bus_num, &bus_prev, 1);
284 if (bus_cur) {
285 rc = alloc_bus_range (&bus_cur, &newrange, curr, IO, 0);
286 if (rc)
287 return rc;
288 } else {
289 /* went through all the buses and didn't find ours, need to create a new bus node */
290 if ((rc = alloc_bus_range (&newbus, &newrange, curr, IO, 1)))
291 return rc;
292 list_add_tail (&newbus->bus_list, &gbuses);
293 debug ("1st Bus, IO Primary Bus %x [%x - %x]\n", newbus->busno, newrange->start, newrange->end);
294 }
295 }
296
297 } else {
298 ; /* type is reserved WHAT TO DO IN THIS CASE???
299 NOTHING TO DO??? */
300 }
301 } else {
302 /* regular pci device resource */
303 if ((curr->rsrc_type & RESTYPE) == MMASK) {
304 /* Memory resource */
305 new_mem = alloc_resources (curr);
306 if (!new_mem)
307 return -ENOMEM;
308 new_mem->type = MEM;
309 /*
310 * if it didn't find the bus, means PCI dev
311 * came b4 the Primary Bus info, so need to
312 * create a bus rangeno becomes a problem...
313 * assign a -1 and then update once the range
314 * actually appears...
315 */
316 if (ibmphp_add_resource (new_mem) < 0) {
317 newbus = alloc_error_bus (curr, 0, 0);
318 if (!newbus)
319 return -ENOMEM;
320 newbus->firstMem = new_mem;
321 ++newbus->needMemUpdate;
322 new_mem->rangeno = -1;
323 }
324 debug ("Memory resource for device %x, bus %x, [%x - %x]\n", new_mem->devfunc, new_mem->busno, new_mem->start, new_mem->end);
325
326 } else if ((curr->rsrc_type & RESTYPE) == PFMASK) {
327 /* PFMemory resource */
328 new_pfmem = alloc_resources (curr);
329 if (!new_pfmem)
330 return -ENOMEM;
331 new_pfmem->type = PFMEM;
332 new_pfmem->fromMem = FALSE;
333 if (ibmphp_add_resource (new_pfmem) < 0) {
334 newbus = alloc_error_bus (curr, 0, 0);
335 if (!newbus)
336 return -ENOMEM;
337 newbus->firstPFMem = new_pfmem;
338 ++newbus->needPFMemUpdate;
339 new_pfmem->rangeno = -1;
340 }
341
342 debug ("PFMemory resource for device %x, bus %x, [%x - %x]\n", new_pfmem->devfunc, new_pfmem->busno, new_pfmem->start, new_pfmem->end);
343 } else if ((curr->rsrc_type & RESTYPE) == IOMASK) {
344 /* IO resource */
345 new_io = alloc_resources (curr);
346 if (!new_io)
347 return -ENOMEM;
348 new_io->type = IO;
349
350 /*
351 * if it didn't find the bus, means PCI dev
352 * came b4 the Primary Bus info, so need to
353 * create a bus rangeno becomes a problem...
354 * Can assign a -1 and then update once the
355 * range actually appears...
356 */
357 if (ibmphp_add_resource (new_io) < 0) {
358 newbus = alloc_error_bus (curr, 0, 0);
359 if (!newbus)
360 return -ENOMEM;
361 newbus->firstIO = new_io;
362 ++newbus->needIOUpdate;
363 new_io->rangeno = -1;
364 }
365 debug ("IO resource for device %x, bus %x, [%x - %x]\n", new_io->devfunc, new_io->busno, new_io->start, new_io->end);
366 }
367 }
368 }
369
370 list_for_each (tmp, &gbuses) {
371 bus_cur = list_entry (tmp, struct bus_node, bus_list);
372 /* This is to get info about PPB resources, since EBDA doesn't put this info into the primary bus info */
373 rc = update_bridge_ranges (&bus_cur);
374 if (rc)
375 return rc;
376 }
377 rc = once_over (); /* This is to align ranges (so no -1) */
378 if (rc)
379 return rc;
380 return 0;
381}
382
383/********************************************************************************
384 * This function adds a range into a sorted list of ranges per bus for a particular
385 * range type, it then calls another routine to update the range numbers on the
386 * pci devices' resources for the appropriate resource
387 *
388 * Input: type of the resource, range to add, current bus
389 * Output: 0 or -1, bus and range ptrs
390 ********************************************************************************/
391static int add_range (int type, struct range_node *range, struct bus_node *bus_cur)
392{
393 struct range_node *range_cur = NULL;
394 struct range_node *range_prev;
395 int count = 0, i_init;
396 int noRanges = 0;
397
398 switch (type) {
399 case MEM:
400 range_cur = bus_cur->rangeMem;
401 noRanges = bus_cur->noMemRanges;
402 break;
403 case PFMEM:
404 range_cur = bus_cur->rangePFMem;
405 noRanges = bus_cur->noPFMemRanges;
406 break;
407 case IO:
408 range_cur = bus_cur->rangeIO;
409 noRanges = bus_cur->noIORanges;
410 break;
411 }
412
413 range_prev = NULL;
414 while (range_cur) {
415 if (range->start < range_cur->start)
416 break;
417 range_prev = range_cur;
418 range_cur = range_cur->next;
419 count = count + 1;
420 }
421 if (!count) {
422 /* our range will go at the beginning of the list */
423 switch (type) {
424 case MEM:
425 bus_cur->rangeMem = range;
426 break;
427 case PFMEM:
428 bus_cur->rangePFMem = range;
429 break;
430 case IO:
431 bus_cur->rangeIO = range;
432 break;
433 }
434 range->next = range_cur;
435 range->rangeno = 1;
436 i_init = 0;
437 } else if (!range_cur) {
438 /* our range will go at the end of the list */
439 range->next = NULL;
440 range_prev->next = range;
441 range->rangeno = range_prev->rangeno + 1;
442 return 0;
443 } else {
444 /* the range is in the middle */
445 range_prev->next = range;
446 range->next = range_cur;
447 range->rangeno = range_cur->rangeno;
448 i_init = range_prev->rangeno;
449 }
450
451 for (count = i_init; count < noRanges; ++count) {
452 ++range_cur->rangeno;
453 range_cur = range_cur->next;
454 }
455
456 update_resources (bus_cur, type, i_init + 1);
457 return 0;
458}
459
460/*******************************************************************************
461 * This routine goes through the list of resources of type 'type' and updates
462 * the range numbers that they correspond to. It was called from add_range fnc
463 *
464 * Input: bus, type of the resource, the rangeno starting from which to update
465 ******************************************************************************/
466static void update_resources (struct bus_node *bus_cur, int type, int rangeno)
467{
468 struct resource_node *res = NULL;
469 u8 eol = FALSE; /* end of list indicator */
470
471 switch (type) {
472 case MEM:
473 if (bus_cur->firstMem)
474 res = bus_cur->firstMem;
475 break;
476 case PFMEM:
477 if (bus_cur->firstPFMem)
478 res = bus_cur->firstPFMem;
479 break;
480 case IO:
481 if (bus_cur->firstIO)
482 res = bus_cur->firstIO;
483 break;
484 }
485
486 if (res) {
487 while (res) {
488 if (res->rangeno == rangeno)
489 break;
490 if (res->next)
491 res = res->next;
492 else if (res->nextRange)
493 res = res->nextRange;
494 else {
495 eol = TRUE;
496 break;
497 }
498 }
499
500 if (!eol) {
501 /* found the range */
502 while (res) {
503 ++res->rangeno;
504 res = res->next;
505 }
506 }
507 }
508}
509
510static void fix_me (struct resource_node *res, struct bus_node *bus_cur, struct range_node *range)
511{
512 char * str = "";
513 switch (res->type) {
514 case IO:
515 str = "io";
516 break;
517 case MEM:
518 str = "mem";
519 break;
520 case PFMEM:
521 str = "pfmem";
522 break;
523 }
524
525 while (res) {
526 if (res->rangeno == -1) {
527 while (range) {
528 if ((res->start >= range->start) && (res->end <= range->end)) {
529 res->rangeno = range->rangeno;
530 debug ("%s->rangeno in fix_resources is %d\n", str, res->rangeno);
531 switch (res->type) {
532 case IO:
533 --bus_cur->needIOUpdate;
534 break;
535 case MEM:
536 --bus_cur->needMemUpdate;
537 break;
538 case PFMEM:
539 --bus_cur->needPFMemUpdate;
540 break;
541 }
542 break;
543 }
544 range = range->next;
545 }
546 }
547 if (res->next)
548 res = res->next;
549 else
550 res = res->nextRange;
551 }
552
553}
554
555/*****************************************************************************
556 * This routine reassigns the range numbers to the resources that had a -1
557 * This case can happen only if upon initialization, resources taken by pci dev
558 * appear in EBDA before the resources allocated for that bus, since we don't
559 * know the range, we assign -1, and this routine is called after a new range
560 * is assigned to see the resources with unknown range belong to the added range
561 *
562 * Input: current bus
563 * Output: none, list of resources for that bus are fixed if can be
564 *******************************************************************************/
565static void fix_resources (struct bus_node *bus_cur)
566{
567 struct range_node *range;
568 struct resource_node *res;
569
570 debug ("%s - bus_cur->busno = %d\n", __FUNCTION__, bus_cur->busno);
571
572 if (bus_cur->needIOUpdate) {
573 res = bus_cur->firstIO;
574 range = bus_cur->rangeIO;
575 fix_me (res, bus_cur, range);
576 }
577 if (bus_cur->needMemUpdate) {
578 res = bus_cur->firstMem;
579 range = bus_cur->rangeMem;
580 fix_me (res, bus_cur, range);
581 }
582 if (bus_cur->needPFMemUpdate) {
583 res = bus_cur->firstPFMem;
584 range = bus_cur->rangePFMem;
585 fix_me (res, bus_cur, range);
586 }
587}
588
589/*******************************************************************************
590 * This routine adds a resource to the list of resources to the appropriate bus
591 * based on their resource type and sorted by their starting addresses. It assigns
592 * the ptrs to next and nextRange if needed.
593 *
594 * Input: resource ptr
595 * Output: ptrs assigned (to the node)
596 * 0 or -1
597 *******************************************************************************/
598int ibmphp_add_resource (struct resource_node *res)
599{
600 struct resource_node *res_cur;
601 struct resource_node *res_prev;
602 struct bus_node *bus_cur;
603 struct range_node *range_cur = NULL;
604 struct resource_node *res_start = NULL;
605
606 debug ("%s - enter\n", __FUNCTION__);
607
608 if (!res) {
609 err ("NULL passed to add\n");
610 return -ENODEV;
611 }
612
613 bus_cur = find_bus_wprev (res->busno, NULL, 0);
614
615 if (!bus_cur) {
616 /* didn't find a bus, smth's wrong!!! */
617 debug ("no bus in the system, either pci_dev's wrong or allocation failed\n");
618 return -ENODEV;
619 }
620
621 /* Normal case */
622 switch (res->type) {
623 case IO:
624 range_cur = bus_cur->rangeIO;
625 res_start = bus_cur->firstIO;
626 break;
627 case MEM:
628 range_cur = bus_cur->rangeMem;
629 res_start = bus_cur->firstMem;
630 break;
631 case PFMEM:
632 range_cur = bus_cur->rangePFMem;
633 res_start = bus_cur->firstPFMem;
634 break;
635 default:
636 err ("cannot read the type of the resource to add... problem\n");
637 return -EINVAL;
638 }
639 while (range_cur) {
640 if ((res->start >= range_cur->start) && (res->end <= range_cur->end)) {
641 res->rangeno = range_cur->rangeno;
642 break;
643 }
644 range_cur = range_cur->next;
645 }
646
647 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
648 * this is again the case of rangeno = -1
649 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
650 */
651
652 if (!range_cur) {
653 switch (res->type) {
654 case IO:
655 ++bus_cur->needIOUpdate;
656 break;
657 case MEM:
658 ++bus_cur->needMemUpdate;
659 break;
660 case PFMEM:
661 ++bus_cur->needPFMemUpdate;
662 break;
663 }
664 res->rangeno = -1;
665 }
666
667 debug ("The range is %d\n", res->rangeno);
668 if (!res_start) {
669 /* no first{IO,Mem,Pfmem} on the bus, 1st IO/Mem/Pfmem resource ever */
670 switch (res->type) {
671 case IO:
672 bus_cur->firstIO = res;
673 break;
674 case MEM:
675 bus_cur->firstMem = res;
676 break;
677 case PFMEM:
678 bus_cur->firstPFMem = res;
679 break;
680 }
681 res->next = NULL;
682 res->nextRange = NULL;
683 } else {
684 res_cur = res_start;
685 res_prev = NULL;
686
687 debug ("res_cur->rangeno is %d\n", res_cur->rangeno);
688
689 while (res_cur) {
690 if (res_cur->rangeno >= res->rangeno)
691 break;
692 res_prev = res_cur;
693 if (res_cur->next)
694 res_cur = res_cur->next;
695 else
696 res_cur = res_cur->nextRange;
697 }
698
699 if (!res_cur) {
700 /* at the end of the resource list */
701 debug ("i should be here, [%x - %x]\n", res->start, res->end);
702 res_prev->nextRange = res;
703 res->next = NULL;
704 res->nextRange = NULL;
705 } else if (res_cur->rangeno == res->rangeno) {
706 /* in the same range */
707 while (res_cur) {
708 if (res->start < res_cur->start)
709 break;
710 res_prev = res_cur;
711 res_cur = res_cur->next;
712 }
713 if (!res_cur) {
714 /* the last resource in this range */
715 res_prev->next = res;
716 res->next = NULL;
717 res->nextRange = res_prev->nextRange;
718 res_prev->nextRange = NULL;
719 } else if (res->start < res_cur->start) {
720 /* at the beginning or middle of the range */
721 if (!res_prev) {
722 switch (res->type) {
723 case IO:
724 bus_cur->firstIO = res;
725 break;
726 case MEM:
727 bus_cur->firstMem = res;
728 break;
729 case PFMEM:
730 bus_cur->firstPFMem = res;
731 break;
732 }
733 } else if (res_prev->rangeno == res_cur->rangeno)
734 res_prev->next = res;
735 else
736 res_prev->nextRange = res;
737
738 res->next = res_cur;
739 res->nextRange = NULL;
740 }
741 } else {
742 /* this is the case where it is 1st occurrence of the range */
743 if (!res_prev) {
744 /* at the beginning of the resource list */
745 res->next = NULL;
746 switch (res->type) {
747 case IO:
748 res->nextRange = bus_cur->firstIO;
749 bus_cur->firstIO = res;
750 break;
751 case MEM:
752 res->nextRange = bus_cur->firstMem;
753 bus_cur->firstMem = res;
754 break;
755 case PFMEM:
756 res->nextRange = bus_cur->firstPFMem;
757 bus_cur->firstPFMem = res;
758 break;
759 }
760 } else if (res_cur->rangeno > res->rangeno) {
761 /* in the middle of the resource list */
762 res_prev->nextRange = res;
763 res->next = NULL;
764 res->nextRange = res_cur;
765 }
766 }
767 }
768
769 debug ("%s - exit\n", __FUNCTION__);
770 return 0;
771}
772
773/****************************************************************************
774 * This routine will remove the resource from the list of resources
775 *
776 * Input: io, mem, and/or pfmem resource to be deleted
777 * Ouput: modified resource list
778 * 0 or error code
779 ****************************************************************************/
780int ibmphp_remove_resource (struct resource_node *res)
781{
782 struct bus_node *bus_cur;
783 struct resource_node *res_cur = NULL;
784 struct resource_node *res_prev;
785 struct resource_node *mem_cur;
786 char * type = "";
787
788 if (!res) {
789 err ("resource to remove is NULL\n");
790 return -ENODEV;
791 }
792
793 bus_cur = find_bus_wprev (res->busno, NULL, 0);
794
795 if (!bus_cur) {
796 err ("cannot find corresponding bus of the io resource to remove "
797 "bailing out...\n");
798 return -ENODEV;
799 }
800
801 switch (res->type) {
802 case IO:
803 res_cur = bus_cur->firstIO;
804 type = "io";
805 break;
806 case MEM:
807 res_cur = bus_cur->firstMem;
808 type = "mem";
809 break;
810 case PFMEM:
811 res_cur = bus_cur->firstPFMem;
812 type = "pfmem";
813 break;
814 default:
815 err ("unknown type for resource to remove\n");
816 return -EINVAL;
817 }
818 res_prev = NULL;
819
820 while (res_cur) {
821 if ((res_cur->start == res->start) && (res_cur->end == res->end))
822 break;
823 res_prev = res_cur;
824 if (res_cur->next)
825 res_cur = res_cur->next;
826 else
827 res_cur = res_cur->nextRange;
828 }
829
830 if (!res_cur) {
831 if (res->type == PFMEM) {
832 /*
833 * case where pfmem might be in the PFMemFromMem list
834 * so will also need to remove the corresponding mem
835 * entry
836 */
837 res_cur = bus_cur->firstPFMemFromMem;
838 res_prev = NULL;
839
840 while (res_cur) {
841 if ((res_cur->start == res->start) && (res_cur->end == res->end)) {
842 mem_cur = bus_cur->firstMem;
843 while (mem_cur) {
844 if ((mem_cur->start == res_cur->start)
845 && (mem_cur->end == res_cur->end))
846 break;
847 if (mem_cur->next)
848 mem_cur = mem_cur->next;
849 else
850 mem_cur = mem_cur->nextRange;
851 }
852 if (!mem_cur) {
853 err ("cannot find corresponding mem node for pfmem...\n");
854 return -EINVAL;
855 }
856
857 ibmphp_remove_resource (mem_cur);
858 if (!res_prev)
859 bus_cur->firstPFMemFromMem = res_cur->next;
860 else
861 res_prev->next = res_cur->next;
862 kfree (res_cur);
863 return 0;
864 }
865 res_prev = res_cur;
866 if (res_cur->next)
867 res_cur = res_cur->next;
868 else
869 res_cur = res_cur->nextRange;
870 }
871 if (!res_cur) {
872 err ("cannot find pfmem to delete...\n");
873 return -EINVAL;
874 }
875 } else {
876 err ("the %s resource is not in the list to be deleted...\n", type);
877 return -EINVAL;
878 }
879 }
880 if (!res_prev) {
881 /* first device to be deleted */
882 if (res_cur->next) {
883 switch (res->type) {
884 case IO:
885 bus_cur->firstIO = res_cur->next;
886 break;
887 case MEM:
888 bus_cur->firstMem = res_cur->next;
889 break;
890 case PFMEM:
891 bus_cur->firstPFMem = res_cur->next;
892 break;
893 }
894 } else if (res_cur->nextRange) {
895 switch (res->type) {
896 case IO:
897 bus_cur->firstIO = res_cur->nextRange;
898 break;
899 case MEM:
900 bus_cur->firstMem = res_cur->nextRange;
901 break;
902 case PFMEM:
903 bus_cur->firstPFMem = res_cur->nextRange;
904 break;
905 }
906 } else {
907 switch (res->type) {
908 case IO:
909 bus_cur->firstIO = NULL;
910 break;
911 case MEM:
912 bus_cur->firstMem = NULL;
913 break;
914 case PFMEM:
915 bus_cur->firstPFMem = NULL;
916 break;
917 }
918 }
919 kfree (res_cur);
920 return 0;
921 } else {
922 if (res_cur->next) {
923 if (res_prev->rangeno == res_cur->rangeno)
924 res_prev->next = res_cur->next;
925 else
926 res_prev->nextRange = res_cur->next;
927 } else if (res_cur->nextRange) {
928 res_prev->next = NULL;
929 res_prev->nextRange = res_cur->nextRange;
930 } else {
931 res_prev->next = NULL;
932 res_prev->nextRange = NULL;
933 }
934 kfree (res_cur);
935 return 0;
936 }
937
938 return 0;
939}
940
941static struct range_node * find_range (struct bus_node *bus_cur, struct resource_node * res)
942{
943 struct range_node * range = NULL;
944
945 switch (res->type) {
946 case IO:
947 range = bus_cur->rangeIO;
948 break;
949 case MEM:
950 range = bus_cur->rangeMem;
951 break;
952 case PFMEM:
953 range = bus_cur->rangePFMem;
954 break;
955 default:
956 err ("cannot read resource type in find_range\n");
957 }
958
959 while (range) {
960 if (res->rangeno == range->rangeno)
961 break;
962 range = range->next;
963 }
964 return range;
965}
966
967/*****************************************************************************
968 * This routine will check to make sure the io/mem/pfmem->len that the device asked for
969 * can fit w/i our list of available IO/MEM/PFMEM resources. If cannot, returns -EINVAL,
970 * otherwise, returns 0
971 *
972 * Input: resource
973 * Ouput: the correct start and end address are inputted into the resource node,
974 * 0 or -EINVAL
975 *****************************************************************************/
976int ibmphp_check_resource (struct resource_node *res, u8 bridge)
977{
978 struct bus_node *bus_cur;
979 struct range_node *range = NULL;
980 struct resource_node *res_prev;
981 struct resource_node *res_cur = NULL;
982 u32 len_cur = 0, start_cur = 0, len_tmp = 0;
983 int noranges = 0;
984 u32 tmp_start; /* this is to make sure start address is divisible by the length needed */
985 u32 tmp_divide;
986 u8 flag = FALSE;
987
988 if (!res)
989 return -EINVAL;
990
991 if (bridge) {
992 /* The rules for bridges are different, 4K divisible for IO, 1M for (pf)mem*/
993 if (res->type == IO)
994 tmp_divide = IOBRIDGE;
995 else
996 tmp_divide = MEMBRIDGE;
997 } else
998 tmp_divide = res->len;
999
1000 bus_cur = find_bus_wprev (res->busno, NULL, 0);
1001
1002 if (!bus_cur) {
1003 /* didn't find a bus, smth's wrong!!! */
1004 debug ("no bus in the system, either pci_dev's wrong or allocation failed\n");
1005 return -EINVAL;
1006 }
1007
1008 debug ("%s - enter\n", __FUNCTION__);
1009 debug ("bus_cur->busno is %d\n", bus_cur->busno);
1010
1011 /* This is a quick fix to not mess up with the code very much. i.e.,
1012 * 2000-2fff, len = 1000, but when we compare, we need it to be fff */
1013 res->len -= 1;
1014
1015 switch (res->type) {
1016 case IO:
1017 res_cur = bus_cur->firstIO;
1018 noranges = bus_cur->noIORanges;
1019 break;
1020 case MEM:
1021 res_cur = bus_cur->firstMem;
1022 noranges = bus_cur->noMemRanges;
1023 break;
1024 case PFMEM:
1025 res_cur = bus_cur->firstPFMem;
1026 noranges = bus_cur->noPFMemRanges;
1027 break;
1028 default:
1029 err ("wrong type of resource to check\n");
1030 return -EINVAL;
1031 }
1032 res_prev = NULL;
1033
1034 while (res_cur) {
1035 range = find_range (bus_cur, res_cur);
1036 debug ("%s - rangeno = %d\n", __FUNCTION__, res_cur->rangeno);
1037
1038 if (!range) {
1039 err ("no range for the device exists... bailing out...\n");
1040 return -EINVAL;
1041 }
1042
1043 /* found our range */
1044 if (!res_prev) {
1045 /* first time in the loop */
1046 if ((res_cur->start != range->start) && ((len_tmp = res_cur->start - 1 - range->start) >= res->len)) {
1047 debug ("len_tmp = %x\n", len_tmp);
1048
1049 if ((len_tmp < len_cur) || (len_cur == 0)) {
1050
1051 if ((range->start % tmp_divide) == 0) {
1052 /* just perfect, starting address is divisible by length */
1053 flag = TRUE;
1054 len_cur = len_tmp;
1055 start_cur = range->start;
1056 } else {
1057 /* Needs adjusting */
1058 tmp_start = range->start;
1059 flag = FALSE;
1060
1061 while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
1062 if ((tmp_start % tmp_divide) == 0) {
1063 flag = TRUE;
1064 len_cur = len_tmp;
1065 start_cur = tmp_start;
1066 break;
1067 }
1068 tmp_start += tmp_divide - tmp_start % tmp_divide;
1069 if (tmp_start >= res_cur->start - 1)
1070 break;
1071 }
1072 }
1073
1074 if (flag && len_cur == res->len) {
1075 debug ("but we are not here, right?\n");
1076 res->start = start_cur;
1077 res->len += 1; /* To restore the balance */
1078 res->end = res->start + res->len - 1;
1079 return 0;
1080 }
1081 }
1082 }
1083 }
1084 if (!res_cur->next) {
1085 /* last device on the range */
1086 if ((range->end != res_cur->end) && ((len_tmp = range->end - (res_cur->end + 1)) >= res->len)) {
1087 debug ("len_tmp = %x\n", len_tmp);
1088 if ((len_tmp < len_cur) || (len_cur == 0)) {
1089
1090 if (((res_cur->end + 1) % tmp_divide) == 0) {
1091 /* just perfect, starting address is divisible by length */
1092 flag = TRUE;
1093 len_cur = len_tmp;
1094 start_cur = res_cur->end + 1;
1095 } else {
1096 /* Needs adjusting */
1097 tmp_start = res_cur->end + 1;
1098 flag = FALSE;
1099
1100 while ((len_tmp = range->end - tmp_start) >= res->len) {
1101 if ((tmp_start % tmp_divide) == 0) {
1102 flag = TRUE;
1103 len_cur = len_tmp;
1104 start_cur = tmp_start;
1105 break;
1106 }
1107 tmp_start += tmp_divide - tmp_start % tmp_divide;
1108 if (tmp_start >= range->end)
1109 break;
1110 }
1111 }
1112 if (flag && len_cur == res->len) {
1113 res->start = start_cur;
1114 res->len += 1; /* To restore the balance */
1115 res->end = res->start + res->len - 1;
1116 return 0;
1117 }
1118 }
1119 }
1120 }
1121
1122 if (res_prev) {
1123 if (res_prev->rangeno != res_cur->rangeno) {
1124 /* 1st device on this range */
1125 if ((res_cur->start != range->start) &&
1126 ((len_tmp = res_cur->start - 1 - range->start) >= res->len)) {
1127 if ((len_tmp < len_cur) || (len_cur == 0)) {
1128 if ((range->start % tmp_divide) == 0) {
1129 /* just perfect, starting address is divisible by length */
1130 flag = TRUE;
1131 len_cur = len_tmp;
1132 start_cur = range->start;
1133 } else {
1134 /* Needs adjusting */
1135 tmp_start = range->start;
1136 flag = FALSE;
1137
1138 while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
1139 if ((tmp_start % tmp_divide) == 0) {
1140 flag = TRUE;
1141 len_cur = len_tmp;
1142 start_cur = tmp_start;
1143 break;
1144 }
1145 tmp_start += tmp_divide - tmp_start % tmp_divide;
1146 if (tmp_start >= res_cur->start - 1)
1147 break;
1148 }
1149 }
1150
1151 if (flag && len_cur == res->len) {
1152 res->start = start_cur;
1153 res->len += 1; /* To restore the balance */
1154 res->end = res->start + res->len - 1;
1155 return 0;
1156 }
1157 }
1158 }
1159 } else {
1160 /* in the same range */
1161 if ((len_tmp = res_cur->start - 1 - res_prev->end - 1) >= res->len) {
1162 if ((len_tmp < len_cur) || (len_cur == 0)) {
1163 if (((res_prev->end + 1) % tmp_divide) == 0) {
1164 /* just perfect, starting address's divisible by length */
1165 flag = TRUE;
1166 len_cur = len_tmp;
1167 start_cur = res_prev->end + 1;
1168 } else {
1169 /* Needs adjusting */
1170 tmp_start = res_prev->end + 1;
1171 flag = FALSE;
1172
1173 while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
1174 if ((tmp_start % tmp_divide) == 0) {
1175 flag = TRUE;
1176 len_cur = len_tmp;
1177 start_cur = tmp_start;
1178 break;
1179 }
1180 tmp_start += tmp_divide - tmp_start % tmp_divide;
1181 if (tmp_start >= res_cur->start - 1)
1182 break;
1183 }
1184 }
1185
1186 if (flag && len_cur == res->len) {
1187 res->start = start_cur;
1188 res->len += 1; /* To restore the balance */
1189 res->end = res->start + res->len - 1;
1190 return 0;
1191 }
1192 }
1193 }
1194 }
1195 }
1196 /* end if (res_prev) */
1197 res_prev = res_cur;
1198 if (res_cur->next)
1199 res_cur = res_cur->next;
1200 else
1201 res_cur = res_cur->nextRange;
1202 } /* end of while */
1203
1204
1205 if (!res_prev) {
1206 /* 1st device ever */
1207 /* need to find appropriate range */
1208 switch (res->type) {
1209 case IO:
1210 range = bus_cur->rangeIO;
1211 break;
1212 case MEM:
1213 range = bus_cur->rangeMem;
1214 break;
1215 case PFMEM:
1216 range = bus_cur->rangePFMem;
1217 break;
1218 }
1219 while (range) {
1220 if ((len_tmp = range->end - range->start) >= res->len) {
1221 if ((len_tmp < len_cur) || (len_cur == 0)) {
1222 if ((range->start % tmp_divide) == 0) {
1223 /* just perfect, starting address's divisible by length */
1224 flag = TRUE;
1225 len_cur = len_tmp;
1226 start_cur = range->start;
1227 } else {
1228 /* Needs adjusting */
1229 tmp_start = range->start;
1230 flag = FALSE;
1231
1232 while ((len_tmp = range->end - tmp_start) >= res->len) {
1233 if ((tmp_start % tmp_divide) == 0) {
1234 flag = TRUE;
1235 len_cur = len_tmp;
1236 start_cur = tmp_start;
1237 break;
1238 }
1239 tmp_start += tmp_divide - tmp_start % tmp_divide;
1240 if (tmp_start >= range->end)
1241 break;
1242 }
1243 }
1244
1245 if (flag && len_cur == res->len) {
1246 res->start = start_cur;
1247 res->len += 1; /* To restore the balance */
1248 res->end = res->start + res->len - 1;
1249 return 0;
1250 }
1251 }
1252 }
1253 range = range->next;
1254 } /* end of while */
1255
1256 if ((!range) && (len_cur == 0)) {
1257 /* have gone through the list of devices and ranges and haven't found n.e.thing */
1258 err ("no appropriate range.. bailing out...\n");
1259 return -EINVAL;
1260 } else if (len_cur) {
1261 res->start = start_cur;
1262 res->len += 1; /* To restore the balance */
1263 res->end = res->start + res->len - 1;
1264 return 0;
1265 }
1266 }
1267
1268 if (!res_cur) {
1269 debug ("prev->rangeno = %d, noranges = %d\n", res_prev->rangeno, noranges);
1270 if (res_prev->rangeno < noranges) {
1271 /* if there're more ranges out there to check */
1272 switch (res->type) {
1273 case IO:
1274 range = bus_cur->rangeIO;
1275 break;
1276 case MEM:
1277 range = bus_cur->rangeMem;
1278 break;
1279 case PFMEM:
1280 range = bus_cur->rangePFMem;
1281 break;
1282 }
1283 while (range) {
1284 if ((len_tmp = range->end - range->start) >= res->len) {
1285 if ((len_tmp < len_cur) || (len_cur == 0)) {
1286 if ((range->start % tmp_divide) == 0) {
1287 /* just perfect, starting address's divisible by length */
1288 flag = TRUE;
1289 len_cur = len_tmp;
1290 start_cur = range->start;
1291 } else {
1292 /* Needs adjusting */
1293 tmp_start = range->start;
1294 flag = FALSE;
1295
1296 while ((len_tmp = range->end - tmp_start) >= res->len) {
1297 if ((tmp_start % tmp_divide) == 0) {
1298 flag = TRUE;
1299 len_cur = len_tmp;
1300 start_cur = tmp_start;
1301 break;
1302 }
1303 tmp_start += tmp_divide - tmp_start % tmp_divide;
1304 if (tmp_start >= range->end)
1305 break;
1306 }
1307 }
1308
1309 if (flag && len_cur == res->len) {
1310 res->start = start_cur;
1311 res->len += 1; /* To restore the balance */
1312 res->end = res->start + res->len - 1;
1313 return 0;
1314 }
1315 }
1316 }
1317 range = range->next;
1318 } /* end of while */
1319
1320 if ((!range) && (len_cur == 0)) {
1321 /* have gone through the list of devices and ranges and haven't found n.e.thing */
1322 err ("no appropriate range.. bailing out...\n");
1323 return -EINVAL;
1324 } else if (len_cur) {
1325 res->start = start_cur;
1326 res->len += 1; /* To restore the balance */
1327 res->end = res->start + res->len - 1;
1328 return 0;
1329 }
1330 } else {
1331 /* no more ranges to check on */
1332 if (len_cur) {
1333 res->start = start_cur;
1334 res->len += 1; /* To restore the balance */
1335 res->end = res->start + res->len - 1;
1336 return 0;
1337 } else {
1338 /* have gone through the list of devices and haven't found n.e.thing */
1339 err ("no appropriate range.. bailing out...\n");
1340 return -EINVAL;
1341 }
1342 }
1343 } /* end if(!res_cur) */
1344 return -EINVAL;
1345}
1346
1347/********************************************************************************
1348 * This routine is called from remove_card if the card contained PPB.
1349 * It will remove all the resources on the bus as well as the bus itself
1350 * Input: Bus
1351 * Ouput: 0, -ENODEV
1352 ********************************************************************************/
1353int ibmphp_remove_bus (struct bus_node *bus, u8 parent_busno)
1354{
1355 struct resource_node *res_cur;
1356 struct resource_node *res_tmp;
1357 struct bus_node *prev_bus;
1358 int rc;
1359
1360 prev_bus = find_bus_wprev (parent_busno, NULL, 0);
1361
1362 if (!prev_bus) {
1363 debug ("something terribly wrong. Cannot find parent bus to the one to remove\n");
1364 return -ENODEV;
1365 }
1366
1367 debug ("In ibmphp_remove_bus... prev_bus->busno is %x\n", prev_bus->busno);
1368
1369 rc = remove_ranges (bus, prev_bus);
1370 if (rc)
1371 return rc;
1372
1373 if (bus->firstIO) {
1374 res_cur = bus->firstIO;
1375 while (res_cur) {
1376 res_tmp = res_cur;
1377 if (res_cur->next)
1378 res_cur = res_cur->next;
1379 else
1380 res_cur = res_cur->nextRange;
1381 kfree (res_tmp);
1382 res_tmp = NULL;
1383 }
1384 bus->firstIO = NULL;
1385 }
1386 if (bus->firstMem) {
1387 res_cur = bus->firstMem;
1388 while (res_cur) {
1389 res_tmp = res_cur;
1390 if (res_cur->next)
1391 res_cur = res_cur->next;
1392 else
1393 res_cur = res_cur->nextRange;
1394 kfree (res_tmp);
1395 res_tmp = NULL;
1396 }
1397 bus->firstMem = NULL;
1398 }
1399 if (bus->firstPFMem) {
1400 res_cur = bus->firstPFMem;
1401 while (res_cur) {
1402 res_tmp = res_cur;
1403 if (res_cur->next)
1404 res_cur = res_cur->next;
1405 else
1406 res_cur = res_cur->nextRange;
1407 kfree (res_tmp);
1408 res_tmp = NULL;
1409 }
1410 bus->firstPFMem = NULL;
1411 }
1412
1413 if (bus->firstPFMemFromMem) {
1414 res_cur = bus->firstPFMemFromMem;
1415 while (res_cur) {
1416 res_tmp = res_cur;
1417 res_cur = res_cur->next;
1418
1419 kfree (res_tmp);
1420 res_tmp = NULL;
1421 }
1422 bus->firstPFMemFromMem = NULL;
1423 }
1424
1425 list_del (&bus->bus_list);
1426 kfree (bus);
1427 return 0;
1428}
1429
1430/******************************************************************************
1431 * This routine deletes the ranges from a given bus, and the entries from the
1432 * parent's bus in the resources
1433 * Input: current bus, previous bus
1434 * Output: 0, -EINVAL
1435 ******************************************************************************/
1436static int remove_ranges (struct bus_node *bus_cur, struct bus_node *bus_prev)
1437{
1438 struct range_node *range_cur;
1439 struct range_node *range_tmp;
1440 int i;
1441 struct resource_node *res = NULL;
1442
1443 if (bus_cur->noIORanges) {
1444 range_cur = bus_cur->rangeIO;
1445 for (i = 0; i < bus_cur->noIORanges; i++) {
1446 if (ibmphp_find_resource (bus_prev, range_cur->start, &res, IO) < 0)
1447 return -EINVAL;
1448 ibmphp_remove_resource (res);
1449
1450 range_tmp = range_cur;
1451 range_cur = range_cur->next;
1452 kfree (range_tmp);
1453 range_tmp = NULL;
1454 }
1455 bus_cur->rangeIO = NULL;
1456 }
1457 if (bus_cur->noMemRanges) {
1458 range_cur = bus_cur->rangeMem;
1459 for (i = 0; i < bus_cur->noMemRanges; i++) {
1460 if (ibmphp_find_resource (bus_prev, range_cur->start, &res, MEM) < 0)
1461 return -EINVAL;
1462
1463 ibmphp_remove_resource (res);
1464 range_tmp = range_cur;
1465 range_cur = range_cur->next;
1466 kfree (range_tmp);
1467 range_tmp = NULL;
1468 }
1469 bus_cur->rangeMem = NULL;
1470 }
1471 if (bus_cur->noPFMemRanges) {
1472 range_cur = bus_cur->rangePFMem;
1473 for (i = 0; i < bus_cur->noPFMemRanges; i++) {
1474 if (ibmphp_find_resource (bus_prev, range_cur->start, &res, PFMEM) < 0)
1475 return -EINVAL;
1476
1477 ibmphp_remove_resource (res);
1478 range_tmp = range_cur;
1479 range_cur = range_cur->next;
1480 kfree (range_tmp);
1481 range_tmp = NULL;
1482 }
1483 bus_cur->rangePFMem = NULL;
1484 }
1485 return 0;
1486}
1487
1488/*
1489 * find the resource node in the bus
1490 * Input: Resource needed, start address of the resource, type of resource
1491 */
1492int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resource_node **res, int flag)
1493{
1494 struct resource_node *res_cur = NULL;
1495 char * type = "";
1496
1497 if (!bus) {
1498 err ("The bus passed in NULL to find resource\n");
1499 return -ENODEV;
1500 }
1501
1502 switch (flag) {
1503 case IO:
1504 res_cur = bus->firstIO;
1505 type = "io";
1506 break;
1507 case MEM:
1508 res_cur = bus->firstMem;
1509 type = "mem";
1510 break;
1511 case PFMEM:
1512 res_cur = bus->firstPFMem;
1513 type = "pfmem";
1514 break;
1515 default:
1516 err ("wrong type of flag\n");
1517 return -EINVAL;
1518 }
1519
1520 while (res_cur) {
1521 if (res_cur->start == start_address) {
1522 *res = res_cur;
1523 break;
1524 }
1525 if (res_cur->next)
1526 res_cur = res_cur->next;
1527 else
1528 res_cur = res_cur->nextRange;
1529 }
1530
1531 if (!res_cur) {
1532 if (flag == PFMEM) {
1533 res_cur = bus->firstPFMemFromMem;
1534 while (res_cur) {
1535 if (res_cur->start == start_address) {
1536 *res = res_cur;
1537 break;
1538 }
1539 res_cur = res_cur->next;
1540 }
1541 if (!res_cur) {
1542 debug ("SOS...cannot find %s resource in the bus.\n", type);
1543 return -EINVAL;
1544 }
1545 } else {
1546 debug ("SOS... cannot find %s resource in the bus.\n", type);
1547 return -EINVAL;
1548 }
1549 }
1550
1551 if (*res)
1552 debug ("*res->start = %x\n", (*res)->start);
1553
1554 return 0;
1555}
1556
1557/***********************************************************************
1558 * This routine will free the resource structures used by the
1559 * system. It is called from cleanup routine for the module
1560 * Parameters: none
1561 * Returns: none
1562 ***********************************************************************/
1563void ibmphp_free_resources (void)
1564{
1565 struct bus_node *bus_cur = NULL;
1566 struct bus_node *bus_tmp;
1567 struct range_node *range_cur;
1568 struct range_node *range_tmp;
1569 struct resource_node *res_cur;
1570 struct resource_node *res_tmp;
1571 struct list_head *tmp;
1572 struct list_head *next;
1573 int i = 0;
1574 flags = 1;
1575
1576 list_for_each_safe (tmp, next, &gbuses) {
1577 bus_cur = list_entry (tmp, struct bus_node, bus_list);
1578 if (bus_cur->noIORanges) {
1579 range_cur = bus_cur->rangeIO;
1580 for (i = 0; i < bus_cur->noIORanges; i++) {
1581 if (!range_cur)
1582 break;
1583 range_tmp = range_cur;
1584 range_cur = range_cur->next;
1585 kfree (range_tmp);
1586 range_tmp = NULL;
1587 }
1588 }
1589 if (bus_cur->noMemRanges) {
1590 range_cur = bus_cur->rangeMem;
1591 for (i = 0; i < bus_cur->noMemRanges; i++) {
1592 if (!range_cur)
1593 break;
1594 range_tmp = range_cur;
1595 range_cur = range_cur->next;
1596 kfree (range_tmp);
1597 range_tmp = NULL;
1598 }
1599 }
1600 if (bus_cur->noPFMemRanges) {
1601 range_cur = bus_cur->rangePFMem;
1602 for (i = 0; i < bus_cur->noPFMemRanges; i++) {
1603 if (!range_cur)
1604 break;
1605 range_tmp = range_cur;
1606 range_cur = range_cur->next;
1607 kfree (range_tmp);
1608 range_tmp = NULL;
1609 }
1610 }
1611
1612 if (bus_cur->firstIO) {
1613 res_cur = bus_cur->firstIO;
1614 while (res_cur) {
1615 res_tmp = res_cur;
1616 if (res_cur->next)
1617 res_cur = res_cur->next;
1618 else
1619 res_cur = res_cur->nextRange;
1620 kfree (res_tmp);
1621 res_tmp = NULL;
1622 }
1623 bus_cur->firstIO = NULL;
1624 }
1625 if (bus_cur->firstMem) {
1626 res_cur = bus_cur->firstMem;
1627 while (res_cur) {
1628 res_tmp = res_cur;
1629 if (res_cur->next)
1630 res_cur = res_cur->next;
1631 else
1632 res_cur = res_cur->nextRange;
1633 kfree (res_tmp);
1634 res_tmp = NULL;
1635 }
1636 bus_cur->firstMem = NULL;
1637 }
1638 if (bus_cur->firstPFMem) {
1639 res_cur = bus_cur->firstPFMem;
1640 while (res_cur) {
1641 res_tmp = res_cur;
1642 if (res_cur->next)
1643 res_cur = res_cur->next;
1644 else
1645 res_cur = res_cur->nextRange;
1646 kfree (res_tmp);
1647 res_tmp = NULL;
1648 }
1649 bus_cur->firstPFMem = NULL;
1650 }
1651
1652 if (bus_cur->firstPFMemFromMem) {
1653 res_cur = bus_cur->firstPFMemFromMem;
1654 while (res_cur) {
1655 res_tmp = res_cur;
1656 res_cur = res_cur->next;
1657
1658 kfree (res_tmp);
1659 res_tmp = NULL;
1660 }
1661 bus_cur->firstPFMemFromMem = NULL;
1662 }
1663
1664 bus_tmp = bus_cur;
1665 list_del (&bus_cur->bus_list);
1666 kfree (bus_tmp);
1667 bus_tmp = NULL;
1668 }
1669}
1670
1671/*********************************************************************************
1672 * This function will go over the PFmem resources to check if the EBDA allocated
1673 * pfmem out of memory buckets of the bus. If so, it will change the range numbers
1674 * and a flag to indicate that this resource is out of memory. It will also move the
1675 * Pfmem out of the pfmem resource list to the PFMemFromMem list, and will create
1676 * a new Mem node
1677 * This routine is called right after initialization
1678 *******************************************************************************/
1679static int __init once_over (void)
1680{
1681 struct resource_node *pfmem_cur;
1682 struct resource_node *pfmem_prev;
1683 struct resource_node *mem;
1684 struct bus_node *bus_cur;
1685 struct list_head *tmp;
1686
1687 list_for_each (tmp, &gbuses) {
1688 bus_cur = list_entry (tmp, struct bus_node, bus_list);
1689 if ((!bus_cur->rangePFMem) && (bus_cur->firstPFMem)) {
1690 for (pfmem_cur = bus_cur->firstPFMem, pfmem_prev = NULL; pfmem_cur; pfmem_prev = pfmem_cur, pfmem_cur = pfmem_cur->next) {
1691 pfmem_cur->fromMem = TRUE;
1692 if (pfmem_prev)
1693 pfmem_prev->next = pfmem_cur->next;
1694 else
1695 bus_cur->firstPFMem = pfmem_cur->next;
1696
1697 if (!bus_cur->firstPFMemFromMem)
1698 pfmem_cur->next = NULL;
1699 else
1700 /* we don't need to sort PFMemFromMem since we're using mem node for
1701 all the real work anyways, so just insert at the beginning of the
1702 list
1703 */
1704 pfmem_cur->next = bus_cur->firstPFMemFromMem;
1705
1706 bus_cur->firstPFMemFromMem = pfmem_cur;
1707
1708 mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
1709 if (!mem) {
1710 err ("out of system memory\n");
1711 return -ENOMEM;
1712 }
1713 memset (mem, 0, sizeof (struct resource_node));
1714 mem->type = MEM;
1715 mem->busno = pfmem_cur->busno;
1716 mem->devfunc = pfmem_cur->devfunc;
1717 mem->start = pfmem_cur->start;
1718 mem->end = pfmem_cur->end;
1719 mem->len = pfmem_cur->len;
1720 if (ibmphp_add_resource (mem) < 0)
1721 err ("Trouble...trouble... EBDA allocated pfmem from mem, but system doesn't display it has this space... unless not PCI device...\n");
1722 pfmem_cur->rangeno = mem->rangeno;
1723 } /* end for pfmem */
1724 } /* end if */
1725 } /* end list_for_each bus */
1726 return 0;
1727}
1728
1729int ibmphp_add_pfmem_from_mem (struct resource_node *pfmem)
1730{
1731 struct bus_node *bus_cur = find_bus_wprev (pfmem->busno, NULL, 0);
1732
1733 if (!bus_cur) {
1734 err ("cannot find bus of pfmem to add...\n");
1735 return -ENODEV;
1736 }
1737
1738 if (bus_cur->firstPFMemFromMem)
1739 pfmem->next = bus_cur->firstPFMemFromMem;
1740 else
1741 pfmem->next = NULL;
1742
1743 bus_cur->firstPFMemFromMem = pfmem;
1744
1745 return 0;
1746}
1747
1748/* This routine just goes through the buses to see if the bus already exists.
1749 * It is called from ibmphp_find_sec_number, to find out a secondary bus number for
1750 * bridged cards
1751 * Parameters: bus_number
1752 * Returns: Bus pointer or NULL
1753 */
1754struct bus_node *ibmphp_find_res_bus (u8 bus_number)
1755{
1756 return find_bus_wprev (bus_number, NULL, 0);
1757}
1758
1759static struct bus_node *find_bus_wprev (u8 bus_number, struct bus_node **prev, u8 flag)
1760{
1761 struct bus_node *bus_cur;
1762 struct list_head *tmp;
1763 struct list_head *tmp_prev;
1764
1765 list_for_each (tmp, &gbuses) {
1766 tmp_prev = tmp->prev;
1767 bus_cur = list_entry (tmp, struct bus_node, bus_list);
1768 if (flag)
1769 *prev = list_entry (tmp_prev, struct bus_node, bus_list);
1770 if (bus_cur->busno == bus_number)
1771 return bus_cur;
1772 }
1773
1774 return NULL;
1775}
1776
1777void ibmphp_print_test (void)
1778{
1779 int i = 0;
1780 struct bus_node *bus_cur = NULL;
1781 struct range_node *range;
1782 struct resource_node *res;
1783 struct list_head *tmp;
1784
1785 debug_pci ("*****************START**********************\n");
1786
1787 if ((!list_empty(&gbuses)) && flags) {
1788 err ("The GBUSES is not NULL?!?!?!?!?\n");
1789 return;
1790 }
1791
1792 list_for_each (tmp, &gbuses) {
1793 bus_cur = list_entry (tmp, struct bus_node, bus_list);
1794 debug_pci ("This is bus # %d. There are\n", bus_cur->busno);
1795 debug_pci ("IORanges = %d\t", bus_cur->noIORanges);
1796 debug_pci ("MemRanges = %d\t", bus_cur->noMemRanges);
1797 debug_pci ("PFMemRanges = %d\n", bus_cur->noPFMemRanges);
1798 debug_pci ("The IO Ranges are as follows:\n");
1799 if (bus_cur->rangeIO) {
1800 range = bus_cur->rangeIO;
1801 for (i = 0; i < bus_cur->noIORanges; i++) {
1802 debug_pci ("rangeno is %d\n", range->rangeno);
1803 debug_pci ("[%x - %x]\n", range->start, range->end);
1804 range = range->next;
1805 }
1806 }
1807
1808 debug_pci ("The Mem Ranges are as follows:\n");
1809 if (bus_cur->rangeMem) {
1810 range = bus_cur->rangeMem;
1811 for (i = 0; i < bus_cur->noMemRanges; i++) {
1812 debug_pci ("rangeno is %d\n", range->rangeno);
1813 debug_pci ("[%x - %x]\n", range->start, range->end);
1814 range = range->next;
1815 }
1816 }
1817
1818 debug_pci ("The PFMem Ranges are as follows:\n");
1819
1820 if (bus_cur->rangePFMem) {
1821 range = bus_cur->rangePFMem;
1822 for (i = 0; i < bus_cur->noPFMemRanges; i++) {
1823 debug_pci ("rangeno is %d\n", range->rangeno);
1824 debug_pci ("[%x - %x]\n", range->start, range->end);
1825 range = range->next;
1826 }
1827 }
1828
1829 debug_pci ("The resources on this bus are as follows\n");
1830
1831 debug_pci ("IO...\n");
1832 if (bus_cur->firstIO) {
1833 res = bus_cur->firstIO;
1834 while (res) {
1835 debug_pci ("The range # is %d\n", res->rangeno);
1836 debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
1837 debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
1838 if (res->next)
1839 res = res->next;
1840 else if (res->nextRange)
1841 res = res->nextRange;
1842 else
1843 break;
1844 }
1845 }
1846 debug_pci ("Mem...\n");
1847 if (bus_cur->firstMem) {
1848 res = bus_cur->firstMem;
1849 while (res) {
1850 debug_pci ("The range # is %d\n", res->rangeno);
1851 debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
1852 debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
1853 if (res->next)
1854 res = res->next;
1855 else if (res->nextRange)
1856 res = res->nextRange;
1857 else
1858 break;
1859 }
1860 }
1861 debug_pci ("PFMem...\n");
1862 if (bus_cur->firstPFMem) {
1863 res = bus_cur->firstPFMem;
1864 while (res) {
1865 debug_pci ("The range # is %d\n", res->rangeno);
1866 debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
1867 debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
1868 if (res->next)
1869 res = res->next;
1870 else if (res->nextRange)
1871 res = res->nextRange;
1872 else
1873 break;
1874 }
1875 }
1876
1877 debug_pci ("PFMemFromMem...\n");
1878 if (bus_cur->firstPFMemFromMem) {
1879 res = bus_cur->firstPFMemFromMem;
1880 while (res) {
1881 debug_pci ("The range # is %d\n", res->rangeno);
1882 debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
1883 debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
1884 res = res->next;
1885 }
1886 }
1887 }
1888 debug_pci ("***********************END***********************\n");
1889}
1890
1891static int range_exists_already (struct range_node * range, struct bus_node * bus_cur, u8 type)
1892{
1893 struct range_node * range_cur = NULL;
1894 switch (type) {
1895 case IO:
1896 range_cur = bus_cur->rangeIO;
1897 break;
1898 case MEM:
1899 range_cur = bus_cur->rangeMem;
1900 break;
1901 case PFMEM:
1902 range_cur = bus_cur->rangePFMem;
1903 break;
1904 default:
1905 err ("wrong type passed to find out if range already exists\n");
1906 return -ENODEV;
1907 }
1908
1909 while (range_cur) {
1910 if ((range_cur->start == range->start) && (range_cur->end == range->end))
1911 return 1;
1912 range_cur = range_cur->next;
1913 }
1914
1915 return 0;
1916}
1917
1918/* This routine will read the windows for any PPB we have and update the
1919 * range info for the secondary bus, and will also input this info into
1920 * primary bus, since BIOS doesn't. This is for PPB that are in the system
1921 * on bootup. For bridged cards that were added during previous load of the
1922 * driver, only the ranges and the bus structure are added, the devices are
1923 * added from NVRAM
1924 * Input: primary busno
1925 * Returns: none
1926 * Note: this function doesn't take into account IO restrictions etc,
1927 * so will only work for bridges with no video/ISA devices behind them It
1928 * also will not work for onboard PPB's that can have more than 1 *bus
1929 * behind them All these are TO DO.
1930 * Also need to add more error checkings... (from fnc returns etc)
1931 */
1932static int __init update_bridge_ranges (struct bus_node **bus)
1933{
1934 u8 sec_busno, device, function, hdr_type, start_io_address, end_io_address;
1935 u16 vendor_id, upper_io_start, upper_io_end, start_mem_address, end_mem_address;
1936 u32 start_address, end_address, upper_start, upper_end;
1937 struct bus_node *bus_sec;
1938 struct bus_node *bus_cur;
1939 struct resource_node *io;
1940 struct resource_node *mem;
1941 struct resource_node *pfmem;
1942 struct range_node *range;
1943 unsigned int devfn;
1944
1945 bus_cur = *bus;
1946 if (!bus_cur)
1947 return -ENODEV;
1948 ibmphp_pci_bus->number = bus_cur->busno;
1949
1950 debug ("inside %s\n", __FUNCTION__);
1951 debug ("bus_cur->busno = %x\n", bus_cur->busno);
1952
1953 for (device = 0; device < 32; device++) {
1954 for (function = 0x00; function < 0x08; function++) {
1955 devfn = PCI_DEVFN(device, function);
1956 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
1957
1958 if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
1959 /* found correct device!!! */
1960 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
1961
1962 switch (hdr_type) {
1963 case PCI_HEADER_TYPE_NORMAL:
1964 function = 0x8;
1965 break;
1966 case PCI_HEADER_TYPE_MULTIDEVICE:
1967 break;
1968 case PCI_HEADER_TYPE_BRIDGE:
1969 function = 0x8;
1970 case PCI_HEADER_TYPE_MULTIBRIDGE:
1971 /* We assume here that only 1 bus behind the bridge
1972 TO DO: add functionality for several:
1973 temp = secondary;
1974 while (temp < subordinate) {
1975 ...
1976 temp++;
1977 }
1978 */
1979 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_busno);
1980 bus_sec = find_bus_wprev (sec_busno, NULL, 0);
1981 /* this bus structure doesn't exist yet, PPB was configured during previous loading of ibmphp */
1982 if (!bus_sec) {
1983 bus_sec = alloc_error_bus (NULL, sec_busno, 1);
1984 /* the rest will be populated during NVRAM call */
1985 return 0;
1986 }
1987 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &start_io_address);
1988 pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, &end_io_address);
1989 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_IO_BASE_UPPER16, &upper_io_start);
1990 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_IO_LIMIT_UPPER16, &upper_io_end);
1991 start_address = (start_io_address & PCI_IO_RANGE_MASK) << 8;
1992 start_address |= (upper_io_start << 16);
1993 end_address = (end_io_address & PCI_IO_RANGE_MASK) << 8;
1994 end_address |= (upper_io_end << 16);
1995
1996 if ((start_address) && (start_address <= end_address)) {
1997 range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
1998 if (!range) {
1999 err ("out of system memory\n");
2000 return -ENOMEM;
2001 }
2002 memset (range, 0, sizeof (struct range_node));
2003 range->start = start_address;
2004 range->end = end_address + 0xfff;
2005
2006 if (bus_sec->noIORanges > 0) {
2007 if (!range_exists_already (range, bus_sec, IO)) {
2008 add_range (IO, range, bus_sec);
2009 ++bus_sec->noIORanges;
2010 } else {
2011 kfree (range);
2012 range = NULL;
2013 }
2014 } else {
2015 /* 1st IO Range on the bus */
2016 range->rangeno = 1;
2017 bus_sec->rangeIO = range;
2018 ++bus_sec->noIORanges;
2019 }
2020 fix_resources (bus_sec);
2021
2022 if (ibmphp_find_resource (bus_cur, start_address, &io, IO)) {
2023 io = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
2024 if (!io) {
2025 kfree (range);
2026 err ("out of system memory\n");
2027 return -ENOMEM;
2028 }
2029 memset (io, 0, sizeof (struct resource_node));
2030 io->type = IO;
2031 io->busno = bus_cur->busno;
2032 io->devfunc = ((device << 3) | (function & 0x7));
2033 io->start = start_address;
2034 io->end = end_address + 0xfff;
2035 io->len = io->end - io->start + 1;
2036 ibmphp_add_resource (io);
2037 }
2038 }
2039
2040 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, &start_mem_address);
2041 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, &end_mem_address);
2042
2043 start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
2044 end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
2045
2046 if ((start_address) && (start_address <= end_address)) {
2047
2048 range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
2049 if (!range) {
2050 err ("out of system memory\n");
2051 return -ENOMEM;
2052 }
2053 memset (range, 0, sizeof (struct range_node));
2054 range->start = start_address;
2055 range->end = end_address + 0xfffff;
2056
2057 if (bus_sec->noMemRanges > 0) {
2058 if (!range_exists_already (range, bus_sec, MEM)) {
2059 add_range (MEM, range, bus_sec);
2060 ++bus_sec->noMemRanges;
2061 } else {
2062 kfree (range);
2063 range = NULL;
2064 }
2065 } else {
2066 /* 1st Mem Range on the bus */
2067 range->rangeno = 1;
2068 bus_sec->rangeMem = range;
2069 ++bus_sec->noMemRanges;
2070 }
2071
2072 fix_resources (bus_sec);
2073
2074 if (ibmphp_find_resource (bus_cur, start_address, &mem, MEM)) {
2075 mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
2076 if (!mem) {
2077 kfree (range);
2078 err ("out of system memory\n");
2079 return -ENOMEM;
2080 }
2081 memset (mem, 0, sizeof (struct resource_node));
2082 mem->type = MEM;
2083 mem->busno = bus_cur->busno;
2084 mem->devfunc = ((device << 3) | (function & 0x7));
2085 mem->start = start_address;
2086 mem->end = end_address + 0xfffff;
2087 mem->len = mem->end - mem->start + 1;
2088 ibmphp_add_resource (mem);
2089 }
2090 }
2091 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &start_mem_address);
2092 pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &end_mem_address);
2093 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_BASE_UPPER32, &upper_start);
2094 pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_LIMIT_UPPER32, &upper_end);
2095 start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
2096 end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
2097#if BITS_PER_LONG == 64
2098 start_address |= ((long) upper_start) << 32;
2099 end_address |= ((long) upper_end) << 32;
2100#endif
2101
2102 if ((start_address) && (start_address <= end_address)) {
2103
2104 range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
2105 if (!range) {
2106 err ("out of system memory\n");
2107 return -ENOMEM;
2108 }
2109 memset (range, 0, sizeof (struct range_node));
2110 range->start = start_address;
2111 range->end = end_address + 0xfffff;
2112
2113 if (bus_sec->noPFMemRanges > 0) {
2114 if (!range_exists_already (range, bus_sec, PFMEM)) {
2115 add_range (PFMEM, range, bus_sec);
2116 ++bus_sec->noPFMemRanges;
2117 } else {
2118 kfree (range);
2119 range = NULL;
2120 }
2121 } else {
2122 /* 1st PFMem Range on the bus */
2123 range->rangeno = 1;
2124 bus_sec->rangePFMem = range;
2125 ++bus_sec->noPFMemRanges;
2126 }
2127
2128 fix_resources (bus_sec);
2129 if (ibmphp_find_resource (bus_cur, start_address, &pfmem, PFMEM)) {
2130 pfmem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
2131 if (!pfmem) {
2132 kfree (range);
2133 err ("out of system memory\n");
2134 return -ENOMEM;
2135 }
2136 memset (pfmem, 0, sizeof (struct resource_node));
2137 pfmem->type = PFMEM;
2138 pfmem->busno = bus_cur->busno;
2139 pfmem->devfunc = ((device << 3) | (function & 0x7));
2140 pfmem->start = start_address;
2141 pfmem->end = end_address + 0xfffff;
2142 pfmem->len = pfmem->end - pfmem->start + 1;
2143 pfmem->fromMem = FALSE;
2144
2145 ibmphp_add_resource (pfmem);
2146 }
2147 }
2148 break;
2149 } /* end of switch */
2150 } /* end if vendor */
2151 } /* end for function */
2152 } /* end for device */
2153
2154 bus = &bus_cur;
2155 return 0;
2156}
diff --git a/drivers/pci/hotplug/pci_hotplug.h b/drivers/pci/hotplug/pci_hotplug.h
new file mode 100644
index 000000000000..57ace325168d
--- /dev/null
+++ b/drivers/pci/hotplug/pci_hotplug.h
@@ -0,0 +1,180 @@
1/*
2 * PCI HotPlug Core Functions
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <greg@kroah.com>
26 *
27 */
28#ifndef _PCI_HOTPLUG_H
29#define _PCI_HOTPLUG_H
30
31
32/* These values come from the PCI Hotplug Spec */
33enum pci_bus_speed {
34 PCI_SPEED_33MHz = 0x00,
35 PCI_SPEED_66MHz = 0x01,
36 PCI_SPEED_66MHz_PCIX = 0x02,
37 PCI_SPEED_100MHz_PCIX = 0x03,
38 PCI_SPEED_133MHz_PCIX = 0x04,
39 PCI_SPEED_66MHz_PCIX_ECC = 0x05,
40 PCI_SPEED_100MHz_PCIX_ECC = 0x06,
41 PCI_SPEED_133MHz_PCIX_ECC = 0x07,
42 PCI_SPEED_66MHz_PCIX_266 = 0x09,
43 PCI_SPEED_100MHz_PCIX_266 = 0x0a,
44 PCI_SPEED_133MHz_PCIX_266 = 0x0b,
45 PCI_SPEED_66MHz_PCIX_533 = 0x11,
46 PCI_SPEED_100MHz_PCIX_533 = 0x12,
47 PCI_SPEED_133MHz_PCIX_533 = 0x13,
48 PCI_SPEED_UNKNOWN = 0xff,
49};
50
51/* These values come from the PCI Express Spec */
52enum pcie_link_width {
53 PCIE_LNK_WIDTH_RESRV = 0x00,
54 PCIE_LNK_X1 = 0x01,
55 PCIE_LNK_X2 = 0x02,
56 PCIE_LNK_X4 = 0x04,
57 PCIE_LNK_X8 = 0x08,
58 PCIE_LNK_X12 = 0x0C,
59 PCIE_LNK_X16 = 0x10,
60 PCIE_LNK_X32 = 0x20,
61 PCIE_LNK_WIDTH_UNKNOWN = 0xFF,
62};
63
64enum pcie_link_speed {
65 PCIE_2PT5GB = 0x14,
66 PCIE_LNK_SPEED_UNKNOWN = 0xFF,
67};
68
69struct hotplug_slot;
70struct hotplug_slot_attribute {
71 struct attribute attr;
72 ssize_t (*show)(struct hotplug_slot *, char *);
73 ssize_t (*store)(struct hotplug_slot *, const char *, size_t);
74};
75#define to_hotplug_attr(n) container_of(n, struct hotplug_slot_attribute, attr);
76
77/**
78 * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use
79 * @owner: The module owner of this structure
80 * @enable_slot: Called when the user wants to enable a specific pci slot
81 * @disable_slot: Called when the user wants to disable a specific pci slot
82 * @set_attention_status: Called to set the specific slot's attention LED to
83 * the specified value
84 * @hardware_test: Called to run a specified hardware test on the specified
85 * slot.
86 * @get_power_status: Called to get the current power status of a slot.
87 * If this field is NULL, the value passed in the struct hotplug_slot_info
88 * will be used when this value is requested by a user.
89 * @get_attention_status: Called to get the current attention status of a slot.
90 * If this field is NULL, the value passed in the struct hotplug_slot_info
91 * will be used when this value is requested by a user.
92 * @get_latch_status: Called to get the current latch status of a slot.
93 * If this field is NULL, the value passed in the struct hotplug_slot_info
94 * will be used when this value is requested by a user.
95 * @get_adapter_status: Called to get see if an adapter is present in the slot or not.
96 * If this field is NULL, the value passed in the struct hotplug_slot_info
97 * will be used when this value is requested by a user.
98 * @get_address: Called to get pci address of a slot.
99 * If this field is NULL, the value passed in the struct hotplug_slot_info
100 * will be used when this value is requested by a user.
101 * @get_max_bus_speed: Called to get the max bus speed for a slot.
102 * If this field is NULL, the value passed in the struct hotplug_slot_info
103 * will be used when this value is requested by a user.
104 * @get_cur_bus_speed: Called to get the current bus speed for a slot.
105 * If this field is NULL, the value passed in the struct hotplug_slot_info
106 * will be used when this value is requested by a user.
107 *
108 * The table of function pointers that is passed to the hotplug pci core by a
109 * hotplug pci driver. These functions are called by the hotplug pci core when
110 * the user wants to do something to a specific slot (query it for information,
111 * set an LED, enable / disable power, etc.)
112 */
113struct hotplug_slot_ops {
114 struct module *owner;
115 int (*enable_slot) (struct hotplug_slot *slot);
116 int (*disable_slot) (struct hotplug_slot *slot);
117 int (*set_attention_status) (struct hotplug_slot *slot, u8 value);
118 int (*hardware_test) (struct hotplug_slot *slot, u32 value);
119 int (*get_power_status) (struct hotplug_slot *slot, u8 *value);
120 int (*get_attention_status) (struct hotplug_slot *slot, u8 *value);
121 int (*get_latch_status) (struct hotplug_slot *slot, u8 *value);
122 int (*get_adapter_status) (struct hotplug_slot *slot, u8 *value);
123 int (*get_address) (struct hotplug_slot *slot, u32 *value);
124 int (*get_max_bus_speed) (struct hotplug_slot *slot, enum pci_bus_speed *value);
125 int (*get_cur_bus_speed) (struct hotplug_slot *slot, enum pci_bus_speed *value);
126};
127
128/**
129 * struct hotplug_slot_info - used to notify the hotplug pci core of the state of the slot
130 * @power: if power is enabled or not (1/0)
131 * @attention_status: if the attention light is enabled or not (1/0)
132 * @latch_status: if the latch (if any) is open or closed (1/0)
133 * @adapter_present: if there is a pci board present in the slot or not (1/0)
134 * @address: (domain << 16 | bus << 8 | dev)
135 *
136 * Used to notify the hotplug pci core of the status of a specific slot.
137 */
138struct hotplug_slot_info {
139 u8 power_status;
140 u8 attention_status;
141 u8 latch_status;
142 u8 adapter_status;
143 u32 address;
144 enum pci_bus_speed max_bus_speed;
145 enum pci_bus_speed cur_bus_speed;
146};
147
148/**
149 * struct hotplug_slot - used to register a physical slot with the hotplug pci core
150 * @name: the name of the slot being registered. This string must
151 * be unique amoung slots registered on this system.
152 * @ops: pointer to the &struct hotplug_slot_ops to be used for this slot
153 * @info: pointer to the &struct hotplug_slot_info for the inital values for
154 * this slot.
155 * @release: called during pci_hp_deregister to free memory allocated in a
156 * hotplug_slot structure.
157 * @private: used by the hotplug pci controller driver to store whatever it
158 * needs.
159 */
160struct hotplug_slot {
161 char *name;
162 struct hotplug_slot_ops *ops;
163 struct hotplug_slot_info *info;
164 void (*release) (struct hotplug_slot *slot);
165 void *private;
166
167 /* Variables below this are for use only by the hotplug pci core. */
168 struct list_head slot_list;
169 struct kobject kobj;
170};
171#define to_hotplug_slot(n) container_of(n, struct hotplug_slot, kobj)
172
173extern int pci_hp_register (struct hotplug_slot *slot);
174extern int pci_hp_deregister (struct hotplug_slot *slot);
175extern int pci_hp_change_slot_info (struct hotplug_slot *slot,
176 struct hotplug_slot_info *info);
177extern struct subsystem pci_hotplug_slots_subsys;
178
179#endif
180
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
new file mode 100644
index 000000000000..c802f6270b89
--- /dev/null
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -0,0 +1,715 @@
1/*
2 * PCI HotPlug Controller Core
3 *
4 * Copyright (C) 2001-2002 Greg Kroah-Hartman (greg@kroah.com)
5 * Copyright (C) 2001-2002 IBM Corp.
6 *
7 * All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
17 * NON INFRINGEMENT. See the GNU General Public License for more
18 * details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * Send feedback to <greg@kroah.com>
25 *
26 * Filesystem portion based on work done by Pat Mochel on ddfs/driverfs
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/moduleparam.h>
33#include <linux/kernel.h>
34#include <linux/types.h>
35#include <linux/list.h>
36#include <linux/pagemap.h>
37#include <linux/slab.h>
38#include <linux/smp_lock.h>
39#include <linux/init.h>
40#include <linux/mount.h>
41#include <linux/namei.h>
42#include <linux/pci.h>
43#include <asm/uaccess.h>
44#include <linux/kobject.h>
45#include <linux/sysfs.h>
46#include "pci_hotplug.h"
47
48
49#define MY_NAME "pci_hotplug"
50
51#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __FUNCTION__ , ## arg); } while (0)
52#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
53#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
54#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
55
56
57/* local variables */
58static int debug;
59
60#define DRIVER_VERSION "0.5"
61#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Scott Murray <scottm@somanetworks.com>"
62#define DRIVER_DESC "PCI Hot Plug PCI Core"
63
64
65//////////////////////////////////////////////////////////////////
66
67static LIST_HEAD(pci_hotplug_slot_list);
68
69struct subsystem pci_hotplug_slots_subsys;
70
71static ssize_t hotplug_slot_attr_show(struct kobject *kobj,
72 struct attribute *attr, char *buf)
73{
74 struct hotplug_slot *slot = to_hotplug_slot(kobj);
75 struct hotplug_slot_attribute *attribute = to_hotplug_attr(attr);
76 return attribute->show ? attribute->show(slot, buf) : 0;
77}
78
79static ssize_t hotplug_slot_attr_store(struct kobject *kobj,
80 struct attribute *attr, const char *buf, size_t len)
81{
82 struct hotplug_slot *slot = to_hotplug_slot(kobj);
83 struct hotplug_slot_attribute *attribute = to_hotplug_attr(attr);
84 return attribute->store ? attribute->store(slot, buf, len) : 0;
85}
86
87static struct sysfs_ops hotplug_slot_sysfs_ops = {
88 .show = hotplug_slot_attr_show,
89 .store = hotplug_slot_attr_store,
90};
91
92static void hotplug_slot_release(struct kobject *kobj)
93{
94 struct hotplug_slot *slot = to_hotplug_slot(kobj);
95 if (slot->release)
96 slot->release(slot);
97}
98
99static struct kobj_type hotplug_slot_ktype = {
100 .sysfs_ops = &hotplug_slot_sysfs_ops,
101 .release = &hotplug_slot_release,
102};
103
104decl_subsys_name(pci_hotplug_slots, slots, &hotplug_slot_ktype, NULL);
105
106/* these strings match up with the values in pci_bus_speed */
107static char *pci_bus_speed_strings[] = {
108 "33 MHz PCI", /* 0x00 */
109 "66 MHz PCI", /* 0x01 */
110 "66 MHz PCIX", /* 0x02 */
111 "100 MHz PCIX", /* 0x03 */
112 "133 MHz PCIX", /* 0x04 */
113 NULL, /* 0x05 */
114 NULL, /* 0x06 */
115 NULL, /* 0x07 */
116 NULL, /* 0x08 */
117 "66 MHz PCIX 266", /* 0x09 */
118 "100 MHz PCIX 266", /* 0x0a */
119 "133 MHz PCIX 266", /* 0x0b */
120 NULL, /* 0x0c */
121 NULL, /* 0x0d */
122 NULL, /* 0x0e */
123 NULL, /* 0x0f */
124 NULL, /* 0x10 */
125 "66 MHz PCIX 533", /* 0x11 */
126 "100 MHz PCIX 533", /* 0x12 */
127 "133 MHz PCIX 533", /* 0x13 */
128 "25 GBps PCI-E", /* 0x14 */
129};
130
131#ifdef CONFIG_HOTPLUG_PCI_CPCI
132extern int cpci_hotplug_init(int debug);
133extern void cpci_hotplug_exit(void);
134#else
135static inline int cpci_hotplug_init(int debug) { return 0; }
136static inline void cpci_hotplug_exit(void) { }
137#endif
138
139/* Weee, fun with macros... */
140#define GET_STATUS(name,type) \
141static int get_##name (struct hotplug_slot *slot, type *value) \
142{ \
143 struct hotplug_slot_ops *ops = slot->ops; \
144 int retval = 0; \
145 if (try_module_get(ops->owner)) { \
146 if (ops->get_##name) \
147 retval = ops->get_##name (slot, value); \
148 else \
149 *value = slot->info->name; \
150 module_put(ops->owner); \
151 } \
152 return retval; \
153}
154
155GET_STATUS(power_status, u8)
156GET_STATUS(attention_status, u8)
157GET_STATUS(latch_status, u8)
158GET_STATUS(adapter_status, u8)
159GET_STATUS(address, u32)
160GET_STATUS(max_bus_speed, enum pci_bus_speed)
161GET_STATUS(cur_bus_speed, enum pci_bus_speed)
162
163static ssize_t power_read_file (struct hotplug_slot *slot, char *buf)
164{
165 int retval;
166 u8 value;
167
168 retval = get_power_status (slot, &value);
169 if (retval)
170 goto exit;
171 retval = sprintf (buf, "%d\n", value);
172exit:
173 return retval;
174}
175
176static ssize_t power_write_file (struct hotplug_slot *slot, const char *buf,
177 size_t count)
178{
179 unsigned long lpower;
180 u8 power;
181 int retval = 0;
182
183 lpower = simple_strtoul (buf, NULL, 10);
184 power = (u8)(lpower & 0xff);
185 dbg ("power = %d\n", power);
186
187 if (!try_module_get(slot->ops->owner)) {
188 retval = -ENODEV;
189 goto exit;
190 }
191 switch (power) {
192 case 0:
193 if (slot->ops->disable_slot)
194 retval = slot->ops->disable_slot(slot);
195 break;
196
197 case 1:
198 if (slot->ops->enable_slot)
199 retval = slot->ops->enable_slot(slot);
200 break;
201
202 default:
203 err ("Illegal value specified for power\n");
204 retval = -EINVAL;
205 }
206 module_put(slot->ops->owner);
207
208exit:
209 if (retval)
210 return retval;
211 return count;
212}
213
214static struct hotplug_slot_attribute hotplug_slot_attr_power = {
215 .attr = {.name = "power", .mode = S_IFREG | S_IRUGO | S_IWUSR},
216 .show = power_read_file,
217 .store = power_write_file
218};
219
220static ssize_t attention_read_file (struct hotplug_slot *slot, char *buf)
221{
222 int retval;
223 u8 value;
224
225 retval = get_attention_status (slot, &value);
226 if (retval)
227 goto exit;
228 retval = sprintf (buf, "%d\n", value);
229
230exit:
231 return retval;
232}
233
234static ssize_t attention_write_file (struct hotplug_slot *slot, const char *buf,
235 size_t count)
236{
237 unsigned long lattention;
238 u8 attention;
239 int retval = 0;
240
241 lattention = simple_strtoul (buf, NULL, 10);
242 attention = (u8)(lattention & 0xff);
243 dbg (" - attention = %d\n", attention);
244
245 if (!try_module_get(slot->ops->owner)) {
246 retval = -ENODEV;
247 goto exit;
248 }
249 if (slot->ops->set_attention_status)
250 retval = slot->ops->set_attention_status(slot, attention);
251 module_put(slot->ops->owner);
252
253exit:
254 if (retval)
255 return retval;
256 return count;
257}
258
259static struct hotplug_slot_attribute hotplug_slot_attr_attention = {
260 .attr = {.name = "attention", .mode = S_IFREG | S_IRUGO | S_IWUSR},
261 .show = attention_read_file,
262 .store = attention_write_file
263};
264
265static ssize_t latch_read_file (struct hotplug_slot *slot, char *buf)
266{
267 int retval;
268 u8 value;
269
270 retval = get_latch_status (slot, &value);
271 if (retval)
272 goto exit;
273 retval = sprintf (buf, "%d\n", value);
274
275exit:
276 return retval;
277}
278
279static struct hotplug_slot_attribute hotplug_slot_attr_latch = {
280 .attr = {.name = "latch", .mode = S_IFREG | S_IRUGO},
281 .show = latch_read_file,
282};
283
284static ssize_t presence_read_file (struct hotplug_slot *slot, char *buf)
285{
286 int retval;
287 u8 value;
288
289 retval = get_adapter_status (slot, &value);
290 if (retval)
291 goto exit;
292 retval = sprintf (buf, "%d\n", value);
293
294exit:
295 return retval;
296}
297
298static struct hotplug_slot_attribute hotplug_slot_attr_presence = {
299 .attr = {.name = "adapter", .mode = S_IFREG | S_IRUGO},
300 .show = presence_read_file,
301};
302
303static ssize_t address_read_file (struct hotplug_slot *slot, char *buf)
304{
305 int retval;
306 u32 address;
307
308 retval = get_address (slot, &address);
309 if (retval)
310 goto exit;
311 retval = sprintf (buf, "%04x:%02x:%02x\n",
312 (address >> 16) & 0xffff,
313 (address >> 8) & 0xff,
314 address & 0xff);
315
316exit:
317 return retval;
318}
319
320static struct hotplug_slot_attribute hotplug_slot_attr_address = {
321 .attr = {.name = "address", .mode = S_IFREG | S_IRUGO},
322 .show = address_read_file,
323};
324
325static char *unknown_speed = "Unknown bus speed";
326
327static ssize_t max_bus_speed_read_file (struct hotplug_slot *slot, char *buf)
328{
329 char *speed_string;
330 int retval;
331 enum pci_bus_speed value;
332
333 retval = get_max_bus_speed (slot, &value);
334 if (retval)
335 goto exit;
336
337 if (value == PCI_SPEED_UNKNOWN)
338 speed_string = unknown_speed;
339 else
340 speed_string = pci_bus_speed_strings[value];
341
342 retval = sprintf (buf, "%s\n", speed_string);
343
344exit:
345 return retval;
346}
347
348static struct hotplug_slot_attribute hotplug_slot_attr_max_bus_speed = {
349 .attr = {.name = "max_bus_speed", .mode = S_IFREG | S_IRUGO},
350 .show = max_bus_speed_read_file,
351};
352
353static ssize_t cur_bus_speed_read_file (struct hotplug_slot *slot, char *buf)
354{
355 char *speed_string;
356 int retval;
357 enum pci_bus_speed value;
358
359 retval = get_cur_bus_speed (slot, &value);
360 if (retval)
361 goto exit;
362
363 if (value == PCI_SPEED_UNKNOWN)
364 speed_string = unknown_speed;
365 else
366 speed_string = pci_bus_speed_strings[value];
367
368 retval = sprintf (buf, "%s\n", speed_string);
369
370exit:
371 return retval;
372}
373
374static struct hotplug_slot_attribute hotplug_slot_attr_cur_bus_speed = {
375 .attr = {.name = "cur_bus_speed", .mode = S_IFREG | S_IRUGO},
376 .show = cur_bus_speed_read_file,
377};
378
379static ssize_t test_write_file (struct hotplug_slot *slot, const char *buf,
380 size_t count)
381{
382 unsigned long ltest;
383 u32 test;
384 int retval = 0;
385
386 ltest = simple_strtoul (buf, NULL, 10);
387 test = (u32)(ltest & 0xffffffff);
388 dbg ("test = %d\n", test);
389
390 if (!try_module_get(slot->ops->owner)) {
391 retval = -ENODEV;
392 goto exit;
393 }
394 if (slot->ops->hardware_test)
395 retval = slot->ops->hardware_test(slot, test);
396 module_put(slot->ops->owner);
397
398exit:
399 if (retval)
400 return retval;
401 return count;
402}
403
404static struct hotplug_slot_attribute hotplug_slot_attr_test = {
405 .attr = {.name = "test", .mode = S_IFREG | S_IRUGO | S_IWUSR},
406 .store = test_write_file
407};
408
409static int has_power_file (struct hotplug_slot *slot)
410{
411 if ((!slot) || (!slot->ops))
412 return -ENODEV;
413 if ((slot->ops->enable_slot) ||
414 (slot->ops->disable_slot) ||
415 (slot->ops->get_power_status))
416 return 0;
417 return -ENOENT;
418}
419
420static int has_attention_file (struct hotplug_slot *slot)
421{
422 if ((!slot) || (!slot->ops))
423 return -ENODEV;
424 if ((slot->ops->set_attention_status) ||
425 (slot->ops->get_attention_status))
426 return 0;
427 return -ENOENT;
428}
429
430static int has_latch_file (struct hotplug_slot *slot)
431{
432 if ((!slot) || (!slot->ops))
433 return -ENODEV;
434 if (slot->ops->get_latch_status)
435 return 0;
436 return -ENOENT;
437}
438
439static int has_adapter_file (struct hotplug_slot *slot)
440{
441 if ((!slot) || (!slot->ops))
442 return -ENODEV;
443 if (slot->ops->get_adapter_status)
444 return 0;
445 return -ENOENT;
446}
447
448static int has_address_file (struct hotplug_slot *slot)
449{
450 if ((!slot) || (!slot->ops))
451 return -ENODEV;
452 if (slot->ops->get_address)
453 return 0;
454 return -ENOENT;
455}
456
457static int has_max_bus_speed_file (struct hotplug_slot *slot)
458{
459 if ((!slot) || (!slot->ops))
460 return -ENODEV;
461 if (slot->ops->get_max_bus_speed)
462 return 0;
463 return -ENOENT;
464}
465
466static int has_cur_bus_speed_file (struct hotplug_slot *slot)
467{
468 if ((!slot) || (!slot->ops))
469 return -ENODEV;
470 if (slot->ops->get_cur_bus_speed)
471 return 0;
472 return -ENOENT;
473}
474
475static int has_test_file (struct hotplug_slot *slot)
476{
477 if ((!slot) || (!slot->ops))
478 return -ENODEV;
479 if (slot->ops->hardware_test)
480 return 0;
481 return -ENOENT;
482}
483
484static int fs_add_slot (struct hotplug_slot *slot)
485{
486 if (has_power_file(slot) == 0)
487 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_power.attr);
488
489 if (has_attention_file(slot) == 0)
490 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
491
492 if (has_latch_file(slot) == 0)
493 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
494
495 if (has_adapter_file(slot) == 0)
496 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
497
498 if (has_address_file(slot) == 0)
499 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_address.attr);
500
501 if (has_max_bus_speed_file(slot) == 0)
502 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
503
504 if (has_cur_bus_speed_file(slot) == 0)
505 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
506
507 if (has_test_file(slot) == 0)
508 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_test.attr);
509
510 return 0;
511}
512
513static void fs_remove_slot (struct hotplug_slot *slot)
514{
515 if (has_power_file(slot) == 0)
516 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr);
517
518 if (has_attention_file(slot) == 0)
519 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
520
521 if (has_latch_file(slot) == 0)
522 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
523
524 if (has_adapter_file(slot) == 0)
525 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
526
527 if (has_address_file(slot) == 0)
528 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_address.attr);
529
530 if (has_max_bus_speed_file(slot) == 0)
531 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
532
533 if (has_cur_bus_speed_file(slot) == 0)
534 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
535
536 if (has_test_file(slot) == 0)
537 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr);
538}
539
540static struct hotplug_slot *get_slot_from_name (const char *name)
541{
542 struct hotplug_slot *slot;
543 struct list_head *tmp;
544
545 list_for_each (tmp, &pci_hotplug_slot_list) {
546 slot = list_entry (tmp, struct hotplug_slot, slot_list);
547 if (strcmp(slot->name, name) == 0)
548 return slot;
549 }
550 return NULL;
551}
552
553/**
554 * pci_hp_register - register a hotplug_slot with the PCI hotplug subsystem
555 * @slot: pointer to the &struct hotplug_slot to register
556 *
557 * Registers a hotplug slot with the pci hotplug subsystem, which will allow
558 * userspace interaction to the slot.
559 *
560 * Returns 0 if successful, anything else for an error.
561 */
562int pci_hp_register (struct hotplug_slot *slot)
563{
564 int result;
565
566 if (slot == NULL)
567 return -ENODEV;
568 if ((slot->info == NULL) || (slot->ops == NULL))
569 return -EINVAL;
570 if (slot->release == NULL) {
571 dbg("Why are you trying to register a hotplug slot"
572 "without a proper release function?\n");
573 return -EINVAL;
574 }
575
576 kobject_set_name(&slot->kobj, "%s", slot->name);
577 kobj_set_kset_s(slot, pci_hotplug_slots_subsys);
578
579 /* this can fail if we have already registered a slot with the same name */
580 if (kobject_register(&slot->kobj)) {
581 err("Unable to register kobject");
582 return -EINVAL;
583 }
584
585 list_add (&slot->slot_list, &pci_hotplug_slot_list);
586
587 result = fs_add_slot (slot);
588 dbg ("Added slot %s to the list\n", slot->name);
589 return result;
590}
591
592/**
593 * pci_hp_deregister - deregister a hotplug_slot with the PCI hotplug subsystem
594 * @slot: pointer to the &struct hotplug_slot to deregister
595 *
596 * The @slot must have been registered with the pci hotplug subsystem
597 * previously with a call to pci_hp_register().
598 *
599 * Returns 0 if successful, anything else for an error.
600 */
601int pci_hp_deregister (struct hotplug_slot *slot)
602{
603 struct hotplug_slot *temp;
604
605 if (slot == NULL)
606 return -ENODEV;
607
608 temp = get_slot_from_name (slot->name);
609 if (temp != slot) {
610 return -ENODEV;
611 }
612 list_del (&slot->slot_list);
613
614 fs_remove_slot (slot);
615 dbg ("Removed slot %s from the list\n", slot->name);
616 kobject_unregister(&slot->kobj);
617 return 0;
618}
619
620/**
621 * pci_hp_change_slot_info - changes the slot's information structure in the core
622 * @slot: pointer to the slot whose info has changed
623 * @info: pointer to the info copy into the slot's info structure
624 *
625 * @slot must have been registered with the pci
626 * hotplug subsystem previously with a call to pci_hp_register().
627 *
628 * Returns 0 if successful, anything else for an error.
629 */
630int pci_hp_change_slot_info (struct hotplug_slot *slot, struct hotplug_slot_info *info)
631{
632 if ((slot == NULL) || (info == NULL))
633 return -ENODEV;
634
635 /*
636 * check all fields in the info structure, and update timestamps
637 * for the files referring to the fields that have now changed.
638 */
639 if ((has_power_file(slot) == 0) &&
640 (slot->info->power_status != info->power_status))
641 sysfs_update_file(&slot->kobj, &hotplug_slot_attr_power.attr);
642
643 if ((has_attention_file(slot) == 0) &&
644 (slot->info->attention_status != info->attention_status))
645 sysfs_update_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
646
647 if ((has_latch_file(slot) == 0) &&
648 (slot->info->latch_status != info->latch_status))
649 sysfs_update_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
650
651 if ((has_adapter_file(slot) == 0) &&
652 (slot->info->adapter_status != info->adapter_status))
653 sysfs_update_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
654
655 if ((has_address_file(slot) == 0) &&
656 (slot->info->address != info->address))
657 sysfs_update_file(&slot->kobj, &hotplug_slot_attr_address.attr);
658
659 if ((has_max_bus_speed_file(slot) == 0) &&
660 (slot->info->max_bus_speed != info->max_bus_speed))
661 sysfs_update_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
662
663 if ((has_cur_bus_speed_file(slot) == 0) &&
664 (slot->info->cur_bus_speed != info->cur_bus_speed))
665 sysfs_update_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
666
667 memcpy (slot->info, info, sizeof (struct hotplug_slot_info));
668
669 return 0;
670}
671
672static int __init pci_hotplug_init (void)
673{
674 int result;
675
676 kset_set_kset_s(&pci_hotplug_slots_subsys, pci_bus_type.subsys);
677 result = subsystem_register(&pci_hotplug_slots_subsys);
678 if (result) {
679 err("Register subsys with error %d\n", result);
680 goto exit;
681 }
682 result = cpci_hotplug_init(debug);
683 if (result) {
684 err ("cpci_hotplug_init with error %d\n", result);
685 goto err_subsys;
686 }
687
688 info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
689 goto exit;
690
691err_subsys:
692 subsystem_unregister(&pci_hotplug_slots_subsys);
693exit:
694 return result;
695}
696
697static void __exit pci_hotplug_exit (void)
698{
699 cpci_hotplug_exit();
700 subsystem_unregister(&pci_hotplug_slots_subsys);
701}
702
703module_init(pci_hotplug_init);
704module_exit(pci_hotplug_exit);
705
706MODULE_AUTHOR(DRIVER_AUTHOR);
707MODULE_DESCRIPTION(DRIVER_DESC);
708MODULE_LICENSE("GPL");
709module_param(debug, bool, 0644);
710MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
711
712EXPORT_SYMBOL_GPL(pci_hotplug_slots_subsys);
713EXPORT_SYMBOL_GPL(pci_hp_register);
714EXPORT_SYMBOL_GPL(pci_hp_deregister);
715EXPORT_SYMBOL_GPL(pci_hp_change_slot_info);
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
new file mode 100644
index 000000000000..f313121d5141
--- /dev/null
+++ b/drivers/pci/hotplug/pciehp.h
@@ -0,0 +1,352 @@
1/*
2 * PCI Express Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
27 *
28 */
29#ifndef _PCIEHP_H
30#define _PCIEHP_H
31
32#include <linux/types.h>
33#include <linux/pci.h>
34#include <linux/delay.h>
35#include <asm/semaphore.h>
36#include <asm/io.h>
37#include <linux/pcieport_if.h>
38#include "pci_hotplug.h"
39
40#define MY_NAME "pciehp"
41
42extern int pciehp_poll_mode;
43extern int pciehp_poll_time;
44extern int pciehp_debug;
45
46/*#define dbg(format, arg...) do { if (pciehp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/
47#define dbg(format, arg...) do { if (pciehp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0)
48#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
49#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
50#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
51
52struct pci_func {
53 struct pci_func *next;
54 u8 bus;
55 u8 device;
56 u8 function;
57 u8 is_a_board;
58 u16 status;
59 u8 configured;
60 u8 switch_save;
61 u8 presence_save;
62 u32 base_length[0x06];
63 u8 base_type[0x06];
64 u16 reserved2;
65 u32 config_space[0x20];
66 struct pci_resource *mem_head;
67 struct pci_resource *p_mem_head;
68 struct pci_resource *io_head;
69 struct pci_resource *bus_head;
70 struct pci_dev* pci_dev;
71};
72
73struct slot {
74 struct slot *next;
75 u8 bus;
76 u8 device;
77 u32 number;
78 u8 is_a_board;
79 u8 configured;
80 u8 state;
81 u8 switch_save;
82 u8 presence_save;
83 u32 capabilities;
84 u16 reserved2;
85 struct timer_list task_event;
86 u8 hp_slot;
87 struct controller *ctrl;
88 struct hpc_ops *hpc_ops;
89 struct hotplug_slot *hotplug_slot;
90 struct list_head slot_list;
91};
92
93struct pci_resource {
94 struct pci_resource * next;
95 u32 base;
96 u32 length;
97};
98
99struct event_info {
100 u32 event_type;
101 u8 hp_slot;
102};
103
104struct controller {
105 struct controller *next;
106 struct semaphore crit_sect; /* critical section semaphore */
107 void *hpc_ctlr_handle; /* HPC controller handle */
108 int num_slots; /* Number of slots on ctlr */
109 int slot_num_inc; /* 1 or -1 */
110 struct pci_resource *mem_head;
111 struct pci_resource *p_mem_head;
112 struct pci_resource *io_head;
113 struct pci_resource *bus_head;
114 struct pci_dev *pci_dev;
115 struct pci_bus *pci_bus;
116 struct event_info event_queue[10];
117 struct slot *slot;
118 struct hpc_ops *hpc_ops;
119 wait_queue_head_t queue; /* sleep & wake process */
120 u8 next_event;
121 u8 seg;
122 u8 bus;
123 u8 device;
124 u8 function;
125 u8 rev;
126 u8 slot_device_offset;
127 u8 add_support;
128 enum pci_bus_speed speed;
129 u32 first_slot; /* First physical slot number */ /* PCIE only has 1 slot */
130 u8 slot_bus; /* Bus where the slots handled by this controller sit */
131 u8 ctrlcap;
132 u16 vendor_id;
133};
134
135struct irq_mapping {
136 u8 barber_pole;
137 u8 valid_INT;
138 u8 interrupt[4];
139};
140
141struct resource_lists {
142 struct pci_resource *mem_head;
143 struct pci_resource *p_mem_head;
144 struct pci_resource *io_head;
145 struct pci_resource *bus_head;
146 struct irq_mapping *irqs;
147};
148
149#define INT_BUTTON_IGNORE 0
150#define INT_PRESENCE_ON 1
151#define INT_PRESENCE_OFF 2
152#define INT_SWITCH_CLOSE 3
153#define INT_SWITCH_OPEN 4
154#define INT_POWER_FAULT 5
155#define INT_POWER_FAULT_CLEAR 6
156#define INT_BUTTON_PRESS 7
157#define INT_BUTTON_RELEASE 8
158#define INT_BUTTON_CANCEL 9
159
160#define STATIC_STATE 0
161#define BLINKINGON_STATE 1
162#define BLINKINGOFF_STATE 2
163#define POWERON_STATE 3
164#define POWEROFF_STATE 4
165
166#define PCI_TO_PCI_BRIDGE_CLASS 0x00060400
167
168/* Error messages */
169#define INTERLOCK_OPEN 0x00000002
170#define ADD_NOT_SUPPORTED 0x00000003
171#define CARD_FUNCTIONING 0x00000005
172#define ADAPTER_NOT_SAME 0x00000006
173#define NO_ADAPTER_PRESENT 0x00000009
174#define NOT_ENOUGH_RESOURCES 0x0000000B
175#define DEVICE_TYPE_NOT_SUPPORTED 0x0000000C
176#define WRONG_BUS_FREQUENCY 0x0000000D
177#define POWER_FAILURE 0x0000000E
178
179#define REMOVE_NOT_SUPPORTED 0x00000003
180
181#define DISABLE_CARD 1
182
183/* Field definitions in Slot Capabilities Register */
184#define ATTN_BUTTN_PRSN 0x00000001
185#define PWR_CTRL_PRSN 0x00000002
186#define MRL_SENS_PRSN 0x00000004
187#define ATTN_LED_PRSN 0x00000008
188#define PWR_LED_PRSN 0x00000010
189#define HP_SUPR_RM_SUP 0x00000020
190
191#define ATTN_BUTTN(cap) (cap & ATTN_BUTTN_PRSN)
192#define POWER_CTRL(cap) (cap & PWR_CTRL_PRSN)
193#define MRL_SENS(cap) (cap & MRL_SENS_PRSN)
194#define ATTN_LED(cap) (cap & ATTN_LED_PRSN)
195#define PWR_LED(cap) (cap & PWR_LED_PRSN)
196#define HP_SUPR_RM(cap) (cap & HP_SUPR_RM_SUP)
197
198/*
199 * error Messages
200 */
201#define msg_initialization_err "Initialization failure, error=%d\n"
202#define msg_HPC_rev_error "Unsupported revision of the PCI hot plug controller found.\n"
203#define msg_HPC_non_pcie "The PCI hot plug controller is not supported by this driver.\n"
204#define msg_HPC_not_supported "This system is not supported by this version of pciephd module. Upgrade to a newer version of pciehpd\n"
205#define msg_unable_to_save "Unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n"
206#define msg_button_on "PCI slot #%d - powering on due to button press.\n"
207#define msg_button_off "PCI slot #%d - powering off due to button press.\n"
208#define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n"
209#define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n"
210
211/* controller functions */
212extern int pciehprm_find_available_resources (struct controller *ctrl);
213extern int pciehp_event_start_thread (void);
214extern void pciehp_event_stop_thread (void);
215extern struct pci_func *pciehp_slot_create (unsigned char busnumber);
216extern struct pci_func *pciehp_slot_find (unsigned char bus, unsigned char device, unsigned char index);
217extern int pciehp_enable_slot (struct slot *slot);
218extern int pciehp_disable_slot (struct slot *slot);
219
220extern u8 pciehp_handle_attention_button (u8 hp_slot, void *inst_id);
221extern u8 pciehp_handle_switch_change (u8 hp_slot, void *inst_id);
222extern u8 pciehp_handle_presence_change (u8 hp_slot, void *inst_id);
223extern u8 pciehp_handle_power_fault (u8 hp_slot, void *inst_id);
224/* extern void long_delay (int delay); */
225
226/* resource functions */
227extern int pciehp_resource_sort_and_combine (struct pci_resource **head);
228
229/* pci functions */
230extern int pciehp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);
231/*extern int pciehp_get_bus_dev (struct controller *ctrl, u8 *bus_num, u8 *dev_num, struct slot *slot);*/
232extern int pciehp_save_config (struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num);
233extern int pciehp_save_used_resources (struct controller *ctrl, struct pci_func * func, int flag);
234extern int pciehp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot);
235extern void pciehp_destroy_board_resources (struct pci_func * func);
236extern int pciehp_return_board_resources (struct pci_func * func, struct resource_lists * resources);
237extern void pciehp_destroy_resource_list (struct resource_lists * resources);
238extern int pciehp_configure_device (struct controller* ctrl, struct pci_func* func);
239extern int pciehp_unconfigure_device (struct pci_func* func);
240
241
242/* Global variables */
243extern struct controller *pciehp_ctrl_list;
244extern struct pci_func *pciehp_slot_list[256];
245
246/* Inline functions */
247
248static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device)
249{
250 struct slot *p_slot, *tmp_slot = NULL;
251
252 p_slot = ctrl->slot;
253
254 dbg("p_slot = %p\n", p_slot);
255
256 while (p_slot && (p_slot->device != device)) {
257 tmp_slot = p_slot;
258 p_slot = p_slot->next;
259 dbg("In while loop, p_slot = %p\n", p_slot);
260 }
261 if (p_slot == NULL) {
262 err("ERROR: pciehp_find_slot device=0x%x\n", device);
263 p_slot = tmp_slot;
264 }
265
266 return p_slot;
267}
268
269static inline int wait_for_ctrl_irq(struct controller *ctrl)
270{
271 int retval = 0;
272
273 DECLARE_WAITQUEUE(wait, current);
274
275 dbg("%s : start\n", __FUNCTION__);
276 add_wait_queue(&ctrl->queue, &wait);
277 if (!pciehp_poll_mode)
278 /* Sleep for up to 1 second */
279 msleep_interruptible(1000);
280 else
281 msleep_interruptible(2500);
282
283 remove_wait_queue(&ctrl->queue, &wait);
284 if (signal_pending(current))
285 retval = -EINTR;
286
287 dbg("%s : end\n", __FUNCTION__);
288 return retval;
289}
290
291/* Puts node back in the resource list pointed to by head */
292static inline void return_resource(struct pci_resource **head, struct pci_resource *node)
293{
294 if (!node || !head)
295 return;
296 node->next = *head;
297 *head = node;
298}
299
300#define SLOT_NAME_SIZE 10
301
302static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
303{
304 snprintf(buffer, buffer_size, "%d", slot->number);
305}
306
307enum php_ctlr_type {
308 PCI,
309 ISA,
310 ACPI
311};
312
313typedef u8(*php_intr_callback_t) (unsigned int change_id, void *instance_id);
314
315int pcie_init(struct controller *ctrl, struct pcie_device *dev,
316 php_intr_callback_t attention_button_callback,
317 php_intr_callback_t switch_change_callback,
318 php_intr_callback_t presence_change_callback,
319 php_intr_callback_t power_fault_callback);
320
321
322/* This has no meaning for PCI Express, as there is only 1 slot per port */
323int pcie_get_ctlr_slot_config(struct controller *ctrl,
324 int *num_ctlr_slots,
325 int *first_device_num,
326 int *physical_slot_num,
327 u8 *ctrlcap);
328
329struct hpc_ops {
330 int (*power_on_slot) (struct slot *slot);
331 int (*power_off_slot) (struct slot *slot);
332 int (*get_power_status) (struct slot *slot, u8 *status);
333 int (*get_attention_status) (struct slot *slot, u8 *status);
334 int (*set_attention_status) (struct slot *slot, u8 status);
335 int (*get_latch_status) (struct slot *slot, u8 *status);
336 int (*get_adapter_status) (struct slot *slot, u8 *status);
337
338 int (*get_max_bus_speed) (struct slot *slot, enum pci_bus_speed *speed);
339 int (*get_cur_bus_speed) (struct slot *slot, enum pci_bus_speed *speed);
340
341 int (*get_max_lnk_width) (struct slot *slot, enum pcie_link_width *value);
342 int (*get_cur_lnk_width) (struct slot *slot, enum pcie_link_width *value);
343
344 int (*query_power_fault) (struct slot *slot);
345 void (*green_led_on) (struct slot *slot);
346 void (*green_led_off) (struct slot *slot);
347 void (*green_led_blink) (struct slot *slot);
348 void (*release_ctlr) (struct controller *ctrl);
349 int (*check_lnk_status) (struct controller *ctrl);
350};
351
352#endif /* _PCIEHP_H */
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
new file mode 100644
index 000000000000..8a5b2b51bde4
--- /dev/null
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -0,0 +1,662 @@
1/*
2 * PCI Express Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/moduleparam.h>
33#include <linux/kernel.h>
34#include <linux/types.h>
35#include <linux/proc_fs.h>
36#include <linux/slab.h>
37#include <linux/workqueue.h>
38#include <linux/pci.h>
39#include <linux/init.h>
40#include <asm/uaccess.h>
41#include "pciehp.h"
42#include "pciehprm.h"
43#include <linux/interrupt.h>
44
45/* Global variables */
46int pciehp_debug;
47int pciehp_poll_mode;
48int pciehp_poll_time;
49struct controller *pciehp_ctrl_list;
50struct pci_func *pciehp_slot_list[256];
51
52#define DRIVER_VERSION "0.4"
53#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
54#define DRIVER_DESC "PCI Express Hot Plug Controller Driver"
55
56MODULE_AUTHOR(DRIVER_AUTHOR);
57MODULE_DESCRIPTION(DRIVER_DESC);
58MODULE_LICENSE("GPL");
59
60module_param(pciehp_debug, bool, 0644);
61module_param(pciehp_poll_mode, bool, 0644);
62module_param(pciehp_poll_time, int, 0644);
63MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not");
64MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not");
65MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds");
66
67#define PCIE_MODULE_NAME "pciehp"
68
69static int pcie_start_thread (void);
70static int set_attention_status (struct hotplug_slot *slot, u8 value);
71static int enable_slot (struct hotplug_slot *slot);
72static int disable_slot (struct hotplug_slot *slot);
73static int get_power_status (struct hotplug_slot *slot, u8 *value);
74static int get_attention_status (struct hotplug_slot *slot, u8 *value);
75static int get_latch_status (struct hotplug_slot *slot, u8 *value);
76static int get_adapter_status (struct hotplug_slot *slot, u8 *value);
77static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
78static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
79
80static struct hotplug_slot_ops pciehp_hotplug_slot_ops = {
81 .owner = THIS_MODULE,
82 .set_attention_status = set_attention_status,
83 .enable_slot = enable_slot,
84 .disable_slot = disable_slot,
85 .get_power_status = get_power_status,
86 .get_attention_status = get_attention_status,
87 .get_latch_status = get_latch_status,
88 .get_adapter_status = get_adapter_status,
89 .get_max_bus_speed = get_max_bus_speed,
90 .get_cur_bus_speed = get_cur_bus_speed,
91};
92
93static int init_slots(struct controller *ctrl)
94{
95 struct slot *new_slot;
96 u8 number_of_slots;
97 u8 slot_device;
98 u32 slot_number;
99 int result = -ENOMEM;
100
101 dbg("%s\n",__FUNCTION__);
102
103 number_of_slots = ctrl->num_slots;
104 slot_device = ctrl->slot_device_offset;
105 slot_number = ctrl->first_slot;
106
107 while (number_of_slots) {
108 new_slot = kmalloc(sizeof(*new_slot), GFP_KERNEL);
109 if (!new_slot)
110 goto error;
111
112 memset(new_slot, 0, sizeof(struct slot));
113 new_slot->hotplug_slot =
114 kmalloc(sizeof(*(new_slot->hotplug_slot)),
115 GFP_KERNEL);
116 if (!new_slot->hotplug_slot)
117 goto error_slot;
118 memset(new_slot->hotplug_slot, 0, sizeof(struct hotplug_slot));
119
120 new_slot->hotplug_slot->info =
121 kmalloc(sizeof(*(new_slot->hotplug_slot->info)),
122 GFP_KERNEL);
123 if (!new_slot->hotplug_slot->info)
124 goto error_hpslot;
125 memset(new_slot->hotplug_slot->info, 0,
126 sizeof(struct hotplug_slot_info));
127 new_slot->hotplug_slot->name = kmalloc(SLOT_NAME_SIZE,
128 GFP_KERNEL);
129 if (!new_slot->hotplug_slot->name)
130 goto error_info;
131
132 new_slot->ctrl = ctrl;
133 new_slot->bus = ctrl->slot_bus;
134 new_slot->device = slot_device;
135 new_slot->hpc_ops = ctrl->hpc_ops;
136
137 new_slot->number = ctrl->first_slot;
138 new_slot->hp_slot = slot_device - ctrl->slot_device_offset;
139
140 /* register this slot with the hotplug pci core */
141 new_slot->hotplug_slot->private = new_slot;
142 make_slot_name (new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot);
143 new_slot->hotplug_slot->ops = &pciehp_hotplug_slot_ops;
144
145 new_slot->hpc_ops->get_power_status(new_slot, &(new_slot->hotplug_slot->info->power_status));
146 new_slot->hpc_ops->get_attention_status(new_slot, &(new_slot->hotplug_slot->info->attention_status));
147 new_slot->hpc_ops->get_latch_status(new_slot, &(new_slot->hotplug_slot->info->latch_status));
148 new_slot->hpc_ops->get_adapter_status(new_slot, &(new_slot->hotplug_slot->info->adapter_status));
149
150 dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x slot_device_offset=%x\n",
151 new_slot->bus, new_slot->device, new_slot->hp_slot, new_slot->number, ctrl->slot_device_offset);
152 result = pci_hp_register (new_slot->hotplug_slot);
153 if (result) {
154 err ("pci_hp_register failed with error %d\n", result);
155 goto error_name;
156 }
157
158 new_slot->next = ctrl->slot;
159 ctrl->slot = new_slot;
160
161 number_of_slots--;
162 slot_device++;
163 slot_number += ctrl->slot_num_inc;
164 }
165
166 return 0;
167
168error_name:
169 kfree(new_slot->hotplug_slot->name);
170error_info:
171 kfree(new_slot->hotplug_slot->info);
172error_hpslot:
173 kfree(new_slot->hotplug_slot);
174error_slot:
175 kfree(new_slot);
176error:
177 return result;
178}
179
180
181static int cleanup_slots (struct controller * ctrl)
182{
183 struct slot *old_slot, *next_slot;
184
185 old_slot = ctrl->slot;
186 ctrl->slot = NULL;
187
188 while (old_slot) {
189 next_slot = old_slot->next;
190 pci_hp_deregister (old_slot->hotplug_slot);
191 kfree(old_slot->hotplug_slot->info);
192 kfree(old_slot->hotplug_slot->name);
193 kfree(old_slot->hotplug_slot);
194 kfree(old_slot);
195 old_slot = next_slot;
196 }
197
198
199 return(0);
200}
201
202static int get_ctlr_slot_config(struct controller *ctrl)
203{
204 int num_ctlr_slots; /* Not needed; PCI Express has 1 slot per port*/
205 int first_device_num; /* Not needed */
206 int physical_slot_num;
207 u8 ctrlcap;
208 int rc;
209
210 rc = pcie_get_ctlr_slot_config(ctrl, &num_ctlr_slots, &first_device_num, &physical_slot_num, &ctrlcap);
211 if (rc) {
212 err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n", __FUNCTION__, ctrl->bus, ctrl->device);
213 return (-1);
214 }
215
216 ctrl->num_slots = num_ctlr_slots; /* PCI Express has 1 slot per port */
217 ctrl->slot_device_offset = first_device_num;
218 ctrl->first_slot = physical_slot_num;
219 ctrl->ctrlcap = ctrlcap;
220
221 dbg("%s: bus(0x%x) num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) ctrlcap(%x) for b:d (%x:%x)\n",
222 __FUNCTION__, ctrl->slot_bus, num_ctlr_slots, first_device_num, physical_slot_num, ctrlcap,
223 ctrl->bus, ctrl->device);
224
225 return (0);
226}
227
228
229/*
230 * set_attention_status - Turns the Amber LED for a slot on, off or blink
231 */
232static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
233{
234 struct slot *slot = hotplug_slot->private;
235
236 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
237
238 hotplug_slot->info->attention_status = status;
239
240 if (ATTN_LED(slot->ctrl->ctrlcap))
241 slot->hpc_ops->set_attention_status(slot, status);
242
243 return 0;
244}
245
246
247static int enable_slot(struct hotplug_slot *hotplug_slot)
248{
249 struct slot *slot = hotplug_slot->private;
250
251 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
252
253 return pciehp_enable_slot(slot);
254}
255
256
257static int disable_slot(struct hotplug_slot *hotplug_slot)
258{
259 struct slot *slot = hotplug_slot->private;
260
261 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
262
263 return pciehp_disable_slot(slot);
264}
265
266static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
267{
268 struct slot *slot = hotplug_slot->private;
269 int retval;
270
271 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
272
273 retval = slot->hpc_ops->get_power_status(slot, value);
274 if (retval < 0)
275 *value = hotplug_slot->info->power_status;
276
277 return 0;
278}
279
280static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
281{
282 struct slot *slot = hotplug_slot->private;
283 int retval;
284
285 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
286
287 retval = slot->hpc_ops->get_attention_status(slot, value);
288 if (retval < 0)
289 *value = hotplug_slot->info->attention_status;
290
291 return 0;
292}
293
294static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
295{
296 struct slot *slot = hotplug_slot->private;
297 int retval;
298
299 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
300
301 retval = slot->hpc_ops->get_latch_status(slot, value);
302 if (retval < 0)
303 *value = hotplug_slot->info->latch_status;
304
305 return 0;
306}
307
308static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
309{
310 struct slot *slot = hotplug_slot->private;
311 int retval;
312
313 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
314
315 retval = slot->hpc_ops->get_adapter_status(slot, value);
316 if (retval < 0)
317 *value = hotplug_slot->info->adapter_status;
318
319 return 0;
320}
321
322static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
323{
324 struct slot *slot = hotplug_slot->private;
325 int retval;
326
327 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
328
329 retval = slot->hpc_ops->get_max_bus_speed(slot, value);
330 if (retval < 0)
331 *value = PCI_SPEED_UNKNOWN;
332
333 return 0;
334}
335
336static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
337{
338 struct slot *slot = hotplug_slot->private;
339 int retval;
340
341 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
342
343 retval = slot->hpc_ops->get_cur_bus_speed(slot, value);
344 if (retval < 0)
345 *value = PCI_SPEED_UNKNOWN;
346
347 return 0;
348}
349
350static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_id *id)
351{
352 int rc;
353 struct controller *ctrl;
354 struct slot *t_slot;
355 int first_device_num = 0 ; /* first PCI device number supported by this PCIE */
356 int num_ctlr_slots; /* number of slots supported by this HPC */
357 u8 value;
358 struct pci_dev *pdev;
359
360 dbg("%s: Called by hp_drv\n", __FUNCTION__);
361 ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL);
362 if (!ctrl) {
363 err("%s : out of memory\n", __FUNCTION__);
364 goto err_out_none;
365 }
366 memset(ctrl, 0, sizeof(struct controller));
367
368 dbg("%s: DRV_thread pid = %d\n", __FUNCTION__, current->pid);
369
370 pdev = dev->port;
371
372 rc = pcie_init(ctrl, dev,
373 (php_intr_callback_t) pciehp_handle_attention_button,
374 (php_intr_callback_t) pciehp_handle_switch_change,
375 (php_intr_callback_t) pciehp_handle_presence_change,
376 (php_intr_callback_t) pciehp_handle_power_fault);
377 if (rc) {
378 dbg("%s: controller initialization failed\n", PCIE_MODULE_NAME);
379 goto err_out_free_ctrl;
380 }
381
382 ctrl->pci_dev = pdev;
383
384 pci_set_drvdata(pdev, ctrl);
385
386 ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL);
387 if (!ctrl->pci_bus) {
388 err("%s: out of memory\n", __FUNCTION__);
389 rc = -ENOMEM;
390 goto err_out_unmap_mmio_region;
391 }
392 dbg("%s: ctrl->pci_bus %p\n", __FUNCTION__, ctrl->pci_bus);
393 memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus));
394 ctrl->bus = pdev->bus->number; /* ctrl bus */
395 ctrl->slot_bus = pdev->subordinate->number; /* bus controlled by this HPC */
396
397 ctrl->device = PCI_SLOT(pdev->devfn);
398 ctrl->function = PCI_FUNC(pdev->devfn);
399 dbg("%s: ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", __FUNCTION__,
400 ctrl->bus, ctrl->device, ctrl->function, pdev->irq);
401
402 /*
403 * Save configuration headers for this and subordinate PCI buses
404 */
405
406 rc = get_ctlr_slot_config(ctrl);
407 if (rc) {
408 err(msg_initialization_err, rc);
409 goto err_out_free_ctrl_bus;
410 }
411 first_device_num = ctrl->slot_device_offset;
412 num_ctlr_slots = ctrl->num_slots;
413
414 /* Store PCI Config Space for all devices on this bus */
415 dbg("%s: Before calling pciehp_save_config, ctrl->bus %x,ctrl->slot_bus %x\n",
416 __FUNCTION__,ctrl->bus, ctrl->slot_bus);
417 rc = pciehp_save_config(ctrl, ctrl->slot_bus, num_ctlr_slots, first_device_num);
418 if (rc) {
419 err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
420 goto err_out_free_ctrl_bus;
421 }
422
423 /* Get IO, memory, and IRQ resources for new devices */
424 rc = pciehprm_find_available_resources(ctrl);
425 ctrl->add_support = !rc;
426
427 if (rc) {
428 dbg("pciehprm_find_available_resources = %#x\n", rc);
429 err("unable to locate PCI configuration resources for hot plug add.\n");
430 goto err_out_free_ctrl_bus;
431 }
432
433 /* Setup the slot information structures */
434 rc = init_slots(ctrl);
435 if (rc) {
436 err(msg_initialization_err, 6);
437 goto err_out_free_ctrl_slot;
438 }
439
440 t_slot = pciehp_find_slot(ctrl, first_device_num);
441 dbg("%s: t_slot %p\n", __FUNCTION__, t_slot);
442
443 /* Finish setting up the hot plug ctrl device */
444 ctrl->next_event = 0;
445
446 if (!pciehp_ctrl_list) {
447 pciehp_ctrl_list = ctrl;
448 ctrl->next = NULL;
449 } else {
450 ctrl->next = pciehp_ctrl_list;
451 pciehp_ctrl_list = ctrl;
452 }
453
454 /* Wait for exclusive access to hardware */
455 down(&ctrl->crit_sect);
456
457 t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */
458 dbg("%s: adpater value %x\n", __FUNCTION__, value);
459
460 if ((POWER_CTRL(ctrl->ctrlcap)) && !value) {
461 rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/
462 if (rc) {
463 /* Done with exclusive hardware access */
464 up(&ctrl->crit_sect);
465 goto err_out_free_ctrl_slot;
466 } else
467 /* Wait for the command to complete */
468 wait_for_ctrl_irq (ctrl);
469 }
470
471 /* Done with exclusive hardware access */
472 up(&ctrl->crit_sect);
473
474 return 0;
475
476err_out_free_ctrl_slot:
477 cleanup_slots(ctrl);
478err_out_free_ctrl_bus:
479 kfree(ctrl->pci_bus);
480err_out_unmap_mmio_region:
481 ctrl->hpc_ops->release_ctlr(ctrl);
482err_out_free_ctrl:
483 kfree(ctrl);
484err_out_none:
485 return -ENODEV;
486}
487
488
489static int pcie_start_thread(void)
490{
491 int loop;
492 int retval = 0;
493
494 dbg("Initialize + Start the notification/polling mechanism \n");
495
496 retval = pciehp_event_start_thread();
497 if (retval) {
498 dbg("pciehp_event_start_thread() failed\n");
499 return retval;
500 }
501
502 dbg("Initialize slot lists\n");
503 /* One slot list for each bus in the system */
504 for (loop = 0; loop < 256; loop++) {
505 pciehp_slot_list[loop] = NULL;
506 }
507
508 return retval;
509}
510
511static inline void __exit
512free_pciehp_res(struct pci_resource *res)
513{
514 struct pci_resource *tres;
515
516 while (res) {
517 tres = res;
518 res = res->next;
519 kfree(tres);
520 }
521}
522
523static void __exit unload_pciehpd(void)
524{
525 struct pci_func *next;
526 struct pci_func *TempSlot;
527 int loop;
528 struct controller *ctrl;
529 struct controller *tctrl;
530
531 ctrl = pciehp_ctrl_list;
532
533 while (ctrl) {
534 cleanup_slots(ctrl);
535
536 free_pciehp_res(ctrl->io_head);
537 free_pciehp_res(ctrl->mem_head);
538 free_pciehp_res(ctrl->p_mem_head);
539 free_pciehp_res(ctrl->bus_head);
540
541 kfree (ctrl->pci_bus);
542
543 ctrl->hpc_ops->release_ctlr(ctrl);
544
545 tctrl = ctrl;
546 ctrl = ctrl->next;
547
548 kfree(tctrl);
549 }
550
551 for (loop = 0; loop < 256; loop++) {
552 next = pciehp_slot_list[loop];
553 while (next != NULL) {
554 free_pciehp_res(next->io_head);
555 free_pciehp_res(next->mem_head);
556 free_pciehp_res(next->p_mem_head);
557 free_pciehp_res(next->bus_head);
558
559 TempSlot = next;
560 next = next->next;
561 kfree(TempSlot);
562 }
563 }
564
565 /* Stop the notification mechanism */
566 pciehp_event_stop_thread();
567
568}
569
570int hpdriver_context = 0;
571
572static void pciehp_remove (struct pcie_device *device)
573{
574 printk("%s ENTRY\n", __FUNCTION__);
575 printk("%s -> Call free_irq for irq = %d\n",
576 __FUNCTION__, device->irq);
577 free_irq(device->irq, &hpdriver_context);
578}
579
580#ifdef CONFIG_PM
581static int pciehp_suspend (struct pcie_device *dev, u32 state)
582{
583 printk("%s ENTRY\n", __FUNCTION__);
584 return 0;
585}
586
587static int pciehp_resume (struct pcie_device *dev)
588{
589 printk("%s ENTRY\n", __FUNCTION__);
590 return 0;
591}
592#endif
593
594static struct pcie_port_service_id port_pci_ids[] = { {
595 .vendor = PCI_ANY_ID,
596 .device = PCI_ANY_ID,
597 .port_type = PCIE_RC_PORT,
598 .service_type = PCIE_PORT_SERVICE_HP,
599 .driver_data = 0,
600 }, { /* end: all zeroes */ }
601};
602static const char device_name[] = "hpdriver";
603
604static struct pcie_port_service_driver hpdriver_portdrv = {
605 .name = (char *)device_name,
606 .id_table = &port_pci_ids[0],
607
608 .probe = pciehp_probe,
609 .remove = pciehp_remove,
610
611#ifdef CONFIG_PM
612 .suspend = pciehp_suspend,
613 .resume = pciehp_resume,
614#endif /* PM */
615};
616
617static int __init pcied_init(void)
618{
619 int retval = 0;
620
621#ifdef CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE
622 pciehp_poll_mode = 1;
623#endif
624
625 retval = pcie_start_thread();
626 if (retval)
627 goto error_hpc_init;
628
629 retval = pciehprm_init(PCI);
630 if (!retval) {
631 retval = pcie_port_service_register(&hpdriver_portdrv);
632 dbg("pcie_port_service_register = %d\n", retval);
633 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
634 if (retval)
635 dbg("%s: Failure to register service\n", __FUNCTION__);
636 }
637
638error_hpc_init:
639 if (retval) {
640 pciehprm_cleanup();
641 pciehp_event_stop_thread();
642 } else
643 pciehprm_print_pirt();
644
645 return retval;
646}
647
648static void __exit pcied_cleanup(void)
649{
650 dbg("unload_pciehpd()\n");
651 unload_pciehpd();
652
653 pciehprm_cleanup();
654
655 dbg("pcie_port_service_unregister\n");
656 pcie_port_service_unregister(&hpdriver_portdrv);
657
658 info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
659}
660
661module_init(pcied_init);
662module_exit(pcied_cleanup);
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
new file mode 100644
index 000000000000..0dbcf04aa35e
--- /dev/null
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -0,0 +1,2706 @@
1/*
2 * PCI Express Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/types.h>
34#include <linux/slab.h>
35#include <linux/workqueue.h>
36#include <linux/interrupt.h>
37#include <linux/delay.h>
38#include <linux/wait.h>
39#include <linux/smp_lock.h>
40#include <linux/pci.h>
41#include "../pci.h"
42#include "pciehp.h"
43#include "pciehprm.h"
44
45static u32 configure_new_device(struct controller *ctrl, struct pci_func *func,
46 u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
47static int configure_new_function( struct controller *ctrl, struct pci_func *func,
48 u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
49static void interrupt_event_handler(struct controller *ctrl);
50
51static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */
52static struct semaphore event_exit; /* guard ensure thread has exited before calling it quits */
53static int event_finished;
54static unsigned long pushbutton_pending; /* = 0 */
55static unsigned long surprise_rm_pending; /* = 0 */
56
57u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id)
58{
59 struct controller *ctrl = (struct controller *) inst_id;
60 struct slot *p_slot;
61 u8 rc = 0;
62 u8 getstatus;
63 struct pci_func *func;
64 struct event_info *taskInfo;
65
66 /* Attention Button Change */
67 dbg("pciehp: Attention button interrupt received.\n");
68
69 func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
70
71 /* This is the structure that tells the worker thread what to do */
72 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
73 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
74
75 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
76 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
77
78 ctrl->next_event = (ctrl->next_event + 1) % 10;
79 taskInfo->hp_slot = hp_slot;
80
81 rc++;
82
83 /*
84 * Button pressed - See if need to TAKE ACTION!!!
85 */
86 info("Button pressed on Slot(%d)\n", ctrl->first_slot + hp_slot);
87 taskInfo->event_type = INT_BUTTON_PRESS;
88
89 if ((p_slot->state == BLINKINGON_STATE)
90 || (p_slot->state == BLINKINGOFF_STATE)) {
91 /* Cancel if we are still blinking; this means that we press the
92 * attention again before the 5 sec. limit expires to cancel hot-add
93 * or hot-remove
94 */
95 taskInfo->event_type = INT_BUTTON_CANCEL;
96 info("Button cancel on Slot(%d)\n", ctrl->first_slot + hp_slot);
97 } else if ((p_slot->state == POWERON_STATE)
98 || (p_slot->state == POWEROFF_STATE)) {
99 /* Ignore if the slot is on power-on or power-off state; this
100 * means that the previous attention button action to hot-add or
101 * hot-remove is undergoing
102 */
103 taskInfo->event_type = INT_BUTTON_IGNORE;
104 info("Button ignore on Slot(%d)\n", ctrl->first_slot + hp_slot);
105 }
106
107 if (rc)
108 up(&event_semaphore); /* signal event thread that new event is posted */
109
110 return 0;
111
112}
113
114u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id)
115{
116 struct controller *ctrl = (struct controller *) inst_id;
117 struct slot *p_slot;
118 u8 rc = 0;
119 u8 getstatus;
120 struct pci_func *func;
121 struct event_info *taskInfo;
122
123 /* Switch Change */
124 dbg("pciehp: Switch interrupt received.\n");
125
126 func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
127
128 /* This is the structure that tells the worker thread
129 * what to do
130 */
131 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
132 ctrl->next_event = (ctrl->next_event + 1) % 10;
133 taskInfo->hp_slot = hp_slot;
134
135 rc++;
136 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
137 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
138 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
139
140 if (getstatus) {
141 /*
142 * Switch opened
143 */
144 info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot);
145 func->switch_save = 0;
146 taskInfo->event_type = INT_SWITCH_OPEN;
147 } else {
148 /*
149 * Switch closed
150 */
151 info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot);
152 func->switch_save = 0x10;
153 taskInfo->event_type = INT_SWITCH_CLOSE;
154 }
155
156 if (rc)
157 up(&event_semaphore); /* signal event thread that new event is posted */
158
159 return rc;
160}
161
162u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id)
163{
164 struct controller *ctrl = (struct controller *) inst_id;
165 struct slot *p_slot;
166 u8 rc = 0;
167 struct pci_func *func;
168 struct event_info *taskInfo;
169
170 /* Presence Change */
171 dbg("pciehp: Presence/Notify input change.\n");
172
173 func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
174
175 /* This is the structure that tells the worker thread
176 * what to do
177 */
178 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
179 ctrl->next_event = (ctrl->next_event + 1) % 10;
180 taskInfo->hp_slot = hp_slot;
181
182 rc++;
183 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
184
185 /* Switch is open, assume a presence change
186 * Save the presence state
187 */
188 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
189 if (func->presence_save) {
190 /*
191 * Card Present
192 */
193 info("Card present on Slot(%d)\n", ctrl->first_slot + hp_slot);
194 taskInfo->event_type = INT_PRESENCE_ON;
195 } else {
196 /*
197 * Not Present
198 */
199 info("Card not present on Slot(%d)\n", ctrl->first_slot + hp_slot);
200 taskInfo->event_type = INT_PRESENCE_OFF;
201 }
202
203 if (rc)
204 up(&event_semaphore); /* signal event thread that new event is posted */
205
206 return rc;
207}
208
209u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
210{
211 struct controller *ctrl = (struct controller *) inst_id;
212 struct slot *p_slot;
213 u8 rc = 0;
214 struct pci_func *func;
215 struct event_info *taskInfo;
216
217 /* power fault */
218 dbg("pciehp: Power fault interrupt received.\n");
219
220 func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
221
222 /* this is the structure that tells the worker thread
223 * what to do
224 */
225 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
226 ctrl->next_event = (ctrl->next_event + 1) % 10;
227 taskInfo->hp_slot = hp_slot;
228
229 rc++;
230 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
231
232 if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) {
233 /*
234 * power fault Cleared
235 */
236 info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot);
237 func->status = 0x00;
238 taskInfo->event_type = INT_POWER_FAULT_CLEAR;
239 } else {
240 /*
241 * power fault
242 */
243 info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot);
244 taskInfo->event_type = INT_POWER_FAULT;
245 /* set power fault status for this board */
246 func->status = 0xFF;
247 info("power fault bit %x set\n", hp_slot);
248 }
249 if (rc)
250 up(&event_semaphore); /* signal event thread that new event is posted */
251
252 return rc;
253}
254
255
256/**
257 * sort_by_size: sort nodes by their length, smallest first.
258 *
259 * @head: list to sort
260 */
261static int sort_by_size(struct pci_resource **head)
262{
263 struct pci_resource *current_res;
264 struct pci_resource *next_res;
265 int out_of_order = 1;
266
267 if (!(*head))
268 return 1;
269
270 if (!((*head)->next))
271 return 0;
272
273 while (out_of_order) {
274 out_of_order = 0;
275
276 /* Special case for swapping list head */
277 if (((*head)->next) &&
278 ((*head)->length > (*head)->next->length)) {
279 out_of_order++;
280 current_res = *head;
281 *head = (*head)->next;
282 current_res->next = (*head)->next;
283 (*head)->next = current_res;
284 }
285
286 current_res = *head;
287
288 while (current_res->next && current_res->next->next) {
289 if (current_res->next->length > current_res->next->next->length) {
290 out_of_order++;
291 next_res = current_res->next;
292 current_res->next = current_res->next->next;
293 current_res = current_res->next;
294 next_res->next = current_res->next;
295 current_res->next = next_res;
296 } else
297 current_res = current_res->next;
298 }
299 } /* End of out_of_order loop */
300
301 return 0;
302}
303
304
305/*
306 * sort_by_max_size
307 *
308 * Sorts nodes on the list by their length.
309 * Largest first.
310 *
311 */
312static int sort_by_max_size(struct pci_resource **head)
313{
314 struct pci_resource *current_res;
315 struct pci_resource *next_res;
316 int out_of_order = 1;
317
318 if (!(*head))
319 return 1;
320
321 if (!((*head)->next))
322 return 0;
323
324 while (out_of_order) {
325 out_of_order = 0;
326
327 /* Special case for swapping list head */
328 if (((*head)->next) &&
329 ((*head)->length < (*head)->next->length)) {
330 out_of_order++;
331 current_res = *head;
332 *head = (*head)->next;
333 current_res->next = (*head)->next;
334 (*head)->next = current_res;
335 }
336
337 current_res = *head;
338
339 while (current_res->next && current_res->next->next) {
340 if (current_res->next->length < current_res->next->next->length) {
341 out_of_order++;
342 next_res = current_res->next;
343 current_res->next = current_res->next->next;
344 current_res = current_res->next;
345 next_res->next = current_res->next;
346 current_res->next = next_res;
347 } else
348 current_res = current_res->next;
349 }
350 } /* End of out_of_order loop */
351
352 return 0;
353}
354
355
356/**
357 * do_pre_bridge_resource_split: return one unused resource node
358 * @head: list to scan
359 *
360 */
361static struct pci_resource *
362do_pre_bridge_resource_split(struct pci_resource **head,
363 struct pci_resource **orig_head, u32 alignment)
364{
365 struct pci_resource *prevnode = NULL;
366 struct pci_resource *node;
367 struct pci_resource *split_node;
368 u32 rc;
369 u32 temp_dword;
370 dbg("do_pre_bridge_resource_split\n");
371
372 if (!(*head) || !(*orig_head))
373 return NULL;
374
375 rc = pciehp_resource_sort_and_combine(head);
376
377 if (rc)
378 return NULL;
379
380 if ((*head)->base != (*orig_head)->base)
381 return NULL;
382
383 if ((*head)->length == (*orig_head)->length)
384 return NULL;
385
386
387 /* If we got here, there the bridge requires some of the resource, but
388 * we may be able to split some off of the front
389 */
390 node = *head;
391
392 if (node->length & (alignment -1)) {
393 /* this one isn't an aligned length, so we'll make a new entry
394 * and split it up.
395 */
396 split_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
397
398 if (!split_node)
399 return NULL;
400
401 temp_dword = (node->length | (alignment-1)) + 1 - alignment;
402
403 split_node->base = node->base;
404 split_node->length = temp_dword;
405
406 node->length -= temp_dword;
407 node->base += split_node->length;
408
409 /* Put it in the list */
410 *head = split_node;
411 split_node->next = node;
412 }
413
414 if (node->length < alignment)
415 return NULL;
416
417 /* Now unlink it */
418 if (*head == node) {
419 *head = node->next;
420 } else {
421 prevnode = *head;
422 while (prevnode->next != node)
423 prevnode = prevnode->next;
424
425 prevnode->next = node->next;
426 }
427 node->next = NULL;
428
429 return node;
430}
431
432
433/**
434 * do_bridge_resource_split: return one unused resource node
435 * @head: list to scan
436 *
437 */
438static struct pci_resource *
439do_bridge_resource_split(struct pci_resource **head, u32 alignment)
440{
441 struct pci_resource *prevnode = NULL;
442 struct pci_resource *node;
443 u32 rc;
444 u32 temp_dword;
445
446 if (!(*head))
447 return NULL;
448
449 rc = pciehp_resource_sort_and_combine(head);
450
451 if (rc)
452 return NULL;
453
454 node = *head;
455
456 while (node->next) {
457 prevnode = node;
458 node = node->next;
459 kfree(prevnode);
460 }
461
462 if (node->length < alignment) {
463 kfree(node);
464 return NULL;
465 }
466
467 if (node->base & (alignment - 1)) {
468 /* Short circuit if adjusted size is too small */
469 temp_dword = (node->base | (alignment-1)) + 1;
470 if ((node->length - (temp_dword - node->base)) < alignment) {
471 kfree(node);
472 return NULL;
473 }
474
475 node->length -= (temp_dword - node->base);
476 node->base = temp_dword;
477 }
478
479 if (node->length & (alignment - 1)) {
480 /* There's stuff in use after this node */
481 kfree(node);
482 return NULL;
483 }
484
485 return node;
486}
487
488
489/*
490 * get_io_resource
491 *
492 * this function sorts the resource list by size and then
493 * returns the first node of "size" length that is not in the
494 * ISA aliasing window. If it finds a node larger than "size"
495 * it will split it up.
496 *
497 * size must be a power of two.
498 */
499static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size)
500{
501 struct pci_resource *prevnode;
502 struct pci_resource *node;
503 struct pci_resource *split_node = NULL;
504 u32 temp_dword;
505
506 if (!(*head))
507 return NULL;
508
509 if ( pciehp_resource_sort_and_combine(head) )
510 return NULL;
511
512 if ( sort_by_size(head) )
513 return NULL;
514
515 for (node = *head; node; node = node->next) {
516 if (node->length < size)
517 continue;
518
519 if (node->base & (size - 1)) {
520 /* this one isn't base aligned properly
521 so we'll make a new entry and split it up */
522 temp_dword = (node->base | (size-1)) + 1;
523
524 /*/ Short circuit if adjusted size is too small */
525 if ((node->length - (temp_dword - node->base)) < size)
526 continue;
527
528 split_node = kmalloc(sizeof(struct pci_resource),
529 GFP_KERNEL);
530
531 if (!split_node)
532 return NULL;
533
534 split_node->base = node->base;
535 split_node->length = temp_dword - node->base;
536 node->base = temp_dword;
537 node->length -= split_node->length;
538
539 /* Put it in the list */
540 split_node->next = node->next;
541 node->next = split_node;
542 } /* End of non-aligned base */
543
544 /* Don't need to check if too small since we already did */
545 if (node->length > size) {
546 /* this one is longer than we need
547 so we'll make a new entry and split it up */
548 split_node = kmalloc(sizeof(struct pci_resource),
549 GFP_KERNEL);
550
551 if (!split_node)
552 return NULL;
553
554 split_node->base = node->base + size;
555 split_node->length = node->length - size;
556 node->length = size;
557
558 /* Put it in the list */
559 split_node->next = node->next;
560 node->next = split_node;
561 } /* End of too big on top end */
562
563 /* For IO make sure it's not in the ISA aliasing space */
564 if (node->base & 0x300L)
565 continue;
566
567 /* If we got here, then it is the right size
568 Now take it out of the list */
569 if (*head == node) {
570 *head = node->next;
571 } else {
572 prevnode = *head;
573 while (prevnode->next != node)
574 prevnode = prevnode->next;
575
576 prevnode->next = node->next;
577 }
578 node->next = NULL;
579 /* Stop looping */
580 break;
581 }
582
583 return node;
584}
585
586
587/*
588 * get_max_resource
589 *
590 * Gets the largest node that is at least "size" big from the
591 * list pointed to by head. It aligns the node on top and bottom
592 * to "size" alignment before returning it.
593 * J.I. modified to put max size limits of; 64M->32M->16M->8M->4M->1M
594 * This is needed to avoid allocating entire ACPI _CRS res to one child bridge/slot.
595 */
596static struct pci_resource *get_max_resource(struct pci_resource **head, u32 size)
597{
598 struct pci_resource *max;
599 struct pci_resource *temp;
600 struct pci_resource *split_node;
601 u32 temp_dword;
602 u32 max_size[] = { 0x4000000, 0x2000000, 0x1000000, 0x0800000, 0x0400000, 0x0200000, 0x0100000, 0x00 };
603 int i;
604
605 if (!(*head))
606 return NULL;
607
608 if (pciehp_resource_sort_and_combine(head))
609 return NULL;
610
611 if (sort_by_max_size(head))
612 return NULL;
613
614 for (max = *head;max; max = max->next) {
615
616 /* If not big enough we could probably just bail,
617 instead we'll continue to the next. */
618 if (max->length < size)
619 continue;
620
621 if (max->base & (size - 1)) {
622 /* this one isn't base aligned properly
623 so we'll make a new entry and split it up */
624 temp_dword = (max->base | (size-1)) + 1;
625
626 /* Short circuit if adjusted size is too small */
627 if ((max->length - (temp_dword - max->base)) < size)
628 continue;
629
630 split_node = kmalloc(sizeof(struct pci_resource),
631 GFP_KERNEL);
632
633 if (!split_node)
634 return NULL;
635
636 split_node->base = max->base;
637 split_node->length = temp_dword - max->base;
638 max->base = temp_dword;
639 max->length -= split_node->length;
640
641 /* Put it next in the list */
642 split_node->next = max->next;
643 max->next = split_node;
644 }
645
646 if ((max->base + max->length) & (size - 1)) {
647 /* this one isn't end aligned properly at the top
648 so we'll make a new entry and split it up */
649 split_node = kmalloc(sizeof(struct pci_resource),
650 GFP_KERNEL);
651
652 if (!split_node)
653 return NULL;
654 temp_dword = ((max->base + max->length) & ~(size - 1));
655 split_node->base = temp_dword;
656 split_node->length = max->length + max->base
657 - split_node->base;
658 max->length -= split_node->length;
659
660 /* Put it in the list */
661 split_node->next = max->next;
662 max->next = split_node;
663 }
664
665 /* Make sure it didn't shrink too much when we aligned it */
666 if (max->length < size)
667 continue;
668
669 for ( i = 0; max_size[i] > size; i++) {
670 if (max->length > max_size[i]) {
671 split_node = kmalloc(sizeof(struct pci_resource),
672 GFP_KERNEL);
673 if (!split_node)
674 break; /* return NULL; */
675 split_node->base = max->base + max_size[i];
676 split_node->length = max->length - max_size[i];
677 max->length = max_size[i];
678 /* Put it next in the list */
679 split_node->next = max->next;
680 max->next = split_node;
681 break;
682 }
683 }
684
685 /* Now take it out of the list */
686 temp = (struct pci_resource*) *head;
687 if (temp == max) {
688 *head = max->next;
689 } else {
690 while (temp && temp->next != max) {
691 temp = temp->next;
692 }
693
694 temp->next = max->next;
695 }
696
697 max->next = NULL;
698 return max;
699 }
700
701 /* If we get here, we couldn't find one */
702 return NULL;
703}
704
705
706/*
707 * get_resource
708 *
709 * this function sorts the resource list by size and then
710 * returns the first node of "size" length. If it finds a node
711 * larger than "size" it will split it up.
712 *
713 * size must be a power of two.
714 */
715static struct pci_resource *get_resource(struct pci_resource **head, u32 size)
716{
717 struct pci_resource *prevnode;
718 struct pci_resource *node;
719 struct pci_resource *split_node;
720 u32 temp_dword;
721
722 if (!(*head))
723 return NULL;
724
725 if ( pciehp_resource_sort_and_combine(head) )
726 return NULL;
727
728 if ( sort_by_size(head) )
729 return NULL;
730
731 for (node = *head; node; node = node->next) {
732 dbg("%s: req_size =0x%x node=%p, base=0x%x, length=0x%x\n",
733 __FUNCTION__, size, node, node->base, node->length);
734 if (node->length < size)
735 continue;
736
737 if (node->base & (size - 1)) {
738 dbg("%s: not aligned\n", __FUNCTION__);
739 /* this one isn't base aligned properly
740 so we'll make a new entry and split it up */
741 temp_dword = (node->base | (size-1)) + 1;
742
743 /* Short circuit if adjusted size is too small */
744 if ((node->length - (temp_dword - node->base)) < size)
745 continue;
746
747 split_node = kmalloc(sizeof(struct pci_resource),
748 GFP_KERNEL);
749
750 if (!split_node)
751 return NULL;
752
753 split_node->base = node->base;
754 split_node->length = temp_dword - node->base;
755 node->base = temp_dword;
756 node->length -= split_node->length;
757
758 /* Put it in the list */
759 split_node->next = node->next;
760 node->next = split_node;
761 } /* End of non-aligned base */
762
763 /* Don't need to check if too small since we already did */
764 if (node->length > size) {
765 dbg("%s: too big\n", __FUNCTION__);
766 /* this one is longer than we need
767 so we'll make a new entry and split it up */
768 split_node = kmalloc(sizeof(struct pci_resource),
769 GFP_KERNEL);
770
771 if (!split_node)
772 return NULL;
773
774 split_node->base = node->base + size;
775 split_node->length = node->length - size;
776 node->length = size;
777
778 /* Put it in the list */
779 split_node->next = node->next;
780 node->next = split_node;
781 } /* End of too big on top end */
782
783 dbg("%s: got one!!!\n", __FUNCTION__);
784 /* If we got here, then it is the right size
785 Now take it out of the list */
786 if (*head == node) {
787 *head = node->next;
788 } else {
789 prevnode = *head;
790 while (prevnode->next != node)
791 prevnode = prevnode->next;
792
793 prevnode->next = node->next;
794 }
795 node->next = NULL;
796 /* Stop looping */
797 break;
798 }
799 return node;
800}
801
802
803/*
804 * pciehp_resource_sort_and_combine
805 *
806 * Sorts all of the nodes in the list in ascending order by
807 * their base addresses. Also does garbage collection by
808 * combining adjacent nodes.
809 *
810 * returns 0 if success
811 */
812int pciehp_resource_sort_and_combine(struct pci_resource **head)
813{
814 struct pci_resource *node1;
815 struct pci_resource *node2;
816 int out_of_order = 1;
817
818 dbg("%s: head = %p, *head = %p\n", __FUNCTION__, head, *head);
819
820 if (!(*head))
821 return 1;
822
823 dbg("*head->next = %p\n",(*head)->next);
824
825 if (!(*head)->next)
826 return 0; /* only one item on the list, already sorted! */
827
828 dbg("*head->base = 0x%x\n",(*head)->base);
829 dbg("*head->next->base = 0x%x\n",(*head)->next->base);
830 while (out_of_order) {
831 out_of_order = 0;
832
833 /* Special case for swapping list head */
834 if (((*head)->next) &&
835 ((*head)->base > (*head)->next->base)) {
836 node1 = *head;
837 (*head) = (*head)->next;
838 node1->next = (*head)->next;
839 (*head)->next = node1;
840 out_of_order++;
841 }
842
843 node1 = (*head);
844
845 while (node1->next && node1->next->next) {
846 if (node1->next->base > node1->next->next->base) {
847 out_of_order++;
848 node2 = node1->next;
849 node1->next = node1->next->next;
850 node1 = node1->next;
851 node2->next = node1->next;
852 node1->next = node2;
853 } else
854 node1 = node1->next;
855 }
856 } /* End of out_of_order loop */
857
858 node1 = *head;
859
860 while (node1 && node1->next) {
861 if ((node1->base + node1->length) == node1->next->base) {
862 /* Combine */
863 dbg("8..\n");
864 node1->length += node1->next->length;
865 node2 = node1->next;
866 node1->next = node1->next->next;
867 kfree(node2);
868 } else
869 node1 = node1->next;
870 }
871
872 return 0;
873}
874
875
876/**
877 * pciehp_slot_create - Creates a node and adds it to the proper bus.
878 * @busnumber - bus where new node is to be located
879 *
880 * Returns pointer to the new node or NULL if unsuccessful
881 */
882struct pci_func *pciehp_slot_create(u8 busnumber)
883{
884 struct pci_func *new_slot;
885 struct pci_func *next;
886 dbg("%s: busnumber %x\n", __FUNCTION__, busnumber);
887 new_slot = kmalloc(sizeof(struct pci_func), GFP_KERNEL);
888
889 if (new_slot == NULL)
890 return new_slot;
891
892 memset(new_slot, 0, sizeof(struct pci_func));
893
894 new_slot->next = NULL;
895 new_slot->configured = 1;
896
897 if (pciehp_slot_list[busnumber] == NULL) {
898 pciehp_slot_list[busnumber] = new_slot;
899 } else {
900 next = pciehp_slot_list[busnumber];
901 while (next->next != NULL)
902 next = next->next;
903 next->next = new_slot;
904 }
905 return new_slot;
906}
907
908
909/**
910 * slot_remove - Removes a node from the linked list of slots.
911 * @old_slot: slot to remove
912 *
913 * Returns 0 if successful, !0 otherwise.
914 */
915static int slot_remove(struct pci_func * old_slot)
916{
917 struct pci_func *next;
918
919 if (old_slot == NULL)
920 return 1;
921
922 next = pciehp_slot_list[old_slot->bus];
923
924 if (next == NULL)
925 return 1;
926
927 if (next == old_slot) {
928 pciehp_slot_list[old_slot->bus] = old_slot->next;
929 pciehp_destroy_board_resources(old_slot);
930 kfree(old_slot);
931 return 0;
932 }
933
934 while ((next->next != old_slot) && (next->next != NULL)) {
935 next = next->next;
936 }
937
938 if (next->next == old_slot) {
939 next->next = old_slot->next;
940 pciehp_destroy_board_resources(old_slot);
941 kfree(old_slot);
942 return 0;
943 } else
944 return 2;
945}
946
947
948/**
949 * bridge_slot_remove - Removes a node from the linked list of slots.
950 * @bridge: bridge to remove
951 *
952 * Returns 0 if successful, !0 otherwise.
953 */
954static int bridge_slot_remove(struct pci_func *bridge)
955{
956 u8 subordinateBus, secondaryBus;
957 u8 tempBus;
958 struct pci_func *next;
959
960 if (bridge == NULL)
961 return 1;
962
963 secondaryBus = (bridge->config_space[0x06] >> 8) & 0xFF;
964 subordinateBus = (bridge->config_space[0x06] >> 16) & 0xFF;
965
966 for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {
967 next = pciehp_slot_list[tempBus];
968
969 while (!slot_remove(next)) {
970 next = pciehp_slot_list[tempBus];
971 }
972 }
973
974 next = pciehp_slot_list[bridge->bus];
975
976 if (next == NULL) {
977 return 1;
978 }
979
980 if (next == bridge) {
981 pciehp_slot_list[bridge->bus] = bridge->next;
982 kfree(bridge);
983 return 0;
984 }
985
986 while ((next->next != bridge) && (next->next != NULL)) {
987 next = next->next;
988 }
989
990 if (next->next == bridge) {
991 next->next = bridge->next;
992 kfree(bridge);
993 return 0;
994 } else
995 return 2;
996}
997
998
999/**
1000 * pciehp_slot_find - Looks for a node by bus, and device, multiple functions accessed
1001 * @bus: bus to find
1002 * @device: device to find
1003 * @index: is 0 for first function found, 1 for the second...
1004 *
1005 * Returns pointer to the node if successful, %NULL otherwise.
1006 */
1007struct pci_func *pciehp_slot_find(u8 bus, u8 device, u8 index)
1008{
1009 int found = -1;
1010 struct pci_func *func;
1011
1012 func = pciehp_slot_list[bus];
1013 dbg("%s: bus %x device %x index %x\n",
1014 __FUNCTION__, bus, device, index);
1015 if (func != NULL) {
1016 dbg("%s: func-> bus %x device %x function %x pci_dev %p\n",
1017 __FUNCTION__, func->bus, func->device, func->function,
1018 func->pci_dev);
1019 } else
1020 dbg("%s: func == NULL\n", __FUNCTION__);
1021
1022 if ((func == NULL) || ((func->device == device) && (index == 0)))
1023 return func;
1024
1025 if (func->device == device)
1026 found++;
1027
1028 while (func->next != NULL) {
1029 func = func->next;
1030
1031 dbg("%s: In while loop, func-> bus %x device %x function %x pci_dev %p\n",
1032 __FUNCTION__, func->bus, func->device, func->function,
1033 func->pci_dev);
1034 if (func->device == device)
1035 found++;
1036 dbg("%s: while loop, found %d, index %d\n", __FUNCTION__,
1037 found, index);
1038
1039 if ((found == index) || (func->function == index)) {
1040 dbg("%s: Found bus %x dev %x func %x\n", __FUNCTION__,
1041 func->bus, func->device, func->function);
1042 return func;
1043 }
1044 }
1045
1046 return NULL;
1047}
1048
1049static int is_bridge(struct pci_func * func)
1050{
1051 /* Check the header type */
1052 if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01)
1053 return 1;
1054 else
1055 return 0;
1056}
1057
1058
1059/* The following routines constitute the bulk of the
1060 hotplug controller logic
1061 */
1062
1063static void set_slot_off(struct controller *ctrl, struct slot * pslot)
1064{
1065 /* Wait for exclusive access to hardware */
1066 down(&ctrl->crit_sect);
1067
1068 /* turn off slot, turn on Amber LED, turn off Green LED if supported*/
1069 if (POWER_CTRL(ctrl->ctrlcap)) {
1070 if (pslot->hpc_ops->power_off_slot(pslot)) {
1071 err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__);
1072 up(&ctrl->crit_sect);
1073 return;
1074 }
1075 wait_for_ctrl_irq (ctrl);
1076 }
1077
1078 if (PWR_LED(ctrl->ctrlcap)) {
1079 pslot->hpc_ops->green_led_off(pslot);
1080 wait_for_ctrl_irq (ctrl);
1081 }
1082
1083 if (ATTN_LED(ctrl->ctrlcap)) {
1084 if (pslot->hpc_ops->set_attention_status(pslot, 1)) {
1085 err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__);
1086 up(&ctrl->crit_sect);
1087 return;
1088 }
1089 wait_for_ctrl_irq (ctrl);
1090 }
1091
1092 /* Done with exclusive hardware access */
1093 up(&ctrl->crit_sect);
1094}
1095
1096/**
1097 * board_added - Called after a board has been added to the system.
1098 *
1099 * Turns power on for the board
1100 * Configures board
1101 *
1102 */
1103static u32 board_added(struct pci_func * func, struct controller * ctrl)
1104{
1105 u8 hp_slot;
1106 int index;
1107 u32 temp_register = 0xFFFFFFFF;
1108 u32 rc = 0;
1109 struct pci_func *new_func = NULL;
1110 struct slot *p_slot;
1111 struct resource_lists res_lists;
1112
1113 p_slot = pciehp_find_slot(ctrl, func->device);
1114 hp_slot = func->device - ctrl->slot_device_offset;
1115
1116 dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n", __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
1117
1118 /* Wait for exclusive access to hardware */
1119 down(&ctrl->crit_sect);
1120
1121 if (POWER_CTRL(ctrl->ctrlcap)) {
1122 /* Power on slot */
1123 rc = p_slot->hpc_ops->power_on_slot(p_slot);
1124 if (rc) {
1125 up(&ctrl->crit_sect);
1126 return -1;
1127 }
1128
1129 /* Wait for the command to complete */
1130 wait_for_ctrl_irq (ctrl);
1131 }
1132
1133 if (PWR_LED(ctrl->ctrlcap)) {
1134 p_slot->hpc_ops->green_led_blink(p_slot);
1135
1136 /* Wait for the command to complete */
1137 wait_for_ctrl_irq (ctrl);
1138 }
1139
1140 /* Done with exclusive hardware access */
1141 up(&ctrl->crit_sect);
1142
1143 /* Wait for ~1 second */
1144 dbg("%s: before long_delay\n", __FUNCTION__);
1145 wait_for_ctrl_irq (ctrl);
1146 dbg("%s: afterlong_delay\n", __FUNCTION__);
1147
1148 /* Check link training status */
1149 rc = p_slot->hpc_ops->check_lnk_status(ctrl);
1150 if (rc) {
1151 err("%s: Failed to check link status\n", __FUNCTION__);
1152 set_slot_off(ctrl, p_slot);
1153 return rc;
1154 }
1155
1156 dbg("%s: func status = %x\n", __FUNCTION__, func->status);
1157
1158 /* Check for a power fault */
1159 if (func->status == 0xFF) {
1160 /* power fault occurred, but it was benign */
1161 temp_register = 0xFFFFFFFF;
1162 dbg("%s: temp register set to %x by power fault\n", __FUNCTION__, temp_register);
1163 rc = POWER_FAILURE;
1164 func->status = 0;
1165 } else {
1166 /* Get vendor/device ID u32 */
1167 rc = pci_bus_read_config_dword (ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function),
1168 PCI_VENDOR_ID, &temp_register);
1169 dbg("%s: pci_bus_read_config_dword returns %d\n", __FUNCTION__, rc);
1170 dbg("%s: temp_register is %x\n", __FUNCTION__, temp_register);
1171
1172 if (rc != 0) {
1173 /* Something's wrong here */
1174 temp_register = 0xFFFFFFFF;
1175 dbg("%s: temp register set to %x by error\n", __FUNCTION__, temp_register);
1176 }
1177 /* Preset return code. It will be changed later if things go okay. */
1178 rc = NO_ADAPTER_PRESENT;
1179 }
1180
1181 /* All F's is an empty slot or an invalid board */
1182 if (temp_register != 0xFFFFFFFF) { /* Check for a board in the slot */
1183 res_lists.io_head = ctrl->io_head;
1184 res_lists.mem_head = ctrl->mem_head;
1185 res_lists.p_mem_head = ctrl->p_mem_head;
1186 res_lists.bus_head = ctrl->bus_head;
1187 res_lists.irqs = NULL;
1188
1189 rc = configure_new_device(ctrl, func, 0, &res_lists, 0, 0);
1190 dbg("%s: back from configure_new_device\n", __FUNCTION__);
1191
1192 ctrl->io_head = res_lists.io_head;
1193 ctrl->mem_head = res_lists.mem_head;
1194 ctrl->p_mem_head = res_lists.p_mem_head;
1195 ctrl->bus_head = res_lists.bus_head;
1196
1197 pciehp_resource_sort_and_combine(&(ctrl->mem_head));
1198 pciehp_resource_sort_and_combine(&(ctrl->p_mem_head));
1199 pciehp_resource_sort_and_combine(&(ctrl->io_head));
1200 pciehp_resource_sort_and_combine(&(ctrl->bus_head));
1201
1202 if (rc) {
1203 set_slot_off(ctrl, p_slot);
1204 return rc;
1205 }
1206 pciehp_save_slot_config(ctrl, func);
1207
1208 func->status = 0;
1209 func->switch_save = 0x10;
1210 func->is_a_board = 0x01;
1211
1212 /* next, we will instantiate the linux pci_dev structures
1213 * (with appropriate driver notification, if already present)
1214 */
1215 index = 0;
1216 do {
1217 new_func = pciehp_slot_find(ctrl->slot_bus, func->device, index++);
1218 if (new_func && !new_func->pci_dev) {
1219 dbg("%s:call pci_hp_configure_dev, func %x\n",
1220 __FUNCTION__, index);
1221 pciehp_configure_device(ctrl, new_func);
1222 }
1223 } while (new_func);
1224
1225 /*
1226 * Some PCI Express root ports require fixup after hot-plug operation.
1227 */
1228 if (pcie_mch_quirk)
1229 pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
1230
1231 if (PWR_LED(ctrl->ctrlcap)) {
1232 /* Wait for exclusive access to hardware */
1233 down(&ctrl->crit_sect);
1234
1235 p_slot->hpc_ops->green_led_on(p_slot);
1236
1237 /* Wait for the command to complete */
1238 wait_for_ctrl_irq (ctrl);
1239
1240 /* Done with exclusive hardware access */
1241 up(&ctrl->crit_sect);
1242 }
1243 } else {
1244 set_slot_off(ctrl, p_slot);
1245 return -1;
1246 }
1247 return 0;
1248}
1249
1250
1251/**
1252 * remove_board - Turns off slot and LED's
1253 *
1254 */
1255static u32 remove_board(struct pci_func *func, struct controller *ctrl)
1256{
1257 int index;
1258 u8 skip = 0;
1259 u8 device;
1260 u8 hp_slot;
1261 u32 rc;
1262 struct resource_lists res_lists;
1263 struct pci_func *temp_func;
1264 struct slot *p_slot;
1265
1266 if (func == NULL)
1267 return 1;
1268
1269 if (pciehp_unconfigure_device(func))
1270 return 1;
1271
1272 device = func->device;
1273
1274 hp_slot = func->device - ctrl->slot_device_offset;
1275 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1276
1277 dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
1278
1279 if ((ctrl->add_support) &&
1280 !(func->bus_head || func->mem_head || func->p_mem_head || func->io_head)) {
1281 /* Here we check to see if we've saved any of the board's
1282 * resources already. If so, we'll skip the attempt to
1283 * determine what's being used.
1284 */
1285 index = 0;
1286
1287 temp_func = func;
1288
1289 while ((temp_func = pciehp_slot_find(temp_func->bus, temp_func->device, index++))) {
1290 if (temp_func->bus_head || temp_func->mem_head
1291 || temp_func->p_mem_head || temp_func->io_head) {
1292 skip = 1;
1293 break;
1294 }
1295 }
1296
1297 if (!skip)
1298 rc = pciehp_save_used_resources(ctrl, func, DISABLE_CARD);
1299 }
1300 /* Change status to shutdown */
1301 if (func->is_a_board)
1302 func->status = 0x01;
1303 func->configured = 0;
1304
1305 /* Wait for exclusive access to hardware */
1306 down(&ctrl->crit_sect);
1307
1308 if (POWER_CTRL(ctrl->ctrlcap)) {
1309 /* power off slot */
1310 rc = p_slot->hpc_ops->power_off_slot(p_slot);
1311 if (rc) {
1312 err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
1313 up(&ctrl->crit_sect);
1314 return rc;
1315 }
1316 /* Wait for the command to complete */
1317 wait_for_ctrl_irq (ctrl);
1318 }
1319
1320 if (PWR_LED(ctrl->ctrlcap)) {
1321 /* turn off Green LED */
1322 p_slot->hpc_ops->green_led_off(p_slot);
1323
1324 /* Wait for the command to complete */
1325 wait_for_ctrl_irq (ctrl);
1326 }
1327
1328 /* Done with exclusive hardware access */
1329 up(&ctrl->crit_sect);
1330
1331 if (ctrl->add_support) {
1332 while (func) {
1333 res_lists.io_head = ctrl->io_head;
1334 res_lists.mem_head = ctrl->mem_head;
1335 res_lists.p_mem_head = ctrl->p_mem_head;
1336 res_lists.bus_head = ctrl->bus_head;
1337
1338 dbg("Returning resources to ctlr lists for (B/D/F) = (%#x/%#x/%#x)\n",
1339 func->bus, func->device, func->function);
1340
1341 pciehp_return_board_resources(func, &res_lists);
1342
1343 ctrl->io_head = res_lists.io_head;
1344 ctrl->mem_head = res_lists.mem_head;
1345 ctrl->p_mem_head = res_lists.p_mem_head;
1346 ctrl->bus_head = res_lists.bus_head;
1347
1348 pciehp_resource_sort_and_combine(&(ctrl->mem_head));
1349 pciehp_resource_sort_and_combine(&(ctrl->p_mem_head));
1350 pciehp_resource_sort_and_combine(&(ctrl->io_head));
1351 pciehp_resource_sort_and_combine(&(ctrl->bus_head));
1352
1353 if (is_bridge(func)) {
1354 dbg("PCI Bridge Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n",
1355 ctrl->seg, func->bus, func->device, func->function);
1356 bridge_slot_remove(func);
1357 } else {
1358 dbg("PCI Function Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n",
1359 ctrl->seg, func->bus, func->device, func->function);
1360 slot_remove(func);
1361 }
1362
1363 func = pciehp_slot_find(ctrl->slot_bus, device, 0);
1364 }
1365
1366 /* Setup slot structure with entry for empty slot */
1367 func = pciehp_slot_create(ctrl->slot_bus);
1368
1369 if (func == NULL) {
1370 return 1;
1371 }
1372
1373 func->bus = ctrl->slot_bus;
1374 func->device = device;
1375 func->function = 0;
1376 func->configured = 0;
1377 func->switch_save = 0x10;
1378 func->is_a_board = 0;
1379 }
1380
1381 return 0;
1382}
1383
1384
1385static void pushbutton_helper_thread(unsigned long data)
1386{
1387 pushbutton_pending = data;
1388
1389 up(&event_semaphore);
1390}
1391
1392/**
1393 * pciehp_pushbutton_thread
1394 *
1395 * Scheduled procedure to handle blocking stuff for the pushbuttons
1396 * Handles all pending events and exits.
1397 *
1398 */
1399static void pciehp_pushbutton_thread(unsigned long slot)
1400{
1401 struct slot *p_slot = (struct slot *) slot;
1402 u8 getstatus;
1403
1404 pushbutton_pending = 0;
1405
1406 if (!p_slot) {
1407 dbg("%s: Error! slot NULL\n", __FUNCTION__);
1408 return;
1409 }
1410
1411 p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
1412 if (getstatus) {
1413 p_slot->state = POWEROFF_STATE;
1414 dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
1415
1416 pciehp_disable_slot(p_slot);
1417 p_slot->state = STATIC_STATE;
1418 } else {
1419 p_slot->state = POWERON_STATE;
1420 dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
1421
1422 if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
1423 /* Wait for exclusive access to hardware */
1424 down(&p_slot->ctrl->crit_sect);
1425
1426 p_slot->hpc_ops->green_led_off(p_slot);
1427
1428 /* Wait for the command to complete */
1429 wait_for_ctrl_irq (p_slot->ctrl);
1430
1431 /* Done with exclusive hardware access */
1432 up(&p_slot->ctrl->crit_sect);
1433 }
1434 p_slot->state = STATIC_STATE;
1435 }
1436
1437 return;
1438}
1439
1440/**
1441 * pciehp_surprise_rm_thread
1442 *
1443 * Scheduled procedure to handle blocking stuff for the surprise removal
1444 * Handles all pending events and exits.
1445 *
1446 */
1447static void pciehp_surprise_rm_thread(unsigned long slot)
1448{
1449 struct slot *p_slot = (struct slot *) slot;
1450 u8 getstatus;
1451
1452 surprise_rm_pending = 0;
1453
1454 if (!p_slot) {
1455 dbg("%s: Error! slot NULL\n", __FUNCTION__);
1456 return;
1457 }
1458
1459 p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
1460 if (!getstatus) {
1461 p_slot->state = POWEROFF_STATE;
1462 dbg("In removing board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
1463
1464 pciehp_disable_slot(p_slot);
1465 p_slot->state = STATIC_STATE;
1466 } else {
1467 p_slot->state = POWERON_STATE;
1468 dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
1469
1470 if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
1471 /* Wait for exclusive access to hardware */
1472 down(&p_slot->ctrl->crit_sect);
1473
1474 p_slot->hpc_ops->green_led_off(p_slot);
1475
1476 /* Wait for the command to complete */
1477 wait_for_ctrl_irq (p_slot->ctrl);
1478
1479 /* Done with exclusive hardware access */
1480 up(&p_slot->ctrl->crit_sect);
1481 }
1482 p_slot->state = STATIC_STATE;
1483 }
1484
1485 return;
1486}
1487
1488
1489
1490/* this is the main worker thread */
1491static int event_thread(void* data)
1492{
1493 struct controller *ctrl;
1494 lock_kernel();
1495 daemonize("pciehpd_event");
1496
1497 unlock_kernel();
1498
1499 while (1) {
1500 dbg("!!!!event_thread sleeping\n");
1501 down_interruptible (&event_semaphore);
1502 dbg("event_thread woken finished = %d\n", event_finished);
1503 if (event_finished || signal_pending(current))
1504 break;
1505 /* Do stuff here */
1506 if (pushbutton_pending)
1507 pciehp_pushbutton_thread(pushbutton_pending);
1508 else if (surprise_rm_pending)
1509 pciehp_surprise_rm_thread(surprise_rm_pending);
1510 else
1511 for (ctrl = pciehp_ctrl_list; ctrl; ctrl=ctrl->next)
1512 interrupt_event_handler(ctrl);
1513 }
1514 dbg("event_thread signals exit\n");
1515 up(&event_exit);
1516 return 0;
1517}
1518
1519int pciehp_event_start_thread(void)
1520{
1521 int pid;
1522
1523 /* initialize our semaphores */
1524 init_MUTEX_LOCKED(&event_exit);
1525 event_finished=0;
1526
1527 init_MUTEX_LOCKED(&event_semaphore);
1528 pid = kernel_thread(event_thread, NULL, 0);
1529
1530 if (pid < 0) {
1531 err ("Can't start up our event thread\n");
1532 return -1;
1533 }
1534 dbg("Our event thread pid = %d\n", pid);
1535 return 0;
1536}
1537
1538
1539void pciehp_event_stop_thread(void)
1540{
1541 event_finished = 1;
1542 dbg("event_thread finish command given\n");
1543 up(&event_semaphore);
1544 dbg("wait for event_thread to exit\n");
1545 down(&event_exit);
1546}
1547
1548
1549static int update_slot_info(struct slot *slot)
1550{
1551 struct hotplug_slot_info *info;
1552 /* char buffer[SLOT_NAME_SIZE]; */
1553 int result;
1554
1555 info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
1556 if (!info)
1557 return -ENOMEM;
1558
1559 /* make_slot_name (&buffer[0], SLOT_NAME_SIZE, slot); */
1560
1561 slot->hpc_ops->get_power_status(slot, &(info->power_status));
1562 slot->hpc_ops->get_attention_status(slot, &(info->attention_status));
1563 slot->hpc_ops->get_latch_status(slot, &(info->latch_status));
1564 slot->hpc_ops->get_adapter_status(slot, &(info->adapter_status));
1565
1566 /* result = pci_hp_change_slot_info(buffer, info); */
1567 result = pci_hp_change_slot_info(slot->hotplug_slot, info);
1568 kfree (info);
1569 return result;
1570}
1571
1572static void interrupt_event_handler(struct controller *ctrl)
1573{
1574 int loop = 0;
1575 int change = 1;
1576 struct pci_func *func;
1577 u8 hp_slot;
1578 u8 getstatus;
1579 struct slot *p_slot;
1580
1581 while (change) {
1582 change = 0;
1583
1584 for (loop = 0; loop < 10; loop++) {
1585 if (ctrl->event_queue[loop].event_type != 0) {
1586 hp_slot = ctrl->event_queue[loop].hp_slot;
1587
1588 func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
1589
1590 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1591
1592 dbg("hp_slot %d, func %p, p_slot %p\n", hp_slot, func, p_slot);
1593
1594 if (ctrl->event_queue[loop].event_type == INT_BUTTON_CANCEL) {
1595 dbg("button cancel\n");
1596 del_timer(&p_slot->task_event);
1597
1598 switch (p_slot->state) {
1599 case BLINKINGOFF_STATE:
1600 /* Wait for exclusive access to hardware */
1601 down(&ctrl->crit_sect);
1602
1603 if (PWR_LED(ctrl->ctrlcap)) {
1604 p_slot->hpc_ops->green_led_on(p_slot);
1605 /* Wait for the command to complete */
1606 wait_for_ctrl_irq (ctrl);
1607 }
1608 if (ATTN_LED(ctrl->ctrlcap)) {
1609 p_slot->hpc_ops->set_attention_status(p_slot, 0);
1610
1611 /* Wait for the command to complete */
1612 wait_for_ctrl_irq (ctrl);
1613 }
1614 /* Done with exclusive hardware access */
1615 up(&ctrl->crit_sect);
1616 break;
1617 case BLINKINGON_STATE:
1618 /* Wait for exclusive access to hardware */
1619 down(&ctrl->crit_sect);
1620
1621 if (PWR_LED(ctrl->ctrlcap)) {
1622 p_slot->hpc_ops->green_led_off(p_slot);
1623 /* Wait for the command to complete */
1624 wait_for_ctrl_irq (ctrl);
1625 }
1626 if (ATTN_LED(ctrl->ctrlcap)){
1627 p_slot->hpc_ops->set_attention_status(p_slot, 0);
1628 /* Wait for the command to complete */
1629 wait_for_ctrl_irq (ctrl);
1630 }
1631 /* Done with exclusive hardware access */
1632 up(&ctrl->crit_sect);
1633
1634 break;
1635 default:
1636 warn("Not a valid state\n");
1637 return;
1638 }
1639 info(msg_button_cancel, p_slot->number);
1640 p_slot->state = STATIC_STATE;
1641 }
1642 /* ***********Button Pressed (No action on 1st press...) */
1643 else if (ctrl->event_queue[loop].event_type == INT_BUTTON_PRESS) {
1644
1645 if (ATTN_BUTTN(ctrl->ctrlcap)) {
1646 dbg("Button pressed\n");
1647 p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
1648 if (getstatus) {
1649 /* slot is on */
1650 dbg("slot is on\n");
1651 p_slot->state = BLINKINGOFF_STATE;
1652 info(msg_button_off, p_slot->number);
1653 } else {
1654 /* slot is off */
1655 dbg("slot is off\n");
1656 p_slot->state = BLINKINGON_STATE;
1657 info(msg_button_on, p_slot->number);
1658 }
1659
1660 /* Wait for exclusive access to hardware */
1661 down(&ctrl->crit_sect);
1662
1663 /* blink green LED and turn off amber */
1664 if (PWR_LED(ctrl->ctrlcap)) {
1665 p_slot->hpc_ops->green_led_blink(p_slot);
1666 /* Wait for the command to complete */
1667 wait_for_ctrl_irq (ctrl);
1668 }
1669
1670 if (ATTN_LED(ctrl->ctrlcap)) {
1671 p_slot->hpc_ops->set_attention_status(p_slot, 0);
1672
1673 /* Wait for the command to complete */
1674 wait_for_ctrl_irq (ctrl);
1675 }
1676
1677 /* Done with exclusive hardware access */
1678 up(&ctrl->crit_sect);
1679
1680 init_timer(&p_slot->task_event);
1681 p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */
1682 p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
1683 p_slot->task_event.data = (unsigned long) p_slot;
1684
1685 dbg("add_timer p_slot = %p\n", (void *) p_slot);
1686 add_timer(&p_slot->task_event);
1687 }
1688 }
1689 /***********POWER FAULT********************/
1690 else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
1691 if (POWER_CTRL(ctrl->ctrlcap)) {
1692 dbg("power fault\n");
1693 /* Wait for exclusive access to hardware */
1694 down(&ctrl->crit_sect);
1695
1696 if (ATTN_LED(ctrl->ctrlcap)) {
1697 p_slot->hpc_ops->set_attention_status(p_slot, 1);
1698 wait_for_ctrl_irq (ctrl);
1699 }
1700
1701 if (PWR_LED(ctrl->ctrlcap)) {
1702 p_slot->hpc_ops->green_led_off(p_slot);
1703 wait_for_ctrl_irq (ctrl);
1704 }
1705
1706 /* Done with exclusive hardware access */
1707 up(&ctrl->crit_sect);
1708 }
1709 }
1710 /***********SURPRISE REMOVAL********************/
1711 else if ((ctrl->event_queue[loop].event_type == INT_PRESENCE_ON) ||
1712 (ctrl->event_queue[loop].event_type == INT_PRESENCE_OFF)) {
1713 if (HP_SUPR_RM(ctrl->ctrlcap)) {
1714 dbg("Surprise Removal\n");
1715 if (p_slot) {
1716 surprise_rm_pending = (unsigned long) p_slot;
1717 up(&event_semaphore);
1718 update_slot_info(p_slot);
1719 }
1720 }
1721 } else {
1722 /* refresh notification */
1723 if (p_slot)
1724 update_slot_info(p_slot);
1725 }
1726
1727 ctrl->event_queue[loop].event_type = 0;
1728
1729 change = 1;
1730 }
1731 } /* End of FOR loop */
1732 }
1733}
1734
1735
1736int pciehp_enable_slot(struct slot *p_slot)
1737{
1738 u8 getstatus = 0;
1739 int rc;
1740 struct pci_func *func;
1741
1742 func = pciehp_slot_find(p_slot->bus, p_slot->device, 0);
1743 if (!func) {
1744 dbg("%s: Error! slot NULL\n", __FUNCTION__);
1745 return 1;
1746 }
1747
1748 /* Check to see if (latch closed, card present, power off) */
1749 down(&p_slot->ctrl->crit_sect);
1750
1751 rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
1752 if (rc || !getstatus) {
1753 info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
1754 up(&p_slot->ctrl->crit_sect);
1755 return 1;
1756 }
1757 if (MRL_SENS(p_slot->ctrl->ctrlcap)) {
1758 rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
1759 if (rc || getstatus) {
1760 info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
1761 up(&p_slot->ctrl->crit_sect);
1762 return 1;
1763 }
1764 }
1765
1766 if (POWER_CTRL(p_slot->ctrl->ctrlcap)) {
1767 rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
1768 if (rc || getstatus) {
1769 info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number);
1770 up(&p_slot->ctrl->crit_sect);
1771 return 1;
1772 }
1773 }
1774 up(&p_slot->ctrl->crit_sect);
1775
1776 slot_remove(func);
1777
1778 func = pciehp_slot_create(p_slot->bus);
1779 if (func == NULL)
1780 return 1;
1781
1782 func->bus = p_slot->bus;
1783 func->device = p_slot->device;
1784 func->function = 0;
1785 func->configured = 0;
1786 func->is_a_board = 1;
1787
1788 /* We have to save the presence info for these slots */
1789 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
1790 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
1791 func->switch_save = !getstatus? 0x10:0;
1792
1793 rc = board_added(func, p_slot->ctrl);
1794 if (rc) {
1795 if (is_bridge(func))
1796 bridge_slot_remove(func);
1797 else
1798 slot_remove(func);
1799
1800 /* Setup slot structure with entry for empty slot */
1801 func = pciehp_slot_create(p_slot->bus);
1802 if (func == NULL)
1803 return 1; /* Out of memory */
1804
1805 func->bus = p_slot->bus;
1806 func->device = p_slot->device;
1807 func->function = 0;
1808 func->configured = 0;
1809 func->is_a_board = 1;
1810
1811 /* We have to save the presence info for these slots */
1812 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
1813 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
1814 func->switch_save = !getstatus? 0x10:0;
1815 }
1816
1817 if (p_slot)
1818 update_slot_info(p_slot);
1819
1820 return rc;
1821}
1822
1823
1824int pciehp_disable_slot(struct slot *p_slot)
1825{
1826 u8 class_code, header_type, BCR;
1827 u8 index = 0;
1828 u8 getstatus = 0;
1829 u32 rc = 0;
1830 int ret = 0;
1831 unsigned int devfn;
1832 struct pci_bus *pci_bus = p_slot->ctrl->pci_dev->subordinate;
1833 struct pci_func *func;
1834
1835 if (!p_slot->ctrl)
1836 return 1;
1837
1838 /* Check to see if (latch closed, card present, power on) */
1839 down(&p_slot->ctrl->crit_sect);
1840
1841 if (!HP_SUPR_RM(p_slot->ctrl->ctrlcap)) {
1842 ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
1843 if (ret || !getstatus) {
1844 info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
1845 up(&p_slot->ctrl->crit_sect);
1846 return 1;
1847 }
1848 }
1849
1850 if (MRL_SENS(p_slot->ctrl->ctrlcap)) {
1851 ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
1852 if (ret || getstatus) {
1853 info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
1854 up(&p_slot->ctrl->crit_sect);
1855 return 1;
1856 }
1857 }
1858
1859 if (POWER_CTRL(p_slot->ctrl->ctrlcap)) {
1860 ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
1861 if (ret || !getstatus) {
1862 info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number);
1863 up(&p_slot->ctrl->crit_sect);
1864 return 1;
1865 }
1866 }
1867
1868 up(&p_slot->ctrl->crit_sect);
1869
1870 func = pciehp_slot_find(p_slot->bus, p_slot->device, index++);
1871
1872 /* Make sure there are no video controllers here
1873 * for all func of p_slot
1874 */
1875 while (func && !rc) {
1876 pci_bus->number = func->bus;
1877 devfn = PCI_DEVFN(func->device, func->function);
1878
1879 /* Check the Class Code */
1880 rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
1881 if (rc)
1882 return rc;
1883
1884 if (class_code == PCI_BASE_CLASS_DISPLAY) {
1885 /* Display/Video adapter (not supported) */
1886 rc = REMOVE_NOT_SUPPORTED;
1887 } else {
1888 /* See if it's a bridge */
1889 rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
1890 if (rc)
1891 return rc;
1892
1893 /* If it's a bridge, check the VGA Enable bit */
1894 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
1895 rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
1896 if (rc)
1897 return rc;
1898
1899 /* If the VGA Enable bit is set, remove isn't supported */
1900 if (BCR & PCI_BRIDGE_CTL_VGA) {
1901 rc = REMOVE_NOT_SUPPORTED;
1902 }
1903 }
1904 }
1905
1906 func = pciehp_slot_find(p_slot->bus, p_slot->device, index++);
1907 }
1908
1909 func = pciehp_slot_find(p_slot->bus, p_slot->device, 0);
1910 if ((func != NULL) && !rc) {
1911 rc = remove_board(func, p_slot->ctrl);
1912 } else if (!rc)
1913 rc = 1;
1914
1915 if (p_slot)
1916 update_slot_info(p_slot);
1917
1918 return rc;
1919}
1920
1921
1922/**
1923 * configure_new_device - Configures the PCI header information of one board.
1924 *
1925 * @ctrl: pointer to controller structure
1926 * @func: pointer to function structure
1927 * @behind_bridge: 1 if this is a recursive call, 0 if not
1928 * @resources: pointer to set of resource lists
1929 *
1930 * Returns 0 if success
1931 *
1932 */
1933static u32 configure_new_device(struct controller * ctrl, struct pci_func * func,
1934 u8 behind_bridge, struct resource_lists * resources, u8 bridge_bus, u8 bridge_dev)
1935{
1936 u8 temp_byte, function, max_functions, stop_it;
1937 int rc;
1938 u32 ID;
1939 struct pci_func *new_slot;
1940 struct pci_bus lpci_bus, *pci_bus;
1941 int index;
1942
1943 new_slot = func;
1944
1945 dbg("%s\n", __FUNCTION__);
1946 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
1947 pci_bus = &lpci_bus;
1948 pci_bus->number = func->bus;
1949
1950 /* Check for Multi-function device */
1951 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);
1952 if (rc) {
1953 dbg("%s: rc = %d\n", __FUNCTION__, rc);
1954 return rc;
1955 }
1956
1957 if (temp_byte & 0x80) /* Multi-function device */
1958 max_functions = 8;
1959 else
1960 max_functions = 1;
1961
1962 function = 0;
1963
1964 do {
1965 rc = configure_new_function(ctrl, new_slot, behind_bridge,
1966 resources, bridge_bus, bridge_dev);
1967
1968 if (rc) {
1969 dbg("configure_new_function failed: %d\n", rc);
1970 index = 0;
1971
1972 while (new_slot) {
1973 new_slot = pciehp_slot_find(new_slot->bus,
1974 new_slot->device, index++);
1975
1976 if (new_slot)
1977 pciehp_return_board_resources(new_slot,
1978 resources);
1979 }
1980
1981 return rc;
1982 }
1983
1984 function++;
1985
1986 stop_it = 0;
1987
1988 /* The following loop skips to the next present function
1989 * and creates a board structure
1990 */
1991
1992 while ((function < max_functions) && (!stop_it)) {
1993 pci_bus_read_config_dword(pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
1994
1995 if (ID == 0xFFFFFFFF) { /* There's nothing there. */
1996 function++;
1997 } else { /* There's something there */
1998 /* Setup slot structure. */
1999 new_slot = pciehp_slot_create(func->bus);
2000
2001 if (new_slot == NULL) {
2002 /* Out of memory */
2003 return 1;
2004 }
2005
2006 new_slot->bus = func->bus;
2007 new_slot->device = func->device;
2008 new_slot->function = function;
2009 new_slot->is_a_board = 1;
2010 new_slot->status = 0;
2011
2012 stop_it++;
2013 }
2014 }
2015
2016 } while (function < max_functions);
2017 dbg("returning from %s\n", __FUNCTION__);
2018
2019 return 0;
2020}
2021
2022/*
2023 * Configuration logic that involves the hotplug data structures and
2024 * their bookkeeping
2025 */
2026
2027/**
2028 * configure_bridge: fill bridge's registers, either configure or disable it.
2029 */
2030static int
2031configure_bridge(struct pci_bus *pci_bus, unsigned int devfn,
2032 struct pci_resource *mem_node,
2033 struct pci_resource **hold_mem_node,
2034 int base_addr, int limit_addr)
2035{
2036 u16 temp_word;
2037 u32 rc;
2038
2039 if (mem_node) {
2040 memcpy(*hold_mem_node, mem_node, sizeof(struct pci_resource));
2041 mem_node->next = NULL;
2042
2043 /* set Mem base and Limit registers */
2044 RES_CHECK(mem_node->base, 16);
2045 temp_word = (u16)(mem_node->base >> 16);
2046 rc = pci_bus_write_config_word(pci_bus, devfn, base_addr, temp_word);
2047
2048 RES_CHECK(mem_node->base + mem_node->length - 1, 16);
2049 temp_word = (u16)((mem_node->base + mem_node->length - 1) >> 16);
2050 rc = pci_bus_write_config_word(pci_bus, devfn, limit_addr, temp_word);
2051 } else {
2052 temp_word = 0xFFFF;
2053 rc = pci_bus_write_config_word(pci_bus, devfn, base_addr, temp_word);
2054
2055 temp_word = 0x0000;
2056 rc = pci_bus_write_config_word(pci_bus, devfn, limit_addr, temp_word);
2057
2058 kfree(*hold_mem_node);
2059 *hold_mem_node = NULL;
2060 }
2061 return rc;
2062}
2063
2064static int
2065configure_new_bridge(struct controller *ctrl, struct pci_func *func,
2066 u8 behind_bridge, struct resource_lists *resources,
2067 struct pci_bus *pci_bus)
2068{
2069 int cloop;
2070 u8 temp_byte;
2071 u8 device;
2072 u16 temp_word;
2073 u32 rc;
2074 u32 ID;
2075 unsigned int devfn;
2076 struct pci_resource *mem_node;
2077 struct pci_resource *p_mem_node;
2078 struct pci_resource *io_node;
2079 struct pci_resource *bus_node;
2080 struct pci_resource *hold_mem_node;
2081 struct pci_resource *hold_p_mem_node;
2082 struct pci_resource *hold_IO_node;
2083 struct pci_resource *hold_bus_node;
2084 struct irq_mapping irqs;
2085 struct pci_func *new_slot;
2086 struct resource_lists temp_resources;
2087
2088 devfn = PCI_DEVFN(func->device, func->function);
2089
2090 /* set Primary bus */
2091 dbg("set Primary bus = 0x%x\n", func->bus);
2092 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
2093 if (rc)
2094 return rc;
2095
2096 /* find range of busses to use */
2097 bus_node = get_max_resource(&resources->bus_head, 1L);
2098
2099 /* If we don't have any busses to allocate, we can't continue */
2100 if (!bus_node) {
2101 err("Got NO bus resource to use\n");
2102 return -ENOMEM;
2103 }
2104 dbg("Got ranges of buses to use: base:len=0x%x:%x\n", bus_node->base, bus_node->length);
2105
2106 /* set Secondary bus */
2107 temp_byte = (u8)bus_node->base;
2108 dbg("set Secondary bus = 0x%x\n", temp_byte);
2109 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, temp_byte);
2110 if (rc)
2111 return rc;
2112
2113 /* set subordinate bus */
2114 temp_byte = (u8)(bus_node->base + bus_node->length - 1);
2115 dbg("set subordinate bus = 0x%x\n", temp_byte);
2116 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
2117 if (rc)
2118 return rc;
2119
2120 /* Set HP parameters (Cache Line Size, Latency Timer) */
2121 rc = pciehprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
2122 if (rc)
2123 return rc;
2124
2125 /* Setup the IO, memory, and prefetchable windows */
2126
2127 io_node = get_max_resource(&(resources->io_head), 0x1000L);
2128 if (io_node) {
2129 dbg("io_node(base, len, next) (%x, %x, %p)\n", io_node->base,
2130 io_node->length, io_node->next);
2131 }
2132
2133 mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
2134 if (mem_node) {
2135 dbg("mem_node(base, len, next) (%x, %x, %p)\n", mem_node->base,
2136 mem_node->length, mem_node->next);
2137 }
2138
2139 if (resources->p_mem_head)
2140 p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000L);
2141 else {
2142 /*
2143 * In some platform implementation, MEM and PMEM are not
2144 * distinguished, and hence ACPI _CRS has only MEM entries
2145 * for both MEM and PMEM.
2146 */
2147 dbg("using MEM for PMEM\n");
2148 p_mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
2149 }
2150 if (p_mem_node) {
2151 dbg("p_mem_node(base, len, next) (%x, %x, %p)\n", p_mem_node->base,
2152 p_mem_node->length, p_mem_node->next);
2153 }
2154
2155 /* set up the IRQ info */
2156 if (!resources->irqs) {
2157 irqs.barber_pole = 0;
2158 irqs.interrupt[0] = 0;
2159 irqs.interrupt[1] = 0;
2160 irqs.interrupt[2] = 0;
2161 irqs.interrupt[3] = 0;
2162 irqs.valid_INT = 0;
2163 } else {
2164 irqs.barber_pole = resources->irqs->barber_pole;
2165 irqs.interrupt[0] = resources->irqs->interrupt[0];
2166 irqs.interrupt[1] = resources->irqs->interrupt[1];
2167 irqs.interrupt[2] = resources->irqs->interrupt[2];
2168 irqs.interrupt[3] = resources->irqs->interrupt[3];
2169 irqs.valid_INT = resources->irqs->valid_INT;
2170 }
2171
2172 /* set up resource lists that are now aligned on top and bottom
2173 * for anything behind the bridge.
2174 */
2175 temp_resources.bus_head = bus_node;
2176 temp_resources.io_head = io_node;
2177 temp_resources.mem_head = mem_node;
2178 temp_resources.p_mem_head = p_mem_node;
2179 temp_resources.irqs = &irqs;
2180
2181 /* Make copies of the nodes we are going to pass down so that
2182 * if there is a problem,we can just use these to free resources
2183 */
2184 hold_bus_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2185 hold_IO_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2186 hold_mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2187 hold_p_mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2188
2189 if (!hold_bus_node || !hold_IO_node || !hold_mem_node || !hold_p_mem_node) {
2190 kfree(hold_bus_node);
2191 kfree(hold_IO_node);
2192 kfree(hold_mem_node);
2193 kfree(hold_p_mem_node);
2194
2195 return 1;
2196 }
2197
2198 memcpy(hold_bus_node, bus_node, sizeof(struct pci_resource));
2199
2200 bus_node->base += 1;
2201 bus_node->length -= 1;
2202 bus_node->next = NULL;
2203
2204 /* If we have IO resources copy them and fill in the bridge's
2205 * IO range registers
2206 */
2207 if (io_node) {
2208 memcpy(hold_IO_node, io_node, sizeof(struct pci_resource));
2209 io_node->next = NULL;
2210
2211 /* set IO base and Limit registers */
2212 RES_CHECK(io_node->base, 8);
2213 temp_byte = (u8)(io_node->base >> 8);
2214 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
2215
2216 RES_CHECK(io_node->base + io_node->length - 1, 8);
2217 temp_byte = (u8)((io_node->base + io_node->length - 1) >> 8);
2218 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2219 } else {
2220 kfree(hold_IO_node);
2221 hold_IO_node = NULL;
2222 }
2223
2224 /* If we have memory resources copy them and fill in the bridge's
2225 * memory range registers. Otherwise, fill in the range
2226 * registers with values that disable them.
2227 */
2228 rc = configure_bridge(pci_bus, devfn, mem_node, &hold_mem_node,
2229 PCI_MEMORY_BASE, PCI_MEMORY_LIMIT);
2230
2231 /* If we have prefetchable memory resources copy them and
2232 * fill in the bridge's memory range registers. Otherwise,
2233 * fill in the range registers with values that disable them.
2234 */
2235 rc = configure_bridge(pci_bus, devfn, p_mem_node, &hold_p_mem_node,
2236 PCI_PREF_MEMORY_BASE, PCI_PREF_MEMORY_LIMIT);
2237
2238 /* Adjust this to compensate for extra adjustment in first loop */
2239 irqs.barber_pole--;
2240
2241 rc = 0;
2242
2243 /* Here we actually find the devices and configure them */
2244 for (device = 0; (device <= 0x1F) && !rc; device++) {
2245 irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;
2246
2247 ID = 0xFFFFFFFF;
2248 pci_bus->number = hold_bus_node->base;
2249 pci_bus_read_config_dword (pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
2250 pci_bus->number = func->bus;
2251
2252 if (ID != 0xFFFFFFFF) { /* device Present */
2253 /* Setup slot structure. */
2254 new_slot = pciehp_slot_create(hold_bus_node->base);
2255
2256 if (new_slot == NULL) {
2257 /* Out of memory */
2258 rc = -ENOMEM;
2259 continue;
2260 }
2261
2262 new_slot->bus = hold_bus_node->base;
2263 new_slot->device = device;
2264 new_slot->function = 0;
2265 new_slot->is_a_board = 1;
2266 new_slot->status = 0;
2267
2268 rc = configure_new_device(ctrl, new_slot, 1,
2269 &temp_resources, func->bus,
2270 func->device);
2271 dbg("configure_new_device rc=0x%x\n",rc);
2272 } /* End of IF (device in slot?) */
2273 } /* End of FOR loop */
2274
2275 if (rc) {
2276 pciehp_destroy_resource_list(&temp_resources);
2277
2278 return_resource(&(resources->bus_head), hold_bus_node);
2279 return_resource(&(resources->io_head), hold_IO_node);
2280 return_resource(&(resources->mem_head), hold_mem_node);
2281 return_resource(&(resources->p_mem_head), hold_p_mem_node);
2282 return(rc);
2283 }
2284
2285 /* save the interrupt routing information */
2286 if (resources->irqs) {
2287 resources->irqs->interrupt[0] = irqs.interrupt[0];
2288 resources->irqs->interrupt[1] = irqs.interrupt[1];
2289 resources->irqs->interrupt[2] = irqs.interrupt[2];
2290 resources->irqs->interrupt[3] = irqs.interrupt[3];
2291 resources->irqs->valid_INT = irqs.valid_INT;
2292 } else if (!behind_bridge) {
2293 /* We need to hook up the interrupts here */
2294 for (cloop = 0; cloop < 4; cloop++) {
2295 if (irqs.valid_INT & (0x01 << cloop)) {
2296 rc = pciehp_set_irq(func->bus, func->device,
2297 0x0A + cloop, irqs.interrupt[cloop]);
2298 if (rc) {
2299 pciehp_destroy_resource_list (&temp_resources);
2300 return_resource(&(resources->bus_head), hold_bus_node);
2301 return_resource(&(resources->io_head), hold_IO_node);
2302 return_resource(&(resources->mem_head), hold_mem_node);
2303 return_resource(&(resources->p_mem_head), hold_p_mem_node);
2304 return rc;
2305 }
2306 }
2307 } /* end of for loop */
2308 }
2309
2310 /* Return unused bus resources
2311 * First use the temporary node to store information for the board
2312 */
2313 if (hold_bus_node && bus_node && temp_resources.bus_head) {
2314 hold_bus_node->length = bus_node->base - hold_bus_node->base;
2315
2316 hold_bus_node->next = func->bus_head;
2317 func->bus_head = hold_bus_node;
2318
2319 temp_byte = (u8)(temp_resources.bus_head->base - 1);
2320
2321 /* set subordinate bus */
2322 dbg("re-set subordinate bus = 0x%x\n", temp_byte);
2323 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
2324
2325 if (temp_resources.bus_head->length == 0) {
2326 kfree(temp_resources.bus_head);
2327 temp_resources.bus_head = NULL;
2328 } else {
2329 dbg("return bus res of b:d(0x%x:%x) base:len(0x%x:%x)\n",
2330 func->bus, func->device, temp_resources.bus_head->base, temp_resources.bus_head->length);
2331 return_resource(&(resources->bus_head), temp_resources.bus_head);
2332 }
2333 }
2334
2335 /* If we have IO space available and there is some left,
2336 * return the unused portion
2337 */
2338 if (hold_IO_node && temp_resources.io_head) {
2339 io_node = do_pre_bridge_resource_split(&(temp_resources.io_head),
2340 &hold_IO_node, 0x1000);
2341
2342 /* Check if we were able to split something off */
2343 if (io_node) {
2344 hold_IO_node->base = io_node->base + io_node->length;
2345
2346 RES_CHECK(hold_IO_node->base, 8);
2347 temp_byte = (u8)((hold_IO_node->base) >> 8);
2348 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
2349
2350 return_resource(&(resources->io_head), io_node);
2351 }
2352
2353 io_node = do_bridge_resource_split(&(temp_resources.io_head), 0x1000);
2354
2355 /* Check if we were able to split something off */
2356 if (io_node) {
2357 /* First use the temporary node to store information for the board */
2358 hold_IO_node->length = io_node->base - hold_IO_node->base;
2359
2360 /* If we used any, add it to the board's list */
2361 if (hold_IO_node->length) {
2362 hold_IO_node->next = func->io_head;
2363 func->io_head = hold_IO_node;
2364
2365 RES_CHECK(io_node->base - 1, 8);
2366 temp_byte = (u8)((io_node->base - 1) >> 8);
2367 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2368
2369 return_resource(&(resources->io_head), io_node);
2370 } else {
2371 /* it doesn't need any IO */
2372 temp_byte = 0x00;
2373 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2374
2375 return_resource(&(resources->io_head), io_node);
2376 kfree(hold_IO_node);
2377 }
2378 } else {
2379 /* it used most of the range */
2380 hold_IO_node->next = func->io_head;
2381 func->io_head = hold_IO_node;
2382 }
2383 } else if (hold_IO_node) {
2384 /* it used the whole range */
2385 hold_IO_node->next = func->io_head;
2386 func->io_head = hold_IO_node;
2387 }
2388
2389 /* If we have memory space available and there is some left,
2390 * return the unused portion
2391 */
2392 if (hold_mem_node && temp_resources.mem_head) {
2393 mem_node = do_pre_bridge_resource_split(&(temp_resources.mem_head), &hold_mem_node, 0x100000L);
2394
2395 /* Check if we were able to split something off */
2396 if (mem_node) {
2397 hold_mem_node->base = mem_node->base + mem_node->length;
2398
2399 RES_CHECK(hold_mem_node->base, 16);
2400 temp_word = (u16)((hold_mem_node->base) >> 16);
2401 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
2402
2403 return_resource(&(resources->mem_head), mem_node);
2404 }
2405
2406 mem_node = do_bridge_resource_split(&(temp_resources.mem_head), 0x100000L);
2407
2408 /* Check if we were able to split something off */
2409 if (mem_node) {
2410 /* First use the temporary node to store information for the board */
2411 hold_mem_node->length = mem_node->base - hold_mem_node->base;
2412
2413 if (hold_mem_node->length) {
2414 hold_mem_node->next = func->mem_head;
2415 func->mem_head = hold_mem_node;
2416
2417 /* configure end address */
2418 RES_CHECK(mem_node->base - 1, 16);
2419 temp_word = (u16)((mem_node->base - 1) >> 16);
2420 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2421
2422 /* Return unused resources to the pool */
2423 return_resource(&(resources->mem_head), mem_node);
2424 } else {
2425 /* it doesn't need any Mem */
2426 temp_word = 0x0000;
2427 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2428
2429 return_resource(&(resources->mem_head), mem_node);
2430 kfree(hold_mem_node);
2431 }
2432 } else {
2433 /* it used most of the range */
2434 hold_mem_node->next = func->mem_head;
2435 func->mem_head = hold_mem_node;
2436 }
2437 } else if (hold_mem_node) {
2438 /* it used the whole range */
2439 hold_mem_node->next = func->mem_head;
2440 func->mem_head = hold_mem_node;
2441 }
2442
2443 /* If we have prefetchable memory space available and there is some
2444 * left at the end, return the unused portion
2445 */
2446 if (hold_p_mem_node && temp_resources.p_mem_head) {
2447 p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head),
2448 &hold_p_mem_node, 0x100000L);
2449
2450 /* Check if we were able to split something off */
2451 if (p_mem_node) {
2452 hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;
2453
2454 RES_CHECK(hold_p_mem_node->base, 16);
2455 temp_word = (u16)((hold_p_mem_node->base) >> 16);
2456 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
2457
2458 return_resource(&(resources->p_mem_head), p_mem_node);
2459 }
2460
2461 p_mem_node = do_bridge_resource_split(&(temp_resources.p_mem_head), 0x100000L);
2462
2463 /* Check if we were able to split something off */
2464 if (p_mem_node) {
2465 /* First use the temporary node to store information for the board */
2466 hold_p_mem_node->length = p_mem_node->base - hold_p_mem_node->base;
2467
2468 /* If we used any, add it to the board's list */
2469 if (hold_p_mem_node->length) {
2470 hold_p_mem_node->next = func->p_mem_head;
2471 func->p_mem_head = hold_p_mem_node;
2472
2473 RES_CHECK(p_mem_node->base - 1, 16);
2474 temp_word = (u16)((p_mem_node->base - 1) >> 16);
2475 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2476
2477 return_resource(&(resources->p_mem_head), p_mem_node);
2478 } else {
2479 /* it doesn't need any PMem */
2480 temp_word = 0x0000;
2481 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2482
2483 return_resource(&(resources->p_mem_head), p_mem_node);
2484 kfree(hold_p_mem_node);
2485 }
2486 } else {
2487 /* it used the most of the range */
2488 hold_p_mem_node->next = func->p_mem_head;
2489 func->p_mem_head = hold_p_mem_node;
2490 }
2491 } else if (hold_p_mem_node) {
2492 /* it used the whole range */
2493 hold_p_mem_node->next = func->p_mem_head;
2494 func->p_mem_head = hold_p_mem_node;
2495 }
2496
2497 /* We should be configuring an IRQ and the bridge's base address
2498 * registers if it needs them. Although we have never seen such
2499 * a device
2500 */
2501
2502 pciehprm_enable_card(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
2503
2504 dbg("PCI Bridge Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function);
2505
2506 return rc;
2507}
2508
2509/**
2510 * configure_new_function - Configures the PCI header information of one device
2511 *
2512 * @ctrl: pointer to controller structure
2513 * @func: pointer to function structure
2514 * @behind_bridge: 1 if this is a recursive call, 0 if not
2515 * @resources: pointer to set of resource lists
2516 *
2517 * Calls itself recursively for bridged devices.
2518 * Returns 0 if success
2519 *
2520 */
2521static int
2522configure_new_function(struct controller *ctrl, struct pci_func *func,
2523 u8 behind_bridge, struct resource_lists *resources,
2524 u8 bridge_bus, u8 bridge_dev)
2525{
2526 int cloop;
2527 u8 temp_byte;
2528 u8 class_code;
2529 u16 temp_word;
2530 u32 rc;
2531 u32 temp_register;
2532 u32 base;
2533 unsigned int devfn;
2534 struct pci_resource *mem_node;
2535 struct pci_resource *io_node;
2536 struct pci_bus lpci_bus, *pci_bus;
2537
2538 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
2539 pci_bus = &lpci_bus;
2540 pci_bus->number = func->bus;
2541 devfn = PCI_DEVFN(func->device, func->function);
2542
2543 /* Check for Bridge */
2544 rc = pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &temp_byte);
2545 if (rc)
2546 return rc;
2547 dbg("%s: bus %x dev %x func %x temp_byte = %x\n", __FUNCTION__,
2548 func->bus, func->device, func->function, temp_byte);
2549
2550 if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
2551 rc = configure_new_bridge(ctrl, func, behind_bridge, resources,
2552 pci_bus);
2553
2554 if (rc)
2555 return rc;
2556 } else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
2557 /* Standard device */
2558 u64 base64;
2559 rc = pci_bus_read_config_byte(pci_bus, devfn, 0x0B, &class_code);
2560
2561 if (class_code == PCI_BASE_CLASS_DISPLAY)
2562 return DEVICE_TYPE_NOT_SUPPORTED;
2563
2564 /* Figure out IO and memory needs */
2565 for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
2566 temp_register = 0xFFFFFFFF;
2567
2568 rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
2569 rc = pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
2570 dbg("Bar[%x]=0x%x on bus:dev:func(0x%x:%x:%x)\n", cloop, temp_register,
2571 func->bus, func->device, func->function);
2572
2573 if (!temp_register)
2574 continue;
2575
2576 base64 = 0L;
2577 if (temp_register & PCI_BASE_ADDRESS_SPACE_IO) {
2578 /* Map IO */
2579
2580 /* set base = amount of IO space */
2581 base = temp_register & 0xFFFFFFFC;
2582 base = ~base + 1;
2583
2584 dbg("NEED IO length(0x%x)\n", base);
2585 io_node = get_io_resource(&(resources->io_head),(ulong)base);
2586
2587 /* allocate the resource to the board */
2588 if (io_node) {
2589 dbg("Got IO base=0x%x(length=0x%x)\n", io_node->base, io_node->length);
2590 base = (u32)io_node->base;
2591 io_node->next = func->io_head;
2592 func->io_head = io_node;
2593 } else {
2594 err("Got NO IO resource(length=0x%x)\n", base);
2595 return -ENOMEM;
2596 }
2597 } else { /* map MEM */
2598 int prefetchable = 1;
2599 struct pci_resource **res_node = &func->p_mem_head;
2600 char *res_type_str = "PMEM";
2601 u32 temp_register2;
2602
2603 if (!(temp_register & PCI_BASE_ADDRESS_MEM_PREFETCH)) {
2604 prefetchable = 0;
2605 res_node = &func->mem_head;
2606 res_type_str++;
2607 }
2608
2609 base = temp_register & 0xFFFFFFF0;
2610 base = ~base + 1;
2611
2612 switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
2613 case PCI_BASE_ADDRESS_MEM_TYPE_32:
2614 dbg("NEED 32 %s bar=0x%x(length=0x%x)\n", res_type_str, temp_register, base);
2615
2616 if (prefetchable && resources->p_mem_head)
2617 mem_node=get_resource(&(resources->p_mem_head), (ulong)base);
2618 else {
2619 if (prefetchable)
2620 dbg("using MEM for PMEM\n");
2621 mem_node = get_resource(&(resources->mem_head), (ulong)base);
2622 }
2623
2624 /* allocate the resource to the board */
2625 if (mem_node) {
2626 base = (u32)mem_node->base;
2627 mem_node->next = *res_node;
2628 *res_node = mem_node;
2629 dbg("Got 32 %s base=0x%x(length=0x%x)\n", res_type_str, mem_node->base,
2630 mem_node->length);
2631 } else {
2632 err("Got NO 32 %s resource(length=0x%x)\n", res_type_str, base);
2633 return -ENOMEM;
2634 }
2635 break;
2636 case PCI_BASE_ADDRESS_MEM_TYPE_64:
2637 rc = pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
2638 dbg("NEED 64 %s bar=0x%x:%x(length=0x%x)\n", res_type_str, temp_register2,
2639 temp_register, base);
2640
2641 if (prefetchable && resources->p_mem_head)
2642 mem_node = get_resource(&(resources->p_mem_head), (ulong)base);
2643 else {
2644 if (prefetchable)
2645 dbg("using MEM for PMEM\n");
2646 mem_node = get_resource(&(resources->mem_head), (ulong)base);
2647 }
2648
2649 /* allocate the resource to the board */
2650 if (mem_node) {
2651 base64 = mem_node->base;
2652 mem_node->next = *res_node;
2653 *res_node = mem_node;
2654 dbg("Got 64 %s base=0x%x:%x(length=%x)\n", res_type_str, (u32)(base64 >> 32),
2655 (u32)base64, mem_node->length);
2656 } else {
2657 err("Got NO 64 %s resource(length=0x%x)\n", res_type_str, base);
2658 return -ENOMEM;
2659 }
2660 break;
2661 default:
2662 dbg("reserved BAR type=0x%x\n", temp_register);
2663 break;
2664 }
2665
2666 }
2667
2668 if (base64) {
2669 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
2670 cloop += 4;
2671 base64 >>= 32;
2672
2673 if (base64) {
2674 dbg("%s: high dword of base64(0x%x) set to 0\n", __FUNCTION__, (u32)base64);
2675 base64 = 0x0L;
2676 }
2677
2678 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
2679 } else {
2680 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, base);
2681 }
2682 } /* End of base register loop */
2683
2684 /* disable ROM base Address */
2685 temp_word = 0x00L;
2686 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_ROM_ADDRESS, temp_word);
2687
2688 /* Set HP parameters (Cache Line Size, Latency Timer) */
2689 rc = pciehprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_NORMAL);
2690 if (rc)
2691 return rc;
2692
2693 pciehprm_enable_card(ctrl, func, PCI_HEADER_TYPE_NORMAL);
2694
2695 dbg("PCI function Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device,
2696 func->function);
2697 } /* End of Not-A-Bridge else */
2698 else {
2699 /* It's some strange type of PCI adapter (Cardbus?) */
2700 return DEVICE_TYPE_NOT_SUPPORTED;
2701 }
2702
2703 func->configured = 1;
2704
2705 return 0;
2706}
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
new file mode 100644
index 000000000000..9e70c4681f77
--- /dev/null
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -0,0 +1,1501 @@
1/*
2 * PCI Express PCI Hot Plug Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>,<dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/kernel.h>
32#include <linux/module.h>
33#include <linux/types.h>
34#include <linux/slab.h>
35#include <linux/vmalloc.h>
36#include <linux/interrupt.h>
37#include <linux/spinlock.h>
38#include <linux/pci.h>
39#include <asm/system.h>
40#include "../pci.h"
41#include "pciehp.h"
42
43#ifdef DEBUG
44#define DBG_K_TRACE_ENTRY ((unsigned int)0x00000001) /* On function entry */
45#define DBG_K_TRACE_EXIT ((unsigned int)0x00000002) /* On function exit */
46#define DBG_K_INFO ((unsigned int)0x00000004) /* Info messages */
47#define DBG_K_ERROR ((unsigned int)0x00000008) /* Error messages */
48#define DBG_K_TRACE (DBG_K_TRACE_ENTRY|DBG_K_TRACE_EXIT)
49#define DBG_K_STANDARD (DBG_K_INFO|DBG_K_ERROR|DBG_K_TRACE)
50/* Redefine this flagword to set debug level */
51#define DEBUG_LEVEL DBG_K_STANDARD
52
53#define DEFINE_DBG_BUFFER char __dbg_str_buf[256];
54
55#define DBG_PRINT( dbg_flags, args... ) \
56 do { \
57 if ( DEBUG_LEVEL & ( dbg_flags ) ) \
58 { \
59 int len; \
60 len = sprintf( __dbg_str_buf, "%s:%d: %s: ", \
61 __FILE__, __LINE__, __FUNCTION__ ); \
62 sprintf( __dbg_str_buf + len, args ); \
63 printk( KERN_NOTICE "%s\n", __dbg_str_buf ); \
64 } \
65 } while (0)
66
67#define DBG_ENTER_ROUTINE DBG_PRINT (DBG_K_TRACE_ENTRY, "%s", "[Entry]");
68#define DBG_LEAVE_ROUTINE DBG_PRINT (DBG_K_TRACE_EXIT, "%s", "[Exit]");
69#else
70#define DEFINE_DBG_BUFFER
71#define DBG_ENTER_ROUTINE
72#define DBG_LEAVE_ROUTINE
73#endif /* DEBUG */
74
75struct ctrl_reg {
76 u8 cap_id;
77 u8 nxt_ptr;
78 u16 cap_reg;
79 u32 dev_cap;
80 u16 dev_ctrl;
81 u16 dev_status;
82 u32 lnk_cap;
83 u16 lnk_ctrl;
84 u16 lnk_status;
85 u32 slot_cap;
86 u16 slot_ctrl;
87 u16 slot_status;
88 u16 root_ctrl;
89 u16 rsvp;
90 u32 root_status;
91} __attribute__ ((packed));
92
93/* offsets to the controller registers based on the above structure layout */
94enum ctrl_offsets {
95 PCIECAPID = offsetof(struct ctrl_reg, cap_id),
96 NXTCAPPTR = offsetof(struct ctrl_reg, nxt_ptr),
97 CAPREG = offsetof(struct ctrl_reg, cap_reg),
98 DEVCAP = offsetof(struct ctrl_reg, dev_cap),
99 DEVCTRL = offsetof(struct ctrl_reg, dev_ctrl),
100 DEVSTATUS = offsetof(struct ctrl_reg, dev_status),
101 LNKCAP = offsetof(struct ctrl_reg, lnk_cap),
102 LNKCTRL = offsetof(struct ctrl_reg, lnk_ctrl),
103 LNKSTATUS = offsetof(struct ctrl_reg, lnk_status),
104 SLOTCAP = offsetof(struct ctrl_reg, slot_cap),
105 SLOTCTRL = offsetof(struct ctrl_reg, slot_ctrl),
106 SLOTSTATUS = offsetof(struct ctrl_reg, slot_status),
107 ROOTCTRL = offsetof(struct ctrl_reg, root_ctrl),
108 ROOTSTATUS = offsetof(struct ctrl_reg, root_status),
109};
110static int pcie_cap_base = 0; /* Base of the PCI Express capability item structure */
111
112#define PCIE_CAP_ID ( pcie_cap_base + PCIECAPID )
113#define NXT_CAP_PTR ( pcie_cap_base + NXTCAPPTR )
114#define CAP_REG ( pcie_cap_base + CAPREG )
115#define DEV_CAP ( pcie_cap_base + DEVCAP )
116#define DEV_CTRL ( pcie_cap_base + DEVCTRL )
117#define DEV_STATUS ( pcie_cap_base + DEVSTATUS )
118#define LNK_CAP ( pcie_cap_base + LNKCAP )
119#define LNK_CTRL ( pcie_cap_base + LNKCTRL )
120#define LNK_STATUS ( pcie_cap_base + LNKSTATUS )
121#define SLOT_CAP ( pcie_cap_base + SLOTCAP )
122#define SLOT_CTRL ( pcie_cap_base + SLOTCTRL )
123#define SLOT_STATUS ( pcie_cap_base + SLOTSTATUS )
124#define ROOT_CTRL ( pcie_cap_base + ROOTCTRL )
125#define ROOT_STATUS ( pcie_cap_base + ROOTSTATUS )
126
127#define hp_register_read_word(pdev, reg , value) \
128 pci_read_config_word(pdev, reg, &value)
129
130#define hp_register_read_dword(pdev, reg , value) \
131 pci_read_config_dword(pdev, reg, &value)
132
133#define hp_register_write_word(pdev, reg , value) \
134 pci_write_config_word(pdev, reg, value)
135
136#define hp_register_dwrite_word(pdev, reg , value) \
137 pci_write_config_dword(pdev, reg, value)
138
139/* Field definitions in PCI Express Capabilities Register */
140#define CAP_VER 0x000F
141#define DEV_PORT_TYPE 0x00F0
142#define SLOT_IMPL 0x0100
143#define MSG_NUM 0x3E00
144
145/* Device or Port Type */
146#define NAT_ENDPT 0x00
147#define LEG_ENDPT 0x01
148#define ROOT_PORT 0x04
149#define UP_STREAM 0x05
150#define DN_STREAM 0x06
151#define PCIE_PCI_BRDG 0x07
152#define PCI_PCIE_BRDG 0x10
153
154/* Field definitions in Device Capabilities Register */
155#define DATTN_BUTTN_PRSN 0x1000
156#define DATTN_LED_PRSN 0x2000
157#define DPWR_LED_PRSN 0x4000
158
159/* Field definitions in Link Capabilities Register */
160#define MAX_LNK_SPEED 0x000F
161#define MAX_LNK_WIDTH 0x03F0
162
163/* Link Width Encoding */
164#define LNK_X1 0x01
165#define LNK_X2 0x02
166#define LNK_X4 0x04
167#define LNK_X8 0x08
168#define LNK_X12 0x0C
169#define LNK_X16 0x10
170#define LNK_X32 0x20
171
172/*Field definitions of Link Status Register */
173#define LNK_SPEED 0x000F
174#define NEG_LINK_WD 0x03F0
175#define LNK_TRN_ERR 0x0400
176#define LNK_TRN 0x0800
177#define SLOT_CLK_CONF 0x1000
178
179/* Field definitions in Slot Capabilities Register */
180#define ATTN_BUTTN_PRSN 0x00000001
181#define PWR_CTRL_PRSN 0x00000002
182#define MRL_SENS_PRSN 0x00000004
183#define ATTN_LED_PRSN 0x00000008
184#define PWR_LED_PRSN 0x00000010
185#define HP_SUPR_RM_SUP 0x00000020
186#define HP_CAP 0x00000040
187#define SLOT_PWR_VALUE 0x000003F8
188#define SLOT_PWR_LIMIT 0x00000C00
189#define PSN 0xFFF80000 /* PSN: Physical Slot Number */
190
191/* Field definitions in Slot Control Register */
192#define ATTN_BUTTN_ENABLE 0x0001
193#define PWR_FAULT_DETECT_ENABLE 0x0002
194#define MRL_DETECT_ENABLE 0x0004
195#define PRSN_DETECT_ENABLE 0x0008
196#define CMD_CMPL_INTR_ENABLE 0x0010
197#define HP_INTR_ENABLE 0x0020
198#define ATTN_LED_CTRL 0x00C0
199#define PWR_LED_CTRL 0x0300
200#define PWR_CTRL 0x0400
201
202/* Attention indicator and Power indicator states */
203#define LED_ON 0x01
204#define LED_BLINK 0x10
205#define LED_OFF 0x11
206
207/* Power Control Command */
208#define POWER_ON 0
209#define POWER_OFF 0x0400
210
211/* Field definitions in Slot Status Register */
212#define ATTN_BUTTN_PRESSED 0x0001
213#define PWR_FAULT_DETECTED 0x0002
214#define MRL_SENS_CHANGED 0x0004
215#define PRSN_DETECT_CHANGED 0x0008
216#define CMD_COMPLETED 0x0010
217#define MRL_STATE 0x0020
218#define PRSN_STATE 0x0040
219
220struct php_ctlr_state_s {
221 struct php_ctlr_state_s *pnext;
222 struct pci_dev *pci_dev;
223 unsigned int irq;
224 unsigned long flags; /* spinlock's */
225 u32 slot_device_offset;
226 u32 num_slots;
227 struct timer_list int_poll_timer; /* Added for poll event */
228 php_intr_callback_t attention_button_callback;
229 php_intr_callback_t switch_change_callback;
230 php_intr_callback_t presence_change_callback;
231 php_intr_callback_t power_fault_callback;
232 void *callback_instance_id;
233 struct ctrl_reg *creg; /* Ptr to controller register space */
234};
235
236
237static spinlock_t hpc_event_lock;
238
239DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */
240static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */
241static int ctlr_seq_num = 0; /* Controller sequence # */
242static spinlock_t list_lock;
243
244static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs);
245
246static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds);
247
248/* This is the interrupt polling timeout function. */
249static void int_poll_timeout(unsigned long lphp_ctlr)
250{
251 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *)lphp_ctlr;
252
253 DBG_ENTER_ROUTINE
254
255 if ( !php_ctlr ) {
256 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
257 return;
258 }
259
260 /* Poll for interrupt events. regs == NULL => polling */
261 pcie_isr( 0, (void *)php_ctlr, NULL );
262
263 init_timer(&php_ctlr->int_poll_timer);
264
265 if (!pciehp_poll_time)
266 pciehp_poll_time = 2; /* reset timer to poll in 2 secs if user doesn't specify at module installation*/
267
268 start_int_poll_timer(php_ctlr, pciehp_poll_time);
269
270 return;
271}
272
273/* This function starts the interrupt polling timer. */
274static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds)
275{
276 if (!php_ctlr) {
277 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
278 return;
279 }
280
281 if ( ( seconds <= 0 ) || ( seconds > 60 ) )
282 seconds = 2; /* Clamp to sane value */
283
284 php_ctlr->int_poll_timer.function = &int_poll_timeout;
285 php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr; /* Instance data */
286 php_ctlr->int_poll_timer.expires = jiffies + seconds * HZ;
287 add_timer(&php_ctlr->int_poll_timer);
288
289 return;
290}
291
292static int pcie_write_cmd(struct slot *slot, u16 cmd)
293{
294 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
295 int retval = 0;
296 u16 slot_status;
297
298 DBG_ENTER_ROUTINE
299
300 dbg("%s : Enter\n", __FUNCTION__);
301 if (!php_ctlr) {
302 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
303 return -1;
304 }
305
306 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
307 if (retval) {
308 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
309 return retval;
310 }
311 dbg("%s : hp_register_read_word SLOT_STATUS %x\n", __FUNCTION__, slot_status);
312
313 if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) {
314 /* After 1 sec and CMD_COMPLETED still not set, just proceed forward to issue
315 the next command according to spec. Just print out the error message */
316 dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__);
317 }
318
319 dbg("%s: Before hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd);
320 retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, cmd | CMD_CMPL_INTR_ENABLE);
321 if (retval) {
322 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
323 return retval;
324 }
325 dbg("%s : hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd | CMD_CMPL_INTR_ENABLE);
326 dbg("%s : Exit\n", __FUNCTION__);
327
328 DBG_LEAVE_ROUTINE
329 return retval;
330}
331
332static int hpc_check_lnk_status(struct controller *ctrl)
333{
334 struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
335 u16 lnk_status;
336 int retval = 0;
337
338 DBG_ENTER_ROUTINE
339
340 if (!php_ctlr) {
341 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
342 return -1;
343 }
344
345 retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status);
346
347 if (retval) {
348 err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
349 return retval;
350 }
351
352 dbg("%s: lnk_status = %x\n", __FUNCTION__, lnk_status);
353 if ( (lnk_status & LNK_TRN) || (lnk_status & LNK_TRN_ERR) ||
354 !(lnk_status & NEG_LINK_WD)) {
355 err("%s : Link Training Error occurs \n", __FUNCTION__);
356 retval = -1;
357 return retval;
358 }
359
360 DBG_LEAVE_ROUTINE
361 return retval;
362}
363
364
365static int hpc_get_attention_status(struct slot *slot, u8 *status)
366{
367 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
368 u16 slot_ctrl;
369 u8 atten_led_state;
370 int retval = 0;
371
372 DBG_ENTER_ROUTINE
373
374 if (!php_ctlr) {
375 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
376 return -1;
377 }
378
379 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
380
381 if (retval) {
382 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
383 return retval;
384 }
385
386 dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__,SLOT_CTRL, slot_ctrl);
387
388 atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6;
389
390 switch (atten_led_state) {
391 case 0:
392 *status = 0xFF; /* Reserved */
393 break;
394 case 1:
395 *status = 1; /* On */
396 break;
397 case 2:
398 *status = 2; /* Blink */
399 break;
400 case 3:
401 *status = 0; /* Off */
402 break;
403 default:
404 *status = 0xFF;
405 break;
406 }
407
408 DBG_LEAVE_ROUTINE
409 return 0;
410}
411
412static int hpc_get_power_status(struct slot * slot, u8 *status)
413{
414 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
415 u16 slot_ctrl;
416 u8 pwr_state;
417 int retval = 0;
418
419 DBG_ENTER_ROUTINE
420
421 if (!php_ctlr) {
422 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
423 return -1;
424 }
425
426 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
427
428 if (retval) {
429 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
430 return retval;
431 }
432 dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, slot_ctrl);
433
434 pwr_state = (slot_ctrl & PWR_CTRL) >> 10;
435
436 switch (pwr_state) {
437 case 0:
438 *status = 1;
439 break;
440 case 1:
441 *status = 0;
442 break;
443 default:
444 *status = 0xFF;
445 break;
446 }
447
448 DBG_LEAVE_ROUTINE
449 return retval;
450}
451
452
453static int hpc_get_latch_status(struct slot *slot, u8 *status)
454{
455 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
456 u16 slot_status;
457 int retval = 0;
458
459 DBG_ENTER_ROUTINE
460
461 if (!php_ctlr) {
462 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
463 return -1;
464 }
465
466 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
467
468 if (retval) {
469 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
470 return retval;
471 }
472
473 *status = (((slot_status & MRL_STATE) >> 5) == 0) ? 0 : 1;
474
475 DBG_LEAVE_ROUTINE
476 return 0;
477}
478
479static int hpc_get_adapter_status(struct slot *slot, u8 *status)
480{
481 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
482 u16 slot_status;
483 u8 card_state;
484 int retval = 0;
485
486 DBG_ENTER_ROUTINE
487
488 if (!php_ctlr) {
489 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
490 return -1;
491 }
492
493 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
494
495 if (retval) {
496 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
497 return retval;
498 }
499 card_state = (u8)((slot_status & PRSN_STATE) >> 6);
500 *status = (card_state == 1) ? 1 : 0;
501
502 DBG_LEAVE_ROUTINE
503 return 0;
504}
505
506static int hpc_query_power_fault(struct slot * slot)
507{
508 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
509 u16 slot_status;
510 u8 pwr_fault;
511 int retval = 0;
512 u8 status;
513
514 DBG_ENTER_ROUTINE
515
516 if (!php_ctlr) {
517 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
518 return -1;
519 }
520
521 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
522
523 if (retval) {
524 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
525 return retval;
526 }
527 pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1);
528 status = (pwr_fault != 1) ? 1 : 0;
529
530 DBG_LEAVE_ROUTINE
531 /* Note: Logic 0 => fault */
532 return status;
533}
534
535static int hpc_set_attention_status(struct slot *slot, u8 value)
536{
537 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
538 u16 slot_cmd = 0;
539 u16 slot_ctrl;
540 int rc = 0;
541
542 dbg("%s: \n", __FUNCTION__);
543 if (!php_ctlr) {
544 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
545 return -1;
546 }
547
548 if (slot->hp_slot >= php_ctlr->num_slots) {
549 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
550 return -1;
551 }
552 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
553
554 if (rc) {
555 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
556 return rc;
557 }
558 dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
559
560 switch (value) {
561 case 0 : /* turn off */
562 slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x00C0;
563 break;
564 case 1: /* turn on */
565 slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x0040;
566 break;
567 case 2: /* turn blink */
568 slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x0080;
569 break;
570 default:
571 return -1;
572 }
573 if (!pciehp_poll_mode)
574 slot_cmd = slot_cmd | HP_INTR_ENABLE;
575
576 pcie_write_cmd(slot, slot_cmd);
577 dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL, slot_cmd);
578
579 return rc;
580}
581
582
583static void hpc_set_green_led_on(struct slot *slot)
584{
585 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
586 u16 slot_cmd;
587 u16 slot_ctrl;
588 int rc = 0;
589
590 dbg("%s: \n", __FUNCTION__);
591 if (!php_ctlr) {
592 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
593 return ;
594 }
595
596 if (slot->hp_slot >= php_ctlr->num_slots) {
597 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
598 return ;
599 }
600
601 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
602
603 if (rc) {
604 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
605 return;
606 }
607 dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
608 slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0100;
609 if (!pciehp_poll_mode)
610 slot_cmd = slot_cmd | HP_INTR_ENABLE;
611
612 pcie_write_cmd(slot, slot_cmd);
613
614 dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd);
615 return;
616}
617
618static void hpc_set_green_led_off(struct slot *slot)
619{
620 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
621 u16 slot_cmd;
622 u16 slot_ctrl;
623 int rc = 0;
624
625 dbg("%s: \n", __FUNCTION__);
626 if (!php_ctlr) {
627 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
628 return ;
629 }
630
631 if (slot->hp_slot >= php_ctlr->num_slots) {
632 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
633 return ;
634 }
635
636 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
637
638 if (rc) {
639 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
640 return;
641 }
642 dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
643
644 slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0300;
645
646 if (!pciehp_poll_mode)
647 slot_cmd = slot_cmd | HP_INTR_ENABLE;
648 pcie_write_cmd(slot, slot_cmd);
649 dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL, slot_cmd);
650
651 return;
652}
653
654static void hpc_set_green_led_blink(struct slot *slot)
655{
656 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
657 u16 slot_cmd;
658 u16 slot_ctrl;
659 int rc = 0;
660
661 dbg("%s: \n", __FUNCTION__);
662 if (!php_ctlr) {
663 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
664 return ;
665 }
666
667 if (slot->hp_slot >= php_ctlr->num_slots) {
668 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
669 return ;
670 }
671
672 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
673
674 if (rc) {
675 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
676 return;
677 }
678 dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
679
680 slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0200;
681
682 if (!pciehp_poll_mode)
683 slot_cmd = slot_cmd | HP_INTR_ENABLE;
684 pcie_write_cmd(slot, slot_cmd);
685
686 dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd);
687 return;
688}
689
690int pcie_get_ctlr_slot_config(struct controller *ctrl,
691 int *num_ctlr_slots, /* number of slots in this HPC; only 1 in PCIE */
692 int *first_device_num, /* PCI dev num of the first slot in this PCIE */
693 int *physical_slot_num, /* phy slot num of the first slot in this PCIE */
694 u8 *ctrlcap)
695{
696 struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
697 u32 slot_cap;
698 int rc = 0;
699
700 DBG_ENTER_ROUTINE
701
702 if (!php_ctlr) {
703 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
704 return -1;
705 }
706
707 *first_device_num = 0;
708 *num_ctlr_slots = 1;
709
710 rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP, slot_cap);
711
712 if (rc) {
713 err("%s : hp_register_read_dword SLOT_CAP failed\n", __FUNCTION__);
714 return -1;
715 }
716
717 *physical_slot_num = slot_cap >> 19;
718 dbg("%s: PSN %d \n", __FUNCTION__, *physical_slot_num);
719
720 *ctrlcap = slot_cap & 0x0000007f;
721
722 DBG_LEAVE_ROUTINE
723 return 0;
724}
725
726static void hpc_release_ctlr(struct controller *ctrl)
727{
728 struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
729 struct php_ctlr_state_s *p, *p_prev;
730
731 DBG_ENTER_ROUTINE
732
733 if (!php_ctlr) {
734 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
735 return ;
736 }
737
738 if (pciehp_poll_mode) {
739 del_timer(&php_ctlr->int_poll_timer);
740 } else {
741 if (php_ctlr->irq) {
742 free_irq(php_ctlr->irq, ctrl);
743 php_ctlr->irq = 0;
744 if (!pcie_mch_quirk)
745 pci_disable_msi(php_ctlr->pci_dev);
746 }
747 }
748 if (php_ctlr->pci_dev)
749 php_ctlr->pci_dev = NULL;
750
751 spin_lock(&list_lock);
752 p = php_ctlr_list_head;
753 p_prev = NULL;
754 while (p) {
755 if (p == php_ctlr) {
756 if (p_prev)
757 p_prev->pnext = p->pnext;
758 else
759 php_ctlr_list_head = p->pnext;
760 break;
761 } else {
762 p_prev = p;
763 p = p->pnext;
764 }
765 }
766 spin_unlock(&list_lock);
767
768 kfree(php_ctlr);
769
770 DBG_LEAVE_ROUTINE
771
772}
773
774static int hpc_power_on_slot(struct slot * slot)
775{
776 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
777 u16 slot_cmd;
778 u16 slot_ctrl;
779
780 int retval = 0;
781
782 DBG_ENTER_ROUTINE
783 dbg("%s: \n", __FUNCTION__);
784
785 if (!php_ctlr) {
786 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
787 return -1;
788 }
789
790 dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot);
791 if (slot->hp_slot >= php_ctlr->num_slots) {
792 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
793 return -1;
794 }
795
796 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
797
798 if (retval) {
799 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
800 return retval;
801 }
802 dbg("%s: SLOT_CTRL %x, value read %xn", __FUNCTION__, SLOT_CTRL,
803 slot_ctrl);
804
805 slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON;
806
807 if (!pciehp_poll_mode)
808 slot_cmd = slot_cmd | HP_INTR_ENABLE;
809
810 retval = pcie_write_cmd(slot, slot_cmd);
811
812 if (retval) {
813 err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd);
814 return -1;
815 }
816 dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd);
817
818 DBG_LEAVE_ROUTINE
819
820 return retval;
821}
822
823static int hpc_power_off_slot(struct slot * slot)
824{
825 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
826 u16 slot_cmd;
827 u16 slot_ctrl;
828
829 int retval = 0;
830
831 DBG_ENTER_ROUTINE
832 dbg("%s: \n", __FUNCTION__);
833
834 if (!php_ctlr) {
835 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
836 return -1;
837 }
838
839 dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot);
840 slot->hp_slot = 0;
841 if (slot->hp_slot >= php_ctlr->num_slots) {
842 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
843 return -1;
844 }
845 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
846
847 if (retval) {
848 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
849 return retval;
850 }
851 dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__, SLOT_CTRL,
852 slot_ctrl);
853
854 slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF;
855
856 if (!pciehp_poll_mode)
857 slot_cmd = slot_cmd | HP_INTR_ENABLE;
858
859 retval = pcie_write_cmd(slot, slot_cmd);
860
861 if (retval) {
862 err("%s: Write command failed!\n", __FUNCTION__);
863 return -1;
864 }
865 dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd);
866
867 DBG_LEAVE_ROUTINE
868
869 return retval;
870}
871
872static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
873{
874 struct controller *ctrl = NULL;
875 struct php_ctlr_state_s *php_ctlr;
876 u8 schedule_flag = 0;
877 u16 slot_status, intr_detect, intr_loc;
878 u16 temp_word;
879 int hp_slot = 0; /* only 1 slot per PCI Express port */
880 int rc = 0;
881
882 if (!dev_id)
883 return IRQ_NONE;
884
885 if (!pciehp_poll_mode) {
886 ctrl = dev_id;
887 php_ctlr = ctrl->hpc_ctlr_handle;
888 } else {
889 php_ctlr = dev_id;
890 ctrl = (struct controller *)php_ctlr->callback_instance_id;
891 }
892
893 if (!ctrl) {
894 dbg("%s: dev_id %p ctlr == NULL\n", __FUNCTION__, (void*) dev_id);
895 return IRQ_NONE;
896 }
897
898 if (!php_ctlr) {
899 dbg("%s: php_ctlr == NULL\n", __FUNCTION__);
900 return IRQ_NONE;
901 }
902
903 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
904 if (rc) {
905 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
906 return IRQ_NONE;
907 }
908
909 intr_detect = ( ATTN_BUTTN_PRESSED | PWR_FAULT_DETECTED | MRL_SENS_CHANGED |
910 PRSN_DETECT_CHANGED | CMD_COMPLETED );
911
912 intr_loc = slot_status & intr_detect;
913
914 /* Check to see if it was our interrupt */
915 if ( !intr_loc )
916 return IRQ_NONE;
917
918 dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc);
919 /* Mask Hot-plug Interrupt Enable */
920 if (!pciehp_poll_mode) {
921 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
922 if (rc) {
923 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
924 return IRQ_NONE;
925 }
926
927 dbg("%s: Set Mask Hot-plug Interrupt Enable\n", __FUNCTION__);
928 dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
929 temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
930
931 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
932 if (rc) {
933 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
934 return IRQ_NONE;
935 }
936 dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
937
938 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
939 if (rc) {
940 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
941 return IRQ_NONE;
942 }
943 dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status);
944
945 /* Clear command complete interrupt caused by this write */
946 temp_word = 0x1f;
947 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
948 if (rc) {
949 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
950 return IRQ_NONE;
951 }
952 dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word);
953 }
954
955 if (intr_loc & CMD_COMPLETED) {
956 /*
957 * Command Complete Interrupt Pending
958 */
959 dbg("%s: In Command Complete Interrupt Pending\n", __FUNCTION__);
960 wake_up_interruptible(&ctrl->queue);
961 }
962
963 if ((php_ctlr->switch_change_callback) && (intr_loc & MRL_SENS_CHANGED))
964 schedule_flag += php_ctlr->switch_change_callback(
965 hp_slot, php_ctlr->callback_instance_id);
966 if ((php_ctlr->attention_button_callback) && (intr_loc & ATTN_BUTTN_PRESSED))
967 schedule_flag += php_ctlr->attention_button_callback(
968 hp_slot, php_ctlr->callback_instance_id);
969 if ((php_ctlr->presence_change_callback) && (intr_loc & PRSN_DETECT_CHANGED))
970 schedule_flag += php_ctlr->presence_change_callback(
971 hp_slot , php_ctlr->callback_instance_id);
972 if ((php_ctlr->power_fault_callback) && (intr_loc & PWR_FAULT_DETECTED))
973 schedule_flag += php_ctlr->power_fault_callback(
974 hp_slot, php_ctlr->callback_instance_id);
975
976 /* Clear all events after serving them */
977 temp_word = 0x1F;
978 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
979 if (rc) {
980 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
981 return IRQ_NONE;
982 }
983 /* Unmask Hot-plug Interrupt Enable */
984 if (!pciehp_poll_mode) {
985 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
986 if (rc) {
987 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
988 return IRQ_NONE;
989 }
990
991 dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__);
992 dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
993 temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
994
995 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
996 if (rc) {
997 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
998 return IRQ_NONE;
999 }
1000 dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
1001
1002 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
1003 if (rc) {
1004 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
1005 return IRQ_NONE;
1006 }
1007 dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status);
1008
1009 /* Clear command complete interrupt caused by this write */
1010 temp_word = 0x1F;
1011 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
1012 if (rc) {
1013 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
1014 return IRQ_NONE;
1015 }
1016 dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word);
1017 }
1018
1019 return IRQ_HANDLED;
1020}
1021
1022static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
1023{
1024 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
1025 enum pcie_link_speed lnk_speed;
1026 u32 lnk_cap;
1027 int retval = 0;
1028
1029 DBG_ENTER_ROUTINE
1030
1031 if (!php_ctlr) {
1032 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
1033 return -1;
1034 }
1035
1036 if (slot->hp_slot >= php_ctlr->num_slots) {
1037 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
1038 return -1;
1039 }
1040
1041 retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP, lnk_cap);
1042
1043 if (retval) {
1044 err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__);
1045 return retval;
1046 }
1047
1048 switch (lnk_cap & 0x000F) {
1049 case 1:
1050 lnk_speed = PCIE_2PT5GB;
1051 break;
1052 default:
1053 lnk_speed = PCIE_LNK_SPEED_UNKNOWN;
1054 break;
1055 }
1056
1057 *value = lnk_speed;
1058 dbg("Max link speed = %d\n", lnk_speed);
1059 DBG_LEAVE_ROUTINE
1060 return retval;
1061}
1062
1063static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value)
1064{
1065 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
1066 enum pcie_link_width lnk_wdth;
1067 u32 lnk_cap;
1068 int retval = 0;
1069
1070 DBG_ENTER_ROUTINE
1071
1072 if (!php_ctlr) {
1073 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
1074 return -1;
1075 }
1076
1077 if (slot->hp_slot >= php_ctlr->num_slots) {
1078 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
1079 return -1;
1080 }
1081
1082 retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP, lnk_cap);
1083
1084 if (retval) {
1085 err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__);
1086 return retval;
1087 }
1088
1089 switch ((lnk_cap & 0x03F0) >> 4){
1090 case 0:
1091 lnk_wdth = PCIE_LNK_WIDTH_RESRV;
1092 break;
1093 case 1:
1094 lnk_wdth = PCIE_LNK_X1;
1095 break;
1096 case 2:
1097 lnk_wdth = PCIE_LNK_X2;
1098 break;
1099 case 4:
1100 lnk_wdth = PCIE_LNK_X4;
1101 break;
1102 case 8:
1103 lnk_wdth = PCIE_LNK_X8;
1104 break;
1105 case 12:
1106 lnk_wdth = PCIE_LNK_X12;
1107 break;
1108 case 16:
1109 lnk_wdth = PCIE_LNK_X16;
1110 break;
1111 case 32:
1112 lnk_wdth = PCIE_LNK_X32;
1113 break;
1114 default:
1115 lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN;
1116 break;
1117 }
1118
1119 *value = lnk_wdth;
1120 dbg("Max link width = %d\n", lnk_wdth);
1121 DBG_LEAVE_ROUTINE
1122 return retval;
1123}
1124
1125static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
1126{
1127 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
1128 enum pcie_link_speed lnk_speed = PCI_SPEED_UNKNOWN;
1129 int retval = 0;
1130 u16 lnk_status;
1131
1132 DBG_ENTER_ROUTINE
1133
1134 if (!php_ctlr) {
1135 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
1136 return -1;
1137 }
1138
1139 if (slot->hp_slot >= php_ctlr->num_slots) {
1140 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
1141 return -1;
1142 }
1143
1144 retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status);
1145
1146 if (retval) {
1147 err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
1148 return retval;
1149 }
1150
1151 switch (lnk_status & 0x0F) {
1152 case 1:
1153 lnk_speed = PCIE_2PT5GB;
1154 break;
1155 default:
1156 lnk_speed = PCIE_LNK_SPEED_UNKNOWN;
1157 break;
1158 }
1159
1160 *value = lnk_speed;
1161 dbg("Current link speed = %d\n", lnk_speed);
1162 DBG_LEAVE_ROUTINE
1163 return retval;
1164}
1165
1166static int hpc_get_cur_lnk_width (struct slot *slot, enum pcie_link_width *value)
1167{
1168 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
1169 enum pcie_link_width lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN;
1170 int retval = 0;
1171 u16 lnk_status;
1172
1173 DBG_ENTER_ROUTINE
1174
1175 if (!php_ctlr) {
1176 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
1177 return -1;
1178 }
1179
1180 if (slot->hp_slot >= php_ctlr->num_slots) {
1181 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
1182 return -1;
1183 }
1184
1185 retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status);
1186
1187 if (retval) {
1188 err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
1189 return retval;
1190 }
1191
1192 switch ((lnk_status & 0x03F0) >> 4){
1193 case 0:
1194 lnk_wdth = PCIE_LNK_WIDTH_RESRV;
1195 break;
1196 case 1:
1197 lnk_wdth = PCIE_LNK_X1;
1198 break;
1199 case 2:
1200 lnk_wdth = PCIE_LNK_X2;
1201 break;
1202 case 4:
1203 lnk_wdth = PCIE_LNK_X4;
1204 break;
1205 case 8:
1206 lnk_wdth = PCIE_LNK_X8;
1207 break;
1208 case 12:
1209 lnk_wdth = PCIE_LNK_X12;
1210 break;
1211 case 16:
1212 lnk_wdth = PCIE_LNK_X16;
1213 break;
1214 case 32:
1215 lnk_wdth = PCIE_LNK_X32;
1216 break;
1217 default:
1218 lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN;
1219 break;
1220 }
1221
1222 *value = lnk_wdth;
1223 dbg("Current link width = %d\n", lnk_wdth);
1224 DBG_LEAVE_ROUTINE
1225 return retval;
1226}
1227
1228static struct hpc_ops pciehp_hpc_ops = {
1229 .power_on_slot = hpc_power_on_slot,
1230 .power_off_slot = hpc_power_off_slot,
1231 .set_attention_status = hpc_set_attention_status,
1232 .get_power_status = hpc_get_power_status,
1233 .get_attention_status = hpc_get_attention_status,
1234 .get_latch_status = hpc_get_latch_status,
1235 .get_adapter_status = hpc_get_adapter_status,
1236
1237 .get_max_bus_speed = hpc_get_max_lnk_speed,
1238 .get_cur_bus_speed = hpc_get_cur_lnk_speed,
1239 .get_max_lnk_width = hpc_get_max_lnk_width,
1240 .get_cur_lnk_width = hpc_get_cur_lnk_width,
1241
1242 .query_power_fault = hpc_query_power_fault,
1243 .green_led_on = hpc_set_green_led_on,
1244 .green_led_off = hpc_set_green_led_off,
1245 .green_led_blink = hpc_set_green_led_blink,
1246
1247 .release_ctlr = hpc_release_ctlr,
1248 .check_lnk_status = hpc_check_lnk_status,
1249};
1250
1251int pcie_init(struct controller * ctrl,
1252 struct pcie_device *dev,
1253 php_intr_callback_t attention_button_callback,
1254 php_intr_callback_t switch_change_callback,
1255 php_intr_callback_t presence_change_callback,
1256 php_intr_callback_t power_fault_callback)
1257{
1258 struct php_ctlr_state_s *php_ctlr, *p;
1259 void *instance_id = ctrl;
1260 int rc;
1261 static int first = 1;
1262 u16 temp_word;
1263 u16 cap_reg;
1264 u16 intr_enable = 0;
1265 u32 slot_cap;
1266 int cap_base, saved_cap_base;
1267 u16 slot_status, slot_ctrl;
1268 struct pci_dev *pdev;
1269
1270 DBG_ENTER_ROUTINE
1271
1272 spin_lock_init(&list_lock);
1273 php_ctlr = (struct php_ctlr_state_s *) kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL);
1274
1275 if (!php_ctlr) { /* allocate controller state data */
1276 err("%s: HPC controller memory allocation error!\n", __FUNCTION__);
1277 goto abort;
1278 }
1279
1280 memset(php_ctlr, 0, sizeof(struct php_ctlr_state_s));
1281
1282 pdev = dev->port;
1283 php_ctlr->pci_dev = pdev; /* save pci_dev in context */
1284
1285 dbg("%s: pdev->vendor %x pdev->device %x\n", __FUNCTION__,
1286 pdev->vendor, pdev->device);
1287
1288 saved_cap_base = pcie_cap_base;
1289
1290 if ((cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP)) == 0) {
1291 dbg("%s: Can't find PCI_CAP_ID_EXP (0x10)\n", __FUNCTION__);
1292 goto abort_free_ctlr;
1293 }
1294
1295 pcie_cap_base = cap_base;
1296
1297 dbg("%s: pcie_cap_base %x\n", __FUNCTION__, pcie_cap_base);
1298
1299 rc = hp_register_read_word(pdev, CAP_REG, cap_reg);
1300 if (rc) {
1301 err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__);
1302 goto abort_free_ctlr;
1303 }
1304 dbg("%s: CAP_REG offset %x cap_reg %x\n", __FUNCTION__, CAP_REG, cap_reg);
1305
1306 if (((cap_reg & SLOT_IMPL) == 0) || ((cap_reg & DEV_PORT_TYPE) != 0x0040)){
1307 dbg("%s : This is not a root port or the port is not connected to a slot\n", __FUNCTION__);
1308 goto abort_free_ctlr;
1309 }
1310
1311 rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP, slot_cap);
1312 if (rc) {
1313 err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__);
1314 goto abort_free_ctlr;
1315 }
1316 dbg("%s: SLOT_CAP offset %x slot_cap %x\n", __FUNCTION__, SLOT_CAP, slot_cap);
1317
1318 if (!(slot_cap & HP_CAP)) {
1319 dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__);
1320 goto abort_free_ctlr;
1321 }
1322 /* For debugging purpose */
1323 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
1324 if (rc) {
1325 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
1326 goto abort_free_ctlr;
1327 }
1328 dbg("%s: SLOT_STATUS offset %x slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status);
1329
1330 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
1331 if (rc) {
1332 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
1333 goto abort_free_ctlr;
1334 }
1335 dbg("%s: SLOT_CTRL offset %x slot_ctrl %x\n", __FUNCTION__, SLOT_CTRL, slot_ctrl);
1336
1337 if (first) {
1338 spin_lock_init(&hpc_event_lock);
1339 first = 0;
1340 }
1341
1342 dbg("pdev = %p: b:d:f:irq=0x%x:%x:%x:%x\n", pdev, pdev->bus->number,
1343 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq);
1344 for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
1345 if (pci_resource_len(pdev, rc) > 0)
1346 dbg("pci resource[%d] start=0x%lx(len=0x%lx)\n", rc,
1347 pci_resource_start(pdev, rc), pci_resource_len(pdev, rc));
1348
1349 info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device,
1350 pdev->subsystem_vendor, pdev->subsystem_device);
1351
1352 if (pci_enable_device(pdev))
1353 goto abort_free_ctlr;
1354
1355 init_MUTEX(&ctrl->crit_sect);
1356 /* setup wait queue */
1357 init_waitqueue_head(&ctrl->queue);
1358
1359 /* find the IRQ */
1360 php_ctlr->irq = dev->irq;
1361 dbg("HPC interrupt = %d\n", php_ctlr->irq);
1362
1363 /* Save interrupt callback info */
1364 php_ctlr->attention_button_callback = attention_button_callback;
1365 php_ctlr->switch_change_callback = switch_change_callback;
1366 php_ctlr->presence_change_callback = presence_change_callback;
1367 php_ctlr->power_fault_callback = power_fault_callback;
1368 php_ctlr->callback_instance_id = instance_id;
1369
1370 /* return PCI Controller Info */
1371 php_ctlr->slot_device_offset = 0;
1372 php_ctlr->num_slots = 1;
1373
1374 /* Mask Hot-plug Interrupt Enable */
1375 rc = hp_register_read_word(pdev, SLOT_CTRL, temp_word);
1376 if (rc) {
1377 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
1378 goto abort_free_ctlr;
1379 }
1380
1381 dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word);
1382 temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
1383
1384 rc = hp_register_write_word(pdev, SLOT_CTRL, temp_word);
1385 if (rc) {
1386 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
1387 goto abort_free_ctlr;
1388 }
1389 dbg("%s : Mask HPIE hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, temp_word);
1390
1391 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
1392 if (rc) {
1393 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
1394 goto abort_free_ctlr;
1395 }
1396 dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status);
1397
1398 temp_word = 0x1F; /* Clear all events */
1399 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
1400 if (rc) {
1401 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
1402 goto abort_free_ctlr;
1403 }
1404 dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word);
1405
1406 if (pciehp_poll_mode) {/* Install interrupt polling code */
1407 /* Install and start the interrupt polling timer */
1408 init_timer(&php_ctlr->int_poll_timer);
1409 start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */
1410 } else {
1411 /* Installs the interrupt handler */
1412 rc = request_irq(php_ctlr->irq, pcie_isr, SA_SHIRQ, MY_NAME, (void *) ctrl);
1413 dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
1414 if (rc) {
1415 err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq);
1416 goto abort_free_ctlr;
1417 }
1418 }
1419
1420 rc = hp_register_read_word(pdev, SLOT_CTRL, temp_word);
1421 if (rc) {
1422 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
1423 goto abort_free_ctlr;
1424 }
1425 dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word);
1426 dbg("%s: slot_cap %x\n", __FUNCTION__, slot_cap);
1427
1428 intr_enable = intr_enable | PRSN_DETECT_ENABLE;
1429
1430 if (ATTN_BUTTN(slot_cap))
1431 intr_enable = intr_enable | ATTN_BUTTN_ENABLE;
1432
1433 if (POWER_CTRL(slot_cap))
1434 intr_enable = intr_enable | PWR_FAULT_DETECT_ENABLE;
1435
1436 if (MRL_SENS(slot_cap))
1437 intr_enable = intr_enable | MRL_DETECT_ENABLE;
1438
1439 temp_word = (temp_word & ~intr_enable) | intr_enable;
1440
1441 if (pciehp_poll_mode) {
1442 temp_word = (temp_word & ~HP_INTR_ENABLE) | 0x0;
1443 } else {
1444 temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
1445 }
1446 dbg("%s: temp_word %x\n", __FUNCTION__, temp_word);
1447
1448 /* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */
1449 rc = hp_register_write_word(pdev, SLOT_CTRL, temp_word);
1450 if (rc) {
1451 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
1452 goto abort_free_ctlr;
1453 }
1454 dbg("%s : Unmask HPIE hp_register_write_word SLOT_CTRL with %x\n", __FUNCTION__, temp_word);
1455 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
1456 if (rc) {
1457 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
1458 goto abort_free_ctlr;
1459 }
1460 dbg("%s: Unmask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__,
1461 SLOT_STATUS, slot_status);
1462
1463 temp_word = 0x1F; /* Clear all events */
1464 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
1465 if (rc) {
1466 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
1467 goto abort_free_ctlr;
1468 }
1469 dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word);
1470
1471 /* Add this HPC instance into the HPC list */
1472 spin_lock(&list_lock);
1473 if (php_ctlr_list_head == 0) {
1474 php_ctlr_list_head = php_ctlr;
1475 p = php_ctlr_list_head;
1476 p->pnext = NULL;
1477 } else {
1478 p = php_ctlr_list_head;
1479
1480 while (p->pnext)
1481 p = p->pnext;
1482
1483 p->pnext = php_ctlr;
1484 }
1485 spin_unlock(&list_lock);
1486
1487 ctlr_seq_num++;
1488 ctrl->hpc_ctlr_handle = php_ctlr;
1489 ctrl->hpc_ops = &pciehp_hpc_ops;
1490
1491 DBG_LEAVE_ROUTINE
1492 return 0;
1493
1494 /* We end up here for the many possible ways to fail this API. */
1495abort_free_ctlr:
1496 pcie_cap_base = saved_cap_base;
1497 kfree(php_ctlr);
1498abort:
1499 DBG_LEAVE_ROUTINE
1500 return -1;
1501}
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
new file mode 100644
index 000000000000..723b12c0bb7c
--- /dev/null
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -0,0 +1,827 @@
1/*
2 * PCI Express Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/types.h>
34#include <linux/slab.h>
35#include <linux/workqueue.h>
36#include <linux/proc_fs.h>
37#include <linux/pci.h>
38#include "../pci.h"
39#include "pciehp.h"
40#ifndef CONFIG_IA64
41#include "../../../arch/i386/pci/pci.h" /* horrible hack showing how processor dependant we are... */
42#endif
43
44
45int pciehp_configure_device (struct controller* ctrl, struct pci_func* func)
46{
47 unsigned char bus;
48 struct pci_bus *child;
49 int num;
50
51 if (func->pci_dev == NULL)
52 func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
53
54 /* Still NULL ? Well then scan for it ! */
55 if (func->pci_dev == NULL) {
56 dbg("%s: pci_dev still null. do pci_scan_slot\n", __FUNCTION__);
57
58 num = pci_scan_slot(ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function));
59
60 if (num)
61 pci_bus_add_devices(ctrl->pci_dev->subordinate);
62
63 func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
64 if (func->pci_dev == NULL) {
65 dbg("ERROR: pci_dev still null\n");
66 return 0;
67 }
68 }
69
70 if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
71 pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus);
72 child = pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus);
73 pci_do_scan_bus(child);
74
75 }
76
77 return 0;
78}
79
80
81int pciehp_unconfigure_device(struct pci_func* func)
82{
83 int rc = 0;
84 int j;
85 struct pci_bus *pbus;
86
87 dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus,
88 func->device, func->function);
89 pbus = func->pci_dev->bus;
90
91 for (j=0; j<8 ; j++) {
92 struct pci_dev* temp = pci_find_slot(func->bus,
93 (func->device << 3) | j);
94 if (temp) {
95 pci_remove_bus_device(temp);
96 }
97 }
98 /*
99 * Some PCI Express root ports require fixup after hot-plug operation.
100 */
101 if (pcie_mch_quirk)
102 pci_fixup_device(pci_fixup_final, pbus->self);
103
104 return rc;
105}
106
107/*
108 * pciehp_set_irq
109 *
110 * @bus_num: bus number of PCI device
111 * @dev_num: device number of PCI device
112 * @slot: pointer to u8 where slot number will be returned
113 */
114int pciehp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
115{
116#if defined(CONFIG_X86) && !defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_64)
117 int rc;
118 u16 temp_word;
119 struct pci_dev fakedev;
120 struct pci_bus fakebus;
121
122 fakedev.devfn = dev_num << 3;
123 fakedev.bus = &fakebus;
124 fakebus.number = bus_num;
125 dbg("%s: dev %d, bus %d, pin %d, num %d\n",
126 __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
127 rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
128 dbg("%s: rc %d\n", __FUNCTION__, rc);
129 if (!rc)
130 return !rc;
131
132 /* set the Edge Level Control Register (ELCR) */
133 temp_word = inb(0x4d0);
134 temp_word |= inb(0x4d1) << 8;
135
136 temp_word |= 0x01 << irq_num;
137
138 /* This should only be for x86 as it sets the Edge Level Control Register */
139 outb((u8) (temp_word & 0xFF), 0x4d0);
140 outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1);
141#endif
142 return 0;
143}
144
145/* More PCI configuration routines; this time centered around hotplug controller */
146
147
148/*
149 * pciehp_save_config
150 *
151 * Reads configuration for all slots in a PCI bus and saves info.
152 *
153 * Note: For non-hot plug busses, the slot # saved is the device #
154 *
155 * returns 0 if success
156 */
157int pciehp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num)
158{
159 int rc;
160 u8 class_code;
161 u8 header_type;
162 u32 ID;
163 u8 secondary_bus;
164 struct pci_func *new_slot;
165 int sub_bus;
166 int max_functions;
167 int function;
168 u8 DevError;
169 int device = 0;
170 int cloop = 0;
171 int stop_it;
172 int index;
173 int is_hot_plug = num_ctlr_slots || first_device_num;
174 struct pci_bus lpci_bus, *pci_bus;
175 int FirstSupported, LastSupported;
176
177 dbg("%s: Enter\n", __FUNCTION__);
178
179 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
180 pci_bus = &lpci_bus;
181
182 dbg("%s: num_ctlr_slots = %d, first_device_num = %d\n", __FUNCTION__,
183 num_ctlr_slots, first_device_num);
184
185 /* Decide which slots are supported */
186 if (is_hot_plug) {
187 /*********************************
188 * is_hot_plug is the slot mask
189 *********************************/
190 FirstSupported = first_device_num;
191 LastSupported = FirstSupported + num_ctlr_slots - 1;
192 } else {
193 FirstSupported = 0;
194 LastSupported = 0x1F;
195 }
196
197 dbg("FirstSupported = %d, LastSupported = %d\n", FirstSupported,
198 LastSupported);
199
200 /* Save PCI configuration space for all devices in supported slots */
201 dbg("%s: pci_bus->number = %x\n", __FUNCTION__, pci_bus->number);
202 pci_bus->number = busnumber;
203 dbg("%s: bus = %x, dev = %x\n", __FUNCTION__, busnumber, device);
204 for (device = FirstSupported; device <= LastSupported; device++) {
205 ID = 0xFFFFFFFF;
206 rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0),
207 PCI_VENDOR_ID, &ID);
208
209 if (ID != 0xFFFFFFFF) { /* device in slot */
210 dbg("%s: ID = %x\n", __FUNCTION__, ID);
211 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
212 0x0B, &class_code);
213 if (rc)
214 return rc;
215
216 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
217 PCI_HEADER_TYPE, &header_type);
218 if (rc)
219 return rc;
220
221 dbg("class_code = %x, header_type = %x\n", class_code, header_type);
222
223 /* If multi-function device, set max_functions to 8 */
224 if (header_type & 0x80)
225 max_functions = 8;
226 else
227 max_functions = 1;
228
229 function = 0;
230
231 do {
232 DevError = 0;
233 dbg("%s: In do loop\n", __FUNCTION__);
234
235 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* P-P Bridge */
236 /* Recurse the subordinate bus
237 * get the subordinate bus number
238 */
239 rc = pci_bus_read_config_byte(pci_bus,
240 PCI_DEVFN(device, function),
241 PCI_SECONDARY_BUS, &secondary_bus);
242 if (rc) {
243 return rc;
244 } else {
245 sub_bus = (int) secondary_bus;
246
247 /* Save secondary bus cfg spc with this recursive call. */
248 rc = pciehp_save_config(ctrl, sub_bus, 0, 0);
249 if (rc)
250 return rc;
251 }
252 }
253
254 index = 0;
255 new_slot = pciehp_slot_find(busnumber, device, index++);
256
257 dbg("%s: new_slot = %p bus %x dev %x fun %x\n",
258 __FUNCTION__, new_slot, busnumber, device, index-1);
259
260 while (new_slot && (new_slot->function != (u8) function)) {
261 new_slot = pciehp_slot_find(busnumber, device, index++);
262 dbg("%s: while loop, new_slot = %p bus %x dev %x fun %x\n",
263 __FUNCTION__, new_slot, busnumber, device, index-1);
264 }
265 if (!new_slot) {
266 /* Setup slot structure. */
267 new_slot = pciehp_slot_create(busnumber);
268 dbg("%s: if, new_slot = %p bus %x dev %x fun %x\n",
269 __FUNCTION__, new_slot, busnumber, device, function);
270
271 if (new_slot == NULL)
272 return(1);
273 }
274
275 new_slot->bus = (u8) busnumber;
276 new_slot->device = (u8) device;
277 new_slot->function = (u8) function;
278 new_slot->is_a_board = 1;
279 new_slot->switch_save = 0x10;
280 /* In case of unsupported board */
281 new_slot->status = DevError;
282 new_slot->pci_dev = pci_find_slot(new_slot->bus,
283 (new_slot->device << 3) | new_slot->function);
284 dbg("new_slot->pci_dev = %p\n", new_slot->pci_dev);
285
286 for (cloop = 0; cloop < 0x20; cloop++) {
287 rc = pci_bus_read_config_dword(pci_bus,
288 PCI_DEVFN(device, function),
289 cloop << 2,
290 (u32 *) &(new_slot->config_space [cloop]));
291 /* dbg("new_slot->config_space[%x] = %x\n",
292 cloop, new_slot->config_space[cloop]); */
293 if (rc)
294 return rc;
295 }
296
297 function++;
298
299 stop_it = 0;
300
301 /* this loop skips to the next present function
302 * reading in Class Code and Header type.
303 */
304
305 while ((function < max_functions)&&(!stop_it)) {
306 dbg("%s: In while loop \n", __FUNCTION__);
307 rc = pci_bus_read_config_dword(pci_bus,
308 PCI_DEVFN(device, function),
309 PCI_VENDOR_ID, &ID);
310
311 if (ID == 0xFFFFFFFF) { /* nothing there. */
312 function++;
313 dbg("Nothing there\n");
314 } else { /* Something there */
315 rc = pci_bus_read_config_byte(pci_bus,
316 PCI_DEVFN(device, function),
317 0x0B, &class_code);
318 if (rc)
319 return rc;
320
321 rc = pci_bus_read_config_byte(pci_bus,
322 PCI_DEVFN(device, function),
323 PCI_HEADER_TYPE, &header_type);
324 if (rc)
325 return rc;
326
327 dbg("class_code = %x, header_type = %x\n", class_code, header_type);
328 stop_it++;
329 }
330 }
331
332 } while (function < max_functions);
333 /* End of IF (device in slot?) */
334 } else if (is_hot_plug) {
335 /* Setup slot structure with entry for empty slot */
336 new_slot = pciehp_slot_create(busnumber);
337
338 if (new_slot == NULL) {
339 return(1);
340 }
341 dbg("new_slot = %p, bus = %x, dev = %x, fun = %x\n", new_slot,
342 new_slot->bus, new_slot->device, new_slot->function);
343
344 new_slot->bus = (u8) busnumber;
345 new_slot->device = (u8) device;
346 new_slot->function = 0;
347 new_slot->is_a_board = 0;
348 new_slot->presence_save = 0;
349 new_slot->switch_save = 0;
350 }
351 } /* End of FOR loop */
352
353 dbg("%s: Exit\n", __FUNCTION__);
354 return(0);
355}
356
357
358/*
359 * pciehp_save_slot_config
360 *
361 * Saves configuration info for all PCI devices in a given slot
362 * including subordinate busses.
363 *
364 * returns 0 if success
365 */
366int pciehp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot)
367{
368 int rc;
369 u8 class_code;
370 u8 header_type;
371 u32 ID;
372 u8 secondary_bus;
373 int sub_bus;
374 int max_functions;
375 int function;
376 int cloop = 0;
377 int stop_it;
378 struct pci_bus lpci_bus, *pci_bus;
379 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
380 pci_bus = &lpci_bus;
381 pci_bus->number = new_slot->bus;
382
383 ID = 0xFFFFFFFF;
384
385 pci_bus_read_config_dword(pci_bus, PCI_DEVFN(new_slot->device, 0),
386 PCI_VENDOR_ID, &ID);
387
388 if (ID != 0xFFFFFFFF) { /* device in slot */
389 pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0),
390 0x0B, &class_code);
391
392 pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0),
393 PCI_HEADER_TYPE, &header_type);
394
395 if (header_type & 0x80) /* Multi-function device */
396 max_functions = 8;
397 else
398 max_functions = 1;
399
400 function = 0;
401
402 do {
403 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
404 /* Recurse the subordinate bus */
405 pci_bus_read_config_byte(pci_bus,
406 PCI_DEVFN(new_slot->device, function),
407 PCI_SECONDARY_BUS, &secondary_bus);
408
409 sub_bus = (int) secondary_bus;
410
411 /* Save the config headers for the secondary bus. */
412 rc = pciehp_save_config(ctrl, sub_bus, 0, 0);
413
414 if (rc)
415 return rc;
416
417 } /* End of IF */
418
419 new_slot->status = 0;
420
421 for (cloop = 0; cloop < 0x20; cloop++) {
422 pci_bus_read_config_dword(pci_bus,
423 PCI_DEVFN(new_slot->device, function),
424 cloop << 2,
425 (u32 *) &(new_slot->config_space [cloop]));
426 }
427
428 function++;
429
430 stop_it = 0;
431
432 /* this loop skips to the next present function
433 * reading in the Class Code and the Header type.
434 */
435
436 while ((function < max_functions) && (!stop_it)) {
437 pci_bus_read_config_dword(pci_bus,
438 PCI_DEVFN(new_slot->device, function),
439 PCI_VENDOR_ID, &ID);
440
441 if (ID == 0xFFFFFFFF) { /* nothing there. */
442 function++;
443 } else { /* Something there */
444 pci_bus_read_config_byte(pci_bus,
445 PCI_DEVFN(new_slot->device, function),
446 0x0B, &class_code);
447
448 pci_bus_read_config_byte(pci_bus,
449 PCI_DEVFN(new_slot->device, function),
450 PCI_HEADER_TYPE, &header_type);
451
452 stop_it++;
453 }
454 }
455
456 } while (function < max_functions);
457 } /* End of IF (device in slot?) */
458 else {
459 return 2;
460 }
461
462 return 0;
463}
464
465
466/*
467 * pciehp_save_used_resources
468 *
469 * Stores used resource information for existing boards. this is
470 * for boards that were in the system when this driver was loaded.
471 * this function is for hot plug ADD
472 *
473 * returns 0 if success
474 * if disable == 1(DISABLE_CARD),
475 * it loops for all functions of the slot and disables them.
476 * else, it just get resources of the function and return.
477 */
478int pciehp_save_used_resources(struct controller *ctrl, struct pci_func *func, int disable)
479{
480 u8 cloop;
481 u8 header_type;
482 u8 secondary_bus;
483 u8 temp_byte;
484 u16 command;
485 u16 save_command;
486 u16 w_base, w_length;
487 u32 temp_register;
488 u32 save_base;
489 u32 base, length;
490 u64 base64 = 0;
491 int index = 0;
492 unsigned int devfn;
493 struct pci_resource *mem_node = NULL;
494 struct pci_resource *p_mem_node = NULL;
495 struct pci_resource *t_mem_node;
496 struct pci_resource *io_node;
497 struct pci_resource *bus_node;
498 struct pci_bus lpci_bus, *pci_bus;
499 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
500 pci_bus = &lpci_bus;
501
502 if (disable)
503 func = pciehp_slot_find(func->bus, func->device, index++);
504
505 while ((func != NULL) && func->is_a_board) {
506 pci_bus->number = func->bus;
507 devfn = PCI_DEVFN(func->device, func->function);
508
509 /* Save the command register */
510 pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command);
511
512 if (disable) {
513 /* disable card */
514 command = 0x00;
515 pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
516 }
517
518 /* Check for Bridge */
519 pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
520
521 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
522 dbg("Save_used_res of PCI bridge b:d=0x%x:%x, sc=0x%x\n",
523 func->bus, func->device, save_command);
524 if (disable) {
525 /* Clear Bridge Control Register */
526 command = 0x00;
527 pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
528 }
529
530 pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
531 pci_bus_read_config_byte(pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte);
532
533 bus_node = kmalloc(sizeof(struct pci_resource),
534 GFP_KERNEL);
535 if (!bus_node)
536 return -ENOMEM;
537
538 bus_node->base = (ulong)secondary_bus;
539 bus_node->length = (ulong)(temp_byte - secondary_bus + 1);
540
541 bus_node->next = func->bus_head;
542 func->bus_head = bus_node;
543
544 /* Save IO base and Limit registers */
545 pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &temp_byte);
546 base = temp_byte;
547 pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &temp_byte);
548 length = temp_byte;
549
550 if ((base <= length) && (!disable || (save_command & PCI_COMMAND_IO))) {
551 io_node = kmalloc(sizeof(struct pci_resource),
552 GFP_KERNEL);
553 if (!io_node)
554 return -ENOMEM;
555
556 io_node->base = (ulong)(base & PCI_IO_RANGE_MASK) << 8;
557 io_node->length = (ulong)(length - base + 0x10) << 8;
558
559 io_node->next = func->io_head;
560 func->io_head = io_node;
561 }
562
563 /* Save memory base and Limit registers */
564 pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_BASE, &w_base);
565 pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length);
566
567 if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
568 mem_node = kmalloc(sizeof(struct pci_resource),
569 GFP_KERNEL);
570 if (!mem_node)
571 return -ENOMEM;
572
573 mem_node->base = (ulong)w_base << 16;
574 mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
575
576 mem_node->next = func->mem_head;
577 func->mem_head = mem_node;
578 }
579 /* Save prefetchable memory base and Limit registers */
580 pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base);
581 pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length);
582
583 if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
584 p_mem_node = kmalloc(sizeof(struct pci_resource),
585 GFP_KERNEL);
586 if (!p_mem_node)
587 return -ENOMEM;
588
589 p_mem_node->base = (ulong)w_base << 16;
590 p_mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
591
592 p_mem_node->next = func->p_mem_head;
593 func->p_mem_head = p_mem_node;
594 }
595 } else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
596 dbg("Save_used_res of PCI adapter b:d=0x%x:%x, sc=0x%x\n",
597 func->bus, func->device, save_command);
598
599 /* Figure out IO and memory base lengths */
600 for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
601 pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base);
602
603 temp_register = 0xFFFFFFFF;
604 pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
605 pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
606
607 if (!disable)
608 pci_bus_write_config_dword(pci_bus, devfn, cloop, save_base);
609
610 if (!temp_register)
611 continue;
612
613 base = temp_register;
614
615 if ((base & PCI_BASE_ADDRESS_SPACE_IO) &&
616 (!disable || (save_command & PCI_COMMAND_IO))) {
617 /* IO base */
618 /* set temp_register = amount of IO space requested */
619 base = base & 0xFFFFFFFCL;
620 base = (~base) + 1;
621
622 io_node = kmalloc(sizeof (struct pci_resource),
623 GFP_KERNEL);
624 if (!io_node)
625 return -ENOMEM;
626
627 io_node->base = (ulong)save_base & PCI_BASE_ADDRESS_IO_MASK;
628 io_node->length = (ulong)base;
629 dbg("sur adapter: IO bar=0x%x(length=0x%x)\n",
630 io_node->base, io_node->length);
631
632 io_node->next = func->io_head;
633 func->io_head = io_node;
634 } else { /* map Memory */
635 int prefetchable = 1;
636 /* struct pci_resources **res_node; */
637 char *res_type_str = "PMEM";
638 u32 temp_register2;
639
640 t_mem_node = kmalloc(sizeof (struct pci_resource),
641 GFP_KERNEL);
642 if (!t_mem_node)
643 return -ENOMEM;
644
645 if (!(base & PCI_BASE_ADDRESS_MEM_PREFETCH) &&
646 (!disable || (save_command & PCI_COMMAND_MEMORY))) {
647 prefetchable = 0;
648 mem_node = t_mem_node;
649 res_type_str++;
650 } else
651 p_mem_node = t_mem_node;
652
653 base = base & 0xFFFFFFF0L;
654 base = (~base) + 1;
655
656 switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
657 case PCI_BASE_ADDRESS_MEM_TYPE_32:
658 if (prefetchable) {
659 p_mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
660 p_mem_node->length = (ulong)base;
661 dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n",
662 res_type_str,
663 p_mem_node->base,
664 p_mem_node->length);
665
666 p_mem_node->next = func->p_mem_head;
667 func->p_mem_head = p_mem_node;
668 } else {
669 mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
670 mem_node->length = (ulong)base;
671 dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n",
672 res_type_str,
673 mem_node->base,
674 mem_node->length);
675
676 mem_node->next = func->mem_head;
677 func->mem_head = mem_node;
678 }
679 break;
680 case PCI_BASE_ADDRESS_MEM_TYPE_64:
681 pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
682 base64 = temp_register2;
683 base64 = (base64 << 32) | save_base;
684
685 if (temp_register2) {
686 dbg("sur adapter: 64 %s high dword of base64(0x%x:%x) masked to 0\n",
687 res_type_str, temp_register2, (u32)base64);
688 base64 &= 0x00000000FFFFFFFFL;
689 }
690
691 if (prefetchable) {
692 p_mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
693 p_mem_node->length = base;
694 dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n",
695 res_type_str,
696 p_mem_node->base,
697 p_mem_node->length);
698
699 p_mem_node->next = func->p_mem_head;
700 func->p_mem_head = p_mem_node;
701 } else {
702 mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
703 mem_node->length = base;
704 dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n",
705 res_type_str,
706 mem_node->base,
707 mem_node->length);
708
709 mem_node->next = func->mem_head;
710 func->mem_head = mem_node;
711 }
712 cloop += 4;
713 break;
714 default:
715 dbg("asur: reserved BAR type=0x%x\n",
716 temp_register);
717 break;
718 }
719 }
720 } /* End of base register loop */
721 } else { /* Some other unknown header type */
722 dbg("Save_used_res of PCI unknown type b:d=0x%x:%x. skip.\n",
723 func->bus, func->device);
724 }
725
726 /* find the next device in this slot */
727 if (!disable)
728 break;
729 func = pciehp_slot_find(func->bus, func->device, index++);
730 }
731
732 return 0;
733}
734
735
736/**
737 * kfree_resource_list: release memory of all list members
738 * @res: resource list to free
739 */
740static inline void
741return_resource_list(struct pci_resource **func, struct pci_resource **res)
742{
743 struct pci_resource *node;
744 struct pci_resource *t_node;
745
746 node = *func;
747 *func = NULL;
748 while (node) {
749 t_node = node->next;
750 return_resource(res, node);
751 node = t_node;
752 }
753}
754
755/*
756 * pciehp_return_board_resources
757 *
758 * this routine returns all resources allocated to a board to
759 * the available pool.
760 *
761 * returns 0 if success
762 */
763int pciehp_return_board_resources(struct pci_func * func,
764 struct resource_lists * resources)
765{
766 int rc;
767
768 dbg("%s\n", __FUNCTION__);
769
770 if (!func)
771 return 1;
772
773 return_resource_list(&(func->io_head),&(resources->io_head));
774 return_resource_list(&(func->mem_head),&(resources->mem_head));
775 return_resource_list(&(func->p_mem_head),&(resources->p_mem_head));
776 return_resource_list(&(func->bus_head),&(resources->bus_head));
777
778 rc = pciehp_resource_sort_and_combine(&(resources->mem_head));
779 rc |= pciehp_resource_sort_and_combine(&(resources->p_mem_head));
780 rc |= pciehp_resource_sort_and_combine(&(resources->io_head));
781 rc |= pciehp_resource_sort_and_combine(&(resources->bus_head));
782
783 return rc;
784}
785
786/**
787 * kfree_resource_list: release memory of all list members
788 * @res: resource list to free
789 */
790static inline void
791kfree_resource_list(struct pci_resource **r)
792{
793 struct pci_resource *res, *tres;
794
795 res = *r;
796 *r = NULL;
797
798 while (res) {
799 tres = res;
800 res = res->next;
801 kfree(tres);
802 }
803}
804
805/**
806 * pciehp_destroy_resource_list: put node back in the resource list
807 * @resources: list to put nodes back
808 */
809void pciehp_destroy_resource_list(struct resource_lists * resources)
810{
811 kfree_resource_list(&(resources->io_head));
812 kfree_resource_list(&(resources->mem_head));
813 kfree_resource_list(&(resources->p_mem_head));
814 kfree_resource_list(&(resources->bus_head));
815}
816
817/**
818 * pciehp_destroy_board_resources: put node back in the resource list
819 * @resources: list to put nodes back
820 */
821void pciehp_destroy_board_resources(struct pci_func * func)
822{
823 kfree_resource_list(&(func->io_head));
824 kfree_resource_list(&(func->mem_head));
825 kfree_resource_list(&(func->p_mem_head));
826 kfree_resource_list(&(func->bus_head));
827}
diff --git a/drivers/pci/hotplug/pciehprm.h b/drivers/pci/hotplug/pciehprm.h
new file mode 100644
index 000000000000..966775ffb0ff
--- /dev/null
+++ b/drivers/pci/hotplug/pciehprm.h
@@ -0,0 +1,52 @@
1/*
2 * PCIEHPRM : PCIEHP Resource Manager for ACPI/non-ACPI platform
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
27 *
28 */
29
30#ifndef _PCIEHPRM_H_
31#define _PCIEHPRM_H_
32
33#ifdef CONFIG_HOTPLUG_PCI_PCIE_PHPRM_NONACPI
34#include "pciehprm_nonacpi.h"
35#endif
36
37int pciehprm_init(enum php_ctlr_type ct);
38void pciehprm_cleanup(void);
39int pciehprm_print_pirt(void);
40int pciehprm_find_available_resources(struct controller *ctrl);
41int pciehprm_set_hpp(struct controller *ctrl, struct pci_func *func, u8 card_type);
42void pciehprm_enable_card(struct controller *ctrl, struct pci_func *func, u8 card_type);
43
44#ifdef DEBUG
45#define RES_CHECK(this, bits) \
46 { if (((this) & (bits - 1))) \
47 printk("%s:%d ERR: potential res loss!\n", __FUNCTION__, __LINE__); }
48#else
49#define RES_CHECK(this, bits)
50#endif
51
52#endif /* _PCIEHPRM_H_ */
diff --git a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/pciehprm_acpi.c
new file mode 100644
index 000000000000..57f4e6d1b27c
--- /dev/null
+++ b/drivers/pci/hotplug/pciehprm_acpi.c
@@ -0,0 +1,1737 @@
1/*
2 * PCIEHPRM ACPI: PHP Resource Manager for ACPI platform
3 *
4 * Copyright (C) 2003-2004 Intel Corporation
5 *
6 * All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
16 * NON INFRINGEMENT. See the GNU General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 * Send feedback to <dely.l.sy@intel.com>
24 *
25 */
26
27#include <linux/config.h>
28#include <linux/module.h>
29#include <linux/kernel.h>
30#include <linux/types.h>
31#include <linux/pci.h>
32#include <linux/init.h>
33#include <linux/acpi.h>
34#include <linux/efi.h>
35#include <linux/pci-acpi.h>
36#include <asm/uaccess.h>
37#include <asm/system.h>
38#ifdef CONFIG_IA64
39#include <asm/iosapic.h>
40#endif
41#include <acpi/acpi.h>
42#include <acpi/acpi_bus.h>
43#include <acpi/actypes.h>
44#include "pciehp.h"
45#include "pciehprm.h"
46
47#define PCI_MAX_BUS 0x100
48#define ACPI_STA_DEVICE_PRESENT 0x01
49
50#define METHOD_NAME__SUN "_SUN"
51#define METHOD_NAME__HPP "_HPP"
52#define METHOD_NAME_OSHP "OSHP"
53
54/* Status code for running acpi method to gain native control */
55#define NC_NOT_RUN 0
56#define OSC_NOT_EXIST 1
57#define OSC_RUN_FAILED 2
58#define OSHP_NOT_EXIST 3
59#define OSHP_RUN_FAILED 4
60#define NC_RUN_SUCCESS 5
61
62#define PHP_RES_BUS 0xA0
63#define PHP_RES_IO 0xA1
64#define PHP_RES_MEM 0xA2
65#define PHP_RES_PMEM 0xA3
66
67#define BRIDGE_TYPE_P2P 0x00
68#define BRIDGE_TYPE_HOST 0x01
69
70/* this should go to drivers/acpi/include/ */
71struct acpi__hpp {
72 u8 cache_line_size;
73 u8 latency_timer;
74 u8 enable_serr;
75 u8 enable_perr;
76};
77
78struct acpi_php_slot {
79 struct acpi_php_slot *next;
80 struct acpi_bridge *bridge;
81 acpi_handle handle;
82 int seg;
83 int bus;
84 int dev;
85 int fun;
86 u32 sun;
87 struct pci_resource *mem_head;
88 struct pci_resource *p_mem_head;
89 struct pci_resource *io_head;
90 struct pci_resource *bus_head;
91 void *slot_ops; /* _STA, _EJx, etc */
92 struct slot *slot;
93}; /* per func */
94
95struct acpi_bridge {
96 struct acpi_bridge *parent;
97 struct acpi_bridge *next;
98 struct acpi_bridge *child;
99 acpi_handle handle;
100 int seg;
101 int pbus; /* pdev->bus->number */
102 int pdevice; /* PCI_SLOT(pdev->devfn) */
103 int pfunction; /* PCI_DEVFN(pdev->devfn) */
104 int bus; /* pdev->subordinate->number */
105 struct acpi__hpp *_hpp;
106 struct acpi_php_slot *slots;
107 struct pci_resource *tmem_head; /* total from crs */
108 struct pci_resource *tp_mem_head; /* total from crs */
109 struct pci_resource *tio_head; /* total from crs */
110 struct pci_resource *tbus_head; /* total from crs */
111 struct pci_resource *mem_head; /* available */
112 struct pci_resource *p_mem_head; /* available */
113 struct pci_resource *io_head; /* available */
114 struct pci_resource *bus_head; /* available */
115 int scanned;
116 int type;
117};
118
119static struct acpi_bridge *acpi_bridges_head;
120
121static u8 * acpi_path_name( acpi_handle handle)
122{
123 acpi_status status;
124 static u8 path_name[ACPI_PATHNAME_MAX];
125 struct acpi_buffer ret_buf = { ACPI_PATHNAME_MAX, path_name };
126
127 memset(path_name, 0, sizeof (path_name));
128 status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf);
129
130 if (ACPI_FAILURE(status))
131 return NULL;
132 else
133 return path_name;
134}
135
136static void acpi_get__hpp ( struct acpi_bridge *ab);
137static int acpi_run_oshp ( struct acpi_bridge *ab);
138static int osc_run_status = NC_NOT_RUN;
139static int oshp_run_status = NC_NOT_RUN;
140
141static int acpi_add_slot_to_php_slots(
142 struct acpi_bridge *ab,
143 int bus_num,
144 acpi_handle handle,
145 u32 adr,
146 u32 sun
147 )
148{
149 struct acpi_php_slot *aps;
150 static long samesun = -1;
151
152 aps = (struct acpi_php_slot *) kmalloc (sizeof(struct acpi_php_slot), GFP_KERNEL);
153 if (!aps) {
154 err ("acpi_pciehprm: alloc for aps fail\n");
155 return -1;
156 }
157 memset(aps, 0, sizeof(struct acpi_php_slot));
158
159 aps->handle = handle;
160 aps->bus = bus_num;
161 aps->dev = (adr >> 16) & 0xffff;
162 aps->fun = adr & 0xffff;
163 aps->sun = sun;
164
165 aps->next = ab->slots; /* cling to the bridge */
166 aps->bridge = ab;
167 ab->slots = aps;
168
169 ab->scanned += 1;
170 if (!ab->_hpp)
171 acpi_get__hpp(ab);
172
173 if (osc_run_status == OSC_NOT_EXIST)
174 oshp_run_status = acpi_run_oshp(ab);
175
176 if (sun != samesun) {
177 info("acpi_pciehprm: Slot sun(%x) at s:b:d:f=0x%02x:%02x:%02x:%02x\n",
178 aps->sun, ab->seg, aps->bus, aps->dev, aps->fun);
179 samesun = sun;
180 }
181 return 0;
182}
183
184static void acpi_get__hpp ( struct acpi_bridge *ab)
185{
186 acpi_status status;
187 u8 nui[4];
188 struct acpi_buffer ret_buf = { 0, NULL};
189 union acpi_object *ext_obj, *package;
190 u8 *path_name = acpi_path_name(ab->handle);
191 int i, len = 0;
192
193 /* get _hpp */
194 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf);
195 switch (status) {
196 case AE_BUFFER_OVERFLOW:
197 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
198 if (!ret_buf.pointer) {
199 err ("acpi_pciehprm:%s alloc for _HPP fail\n", path_name);
200 return;
201 }
202 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf);
203 if (ACPI_SUCCESS(status))
204 break;
205 default:
206 if (ACPI_FAILURE(status)) {
207 err("acpi_pciehprm:%s _HPP fail=0x%x\n", path_name, status);
208 return;
209 }
210 }
211
212 ext_obj = (union acpi_object *) ret_buf.pointer;
213 if (ext_obj->type != ACPI_TYPE_PACKAGE) {
214 err ("acpi_pciehprm:%s _HPP obj not a package\n", path_name);
215 goto free_and_return;
216 }
217
218 len = ext_obj->package.count;
219 package = (union acpi_object *) ret_buf.pointer;
220 for ( i = 0; (i < len) || (i < 4); i++) {
221 ext_obj = (union acpi_object *) &package->package.elements[i];
222 switch (ext_obj->type) {
223 case ACPI_TYPE_INTEGER:
224 nui[i] = (u8)ext_obj->integer.value;
225 break;
226 default:
227 err ("acpi_pciehprm:%s _HPP obj type incorrect\n", path_name);
228 goto free_and_return;
229 }
230 }
231
232 ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL);
233 if (!ab->_hpp) {
234 err ("acpi_pciehprm:%s alloc for _HPP failed\n", path_name);
235 goto free_and_return;
236 }
237 memset(ab->_hpp, 0, sizeof(struct acpi__hpp));
238
239 ab->_hpp->cache_line_size = nui[0];
240 ab->_hpp->latency_timer = nui[1];
241 ab->_hpp->enable_serr = nui[2];
242 ab->_hpp->enable_perr = nui[3];
243
244 dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
245 dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer);
246 dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr);
247 dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr);
248
249free_and_return:
250 kfree(ret_buf.pointer);
251}
252
253static int acpi_run_oshp ( struct acpi_bridge *ab)
254{
255 acpi_status status;
256 u8 *path_name = acpi_path_name(ab->handle);
257
258 /* run OSHP */
259 status = acpi_evaluate_object(ab->handle, METHOD_NAME_OSHP, NULL, NULL);
260 if (ACPI_FAILURE(status)) {
261 err("acpi_pciehprm:%s OSHP fails=0x%x\n", path_name, status);
262 oshp_run_status = (status == AE_NOT_FOUND) ? OSHP_NOT_EXIST : OSHP_RUN_FAILED;
263 } else {
264 oshp_run_status = NC_RUN_SUCCESS;
265 dbg("acpi_pciehprm:%s OSHP passes =0x%x\n", path_name, status);
266 dbg("acpi_pciehprm:%s oshp_run_status =0x%x\n", path_name, oshp_run_status);
267 }
268 return oshp_run_status;
269}
270
271static acpi_status acpi_evaluate_crs(
272 acpi_handle handle,
273 struct acpi_resource **retbuf
274 )
275{
276 acpi_status status;
277 struct acpi_buffer crsbuf;
278 u8 *path_name = acpi_path_name(handle);
279
280 crsbuf.length = 0;
281 crsbuf.pointer = NULL;
282
283 status = acpi_get_current_resources (handle, &crsbuf);
284
285 switch (status) {
286 case AE_BUFFER_OVERFLOW:
287 break; /* found */
288 case AE_NOT_FOUND:
289 dbg("acpi_pciehprm:%s _CRS not found\n", path_name);
290 return status;
291 default:
292 err ("acpi_pciehprm:%s _CRS fail=0x%x\n", path_name, status);
293 return status;
294 }
295
296 crsbuf.pointer = kmalloc (crsbuf.length, GFP_KERNEL);
297 if (!crsbuf.pointer) {
298 err ("acpi_pciehprm: alloc %ld bytes for %s _CRS fail\n", (ulong)crsbuf.length, path_name);
299 return AE_NO_MEMORY;
300 }
301
302 status = acpi_get_current_resources (handle, &crsbuf);
303 if (ACPI_FAILURE(status)) {
304 err("acpi_pciehprm: %s _CRS fail=0x%x.\n", path_name, status);
305 kfree(crsbuf.pointer);
306 return status;
307 }
308
309 *retbuf = crsbuf.pointer;
310
311 return status;
312}
313
314static void free_pci_resource ( struct pci_resource *aprh)
315{
316 struct pci_resource *res, *next;
317
318 for (res = aprh; res; res = next) {
319 next = res->next;
320 kfree(res);
321 }
322}
323
324static void print_pci_resource ( struct pci_resource *aprh)
325{
326 struct pci_resource *res;
327
328 for (res = aprh; res; res = res->next)
329 dbg(" base= 0x%x length= 0x%x\n", res->base, res->length);
330}
331
332static void print_slot_resources( struct acpi_php_slot *aps)
333{
334 if (aps->bus_head) {
335 dbg(" BUS Resources:\n");
336 print_pci_resource (aps->bus_head);
337 }
338
339 if (aps->io_head) {
340 dbg(" IO Resources:\n");
341 print_pci_resource (aps->io_head);
342 }
343
344 if (aps->mem_head) {
345 dbg(" MEM Resources:\n");
346 print_pci_resource (aps->mem_head);
347 }
348
349 if (aps->p_mem_head) {
350 dbg(" PMEM Resources:\n");
351 print_pci_resource (aps->p_mem_head);
352 }
353}
354
355static void print_pci_resources( struct acpi_bridge *ab)
356{
357 if (ab->tbus_head) {
358 dbg(" Total BUS Resources:\n");
359 print_pci_resource (ab->tbus_head);
360 }
361 if (ab->bus_head) {
362 dbg(" BUS Resources:\n");
363 print_pci_resource (ab->bus_head);
364 }
365
366 if (ab->tio_head) {
367 dbg(" Total IO Resources:\n");
368 print_pci_resource (ab->tio_head);
369 }
370 if (ab->io_head) {
371 dbg(" IO Resources:\n");
372 print_pci_resource (ab->io_head);
373 }
374
375 if (ab->tmem_head) {
376 dbg(" Total MEM Resources:\n");
377 print_pci_resource (ab->tmem_head);
378 }
379 if (ab->mem_head) {
380 dbg(" MEM Resources:\n");
381 print_pci_resource (ab->mem_head);
382 }
383
384 if (ab->tp_mem_head) {
385 dbg(" Total PMEM Resources:\n");
386 print_pci_resource (ab->tp_mem_head);
387 }
388 if (ab->p_mem_head) {
389 dbg(" PMEM Resources:\n");
390 print_pci_resource (ab->p_mem_head);
391 }
392 if (ab->_hpp) {
393 dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
394 dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer);
395 dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr);
396 dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr);
397 }
398}
399
400static int pciehprm_delete_resource(
401 struct pci_resource **aprh,
402 ulong base,
403 ulong size)
404{
405 struct pci_resource *res;
406 struct pci_resource *prevnode;
407 struct pci_resource *split_node;
408 ulong tbase;
409
410 pciehp_resource_sort_and_combine(aprh);
411
412 for (res = *aprh; res; res = res->next) {
413 if (res->base > base)
414 continue;
415
416 if ((res->base + res->length) < (base + size))
417 continue;
418
419 if (res->base < base) {
420 tbase = base;
421
422 if ((res->length - (tbase - res->base)) < size)
423 continue;
424
425 split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
426 if (!split_node)
427 return -ENOMEM;
428
429 split_node->base = res->base;
430 split_node->length = tbase - res->base;
431 res->base = tbase;
432 res->length -= split_node->length;
433
434 split_node->next = res->next;
435 res->next = split_node;
436 }
437
438 if (res->length >= size) {
439 split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
440 if (!split_node)
441 return -ENOMEM;
442
443 split_node->base = res->base + size;
444 split_node->length = res->length - size;
445 res->length = size;
446
447 split_node->next = res->next;
448 res->next = split_node;
449 }
450
451 if (*aprh == res) {
452 *aprh = res->next;
453 } else {
454 prevnode = *aprh;
455 while (prevnode->next != res)
456 prevnode = prevnode->next;
457
458 prevnode->next = res->next;
459 }
460 res->next = NULL;
461 kfree(res);
462 break;
463 }
464
465 return 0;
466}
467
468static int pciehprm_delete_resources(
469 struct pci_resource **aprh,
470 struct pci_resource *this
471 )
472{
473 struct pci_resource *res;
474
475 for (res = this; res; res = res->next)
476 pciehprm_delete_resource(aprh, res->base, res->length);
477
478 return 0;
479}
480
481static int pciehprm_add_resource(
482 struct pci_resource **aprh,
483 ulong base,
484 ulong size)
485{
486 struct pci_resource *res;
487
488 for (res = *aprh; res; res = res->next) {
489 if ((res->base + res->length) == base) {
490 res->length += size;
491 size = 0L;
492 break;
493 }
494 if (res->next == *aprh)
495 break;
496 }
497
498 if (size) {
499 res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
500 if (!res) {
501 err ("acpi_pciehprm: alloc for res fail\n");
502 return -ENOMEM;
503 }
504 memset(res, 0, sizeof (struct pci_resource));
505
506 res->base = base;
507 res->length = size;
508 res->next = *aprh;
509 *aprh = res;
510 }
511
512 return 0;
513}
514
515static int pciehprm_add_resources(
516 struct pci_resource **aprh,
517 struct pci_resource *this
518 )
519{
520 struct pci_resource *res;
521 int rc = 0;
522
523 for (res = this; res && !rc; res = res->next)
524 rc = pciehprm_add_resource(aprh, res->base, res->length);
525
526 return rc;
527}
528
529static void acpi_parse_io (
530 struct acpi_bridge *ab,
531 union acpi_resource_data *data
532 )
533{
534 struct acpi_resource_io *dataio;
535 dataio = (struct acpi_resource_io *) data;
536
537 dbg("Io Resource\n");
538 dbg(" %d bit decode\n", ACPI_DECODE_16 == dataio->io_decode ? 16:10);
539 dbg(" Range minimum base: %08X\n", dataio->min_base_address);
540 dbg(" Range maximum base: %08X\n", dataio->max_base_address);
541 dbg(" Alignment: %08X\n", dataio->alignment);
542 dbg(" Range Length: %08X\n", dataio->range_length);
543}
544
545static void acpi_parse_fixed_io (
546 struct acpi_bridge *ab,
547 union acpi_resource_data *data
548 )
549{
550 struct acpi_resource_fixed_io *datafio;
551 datafio = (struct acpi_resource_fixed_io *) data;
552
553 dbg("Fixed Io Resource\n");
554 dbg(" Range base address: %08X", datafio->base_address);
555 dbg(" Range length: %08X", datafio->range_length);
556}
557
558static void acpi_parse_address16_32 (
559 struct acpi_bridge *ab,
560 union acpi_resource_data *data,
561 acpi_resource_type id
562 )
563{
564 /*
565 * acpi_resource_address16 == acpi_resource_address32
566 * acpi_resource_address16 *data16 = (acpi_resource_address16 *) data;
567 */
568 struct acpi_resource_address32 *data32 = (struct acpi_resource_address32 *) data;
569 struct pci_resource **aprh, **tprh;
570
571 if (id == ACPI_RSTYPE_ADDRESS16)
572 dbg("acpi_pciehprm:16-Bit Address Space Resource\n");
573 else
574 dbg("acpi_pciehprm:32-Bit Address Space Resource\n");
575
576 switch (data32->resource_type) {
577 case ACPI_MEMORY_RANGE:
578 dbg(" Resource Type: Memory Range\n");
579 aprh = &ab->mem_head;
580 tprh = &ab->tmem_head;
581
582 switch (data32->attribute.memory.cache_attribute) {
583 case ACPI_NON_CACHEABLE_MEMORY:
584 dbg(" Type Specific: Noncacheable memory\n");
585 break;
586 case ACPI_CACHABLE_MEMORY:
587 dbg(" Type Specific: Cacheable memory\n");
588 break;
589 case ACPI_WRITE_COMBINING_MEMORY:
590 dbg(" Type Specific: Write-combining memory\n");
591 break;
592 case ACPI_PREFETCHABLE_MEMORY:
593 aprh = &ab->p_mem_head;
594 dbg(" Type Specific: Prefetchable memory\n");
595 break;
596 default:
597 dbg(" Type Specific: Invalid cache attribute\n");
598 break;
599 }
600
601 dbg(" Type Specific: Read%s\n", ACPI_READ_WRITE_MEMORY == data32->attribute.memory.read_write_attribute ? "/Write":" Only");
602 break;
603
604 case ACPI_IO_RANGE:
605 dbg(" Resource Type: I/O Range\n");
606 aprh = &ab->io_head;
607 tprh = &ab->tio_head;
608
609 switch (data32->attribute.io.range_attribute) {
610 case ACPI_NON_ISA_ONLY_RANGES:
611 dbg(" Type Specific: Non-ISA Io Addresses\n");
612 break;
613 case ACPI_ISA_ONLY_RANGES:
614 dbg(" Type Specific: ISA Io Addresses\n");
615 break;
616 case ACPI_ENTIRE_RANGE:
617 dbg(" Type Specific: ISA and non-ISA Io Addresses\n");
618 break;
619 default:
620 dbg(" Type Specific: Invalid range attribute\n");
621 break;
622 }
623 break;
624
625 case ACPI_BUS_NUMBER_RANGE:
626 dbg(" Resource Type: Bus Number Range(fixed)\n");
627 /* fixup to be compatible with the rest of php driver */
628 data32->min_address_range++;
629 data32->address_length--;
630 aprh = &ab->bus_head;
631 tprh = &ab->tbus_head;
632 break;
633 default:
634 dbg(" Resource Type: Invalid resource type. Exiting.\n");
635 return;
636 }
637
638 dbg(" Resource %s\n", ACPI_CONSUMER == data32->producer_consumer ? "Consumer":"Producer");
639 dbg(" %s decode\n", ACPI_SUB_DECODE == data32->decode ? "Subtractive":"Positive");
640 dbg(" Min address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->min_address_fixed ? "":"not");
641 dbg(" Max address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->max_address_fixed ? "":"not");
642 dbg(" Granularity: %08X\n", data32->granularity);
643 dbg(" Address range min: %08X\n", data32->min_address_range);
644 dbg(" Address range max: %08X\n", data32->max_address_range);
645 dbg(" Address translation offset: %08X\n", data32->address_translation_offset);
646 dbg(" Address Length: %08X\n", data32->address_length);
647
648 if (0xFF != data32->resource_source.index) {
649 dbg(" Resource Source Index: %X\n", data32->resource_source.index);
650 /* dbg(" Resource Source: %s\n", data32->resource_source.string_ptr); */
651 }
652
653 pciehprm_add_resource(aprh, data32->min_address_range, data32->address_length);
654}
655
656static acpi_status acpi_parse_crs(
657 struct acpi_bridge *ab,
658 struct acpi_resource *crsbuf
659 )
660{
661 acpi_status status = AE_OK;
662 struct acpi_resource *resource = crsbuf;
663 u8 count = 0;
664 u8 done = 0;
665
666 while (!done) {
667 dbg("acpi_pciehprm: PCI bus 0x%x Resource structure %x.\n", ab->bus, count++);
668 switch (resource->id) {
669 case ACPI_RSTYPE_IRQ:
670 dbg("Irq -------- Resource\n");
671 break;
672 case ACPI_RSTYPE_DMA:
673 dbg("DMA -------- Resource\n");
674 break;
675 case ACPI_RSTYPE_START_DPF:
676 dbg("Start DPF -------- Resource\n");
677 break;
678 case ACPI_RSTYPE_END_DPF:
679 dbg("End DPF -------- Resource\n");
680 break;
681 case ACPI_RSTYPE_IO:
682 acpi_parse_io (ab, &resource->data);
683 break;
684 case ACPI_RSTYPE_FIXED_IO:
685 acpi_parse_fixed_io (ab, &resource->data);
686 break;
687 case ACPI_RSTYPE_VENDOR:
688 dbg("Vendor -------- Resource\n");
689 break;
690 case ACPI_RSTYPE_END_TAG:
691 dbg("End_tag -------- Resource\n");
692 done = 1;
693 break;
694 case ACPI_RSTYPE_MEM24:
695 dbg("Mem24 -------- Resource\n");
696 break;
697 case ACPI_RSTYPE_MEM32:
698 dbg("Mem32 -------- Resource\n");
699 break;
700 case ACPI_RSTYPE_FIXED_MEM32:
701 dbg("Fixed Mem32 -------- Resource\n");
702 break;
703 case ACPI_RSTYPE_ADDRESS16:
704 acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS16);
705 break;
706 case ACPI_RSTYPE_ADDRESS32:
707 acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS32);
708 break;
709 case ACPI_RSTYPE_ADDRESS64:
710 info("Address64 -------- Resource unparsed\n");
711 break;
712 case ACPI_RSTYPE_EXT_IRQ:
713 dbg("Ext Irq -------- Resource\n");
714 break;
715 default:
716 dbg("Invalid -------- resource type 0x%x\n", resource->id);
717 break;
718 }
719
720 resource = (struct acpi_resource *) ((char *)resource + resource->length);
721 }
722
723 return status;
724}
725
726static acpi_status acpi_get_crs( struct acpi_bridge *ab)
727{
728 acpi_status status;
729 struct acpi_resource *crsbuf;
730
731 status = acpi_evaluate_crs(ab->handle, &crsbuf);
732 if (ACPI_SUCCESS(status)) {
733 status = acpi_parse_crs(ab, crsbuf);
734 kfree(crsbuf);
735
736 pciehp_resource_sort_and_combine(&ab->bus_head);
737 pciehp_resource_sort_and_combine(&ab->io_head);
738 pciehp_resource_sort_and_combine(&ab->mem_head);
739 pciehp_resource_sort_and_combine(&ab->p_mem_head);
740
741 pciehprm_add_resources (&ab->tbus_head, ab->bus_head);
742 pciehprm_add_resources (&ab->tio_head, ab->io_head);
743 pciehprm_add_resources (&ab->tmem_head, ab->mem_head);
744 pciehprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
745 }
746
747 return status;
748}
749
750/* find acpi_bridge downword from ab. */
751static struct acpi_bridge *
752find_acpi_bridge_by_bus(
753 struct acpi_bridge *ab,
754 int seg,
755 int bus /* pdev->subordinate->number */
756 )
757{
758 struct acpi_bridge *lab = NULL;
759
760 if (!ab)
761 return NULL;
762
763 if ((ab->bus == bus) && (ab->seg == seg))
764 return ab;
765
766 if (ab->child)
767 lab = find_acpi_bridge_by_bus(ab->child, seg, bus);
768
769 if (!lab)
770 if (ab->next)
771 lab = find_acpi_bridge_by_bus(ab->next, seg, bus);
772
773 return lab;
774}
775
776/*
777 * Build a device tree of ACPI PCI Bridges
778 */
779static void pciehprm_acpi_register_a_bridge (
780 struct acpi_bridge **head,
781 struct acpi_bridge *pab, /* parent bridge to which child bridge is added */
782 struct acpi_bridge *cab /* child bridge to add */
783 )
784{
785 struct acpi_bridge *lpab;
786 struct acpi_bridge *lcab;
787
788 lpab = find_acpi_bridge_by_bus(*head, pab->seg, pab->bus);
789 if (!lpab) {
790 if (!(pab->type & BRIDGE_TYPE_HOST))
791 warn("PCI parent bridge s:b(%x:%x) not in list.\n", pab->seg, pab->bus);
792 pab->next = *head;
793 *head = pab;
794 lpab = pab;
795 }
796
797 if ((cab->type & BRIDGE_TYPE_HOST) && (pab == cab))
798 return;
799
800 lcab = find_acpi_bridge_by_bus(*head, cab->seg, cab->bus);
801 if (lcab) {
802 if ((pab->bus != lcab->parent->bus) || (lcab->bus != cab->bus))
803 err("PCI child bridge s:b(%x:%x) in list with diff parent.\n", cab->seg, cab->bus);
804 return;
805 } else
806 lcab = cab;
807
808 lcab->parent = lpab;
809 lcab->next = lpab->child;
810 lpab->child = lcab;
811}
812
813static acpi_status pciehprm_acpi_build_php_slots_callback(
814 acpi_handle handle,
815 u32 Level,
816 void *context,
817 void **retval
818 )
819{
820 ulong bus_num;
821 ulong seg_num;
822 ulong sun, adr;
823 ulong padr = 0;
824 acpi_handle phandle = NULL;
825 struct acpi_bridge *pab = (struct acpi_bridge *)context;
826 struct acpi_bridge *lab;
827 acpi_status status;
828 u8 *path_name = acpi_path_name(handle);
829
830 /* get _SUN */
831 status = acpi_evaluate_integer(handle, METHOD_NAME__SUN, NULL, &sun);
832 switch(status) {
833 case AE_NOT_FOUND:
834 return AE_OK;
835 default:
836 if (ACPI_FAILURE(status)) {
837 err("acpi_pciehprm:%s _SUN fail=0x%x\n", path_name, status);
838 return status;
839 }
840 }
841
842 /* get _ADR. _ADR must exist if _SUN exists */
843 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
844 if (ACPI_FAILURE(status)) {
845 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
846 return status;
847 }
848
849 dbg("acpi_pciehprm:%s sun=0x%08x adr=0x%08x\n", path_name, (u32)sun, (u32)adr);
850
851 status = acpi_get_parent(handle, &phandle);
852 if (ACPI_FAILURE(status)) {
853 err("acpi_pciehprm:%s get_parent fail=0x%x\n", path_name, status);
854 return (status);
855 }
856
857 bus_num = pab->bus;
858 seg_num = pab->seg;
859
860 if (pab->bus == bus_num) {
861 lab = pab;
862 } else {
863 dbg("WARN: pab is not parent\n");
864 lab = find_acpi_bridge_by_bus(pab, seg_num, bus_num);
865 if (!lab) {
866 dbg("acpi_pciehprm: alloc new P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
867 lab = (struct acpi_bridge *)kmalloc(sizeof(struct acpi_bridge), GFP_KERNEL);
868 if (!lab) {
869 err("acpi_pciehprm: alloc for ab fail\n");
870 return AE_NO_MEMORY;
871 }
872 memset(lab, 0, sizeof(struct acpi_bridge));
873
874 lab->handle = phandle;
875 lab->pbus = pab->bus;
876 lab->pdevice = (int)(padr >> 16) & 0xffff;
877 lab->pfunction = (int)(padr & 0xffff);
878 lab->bus = (int)bus_num;
879 lab->scanned = 0;
880 lab->type = BRIDGE_TYPE_P2P;
881
882 pciehprm_acpi_register_a_bridge (&acpi_bridges_head, pab, lab);
883 } else
884 dbg("acpi_pciehprm: found P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
885 }
886
887 acpi_add_slot_to_php_slots(lab, (int)bus_num, handle, (u32)adr, (u32)sun);
888
889 return (status);
890}
891
892static int pciehprm_acpi_build_php_slots(
893 struct acpi_bridge *ab,
894 u32 depth
895 )
896{
897 acpi_status status;
898 u8 *path_name = acpi_path_name(ab->handle);
899
900 /* Walk down this pci bridge to get _SUNs if any behind P2P */
901 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
902 ab->handle,
903 depth,
904 pciehprm_acpi_build_php_slots_callback,
905 ab,
906 NULL );
907 if (ACPI_FAILURE(status)) {
908 dbg("acpi_pciehprm:%s walk for _SUN on pci bridge seg:bus(%x:%x) fail=0x%x\n", path_name, ab->seg, ab->bus, status);
909 return -1;
910 }
911
912 return 0;
913}
914
915static void build_a_bridge(
916 struct acpi_bridge *pab,
917 struct acpi_bridge *ab
918 )
919{
920 u8 *path_name = acpi_path_name(ab->handle);
921
922 pciehprm_acpi_register_a_bridge (&acpi_bridges_head, pab, ab);
923
924 switch (ab->type) {
925 case BRIDGE_TYPE_HOST:
926 dbg("acpi_pciehprm: Registered PCI HOST Bridge(%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
927 ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
928 break;
929 case BRIDGE_TYPE_P2P:
930 dbg("acpi_pciehprm: Registered PCI P2P Bridge(%02x-%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
931 ab->pbus, ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
932 break;
933 };
934
935 /* build any immediate PHP slots under this pci bridge */
936 pciehprm_acpi_build_php_slots(ab, 1);
937}
938
939static struct acpi_bridge * add_p2p_bridge(
940 acpi_handle handle,
941 struct acpi_bridge *pab, /* parent */
942 ulong adr
943 )
944{
945 struct acpi_bridge *ab;
946 struct pci_dev *pdev;
947 ulong devnum, funcnum;
948 u8 *path_name = acpi_path_name(handle);
949
950 ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
951 if (!ab) {
952 err("acpi_pciehprm: alloc for ab fail\n");
953 return NULL;
954 }
955 memset(ab, 0, sizeof(struct acpi_bridge));
956
957 devnum = (adr >> 16) & 0xffff;
958 funcnum = adr & 0xffff;
959
960 pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
961 if (!pdev || !pdev->subordinate) {
962 err("acpi_pciehprm:%s is not a P2P Bridge\n", path_name);
963 kfree(ab);
964 return NULL;
965 }
966
967 ab->handle = handle;
968 ab->seg = pab->seg;
969 ab->pbus = pab->bus; /* or pdev->bus->number */
970 ab->pdevice = devnum; /* or PCI_SLOT(pdev->devfn) */
971 ab->pfunction = funcnum; /* or PCI_FUNC(pdev->devfn) */
972 ab->bus = pdev->subordinate->number;
973 ab->scanned = 0;
974 ab->type = BRIDGE_TYPE_P2P;
975
976 dbg("acpi_pciehprm: P2P(%x-%x) on pci=b:d:f(%x:%x:%x) acpi=b:d:f(%x:%x:%x) [%s]\n",
977 pab->bus, ab->bus, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
978 pab->bus, (u32)devnum, (u32)funcnum, path_name);
979
980 build_a_bridge(pab, ab);
981
982 return ab;
983}
984
985static acpi_status scan_p2p_bridge(
986 acpi_handle handle,
987 u32 Level,
988 void *context,
989 void **retval
990 )
991{
992 struct acpi_bridge *pab = (struct acpi_bridge *)context;
993 struct acpi_bridge *ab;
994 acpi_status status;
995 ulong adr = 0;
996 u8 *path_name = acpi_path_name(handle);
997 ulong devnum, funcnum;
998 struct pci_dev *pdev;
999
1000 /* get device, function */
1001 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
1002 if (ACPI_FAILURE(status)) {
1003 if (status != AE_NOT_FOUND)
1004 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
1005 return AE_OK;
1006 }
1007
1008 devnum = (adr >> 16) & 0xffff;
1009 funcnum = adr & 0xffff;
1010
1011 pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
1012 if (!pdev)
1013 return AE_OK;
1014 if (!pdev->subordinate)
1015 return AE_OK;
1016
1017 ab = add_p2p_bridge(handle, pab, adr);
1018 if (ab) {
1019 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
1020 handle,
1021 (u32)1,
1022 scan_p2p_bridge,
1023 ab,
1024 NULL);
1025 if (ACPI_FAILURE(status))
1026 dbg("acpi_pciehprm:%s find_p2p fail=0x%x\n", path_name, status);
1027 }
1028
1029 return AE_OK;
1030}
1031
1032static struct acpi_bridge * add_host_bridge(
1033 acpi_handle handle,
1034 ulong segnum,
1035 ulong busnum
1036 )
1037{
1038 ulong adr = 0;
1039 acpi_status status;
1040 struct acpi_bridge *ab;
1041 u8 *path_name = acpi_path_name(handle);
1042
1043 /* get device, function: host br adr is always 0000 though. */
1044 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
1045 if (ACPI_FAILURE(status)) {
1046 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
1047 return NULL;
1048 }
1049 dbg("acpi_pciehprm: ROOT PCI seg(0x%x)bus(0x%x)dev(0x%x)func(0x%x) [%s]\n", (u32)segnum,
1050 (u32)busnum, (u32)(adr >> 16) & 0xffff, (u32)adr & 0xffff, path_name);
1051
1052 ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
1053 if (!ab) {
1054 err("acpi_pciehprm: alloc for ab fail\n");
1055 return NULL;
1056 }
1057 memset(ab, 0, sizeof(struct acpi_bridge));
1058
1059 ab->handle = handle;
1060 ab->seg = (int)segnum;
1061 ab->bus = ab->pbus = (int)busnum;
1062 ab->pdevice = (int)(adr >> 16) & 0xffff;
1063 ab->pfunction = (int)(adr & 0xffff);
1064 ab->scanned = 0;
1065 ab->type = BRIDGE_TYPE_HOST;
1066
1067 /* get root pci bridge's current resources */
1068 status = acpi_get_crs(ab);
1069 if (ACPI_FAILURE(status)) {
1070 err("acpi_pciehprm:%s evaluate _CRS fail=0x%x\n", path_name, status);
1071 kfree(ab);
1072 return NULL;
1073 }
1074
1075 status = pci_osc_control_set (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
1076 if (ACPI_FAILURE(status)) {
1077 err("%s: status %x\n", __FUNCTION__, status);
1078 osc_run_status = (status == AE_NOT_FOUND) ? OSC_NOT_EXIST : OSC_RUN_FAILED;
1079 } else {
1080 osc_run_status = NC_RUN_SUCCESS;
1081 }
1082 dbg("%s: osc_run_status %x\n", __FUNCTION__, osc_run_status);
1083
1084 build_a_bridge(ab, ab);
1085
1086 return ab;
1087}
1088
1089static acpi_status acpi_scan_from_root_pci_callback (
1090 acpi_handle handle,
1091 u32 Level,
1092 void *context,
1093 void **retval
1094 )
1095{
1096 ulong segnum = 0;
1097 ulong busnum = 0;
1098 acpi_status status;
1099 struct acpi_bridge *ab;
1100 u8 *path_name = acpi_path_name(handle);
1101
1102 /* get bus number of this pci root bridge */
1103 status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &segnum);
1104 if (ACPI_FAILURE(status)) {
1105 if (status != AE_NOT_FOUND) {
1106 err("acpi_pciehprm:%s evaluate _SEG fail=0x%x\n", path_name, status);
1107 return status;
1108 }
1109 segnum = 0;
1110 }
1111
1112 /* get bus number of this pci root bridge */
1113 status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, &busnum);
1114 if (ACPI_FAILURE(status)) {
1115 err("acpi_pciehprm:%s evaluate _BBN fail=0x%x\n", path_name, status);
1116 return (status);
1117 }
1118
1119 ab = add_host_bridge(handle, segnum, busnum);
1120 if (ab) {
1121 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
1122 handle,
1123 1,
1124 scan_p2p_bridge,
1125 ab,
1126 NULL);
1127 if (ACPI_FAILURE(status))
1128 dbg("acpi_pciehprm:%s find_p2p fail=0x%x\n", path_name, status);
1129 }
1130
1131 return AE_OK;
1132}
1133
1134static int pciehprm_acpi_scan_pci (void)
1135{
1136 acpi_status status;
1137
1138 /*
1139 * TBD: traverse LDM device tree with the help of
1140 * unified ACPI augmented for php device population.
1141 */
1142 status = acpi_get_devices ( PCI_ROOT_HID_STRING,
1143 acpi_scan_from_root_pci_callback,
1144 NULL,
1145 NULL );
1146 if (ACPI_FAILURE(status)) {
1147 err("acpi_pciehprm:get_device PCI ROOT HID fail=0x%x\n", status);
1148 return -1;
1149 }
1150
1151 return 0;
1152}
1153
1154int pciehprm_init(enum php_ctlr_type ctlr_type)
1155{
1156 int rc;
1157
1158 if (ctlr_type != PCI)
1159 return -ENODEV;
1160
1161 dbg("pciehprm ACPI init <enter>\n");
1162 acpi_bridges_head = NULL;
1163
1164 /* construct PCI bus:device tree of acpi_handles */
1165 rc = pciehprm_acpi_scan_pci();
1166 if (rc)
1167 return rc;
1168
1169 if ((oshp_run_status != NC_RUN_SUCCESS) && (osc_run_status != NC_RUN_SUCCESS)) {
1170 err("Fails to gain control of native hot-plug\n");
1171 rc = -ENODEV;
1172 }
1173
1174 dbg("pciehprm ACPI init %s\n", (rc)?"fail":"success");
1175 return rc;
1176}
1177
1178static void free_a_slot(struct acpi_php_slot *aps)
1179{
1180 dbg(" free a php func of slot(0x%02x) on PCI b:d:f=0x%02x:%02x:%02x\n", aps->sun, aps->bus, aps->dev, aps->fun);
1181
1182 free_pci_resource (aps->io_head);
1183 free_pci_resource (aps->bus_head);
1184 free_pci_resource (aps->mem_head);
1185 free_pci_resource (aps->p_mem_head);
1186
1187 kfree(aps);
1188}
1189
1190static void free_a_bridge( struct acpi_bridge *ab)
1191{
1192 struct acpi_php_slot *aps, *next;
1193
1194 switch (ab->type) {
1195 case BRIDGE_TYPE_HOST:
1196 dbg("Free ACPI PCI HOST Bridge(%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
1197 ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
1198 break;
1199 case BRIDGE_TYPE_P2P:
1200 dbg("Free ACPI PCI P2P Bridge(%x-%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
1201 ab->pbus, ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
1202 break;
1203 };
1204
1205 /* free slots first */
1206 for (aps = ab->slots; aps; aps = next) {
1207 next = aps->next;
1208 free_a_slot(aps);
1209 }
1210
1211 free_pci_resource (ab->io_head);
1212 free_pci_resource (ab->tio_head);
1213 free_pci_resource (ab->bus_head);
1214 free_pci_resource (ab->tbus_head);
1215 free_pci_resource (ab->mem_head);
1216 free_pci_resource (ab->tmem_head);
1217 free_pci_resource (ab->p_mem_head);
1218 free_pci_resource (ab->tp_mem_head);
1219
1220 kfree(ab);
1221}
1222
1223static void pciehprm_free_bridges ( struct acpi_bridge *ab)
1224{
1225 if (!ab)
1226 return;
1227
1228 if (ab->child)
1229 pciehprm_free_bridges (ab->child);
1230
1231 if (ab->next)
1232 pciehprm_free_bridges (ab->next);
1233
1234 free_a_bridge(ab);
1235}
1236
1237void pciehprm_cleanup(void)
1238{
1239 pciehprm_free_bridges (acpi_bridges_head);
1240}
1241
1242static int get_number_of_slots (
1243 struct acpi_bridge *ab,
1244 int selfonly
1245 )
1246{
1247 struct acpi_php_slot *aps;
1248 int prev_slot = -1;
1249 int slot_num = 0;
1250
1251 for ( aps = ab->slots; aps; aps = aps->next)
1252 if (aps->dev != prev_slot) {
1253 prev_slot = aps->dev;
1254 slot_num++;
1255 }
1256
1257 if (ab->child)
1258 slot_num += get_number_of_slots (ab->child, 0);
1259
1260 if (selfonly)
1261 return slot_num;
1262
1263 if (ab->next)
1264 slot_num += get_number_of_slots (ab->next, 0);
1265
1266 return slot_num;
1267}
1268
1269static int print_acpi_resources (struct acpi_bridge *ab)
1270{
1271 struct acpi_php_slot *aps;
1272 int i;
1273
1274 switch (ab->type) {
1275 case BRIDGE_TYPE_HOST:
1276 dbg("PCI HOST Bridge (%x) [%s]\n", ab->bus, acpi_path_name(ab->handle));
1277 break;
1278 case BRIDGE_TYPE_P2P:
1279 dbg("PCI P2P Bridge (%x-%x) [%s]\n", ab->pbus, ab->bus, acpi_path_name(ab->handle));
1280 break;
1281 };
1282
1283 print_pci_resources (ab);
1284
1285 for ( i = -1, aps = ab->slots; aps; aps = aps->next) {
1286 if (aps->dev == i)
1287 continue;
1288 dbg(" Slot sun(%x) s:b:d:f(%02x:%02x:%02x:%02x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
1289 print_slot_resources(aps);
1290 i = aps->dev;
1291 }
1292
1293 if (ab->child)
1294 print_acpi_resources (ab->child);
1295
1296 if (ab->next)
1297 print_acpi_resources (ab->next);
1298
1299 return 0;
1300}
1301
1302int pciehprm_print_pirt(void)
1303{
1304 dbg("PCIEHPRM ACPI Slots\n");
1305 if (acpi_bridges_head)
1306 print_acpi_resources (acpi_bridges_head);
1307
1308 return 0;
1309}
1310
1311static struct acpi_php_slot * get_acpi_slot (
1312 struct acpi_bridge *ab,
1313 u32 sun
1314 )
1315{
1316 struct acpi_php_slot *aps = NULL;
1317
1318 for ( aps = ab->slots; aps; aps = aps->next)
1319 if (aps->sun == sun)
1320 return aps;
1321
1322 if (!aps && ab->child) {
1323 aps = (struct acpi_php_slot *)get_acpi_slot (ab->child, sun);
1324 if (aps)
1325 return aps;
1326 }
1327
1328 if (!aps && ab->next) {
1329 aps = (struct acpi_php_slot *)get_acpi_slot (ab->next, sun);
1330 if (aps)
1331 return aps;
1332 }
1333
1334 return aps;
1335
1336}
1337
1338#if 0
1339void * pciehprm_get_slot(struct slot *slot)
1340{
1341 struct acpi_bridge *ab = acpi_bridges_head;
1342 struct acpi_php_slot *aps = get_acpi_slot (ab, slot->number);
1343
1344 aps->slot = slot;
1345
1346 dbg("Got acpi slot sun(%x): s:b:d:f(%x:%x:%x:%x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
1347
1348 return (void *)aps;
1349}
1350#endif
1351
1352static void pciehprm_dump_func_res( struct pci_func *fun)
1353{
1354 struct pci_func *func = fun;
1355
1356 if (func->bus_head) {
1357 dbg(": BUS Resources:\n");
1358 print_pci_resource (func->bus_head);
1359 }
1360 if (func->io_head) {
1361 dbg(": IO Resources:\n");
1362 print_pci_resource (func->io_head);
1363 }
1364 if (func->mem_head) {
1365 dbg(": MEM Resources:\n");
1366 print_pci_resource (func->mem_head);
1367 }
1368 if (func->p_mem_head) {
1369 dbg(": PMEM Resources:\n");
1370 print_pci_resource (func->p_mem_head);
1371 }
1372}
1373
1374static void pciehprm_dump_ctrl_res( struct controller *ctlr)
1375{
1376 struct controller *ctrl = ctlr;
1377
1378 if (ctrl->bus_head) {
1379 dbg(": BUS Resources:\n");
1380 print_pci_resource (ctrl->bus_head);
1381 }
1382 if (ctrl->io_head) {
1383 dbg(": IO Resources:\n");
1384 print_pci_resource (ctrl->io_head);
1385 }
1386 if (ctrl->mem_head) {
1387 dbg(": MEM Resources:\n");
1388 print_pci_resource (ctrl->mem_head);
1389 }
1390 if (ctrl->p_mem_head) {
1391 dbg(": PMEM Resources:\n");
1392 print_pci_resource (ctrl->p_mem_head);
1393 }
1394}
1395
1396static int pciehprm_get_used_resources (
1397 struct controller *ctrl,
1398 struct pci_func *func
1399 )
1400{
1401 return pciehp_save_used_resources (ctrl, func, !DISABLE_CARD);
1402}
1403
1404static int configure_existing_function(
1405 struct controller *ctrl,
1406 struct pci_func *func
1407 )
1408{
1409 int rc;
1410
1411 /* see how much resources the func has used. */
1412 rc = pciehprm_get_used_resources (ctrl, func);
1413
1414 if (!rc) {
1415 /* subtract the resources used by the func from ctrl resources */
1416 rc = pciehprm_delete_resources (&ctrl->bus_head, func->bus_head);
1417 rc |= pciehprm_delete_resources (&ctrl->io_head, func->io_head);
1418 rc |= pciehprm_delete_resources (&ctrl->mem_head, func->mem_head);
1419 rc |= pciehprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
1420 if (rc)
1421 warn("aCEF: cannot del used resources\n");
1422 } else
1423 err("aCEF: cannot get used resources\n");
1424
1425 return rc;
1426}
1427
1428static int bind_pci_resources_to_slots ( struct controller *ctrl)
1429{
1430 struct pci_func *func, new_func;
1431 int busn = ctrl->slot_bus;
1432 int devn, funn;
1433 u32 vid;
1434
1435 for (devn = 0; devn < 32; devn++) {
1436 for (funn = 0; funn < 8; funn++) {
1437 /*
1438 if (devn == ctrl->device && funn == ctrl->function)
1439 continue;
1440 */
1441 /* find out if this entry is for an occupied slot */
1442 vid = 0xFFFFFFFF;
1443 pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
1444
1445 if (vid != 0xFFFFFFFF) {
1446 dbg("%s: vid = %x\n", __FUNCTION__, vid);
1447 func = pciehp_slot_find(busn, devn, funn);
1448 if (!func) {
1449 memset(&new_func, 0, sizeof(struct pci_func));
1450 new_func.bus = busn;
1451 new_func.device = devn;
1452 new_func.function = funn;
1453 new_func.is_a_board = 1;
1454 configure_existing_function(ctrl, &new_func);
1455 pciehprm_dump_func_res(&new_func);
1456 } else {
1457 configure_existing_function(ctrl, func);
1458 pciehprm_dump_func_res(func);
1459 }
1460 dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
1461 }
1462 }
1463 }
1464
1465 return 0;
1466}
1467
1468static int bind_pci_resources(
1469 struct controller *ctrl,
1470 struct acpi_bridge *ab
1471 )
1472{
1473 int status = 0;
1474
1475 if (ab->bus_head) {
1476 dbg("bapr: BUS Resources add on PCI 0x%x\n", ab->bus);
1477 status = pciehprm_add_resources (&ctrl->bus_head, ab->bus_head);
1478 if (pciehprm_delete_resources (&ab->bus_head, ctrl->bus_head))
1479 warn("bapr: cannot sub BUS Resource on PCI 0x%x\n", ab->bus);
1480 if (status) {
1481 err("bapr: BUS Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1482 return status;
1483 }
1484 } else
1485 info("bapr: No BUS Resource on PCI 0x%x.\n", ab->bus);
1486
1487 if (ab->io_head) {
1488 dbg("bapr: IO Resources add on PCI 0x%x\n", ab->bus);
1489 status = pciehprm_add_resources (&ctrl->io_head, ab->io_head);
1490 if (pciehprm_delete_resources (&ab->io_head, ctrl->io_head))
1491 warn("bapr: cannot sub IO Resource on PCI 0x%x\n", ab->bus);
1492 if (status) {
1493 err("bapr: IO Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1494 return status;
1495 }
1496 } else
1497 info("bapr: No IO Resource on PCI 0x%x.\n", ab->bus);
1498
1499 if (ab->mem_head) {
1500 dbg("bapr: MEM Resources add on PCI 0x%x\n", ab->bus);
1501 status = pciehprm_add_resources (&ctrl->mem_head, ab->mem_head);
1502 if (pciehprm_delete_resources (&ab->mem_head, ctrl->mem_head))
1503 warn("bapr: cannot sub MEM Resource on PCI 0x%x\n", ab->bus);
1504 if (status) {
1505 err("bapr: MEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1506 return status;
1507 }
1508 } else
1509 info("bapr: No MEM Resource on PCI 0x%x.\n", ab->bus);
1510
1511 if (ab->p_mem_head) {
1512 dbg("bapr: PMEM Resources add on PCI 0x%x\n", ab->bus);
1513 status = pciehprm_add_resources (&ctrl->p_mem_head, ab->p_mem_head);
1514 if (pciehprm_delete_resources (&ab->p_mem_head, ctrl->p_mem_head))
1515 warn("bapr: cannot sub PMEM Resource on PCI 0x%x\n", ab->bus);
1516 if (status) {
1517 err("bapr: PMEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1518 return status;
1519 }
1520 } else
1521 info("bapr: No PMEM Resource on PCI 0x%x.\n", ab->bus);
1522
1523 return status;
1524}
1525
1526static int no_pci_resources( struct acpi_bridge *ab)
1527{
1528 return !(ab->p_mem_head || ab->mem_head || ab->io_head || ab->bus_head);
1529}
1530
1531static int find_pci_bridge_resources (
1532 struct controller *ctrl,
1533 struct acpi_bridge *ab
1534 )
1535{
1536 int rc = 0;
1537 struct pci_func func;
1538
1539 memset(&func, 0, sizeof(struct pci_func));
1540
1541 func.bus = ab->pbus;
1542 func.device = ab->pdevice;
1543 func.function = ab->pfunction;
1544 func.is_a_board = 1;
1545
1546 /* Get used resources for this PCI bridge */
1547 rc = pciehp_save_used_resources (ctrl, &func, !DISABLE_CARD);
1548
1549 ab->io_head = func.io_head;
1550 ab->mem_head = func.mem_head;
1551 ab->p_mem_head = func.p_mem_head;
1552 ab->bus_head = func.bus_head;
1553 if (ab->bus_head)
1554 pciehprm_delete_resource(&ab->bus_head, ctrl->pci_dev->subordinate->number, 1);
1555
1556 return rc;
1557}
1558
1559static int get_pci_resources_from_bridge(
1560 struct controller *ctrl,
1561 struct acpi_bridge *ab
1562 )
1563{
1564 int rc = 0;
1565
1566 dbg("grfb: Get Resources for PCI 0x%x from actual PCI bridge 0x%x.\n", ctrl->bus, ab->bus);
1567
1568 rc = find_pci_bridge_resources (ctrl, ab);
1569
1570 pciehp_resource_sort_and_combine(&ab->bus_head);
1571 pciehp_resource_sort_and_combine(&ab->io_head);
1572 pciehp_resource_sort_and_combine(&ab->mem_head);
1573 pciehp_resource_sort_and_combine(&ab->p_mem_head);
1574
1575 pciehprm_add_resources (&ab->tbus_head, ab->bus_head);
1576 pciehprm_add_resources (&ab->tio_head, ab->io_head);
1577 pciehprm_add_resources (&ab->tmem_head, ab->mem_head);
1578 pciehprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
1579
1580 return rc;
1581}
1582
1583static int get_pci_resources(
1584 struct controller *ctrl,
1585 struct acpi_bridge *ab
1586 )
1587{
1588 int rc = 0;
1589
1590 if (no_pci_resources(ab)) {
1591 dbg("spbr:PCI 0x%x has no resources. Get parent resources.\n", ab->bus);
1592 rc = get_pci_resources_from_bridge(ctrl, ab);
1593 }
1594
1595 return rc;
1596}
1597
1598/*
1599 * Get resources for this ctrl.
1600 * 1. get total resources from ACPI _CRS or bridge (this ctrl)
1601 * 2. find used resources of existing adapters
1602 * 3. subtract used resources from total resources
1603 */
1604int pciehprm_find_available_resources( struct controller *ctrl)
1605{
1606 int rc = 0;
1607 struct acpi_bridge *ab;
1608
1609 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->pci_dev->subordinate->number);
1610 if (!ab) {
1611 err("pfar:cannot locate acpi bridge of PCI 0x%x.\n", ctrl->pci_dev->subordinate->number);
1612 return -1;
1613 }
1614 if (no_pci_resources(ab)) {
1615 rc = get_pci_resources(ctrl, ab);
1616 if (rc) {
1617 err("pfar:cannot get pci resources of PCI 0x%x.\n", ctrl->pci_dev->subordinate->number);
1618 return -1;
1619 }
1620 }
1621
1622 rc = bind_pci_resources(ctrl, ab);
1623 dbg("pfar:pre-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
1624 pciehprm_dump_ctrl_res(ctrl);
1625
1626 bind_pci_resources_to_slots (ctrl);
1627
1628 dbg("pfar:post-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
1629 pciehprm_dump_ctrl_res(ctrl);
1630
1631 return rc;
1632}
1633
1634int pciehprm_set_hpp(
1635 struct controller *ctrl,
1636 struct pci_func *func,
1637 u8 card_type
1638 )
1639{
1640 struct acpi_bridge *ab;
1641 struct pci_bus lpci_bus, *pci_bus;
1642 int rc = 0;
1643 unsigned int devfn;
1644 u8 cls= 0x08; /* default cache line size */
1645 u8 lt = 0x40; /* default latency timer */
1646 u8 ep = 0;
1647 u8 es = 0;
1648
1649 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
1650 pci_bus = &lpci_bus;
1651 pci_bus->number = func->bus;
1652 devfn = PCI_DEVFN(func->device, func->function);
1653
1654 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
1655
1656 if (ab) {
1657 if (ab->_hpp) {
1658 lt = (u8)ab->_hpp->latency_timer;
1659 cls = (u8)ab->_hpp->cache_line_size;
1660 ep = (u8)ab->_hpp->enable_perr;
1661 es = (u8)ab->_hpp->enable_serr;
1662 } else
1663 dbg("_hpp: no _hpp for B/D/F=%#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
1664 } else
1665 dbg("_hpp: no acpi bridge for B/D/F = %#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
1666
1667
1668 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
1669 /* set subordinate Latency Timer */
1670 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, lt);
1671 }
1672
1673 /* set base Latency Timer */
1674 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, lt);
1675 dbg(" set latency timer =0x%02x: %x\n", lt, rc);
1676
1677 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, cls);
1678 dbg(" set cache_line_size=0x%02x: %x\n", cls, rc);
1679
1680 return rc;
1681}
1682
1683void pciehprm_enable_card(
1684 struct controller *ctrl,
1685 struct pci_func *func,
1686 u8 card_type)
1687{
1688 u16 command, cmd, bcommand, bcmd;
1689 struct pci_bus lpci_bus, *pci_bus;
1690 struct acpi_bridge *ab;
1691 unsigned int devfn;
1692 int rc;
1693
1694 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
1695 pci_bus = &lpci_bus;
1696 pci_bus->number = func->bus;
1697 devfn = PCI_DEVFN(func->device, func->function);
1698
1699 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
1700
1701 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
1702 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
1703 }
1704
1705 cmd = command = command | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
1706 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
1707 bcmd = bcommand = bcommand | PCI_BRIDGE_CTL_NO_ISA;
1708
1709 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
1710 if (ab) {
1711 if (ab->_hpp) {
1712 if (ab->_hpp->enable_perr) {
1713 command |= PCI_COMMAND_PARITY;
1714 bcommand |= PCI_BRIDGE_CTL_PARITY;
1715 } else {
1716 command &= ~PCI_COMMAND_PARITY;
1717 bcommand &= ~PCI_BRIDGE_CTL_PARITY;
1718 }
1719 if (ab->_hpp->enable_serr) {
1720 command |= PCI_COMMAND_SERR;
1721 bcommand |= PCI_BRIDGE_CTL_SERR;
1722 } else {
1723 command &= ~PCI_COMMAND_SERR;
1724 bcommand &= ~PCI_BRIDGE_CTL_SERR;
1725 }
1726 } else
1727 dbg("no _hpp for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
1728 } else
1729 dbg("no acpi bridge for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
1730
1731 if (command != cmd) {
1732 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
1733 }
1734 if ((card_type == PCI_HEADER_TYPE_BRIDGE) && (bcommand != bcmd)) {
1735 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
1736 }
1737}
diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.c b/drivers/pci/hotplug/pciehprm_nonacpi.c
new file mode 100644
index 000000000000..79a0aa6238ef
--- /dev/null
+++ b/drivers/pci/hotplug/pciehprm_nonacpi.c
@@ -0,0 +1,501 @@
1/*
2 * PCIEHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/types.h>
34#include <linux/pci.h>
35#include <linux/init.h>
36#include <asm/uaccess.h>
37#ifdef CONFIG_IA64
38#include <asm/iosapic.h>
39#endif
40#include "pciehp.h"
41#include "pciehprm.h"
42#include "pciehprm_nonacpi.h"
43
44
45void pciehprm_cleanup(void)
46{
47 return;
48}
49
50int pciehprm_print_pirt(void)
51{
52 return 0;
53}
54
55int pciehprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
56{
57
58 *sun = (u8) (ctrl->first_slot);
59 return 0;
60}
61
62
63static void print_pci_resource ( struct pci_resource *aprh)
64{
65 struct pci_resource *res;
66
67 for (res = aprh; res; res = res->next)
68 dbg(" base= 0x%x length= 0x%x\n", res->base, res->length);
69}
70
71
72static void phprm_dump_func_res( struct pci_func *fun)
73{
74 struct pci_func *func = fun;
75
76 if (func->bus_head) {
77 dbg(": BUS Resources:\n");
78 print_pci_resource (func->bus_head);
79 }
80 if (func->io_head) {
81 dbg(": IO Resources:\n");
82 print_pci_resource (func->io_head);
83 }
84 if (func->mem_head) {
85 dbg(": MEM Resources:\n");
86 print_pci_resource (func->mem_head);
87 }
88 if (func->p_mem_head) {
89 dbg(": PMEM Resources:\n");
90 print_pci_resource (func->p_mem_head);
91 }
92}
93
94static int phprm_get_used_resources (
95 struct controller *ctrl,
96 struct pci_func *func
97 )
98{
99 return pciehp_save_used_resources (ctrl, func, !DISABLE_CARD);
100}
101
102static int phprm_delete_resource(
103 struct pci_resource **aprh,
104 ulong base,
105 ulong size)
106{
107 struct pci_resource *res;
108 struct pci_resource *prevnode;
109 struct pci_resource *split_node;
110 ulong tbase;
111
112 pciehp_resource_sort_and_combine(aprh);
113
114 for (res = *aprh; res; res = res->next) {
115 if (res->base > base)
116 continue;
117
118 if ((res->base + res->length) < (base + size))
119 continue;
120
121 if (res->base < base) {
122 tbase = base;
123
124 if ((res->length - (tbase - res->base)) < size)
125 continue;
126
127 split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
128 if (!split_node)
129 return -ENOMEM;
130
131 split_node->base = res->base;
132 split_node->length = tbase - res->base;
133 res->base = tbase;
134 res->length -= split_node->length;
135
136 split_node->next = res->next;
137 res->next = split_node;
138 }
139
140 if (res->length >= size) {
141 split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
142 if (!split_node)
143 return -ENOMEM;
144
145 split_node->base = res->base + size;
146 split_node->length = res->length - size;
147 res->length = size;
148
149 split_node->next = res->next;
150 res->next = split_node;
151 }
152
153 if (*aprh == res) {
154 *aprh = res->next;
155 } else {
156 prevnode = *aprh;
157 while (prevnode->next != res)
158 prevnode = prevnode->next;
159
160 prevnode->next = res->next;
161 }
162 res->next = NULL;
163 kfree(res);
164 break;
165 }
166
167 return 0;
168}
169
170
171static int phprm_delete_resources(
172 struct pci_resource **aprh,
173 struct pci_resource *this
174 )
175{
176 struct pci_resource *res;
177
178 for (res = this; res; res = res->next)
179 phprm_delete_resource(aprh, res->base, res->length);
180
181 return 0;
182}
183
184
185static int configure_existing_function(
186 struct controller *ctrl,
187 struct pci_func *func
188 )
189{
190 int rc;
191
192 /* see how much resources the func has used. */
193 rc = phprm_get_used_resources (ctrl, func);
194
195 if (!rc) {
196 /* subtract the resources used by the func from ctrl resources */
197 rc = phprm_delete_resources (&ctrl->bus_head, func->bus_head);
198 rc |= phprm_delete_resources (&ctrl->io_head, func->io_head);
199 rc |= phprm_delete_resources (&ctrl->mem_head, func->mem_head);
200 rc |= phprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
201 if (rc)
202 warn("aCEF: cannot del used resources\n");
203 } else
204 err("aCEF: cannot get used resources\n");
205
206 return rc;
207}
208
209static int pciehprm_delete_resource(
210 struct pci_resource **aprh,
211 ulong base,
212 ulong size)
213{
214 struct pci_resource *res;
215 struct pci_resource *prevnode;
216 struct pci_resource *split_node;
217 ulong tbase;
218
219 pciehp_resource_sort_and_combine(aprh);
220
221 for (res = *aprh; res; res = res->next) {
222 if (res->base > base)
223 continue;
224
225 if ((res->base + res->length) < (base + size))
226 continue;
227
228 if (res->base < base) {
229 tbase = base;
230
231 if ((res->length - (tbase - res->base)) < size)
232 continue;
233
234 split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
235 if (!split_node)
236 return -ENOMEM;
237
238 split_node->base = res->base;
239 split_node->length = tbase - res->base;
240 res->base = tbase;
241 res->length -= split_node->length;
242
243 split_node->next = res->next;
244 res->next = split_node;
245 }
246
247 if (res->length >= size) {
248 split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
249 if (!split_node)
250 return -ENOMEM;
251
252 split_node->base = res->base + size;
253 split_node->length = res->length - size;
254 res->length = size;
255
256 split_node->next = res->next;
257 res->next = split_node;
258 }
259
260 if (*aprh == res) {
261 *aprh = res->next;
262 } else {
263 prevnode = *aprh;
264 while (prevnode->next != res)
265 prevnode = prevnode->next;
266
267 prevnode->next = res->next;
268 }
269 res->next = NULL;
270 kfree(res);
271 break;
272 }
273
274 return 0;
275}
276
277static int bind_pci_resources_to_slots ( struct controller *ctrl)
278{
279 struct pci_func *func, new_func;
280 int busn = ctrl->slot_bus;
281 int devn, funn;
282 u32 vid;
283
284 for (devn = 0; devn < 32; devn++) {
285 for (funn = 0; funn < 8; funn++) {
286 /*
287 if (devn == ctrl->device && funn == ctrl->function)
288 continue;
289 */
290 /* find out if this entry is for an occupied slot */
291 vid = 0xFFFFFFFF;
292
293 pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
294
295 if (vid != 0xFFFFFFFF) {
296 dbg("%s: vid = %x bus %x dev %x fun %x\n", __FUNCTION__,
297 vid, busn, devn, funn);
298 func = pciehp_slot_find(busn, devn, funn);
299 dbg("%s: func = %p\n", __FUNCTION__,func);
300 if (!func) {
301 memset(&new_func, 0, sizeof(struct pci_func));
302 new_func.bus = busn;
303 new_func.device = devn;
304 new_func.function = funn;
305 new_func.is_a_board = 1;
306 configure_existing_function(ctrl, &new_func);
307 phprm_dump_func_res(&new_func);
308 } else {
309 configure_existing_function(ctrl, func);
310 phprm_dump_func_res(func);
311 }
312 dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
313 }
314 }
315 }
316
317 return 0;
318}
319
320static void phprm_dump_ctrl_res( struct controller *ctlr)
321{
322 struct controller *ctrl = ctlr;
323
324 if (ctrl->bus_head) {
325 dbg(": BUS Resources:\n");
326 print_pci_resource (ctrl->bus_head);
327 }
328 if (ctrl->io_head) {
329 dbg(": IO Resources:\n");
330 print_pci_resource (ctrl->io_head);
331 }
332 if (ctrl->mem_head) {
333 dbg(": MEM Resources:\n");
334 print_pci_resource (ctrl->mem_head);
335 }
336 if (ctrl->p_mem_head) {
337 dbg(": PMEM Resources:\n");
338 print_pci_resource (ctrl->p_mem_head);
339 }
340}
341
342/*
343 * phprm_find_available_resources
344 *
345 * Finds available memory, IO, and IRQ resources for programming
346 * devices which may be added to the system
347 * this function is for hot plug ADD!
348 *
349 * returns 0 if success
350 */
351int pciehprm_find_available_resources(struct controller *ctrl)
352{
353 struct pci_func func;
354 u32 rc;
355
356 memset(&func, 0, sizeof(struct pci_func));
357
358 func.bus = ctrl->bus;
359 func.device = ctrl->device;
360 func.function = ctrl->function;
361 func.is_a_board = 1;
362
363 /* Get resources for this PCI bridge */
364 rc = pciehp_save_used_resources (ctrl, &func, !DISABLE_CARD);
365 dbg("%s: pciehp_save_used_resources rc = %d\n", __FUNCTION__, rc);
366
367 if (func.mem_head)
368 func.mem_head->next = ctrl->mem_head;
369 ctrl->mem_head = func.mem_head;
370
371 if (func.p_mem_head)
372 func.p_mem_head->next = ctrl->p_mem_head;
373 ctrl->p_mem_head = func.p_mem_head;
374
375 if (func.io_head)
376 func.io_head->next = ctrl->io_head;
377 ctrl->io_head = func.io_head;
378
379 if(func.bus_head)
380 func.bus_head->next = ctrl->bus_head;
381 ctrl->bus_head = func.bus_head;
382
383 if (ctrl->bus_head)
384 pciehprm_delete_resource(&ctrl->bus_head, ctrl->pci_dev->subordinate->number, 1);
385
386 dbg("%s:pre-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
387 phprm_dump_ctrl_res(ctrl);
388
389 dbg("%s: before bind_pci_resources_to slots\n", __FUNCTION__);
390
391 bind_pci_resources_to_slots (ctrl);
392
393 dbg("%s:post-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
394 phprm_dump_ctrl_res(ctrl);
395
396 return (rc);
397}
398
399int pciehprm_set_hpp(
400 struct controller *ctrl,
401 struct pci_func *func,
402 u8 card_type)
403{
404 u32 rc;
405 u8 temp_byte;
406 struct pci_bus lpci_bus, *pci_bus;
407 unsigned int devfn;
408 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
409 pci_bus = &lpci_bus;
410 pci_bus->number = func->bus;
411 devfn = PCI_DEVFN(func->device, func->function);
412
413 temp_byte = 0x40; /* hard coded value for LT */
414 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
415 /* set subordinate Latency Timer */
416 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
417
418 if (rc) {
419 dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__,
420 func->bus, func->device, func->function);
421 return rc;
422 }
423 }
424
425 /* set base Latency Timer */
426 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
427
428 if (rc) {
429 dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
430 return rc;
431 }
432
433 /* set Cache Line size */
434 temp_byte = 0x08; /* hard coded value for CLS */
435
436 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
437
438 if (rc) {
439 dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
440 }
441
442 /* set enable_perr */
443 /* set enable_serr */
444
445 return rc;
446}
447
448void pciehprm_enable_card(
449 struct controller *ctrl,
450 struct pci_func *func,
451 u8 card_type)
452{
453 u16 command, bcommand;
454 struct pci_bus lpci_bus, *pci_bus;
455 unsigned int devfn;
456 int rc;
457
458 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
459 pci_bus = &lpci_bus;
460 pci_bus->number = func->bus;
461 devfn = PCI_DEVFN(func->device, func->function);
462
463 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
464
465 command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR
466 | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
467 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
468
469 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
470
471 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
472
473 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
474
475 bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR
476 | PCI_BRIDGE_CTL_NO_ISA;
477
478 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
479 }
480}
481
482static int legacy_pciehprm_init_pci(void)
483{
484 return 0;
485}
486
487int pciehprm_init(enum php_ctlr_type ctrl_type)
488{
489 int retval;
490
491 switch (ctrl_type) {
492 case PCI:
493 retval = legacy_pciehprm_init_pci();
494 break;
495 default:
496 retval = -ENODEV;
497 break;
498 }
499
500 return retval;
501}
diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.h b/drivers/pci/hotplug/pciehprm_nonacpi.h
new file mode 100644
index 000000000000..87c90e85ede9
--- /dev/null
+++ b/drivers/pci/hotplug/pciehprm_nonacpi.h
@@ -0,0 +1,56 @@
1/*
2 * PCIEHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
27 *
28 */
29
30#ifndef _PCIEHPRM_NONACPI_H_
31#define _PCIEHPRM_NONACPI_H_
32
33struct irq_info {
34 u8 bus, devfn; /* bus, device and function */
35 struct {
36 u8 link; /* IRQ line ID, chipset dependent, 0=not routed */
37 u16 bitmap; /* Available IRQs */
38 } __attribute__ ((packed)) irq[4];
39 u8 slot; /* slot number, 0=onboard */
40 u8 rfu;
41} __attribute__ ((packed));
42
43struct irq_routing_table {
44 u32 signature; /* PIRQ_SIGNATURE should be here */
45 u16 version; /* PIRQ_VERSION */
46 u16 size; /* Table size in bytes */
47 u8 rtr_bus, rtr_devfn; /* Where the interrupt router lies */
48 u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */
49 u16 rtr_vendor, rtr_device; /* Vendor and device ID of interrupt router */
50 u32 miniport_data; /* Crap */
51 u8 rfu[11];
52 u8 checksum; /* Modulo 256 checksum must give zero */
53 struct irq_info slots[0];
54} __attribute__ ((packed));
55
56#endif /* _PCIEHPRM_NONACPI_H_ */
diff --git a/drivers/pci/hotplug/pcihp_skeleton.c b/drivers/pci/hotplug/pcihp_skeleton.c
new file mode 100644
index 000000000000..6605d6bda529
--- /dev/null
+++ b/drivers/pci/hotplug/pcihp_skeleton.c
@@ -0,0 +1,375 @@
1/*
2 * PCI Hot Plug Controller Skeleton Driver - 0.2
3 *
4 * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
5 * Copyright (C) 2001,2003 IBM Corp.
6 *
7 * All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
17 * NON INFRINGEMENT. See the GNU General Public License for more
18 * details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * This driver is to be used as a skeleton driver to be show how to interface
25 * with the pci hotplug core easily.
26 *
27 * Send feedback to <greg@kroah.com>
28 *
29 */
30
31#include <linux/config.h>
32#include <linux/module.h>
33#include <linux/moduleparam.h>
34#include <linux/kernel.h>
35#include <linux/slab.h>
36#include <linux/pci.h>
37#include <linux/init.h>
38#include "pci_hotplug.h"
39
40struct slot {
41 u8 number;
42 struct hotplug_slot *hotplug_slot;
43 struct list_head slot_list;
44};
45
46static LIST_HEAD(slot_list);
47
48#define MY_NAME "pcihp_skeleton"
49
50#define dbg(format, arg...) \
51 do { \
52 if (debug) \
53 printk (KERN_DEBUG "%s: " format "\n", \
54 MY_NAME , ## arg); \
55 } while (0)
56#define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
57#define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
58#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
59
60
61
62/* local variables */
63static int debug;
64static int num_slots;
65
66#define DRIVER_VERSION "0.3"
67#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
68#define DRIVER_DESC "Hot Plug PCI Controller Skeleton Driver"
69
70MODULE_AUTHOR(DRIVER_AUTHOR);
71MODULE_DESCRIPTION(DRIVER_DESC);
72MODULE_LICENSE("GPL");
73module_param(debug, bool, 0644);
74MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
75
76static int enable_slot (struct hotplug_slot *slot);
77static int disable_slot (struct hotplug_slot *slot);
78static int set_attention_status (struct hotplug_slot *slot, u8 value);
79static int hardware_test (struct hotplug_slot *slot, u32 value);
80static int get_power_status (struct hotplug_slot *slot, u8 *value);
81static int get_attention_status (struct hotplug_slot *slot, u8 *value);
82static int get_latch_status (struct hotplug_slot *slot, u8 *value);
83static int get_adapter_status (struct hotplug_slot *slot, u8 *value);
84
85static struct hotplug_slot_ops skel_hotplug_slot_ops = {
86 .owner = THIS_MODULE,
87 .enable_slot = enable_slot,
88 .disable_slot = disable_slot,
89 .set_attention_status = set_attention_status,
90 .hardware_test = hardware_test,
91 .get_power_status = get_power_status,
92 .get_attention_status = get_attention_status,
93 .get_latch_status = get_latch_status,
94 .get_adapter_status = get_adapter_status,
95};
96
97static int enable_slot(struct hotplug_slot *hotplug_slot)
98{
99 struct slot *slot = hotplug_slot->private;
100 int retval = 0;
101
102 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
103
104 /*
105 * Fill in code here to enable the specified slot
106 */
107
108 return retval;
109}
110
111
112static int disable_slot(struct hotplug_slot *hotplug_slot)
113{
114 struct slot *slot = hotplug_slot->private;
115 int retval = 0;
116
117 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
118
119 /*
120 * Fill in code here to disable the specified slot
121 */
122
123 return retval;
124}
125
126static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
127{
128 struct slot *slot = hotplug_slot->private;
129 int retval = 0;
130
131 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
132
133 switch (status) {
134 case 0:
135 /*
136 * Fill in code here to turn light off
137 */
138 break;
139
140 case 1:
141 default:
142 /*
143 * Fill in code here to turn light on
144 */
145 break;
146 }
147
148 return retval;
149}
150
151static int hardware_test(struct hotplug_slot *hotplug_slot, u32 value)
152{
153 struct slot *slot = hotplug_slot->private;
154 int retval = 0;
155
156 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
157
158 switch (value) {
159 case 0:
160 /* Specify a test here */
161 break;
162 case 1:
163 /* Specify another test here */
164 break;
165 }
166
167 return retval;
168}
169
170static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
171{
172 struct slot *slot = hotplug_slot->private;
173 int retval = 0;
174
175 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
176
177 /*
178 * Fill in logic to get the current power status of the specific
179 * slot and store it in the *value location.
180 */
181
182 return retval;
183}
184
185static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
186{
187 struct slot *slot = hotplug_slot->private;
188 int retval = 0;
189
190 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
191
192 /*
193 * Fill in logic to get the current attention status of the specific
194 * slot and store it in the *value location.
195 */
196
197 return retval;
198}
199
200static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
201{
202 struct slot *slot = hotplug_slot->private;
203 int retval = 0;
204
205 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
206
207 /*
208 * Fill in logic to get the current latch status of the specific
209 * slot and store it in the *value location.
210 */
211
212 return retval;
213}
214
215static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
216{
217 struct slot *slot = hotplug_slot->private;
218 int retval = 0;
219
220 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
221
222 /*
223 * Fill in logic to get the current adapter status of the specific
224 * slot and store it in the *value location.
225 */
226
227 return retval;
228}
229
230static void release_slot(struct hotplug_slot *hotplug_slot)
231{
232 struct slot *slot = hotplug_slot->private;
233
234 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
235 kfree(slot->hotplug_slot->info);
236 kfree(slot->hotplug_slot->name);
237 kfree(slot->hotplug_slot);
238 kfree(slot);
239}
240
241#define SLOT_NAME_SIZE 10
242static void make_slot_name(struct slot *slot)
243{
244 /*
245 * Stupid way to make a filename out of the slot name.
246 * replace this if your hardware provides a better way to name slots.
247 */
248 snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%d", slot->number);
249}
250
251/**
252 * init_slots - initialize 'struct slot' structures for each slot
253 *
254 */
255static int __init init_slots(void)
256{
257 struct slot *slot;
258 struct hotplug_slot *hotplug_slot;
259 struct hotplug_slot_info *info;
260 char *name;
261 int retval = -ENOMEM;
262 int i;
263
264 /*
265 * Create a structure for each slot, and register that slot
266 * with the pci_hotplug subsystem.
267 */
268 for (i = 0; i < num_slots; ++i) {
269 slot = kmalloc(sizeof(struct slot), GFP_KERNEL);
270 if (!slot)
271 goto error;
272 memset(slot, 0, sizeof(struct slot));
273
274 hotplug_slot = kmalloc(sizeof(struct hotplug_slot),
275 GFP_KERNEL);
276 if (!hotplug_slot)
277 goto error_slot;
278 memset(hotplug_slot, 0, sizeof (struct hotplug_slot));
279 slot->hotplug_slot = hotplug_slot;
280
281 info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
282 if (!info)
283 goto error_hpslot;
284 memset(info, 0, sizeof (struct hotplug_slot_info));
285 hotplug_slot->info = info;
286
287 name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
288 if (!name)
289 goto error_info;
290 hotplug_slot->name = name;
291
292 slot->number = i;
293
294 hotplug_slot->private = slot;
295 hotplug_slot->release = &release_slot;
296 make_slot_name(slot);
297 hotplug_slot->ops = &skel_hotplug_slot_ops;
298
299 /*
300 * Initilize the slot info structure with some known
301 * good values.
302 */
303 info->power_status = get_power_status(slot);
304 info->attention_status = get_attention_status(slot);
305 info->latch_status = get_latch_status(slot);
306 info->adapter_status = get_adapter_status(slot);
307
308 dbg("registering slot %d\n", i);
309 retval = pci_hp_register(slot->hotplug_slot);
310 if (retval) {
311 err("pci_hp_register failed with error %d\n", retval);
312 goto error_name;
313 }
314
315 /* add slot to our internal list */
316 list_add(&slot->slot_list, &slot_list);
317 }
318
319 return 0;
320error_name:
321 kfree(name);
322error_info:
323 kfree(info);
324error_hpslot:
325 kfree(hotplug_slot);
326error_slot:
327 kfree(slot);
328error:
329 return retval;
330}
331
332static void __exit cleanup_slots(void)
333{
334 struct list_head *tmp;
335 struct list_head *next;
336 struct slot *slot;
337
338 /*
339 * Unregister all of our slots with the pci_hotplug subsystem.
340 * Memory will be freed in release_slot() callback after slot's
341 * lifespan is finished.
342 */
343 list_for_each_safe(tmp, next, &slot_list) {
344 slot = list_entry(tmp, struct slot, slot_list);
345 list_del(&slot->slot_list);
346 pci_hp_deregister(slot->hotplug_slot);
347 }
348}
349
350static int __init pcihp_skel_init(void)
351{
352 int retval;
353
354 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
355 /*
356 * Do specific initialization stuff for your driver here
357 * Like initializing your controller hardware (if any) and
358 * determining the number of slots you have in the system
359 * right now.
360 */
361 num_slots = 5;
362
363 return init_slots();
364}
365
366static void __exit pcihp_skel_exit(void)
367{
368 /*
369 * Clean everything up.
370 */
371 cleanup_slots();
372}
373
374module_init(pcihp_skel_init);
375module_exit(pcihp_skel_exit);
diff --git a/drivers/pci/hotplug/rpadlpar.h b/drivers/pci/hotplug/rpadlpar.h
new file mode 100644
index 000000000000..4a0a59b82eae
--- /dev/null
+++ b/drivers/pci/hotplug/rpadlpar.h
@@ -0,0 +1,24 @@
1/*
2 * Interface for Dynamic Logical Partitioning of I/O Slots on
3 * RPA-compliant PPC64 platform.
4 *
5 * John Rose <johnrose@austin.ibm.com>
6 * October 2003
7 *
8 * Copyright (C) 2003 IBM.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15#ifndef _RPADLPAR_IO_H_
16#define _RPADLPAR_IO_H_
17
18extern int dlpar_sysfs_init(void);
19extern void dlpar_sysfs_exit(void);
20
21extern int dlpar_add_slot(char *drc_name);
22extern int dlpar_remove_slot(char *drc_name);
23
24#endif
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
new file mode 100644
index 000000000000..86b384e42717
--- /dev/null
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -0,0 +1,503 @@
1/*
2 * Interface for Dynamic Logical Partitioning of I/O Slots on
3 * RPA-compliant PPC64 platform.
4 *
5 * John Rose <johnrose@austin.ibm.com>
6 * Linda Xie <lxie@us.ibm.com>
7 *
8 * October 2003
9 *
10 * Copyright (C) 2003 IBM.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version
15 * 2 of the License, or (at your option) any later version.
16 */
17#include <linux/init.h>
18#include <linux/pci.h>
19#include <asm/pci-bridge.h>
20#include <asm/semaphore.h>
21#include <asm/rtas.h>
22#include "../pci.h"
23#include "rpaphp.h"
24#include "rpadlpar.h"
25
26static DECLARE_MUTEX(rpadlpar_sem);
27
28#define NODE_TYPE_VIO 1
29#define NODE_TYPE_SLOT 2
30#define NODE_TYPE_PHB 3
31
32static struct device_node *find_php_slot_vio_node(char *drc_name)
33{
34 struct device_node *child;
35 struct device_node *parent = of_find_node_by_name(NULL, "vdevice");
36 char *loc_code;
37
38 if (!parent)
39 return NULL;
40
41 for (child = of_get_next_child(parent, NULL);
42 child; child = of_get_next_child(parent, child)) {
43 loc_code = get_property(child, "ibm,loc-code", NULL);
44 if (loc_code && !strncmp(loc_code, drc_name, strlen(drc_name)))
45 return child;
46 }
47
48 return NULL;
49}
50
51/* Find dlpar-capable pci node that contains the specified name and type */
52static struct device_node *find_php_slot_pci_node(char *drc_name,
53 char *drc_type)
54{
55 struct device_node *np = NULL;
56 char *name;
57 char *type;
58 int rc;
59
60 while ((np = of_find_node_by_type(np, "pci"))) {
61 rc = rpaphp_get_drc_props(np, NULL, &name, &type, NULL);
62 if (rc == 0)
63 if (!strcmp(drc_name, name) && !strcmp(drc_type, type))
64 break;
65 }
66
67 return np;
68}
69
70static struct device_node *find_newly_added_node(char *drc_name, int *node_type)
71{
72 struct device_node *dn;
73
74 dn = find_php_slot_pci_node(drc_name, "SLOT");
75 if (dn) {
76 *node_type = NODE_TYPE_SLOT;
77 return dn;
78 }
79
80 dn = find_php_slot_pci_node(drc_name, "PHB");
81 if (dn) {
82 *node_type = NODE_TYPE_PHB;
83 return dn;
84 }
85
86 dn = find_php_slot_vio_node(drc_name);
87 if (dn) {
88 *node_type = NODE_TYPE_VIO;
89 return dn;
90 }
91
92 return NULL;
93}
94
95static struct slot *find_slot(char *drc_name)
96{
97 struct list_head *tmp, *n;
98 struct slot *slot;
99
100 list_for_each_safe(tmp, n, &rpaphp_slot_head) {
101 slot = list_entry(tmp, struct slot, rpaphp_slot_list);
102 if (strcmp(slot->location, drc_name) == 0)
103 return slot;
104 }
105
106 return NULL;
107}
108
109static void rpadlpar_claim_one_bus(struct pci_bus *b)
110{
111 struct list_head *ld;
112 struct pci_bus *child_bus;
113
114 for (ld = b->devices.next; ld != &b->devices; ld = ld->next) {
115 struct pci_dev *dev = pci_dev_b(ld);
116 int i;
117
118 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
119 struct resource *r = &dev->resource[i];
120
121 if (r->parent || !r->start || !r->flags)
122 continue;
123 rpaphp_claim_resource(dev, i);
124 }
125 }
126
127 list_for_each_entry(child_bus, &b->children, node)
128 rpadlpar_claim_one_bus(child_bus);
129}
130
131static int pci_add_secondary_bus(struct device_node *dn,
132 struct pci_dev *bridge_dev)
133{
134 struct pci_controller *hose = dn->phb;
135 struct pci_bus *child;
136 u8 sec_busno;
137
138 /* Get busno of downstream bus */
139 pci_read_config_byte(bridge_dev, PCI_SECONDARY_BUS, &sec_busno);
140
141 /* Allocate and add to children of bridge_dev->bus */
142 child = pci_add_new_bus(bridge_dev->bus, bridge_dev, sec_busno);
143 if (!child) {
144 printk(KERN_ERR "%s: could not add secondary bus\n", __FUNCTION__);
145 return -ENOMEM;
146 }
147
148 sprintf(child->name, "PCI Bus #%02x", child->number);
149
150 /* Fixup subordinate bridge bases and resources */
151 pcibios_fixup_bus(child);
152
153 /* Claim new bus resources */
154 rpadlpar_claim_one_bus(bridge_dev->bus);
155
156 if (hose->last_busno < child->number)
157 hose->last_busno = child->number;
158
159 dn->bussubno = child->number;
160
161 /* ioremap() for child bus, which may or may not succeed */
162 remap_bus_range(child);
163
164 return 0;
165}
166
167static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
168{
169 struct pci_controller *hose = dn->phb;
170 struct pci_dev *dev = NULL;
171
172 /* Scan phb bus for EADS device, adding new one to bus->devices */
173 if (!pci_scan_single_device(hose->bus, dn->devfn)) {
174 printk(KERN_ERR "%s: found no device on bus\n", __FUNCTION__);
175 return NULL;
176 }
177
178 /* Add new devices to global lists. Register in proc, sysfs. */
179 pci_bus_add_devices(hose->bus);
180
181 /* Confirm new bridge dev was created */
182 dev = rpaphp_find_pci_dev(dn);
183 if (!dev) {
184 printk(KERN_ERR "%s: failed to add pci device\n", __FUNCTION__);
185 return NULL;
186 }
187
188 if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
189 printk(KERN_ERR "%s: unexpected header type %d\n",
190 __FUNCTION__, dev->hdr_type);
191 return NULL;
192 }
193
194 if (pci_add_secondary_bus(dn, dev))
195 return NULL;
196
197 return dev;
198}
199
200static int dlpar_pci_remove_bus(struct pci_dev *bridge_dev)
201{
202 struct pci_bus *secondary_bus;
203
204 if (!bridge_dev) {
205 printk(KERN_ERR "%s: unexpected null device\n",
206 __FUNCTION__);
207 return -EINVAL;
208 }
209
210 secondary_bus = bridge_dev->subordinate;
211
212 if (unmap_bus_range(secondary_bus)) {
213 printk(KERN_ERR "%s: failed to unmap bus range\n",
214 __FUNCTION__);
215 return -ERANGE;
216 }
217
218 pci_remove_bus_device(bridge_dev);
219 return 0;
220}
221
222static inline int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
223{
224 struct pci_dev *dev;
225
226 /* Add pci bus */
227 dev = dlpar_pci_add_bus(dn);
228 if (!dev) {
229 printk(KERN_ERR "%s: unable to add bus %s\n", __FUNCTION__,
230 drc_name);
231 return -EIO;
232 }
233
234 return 0;
235}
236
237static int dlpar_remove_root_bus(struct pci_controller *phb)
238{
239 struct pci_bus *phb_bus;
240 int rc;
241
242 phb_bus = phb->bus;
243 if (!(list_empty(&phb_bus->children) &&
244 list_empty(&phb_bus->devices))) {
245 return -EBUSY;
246 }
247
248 rc = pcibios_remove_root_bus(phb);
249 if (rc)
250 return -EIO;
251
252 device_unregister(phb_bus->bridge);
253 pci_remove_bus(phb_bus);
254
255 return 0;
256}
257
258static int dlpar_remove_phb(struct slot *slot)
259{
260 struct pci_controller *phb;
261 struct device_node *dn;
262 int rc = 0;
263
264 dn = slot->dn;
265 if (!dn) {
266 printk(KERN_ERR "%s: unexpected NULL slot device node\n",
267 __FUNCTION__);
268 return -EIO;
269 }
270
271 phb = dn->phb;
272 if (!phb) {
273 printk(KERN_ERR "%s: unexpected NULL phb pointer\n",
274 __FUNCTION__);
275 return -EIO;
276 }
277
278 if (rpaphp_remove_slot(slot)) {
279 printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
280 __FUNCTION__, slot->location);
281 return -EIO;
282 }
283
284 rc = dlpar_remove_root_bus(phb);
285 if (rc < 0)
286 return rc;
287
288 return 0;
289}
290
291static int dlpar_add_phb(struct device_node *dn)
292{
293 struct pci_controller *phb;
294
295 phb = init_phb_dynamic(dn);
296 if (!phb)
297 return -EINVAL;
298
299 return 0;
300}
301
302/**
303 * dlpar_add_slot - DLPAR add an I/O Slot
304 * @drc_name: drc-name of newly added slot
305 *
306 * Make the hotplug module and the kernel aware
307 * of a newly added I/O Slot.
308 * Return Codes -
309 * 0 Success
310 * -ENODEV Not a valid drc_name
311 * -EINVAL Slot already added
312 * -ERESTARTSYS Signalled before obtaining lock
313 * -EIO Internal PCI Error
314 */
315int dlpar_add_slot(char *drc_name)
316{
317 struct device_node *dn = NULL;
318 int node_type;
319 int rc = 0;
320
321 if (down_interruptible(&rpadlpar_sem))
322 return -ERESTARTSYS;
323
324 /* Check for existing hotplug slot */
325 if (find_slot(drc_name)) {
326 rc = -EINVAL;
327 goto exit;
328 }
329
330 dn = find_newly_added_node(drc_name, &node_type);
331 if (!dn) {
332 rc = -ENODEV;
333 goto exit;
334 }
335
336 switch (node_type) {
337 case NODE_TYPE_VIO:
338 /* Just add hotplug slot */
339 break;
340 case NODE_TYPE_SLOT:
341 rc = dlpar_add_pci_slot(drc_name, dn);
342 break;
343 case NODE_TYPE_PHB:
344 rc = dlpar_add_phb(dn);
345 break;
346 default:
347 printk("%s: unexpected node type\n", __FUNCTION__);
348 return -EIO;
349 }
350
351 if (!rc && rpaphp_add_slot(dn)) {
352 printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
353 __FUNCTION__, drc_name);
354 rc = -EIO;
355 }
356exit:
357 up(&rpadlpar_sem);
358 return rc;
359}
360
361/**
362 * dlpar_remove_vio_slot - DLPAR remove a virtual I/O Slot
363 * @drc_name: drc-name of newly added slot
364 *
365 * Remove the kernel and hotplug representations
366 * of an I/O Slot.
367 * Return Codes:
368 * 0 Success
369 * -EIO Internal Error
370 */
371int dlpar_remove_vio_slot(struct slot *slot, char *drc_name)
372{
373 /* Remove hotplug slot */
374
375 if (rpaphp_remove_slot(slot)) {
376 printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
377 __FUNCTION__, drc_name);
378 return -EIO;
379 }
380 return 0;
381}
382
383/**
384 * dlpar_remove_slot - DLPAR remove a PCI I/O Slot
385 * @drc_name: drc-name of newly added slot
386 *
387 * Remove the kernel and hotplug representations
388 * of a PCI I/O Slot.
389 * Return Codes:
390 * 0 Success
391 * -ENODEV Not a valid drc_name
392 * -EIO Internal PCI Error
393 */
394int dlpar_remove_pci_slot(struct slot *slot, char *drc_name)
395{
396 struct pci_dev *bridge_dev;
397
398 bridge_dev = slot->bridge;
399 if (!bridge_dev) {
400 printk(KERN_ERR "%s: unexpected null bridge device\n",
401 __FUNCTION__);
402 return -EIO;
403 }
404
405 /* Remove hotplug slot */
406 if (rpaphp_remove_slot(slot)) {
407 printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
408 __FUNCTION__, drc_name);
409 return -EIO;
410 }
411
412 /* Remove pci bus */
413
414 if (dlpar_pci_remove_bus(bridge_dev)) {
415 printk(KERN_ERR "%s: unable to remove pci bus %s\n",
416 __FUNCTION__, drc_name);
417 return -EIO;
418 }
419 return 0;
420}
421
422/**
423 * dlpar_remove_slot - DLPAR remove an I/O Slot
424 * @drc_name: drc-name of newly added slot
425 *
426 * Remove the kernel and hotplug representations
427 * of an I/O Slot.
428 * Return Codes:
429 * 0 Success
430 * -ENODEV Not a valid drc_name
431 * -EINVAL Slot already removed
432 * -ERESTARTSYS Signalled before obtaining lock
433 * -EIO Internal Error
434 */
435int dlpar_remove_slot(char *drc_name)
436{
437 struct slot *slot;
438 int rc = 0;
439
440 if (down_interruptible(&rpadlpar_sem))
441 return -ERESTARTSYS;
442
443 if (!find_php_slot_vio_node(drc_name) &&
444 !find_php_slot_pci_node(drc_name, "SLOT") &&
445 !find_php_slot_pci_node(drc_name, "PHB")) {
446 rc = -ENODEV;
447 goto exit;
448 }
449
450 slot = find_slot(drc_name);
451 if (!slot) {
452 rc = -EINVAL;
453 goto exit;
454 }
455
456 if (slot->type == PHB) {
457 rc = dlpar_remove_phb(slot);
458 } else {
459 switch (slot->dev_type) {
460 case PCI_DEV:
461 rc = dlpar_remove_pci_slot(slot, drc_name);
462 break;
463
464 case VIO_DEV:
465 rc = dlpar_remove_vio_slot(slot, drc_name);
466 break;
467 }
468 }
469exit:
470 up(&rpadlpar_sem);
471 return rc;
472}
473
474static inline int is_dlpar_capable(void)
475{
476 int rc = rtas_token("ibm,configure-connector");
477
478 return (int) (rc != RTAS_UNKNOWN_SERVICE);
479}
480
481int __init rpadlpar_io_init(void)
482{
483 int rc = 0;
484
485 if (!is_dlpar_capable()) {
486 printk(KERN_WARNING "%s: partition not DLPAR capable\n",
487 __FUNCTION__);
488 return -EPERM;
489 }
490
491 rc = dlpar_sysfs_init();
492 return rc;
493}
494
495void rpadlpar_io_exit(void)
496{
497 dlpar_sysfs_exit();
498 return;
499}
500
501module_init(rpadlpar_io_init);
502module_exit(rpadlpar_io_exit);
503MODULE_LICENSE("GPL");
diff --git a/drivers/pci/hotplug/rpadlpar_sysfs.c b/drivers/pci/hotplug/rpadlpar_sysfs.c
new file mode 100644
index 000000000000..3285b822478d
--- /dev/null
+++ b/drivers/pci/hotplug/rpadlpar_sysfs.c
@@ -0,0 +1,151 @@
1/*
2 * Interface for Dynamic Logical Partitioning of I/O Slots on
3 * RPA-compliant PPC64 platform.
4 *
5 * John Rose <johnrose@austin.ibm.com>
6 * October 2003
7 *
8 * Copyright (C) 2003 IBM.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15#include <linux/kobject.h>
16#include <linux/string.h>
17#include "pci_hotplug.h"
18#include "rpadlpar.h"
19
20#define DLPAR_KOBJ_NAME "control"
21#define ADD_SLOT_ATTR_NAME "add_slot"
22#define REMOVE_SLOT_ATTR_NAME "remove_slot"
23
24#define MAX_DRC_NAME_LEN 64
25
26/* Store return code of dlpar operation in attribute struct */
27struct dlpar_io_attr {
28 int rc;
29 struct attribute attr;
30 ssize_t (*store)(struct dlpar_io_attr *dlpar_attr, const char *buf,
31 size_t nbytes);
32};
33
34/* Common show callback for all attrs, display the return code
35 * of the dlpar op */
36static ssize_t
37dlpar_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
38{
39 struct dlpar_io_attr *dlpar_attr = container_of(attr,
40 struct dlpar_io_attr, attr);
41 return sprintf(buf, "%d\n", dlpar_attr->rc);
42}
43
44static ssize_t
45dlpar_attr_store(struct kobject * kobj, struct attribute * attr,
46 const char *buf, size_t nbytes)
47{
48 struct dlpar_io_attr *dlpar_attr = container_of(attr,
49 struct dlpar_io_attr, attr);
50 return dlpar_attr->store ?
51 dlpar_attr->store(dlpar_attr, buf, nbytes) : 0;
52}
53
54static struct sysfs_ops dlpar_attr_sysfs_ops = {
55 .show = dlpar_attr_show,
56 .store = dlpar_attr_store,
57};
58
59static ssize_t add_slot_store(struct dlpar_io_attr *dlpar_attr,
60 const char *buf, size_t nbytes)
61{
62 char drc_name[MAX_DRC_NAME_LEN];
63 char *end;
64
65 if (nbytes > MAX_DRC_NAME_LEN)
66 return 0;
67
68 memcpy(drc_name, buf, nbytes);
69
70 end = strchr(drc_name, '\n');
71 if (!end)
72 end = &drc_name[nbytes];
73 *end = '\0';
74
75 dlpar_attr->rc = dlpar_add_slot(drc_name);
76
77 return nbytes;
78}
79
80static ssize_t remove_slot_store(struct dlpar_io_attr *dlpar_attr,
81 const char *buf, size_t nbytes)
82{
83 char drc_name[MAX_DRC_NAME_LEN];
84 char *end;
85
86 if (nbytes > MAX_DRC_NAME_LEN)
87 return 0;
88
89 memcpy(drc_name, buf, nbytes);
90
91 end = strchr(drc_name, '\n');
92 if (!end)
93 end = &drc_name[nbytes];
94 *end = '\0';
95
96 dlpar_attr->rc = dlpar_remove_slot(drc_name);
97
98 return nbytes;
99}
100
101static struct dlpar_io_attr add_slot_attr = {
102 .rc = 0,
103 .attr = { .name = ADD_SLOT_ATTR_NAME, .mode = 0644, },
104 .store = add_slot_store,
105};
106
107static struct dlpar_io_attr remove_slot_attr = {
108 .rc = 0,
109 .attr = { .name = REMOVE_SLOT_ATTR_NAME, .mode = 0644},
110 .store = remove_slot_store,
111};
112
113static struct attribute *default_attrs[] = {
114 &add_slot_attr.attr,
115 &remove_slot_attr.attr,
116 NULL,
117};
118
119static void dlpar_io_release(struct kobject *kobj)
120{
121 /* noop */
122 return;
123}
124
125struct kobj_type ktype_dlpar_io = {
126 .release = dlpar_io_release,
127 .sysfs_ops = &dlpar_attr_sysfs_ops,
128 .default_attrs = default_attrs,
129};
130
131struct kset dlpar_io_kset = {
132 .subsys = &pci_hotplug_slots_subsys,
133 .kobj = {.name = DLPAR_KOBJ_NAME, .ktype=&ktype_dlpar_io,},
134 .ktype = &ktype_dlpar_io,
135};
136
137int dlpar_sysfs_init(void)
138{
139 if (kset_register(&dlpar_io_kset)) {
140 printk(KERN_ERR "rpadlpar_io: cannot register kset for %s\n",
141 dlpar_io_kset.kobj.name);
142 return -EINVAL;
143 }
144
145 return 0;
146}
147
148void dlpar_sysfs_exit(void)
149{
150 kset_unregister(&dlpar_io_kset);
151}
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
new file mode 100644
index 000000000000..81746e6e0e0f
--- /dev/null
+++ b/drivers/pci/hotplug/rpaphp.h
@@ -0,0 +1,138 @@
1/*
2 * PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform.
3 *
4 * Copyright (C) 2003 Linda Xie <lxie@us.ibm.com>
5 *
6 * All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
16 * NON INFRINGEMENT. See the GNU General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 * Send feedback to <lxie@us.ibm.com>,
24 *
25 */
26
27#ifndef _PPC64PHP_H
28#define _PPC64PHP_H
29
30#include <linux/pci.h>
31#include "pci_hotplug.h"
32
33#define PHB 2
34#define HOTPLUG 1
35#define EMBEDDED 0
36
37#define DR_INDICATOR 9002
38#define DR_ENTITY_SENSE 9003
39
40#define POWER_ON 100
41#define POWER_OFF 0
42
43#define LED_OFF 0
44#define LED_ON 1 /* continuous on */
45#define LED_ID 2 /* slow blinking */
46#define LED_ACTION 3 /* fast blinking */
47
48/* Sensor values from rtas_get-sensor */
49#define EMPTY 0 /* No card in slot */
50#define PRESENT 1 /* Card in slot */
51
52#define MY_NAME "rpaphp"
53extern int debug;
54#define dbg(format, arg...) \
55 do { \
56 if (debug) \
57 printk(KERN_DEBUG "%s: " format, \
58 MY_NAME , ## arg); \
59 } while (0)
60#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
61#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
62#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
63
64/* slot types */
65#define VIO_DEV 1
66#define PCI_DEV 2
67
68/* slot states */
69
70#define NOT_VALID 3
71#define NOT_CONFIGURED 2
72#define CONFIGURED 1
73#define EMPTY 0
74
75struct rpaphp_pci_func {
76 struct pci_dev *pci_dev;
77 struct list_head sibling;
78};
79
80/*
81 * struct slot - slot information for each *physical* slot
82 */
83struct slot {
84 struct list_head rpaphp_slot_list;
85 int state;
86 u32 index;
87 u32 type;
88 u32 power_domain;
89 char *name;
90 char *location;
91 u8 removable;
92 u8 dev_type; /* VIO or PCI */
93 struct device_node *dn; /* slot's device_node in OFDT */
94 /* dn has phb info */
95 struct pci_dev *bridge; /* slot's pci_dev in pci_devices */
96 union {
97 struct list_head *pci_devs; /* pci_devs in PCI slot */
98 struct vio_dev *vio_dev; /* vio_dev in VIO slot */
99 } dev;
100 struct hotplug_slot *hotplug_slot;
101};
102
103extern struct hotplug_slot_ops rpaphp_hotplug_slot_ops;
104extern struct list_head rpaphp_slot_head;
105extern int num_slots;
106
107/* function prototypes */
108
109/* rpaphp_pci.c */
110extern struct pci_dev *rpaphp_find_pci_dev(struct device_node *dn);
111extern int rpaphp_claim_resource(struct pci_dev *dev, int resource);
112extern int rpaphp_enable_pci_slot(struct slot *slot);
113extern int register_pci_slot(struct slot *slot);
114extern int rpaphp_unconfig_pci_adapter(struct slot *slot);
115extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value);
116extern struct hotplug_slot *rpaphp_find_hotplug_slot(struct pci_dev *dev);
117
118/* rpaphp_core.c */
119extern int rpaphp_add_slot(struct device_node *dn);
120extern int rpaphp_remove_slot(struct slot *slot);
121extern int rpaphp_get_drc_props(struct device_node *dn, int *drc_index,
122 char **drc_name, char **drc_type, int *drc_power_domain);
123
124/* rpaphp_vio.c */
125extern int rpaphp_get_vio_adapter_status(struct slot *slot, int is_init, u8 * value);
126extern int rpaphp_unconfig_vio_adapter(struct slot *slot);
127extern int register_vio_slot(struct device_node *dn);
128extern int rpaphp_enable_vio_slot(struct slot *slot);
129
130/* rpaphp_slot.c */
131extern void dealloc_slot_struct(struct slot *slot);
132extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain);
133extern int register_slot(struct slot *slot);
134extern int deregister_slot(struct slot *slot);
135extern int rpaphp_get_power_status(struct slot *slot, u8 * value);
136extern int rpaphp_set_attention_status(struct slot *slot, u8 status);
137
138#endif /* _PPC64PHP_H */
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
new file mode 100644
index 000000000000..29117a3a3287
--- /dev/null
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -0,0 +1,536 @@
1/*
2 * PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform.
3 * Copyright (C) 2003 Linda Xie <lxie@us.ibm.com>
4 *
5 * All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or (at
10 * your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
15 * NON INFRINGEMENT. See the GNU General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * Send feedback to <lxie@us.ibm.com>
23 *
24 */
25#include <linux/config.h>
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/pci.h>
30#include <linux/slab.h>
31#include <linux/smp.h>
32#include <linux/smp_lock.h>
33#include <linux/init.h>
34#include <asm/eeh.h> /* for eeh_add_device() */
35#include <asm/rtas.h> /* rtas_call */
36#include <asm/pci-bridge.h> /* for pci_controller */
37#include "../pci.h" /* for pci_add_new_bus */
38 /* and pci_do_scan_bus */
39#include "rpaphp.h"
40#include "pci_hotplug.h"
41
42int debug;
43static struct semaphore rpaphp_sem;
44LIST_HEAD(rpaphp_slot_head);
45int num_slots;
46
47#define DRIVER_VERSION "0.1"
48#define DRIVER_AUTHOR "Linda Xie <lxie@us.ibm.com>"
49#define DRIVER_DESC "RPA HOT Plug PCI Controller Driver"
50
51#define MAX_LOC_CODE 128
52
53MODULE_AUTHOR(DRIVER_AUTHOR);
54MODULE_DESCRIPTION(DRIVER_DESC);
55MODULE_LICENSE("GPL");
56
57module_param(debug, bool, 0644);
58
59static int enable_slot(struct hotplug_slot *slot);
60static int disable_slot(struct hotplug_slot *slot);
61static int set_attention_status(struct hotplug_slot *slot, u8 value);
62static int get_power_status(struct hotplug_slot *slot, u8 * value);
63static int get_attention_status(struct hotplug_slot *slot, u8 * value);
64static int get_adapter_status(struct hotplug_slot *slot, u8 * value);
65static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value);
66
67struct hotplug_slot_ops rpaphp_hotplug_slot_ops = {
68 .owner = THIS_MODULE,
69 .enable_slot = enable_slot,
70 .disable_slot = disable_slot,
71 .set_attention_status = set_attention_status,
72 .get_power_status = get_power_status,
73 .get_attention_status = get_attention_status,
74 .get_adapter_status = get_adapter_status,
75 .get_max_bus_speed = get_max_bus_speed,
76};
77
78static int rpaphp_get_attention_status(struct slot *slot)
79{
80 return slot->hotplug_slot->info->attention_status;
81}
82
83/**
84 * set_attention_status - set attention LED
85 * echo 0 > attention -- set LED OFF
86 * echo 1 > attention -- set LED ON
87 * echo 2 > attention -- set LED ID(identify, light is blinking)
88 *
89 */
90static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)
91{
92 int retval = 0;
93 struct slot *slot = (struct slot *)hotplug_slot->private;
94
95 down(&rpaphp_sem);
96 switch (value) {
97 case 0:
98 retval = rpaphp_set_attention_status(slot, LED_OFF);
99 hotplug_slot->info->attention_status = 0;
100 break;
101 case 1:
102 default:
103 retval = rpaphp_set_attention_status(slot, LED_ON);
104 hotplug_slot->info->attention_status = 1;
105 break;
106 case 2:
107 retval = rpaphp_set_attention_status(slot, LED_ID);
108 hotplug_slot->info->attention_status = 2;
109 break;
110 }
111 up(&rpaphp_sem);
112 return retval;
113}
114
115/**
116 * get_power_status - get power status of a slot
117 * @hotplug_slot: slot to get status
118 * @value: pointer to store status
119 *
120 *
121 */
122static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)
123{
124 int retval;
125 struct slot *slot = (struct slot *)hotplug_slot->private;
126
127 down(&rpaphp_sem);
128 retval = rpaphp_get_power_status(slot, value);
129 up(&rpaphp_sem);
130 return retval;
131}
132
133/**
134 * get_attention_status - get attention LED status
135 *
136 *
137 */
138static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)
139{
140 int retval = 0;
141 struct slot *slot = (struct slot *)hotplug_slot->private;
142
143 down(&rpaphp_sem);
144 *value = rpaphp_get_attention_status(slot);
145 up(&rpaphp_sem);
146 return retval;
147}
148
149static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value)
150{
151 struct slot *slot = (struct slot *)hotplug_slot->private;
152 int retval = 0;
153
154 down(&rpaphp_sem);
155 /* have to go through this */
156 switch (slot->dev_type) {
157 case PCI_DEV:
158 retval = rpaphp_get_pci_adapter_status(slot, 0, value);
159 break;
160 case VIO_DEV:
161 retval = rpaphp_get_vio_adapter_status(slot, 0, value);
162 break;
163 default:
164 retval = -EINVAL;
165 }
166 up(&rpaphp_sem);
167 return retval;
168}
169
170static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
171{
172 struct slot *slot = (struct slot *)hotplug_slot->private;
173
174 down(&rpaphp_sem);
175 switch (slot->type) {
176 case 1:
177 case 2:
178 case 3:
179 case 4:
180 case 5:
181 case 6:
182 *value = PCI_SPEED_33MHz; /* speed for case 1-6 */
183 break;
184 case 7:
185 case 8:
186 *value = PCI_SPEED_66MHz;
187 break;
188 case 11:
189 case 14:
190 *value = PCI_SPEED_66MHz_PCIX;
191 break;
192 case 12:
193 case 15:
194 *value = PCI_SPEED_100MHz_PCIX;
195 break;
196 case 13:
197 case 16:
198 *value = PCI_SPEED_133MHz_PCIX;
199 break;
200 default:
201 *value = PCI_SPEED_UNKNOWN;
202 break;
203
204 }
205 up(&rpaphp_sem);
206 return 0;
207}
208
209int rpaphp_remove_slot(struct slot *slot)
210{
211 return deregister_slot(slot);
212}
213
214static int get_children_props(struct device_node *dn, int **drc_indexes,
215 int **drc_names, int **drc_types, int **drc_power_domains)
216{
217 int *indexes, *names;
218 int *types, *domains;
219
220 indexes = (int *) get_property(dn, "ibm,drc-indexes", NULL);
221 names = (int *) get_property(dn, "ibm,drc-names", NULL);
222 types = (int *) get_property(dn, "ibm,drc-types", NULL);
223 domains = (int *) get_property(dn, "ibm,drc-power-domains", NULL);
224
225 if (!indexes || !names || !types || !domains) {
226 /* Slot does not have dynamically-removable children */
227 return -EINVAL;
228 }
229 if (drc_indexes)
230 *drc_indexes = indexes;
231 if (drc_names)
232 /* &drc_names[1] contains NULL terminated slot names */
233 *drc_names = names;
234 if (drc_types)
235 /* &drc_types[1] contains NULL terminated slot types */
236 *drc_types = types;
237 if (drc_power_domains)
238 *drc_power_domains = domains;
239
240 return 0;
241}
242
243/* To get the DRC props describing the current node, first obtain it's
244 * my-drc-index property. Next obtain the DRC list from it's parent. Use
245 * the my-drc-index for correlation, and obtain the requested properties.
246 */
247int rpaphp_get_drc_props(struct device_node *dn, int *drc_index,
248 char **drc_name, char **drc_type, int *drc_power_domain)
249{
250 int *indexes, *names;
251 int *types, *domains;
252 unsigned int *my_index;
253 char *name_tmp, *type_tmp;
254 int i, rc;
255
256 my_index = (int *) get_property(dn, "ibm,my-drc-index", NULL);
257 if (!my_index) {
258 /* Node isn't DLPAR/hotplug capable */
259 return -EINVAL;
260 }
261
262 rc = get_children_props(dn->parent, &indexes, &names, &types, &domains);
263 if (rc < 0) {
264 return -EINVAL;
265 }
266
267 name_tmp = (char *) &names[1];
268 type_tmp = (char *) &types[1];
269
270 /* Iterate through parent properties, looking for my-drc-index */
271 for (i = 0; i < indexes[0]; i++) {
272 if ((unsigned int) indexes[i + 1] == *my_index) {
273 if (drc_name)
274 *drc_name = name_tmp;
275 if (drc_type)
276 *drc_type = type_tmp;
277 if (drc_index)
278 *drc_index = *my_index;
279 if (drc_power_domain)
280 *drc_power_domain = domains[i+1];
281 return 0;
282 }
283 name_tmp += (strlen(name_tmp) + 1);
284 type_tmp += (strlen(type_tmp) + 1);
285 }
286
287 return -EINVAL;
288}
289
290static int is_php_type(char *drc_type)
291{
292 unsigned long value;
293 char *endptr;
294
295 /* PCI Hotplug nodes have an integer for drc_type */
296 value = simple_strtoul(drc_type, &endptr, 10);
297 if (endptr == drc_type)
298 return 0;
299
300 return 1;
301}
302
303static int is_php_dn(struct device_node *dn, int **indexes, int **names,
304 int **types, int **power_domains)
305{
306 int *drc_types;
307 int rc;
308
309 rc = get_children_props(dn, indexes, names, &drc_types, power_domains);
310 if (rc >= 0) {
311 if (is_php_type((char *) &drc_types[1])) {
312 *types = drc_types;
313 return 1;
314 }
315 }
316
317 return 0;
318}
319
320static int is_dr_dn(struct device_node *dn, int **indexes, int **names,
321 int **types, int **power_domains, int **my_drc_index)
322{
323 int rc;
324
325 *my_drc_index = (int *) get_property(dn, "ibm,my-drc-index", NULL);
326 if(!*my_drc_index)
327 return (0);
328
329 if (!dn->parent)
330 return (0);
331
332 rc = get_children_props(dn->parent, indexes, names, types,
333 power_domains);
334 return (rc >= 0);
335}
336
337static inline int is_vdevice_root(struct device_node *dn)
338{
339 return !strcmp(dn->name, "vdevice");
340}
341
342int is_dlpar_type(const char *type_str)
343{
344 /* Only register DLPAR-capable nodes of drc-type PHB or SLOT */
345 return (!strcmp(type_str, "PHB") || !strcmp(type_str, "SLOT"));
346}
347
348/****************************************************************
349 * rpaphp not only registers PCI hotplug slots(HOTPLUG),
350 * but also logical DR slots(EMBEDDED).
351 * HOTPLUG slot: An adapter can be physically added/removed.
352 * EMBEDDED slot: An adapter can be logically removed/added
353 * from/to a partition with the slot.
354 ***************************************************************/
355int rpaphp_add_slot(struct device_node *dn)
356{
357 struct slot *slot;
358 int retval = 0;
359 int i, *my_drc_index, slot_type;
360 int *indexes, *names, *types, *power_domains;
361 char *name, *type;
362
363 dbg("Entry %s: dn->full_name=%s\n", __FUNCTION__, dn->full_name);
364
365 if (dn->parent && is_vdevice_root(dn->parent)) {
366 /* register a VIO device */
367 retval = register_vio_slot(dn);
368 goto exit;
369 }
370
371 /* register PCI devices */
372 if (dn->name != 0 && strcmp(dn->name, "pci") == 0) {
373 if (is_php_dn(dn, &indexes, &names, &types, &power_domains))
374 slot_type = HOTPLUG;
375 else if (is_dr_dn(dn, &indexes, &names, &types, &power_domains, &my_drc_index))
376 slot_type = EMBEDDED;
377 else goto exit;
378
379 name = (char *) &names[1];
380 type = (char *) &types[1];
381 for (i = 0; i < indexes[0]; i++,
382 name += (strlen(name) + 1), type += (strlen(type) + 1)) {
383
384 if (slot_type == HOTPLUG ||
385 (slot_type == EMBEDDED &&
386 indexes[i + 1] == my_drc_index[0] &&
387 is_dlpar_type(type))) {
388 if (!(slot = alloc_slot_struct(dn, indexes[i + 1], name,
389 power_domains[i + 1]))) {
390 retval = -ENOMEM;
391 goto exit;
392 }
393 if (!strcmp(type, "PHB"))
394 slot->type = PHB;
395 else if (slot_type == EMBEDDED)
396 slot->type = EMBEDDED;
397 else
398 slot->type = simple_strtoul(type, NULL, 10);
399
400 dbg(" Found drc-index:0x%x drc-name:%s drc-type:%s\n",
401 indexes[i + 1], name, type);
402
403 retval = register_pci_slot(slot);
404 if (slot_type == EMBEDDED)
405 goto exit;
406 }
407 }
408 }
409exit:
410 dbg("%s - Exit: num_slots=%d rc[%d]\n",
411 __FUNCTION__, num_slots, retval);
412 return retval;
413}
414
415/*
416 * init_slots - initialize 'struct slot' structures for each slot
417 *
418 */
419static void init_slots(void)
420{
421 struct device_node *dn;
422
423 for (dn = find_all_nodes(); dn; dn = dn->next)
424 rpaphp_add_slot(dn);
425}
426
427static int __init init_rpa(void)
428{
429
430 init_MUTEX(&rpaphp_sem);
431
432 /* initialize internal data structure etc. */
433 init_slots();
434 if (!num_slots)
435 return -ENODEV;
436
437 return 0;
438}
439
440static void __exit cleanup_slots(void)
441{
442 struct list_head *tmp, *n;
443 struct slot *slot;
444
445 /*
446 * Unregister all of our slots with the pci_hotplug subsystem,
447 * and free up all memory that we had allocated.
448 * memory will be freed in release_slot callback.
449 */
450
451 list_for_each_safe(tmp, n, &rpaphp_slot_head) {
452 slot = list_entry(tmp, struct slot, rpaphp_slot_list);
453 list_del(&slot->rpaphp_slot_list);
454 pci_hp_deregister(slot->hotplug_slot);
455 }
456 return;
457}
458
459static int __init rpaphp_init(void)
460{
461 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
462
463 /* read all the PRA info from the system */
464 return init_rpa();
465}
466
467static void __exit rpaphp_exit(void)
468{
469 cleanup_slots();
470}
471
472static int enable_slot(struct hotplug_slot *hotplug_slot)
473{
474 int retval = 0;
475 struct slot *slot = (struct slot *)hotplug_slot->private;
476
477 if (slot->state == CONFIGURED) {
478 dbg("%s: %s is already enabled\n", __FUNCTION__, slot->name);
479 goto exit;
480 }
481
482 dbg("ENABLING SLOT %s\n", slot->name);
483 down(&rpaphp_sem);
484 switch (slot->dev_type) {
485 case PCI_DEV:
486 retval = rpaphp_enable_pci_slot(slot);
487 break;
488 case VIO_DEV:
489 retval = rpaphp_enable_vio_slot(slot);
490 break;
491 default:
492 retval = -EINVAL;
493 }
494 up(&rpaphp_sem);
495exit:
496 dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
497 return retval;
498}
499
500static int disable_slot(struct hotplug_slot *hotplug_slot)
501{
502 int retval = -EINVAL;
503 struct slot *slot = (struct slot *)hotplug_slot->private;
504
505 dbg("%s - Entry: slot[%s]\n", __FUNCTION__, slot->name);
506
507 if (slot->state == NOT_CONFIGURED) {
508 dbg("%s: %s is already disabled\n", __FUNCTION__, slot->name);
509 goto exit;
510 }
511
512 dbg("DISABLING SLOT %s\n", slot->name);
513 down(&rpaphp_sem);
514 switch (slot->dev_type) {
515 case PCI_DEV:
516 retval = rpaphp_unconfig_pci_adapter(slot);
517 break;
518 case VIO_DEV:
519 retval = rpaphp_unconfig_vio_adapter(slot);
520 break;
521 default:
522 retval = -ENODEV;
523 }
524 up(&rpaphp_sem);
525exit:
526 dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
527 return retval;
528}
529
530module_init(rpaphp_init);
531module_exit(rpaphp_exit);
532
533EXPORT_SYMBOL_GPL(rpaphp_add_slot);
534EXPORT_SYMBOL_GPL(rpaphp_remove_slot);
535EXPORT_SYMBOL_GPL(rpaphp_slot_head);
536EXPORT_SYMBOL_GPL(rpaphp_get_drc_props);
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c
new file mode 100644
index 000000000000..d8305a935aab
--- /dev/null
+++ b/drivers/pci/hotplug/rpaphp_pci.c
@@ -0,0 +1,538 @@
1/*
2 * PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform.
3 * Copyright (C) 2003 Linda Xie <lxie@us.ibm.com>
4 *
5 * All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or (at
10 * your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
15 * NON INFRINGEMENT. See the GNU General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * Send feedback to <lxie@us.ibm.com>
23 *
24 */
25#include <linux/pci.h>
26#include <asm/pci-bridge.h>
27#include <asm/rtas.h>
28#include <asm/machdep.h>
29#include "../pci.h" /* for pci_add_new_bus */
30
31#include "rpaphp.h"
32
33struct pci_dev *rpaphp_find_pci_dev(struct device_node *dn)
34{
35 struct pci_dev *dev = NULL;
36 char bus_id[BUS_ID_SIZE];
37
38 sprintf(bus_id, "%04x:%02x:%02x.%d", dn->phb->global_number,
39 dn->busno, PCI_SLOT(dn->devfn), PCI_FUNC(dn->devfn));
40 for_each_pci_dev(dev) {
41 if (!strcmp(pci_name(dev), bus_id)) {
42 break;
43 }
44 }
45 return dev;
46}
47
48EXPORT_SYMBOL_GPL(rpaphp_find_pci_dev);
49
50int rpaphp_claim_resource(struct pci_dev *dev, int resource)
51{
52 struct resource *res = &dev->resource[resource];
53 struct resource *root = pci_find_parent_resource(dev, res);
54 char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge";
55 int err = -EINVAL;
56
57 if (root != NULL) {
58 err = request_resource(root, res);
59 }
60
61 if (err) {
62 err("PCI: %s region %d of %s %s [%lx:%lx]\n",
63 root ? "Address space collision on" :
64 "No parent found for",
65 resource, dtype, pci_name(dev), res->start, res->end);
66 }
67 return err;
68}
69
70EXPORT_SYMBOL_GPL(rpaphp_claim_resource);
71
72static struct pci_dev *rpaphp_find_bridge_pdev(struct slot *slot)
73{
74 return rpaphp_find_pci_dev(slot->dn);
75}
76
77static int rpaphp_get_sensor_state(struct slot *slot, int *state)
78{
79 int rc;
80 int setlevel;
81
82 rc = rtas_get_sensor(DR_ENTITY_SENSE, slot->index, state);
83
84 if (rc < 0) {
85 if (rc == -EFAULT || rc == -EEXIST) {
86 dbg("%s: slot must be power up to get sensor-state\n",
87 __FUNCTION__);
88
89 /* some slots have to be powered up
90 * before get-sensor will succeed.
91 */
92 rc = rtas_set_power_level(slot->power_domain, POWER_ON,
93 &setlevel);
94 if (rc < 0) {
95 dbg("%s: power on slot[%s] failed rc=%d.\n",
96 __FUNCTION__, slot->name, rc);
97 } else {
98 rc = rtas_get_sensor(DR_ENTITY_SENSE,
99 slot->index, state);
100 }
101 } else if (rc == -ENODEV)
102 info("%s: slot is unusable\n", __FUNCTION__);
103 else
104 err("%s failed to get sensor state\n", __FUNCTION__);
105 }
106 return rc;
107}
108
109/**
110 * get_pci_adapter_status - get the status of a slot
111 *
112 * 0-- slot is empty
113 * 1-- adapter is configured
114 * 2-- adapter is not configured
115 * 3-- not valid
116 */
117int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value)
118{
119 int state, rc;
120 struct device_node *child_dn;
121 struct pci_dev *child_dev = NULL;
122
123 *value = NOT_VALID;
124 rc = rpaphp_get_sensor_state(slot, &state);
125 if (rc)
126 goto exit;
127
128 if ((state == EMPTY) || (slot->type == PHB)) {
129 dbg("slot is empty\n");
130 *value = EMPTY;
131 }
132 else if (state == PRESENT) {
133 if (!is_init) {
134 /* at run-time slot->state can be changed by */
135 /* config/unconfig adapter */
136 *value = slot->state;
137 } else {
138 child_dn = slot->dn->child;
139 if (child_dn)
140 child_dev = rpaphp_find_pci_dev(child_dn);
141
142 if (child_dev)
143 *value = CONFIGURED;
144 else if (!child_dn)
145 dbg("%s: %s is not valid OFDT node\n",
146 __FUNCTION__, slot->dn->full_name);
147 else {
148 err("%s: can't find pdev of adapter in slot[%s]\n",
149 __FUNCTION__, slot->dn->full_name);
150 *value = NOT_CONFIGURED;
151 }
152 }
153 }
154exit:
155 return rc;
156}
157
158/* Must be called before pci_bus_add_devices */
159static void
160rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
161{
162 struct pci_dev *dev;
163
164 list_for_each_entry(dev, &bus->devices, bus_list) {
165 /*
166 * Skip already-present devices (which are on the
167 * global device list.)
168 */
169 if (list_empty(&dev->global_list)) {
170 int i;
171
172 /* Need to setup IOMMU tables */
173 ppc_md.iommu_dev_setup(dev);
174
175 if(fix_bus)
176 pcibios_fixup_device_resources(dev, bus);
177 pci_read_irq_line(dev);
178 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
179 struct resource *r = &dev->resource[i];
180
181 if (r->parent || !r->start || !r->flags)
182 continue;
183 rpaphp_claim_resource(dev, i);
184 }
185 }
186 }
187}
188
189static int rpaphp_pci_config_bridge(struct pci_dev *dev);
190
191/*****************************************************************************
192 rpaphp_pci_config_slot() will configure all devices under the
193 given slot->dn and return the the first pci_dev.
194 *****************************************************************************/
195static struct pci_dev *
196rpaphp_pci_config_slot(struct device_node *dn, struct pci_bus *bus)
197{
198 struct device_node *eads_first_child = dn->child;
199 struct pci_dev *dev = NULL;
200 int num;
201
202 dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name);
203
204 if (eads_first_child) {
205 /* pci_scan_slot should find all children of EADs */
206 num = pci_scan_slot(bus, PCI_DEVFN(PCI_SLOT(eads_first_child->devfn), 0));
207 if (num) {
208 rpaphp_fixup_new_pci_devices(bus, 1);
209 pci_bus_add_devices(bus);
210 }
211 dev = rpaphp_find_pci_dev(eads_first_child);
212 if (!dev) {
213 err("No new device found\n");
214 return NULL;
215 }
216 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
217 rpaphp_pci_config_bridge(dev);
218 }
219 return dev;
220}
221
222static int rpaphp_pci_config_bridge(struct pci_dev *dev)
223{
224 u8 sec_busno;
225 struct pci_bus *child_bus;
226 struct pci_dev *child_dev;
227
228 dbg("Enter %s: BRIDGE dev=%s\n", __FUNCTION__, pci_name(dev));
229
230 /* get busno of downstream bus */
231 pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno);
232
233 /* add to children of PCI bridge dev->bus */
234 child_bus = pci_add_new_bus(dev->bus, dev, sec_busno);
235 if (!child_bus) {
236 err("%s: could not add second bus\n", __FUNCTION__);
237 return -EIO;
238 }
239 sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number);
240 /* do pci_scan_child_bus */
241 pci_scan_child_bus(child_bus);
242
243 list_for_each_entry(child_dev, &child_bus->devices, bus_list) {
244 eeh_add_device_late(child_dev);
245 }
246
247 /* fixup new pci devices without touching bus struct */
248 rpaphp_fixup_new_pci_devices(child_bus, 0);
249
250 /* Make the discovered devices available */
251 pci_bus_add_devices(child_bus);
252 return 0;
253}
254
255static void enable_eeh(struct device_node *dn)
256{
257 struct device_node *sib;
258
259 for (sib = dn->child; sib; sib = sib->sibling)
260 enable_eeh(sib);
261 eeh_add_device_early(dn);
262 return;
263
264}
265
266static void print_slot_pci_funcs(struct slot *slot)
267{
268 struct pci_dev *dev;
269
270 if (slot->dev_type == PCI_DEV) {
271 dbg("%s: pci_devs of slot[%s]\n", __FUNCTION__, slot->name);
272 list_for_each_entry (dev, slot->dev.pci_devs, bus_list)
273 dbg("\t%s\n", pci_name(dev));
274 }
275 return;
276}
277
278static int rpaphp_config_pci_adapter(struct slot *slot)
279{
280 struct pci_bus *pci_bus;
281 struct pci_dev *dev;
282 int rc = -ENODEV;
283
284 dbg("Entry %s: slot[%s]\n", __FUNCTION__, slot->name);
285
286 if (slot->bridge) {
287
288 pci_bus = slot->bridge->subordinate;
289 if (!pci_bus) {
290 err("%s: can't find bus structure\n", __FUNCTION__);
291 goto exit;
292 }
293 enable_eeh(slot->dn);
294 dev = rpaphp_pci_config_slot(slot->dn, pci_bus);
295 if (!dev) {
296 err("%s: can't find any devices.\n", __FUNCTION__);
297 goto exit;
298 }
299 print_slot_pci_funcs(slot);
300 rc = 0;
301 } else {
302 /* slot is not enabled */
303 err("slot doesn't have pci_dev structure\n");
304 }
305exit:
306 dbg("Exit %s: rc=%d\n", __FUNCTION__, rc);
307 return rc;
308}
309
310static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev)
311{
312 eeh_remove_device(dev);
313 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
314 struct pci_bus *bus = dev->subordinate;
315 struct list_head *ln;
316 if (!bus)
317 return;
318 for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
319 struct pci_dev *pdev = pci_dev_b(ln);
320 if (pdev)
321 rpaphp_eeh_remove_bus_device(pdev);
322 }
323
324 }
325 return;
326}
327
328int rpaphp_unconfig_pci_adapter(struct slot *slot)
329{
330 struct pci_dev *dev;
331 int retval = 0;
332
333 list_for_each_entry(dev, slot->dev.pci_devs, bus_list)
334 rpaphp_eeh_remove_bus_device(dev);
335
336 pci_remove_behind_bridge(slot->bridge);
337 slot->state = NOT_CONFIGURED;
338 info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__,
339 slot->name);
340 return retval;
341}
342
343static int setup_pci_hotplug_slot_info(struct slot *slot)
344{
345 dbg("%s Initilize the PCI slot's hotplug->info structure ...\n",
346 __FUNCTION__);
347 rpaphp_get_power_status(slot, &slot->hotplug_slot->info->power_status);
348 rpaphp_get_pci_adapter_status(slot, 1,
349 &slot->hotplug_slot->info->
350 adapter_status);
351 if (slot->hotplug_slot->info->adapter_status == NOT_VALID) {
352 err("%s: NOT_VALID: skip dn->full_name=%s\n",
353 __FUNCTION__, slot->dn->full_name);
354 return -EINVAL;
355 }
356 return 0;
357}
358
359static int set_phb_slot_name(struct slot *slot)
360{
361 struct device_node *dn;
362 struct pci_controller *phb;
363 struct pci_bus *bus;
364
365 dn = slot->dn;
366 if (!dn) {
367 return -EINVAL;
368 }
369 phb = dn->phb;
370 if (!phb) {
371 return -EINVAL;
372 }
373 bus = phb->bus;
374 if (!bus) {
375 return -EINVAL;
376 }
377
378 sprintf(slot->name, "%04x:%02x:%02x.%x", pci_domain_nr(bus),
379 bus->number, 0, 0);
380 return 0;
381}
382
383static int setup_pci_slot(struct slot *slot)
384{
385 struct pci_bus *bus;
386 int rc;
387
388 if (slot->type == PHB) {
389 rc = set_phb_slot_name(slot);
390 if (rc < 0) {
391 err("%s: failed to set phb slot name\n", __FUNCTION__);
392 goto exit_rc;
393 }
394 } else {
395 slot->bridge = rpaphp_find_bridge_pdev(slot);
396 if (!slot->bridge) {
397 /* slot being added doesn't have pci_dev yet */
398 err("%s: no pci_dev for bridge dn %s\n",
399 __FUNCTION__, slot->name);
400 goto exit_rc;
401 }
402
403 bus = slot->bridge->subordinate;
404 if (!bus)
405 goto exit_rc;
406 slot->dev.pci_devs = &bus->devices;
407
408 dbg("%s set slot->name to %s\n", __FUNCTION__,
409 pci_name(slot->bridge));
410 strcpy(slot->name, pci_name(slot->bridge));
411 }
412
413 /* find slot's pci_dev if it's not empty */
414 if (slot->hotplug_slot->info->adapter_status == EMPTY) {
415 slot->state = EMPTY; /* slot is empty */
416 } else {
417 /* slot is occupied */
418 if (!(slot->dn->child)) {
419 /* non-empty slot has to have child */
420 err("%s: slot[%s]'s device_node doesn't have child for adapter\n",
421 __FUNCTION__, slot->name);
422 goto exit_rc;
423 }
424
425 if (slot->hotplug_slot->info->adapter_status == NOT_CONFIGURED) {
426 dbg("%s CONFIGURING pci adapter in slot[%s]\n",
427 __FUNCTION__, slot->name);
428 if (rpaphp_config_pci_adapter(slot)) {
429 err("%s: CONFIG pci adapter failed\n", __FUNCTION__);
430 goto exit_rc;
431 }
432
433 } else if (slot->hotplug_slot->info->adapter_status != CONFIGURED) {
434 err("%s: slot[%s]'s adapter_status is NOT_VALID.\n",
435 __FUNCTION__, slot->name);
436 goto exit_rc;
437 }
438 print_slot_pci_funcs(slot);
439 if (!list_empty(slot->dev.pci_devs)) {
440 slot->state = CONFIGURED;
441 } else {
442 /* DLPAR add as opposed to
443 * boot time */
444 slot->state = NOT_CONFIGURED;
445 }
446 }
447 return 0;
448exit_rc:
449 dealloc_slot_struct(slot);
450 return -EINVAL;
451}
452
453int register_pci_slot(struct slot *slot)
454{
455 int rc = -EINVAL;
456
457 slot->dev_type = PCI_DEV;
458 if ((slot->type == EMBEDDED) || (slot->type == PHB))
459 slot->removable = 0;
460 else
461 slot->removable = 1;
462 if (setup_pci_hotplug_slot_info(slot))
463 goto exit_rc;
464 if (setup_pci_slot(slot))
465 goto exit_rc;
466 rc = register_slot(slot);
467exit_rc:
468 return rc;
469}
470
471int rpaphp_enable_pci_slot(struct slot *slot)
472{
473 int retval = 0, state;
474
475 retval = rpaphp_get_sensor_state(slot, &state);
476 if (retval)
477 goto exit;
478 dbg("%s: sensor state[%d]\n", __FUNCTION__, state);
479 /* if slot is not empty, enable the adapter */
480 if (state == PRESENT) {
481 dbg("%s : slot[%s] is occupied.\n", __FUNCTION__, slot->name);
482 retval = rpaphp_config_pci_adapter(slot);
483 if (!retval) {
484 slot->state = CONFIGURED;
485 dbg("%s: PCI devices in slot[%s] has been configured\n",
486 __FUNCTION__, slot->name);
487 } else {
488 slot->state = NOT_CONFIGURED;
489 dbg("%s: no pci_dev struct for adapter in slot[%s]\n",
490 __FUNCTION__, slot->name);
491 }
492 } else if (state == EMPTY) {
493 dbg("%s : slot[%s] is empty\n", __FUNCTION__, slot->name);
494 slot->state = EMPTY;
495 } else {
496 err("%s: slot[%s] is in invalid state\n", __FUNCTION__,
497 slot->name);
498 slot->state = NOT_VALID;
499 retval = -EINVAL;
500 }
501exit:
502 dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
503 return retval;
504}
505
506struct hotplug_slot *rpaphp_find_hotplug_slot(struct pci_dev *dev)
507{
508 struct list_head *tmp, *n;
509 struct slot *slot;
510
511 list_for_each_safe(tmp, n, &rpaphp_slot_head) {
512 struct pci_bus *bus;
513 struct list_head *ln;
514
515 slot = list_entry(tmp, struct slot, rpaphp_slot_list);
516 if (slot->bridge == NULL) {
517 if (slot->dev_type == PCI_DEV) {
518 printk(KERN_WARNING "PCI slot missing bridge %s %s \n",
519 slot->name, slot->location);
520 }
521 continue;
522 }
523
524 bus = slot->bridge->subordinate;
525 if (!bus) {
526 continue; /* should never happen? */
527 }
528 for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
529 struct pci_dev *pdev = pci_dev_b(ln);
530 if (pdev == dev)
531 return slot->hotplug_slot;
532 }
533 }
534
535 return NULL;
536}
537
538EXPORT_SYMBOL_GPL(rpaphp_find_hotplug_slot);
diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c
new file mode 100644
index 000000000000..ff2cbf0652d8
--- /dev/null
+++ b/drivers/pci/hotplug/rpaphp_slot.c
@@ -0,0 +1,267 @@
1/*
2 * RPA Virtual I/O device functions
3 * Copyright (C) 2004 Linda Xie <lxie@us.ibm.com>
4 *
5 * All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or (at
10 * your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
15 * NON INFRINGEMENT. See the GNU General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * Send feedback to <lxie@us.ibm.com>
23 *
24 */
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/kobject.h>
28#include <linux/sysfs.h>
29#include <linux/pci.h>
30#include <asm/rtas.h>
31#include "rpaphp.h"
32
33static ssize_t removable_read_file (struct hotplug_slot *php_slot, char *buf)
34{
35 u8 value;
36 int retval = -ENOENT;
37 struct slot *slot = (struct slot *)php_slot->private;
38
39 if (!slot)
40 return retval;
41
42 value = slot->removable;
43 retval = sprintf (buf, "%d\n", value);
44 return retval;
45}
46
47static struct hotplug_slot_attribute hotplug_slot_attr_removable = {
48 .attr = {.name = "phy_removable", .mode = S_IFREG | S_IRUGO},
49 .show = removable_read_file,
50};
51
52static void rpaphp_sysfs_add_attr_removable (struct hotplug_slot *slot)
53{
54 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_removable.attr);
55}
56
57static void rpaphp_sysfs_remove_attr_removable (struct hotplug_slot *slot)
58{
59 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_removable.attr);
60}
61
62static ssize_t location_read_file (struct hotplug_slot *php_slot, char *buf)
63{
64 char *value;
65 int retval = -ENOENT;
66 struct slot *slot = (struct slot *)php_slot->private;
67
68 if (!slot)
69 return retval;
70
71 value = slot->location;
72 retval = sprintf (buf, "%s\n", value);
73 return retval;
74}
75
76static struct hotplug_slot_attribute hotplug_slot_attr_location = {
77 .attr = {.name = "phy_location", .mode = S_IFREG | S_IRUGO},
78 .show = location_read_file,
79};
80
81static void rpaphp_sysfs_add_attr_location (struct hotplug_slot *slot)
82{
83 sysfs_create_file(&slot->kobj, &hotplug_slot_attr_location.attr);
84}
85
86static void rpaphp_sysfs_remove_attr_location (struct hotplug_slot *slot)
87{
88 sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_location.attr);
89}
90
91/* free up the memory used by a slot */
92static void rpaphp_release_slot(struct hotplug_slot *hotplug_slot)
93{
94 struct slot *slot = (struct slot *) hotplug_slot->private;
95
96 dealloc_slot_struct(slot);
97}
98
99void dealloc_slot_struct(struct slot *slot)
100{
101 kfree(slot->hotplug_slot->info);
102 kfree(slot->hotplug_slot->name);
103 kfree(slot->hotplug_slot);
104 kfree(slot);
105 return;
106}
107
108struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name,
109 int power_domain)
110{
111 struct slot *slot;
112
113 slot = kmalloc(sizeof (struct slot), GFP_KERNEL);
114 if (!slot)
115 goto error_nomem;
116 memset(slot, 0, sizeof (struct slot));
117 slot->hotplug_slot = kmalloc(sizeof (struct hotplug_slot), GFP_KERNEL);
118 if (!slot->hotplug_slot)
119 goto error_slot;
120 memset(slot->hotplug_slot, 0, sizeof (struct hotplug_slot));
121 slot->hotplug_slot->info = kmalloc(sizeof (struct hotplug_slot_info),
122 GFP_KERNEL);
123 if (!slot->hotplug_slot->info)
124 goto error_hpslot;
125 memset(slot->hotplug_slot->info, 0, sizeof (struct hotplug_slot_info));
126 slot->hotplug_slot->name = kmalloc(BUS_ID_SIZE + 1, GFP_KERNEL);
127 if (!slot->hotplug_slot->name)
128 goto error_info;
129 slot->location = kmalloc(strlen(drc_name) + 1, GFP_KERNEL);
130 if (!slot->location)
131 goto error_name;
132 slot->name = slot->hotplug_slot->name;
133 slot->dn = dn;
134 slot->index = drc_index;
135 strcpy(slot->location, drc_name);
136 slot->power_domain = power_domain;
137 slot->hotplug_slot->private = slot;
138 slot->hotplug_slot->ops = &rpaphp_hotplug_slot_ops;
139 slot->hotplug_slot->release = &rpaphp_release_slot;
140
141 return (slot);
142
143error_name:
144 kfree(slot->hotplug_slot->name);
145error_info:
146 kfree(slot->hotplug_slot->info);
147error_hpslot:
148 kfree(slot->hotplug_slot);
149error_slot:
150 kfree(slot);
151error_nomem:
152 return NULL;
153}
154
155static int is_registered(struct slot *slot)
156{
157 struct slot *tmp_slot;
158
159 list_for_each_entry(tmp_slot, &rpaphp_slot_head, rpaphp_slot_list) {
160 if (!strcmp(tmp_slot->name, slot->name))
161 return 1;
162 }
163 return 0;
164}
165
166int deregister_slot(struct slot *slot)
167{
168 int retval = 0;
169 struct hotplug_slot *php_slot = slot->hotplug_slot;
170
171 dbg("%s - Entry: deregistering slot=%s\n",
172 __FUNCTION__, slot->name);
173
174 list_del(&slot->rpaphp_slot_list);
175
176 /* remove "phy_location" file */
177 rpaphp_sysfs_remove_attr_location(php_slot);
178
179 /* remove "phy_removable" file */
180 rpaphp_sysfs_remove_attr_removable(php_slot);
181
182 retval = pci_hp_deregister(php_slot);
183 if (retval)
184 err("Problem unregistering a slot %s\n", slot->name);
185 else
186 num_slots--;
187
188 dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval);
189 return retval;
190}
191
192int register_slot(struct slot *slot)
193{
194 int retval;
195
196 dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n",
197 __FUNCTION__, slot->dn->full_name, slot->index, slot->name,
198 slot->power_domain, slot->type);
199 /* should not try to register the same slot twice */
200 if (is_registered(slot)) { /* should't be here */
201 err("register_slot: slot[%s] is already registered\n", slot->name);
202 rpaphp_release_slot(slot->hotplug_slot);
203 return -EAGAIN;
204 }
205 retval = pci_hp_register(slot->hotplug_slot);
206 if (retval) {
207 err("pci_hp_register failed with error %d\n", retval);
208 rpaphp_release_slot(slot->hotplug_slot);
209 return retval;
210 }
211
212 /* create "phy_locatoin" file */
213 rpaphp_sysfs_add_attr_location(slot->hotplug_slot);
214
215 /* create "phy_removable" file */
216 rpaphp_sysfs_add_attr_removable(slot->hotplug_slot);
217
218 /* add slot to our internal list */
219 dbg("%s adding slot[%s] to rpaphp_slot_list\n",
220 __FUNCTION__, slot->name);
221
222 list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head);
223
224 if (slot->dev_type == VIO_DEV)
225 info("Slot [%s](VIO location=%s) registered\n",
226 slot->name, slot->location);
227 else
228 info("Slot [%s](PCI location=%s) registered\n",
229 slot->name, slot->location);
230 num_slots++;
231 return 0;
232}
233
234int rpaphp_get_power_status(struct slot *slot, u8 * value)
235{
236 int rc = 0, level;
237
238 if (slot->type == HOTPLUG) {
239 rc = rtas_get_power_level(slot->power_domain, &level);
240 if (!rc) {
241 dbg("%s the power level of slot %s(pwd-domain:0x%x) is %d\n",
242 __FUNCTION__, slot->name, slot->power_domain, level);
243 *value = level;
244 } else
245 err("failed to get power-level for slot(%s), rc=0x%x\n",
246 slot->location, rc);
247 } else {
248 dbg("%s report POWER_ON for EMBEDDED or PHB slot %s\n",
249 __FUNCTION__, slot->location);
250 *value = (u8) POWER_ON;
251 }
252
253 return rc;
254}
255
256int rpaphp_set_attention_status(struct slot *slot, u8 status)
257{
258 int rc;
259
260 /* status: LED_OFF or LED_ON */
261 rc = rtas_set_indicator(DR_INDICATOR, slot->index, status);
262 if (rc < 0)
263 err("slot(name=%s location=%s index=0x%x) set attention-status(%d) failed! rc=0x%x\n",
264 slot->name, slot->location, slot->index, status, rc);
265
266 return rc;
267}
diff --git a/drivers/pci/hotplug/rpaphp_vio.c b/drivers/pci/hotplug/rpaphp_vio.c
new file mode 100644
index 000000000000..74df6a305e64
--- /dev/null
+++ b/drivers/pci/hotplug/rpaphp_vio.c
@@ -0,0 +1,129 @@
1/*
2 * RPA Hot Plug Virtual I/O device functions
3 * Copyright (C) 2004 Linda Xie <lxie@us.ibm.com>
4 *
5 * All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or (at
10 * your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
15 * NON INFRINGEMENT. See the GNU General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * Send feedback to <lxie@us.ibm.com>
23 *
24 */
25#include <asm/vio.h>
26#include "rpaphp.h"
27
28/*
29 * get_vio_adapter_status - get the status of a slot
30 *
31 * status:
32 *
33 * 1-- adapter is configured
34 * 2-- adapter is not configured
35 * 3-- not valid
36 */
37inline int rpaphp_get_vio_adapter_status(struct slot *slot, int is_init, u8 *value)
38{
39 *value = slot->state;
40 return 0;
41}
42
43int rpaphp_unconfig_vio_adapter(struct slot *slot)
44{
45 int retval = 0;
46
47 dbg("Entry %s: slot[%s]\n", __FUNCTION__, slot->name);
48 if (!slot->dev.vio_dev) {
49 info("%s: no VIOA in slot[%s]\n", __FUNCTION__, slot->name);
50 retval = -EINVAL;
51 goto exit;
52 }
53 /* remove the device from the vio core */
54 vio_unregister_device(slot->dev.vio_dev);
55 slot->state = NOT_CONFIGURED;
56 info("%s: adapter in slot[%s] unconfigured.\n", __FUNCTION__, slot->name);
57exit:
58 dbg("Exit %s, rc=0x%x\n", __FUNCTION__, retval);
59 return retval;
60}
61
62static int setup_vio_hotplug_slot_info(struct slot *slot)
63{
64 slot->hotplug_slot->info->power_status = 1;
65 rpaphp_get_vio_adapter_status(slot, 1,
66 &slot->hotplug_slot->info->adapter_status);
67 return 0;
68}
69
70int register_vio_slot(struct device_node *dn)
71{
72 u32 *index;
73 char *name;
74 int rc = -EINVAL;
75 struct slot *slot = NULL;
76
77 rc = rpaphp_get_drc_props(dn, NULL, &name, NULL, NULL);
78 if (rc < 0)
79 goto exit_rc;
80 index = (u32 *) get_property(dn, "ibm,my-drc-index", NULL);
81 if (!index)
82 goto exit_rc;
83 if (!(slot = alloc_slot_struct(dn, *index, name, 0))) {
84 rc = -ENOMEM;
85 goto exit_rc;
86 }
87 slot->dev_type = VIO_DEV;
88 slot->dev.vio_dev = vio_find_node(dn);
89 if (slot->dev.vio_dev) {
90 /*
91 * rpaphp is the only owner of vio devices and
92 * does not need extra reference taken by
93 * vio_find_node
94 */
95 put_device(&slot->dev.vio_dev->dev);
96 } else
97 slot->dev.vio_dev = vio_register_device_node(dn);
98 if (slot->dev.vio_dev)
99 slot->state = CONFIGURED;
100 else
101 slot->state = NOT_CONFIGURED;
102 if (setup_vio_hotplug_slot_info(slot))
103 goto exit_rc;
104 strcpy(slot->name, slot->dev.vio_dev->dev.bus_id);
105 info("%s: registered VIO device[name=%s vio_dev=%p]\n",
106 __FUNCTION__, slot->name, slot->dev.vio_dev);
107 rc = register_slot(slot);
108exit_rc:
109 if (rc && slot)
110 dealloc_slot_struct(slot);
111 return (rc);
112}
113
114int rpaphp_enable_vio_slot(struct slot *slot)
115{
116 int retval = 0;
117
118 if ((slot->dev.vio_dev = vio_register_device_node(slot->dn))) {
119 info("%s: VIO adapter %s in slot[%s] has been configured\n",
120 __FUNCTION__, slot->dn->name, slot->name);
121 slot->state = CONFIGURED;
122 } else {
123 info("%s: no vio_dev struct for adapter in slot[%s]\n",
124 __FUNCTION__, slot->name);
125 slot->state = NOT_CONFIGURED;
126 }
127
128 return retval;
129}
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
new file mode 100644
index 000000000000..67b6a3370ceb
--- /dev/null
+++ b/drivers/pci/hotplug/shpchp.h
@@ -0,0 +1,463 @@
1/*
2 * Standard Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>,<dely.l.sy@intel.com>
27 *
28 */
29#ifndef _SHPCHP_H
30#define _SHPCHP_H
31
32#include <linux/types.h>
33#include <linux/pci.h>
34#include <linux/delay.h>
35#include <asm/semaphore.h>
36#include <asm/io.h>
37#include "pci_hotplug.h"
38
39#if !defined(MODULE)
40 #define MY_NAME "shpchp"
41#else
42 #define MY_NAME THIS_MODULE->name
43#endif
44
45extern int shpchp_poll_mode;
46extern int shpchp_poll_time;
47extern int shpchp_debug;
48
49/*#define dbg(format, arg...) do { if (shpchp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/
50#define dbg(format, arg...) do { if (shpchp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0)
51#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
52#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
53#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
54
55struct pci_func {
56 struct pci_func *next;
57 u8 bus;
58 u8 device;
59 u8 function;
60 u8 is_a_board;
61 u16 status;
62 u8 configured;
63 u8 switch_save;
64 u8 presence_save;
65 u8 pwr_save;
66 u32 base_length[0x06];
67 u8 base_type[0x06];
68 u16 reserved2;
69 u32 config_space[0x20];
70 struct pci_resource *mem_head;
71 struct pci_resource *p_mem_head;
72 struct pci_resource *io_head;
73 struct pci_resource *bus_head;
74 struct pci_dev* pci_dev;
75};
76
77#define SLOT_MAGIC 0x67267321
78struct slot {
79 u32 magic;
80 struct slot *next;
81 u8 bus;
82 u8 device;
83 u32 number;
84 u8 is_a_board;
85 u8 configured;
86 u8 state;
87 u8 switch_save;
88 u8 presence_save;
89 u32 capabilities;
90 u16 reserved2;
91 struct timer_list task_event;
92 u8 hp_slot;
93 struct controller *ctrl;
94 struct hpc_ops *hpc_ops;
95 struct hotplug_slot *hotplug_slot;
96 struct list_head slot_list;
97};
98
99struct pci_resource {
100 struct pci_resource * next;
101 u32 base;
102 u32 length;
103};
104
105struct event_info {
106 u32 event_type;
107 u8 hp_slot;
108};
109
110struct controller {
111 struct controller *next;
112 struct semaphore crit_sect; /* critical section semaphore */
113 void * hpc_ctlr_handle; /* HPC controller handle */
114 int num_slots; /* Number of slots on ctlr */
115 int slot_num_inc; /* 1 or -1 */
116 struct pci_resource *mem_head;
117 struct pci_resource *p_mem_head;
118 struct pci_resource *io_head;
119 struct pci_resource *bus_head;
120 struct pci_dev *pci_dev;
121 struct pci_bus *pci_bus;
122 struct event_info event_queue[10];
123 struct slot *slot;
124 struct hpc_ops *hpc_ops;
125 wait_queue_head_t queue; /* sleep & wake process */
126 u8 next_event;
127 u8 seg;
128 u8 bus;
129 u8 device;
130 u8 function;
131 u8 rev;
132 u8 slot_device_offset;
133 u8 add_support;
134 enum pci_bus_speed speed;
135 u32 first_slot; /* First physical slot number */
136 u8 slot_bus; /* Bus where the slots handled by this controller sit */
137 u8 push_flag;
138 u16 ctlrcap;
139 u16 vendor_id;
140};
141
142struct irq_mapping {
143 u8 barber_pole;
144 u8 valid_INT;
145 u8 interrupt[4];
146};
147
148struct resource_lists {
149 struct pci_resource *mem_head;
150 struct pci_resource *p_mem_head;
151 struct pci_resource *io_head;
152 struct pci_resource *bus_head;
153 struct irq_mapping *irqs;
154};
155
156/* Define AMD SHPC ID */
157#define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450
158
159#define INT_BUTTON_IGNORE 0
160#define INT_PRESENCE_ON 1
161#define INT_PRESENCE_OFF 2
162#define INT_SWITCH_CLOSE 3
163#define INT_SWITCH_OPEN 4
164#define INT_POWER_FAULT 5
165#define INT_POWER_FAULT_CLEAR 6
166#define INT_BUTTON_PRESS 7
167#define INT_BUTTON_RELEASE 8
168#define INT_BUTTON_CANCEL 9
169
170#define STATIC_STATE 0
171#define BLINKINGON_STATE 1
172#define BLINKINGOFF_STATE 2
173#define POWERON_STATE 3
174#define POWEROFF_STATE 4
175
176#define PCI_TO_PCI_BRIDGE_CLASS 0x00060400
177
178/* Error messages */
179#define INTERLOCK_OPEN 0x00000002
180#define ADD_NOT_SUPPORTED 0x00000003
181#define CARD_FUNCTIONING 0x00000005
182#define ADAPTER_NOT_SAME 0x00000006
183#define NO_ADAPTER_PRESENT 0x00000009
184#define NOT_ENOUGH_RESOURCES 0x0000000B
185#define DEVICE_TYPE_NOT_SUPPORTED 0x0000000C
186#define WRONG_BUS_FREQUENCY 0x0000000D
187#define POWER_FAILURE 0x0000000E
188
189#define REMOVE_NOT_SUPPORTED 0x00000003
190
191#define DISABLE_CARD 1
192
193/*
194 * error Messages
195 */
196#define msg_initialization_err "Initialization failure, error=%d\n"
197#define msg_HPC_rev_error "Unsupported revision of the PCI hot plug controller found.\n"
198#define msg_HPC_non_shpc "The PCI hot plug controller is not supported by this driver.\n"
199#define msg_HPC_not_supported "This system is not supported by this version of shpcphd mdoule. Upgrade to a newer version of shpchpd\n"
200#define msg_unable_to_save "Unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n"
201#define msg_button_on "PCI slot #%d - powering on due to button press.\n"
202#define msg_button_off "PCI slot #%d - powering off due to button press.\n"
203#define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n"
204#define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n"
205
206/* sysfs functions for the hotplug controller info */
207extern void shpchp_create_ctrl_files (struct controller *ctrl);
208
209/* controller functions */
210extern int shpchprm_find_available_resources(struct controller *ctrl);
211extern int shpchp_event_start_thread(void);
212extern void shpchp_event_stop_thread(void);
213extern struct pci_func *shpchp_slot_create(unsigned char busnumber);
214extern struct pci_func *shpchp_slot_find(unsigned char bus, unsigned char device, unsigned char index);
215extern int shpchp_enable_slot(struct slot *slot);
216extern int shpchp_disable_slot(struct slot *slot);
217
218extern u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id);
219extern u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id);
220extern u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id);
221extern u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id);
222
223/* resource functions */
224extern int shpchp_resource_sort_and_combine(struct pci_resource **head);
225
226/* pci functions */
227extern int shpchp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);
228/*extern int shpchp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, struct slot *slot);*/
229extern int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num);
230extern int shpchp_save_used_resources(struct controller *ctrl, struct pci_func * func, int flag);
231extern int shpchp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot);
232extern void shpchp_destroy_board_resources(struct pci_func * func);
233extern int shpchp_return_board_resources(struct pci_func * func, struct resource_lists * resources);
234extern void shpchp_destroy_resource_list(struct resource_lists * resources);
235extern int shpchp_configure_device(struct controller* ctrl, struct pci_func* func);
236extern int shpchp_unconfigure_device(struct pci_func* func);
237
238
239/* Global variables */
240extern struct controller *shpchp_ctrl_list;
241extern struct pci_func *shpchp_slot_list[256];
242
243/* These are added to support AMD shpc */
244extern u8 shpchp_nic_irq;
245extern u8 shpchp_disk_irq;
246
247struct ctrl_reg {
248 volatile u32 base_offset;
249 volatile u32 slot_avail1;
250 volatile u32 slot_avail2;
251 volatile u32 slot_config;
252 volatile u16 sec_bus_config;
253 volatile u8 msi_ctrl;
254 volatile u8 prog_interface;
255 volatile u16 cmd;
256 volatile u16 cmd_status;
257 volatile u32 intr_loc;
258 volatile u32 serr_loc;
259 volatile u32 serr_intr_enable;
260 volatile u32 slot1;
261 volatile u32 slot2;
262 volatile u32 slot3;
263 volatile u32 slot4;
264 volatile u32 slot5;
265 volatile u32 slot6;
266 volatile u32 slot7;
267 volatile u32 slot8;
268 volatile u32 slot9;
269 volatile u32 slot10;
270 volatile u32 slot11;
271 volatile u32 slot12;
272} __attribute__ ((packed));
273
274/* offsets to the controller registers based on the above structure layout */
275enum ctrl_offsets {
276 BASE_OFFSET = offsetof(struct ctrl_reg, base_offset),
277 SLOT_AVAIL1 = offsetof(struct ctrl_reg, slot_avail1),
278 SLOT_AVAIL2 = offsetof(struct ctrl_reg, slot_avail2),
279 SLOT_CONFIG = offsetof(struct ctrl_reg, slot_config),
280 SEC_BUS_CONFIG = offsetof(struct ctrl_reg, sec_bus_config),
281 MSI_CTRL = offsetof(struct ctrl_reg, msi_ctrl),
282 PROG_INTERFACE = offsetof(struct ctrl_reg, prog_interface),
283 CMD = offsetof(struct ctrl_reg, cmd),
284 CMD_STATUS = offsetof(struct ctrl_reg, cmd_status),
285 INTR_LOC = offsetof(struct ctrl_reg, intr_loc),
286 SERR_LOC = offsetof(struct ctrl_reg, serr_loc),
287 SERR_INTR_ENABLE = offsetof(struct ctrl_reg, serr_intr_enable),
288 SLOT1 = offsetof(struct ctrl_reg, slot1),
289 SLOT2 = offsetof(struct ctrl_reg, slot2),
290 SLOT3 = offsetof(struct ctrl_reg, slot3),
291 SLOT4 = offsetof(struct ctrl_reg, slot4),
292 SLOT5 = offsetof(struct ctrl_reg, slot5),
293 SLOT6 = offsetof(struct ctrl_reg, slot6),
294 SLOT7 = offsetof(struct ctrl_reg, slot7),
295 SLOT8 = offsetof(struct ctrl_reg, slot8),
296 SLOT9 = offsetof(struct ctrl_reg, slot9),
297 SLOT10 = offsetof(struct ctrl_reg, slot10),
298 SLOT11 = offsetof(struct ctrl_reg, slot11),
299 SLOT12 = offsetof(struct ctrl_reg, slot12),
300};
301typedef u8(*php_intr_callback_t) (unsigned int change_id, void *instance_id);
302struct php_ctlr_state_s {
303 struct php_ctlr_state_s *pnext;
304 struct pci_dev *pci_dev;
305 unsigned int irq;
306 unsigned long flags; /* spinlock's */
307 u32 slot_device_offset;
308 u32 num_slots;
309 struct timer_list int_poll_timer; /* Added for poll event */
310 php_intr_callback_t attention_button_callback;
311 php_intr_callback_t switch_change_callback;
312 php_intr_callback_t presence_change_callback;
313 php_intr_callback_t power_fault_callback;
314 void *callback_instance_id;
315 void __iomem *creg; /* Ptr to controller register space */
316};
317/* Inline functions */
318
319
320/* Inline functions to check the sanity of a pointer that is passed to us */
321static inline int slot_paranoia_check (struct slot *slot, const char *function)
322{
323 if (!slot) {
324 dbg("%s - slot == NULL", function);
325 return -1;
326 }
327 if (slot->magic != SLOT_MAGIC) {
328 dbg("%s - bad magic number for slot", function);
329 return -1;
330 }
331 if (!slot->hotplug_slot) {
332 dbg("%s - slot->hotplug_slot == NULL!", function);
333 return -1;
334 }
335 return 0;
336}
337
338static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const char *function)
339{
340 struct slot *slot;
341
342 if (!hotplug_slot) {
343 dbg("%s - hotplug_slot == NULL\n", function);
344 return NULL;
345 }
346
347 slot = (struct slot *)hotplug_slot->private;
348 if (slot_paranoia_check (slot, function))
349 return NULL;
350 return slot;
351}
352
353static inline struct slot *shpchp_find_slot (struct controller *ctrl, u8 device)
354{
355 struct slot *p_slot, *tmp_slot = NULL;
356
357 if (!ctrl)
358 return NULL;
359
360 p_slot = ctrl->slot;
361
362 dbg("p_slot = %p\n", p_slot);
363
364 while (p_slot && (p_slot->device != device)) {
365 tmp_slot = p_slot;
366 p_slot = p_slot->next;
367 dbg("In while loop, p_slot = %p\n", p_slot);
368 }
369 if (p_slot == NULL) {
370 err("ERROR: shpchp_find_slot device=0x%x\n", device);
371 p_slot = tmp_slot;
372 }
373
374 return (p_slot);
375}
376
377static inline int wait_for_ctrl_irq (struct controller *ctrl)
378{
379 DECLARE_WAITQUEUE(wait, current);
380 int retval = 0;
381
382 dbg("%s : start\n",__FUNCTION__);
383
384 add_wait_queue(&ctrl->queue, &wait);
385
386 if (!shpchp_poll_mode) {
387 /* Sleep for up to 1 second */
388 msleep_interruptible(1000);
389 } else {
390 /* Sleep for up to 2 seconds */
391 msleep_interruptible(2000);
392 }
393 remove_wait_queue(&ctrl->queue, &wait);
394 if (signal_pending(current))
395 retval = -EINTR;
396
397 dbg("%s : end\n", __FUNCTION__);
398 return retval;
399}
400
401/* Puts node back in the resource list pointed to by head */
402static inline void return_resource(struct pci_resource **head, struct pci_resource *node)
403{
404 if (!node || !head)
405 return;
406 node->next = *head;
407 *head = node;
408}
409
410#define SLOT_NAME_SIZE 10
411
412static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
413{
414 snprintf(buffer, buffer_size, "%d", slot->number);
415}
416
417enum php_ctlr_type {
418 PCI,
419 ISA,
420 ACPI
421};
422
423int shpc_init( struct controller *ctrl, struct pci_dev *pdev,
424 php_intr_callback_t attention_button_callback,
425 php_intr_callback_t switch_change_callback,
426 php_intr_callback_t presence_change_callback,
427 php_intr_callback_t power_fault_callback);
428
429int shpc_get_ctlr_slot_config( struct controller *ctrl,
430 int *num_ctlr_slots,
431 int *first_device_num,
432 int *physical_slot_num,
433 int *updown,
434 int *flags);
435
436struct hpc_ops {
437 int (*power_on_slot ) (struct slot *slot);
438 int (*slot_enable ) (struct slot *slot);
439 int (*slot_disable ) (struct slot *slot);
440 int (*enable_all_slots) (struct slot *slot);
441 int (*pwr_on_all_slots) (struct slot *slot);
442 int (*set_bus_speed_mode) (struct slot *slot, enum pci_bus_speed speed);
443 int (*get_power_status) (struct slot *slot, u8 *status);
444 int (*get_attention_status) (struct slot *slot, u8 *status);
445 int (*set_attention_status) (struct slot *slot, u8 status);
446 int (*get_latch_status) (struct slot *slot, u8 *status);
447 int (*get_adapter_status) (struct slot *slot, u8 *status);
448
449 int (*get_max_bus_speed) (struct slot *slot, enum pci_bus_speed *speed);
450 int (*get_cur_bus_speed) (struct slot *slot, enum pci_bus_speed *speed);
451 int (*get_adapter_speed) (struct slot *slot, enum pci_bus_speed *speed);
452 int (*get_mode1_ECC_cap) (struct slot *slot, u8 *mode);
453 int (*get_prog_int) (struct slot *slot, u8 *prog_int);
454
455 int (*query_power_fault) (struct slot *slot);
456 void (*green_led_on) (struct slot *slot);
457 void (*green_led_off) (struct slot *slot);
458 void (*green_led_blink) (struct slot *slot);
459 void (*release_ctlr) (struct controller *ctrl);
460 int (*check_cmd_status) (struct controller *ctrl);
461};
462
463#endif /* _SHPCHP_H */
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
new file mode 100644
index 000000000000..f0c53f850aed
--- /dev/null
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -0,0 +1,630 @@
1/*
2 * Standard Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/moduleparam.h>
33#include <linux/kernel.h>
34#include <linux/types.h>
35#include <linux/proc_fs.h>
36#include <linux/slab.h>
37#include <linux/workqueue.h>
38#include <linux/pci.h>
39#include <linux/init.h>
40#include <asm/uaccess.h>
41#include "shpchp.h"
42#include "shpchprm.h"
43
44/* Global variables */
45int shpchp_debug;
46int shpchp_poll_mode;
47int shpchp_poll_time;
48struct controller *shpchp_ctrl_list; /* = NULL */
49struct pci_func *shpchp_slot_list[256];
50
51#define DRIVER_VERSION "0.4"
52#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
53#define DRIVER_DESC "Standard Hot Plug PCI Controller Driver"
54
55MODULE_AUTHOR(DRIVER_AUTHOR);
56MODULE_DESCRIPTION(DRIVER_DESC);
57MODULE_LICENSE("GPL");
58
59module_param(shpchp_debug, bool, 0644);
60module_param(shpchp_poll_mode, bool, 0644);
61module_param(shpchp_poll_time, int, 0644);
62MODULE_PARM_DESC(shpchp_debug, "Debugging mode enabled or not");
63MODULE_PARM_DESC(shpchp_poll_mode, "Using polling mechanism for hot-plug events or not");
64MODULE_PARM_DESC(shpchp_poll_time, "Polling mechanism frequency, in seconds");
65
66#define SHPC_MODULE_NAME "shpchp"
67
68static int shpc_start_thread (void);
69static int set_attention_status (struct hotplug_slot *slot, u8 value);
70static int enable_slot (struct hotplug_slot *slot);
71static int disable_slot (struct hotplug_slot *slot);
72static int get_power_status (struct hotplug_slot *slot, u8 *value);
73static int get_attention_status (struct hotplug_slot *slot, u8 *value);
74static int get_latch_status (struct hotplug_slot *slot, u8 *value);
75static int get_adapter_status (struct hotplug_slot *slot, u8 *value);
76static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
77static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
78
79static struct hotplug_slot_ops shpchp_hotplug_slot_ops = {
80 .owner = THIS_MODULE,
81 .set_attention_status = set_attention_status,
82 .enable_slot = enable_slot,
83 .disable_slot = disable_slot,
84 .get_power_status = get_power_status,
85 .get_attention_status = get_attention_status,
86 .get_latch_status = get_latch_status,
87 .get_adapter_status = get_adapter_status,
88 .get_max_bus_speed = get_max_bus_speed,
89 .get_cur_bus_speed = get_cur_bus_speed,
90};
91
92/**
93 * release_slot - free up the memory used by a slot
94 * @hotplug_slot: slot to free
95 */
96static void release_slot(struct hotplug_slot *hotplug_slot)
97{
98 struct slot *slot = (struct slot *)hotplug_slot->private;
99
100 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
101
102 kfree(slot->hotplug_slot->info);
103 kfree(slot->hotplug_slot->name);
104 kfree(slot->hotplug_slot);
105 kfree(slot);
106}
107
108static int init_slots(struct controller *ctrl)
109{
110 struct slot *new_slot;
111 u8 number_of_slots;
112 u8 slot_device;
113 u32 slot_number, sun;
114 int result = -ENOMEM;
115
116 dbg("%s\n",__FUNCTION__);
117
118 number_of_slots = ctrl->num_slots;
119 slot_device = ctrl->slot_device_offset;
120 slot_number = ctrl->first_slot;
121
122 while (number_of_slots) {
123 new_slot = (struct slot *) kmalloc(sizeof(struct slot), GFP_KERNEL);
124 if (!new_slot)
125 goto error;
126
127 memset(new_slot, 0, sizeof(struct slot));
128 new_slot->hotplug_slot = kmalloc (sizeof (struct hotplug_slot), GFP_KERNEL);
129 if (!new_slot->hotplug_slot)
130 goto error_slot;
131 memset(new_slot->hotplug_slot, 0, sizeof (struct hotplug_slot));
132
133 new_slot->hotplug_slot->info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
134 if (!new_slot->hotplug_slot->info)
135 goto error_hpslot;
136 memset(new_slot->hotplug_slot->info, 0, sizeof (struct hotplug_slot_info));
137 new_slot->hotplug_slot->name = kmalloc (SLOT_NAME_SIZE, GFP_KERNEL);
138 if (!new_slot->hotplug_slot->name)
139 goto error_info;
140
141 new_slot->magic = SLOT_MAGIC;
142 new_slot->ctrl = ctrl;
143 new_slot->bus = ctrl->slot_bus;
144 new_slot->device = slot_device;
145 new_slot->hpc_ops = ctrl->hpc_ops;
146
147 if (shpchprm_get_physical_slot_number(ctrl, &sun,
148 new_slot->bus, new_slot->device))
149 goto error_name;
150
151 new_slot->number = sun;
152 new_slot->hp_slot = slot_device - ctrl->slot_device_offset;
153
154 /* register this slot with the hotplug pci core */
155 new_slot->hotplug_slot->private = new_slot;
156 new_slot->hotplug_slot->release = &release_slot;
157 make_slot_name(new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot);
158 new_slot->hotplug_slot->ops = &shpchp_hotplug_slot_ops;
159
160 new_slot->hpc_ops->get_power_status(new_slot, &(new_slot->hotplug_slot->info->power_status));
161 new_slot->hpc_ops->get_attention_status(new_slot, &(new_slot->hotplug_slot->info->attention_status));
162 new_slot->hpc_ops->get_latch_status(new_slot, &(new_slot->hotplug_slot->info->latch_status));
163 new_slot->hpc_ops->get_adapter_status(new_slot, &(new_slot->hotplug_slot->info->adapter_status));
164
165 dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x slot_device_offset=%x\n", new_slot->bus,
166 new_slot->device, new_slot->hp_slot, new_slot->number, ctrl->slot_device_offset);
167 result = pci_hp_register (new_slot->hotplug_slot);
168 if (result) {
169 err ("pci_hp_register failed with error %d\n", result);
170 goto error_name;
171 }
172
173 new_slot->next = ctrl->slot;
174 ctrl->slot = new_slot;
175
176 number_of_slots--;
177 slot_device++;
178 slot_number += ctrl->slot_num_inc;
179 }
180
181 return 0;
182
183error_name:
184 kfree(new_slot->hotplug_slot->name);
185error_info:
186 kfree(new_slot->hotplug_slot->info);
187error_hpslot:
188 kfree(new_slot->hotplug_slot);
189error_slot:
190 kfree(new_slot);
191error:
192 return result;
193}
194
195static void cleanup_slots(struct controller *ctrl)
196{
197 struct slot *old_slot, *next_slot;
198
199 old_slot = ctrl->slot;
200 ctrl->slot = NULL;
201
202 while (old_slot) {
203 next_slot = old_slot->next;
204 pci_hp_deregister(old_slot->hotplug_slot);
205 old_slot = next_slot;
206 }
207}
208
209static int get_ctlr_slot_config(struct controller *ctrl)
210{
211 int num_ctlr_slots;
212 int first_device_num;
213 int physical_slot_num;
214 int updown;
215 int rc;
216 int flags;
217
218 rc = shpc_get_ctlr_slot_config(ctrl, &num_ctlr_slots, &first_device_num, &physical_slot_num, &updown, &flags);
219 if (rc) {
220 err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n", __FUNCTION__, ctrl->bus, ctrl->device);
221 return -1;
222 }
223
224 ctrl->num_slots = num_ctlr_slots;
225 ctrl->slot_device_offset = first_device_num;
226 ctrl->first_slot = physical_slot_num;
227 ctrl->slot_num_inc = updown; /* either -1 or 1 */
228
229 dbg("%s: num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) updown(%d) for b:d (%x:%x)\n",
230 __FUNCTION__, num_ctlr_slots, first_device_num, physical_slot_num, updown, ctrl->bus, ctrl->device);
231
232 return 0;
233}
234
235
236/*
237 * set_attention_status - Turns the Amber LED for a slot on, off or blink
238 */
239static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
240{
241 struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
242
243 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
244
245 hotplug_slot->info->attention_status = status;
246 slot->hpc_ops->set_attention_status(slot, status);
247
248 return 0;
249}
250
251
252static int enable_slot (struct hotplug_slot *hotplug_slot)
253{
254 struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
255
256 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
257
258 return shpchp_enable_slot(slot);
259}
260
261
262static int disable_slot (struct hotplug_slot *hotplug_slot)
263{
264 struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
265
266 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
267
268 return shpchp_disable_slot(slot);
269}
270
271static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
272{
273 struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
274 int retval;
275
276 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
277
278 retval = slot->hpc_ops->get_power_status(slot, value);
279 if (retval < 0)
280 *value = hotplug_slot->info->power_status;
281
282 return 0;
283}
284
285static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
286{
287 struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
288 int retval;
289
290 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
291
292 retval = slot->hpc_ops->get_attention_status(slot, value);
293 if (retval < 0)
294 *value = hotplug_slot->info->attention_status;
295
296 return 0;
297}
298
299static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
300{
301 struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
302 int retval;
303
304 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
305
306 retval = slot->hpc_ops->get_latch_status(slot, value);
307 if (retval < 0)
308 *value = hotplug_slot->info->latch_status;
309
310 return 0;
311}
312
313static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
314{
315 struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
316 int retval;
317
318 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
319
320 retval = slot->hpc_ops->get_adapter_status(slot, value);
321 if (retval < 0)
322 *value = hotplug_slot->info->adapter_status;
323
324 return 0;
325}
326
327static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
328{
329 struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
330 int retval;
331
332 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
333
334 retval = slot->hpc_ops->get_max_bus_speed(slot, value);
335 if (retval < 0)
336 *value = PCI_SPEED_UNKNOWN;
337
338 return 0;
339}
340
341static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
342{
343 struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
344 int retval;
345
346 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
347
348 retval = slot->hpc_ops->get_cur_bus_speed(slot, value);
349 if (retval < 0)
350 *value = PCI_SPEED_UNKNOWN;
351
352 return 0;
353}
354
355static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
356{
357 int rc;
358 struct controller *ctrl;
359 struct slot *t_slot;
360 int first_device_num; /* first PCI device number supported by this SHPC */
361 int num_ctlr_slots; /* number of slots supported by this SHPC */
362
363 ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
364 if (!ctrl) {
365 err("%s : out of memory\n", __FUNCTION__);
366 goto err_out_none;
367 }
368 memset(ctrl, 0, sizeof(struct controller));
369
370 dbg("DRV_thread pid = %d\n", current->pid);
371
372 rc = shpc_init(ctrl, pdev,
373 (php_intr_callback_t) shpchp_handle_attention_button,
374 (php_intr_callback_t) shpchp_handle_switch_change,
375 (php_intr_callback_t) shpchp_handle_presence_change,
376 (php_intr_callback_t) shpchp_handle_power_fault);
377 if (rc) {
378 dbg("%s: controller initialization failed\n", SHPC_MODULE_NAME);
379 goto err_out_free_ctrl;
380 }
381
382 dbg("%s: controller initialization success\n", __FUNCTION__);
383 ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */
384
385 pci_set_drvdata(pdev, ctrl);
386
387 ctrl->pci_bus = kmalloc (sizeof (*ctrl->pci_bus), GFP_KERNEL);
388 if (!ctrl->pci_bus) {
389 err("out of memory\n");
390 rc = -ENOMEM;
391 goto err_out_unmap_mmio_region;
392 }
393
394 memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus));
395 ctrl->bus = pdev->bus->number;
396 ctrl->slot_bus = pdev->subordinate->number;
397
398 ctrl->device = PCI_SLOT(pdev->devfn);
399 ctrl->function = PCI_FUNC(pdev->devfn);
400 dbg("ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", ctrl->bus, ctrl->device, ctrl->function, pdev->irq);
401
402 /*
403 * Save configuration headers for this and subordinate PCI buses
404 */
405
406 rc = get_ctlr_slot_config(ctrl);
407 if (rc) {
408 err(msg_initialization_err, rc);
409 goto err_out_free_ctrl_bus;
410 }
411 first_device_num = ctrl->slot_device_offset;
412 num_ctlr_slots = ctrl->num_slots;
413
414 /* Store PCI Config Space for all devices on this bus */
415 rc = shpchp_save_config(ctrl, ctrl->slot_bus, num_ctlr_slots, first_device_num);
416 if (rc) {
417 err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
418 goto err_out_free_ctrl_bus;
419 }
420
421 /* Get IO, memory, and IRQ resources for new devices */
422 rc = shpchprm_find_available_resources(ctrl);
423 ctrl->add_support = !rc;
424
425 if (rc) {
426 dbg("shpchprm_find_available_resources = %#x\n", rc);
427 err("unable to locate PCI configuration resources for hot plug add.\n");
428 goto err_out_free_ctrl_bus;
429 }
430
431 /* Setup the slot information structures */
432 rc = init_slots(ctrl);
433 if (rc) {
434 err(msg_initialization_err, 6);
435 goto err_out_free_ctrl_slot;
436 }
437
438 /* Now hpc_functions (slot->hpc_ops->functions) are ready */
439 t_slot = shpchp_find_slot(ctrl, first_device_num);
440
441 /* Check for operation bus speed */
442 rc = t_slot->hpc_ops->get_cur_bus_speed(t_slot, &ctrl->speed);
443 dbg("%s: t_slot->hp_slot %x\n", __FUNCTION__,t_slot->hp_slot);
444
445 if (rc || ctrl->speed == PCI_SPEED_UNKNOWN) {
446 err(SHPC_MODULE_NAME ": Can't get current bus speed. Set to 33MHz PCI.\n");
447 ctrl->speed = PCI_SPEED_33MHz;
448 }
449
450 /* Finish setting up the hot plug ctrl device */
451 ctrl->next_event = 0;
452
453 if (!shpchp_ctrl_list) {
454 shpchp_ctrl_list = ctrl;
455 ctrl->next = NULL;
456 } else {
457 ctrl->next = shpchp_ctrl_list;
458 shpchp_ctrl_list = ctrl;
459 }
460
461 shpchp_create_ctrl_files(ctrl);
462
463 return 0;
464
465err_out_free_ctrl_slot:
466 cleanup_slots(ctrl);
467err_out_free_ctrl_bus:
468 kfree(ctrl->pci_bus);
469err_out_unmap_mmio_region:
470 ctrl->hpc_ops->release_ctlr(ctrl);
471err_out_free_ctrl:
472 kfree(ctrl);
473err_out_none:
474 return -ENODEV;
475}
476
477
478static int shpc_start_thread(void)
479{
480 int loop;
481 int retval = 0;
482
483 dbg("Initialize + Start the notification/polling mechanism \n");
484
485 retval = shpchp_event_start_thread();
486 if (retval) {
487 dbg("shpchp_event_start_thread() failed\n");
488 return retval;
489 }
490
491 dbg("Initialize slot lists\n");
492 /* One slot list for each bus in the system */
493 for (loop = 0; loop < 256; loop++) {
494 shpchp_slot_list[loop] = NULL;
495 }
496
497 return retval;
498}
499
500static inline void __exit
501free_shpchp_res(struct pci_resource *res)
502{
503 struct pci_resource *tres;
504
505 while (res) {
506 tres = res;
507 res = res->next;
508 kfree(tres);
509 }
510}
511
512static void __exit unload_shpchpd(void)
513{
514 struct pci_func *next;
515 struct pci_func *TempSlot;
516 int loop;
517 struct controller *ctrl;
518 struct controller *tctrl;
519
520 ctrl = shpchp_ctrl_list;
521
522 while (ctrl) {
523 cleanup_slots(ctrl);
524
525 free_shpchp_res(ctrl->io_head);
526 free_shpchp_res(ctrl->mem_head);
527 free_shpchp_res(ctrl->p_mem_head);
528 free_shpchp_res(ctrl->bus_head);
529
530 kfree (ctrl->pci_bus);
531
532 dbg("%s: calling release_ctlr\n", __FUNCTION__);
533 ctrl->hpc_ops->release_ctlr(ctrl);
534
535 tctrl = ctrl;
536 ctrl = ctrl->next;
537
538 kfree(tctrl);
539 }
540
541 for (loop = 0; loop < 256; loop++) {
542 next = shpchp_slot_list[loop];
543 while (next != NULL) {
544 free_shpchp_res(next->io_head);
545 free_shpchp_res(next->mem_head);
546 free_shpchp_res(next->p_mem_head);
547 free_shpchp_res(next->bus_head);
548
549 TempSlot = next;
550 next = next->next;
551 kfree(TempSlot);
552 }
553 }
554
555 /* Stop the notification mechanism */
556 shpchp_event_stop_thread();
557
558}
559
560
561static struct pci_device_id shpcd_pci_tbl[] = {
562 {
563 .class = ((PCI_CLASS_BRIDGE_PCI << 8) | 0x00),
564 .class_mask = ~0,
565 .vendor = PCI_ANY_ID,
566 .device = PCI_ANY_ID,
567 .subvendor = PCI_ANY_ID,
568 .subdevice = PCI_ANY_ID,
569 },
570
571 { /* end: all zeroes */ }
572};
573
574MODULE_DEVICE_TABLE(pci, shpcd_pci_tbl);
575
576
577
578static struct pci_driver shpc_driver = {
579 .name = SHPC_MODULE_NAME,
580 .id_table = shpcd_pci_tbl,
581 .probe = shpc_probe,
582 /* remove: shpc_remove_one, */
583};
584
585
586
587static int __init shpcd_init(void)
588{
589 int retval = 0;
590
591#ifdef CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE
592 shpchp_poll_mode = 1;
593#endif
594
595 retval = shpc_start_thread();
596 if (retval)
597 goto error_hpc_init;
598
599 retval = shpchprm_init(PCI);
600 if (!retval) {
601 retval = pci_register_driver(&shpc_driver);
602 dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval);
603 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
604 }
605
606error_hpc_init:
607 if (retval) {
608 shpchprm_cleanup();
609 shpchp_event_stop_thread();
610 } else
611 shpchprm_print_pirt();
612
613 return retval;
614}
615
616static void __exit shpcd_cleanup(void)
617{
618 dbg("unload_shpchpd()\n");
619 unload_shpchpd();
620
621 shpchprm_cleanup();
622
623 dbg("pci_unregister_driver\n");
624 pci_unregister_driver(&shpc_driver);
625
626 info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
627}
628
629module_init(shpcd_init);
630module_exit(shpcd_cleanup);
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
new file mode 100644
index 000000000000..9f90eb8e6ecd
--- /dev/null
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -0,0 +1,2848 @@
1/*
2 * Standard Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/types.h>
34#include <linux/slab.h>
35#include <linux/workqueue.h>
36#include <linux/interrupt.h>
37#include <linux/delay.h>
38#include <linux/wait.h>
39#include <linux/smp_lock.h>
40#include <linux/pci.h>
41#include "shpchp.h"
42#include "shpchprm.h"
43
44static u32 configure_new_device(struct controller *ctrl, struct pci_func *func,
45 u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
46static int configure_new_function( struct controller *ctrl, struct pci_func *func,
47 u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
48static void interrupt_event_handler(struct controller *ctrl);
49
50static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */
51static struct semaphore event_exit; /* guard ensure thread has exited before calling it quits */
52static int event_finished;
53static unsigned long pushbutton_pending; /* = 0 */
54
55u8 shpchp_disk_irq;
56u8 shpchp_nic_irq;
57
58u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id)
59{
60 struct controller *ctrl = (struct controller *) inst_id;
61 struct slot *p_slot;
62 u8 rc = 0;
63 u8 getstatus;
64 struct pci_func *func;
65 struct event_info *taskInfo;
66
67 /* Attention Button Change */
68 dbg("shpchp: Attention button interrupt received.\n");
69
70 func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
71
72 /* This is the structure that tells the worker thread what to do */
73 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
74 p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
75
76 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
77 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
78
79 ctrl->next_event = (ctrl->next_event + 1) % 10;
80 taskInfo->hp_slot = hp_slot;
81
82 rc++;
83
84 /*
85 * Button pressed - See if need to TAKE ACTION!!!
86 */
87 info("Button pressed on Slot(%d)\n", ctrl->first_slot + hp_slot);
88 taskInfo->event_type = INT_BUTTON_PRESS;
89
90 if ((p_slot->state == BLINKINGON_STATE)
91 || (p_slot->state == BLINKINGOFF_STATE)) {
92 /* Cancel if we are still blinking; this means that we press the
93 * attention again before the 5 sec. limit expires to cancel hot-add
94 * or hot-remove
95 */
96 taskInfo->event_type = INT_BUTTON_CANCEL;
97 info("Button cancel on Slot(%d)\n", ctrl->first_slot + hp_slot);
98 } else if ((p_slot->state == POWERON_STATE)
99 || (p_slot->state == POWEROFF_STATE)) {
100 /* Ignore if the slot is on power-on or power-off state; this
101 * means that the previous attention button action to hot-add or
102 * hot-remove is undergoing
103 */
104 taskInfo->event_type = INT_BUTTON_IGNORE;
105 info("Button ignore on Slot(%d)\n", ctrl->first_slot + hp_slot);
106 }
107
108 if (rc)
109 up(&event_semaphore); /* signal event thread that new event is posted */
110
111 return 0;
112
113}
114
115u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
116{
117 struct controller *ctrl = (struct controller *) inst_id;
118 struct slot *p_slot;
119 u8 rc = 0;
120 u8 getstatus;
121 struct pci_func *func;
122 struct event_info *taskInfo;
123
124 /* Switch Change */
125 dbg("shpchp: Switch interrupt received.\n");
126
127 func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
128
129 /* This is the structure that tells the worker thread
130 * what to do
131 */
132 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
133 ctrl->next_event = (ctrl->next_event + 1) % 10;
134 taskInfo->hp_slot = hp_slot;
135
136 rc++;
137 p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
138 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
139 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
140 dbg("%s: Card present %x Power status %x\n", __FUNCTION__,
141 func->presence_save, func->pwr_save);
142
143 if (getstatus) {
144 /*
145 * Switch opened
146 */
147 info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot);
148 func->switch_save = 0;
149 taskInfo->event_type = INT_SWITCH_OPEN;
150 if (func->pwr_save && func->presence_save) {
151 taskInfo->event_type = INT_POWER_FAULT;
152 err("Surprise Removal of card\n");
153 }
154 } else {
155 /*
156 * Switch closed
157 */
158 info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot);
159 func->switch_save = 0x10;
160 taskInfo->event_type = INT_SWITCH_CLOSE;
161 }
162
163 if (rc)
164 up(&event_semaphore); /* signal event thread that new event is posted */
165
166 return rc;
167}
168
169u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id)
170{
171 struct controller *ctrl = (struct controller *) inst_id;
172 struct slot *p_slot;
173 u8 rc = 0;
174 /*u8 temp_byte;*/
175 struct pci_func *func;
176 struct event_info *taskInfo;
177
178 /* Presence Change */
179 dbg("shpchp: Presence/Notify input change.\n");
180
181 func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
182
183 /* This is the structure that tells the worker thread
184 * what to do
185 */
186 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
187 ctrl->next_event = (ctrl->next_event + 1) % 10;
188 taskInfo->hp_slot = hp_slot;
189
190 rc++;
191 p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
192
193 /*
194 * Save the presence state
195 */
196 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
197 if (func->presence_save) {
198 /*
199 * Card Present
200 */
201 info("Card present on Slot(%d)\n", ctrl->first_slot + hp_slot);
202 taskInfo->event_type = INT_PRESENCE_ON;
203 } else {
204 /*
205 * Not Present
206 */
207 info("Card not present on Slot(%d)\n", ctrl->first_slot + hp_slot);
208 taskInfo->event_type = INT_PRESENCE_OFF;
209 }
210
211 if (rc)
212 up(&event_semaphore); /* signal event thread that new event is posted */
213
214 return rc;
215}
216
217u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id)
218{
219 struct controller *ctrl = (struct controller *) inst_id;
220 struct slot *p_slot;
221 u8 rc = 0;
222 struct pci_func *func;
223 struct event_info *taskInfo;
224
225 /* Power fault */
226 dbg("shpchp: Power fault interrupt received.\n");
227
228 func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
229
230 /* This is the structure that tells the worker thread
231 * what to do
232 */
233 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
234 ctrl->next_event = (ctrl->next_event + 1) % 10;
235 taskInfo->hp_slot = hp_slot;
236
237 rc++;
238 p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
239
240 if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) {
241 /*
242 * Power fault Cleared
243 */
244 info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot);
245 func->status = 0x00;
246 taskInfo->event_type = INT_POWER_FAULT_CLEAR;
247 } else {
248 /*
249 * Power fault
250 */
251 info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot);
252 taskInfo->event_type = INT_POWER_FAULT;
253 /* set power fault status for this board */
254 func->status = 0xFF;
255 info("power fault bit %x set\n", hp_slot);
256 }
257 if (rc)
258 up(&event_semaphore); /* signal event thread that new event is posted */
259
260 return rc;
261}
262
263
264/*
265 * sort_by_size
266 *
267 * Sorts nodes on the list by their length.
268 * Smallest first.
269 *
270 */
271static int sort_by_size(struct pci_resource **head)
272{
273 struct pci_resource *current_res;
274 struct pci_resource *next_res;
275 int out_of_order = 1;
276
277 if (!(*head))
278 return(1);
279
280 if (!((*head)->next))
281 return(0);
282
283 while (out_of_order) {
284 out_of_order = 0;
285
286 /* Special case for swapping list head */
287 if (((*head)->next) &&
288 ((*head)->length > (*head)->next->length)) {
289 out_of_order++;
290 current_res = *head;
291 *head = (*head)->next;
292 current_res->next = (*head)->next;
293 (*head)->next = current_res;
294 }
295
296 current_res = *head;
297
298 while (current_res->next && current_res->next->next) {
299 if (current_res->next->length > current_res->next->next->length) {
300 out_of_order++;
301 next_res = current_res->next;
302 current_res->next = current_res->next->next;
303 current_res = current_res->next;
304 next_res->next = current_res->next;
305 current_res->next = next_res;
306 } else
307 current_res = current_res->next;
308 }
309 } /* End of out_of_order loop */
310
311 return(0);
312}
313
314
315/*
316 * sort_by_max_size
317 *
318 * Sorts nodes on the list by their length.
319 * Largest first.
320 *
321 */
322static int sort_by_max_size(struct pci_resource **head)
323{
324 struct pci_resource *current_res;
325 struct pci_resource *next_res;
326 int out_of_order = 1;
327
328 if (!(*head))
329 return(1);
330
331 if (!((*head)->next))
332 return(0);
333
334 while (out_of_order) {
335 out_of_order = 0;
336
337 /* Special case for swapping list head */
338 if (((*head)->next) &&
339 ((*head)->length < (*head)->next->length)) {
340 out_of_order++;
341 current_res = *head;
342 *head = (*head)->next;
343 current_res->next = (*head)->next;
344 (*head)->next = current_res;
345 }
346
347 current_res = *head;
348
349 while (current_res->next && current_res->next->next) {
350 if (current_res->next->length < current_res->next->next->length) {
351 out_of_order++;
352 next_res = current_res->next;
353 current_res->next = current_res->next->next;
354 current_res = current_res->next;
355 next_res->next = current_res->next;
356 current_res->next = next_res;
357 } else
358 current_res = current_res->next;
359 }
360 } /* End of out_of_order loop */
361
362 return(0);
363}
364
365
366/*
367 * do_pre_bridge_resource_split
368 *
369 * Returns zero or one node of resources that aren't in use
370 *
371 */
372static struct pci_resource *do_pre_bridge_resource_split (struct pci_resource **head, struct pci_resource **orig_head, u32 alignment)
373{
374 struct pci_resource *prevnode = NULL;
375 struct pci_resource *node;
376 struct pci_resource *split_node;
377 u32 rc;
378 u32 temp_dword;
379 dbg("do_pre_bridge_resource_split\n");
380
381 if (!(*head) || !(*orig_head))
382 return(NULL);
383
384 rc = shpchp_resource_sort_and_combine(head);
385
386 if (rc)
387 return(NULL);
388
389 if ((*head)->base != (*orig_head)->base)
390 return(NULL);
391
392 if ((*head)->length == (*orig_head)->length)
393 return(NULL);
394
395
396 /* If we got here, there the bridge requires some of the resource, but
397 * we may be able to split some off of the front
398 */
399 node = *head;
400
401 if (node->length & (alignment -1)) {
402 /* This one isn't an aligned length, so we'll make a new entry
403 * and split it up.
404 */
405 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
406
407 if (!split_node)
408 return(NULL);
409
410 temp_dword = (node->length | (alignment-1)) + 1 - alignment;
411
412 split_node->base = node->base;
413 split_node->length = temp_dword;
414
415 node->length -= temp_dword;
416 node->base += split_node->length;
417
418 /* Put it in the list */
419 *head = split_node;
420 split_node->next = node;
421 }
422
423 if (node->length < alignment) {
424 return(NULL);
425 }
426
427 /* Now unlink it */
428 if (*head == node) {
429 *head = node->next;
430 node->next = NULL;
431 } else {
432 prevnode = *head;
433 while (prevnode->next != node)
434 prevnode = prevnode->next;
435
436 prevnode->next = node->next;
437 node->next = NULL;
438 }
439
440 return(node);
441}
442
443
444/*
445 * do_bridge_resource_split
446 *
447 * Returns zero or one node of resources that aren't in use
448 *
449 */
450static struct pci_resource *do_bridge_resource_split (struct pci_resource **head, u32 alignment)
451{
452 struct pci_resource *prevnode = NULL;
453 struct pci_resource *node;
454 u32 rc;
455 u32 temp_dword;
456
457 if (!(*head))
458 return(NULL);
459
460 rc = shpchp_resource_sort_and_combine(head);
461
462 if (rc)
463 return(NULL);
464
465 node = *head;
466
467 while (node->next) {
468 prevnode = node;
469 node = node->next;
470 kfree(prevnode);
471 }
472
473 if (node->length < alignment) {
474 kfree(node);
475 return(NULL);
476 }
477
478 if (node->base & (alignment - 1)) {
479 /* Short circuit if adjusted size is too small */
480 temp_dword = (node->base | (alignment-1)) + 1;
481 if ((node->length - (temp_dword - node->base)) < alignment) {
482 kfree(node);
483 return(NULL);
484 }
485
486 node->length -= (temp_dword - node->base);
487 node->base = temp_dword;
488 }
489
490 if (node->length & (alignment - 1)) {
491 /* There's stuff in use after this node */
492 kfree(node);
493 return(NULL);
494 }
495
496 return(node);
497}
498
499
500/*
501 * get_io_resource
502 *
503 * this function sorts the resource list by size and then
504 * returns the first node of "size" length that is not in the
505 * ISA aliasing window. If it finds a node larger than "size"
506 * it will split it up.
507 *
508 * size must be a power of two.
509 */
510static struct pci_resource *get_io_resource (struct pci_resource **head, u32 size)
511{
512 struct pci_resource *prevnode;
513 struct pci_resource *node;
514 struct pci_resource *split_node = NULL;
515 u32 temp_dword;
516
517 if (!(*head))
518 return(NULL);
519
520 if ( shpchp_resource_sort_and_combine(head) )
521 return(NULL);
522
523 if ( sort_by_size(head) )
524 return(NULL);
525
526 for (node = *head; node; node = node->next) {
527 if (node->length < size)
528 continue;
529
530 if (node->base & (size - 1)) {
531 /* This one isn't base aligned properly
532 so we'll make a new entry and split it up */
533 temp_dword = (node->base | (size-1)) + 1;
534
535 /*/ Short circuit if adjusted size is too small */
536 if ((node->length - (temp_dword - node->base)) < size)
537 continue;
538
539 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
540
541 if (!split_node)
542 return(NULL);
543
544 split_node->base = node->base;
545 split_node->length = temp_dword - node->base;
546 node->base = temp_dword;
547 node->length -= split_node->length;
548
549 /* Put it in the list */
550 split_node->next = node->next;
551 node->next = split_node;
552 } /* End of non-aligned base */
553
554 /* Don't need to check if too small since we already did */
555 if (node->length > size) {
556 /* This one is longer than we need
557 so we'll make a new entry and split it up */
558 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
559
560 if (!split_node)
561 return(NULL);
562
563 split_node->base = node->base + size;
564 split_node->length = node->length - size;
565 node->length = size;
566
567 /* Put it in the list */
568 split_node->next = node->next;
569 node->next = split_node;
570 } /* End of too big on top end */
571
572 /* For IO make sure it's not in the ISA aliasing space */
573 if (node->base & 0x300L)
574 continue;
575
576 /* If we got here, then it is the right size
577 Now take it out of the list */
578 if (*head == node) {
579 *head = node->next;
580 } else {
581 prevnode = *head;
582 while (prevnode->next != node)
583 prevnode = prevnode->next;
584
585 prevnode->next = node->next;
586 }
587 node->next = NULL;
588 /* Stop looping */
589 break;
590 }
591
592 return(node);
593}
594
595
596/*
597 * get_max_resource
598 *
599 * Gets the largest node that is at least "size" big from the
600 * list pointed to by head. It aligns the node on top and bottom
601 * to "size" alignment before returning it.
602 * J.I. modified to put max size limits of; 64M->32M->16M->8M->4M->1M
603 * This is needed to avoid allocating entire ACPI _CRS res to one child bridge/slot.
604 */
605static struct pci_resource *get_max_resource (struct pci_resource **head, u32 size)
606{
607 struct pci_resource *max;
608 struct pci_resource *temp;
609 struct pci_resource *split_node;
610 u32 temp_dword;
611 u32 max_size[] = { 0x4000000, 0x2000000, 0x1000000, 0x0800000, 0x0400000, 0x0200000, 0x0100000, 0x00 };
612 int i;
613
614 if (!(*head))
615 return(NULL);
616
617 if (shpchp_resource_sort_and_combine(head))
618 return(NULL);
619
620 if (sort_by_max_size(head))
621 return(NULL);
622
623 for (max = *head;max; max = max->next) {
624
625 /* If not big enough we could probably just bail,
626 instead we'll continue to the next. */
627 if (max->length < size)
628 continue;
629
630 if (max->base & (size - 1)) {
631 /* This one isn't base aligned properly
632 so we'll make a new entry and split it up */
633 temp_dword = (max->base | (size-1)) + 1;
634
635 /* Short circuit if adjusted size is too small */
636 if ((max->length - (temp_dword - max->base)) < size)
637 continue;
638
639 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
640
641 if (!split_node)
642 return(NULL);
643
644 split_node->base = max->base;
645 split_node->length = temp_dword - max->base;
646 max->base = temp_dword;
647 max->length -= split_node->length;
648
649 /* Put it next in the list */
650 split_node->next = max->next;
651 max->next = split_node;
652 }
653
654 if ((max->base + max->length) & (size - 1)) {
655 /* This one isn't end aligned properly at the top
656 so we'll make a new entry and split it up */
657 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
658
659 if (!split_node)
660 return(NULL);
661 temp_dword = ((max->base + max->length) & ~(size - 1));
662 split_node->base = temp_dword;
663 split_node->length = max->length + max->base
664 - split_node->base;
665 max->length -= split_node->length;
666
667 /* Put it in the list */
668 split_node->next = max->next;
669 max->next = split_node;
670 }
671
672 /* Make sure it didn't shrink too much when we aligned it */
673 if (max->length < size)
674 continue;
675
676 for ( i = 0; max_size[i] > size; i++) {
677 if (max->length > max_size[i]) {
678 split_node = kmalloc(sizeof(*split_node),
679 GFP_KERNEL);
680 if (!split_node)
681 break; /* return (NULL); */
682 split_node->base = max->base + max_size[i];
683 split_node->length = max->length - max_size[i];
684 max->length = max_size[i];
685 /* Put it next in the list */
686 split_node->next = max->next;
687 max->next = split_node;
688 break;
689 }
690 }
691
692 /* Now take it out of the list */
693 temp = (struct pci_resource*) *head;
694 if (temp == max) {
695 *head = max->next;
696 } else {
697 while (temp && temp->next != max) {
698 temp = temp->next;
699 }
700
701 temp->next = max->next;
702 }
703
704 max->next = NULL;
705 return(max);
706 }
707
708 /* If we get here, we couldn't find one */
709 return(NULL);
710}
711
712
713/*
714 * get_resource
715 *
716 * this function sorts the resource list by size and then
717 * returns the first node of "size" length. If it finds a node
718 * larger than "size" it will split it up.
719 *
720 * size must be a power of two.
721 */
722static struct pci_resource *get_resource (struct pci_resource **head, u32 size)
723{
724 struct pci_resource *prevnode;
725 struct pci_resource *node;
726 struct pci_resource *split_node;
727 u32 temp_dword;
728
729 if (!(*head))
730 return(NULL);
731
732 if ( shpchp_resource_sort_and_combine(head) )
733 return(NULL);
734
735 if ( sort_by_size(head) )
736 return(NULL);
737
738 for (node = *head; node; node = node->next) {
739 dbg("%s: req_size =0x%x node=%p, base=0x%x, length=0x%x\n",
740 __FUNCTION__, size, node, node->base, node->length);
741 if (node->length < size)
742 continue;
743
744 if (node->base & (size - 1)) {
745 dbg("%s: not aligned\n", __FUNCTION__);
746 /* this one isn't base aligned properly
747 so we'll make a new entry and split it up */
748 temp_dword = (node->base | (size-1)) + 1;
749
750 /* Short circuit if adjusted size is too small */
751 if ((node->length - (temp_dword - node->base)) < size)
752 continue;
753
754 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
755
756 if (!split_node)
757 return(NULL);
758
759 split_node->base = node->base;
760 split_node->length = temp_dword - node->base;
761 node->base = temp_dword;
762 node->length -= split_node->length;
763
764 /* Put it in the list */
765 split_node->next = node->next;
766 node->next = split_node;
767 } /* End of non-aligned base */
768
769 /* Don't need to check if too small since we already did */
770 if (node->length > size) {
771 dbg("%s: too big\n", __FUNCTION__);
772 /* this one is longer than we need
773 so we'll make a new entry and split it up */
774 split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
775
776 if (!split_node)
777 return(NULL);
778
779 split_node->base = node->base + size;
780 split_node->length = node->length - size;
781 node->length = size;
782
783 /* Put it in the list */
784 split_node->next = node->next;
785 node->next = split_node;
786 } /* End of too big on top end */
787
788 dbg("%s: got one!!!\n", __FUNCTION__);
789 /* If we got here, then it is the right size
790 Now take it out of the list */
791 if (*head == node) {
792 *head = node->next;
793 } else {
794 prevnode = *head;
795 while (prevnode->next != node)
796 prevnode = prevnode->next;
797
798 prevnode->next = node->next;
799 }
800 node->next = NULL;
801 /* Stop looping */
802 break;
803 }
804 return(node);
805}
806
807
808/*
809 * shpchp_resource_sort_and_combine
810 *
811 * Sorts all of the nodes in the list in ascending order by
812 * their base addresses. Also does garbage collection by
813 * combining adjacent nodes.
814 *
815 * returns 0 if success
816 */
817int shpchp_resource_sort_and_combine(struct pci_resource **head)
818{
819 struct pci_resource *node1;
820 struct pci_resource *node2;
821 int out_of_order = 1;
822
823 dbg("%s: head = %p, *head = %p\n", __FUNCTION__, head, *head);
824
825 if (!(*head))
826 return(1);
827
828 dbg("*head->next = %p\n",(*head)->next);
829
830 if (!(*head)->next)
831 return(0); /* only one item on the list, already sorted! */
832
833 dbg("*head->base = 0x%x\n",(*head)->base);
834 dbg("*head->next->base = 0x%x\n",(*head)->next->base);
835 while (out_of_order) {
836 out_of_order = 0;
837
838 /* Special case for swapping list head */
839 if (((*head)->next) &&
840 ((*head)->base > (*head)->next->base)) {
841 node1 = *head;
842 (*head) = (*head)->next;
843 node1->next = (*head)->next;
844 (*head)->next = node1;
845 out_of_order++;
846 }
847
848 node1 = (*head);
849
850 while (node1->next && node1->next->next) {
851 if (node1->next->base > node1->next->next->base) {
852 out_of_order++;
853 node2 = node1->next;
854 node1->next = node1->next->next;
855 node1 = node1->next;
856 node2->next = node1->next;
857 node1->next = node2;
858 } else
859 node1 = node1->next;
860 }
861 } /* End of out_of_order loop */
862
863 node1 = *head;
864
865 while (node1 && node1->next) {
866 if ((node1->base + node1->length) == node1->next->base) {
867 /* Combine */
868 dbg("8..\n");
869 node1->length += node1->next->length;
870 node2 = node1->next;
871 node1->next = node1->next->next;
872 kfree(node2);
873 } else
874 node1 = node1->next;
875 }
876
877 return(0);
878}
879
880
881/**
882 * shpchp_slot_create - Creates a node and adds it to the proper bus.
883 * @busnumber - bus where new node is to be located
884 *
885 * Returns pointer to the new node or NULL if unsuccessful
886 */
887struct pci_func *shpchp_slot_create(u8 busnumber)
888{
889 struct pci_func *new_slot;
890 struct pci_func *next;
891
892 new_slot = kmalloc(sizeof(*new_slot), GFP_KERNEL);
893
894 if (new_slot == NULL) {
895 return(new_slot);
896 }
897
898 memset(new_slot, 0, sizeof(struct pci_func));
899
900 new_slot->next = NULL;
901 new_slot->configured = 1;
902
903 if (shpchp_slot_list[busnumber] == NULL) {
904 shpchp_slot_list[busnumber] = new_slot;
905 } else {
906 next = shpchp_slot_list[busnumber];
907 while (next->next != NULL)
908 next = next->next;
909 next->next = new_slot;
910 }
911 return(new_slot);
912}
913
914
915/*
916 * slot_remove - Removes a node from the linked list of slots.
917 * @old_slot: slot to remove
918 *
919 * Returns 0 if successful, !0 otherwise.
920 */
921static int slot_remove(struct pci_func * old_slot)
922{
923 struct pci_func *next;
924
925 if (old_slot == NULL)
926 return(1);
927
928 next = shpchp_slot_list[old_slot->bus];
929
930 if (next == NULL) {
931 return(1);
932 }
933
934 if (next == old_slot) {
935 shpchp_slot_list[old_slot->bus] = old_slot->next;
936 shpchp_destroy_board_resources(old_slot);
937 kfree(old_slot);
938 return(0);
939 }
940
941 while ((next->next != old_slot) && (next->next != NULL)) {
942 next = next->next;
943 }
944
945 if (next->next == old_slot) {
946 next->next = old_slot->next;
947 shpchp_destroy_board_resources(old_slot);
948 kfree(old_slot);
949 return(0);
950 } else
951 return(2);
952}
953
954
955/**
956 * bridge_slot_remove - Removes a node from the linked list of slots.
957 * @bridge: bridge to remove
958 *
959 * Returns 0 if successful, !0 otherwise.
960 */
961static int bridge_slot_remove(struct pci_func *bridge)
962{
963 u8 subordinateBus, secondaryBus;
964 u8 tempBus;
965 struct pci_func *next;
966
967 if (bridge == NULL)
968 return(1);
969
970 secondaryBus = (bridge->config_space[0x06] >> 8) & 0xFF;
971 subordinateBus = (bridge->config_space[0x06] >> 16) & 0xFF;
972
973 for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {
974 next = shpchp_slot_list[tempBus];
975
976 while (!slot_remove(next)) {
977 next = shpchp_slot_list[tempBus];
978 }
979 }
980
981 next = shpchp_slot_list[bridge->bus];
982
983 if (next == NULL) {
984 return(1);
985 }
986
987 if (next == bridge) {
988 shpchp_slot_list[bridge->bus] = bridge->next;
989 kfree(bridge);
990 return(0);
991 }
992
993 while ((next->next != bridge) && (next->next != NULL)) {
994 next = next->next;
995 }
996
997 if (next->next == bridge) {
998 next->next = bridge->next;
999 kfree(bridge);
1000 return(0);
1001 } else
1002 return(2);
1003}
1004
1005
1006/**
1007 * shpchp_slot_find - Looks for a node by bus, and device, multiple functions accessed
1008 * @bus: bus to find
1009 * @device: device to find
1010 * @index: is 0 for first function found, 1 for the second...
1011 *
1012 * Returns pointer to the node if successful, %NULL otherwise.
1013 */
1014struct pci_func *shpchp_slot_find(u8 bus, u8 device, u8 index)
1015{
1016 int found = -1;
1017 struct pci_func *func;
1018
1019 func = shpchp_slot_list[bus];
1020
1021 if ((func == NULL) || ((func->device == device) && (index == 0)))
1022 return(func);
1023
1024 if (func->device == device)
1025 found++;
1026
1027 while (func->next != NULL) {
1028 func = func->next;
1029
1030 if (func->device == device)
1031 found++;
1032
1033 if (found == index)
1034 return(func);
1035 }
1036
1037 return(NULL);
1038}
1039
1040static int is_bridge(struct pci_func * func)
1041{
1042 /* Check the header type */
1043 if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01)
1044 return 1;
1045 else
1046 return 0;
1047}
1048
1049
1050/* The following routines constitute the bulk of the
1051 hotplug controller logic
1052 */
1053static u32 change_bus_speed(struct controller *ctrl, struct slot *p_slot, enum pci_bus_speed speed)
1054{
1055 u32 rc = 0;
1056
1057 dbg("%s: change to speed %d\n", __FUNCTION__, speed);
1058 down(&ctrl->crit_sect);
1059 if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, speed))) {
1060 err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
1061 up(&ctrl->crit_sect);
1062 return WRONG_BUS_FREQUENCY;
1063 }
1064 wait_for_ctrl_irq (ctrl);
1065
1066 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
1067 err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
1068 __FUNCTION__);
1069 err("%s: Error code (%d)\n", __FUNCTION__, rc);
1070 up(&ctrl->crit_sect);
1071 return WRONG_BUS_FREQUENCY;
1072 }
1073 up(&ctrl->crit_sect);
1074 return rc;
1075}
1076
1077static u32 fix_bus_speed(struct controller *ctrl, struct slot *pslot, u8 flag,
1078enum pci_bus_speed asp, enum pci_bus_speed bsp, enum pci_bus_speed msp)
1079{
1080 u32 rc = 0;
1081
1082 if (flag != 0) { /* Other slots on the same bus are occupied */
1083 if ( asp < bsp ) {
1084 err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bsp, asp);
1085 return WRONG_BUS_FREQUENCY;
1086 }
1087 } else {
1088 /* Other slots on the same bus are empty */
1089 if (msp == bsp) {
1090 /* if adapter_speed >= bus_speed, do nothing */
1091 if (asp < bsp) {
1092 /*
1093 * Try to lower bus speed to accommodate the adapter if other slots
1094 * on the same controller are empty
1095 */
1096 if ((rc = change_bus_speed(ctrl, pslot, asp)))
1097 return rc;
1098 }
1099 } else {
1100 if (asp < msp) {
1101 if ((rc = change_bus_speed(ctrl, pslot, asp)))
1102 return rc;
1103 } else {
1104 if ((rc = change_bus_speed(ctrl, pslot, msp)))
1105 return rc;
1106 }
1107 }
1108 }
1109 return rc;
1110}
1111
1112/**
1113 * board_added - Called after a board has been added to the system.
1114 *
1115 * Turns power on for the board
1116 * Configures board
1117 *
1118 */
1119static u32 board_added(struct pci_func * func, struct controller * ctrl)
1120{
1121 u8 hp_slot;
1122 u8 slots_not_empty = 0;
1123 int index;
1124 u32 temp_register = 0xFFFFFFFF;
1125 u32 retval, rc = 0;
1126 struct pci_func *new_func = NULL;
1127 struct slot *p_slot;
1128 struct resource_lists res_lists;
1129 enum pci_bus_speed adapter_speed, bus_speed, max_bus_speed;
1130 u8 pi, mode;
1131
1132 p_slot = shpchp_find_slot(ctrl, func->device);
1133 hp_slot = func->device - ctrl->slot_device_offset;
1134
1135 dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n", __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
1136
1137 /* Wait for exclusive access to hardware */
1138 down(&ctrl->crit_sect);
1139
1140 /* Power on slot without connecting to bus */
1141 rc = p_slot->hpc_ops->power_on_slot(p_slot);
1142 if (rc) {
1143 err("%s: Failed to power on slot\n", __FUNCTION__);
1144 /* Done with exclusive hardware access */
1145 up(&ctrl->crit_sect);
1146 return -1;
1147 }
1148
1149 /* Wait for the command to complete */
1150 wait_for_ctrl_irq (ctrl);
1151
1152 rc = p_slot->hpc_ops->check_cmd_status(ctrl);
1153 if (rc) {
1154 err("%s: Failed to power on slot, error code(%d)\n", __FUNCTION__, rc);
1155 /* Done with exclusive hardware access */
1156 up(&ctrl->crit_sect);
1157 return -1;
1158 }
1159
1160
1161 if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) {
1162 if (slots_not_empty)
1163 return WRONG_BUS_FREQUENCY;
1164
1165 if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) {
1166 err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
1167 up(&ctrl->crit_sect);
1168 return WRONG_BUS_FREQUENCY;
1169 }
1170 wait_for_ctrl_irq (ctrl);
1171
1172 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
1173 err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
1174 __FUNCTION__);
1175 err("%s: Error code (%d)\n", __FUNCTION__, rc);
1176 up(&ctrl->crit_sect);
1177 return WRONG_BUS_FREQUENCY;
1178 }
1179 /* turn on board, blink green LED, turn off Amber LED */
1180 if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
1181 err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
1182 up(&ctrl->crit_sect);
1183 return rc;
1184 }
1185 wait_for_ctrl_irq (ctrl);
1186
1187 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
1188 err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
1189 up(&ctrl->crit_sect);
1190 return rc;
1191 }
1192 }
1193
1194 rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &adapter_speed);
1195 /* 0 = PCI 33Mhz, 1 = PCI 66 Mhz, 2 = PCI-X 66 PA, 4 = PCI-X 66 ECC, */
1196 /* 5 = PCI-X 133 PA, 7 = PCI-X 133 ECC, 0xa = PCI-X 133 Mhz 266, */
1197 /* 0xd = PCI-X 133 Mhz 533 */
1198 /* This encoding is different from the one used in cur_bus_speed & */
1199 /* max_bus_speed */
1200
1201 if (rc || adapter_speed == PCI_SPEED_UNKNOWN) {
1202 err("%s: Can't get adapter speed or bus mode mismatch\n", __FUNCTION__);
1203 /* Done with exclusive hardware access */
1204 up(&ctrl->crit_sect);
1205 return WRONG_BUS_FREQUENCY;
1206 }
1207
1208 rc = p_slot->hpc_ops->get_cur_bus_speed(p_slot, &bus_speed);
1209 if (rc || bus_speed == PCI_SPEED_UNKNOWN) {
1210 err("%s: Can't get bus operation speed\n", __FUNCTION__);
1211 /* Done with exclusive hardware access */
1212 up(&ctrl->crit_sect);
1213 return WRONG_BUS_FREQUENCY;
1214 }
1215
1216 rc = p_slot->hpc_ops->get_max_bus_speed(p_slot, &max_bus_speed);
1217 if (rc || max_bus_speed == PCI_SPEED_UNKNOWN) {
1218 err("%s: Can't get max bus operation speed\n", __FUNCTION__);
1219 max_bus_speed = bus_speed;
1220 }
1221
1222 /* Done with exclusive hardware access */
1223 up(&ctrl->crit_sect);
1224
1225 if ((rc = p_slot->hpc_ops->get_prog_int(p_slot, &pi))) {
1226 err("%s: Can't get controller programming interface, set it to 1\n", __FUNCTION__);
1227 pi = 1;
1228 }
1229
1230 /* Check if there are other slots or devices on the same bus */
1231 if (!list_empty(&ctrl->pci_dev->subordinate->devices))
1232 slots_not_empty = 1;
1233
1234 dbg("%s: slots_not_empty %d, pi %d\n", __FUNCTION__,
1235 slots_not_empty, pi);
1236 dbg("adapter_speed %d, bus_speed %d, max_bus_speed %d\n",
1237 adapter_speed, bus_speed, max_bus_speed);
1238
1239 if (pi == 2) {
1240 dbg("%s: In PI = %d\n", __FUNCTION__, pi);
1241 if ((rc = p_slot->hpc_ops->get_mode1_ECC_cap(p_slot, &mode))) {
1242 err("%s: Can't get Mode1_ECC, set mode to 0\n", __FUNCTION__);
1243 mode = 0;
1244 }
1245
1246 switch (adapter_speed) {
1247 case PCI_SPEED_133MHz_PCIX_533:
1248 case PCI_SPEED_133MHz_PCIX_266:
1249 if ((bus_speed != adapter_speed) &&
1250 ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
1251 return rc;
1252 break;
1253 case PCI_SPEED_133MHz_PCIX_ECC:
1254 case PCI_SPEED_133MHz_PCIX:
1255 if (mode) { /* Bus - Mode 1 ECC */
1256 if ((bus_speed != 0x7) &&
1257 ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
1258 return rc;
1259 } else {
1260 if ((bus_speed != 0x4) &&
1261 ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
1262 return rc;
1263 }
1264 break;
1265 case PCI_SPEED_66MHz_PCIX_ECC:
1266 case PCI_SPEED_66MHz_PCIX:
1267 if (mode) { /* Bus - Mode 1 ECC */
1268 if ((bus_speed != 0x5) &&
1269 ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
1270 return rc;
1271 } else {
1272 if ((bus_speed != 0x2) &&
1273 ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
1274 return rc;
1275 }
1276 break;
1277 case PCI_SPEED_66MHz:
1278 if ((bus_speed != 0x1) &&
1279 ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
1280 return rc;
1281 break;
1282 case PCI_SPEED_33MHz:
1283 if (bus_speed > 0x0) {
1284 if (slots_not_empty == 0) {
1285 if ((rc = change_bus_speed(ctrl, p_slot, adapter_speed)))
1286 return rc;
1287 } else {
1288 err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
1289 return WRONG_BUS_FREQUENCY;
1290 }
1291 }
1292 break;
1293 default:
1294 err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
1295 return WRONG_BUS_FREQUENCY;
1296 }
1297 } else {
1298 /* If adpater_speed == bus_speed, nothing to do here */
1299 dbg("%s: In PI = %d\n", __FUNCTION__, pi);
1300 if ((adapter_speed != bus_speed) &&
1301 ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
1302 return rc;
1303 }
1304
1305 down(&ctrl->crit_sect);
1306 /* turn on board, blink green LED, turn off Amber LED */
1307 if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
1308 err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
1309 up(&ctrl->crit_sect);
1310 return rc;
1311 }
1312 wait_for_ctrl_irq (ctrl);
1313
1314 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
1315 err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
1316 up(&ctrl->crit_sect);
1317 return rc;
1318 }
1319
1320 up(&ctrl->crit_sect);
1321
1322 /* Wait for ~1 second */
1323 dbg("%s: before long_delay\n", __FUNCTION__);
1324 wait_for_ctrl_irq (ctrl);
1325 dbg("%s: after long_delay\n", __FUNCTION__);
1326
1327 dbg("%s: func status = %x\n", __FUNCTION__, func->status);
1328 /* Check for a power fault */
1329 if (func->status == 0xFF) {
1330 /* power fault occurred, but it was benign */
1331 temp_register = 0xFFFFFFFF;
1332 dbg("%s: temp register set to %x by power fault\n", __FUNCTION__, temp_register);
1333 rc = POWER_FAILURE;
1334 func->status = 0;
1335 } else {
1336 /* Get vendor/device ID u32 */
1337 rc = pci_bus_read_config_dword (ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function),
1338 PCI_VENDOR_ID, &temp_register);
1339 dbg("%s: pci_bus_read_config_dword returns %d\n", __FUNCTION__, rc);
1340 dbg("%s: temp_register is %x\n", __FUNCTION__, temp_register);
1341
1342 if (rc != 0) {
1343 /* Something's wrong here */
1344 temp_register = 0xFFFFFFFF;
1345 dbg("%s: temp register set to %x by error\n", __FUNCTION__, temp_register);
1346 }
1347 /* Preset return code. It will be changed later if things go okay. */
1348 rc = NO_ADAPTER_PRESENT;
1349 }
1350
1351 /* All F's is an empty slot or an invalid board */
1352 if (temp_register != 0xFFFFFFFF) { /* Check for a board in the slot */
1353 res_lists.io_head = ctrl->io_head;
1354 res_lists.mem_head = ctrl->mem_head;
1355 res_lists.p_mem_head = ctrl->p_mem_head;
1356 res_lists.bus_head = ctrl->bus_head;
1357 res_lists.irqs = NULL;
1358
1359 rc = configure_new_device(ctrl, func, 0, &res_lists, 0, 0);
1360 dbg("%s: back from configure_new_device\n", __FUNCTION__);
1361
1362 ctrl->io_head = res_lists.io_head;
1363 ctrl->mem_head = res_lists.mem_head;
1364 ctrl->p_mem_head = res_lists.p_mem_head;
1365 ctrl->bus_head = res_lists.bus_head;
1366
1367 shpchp_resource_sort_and_combine(&(ctrl->mem_head));
1368 shpchp_resource_sort_and_combine(&(ctrl->p_mem_head));
1369 shpchp_resource_sort_and_combine(&(ctrl->io_head));
1370 shpchp_resource_sort_and_combine(&(ctrl->bus_head));
1371
1372 if (rc) {
1373 /* Wait for exclusive access to hardware */
1374 down(&ctrl->crit_sect);
1375
1376 /* turn off slot, turn on Amber LED, turn off Green LED */
1377 retval = p_slot->hpc_ops->slot_disable(p_slot);
1378 if (retval) {
1379 err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
1380 /* Done with exclusive hardware access */
1381 up(&ctrl->crit_sect);
1382 return retval;
1383 }
1384 /* Wait for the command to complete */
1385 wait_for_ctrl_irq (ctrl);
1386
1387 retval = p_slot->hpc_ops->check_cmd_status(ctrl);
1388 if (retval) {
1389 err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, retval);
1390 /* Done with exclusive hardware access */
1391 up(&ctrl->crit_sect);
1392 return retval;
1393 }
1394
1395 /* Done with exclusive hardware access */
1396 up(&ctrl->crit_sect);
1397
1398 return(rc);
1399 }
1400 shpchp_save_slot_config(ctrl, func);
1401
1402 func->status = 0;
1403 func->switch_save = 0x10;
1404 func->is_a_board = 0x01;
1405 func->pwr_save = 1;
1406
1407 /* Next, we will instantiate the linux pci_dev structures
1408 * (with appropriate driver notification, if already present)
1409 */
1410 index = 0;
1411 do {
1412 new_func = shpchp_slot_find(ctrl->slot_bus, func->device, index++);
1413 if (new_func && !new_func->pci_dev) {
1414 dbg("%s:call pci_hp_configure_dev\n", __FUNCTION__);
1415 shpchp_configure_device(ctrl, new_func);
1416 }
1417 } while (new_func);
1418
1419 /* Wait for exclusive access to hardware */
1420 down(&ctrl->crit_sect);
1421
1422 p_slot->hpc_ops->green_led_on(p_slot);
1423
1424 /* Wait for the command to complete */
1425 wait_for_ctrl_irq (ctrl);
1426
1427
1428 /* Done with exclusive hardware access */
1429 up(&ctrl->crit_sect);
1430
1431 } else {
1432 /* Wait for exclusive access to hardware */
1433 down(&ctrl->crit_sect);
1434
1435 /* turn off slot, turn on Amber LED, turn off Green LED */
1436 rc = p_slot->hpc_ops->slot_disable(p_slot);
1437 if (rc) {
1438 err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
1439 /* Done with exclusive hardware access */
1440 up(&ctrl->crit_sect);
1441 return rc;
1442 }
1443 /* Wait for the command to complete */
1444 wait_for_ctrl_irq (ctrl);
1445
1446 rc = p_slot->hpc_ops->check_cmd_status(ctrl);
1447 if (rc) {
1448 err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc);
1449 /* Done with exclusive hardware access */
1450 up(&ctrl->crit_sect);
1451 return rc;
1452 }
1453
1454 /* Done with exclusive hardware access */
1455 up(&ctrl->crit_sect);
1456
1457 return(rc);
1458 }
1459 return 0;
1460}
1461
1462
1463/**
1464 * remove_board - Turns off slot and LED's
1465 *
1466 */
1467static u32 remove_board(struct pci_func *func, struct controller *ctrl)
1468{
1469 int index;
1470 u8 skip = 0;
1471 u8 device;
1472 u8 hp_slot;
1473 u32 rc;
1474 struct resource_lists res_lists;
1475 struct pci_func *temp_func;
1476 struct slot *p_slot;
1477
1478 if (func == NULL)
1479 return(1);
1480
1481 if (shpchp_unconfigure_device(func))
1482 return(1);
1483
1484 device = func->device;
1485
1486 hp_slot = func->device - ctrl->slot_device_offset;
1487 p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1488
1489 dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
1490
1491 if ((ctrl->add_support) &&
1492 !(func->bus_head || func->mem_head || func->p_mem_head || func->io_head)) {
1493 /* Here we check to see if we've saved any of the board's
1494 * resources already. If so, we'll skip the attempt to
1495 * determine what's being used.
1496 */
1497 index = 0;
1498
1499 temp_func = func;
1500
1501 while ((temp_func = shpchp_slot_find(temp_func->bus, temp_func->device, index++))) {
1502 if (temp_func->bus_head || temp_func->mem_head
1503 || temp_func->p_mem_head || temp_func->io_head) {
1504 skip = 1;
1505 break;
1506 }
1507 }
1508
1509 if (!skip)
1510 rc = shpchp_save_used_resources(ctrl, func, DISABLE_CARD);
1511 }
1512 /* Change status to shutdown */
1513 if (func->is_a_board)
1514 func->status = 0x01;
1515 func->configured = 0;
1516
1517 /* Wait for exclusive access to hardware */
1518 down(&ctrl->crit_sect);
1519
1520 /* turn off slot, turn on Amber LED, turn off Green LED */
1521 rc = p_slot->hpc_ops->slot_disable(p_slot);
1522 if (rc) {
1523 err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
1524 /* Done with exclusive hardware access */
1525 up(&ctrl->crit_sect);
1526 return rc;
1527 }
1528 /* Wait for the command to complete */
1529 wait_for_ctrl_irq (ctrl);
1530
1531 rc = p_slot->hpc_ops->check_cmd_status(ctrl);
1532 if (rc) {
1533 err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc);
1534 /* Done with exclusive hardware access */
1535 up(&ctrl->crit_sect);
1536 return rc;
1537 }
1538
1539 rc = p_slot->hpc_ops->set_attention_status(p_slot, 0);
1540 if (rc) {
1541 err("%s: Issue of Set Attention command failed\n", __FUNCTION__);
1542 /* Done with exclusive hardware access */
1543 up(&ctrl->crit_sect);
1544 return rc;
1545 }
1546 /* Wait for the command to complete */
1547 wait_for_ctrl_irq (ctrl);
1548
1549 /* Done with exclusive hardware access */
1550 up(&ctrl->crit_sect);
1551
1552 if (ctrl->add_support) {
1553 while (func) {
1554 res_lists.io_head = ctrl->io_head;
1555 res_lists.mem_head = ctrl->mem_head;
1556 res_lists.p_mem_head = ctrl->p_mem_head;
1557 res_lists.bus_head = ctrl->bus_head;
1558
1559 dbg("Returning resources to ctlr lists for (B/D/F) = (%#x/%#x/%#x)\n", func->bus,
1560 func->device, func->function);
1561
1562 shpchp_return_board_resources(func, &res_lists);
1563
1564 ctrl->io_head = res_lists.io_head;
1565 ctrl->mem_head = res_lists.mem_head;
1566 ctrl->p_mem_head = res_lists.p_mem_head;
1567 ctrl->bus_head = res_lists.bus_head;
1568
1569 shpchp_resource_sort_and_combine(&(ctrl->mem_head));
1570 shpchp_resource_sort_and_combine(&(ctrl->p_mem_head));
1571 shpchp_resource_sort_and_combine(&(ctrl->io_head));
1572 shpchp_resource_sort_and_combine(&(ctrl->bus_head));
1573
1574 if (is_bridge(func)) {
1575 dbg("PCI Bridge Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus,
1576 func->device, func->function);
1577 bridge_slot_remove(func);
1578 } else
1579 dbg("PCI Function Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus,
1580 func->device, func->function);
1581 slot_remove(func);
1582
1583 func = shpchp_slot_find(ctrl->slot_bus, device, 0);
1584 }
1585
1586 /* Setup slot structure with entry for empty slot */
1587 func = shpchp_slot_create(ctrl->slot_bus);
1588
1589 if (func == NULL) {
1590 return(1);
1591 }
1592
1593 func->bus = ctrl->slot_bus;
1594 func->device = device;
1595 func->function = 0;
1596 func->configured = 0;
1597 func->switch_save = 0x10;
1598 func->pwr_save = 0;
1599 func->is_a_board = 0;
1600 }
1601
1602 return 0;
1603}
1604
1605
1606static void pushbutton_helper_thread (unsigned long data)
1607{
1608 pushbutton_pending = data;
1609
1610 up(&event_semaphore);
1611}
1612
1613
1614/**
1615 * shpchp_pushbutton_thread
1616 *
1617 * Scheduled procedure to handle blocking stuff for the pushbuttons
1618 * Handles all pending events and exits.
1619 *
1620 */
1621static void shpchp_pushbutton_thread (unsigned long slot)
1622{
1623 struct slot *p_slot = (struct slot *) slot;
1624 u8 getstatus;
1625
1626 pushbutton_pending = 0;
1627
1628 if (!p_slot) {
1629 dbg("%s: Error! slot NULL\n", __FUNCTION__);
1630 return;
1631 }
1632
1633 p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
1634 if (getstatus) {
1635 p_slot->state = POWEROFF_STATE;
1636 dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
1637
1638 shpchp_disable_slot(p_slot);
1639 p_slot->state = STATIC_STATE;
1640 } else {
1641 p_slot->state = POWERON_STATE;
1642 dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
1643
1644 if (shpchp_enable_slot(p_slot)) {
1645 /* Wait for exclusive access to hardware */
1646 down(&p_slot->ctrl->crit_sect);
1647
1648 p_slot->hpc_ops->green_led_off(p_slot);
1649
1650 /* Wait for the command to complete */
1651 wait_for_ctrl_irq (p_slot->ctrl);
1652
1653 /* Done with exclusive hardware access */
1654 up(&p_slot->ctrl->crit_sect);
1655 }
1656 p_slot->state = STATIC_STATE;
1657 }
1658
1659 return;
1660}
1661
1662
1663/* this is the main worker thread */
1664static int event_thread(void* data)
1665{
1666 struct controller *ctrl;
1667 lock_kernel();
1668 daemonize("shpchpd_event");
1669 unlock_kernel();
1670
1671 while (1) {
1672 dbg("!!!!event_thread sleeping\n");
1673 down_interruptible (&event_semaphore);
1674 dbg("event_thread woken finished = %d\n", event_finished);
1675 if (event_finished || signal_pending(current))
1676 break;
1677 /* Do stuff here */
1678 if (pushbutton_pending)
1679 shpchp_pushbutton_thread(pushbutton_pending);
1680 else
1681 for (ctrl = shpchp_ctrl_list; ctrl; ctrl=ctrl->next)
1682 interrupt_event_handler(ctrl);
1683 }
1684 dbg("event_thread signals exit\n");
1685 up(&event_exit);
1686 return 0;
1687}
1688
1689int shpchp_event_start_thread (void)
1690{
1691 int pid;
1692
1693 /* initialize our semaphores */
1694 init_MUTEX_LOCKED(&event_exit);
1695 event_finished=0;
1696
1697 init_MUTEX_LOCKED(&event_semaphore);
1698 pid = kernel_thread(event_thread, NULL, 0);
1699
1700 if (pid < 0) {
1701 err ("Can't start up our event thread\n");
1702 return -1;
1703 }
1704 dbg("Our event thread pid = %d\n", pid);
1705 return 0;
1706}
1707
1708
1709void shpchp_event_stop_thread (void)
1710{
1711 event_finished = 1;
1712 dbg("event_thread finish command given\n");
1713 up(&event_semaphore);
1714 dbg("wait for event_thread to exit\n");
1715 down(&event_exit);
1716}
1717
1718
1719static int update_slot_info (struct slot *slot)
1720{
1721 struct hotplug_slot_info *info;
1722 int result;
1723
1724 info = kmalloc(sizeof(*info), GFP_KERNEL);
1725 if (!info)
1726 return -ENOMEM;
1727
1728 slot->hpc_ops->get_power_status(slot, &(info->power_status));
1729 slot->hpc_ops->get_attention_status(slot, &(info->attention_status));
1730 slot->hpc_ops->get_latch_status(slot, &(info->latch_status));
1731 slot->hpc_ops->get_adapter_status(slot, &(info->adapter_status));
1732
1733 result = pci_hp_change_slot_info(slot->hotplug_slot, info);
1734 kfree (info);
1735 return result;
1736}
1737
1738static void interrupt_event_handler(struct controller *ctrl)
1739{
1740 int loop = 0;
1741 int change = 1;
1742 struct pci_func *func;
1743 u8 hp_slot;
1744 u8 getstatus;
1745 struct slot *p_slot;
1746
1747 dbg("%s:\n", __FUNCTION__);
1748 while (change) {
1749 change = 0;
1750
1751 for (loop = 0; loop < 10; loop++) {
1752 if (ctrl->event_queue[loop].event_type != 0) {
1753 dbg("%s:loop %x event_type %x\n", __FUNCTION__, loop,
1754 ctrl->event_queue[loop].event_type);
1755 hp_slot = ctrl->event_queue[loop].hp_slot;
1756
1757 func = shpchp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
1758
1759 p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1760
1761 dbg("%s: hp_slot %d, func %p, p_slot %p\n", __FUNCTION__, hp_slot, func, p_slot);
1762
1763 if (ctrl->event_queue[loop].event_type == INT_BUTTON_CANCEL) {
1764 dbg("%s: button cancel\n", __FUNCTION__);
1765 del_timer(&p_slot->task_event);
1766
1767 switch (p_slot->state) {
1768 case BLINKINGOFF_STATE:
1769 /* Wait for exclusive access to hardware */
1770 down(&ctrl->crit_sect);
1771
1772 p_slot->hpc_ops->green_led_on(p_slot);
1773 /* Wait for the command to complete */
1774 wait_for_ctrl_irq (ctrl);
1775
1776 p_slot->hpc_ops->set_attention_status(p_slot, 0);
1777
1778 /* Wait for the command to complete */
1779 wait_for_ctrl_irq (ctrl);
1780
1781 /* Done with exclusive hardware access */
1782 up(&ctrl->crit_sect);
1783 break;
1784 case BLINKINGON_STATE:
1785 /* Wait for exclusive access to hardware */
1786 down(&ctrl->crit_sect);
1787
1788 p_slot->hpc_ops->green_led_off(p_slot);
1789 /* Wait for the command to complete */
1790 wait_for_ctrl_irq (ctrl);
1791
1792 p_slot->hpc_ops->set_attention_status(p_slot, 0);
1793 /* Wait for the command to complete */
1794 wait_for_ctrl_irq (ctrl);
1795
1796 /* Done with exclusive hardware access */
1797 up(&ctrl->crit_sect);
1798
1799 break;
1800 default:
1801 warn("Not a valid state\n");
1802 return;
1803 }
1804 info(msg_button_cancel, p_slot->number);
1805 p_slot->state = STATIC_STATE;
1806 } else if (ctrl->event_queue[loop].event_type == INT_BUTTON_PRESS) {
1807 /* Button Pressed (No action on 1st press...) */
1808 dbg("%s: Button pressed\n", __FUNCTION__);
1809
1810 p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
1811 if (getstatus) {
1812 /* slot is on */
1813 dbg("%s: slot is on\n", __FUNCTION__);
1814 p_slot->state = BLINKINGOFF_STATE;
1815 info(msg_button_off, p_slot->number);
1816 } else {
1817 /* slot is off */
1818 dbg("%s: slot is off\n", __FUNCTION__);
1819 p_slot->state = BLINKINGON_STATE;
1820 info(msg_button_on, p_slot->number);
1821 }
1822
1823 /* Wait for exclusive access to hardware */
1824 down(&ctrl->crit_sect);
1825
1826 /* blink green LED and turn off amber */
1827 p_slot->hpc_ops->green_led_blink(p_slot);
1828 /* Wait for the command to complete */
1829 wait_for_ctrl_irq (ctrl);
1830
1831 p_slot->hpc_ops->set_attention_status(p_slot, 0);
1832
1833 /* Wait for the command to complete */
1834 wait_for_ctrl_irq (ctrl);
1835
1836 /* Done with exclusive hardware access */
1837 up(&ctrl->crit_sect);
1838
1839 init_timer(&p_slot->task_event);
1840 p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */
1841 p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
1842 p_slot->task_event.data = (unsigned long) p_slot;
1843
1844 dbg("%s: add_timer p_slot = %p\n", __FUNCTION__,(void *) p_slot);
1845 add_timer(&p_slot->task_event);
1846 } else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
1847 /***********POWER FAULT********************/
1848 dbg("%s: power fault\n", __FUNCTION__);
1849 /* Wait for exclusive access to hardware */
1850 down(&ctrl->crit_sect);
1851
1852 p_slot->hpc_ops->set_attention_status(p_slot, 1);
1853 /* Wait for the command to complete */
1854 wait_for_ctrl_irq (ctrl);
1855
1856 p_slot->hpc_ops->green_led_off(p_slot);
1857 /* Wait for the command to complete */
1858 wait_for_ctrl_irq (ctrl);
1859
1860 /* Done with exclusive hardware access */
1861 up(&ctrl->crit_sect);
1862 } else {
1863 /* refresh notification */
1864 if (p_slot)
1865 update_slot_info(p_slot);
1866 }
1867
1868 ctrl->event_queue[loop].event_type = 0;
1869
1870 change = 1;
1871 }
1872 } /* End of FOR loop */
1873 }
1874
1875 return;
1876}
1877
1878
1879int shpchp_enable_slot (struct slot *p_slot)
1880{
1881 u8 getstatus = 0;
1882 int rc;
1883 struct pci_func *func;
1884
1885 func = shpchp_slot_find(p_slot->bus, p_slot->device, 0);
1886 if (!func) {
1887 dbg("%s: Error! slot NULL\n", __FUNCTION__);
1888 return 1;
1889 }
1890
1891 /* Check to see if (latch closed, card present, power off) */
1892 down(&p_slot->ctrl->crit_sect);
1893 rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
1894 if (rc || !getstatus) {
1895 info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
1896 up(&p_slot->ctrl->crit_sect);
1897 return 1;
1898 }
1899 rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
1900 if (rc || getstatus) {
1901 info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
1902 up(&p_slot->ctrl->crit_sect);
1903 return 1;
1904 }
1905 rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
1906 if (rc || getstatus) {
1907 info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number);
1908 up(&p_slot->ctrl->crit_sect);
1909 return 1;
1910 }
1911 up(&p_slot->ctrl->crit_sect);
1912
1913 slot_remove(func);
1914
1915 func = shpchp_slot_create(p_slot->bus);
1916 if (func == NULL)
1917 return 1;
1918
1919 func->bus = p_slot->bus;
1920 func->device = p_slot->device;
1921 func->function = 0;
1922 func->configured = 0;
1923 func->is_a_board = 1;
1924
1925 /* We have to save the presence info for these slots */
1926 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
1927 p_slot->hpc_ops->get_power_status(p_slot, &(func->pwr_save));
1928 dbg("%s: func->pwr_save %x\n", __FUNCTION__, func->pwr_save);
1929 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
1930 func->switch_save = !getstatus? 0x10:0;
1931
1932 rc = board_added(func, p_slot->ctrl);
1933 if (rc) {
1934 if (is_bridge(func))
1935 bridge_slot_remove(func);
1936 else
1937 slot_remove(func);
1938
1939 /* Setup slot structure with entry for empty slot */
1940 func = shpchp_slot_create(p_slot->bus);
1941 if (func == NULL)
1942 return (1); /* Out of memory */
1943
1944 func->bus = p_slot->bus;
1945 func->device = p_slot->device;
1946 func->function = 0;
1947 func->configured = 0;
1948 func->is_a_board = 1;
1949
1950 /* We have to save the presence info for these slots */
1951 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
1952 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
1953 func->switch_save = !getstatus? 0x10:0;
1954 }
1955
1956 if (p_slot)
1957 update_slot_info(p_slot);
1958
1959 return rc;
1960}
1961
1962
1963int shpchp_disable_slot (struct slot *p_slot)
1964{
1965 u8 class_code, header_type, BCR;
1966 u8 index = 0;
1967 u8 getstatus = 0;
1968 u32 rc = 0;
1969 int ret = 0;
1970 unsigned int devfn;
1971 struct pci_bus *pci_bus;
1972 struct pci_func *func;
1973
1974 if (!p_slot->ctrl)
1975 return 1;
1976
1977 pci_bus = p_slot->ctrl->pci_dev->subordinate;
1978
1979 /* Check to see if (latch closed, card present, power on) */
1980 down(&p_slot->ctrl->crit_sect);
1981
1982 ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
1983 if (ret || !getstatus) {
1984 info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
1985 up(&p_slot->ctrl->crit_sect);
1986 return 1;
1987 }
1988 ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
1989 if (ret || getstatus) {
1990 info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
1991 up(&p_slot->ctrl->crit_sect);
1992 return 1;
1993 }
1994 ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
1995 if (ret || !getstatus) {
1996 info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number);
1997 up(&p_slot->ctrl->crit_sect);
1998 return 1;
1999 }
2000 up(&p_slot->ctrl->crit_sect);
2001
2002 func = shpchp_slot_find(p_slot->bus, p_slot->device, index++);
2003
2004 /* Make sure there are no video controllers here
2005 * for all func of p_slot
2006 */
2007 while (func && !rc) {
2008 pci_bus->number = func->bus;
2009 devfn = PCI_DEVFN(func->device, func->function);
2010
2011 /* Check the Class Code */
2012 rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
2013 if (rc)
2014 return rc;
2015
2016 if (class_code == PCI_BASE_CLASS_DISPLAY) {
2017 /* Display/Video adapter (not supported) */
2018 rc = REMOVE_NOT_SUPPORTED;
2019 } else {
2020 /* See if it's a bridge */
2021 rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
2022 if (rc)
2023 return rc;
2024
2025 /* If it's a bridge, check the VGA Enable bit */
2026 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
2027 rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
2028 if (rc)
2029 return rc;
2030
2031 /* If the VGA Enable bit is set, remove isn't supported */
2032 if (BCR & PCI_BRIDGE_CTL_VGA) {
2033 rc = REMOVE_NOT_SUPPORTED;
2034 }
2035 }
2036 }
2037
2038 func = shpchp_slot_find(p_slot->bus, p_slot->device, index++);
2039 }
2040
2041 func = shpchp_slot_find(p_slot->bus, p_slot->device, 0);
2042 if ((func != NULL) && !rc) {
2043 rc = remove_board(func, p_slot->ctrl);
2044 } else if (!rc)
2045 rc = 1;
2046
2047 if (p_slot)
2048 update_slot_info(p_slot);
2049
2050 return(rc);
2051}
2052
2053
2054/**
2055 * configure_new_device - Configures the PCI header information of one board.
2056 *
2057 * @ctrl: pointer to controller structure
2058 * @func: pointer to function structure
2059 * @behind_bridge: 1 if this is a recursive call, 0 if not
2060 * @resources: pointer to set of resource lists
2061 *
2062 * Returns 0 if success
2063 *
2064 */
2065static u32 configure_new_device (struct controller * ctrl, struct pci_func * func,
2066 u8 behind_bridge, struct resource_lists * resources, u8 bridge_bus, u8 bridge_dev)
2067{
2068 u8 temp_byte, function, max_functions, stop_it;
2069 int rc;
2070 u32 ID;
2071 struct pci_func *new_slot;
2072 struct pci_bus lpci_bus, *pci_bus;
2073 int index;
2074
2075 new_slot = func;
2076
2077 dbg("%s\n", __FUNCTION__);
2078 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
2079 pci_bus = &lpci_bus;
2080 pci_bus->number = func->bus;
2081
2082 /* Check for Multi-function device */
2083 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);
2084 if (rc) {
2085 dbg("%s: rc = %d\n", __FUNCTION__, rc);
2086 return rc;
2087 }
2088
2089 if (temp_byte & 0x80) /* Multi-function device */
2090 max_functions = 8;
2091 else
2092 max_functions = 1;
2093
2094 function = 0;
2095
2096 do {
2097 rc = configure_new_function(ctrl, new_slot, behind_bridge, resources, bridge_bus, bridge_dev);
2098
2099 if (rc) {
2100 dbg("configure_new_function failed %d\n",rc);
2101 index = 0;
2102
2103 while (new_slot) {
2104 new_slot = shpchp_slot_find(new_slot->bus, new_slot->device, index++);
2105
2106 if (new_slot)
2107 shpchp_return_board_resources(new_slot, resources);
2108 }
2109
2110 return(rc);
2111 }
2112
2113 function++;
2114
2115 stop_it = 0;
2116
2117 /* The following loop skips to the next present function
2118 * and creates a board structure
2119 */
2120
2121 while ((function < max_functions) && (!stop_it)) {
2122 pci_bus_read_config_dword(pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
2123
2124 if (ID == 0xFFFFFFFF) { /* There's nothing there. */
2125 function++;
2126 } else { /* There's something there */
2127 /* Setup slot structure. */
2128 new_slot = shpchp_slot_create(func->bus);
2129
2130 if (new_slot == NULL) {
2131 /* Out of memory */
2132 return(1);
2133 }
2134
2135 new_slot->bus = func->bus;
2136 new_slot->device = func->device;
2137 new_slot->function = function;
2138 new_slot->is_a_board = 1;
2139 new_slot->status = 0;
2140
2141 stop_it++;
2142 }
2143 }
2144
2145 } while (function < max_functions);
2146 dbg("returning from configure_new_device\n");
2147
2148 return 0;
2149}
2150
2151
2152/*
2153 * Configuration logic that involves the hotplug data structures and
2154 * their bookkeeping
2155 */
2156
2157
2158/**
2159 * configure_new_function - Configures the PCI header information of one device
2160 *
2161 * @ctrl: pointer to controller structure
2162 * @func: pointer to function structure
2163 * @behind_bridge: 1 if this is a recursive call, 0 if not
2164 * @resources: pointer to set of resource lists
2165 *
2166 * Calls itself recursively for bridged devices.
2167 * Returns 0 if success
2168 *
2169 */
2170static int configure_new_function (struct controller * ctrl, struct pci_func * func,
2171 u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev)
2172{
2173 int cloop;
2174 u8 temp_byte;
2175 u8 device;
2176 u8 class_code;
2177 u16 temp_word;
2178 u32 rc;
2179 u32 temp_register;
2180 u32 base;
2181 u32 ID;
2182 unsigned int devfn;
2183 struct pci_resource *mem_node;
2184 struct pci_resource *p_mem_node;
2185 struct pci_resource *io_node;
2186 struct pci_resource *bus_node;
2187 struct pci_resource *hold_mem_node;
2188 struct pci_resource *hold_p_mem_node;
2189 struct pci_resource *hold_IO_node;
2190 struct pci_resource *hold_bus_node;
2191 struct irq_mapping irqs;
2192 struct pci_func *new_slot;
2193 struct pci_bus lpci_bus, *pci_bus;
2194 struct resource_lists temp_resources;
2195#if defined(CONFIG_X86_64)
2196 u8 IRQ=0;
2197#endif
2198
2199 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
2200 pci_bus = &lpci_bus;
2201 pci_bus->number = func->bus;
2202 devfn = PCI_DEVFN(func->device, func->function);
2203
2204 /* Check for Bridge */
2205 rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &temp_byte);
2206 if (rc)
2207 return rc;
2208
2209 if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
2210 /* set Primary bus */
2211 dbg("set Primary bus = 0x%x\n", func->bus);
2212 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
2213 if (rc)
2214 return rc;
2215
2216 /* find range of busses to use */
2217 bus_node = get_max_resource(&resources->bus_head, 1L);
2218
2219 /* If we don't have any busses to allocate, we can't continue */
2220 if (!bus_node) {
2221 err("Got NO bus resource to use\n");
2222 return -ENOMEM;
2223 }
2224 dbg("Got ranges of buses to use: base:len=0x%x:%x\n", bus_node->base, bus_node->length);
2225
2226 /* set Secondary bus */
2227 temp_byte = (u8)bus_node->base;
2228 dbg("set Secondary bus = 0x%x\n", temp_byte);
2229 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, temp_byte);
2230 if (rc)
2231 return rc;
2232
2233 /* set subordinate bus */
2234 temp_byte = (u8)(bus_node->base + bus_node->length - 1);
2235 dbg("set subordinate bus = 0x%x\n", temp_byte);
2236 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
2237 if (rc)
2238 return rc;
2239
2240 /* Set HP parameters (Cache Line Size, Latency Timer) */
2241 rc = shpchprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
2242 if (rc)
2243 return rc;
2244
2245 /* Setup the IO, memory, and prefetchable windows */
2246
2247 io_node = get_max_resource(&(resources->io_head), 0x1000L);
2248 if (io_node) {
2249 dbg("io_node(base, len, next) (%x, %x, %p)\n", io_node->base, io_node->length, io_node->next);
2250 }
2251
2252 mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
2253 if (mem_node) {
2254 dbg("mem_node(base, len, next) (%x, %x, %p)\n", mem_node->base, mem_node->length, mem_node->next);
2255 }
2256
2257 if (resources->p_mem_head)
2258 p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000L);
2259 else {
2260 /*
2261 * In some platform implementation, MEM and PMEM are not
2262 * distinguished, and hence ACPI _CRS has only MEM entries
2263 * for both MEM and PMEM.
2264 */
2265 dbg("using MEM for PMEM\n");
2266 p_mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
2267 }
2268 if (p_mem_node) {
2269 dbg("p_mem_node(base, len, next) (%x, %x, %p)\n", p_mem_node->base, p_mem_node->length, p_mem_node->next);
2270 }
2271
2272 /* set up the IRQ info */
2273 if (!resources->irqs) {
2274 irqs.barber_pole = 0;
2275 irqs.interrupt[0] = 0;
2276 irqs.interrupt[1] = 0;
2277 irqs.interrupt[2] = 0;
2278 irqs.interrupt[3] = 0;
2279 irqs.valid_INT = 0;
2280 } else {
2281 irqs.barber_pole = resources->irqs->barber_pole;
2282 irqs.interrupt[0] = resources->irqs->interrupt[0];
2283 irqs.interrupt[1] = resources->irqs->interrupt[1];
2284 irqs.interrupt[2] = resources->irqs->interrupt[2];
2285 irqs.interrupt[3] = resources->irqs->interrupt[3];
2286 irqs.valid_INT = resources->irqs->valid_INT;
2287 }
2288
2289 /* set up resource lists that are now aligned on top and bottom
2290 * for anything behind the bridge.
2291 */
2292 temp_resources.bus_head = bus_node;
2293 temp_resources.io_head = io_node;
2294 temp_resources.mem_head = mem_node;
2295 temp_resources.p_mem_head = p_mem_node;
2296 temp_resources.irqs = &irqs;
2297
2298 /* Make copies of the nodes we are going to pass down so that
2299 * if there is a problem,we can just use these to free resources
2300 */
2301 hold_bus_node = kmalloc(sizeof(*hold_bus_node), GFP_KERNEL);
2302 hold_IO_node = kmalloc(sizeof(*hold_IO_node), GFP_KERNEL);
2303 hold_mem_node = kmalloc(sizeof(*hold_mem_node), GFP_KERNEL);
2304 hold_p_mem_node = kmalloc(sizeof(*hold_p_mem_node), GFP_KERNEL);
2305
2306 if (!hold_bus_node || !hold_IO_node || !hold_mem_node || !hold_p_mem_node) {
2307 kfree(hold_bus_node);
2308 kfree(hold_IO_node);
2309 kfree(hold_mem_node);
2310 kfree(hold_p_mem_node);
2311
2312 return 1;
2313 }
2314
2315 memcpy(hold_bus_node, bus_node, sizeof(struct pci_resource));
2316
2317 bus_node->base += 1;
2318 bus_node->length -= 1;
2319 bus_node->next = NULL;
2320
2321 /* If we have IO resources copy them and fill in the bridge's
2322 * IO range registers
2323 */
2324 if (io_node) {
2325 memcpy(hold_IO_node, io_node, sizeof(struct pci_resource));
2326 io_node->next = NULL;
2327
2328 /* set IO base and Limit registers */
2329 RES_CHECK(io_node->base, 8);
2330 temp_byte = (u8)(io_node->base >> 8);
2331 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_BASE, temp_byte);
2332
2333 RES_CHECK(io_node->base + io_node->length - 1, 8);
2334 temp_byte = (u8)((io_node->base + io_node->length - 1) >> 8);
2335 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2336 } else {
2337 kfree(hold_IO_node);
2338 hold_IO_node = NULL;
2339 }
2340
2341 /* If we have memory resources copy them and fill in the bridge's
2342 * memory range registers. Otherwise, fill in the range
2343 * registers with values that disable them.
2344 */
2345 if (mem_node) {
2346 memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource));
2347 mem_node->next = NULL;
2348
2349 /* set Mem base and Limit registers */
2350 RES_CHECK(mem_node->base, 16);
2351 temp_word = (u32)(mem_node->base >> 16);
2352 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
2353
2354 RES_CHECK(mem_node->base + mem_node->length - 1, 16);
2355 temp_word = (u32)((mem_node->base + mem_node->length - 1) >> 16);
2356 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2357 } else {
2358 temp_word = 0xFFFF;
2359 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
2360
2361 temp_word = 0x0000;
2362 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2363
2364 kfree(hold_mem_node);
2365 hold_mem_node = NULL;
2366 }
2367
2368 /* If we have prefetchable memory resources copy them and
2369 * fill in the bridge's memory range registers. Otherwise,
2370 * fill in the range registers with values that disable them.
2371 */
2372 if (p_mem_node) {
2373 memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource));
2374 p_mem_node->next = NULL;
2375
2376 /* set Pre Mem base and Limit registers */
2377 RES_CHECK(p_mem_node->base, 16);
2378 temp_word = (u32)(p_mem_node->base >> 16);
2379 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
2380
2381 RES_CHECK(p_mem_node->base + p_mem_node->length - 1, 16);
2382 temp_word = (u32)((p_mem_node->base + p_mem_node->length - 1) >> 16);
2383 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2384 } else {
2385 temp_word = 0xFFFF;
2386 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
2387
2388 temp_word = 0x0000;
2389 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2390
2391 kfree(hold_p_mem_node);
2392 hold_p_mem_node = NULL;
2393 }
2394
2395 /* Adjust this to compensate for extra adjustment in first loop */
2396 irqs.barber_pole--;
2397
2398 rc = 0;
2399
2400 /* Here we actually find the devices and configure them */
2401 for (device = 0; (device <= 0x1F) && !rc; device++) {
2402 irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;
2403
2404 ID = 0xFFFFFFFF;
2405 pci_bus->number = hold_bus_node->base;
2406 pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0),
2407 PCI_VENDOR_ID, &ID);
2408 pci_bus->number = func->bus;
2409
2410 if (ID != 0xFFFFFFFF) { /* device Present */
2411 /* Setup slot structure. */
2412 new_slot = shpchp_slot_create(hold_bus_node->base);
2413
2414 if (new_slot == NULL) {
2415 /* Out of memory */
2416 rc = -ENOMEM;
2417 continue;
2418 }
2419
2420 new_slot->bus = hold_bus_node->base;
2421 new_slot->device = device;
2422 new_slot->function = 0;
2423 new_slot->is_a_board = 1;
2424 new_slot->status = 0;
2425
2426 rc = configure_new_device(ctrl, new_slot, 1, &temp_resources, func->bus, func->device);
2427 dbg("configure_new_device rc=0x%x\n",rc);
2428 } /* End of IF (device in slot?) */
2429 } /* End of FOR loop */
2430
2431 if (rc) {
2432 shpchp_destroy_resource_list(&temp_resources);
2433
2434 return_resource(&(resources->bus_head), hold_bus_node);
2435 return_resource(&(resources->io_head), hold_IO_node);
2436 return_resource(&(resources->mem_head), hold_mem_node);
2437 return_resource(&(resources->p_mem_head), hold_p_mem_node);
2438 return(rc);
2439 }
2440
2441 /* save the interrupt routing information */
2442 if (resources->irqs) {
2443 resources->irqs->interrupt[0] = irqs.interrupt[0];
2444 resources->irqs->interrupt[1] = irqs.interrupt[1];
2445 resources->irqs->interrupt[2] = irqs.interrupt[2];
2446 resources->irqs->interrupt[3] = irqs.interrupt[3];
2447 resources->irqs->valid_INT = irqs.valid_INT;
2448 } else if (!behind_bridge) {
2449 /* We need to hook up the interrupts here */
2450 for (cloop = 0; cloop < 4; cloop++) {
2451 if (irqs.valid_INT & (0x01 << cloop)) {
2452 rc = shpchp_set_irq(func->bus, func->device,
2453 0x0A + cloop, irqs.interrupt[cloop]);
2454 if (rc) {
2455 shpchp_destroy_resource_list (&temp_resources);
2456 return_resource(&(resources->bus_head), hold_bus_node);
2457 return_resource(&(resources->io_head), hold_IO_node);
2458 return_resource(&(resources->mem_head), hold_mem_node);
2459 return_resource(&(resources->p_mem_head), hold_p_mem_node);
2460 return rc;
2461 }
2462 }
2463 } /* end of for loop */
2464 }
2465
2466 /* Return unused bus resources
2467 * First use the temporary node to store information for the board
2468 */
2469 if (hold_bus_node && bus_node && temp_resources.bus_head) {
2470 hold_bus_node->length = bus_node->base - hold_bus_node->base;
2471
2472 hold_bus_node->next = func->bus_head;
2473 func->bus_head = hold_bus_node;
2474
2475 temp_byte = (u8)(temp_resources.bus_head->base - 1);
2476
2477 /* set subordinate bus */
2478 dbg("re-set subordinate bus = 0x%x\n", temp_byte);
2479 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
2480
2481 if (temp_resources.bus_head->length == 0) {
2482 kfree(temp_resources.bus_head);
2483 temp_resources.bus_head = NULL;
2484 } else {
2485 dbg("return bus res of b:d(0x%x:%x) base:len(0x%x:%x)\n",
2486 func->bus, func->device, temp_resources.bus_head->base, temp_resources.bus_head->length);
2487 return_resource(&(resources->bus_head), temp_resources.bus_head);
2488 }
2489 }
2490
2491 /* If we have IO space available and there is some left,
2492 * return the unused portion
2493 */
2494 if (hold_IO_node && temp_resources.io_head) {
2495 io_node = do_pre_bridge_resource_split(&(temp_resources.io_head),
2496 &hold_IO_node, 0x1000);
2497
2498 /* Check if we were able to split something off */
2499 if (io_node) {
2500 hold_IO_node->base = io_node->base + io_node->length;
2501
2502 RES_CHECK(hold_IO_node->base, 8);
2503 temp_byte = (u8)((hold_IO_node->base) >> 8);
2504 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
2505
2506 return_resource(&(resources->io_head), io_node);
2507 }
2508
2509 io_node = do_bridge_resource_split(&(temp_resources.io_head), 0x1000);
2510
2511 /* Check if we were able to split something off */
2512 if (io_node) {
2513 /* First use the temporary node to store information for the board */
2514 hold_IO_node->length = io_node->base - hold_IO_node->base;
2515
2516 /* If we used any, add it to the board's list */
2517 if (hold_IO_node->length) {
2518 hold_IO_node->next = func->io_head;
2519 func->io_head = hold_IO_node;
2520
2521 RES_CHECK(io_node->base - 1, 8);
2522 temp_byte = (u8)((io_node->base - 1) >> 8);
2523 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2524
2525 return_resource(&(resources->io_head), io_node);
2526 } else {
2527 /* it doesn't need any IO */
2528 temp_byte = 0x00;
2529 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2530
2531 return_resource(&(resources->io_head), io_node);
2532 kfree(hold_IO_node);
2533 }
2534 } else {
2535 /* it used most of the range */
2536 hold_IO_node->next = func->io_head;
2537 func->io_head = hold_IO_node;
2538 }
2539 } else if (hold_IO_node) {
2540 /* it used the whole range */
2541 hold_IO_node->next = func->io_head;
2542 func->io_head = hold_IO_node;
2543 }
2544
2545 /* If we have memory space available and there is some left,
2546 * return the unused portion
2547 */
2548 if (hold_mem_node && temp_resources.mem_head) {
2549 mem_node = do_pre_bridge_resource_split(&(temp_resources.mem_head), &hold_mem_node, 0x100000L);
2550
2551 /* Check if we were able to split something off */
2552 if (mem_node) {
2553 hold_mem_node->base = mem_node->base + mem_node->length;
2554
2555 RES_CHECK(hold_mem_node->base, 16);
2556 temp_word = (u32)((hold_mem_node->base) >> 16);
2557 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
2558
2559 return_resource(&(resources->mem_head), mem_node);
2560 }
2561
2562 mem_node = do_bridge_resource_split(&(temp_resources.mem_head), 0x100000L);
2563
2564 /* Check if we were able to split something off */
2565 if (mem_node) {
2566 /* First use the temporary node to store information for the board */
2567 hold_mem_node->length = mem_node->base - hold_mem_node->base;
2568
2569 if (hold_mem_node->length) {
2570 hold_mem_node->next = func->mem_head;
2571 func->mem_head = hold_mem_node;
2572
2573 /* configure end address */
2574 RES_CHECK(mem_node->base - 1, 16);
2575 temp_word = (u32)((mem_node->base - 1) >> 16);
2576 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2577
2578 /* Return unused resources to the pool */
2579 return_resource(&(resources->mem_head), mem_node);
2580 } else {
2581 /* it doesn't need any Mem */
2582 temp_word = 0x0000;
2583 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2584
2585 return_resource(&(resources->mem_head), mem_node);
2586 kfree(hold_mem_node);
2587 }
2588 } else {
2589 /* it used most of the range */
2590 hold_mem_node->next = func->mem_head;
2591 func->mem_head = hold_mem_node;
2592 }
2593 } else if (hold_mem_node) {
2594 /* it used the whole range */
2595 hold_mem_node->next = func->mem_head;
2596 func->mem_head = hold_mem_node;
2597 }
2598
2599 /* If we have prefetchable memory space available and there is some
2600 * left at the end, return the unused portion
2601 */
2602 if (hold_p_mem_node && temp_resources.p_mem_head) {
2603 p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head),
2604 &hold_p_mem_node, 0x100000L);
2605
2606 /* Check if we were able to split something off */
2607 if (p_mem_node) {
2608 hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;
2609
2610 RES_CHECK(hold_p_mem_node->base, 16);
2611 temp_word = (u32)((hold_p_mem_node->base) >> 16);
2612 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
2613
2614 return_resource(&(resources->p_mem_head), p_mem_node);
2615 }
2616
2617 p_mem_node = do_bridge_resource_split(&(temp_resources.p_mem_head), 0x100000L);
2618
2619 /* Check if we were able to split something off */
2620 if (p_mem_node) {
2621 /* First use the temporary node to store information for the board */
2622 hold_p_mem_node->length = p_mem_node->base - hold_p_mem_node->base;
2623
2624 /* If we used any, add it to the board's list */
2625 if (hold_p_mem_node->length) {
2626 hold_p_mem_node->next = func->p_mem_head;
2627 func->p_mem_head = hold_p_mem_node;
2628
2629 RES_CHECK(p_mem_node->base - 1, 16);
2630 temp_word = (u32)((p_mem_node->base - 1) >> 16);
2631 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2632
2633 return_resource(&(resources->p_mem_head), p_mem_node);
2634 } else {
2635 /* it doesn't need any PMem */
2636 temp_word = 0x0000;
2637 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2638
2639 return_resource(&(resources->p_mem_head), p_mem_node);
2640 kfree(hold_p_mem_node);
2641 }
2642 } else {
2643 /* it used the most of the range */
2644 hold_p_mem_node->next = func->p_mem_head;
2645 func->p_mem_head = hold_p_mem_node;
2646 }
2647 } else if (hold_p_mem_node) {
2648 /* it used the whole range */
2649 hold_p_mem_node->next = func->p_mem_head;
2650 func->p_mem_head = hold_p_mem_node;
2651 }
2652
2653 /* We should be configuring an IRQ and the bridge's base address
2654 * registers if it needs them. Although we have never seen such
2655 * a device
2656 */
2657
2658 shpchprm_enable_card(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
2659
2660 dbg("PCI Bridge Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function);
2661 } else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
2662 /* Standard device */
2663 u64 base64;
2664 rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
2665
2666 if (class_code == PCI_BASE_CLASS_DISPLAY)
2667 return (DEVICE_TYPE_NOT_SUPPORTED);
2668
2669 /* Figure out IO and memory needs */
2670 for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
2671 temp_register = 0xFFFFFFFF;
2672
2673 rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
2674 rc = pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
2675 dbg("Bar[%x]=0x%x on bus:dev:func(0x%x:%x:%x)\n", cloop, temp_register, func->bus, func->device,
2676 func->function);
2677
2678 if (!temp_register)
2679 continue;
2680
2681 base64 = 0L;
2682 if (temp_register & PCI_BASE_ADDRESS_SPACE_IO) {
2683 /* Map IO */
2684
2685 /* set base = amount of IO space */
2686 base = temp_register & 0xFFFFFFFC;
2687 base = ~base + 1;
2688
2689 dbg("NEED IO length(0x%x)\n", base);
2690 io_node = get_io_resource(&(resources->io_head),(ulong)base);
2691
2692 /* allocate the resource to the board */
2693 if (io_node) {
2694 dbg("Got IO base=0x%x(length=0x%x)\n", io_node->base, io_node->length);
2695 base = (u32)io_node->base;
2696 io_node->next = func->io_head;
2697 func->io_head = io_node;
2698 } else {
2699 err("Got NO IO resource(length=0x%x)\n", base);
2700 return -ENOMEM;
2701 }
2702 } else { /* map MEM */
2703 int prefetchable = 1;
2704 struct pci_resource **res_node = &func->p_mem_head;
2705 char *res_type_str = "PMEM";
2706 u32 temp_register2;
2707
2708 if (!(temp_register & PCI_BASE_ADDRESS_MEM_PREFETCH)) {
2709 prefetchable = 0;
2710 res_node = &func->mem_head;
2711 res_type_str++;
2712 }
2713
2714 base = temp_register & 0xFFFFFFF0;
2715 base = ~base + 1;
2716
2717 switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
2718 case PCI_BASE_ADDRESS_MEM_TYPE_32:
2719 dbg("NEED 32 %s bar=0x%x(length=0x%x)\n", res_type_str, temp_register, base);
2720
2721 if (prefetchable && resources->p_mem_head)
2722 mem_node=get_resource(&(resources->p_mem_head), (ulong)base);
2723 else {
2724 if (prefetchable)
2725 dbg("using MEM for PMEM\n");
2726 mem_node=get_resource(&(resources->mem_head), (ulong)base);
2727 }
2728
2729 /* allocate the resource to the board */
2730 if (mem_node) {
2731 base = (u32)mem_node->base;
2732 mem_node->next = *res_node;
2733 *res_node = mem_node;
2734 dbg("Got 32 %s base=0x%x(length=0x%x)\n", res_type_str, mem_node->base,
2735 mem_node->length);
2736 } else {
2737 err("Got NO 32 %s resource(length=0x%x)\n", res_type_str, base);
2738 return -ENOMEM;
2739 }
2740 break;
2741 case PCI_BASE_ADDRESS_MEM_TYPE_64:
2742 rc = pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
2743 dbg("NEED 64 %s bar=0x%x:%x(length=0x%x)\n", res_type_str, temp_register2,
2744 temp_register, base);
2745
2746 if (prefetchable && resources->p_mem_head)
2747 mem_node = get_resource(&(resources->p_mem_head), (ulong)base);
2748 else {
2749 if (prefetchable)
2750 dbg("using MEM for PMEM\n");
2751 mem_node = get_resource(&(resources->mem_head), (ulong)base);
2752 }
2753
2754 /* allocate the resource to the board */
2755 if (mem_node) {
2756 base64 = mem_node->base;
2757 mem_node->next = *res_node;
2758 *res_node = mem_node;
2759 dbg("Got 64 %s base=0x%x:%x(length=%x)\n", res_type_str, (u32)(base64 >> 32),
2760 (u32)base64, mem_node->length);
2761 } else {
2762 err("Got NO 64 %s resource(length=0x%x)\n", res_type_str, base);
2763 return -ENOMEM;
2764 }
2765 break;
2766 default:
2767 dbg("reserved BAR type=0x%x\n", temp_register);
2768 break;
2769 }
2770
2771 }
2772
2773 if (base64) {
2774 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
2775 cloop += 4;
2776 base64 >>= 32;
2777
2778 if (base64) {
2779 dbg("%s: high dword of base64(0x%x) set to 0\n", __FUNCTION__, (u32)base64);
2780 base64 = 0x0L;
2781 }
2782
2783 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
2784 } else {
2785 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, base);
2786 }
2787 } /* End of base register loop */
2788
2789#if defined(CONFIG_X86_64)
2790 /* Figure out which interrupt pin this function uses */
2791 rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_INTERRUPT_PIN, &temp_byte);
2792
2793 /* If this function needs an interrupt and we are behind a bridge
2794 and the pin is tied to something that's alread mapped,
2795 set this one the same
2796 */
2797 if (temp_byte && resources->irqs &&
2798 (resources->irqs->valid_INT &
2799 (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) {
2800 /* We have to share with something already set up */
2801 IRQ = resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03];
2802 } else {
2803 /* Program IRQ based on card type */
2804 rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
2805
2806 if (class_code == PCI_BASE_CLASS_STORAGE) {
2807 IRQ = shpchp_disk_irq;
2808 } else {
2809 IRQ = shpchp_nic_irq;
2810 }
2811 }
2812
2813 /* IRQ Line */
2814 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_INTERRUPT_LINE, IRQ);
2815
2816 if (!behind_bridge) {
2817 rc = shpchp_set_irq(func->bus, func->device, temp_byte + 0x09, IRQ);
2818 if (rc)
2819 return(1);
2820 } else {
2821 /* TBD - this code may also belong in the other clause of this If statement */
2822 resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03] = IRQ;
2823 resources->irqs->valid_INT |= 0x01 << (temp_byte + resources->irqs->barber_pole - 1) & 0x03;
2824 }
2825#endif
2826 /* Disable ROM base Address */
2827 temp_word = 0x00L;
2828 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_ROM_ADDRESS, temp_word);
2829
2830 /* Set HP parameters (Cache Line Size, Latency Timer) */
2831 rc = shpchprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_NORMAL);
2832 if (rc)
2833 return rc;
2834
2835 shpchprm_enable_card(ctrl, func, PCI_HEADER_TYPE_NORMAL);
2836
2837 dbg("PCI function Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function);
2838 } /* End of Not-A-Bridge else */
2839 else {
2840 /* It's some strange type of PCI adapter (Cardbus?) */
2841 return(DEVICE_TYPE_NOT_SUPPORTED);
2842 }
2843
2844 func->configured = 1;
2845
2846 return 0;
2847}
2848
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
new file mode 100644
index 000000000000..38c5d9066697
--- /dev/null
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -0,0 +1,1620 @@
1/*
2 * Standard PCI Hot Plug Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>,<dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/kernel.h>
32#include <linux/module.h>
33#include <linux/types.h>
34#include <linux/slab.h>
35#include <linux/vmalloc.h>
36#include <linux/interrupt.h>
37#include <linux/spinlock.h>
38#include <linux/delay.h>
39#include <linux/pci.h>
40#include <asm/system.h>
41#include "shpchp.h"
42
43#ifdef DEBUG
44#define DBG_K_TRACE_ENTRY ((unsigned int)0x00000001) /* On function entry */
45#define DBG_K_TRACE_EXIT ((unsigned int)0x00000002) /* On function exit */
46#define DBG_K_INFO ((unsigned int)0x00000004) /* Info messages */
47#define DBG_K_ERROR ((unsigned int)0x00000008) /* Error messages */
48#define DBG_K_TRACE (DBG_K_TRACE_ENTRY|DBG_K_TRACE_EXIT)
49#define DBG_K_STANDARD (DBG_K_INFO|DBG_K_ERROR|DBG_K_TRACE)
50/* Redefine this flagword to set debug level */
51#define DEBUG_LEVEL DBG_K_STANDARD
52
53#define DEFINE_DBG_BUFFER char __dbg_str_buf[256];
54
55#define DBG_PRINT( dbg_flags, args... ) \
56 do { \
57 if ( DEBUG_LEVEL & ( dbg_flags ) ) \
58 { \
59 int len; \
60 len = sprintf( __dbg_str_buf, "%s:%d: %s: ", \
61 __FILE__, __LINE__, __FUNCTION__ ); \
62 sprintf( __dbg_str_buf + len, args ); \
63 printk( KERN_NOTICE "%s\n", __dbg_str_buf ); \
64 } \
65 } while (0)
66
67#define DBG_ENTER_ROUTINE DBG_PRINT (DBG_K_TRACE_ENTRY, "%s", "[Entry]");
68#define DBG_LEAVE_ROUTINE DBG_PRINT (DBG_K_TRACE_EXIT, "%s", "[Exit]");
69#else
70#define DEFINE_DBG_BUFFER
71#define DBG_ENTER_ROUTINE
72#define DBG_LEAVE_ROUTINE
73#endif /* DEBUG */
74
75/* Slot Available Register I field definition */
76#define SLOT_33MHZ 0x0000001f
77#define SLOT_66MHZ_PCIX 0x00001f00
78#define SLOT_100MHZ_PCIX 0x001f0000
79#define SLOT_133MHZ_PCIX 0x1f000000
80
81/* Slot Available Register II field definition */
82#define SLOT_66MHZ 0x0000001f
83#define SLOT_66MHZ_PCIX_266 0x00000f00
84#define SLOT_100MHZ_PCIX_266 0x0000f000
85#define SLOT_133MHZ_PCIX_266 0x000f0000
86#define SLOT_66MHZ_PCIX_533 0x00f00000
87#define SLOT_100MHZ_PCIX_533 0x0f000000
88#define SLOT_133MHZ_PCIX_533 0xf0000000
89
90
91/* Secondary Bus Configuration Register */
92/* For PI = 1, Bits 0 to 2 have been encoded as follows to show current bus speed/mode */
93#define PCI_33MHZ 0x0
94#define PCI_66MHZ 0x1
95#define PCIX_66MHZ 0x2
96#define PCIX_100MHZ 0x3
97#define PCIX_133MHZ 0x4
98
99/* For PI = 2, Bits 0 to 3 have been encoded as follows to show current bus speed/mode */
100#define PCI_33MHZ 0x0
101#define PCI_66MHZ 0x1
102#define PCIX_66MHZ 0x2
103#define PCIX_100MHZ 0x3
104#define PCIX_133MHZ 0x4
105#define PCIX_66MHZ_ECC 0x5
106#define PCIX_100MHZ_ECC 0x6
107#define PCIX_133MHZ_ECC 0x7
108#define PCIX_66MHZ_266 0x9
109#define PCIX_100MHZ_266 0xa
110#define PCIX_133MHZ_266 0xb
111#define PCIX_66MHZ_533 0x11
112#define PCIX_100MHZ_533 0x12
113#define PCIX_133MHZ_533 0x13
114
115/* Slot Configuration */
116#define SLOT_NUM 0x0000001F
117#define FIRST_DEV_NUM 0x00001F00
118#define PSN 0x07FF0000
119#define UPDOWN 0x20000000
120#define MRLSENSOR 0x40000000
121#define ATTN_BUTTON 0x80000000
122
123/* Slot Status Field Definitions */
124/* Slot State */
125#define PWR_ONLY 0x0001
126#define ENABLED 0x0002
127#define DISABLED 0x0003
128
129/* Power Indicator State */
130#define PWR_LED_ON 0x0004
131#define PWR_LED_BLINK 0x0008
132#define PWR_LED_OFF 0x000c
133
134/* Attention Indicator State */
135#define ATTEN_LED_ON 0x0010
136#define ATTEN_LED_BLINK 0x0020
137#define ATTEN_LED_OFF 0x0030
138
139/* Power Fault */
140#define pwr_fault 0x0040
141
142/* Attention Button */
143#define ATTEN_BUTTON 0x0080
144
145/* MRL Sensor */
146#define MRL_SENSOR 0x0100
147
148/* 66 MHz Capable */
149#define IS_66MHZ_CAP 0x0200
150
151/* PRSNT1#/PRSNT2# */
152#define SLOT_EMP 0x0c00
153
154/* PCI-X Capability */
155#define NON_PCIX 0x0000
156#define PCIX_66 0x1000
157#define PCIX_133 0x3000
158#define PCIX_266 0x4000 /* For PI = 2 only */
159#define PCIX_533 0x5000 /* For PI = 2 only */
160
161/* SHPC 'write' operations/commands */
162
163/* Slot operation - 0x00h to 0x3Fh */
164
165#define NO_CHANGE 0x00
166
167/* Slot state - Bits 0 & 1 of controller command register */
168#define SET_SLOT_PWR 0x01
169#define SET_SLOT_ENABLE 0x02
170#define SET_SLOT_DISABLE 0x03
171
172/* Power indicator state - Bits 2 & 3 of controller command register*/
173#define SET_PWR_ON 0x04
174#define SET_PWR_BLINK 0x08
175#define SET_PWR_OFF 0x0C
176
177/* Attention indicator state - Bits 4 & 5 of controller command register*/
178#define SET_ATTN_ON 0x010
179#define SET_ATTN_BLINK 0x020
180#define SET_ATTN_OFF 0x030
181
182/* Set bus speed/mode A - 0x40h to 0x47h */
183#define SETA_PCI_33MHZ 0x40
184#define SETA_PCI_66MHZ 0x41
185#define SETA_PCIX_66MHZ 0x42
186#define SETA_PCIX_100MHZ 0x43
187#define SETA_PCIX_133MHZ 0x44
188#define RESERV_1 0x45
189#define RESERV_2 0x46
190#define RESERV_3 0x47
191
192/* Set bus speed/mode B - 0x50h to 0x5fh */
193#define SETB_PCI_33MHZ 0x50
194#define SETB_PCI_66MHZ 0x51
195#define SETB_PCIX_66MHZ_PM 0x52
196#define SETB_PCIX_100MHZ_PM 0x53
197#define SETB_PCIX_133MHZ_PM 0x54
198#define SETB_PCIX_66MHZ_EM 0x55
199#define SETB_PCIX_100MHZ_EM 0x56
200#define SETB_PCIX_133MHZ_EM 0x57
201#define SETB_PCIX_66MHZ_266 0x58
202#define SETB_PCIX_100MHZ_266 0x59
203#define SETB_PCIX_133MHZ_266 0x5a
204#define SETB_PCIX_66MHZ_533 0x5b
205#define SETB_PCIX_100MHZ_533 0x5c
206#define SETB_PCIX_133MHZ_533 0x5d
207
208
209/* Power-on all slots - 0x48h */
210#define SET_PWR_ON_ALL 0x48
211
212/* Enable all slots - 0x49h */
213#define SET_ENABLE_ALL 0x49
214
215/* SHPC controller command error code */
216#define SWITCH_OPEN 0x1
217#define INVALID_CMD 0x2
218#define INVALID_SPEED_MODE 0x4
219
220/* For accessing SHPC Working Register Set */
221#define DWORD_SELECT 0x2
222#define DWORD_DATA 0x4
223#define BASE_OFFSET 0x0
224
225/* Field Offset in Logical Slot Register - byte boundary */
226#define SLOT_EVENT_LATCH 0x2
227#define SLOT_SERR_INT_MASK 0x3
228
229static spinlock_t hpc_event_lock;
230
231DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */
232static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */
233static int ctlr_seq_num = 0; /* Controller sequenc # */
234static spinlock_t list_lock;
235
236static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs);
237
238static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds);
239
240/* This is the interrupt polling timeout function. */
241static void int_poll_timeout(unsigned long lphp_ctlr)
242{
243 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *)lphp_ctlr;
244
245 DBG_ENTER_ROUTINE
246
247 if ( !php_ctlr ) {
248 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
249 return;
250 }
251
252 /* Poll for interrupt events. regs == NULL => polling */
253 shpc_isr( 0, (void *)php_ctlr, NULL );
254
255 init_timer(&php_ctlr->int_poll_timer);
256 if (!shpchp_poll_time)
257 shpchp_poll_time = 2; /* reset timer to poll in 2 secs if user doesn't specify at module installation*/
258
259 start_int_poll_timer(php_ctlr, shpchp_poll_time);
260
261 return;
262}
263
264/* This function starts the interrupt polling timer. */
265static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds)
266{
267 if (!php_ctlr) {
268 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
269 return;
270 }
271
272 if ( ( seconds <= 0 ) || ( seconds > 60 ) )
273 seconds = 2; /* Clamp to sane value */
274
275 php_ctlr->int_poll_timer.function = &int_poll_timeout;
276 php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr; /* Instance data */
277 php_ctlr->int_poll_timer.expires = jiffies + seconds * HZ;
278 add_timer(&php_ctlr->int_poll_timer);
279
280 return;
281}
282
283static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
284{
285 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
286 u16 cmd_status;
287 int retval = 0;
288 u16 temp_word;
289 int i;
290
291 DBG_ENTER_ROUTINE
292
293 if (!php_ctlr) {
294 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
295 return -1;
296 }
297
298 for (i = 0; i < 10; i++) {
299 cmd_status = readw(php_ctlr->creg + CMD_STATUS);
300
301 if (!(cmd_status & 0x1))
302 break;
303 /* Check every 0.1 sec for a total of 1 sec*/
304 msleep(100);
305 }
306
307 cmd_status = readw(php_ctlr->creg + CMD_STATUS);
308
309 if (cmd_status & 0x1) {
310 /* After 1 sec and and the controller is still busy */
311 err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__);
312 return -1;
313 }
314
315 ++t_slot;
316 temp_word = (t_slot << 8) | (cmd & 0xFF);
317 dbg("%s: t_slot %x cmd %x\n", __FUNCTION__, t_slot, cmd);
318
319 /* To make sure the Controller Busy bit is 0 before we send out the
320 * command.
321 */
322 writew(temp_word, php_ctlr->creg + CMD);
323 dbg("%s: temp_word written %x\n", __FUNCTION__, temp_word);
324
325 DBG_LEAVE_ROUTINE
326 return retval;
327}
328
329static int hpc_check_cmd_status(struct controller *ctrl)
330{
331 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle;
332 u16 cmd_status;
333 int retval = 0;
334
335 DBG_ENTER_ROUTINE
336
337 if (!ctrl->hpc_ctlr_handle) {
338 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
339 return -1;
340 }
341
342 cmd_status = readw(php_ctlr->creg + CMD_STATUS) & 0x000F;
343
344 switch (cmd_status >> 1) {
345 case 0:
346 retval = 0;
347 break;
348 case 1:
349 retval = SWITCH_OPEN;
350 err("%s: Switch opened!\n", __FUNCTION__);
351 break;
352 case 2:
353 retval = INVALID_CMD;
354 err("%s: Invalid HPC command!\n", __FUNCTION__);
355 break;
356 case 4:
357 retval = INVALID_SPEED_MODE;
358 err("%s: Invalid bus speed/mode!\n", __FUNCTION__);
359 break;
360 default:
361 retval = cmd_status;
362 }
363
364 DBG_LEAVE_ROUTINE
365 return retval;
366}
367
368
369static int hpc_get_attention_status(struct slot *slot, u8 *status)
370{
371 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
372 u32 slot_reg;
373 u16 slot_status;
374 u8 atten_led_state;
375
376 DBG_ENTER_ROUTINE
377
378 if (!slot->ctrl->hpc_ctlr_handle) {
379 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
380 return -1;
381 }
382
383 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
384 slot_status = (u16) slot_reg;
385 atten_led_state = (slot_status & 0x0030) >> 4;
386
387 switch (atten_led_state) {
388 case 0:
389 *status = 0xFF; /* Reserved */
390 break;
391 case 1:
392 *status = 1; /* On */
393 break;
394 case 2:
395 *status = 2; /* Blink */
396 break;
397 case 3:
398 *status = 0; /* Off */
399 break;
400 default:
401 *status = 0xFF;
402 break;
403 }
404
405 DBG_LEAVE_ROUTINE
406 return 0;
407}
408
409static int hpc_get_power_status(struct slot * slot, u8 *status)
410{
411 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
412 u32 slot_reg;
413 u16 slot_status;
414 u8 slot_state;
415 int retval = 0;
416
417 DBG_ENTER_ROUTINE
418
419 if (!slot->ctrl->hpc_ctlr_handle) {
420 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
421 return -1;
422 }
423
424 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
425 slot_status = (u16) slot_reg;
426 slot_state = (slot_status & 0x0003);
427
428 switch (slot_state) {
429 case 0:
430 *status = 0xFF;
431 break;
432 case 1:
433 *status = 2; /* Powered only */
434 break;
435 case 2:
436 *status = 1; /* Enabled */
437 break;
438 case 3:
439 *status = 0; /* Disabled */
440 break;
441 default:
442 *status = 0xFF;
443 break;
444 }
445
446 DBG_LEAVE_ROUTINE
447 return retval;
448}
449
450
451static int hpc_get_latch_status(struct slot *slot, u8 *status)
452{
453 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
454 u32 slot_reg;
455 u16 slot_status;
456
457 DBG_ENTER_ROUTINE
458
459 if (!slot->ctrl->hpc_ctlr_handle) {
460 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
461 return -1;
462 }
463
464 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
465 slot_status = (u16)slot_reg;
466
467 *status = ((slot_status & 0x0100) == 0) ? 0 : 1; /* 0 -> close; 1 -> open */
468
469
470 DBG_LEAVE_ROUTINE
471 return 0;
472}
473
474static int hpc_get_adapter_status(struct slot *slot, u8 *status)
475{
476 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
477 u32 slot_reg;
478 u16 slot_status;
479 u8 card_state;
480
481 DBG_ENTER_ROUTINE
482
483 if (!slot->ctrl->hpc_ctlr_handle) {
484 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
485 return -1;
486 }
487
488 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
489 slot_status = (u16)slot_reg;
490 card_state = (u8)((slot_status & 0x0C00) >> 10);
491 *status = (card_state != 0x3) ? 1 : 0;
492
493 DBG_LEAVE_ROUTINE
494 return 0;
495}
496
497static int hpc_get_prog_int(struct slot *slot, u8 *prog_int)
498{
499 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
500
501 DBG_ENTER_ROUTINE
502
503 if (!slot->ctrl->hpc_ctlr_handle) {
504 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
505 return -1;
506 }
507
508 *prog_int = readb(php_ctlr->creg + PROG_INTERFACE);
509
510 DBG_LEAVE_ROUTINE
511 return 0;
512}
513
514static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value)
515{
516 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
517 u32 slot_reg;
518 u16 slot_status, sec_bus_status;
519 u8 m66_cap, pcix_cap, pi;
520 int retval = 0;
521
522 DBG_ENTER_ROUTINE
523
524 if (!slot->ctrl->hpc_ctlr_handle) {
525 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
526 return -1;
527 }
528
529 if (slot->hp_slot >= php_ctlr->num_slots) {
530 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
531 return -1;
532 }
533
534 pi = readb(php_ctlr->creg + PROG_INTERFACE);
535 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
536 dbg("%s: pi = %d, slot_reg = %x\n", __FUNCTION__, pi, slot_reg);
537 slot_status = (u16) slot_reg;
538 dbg("%s: slot_status = %x\n", __FUNCTION__, slot_status);
539 sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG);
540
541 pcix_cap = (u8) ((slot_status & 0x3000) >> 12);
542 dbg("%s: pcix_cap = %x\n", __FUNCTION__, pcix_cap);
543 m66_cap = (u8) ((slot_status & 0x0200) >> 9);
544 dbg("%s: m66_cap = %x\n", __FUNCTION__, m66_cap);
545
546
547 if (pi == 2) {
548 switch (pcix_cap) {
549 case 0:
550 *value = m66_cap ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
551 break;
552 case 1:
553 *value = PCI_SPEED_66MHz_PCIX;
554 break;
555 case 3:
556 *value = PCI_SPEED_133MHz_PCIX;
557 break;
558 case 4:
559 *value = PCI_SPEED_133MHz_PCIX_266;
560 break;
561 case 5:
562 *value = PCI_SPEED_133MHz_PCIX_533;
563 break;
564 case 2: /* Reserved */
565 default:
566 *value = PCI_SPEED_UNKNOWN;
567 retval = -ENODEV;
568 break;
569 }
570 } else {
571 switch (pcix_cap) {
572 case 0:
573 *value = m66_cap ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
574 break;
575 case 1:
576 *value = PCI_SPEED_66MHz_PCIX;
577 break;
578 case 3:
579 *value = PCI_SPEED_133MHz_PCIX;
580 break;
581 case 2: /* Reserved */
582 default:
583 *value = PCI_SPEED_UNKNOWN;
584 retval = -ENODEV;
585 break;
586 }
587 }
588
589 dbg("Adapter speed = %d\n", *value);
590
591 DBG_LEAVE_ROUTINE
592 return retval;
593}
594
595static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode)
596{
597 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
598 u16 sec_bus_status;
599 u8 pi;
600 int retval = 0;
601
602 DBG_ENTER_ROUTINE
603
604 if (!slot->ctrl->hpc_ctlr_handle) {
605 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
606 return -1;
607 }
608
609 pi = readb(php_ctlr->creg + PROG_INTERFACE);
610 sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG);
611
612 if (pi == 2) {
613 *mode = (sec_bus_status & 0x0100) >> 7;
614 } else {
615 retval = -1;
616 }
617
618 dbg("Mode 1 ECC cap = %d\n", *mode);
619
620 DBG_LEAVE_ROUTINE
621 return retval;
622}
623
624static int hpc_query_power_fault(struct slot * slot)
625{
626 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
627 u32 slot_reg;
628 u16 slot_status;
629 u8 pwr_fault_state, status;
630
631 DBG_ENTER_ROUTINE
632
633 if (!slot->ctrl->hpc_ctlr_handle) {
634 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
635 return -1;
636 }
637
638 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
639 slot_status = (u16) slot_reg;
640 pwr_fault_state = (slot_status & 0x0040) >> 7;
641 status = (pwr_fault_state == 1) ? 0 : 1;
642
643 DBG_LEAVE_ROUTINE
644 /* Note: Logic 0 => fault */
645 return status;
646}
647
648static int hpc_set_attention_status(struct slot *slot, u8 value)
649{
650 struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
651 u8 slot_cmd = 0;
652 int rc = 0;
653
654 if (!slot->ctrl->hpc_ctlr_handle) {
655 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
656 return -1;
657 }
658
659 if (slot->hp_slot >= php_ctlr->num_slots) {
660 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
661 return -1;
662 }
663
664 switch (value) {
665 case 0 :
666 slot_cmd = 0x30; /* OFF */
667 break;
668 case 1:
669 slot_cmd = 0x10; /* ON */
670 break;
671 case 2:
672 slot_cmd = 0x20; /* BLINK */
673 break;
674 default:
675 return -1;
676 }
677
678 shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
679
680 return rc;
681}
682
683
684static void hpc_set_green_led_on(struct slot *slot)
685{
686 struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
687 u8 slot_cmd;
688
689 if (!slot->ctrl->hpc_ctlr_handle) {
690 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
691 return ;
692 }
693
694 if (slot->hp_slot >= php_ctlr->num_slots) {
695 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
696 return ;
697 }
698
699 slot_cmd = 0x04;
700
701 shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
702
703 return;
704}
705
706static void hpc_set_green_led_off(struct slot *slot)
707{
708 struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
709 u8 slot_cmd;
710
711 if (!slot->ctrl->hpc_ctlr_handle) {
712 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
713 return ;
714 }
715
716 if (slot->hp_slot >= php_ctlr->num_slots) {
717 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
718 return ;
719 }
720
721 slot_cmd = 0x0C;
722
723 shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
724
725 return;
726}
727
728static void hpc_set_green_led_blink(struct slot *slot)
729{
730 struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
731 u8 slot_cmd;
732
733 if (!slot->ctrl->hpc_ctlr_handle) {
734 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
735 return ;
736 }
737
738 if (slot->hp_slot >= php_ctlr->num_slots) {
739 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
740 return ;
741 }
742
743 slot_cmd = 0x08;
744
745 shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
746
747 return;
748}
749
750int shpc_get_ctlr_slot_config(struct controller *ctrl,
751 int *num_ctlr_slots, /* number of slots in this HPC */
752 int *first_device_num, /* PCI dev num of the first slot in this SHPC */
753 int *physical_slot_num, /* phy slot num of the first slot in this SHPC */
754 int *updown, /* physical_slot_num increament: 1 or -1 */
755 int *flags)
756{
757 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle;
758
759 DBG_ENTER_ROUTINE
760
761 if (!ctrl->hpc_ctlr_handle) {
762 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
763 return -1;
764 }
765
766 *first_device_num = php_ctlr->slot_device_offset; /* Obtained in shpc_init() */
767 *num_ctlr_slots = php_ctlr->num_slots; /* Obtained in shpc_init() */
768
769 *physical_slot_num = (readl(php_ctlr->creg + SLOT_CONFIG) & PSN) >> 16;
770 dbg("%s: physical_slot_num = %x\n", __FUNCTION__, *physical_slot_num);
771 *updown = ((readl(php_ctlr->creg + SLOT_CONFIG) & UPDOWN ) >> 29) ? 1 : -1;
772
773 DBG_LEAVE_ROUTINE
774 return 0;
775}
776
777static void hpc_release_ctlr(struct controller *ctrl)
778{
779 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle;
780 struct php_ctlr_state_s *p, *p_prev;
781
782 DBG_ENTER_ROUTINE
783
784 if (!ctrl->hpc_ctlr_handle) {
785 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
786 return ;
787 }
788
789 if (shpchp_poll_mode) {
790 del_timer(&php_ctlr->int_poll_timer);
791 } else {
792 if (php_ctlr->irq) {
793 free_irq(php_ctlr->irq, ctrl);
794 php_ctlr->irq = 0;
795 pci_disable_msi(php_ctlr->pci_dev);
796 }
797 }
798 if (php_ctlr->pci_dev) {
799 dbg("%s: before calling iounmap & release_mem_region\n", __FUNCTION__);
800 iounmap(php_ctlr->creg);
801 release_mem_region(pci_resource_start(php_ctlr->pci_dev, 0), pci_resource_len(php_ctlr->pci_dev, 0));
802 dbg("%s: before calling iounmap & release_mem_region\n", __FUNCTION__);
803 php_ctlr->pci_dev = NULL;
804 }
805
806 spin_lock(&list_lock);
807 p = php_ctlr_list_head;
808 p_prev = NULL;
809 while (p) {
810 if (p == php_ctlr) {
811 if (p_prev)
812 p_prev->pnext = p->pnext;
813 else
814 php_ctlr_list_head = p->pnext;
815 break;
816 } else {
817 p_prev = p;
818 p = p->pnext;
819 }
820 }
821 spin_unlock(&list_lock);
822
823 kfree(php_ctlr);
824
825DBG_LEAVE_ROUTINE
826
827}
828
829static int hpc_power_on_slot(struct slot * slot)
830{
831 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
832 u8 slot_cmd;
833 int retval = 0;
834
835 DBG_ENTER_ROUTINE
836
837 if (!slot->ctrl->hpc_ctlr_handle) {
838 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
839 return -1;
840 }
841
842 if (slot->hp_slot >= php_ctlr->num_slots) {
843 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
844 return -1;
845 }
846 slot_cmd = 0x01;
847
848 retval = shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
849
850 if (retval) {
851 err("%s: Write command failed!\n", __FUNCTION__);
852 return -1;
853 }
854
855 DBG_LEAVE_ROUTINE
856
857 return retval;
858}
859
860static int hpc_slot_enable(struct slot * slot)
861{
862 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
863 u8 slot_cmd;
864 int retval = 0;
865
866 DBG_ENTER_ROUTINE
867
868 if (!slot->ctrl->hpc_ctlr_handle) {
869 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
870 return -1;
871 }
872
873 if (slot->hp_slot >= php_ctlr->num_slots) {
874 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
875 return -1;
876 }
877 /* 3A => Slot - Enable, Power Indicator - Blink, Attention Indicator - Off */
878 slot_cmd = 0x3A;
879
880 retval = shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
881
882 if (retval) {
883 err("%s: Write command failed!\n", __FUNCTION__);
884 return -1;
885 }
886
887 DBG_LEAVE_ROUTINE
888 return retval;
889}
890
891static int hpc_slot_disable(struct slot * slot)
892{
893 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
894 u8 slot_cmd;
895 int retval = 0;
896
897 DBG_ENTER_ROUTINE
898
899 if (!slot->ctrl->hpc_ctlr_handle) {
900 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
901 return -1;
902 }
903
904 if (slot->hp_slot >= php_ctlr->num_slots) {
905 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
906 return -1;
907 }
908
909 /* 1F => Slot - Disable, Power Indicator - Off, Attention Indicator - On */
910 slot_cmd = 0x1F;
911
912 retval = shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
913
914 if (retval) {
915 err("%s: Write command failed!\n", __FUNCTION__);
916 return -1;
917 }
918
919 DBG_LEAVE_ROUTINE
920 return retval;
921}
922
923static int hpc_enable_all_slots( struct slot *slot )
924{
925 int retval = 0;
926
927 DBG_ENTER_ROUTINE
928
929 if (!slot->ctrl->hpc_ctlr_handle) {
930 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
931 return -1;
932 }
933
934 retval = shpc_write_cmd(slot, 0, SET_ENABLE_ALL);
935 if (retval) {
936 err("%s: Write command failed!\n", __FUNCTION__);
937 return -1;
938 }
939
940 DBG_LEAVE_ROUTINE
941
942 return retval;
943}
944
945static int hpc_pwr_on_all_slots(struct slot *slot)
946{
947 int retval = 0;
948
949 DBG_ENTER_ROUTINE
950
951 retval = shpc_write_cmd(slot, 0, SET_PWR_ON_ALL);
952
953 if (retval) {
954 err("%s: Write command failed!\n", __FUNCTION__);
955 return -1;
956 }
957
958 DBG_LEAVE_ROUTINE
959 return retval;
960}
961
962static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value)
963{
964 u8 slot_cmd;
965 u8 pi;
966 int retval = 0;
967 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
968
969 DBG_ENTER_ROUTINE
970
971 if (!slot->ctrl->hpc_ctlr_handle) {
972 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
973 return -1;
974 }
975
976 pi = readb(php_ctlr->creg + PROG_INTERFACE);
977
978 if (pi == 1) {
979 switch (value) {
980 case 0:
981 slot_cmd = SETA_PCI_33MHZ;
982 break;
983 case 1:
984 slot_cmd = SETA_PCI_66MHZ;
985 break;
986 case 2:
987 slot_cmd = SETA_PCIX_66MHZ;
988 break;
989 case 3:
990 slot_cmd = SETA_PCIX_100MHZ;
991 break;
992 case 4:
993 slot_cmd = SETA_PCIX_133MHZ;
994 break;
995 default:
996 slot_cmd = PCI_SPEED_UNKNOWN;
997 retval = -ENODEV;
998 return retval;
999 }
1000 } else {
1001 switch (value) {
1002 case 0:
1003 slot_cmd = SETB_PCI_33MHZ;
1004 break;
1005 case 1:
1006 slot_cmd = SETB_PCI_66MHZ;
1007 break;
1008 case 2:
1009 slot_cmd = SETB_PCIX_66MHZ_PM;
1010 break;
1011 case 3:
1012 slot_cmd = SETB_PCIX_100MHZ_PM;
1013 break;
1014 case 4:
1015 slot_cmd = SETB_PCIX_133MHZ_PM;
1016 break;
1017 case 5:
1018 slot_cmd = SETB_PCIX_66MHZ_EM;
1019 break;
1020 case 6:
1021 slot_cmd = SETB_PCIX_100MHZ_EM;
1022 break;
1023 case 7:
1024 slot_cmd = SETB_PCIX_133MHZ_EM;
1025 break;
1026 case 8:
1027 slot_cmd = SETB_PCIX_66MHZ_266;
1028 break;
1029 case 0x9:
1030 slot_cmd = SETB_PCIX_100MHZ_266;
1031 break;
1032 case 0xa:
1033 slot_cmd = SETB_PCIX_133MHZ_266;
1034 break;
1035 case 0xb:
1036 slot_cmd = SETB_PCIX_66MHZ_533;
1037 break;
1038 case 0xc:
1039 slot_cmd = SETB_PCIX_100MHZ_533;
1040 break;
1041 case 0xd:
1042 slot_cmd = SETB_PCIX_133MHZ_533;
1043 break;
1044 default:
1045 slot_cmd = PCI_SPEED_UNKNOWN;
1046 retval = -ENODEV;
1047 return retval;
1048 }
1049
1050 }
1051 retval = shpc_write_cmd(slot, 0, slot_cmd);
1052 if (retval) {
1053 err("%s: Write command failed!\n", __FUNCTION__);
1054 return -1;
1055 }
1056
1057 DBG_LEAVE_ROUTINE
1058 return retval;
1059}
1060
1061static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
1062{
1063 struct controller *ctrl = NULL;
1064 struct php_ctlr_state_s *php_ctlr;
1065 u8 schedule_flag = 0;
1066 u8 temp_byte;
1067 u32 temp_dword, intr_loc, intr_loc2;
1068 int hp_slot;
1069
1070 if (!dev_id)
1071 return IRQ_NONE;
1072
1073 if (!shpchp_poll_mode) {
1074 ctrl = (struct controller *)dev_id;
1075 php_ctlr = ctrl->hpc_ctlr_handle;
1076 } else {
1077 php_ctlr = (struct php_ctlr_state_s *) dev_id;
1078 ctrl = (struct controller *)php_ctlr->callback_instance_id;
1079 }
1080
1081 if (!ctrl)
1082 return IRQ_NONE;
1083
1084 if (!php_ctlr || !php_ctlr->creg)
1085 return IRQ_NONE;
1086
1087 /* Check to see if it was our interrupt */
1088 intr_loc = readl(php_ctlr->creg + INTR_LOC);
1089
1090 if (!intr_loc)
1091 return IRQ_NONE;
1092 dbg("%s: shpc_isr proceeds\n", __FUNCTION__);
1093 dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc);
1094
1095 if(!shpchp_poll_mode) {
1096 /* Mask Global Interrupt Mask - see implementation note on p. 139 */
1097 /* of SHPC spec rev 1.0*/
1098 temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1099 dbg("%s: Before masking global interrupt, temp_dword = %x\n",
1100 __FUNCTION__, temp_dword);
1101 temp_dword |= 0x00000001;
1102 dbg("%s: After masking global interrupt, temp_dword = %x\n",
1103 __FUNCTION__, temp_dword);
1104 writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
1105
1106 intr_loc2 = readl(php_ctlr->creg + INTR_LOC);
1107 dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2);
1108 }
1109
1110 if (intr_loc & 0x0001) {
1111 /*
1112 * Command Complete Interrupt Pending
1113 * RO only - clear by writing 0 to the Command Completion
1114 * Detect bit in Controller SERR-INT register
1115 */
1116 temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1117 dbg("%s: Before clearing CCIP, temp_dword = %x\n",
1118 __FUNCTION__, temp_dword);
1119 temp_dword &= 0xfffeffff;
1120 dbg("%s: After clearing CCIP, temp_dword = %x\n",
1121 __FUNCTION__, temp_dword);
1122 writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
1123 wake_up_interruptible(&ctrl->queue);
1124 }
1125
1126 if ((intr_loc = (intr_loc >> 1)) == 0) {
1127 /* Unmask Global Interrupt Mask */
1128 temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1129 dbg("%s: 1-Before unmasking global interrupt, temp_dword = %x\n",
1130 __FUNCTION__, temp_dword);
1131 temp_dword &= 0xfffffffe;
1132 dbg("%s: 1-After unmasking global interrupt, temp_dword = %x\n",
1133 __FUNCTION__, temp_dword);
1134 writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
1135
1136 return IRQ_NONE;
1137 }
1138
1139 for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) {
1140 /* To find out which slot has interrupt pending */
1141 if ((intr_loc >> hp_slot) & 0x01) {
1142 temp_dword = readl(php_ctlr->creg + SLOT1 + (4*hp_slot));
1143 dbg("%s: Slot %x with intr, temp_dword = %x\n",
1144 __FUNCTION__, hp_slot, temp_dword);
1145 temp_byte = (temp_dword >> 16) & 0xFF;
1146 dbg("%s: Slot with intr, temp_byte = %x\n",
1147 __FUNCTION__, temp_byte);
1148 if ((php_ctlr->switch_change_callback) && (temp_byte & 0x08))
1149 schedule_flag += php_ctlr->switch_change_callback(
1150 hp_slot, php_ctlr->callback_instance_id);
1151 if ((php_ctlr->attention_button_callback) && (temp_byte & 0x04))
1152 schedule_flag += php_ctlr->attention_button_callback(
1153 hp_slot, php_ctlr->callback_instance_id);
1154 if ((php_ctlr->presence_change_callback) && (temp_byte & 0x01))
1155 schedule_flag += php_ctlr->presence_change_callback(
1156 hp_slot , php_ctlr->callback_instance_id);
1157 if ((php_ctlr->power_fault_callback) && (temp_byte & 0x12))
1158 schedule_flag += php_ctlr->power_fault_callback(
1159 hp_slot, php_ctlr->callback_instance_id);
1160
1161 /* Clear all slot events */
1162 temp_dword = 0xe01f3fff;
1163 dbg("%s: Clearing slot events, temp_dword = %x\n",
1164 __FUNCTION__, temp_dword);
1165 writel(temp_dword, php_ctlr->creg + SLOT1 + (4*hp_slot));
1166
1167 intr_loc2 = readl(php_ctlr->creg + INTR_LOC);
1168 dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2);
1169 }
1170 }
1171 if (!shpchp_poll_mode) {
1172 /* Unmask Global Interrupt Mask */
1173 temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1174 dbg("%s: 2-Before unmasking global interrupt, temp_dword = %x\n",
1175 __FUNCTION__, temp_dword);
1176 temp_dword &= 0xfffffffe;
1177 dbg("%s: 2-After unmasking global interrupt, temp_dword = %x\n",
1178 __FUNCTION__, temp_dword);
1179 writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
1180 }
1181
1182 return IRQ_HANDLED;
1183}
1184
1185static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value)
1186{
1187 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
1188 enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN;
1189 int retval = 0;
1190 u8 pi;
1191 u32 slot_avail1, slot_avail2;
1192 int slot_num;
1193
1194 DBG_ENTER_ROUTINE
1195
1196 if (!slot->ctrl->hpc_ctlr_handle) {
1197 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
1198 return -1;
1199 }
1200
1201 if (slot->hp_slot >= php_ctlr->num_slots) {
1202 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
1203 return -1;
1204 }
1205
1206 pi = readb(php_ctlr->creg + PROG_INTERFACE);
1207 slot_avail1 = readl(php_ctlr->creg + SLOT_AVAIL1);
1208 slot_avail2 = readl(php_ctlr->creg + SLOT_AVAIL2);
1209
1210 if (pi == 2) {
1211 if ((slot_num = ((slot_avail2 & SLOT_133MHZ_PCIX_533) >> 27) ) != 0 )
1212 bus_speed = PCIX_133MHZ_533;
1213 else if ((slot_num = ((slot_avail2 & SLOT_100MHZ_PCIX_533) >> 23) ) != 0 )
1214 bus_speed = PCIX_100MHZ_533;
1215 else if ((slot_num = ((slot_avail2 & SLOT_66MHZ_PCIX_533) >> 19) ) != 0 )
1216 bus_speed = PCIX_66MHZ_533;
1217 else if ((slot_num = ((slot_avail2 & SLOT_133MHZ_PCIX_266) >> 15) ) != 0 )
1218 bus_speed = PCIX_133MHZ_266;
1219 else if ((slot_num = ((slot_avail2 & SLOT_100MHZ_PCIX_266) >> 11) ) != 0 )
1220 bus_speed = PCIX_100MHZ_266;
1221 else if ((slot_num = ((slot_avail2 & SLOT_66MHZ_PCIX_266) >> 7) ) != 0 )
1222 bus_speed = PCIX_66MHZ_266;
1223 else if ((slot_num = ((slot_avail1 & SLOT_133MHZ_PCIX) >> 23) ) != 0 )
1224 bus_speed = PCIX_133MHZ;
1225 else if ((slot_num = ((slot_avail1 & SLOT_100MHZ_PCIX) >> 15) ) != 0 )
1226 bus_speed = PCIX_100MHZ;
1227 else if ((slot_num = ((slot_avail1 & SLOT_66MHZ_PCIX) >> 7) ) != 0 )
1228 bus_speed = PCIX_66MHZ;
1229 else if ((slot_num = (slot_avail2 & SLOT_66MHZ)) != 0 )
1230 bus_speed = PCI_66MHZ;
1231 else if ((slot_num = (slot_avail1 & SLOT_33MHZ)) != 0 )
1232 bus_speed = PCI_33MHZ;
1233 else bus_speed = PCI_SPEED_UNKNOWN;
1234 } else {
1235 if ((slot_num = ((slot_avail1 & SLOT_133MHZ_PCIX) >> 23) ) != 0 )
1236 bus_speed = PCIX_133MHZ;
1237 else if ((slot_num = ((slot_avail1 & SLOT_100MHZ_PCIX) >> 15) ) != 0 )
1238 bus_speed = PCIX_100MHZ;
1239 else if ((slot_num = ((slot_avail1 & SLOT_66MHZ_PCIX) >> 7) ) != 0 )
1240 bus_speed = PCIX_66MHZ;
1241 else if ((slot_num = (slot_avail2 & SLOT_66MHZ)) != 0 )
1242 bus_speed = PCI_66MHZ;
1243 else if ((slot_num = (slot_avail1 & SLOT_33MHZ)) != 0 )
1244 bus_speed = PCI_33MHZ;
1245 else bus_speed = PCI_SPEED_UNKNOWN;
1246 }
1247
1248 *value = bus_speed;
1249 dbg("Max bus speed = %d\n", bus_speed);
1250 DBG_LEAVE_ROUTINE
1251 return retval;
1252}
1253
1254static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value)
1255{
1256 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
1257 enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN;
1258 u16 sec_bus_status;
1259 int retval = 0;
1260 u8 pi;
1261
1262 DBG_ENTER_ROUTINE
1263
1264 if (!slot->ctrl->hpc_ctlr_handle) {
1265 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
1266 return -1;
1267 }
1268
1269 if (slot->hp_slot >= php_ctlr->num_slots) {
1270 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
1271 return -1;
1272 }
1273
1274 pi = readb(php_ctlr->creg + PROG_INTERFACE);
1275 sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG);
1276
1277 if (pi == 2) {
1278 switch (sec_bus_status & 0x000f) {
1279 case 0:
1280 bus_speed = PCI_SPEED_33MHz;
1281 break;
1282 case 1:
1283 bus_speed = PCI_SPEED_66MHz;
1284 break;
1285 case 2:
1286 bus_speed = PCI_SPEED_66MHz_PCIX;
1287 break;
1288 case 3:
1289 bus_speed = PCI_SPEED_100MHz_PCIX;
1290 break;
1291 case 4:
1292 bus_speed = PCI_SPEED_133MHz_PCIX;
1293 break;
1294 case 5:
1295 bus_speed = PCI_SPEED_66MHz_PCIX_ECC;
1296 break;
1297 case 6:
1298 bus_speed = PCI_SPEED_100MHz_PCIX_ECC;
1299 break;
1300 case 7:
1301 bus_speed = PCI_SPEED_133MHz_PCIX_ECC;
1302 break;
1303 case 8:
1304 bus_speed = PCI_SPEED_66MHz_PCIX_266;
1305 break;
1306 case 9:
1307 bus_speed = PCI_SPEED_100MHz_PCIX_266;
1308 break;
1309 case 0xa:
1310 bus_speed = PCI_SPEED_133MHz_PCIX_266;
1311 break;
1312 case 0xb:
1313 bus_speed = PCI_SPEED_66MHz_PCIX_533;
1314 break;
1315 case 0xc:
1316 bus_speed = PCI_SPEED_100MHz_PCIX_533;
1317 break;
1318 case 0xd:
1319 bus_speed = PCI_SPEED_133MHz_PCIX_533;
1320 break;
1321 case 0xe:
1322 case 0xf:
1323 default:
1324 bus_speed = PCI_SPEED_UNKNOWN;
1325 break;
1326 }
1327 } else {
1328 /* In the case where pi is undefined, default it to 1 */
1329 switch (sec_bus_status & 0x0007) {
1330 case 0:
1331 bus_speed = PCI_SPEED_33MHz;
1332 break;
1333 case 1:
1334 bus_speed = PCI_SPEED_66MHz;
1335 break;
1336 case 2:
1337 bus_speed = PCI_SPEED_66MHz_PCIX;
1338 break;
1339 case 3:
1340 bus_speed = PCI_SPEED_100MHz_PCIX;
1341 break;
1342 case 4:
1343 bus_speed = PCI_SPEED_133MHz_PCIX;
1344 break;
1345 case 5:
1346 bus_speed = PCI_SPEED_UNKNOWN; /* Reserved */
1347 break;
1348 case 6:
1349 bus_speed = PCI_SPEED_UNKNOWN; /* Reserved */
1350 break;
1351 case 7:
1352 bus_speed = PCI_SPEED_UNKNOWN; /* Reserved */
1353 break;
1354 default:
1355 bus_speed = PCI_SPEED_UNKNOWN;
1356 break;
1357 }
1358 }
1359
1360 *value = bus_speed;
1361 dbg("Current bus speed = %d\n", bus_speed);
1362 DBG_LEAVE_ROUTINE
1363 return retval;
1364}
1365
1366static struct hpc_ops shpchp_hpc_ops = {
1367 .power_on_slot = hpc_power_on_slot,
1368 .slot_enable = hpc_slot_enable,
1369 .slot_disable = hpc_slot_disable,
1370 .enable_all_slots = hpc_enable_all_slots,
1371 .pwr_on_all_slots = hpc_pwr_on_all_slots,
1372 .set_bus_speed_mode = hpc_set_bus_speed_mode,
1373 .set_attention_status = hpc_set_attention_status,
1374 .get_power_status = hpc_get_power_status,
1375 .get_attention_status = hpc_get_attention_status,
1376 .get_latch_status = hpc_get_latch_status,
1377 .get_adapter_status = hpc_get_adapter_status,
1378
1379 .get_max_bus_speed = hpc_get_max_bus_speed,
1380 .get_cur_bus_speed = hpc_get_cur_bus_speed,
1381 .get_adapter_speed = hpc_get_adapter_speed,
1382 .get_mode1_ECC_cap = hpc_get_mode1_ECC_cap,
1383 .get_prog_int = hpc_get_prog_int,
1384
1385 .query_power_fault = hpc_query_power_fault,
1386 .green_led_on = hpc_set_green_led_on,
1387 .green_led_off = hpc_set_green_led_off,
1388 .green_led_blink = hpc_set_green_led_blink,
1389
1390 .release_ctlr = hpc_release_ctlr,
1391 .check_cmd_status = hpc_check_cmd_status,
1392};
1393
1394int shpc_init(struct controller * ctrl,
1395 struct pci_dev * pdev,
1396 php_intr_callback_t attention_button_callback,
1397 php_intr_callback_t switch_change_callback,
1398 php_intr_callback_t presence_change_callback,
1399 php_intr_callback_t power_fault_callback)
1400{
1401 struct php_ctlr_state_s *php_ctlr, *p;
1402 void *instance_id = ctrl;
1403 int rc;
1404 u8 hp_slot;
1405 static int first = 1;
1406 u32 shpc_cap_offset, shpc_base_offset;
1407 u32 tempdword, slot_reg;
1408 u16 vendor_id, device_id;
1409 u8 i;
1410
1411 DBG_ENTER_ROUTINE
1412
1413 spin_lock_init(&list_lock);
1414 php_ctlr = (struct php_ctlr_state_s *) kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL);
1415
1416 if (!php_ctlr) { /* allocate controller state data */
1417 err("%s: HPC controller memory allocation error!\n", __FUNCTION__);
1418 goto abort;
1419 }
1420
1421 memset(php_ctlr, 0, sizeof(struct php_ctlr_state_s));
1422
1423 php_ctlr->pci_dev = pdev; /* save pci_dev in context */
1424
1425 rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id);
1426 dbg("%s: Vendor ID: %x\n",__FUNCTION__, vendor_id);
1427 if (rc) {
1428 err("%s: unable to read PCI configuration data\n", __FUNCTION__);
1429 goto abort_free_ctlr;
1430 }
1431
1432 rc = pci_read_config_word(pdev, PCI_DEVICE_ID, &device_id);
1433 dbg("%s: Device ID: %x\n",__FUNCTION__, device_id);
1434 if (rc) {
1435 err("%s: unable to read PCI configuration data\n", __FUNCTION__);
1436 goto abort_free_ctlr;
1437 }
1438
1439 if ((vendor_id == PCI_VENDOR_ID_AMD) || (device_id == PCI_DEVICE_ID_AMD_GOLAM_7450)) {
1440 shpc_base_offset = 0; /* amd shpc driver doesn't use this; assume 0 */
1441 } else {
1442 if ((shpc_cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC)) == 0) {
1443 err("%s : shpc_cap_offset == 0\n", __FUNCTION__);
1444 goto abort_free_ctlr;
1445 }
1446 dbg("%s: shpc_cap_offset = %x\n", __FUNCTION__, shpc_cap_offset);
1447
1448 rc = pci_write_config_byte(pdev, (u8)shpc_cap_offset + DWORD_SELECT , BASE_OFFSET);
1449 if (rc) {
1450 err("%s : pci_word_config_byte failed\n", __FUNCTION__);
1451 goto abort_free_ctlr;
1452 }
1453
1454 rc = pci_read_config_dword(pdev, (u8)shpc_cap_offset + DWORD_DATA, &shpc_base_offset);
1455 if (rc) {
1456 err("%s : pci_read_config_dword failed\n", __FUNCTION__);
1457 goto abort_free_ctlr;
1458 }
1459
1460 for (i = 0; i <= 14; i++) {
1461 rc = pci_write_config_byte(pdev, (u8)shpc_cap_offset + DWORD_SELECT , i);
1462 if (rc) {
1463 err("%s : pci_word_config_byte failed\n", __FUNCTION__);
1464 goto abort_free_ctlr;
1465 }
1466
1467 rc = pci_read_config_dword(pdev, (u8)shpc_cap_offset + DWORD_DATA, &tempdword);
1468 if (rc) {
1469 err("%s : pci_read_config_dword failed\n", __FUNCTION__);
1470 goto abort_free_ctlr;
1471 }
1472 dbg("%s: offset %d: tempdword %x\n", __FUNCTION__,i, tempdword);
1473 }
1474 }
1475
1476 if (first) {
1477 spin_lock_init(&hpc_event_lock);
1478 first = 0;
1479 }
1480
1481 dbg("pdev = %p: b:d:f:irq=0x%x:%x:%x:%x\n", pdev, pdev->bus->number, PCI_SLOT(pdev->devfn),
1482 PCI_FUNC(pdev->devfn), pdev->irq);
1483 for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
1484 if (pci_resource_len(pdev, rc) > 0)
1485 dbg("pci resource[%d] start=0x%lx(len=0x%lx), shpc_base_offset %x\n", rc,
1486 pci_resource_start(pdev, rc), pci_resource_len(pdev, rc), shpc_base_offset);
1487
1488 info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor,
1489 pdev->subsystem_device);
1490
1491 if (pci_enable_device(pdev))
1492 goto abort_free_ctlr;
1493
1494 if (!request_mem_region(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0), MY_NAME)) {
1495 err("%s: cannot reserve MMIO region\n", __FUNCTION__);
1496 goto abort_free_ctlr;
1497 }
1498
1499 php_ctlr->creg = ioremap(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0));
1500 if (!php_ctlr->creg) {
1501 err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, pci_resource_len(pdev, 0),
1502 pci_resource_start(pdev, 0) + shpc_base_offset);
1503 release_mem_region(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0));
1504 goto abort_free_ctlr;
1505 }
1506 dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
1507 dbg("%s: physical addr %p\n", __FUNCTION__, (void*)pci_resource_start(pdev, 0));
1508
1509 init_MUTEX(&ctrl->crit_sect);
1510 /* Setup wait queue */
1511 init_waitqueue_head(&ctrl->queue);
1512
1513 /* Find the IRQ */
1514 php_ctlr->irq = pdev->irq;
1515 dbg("HPC interrupt = %d\n", php_ctlr->irq);
1516
1517 /* Save interrupt callback info */
1518 php_ctlr->attention_button_callback = attention_button_callback;
1519 php_ctlr->switch_change_callback = switch_change_callback;
1520 php_ctlr->presence_change_callback = presence_change_callback;
1521 php_ctlr->power_fault_callback = power_fault_callback;
1522 php_ctlr->callback_instance_id = instance_id;
1523
1524 /* Return PCI Controller Info */
1525 php_ctlr->slot_device_offset = (readl(php_ctlr->creg + SLOT_CONFIG) & FIRST_DEV_NUM ) >> 8;
1526 php_ctlr->num_slots = readl(php_ctlr->creg + SLOT_CONFIG) & SLOT_NUM;
1527 dbg("%s: slot_device_offset %x\n", __FUNCTION__, php_ctlr->slot_device_offset);
1528 dbg("%s: num_slots %x\n", __FUNCTION__, php_ctlr->num_slots);
1529
1530 /* Mask Global Interrupt Mask & Command Complete Interrupt Mask */
1531 tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1532 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);
1533 tempdword = 0x0003000f;
1534 writel(tempdword, php_ctlr->creg + SERR_INTR_ENABLE);
1535 tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1536 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);
1537
1538 /* Mask the MRL sensor SERR Mask of individual slot in
1539 * Slot SERR-INT Mask & clear all the existing event if any
1540 */
1541 for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) {
1542 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*hp_slot );
1543 dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__,
1544 hp_slot, slot_reg);
1545 tempdword = 0xffff3fff;
1546 writel(tempdword, php_ctlr->creg + SLOT1 + (4*hp_slot));
1547 }
1548
1549 if (shpchp_poll_mode) {/* Install interrupt polling code */
1550 /* Install and start the interrupt polling timer */
1551 init_timer(&php_ctlr->int_poll_timer);
1552 start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */
1553 } else {
1554 /* Installs the interrupt handler */
1555 rc = pci_enable_msi(pdev);
1556 if (rc) {
1557 info("Can't get msi for the hotplug controller\n");
1558 info("Use INTx for the hotplug controller\n");
1559 dbg("%s: rc = %x\n", __FUNCTION__, rc);
1560 } else
1561 php_ctlr->irq = pdev->irq;
1562
1563 rc = request_irq(php_ctlr->irq, shpc_isr, SA_SHIRQ, MY_NAME, (void *) ctrl);
1564 dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
1565 if (rc) {
1566 err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq);
1567 goto abort_free_ctlr;
1568 }
1569 /* Execute OSHP method here */
1570 }
1571 dbg("%s: Before adding HPC to HPC list\n", __FUNCTION__);
1572
1573 /* Add this HPC instance into the HPC list */
1574 spin_lock(&list_lock);
1575 if (php_ctlr_list_head == 0) {
1576 php_ctlr_list_head = php_ctlr;
1577 p = php_ctlr_list_head;
1578 p->pnext = NULL;
1579 } else {
1580 p = php_ctlr_list_head;
1581
1582 while (p->pnext)
1583 p = p->pnext;
1584
1585 p->pnext = php_ctlr;
1586 }
1587 spin_unlock(&list_lock);
1588
1589
1590 ctlr_seq_num++;
1591 ctrl->hpc_ctlr_handle = php_ctlr;
1592 ctrl->hpc_ops = &shpchp_hpc_ops;
1593
1594 for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) {
1595 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*hp_slot );
1596 dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__,
1597 hp_slot, slot_reg);
1598 tempdword = 0xe01f3fff;
1599 writel(tempdword, php_ctlr->creg + SLOT1 + (4*hp_slot));
1600 }
1601 if (!shpchp_poll_mode) {
1602 /* Unmask all general input interrupts and SERR */
1603 tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1604 tempdword = 0x0000000a;
1605 writel(tempdword, php_ctlr->creg + SERR_INTR_ENABLE);
1606 tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1607 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);
1608 }
1609
1610 dbg("%s: Leaving shpc_init\n", __FUNCTION__);
1611 DBG_LEAVE_ROUTINE
1612 return 0;
1613
1614 /* We end up here for the many possible ways to fail this API. */
1615abort_free_ctlr:
1616 kfree(php_ctlr);
1617abort:
1618 DBG_LEAVE_ROUTINE
1619 return -1;
1620}
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
new file mode 100644
index 000000000000..90113e9cd69b
--- /dev/null
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -0,0 +1,810 @@
1/*
2 * Standard Hot Plug Controller Driver
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/types.h>
34#include <linux/slab.h>
35#include <linux/workqueue.h>
36#include <linux/proc_fs.h>
37#include <linux/pci.h>
38#include "../pci.h"
39#include "shpchp.h"
40#ifndef CONFIG_IA64
41#include "../../../arch/i386/pci/pci.h" /* horrible hack showing how processor dependant we are... */
42#endif
43
44int shpchp_configure_device (struct controller* ctrl, struct pci_func* func)
45{
46 unsigned char bus;
47 struct pci_bus *child;
48 int num;
49
50 if (func->pci_dev == NULL)
51 func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
52
53 /* Still NULL ? Well then scan for it ! */
54 if (func->pci_dev == NULL) {
55 num = pci_scan_slot(ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function));
56 if (num) {
57 dbg("%s: subordiante %p number %x\n", __FUNCTION__, ctrl->pci_dev->subordinate,
58 ctrl->pci_dev->subordinate->number);
59 pci_bus_add_devices(ctrl->pci_dev->subordinate);
60 }
61
62 func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
63 if (func->pci_dev == NULL) {
64 dbg("ERROR: pci_dev still null\n");
65 return 0;
66 }
67 }
68
69 if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
70 pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus);
71 child = pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus);
72 pci_do_scan_bus(child);
73
74 }
75
76 return 0;
77}
78
79
80int shpchp_unconfigure_device(struct pci_func* func)
81{
82 int rc = 0;
83 int j;
84
85 dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus,
86 func->device, func->function);
87
88 for (j=0; j<8 ; j++) {
89 struct pci_dev* temp = pci_find_slot(func->bus,
90 (func->device << 3) | j);
91 if (temp) {
92 pci_remove_bus_device(temp);
93 }
94 }
95 return rc;
96}
97
98/*
99 * shpchp_set_irq
100 *
101 * @bus_num: bus number of PCI device
102 * @dev_num: device number of PCI device
103 * @slot: pointer to u8 where slot number will be returned
104 */
105int shpchp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
106{
107#if defined(CONFIG_X86) && !defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_64)
108 int rc;
109 u16 temp_word;
110 struct pci_dev fakedev;
111 struct pci_bus fakebus;
112
113 fakedev.devfn = dev_num << 3;
114 fakedev.bus = &fakebus;
115 fakebus.number = bus_num;
116 dbg("%s: dev %d, bus %d, pin %d, num %d\n",
117 __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
118 rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
119 dbg("%s: rc %d\n", __FUNCTION__, rc);
120 if (!rc)
121 return !rc;
122
123 /* set the Edge Level Control Register (ELCR) */
124 temp_word = inb(0x4d0);
125 temp_word |= inb(0x4d1) << 8;
126
127 temp_word |= 0x01 << irq_num;
128
129 /* This should only be for x86 as it sets the Edge Level Control Register */
130 outb((u8) (temp_word & 0xFF), 0x4d0);
131 outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1);
132#endif
133 return 0;
134}
135
136/* More PCI configuration routines; this time centered around hotplug controller */
137
138
139/*
140 * shpchp_save_config
141 *
142 * Reads configuration for all slots in a PCI bus and saves info.
143 *
144 * Note: For non-hot plug busses, the slot # saved is the device #
145 *
146 * returns 0 if success
147 */
148int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num)
149{
150 int rc;
151 u8 class_code;
152 u8 header_type;
153 u32 ID;
154 u8 secondary_bus;
155 struct pci_func *new_slot;
156 int sub_bus;
157 int FirstSupported;
158 int LastSupported;
159 int max_functions;
160 int function;
161 u8 DevError;
162 int device = 0;
163 int cloop = 0;
164 int stop_it;
165 int index;
166 int is_hot_plug = num_ctlr_slots || first_device_num;
167 struct pci_bus lpci_bus, *pci_bus;
168
169 dbg("%s: num_ctlr_slots = %d, first_device_num = %d\n", __FUNCTION__,
170 num_ctlr_slots, first_device_num);
171
172 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
173 pci_bus = &lpci_bus;
174
175 dbg("%s: num_ctlr_slots = %d, first_device_num = %d\n", __FUNCTION__,
176 num_ctlr_slots, first_device_num);
177
178 /* Decide which slots are supported */
179 if (is_hot_plug) {
180 /*********************************
181 * is_hot_plug is the slot mask
182 *********************************/
183 FirstSupported = first_device_num;
184 LastSupported = FirstSupported + num_ctlr_slots - 1;
185 } else {
186 FirstSupported = 0;
187 LastSupported = 0x1F;
188 }
189
190 dbg("FirstSupported = %d, LastSupported = %d\n", FirstSupported,
191 LastSupported);
192
193 /* Save PCI configuration space for all devices in supported slots */
194 pci_bus->number = busnumber;
195 for (device = FirstSupported; device <= LastSupported; device++) {
196 ID = 0xFFFFFFFF;
197 rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0),
198 PCI_VENDOR_ID, &ID);
199
200 if (ID != 0xFFFFFFFF) { /* device in slot */
201 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
202 0x0B, &class_code);
203 if (rc)
204 return rc;
205
206 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
207 PCI_HEADER_TYPE, &header_type);
208 if (rc)
209 return rc;
210
211 dbg("class_code = %x, header_type = %x\n", class_code, header_type);
212
213 /* If multi-function device, set max_functions to 8 */
214 if (header_type & 0x80)
215 max_functions = 8;
216 else
217 max_functions = 1;
218
219 function = 0;
220
221 do {
222 DevError = 0;
223
224 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* P-P Bridge */
225 /* Recurse the subordinate bus
226 * get the subordinate bus number
227 */
228 rc = pci_bus_read_config_byte(pci_bus,
229 PCI_DEVFN(device, function),
230 PCI_SECONDARY_BUS, &secondary_bus);
231 if (rc) {
232 return rc;
233 } else {
234 sub_bus = (int) secondary_bus;
235
236 /* Save secondary bus cfg spc with this recursive call. */
237 rc = shpchp_save_config(ctrl, sub_bus, 0, 0);
238 if (rc)
239 return rc;
240 }
241 }
242
243 index = 0;
244 new_slot = shpchp_slot_find(busnumber, device, index++);
245
246 dbg("new_slot = %p\n", new_slot);
247
248 while (new_slot && (new_slot->function != (u8) function)) {
249 new_slot = shpchp_slot_find(busnumber, device, index++);
250 dbg("new_slot = %p\n", new_slot);
251 }
252 if (!new_slot) {
253 /* Setup slot structure. */
254 new_slot = shpchp_slot_create(busnumber);
255 dbg("new_slot = %p\n", new_slot);
256
257 if (new_slot == NULL)
258 return(1);
259 }
260
261 new_slot->bus = (u8) busnumber;
262 new_slot->device = (u8) device;
263 new_slot->function = (u8) function;
264 new_slot->is_a_board = 1;
265 new_slot->switch_save = 0x10;
266 new_slot->pwr_save = 1;
267 /* In case of unsupported board */
268 new_slot->status = DevError;
269 new_slot->pci_dev = pci_find_slot(new_slot->bus,
270 (new_slot->device << 3) | new_slot->function);
271 dbg("new_slot->pci_dev = %p\n", new_slot->pci_dev);
272
273 for (cloop = 0; cloop < 0x20; cloop++) {
274 rc = pci_bus_read_config_dword(pci_bus,
275 PCI_DEVFN(device, function),
276 cloop << 2,
277 (u32 *) &(new_slot->config_space [cloop]));
278 /* dbg("new_slot->config_space[%x] = %x\n",
279 cloop, new_slot->config_space[cloop]); */
280 if (rc)
281 return rc;
282 }
283
284 function++;
285
286 stop_it = 0;
287
288 /* this loop skips to the next present function
289 * reading in Class Code and Header type.
290 */
291
292 while ((function < max_functions)&&(!stop_it)) {
293 rc = pci_bus_read_config_dword(pci_bus,
294 PCI_DEVFN(device, function),
295 PCI_VENDOR_ID, &ID);
296
297 if (ID == 0xFFFFFFFF) { /* nothing there. */
298 function++;
299 dbg("Nothing there\n");
300 } else { /* Something there */
301 rc = pci_bus_read_config_byte(pci_bus,
302 PCI_DEVFN(device, function),
303 0x0B, &class_code);
304 if (rc)
305 return rc;
306
307 rc = pci_bus_read_config_byte(pci_bus,
308 PCI_DEVFN(device, function),
309 PCI_HEADER_TYPE, &header_type);
310 if (rc)
311 return rc;
312
313 dbg("class_code = %x, header_type = %x\n",
314 class_code, header_type);
315 stop_it++;
316 }
317 }
318
319 } while (function < max_functions);
320 /* End of IF (device in slot?) */
321 } else if (is_hot_plug) {
322 /* Setup slot structure with entry for empty slot */
323 new_slot = shpchp_slot_create(busnumber);
324
325 if (new_slot == NULL) {
326 return(1);
327 }
328 dbg("new_slot = %p\n", new_slot);
329
330 new_slot->bus = (u8) busnumber;
331 new_slot->device = (u8) device;
332 new_slot->function = 0;
333 new_slot->is_a_board = 0;
334 new_slot->presence_save = 0;
335 new_slot->switch_save = 0;
336 }
337 } /* End of FOR loop */
338
339 return(0);
340}
341
342
343/*
344 * shpchp_save_slot_config
345 *
346 * Saves configuration info for all PCI devices in a given slot
347 * including subordinate busses.
348 *
349 * returns 0 if success
350 */
351int shpchp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot)
352{
353 int rc;
354 u8 class_code;
355 u8 header_type;
356 u32 ID;
357 u8 secondary_bus;
358 int sub_bus;
359 int max_functions;
360 int function;
361 int cloop = 0;
362 int stop_it;
363 struct pci_bus lpci_bus, *pci_bus;
364 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
365 pci_bus = &lpci_bus;
366 pci_bus->number = new_slot->bus;
367
368 ID = 0xFFFFFFFF;
369
370 pci_bus_read_config_dword(pci_bus, PCI_DEVFN(new_slot->device, 0),
371 PCI_VENDOR_ID, &ID);
372
373 if (ID != 0xFFFFFFFF) { /* device in slot */
374 pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0),
375 0x0B, &class_code);
376
377 pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0),
378 PCI_HEADER_TYPE, &header_type);
379
380 if (header_type & 0x80) /* Multi-function device */
381 max_functions = 8;
382 else
383 max_functions = 1;
384
385 function = 0;
386
387 do {
388 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
389 /* Recurse the subordinate bus */
390 pci_bus_read_config_byte(pci_bus,
391 PCI_DEVFN(new_slot->device, function),
392 PCI_SECONDARY_BUS, &secondary_bus);
393
394 sub_bus = (int) secondary_bus;
395
396 /* Save the config headers for the secondary bus. */
397 rc = shpchp_save_config(ctrl, sub_bus, 0, 0);
398
399 if (rc)
400 return rc;
401
402 } /* End of IF */
403
404 new_slot->status = 0;
405
406 for (cloop = 0; cloop < 0x20; cloop++) {
407 pci_bus_read_config_dword(pci_bus,
408 PCI_DEVFN(new_slot->device, function),
409 cloop << 2,
410 (u32 *) &(new_slot->config_space [cloop]));
411 }
412
413 function++;
414
415 stop_it = 0;
416
417 /* this loop skips to the next present function
418 * reading in the Class Code and the Header type.
419 */
420
421 while ((function < max_functions) && (!stop_it)) {
422 pci_bus_read_config_dword(pci_bus,
423 PCI_DEVFN(new_slot->device, function),
424 PCI_VENDOR_ID, &ID);
425
426 if (ID == 0xFFFFFFFF) { /* nothing there. */
427 function++;
428 } else { /* Something there */
429 pci_bus_read_config_byte(pci_bus,
430 PCI_DEVFN(new_slot->device, function),
431 0x0B, &class_code);
432
433 pci_bus_read_config_byte(pci_bus,
434 PCI_DEVFN(new_slot->device, function),
435 PCI_HEADER_TYPE, &header_type);
436
437 stop_it++;
438 }
439 }
440
441 } while (function < max_functions);
442 } /* End of IF (device in slot?) */
443 else {
444 return 2;
445 }
446
447 return 0;
448}
449
450
451/*
452 * shpchp_save_used_resources
453 *
454 * Stores used resource information for existing boards. this is
455 * for boards that were in the system when this driver was loaded.
456 * this function is for hot plug ADD
457 *
458 * returns 0 if success
459 * if disable == 1(DISABLE_CARD),
460 * it loops for all functions of the slot and disables them.
461 * else, it just get resources of the function and return.
462 */
463int shpchp_save_used_resources(struct controller *ctrl, struct pci_func *func, int disable)
464{
465 u8 cloop;
466 u8 header_type;
467 u8 secondary_bus;
468 u8 temp_byte;
469 u16 command;
470 u16 save_command;
471 u16 w_base, w_length;
472 u32 temp_register;
473 u32 save_base;
474 u32 base, length;
475 u64 base64 = 0;
476 int index = 0;
477 unsigned int devfn;
478 struct pci_resource *mem_node = NULL;
479 struct pci_resource *p_mem_node = NULL;
480 struct pci_resource *t_mem_node;
481 struct pci_resource *io_node;
482 struct pci_resource *bus_node;
483 struct pci_bus lpci_bus, *pci_bus;
484 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
485 pci_bus = &lpci_bus;
486
487 if (disable)
488 func = shpchp_slot_find(func->bus, func->device, index++);
489
490 while ((func != NULL) && func->is_a_board) {
491 pci_bus->number = func->bus;
492 devfn = PCI_DEVFN(func->device, func->function);
493
494 /* Save the command register */
495 pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command);
496
497 if (disable) {
498 /* disable card */
499 command = 0x00;
500 pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
501 }
502
503 /* Check for Bridge */
504 pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
505
506 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
507 dbg("Save_used_res of PCI bridge b:d=0x%x:%x, sc=0x%x\n",
508 func->bus, func->device, save_command);
509 if (disable) {
510 /* Clear Bridge Control Register */
511 command = 0x00;
512 pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
513 }
514
515 pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
516 pci_bus_read_config_byte(pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte);
517
518 bus_node = kmalloc(sizeof(struct pci_resource),
519 GFP_KERNEL);
520 if (!bus_node)
521 return -ENOMEM;
522
523 bus_node->base = (ulong)secondary_bus;
524 bus_node->length = (ulong)(temp_byte - secondary_bus + 1);
525
526 bus_node->next = func->bus_head;
527 func->bus_head = bus_node;
528
529 /* Save IO base and Limit registers */
530 pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &temp_byte);
531 base = temp_byte;
532 pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &temp_byte);
533 length = temp_byte;
534
535 if ((base <= length) && (!disable || (save_command & PCI_COMMAND_IO))) {
536 io_node = kmalloc(sizeof(struct pci_resource),
537 GFP_KERNEL);
538 if (!io_node)
539 return -ENOMEM;
540
541 io_node->base = (ulong)(base & PCI_IO_RANGE_MASK) << 8;
542 io_node->length = (ulong)(length - base + 0x10) << 8;
543
544 io_node->next = func->io_head;
545 func->io_head = io_node;
546 }
547
548 /* Save memory base and Limit registers */
549 pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_BASE, &w_base);
550 pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length);
551
552 if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
553 mem_node = kmalloc(sizeof(struct pci_resource),
554 GFP_KERNEL);
555 if (!mem_node)
556 return -ENOMEM;
557
558 mem_node->base = (ulong)w_base << 16;
559 mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
560
561 mem_node->next = func->mem_head;
562 func->mem_head = mem_node;
563 }
564 /* Save prefetchable memory base and Limit registers */
565 pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base);
566 pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length);
567
568 if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
569 p_mem_node = kmalloc(sizeof(struct pci_resource),
570 GFP_KERNEL);
571 if (!p_mem_node)
572 return -ENOMEM;
573
574 p_mem_node->base = (ulong)w_base << 16;
575 p_mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
576
577 p_mem_node->next = func->p_mem_head;
578 func->p_mem_head = p_mem_node;
579 }
580 } else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
581 dbg("Save_used_res of PCI adapter b:d=0x%x:%x, sc=0x%x\n",
582 func->bus, func->device, save_command);
583
584 /* Figure out IO and memory base lengths */
585 for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
586 pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base);
587
588 temp_register = 0xFFFFFFFF;
589 pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
590 pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
591
592 if (!disable)
593 pci_bus_write_config_dword(pci_bus, devfn, cloop, save_base);
594
595 if (!temp_register)
596 continue;
597
598 base = temp_register;
599
600 if ((base & PCI_BASE_ADDRESS_SPACE_IO) &&
601 (!disable || (save_command & PCI_COMMAND_IO))) {
602 /* IO base */
603 /* set temp_register = amount of IO space requested */
604 base = base & 0xFFFFFFFCL;
605 base = (~base) + 1;
606
607 io_node = kmalloc(sizeof (struct pci_resource),
608 GFP_KERNEL);
609 if (!io_node)
610 return -ENOMEM;
611
612 io_node->base = (ulong)save_base & PCI_BASE_ADDRESS_IO_MASK;
613 io_node->length = (ulong)base;
614 dbg("sur adapter: IO bar=0x%x(length=0x%x)\n",
615 io_node->base, io_node->length);
616
617 io_node->next = func->io_head;
618 func->io_head = io_node;
619 } else { /* map Memory */
620 int prefetchable = 1;
621 /* struct pci_resources **res_node; */
622 char *res_type_str = "PMEM";
623 u32 temp_register2;
624
625 t_mem_node = kmalloc(sizeof (struct pci_resource),
626 GFP_KERNEL);
627 if (!t_mem_node)
628 return -ENOMEM;
629
630 if (!(base & PCI_BASE_ADDRESS_MEM_PREFETCH) &&
631 (!disable || (save_command & PCI_COMMAND_MEMORY))) {
632 prefetchable = 0;
633 mem_node = t_mem_node;
634 res_type_str++;
635 } else
636 p_mem_node = t_mem_node;
637
638 base = base & 0xFFFFFFF0L;
639 base = (~base) + 1;
640
641 switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
642 case PCI_BASE_ADDRESS_MEM_TYPE_32:
643 if (prefetchable) {
644 p_mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
645 p_mem_node->length = (ulong)base;
646 dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n",
647 res_type_str,
648 p_mem_node->base,
649 p_mem_node->length);
650
651 p_mem_node->next = func->p_mem_head;
652 func->p_mem_head = p_mem_node;
653 } else {
654 mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
655 mem_node->length = (ulong)base;
656 dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n",
657 res_type_str,
658 mem_node->base,
659 mem_node->length);
660
661 mem_node->next = func->mem_head;
662 func->mem_head = mem_node;
663 }
664 break;
665 case PCI_BASE_ADDRESS_MEM_TYPE_64:
666 pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
667 base64 = temp_register2;
668 base64 = (base64 << 32) | save_base;
669
670 if (temp_register2) {
671 dbg("sur adapter: 64 %s high dword of base64(0x%x:%x) masked to 0\n",
672 res_type_str, temp_register2, (u32)base64);
673 base64 &= 0x00000000FFFFFFFFL;
674 }
675
676 if (prefetchable) {
677 p_mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
678 p_mem_node->length = base;
679 dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n",
680 res_type_str,
681 p_mem_node->base,
682 p_mem_node->length);
683
684 p_mem_node->next = func->p_mem_head;
685 func->p_mem_head = p_mem_node;
686 } else {
687 mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
688 mem_node->length = base;
689 dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n",
690 res_type_str,
691 mem_node->base,
692 mem_node->length);
693
694 mem_node->next = func->mem_head;
695 func->mem_head = mem_node;
696 }
697 cloop += 4;
698 break;
699 default:
700 dbg("asur: reserved BAR type=0x%x\n",
701 temp_register);
702 break;
703 }
704 }
705 } /* End of base register loop */
706 } else { /* Some other unknown header type */
707 dbg("Save_used_res of PCI unknown type b:d=0x%x:%x. skip.\n",
708 func->bus, func->device);
709 }
710
711 /* find the next device in this slot */
712 if (!disable)
713 break;
714 func = shpchp_slot_find(func->bus, func->device, index++);
715 }
716
717 return 0;
718}
719
720/**
721 * kfree_resource_list: release memory of all list members
722 * @res: resource list to free
723 */
724static inline void
725return_resource_list(struct pci_resource **func, struct pci_resource **res)
726{
727 struct pci_resource *node;
728 struct pci_resource *t_node;
729
730 node = *func;
731 *func = NULL;
732 while (node) {
733 t_node = node->next;
734 return_resource(res, node);
735 node = t_node;
736 }
737}
738
739/*
740 * shpchp_return_board_resources
741 *
742 * this routine returns all resources allocated to a board to
743 * the available pool.
744 *
745 * returns 0 if success
746 */
747int shpchp_return_board_resources(struct pci_func * func,
748 struct resource_lists * resources)
749{
750 int rc;
751 dbg("%s\n", __FUNCTION__);
752
753 if (!func)
754 return 1;
755
756 return_resource_list(&(func->io_head),&(resources->io_head));
757 return_resource_list(&(func->mem_head),&(resources->mem_head));
758 return_resource_list(&(func->p_mem_head),&(resources->p_mem_head));
759 return_resource_list(&(func->bus_head),&(resources->bus_head));
760
761 rc = shpchp_resource_sort_and_combine(&(resources->mem_head));
762 rc |= shpchp_resource_sort_and_combine(&(resources->p_mem_head));
763 rc |= shpchp_resource_sort_and_combine(&(resources->io_head));
764 rc |= shpchp_resource_sort_and_combine(&(resources->bus_head));
765
766 return rc;
767}
768
769/**
770 * kfree_resource_list: release memory of all list members
771 * @res: resource list to free
772 */
773static inline void
774kfree_resource_list(struct pci_resource **r)
775{
776 struct pci_resource *res, *tres;
777
778 res = *r;
779 *r = NULL;
780
781 while (res) {
782 tres = res;
783 res = res->next;
784 kfree(tres);
785 }
786}
787
788/**
789 * shpchp_destroy_resource_list: put node back in the resource list
790 * @resources: list to put nodes back
791 */
792void shpchp_destroy_resource_list(struct resource_lists *resources)
793{
794 kfree_resource_list(&(resources->io_head));
795 kfree_resource_list(&(resources->mem_head));
796 kfree_resource_list(&(resources->p_mem_head));
797 kfree_resource_list(&(resources->bus_head));
798}
799
800/**
801 * shpchp_destroy_board_resources: put node back in the resource list
802 * @resources: list to put nodes back
803 */
804void shpchp_destroy_board_resources(struct pci_func * func)
805{
806 kfree_resource_list(&(func->io_head));
807 kfree_resource_list(&(func->mem_head));
808 kfree_resource_list(&(func->p_mem_head));
809 kfree_resource_list(&(func->bus_head));
810}
diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c
new file mode 100644
index 000000000000..9a1ee132d12c
--- /dev/null
+++ b/drivers/pci/hotplug/shpchp_sysfs.c
@@ -0,0 +1,143 @@
1/*
2 * Compaq Hot Plug Controller Driver
3 *
4 * Copyright (c) 1995,2001 Compaq Computer Corporation
5 * Copyright (c) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (c) 2001 IBM Corp.
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <greg@kroah.com>
26 *
27 */
28
29#include <linux/config.h>
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/types.h>
33#include <linux/proc_fs.h>
34#include <linux/workqueue.h>
35#include <linux/pci.h>
36#include "shpchp.h"
37
38
39/* A few routines that create sysfs entries for the hot plug controller */
40
41static ssize_t show_ctrl (struct device *dev, char *buf)
42{
43 struct pci_dev *pci_dev;
44 struct controller *ctrl;
45 char * out = buf;
46 int index;
47 struct pci_resource *res;
48
49 pci_dev = container_of (dev, struct pci_dev, dev);
50 ctrl = pci_get_drvdata(pci_dev);
51
52 out += sprintf(buf, "Free resources: memory\n");
53 index = 11;
54 res = ctrl->mem_head;
55 while (res && index--) {
56 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
57 res = res->next;
58 }
59 out += sprintf(out, "Free resources: prefetchable memory\n");
60 index = 11;
61 res = ctrl->p_mem_head;
62 while (res && index--) {
63 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
64 res = res->next;
65 }
66 out += sprintf(out, "Free resources: IO\n");
67 index = 11;
68 res = ctrl->io_head;
69 while (res && index--) {
70 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
71 res = res->next;
72 }
73 out += sprintf(out, "Free resources: bus numbers\n");
74 index = 11;
75 res = ctrl->bus_head;
76 while (res && index--) {
77 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
78 res = res->next;
79 }
80
81 return out - buf;
82}
83static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL);
84
85static ssize_t show_dev (struct device *dev, char *buf)
86{
87 struct pci_dev *pci_dev;
88 struct controller *ctrl;
89 char * out = buf;
90 int index;
91 struct pci_resource *res;
92 struct pci_func *new_slot;
93 struct slot *slot;
94
95 pci_dev = container_of (dev, struct pci_dev, dev);
96 ctrl = pci_get_drvdata(pci_dev);
97
98 slot=ctrl->slot;
99
100 while (slot) {
101 new_slot = shpchp_slot_find(slot->bus, slot->device, 0);
102 if (!new_slot)
103 break;
104 out += sprintf(out, "assigned resources: memory\n");
105 index = 11;
106 res = new_slot->mem_head;
107 while (res && index--) {
108 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
109 res = res->next;
110 }
111 out += sprintf(out, "assigned resources: prefetchable memory\n");
112 index = 11;
113 res = new_slot->p_mem_head;
114 while (res && index--) {
115 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
116 res = res->next;
117 }
118 out += sprintf(out, "assigned resources: IO\n");
119 index = 11;
120 res = new_slot->io_head;
121 while (res && index--) {
122 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
123 res = res->next;
124 }
125 out += sprintf(out, "assigned resources: bus numbers\n");
126 index = 11;
127 res = new_slot->bus_head;
128 while (res && index--) {
129 out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
130 res = res->next;
131 }
132 slot=slot->next;
133 }
134
135 return out - buf;
136}
137static DEVICE_ATTR (dev, S_IRUGO, show_dev, NULL);
138
139void shpchp_create_ctrl_files (struct controller *ctrl)
140{
141 device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl);
142 device_create_file (&ctrl->pci_dev->dev, &dev_attr_dev);
143}
diff --git a/drivers/pci/hotplug/shpchprm.h b/drivers/pci/hotplug/shpchprm.h
new file mode 100644
index 000000000000..88aeb978c911
--- /dev/null
+++ b/drivers/pci/hotplug/shpchprm.h
@@ -0,0 +1,55 @@
1/*
2 * SHPCHPRM : SHPCHP Resource Manager for ACPI/non-ACPI platform
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
27 *
28 */
29
30#ifndef _SHPCHPRM_H_
31#define _SHPCHPRM_H_
32
33#ifdef CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY
34#include "shpchprm_legacy.h"
35#else
36#include "shpchprm_nonacpi.h"
37#endif
38
39int shpchprm_init(enum php_ctlr_type ct);
40void shpchprm_cleanup(void);
41int shpchprm_print_pirt(void);
42int shpchprm_find_available_resources(struct controller *ctrl);
43int shpchprm_set_hpp(struct controller *ctrl, struct pci_func *func, u8 card_type);
44void shpchprm_enable_card(struct controller *ctrl, struct pci_func *func, u8 card_type);
45int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum);
46
47#ifdef DEBUG
48#define RES_CHECK(this, bits) \
49 { if (((this) & (bits - 1))) \
50 printk("%s:%d ERR: potential res loss!\n", __FUNCTION__, __LINE__); }
51#else
52#define RES_CHECK(this, bits)
53#endif
54
55#endif /* _SHPCHPRM_H_ */
diff --git a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c
new file mode 100644
index 000000000000..243a51d88b86
--- /dev/null
+++ b/drivers/pci/hotplug/shpchprm_acpi.c
@@ -0,0 +1,1713 @@
1/*
2 * SHPCHPRM ACPI: PHP Resource Manager for ACPI platform
3 *
4 * Copyright (C) 2003-2004 Intel Corporation
5 *
6 * All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
16 * NON INFRINGEMENT. See the GNU General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 * Send feedback to <dely.l.sy@intel.com>
24 *
25 */
26
27#include <linux/config.h>
28#include <linux/module.h>
29#include <linux/kernel.h>
30#include <linux/types.h>
31#include <linux/pci.h>
32#include <linux/init.h>
33#include <linux/acpi.h>
34#include <linux/efi.h>
35#include <asm/uaccess.h>
36#include <asm/system.h>
37#ifdef CONFIG_IA64
38#include <asm/iosapic.h>
39#endif
40#include <acpi/acpi.h>
41#include <acpi/acpi_bus.h>
42#include <acpi/actypes.h>
43#include "shpchp.h"
44#include "shpchprm.h"
45
46#define PCI_MAX_BUS 0x100
47#define ACPI_STA_DEVICE_PRESENT 0x01
48
49#define METHOD_NAME__SUN "_SUN"
50#define METHOD_NAME__HPP "_HPP"
51#define METHOD_NAME_OSHP "OSHP"
52
53#define PHP_RES_BUS 0xA0
54#define PHP_RES_IO 0xA1
55#define PHP_RES_MEM 0xA2
56#define PHP_RES_PMEM 0xA3
57
58#define BRIDGE_TYPE_P2P 0x00
59#define BRIDGE_TYPE_HOST 0x01
60
61/* this should go to drivers/acpi/include/ */
62struct acpi__hpp {
63 u8 cache_line_size;
64 u8 latency_timer;
65 u8 enable_serr;
66 u8 enable_perr;
67};
68
69struct acpi_php_slot {
70 struct acpi_php_slot *next;
71 struct acpi_bridge *bridge;
72 acpi_handle handle;
73 int seg;
74 int bus;
75 int dev;
76 int fun;
77 u32 sun;
78 struct pci_resource *mem_head;
79 struct pci_resource *p_mem_head;
80 struct pci_resource *io_head;
81 struct pci_resource *bus_head;
82 void *slot_ops; /* _STA, _EJx, etc */
83 struct slot *slot;
84}; /* per func */
85
86struct acpi_bridge {
87 struct acpi_bridge *parent;
88 struct acpi_bridge *next;
89 struct acpi_bridge *child;
90 acpi_handle handle;
91 int seg;
92 int pbus; /* pdev->bus->number */
93 int pdevice; /* PCI_SLOT(pdev->devfn) */
94 int pfunction; /* PCI_DEVFN(pdev->devfn) */
95 int bus; /* pdev->subordinate->number */
96 struct acpi__hpp *_hpp;
97 struct acpi_php_slot *slots;
98 struct pci_resource *tmem_head; /* total from crs */
99 struct pci_resource *tp_mem_head; /* total from crs */
100 struct pci_resource *tio_head; /* total from crs */
101 struct pci_resource *tbus_head; /* total from crs */
102 struct pci_resource *mem_head; /* available */
103 struct pci_resource *p_mem_head; /* available */
104 struct pci_resource *io_head; /* available */
105 struct pci_resource *bus_head; /* available */
106 int scanned;
107 int type;
108};
109
110static struct acpi_bridge *acpi_bridges_head;
111
112static u8 * acpi_path_name( acpi_handle handle)
113{
114 acpi_status status;
115 static u8 path_name[ACPI_PATHNAME_MAX];
116 struct acpi_buffer ret_buf = { ACPI_PATHNAME_MAX, path_name };
117
118 memset(path_name, 0, sizeof (path_name));
119 status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf);
120
121 if (ACPI_FAILURE(status))
122 return NULL;
123 else
124 return path_name;
125}
126
127static void acpi_get__hpp ( struct acpi_bridge *ab);
128static void acpi_run_oshp ( struct acpi_bridge *ab);
129
130static int acpi_add_slot_to_php_slots(
131 struct acpi_bridge *ab,
132 int bus_num,
133 acpi_handle handle,
134 u32 adr,
135 u32 sun
136 )
137{
138 struct acpi_php_slot *aps;
139 static long samesun = -1;
140
141 aps = (struct acpi_php_slot *) kmalloc (sizeof(struct acpi_php_slot), GFP_KERNEL);
142 if (!aps) {
143 err ("acpi_shpchprm: alloc for aps fail\n");
144 return -1;
145 }
146 memset(aps, 0, sizeof(struct acpi_php_slot));
147
148 aps->handle = handle;
149 aps->bus = bus_num;
150 aps->dev = (adr >> 16) & 0xffff;
151 aps->fun = adr & 0xffff;
152 aps->sun = sun;
153
154 aps->next = ab->slots; /* cling to the bridge */
155 aps->bridge = ab;
156 ab->slots = aps;
157
158 ab->scanned += 1;
159 if (!ab->_hpp)
160 acpi_get__hpp(ab);
161
162 acpi_run_oshp(ab);
163
164 if (sun != samesun) {
165 info("acpi_shpchprm: Slot sun(%x) at s:b:d:f=0x%02x:%02x:%02x:%02x\n", aps->sun, ab->seg,
166 aps->bus, aps->dev, aps->fun);
167 samesun = sun;
168 }
169 return 0;
170}
171
172static void acpi_get__hpp ( struct acpi_bridge *ab)
173{
174 acpi_status status;
175 u8 nui[4];
176 struct acpi_buffer ret_buf = { 0, NULL};
177 union acpi_object *ext_obj, *package;
178 u8 *path_name = acpi_path_name(ab->handle);
179 int i, len = 0;
180
181 /* get _hpp */
182 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf);
183 switch (status) {
184 case AE_BUFFER_OVERFLOW:
185 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
186 if (!ret_buf.pointer) {
187 err ("acpi_shpchprm:%s alloc for _HPP fail\n", path_name);
188 return;
189 }
190 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf);
191 if (ACPI_SUCCESS(status))
192 break;
193 default:
194 if (ACPI_FAILURE(status)) {
195 err("acpi_shpchprm:%s _HPP fail=0x%x\n", path_name, status);
196 return;
197 }
198 }
199
200 ext_obj = (union acpi_object *) ret_buf.pointer;
201 if (ext_obj->type != ACPI_TYPE_PACKAGE) {
202 err ("acpi_shpchprm:%s _HPP obj not a package\n", path_name);
203 goto free_and_return;
204 }
205
206 len = ext_obj->package.count;
207 package = (union acpi_object *) ret_buf.pointer;
208 for ( i = 0; (i < len) || (i < 4); i++) {
209 ext_obj = (union acpi_object *) &package->package.elements[i];
210 switch (ext_obj->type) {
211 case ACPI_TYPE_INTEGER:
212 nui[i] = (u8)ext_obj->integer.value;
213 break;
214 default:
215 err ("acpi_shpchprm:%s _HPP obj type incorrect\n", path_name);
216 goto free_and_return;
217 }
218 }
219
220 ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL);
221 if (!ab->_hpp) {
222 err ("acpi_shpchprm:%s alloc for _HPP failed\n", path_name);
223 goto free_and_return;
224 }
225 memset(ab->_hpp, 0, sizeof(struct acpi__hpp));
226
227 ab->_hpp->cache_line_size = nui[0];
228 ab->_hpp->latency_timer = nui[1];
229 ab->_hpp->enable_serr = nui[2];
230 ab->_hpp->enable_perr = nui[3];
231
232 dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
233 dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer);
234 dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr);
235 dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr);
236
237free_and_return:
238 kfree(ret_buf.pointer);
239}
240
241static void acpi_run_oshp ( struct acpi_bridge *ab)
242{
243 acpi_status status;
244 u8 *path_name = acpi_path_name(ab->handle);
245
246 /* run OSHP */
247 status = acpi_evaluate_object(ab->handle, METHOD_NAME_OSHP, NULL, NULL);
248 if (ACPI_FAILURE(status)) {
249 err("acpi_pciehprm:%s OSHP fails=0x%x\n", path_name, status);
250 } else
251 dbg("acpi_pciehprm:%s OSHP passes =0x%x\n", path_name, status);
252 return;
253}
254
255static acpi_status acpi_evaluate_crs(
256 acpi_handle handle,
257 struct acpi_resource **retbuf
258 )
259{
260 acpi_status status;
261 struct acpi_buffer crsbuf;
262 u8 *path_name = acpi_path_name(handle);
263
264 crsbuf.length = 0;
265 crsbuf.pointer = NULL;
266
267 status = acpi_get_current_resources (handle, &crsbuf);
268
269 switch (status) {
270 case AE_BUFFER_OVERFLOW:
271 break; /* found */
272 case AE_NOT_FOUND:
273 dbg("acpi_shpchprm:%s _CRS not found\n", path_name);
274 return status;
275 default:
276 err ("acpi_shpchprm:%s _CRS fail=0x%x\n", path_name, status);
277 return status;
278 }
279
280 crsbuf.pointer = kmalloc (crsbuf.length, GFP_KERNEL);
281 if (!crsbuf.pointer) {
282 err ("acpi_shpchprm: alloc %ld bytes for %s _CRS fail\n", (ulong)crsbuf.length, path_name);
283 return AE_NO_MEMORY;
284 }
285
286 status = acpi_get_current_resources (handle, &crsbuf);
287 if (ACPI_FAILURE(status)) {
288 err("acpi_shpchprm: %s _CRS fail=0x%x.\n", path_name, status);
289 kfree(crsbuf.pointer);
290 return status;
291 }
292
293 *retbuf = crsbuf.pointer;
294
295 return status;
296}
297
298static void free_pci_resource ( struct pci_resource *aprh)
299{
300 struct pci_resource *res, *next;
301
302 for (res = aprh; res; res = next) {
303 next = res->next;
304 kfree(res);
305 }
306}
307
308static void print_pci_resource ( struct pci_resource *aprh)
309{
310 struct pci_resource *res;
311
312 for (res = aprh; res; res = res->next)
313 dbg(" base= 0x%x length= 0x%x\n", res->base, res->length);
314}
315
316static void print_slot_resources( struct acpi_php_slot *aps)
317{
318 if (aps->bus_head) {
319 dbg(" BUS Resources:\n");
320 print_pci_resource (aps->bus_head);
321 }
322
323 if (aps->io_head) {
324 dbg(" IO Resources:\n");
325 print_pci_resource (aps->io_head);
326 }
327
328 if (aps->mem_head) {
329 dbg(" MEM Resources:\n");
330 print_pci_resource (aps->mem_head);
331 }
332
333 if (aps->p_mem_head) {
334 dbg(" PMEM Resources:\n");
335 print_pci_resource (aps->p_mem_head);
336 }
337}
338
339static void print_pci_resources( struct acpi_bridge *ab)
340{
341 if (ab->tbus_head) {
342 dbg(" Total BUS Resources:\n");
343 print_pci_resource (ab->tbus_head);
344 }
345 if (ab->bus_head) {
346 dbg(" BUS Resources:\n");
347 print_pci_resource (ab->bus_head);
348 }
349
350 if (ab->tio_head) {
351 dbg(" Total IO Resources:\n");
352 print_pci_resource (ab->tio_head);
353 }
354 if (ab->io_head) {
355 dbg(" IO Resources:\n");
356 print_pci_resource (ab->io_head);
357 }
358
359 if (ab->tmem_head) {
360 dbg(" Total MEM Resources:\n");
361 print_pci_resource (ab->tmem_head);
362 }
363 if (ab->mem_head) {
364 dbg(" MEM Resources:\n");
365 print_pci_resource (ab->mem_head);
366 }
367
368 if (ab->tp_mem_head) {
369 dbg(" Total PMEM Resources:\n");
370 print_pci_resource (ab->tp_mem_head);
371 }
372 if (ab->p_mem_head) {
373 dbg(" PMEM Resources:\n");
374 print_pci_resource (ab->p_mem_head);
375 }
376 if (ab->_hpp) {
377 dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
378 dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer);
379 dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr);
380 dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr);
381 }
382}
383
384static int shpchprm_delete_resource(
385 struct pci_resource **aprh,
386 ulong base,
387 ulong size)
388{
389 struct pci_resource *res;
390 struct pci_resource *prevnode;
391 struct pci_resource *split_node;
392 ulong tbase;
393
394 shpchp_resource_sort_and_combine(aprh);
395
396 for (res = *aprh; res; res = res->next) {
397 if (res->base > base)
398 continue;
399
400 if ((res->base + res->length) < (base + size))
401 continue;
402
403 if (res->base < base) {
404 tbase = base;
405
406 if ((res->length - (tbase - res->base)) < size)
407 continue;
408
409 split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
410 if (!split_node)
411 return -ENOMEM;
412
413 split_node->base = res->base;
414 split_node->length = tbase - res->base;
415 res->base = tbase;
416 res->length -= split_node->length;
417
418 split_node->next = res->next;
419 res->next = split_node;
420 }
421
422 if (res->length >= size) {
423 split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
424 if (!split_node)
425 return -ENOMEM;
426
427 split_node->base = res->base + size;
428 split_node->length = res->length - size;
429 res->length = size;
430
431 split_node->next = res->next;
432 res->next = split_node;
433 }
434
435 if (*aprh == res) {
436 *aprh = res->next;
437 } else {
438 prevnode = *aprh;
439 while (prevnode->next != res)
440 prevnode = prevnode->next;
441
442 prevnode->next = res->next;
443 }
444 res->next = NULL;
445 kfree(res);
446 break;
447 }
448
449 return 0;
450}
451
452static int shpchprm_delete_resources(
453 struct pci_resource **aprh,
454 struct pci_resource *this
455 )
456{
457 struct pci_resource *res;
458
459 for (res = this; res; res = res->next)
460 shpchprm_delete_resource(aprh, res->base, res->length);
461
462 return 0;
463}
464
465static int shpchprm_add_resource(
466 struct pci_resource **aprh,
467 ulong base,
468 ulong size)
469{
470 struct pci_resource *res;
471
472 for (res = *aprh; res; res = res->next) {
473 if ((res->base + res->length) == base) {
474 res->length += size;
475 size = 0L;
476 break;
477 }
478 if (res->next == *aprh)
479 break;
480 }
481
482 if (size) {
483 res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
484 if (!res) {
485 err ("acpi_shpchprm: alloc for res fail\n");
486 return -ENOMEM;
487 }
488 memset(res, 0, sizeof (struct pci_resource));
489
490 res->base = base;
491 res->length = size;
492 res->next = *aprh;
493 *aprh = res;
494 }
495
496 return 0;
497}
498
499static int shpchprm_add_resources(
500 struct pci_resource **aprh,
501 struct pci_resource *this
502 )
503{
504 struct pci_resource *res;
505 int rc = 0;
506
507 for (res = this; res && !rc; res = res->next)
508 rc = shpchprm_add_resource(aprh, res->base, res->length);
509
510 return rc;
511}
512
513static void acpi_parse_io (
514 struct acpi_bridge *ab,
515 union acpi_resource_data *data
516 )
517{
518 struct acpi_resource_io *dataio;
519 dataio = (struct acpi_resource_io *) data;
520
521 dbg("Io Resource\n");
522 dbg(" %d bit decode\n", ACPI_DECODE_16 == dataio->io_decode ? 16:10);
523 dbg(" Range minimum base: %08X\n", dataio->min_base_address);
524 dbg(" Range maximum base: %08X\n", dataio->max_base_address);
525 dbg(" Alignment: %08X\n", dataio->alignment);
526 dbg(" Range Length: %08X\n", dataio->range_length);
527}
528
529static void acpi_parse_fixed_io (
530 struct acpi_bridge *ab,
531 union acpi_resource_data *data
532 )
533{
534 struct acpi_resource_fixed_io *datafio;
535 datafio = (struct acpi_resource_fixed_io *) data;
536
537 dbg("Fixed Io Resource\n");
538 dbg(" Range base address: %08X", datafio->base_address);
539 dbg(" Range length: %08X", datafio->range_length);
540}
541
542static void acpi_parse_address16_32 (
543 struct acpi_bridge *ab,
544 union acpi_resource_data *data,
545 acpi_resource_type id
546 )
547{
548 /*
549 * acpi_resource_address16 == acpi_resource_address32
550 * acpi_resource_address16 *data16 = (acpi_resource_address16 *) data;
551 */
552 struct acpi_resource_address32 *data32 = (struct acpi_resource_address32 *) data;
553 struct pci_resource **aprh, **tprh;
554
555 if (id == ACPI_RSTYPE_ADDRESS16)
556 dbg("acpi_shpchprm:16-Bit Address Space Resource\n");
557 else
558 dbg("acpi_shpchprm:32-Bit Address Space Resource\n");
559
560 switch (data32->resource_type) {
561 case ACPI_MEMORY_RANGE:
562 dbg(" Resource Type: Memory Range\n");
563 aprh = &ab->mem_head;
564 tprh = &ab->tmem_head;
565
566 switch (data32->attribute.memory.cache_attribute) {
567 case ACPI_NON_CACHEABLE_MEMORY:
568 dbg(" Type Specific: Noncacheable memory\n");
569 break;
570 case ACPI_CACHABLE_MEMORY:
571 dbg(" Type Specific: Cacheable memory\n");
572 break;
573 case ACPI_WRITE_COMBINING_MEMORY:
574 dbg(" Type Specific: Write-combining memory\n");
575 break;
576 case ACPI_PREFETCHABLE_MEMORY:
577 aprh = &ab->p_mem_head;
578 dbg(" Type Specific: Prefetchable memory\n");
579 break;
580 default:
581 dbg(" Type Specific: Invalid cache attribute\n");
582 break;
583 }
584
585 dbg(" Type Specific: Read%s\n", ACPI_READ_WRITE_MEMORY == data32->attribute.memory.read_write_attribute ? "/Write":" Only");
586 break;
587
588 case ACPI_IO_RANGE:
589 dbg(" Resource Type: I/O Range\n");
590 aprh = &ab->io_head;
591 tprh = &ab->tio_head;
592
593 switch (data32->attribute.io.range_attribute) {
594 case ACPI_NON_ISA_ONLY_RANGES:
595 dbg(" Type Specific: Non-ISA Io Addresses\n");
596 break;
597 case ACPI_ISA_ONLY_RANGES:
598 dbg(" Type Specific: ISA Io Addresses\n");
599 break;
600 case ACPI_ENTIRE_RANGE:
601 dbg(" Type Specific: ISA and non-ISA Io Addresses\n");
602 break;
603 default:
604 dbg(" Type Specific: Invalid range attribute\n");
605 break;
606 }
607 break;
608
609 case ACPI_BUS_NUMBER_RANGE:
610 dbg(" Resource Type: Bus Number Range(fixed)\n");
611 /* fixup to be compatible with the rest of php driver */
612 data32->min_address_range++;
613 data32->address_length--;
614 aprh = &ab->bus_head;
615 tprh = &ab->tbus_head;
616 break;
617 default:
618 dbg(" Resource Type: Invalid resource type. Exiting.\n");
619 return;
620 }
621
622 dbg(" Resource %s\n", ACPI_CONSUMER == data32->producer_consumer ? "Consumer":"Producer");
623 dbg(" %s decode\n", ACPI_SUB_DECODE == data32->decode ? "Subtractive":"Positive");
624 dbg(" Min address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->min_address_fixed ? "":"not");
625 dbg(" Max address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->max_address_fixed ? "":"not");
626 dbg(" Granularity: %08X\n", data32->granularity);
627 dbg(" Address range min: %08X\n", data32->min_address_range);
628 dbg(" Address range max: %08X\n", data32->max_address_range);
629 dbg(" Address translation offset: %08X\n", data32->address_translation_offset);
630 dbg(" Address Length: %08X\n", data32->address_length);
631
632 if (0xFF != data32->resource_source.index) {
633 dbg(" Resource Source Index: %X\n", data32->resource_source.index);
634 /* dbg(" Resource Source: %s\n", data32->resource_source.string_ptr); */
635 }
636
637 shpchprm_add_resource(aprh, data32->min_address_range, data32->address_length);
638}
639
640static acpi_status acpi_parse_crs(
641 struct acpi_bridge *ab,
642 struct acpi_resource *crsbuf
643 )
644{
645 acpi_status status = AE_OK;
646 struct acpi_resource *resource = crsbuf;
647 u8 count = 0;
648 u8 done = 0;
649
650 while (!done) {
651 dbg("acpi_shpchprm: PCI bus 0x%x Resource structure %x.\n", ab->bus, count++);
652 switch (resource->id) {
653 case ACPI_RSTYPE_IRQ:
654 dbg("Irq -------- Resource\n");
655 break;
656 case ACPI_RSTYPE_DMA:
657 dbg("DMA -------- Resource\n");
658 break;
659 case ACPI_RSTYPE_START_DPF:
660 dbg("Start DPF -------- Resource\n");
661 break;
662 case ACPI_RSTYPE_END_DPF:
663 dbg("End DPF -------- Resource\n");
664 break;
665 case ACPI_RSTYPE_IO:
666 acpi_parse_io (ab, &resource->data);
667 break;
668 case ACPI_RSTYPE_FIXED_IO:
669 acpi_parse_fixed_io (ab, &resource->data);
670 break;
671 case ACPI_RSTYPE_VENDOR:
672 dbg("Vendor -------- Resource\n");
673 break;
674 case ACPI_RSTYPE_END_TAG:
675 dbg("End_tag -------- Resource\n");
676 done = 1;
677 break;
678 case ACPI_RSTYPE_MEM24:
679 dbg("Mem24 -------- Resource\n");
680 break;
681 case ACPI_RSTYPE_MEM32:
682 dbg("Mem32 -------- Resource\n");
683 break;
684 case ACPI_RSTYPE_FIXED_MEM32:
685 dbg("Fixed Mem32 -------- Resource\n");
686 break;
687 case ACPI_RSTYPE_ADDRESS16:
688 acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS16);
689 break;
690 case ACPI_RSTYPE_ADDRESS32:
691 acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS32);
692 break;
693 case ACPI_RSTYPE_ADDRESS64:
694 info("Address64 -------- Resource unparsed\n");
695 break;
696 case ACPI_RSTYPE_EXT_IRQ:
697 dbg("Ext Irq -------- Resource\n");
698 break;
699 default:
700 dbg("Invalid -------- resource type 0x%x\n", resource->id);
701 break;
702 }
703
704 resource = (struct acpi_resource *) ((char *)resource + resource->length);
705 }
706
707 return status;
708}
709
710static acpi_status acpi_get_crs( struct acpi_bridge *ab)
711{
712 acpi_status status;
713 struct acpi_resource *crsbuf;
714
715 status = acpi_evaluate_crs(ab->handle, &crsbuf);
716 if (ACPI_SUCCESS(status)) {
717 status = acpi_parse_crs(ab, crsbuf);
718 kfree(crsbuf);
719
720 shpchp_resource_sort_and_combine(&ab->bus_head);
721 shpchp_resource_sort_and_combine(&ab->io_head);
722 shpchp_resource_sort_and_combine(&ab->mem_head);
723 shpchp_resource_sort_and_combine(&ab->p_mem_head);
724
725 shpchprm_add_resources (&ab->tbus_head, ab->bus_head);
726 shpchprm_add_resources (&ab->tio_head, ab->io_head);
727 shpchprm_add_resources (&ab->tmem_head, ab->mem_head);
728 shpchprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
729 }
730
731 return status;
732}
733
734/* find acpi_bridge downword from ab. */
735static struct acpi_bridge *
736find_acpi_bridge_by_bus(
737 struct acpi_bridge *ab,
738 int seg,
739 int bus /* pdev->subordinate->number */
740 )
741{
742 struct acpi_bridge *lab = NULL;
743
744 if (!ab)
745 return NULL;
746
747 if ((ab->bus == bus) && (ab->seg == seg))
748 return ab;
749
750 if (ab->child)
751 lab = find_acpi_bridge_by_bus(ab->child, seg, bus);
752
753 if (!lab)
754 if (ab->next)
755 lab = find_acpi_bridge_by_bus(ab->next, seg, bus);
756
757 return lab;
758}
759
760/*
761 * Build a device tree of ACPI PCI Bridges
762 */
763static void shpchprm_acpi_register_a_bridge (
764 struct acpi_bridge **head,
765 struct acpi_bridge *pab, /* parent bridge to which child bridge is added */
766 struct acpi_bridge *cab /* child bridge to add */
767 )
768{
769 struct acpi_bridge *lpab;
770 struct acpi_bridge *lcab;
771
772 lpab = find_acpi_bridge_by_bus(*head, pab->seg, pab->bus);
773 if (!lpab) {
774 if (!(pab->type & BRIDGE_TYPE_HOST))
775 warn("PCI parent bridge s:b(%x:%x) not in list.\n", pab->seg, pab->bus);
776 pab->next = *head;
777 *head = pab;
778 lpab = pab;
779 }
780
781 if ((cab->type & BRIDGE_TYPE_HOST) && (pab == cab))
782 return;
783
784 lcab = find_acpi_bridge_by_bus(*head, cab->seg, cab->bus);
785 if (lcab) {
786 if ((pab->bus != lcab->parent->bus) || (lcab->bus != cab->bus))
787 err("PCI child bridge s:b(%x:%x) in list with diff parent.\n", cab->seg, cab->bus);
788 return;
789 } else
790 lcab = cab;
791
792 lcab->parent = lpab;
793 lcab->next = lpab->child;
794 lpab->child = lcab;
795}
796
797static acpi_status shpchprm_acpi_build_php_slots_callback(
798 acpi_handle handle,
799 u32 Level,
800 void *context,
801 void **retval
802 )
803{
804 ulong bus_num;
805 ulong seg_num;
806 ulong sun, adr;
807 ulong padr = 0;
808 acpi_handle phandle = NULL;
809 struct acpi_bridge *pab = (struct acpi_bridge *)context;
810 struct acpi_bridge *lab;
811 acpi_status status;
812 u8 *path_name = acpi_path_name(handle);
813
814 /* get _SUN */
815 status = acpi_evaluate_integer(handle, METHOD_NAME__SUN, NULL, &sun);
816 switch(status) {
817 case AE_NOT_FOUND:
818 return AE_OK;
819 default:
820 if (ACPI_FAILURE(status)) {
821 err("acpi_shpchprm:%s _SUN fail=0x%x\n", path_name, status);
822 return status;
823 }
824 }
825
826 /* get _ADR. _ADR must exist if _SUN exists */
827 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
828 if (ACPI_FAILURE(status)) {
829 err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status);
830 return status;
831 }
832
833 dbg("acpi_shpchprm:%s sun=0x%08x adr=0x%08x\n", path_name, (u32)sun, (u32)adr);
834
835 status = acpi_get_parent(handle, &phandle);
836 if (ACPI_FAILURE(status)) {
837 err("acpi_shpchprm:%s get_parent fail=0x%x\n", path_name, status);
838 return (status);
839 }
840
841 bus_num = pab->bus;
842 seg_num = pab->seg;
843
844 if (pab->bus == bus_num) {
845 lab = pab;
846 } else {
847 dbg("WARN: pab is not parent\n");
848 lab = find_acpi_bridge_by_bus(pab, seg_num, bus_num);
849 if (!lab) {
850 dbg("acpi_shpchprm: alloc new P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
851 lab = (struct acpi_bridge *)kmalloc(sizeof(struct acpi_bridge), GFP_KERNEL);
852 if (!lab) {
853 err("acpi_shpchprm: alloc for ab fail\n");
854 return AE_NO_MEMORY;
855 }
856 memset(lab, 0, sizeof(struct acpi_bridge));
857
858 lab->handle = phandle;
859 lab->pbus = pab->bus;
860 lab->pdevice = (int)(padr >> 16) & 0xffff;
861 lab->pfunction = (int)(padr & 0xffff);
862 lab->bus = (int)bus_num;
863 lab->scanned = 0;
864 lab->type = BRIDGE_TYPE_P2P;
865
866 shpchprm_acpi_register_a_bridge (&acpi_bridges_head, pab, lab);
867 } else
868 dbg("acpi_shpchprm: found P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
869 }
870
871 acpi_add_slot_to_php_slots(lab, (int)bus_num, handle, (u32)adr, (u32)sun);
872 return (status);
873}
874
875static int shpchprm_acpi_build_php_slots(
876 struct acpi_bridge *ab,
877 u32 depth
878 )
879{
880 acpi_status status;
881 u8 *path_name = acpi_path_name(ab->handle);
882
883 /* Walk down this pci bridge to get _SUNs if any behind P2P */
884 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
885 ab->handle,
886 depth,
887 shpchprm_acpi_build_php_slots_callback,
888 ab,
889 NULL );
890 if (ACPI_FAILURE(status)) {
891 dbg("acpi_shpchprm:%s walk for _SUN on pci bridge seg:bus(%x:%x) fail=0x%x\n", path_name, ab->seg, ab->bus, status);
892 return -1;
893 }
894
895 return 0;
896}
897
898static void build_a_bridge(
899 struct acpi_bridge *pab,
900 struct acpi_bridge *ab
901 )
902{
903 u8 *path_name = acpi_path_name(ab->handle);
904
905 shpchprm_acpi_register_a_bridge (&acpi_bridges_head, pab, ab);
906
907 switch (ab->type) {
908 case BRIDGE_TYPE_HOST:
909 dbg("acpi_shpchprm: Registered PCI HOST Bridge(%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
910 ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
911 break;
912 case BRIDGE_TYPE_P2P:
913 dbg("acpi_shpchprm: Registered PCI P2P Bridge(%02x-%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
914 ab->pbus, ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
915 break;
916 };
917
918 /* build any immediate PHP slots under this pci bridge */
919 shpchprm_acpi_build_php_slots(ab, 1);
920}
921
922static struct acpi_bridge * add_p2p_bridge(
923 acpi_handle handle,
924 struct acpi_bridge *pab, /* parent */
925 ulong adr
926 )
927{
928 struct acpi_bridge *ab;
929 struct pci_dev *pdev;
930 ulong devnum, funcnum;
931 u8 *path_name = acpi_path_name(handle);
932
933 ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
934 if (!ab) {
935 err("acpi_shpchprm: alloc for ab fail\n");
936 return NULL;
937 }
938 memset(ab, 0, sizeof(struct acpi_bridge));
939
940 devnum = (adr >> 16) & 0xffff;
941 funcnum = adr & 0xffff;
942
943 pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
944 if (!pdev || !pdev->subordinate) {
945 err("acpi_shpchprm:%s is not a P2P Bridge\n", path_name);
946 kfree(ab);
947 return NULL;
948 }
949
950 ab->handle = handle;
951 ab->seg = pab->seg;
952 ab->pbus = pab->bus; /* or pdev->bus->number */
953 ab->pdevice = devnum; /* or PCI_SLOT(pdev->devfn) */
954 ab->pfunction = funcnum; /* or PCI_FUNC(pdev->devfn) */
955 ab->bus = pdev->subordinate->number;
956 ab->scanned = 0;
957 ab->type = BRIDGE_TYPE_P2P;
958
959 dbg("acpi_shpchprm: P2P(%x-%x) on pci=b:d:f(%x:%x:%x) acpi=b:d:f(%x:%x:%x) [%s]\n",
960 pab->bus, ab->bus, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
961 pab->bus, (u32)devnum, (u32)funcnum, path_name);
962
963 build_a_bridge(pab, ab);
964
965 return ab;
966}
967
968static acpi_status scan_p2p_bridge(
969 acpi_handle handle,
970 u32 Level,
971 void *context,
972 void **retval
973 )
974{
975 struct acpi_bridge *pab = (struct acpi_bridge *)context;
976 struct acpi_bridge *ab;
977 acpi_status status;
978 ulong adr = 0;
979 u8 *path_name = acpi_path_name(handle);
980 ulong devnum, funcnum;
981 struct pci_dev *pdev;
982
983 /* get device, function */
984 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
985 if (ACPI_FAILURE(status)) {
986 if (status != AE_NOT_FOUND)
987 err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status);
988 return AE_OK;
989 }
990
991 devnum = (adr >> 16) & 0xffff;
992 funcnum = adr & 0xffff;
993
994 pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
995 if (!pdev)
996 return AE_OK;
997 if (!pdev->subordinate)
998 return AE_OK;
999
1000 ab = add_p2p_bridge(handle, pab, adr);
1001 if (ab) {
1002 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
1003 handle,
1004 (u32)1,
1005 scan_p2p_bridge,
1006 ab,
1007 NULL);
1008 if (ACPI_FAILURE(status))
1009 dbg("acpi_shpchprm:%s find_p2p fail=0x%x\n", path_name, status);
1010 }
1011
1012 return AE_OK;
1013}
1014
1015static struct acpi_bridge * add_host_bridge(
1016 acpi_handle handle,
1017 ulong segnum,
1018 ulong busnum
1019 )
1020{
1021 ulong adr = 0;
1022 acpi_status status;
1023 struct acpi_bridge *ab;
1024 u8 *path_name = acpi_path_name(handle);
1025
1026 /* get device, function: host br adr is always 0000 though. */
1027 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
1028 if (ACPI_FAILURE(status)) {
1029 err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status);
1030 return NULL;
1031 }
1032 dbg("acpi_shpchprm: ROOT PCI seg(0x%x)bus(0x%x)dev(0x%x)func(0x%x) [%s]\n", (u32)segnum, (u32)busnum,
1033 (u32)(adr >> 16) & 0xffff, (u32)adr & 0xffff, path_name);
1034
1035 ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
1036 if (!ab) {
1037 err("acpi_shpchprm: alloc for ab fail\n");
1038 return NULL;
1039 }
1040 memset(ab, 0, sizeof(struct acpi_bridge));
1041
1042 ab->handle = handle;
1043 ab->seg = (int)segnum;
1044 ab->bus = ab->pbus = (int)busnum;
1045 ab->pdevice = (int)(adr >> 16) & 0xffff;
1046 ab->pfunction = (int)(adr & 0xffff);
1047 ab->scanned = 0;
1048 ab->type = BRIDGE_TYPE_HOST;
1049
1050 /* get root pci bridge's current resources */
1051 status = acpi_get_crs(ab);
1052 if (ACPI_FAILURE(status)) {
1053 err("acpi_shpchprm:%s evaluate _CRS fail=0x%x\n", path_name, status);
1054 kfree(ab);
1055 return NULL;
1056 }
1057 build_a_bridge(ab, ab);
1058
1059 return ab;
1060}
1061
1062static acpi_status acpi_scan_from_root_pci_callback (
1063 acpi_handle handle,
1064 u32 Level,
1065 void *context,
1066 void **retval
1067 )
1068{
1069 ulong segnum = 0;
1070 ulong busnum = 0;
1071 acpi_status status;
1072 struct acpi_bridge *ab;
1073 u8 *path_name = acpi_path_name(handle);
1074
1075 /* get bus number of this pci root bridge */
1076 status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &segnum);
1077 if (ACPI_FAILURE(status)) {
1078 if (status != AE_NOT_FOUND) {
1079 err("acpi_shpchprm:%s evaluate _SEG fail=0x%x\n", path_name, status);
1080 return status;
1081 }
1082 segnum = 0;
1083 }
1084
1085 /* get bus number of this pci root bridge */
1086 status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, &busnum);
1087 if (ACPI_FAILURE(status)) {
1088 err("acpi_shpchprm:%s evaluate _BBN fail=0x%x\n", path_name, status);
1089 return (status);
1090 }
1091
1092 ab = add_host_bridge(handle, segnum, busnum);
1093 if (ab) {
1094 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
1095 handle,
1096 1,
1097 scan_p2p_bridge,
1098 ab,
1099 NULL);
1100 if (ACPI_FAILURE(status))
1101 dbg("acpi_shpchprm:%s find_p2p fail=0x%x\n", path_name, status);
1102 }
1103
1104 return AE_OK;
1105}
1106
1107static int shpchprm_acpi_scan_pci (void)
1108{
1109 acpi_status status;
1110
1111 /*
1112 * TBD: traverse LDM device tree with the help of
1113 * unified ACPI augmented for php device population.
1114 */
1115 status = acpi_get_devices ( PCI_ROOT_HID_STRING,
1116 acpi_scan_from_root_pci_callback,
1117 NULL,
1118 NULL );
1119 if (ACPI_FAILURE(status)) {
1120 err("acpi_shpchprm:get_device PCI ROOT HID fail=0x%x\n", status);
1121 return -1;
1122 }
1123
1124 return 0;
1125}
1126
1127int shpchprm_init(enum php_ctlr_type ctlr_type)
1128{
1129 int rc;
1130
1131 if (ctlr_type != PCI)
1132 return -ENODEV;
1133
1134 dbg("shpchprm ACPI init <enter>\n");
1135 acpi_bridges_head = NULL;
1136
1137 /* construct PCI bus:device tree of acpi_handles */
1138 rc = shpchprm_acpi_scan_pci();
1139 if (rc)
1140 return rc;
1141
1142 dbg("shpchprm ACPI init %s\n", (rc)?"fail":"success");
1143 return rc;
1144}
1145
1146static void free_a_slot(struct acpi_php_slot *aps)
1147{
1148 dbg(" free a php func of slot(0x%02x) on PCI b:d:f=0x%02x:%02x:%02x\n", aps->sun, aps->bus, aps->dev, aps->fun);
1149
1150 free_pci_resource (aps->io_head);
1151 free_pci_resource (aps->bus_head);
1152 free_pci_resource (aps->mem_head);
1153 free_pci_resource (aps->p_mem_head);
1154
1155 kfree(aps);
1156}
1157
1158static void free_a_bridge( struct acpi_bridge *ab)
1159{
1160 struct acpi_php_slot *aps, *next;
1161
1162 switch (ab->type) {
1163 case BRIDGE_TYPE_HOST:
1164 dbg("Free ACPI PCI HOST Bridge(%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
1165 ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
1166 break;
1167 case BRIDGE_TYPE_P2P:
1168 dbg("Free ACPI PCI P2P Bridge(%x-%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
1169 ab->pbus, ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
1170 break;
1171 };
1172
1173 /* free slots first */
1174 for (aps = ab->slots; aps; aps = next) {
1175 next = aps->next;
1176 free_a_slot(aps);
1177 }
1178
1179 free_pci_resource (ab->io_head);
1180 free_pci_resource (ab->tio_head);
1181 free_pci_resource (ab->bus_head);
1182 free_pci_resource (ab->tbus_head);
1183 free_pci_resource (ab->mem_head);
1184 free_pci_resource (ab->tmem_head);
1185 free_pci_resource (ab->p_mem_head);
1186 free_pci_resource (ab->tp_mem_head);
1187
1188 kfree(ab);
1189}
1190
1191static void shpchprm_free_bridges ( struct acpi_bridge *ab)
1192{
1193 if (!ab)
1194 return;
1195
1196 if (ab->child)
1197 shpchprm_free_bridges (ab->child);
1198
1199 if (ab->next)
1200 shpchprm_free_bridges (ab->next);
1201
1202 free_a_bridge(ab);
1203}
1204
1205void shpchprm_cleanup(void)
1206{
1207 shpchprm_free_bridges (acpi_bridges_head);
1208}
1209
1210static int get_number_of_slots (
1211 struct acpi_bridge *ab,
1212 int selfonly
1213 )
1214{
1215 struct acpi_php_slot *aps;
1216 int prev_slot = -1;
1217 int slot_num = 0;
1218
1219 for ( aps = ab->slots; aps; aps = aps->next)
1220 if (aps->dev != prev_slot) {
1221 prev_slot = aps->dev;
1222 slot_num++;
1223 }
1224
1225 if (ab->child)
1226 slot_num += get_number_of_slots (ab->child, 0);
1227
1228 if (selfonly)
1229 return slot_num;
1230
1231 if (ab->next)
1232 slot_num += get_number_of_slots (ab->next, 0);
1233
1234 return slot_num;
1235}
1236
1237static int print_acpi_resources (struct acpi_bridge *ab)
1238{
1239 struct acpi_php_slot *aps;
1240 int i;
1241
1242 switch (ab->type) {
1243 case BRIDGE_TYPE_HOST:
1244 dbg("PCI HOST Bridge (%x) [%s]\n", ab->bus, acpi_path_name(ab->handle));
1245 break;
1246 case BRIDGE_TYPE_P2P:
1247 dbg("PCI P2P Bridge (%x-%x) [%s]\n", ab->pbus, ab->bus, acpi_path_name(ab->handle));
1248 break;
1249 };
1250
1251 print_pci_resources (ab);
1252
1253 for ( i = -1, aps = ab->slots; aps; aps = aps->next) {
1254 if (aps->dev == i)
1255 continue;
1256 dbg(" Slot sun(%x) s:b:d:f(%02x:%02x:%02x:%02x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
1257 print_slot_resources(aps);
1258 i = aps->dev;
1259 }
1260
1261 if (ab->child)
1262 print_acpi_resources (ab->child);
1263
1264 if (ab->next)
1265 print_acpi_resources (ab->next);
1266
1267 return 0;
1268}
1269
1270int shpchprm_print_pirt(void)
1271{
1272 dbg("SHPCHPRM ACPI Slots\n");
1273 if (acpi_bridges_head)
1274 print_acpi_resources (acpi_bridges_head);
1275 return 0;
1276}
1277
1278static struct acpi_php_slot * get_acpi_slot (
1279 struct acpi_bridge *ab,
1280 u32 sun
1281 )
1282{
1283 struct acpi_php_slot *aps = NULL;
1284
1285 for ( aps = ab->slots; aps; aps = aps->next)
1286 if (aps->sun == sun)
1287 return aps;
1288
1289 if (!aps && ab->child) {
1290 aps = (struct acpi_php_slot *)get_acpi_slot (ab->child, sun);
1291 if (aps)
1292 return aps;
1293 }
1294
1295 if (!aps && ab->next) {
1296 aps = (struct acpi_php_slot *)get_acpi_slot (ab->next, sun);
1297 if (aps)
1298 return aps;
1299 }
1300
1301 return aps;
1302
1303}
1304
1305#if 0
1306static void * shpchprm_get_slot(struct slot *slot)
1307{
1308 struct acpi_bridge *ab = acpi_bridges_head;
1309 struct acpi_php_slot *aps = get_acpi_slot (ab, slot->number);
1310
1311 aps->slot = slot;
1312
1313 dbg("Got acpi slot sun(%x): s:b:d:f(%x:%x:%x:%x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
1314
1315 return (void *)aps;
1316}
1317#endif
1318
1319static void shpchprm_dump_func_res( struct pci_func *fun)
1320{
1321 struct pci_func *func = fun;
1322
1323 if (func->bus_head) {
1324 dbg(": BUS Resources:\n");
1325 print_pci_resource (func->bus_head);
1326 }
1327 if (func->io_head) {
1328 dbg(": IO Resources:\n");
1329 print_pci_resource (func->io_head);
1330 }
1331 if (func->mem_head) {
1332 dbg(": MEM Resources:\n");
1333 print_pci_resource (func->mem_head);
1334 }
1335 if (func->p_mem_head) {
1336 dbg(": PMEM Resources:\n");
1337 print_pci_resource (func->p_mem_head);
1338 }
1339}
1340
1341static void shpchprm_dump_ctrl_res( struct controller *ctlr)
1342{
1343 struct controller *ctrl = ctlr;
1344
1345 if (ctrl->bus_head) {
1346 dbg(": BUS Resources:\n");
1347 print_pci_resource (ctrl->bus_head);
1348 }
1349 if (ctrl->io_head) {
1350 dbg(": IO Resources:\n");
1351 print_pci_resource (ctrl->io_head);
1352 }
1353 if (ctrl->mem_head) {
1354 dbg(": MEM Resources:\n");
1355 print_pci_resource (ctrl->mem_head);
1356 }
1357 if (ctrl->p_mem_head) {
1358 dbg(": PMEM Resources:\n");
1359 print_pci_resource (ctrl->p_mem_head);
1360 }
1361}
1362
1363static int shpchprm_get_used_resources (
1364 struct controller *ctrl,
1365 struct pci_func *func
1366 )
1367{
1368 return shpchp_save_used_resources (ctrl, func, !DISABLE_CARD);
1369}
1370
1371static int configure_existing_function(
1372 struct controller *ctrl,
1373 struct pci_func *func
1374 )
1375{
1376 int rc;
1377
1378 /* see how much resources the func has used. */
1379 rc = shpchprm_get_used_resources (ctrl, func);
1380
1381 if (!rc) {
1382 /* subtract the resources used by the func from ctrl resources */
1383 rc = shpchprm_delete_resources (&ctrl->bus_head, func->bus_head);
1384 rc |= shpchprm_delete_resources (&ctrl->io_head, func->io_head);
1385 rc |= shpchprm_delete_resources (&ctrl->mem_head, func->mem_head);
1386 rc |= shpchprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
1387 if (rc)
1388 warn("aCEF: cannot del used resources\n");
1389 } else
1390 err("aCEF: cannot get used resources\n");
1391
1392 return rc;
1393}
1394
1395static int bind_pci_resources_to_slots ( struct controller *ctrl)
1396{
1397 struct pci_func *func, new_func;
1398 int busn = ctrl->slot_bus;
1399 int devn, funn;
1400 u32 vid;
1401
1402 for (devn = 0; devn < 32; devn++) {
1403 for (funn = 0; funn < 8; funn++) {
1404 /*
1405 if (devn == ctrl->device && funn == ctrl->function)
1406 continue;
1407 */
1408 /* find out if this entry is for an occupied slot */
1409 vid = 0xFFFFFFFF;
1410 pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
1411
1412 if (vid != 0xFFFFFFFF) {
1413 func = shpchp_slot_find(busn, devn, funn);
1414 if (!func) {
1415 memset(&new_func, 0, sizeof(struct pci_func));
1416 new_func.bus = busn;
1417 new_func.device = devn;
1418 new_func.function = funn;
1419 new_func.is_a_board = 1;
1420 configure_existing_function(ctrl, &new_func);
1421 shpchprm_dump_func_res(&new_func);
1422 } else {
1423 configure_existing_function(ctrl, func);
1424 shpchprm_dump_func_res(func);
1425 }
1426 dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
1427 }
1428 }
1429 }
1430
1431 return 0;
1432}
1433
1434static int bind_pci_resources(
1435 struct controller *ctrl,
1436 struct acpi_bridge *ab
1437 )
1438{
1439 int status = 0;
1440
1441 if (ab->bus_head) {
1442 dbg("bapr: BUS Resources add on PCI 0x%x\n", ab->bus);
1443 status = shpchprm_add_resources (&ctrl->bus_head, ab->bus_head);
1444 if (shpchprm_delete_resources (&ab->bus_head, ctrl->bus_head))
1445 warn("bapr: cannot sub BUS Resource on PCI 0x%x\n", ab->bus);
1446 if (status) {
1447 err("bapr: BUS Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1448 return status;
1449 }
1450 } else
1451 info("bapr: No BUS Resource on PCI 0x%x.\n", ab->bus);
1452
1453 if (ab->io_head) {
1454 dbg("bapr: IO Resources add on PCI 0x%x\n", ab->bus);
1455 status = shpchprm_add_resources (&ctrl->io_head, ab->io_head);
1456 if (shpchprm_delete_resources (&ab->io_head, ctrl->io_head))
1457 warn("bapr: cannot sub IO Resource on PCI 0x%x\n", ab->bus);
1458 if (status) {
1459 err("bapr: IO Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1460 return status;
1461 }
1462 } else
1463 info("bapr: No IO Resource on PCI 0x%x.\n", ab->bus);
1464
1465 if (ab->mem_head) {
1466 dbg("bapr: MEM Resources add on PCI 0x%x\n", ab->bus);
1467 status = shpchprm_add_resources (&ctrl->mem_head, ab->mem_head);
1468 if (shpchprm_delete_resources (&ab->mem_head, ctrl->mem_head))
1469 warn("bapr: cannot sub MEM Resource on PCI 0x%x\n", ab->bus);
1470 if (status) {
1471 err("bapr: MEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1472 return status;
1473 }
1474 } else
1475 info("bapr: No MEM Resource on PCI 0x%x.\n", ab->bus);
1476
1477 if (ab->p_mem_head) {
1478 dbg("bapr: PMEM Resources add on PCI 0x%x\n", ab->bus);
1479 status = shpchprm_add_resources (&ctrl->p_mem_head, ab->p_mem_head);
1480 if (shpchprm_delete_resources (&ab->p_mem_head, ctrl->p_mem_head))
1481 warn("bapr: cannot sub PMEM Resource on PCI 0x%x\n", ab->bus);
1482 if (status) {
1483 err("bapr: PMEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1484 return status;
1485 }
1486 } else
1487 info("bapr: No PMEM Resource on PCI 0x%x.\n", ab->bus);
1488
1489 return status;
1490}
1491
1492static int no_pci_resources( struct acpi_bridge *ab)
1493{
1494 return !(ab->p_mem_head || ab->mem_head || ab->io_head || ab->bus_head);
1495}
1496
1497static int find_pci_bridge_resources (
1498 struct controller *ctrl,
1499 struct acpi_bridge *ab
1500 )
1501{
1502 int rc = 0;
1503 struct pci_func func;
1504
1505 memset(&func, 0, sizeof(struct pci_func));
1506
1507 func.bus = ab->pbus;
1508 func.device = ab->pdevice;
1509 func.function = ab->pfunction;
1510 func.is_a_board = 1;
1511
1512 /* Get used resources for this PCI bridge */
1513 rc = shpchp_save_used_resources (ctrl, &func, !DISABLE_CARD);
1514
1515 ab->io_head = func.io_head;
1516 ab->mem_head = func.mem_head;
1517 ab->p_mem_head = func.p_mem_head;
1518 ab->bus_head = func.bus_head;
1519 if (ab->bus_head)
1520 shpchprm_delete_resource(&ab->bus_head, ctrl->bus, 1);
1521
1522 return rc;
1523}
1524
1525static int get_pci_resources_from_bridge(
1526 struct controller *ctrl,
1527 struct acpi_bridge *ab
1528 )
1529{
1530 int rc = 0;
1531
1532 dbg("grfb: Get Resources for PCI 0x%x from actual PCI bridge 0x%x.\n", ctrl->bus, ab->bus);
1533
1534 rc = find_pci_bridge_resources (ctrl, ab);
1535
1536 shpchp_resource_sort_and_combine(&ab->bus_head);
1537 shpchp_resource_sort_and_combine(&ab->io_head);
1538 shpchp_resource_sort_and_combine(&ab->mem_head);
1539 shpchp_resource_sort_and_combine(&ab->p_mem_head);
1540
1541 shpchprm_add_resources (&ab->tbus_head, ab->bus_head);
1542 shpchprm_add_resources (&ab->tio_head, ab->io_head);
1543 shpchprm_add_resources (&ab->tmem_head, ab->mem_head);
1544 shpchprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
1545
1546 return rc;
1547}
1548
1549static int get_pci_resources(
1550 struct controller *ctrl,
1551 struct acpi_bridge *ab
1552 )
1553{
1554 int rc = 0;
1555
1556 if (no_pci_resources(ab)) {
1557 dbg("spbr:PCI 0x%x has no resources. Get parent resources.\n", ab->bus);
1558 rc = get_pci_resources_from_bridge(ctrl, ab);
1559 }
1560
1561 return rc;
1562}
1563
1564int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
1565{
1566 int offset = devnum - ctrl->slot_device_offset;
1567
1568 dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__, ctrl->slot_num_inc, offset);
1569 *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc *offset);
1570 return 0;
1571}
1572
1573/*
1574 * Get resources for this ctrl.
1575 * 1. get total resources from ACPI _CRS or bridge (this ctrl)
1576 * 2. find used resources of existing adapters
1577 * 3. subtract used resources from total resources
1578 */
1579int shpchprm_find_available_resources( struct controller *ctrl)
1580{
1581 int rc = 0;
1582 struct acpi_bridge *ab;
1583
1584 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->pci_dev->subordinate->number);
1585 if (!ab) {
1586 err("pfar:cannot locate acpi bridge of PCI 0x%x.\n", ctrl->pci_dev->subordinate->number);
1587 return -1;
1588 }
1589 if (no_pci_resources(ab)) {
1590 rc = get_pci_resources(ctrl, ab);
1591 if (rc) {
1592 err("pfar:cannot get pci resources of PCI 0x%x.\n",ctrl->pci_dev->subordinate->number);
1593 return -1;
1594 }
1595 }
1596
1597 rc = bind_pci_resources(ctrl, ab);
1598 dbg("pfar:pre-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
1599 shpchprm_dump_ctrl_res(ctrl);
1600
1601 bind_pci_resources_to_slots (ctrl);
1602
1603 dbg("pfar:post-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
1604 shpchprm_dump_ctrl_res(ctrl);
1605
1606 return rc;
1607}
1608
1609int shpchprm_set_hpp(
1610 struct controller *ctrl,
1611 struct pci_func *func,
1612 u8 card_type
1613 )
1614{
1615 struct acpi_bridge *ab;
1616 struct pci_bus lpci_bus, *pci_bus;
1617 int rc = 0;
1618 unsigned int devfn;
1619 u8 cls= 0x08; /* default cache line size */
1620 u8 lt = 0x40; /* default latency timer */
1621 u8 ep = 0;
1622 u8 es = 0;
1623
1624 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
1625 pci_bus = &lpci_bus;
1626 pci_bus->number = func->bus;
1627 devfn = PCI_DEVFN(func->device, func->function);
1628
1629 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
1630
1631 if (ab) {
1632 if (ab->_hpp) {
1633 lt = (u8)ab->_hpp->latency_timer;
1634 cls = (u8)ab->_hpp->cache_line_size;
1635 ep = (u8)ab->_hpp->enable_perr;
1636 es = (u8)ab->_hpp->enable_serr;
1637 } else
1638 dbg("_hpp: no _hpp for B/D/F=%#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
1639 } else
1640 dbg("_hpp: no acpi bridge for B/D/F = %#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
1641
1642
1643 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
1644 /* set subordinate Latency Timer */
1645 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, lt);
1646 }
1647
1648 /* set base Latency Timer */
1649 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, lt);
1650 dbg(" set latency timer =0x%02x: %x\n", lt, rc);
1651
1652 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, cls);
1653 dbg(" set cache_line_size=0x%02x: %x\n", cls, rc);
1654
1655 return rc;
1656}
1657
1658void shpchprm_enable_card(
1659 struct controller *ctrl,
1660 struct pci_func *func,
1661 u8 card_type)
1662{
1663 u16 command, cmd, bcommand, bcmd;
1664 struct pci_bus lpci_bus, *pci_bus;
1665 struct acpi_bridge *ab;
1666 unsigned int devfn;
1667 int rc;
1668
1669 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
1670 pci_bus = &lpci_bus;
1671 pci_bus->number = func->bus;
1672 devfn = PCI_DEVFN(func->device, func->function);
1673
1674 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
1675
1676 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
1677 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
1678 }
1679
1680 cmd = command = command | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
1681 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
1682 bcmd = bcommand = bcommand | PCI_BRIDGE_CTL_NO_ISA;
1683
1684 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
1685 if (ab) {
1686 if (ab->_hpp) {
1687 if (ab->_hpp->enable_perr) {
1688 command |= PCI_COMMAND_PARITY;
1689 bcommand |= PCI_BRIDGE_CTL_PARITY;
1690 } else {
1691 command &= ~PCI_COMMAND_PARITY;
1692 bcommand &= ~PCI_BRIDGE_CTL_PARITY;
1693 }
1694 if (ab->_hpp->enable_serr) {
1695 command |= PCI_COMMAND_SERR;
1696 bcommand |= PCI_BRIDGE_CTL_SERR;
1697 } else {
1698 command &= ~PCI_COMMAND_SERR;
1699 bcommand &= ~PCI_BRIDGE_CTL_SERR;
1700 }
1701 } else
1702 dbg("no _hpp for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
1703 } else
1704 dbg("no acpi bridge for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
1705
1706 if (command != cmd) {
1707 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
1708 }
1709 if ((card_type == PCI_HEADER_TYPE_BRIDGE) && (bcommand != bcmd)) {
1710 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
1711 }
1712}
1713
diff --git a/drivers/pci/hotplug/shpchprm_legacy.c b/drivers/pci/hotplug/shpchprm_legacy.c
new file mode 100644
index 000000000000..37fa77a98289
--- /dev/null
+++ b/drivers/pci/hotplug/shpchprm_legacy.c
@@ -0,0 +1,439 @@
1/*
2 * SHPCHPRM Legacy: PHP Resource Manager for Non-ACPI/Legacy platform
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>,<dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/types.h>
34#include <linux/pci.h>
35#include <linux/init.h>
36#include <asm/uaccess.h>
37#ifdef CONFIG_IA64
38#include <asm/iosapic.h>
39#endif
40#include "shpchp.h"
41#include "shpchprm.h"
42#include "shpchprm_legacy.h"
43
44static void __iomem *shpchp_rom_start;
45static u16 unused_IRQ;
46
47void shpchprm_cleanup(void)
48{
49 if (shpchp_rom_start)
50 iounmap(shpchp_rom_start);
51}
52
53int shpchprm_print_pirt(void)
54{
55 return 0;
56}
57
58int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
59{
60 int offset = devnum - ctrl->slot_device_offset;
61
62 *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc * offset);
63 return 0;
64}
65
66/* Find the Hot Plug Resource Table in the specified region of memory */
67static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iomem *end)
68{
69 void __iomem *fp;
70 void __iomem *endp;
71 u8 temp1, temp2, temp3, temp4;
72 int status = 0;
73
74 endp = (end - sizeof(struct hrt) + 1);
75
76 for (fp = begin; fp <= endp; fp += 16) {
77 temp1 = readb(fp + SIG0);
78 temp2 = readb(fp + SIG1);
79 temp3 = readb(fp + SIG2);
80 temp4 = readb(fp + SIG3);
81 if (temp1 == '$' && temp2 == 'H' && temp3 == 'R' && temp4 == 'T') {
82 status = 1;
83 break;
84 }
85 }
86
87 if (!status)
88 fp = NULL;
89
90 dbg("Discovered Hotplug Resource Table at %p\n", fp);
91 return fp;
92}
93
94/*
95 * shpchprm_find_available_resources
96 *
97 * Finds available memory, IO, and IRQ resources for programming
98 * devices which may be added to the system
99 * this function is for hot plug ADD!
100 *
101 * returns 0 if success
102 */
103int shpchprm_find_available_resources(struct controller *ctrl)
104{
105 u8 populated_slot;
106 u8 bridged_slot;
107 void __iomem *one_slot;
108 struct pci_func *func = NULL;
109 int i = 10, index = 0;
110 u32 temp_dword, rc;
111 ulong temp_ulong;
112 struct pci_resource *mem_node;
113 struct pci_resource *p_mem_node;
114 struct pci_resource *io_node;
115 struct pci_resource *bus_node;
116 void __iomem *rom_resource_table;
117 struct pci_bus lpci_bus, *pci_bus;
118 u8 cfgspc_irq, temp;
119
120 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
121 pci_bus = &lpci_bus;
122 rom_resource_table = detect_HRT_floating_pointer(shpchp_rom_start, shpchp_rom_start + 0xffff);
123 dbg("rom_resource_table = %p\n", rom_resource_table);
124 if (rom_resource_table == NULL)
125 return -ENODEV;
126
127 /* Sum all resources and setup resource maps */
128 unused_IRQ = readl(rom_resource_table + UNUSED_IRQ);
129 dbg("unused_IRQ = %x\n", unused_IRQ);
130
131 temp = 0;
132 while (unused_IRQ) {
133 if (unused_IRQ & 1) {
134 shpchp_disk_irq = temp;
135 break;
136 }
137 unused_IRQ = unused_IRQ >> 1;
138 temp++;
139 }
140
141 dbg("shpchp_disk_irq= %d\n", shpchp_disk_irq);
142 unused_IRQ = unused_IRQ >> 1;
143 temp++;
144
145 while (unused_IRQ) {
146 if (unused_IRQ & 1) {
147 shpchp_nic_irq = temp;
148 break;
149 }
150 unused_IRQ = unused_IRQ >> 1;
151 temp++;
152 }
153
154 dbg("shpchp_nic_irq= %d\n", shpchp_nic_irq);
155 unused_IRQ = readl(rom_resource_table + PCIIRQ);
156
157 temp = 0;
158
159 pci_read_config_byte(ctrl->pci_dev, PCI_INTERRUPT_LINE, &cfgspc_irq);
160
161 if (!shpchp_nic_irq) {
162 shpchp_nic_irq = cfgspc_irq;
163 }
164
165 if (!shpchp_disk_irq) {
166 shpchp_disk_irq = cfgspc_irq;
167 }
168
169 dbg("shpchp_disk_irq, shpchp_nic_irq= %d, %d\n", shpchp_disk_irq, shpchp_nic_irq);
170
171 one_slot = rom_resource_table + sizeof(struct hrt);
172
173 i = readb(rom_resource_table + NUMBER_OF_ENTRIES);
174 dbg("number_of_entries = %d\n", i);
175
176 if (!readb(one_slot + SECONDARY_BUS))
177 return (1);
178
179 dbg("dev|IO base|length|MEMbase|length|PM base|length|PB SB MB\n");
180
181 while (i && readb(one_slot + SECONDARY_BUS)) {
182 u8 dev_func = readb(one_slot + DEV_FUNC);
183 u8 primary_bus = readb(one_slot + PRIMARY_BUS);
184 u8 secondary_bus = readb(one_slot + SECONDARY_BUS);
185 u8 max_bus = readb(one_slot + MAX_BUS);
186 u16 io_base = readw(one_slot + IO_BASE);
187 u16 io_length = readw(one_slot + IO_LENGTH);
188 u16 mem_base = readw(one_slot + MEM_BASE);
189 u16 mem_length = readw(one_slot + MEM_LENGTH);
190 u16 pre_mem_base = readw(one_slot + PRE_MEM_BASE);
191 u16 pre_mem_length = readw(one_slot + PRE_MEM_LENGTH);
192
193 dbg("%2.2x | %4.4x | %4.4x | %4.4x | %4.4x | %4.4x | %4.4x |%2.2x %2.2x %2.2x\n",
194 dev_func, io_base, io_length, mem_base, mem_length, pre_mem_base, pre_mem_length,
195 primary_bus, secondary_bus, max_bus);
196
197 /* If this entry isn't for our controller's bus, ignore it */
198 if (primary_bus != ctrl->slot_bus) {
199 i--;
200 one_slot += sizeof(struct slot_rt);
201 continue;
202 }
203 /* find out if this entry is for an occupied slot */
204 temp_dword = 0xFFFFFFFF;
205 pci_bus->number = primary_bus;
206 pci_bus_read_config_dword(pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword);
207
208 dbg("temp_D_word = %x\n", temp_dword);
209
210 if (temp_dword != 0xFFFFFFFF) {
211 index = 0;
212 func = shpchp_slot_find(primary_bus, dev_func >> 3, 0);
213
214 while (func && (func->function != (dev_func & 0x07))) {
215 dbg("func = %p b:d:f(%x:%x:%x)\n", func, primary_bus, dev_func >> 3, index);
216 func = shpchp_slot_find(primary_bus, dev_func >> 3, index++);
217 }
218
219 /* If we can't find a match, skip this table entry */
220 if (!func) {
221 i--;
222 one_slot += sizeof(struct slot_rt);
223 continue;
224 }
225 /* this may not work and shouldn't be used */
226 if (secondary_bus != primary_bus)
227 bridged_slot = 1;
228 else
229 bridged_slot = 0;
230
231 populated_slot = 1;
232 } else {
233 populated_slot = 0;
234 bridged_slot = 0;
235 }
236 dbg("slot populated =%s \n", populated_slot?"yes":"no");
237
238 /* If we've got a valid IO base, use it */
239
240 temp_ulong = io_base + io_length;
241
242 if ((io_base) && (temp_ulong <= 0x10000)) {
243 io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
244 if (!io_node)
245 return -ENOMEM;
246
247 io_node->base = (ulong)io_base;
248 io_node->length = (ulong)io_length;
249 dbg("found io_node(base, length) = %x, %x\n", io_node->base, io_node->length);
250
251 if (!populated_slot) {
252 io_node->next = ctrl->io_head;
253 ctrl->io_head = io_node;
254 } else {
255 io_node->next = func->io_head;
256 func->io_head = io_node;
257 }
258 }
259
260 /* If we've got a valid memory base, use it */
261 temp_ulong = mem_base + mem_length;
262 if ((mem_base) && (temp_ulong <= 0x10000)) {
263 mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
264 if (!mem_node)
265 return -ENOMEM;
266
267 mem_node->base = (ulong)mem_base << 16;
268 mem_node->length = (ulong)(mem_length << 16);
269 dbg("found mem_node(base, length) = %x, %x\n", mem_node->base, mem_node->length);
270
271 if (!populated_slot) {
272 mem_node->next = ctrl->mem_head;
273 ctrl->mem_head = mem_node;
274 } else {
275 mem_node->next = func->mem_head;
276 func->mem_head = mem_node;
277 }
278 }
279
280 /*
281 * If we've got a valid prefetchable memory base, and
282 * the base + length isn't greater than 0xFFFF
283 */
284 temp_ulong = pre_mem_base + pre_mem_length;
285 if ((pre_mem_base) && (temp_ulong <= 0x10000)) {
286 p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
287 if (!p_mem_node)
288 return -ENOMEM;
289
290 p_mem_node->base = (ulong)pre_mem_base << 16;
291 p_mem_node->length = (ulong)pre_mem_length << 16;
292 dbg("found p_mem_node(base, length) = %x, %x\n", p_mem_node->base, p_mem_node->length);
293
294 if (!populated_slot) {
295 p_mem_node->next = ctrl->p_mem_head;
296 ctrl->p_mem_head = p_mem_node;
297 } else {
298 p_mem_node->next = func->p_mem_head;
299 func->p_mem_head = p_mem_node;
300 }
301 }
302
303 /*
304 * If we've got a valid bus number, use it
305 * The second condition is to ignore bus numbers on
306 * populated slots that don't have PCI-PCI bridges
307 */
308 if (secondary_bus && (secondary_bus != primary_bus)) {
309 bus_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
310 if (!bus_node)
311 return -ENOMEM;
312
313 bus_node->base = (ulong)secondary_bus;
314 bus_node->length = (ulong)(max_bus - secondary_bus + 1);
315 dbg("found bus_node(base, length) = %x, %x\n", bus_node->base, bus_node->length);
316
317 if (!populated_slot) {
318 bus_node->next = ctrl->bus_head;
319 ctrl->bus_head = bus_node;
320 } else {
321 bus_node->next = func->bus_head;
322 func->bus_head = bus_node;
323 }
324 }
325
326 i--;
327 one_slot += sizeof(struct slot_rt);
328 }
329
330 /* If all of the following fail, we don't have any resources for hot plug add */
331 rc = 1;
332 rc &= shpchp_resource_sort_and_combine(&(ctrl->mem_head));
333 rc &= shpchp_resource_sort_and_combine(&(ctrl->p_mem_head));
334 rc &= shpchp_resource_sort_and_combine(&(ctrl->io_head));
335 rc &= shpchp_resource_sort_and_combine(&(ctrl->bus_head));
336
337 return (rc);
338}
339
340int shpchprm_set_hpp(
341 struct controller *ctrl,
342 struct pci_func *func,
343 u8 card_type)
344{
345 u32 rc;
346 u8 temp_byte;
347 struct pci_bus lpci_bus, *pci_bus;
348 unsigned int devfn;
349 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
350 pci_bus = &lpci_bus;
351 pci_bus->number = func->bus;
352 devfn = PCI_DEVFN(func->device, func->function);
353
354 temp_byte = 0x40; /* hard coded value for LT */
355 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
356 /* set subordinate Latency Timer */
357 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
358 if (rc) {
359 dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus,
360 func->device, func->function);
361 return rc;
362 }
363 }
364
365 /* set base Latency Timer */
366 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
367 if (rc) {
368 dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
369 return rc;
370 }
371
372 /* set Cache Line size */
373 temp_byte = 0x08; /* hard coded value for CLS */
374 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
375 if (rc) {
376 dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
377 }
378
379 /* set enable_perr */
380 /* set enable_serr */
381
382 return rc;
383}
384
385void shpchprm_enable_card(
386 struct controller *ctrl,
387 struct pci_func *func,
388 u8 card_type)
389{
390 u16 command, bcommand;
391 struct pci_bus lpci_bus, *pci_bus;
392 unsigned int devfn;
393 int rc;
394
395 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
396 pci_bus = &lpci_bus;
397 pci_bus->number = func->bus;
398 devfn = PCI_DEVFN(func->device, func->function);
399
400 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
401 command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR
402 | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
403 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
404 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
405
406 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
407 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
408 bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR
409 | PCI_BRIDGE_CTL_NO_ISA;
410 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
411 }
412}
413
414static int legacy_shpchprm_init_pci(void)
415{
416 shpchp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN);
417 if (!shpchp_rom_start) {
418 err("Could not ioremap memory region for ROM\n");
419 return -EIO;
420 }
421
422 return 0;
423}
424
425int shpchprm_init(enum php_ctlr_type ctrl_type)
426{
427 int retval;
428
429 switch (ctrl_type) {
430 case PCI:
431 retval = legacy_shpchprm_init_pci();
432 break;
433 default:
434 retval = -ENODEV;
435 break;
436 }
437
438 return retval;
439}
diff --git a/drivers/pci/hotplug/shpchprm_legacy.h b/drivers/pci/hotplug/shpchprm_legacy.h
new file mode 100644
index 000000000000..29ccea5e57e5
--- /dev/null
+++ b/drivers/pci/hotplug/shpchprm_legacy.h
@@ -0,0 +1,113 @@
1/*
2 * SHPCHPRM Legacy: PHP Resource Manager for Non-ACPI/Legacy platform using HRT
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
27 *
28 */
29
30#ifndef _SHPCHPRM_LEGACY_H_
31#define _SHPCHPRM_LEGACY_H_
32
33#define ROM_PHY_ADDR 0x0F0000
34#define ROM_PHY_LEN 0x00FFFF
35
36struct slot_rt {
37 u8 dev_func;
38 u8 primary_bus;
39 u8 secondary_bus;
40 u8 max_bus;
41 u16 io_base;
42 u16 io_length;
43 u16 mem_base;
44 u16 mem_length;
45 u16 pre_mem_base;
46 u16 pre_mem_length;
47} __attribute__ ((packed));
48
49/* offsets to the hotplug slot resource table registers based on the above structure layout */
50enum slot_rt_offsets {
51 DEV_FUNC = offsetof(struct slot_rt, dev_func),
52 PRIMARY_BUS = offsetof(struct slot_rt, primary_bus),
53 SECONDARY_BUS = offsetof(struct slot_rt, secondary_bus),
54 MAX_BUS = offsetof(struct slot_rt, max_bus),
55 IO_BASE = offsetof(struct slot_rt, io_base),
56 IO_LENGTH = offsetof(struct slot_rt, io_length),
57 MEM_BASE = offsetof(struct slot_rt, mem_base),
58 MEM_LENGTH = offsetof(struct slot_rt, mem_length),
59 PRE_MEM_BASE = offsetof(struct slot_rt, pre_mem_base),
60 PRE_MEM_LENGTH = offsetof(struct slot_rt, pre_mem_length),
61};
62
63struct hrt {
64 char sig0;
65 char sig1;
66 char sig2;
67 char sig3;
68 u16 unused_IRQ;
69 u16 PCIIRQ;
70 u8 number_of_entries;
71 u8 revision;
72 u16 reserved1;
73 u32 reserved2;
74} __attribute__ ((packed));
75
76/* offsets to the hotplug resource table registers based on the above structure layout */
77enum hrt_offsets {
78 SIG0 = offsetof(struct hrt, sig0),
79 SIG1 = offsetof(struct hrt, sig1),
80 SIG2 = offsetof(struct hrt, sig2),
81 SIG3 = offsetof(struct hrt, sig3),
82 UNUSED_IRQ = offsetof(struct hrt, unused_IRQ),
83 PCIIRQ = offsetof(struct hrt, PCIIRQ),
84 NUMBER_OF_ENTRIES = offsetof(struct hrt, number_of_entries),
85 REVISION = offsetof(struct hrt, revision),
86 HRT_RESERVED1 = offsetof(struct hrt, reserved1),
87 HRT_RESERVED2 = offsetof(struct hrt, reserved2),
88};
89
90struct irq_info {
91 u8 bus, devfn; /* bus, device and function */
92 struct {
93 u8 link; /* IRQ line ID, chipset dependent, 0=not routed */
94 u16 bitmap; /* Available IRQs */
95 } __attribute__ ((packed)) irq[4];
96 u8 slot; /* slot number, 0=onboard */
97 u8 rfu;
98} __attribute__ ((packed));
99
100struct irq_routing_table {
101 u32 signature; /* PIRQ_SIGNATURE should be here */
102 u16 version; /* PIRQ_VERSION */
103 u16 size; /* Table size in bytes */
104 u8 rtr_bus, rtr_devfn; /* Where the interrupt router lies */
105 u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */
106 u16 rtr_vendor, rtr_device; /* Vendor and device ID of interrupt router */
107 u32 miniport_data; /* Crap */
108 u8 rfu[11];
109 u8 checksum; /* Modulo 256 checksum must give zero */
110 struct irq_info slots[0];
111} __attribute__ ((packed));
112
113#endif /* _SHPCHPRM_LEGACY_H_ */
diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.c b/drivers/pci/hotplug/shpchprm_nonacpi.c
new file mode 100644
index 000000000000..88f4d9f41886
--- /dev/null
+++ b/drivers/pci/hotplug/shpchprm_nonacpi.c
@@ -0,0 +1,434 @@
1/*
2 * SHPCHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/types.h>
34#include <linux/pci.h>
35#include <linux/init.h>
36#include <asm/uaccess.h>
37#ifdef CONFIG_IA64
38#include <asm/iosapic.h>
39#endif
40#include "shpchp.h"
41#include "shpchprm.h"
42#include "shpchprm_nonacpi.h"
43
44void shpchprm_cleanup(void)
45{
46 return;
47}
48
49int shpchprm_print_pirt(void)
50{
51 return 0;
52}
53
54int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
55{
56 int offset = devnum - ctrl->slot_device_offset;
57
58 dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__, ctrl->slot_num_inc, offset);
59 *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc * offset);
60 return 0;
61}
62
63static void print_pci_resource ( struct pci_resource *aprh)
64{
65 struct pci_resource *res;
66
67 for (res = aprh; res; res = res->next)
68 dbg(" base= 0x%x length= 0x%x\n", res->base, res->length);
69}
70
71
72static void phprm_dump_func_res( struct pci_func *fun)
73{
74 struct pci_func *func = fun;
75
76 if (func->bus_head) {
77 dbg(": BUS Resources:\n");
78 print_pci_resource (func->bus_head);
79 }
80 if (func->io_head) {
81 dbg(": IO Resources:\n");
82 print_pci_resource (func->io_head);
83 }
84 if (func->mem_head) {
85 dbg(": MEM Resources:\n");
86 print_pci_resource (func->mem_head);
87 }
88 if (func->p_mem_head) {
89 dbg(": PMEM Resources:\n");
90 print_pci_resource (func->p_mem_head);
91 }
92}
93
94static int phprm_get_used_resources (
95 struct controller *ctrl,
96 struct pci_func *func
97 )
98{
99 return shpchp_save_used_resources (ctrl, func, !DISABLE_CARD);
100}
101
102static int phprm_delete_resource(
103 struct pci_resource **aprh,
104 ulong base,
105 ulong size)
106{
107 struct pci_resource *res;
108 struct pci_resource *prevnode;
109 struct pci_resource *split_node;
110 ulong tbase;
111
112 shpchp_resource_sort_and_combine(aprh);
113
114 for (res = *aprh; res; res = res->next) {
115 if (res->base > base)
116 continue;
117
118 if ((res->base + res->length) < (base + size))
119 continue;
120
121 if (res->base < base) {
122 tbase = base;
123
124 if ((res->length - (tbase - res->base)) < size)
125 continue;
126
127 split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
128 if (!split_node)
129 return -ENOMEM;
130
131 split_node->base = res->base;
132 split_node->length = tbase - res->base;
133 res->base = tbase;
134 res->length -= split_node->length;
135
136 split_node->next = res->next;
137 res->next = split_node;
138 }
139
140 if (res->length >= size) {
141 split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
142 if (!split_node)
143 return -ENOMEM;
144
145 split_node->base = res->base + size;
146 split_node->length = res->length - size;
147 res->length = size;
148
149 split_node->next = res->next;
150 res->next = split_node;
151 }
152
153 if (*aprh == res) {
154 *aprh = res->next;
155 } else {
156 prevnode = *aprh;
157 while (prevnode->next != res)
158 prevnode = prevnode->next;
159
160 prevnode->next = res->next;
161 }
162 res->next = NULL;
163 kfree(res);
164 break;
165 }
166
167 return 0;
168}
169
170
171static int phprm_delete_resources(
172 struct pci_resource **aprh,
173 struct pci_resource *this
174 )
175{
176 struct pci_resource *res;
177
178 for (res = this; res; res = res->next)
179 phprm_delete_resource(aprh, res->base, res->length);
180
181 return 0;
182}
183
184
185static int configure_existing_function(
186 struct controller *ctrl,
187 struct pci_func *func
188 )
189{
190 int rc;
191
192 /* see how much resources the func has used. */
193 rc = phprm_get_used_resources (ctrl, func);
194
195 if (!rc) {
196 /* subtract the resources used by the func from ctrl resources */
197 rc = phprm_delete_resources (&ctrl->bus_head, func->bus_head);
198 rc |= phprm_delete_resources (&ctrl->io_head, func->io_head);
199 rc |= phprm_delete_resources (&ctrl->mem_head, func->mem_head);
200 rc |= phprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
201 if (rc)
202 warn("aCEF: cannot del used resources\n");
203 } else
204 err("aCEF: cannot get used resources\n");
205
206 return rc;
207}
208
209static int bind_pci_resources_to_slots ( struct controller *ctrl)
210{
211 struct pci_func *func, new_func;
212 int busn = ctrl->slot_bus;
213 int devn, funn;
214 u32 vid;
215
216 for (devn = 0; devn < 32; devn++) {
217 for (funn = 0; funn < 8; funn++) {
218 /*
219 if (devn == ctrl->device && funn == ctrl->function)
220 continue;
221 */
222 /* find out if this entry is for an occupied slot */
223 vid = 0xFFFFFFFF;
224
225 pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
226
227 if (vid != 0xFFFFFFFF) {
228 func = shpchp_slot_find(busn, devn, funn);
229 if (!func) {
230 memset(&new_func, 0, sizeof(struct pci_func));
231 new_func.bus = busn;
232 new_func.device = devn;
233 new_func.function = funn;
234 new_func.is_a_board = 1;
235 configure_existing_function(ctrl, &new_func);
236 phprm_dump_func_res(&new_func);
237 } else {
238 configure_existing_function(ctrl, func);
239 phprm_dump_func_res(func);
240 }
241 dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
242 }
243 }
244 }
245
246 return 0;
247}
248
249static void phprm_dump_ctrl_res( struct controller *ctlr)
250{
251 struct controller *ctrl = ctlr;
252
253 if (ctrl->bus_head) {
254 dbg(": BUS Resources:\n");
255 print_pci_resource (ctrl->bus_head);
256 }
257 if (ctrl->io_head) {
258 dbg(": IO Resources:\n");
259 print_pci_resource (ctrl->io_head);
260 }
261 if (ctrl->mem_head) {
262 dbg(": MEM Resources:\n");
263 print_pci_resource (ctrl->mem_head);
264 }
265 if (ctrl->p_mem_head) {
266 dbg(": PMEM Resources:\n");
267 print_pci_resource (ctrl->p_mem_head);
268 }
269}
270
271/*
272 * phprm_find_available_resources
273 *
274 * Finds available memory, IO, and IRQ resources for programming
275 * devices which may be added to the system
276 * this function is for hot plug ADD!
277 *
278 * returns 0 if success
279 */
280int shpchprm_find_available_resources(struct controller *ctrl)
281{
282 struct pci_func func;
283 u32 rc;
284
285 memset(&func, 0, sizeof(struct pci_func));
286
287 func.bus = ctrl->bus;
288 func.device = ctrl->device;
289 func.function = ctrl->function;
290 func.is_a_board = 1;
291
292 /* Get resources for this PCI bridge */
293 rc = shpchp_save_used_resources (ctrl, &func, !DISABLE_CARD);
294 dbg("%s: shpchp_save_used_resources rc = %d\n", __FUNCTION__, rc);
295
296 if (func.mem_head)
297 func.mem_head->next = ctrl->mem_head;
298 ctrl->mem_head = func.mem_head;
299
300 if (func.p_mem_head)
301 func.p_mem_head->next = ctrl->p_mem_head;
302 ctrl->p_mem_head = func.p_mem_head;
303
304 if (func.io_head)
305 func.io_head->next = ctrl->io_head;
306 ctrl->io_head = func.io_head;
307
308 if(func.bus_head)
309 func.bus_head->next = ctrl->bus_head;
310 ctrl->bus_head = func.bus_head;
311 if (ctrl->bus_head)
312 phprm_delete_resource(&ctrl->bus_head, ctrl->pci_dev->subordinate->number, 1);
313
314 dbg("%s:pre-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
315 phprm_dump_ctrl_res(ctrl);
316 bind_pci_resources_to_slots (ctrl);
317
318 dbg("%s:post-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
319 phprm_dump_ctrl_res(ctrl);
320
321
322 /* If all of the following fail, we don't have any resources for hot plug add */
323 rc = 1;
324 rc &= shpchp_resource_sort_and_combine(&(ctrl->mem_head));
325 rc &= shpchp_resource_sort_and_combine(&(ctrl->p_mem_head));
326 rc &= shpchp_resource_sort_and_combine(&(ctrl->io_head));
327 rc &= shpchp_resource_sort_and_combine(&(ctrl->bus_head));
328
329 return (rc);
330}
331
332int shpchprm_set_hpp(
333 struct controller *ctrl,
334 struct pci_func *func,
335 u8 card_type)
336{
337 u32 rc;
338 u8 temp_byte;
339 struct pci_bus lpci_bus, *pci_bus;
340 unsigned int devfn;
341 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
342 pci_bus = &lpci_bus;
343 pci_bus->number = func->bus;
344 devfn = PCI_DEVFN(func->device, func->function);
345
346 temp_byte = 0x40; /* hard coded value for LT */
347 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
348 /* set subordinate Latency Timer */
349 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
350
351 if (rc) {
352 dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus,
353 func->device, func->function);
354 return rc;
355 }
356 }
357
358 /* set base Latency Timer */
359 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
360
361 if (rc) {
362 dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
363 return rc;
364 }
365
366 /* set Cache Line size */
367 temp_byte = 0x08; /* hard coded value for CLS */
368
369 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
370
371 if (rc) {
372 dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
373 }
374
375 /* set enable_perr */
376 /* set enable_serr */
377
378 return rc;
379}
380
381void shpchprm_enable_card(
382 struct controller *ctrl,
383 struct pci_func *func,
384 u8 card_type)
385{
386 u16 command, bcommand;
387 struct pci_bus lpci_bus, *pci_bus;
388 unsigned int devfn;
389 int rc;
390
391 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
392 pci_bus = &lpci_bus;
393 pci_bus->number = func->bus;
394 devfn = PCI_DEVFN(func->device, func->function);
395
396 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
397
398 command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR
399 | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
400 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
401
402 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
403
404 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
405
406 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
407
408 bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR
409 | PCI_BRIDGE_CTL_NO_ISA;
410
411 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
412 }
413}
414
415static int legacy_shpchprm_init_pci(void)
416{
417 return 0;
418}
419
420int shpchprm_init(enum php_ctlr_type ctrl_type)
421{
422 int retval;
423
424 switch (ctrl_type) {
425 case PCI:
426 retval = legacy_shpchprm_init_pci();
427 break;
428 default:
429 retval = -ENODEV;
430 break;
431 }
432
433 return retval;
434}
diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.h b/drivers/pci/hotplug/shpchprm_nonacpi.h
new file mode 100644
index 000000000000..6bc8668023c3
--- /dev/null
+++ b/drivers/pci/hotplug/shpchprm_nonacpi.h
@@ -0,0 +1,56 @@
1/*
2 * SHPCHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
27 *
28 */
29
30#ifndef _SHPCHPRM_NONACPI_H_
31#define _SHPCHPRM_NONACPI_H_
32
33struct irq_info {
34 u8 bus, devfn; /* bus, device and function */
35 struct {
36 u8 link; /* IRQ line ID, chipset dependent, 0=not routed */
37 u16 bitmap; /* Available IRQs */
38 } __attribute__ ((packed)) irq[4];
39 u8 slot; /* slot number, 0=onboard */
40 u8 rfu;
41} __attribute__ ((packed));
42
43struct irq_routing_table {
44 u32 signature; /* PIRQ_SIGNATURE should be here */
45 u16 version; /* PIRQ_VERSION */
46 u16 size; /* Table size in bytes */
47 u8 rtr_bus, rtr_devfn; /* Where the interrupt router lies */
48 u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */
49 u16 rtr_vendor, rtr_device; /* Vendor and device ID of interrupt router */
50 u32 miniport_data; /* Crap */
51 u8 rfu[11];
52 u8 checksum; /* Modulo 256 checksum must give zero */
53 struct irq_info slots[0];
54} __attribute__ ((packed));
55
56#endif /* _SHPCHPRM_NONACPI_H_ */
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
new file mode 100644
index 000000000000..22ecd3b058be
--- /dev/null
+++ b/drivers/pci/msi.c
@@ -0,0 +1,1151 @@
1/*
2 * File: msi.c
3 * Purpose: PCI Message Signaled Interrupt (MSI)
4 *
5 * Copyright (C) 2003-2004 Intel
6 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
7 */
8
9#include <linux/mm.h>
10#include <linux/irq.h>
11#include <linux/interrupt.h>
12#include <linux/init.h>
13#include <linux/config.h>
14#include <linux/ioport.h>
15#include <linux/smp_lock.h>
16#include <linux/pci.h>
17#include <linux/proc_fs.h>
18
19#include <asm/errno.h>
20#include <asm/io.h>
21#include <asm/smp.h>
22
23#include "pci.h"
24#include "msi.h"
25
26static DEFINE_SPINLOCK(msi_lock);
27static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
28static kmem_cache_t* msi_cachep;
29
30static int pci_msi_enable = 1;
31static int last_alloc_vector = 0;
32static int nr_released_vectors = 0;
33static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS;
34static int nr_msix_devices = 0;
35
36#ifndef CONFIG_X86_IO_APIC
37int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};
38u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 };
39#endif
40
41static void msi_cache_ctor(void *p, kmem_cache_t *cache, unsigned long flags)
42{
43 memset(p, 0, NR_IRQS * sizeof(struct msi_desc));
44}
45
46static int msi_cache_init(void)
47{
48 msi_cachep = kmem_cache_create("msi_cache",
49 NR_IRQS * sizeof(struct msi_desc),
50 0, SLAB_HWCACHE_ALIGN, msi_cache_ctor, NULL);
51 if (!msi_cachep)
52 return -ENOMEM;
53
54 return 0;
55}
56
57static void msi_set_mask_bit(unsigned int vector, int flag)
58{
59 struct msi_desc *entry;
60
61 entry = (struct msi_desc *)msi_desc[vector];
62 if (!entry || !entry->dev || !entry->mask_base)
63 return;
64 switch (entry->msi_attrib.type) {
65 case PCI_CAP_ID_MSI:
66 {
67 int pos;
68 u32 mask_bits;
69
70 pos = (long)entry->mask_base;
71 pci_read_config_dword(entry->dev, pos, &mask_bits);
72 mask_bits &= ~(1);
73 mask_bits |= flag;
74 pci_write_config_dword(entry->dev, pos, mask_bits);
75 break;
76 }
77 case PCI_CAP_ID_MSIX:
78 {
79 int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
80 PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
81 writel(flag, entry->mask_base + offset);
82 break;
83 }
84 default:
85 break;
86 }
87}
88
89#ifdef CONFIG_SMP
90static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
91{
92 struct msi_desc *entry;
93 struct msg_address address;
94
95 entry = (struct msi_desc *)msi_desc[vector];
96 if (!entry || !entry->dev)
97 return;
98
99 switch (entry->msi_attrib.type) {
100 case PCI_CAP_ID_MSI:
101 {
102 int pos;
103
104 if (!(pos = pci_find_capability(entry->dev, PCI_CAP_ID_MSI)))
105 return;
106
107 pci_read_config_dword(entry->dev, msi_lower_address_reg(pos),
108 &address.lo_address.value);
109 address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK;
110 address.lo_address.value |= (cpu_mask_to_apicid(cpu_mask) <<
111 MSI_TARGET_CPU_SHIFT);
112 entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask);
113 pci_write_config_dword(entry->dev, msi_lower_address_reg(pos),
114 address.lo_address.value);
115 break;
116 }
117 case PCI_CAP_ID_MSIX:
118 {
119 int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
120 PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET;
121
122 address.lo_address.value = readl(entry->mask_base + offset);
123 address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK;
124 address.lo_address.value |= (cpu_mask_to_apicid(cpu_mask) <<
125 MSI_TARGET_CPU_SHIFT);
126 entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask);
127 writel(address.lo_address.value, entry->mask_base + offset);
128 break;
129 }
130 default:
131 break;
132 }
133}
134
135#ifdef CONFIG_IRQBALANCE
136static inline void move_msi(int vector)
137{
138 if (!cpus_empty(pending_irq_balance_cpumask[vector])) {
139 set_msi_affinity(vector, pending_irq_balance_cpumask[vector]);
140 cpus_clear(pending_irq_balance_cpumask[vector]);
141 }
142}
143#endif /* CONFIG_IRQBALANCE */
144#endif /* CONFIG_SMP */
145
146static void mask_MSI_irq(unsigned int vector)
147{
148 msi_set_mask_bit(vector, 1);
149}
150
151static void unmask_MSI_irq(unsigned int vector)
152{
153 msi_set_mask_bit(vector, 0);
154}
155
156static unsigned int startup_msi_irq_wo_maskbit(unsigned int vector)
157{
158 struct msi_desc *entry;
159 unsigned long flags;
160
161 spin_lock_irqsave(&msi_lock, flags);
162 entry = msi_desc[vector];
163 if (!entry || !entry->dev) {
164 spin_unlock_irqrestore(&msi_lock, flags);
165 return 0;
166 }
167 entry->msi_attrib.state = 1; /* Mark it active */
168 spin_unlock_irqrestore(&msi_lock, flags);
169
170 return 0; /* never anything pending */
171}
172
173static void release_msi(unsigned int vector);
174static void shutdown_msi_irq(unsigned int vector)
175{
176 release_msi(vector);
177}
178
179#define shutdown_msi_irq_wo_maskbit shutdown_msi_irq
180static void enable_msi_irq_wo_maskbit(unsigned int vector) {}
181static void disable_msi_irq_wo_maskbit(unsigned int vector) {}
182static void ack_msi_irq_wo_maskbit(unsigned int vector) {}
183static void end_msi_irq_wo_maskbit(unsigned int vector)
184{
185 move_msi(vector);
186 ack_APIC_irq();
187}
188
189static unsigned int startup_msi_irq_w_maskbit(unsigned int vector)
190{
191 struct msi_desc *entry;
192 unsigned long flags;
193
194 spin_lock_irqsave(&msi_lock, flags);
195 entry = msi_desc[vector];
196 if (!entry || !entry->dev) {
197 spin_unlock_irqrestore(&msi_lock, flags);
198 return 0;
199 }
200 entry->msi_attrib.state = 1; /* Mark it active */
201 spin_unlock_irqrestore(&msi_lock, flags);
202
203 unmask_MSI_irq(vector);
204 return 0; /* never anything pending */
205}
206
207#define shutdown_msi_irq_w_maskbit shutdown_msi_irq
208#define enable_msi_irq_w_maskbit unmask_MSI_irq
209#define disable_msi_irq_w_maskbit mask_MSI_irq
210#define ack_msi_irq_w_maskbit mask_MSI_irq
211
212static void end_msi_irq_w_maskbit(unsigned int vector)
213{
214 move_msi(vector);
215 unmask_MSI_irq(vector);
216 ack_APIC_irq();
217}
218
219/*
220 * Interrupt Type for MSI-X PCI/PCI-X/PCI-Express Devices,
221 * which implement the MSI-X Capability Structure.
222 */
223static struct hw_interrupt_type msix_irq_type = {
224 .typename = "PCI-MSI-X",
225 .startup = startup_msi_irq_w_maskbit,
226 .shutdown = shutdown_msi_irq_w_maskbit,
227 .enable = enable_msi_irq_w_maskbit,
228 .disable = disable_msi_irq_w_maskbit,
229 .ack = ack_msi_irq_w_maskbit,
230 .end = end_msi_irq_w_maskbit,
231 .set_affinity = set_msi_irq_affinity
232};
233
234/*
235 * Interrupt Type for MSI PCI/PCI-X/PCI-Express Devices,
236 * which implement the MSI Capability Structure with
237 * Mask-and-Pending Bits.
238 */
239static struct hw_interrupt_type msi_irq_w_maskbit_type = {
240 .typename = "PCI-MSI",
241 .startup = startup_msi_irq_w_maskbit,
242 .shutdown = shutdown_msi_irq_w_maskbit,
243 .enable = enable_msi_irq_w_maskbit,
244 .disable = disable_msi_irq_w_maskbit,
245 .ack = ack_msi_irq_w_maskbit,
246 .end = end_msi_irq_w_maskbit,
247 .set_affinity = set_msi_irq_affinity
248};
249
250/*
251 * Interrupt Type for MSI PCI/PCI-X/PCI-Express Devices,
252 * which implement the MSI Capability Structure without
253 * Mask-and-Pending Bits.
254 */
255static struct hw_interrupt_type msi_irq_wo_maskbit_type = {
256 .typename = "PCI-MSI",
257 .startup = startup_msi_irq_wo_maskbit,
258 .shutdown = shutdown_msi_irq_wo_maskbit,
259 .enable = enable_msi_irq_wo_maskbit,
260 .disable = disable_msi_irq_wo_maskbit,
261 .ack = ack_msi_irq_wo_maskbit,
262 .end = end_msi_irq_wo_maskbit,
263 .set_affinity = set_msi_irq_affinity
264};
265
266static void msi_data_init(struct msg_data *msi_data,
267 unsigned int vector)
268{
269 memset(msi_data, 0, sizeof(struct msg_data));
270 msi_data->vector = (u8)vector;
271 msi_data->delivery_mode = MSI_DELIVERY_MODE;
272 msi_data->level = MSI_LEVEL_MODE;
273 msi_data->trigger = MSI_TRIGGER_MODE;
274}
275
276static void msi_address_init(struct msg_address *msi_address)
277{
278 unsigned int dest_id;
279
280 memset(msi_address, 0, sizeof(struct msg_address));
281 msi_address->hi_address = (u32)0;
282 dest_id = (MSI_ADDRESS_HEADER << MSI_ADDRESS_HEADER_SHIFT);
283 msi_address->lo_address.u.dest_mode = MSI_DEST_MODE;
284 msi_address->lo_address.u.redirection_hint = MSI_REDIRECTION_HINT_MODE;
285 msi_address->lo_address.u.dest_id = dest_id;
286 msi_address->lo_address.value |= (MSI_TARGET_CPU << MSI_TARGET_CPU_SHIFT);
287}
288
289static int msi_free_vector(struct pci_dev* dev, int vector, int reassign);
290static int assign_msi_vector(void)
291{
292 static int new_vector_avail = 1;
293 int vector;
294 unsigned long flags;
295
296 /*
297 * msi_lock is provided to ensure that successful allocation of MSI
298 * vector is assigned unique among drivers.
299 */
300 spin_lock_irqsave(&msi_lock, flags);
301
302 if (!new_vector_avail) {
303 int free_vector = 0;
304
305 /*
306 * vector_irq[] = -1 indicates that this specific vector is:
307 * - assigned for MSI (since MSI have no associated IRQ) or
308 * - assigned for legacy if less than 16, or
309 * - having no corresponding 1:1 vector-to-IOxAPIC IRQ mapping
310 * vector_irq[] = 0 indicates that this vector, previously
311 * assigned for MSI, is freed by hotplug removed operations.
312 * This vector will be reused for any subsequent hotplug added
313 * operations.
314 * vector_irq[] > 0 indicates that this vector is assigned for
315 * IOxAPIC IRQs. This vector and its value provides a 1-to-1
316 * vector-to-IOxAPIC IRQ mapping.
317 */
318 for (vector = FIRST_DEVICE_VECTOR; vector < NR_IRQS; vector++) {
319 if (vector_irq[vector] != 0)
320 continue;
321 free_vector = vector;
322 if (!msi_desc[vector])
323 break;
324 else
325 continue;
326 }
327 if (!free_vector) {
328 spin_unlock_irqrestore(&msi_lock, flags);
329 return -EBUSY;
330 }
331 vector_irq[free_vector] = -1;
332 nr_released_vectors--;
333 spin_unlock_irqrestore(&msi_lock, flags);
334 if (msi_desc[free_vector] != NULL) {
335 struct pci_dev *dev;
336 int tail;
337
338 /* free all linked vectors before re-assign */
339 do {
340 spin_lock_irqsave(&msi_lock, flags);
341 dev = msi_desc[free_vector]->dev;
342 tail = msi_desc[free_vector]->link.tail;
343 spin_unlock_irqrestore(&msi_lock, flags);
344 msi_free_vector(dev, tail, 1);
345 } while (free_vector != tail);
346 }
347
348 return free_vector;
349 }
350 vector = assign_irq_vector(AUTO_ASSIGN);
351 last_alloc_vector = vector;
352 if (vector == LAST_DEVICE_VECTOR)
353 new_vector_avail = 0;
354
355 spin_unlock_irqrestore(&msi_lock, flags);
356 return vector;
357}
358
359static int get_new_vector(void)
360{
361 int vector;
362
363 if ((vector = assign_msi_vector()) > 0)
364 set_intr_gate(vector, interrupt[vector]);
365
366 return vector;
367}
368
369static int msi_init(void)
370{
371 static int status = -ENOMEM;
372
373 if (!status)
374 return status;
375
376 if (pci_msi_quirk) {
377 pci_msi_enable = 0;
378 printk(KERN_WARNING "PCI: MSI quirk detected. MSI disabled.\n");
379 status = -EINVAL;
380 return status;
381 }
382
383 if ((status = msi_cache_init()) < 0) {
384 pci_msi_enable = 0;
385 printk(KERN_WARNING "PCI: MSI cache init failed\n");
386 return status;
387 }
388 last_alloc_vector = assign_irq_vector(AUTO_ASSIGN);
389 if (last_alloc_vector < 0) {
390 pci_msi_enable = 0;
391 printk(KERN_WARNING "PCI: No interrupt vectors available for MSI\n");
392 status = -EBUSY;
393 return status;
394 }
395 vector_irq[last_alloc_vector] = 0;
396 nr_released_vectors++;
397
398 return status;
399}
400
401static int get_msi_vector(struct pci_dev *dev)
402{
403 return get_new_vector();
404}
405
406static struct msi_desc* alloc_msi_entry(void)
407{
408 struct msi_desc *entry;
409
410 entry = (struct msi_desc*) kmem_cache_alloc(msi_cachep, SLAB_KERNEL);
411 if (!entry)
412 return NULL;
413
414 memset(entry, 0, sizeof(struct msi_desc));
415 entry->link.tail = entry->link.head = 0; /* single message */
416 entry->dev = NULL;
417
418 return entry;
419}
420
421static void attach_msi_entry(struct msi_desc *entry, int vector)
422{
423 unsigned long flags;
424
425 spin_lock_irqsave(&msi_lock, flags);
426 msi_desc[vector] = entry;
427 spin_unlock_irqrestore(&msi_lock, flags);
428}
429
430static void irq_handler_init(int cap_id, int pos, int mask)
431{
432 spin_lock(&irq_desc[pos].lock);
433 if (cap_id == PCI_CAP_ID_MSIX)
434 irq_desc[pos].handler = &msix_irq_type;
435 else {
436 if (!mask)
437 irq_desc[pos].handler = &msi_irq_wo_maskbit_type;
438 else
439 irq_desc[pos].handler = &msi_irq_w_maskbit_type;
440 }
441 spin_unlock(&irq_desc[pos].lock);
442}
443
444static void enable_msi_mode(struct pci_dev *dev, int pos, int type)
445{
446 u16 control;
447
448 pci_read_config_word(dev, msi_control_reg(pos), &control);
449 if (type == PCI_CAP_ID_MSI) {
450 /* Set enabled bits to single MSI & enable MSI_enable bit */
451 msi_enable(control, 1);
452 pci_write_config_word(dev, msi_control_reg(pos), control);
453 } else {
454 msix_enable(control);
455 pci_write_config_word(dev, msi_control_reg(pos), control);
456 }
457 if (pci_find_capability(dev, PCI_CAP_ID_EXP)) {
458 /* PCI Express Endpoint device detected */
459 u16 cmd;
460 pci_read_config_word(dev, PCI_COMMAND, &cmd);
461 cmd |= PCI_COMMAND_INTX_DISABLE;
462 pci_write_config_word(dev, PCI_COMMAND, cmd);
463 }
464}
465
466static void disable_msi_mode(struct pci_dev *dev, int pos, int type)
467{
468 u16 control;
469
470 pci_read_config_word(dev, msi_control_reg(pos), &control);
471 if (type == PCI_CAP_ID_MSI) {
472 /* Set enabled bits to single MSI & enable MSI_enable bit */
473 msi_disable(control);
474 pci_write_config_word(dev, msi_control_reg(pos), control);
475 } else {
476 msix_disable(control);
477 pci_write_config_word(dev, msi_control_reg(pos), control);
478 }
479 if (pci_find_capability(dev, PCI_CAP_ID_EXP)) {
480 /* PCI Express Endpoint device detected */
481 u16 cmd;
482 pci_read_config_word(dev, PCI_COMMAND, &cmd);
483 cmd &= ~PCI_COMMAND_INTX_DISABLE;
484 pci_write_config_word(dev, PCI_COMMAND, cmd);
485 }
486}
487
488static int msi_lookup_vector(struct pci_dev *dev, int type)
489{
490 int vector;
491 unsigned long flags;
492
493 spin_lock_irqsave(&msi_lock, flags);
494 for (vector = FIRST_DEVICE_VECTOR; vector < NR_IRQS; vector++) {
495 if (!msi_desc[vector] || msi_desc[vector]->dev != dev ||
496 msi_desc[vector]->msi_attrib.type != type ||
497 msi_desc[vector]->msi_attrib.default_vector != dev->irq)
498 continue;
499 spin_unlock_irqrestore(&msi_lock, flags);
500 /* This pre-assigned MSI vector for this device
501 already exits. Override dev->irq with this vector */
502 dev->irq = vector;
503 return 0;
504 }
505 spin_unlock_irqrestore(&msi_lock, flags);
506
507 return -EACCES;
508}
509
510void pci_scan_msi_device(struct pci_dev *dev)
511{
512 if (!dev)
513 return;
514
515 if (pci_find_capability(dev, PCI_CAP_ID_MSIX) > 0)
516 nr_msix_devices++;
517 else if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0)
518 nr_reserved_vectors++;
519}
520
521/**
522 * msi_capability_init - configure device's MSI capability structure
523 * @dev: pointer to the pci_dev data structure of MSI device function
524 *
525 * Setup the MSI capability structure of device funtion with a single
526 * MSI vector, regardless of device function is capable of handling
527 * multiple messages. A return of zero indicates the successful setup
528 * of an entry zero with the new MSI vector or non-zero for otherwise.
529 **/
530static int msi_capability_init(struct pci_dev *dev)
531{
532 struct msi_desc *entry;
533 struct msg_address address;
534 struct msg_data data;
535 int pos, vector;
536 u16 control;
537
538 pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
539 pci_read_config_word(dev, msi_control_reg(pos), &control);
540 /* MSI Entry Initialization */
541 if (!(entry = alloc_msi_entry()))
542 return -ENOMEM;
543
544 if ((vector = get_msi_vector(dev)) < 0) {
545 kmem_cache_free(msi_cachep, entry);
546 return -EBUSY;
547 }
548 entry->link.head = vector;
549 entry->link.tail = vector;
550 entry->msi_attrib.type = PCI_CAP_ID_MSI;
551 entry->msi_attrib.state = 0; /* Mark it not active */
552 entry->msi_attrib.entry_nr = 0;
553 entry->msi_attrib.maskbit = is_mask_bit_support(control);
554 entry->msi_attrib.default_vector = dev->irq; /* Save IOAPIC IRQ */
555 dev->irq = vector;
556 entry->dev = dev;
557 if (is_mask_bit_support(control)) {
558 entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos,
559 is_64bit_address(control));
560 }
561 /* Replace with MSI handler */
562 irq_handler_init(PCI_CAP_ID_MSI, vector, entry->msi_attrib.maskbit);
563 /* Configure MSI capability structure */
564 msi_address_init(&address);
565 msi_data_init(&data, vector);
566 entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >>
567 MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK);
568 pci_write_config_dword(dev, msi_lower_address_reg(pos),
569 address.lo_address.value);
570 if (is_64bit_address(control)) {
571 pci_write_config_dword(dev,
572 msi_upper_address_reg(pos), address.hi_address);
573 pci_write_config_word(dev,
574 msi_data_reg(pos, 1), *((u32*)&data));
575 } else
576 pci_write_config_word(dev,
577 msi_data_reg(pos, 0), *((u32*)&data));
578 if (entry->msi_attrib.maskbit) {
579 unsigned int maskbits, temp;
580 /* All MSIs are unmasked by default, Mask them all */
581 pci_read_config_dword(dev,
582 msi_mask_bits_reg(pos, is_64bit_address(control)),
583 &maskbits);
584 temp = (1 << multi_msi_capable(control));
585 temp = ((temp - 1) & ~temp);
586 maskbits |= temp;
587 pci_write_config_dword(dev,
588 msi_mask_bits_reg(pos, is_64bit_address(control)),
589 maskbits);
590 }
591 attach_msi_entry(entry, vector);
592 /* Set MSI enabled bits */
593 enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
594
595 return 0;
596}
597
598/**
599 * msix_capability_init - configure device's MSI-X capability
600 * @dev: pointer to the pci_dev data structure of MSI-X device function
601 *
602 * Setup the MSI-X capability structure of device funtion with a
603 * single MSI-X vector. A return of zero indicates the successful setup of
604 * requested MSI-X entries with allocated vectors or non-zero for otherwise.
605 **/
606static int msix_capability_init(struct pci_dev *dev,
607 struct msix_entry *entries, int nvec)
608{
609 struct msi_desc *head = NULL, *tail = NULL, *entry = NULL;
610 struct msg_address address;
611 struct msg_data data;
612 int vector, pos, i, j, nr_entries, temp = 0;
613 u32 phys_addr, table_offset;
614 u16 control;
615 u8 bir;
616 void __iomem *base;
617
618 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
619 /* Request & Map MSI-X table region */
620 pci_read_config_word(dev, msi_control_reg(pos), &control);
621 nr_entries = multi_msix_capable(control);
622 pci_read_config_dword(dev, msix_table_offset_reg(pos),
623 &table_offset);
624 bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
625 phys_addr = pci_resource_start (dev, bir);
626 phys_addr += (u32)(table_offset & ~PCI_MSIX_FLAGS_BIRMASK);
627 base = ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE);
628 if (base == NULL)
629 return -ENOMEM;
630
631 /* MSI-X Table Initialization */
632 for (i = 0; i < nvec; i++) {
633 entry = alloc_msi_entry();
634 if (!entry)
635 break;
636 if ((vector = get_msi_vector(dev)) < 0)
637 break;
638
639 j = entries[i].entry;
640 entries[i].vector = vector;
641 entry->msi_attrib.type = PCI_CAP_ID_MSIX;
642 entry->msi_attrib.state = 0; /* Mark it not active */
643 entry->msi_attrib.entry_nr = j;
644 entry->msi_attrib.maskbit = 1;
645 entry->msi_attrib.default_vector = dev->irq;
646 entry->dev = dev;
647 entry->mask_base = base;
648 if (!head) {
649 entry->link.head = vector;
650 entry->link.tail = vector;
651 head = entry;
652 } else {
653 entry->link.head = temp;
654 entry->link.tail = tail->link.tail;
655 tail->link.tail = vector;
656 head->link.head = vector;
657 }
658 temp = vector;
659 tail = entry;
660 /* Replace with MSI-X handler */
661 irq_handler_init(PCI_CAP_ID_MSIX, vector, 1);
662 /* Configure MSI-X capability structure */
663 msi_address_init(&address);
664 msi_data_init(&data, vector);
665 entry->msi_attrib.current_cpu =
666 ((address.lo_address.u.dest_id >>
667 MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK);
668 writel(address.lo_address.value,
669 base + j * PCI_MSIX_ENTRY_SIZE +
670 PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
671 writel(address.hi_address,
672 base + j * PCI_MSIX_ENTRY_SIZE +
673 PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
674 writel(*(u32*)&data,
675 base + j * PCI_MSIX_ENTRY_SIZE +
676 PCI_MSIX_ENTRY_DATA_OFFSET);
677 attach_msi_entry(entry, vector);
678 }
679 if (i != nvec) {
680 i--;
681 for (; i >= 0; i--) {
682 vector = (entries + i)->vector;
683 msi_free_vector(dev, vector, 0);
684 (entries + i)->vector = 0;
685 }
686 return -EBUSY;
687 }
688 /* Set MSI-X enabled bits */
689 enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
690
691 return 0;
692}
693
694/**
695 * pci_enable_msi - configure device's MSI capability structure
696 * @dev: pointer to the pci_dev data structure of MSI device function
697 *
698 * Setup the MSI capability structure of device function with
699 * a single MSI vector upon its software driver call to request for
700 * MSI mode enabled on its hardware device function. A return of zero
701 * indicates the successful setup of an entry zero with the new MSI
702 * vector or non-zero for otherwise.
703 **/
704int pci_enable_msi(struct pci_dev* dev)
705{
706 int pos, temp, status = -EINVAL;
707 u16 control;
708
709 if (!pci_msi_enable || !dev)
710 return status;
711
712 temp = dev->irq;
713
714 if ((status = msi_init()) < 0)
715 return status;
716
717 if (!(pos = pci_find_capability(dev, PCI_CAP_ID_MSI)))
718 return -EINVAL;
719
720 pci_read_config_word(dev, msi_control_reg(pos), &control);
721 if (control & PCI_MSI_FLAGS_ENABLE)
722 return 0; /* Already in MSI mode */
723
724 if (!msi_lookup_vector(dev, PCI_CAP_ID_MSI)) {
725 /* Lookup Sucess */
726 unsigned long flags;
727
728 spin_lock_irqsave(&msi_lock, flags);
729 if (!vector_irq[dev->irq]) {
730 msi_desc[dev->irq]->msi_attrib.state = 0;
731 vector_irq[dev->irq] = -1;
732 nr_released_vectors--;
733 spin_unlock_irqrestore(&msi_lock, flags);
734 enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
735 return 0;
736 }
737 spin_unlock_irqrestore(&msi_lock, flags);
738 dev->irq = temp;
739 }
740 /* Check whether driver already requested for MSI-X vectors */
741 if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)) > 0 &&
742 !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
743 printk(KERN_INFO "PCI: %s: Can't enable MSI. "
744 "Device already has MSI-X vectors assigned\n",
745 pci_name(dev));
746 dev->irq = temp;
747 return -EINVAL;
748 }
749 status = msi_capability_init(dev);
750 if (!status) {
751 if (!pos)
752 nr_reserved_vectors--; /* Only MSI capable */
753 else if (nr_msix_devices > 0)
754 nr_msix_devices--; /* Both MSI and MSI-X capable,
755 but choose enabling MSI */
756 }
757
758 return status;
759}
760
761void pci_disable_msi(struct pci_dev* dev)
762{
763 struct msi_desc *entry;
764 int pos, default_vector;
765 u16 control;
766 unsigned long flags;
767
768 if (!dev || !(pos = pci_find_capability(dev, PCI_CAP_ID_MSI)))
769 return;
770
771 pci_read_config_word(dev, msi_control_reg(pos), &control);
772 if (!(control & PCI_MSI_FLAGS_ENABLE))
773 return;
774
775 spin_lock_irqsave(&msi_lock, flags);
776 entry = msi_desc[dev->irq];
777 if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) {
778 spin_unlock_irqrestore(&msi_lock, flags);
779 return;
780 }
781 if (entry->msi_attrib.state) {
782 spin_unlock_irqrestore(&msi_lock, flags);
783 printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without "
784 "free_irq() on MSI vector %d\n",
785 pci_name(dev), dev->irq);
786 BUG_ON(entry->msi_attrib.state > 0);
787 } else {
788 vector_irq[dev->irq] = 0; /* free it */
789 nr_released_vectors++;
790 default_vector = entry->msi_attrib.default_vector;
791 spin_unlock_irqrestore(&msi_lock, flags);
792 /* Restore dev->irq to its default pin-assertion vector */
793 dev->irq = default_vector;
794 disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI),
795 PCI_CAP_ID_MSI);
796 }
797}
798
799static void release_msi(unsigned int vector)
800{
801 struct msi_desc *entry;
802 unsigned long flags;
803
804 spin_lock_irqsave(&msi_lock, flags);
805 entry = msi_desc[vector];
806 if (entry && entry->dev)
807 entry->msi_attrib.state = 0; /* Mark it not active */
808 spin_unlock_irqrestore(&msi_lock, flags);
809}
810
811static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
812{
813 struct msi_desc *entry;
814 int head, entry_nr, type;
815 void __iomem *base;
816 unsigned long flags;
817
818 spin_lock_irqsave(&msi_lock, flags);
819 entry = msi_desc[vector];
820 if (!entry || entry->dev != dev) {
821 spin_unlock_irqrestore(&msi_lock, flags);
822 return -EINVAL;
823 }
824 type = entry->msi_attrib.type;
825 entry_nr = entry->msi_attrib.entry_nr;
826 head = entry->link.head;
827 base = entry->mask_base;
828 msi_desc[entry->link.head]->link.tail = entry->link.tail;
829 msi_desc[entry->link.tail]->link.head = entry->link.head;
830 entry->dev = NULL;
831 if (!reassign) {
832 vector_irq[vector] = 0;
833 nr_released_vectors++;
834 }
835 msi_desc[vector] = NULL;
836 spin_unlock_irqrestore(&msi_lock, flags);
837
838 kmem_cache_free(msi_cachep, entry);
839
840 if (type == PCI_CAP_ID_MSIX) {
841 if (!reassign)
842 writel(1, base +
843 entry_nr * PCI_MSIX_ENTRY_SIZE +
844 PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
845
846 if (head == vector) {
847 /*
848 * Detect last MSI-X vector to be released.
849 * Release the MSI-X memory-mapped table.
850 */
851 int pos, nr_entries;
852 u32 phys_addr, table_offset;
853 u16 control;
854 u8 bir;
855
856 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
857 pci_read_config_word(dev, msi_control_reg(pos),
858 &control);
859 nr_entries = multi_msix_capable(control);
860 pci_read_config_dword(dev, msix_table_offset_reg(pos),
861 &table_offset);
862 bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
863 phys_addr = pci_resource_start (dev, bir);
864 phys_addr += (u32)(table_offset &
865 ~PCI_MSIX_FLAGS_BIRMASK);
866 iounmap(base);
867 }
868 }
869
870 return 0;
871}
872
873static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec)
874{
875 int vector = head, tail = 0;
876 int i, j = 0, nr_entries = 0;
877 void __iomem *base;
878 unsigned long flags;
879
880 spin_lock_irqsave(&msi_lock, flags);
881 while (head != tail) {
882 nr_entries++;
883 tail = msi_desc[vector]->link.tail;
884 if (entries[0].entry == msi_desc[vector]->msi_attrib.entry_nr)
885 j = vector;
886 vector = tail;
887 }
888 if (*nvec > nr_entries) {
889 spin_unlock_irqrestore(&msi_lock, flags);
890 *nvec = nr_entries;
891 return -EINVAL;
892 }
893 vector = ((j > 0) ? j : head);
894 for (i = 0; i < *nvec; i++) {
895 j = msi_desc[vector]->msi_attrib.entry_nr;
896 msi_desc[vector]->msi_attrib.state = 0; /* Mark it not active */
897 vector_irq[vector] = -1; /* Mark it busy */
898 nr_released_vectors--;
899 entries[i].vector = vector;
900 if (j != (entries + i)->entry) {
901 base = msi_desc[vector]->mask_base;
902 msi_desc[vector]->msi_attrib.entry_nr =
903 (entries + i)->entry;
904 writel( readl(base + j * PCI_MSIX_ENTRY_SIZE +
905 PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET), base +
906 (entries + i)->entry * PCI_MSIX_ENTRY_SIZE +
907 PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
908 writel( readl(base + j * PCI_MSIX_ENTRY_SIZE +
909 PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET), base +
910 (entries + i)->entry * PCI_MSIX_ENTRY_SIZE +
911 PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
912 writel( (readl(base + j * PCI_MSIX_ENTRY_SIZE +
913 PCI_MSIX_ENTRY_DATA_OFFSET) & 0xff00) | vector,
914 base + (entries+i)->entry*PCI_MSIX_ENTRY_SIZE +
915 PCI_MSIX_ENTRY_DATA_OFFSET);
916 }
917 vector = msi_desc[vector]->link.tail;
918 }
919 spin_unlock_irqrestore(&msi_lock, flags);
920
921 return 0;
922}
923
924/**
925 * pci_enable_msix - configure device's MSI-X capability structure
926 * @dev: pointer to the pci_dev data structure of MSI-X device function
927 * @data: pointer to an array of MSI-X entries
928 * @nvec: number of MSI-X vectors requested for allocation by device driver
929 *
930 * Setup the MSI-X capability structure of device function with the number
931 * of requested vectors upon its software driver call to request for
932 * MSI-X mode enabled on its hardware device function. A return of zero
933 * indicates the successful configuration of MSI-X capability structure
934 * with new allocated MSI-X vectors. A return of < 0 indicates a failure.
935 * Or a return of > 0 indicates that driver request is exceeding the number
936 * of vectors available. Driver should use the returned value to re-send
937 * its request.
938 **/
939int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
940{
941 int status, pos, nr_entries, free_vectors;
942 int i, j, temp;
943 u16 control;
944 unsigned long flags;
945
946 if (!pci_msi_enable || !dev || !entries)
947 return -EINVAL;
948
949 if ((status = msi_init()) < 0)
950 return status;
951
952 if (!(pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)))
953 return -EINVAL;
954
955 pci_read_config_word(dev, msi_control_reg(pos), &control);
956 if (control & PCI_MSIX_FLAGS_ENABLE)
957 return -EINVAL; /* Already in MSI-X mode */
958
959 nr_entries = multi_msix_capable(control);
960 if (nvec > nr_entries)
961 return -EINVAL;
962
963 /* Check for any invalid entries */
964 for (i = 0; i < nvec; i++) {
965 if (entries[i].entry >= nr_entries)
966 return -EINVAL; /* invalid entry */
967 for (j = i + 1; j < nvec; j++) {
968 if (entries[i].entry == entries[j].entry)
969 return -EINVAL; /* duplicate entry */
970 }
971 }
972 temp = dev->irq;
973 if (!msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
974 /* Lookup Sucess */
975 nr_entries = nvec;
976 /* Reroute MSI-X table */
977 if (reroute_msix_table(dev->irq, entries, &nr_entries)) {
978 /* #requested > #previous-assigned */
979 dev->irq = temp;
980 return nr_entries;
981 }
982 dev->irq = temp;
983 enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
984 return 0;
985 }
986 /* Check whether driver already requested for MSI vector */
987 if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0 &&
988 !msi_lookup_vector(dev, PCI_CAP_ID_MSI)) {
989 printk(KERN_INFO "PCI: %s: Can't enable MSI-X. "
990 "Device already has an MSI vector assigned\n",
991 pci_name(dev));
992 dev->irq = temp;
993 return -EINVAL;
994 }
995
996 spin_lock_irqsave(&msi_lock, flags);
997 /*
998 * msi_lock is provided to ensure that enough vectors resources are
999 * available before granting.
1000 */
1001 free_vectors = pci_vector_resources(last_alloc_vector,
1002 nr_released_vectors);
1003 /* Ensure that each MSI/MSI-X device has one vector reserved by
1004 default to avoid any MSI-X driver to take all available
1005 resources */
1006 free_vectors -= nr_reserved_vectors;
1007 /* Find the average of free vectors among MSI-X devices */
1008 if (nr_msix_devices > 0)
1009 free_vectors /= nr_msix_devices;
1010 spin_unlock_irqrestore(&msi_lock, flags);
1011
1012 if (nvec > free_vectors) {
1013 if (free_vectors > 0)
1014 return free_vectors;
1015 else
1016 return -EBUSY;
1017 }
1018
1019 status = msix_capability_init(dev, entries, nvec);
1020 if (!status && nr_msix_devices > 0)
1021 nr_msix_devices--;
1022
1023 return status;
1024}
1025
1026void pci_disable_msix(struct pci_dev* dev)
1027{
1028 int pos, temp;
1029 u16 control;
1030
1031 if (!dev || !(pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)))
1032 return;
1033
1034 pci_read_config_word(dev, msi_control_reg(pos), &control);
1035 if (!(control & PCI_MSIX_FLAGS_ENABLE))
1036 return;
1037
1038 temp = dev->irq;
1039 if (!msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
1040 int state, vector, head, tail = 0, warning = 0;
1041 unsigned long flags;
1042
1043 vector = head = dev->irq;
1044 spin_lock_irqsave(&msi_lock, flags);
1045 while (head != tail) {
1046 state = msi_desc[vector]->msi_attrib.state;
1047 if (state)
1048 warning = 1;
1049 else {
1050 vector_irq[vector] = 0; /* free it */
1051 nr_released_vectors++;
1052 }
1053 tail = msi_desc[vector]->link.tail;
1054 vector = tail;
1055 }
1056 spin_unlock_irqrestore(&msi_lock, flags);
1057 if (warning) {
1058 dev->irq = temp;
1059 printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without "
1060 "free_irq() on all MSI-X vectors\n",
1061 pci_name(dev));
1062 BUG_ON(warning > 0);
1063 } else {
1064 dev->irq = temp;
1065 disable_msi_mode(dev,
1066 pci_find_capability(dev, PCI_CAP_ID_MSIX),
1067 PCI_CAP_ID_MSIX);
1068
1069 }
1070 }
1071}
1072
1073/**
1074 * msi_remove_pci_irq_vectors - reclaim MSI(X) vectors to unused state
1075 * @dev: pointer to the pci_dev data structure of MSI(X) device function
1076 *
1077 * Being called during hotplug remove, from which the device funciton
1078 * is hot-removed. All previous assigned MSI/MSI-X vectors, if
1079 * allocated for this device function, are reclaimed to unused state,
1080 * which may be used later on.
1081 **/
1082void msi_remove_pci_irq_vectors(struct pci_dev* dev)
1083{
1084 int state, pos, temp;
1085 unsigned long flags;
1086
1087 if (!pci_msi_enable || !dev)
1088 return;
1089
1090 temp = dev->irq; /* Save IOAPIC IRQ */
1091 if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) > 0 &&
1092 !msi_lookup_vector(dev, PCI_CAP_ID_MSI)) {
1093 spin_lock_irqsave(&msi_lock, flags);
1094 state = msi_desc[dev->irq]->msi_attrib.state;
1095 spin_unlock_irqrestore(&msi_lock, flags);
1096 if (state) {
1097 printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
1098 "called without free_irq() on MSI vector %d\n",
1099 pci_name(dev), dev->irq);
1100 BUG_ON(state > 0);
1101 } else /* Release MSI vector assigned to this device */
1102 msi_free_vector(dev, dev->irq, 0);
1103 dev->irq = temp; /* Restore IOAPIC IRQ */
1104 }
1105 if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)) > 0 &&
1106 !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
1107 int vector, head, tail = 0, warning = 0;
1108 void __iomem *base = NULL;
1109
1110 vector = head = dev->irq;
1111 while (head != tail) {
1112 spin_lock_irqsave(&msi_lock, flags);
1113 state = msi_desc[vector]->msi_attrib.state;
1114 tail = msi_desc[vector]->link.tail;
1115 base = msi_desc[vector]->mask_base;
1116 spin_unlock_irqrestore(&msi_lock, flags);
1117 if (state)
1118 warning = 1;
1119 else if (vector != head) /* Release MSI-X vector */
1120 msi_free_vector(dev, vector, 0);
1121 vector = tail;
1122 }
1123 msi_free_vector(dev, vector, 0);
1124 if (warning) {
1125 /* Force to release the MSI-X memory-mapped table */
1126 u32 phys_addr, table_offset;
1127 u16 control;
1128 u8 bir;
1129
1130 pci_read_config_word(dev, msi_control_reg(pos),
1131 &control);
1132 pci_read_config_dword(dev, msix_table_offset_reg(pos),
1133 &table_offset);
1134 bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
1135 phys_addr = pci_resource_start (dev, bir);
1136 phys_addr += (u32)(table_offset &
1137 ~PCI_MSIX_FLAGS_BIRMASK);
1138 iounmap(base);
1139 printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
1140 "called without free_irq() on all MSI-X vectors\n",
1141 pci_name(dev));
1142 BUG_ON(warning > 0);
1143 }
1144 dev->irq = temp; /* Restore IOAPIC IRQ */
1145 }
1146}
1147
1148EXPORT_SYMBOL(pci_enable_msi);
1149EXPORT_SYMBOL(pci_disable_msi);
1150EXPORT_SYMBOL(pci_enable_msix);
1151EXPORT_SYMBOL(pci_disable_msix);
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h
new file mode 100644
index 000000000000..bef21ae3cbd0
--- /dev/null
+++ b/drivers/pci/msi.h
@@ -0,0 +1,159 @@
1/*
2 * Copyright (C) 2003-2004 Intel
3 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
4 */
5
6#ifndef MSI_H
7#define MSI_H
8
9#include <asm/msi.h>
10
11/*
12 * Assume the maximum number of hot plug slots supported by the system is about
13 * ten. The worstcase is that each of these slots is hot-added with a device,
14 * which has two MSI/MSI-X capable functions. To avoid any MSI-X driver, which
15 * attempts to request all available vectors, NR_HP_RESERVED_VECTORS is defined
16 * as below to ensure at least one message is assigned to each detected MSI/
17 * MSI-X device function.
18 */
19#define NR_HP_RESERVED_VECTORS 20
20
21extern int vector_irq[NR_VECTORS];
22extern cpumask_t pending_irq_balance_cpumask[NR_IRQS];
23extern void (*interrupt[NR_IRQS])(void);
24extern int pci_vector_resources(int last, int nr_released);
25
26#ifdef CONFIG_SMP
27#define set_msi_irq_affinity set_msi_affinity
28#else
29#define set_msi_irq_affinity NULL
30#endif
31
32#ifndef CONFIG_IRQBALANCE
33static inline void move_msi(int vector) {}
34#endif
35
36/*
37 * MSI-X Address Register
38 */
39#define PCI_MSIX_FLAGS_QSIZE 0x7FF
40#define PCI_MSIX_FLAGS_ENABLE (1 << 15)
41#define PCI_MSIX_FLAGS_BIRMASK (7 << 0)
42#define PCI_MSIX_FLAGS_BITMASK (1 << 0)
43
44#define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET 0
45#define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET 4
46#define PCI_MSIX_ENTRY_DATA_OFFSET 8
47#define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET 12
48#define PCI_MSIX_ENTRY_SIZE 16
49
50#define msi_control_reg(base) (base + PCI_MSI_FLAGS)
51#define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO)
52#define msi_upper_address_reg(base) (base + PCI_MSI_ADDRESS_HI)
53#define msi_data_reg(base, is64bit) \
54 ( (is64bit == 1) ? base+PCI_MSI_DATA_64 : base+PCI_MSI_DATA_32 )
55#define msi_mask_bits_reg(base, is64bit) \
56 ( (is64bit == 1) ? base+PCI_MSI_MASK_BIT : base+PCI_MSI_MASK_BIT-4)
57#define msi_disable(control) control &= ~PCI_MSI_FLAGS_ENABLE
58#define multi_msi_capable(control) \
59 (1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1))
60#define multi_msi_enable(control, num) \
61 control |= (((num >> 1) << 4) & PCI_MSI_FLAGS_QSIZE);
62#define is_64bit_address(control) (control & PCI_MSI_FLAGS_64BIT)
63#define is_mask_bit_support(control) (control & PCI_MSI_FLAGS_MASKBIT)
64#define msi_enable(control, num) multi_msi_enable(control, num); \
65 control |= PCI_MSI_FLAGS_ENABLE
66
67#define msix_control_reg msi_control_reg
68#define msix_table_offset_reg(base) (base + 0x04)
69#define msix_pba_offset_reg(base) (base + 0x08)
70#define msix_enable(control) control |= PCI_MSIX_FLAGS_ENABLE
71#define msix_disable(control) control &= ~PCI_MSIX_FLAGS_ENABLE
72#define msix_table_size(control) ((control & PCI_MSIX_FLAGS_QSIZE)+1)
73#define multi_msix_capable msix_table_size
74#define msix_unmask(address) (address & ~PCI_MSIX_FLAGS_BITMASK)
75#define msix_mask(address) (address | PCI_MSIX_FLAGS_BITMASK)
76#define msix_is_pending(address) (address & PCI_MSIX_FLAGS_PENDMASK)
77
78/*
79 * MSI Defined Data Structures
80 */
81#define MSI_ADDRESS_HEADER 0xfee
82#define MSI_ADDRESS_HEADER_SHIFT 12
83#define MSI_ADDRESS_HEADER_MASK 0xfff000
84#define MSI_ADDRESS_DEST_ID_MASK 0xfff0000f
85#define MSI_TARGET_CPU_MASK 0xff
86#define MSI_DELIVERY_MODE 0
87#define MSI_LEVEL_MODE 1 /* Edge always assert */
88#define MSI_TRIGGER_MODE 0 /* MSI is edge sensitive */
89#define MSI_PHYSICAL_MODE 0
90#define MSI_LOGICAL_MODE 1
91#define MSI_REDIRECTION_HINT_MODE 0
92
93struct msg_data {
94#if defined(__LITTLE_ENDIAN_BITFIELD)
95 __u32 vector : 8;
96 __u32 delivery_mode : 3; /* 000b: FIXED | 001b: lowest prior */
97 __u32 reserved_1 : 3;
98 __u32 level : 1; /* 0: deassert | 1: assert */
99 __u32 trigger : 1; /* 0: edge | 1: level */
100 __u32 reserved_2 : 16;
101#elif defined(__BIG_ENDIAN_BITFIELD)
102 __u32 reserved_2 : 16;
103 __u32 trigger : 1; /* 0: edge | 1: level */
104 __u32 level : 1; /* 0: deassert | 1: assert */
105 __u32 reserved_1 : 3;
106 __u32 delivery_mode : 3; /* 000b: FIXED | 001b: lowest prior */
107 __u32 vector : 8;
108#else
109#error "Bitfield endianness not defined! Check your byteorder.h"
110#endif
111} __attribute__ ((packed));
112
113struct msg_address {
114 union {
115 struct {
116#if defined(__LITTLE_ENDIAN_BITFIELD)
117 __u32 reserved_1 : 2;
118 __u32 dest_mode : 1; /*0:physic | 1:logic */
119 __u32 redirection_hint: 1; /*0: dedicated CPU
120 1: lowest priority */
121 __u32 reserved_2 : 4;
122 __u32 dest_id : 24; /* Destination ID */
123#elif defined(__BIG_ENDIAN_BITFIELD)
124 __u32 dest_id : 24; /* Destination ID */
125 __u32 reserved_2 : 4;
126 __u32 redirection_hint: 1; /*0: dedicated CPU
127 1: lowest priority */
128 __u32 dest_mode : 1; /*0:physic | 1:logic */
129 __u32 reserved_1 : 2;
130#else
131#error "Bitfield endianness not defined! Check your byteorder.h"
132#endif
133 }u;
134 __u32 value;
135 }lo_address;
136 __u32 hi_address;
137} __attribute__ ((packed));
138
139struct msi_desc {
140 struct {
141 __u8 type : 5; /* {0: unused, 5h:MSI, 11h:MSI-X} */
142 __u8 maskbit : 1; /* mask-pending bit supported ? */
143 __u8 state : 1; /* {0: free, 1: busy} */
144 __u8 reserved: 1; /* reserved */
145 __u8 entry_nr; /* specific enabled entry */
146 __u8 default_vector; /* default pre-assigned vector */
147 __u8 current_cpu; /* current destination cpu */
148 }msi_attrib;
149
150 struct {
151 __u16 head;
152 __u16 tail;
153 }link;
154
155 void __iomem *mask_base;
156 struct pci_dev *dev;
157};
158
159#endif /* MSI_H */
diff --git a/drivers/pci/names.c b/drivers/pci/names.c
new file mode 100644
index 000000000000..ad224aada7c9
--- /dev/null
+++ b/drivers/pci/names.c
@@ -0,0 +1,137 @@
1/*
2 * PCI Class and Device Name Tables
3 *
4 * Copyright 1993--1999 Drew Eckhardt, Frederic Potter,
5 * David Mosberger-Tang, Martin Mares
6 */
7
8#include <linux/config.h>
9#include <linux/types.h>
10#include <linux/kernel.h>
11#include <linux/pci.h>
12#include <linux/init.h>
13
14#ifdef CONFIG_PCI_NAMES
15
16struct pci_device_info {
17 unsigned short device;
18 unsigned short seen;
19 const char *name;
20};
21
22struct pci_vendor_info {
23 unsigned short vendor;
24 unsigned short nr;
25 const char *name;
26 struct pci_device_info *devices;
27};
28
29/*
30 * This is ridiculous, but we want the strings in
31 * the .init section so that they don't take up
32 * real memory.. Parse the same file multiple times
33 * to get all the info.
34 */
35#define VENDOR( vendor, name ) static char __vendorstr_##vendor[] __devinitdata = name;
36#define ENDVENDOR()
37#define DEVICE( vendor, device, name ) static char __devicestr_##vendor##device[] __devinitdata = name;
38#include "devlist.h"
39
40
41#define VENDOR( vendor, name ) static struct pci_device_info __devices_##vendor[] __devinitdata = {
42#define ENDVENDOR() };
43#define DEVICE( vendor, device, name ) { 0x##device, 0, __devicestr_##vendor##device },
44#include "devlist.h"
45
46static struct pci_vendor_info __devinitdata pci_vendor_list[] = {
47#define VENDOR( vendor, name ) { 0x##vendor, sizeof(__devices_##vendor) / sizeof(struct pci_device_info), __vendorstr_##vendor, __devices_##vendor },
48#define ENDVENDOR()
49#define DEVICE( vendor, device, name )
50#include "devlist.h"
51};
52
53#define VENDORS (sizeof(pci_vendor_list)/sizeof(struct pci_vendor_info))
54
55void __devinit pci_name_device(struct pci_dev *dev)
56{
57 const struct pci_vendor_info *vendor_p = pci_vendor_list;
58 int i = VENDORS;
59 char *name = dev->pretty_name;
60
61 do {
62 if (vendor_p->vendor == dev->vendor)
63 goto match_vendor;
64 vendor_p++;
65 } while (--i);
66
67 /* Couldn't find either the vendor nor the device */
68 sprintf(name, "PCI device %04x:%04x", dev->vendor, dev->device);
69 return;
70
71 match_vendor: {
72 struct pci_device_info *device_p = vendor_p->devices;
73 int i = vendor_p->nr;
74
75 while (i > 0) {
76 if (device_p->device == dev->device)
77 goto match_device;
78 device_p++;
79 i--;
80 }
81
82 /* Ok, found the vendor, but unknown device */
83 sprintf(name, "PCI device %04x:%04x (%." PCI_NAME_HALF "s)",
84 dev->vendor, dev->device, vendor_p->name);
85 return;
86
87 /* Full match */
88 match_device: {
89 char *n = name + sprintf(name, "%s %s",
90 vendor_p->name, device_p->name);
91 int nr = device_p->seen + 1;
92 device_p->seen = nr;
93 if (nr > 1)
94 sprintf(n, " (#%d)", nr);
95 }
96 }
97}
98
99/*
100 * Class names. Not in .init section as they are needed in runtime.
101 */
102
103static u16 pci_class_numbers[] = {
104#define CLASS(x,y) 0x##x,
105#include "classlist.h"
106};
107
108static char *pci_class_names[] = {
109#define CLASS(x,y) y,
110#include "classlist.h"
111};
112
113char *
114pci_class_name(u32 class)
115{
116 int i;
117
118 for(i=0; i<sizeof(pci_class_numbers)/sizeof(pci_class_numbers[0]); i++)
119 if (pci_class_numbers[i] == class)
120 return pci_class_names[i];
121 return NULL;
122}
123
124#else
125
126void __devinit pci_name_device(struct pci_dev *dev)
127{
128}
129
130char *
131pci_class_name(u32 class)
132{
133 return NULL;
134}
135
136#endif /* CONFIG_PCI_NAMES */
137
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
new file mode 100644
index 000000000000..968eb32f292d
--- /dev/null
+++ b/drivers/pci/pci-acpi.c
@@ -0,0 +1,209 @@
1/*
2 * File: pci-acpi.c
3 * Purpose: Provide PCI supports in ACPI
4 *
5 * Copyright (C) 2004 Intel
6 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
7 */
8
9#include <linux/delay.h>
10#include <linux/init.h>
11#include <linux/pci.h>
12#include <linux/module.h>
13#include <acpi/acpi.h>
14#include <acpi/acnamesp.h>
15#include <acpi/acresrc.h>
16#include <acpi/acpi_bus.h>
17
18#include <linux/pci-acpi.h>
19
20static u32 ctrlset_buf[3] = {0, 0, 0};
21static u32 global_ctrlsets = 0;
22u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40, 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};
23
24static acpi_status
25acpi_query_osc (
26 acpi_handle handle,
27 u32 level,
28 void *context,
29 void **retval )
30{
31 acpi_status status;
32 struct acpi_object_list input;
33 union acpi_object in_params[4];
34 struct acpi_buffer output;
35 union acpi_object out_obj;
36 u32 osc_dw0;
37
38 /* Setting up output buffer */
39 output.length = sizeof(out_obj) + 3*sizeof(u32);
40 output.pointer = &out_obj;
41
42 /* Setting up input parameters */
43 input.count = 4;
44 input.pointer = in_params;
45 in_params[0].type = ACPI_TYPE_BUFFER;
46 in_params[0].buffer.length = 16;
47 in_params[0].buffer.pointer = OSC_UUID;
48 in_params[1].type = ACPI_TYPE_INTEGER;
49 in_params[1].integer.value = 1;
50 in_params[2].type = ACPI_TYPE_INTEGER;
51 in_params[2].integer.value = 3;
52 in_params[3].type = ACPI_TYPE_BUFFER;
53 in_params[3].buffer.length = 12;
54 in_params[3].buffer.pointer = (u8 *)context;
55
56 status = acpi_evaluate_object(handle, "_OSC", &input, &output);
57 if (ACPI_FAILURE (status)) {
58 printk(KERN_DEBUG
59 "Evaluate _OSC Set fails. Status = 0x%04x\n", status);
60 return status;
61 }
62 if (out_obj.type != ACPI_TYPE_BUFFER) {
63 printk(KERN_DEBUG
64 "Evaluate _OSC returns wrong type\n");
65 return AE_TYPE;
66 }
67 osc_dw0 = *((u32 *) out_obj.buffer.pointer);
68 if (osc_dw0) {
69 if (osc_dw0 & OSC_REQUEST_ERROR)
70 printk(KERN_DEBUG "_OSC request fails\n");
71 if (osc_dw0 & OSC_INVALID_UUID_ERROR)
72 printk(KERN_DEBUG "_OSC invalid UUID\n");
73 if (osc_dw0 & OSC_INVALID_REVISION_ERROR)
74 printk(KERN_DEBUG "_OSC invalid revision\n");
75 if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
76 /* Update Global Control Set */
77 global_ctrlsets = *((u32 *)(out_obj.buffer.pointer+8));
78 return AE_OK;
79 }
80 return AE_ERROR;
81 }
82
83 /* Update Global Control Set */
84 global_ctrlsets = *((u32 *)(out_obj.buffer.pointer + 8));
85 return AE_OK;
86}
87
88
89static acpi_status
90acpi_run_osc (
91 acpi_handle handle,
92 u32 level,
93 void *context,
94 void **retval )
95{
96 acpi_status status;
97 struct acpi_object_list input;
98 union acpi_object in_params[4];
99 struct acpi_buffer output;
100 union acpi_object out_obj;
101 u32 osc_dw0;
102
103 /* Setting up output buffer */
104 output.length = sizeof(out_obj) + 3*sizeof(u32);
105 output.pointer = &out_obj;
106
107 /* Setting up input parameters */
108 input.count = 4;
109 input.pointer = in_params;
110 in_params[0].type = ACPI_TYPE_BUFFER;
111 in_params[0].buffer.length = 16;
112 in_params[0].buffer.pointer = OSC_UUID;
113 in_params[1].type = ACPI_TYPE_INTEGER;
114 in_params[1].integer.value = 1;
115 in_params[2].type = ACPI_TYPE_INTEGER;
116 in_params[2].integer.value = 3;
117 in_params[3].type = ACPI_TYPE_BUFFER;
118 in_params[3].buffer.length = 12;
119 in_params[3].buffer.pointer = (u8 *)context;
120
121 status = acpi_evaluate_object(handle, "_OSC", &input, &output);
122 if (ACPI_FAILURE (status)) {
123 printk(KERN_DEBUG
124 "Evaluate _OSC Set fails. Status = 0x%04x\n", status);
125 return status;
126 }
127 if (out_obj.type != ACPI_TYPE_BUFFER) {
128 printk(KERN_DEBUG
129 "Evaluate _OSC returns wrong type\n");
130 return AE_TYPE;
131 }
132 osc_dw0 = *((u32 *) out_obj.buffer.pointer);
133 if (osc_dw0) {
134 if (osc_dw0 & OSC_REQUEST_ERROR)
135 printk(KERN_DEBUG "_OSC request fails\n");
136 if (osc_dw0 & OSC_INVALID_UUID_ERROR)
137 printk(KERN_DEBUG "_OSC invalid UUID\n");
138 if (osc_dw0 & OSC_INVALID_REVISION_ERROR)
139 printk(KERN_DEBUG "_OSC invalid revision\n");
140 if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
141 printk(KERN_DEBUG "_OSC FW not grant req. control\n");
142 return AE_SUPPORT;
143 }
144 return AE_ERROR;
145 }
146 return AE_OK;
147}
148
149/**
150 * pci_osc_support_set - register OS support to Firmware
151 * @flags: OS support bits
152 *
153 * Update OS support fields and doing a _OSC Query to obtain an update
154 * from Firmware on supported control bits.
155 **/
156acpi_status pci_osc_support_set(u32 flags)
157{
158 u32 temp;
159
160 if (!(flags & OSC_SUPPORT_MASKS)) {
161 return AE_TYPE;
162 }
163 ctrlset_buf[OSC_SUPPORT_TYPE] |= (flags & OSC_SUPPORT_MASKS);
164
165 /* do _OSC query for all possible controls */
166 temp = ctrlset_buf[OSC_CONTROL_TYPE];
167 ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
168 ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
169 acpi_get_devices ( PCI_ROOT_HID_STRING,
170 acpi_query_osc,
171 ctrlset_buf,
172 NULL );
173 ctrlset_buf[OSC_QUERY_TYPE] = !OSC_QUERY_ENABLE;
174 ctrlset_buf[OSC_CONTROL_TYPE] = temp;
175 return AE_OK;
176}
177EXPORT_SYMBOL(pci_osc_support_set);
178
179/**
180 * pci_osc_control_set - commit requested control to Firmware
181 * @flags: driver's requested control bits
182 *
183 * Attempt to take control from Firmware on requested control bits.
184 **/
185acpi_status pci_osc_control_set(u32 flags)
186{
187 acpi_status status;
188 u32 ctrlset;
189
190 ctrlset = (flags & OSC_CONTROL_MASKS);
191 if (!ctrlset) {
192 return AE_TYPE;
193 }
194 if (ctrlset_buf[OSC_SUPPORT_TYPE] &&
195 ((global_ctrlsets & ctrlset) != ctrlset)) {
196 return AE_SUPPORT;
197 }
198 ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset;
199 status = acpi_get_devices ( PCI_ROOT_HID_STRING,
200 acpi_run_osc,
201 ctrlset_buf,
202 NULL );
203 if (ACPI_FAILURE (status)) {
204 ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset;
205 }
206
207 return status;
208}
209EXPORT_SYMBOL(pci_osc_control_set);
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
new file mode 100644
index 000000000000..37b7961efc44
--- /dev/null
+++ b/drivers/pci/pci-driver.c
@@ -0,0 +1,531 @@
1/*
2 * drivers/pci/pci-driver.c
3 *
4 */
5
6#include <linux/pci.h>
7#include <linux/module.h>
8#include <linux/init.h>
9#include <linux/device.h>
10#include <linux/pci-dynids.h>
11#include "pci.h"
12
13/*
14 * Registration of PCI drivers and handling of hot-pluggable devices.
15 */
16
17/*
18 * Dynamic device IDs are disabled for !CONFIG_HOTPLUG
19 */
20
21#ifdef CONFIG_HOTPLUG
22/**
23 * pci_device_probe_dynamic()
24 *
25 * Walk the dynamic ID list looking for a match.
26 * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error.
27 */
28static int
29pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
30{
31 int error = -ENODEV;
32 struct list_head *pos;
33 struct dynid *dynid;
34
35 spin_lock(&drv->dynids.lock);
36 list_for_each(pos, &drv->dynids.list) {
37 dynid = list_entry(pos, struct dynid, node);
38 if (pci_match_one_device(&dynid->id, pci_dev)) {
39 spin_unlock(&drv->dynids.lock);
40 error = drv->probe(pci_dev, &dynid->id);
41 if (error >= 0) {
42 pci_dev->driver = drv;
43 return 0;
44 }
45 return error;
46 }
47 }
48 spin_unlock(&drv->dynids.lock);
49 return error;
50}
51
52/**
53 * store_new_id
54 *
55 * Adds a new dynamic pci device ID to this driver,
56 * and causes the driver to probe for all devices again.
57 */
58static inline ssize_t
59store_new_id(struct device_driver *driver, const char *buf, size_t count)
60{
61 struct dynid *dynid;
62 struct bus_type * bus;
63 struct pci_driver *pdrv = to_pci_driver(driver);
64 __u32 vendor=PCI_ANY_ID, device=PCI_ANY_ID, subvendor=PCI_ANY_ID,
65 subdevice=PCI_ANY_ID, class=0, class_mask=0;
66 unsigned long driver_data=0;
67 int fields=0;
68
69 fields = sscanf(buf, "%x %x %x %x %x %x %lux",
70 &vendor, &device, &subvendor, &subdevice,
71 &class, &class_mask, &driver_data);
72 if (fields < 0)
73 return -EINVAL;
74
75 dynid = kmalloc(sizeof(*dynid), GFP_KERNEL);
76 if (!dynid)
77 return -ENOMEM;
78
79 memset(dynid, 0, sizeof(*dynid));
80 INIT_LIST_HEAD(&dynid->node);
81 dynid->id.vendor = vendor;
82 dynid->id.device = device;
83 dynid->id.subvendor = subvendor;
84 dynid->id.subdevice = subdevice;
85 dynid->id.class = class;
86 dynid->id.class_mask = class_mask;
87 dynid->id.driver_data = pdrv->dynids.use_driver_data ?
88 driver_data : 0UL;
89
90 spin_lock(&pdrv->dynids.lock);
91 list_add_tail(&pdrv->dynids.list, &dynid->node);
92 spin_unlock(&pdrv->dynids.lock);
93
94 bus = get_bus(pdrv->driver.bus);
95 if (bus) {
96 if (get_driver(&pdrv->driver)) {
97 down_write(&bus->subsys.rwsem);
98 driver_attach(&pdrv->driver);
99 up_write(&bus->subsys.rwsem);
100 put_driver(&pdrv->driver);
101 }
102 put_bus(bus);
103 }
104
105 return count;
106}
107
108static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
109static inline void
110pci_init_dynids(struct pci_dynids *dynids)
111{
112 spin_lock_init(&dynids->lock);
113 INIT_LIST_HEAD(&dynids->list);
114}
115
116static void
117pci_free_dynids(struct pci_driver *drv)
118{
119 struct list_head *pos, *n;
120 struct dynid *dynid;
121
122 spin_lock(&drv->dynids.lock);
123 list_for_each_safe(pos, n, &drv->dynids.list) {
124 dynid = list_entry(pos, struct dynid, node);
125 list_del(&dynid->node);
126 kfree(dynid);
127 }
128 spin_unlock(&drv->dynids.lock);
129}
130
131static int
132pci_create_newid_file(struct pci_driver *drv)
133{
134 int error = 0;
135 if (drv->probe != NULL)
136 error = sysfs_create_file(&drv->driver.kobj,
137 &driver_attr_new_id.attr);
138 return error;
139}
140
141static int
142pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv)
143{
144 struct list_head *pos;
145 struct dynid *dynid;
146
147 spin_lock(&pci_drv->dynids.lock);
148 list_for_each(pos, &pci_drv->dynids.list) {
149 dynid = list_entry(pos, struct dynid, node);
150 if (pci_match_one_device(&dynid->id, pci_dev)) {
151 spin_unlock(&pci_drv->dynids.lock);
152 return 1;
153 }
154 }
155 spin_unlock(&pci_drv->dynids.lock);
156 return 0;
157}
158
159#else /* !CONFIG_HOTPLUG */
160static inline int pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
161{
162 return -ENODEV;
163}
164static inline void pci_init_dynids(struct pci_dynids *dynids) {}
165static inline void pci_free_dynids(struct pci_driver *drv) {}
166static inline int pci_create_newid_file(struct pci_driver *drv)
167{
168 return 0;
169}
170static inline int pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv)
171{
172 return 0;
173}
174#endif
175
176/**
177 * pci_match_device - Tell if a PCI device structure has a matching
178 * PCI device id structure
179 * @ids: array of PCI device id structures to search in
180 * @dev: the PCI device structure to match against
181 *
182 * Used by a driver to check whether a PCI device present in the
183 * system is in its list of supported devices.Returns the matching
184 * pci_device_id structure or %NULL if there is no match.
185 */
186const struct pci_device_id *
187pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev)
188{
189 while (ids->vendor || ids->subvendor || ids->class_mask) {
190 if (pci_match_one_device(ids, dev))
191 return ids;
192 ids++;
193 }
194 return NULL;
195}
196
197/**
198 * pci_device_probe_static()
199 *
200 * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error.
201 */
202static int
203pci_device_probe_static(struct pci_driver *drv, struct pci_dev *pci_dev)
204{
205 int error = -ENODEV;
206 const struct pci_device_id *id;
207
208 if (!drv->id_table)
209 return error;
210 id = pci_match_device(drv->id_table, pci_dev);
211 if (id)
212 error = drv->probe(pci_dev, id);
213 if (error >= 0) {
214 pci_dev->driver = drv;
215 error = 0;
216 }
217 return error;
218}
219
220/**
221 * __pci_device_probe()
222 *
223 * returns 0 on success, else error.
224 * side-effect: pci_dev->driver is set to drv when drv claims pci_dev.
225 */
226static int
227__pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
228{
229 int error = 0;
230
231 if (!pci_dev->driver && drv->probe) {
232 error = pci_device_probe_static(drv, pci_dev);
233 if (error == -ENODEV)
234 error = pci_device_probe_dynamic(drv, pci_dev);
235 }
236 return error;
237}
238
239static int pci_device_probe(struct device * dev)
240{
241 int error = 0;
242 struct pci_driver *drv;
243 struct pci_dev *pci_dev;
244
245 drv = to_pci_driver(dev->driver);
246 pci_dev = to_pci_dev(dev);
247 pci_dev_get(pci_dev);
248 error = __pci_device_probe(drv, pci_dev);
249 if (error)
250 pci_dev_put(pci_dev);
251
252 return error;
253}
254
255static int pci_device_remove(struct device * dev)
256{
257 struct pci_dev * pci_dev = to_pci_dev(dev);
258 struct pci_driver * drv = pci_dev->driver;
259
260 if (drv) {
261 if (drv->remove)
262 drv->remove(pci_dev);
263 pci_dev->driver = NULL;
264 }
265
266 /*
267 * We would love to complain here if pci_dev->is_enabled is set, that
268 * the driver should have called pci_disable_device(), but the
269 * unfortunate fact is there are too many odd BIOS and bridge setups
270 * that don't like drivers doing that all of the time.
271 * Oh well, we can dream of sane hardware when we sleep, no matter how
272 * horrible the crap we have to deal with is when we are awake...
273 */
274
275 pci_dev_put(pci_dev);
276 return 0;
277}
278
279static int pci_device_suspend(struct device * dev, pm_message_t state)
280{
281 struct pci_dev * pci_dev = to_pci_dev(dev);
282 struct pci_driver * drv = pci_dev->driver;
283 int i = 0;
284
285 if (drv && drv->suspend)
286 i = drv->suspend(pci_dev, state);
287 else
288 pci_save_state(pci_dev);
289 return i;
290}
291
292
293/*
294 * Default resume method for devices that have no driver provided resume,
295 * or not even a driver at all.
296 */
297static void pci_default_resume(struct pci_dev *pci_dev)
298{
299 /* restore the PCI config space */
300 pci_restore_state(pci_dev);
301 /* if the device was enabled before suspend, reenable */
302 if (pci_dev->is_enabled)
303 pci_enable_device(pci_dev);
304 /* if the device was busmaster before the suspend, make it busmaster again */
305 if (pci_dev->is_busmaster)
306 pci_set_master(pci_dev);
307}
308
309static int pci_device_resume(struct device * dev)
310{
311 struct pci_dev * pci_dev = to_pci_dev(dev);
312 struct pci_driver * drv = pci_dev->driver;
313
314 if (drv && drv->resume)
315 drv->resume(pci_dev);
316 else
317 pci_default_resume(pci_dev);
318 return 0;
319}
320
321
322#define kobj_to_pci_driver(obj) container_of(obj, struct device_driver, kobj)
323#define attr_to_driver_attribute(obj) container_of(obj, struct driver_attribute, attr)
324
325static ssize_t
326pci_driver_attr_show(struct kobject * kobj, struct attribute *attr, char *buf)
327{
328 struct device_driver *driver = kobj_to_pci_driver(kobj);
329 struct driver_attribute *dattr = attr_to_driver_attribute(attr);
330 ssize_t ret = 0;
331
332 if (get_driver(driver)) {
333 if (dattr->show)
334 ret = dattr->show(driver, buf);
335 put_driver(driver);
336 }
337 return ret;
338}
339
340static ssize_t
341pci_driver_attr_store(struct kobject * kobj, struct attribute *attr,
342 const char *buf, size_t count)
343{
344 struct device_driver *driver = kobj_to_pci_driver(kobj);
345 struct driver_attribute *dattr = attr_to_driver_attribute(attr);
346 ssize_t ret = 0;
347
348 if (get_driver(driver)) {
349 if (dattr->store)
350 ret = dattr->store(driver, buf, count);
351 put_driver(driver);
352 }
353 return ret;
354}
355
356static struct sysfs_ops pci_driver_sysfs_ops = {
357 .show = pci_driver_attr_show,
358 .store = pci_driver_attr_store,
359};
360static struct kobj_type pci_driver_kobj_type = {
361 .sysfs_ops = &pci_driver_sysfs_ops,
362};
363
364static int
365pci_populate_driver_dir(struct pci_driver *drv)
366{
367 return pci_create_newid_file(drv);
368}
369
370/**
371 * pci_register_driver - register a new pci driver
372 * @drv: the driver structure to register
373 *
374 * Adds the driver structure to the list of registered drivers.
375 * Returns a negative value on error, otherwise 0.
376 * If no error occured, the driver remains registered even if
377 * no device was claimed during registration.
378 */
379int pci_register_driver(struct pci_driver *drv)
380{
381 int error;
382
383 /* initialize common driver fields */
384 drv->driver.name = drv->name;
385 drv->driver.bus = &pci_bus_type;
386 drv->driver.probe = pci_device_probe;
387 drv->driver.remove = pci_device_remove;
388 drv->driver.owner = drv->owner;
389 drv->driver.kobj.ktype = &pci_driver_kobj_type;
390 pci_init_dynids(&drv->dynids);
391
392 /* register with core */
393 error = driver_register(&drv->driver);
394
395 if (!error)
396 pci_populate_driver_dir(drv);
397
398 return error;
399}
400
401/**
402 * pci_unregister_driver - unregister a pci driver
403 * @drv: the driver structure to unregister
404 *
405 * Deletes the driver structure from the list of registered PCI drivers,
406 * gives it a chance to clean up by calling its remove() function for
407 * each device it was responsible for, and marks those devices as
408 * driverless.
409 */
410
411void
412pci_unregister_driver(struct pci_driver *drv)
413{
414 driver_unregister(&drv->driver);
415 pci_free_dynids(drv);
416}
417
418static struct pci_driver pci_compat_driver = {
419 .name = "compat"
420};
421
422/**
423 * pci_dev_driver - get the pci_driver of a device
424 * @dev: the device to query
425 *
426 * Returns the appropriate pci_driver structure or %NULL if there is no
427 * registered driver for the device.
428 */
429struct pci_driver *
430pci_dev_driver(const struct pci_dev *dev)
431{
432 if (dev->driver)
433 return dev->driver;
434 else {
435 int i;
436 for(i=0; i<=PCI_ROM_RESOURCE; i++)
437 if (dev->resource[i].flags & IORESOURCE_BUSY)
438 return &pci_compat_driver;
439 }
440 return NULL;
441}
442
443/**
444 * pci_bus_match - Tell if a PCI device structure has a matching PCI device id structure
445 * @ids: array of PCI device id structures to search in
446 * @dev: the PCI device structure to match against
447 *
448 * Used by a driver to check whether a PCI device present in the
449 * system is in its list of supported devices.Returns the matching
450 * pci_device_id structure or %NULL if there is no match.
451 */
452static int pci_bus_match(struct device * dev, struct device_driver * drv)
453{
454 const struct pci_dev * pci_dev = to_pci_dev(dev);
455 struct pci_driver * pci_drv = to_pci_driver(drv);
456 const struct pci_device_id * ids = pci_drv->id_table;
457 const struct pci_device_id *found_id;
458
459 if (!ids)
460 return 0;
461
462 found_id = pci_match_device(ids, pci_dev);
463 if (found_id)
464 return 1;
465
466 return pci_bus_match_dynids(pci_dev, pci_drv);
467}
468
469/**
470 * pci_dev_get - increments the reference count of the pci device structure
471 * @dev: the device being referenced
472 *
473 * Each live reference to a device should be refcounted.
474 *
475 * Drivers for PCI devices should normally record such references in
476 * their probe() methods, when they bind to a device, and release
477 * them by calling pci_dev_put(), in their disconnect() methods.
478 *
479 * A pointer to the device with the incremented reference counter is returned.
480 */
481struct pci_dev *pci_dev_get(struct pci_dev *dev)
482{
483 if (dev)
484 get_device(&dev->dev);
485 return dev;
486}
487
488/**
489 * pci_dev_put - release a use of the pci device structure
490 * @dev: device that's been disconnected
491 *
492 * Must be called when a user of a device is finished with it. When the last
493 * user of the device calls this function, the memory of the device is freed.
494 */
495void pci_dev_put(struct pci_dev *dev)
496{
497 if (dev)
498 put_device(&dev->dev);
499}
500
501#ifndef CONFIG_HOTPLUG
502int pci_hotplug (struct device *dev, char **envp, int num_envp,
503 char *buffer, int buffer_size)
504{
505 return -ENODEV;
506}
507#endif
508
509struct bus_type pci_bus_type = {
510 .name = "pci",
511 .match = pci_bus_match,
512 .hotplug = pci_hotplug,
513 .suspend = pci_device_suspend,
514 .resume = pci_device_resume,
515 .dev_attrs = pci_dev_attrs,
516};
517
518static int __init pci_driver_init(void)
519{
520 return bus_register(&pci_bus_type);
521}
522
523postcore_initcall(pci_driver_init);
524
525EXPORT_SYMBOL(pci_match_device);
526EXPORT_SYMBOL(pci_register_driver);
527EXPORT_SYMBOL(pci_unregister_driver);
528EXPORT_SYMBOL(pci_dev_driver);
529EXPORT_SYMBOL(pci_bus_type);
530EXPORT_SYMBOL(pci_dev_get);
531EXPORT_SYMBOL(pci_dev_put);
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
new file mode 100644
index 000000000000..d57ae71d32b1
--- /dev/null
+++ b/drivers/pci/pci-sysfs.c
@@ -0,0 +1,490 @@
1/*
2 * drivers/pci/pci-sysfs.c
3 *
4 * (C) Copyright 2002-2004 Greg Kroah-Hartman <greg@kroah.com>
5 * (C) Copyright 2002-2004 IBM Corp.
6 * (C) Copyright 2003 Matthew Wilcox
7 * (C) Copyright 2003 Hewlett-Packard
8 * (C) Copyright 2004 Jon Smirl <jonsmirl@yahoo.com>
9 * (C) Copyright 2004 Silicon Graphics, Inc. Jesse Barnes <jbarnes@sgi.com>
10 *
11 * File attributes for PCI devices
12 *
13 * Modeled after usb's driverfs.c
14 *
15 */
16
17
18#include <linux/config.h>
19#include <linux/kernel.h>
20#include <linux/pci.h>
21#include <linux/stat.h>
22#include <linux/topology.h>
23#include <linux/mm.h>
24
25#include "pci.h"
26
27static int sysfs_initialized; /* = 0 */
28
29/* show configuration fields */
30#define pci_config_attr(field, format_string) \
31static ssize_t \
32field##_show(struct device *dev, char *buf) \
33{ \
34 struct pci_dev *pdev; \
35 \
36 pdev = to_pci_dev (dev); \
37 return sprintf (buf, format_string, pdev->field); \
38}
39
40pci_config_attr(vendor, "0x%04x\n");
41pci_config_attr(device, "0x%04x\n");
42pci_config_attr(subsystem_vendor, "0x%04x\n");
43pci_config_attr(subsystem_device, "0x%04x\n");
44pci_config_attr(class, "0x%06x\n");
45pci_config_attr(irq, "%u\n");
46
47static ssize_t local_cpus_show(struct device *dev, char *buf)
48{
49 cpumask_t mask = pcibus_to_cpumask(to_pci_dev(dev)->bus);
50 int len = cpumask_scnprintf(buf, PAGE_SIZE-2, mask);
51 strcat(buf,"\n");
52 return 1+len;
53}
54
55/* show resources */
56static ssize_t
57resource_show(struct device * dev, char * buf)
58{
59 struct pci_dev * pci_dev = to_pci_dev(dev);
60 char * str = buf;
61 int i;
62 int max = 7;
63
64 if (pci_dev->subordinate)
65 max = DEVICE_COUNT_RESOURCE;
66
67 for (i = 0; i < max; i++) {
68 str += sprintf(str,"0x%016lx 0x%016lx 0x%016lx\n",
69 pci_resource_start(pci_dev,i),
70 pci_resource_end(pci_dev,i),
71 pci_resource_flags(pci_dev,i));
72 }
73 return (str - buf);
74}
75
76struct device_attribute pci_dev_attrs[] = {
77 __ATTR_RO(resource),
78 __ATTR_RO(vendor),
79 __ATTR_RO(device),
80 __ATTR_RO(subsystem_vendor),
81 __ATTR_RO(subsystem_device),
82 __ATTR_RO(class),
83 __ATTR_RO(irq),
84 __ATTR_RO(local_cpus),
85 __ATTR_NULL,
86};
87
88static ssize_t
89pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
90{
91 struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
92 unsigned int size = 64;
93 loff_t init_off = off;
94
95 /* Several chips lock up trying to read undefined config space */
96 if (capable(CAP_SYS_ADMIN)) {
97 size = dev->cfg_size;
98 } else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
99 size = 128;
100 }
101
102 if (off > size)
103 return 0;
104 if (off + count > size) {
105 size -= off;
106 count = size;
107 } else {
108 size = count;
109 }
110
111 while (off & 3) {
112 unsigned char val;
113 pci_read_config_byte(dev, off, &val);
114 buf[off - init_off] = val;
115 off++;
116 if (--size == 0)
117 break;
118 }
119
120 while (size > 3) {
121 unsigned int val;
122 pci_read_config_dword(dev, off, &val);
123 buf[off - init_off] = val & 0xff;
124 buf[off - init_off + 1] = (val >> 8) & 0xff;
125 buf[off - init_off + 2] = (val >> 16) & 0xff;
126 buf[off - init_off + 3] = (val >> 24) & 0xff;
127 off += 4;
128 size -= 4;
129 }
130
131 while (size > 0) {
132 unsigned char val;
133 pci_read_config_byte(dev, off, &val);
134 buf[off - init_off] = val;
135 off++;
136 --size;
137 }
138
139 return count;
140}
141
142static ssize_t
143pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
144{
145 struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
146 unsigned int size = count;
147 loff_t init_off = off;
148
149 if (off > dev->cfg_size)
150 return 0;
151 if (off + count > dev->cfg_size) {
152 size = dev->cfg_size - off;
153 count = size;
154 }
155
156 while (off & 3) {
157 pci_write_config_byte(dev, off, buf[off - init_off]);
158 off++;
159 if (--size == 0)
160 break;
161 }
162
163 while (size > 3) {
164 unsigned int val = buf[off - init_off];
165 val |= (unsigned int) buf[off - init_off + 1] << 8;
166 val |= (unsigned int) buf[off - init_off + 2] << 16;
167 val |= (unsigned int) buf[off - init_off + 3] << 24;
168 pci_write_config_dword(dev, off, val);
169 off += 4;
170 size -= 4;
171 }
172
173 while (size > 0) {
174 pci_write_config_byte(dev, off, buf[off - init_off]);
175 off++;
176 --size;
177 }
178
179 return count;
180}
181
182#ifdef HAVE_PCI_LEGACY
183/**
184 * pci_read_legacy_io - read byte(s) from legacy I/O port space
185 * @kobj: kobject corresponding to file to read from
186 * @buf: buffer to store results
187 * @off: offset into legacy I/O port space
188 * @count: number of bytes to read
189 *
190 * Reads 1, 2, or 4 bytes from legacy I/O port space using an arch specific
191 * callback routine (pci_legacy_read).
192 */
193ssize_t
194pci_read_legacy_io(struct kobject *kobj, char *buf, loff_t off, size_t count)
195{
196 struct pci_bus *bus = to_pci_bus(container_of(kobj,
197 struct class_device,
198 kobj));
199
200 /* Only support 1, 2 or 4 byte accesses */
201 if (count != 1 && count != 2 && count != 4)
202 return -EINVAL;
203
204 return pci_legacy_read(bus, off, (u32 *)buf, count);
205}
206
207/**
208 * pci_write_legacy_io - write byte(s) to legacy I/O port space
209 * @kobj: kobject corresponding to file to read from
210 * @buf: buffer containing value to be written
211 * @off: offset into legacy I/O port space
212 * @count: number of bytes to write
213 *
214 * Writes 1, 2, or 4 bytes from legacy I/O port space using an arch specific
215 * callback routine (pci_legacy_write).
216 */
217ssize_t
218pci_write_legacy_io(struct kobject *kobj, char *buf, loff_t off, size_t count)
219{
220 struct pci_bus *bus = to_pci_bus(container_of(kobj,
221 struct class_device,
222 kobj));
223 /* Only support 1, 2 or 4 byte accesses */
224 if (count != 1 && count != 2 && count != 4)
225 return -EINVAL;
226
227 return pci_legacy_write(bus, off, *(u32 *)buf, count);
228}
229
230/**
231 * pci_mmap_legacy_mem - map legacy PCI memory into user memory space
232 * @kobj: kobject corresponding to device to be mapped
233 * @attr: struct bin_attribute for this file
234 * @vma: struct vm_area_struct passed to mmap
235 *
236 * Uses an arch specific callback, pci_mmap_legacy_page_range, to mmap
237 * legacy memory space (first meg of bus space) into application virtual
238 * memory space.
239 */
240int
241pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr,
242 struct vm_area_struct *vma)
243{
244 struct pci_bus *bus = to_pci_bus(container_of(kobj,
245 struct class_device,
246 kobj));
247
248 return pci_mmap_legacy_page_range(bus, vma);
249}
250#endif /* HAVE_PCI_LEGACY */
251
252#ifdef HAVE_PCI_MMAP
253/**
254 * pci_mmap_resource - map a PCI resource into user memory space
255 * @kobj: kobject for mapping
256 * @attr: struct bin_attribute for the file being mapped
257 * @vma: struct vm_area_struct passed into the mmap
258 *
259 * Use the regular PCI mapping routines to map a PCI resource into userspace.
260 * FIXME: write combining? maybe automatic for prefetchable regions?
261 */
262static int
263pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
264 struct vm_area_struct *vma)
265{
266 struct pci_dev *pdev = to_pci_dev(container_of(kobj,
267 struct device, kobj));
268 struct resource *res = (struct resource *)attr->private;
269 enum pci_mmap_state mmap_type;
270
271 vma->vm_pgoff += res->start >> PAGE_SHIFT;
272 mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
273
274 return pci_mmap_page_range(pdev, vma, mmap_type, 0);
275}
276
277/**
278 * pci_create_resource_files - create resource files in sysfs for @dev
279 * @dev: dev in question
280 *
281 * Walk the resources in @dev creating files for each resource available.
282 */
283static void
284pci_create_resource_files(struct pci_dev *pdev)
285{
286 int i;
287
288 /* Expose the PCI resources from this device as files */
289 for (i = 0; i < PCI_ROM_RESOURCE; i++) {
290 struct bin_attribute *res_attr;
291
292 /* skip empty resources */
293 if (!pci_resource_len(pdev, i))
294 continue;
295
296 res_attr = kmalloc(sizeof(*res_attr) + 10, GFP_ATOMIC);
297 if (res_attr) {
298 memset(res_attr, 0, sizeof(*res_attr) + 10);
299 pdev->res_attr[i] = res_attr;
300 /* Allocated above after the res_attr struct */
301 res_attr->attr.name = (char *)(res_attr + 1);
302 sprintf(res_attr->attr.name, "resource%d", i);
303 res_attr->size = pci_resource_len(pdev, i);
304 res_attr->attr.mode = S_IRUSR | S_IWUSR;
305 res_attr->attr.owner = THIS_MODULE;
306 res_attr->mmap = pci_mmap_resource;
307 res_attr->private = &pdev->resource[i];
308 sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
309 }
310 }
311}
312
313/**
314 * pci_remove_resource_files - cleanup resource files
315 * @dev: dev to cleanup
316 *
317 * If we created resource files for @dev, remove them from sysfs and
318 * free their resources.
319 */
320static void
321pci_remove_resource_files(struct pci_dev *pdev)
322{
323 int i;
324
325 for (i = 0; i < PCI_ROM_RESOURCE; i++) {
326 struct bin_attribute *res_attr;
327
328 res_attr = pdev->res_attr[i];
329 if (res_attr) {
330 sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
331 kfree(res_attr);
332 }
333 }
334}
335#else /* !HAVE_PCI_MMAP */
336static inline void pci_create_resource_files(struct pci_dev *dev) { return; }
337static inline void pci_remove_resource_files(struct pci_dev *dev) { return; }
338#endif /* HAVE_PCI_MMAP */
339
340/**
341 * pci_write_rom - used to enable access to the PCI ROM display
342 * @kobj: kernel object handle
343 * @buf: user input
344 * @off: file offset
345 * @count: number of byte in input
346 *
347 * writing anything except 0 enables it
348 */
349static ssize_t
350pci_write_rom(struct kobject *kobj, char *buf, loff_t off, size_t count)
351{
352 struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj));
353
354 if ((off == 0) && (*buf == '0') && (count == 2))
355 pdev->rom_attr_enabled = 0;
356 else
357 pdev->rom_attr_enabled = 1;
358
359 return count;
360}
361
362/**
363 * pci_read_rom - read a PCI ROM
364 * @kobj: kernel object handle
365 * @buf: where to put the data we read from the ROM
366 * @off: file offset
367 * @count: number of bytes to read
368 *
369 * Put @count bytes starting at @off into @buf from the ROM in the PCI
370 * device corresponding to @kobj.
371 */
372static ssize_t
373pci_read_rom(struct kobject *kobj, char *buf, loff_t off, size_t count)
374{
375 struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj));
376 void __iomem *rom;
377 size_t size;
378
379 if (!pdev->rom_attr_enabled)
380 return -EINVAL;
381
382 rom = pci_map_rom(pdev, &size); /* size starts out as PCI window size */
383 if (!rom)
384 return 0;
385
386 if (off >= size)
387 count = 0;
388 else {
389 if (off + count > size)
390 count = size - off;
391
392 memcpy_fromio(buf, rom + off, count);
393 }
394 pci_unmap_rom(pdev, rom);
395
396 return count;
397}
398
399static struct bin_attribute pci_config_attr = {
400 .attr = {
401 .name = "config",
402 .mode = S_IRUGO | S_IWUSR,
403 .owner = THIS_MODULE,
404 },
405 .size = 256,
406 .read = pci_read_config,
407 .write = pci_write_config,
408};
409
410static struct bin_attribute pcie_config_attr = {
411 .attr = {
412 .name = "config",
413 .mode = S_IRUGO | S_IWUSR,
414 .owner = THIS_MODULE,
415 },
416 .size = 4096,
417 .read = pci_read_config,
418 .write = pci_write_config,
419};
420
421int pci_create_sysfs_dev_files (struct pci_dev *pdev)
422{
423 if (!sysfs_initialized)
424 return -EACCES;
425
426 if (pdev->cfg_size < 4096)
427 sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
428 else
429 sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
430
431 pci_create_resource_files(pdev);
432
433 /* If the device has a ROM, try to expose it in sysfs. */
434 if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
435 struct bin_attribute *rom_attr;
436
437 rom_attr = kmalloc(sizeof(*rom_attr), GFP_ATOMIC);
438 if (rom_attr) {
439 memset(rom_attr, 0x00, sizeof(*rom_attr));
440 pdev->rom_attr = rom_attr;
441 rom_attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
442 rom_attr->attr.name = "rom";
443 rom_attr->attr.mode = S_IRUSR;
444 rom_attr->attr.owner = THIS_MODULE;
445 rom_attr->read = pci_read_rom;
446 rom_attr->write = pci_write_rom;
447 sysfs_create_bin_file(&pdev->dev.kobj, rom_attr);
448 }
449 }
450 /* add platform-specific attributes */
451 pcibios_add_platform_entries(pdev);
452
453 return 0;
454}
455
456/**
457 * pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files
458 * @pdev: device whose entries we should free
459 *
460 * Cleanup when @pdev is removed from sysfs.
461 */
462void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
463{
464 if (pdev->cfg_size < 4096)
465 sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
466 else
467 sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
468
469 pci_remove_resource_files(pdev);
470
471 if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
472 if (pdev->rom_attr) {
473 sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
474 kfree(pdev->rom_attr);
475 }
476 }
477}
478
479static int __init pci_sysfs_init(void)
480{
481 struct pci_dev *pdev = NULL;
482
483 sysfs_initialized = 1;
484 for_each_pci_dev(pdev)
485 pci_create_sysfs_dev_files(pdev);
486
487 return 0;
488}
489
490__initcall(pci_sysfs_init);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
new file mode 100644
index 000000000000..bfbff8335268
--- /dev/null
+++ b/drivers/pci/pci.c
@@ -0,0 +1,837 @@
1/*
2 * $Id: pci.c,v 1.91 1999/01/21 13:34:01 davem Exp $
3 *
4 * PCI Bus Services, see include/linux/pci.h for further explanation.
5 *
6 * Copyright 1993 -- 1997 Drew Eckhardt, Frederic Potter,
7 * David Mosberger-Tang
8 *
9 * Copyright 1997 -- 2000 Martin Mares <mj@ucw.cz>
10 */
11
12#include <linux/kernel.h>
13#include <linux/delay.h>
14#include <linux/init.h>
15#include <linux/pci.h>
16#include <linux/module.h>
17#include <linux/spinlock.h>
18#include <asm/dma.h> /* isa_dma_bridge_buggy */
19
20
21/**
22 * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
23 * @bus: pointer to PCI bus structure to search
24 *
25 * Given a PCI bus, returns the highest PCI bus number present in the set
26 * including the given PCI bus and its list of child PCI buses.
27 */
28unsigned char __devinit
29pci_bus_max_busnr(struct pci_bus* bus)
30{
31 struct list_head *tmp;
32 unsigned char max, n;
33
34 max = bus->number;
35 list_for_each(tmp, &bus->children) {
36 n = pci_bus_max_busnr(pci_bus_b(tmp));
37 if(n > max)
38 max = n;
39 }
40 return max;
41}
42
43/**
44 * pci_max_busnr - returns maximum PCI bus number
45 *
46 * Returns the highest PCI bus number present in the system global list of
47 * PCI buses.
48 */
49unsigned char __devinit
50pci_max_busnr(void)
51{
52 struct pci_bus *bus = NULL;
53 unsigned char max, n;
54
55 max = 0;
56 while ((bus = pci_find_next_bus(bus)) != NULL) {
57 n = pci_bus_max_busnr(bus);
58 if(n > max)
59 max = n;
60 }
61 return max;
62}
63
64static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_type, int cap)
65{
66 u16 status;
67 u8 pos, id;
68 int ttl = 48;
69
70 pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status);
71 if (!(status & PCI_STATUS_CAP_LIST))
72 return 0;
73
74 switch (hdr_type) {
75 case PCI_HEADER_TYPE_NORMAL:
76 case PCI_HEADER_TYPE_BRIDGE:
77 pci_bus_read_config_byte(bus, devfn, PCI_CAPABILITY_LIST, &pos);
78 break;
79 case PCI_HEADER_TYPE_CARDBUS:
80 pci_bus_read_config_byte(bus, devfn, PCI_CB_CAPABILITY_LIST, &pos);
81 break;
82 default:
83 return 0;
84 }
85 while (ttl-- && pos >= 0x40) {
86 pos &= ~3;
87 pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_ID, &id);
88 if (id == 0xff)
89 break;
90 if (id == cap)
91 return pos;
92 pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_NEXT, &pos);
93 }
94 return 0;
95}
96
97/**
98 * pci_find_capability - query for devices' capabilities
99 * @dev: PCI device to query
100 * @cap: capability code
101 *
102 * Tell if a device supports a given PCI capability.
103 * Returns the address of the requested capability structure within the
104 * device's PCI configuration space or 0 in case the device does not
105 * support it. Possible values for @cap:
106 *
107 * %PCI_CAP_ID_PM Power Management
108 * %PCI_CAP_ID_AGP Accelerated Graphics Port
109 * %PCI_CAP_ID_VPD Vital Product Data
110 * %PCI_CAP_ID_SLOTID Slot Identification
111 * %PCI_CAP_ID_MSI Message Signalled Interrupts
112 * %PCI_CAP_ID_CHSWP CompactPCI HotSwap
113 * %PCI_CAP_ID_PCIX PCI-X
114 * %PCI_CAP_ID_EXP PCI Express
115 */
116int pci_find_capability(struct pci_dev *dev, int cap)
117{
118 return __pci_bus_find_cap(dev->bus, dev->devfn, dev->hdr_type, cap);
119}
120
121/**
122 * pci_bus_find_capability - query for devices' capabilities
123 * @bus: the PCI bus to query
124 * @devfn: PCI device to query
125 * @cap: capability code
126 *
127 * Like pci_find_capability() but works for pci devices that do not have a
128 * pci_dev structure set up yet.
129 *
130 * Returns the address of the requested capability structure within the
131 * device's PCI configuration space or 0 in case the device does not
132 * support it.
133 */
134int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap)
135{
136 u8 hdr_type;
137
138 pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type);
139
140 return __pci_bus_find_cap(bus, devfn, hdr_type & 0x7f, cap);
141}
142
143/**
144 * pci_find_ext_capability - Find an extended capability
145 * @dev: PCI device to query
146 * @cap: capability code
147 *
148 * Returns the address of the requested extended capability structure
149 * within the device's PCI configuration space or 0 if the device does
150 * not support it. Possible values for @cap:
151 *
152 * %PCI_EXT_CAP_ID_ERR Advanced Error Reporting
153 * %PCI_EXT_CAP_ID_VC Virtual Channel
154 * %PCI_EXT_CAP_ID_DSN Device Serial Number
155 * %PCI_EXT_CAP_ID_PWR Power Budgeting
156 */
157int pci_find_ext_capability(struct pci_dev *dev, int cap)
158{
159 u32 header;
160 int ttl = 480; /* 3840 bytes, minimum 8 bytes per capability */
161 int pos = 0x100;
162
163 if (dev->cfg_size <= 256)
164 return 0;
165
166 if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
167 return 0;
168
169 /*
170 * If we have no capabilities, this is indicated by cap ID,
171 * cap version and next pointer all being 0.
172 */
173 if (header == 0)
174 return 0;
175
176 while (ttl-- > 0) {
177 if (PCI_EXT_CAP_ID(header) == cap)
178 return pos;
179
180 pos = PCI_EXT_CAP_NEXT(header);
181 if (pos < 0x100)
182 break;
183
184 if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
185 break;
186 }
187
188 return 0;
189}
190
191/**
192 * pci_find_parent_resource - return resource region of parent bus of given region
193 * @dev: PCI device structure contains resources to be searched
194 * @res: child resource record for which parent is sought
195 *
196 * For given resource region of given device, return the resource
197 * region of parent bus the given region is contained in or where
198 * it should be allocated from.
199 */
200struct resource *
201pci_find_parent_resource(const struct pci_dev *dev, struct resource *res)
202{
203 const struct pci_bus *bus = dev->bus;
204 int i;
205 struct resource *best = NULL;
206
207 for(i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
208 struct resource *r = bus->resource[i];
209 if (!r)
210 continue;
211 if (res->start && !(res->start >= r->start && res->end <= r->end))
212 continue; /* Not contained */
213 if ((res->flags ^ r->flags) & (IORESOURCE_IO | IORESOURCE_MEM))
214 continue; /* Wrong type */
215 if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH))
216 return r; /* Exact match */
217 if ((res->flags & IORESOURCE_PREFETCH) && !(r->flags & IORESOURCE_PREFETCH))
218 best = r; /* Approximating prefetchable by non-prefetchable */
219 }
220 return best;
221}
222
223/**
224 * pci_set_power_state - Set the power state of a PCI device
225 * @dev: PCI device to be suspended
226 * @state: PCI power state (D0, D1, D2, D3hot, D3cold) we're entering
227 *
228 * Transition a device to a new power state, using the Power Management
229 * Capabilities in the device's config space.
230 *
231 * RETURN VALUE:
232 * -EINVAL if trying to enter a lower state than we're already in.
233 * 0 if we're already in the requested state.
234 * -EIO if device does not support PCI PM.
235 * 0 if we can successfully change the power state.
236 */
237
238int
239pci_set_power_state(struct pci_dev *dev, pci_power_t state)
240{
241 int pm;
242 u16 pmcsr, pmc;
243
244 /* bound the state we're entering */
245 if (state > PCI_D3hot)
246 state = PCI_D3hot;
247
248 /* Validate current state:
249 * Can enter D0 from any state, but if we can only go deeper
250 * to sleep if we're already in a low power state
251 */
252 if (state != PCI_D0 && dev->current_state > state)
253 return -EINVAL;
254 else if (dev->current_state == state)
255 return 0; /* we're already there */
256
257 /* find PCI PM capability in list */
258 pm = pci_find_capability(dev, PCI_CAP_ID_PM);
259
260 /* abort if the device doesn't support PM capabilities */
261 if (!pm)
262 return -EIO;
263
264 pci_read_config_word(dev,pm + PCI_PM_PMC,&pmc);
265 if ((pmc & PCI_PM_CAP_VER_MASK) > 2) {
266 printk(KERN_DEBUG
267 "PCI: %s has unsupported PM cap regs version (%u)\n",
268 pci_name(dev), pmc & PCI_PM_CAP_VER_MASK);
269 return -EIO;
270 }
271
272 /* check if this device supports the desired state */
273 if (state == PCI_D1 || state == PCI_D2) {
274 if (state == PCI_D1 && !(pmc & PCI_PM_CAP_D1))
275 return -EIO;
276 else if (state == PCI_D2 && !(pmc & PCI_PM_CAP_D2))
277 return -EIO;
278 }
279
280 /* If we're in D3, force entire word to 0.
281 * This doesn't affect PME_Status, disables PME_En, and
282 * sets PowerState to 0.
283 */
284 if (dev->current_state >= PCI_D3hot)
285 pmcsr = 0;
286 else {
287 pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
288 pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
289 pmcsr |= state;
290 }
291
292 /* enter specified state */
293 pci_write_config_word(dev, pm + PCI_PM_CTRL, pmcsr);
294
295 /* Mandatory power management transition delays */
296 /* see PCI PM 1.1 5.6.1 table 18 */
297 if (state == PCI_D3hot || dev->current_state == PCI_D3hot)
298 msleep(10);
299 else if (state == PCI_D2 || dev->current_state == PCI_D2)
300 udelay(200);
301 dev->current_state = state;
302
303 return 0;
304}
305
306/**
307 * pci_choose_state - Choose the power state of a PCI device
308 * @dev: PCI device to be suspended
309 * @state: target sleep state for the whole system. This is the value
310 * that is passed to suspend() function.
311 *
312 * Returns PCI power state suitable for given device and given system
313 * message.
314 */
315
316pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state)
317{
318 if (!pci_find_capability(dev, PCI_CAP_ID_PM))
319 return PCI_D0;
320
321 switch (state) {
322 case 0: return PCI_D0;
323 case 3: return PCI_D3hot;
324 default:
325 printk("They asked me for state %d\n", state);
326 BUG();
327 }
328 return PCI_D0;
329}
330
331EXPORT_SYMBOL(pci_choose_state);
332
333/**
334 * pci_save_state - save the PCI configuration space of a device before suspending
335 * @dev: - PCI device that we're dealing with
336 * @buffer: - buffer to hold config space context
337 *
338 * @buffer must be large enough to hold the entire PCI 2.2 config space
339 * (>= 64 bytes).
340 */
341int
342pci_save_state(struct pci_dev *dev)
343{
344 int i;
345 /* XXX: 100% dword access ok here? */
346 for (i = 0; i < 16; i++)
347 pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]);
348 return 0;
349}
350
351/**
352 * pci_restore_state - Restore the saved state of a PCI device
353 * @dev: - PCI device that we're dealing with
354 * @buffer: - saved PCI config space
355 *
356 */
357int
358pci_restore_state(struct pci_dev *dev)
359{
360 int i;
361
362 for (i = 0; i < 16; i++)
363 pci_write_config_dword(dev,i * 4, dev->saved_config_space[i]);
364 return 0;
365}
366
367/**
368 * pci_enable_device_bars - Initialize some of a device for use
369 * @dev: PCI device to be initialized
370 * @bars: bitmask of BAR's that must be configured
371 *
372 * Initialize device before it's used by a driver. Ask low-level code
373 * to enable selected I/O and memory resources. Wake up the device if it
374 * was suspended. Beware, this function can fail.
375 */
376
377int
378pci_enable_device_bars(struct pci_dev *dev, int bars)
379{
380 int err;
381
382 pci_set_power_state(dev, PCI_D0);
383 if ((err = pcibios_enable_device(dev, bars)) < 0)
384 return err;
385 return 0;
386}
387
388/**
389 * pci_enable_device - Initialize device before it's used by a driver.
390 * @dev: PCI device to be initialized
391 *
392 * Initialize device before it's used by a driver. Ask low-level code
393 * to enable I/O and memory. Wake up the device if it was suspended.
394 * Beware, this function can fail.
395 */
396int
397pci_enable_device(struct pci_dev *dev)
398{
399 int err;
400
401 dev->is_enabled = 1;
402 if ((err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1)))
403 return err;
404 pci_fixup_device(pci_fixup_enable, dev);
405 return 0;
406}
407
408/**
409 * pcibios_disable_device - disable arch specific PCI resources for device dev
410 * @dev: the PCI device to disable
411 *
412 * Disables architecture specific PCI resources for the device. This
413 * is the default implementation. Architecture implementations can
414 * override this.
415 */
416void __attribute__ ((weak)) pcibios_disable_device (struct pci_dev *dev) {}
417
418/**
419 * pci_disable_device - Disable PCI device after use
420 * @dev: PCI device to be disabled
421 *
422 * Signal to the system that the PCI device is not in use by the system
423 * anymore. This only involves disabling PCI bus-mastering, if active.
424 */
425void
426pci_disable_device(struct pci_dev *dev)
427{
428 u16 pci_command;
429
430 dev->is_enabled = 0;
431 dev->is_busmaster = 0;
432
433 pci_read_config_word(dev, PCI_COMMAND, &pci_command);
434 if (pci_command & PCI_COMMAND_MASTER) {
435 pci_command &= ~PCI_COMMAND_MASTER;
436 pci_write_config_word(dev, PCI_COMMAND, pci_command);
437 }
438
439 pcibios_disable_device(dev);
440}
441
442/**
443 * pci_enable_wake - enable device to generate PME# when suspended
444 * @dev: - PCI device to operate on
445 * @state: - Current state of device.
446 * @enable: - Flag to enable or disable generation
447 *
448 * Set the bits in the device's PM Capabilities to generate PME# when
449 * the system is suspended.
450 *
451 * -EIO is returned if device doesn't have PM Capabilities.
452 * -EINVAL is returned if device supports it, but can't generate wake events.
453 * 0 if operation is successful.
454 *
455 */
456int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable)
457{
458 int pm;
459 u16 value;
460
461 /* find PCI PM capability in list */
462 pm = pci_find_capability(dev, PCI_CAP_ID_PM);
463
464 /* If device doesn't support PM Capabilities, but request is to disable
465 * wake events, it's a nop; otherwise fail */
466 if (!pm)
467 return enable ? -EIO : 0;
468
469 /* Check device's ability to generate PME# */
470 pci_read_config_word(dev,pm+PCI_PM_PMC,&value);
471
472 value &= PCI_PM_CAP_PME_MASK;
473 value >>= ffs(PCI_PM_CAP_PME_MASK) - 1; /* First bit of mask */
474
475 /* Check if it can generate PME# from requested state. */
476 if (!value || !(value & (1 << state)))
477 return enable ? -EINVAL : 0;
478
479 pci_read_config_word(dev, pm + PCI_PM_CTRL, &value);
480
481 /* Clear PME_Status by writing 1 to it and enable PME# */
482 value |= PCI_PM_CTRL_PME_STATUS | PCI_PM_CTRL_PME_ENABLE;
483
484 if (!enable)
485 value &= ~PCI_PM_CTRL_PME_ENABLE;
486
487 pci_write_config_word(dev, pm + PCI_PM_CTRL, value);
488
489 return 0;
490}
491
492int
493pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge)
494{
495 u8 pin;
496
497 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
498 if (!pin)
499 return -1;
500 pin--;
501 while (dev->bus->self) {
502 pin = (pin + PCI_SLOT(dev->devfn)) % 4;
503 dev = dev->bus->self;
504 }
505 *bridge = dev;
506 return pin;
507}
508
509/**
510 * pci_release_region - Release a PCI bar
511 * @pdev: PCI device whose resources were previously reserved by pci_request_region
512 * @bar: BAR to release
513 *
514 * Releases the PCI I/O and memory resources previously reserved by a
515 * successful call to pci_request_region. Call this function only
516 * after all use of the PCI regions has ceased.
517 */
518void pci_release_region(struct pci_dev *pdev, int bar)
519{
520 if (pci_resource_len(pdev, bar) == 0)
521 return;
522 if (pci_resource_flags(pdev, bar) & IORESOURCE_IO)
523 release_region(pci_resource_start(pdev, bar),
524 pci_resource_len(pdev, bar));
525 else if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM)
526 release_mem_region(pci_resource_start(pdev, bar),
527 pci_resource_len(pdev, bar));
528}
529
530/**
531 * pci_request_region - Reserved PCI I/O and memory resource
532 * @pdev: PCI device whose resources are to be reserved
533 * @bar: BAR to be reserved
534 * @res_name: Name to be associated with resource.
535 *
536 * Mark the PCI region associated with PCI device @pdev BR @bar as
537 * being reserved by owner @res_name. Do not access any
538 * address inside the PCI regions unless this call returns
539 * successfully.
540 *
541 * Returns 0 on success, or %EBUSY on error. A warning
542 * message is also printed on failure.
543 */
544int pci_request_region(struct pci_dev *pdev, int bar, char *res_name)
545{
546 if (pci_resource_len(pdev, bar) == 0)
547 return 0;
548
549 if (pci_resource_flags(pdev, bar) & IORESOURCE_IO) {
550 if (!request_region(pci_resource_start(pdev, bar),
551 pci_resource_len(pdev, bar), res_name))
552 goto err_out;
553 }
554 else if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
555 if (!request_mem_region(pci_resource_start(pdev, bar),
556 pci_resource_len(pdev, bar), res_name))
557 goto err_out;
558 }
559
560 return 0;
561
562err_out:
563 printk (KERN_WARNING "PCI: Unable to reserve %s region #%d:%lx@%lx for device %s\n",
564 pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem",
565 bar + 1, /* PCI BAR # */
566 pci_resource_len(pdev, bar), pci_resource_start(pdev, bar),
567 pci_name(pdev));
568 return -EBUSY;
569}
570
571
572/**
573 * pci_release_regions - Release reserved PCI I/O and memory resources
574 * @pdev: PCI device whose resources were previously reserved by pci_request_regions
575 *
576 * Releases all PCI I/O and memory resources previously reserved by a
577 * successful call to pci_request_regions. Call this function only
578 * after all use of the PCI regions has ceased.
579 */
580
581void pci_release_regions(struct pci_dev *pdev)
582{
583 int i;
584
585 for (i = 0; i < 6; i++)
586 pci_release_region(pdev, i);
587}
588
589/**
590 * pci_request_regions - Reserved PCI I/O and memory resources
591 * @pdev: PCI device whose resources are to be reserved
592 * @res_name: Name to be associated with resource.
593 *
594 * Mark all PCI regions associated with PCI device @pdev as
595 * being reserved by owner @res_name. Do not access any
596 * address inside the PCI regions unless this call returns
597 * successfully.
598 *
599 * Returns 0 on success, or %EBUSY on error. A warning
600 * message is also printed on failure.
601 */
602int pci_request_regions(struct pci_dev *pdev, char *res_name)
603{
604 int i;
605
606 for (i = 0; i < 6; i++)
607 if(pci_request_region(pdev, i, res_name))
608 goto err_out;
609 return 0;
610
611err_out:
612 while(--i >= 0)
613 pci_release_region(pdev, i);
614
615 return -EBUSY;
616}
617
618/**
619 * pci_set_master - enables bus-mastering for device dev
620 * @dev: the PCI device to enable
621 *
622 * Enables bus-mastering on the device and calls pcibios_set_master()
623 * to do the needed arch specific settings.
624 */
625void
626pci_set_master(struct pci_dev *dev)
627{
628 u16 cmd;
629
630 pci_read_config_word(dev, PCI_COMMAND, &cmd);
631 if (! (cmd & PCI_COMMAND_MASTER)) {
632 pr_debug("PCI: Enabling bus mastering for device %s\n", pci_name(dev));
633 cmd |= PCI_COMMAND_MASTER;
634 pci_write_config_word(dev, PCI_COMMAND, cmd);
635 }
636 dev->is_busmaster = 1;
637 pcibios_set_master(dev);
638}
639
640#ifndef HAVE_ARCH_PCI_MWI
641/* This can be overridden by arch code. */
642u8 pci_cache_line_size = L1_CACHE_BYTES >> 2;
643
644/**
645 * pci_generic_prep_mwi - helper function for pci_set_mwi
646 * @dev: the PCI device for which MWI is enabled
647 *
648 * Helper function for generic implementation of pcibios_prep_mwi
649 * function. Originally copied from drivers/net/acenic.c.
650 * Copyright 1998-2001 by Jes Sorensen, <jes@trained-monkey.org>.
651 *
652 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
653 */
654static int
655pci_generic_prep_mwi(struct pci_dev *dev)
656{
657 u8 cacheline_size;
658
659 if (!pci_cache_line_size)
660 return -EINVAL; /* The system doesn't support MWI. */
661
662 /* Validate current setting: the PCI_CACHE_LINE_SIZE must be
663 equal to or multiple of the right value. */
664 pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &cacheline_size);
665 if (cacheline_size >= pci_cache_line_size &&
666 (cacheline_size % pci_cache_line_size) == 0)
667 return 0;
668
669 /* Write the correct value. */
670 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, pci_cache_line_size);
671 /* Read it back. */
672 pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &cacheline_size);
673 if (cacheline_size == pci_cache_line_size)
674 return 0;
675
676 printk(KERN_DEBUG "PCI: cache line size of %d is not supported "
677 "by device %s\n", pci_cache_line_size << 2, pci_name(dev));
678
679 return -EINVAL;
680}
681#endif /* !HAVE_ARCH_PCI_MWI */
682
683/**
684 * pci_set_mwi - enables memory-write-invalidate PCI transaction
685 * @dev: the PCI device for which MWI is enabled
686 *
687 * Enables the Memory-Write-Invalidate transaction in %PCI_COMMAND,
688 * and then calls @pcibios_set_mwi to do the needed arch specific
689 * operations or a generic mwi-prep function.
690 *
691 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
692 */
693int
694pci_set_mwi(struct pci_dev *dev)
695{
696 int rc;
697 u16 cmd;
698
699#ifdef HAVE_ARCH_PCI_MWI
700 rc = pcibios_prep_mwi(dev);
701#else
702 rc = pci_generic_prep_mwi(dev);
703#endif
704
705 if (rc)
706 return rc;
707
708 pci_read_config_word(dev, PCI_COMMAND, &cmd);
709 if (! (cmd & PCI_COMMAND_INVALIDATE)) {
710 pr_debug("PCI: Enabling Mem-Wr-Inval for device %s\n", pci_name(dev));
711 cmd |= PCI_COMMAND_INVALIDATE;
712 pci_write_config_word(dev, PCI_COMMAND, cmd);
713 }
714
715 return 0;
716}
717
718/**
719 * pci_clear_mwi - disables Memory-Write-Invalidate for device dev
720 * @dev: the PCI device to disable
721 *
722 * Disables PCI Memory-Write-Invalidate transaction on the device
723 */
724void
725pci_clear_mwi(struct pci_dev *dev)
726{
727 u16 cmd;
728
729 pci_read_config_word(dev, PCI_COMMAND, &cmd);
730 if (cmd & PCI_COMMAND_INVALIDATE) {
731 cmd &= ~PCI_COMMAND_INVALIDATE;
732 pci_write_config_word(dev, PCI_COMMAND, cmd);
733 }
734}
735
736#ifndef HAVE_ARCH_PCI_SET_DMA_MASK
737/*
738 * These can be overridden by arch-specific implementations
739 */
740int
741pci_set_dma_mask(struct pci_dev *dev, u64 mask)
742{
743 if (!pci_dma_supported(dev, mask))
744 return -EIO;
745
746 dev->dma_mask = mask;
747
748 return 0;
749}
750
751int
752pci_dac_set_dma_mask(struct pci_dev *dev, u64 mask)
753{
754 if (!pci_dac_dma_supported(dev, mask))
755 return -EIO;
756
757 dev->dma_mask = mask;
758
759 return 0;
760}
761
762int
763pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
764{
765 if (!pci_dma_supported(dev, mask))
766 return -EIO;
767
768 dev->dev.coherent_dma_mask = mask;
769
770 return 0;
771}
772#endif
773
774static int __devinit pci_init(void)
775{
776 struct pci_dev *dev = NULL;
777
778 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
779 pci_fixup_device(pci_fixup_final, dev);
780 }
781 return 0;
782}
783
784static int __devinit pci_setup(char *str)
785{
786 while (str) {
787 char *k = strchr(str, ',');
788 if (k)
789 *k++ = 0;
790 if (*str && (str = pcibios_setup(str)) && *str) {
791 /* PCI layer options should be handled here */
792 printk(KERN_ERR "PCI: Unknown option `%s'\n", str);
793 }
794 str = k;
795 }
796 return 1;
797}
798
799device_initcall(pci_init);
800
801__setup("pci=", pci_setup);
802
803#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
804/* FIXME: Some boxes have multiple ISA bridges! */
805struct pci_dev *isa_bridge;
806EXPORT_SYMBOL(isa_bridge);
807#endif
808
809EXPORT_SYMBOL(pci_enable_device_bars);
810EXPORT_SYMBOL(pci_enable_device);
811EXPORT_SYMBOL(pci_disable_device);
812EXPORT_SYMBOL(pci_max_busnr);
813EXPORT_SYMBOL(pci_bus_max_busnr);
814EXPORT_SYMBOL(pci_find_capability);
815EXPORT_SYMBOL(pci_bus_find_capability);
816EXPORT_SYMBOL(pci_release_regions);
817EXPORT_SYMBOL(pci_request_regions);
818EXPORT_SYMBOL(pci_release_region);
819EXPORT_SYMBOL(pci_request_region);
820EXPORT_SYMBOL(pci_set_master);
821EXPORT_SYMBOL(pci_set_mwi);
822EXPORT_SYMBOL(pci_clear_mwi);
823EXPORT_SYMBOL(pci_set_dma_mask);
824EXPORT_SYMBOL(pci_dac_set_dma_mask);
825EXPORT_SYMBOL(pci_set_consistent_dma_mask);
826EXPORT_SYMBOL(pci_assign_resource);
827EXPORT_SYMBOL(pci_find_parent_resource);
828
829EXPORT_SYMBOL(pci_set_power_state);
830EXPORT_SYMBOL(pci_save_state);
831EXPORT_SYMBOL(pci_restore_state);
832EXPORT_SYMBOL(pci_enable_wake);
833
834/* Quirk info */
835
836EXPORT_SYMBOL(isa_dma_bridge_buggy);
837EXPORT_SYMBOL(pci_pci_problems);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
new file mode 100644
index 000000000000..79cdc16c52c8
--- /dev/null
+++ b/drivers/pci/pci.h
@@ -0,0 +1,96 @@
1/* Functions internal to the PCI core code */
2
3extern int pci_hotplug (struct device *dev, char **envp, int num_envp,
4 char *buffer, int buffer_size);
5extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
6extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
7extern void pci_cleanup_rom(struct pci_dev *dev);
8extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
9 unsigned long size, unsigned long align,
10 unsigned long min, unsigned int type_mask,
11 void (*alignf)(void *, struct resource *,
12 unsigned long, unsigned long),
13 void *alignf_data);
14/* PCI /proc functions */
15#ifdef CONFIG_PROC_FS
16extern int pci_proc_attach_device(struct pci_dev *dev);
17extern int pci_proc_detach_device(struct pci_dev *dev);
18extern int pci_proc_attach_bus(struct pci_bus *bus);
19extern int pci_proc_detach_bus(struct pci_bus *bus);
20#else
21static inline int pci_proc_attach_device(struct pci_dev *dev) { return 0; }
22static inline int pci_proc_detach_device(struct pci_dev *dev) { return 0; }
23static inline int pci_proc_attach_bus(struct pci_bus *bus) { return 0; }
24static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; }
25#endif
26
27/* Functions for PCI Hotplug drivers to use */
28extern struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr);
29extern unsigned int pci_do_scan_bus(struct pci_bus *bus);
30extern int pci_remove_device_safe(struct pci_dev *dev);
31extern unsigned char pci_max_busnr(void);
32extern unsigned char pci_bus_max_busnr(struct pci_bus *bus);
33extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap);
34
35struct pci_dev_wrapped {
36 struct pci_dev *dev;
37 void *data;
38};
39
40struct pci_bus_wrapped {
41 struct pci_bus *bus;
42 void *data;
43};
44
45struct pci_visit {
46 int (* pre_visit_pci_bus) (struct pci_bus_wrapped *,
47 struct pci_dev_wrapped *);
48 int (* post_visit_pci_bus) (struct pci_bus_wrapped *,
49 struct pci_dev_wrapped *);
50
51 int (* pre_visit_pci_dev) (struct pci_dev_wrapped *,
52 struct pci_bus_wrapped *);
53 int (* visit_pci_dev) (struct pci_dev_wrapped *,
54 struct pci_bus_wrapped *);
55 int (* post_visit_pci_dev) (struct pci_dev_wrapped *,
56 struct pci_bus_wrapped *);
57};
58
59extern int pci_visit_dev(struct pci_visit *fn,
60 struct pci_dev_wrapped *wrapped_dev,
61 struct pci_bus_wrapped *wrapped_parent);
62extern void pci_remove_legacy_files(struct pci_bus *bus);
63
64/* Lock for read/write access to pci device and bus lists */
65extern spinlock_t pci_bus_lock;
66
67#ifdef CONFIG_X86_IO_APIC
68extern int pci_msi_quirk;
69#else
70#define pci_msi_quirk 0
71#endif
72
73extern int pcie_mch_quirk;
74extern struct device_attribute pci_dev_attrs[];
75extern struct class_device_attribute class_device_attr_cpuaffinity;
76
77/**
78 * pci_match_one_device - Tell if a PCI device structure has a matching
79 * PCI device id structure
80 * @id: single PCI device id structure to match
81 * @dev: the PCI device structure to match against
82 *
83 * Returns the matching pci_device_id structure or %NULL if there is no match.
84 */
85static inline const struct pci_device_id *
86pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)
87{
88 if ((id->vendor == PCI_ANY_ID || id->vendor == dev->vendor) &&
89 (id->device == PCI_ANY_ID || id->device == dev->device) &&
90 (id->subvendor == PCI_ANY_ID || id->subvendor == dev->subsystem_vendor) &&
91 (id->subdevice == PCI_ANY_ID || id->subdevice == dev->subsystem_device) &&
92 !((id->class ^ dev->class) & id->class_mask))
93 return id;
94 return NULL;
95}
96
diff --git a/drivers/pci/pci.ids b/drivers/pci/pci.ids
new file mode 100644
index 000000000000..93481b41b613
--- /dev/null
+++ b/drivers/pci/pci.ids
@@ -0,0 +1,10179 @@
1#
2# List of PCI ID's
3#
4# Maintained by Martin Mares <mj@ucw.cz> and other volunteers from the
5# Linux PCI ID's Project at http://pciids.sf.net/. New data are always
6# welcome (if they are accurate), we're eagerly expecting new entries,
7# so if you have anything to contribute, please visit the home page or
8# send a diff -u against the most recent pci.ids to pci-ids@ucw.cz.
9#
10# Daily snapshot on Tue 2005-03-08 10:11:48
11#
12
13# Vendors, devices and subsystems. Please keep sorted.
14
15# Syntax:
16# vendor vendor_name
17# device device_name <-- single tab
18# subvendor subdevice subsystem_name <-- two tabs
19
200000 Gammagraphx, Inc.
21001a Ascend Communications, Inc.
220033 Paradyne corp.
23003d Lockheed Martin-Marietta Corp
24# Real TJN ID is e159, but they got it wrong several times --mj
250059 Tiger Jet Network Inc. (Wrong ID)
260070 Hauppauge computer works Inc.
27 4000 WinTV PVR-350
28 4001 WinTV PVR-250 (v1)
29 4009 WinTV PVR-250
30 4801 WinTV PVR-250 MCE
310071 Nebula Electronics Ltd.
320095 Silicon Image, Inc. (Wrong ID)
33 0680 Ultra ATA/133 IDE RAID CONTROLLER CARD
340100 Ncipher Corp Ltd
35# 018a is not LevelOne but there is a board misprogrammed
36018a LevelOne
37 0106 FPC-0106TX misprogrammed [RTL81xx]
38# 021b is not Compaq but there is a board misprogrammed
39021b Compaq Computer Corporation
40 8139 HNE-300 (RealTek RTL8139c) [iPaq Networking]
41# http://www.davicom.com.tw/
420291 Davicom Semiconductor, Inc.
43 8212 DM9102A(DM9102AE, SM9102AF) Ethernet 100/10 MBit(Rev 40)
44# SpeedStream is Efficient Networks, Inc, a Siemens Company
4502ac SpeedStream
46 1012 1012 PCMCIA 10/100 Ethernet Card [RTL81xx]
470357 TTTech AG
48 000a TTP-Monitoring Card V2.0
490432 SCM Microsystems, Inc.
50 0001 Pluto2 DVB-T Receiver for PCMCIA [EasyWatch MobilSet]
5105e3 CyberDoor
52 0701 CBD516
530675 Dynalink
54 1700 IS64PH ISDN Adapter
55 1702 IS64PH ISDN Adapter
56# Wrong ID used in subsystem ID of VIA USB controllers.
570925 VIA Technologies, Inc. (Wrong ID)
5809c1 Arris
59 0704 CM 200E Cable Modem
600a89 BREA Technologies Inc
610b49 ASCII Corporation
62# see http://homepage1.nifty.com/mcn/lab/machines/trance_vibrator/usbview.vib.txt
63 064f Trance Vibrator
640e11 Compaq Computer Corporation
65 0001 PCI to EISA Bridge
66 0002 PCI to ISA Bridge
67 0046 Smart Array 64xx
68 0e11 409a Smart Array 641
69 0e11 409b Smart Array 642
70 0e11 409c Smart Array 6400
71 0e11 409d Smart Array 6400 EM
72 0049 NC7132 Gigabit Upgrade Module
73 004a NC6136 Gigabit Server Adapter
74 007c NC7770 1000BaseTX
75 007d NC6770 1000BaseTX
76 0085 NC7780 1000BaseTX
77 00bb NC7760
78 00ca NC7771
79 00cb NC7781
80 00cf NC7772
81 00d0 NC7782
82 00d1 NC7783
83 00e3 NC7761
84 0508 Netelligent 4/16 Token Ring
85 1000 Triflex/Pentium Bridge, Model 1000
86 2000 Triflex/Pentium Bridge, Model 2000
87 3032 QVision 1280/p
88 3033 QVision 1280/p
89 3034 QVision 1280/p
90 4000 4000 [Triflex]
91 4030 SMART-2/P
92 4031 SMART-2SL
93 4032 Smart Array 3200
94 4033 Smart Array 3100ES
95 4034 Smart Array 221
96 4040 Integrated Array
97 4048 Compaq Raid LC2
98 4050 Smart Array 4200
99 4051 Smart Array 4250ES
100 4058 Smart Array 431
101 4070 Smart Array 5300
102 4080 Smart Array 5i
103 4082 Smart Array 532
104 4083 Smart Array 5312
105 4091 Smart Array 6i
106 409a Smart Array 641
107 409b Smart Array 642
108 409c Smart Array 6400
109 409d Smart Array 6400 EM
110 6010 HotPlug PCI Bridge 6010
111 7020 USB Controller
112 a0ec Fibre Channel Host Controller
113 a0f0 Advanced System Management Controller
114 a0f3 Triflex PCI to ISA Bridge
115 a0f7 PCI Hotplug Controller
116 8086 002a PCI Hotplug Controller A
117 8086 002b PCI Hotplug Controller B
118 a0f8 ZFMicro Chipset USB
119 a0fc FibreChannel HBA Tachyon
120 ae10 Smart-2/P RAID Controller
121 0e11 4030 Smart-2/P Array Controller
122 0e11 4031 Smart-2SL Array Controller
123 0e11 4032 Smart Array Controller
124 0e11 4033 Smart 3100ES Array Controller
125 ae29 MIS-L
126 ae2a MPC
127 ae2b MIS-E
128 ae31 System Management Controller
129 ae32 Netelligent 10/100 TX PCI UTP
130 ae33 Triflex Dual EIDE Controller
131 ae34 Netelligent 10 T PCI UTP
132 ae35 Integrated NetFlex-3/P
133 ae40 Netelligent Dual 10/100 TX PCI UTP
134 ae43 Netelligent Integrated 10/100 TX UTP
135 ae69 CETUS-L
136 ae6c Northstar
137 ae6d NorthStar CPU to PCI Bridge
138 b011 Netelligent 10/100 TX Embedded UTP
139 b012 Netelligent 10 T/2 PCI UTP/Coax
140 b01e NC3120 Fast Ethernet NIC
141 b01f NC3122 Fast Ethernet NIC
142 b02f NC1120 Ethernet NIC
143 b030 Netelligent 10/100 TX UTP
144 b04a 10/100 TX PCI Intel WOL UTP Controller
145 b060 Smart Array 5300 Controller
146 b0c6 NC3161 Fast Ethernet NIC
147 b0c7 NC3160 Fast Ethernet NIC
148 b0d7 NC3121 Fast Ethernet NIC
149 b0dd NC3131 Fast Ethernet NIC
150 b0de NC3132 Fast Ethernet Module
151 b0df NC6132 Gigabit Module
152 b0e0 NC6133 Gigabit Module
153 b0e1 NC3133 Fast Ethernet Module
154 b123 NC6134 Gigabit NIC
155 b134 NC3163 Fast Ethernet NIC
156 b13c NC3162 Fast Ethernet NIC
157 b144 NC3123 Fast Ethernet NIC
158 b163 NC3134 Fast Ethernet NIC
159 b164 NC3165 Fast Ethernet Upgrade Module
160 b178 Smart Array 5i/532
161 0e11 4080 Smart Array 5i
162 0e11 4082 Smart Array 532
163 0e11 4083 Smart Array 5312
164 b1a4 NC7131 Gigabit Server Adapter
165# HP Memory Hot-Plug Controller
166 b200 Memory Hot-Plug Controller
167 b203 Integrated Lights Out Controller
168 b204 Integrated Lights Out Processor
169 f130 NetFlex-3/P ThunderLAN 1.0
170 f150 NetFlex-3/P ThunderLAN 2.3
1710e55 HaSoTec GmbH
172# Formerly NCR
1731000 LSI Logic / Symbios Logic
174 0001 53c810
175 1000 1000 LSI53C810AE PCI to SCSI I/O Processor
176 0002 53c820
177 0003 53c825
178 1000 1000 LSI53C825AE PCI to SCSI I/O Processor (Ultra Wide)
179 0004 53c815
180 0005 53c810AP
181 0006 53c860
182 1000 1000 LSI53C860E PCI to Ultra SCSI I/O Processor
183 000a 53c1510
184 1000 1000 LSI53C1510 PCI to Dual Channel Wide Ultra2 SCSI Controller (Nonintelligent mode)
185 000b 53C896/897
186 0e11 6004 EOB003 Series SCSI host adapter
187 1000 1000 LSI53C896/7 PCI to Dual Channel Ultra2 SCSI Multifunction Controller
188 1000 1010 LSI22910 PCI to Dual Channel Ultra2 SCSI host adapter
189 1000 1020 LSI21002 PCI to Dual Channel Ultra2 SCSI host adapter
190# multifunction PCI card: Dual U2W SCSI, dual 10/100TX, graphics
191 13e9 1000 6221L-4U
192 000c 53c895
193 1000 1010 LSI8951U PCI to Ultra2 SCSI host adapter
194 1000 1020 LSI8952U PCI to Ultra2 SCSI host adapter
195 1de1 3906 DC-390U2B SCSI adapter
196 1de1 3907 DC-390U2W
197 000d 53c885
198 000f 53c875
199 0e11 7004 Embedded Ultra Wide SCSI Controller
200 1000 1000 LSI53C876/E PCI to Dual Channel SCSI Controller
201 1000 1010 LSI22801 PCI to Dual Channel Ultra SCSI host adapter
202 1000 1020 LSI22802 PCI to Dual Channel Ultra SCSI host adapter
203 1092 8760 FirePort 40 Dual SCSI Controller
204 1de1 3904 DC390F/U Ultra Wide SCSI Adapter
205 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
206 4c53 1050 CT7 mainboard
207 0010 53C1510
208 0e11 4040 Integrated Array Controller
209 0e11 4048 RAID LC2 Controller
210 1000 1000 53C1510 PCI to Dual Channel Wide Ultra2 SCSI Controller (Intelligent mode)
211 0012 53c895a
212 1000 1000 LSI53C895A PCI to Ultra2 SCSI Controller
213 0013 53c875a
214 1000 1000 LSI53C875A PCI to Ultra SCSI Controller
215 0020 53c1010 Ultra3 SCSI Adapter
216 1000 1000 LSI53C1010-33 PCI to Dual Channel Ultra160 SCSI Controller
217 1de1 1020 DC-390U3W
218 0021 53c1010 66MHz Ultra3 SCSI Adapter
219 1000 1000 LSI53C1000/1000R/1010R/1010-66 PCI to Ultra160 SCSI Controller
220 1000 1010 Asus TR-DLS onboard 53C1010-66
221 124b 1070 PMC-USCSI3
222 4c53 1080 CT8 mainboard
223 4c53 1300 P017 mezzanine (32-bit PMC)
224 4c53 1310 P017 mezzanine (64-bit PMC)
225 0030 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI
226 1028 0123 PowerEdge 2600
227 1028 014a PowerEdge 1750
228 1028 016c PowerEdge 1850 MPT Fusion SCSI/RAID (Perc 4)
229 1028 0183 PowerEdge 1800
230 1028 1010 LSI U320 SCSI Controller
231 0031 53c1030ZC PCI-X Fusion-MPT Dual Ultra320 SCSI
232 0032 53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
233 1000 1000 LSI53C1020/1030 PCI-X to Ultra320 SCSI Controller
234 0033 1030ZC_53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
235 0040 53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
236 1000 0033 MegaRAID SCSI 320-2XR
237 1000 0066 MegaRAID SCSI 320-2XRWS
238 0041 53C1035ZC PCI-X Fusion-MPT Dual Ultra320 SCSI
239 008f 53c875J
240 1092 8000 FirePort 40 SCSI Controller
241 1092 8760 FirePort 40 Dual SCSI Host Adapter
242 0407 MegaRAID
243 1000 0530 MegaRAID 530 SCSI 320-0X RAID Controller
244 1000 0531 MegaRAID 531 SCSI 320-4X RAID Controller
245 1000 0532 MegaRAID 532 SCSI 320-2X RAID Controller
246 1028 0531 PowerEdge Expandable RAID Controller 4/QC
247 1028 0533 PowerEdge Expandable RAID Controller 4/QC
248 8086 0530 MegaRAID Intel RAID Controller SRCZCRX
249 8086 0532 MegaRAID Intel RAID Controller SRCU42X
250 0408 MegaRAID
251 1000 0001 MegaRAID SCSI 320-1E RAID Controller
252 1000 0002 MegaRAID SCSI 320-2E RAID Controller
253 1025 004d MegaRAID ACER ROMB-2E RAID Controller
254 1028 0001 PowerEdge RAID Controller PERC4e/SC
255 1028 0002 PowerEdge RAID Controller PERC4e/DC
256 1734 1065 FSC MegaRAID PCI Express ROMB
257 8086 0002 MegaRAID Intel RAID Controller SRCU42E
258 0409 MegaRAID
259 1000 3004 MegaRAID SATA 300-4X RAID Controller
260 1000 3008 MegaRAID SATA 300-8X RAID Controller
261 8086 3008 MegaRAID RAID Controller SRCS28X
262 8086 3431 MegaRAID RAID Controller Alief SROMBU42E
263 8086 3499 MegaRAID RAID Controller Harwich SROMBU42E
264 0621 FC909 Fibre Channel Adapter
265 0622 FC929 Fibre Channel Adapter
266 1000 1020 44929 O Dual Fibre Channel card
267 0623 FC929 LAN
268 0624 FC919 Fibre Channel Adapter
269 0625 FC919 LAN
270 0626 FC929X Fibre Channel Adapter
271 1000 1010 7202-XP-LC Dual Fibre Channel card
272 0627 FC929X LAN
273 0628 FC919X Fibre Channel Adapter
274 0629 FC919X LAN
275 0701 83C885 NT50 DigitalScape Fast Ethernet
276 0702 Yellowfin G-NIC gigabit ethernet
277 1318 0000 PEI100X
278 0804 SA2010
279 0805 SA2010ZC
280 0806 SA2020
281 0807 SA2020ZC
282 0901 61C102
283 1000 63C815
284 1960 MegaRAID
285 1000 0518 MegaRAID 518 SCSI 320-2 Controller
286 1000 0520 MegaRAID 520 SCSI 320-1 Controller
287 1000 0522 MegaRAID 522 i4 133 RAID Controller
288 1000 0523 MegaRAID SATA 150-6 RAID Controller
289 1000 4523 MegaRAID SATA 150-4 RAID Controller
290 1000 a520 MegaRAID ZCR SCSI 320-0 Controller
291 1028 0518 MegaRAID 518 DELL PERC 4/DC RAID Controller
292 1028 0520 MegaRAID 520 DELL PERC 4/SC RAID Controller
293 1028 0531 PowerEdge Expandable RAID Controller 4/QC
294 1028 0533 PowerEdge Expandable RAID Controller 4/QC
295 8086 0520 MegaRAIDRAID Controller SRCU41L
296 8086 0523 MegaRAID RAID Controller SRCS16
2971001 Kolter Electronic
298 0010 PCI 1616 Measurement card with 32 digital I/O lines
299 0011 OPTO-PCI Opto-Isolated digital I/O board
300 0012 PCI-AD/DA Analogue I/O board
301 0013 PCI-OPTO-RELAIS Digital I/O board with relay outputs
302 0014 PCI-Counter/Timer Counter Timer board
303 0015 PCI-DAC416 Analogue output board
304 0016 PCI-MFB Analogue I/O board
305 0017 PROTO-3 PCI Prototyping board
306 9100 INI-9100/9100W SCSI Host
3071002 ATI Technologies Inc
308 3150 M24 1P [Radeon Mobility X600]
309 3154 M24 1T [FireGL M24 GL]
310 3e50 RV380 0x3e50 [Radeon X600]
311 3e54 RV380 0x3e54 [FireGL V3200]
312 3e70 RV380 [Radeon X600] Secondary
313 4136 Radeon IGP 320 M
314 4137 Radeon IGP330/340/350
315 4144 R300 AD [Radeon 9500 Pro]
316# New PCI ID provided by ATI developer relations (correction to above)
317 4145 R300 AE [Radeon 9700 Pro]
318# New PCI ID provided by ATI developer relations (oops, correction to above)
319 4146 R300 AF [Radeon 9700 Pro]
320 4147 R300 AG [FireGL Z1/X1]
321 4148 R350 AH [Radeon 9800]
322 4149 R350 AI [Radeon 9800]
323 414a R350 AJ [Radeon 9800]
324 414b R350 AK [Fire GL X2]
325# New PCI ID provided by ATI developer relations
326 4150 RV350 AP [Radeon 9600]
327 1002 0002 R9600 Pro primary (Asus OEM for HP)
328 1002 0003 R9600 Pro secondary (Asus OEM for HP)
329 1458 4024 Giga-Byte GV-R96128D Primary
330 148c 2064 PowerColor R96A-C3N
331 148c 2066 PowerColor R96A-C3N
332 174b 7c19 Sapphire Atlantis Radeon 9600 Pro
333 174b 7c29 GC-R9600PRO Primary [Sapphire]
334 17ee 2002 Radeon 9600 256Mb Primary
335 18bc 0101 GC-R9600PRO Primary
336# New PCI ID provided by ATI developer relations
337 4151 RV350 AQ [Radeon 9600]
338 1043 c004 A9600SE
339# New PCI ID provided by ATI developer relations
340 4152 RV350 AR [Radeon 9600]
341 1002 0002 Radeon 9600XT
342 1043 c002 Radeon 9600 XT TVD
343 174b 7c29 Sapphire Radeon 9600XT
344 1787 4002 Radeon 9600 XT
345 4153 RV350 AS [Radeon 9600 AS]
346 4154 RV350 AT [Fire GL T2]
347 4155 RV350 AU [Fire GL T2]
348 4156 RV350 AV [Fire GL T2]
349 4157 RV350 AW [Fire GL T2]
350 4158 68800AX [Mach32]
351# The PCI ID is unrelated to any DVI output.
352 4164 R300 AD [Radeon 9500 Pro] (Secondary)
353# New PCI ID info provided by ATI developer relations
354 4165 R300 AE [Radeon 9700 Pro] (Secondary)
355# New PCI ID info provided by ATI developer relations
356 4166 R300 AF [Radeon 9700 Pro] (Secondary)
357# New PCI ID provided by ATI developer relations
358 4168 Radeon R350 [Radeon 9800] (Secondary)
359# New PCI ID provided by ATI developer relations (correction to above)
360 4170 RV350 AP [Radeon 9600] (Secondary)
361 1458 4025 Giga-Byte GV-R96128D Secondary
362 148c 2067 PowerColor R96A-C3N (Secondary)
363 174b 7c28 GC-R9600PRO Secondary [Sapphire]
364 17ee 2003 Radeon 9600 256Mb Secondary
365 18bc 0100 GC-R9600PRO Secondary
366# New PCI ID provided by ATI developer relations (correction to above)
367 4171 RV350 AQ [Radeon 9600] (Secondary)
368 1043 c005 A9600SE (Secondary)
369# New PCI ID provided by ATI developer relations (correction to above)
370 4172 RV350 AR [Radeon 9600] (Secondary)
371 1002 0003 Radeon 9600XT (Secondary)
372 1043 c003 A9600XT (Secondary)
373 174b 7c28 Sapphire Radeon 9600XT (Secondary)
374 1787 4003 Radeon 9600 XT (Secondary)
375 4173 RV350 ?? [Radeon 9550] (Secondary)
376 4237 Radeon 7000 IGP
377 4242 R200 BB [Radeon All in Wonder 8500DV]
378 1002 02aa Radeon 8500 AIW DV Edition
379 4243 R200 BC [Radeon All in Wonder 8500]
380 4336 Radeon Mobility U1
381 103c 0024 Pavilion ze4400 builtin Video
382 4337 Radeon IGP 330M/340M/350M
383 1014 053a ThinkPad R40e (2684-HVG) builtin VGA controller
384 103c 0850 Radeon IGP 345M
385 4341 IXP150 AC'97 Audio Controller
386 4345 EHCI USB Controller
387 4347 OHCI USB Controller #1
388 4348 OHCI USB Controller #2
389 4349 ATI Dual Channel Bus Master PCI IDE Controller
390 434d IXP AC'97 Modem
391 4353 ATI SMBus
392 4354 215CT [Mach64 CT]
393 4358 210888CX [Mach64 CX]
394 4363 ATI SMBus
395 436e ATI 436E Serial ATA Controller
396 4372 ATI SMBus
397 4376 Standard Dual Channel PCI IDE Controller ATI
398 4379 ATI 4379 Serial ATA Controller
399 437a ATI 437A Serial ATA Controller
400 4437 Radeon Mobility 7000 IGP
401 4554 210888ET [Mach64 ET]
402 4654 Mach64 VT
403 4742 3D Rage Pro AGP 1X/2X
404 1002 0040 Rage Pro Turbo AGP 2X
405 1002 0044 Rage Pro Turbo AGP 2X
406 1002 0061 Rage Pro AIW AGP 2X
407 1002 0062 Rage Pro AIW AGP 2X
408 1002 0063 Rage Pro AIW AGP 2X
409 1002 0080 Rage Pro Turbo AGP 2X
410 1002 0084 Rage Pro Turbo AGP 2X
411 1002 4742 Rage Pro Turbo AGP 2X
412 1002 8001 Rage Pro Turbo AGP 2X
413 1028 0082 Rage Pro Turbo AGP 2X
414 1028 4082 Optiplex GX1 Onboard Display Adapter
415 1028 8082 Rage Pro Turbo AGP 2X
416 1028 c082 Rage Pro Turbo AGP 2X
417 8086 4152 Xpert 98D AGP 2X
418 8086 464a Rage Pro Turbo AGP 2X
419 4744 3D Rage Pro AGP 1X
420 1002 4744 Rage Pro Turbo AGP
421 4747 3D Rage Pro
422 4749 3D Rage Pro
423 1002 0061 Rage Pro AIW
424 1002 0062 Rage Pro AIW
425 474c Rage XC
426 474d Rage XL AGP 2X
427 1002 0004 Xpert 98 RXL AGP 2X
428 1002 0008 Xpert 98 RXL AGP 2X
429 1002 0080 Rage XL AGP 2X
430 1002 0084 Xpert 98 AGP 2X
431 1002 474d Rage XL AGP
432 1033 806a Rage XL AGP
433 474e Rage XC AGP
434 1002 474e Rage XC AGP
435 474f Rage XL
436 1002 0008 Rage XL
437 1002 474f Rage XL
438 4750 3D Rage Pro 215GP
439 1002 0040 Rage Pro Turbo
440 1002 0044 Rage Pro Turbo
441 1002 0080 Rage Pro Turbo
442 1002 0084 Rage Pro Turbo
443 1002 4750 Rage Pro Turbo
444 4751 3D Rage Pro 215GQ
445 4752 Rage XL
446 1002 0008 Rage XL
447 1002 4752 Rage XL
448 1002 8008 Rage XL
449 1028 00ce PowerEdge 1400
450 1028 00d1 PowerEdge 2550
451 1028 00d9 PowerEdge 2500
452 8086 3411 SDS2 Mainboard
453 8086 3427 S875WP1-E mainboard
454 4753 Rage XC
455 1002 4753 Rage XC
456 4754 3D Rage I/II 215GT [Mach64 GT]
457 4755 3D Rage II+ 215GTB [Mach64 GTB]
458 4756 3D Rage IIC 215IIC [Mach64 GT IIC]
459 1002 4756 Rage IIC
460 4757 3D Rage IIC AGP
461 1002 4757 Rage IIC AGP
462 1028 0089 Rage 3D IIC
463 1028 4082 Rage 3D IIC
464 1028 8082 Rage 3D IIC
465 1028 c082 Rage 3D IIC
466 4758 210888GX [Mach64 GX]
467 4759 3D Rage IIC
468 475a 3D Rage IIC AGP
469 1002 0084 Rage 3D Pro AGP 2x XPERT 98
470 1002 0087 Rage 3D IIC
471 1002 475a Rage IIC AGP
472 4964 Radeon RV250 Id [Radeon 9000]
473 4965 Radeon RV250 Ie [Radeon 9000]
474 4966 Radeon RV250 If [Radeon 9000]
475 10f1 0002 RV250 If [Tachyon G9000 PRO]
476 148c 2039 RV250 If [Radeon 9000 Pro "Evil Commando"]
477 1509 9a00 RV250 If [Radeon 9000 "AT009"]
478# New subdevice - 3D Prophet 9000 PCI by Hercules. AGP version probably would have same ID, so not specified.
479 1681 0040 RV250 If [3D prophet 9000]
480 174b 7176 RV250 If [Sapphire Radeon 9000 Pro]
481 174b 7192 RV250 If [Radeon 9000 "Atlantis"]
482 17af 2005 RV250 If [Excalibur Radeon 9000 Pro]
483 17af 2006 RV250 If [Excalibur Radeon 9000]
484 4967 Radeon RV250 Ig [Radeon 9000]
485 496e Radeon RV250 [Radeon 9000] (Secondary)
486 4a48 R420 JH [Radeon X800]
487 4a49 R420 JI [Radeon X800PRO]
488 4a4a R420 JJ [Radeon X800SE]
489 4a4b R420 JK [Radeon X800]
490 4a4c R420 JL [Radeon X800]
491 4a4d R420 JM [FireGL X3]
492 4a4e M18 JN [Radeon Mobility 9800]
493 4a50 R420 JP [Radeon X800XT]
494 4a70 R420 [X800XT-PE] (Secondary)
495 4c42 3D Rage LT Pro AGP-133
496 0e11 b0e7 Rage LT Pro (Compaq Presario 5240)
497 0e11 b0e8 Rage 3D LT Pro
498 0e11 b10e 3D Rage LT Pro (Compaq Armada 1750)
499 1002 0040 Rage LT Pro AGP 2X
500 1002 0044 Rage LT Pro AGP 2X
501 1002 4c42 Rage LT Pro AGP 2X
502 1002 8001 Rage LT Pro AGP 2X
503 1028 0085 Rage 3D LT Pro
504 4c44 3D Rage LT Pro AGP-66
505 4c45 Rage Mobility M3 AGP
506 4c46 Rage Mobility M3 AGP 2x
507 1028 00b1 Latitude C600
508 4c47 3D Rage LT-G 215LG
509 4c49 3D Rage LT Pro
510 1002 0004 Rage LT Pro
511 1002 0040 Rage LT Pro
512 1002 0044 Rage LT Pro
513 1002 4c49 Rage LT Pro
514 4c4d Rage Mobility P/M AGP 2x
515 0e11 b111 Armada M700
516 0e11 b160 Armada E500
517 1002 0084 Xpert 98 AGP 2X (Mobility)
518 1014 0154 ThinkPad A20m
519 1028 00aa Latitude CPt
520 1028 00bb Latitude CPx
521 4c4e Rage Mobility L AGP 2x
522 4c50 3D Rage LT Pro
523 1002 4c50 Rage LT Pro
524 4c51 3D Rage LT Pro
525 4c52 Rage Mobility P/M
526 1033 8112 Versa Note VXi
527 4c53 Rage Mobility L
528 4c54 264LT [Mach64 LT]
529 4c57 Radeon Mobility M7 LW [Radeon Mobility 7500]
530 1014 0517 ThinkPad T30
531 1028 00e6 Radeon Mobility M7 LW (Dell Inspiron 8100)
532 1028 012a Latitude C640
533 144d c006 Radeon Mobility M7 LW in vpr Matrix 170B4
534 4c58 Radeon RV200 LX [Mobility FireGL 7800 M7]
535 4c59 Radeon Mobility M6 LY
536 1014 0235 ThinkPad A30/A30p (2652/2653)
537 1014 0239 ThinkPad X22/X23/X24
538 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
539 4c5a Radeon Mobility M6 LZ
540 4c64 Radeon R250 Ld [Radeon Mobility 9000 M9]
541 4c65 Radeon R250 Le [Radeon Mobility 9000 M9]
542 4c66 Radeon R250 Lf [FireGL 9000]
543 4c67 Radeon R250 Lg [Radeon Mobility 9000 M9]
544# Secondary chip to the Lf
545 4c6e Radeon R250 Ln [Radeon Mobility 9000 M9] [Secondary]
546 4d46 Rage Mobility M4 AGP
547 4d4c Rage Mobility M4 AGP
548 4e44 Radeon R300 ND [Radeon 9700 Pro]
549 4e45 Radeon R300 NE [Radeon 9500 Pro]
550 1002 0002 Radeon R300 NE [Radeon 9500 Pro]
551 1681 0002 Hercules 3D Prophet 9500 PRO [Radeon 9500 Pro]
552# New PCI ID provided by ATI developer relations (correction to above)
553 4e46 RV350 NF [Radeon 9600]
554 4e47 Radeon R300 NG [FireGL X1]
555# (added pro)
556 4e48 Radeon R350 [Radeon 9800 Pro]
557# New PCI ID provided by ATI developer relations
558 4e49 Radeon R350 [Radeon 9800]
559 4e4a RV350 NJ [Radeon 9800 XT]
560 4e4b R350 NK [Fire GL X2]
561# New PCI ID provided by ATI developer relations
562 4e50 RV350 [Mobility Radeon 9600 M10]
563 1025 005a TravelMate 290
564 103c 088c nc8000 laptop
565 103c 0890 nc6000 laptop
566 1734 1055 Amilo M1420W
567 4e51 M10 NQ [Radeon Mobility 9600]
568 4e52 RV350 [Mobility Radeon 9600 M10]
569 4e53 M10 NS [Radeon Mobility 9600]
570 4e54 M10 NT [FireGL Mobility T2]
571 4e56 M11 NV [FireGL Mobility T2e]
572 4e64 Radeon R300 [Radeon 9700 Pro] (Secondary)
573 4e65 Radeon R300 [Radeon 9500 Pro] (Secondary)
574 1002 0003 Radeon R300 NE [Radeon 9500 Pro]
575 1681 0003 Hercules 3D Prophet 9500 PRO [Radeon 9500 Pro] (Secondary)
576# New PCI ID provided by ATI developer relations (correction to above)
577 4e66 RV350 NF [Radeon 9600] (Secondary)
578 4e67 Radeon R300 [FireGL X1] (Secondary)
579# (added pro)
580 4e68 Radeon R350 [Radeon 9800 Pro] (Secondary)
581# New PCI ID provided by ATI developer relations
582 4e69 Radeon R350 [Radeon 9800] (Secondary)
583 4e6a RV350 NJ [Radeon 9800 XT] (Secondary)
584 1002 4e71 ATI Technologies Inc M10 NQ [Radeon Mobility 9600]
585 5041 Rage 128 PA/PRO
586 5042 Rage 128 PB/PRO AGP 2x
587 5043 Rage 128 PC/PRO AGP 4x
588 5044 Rage 128 PD/PRO TMDS
589 1002 0028 Rage 128 AIW
590 1002 0029 Rage 128 AIW
591 5045 Rage 128 PE/PRO AGP 2x TMDS
592 5046 Rage 128 PF/PRO AGP 4x TMDS
593 1002 0004 Rage Fury Pro
594 1002 0008 Rage Fury Pro/Xpert 2000 Pro
595 1002 0014 Rage Fury Pro
596 1002 0018 Rage Fury Pro/Xpert 2000 Pro
597 1002 0028 Rage 128 Pro AIW AGP
598 1002 002a Rage 128 Pro AIW AGP
599 1002 0048 Rage Fury Pro
600 1002 2000 Rage Fury MAXX AGP 4x (TMDS) (VGA device)
601 1002 2001 Rage Fury MAXX AGP 4x (TMDS) (Extra device?!)
602 5047 Rage 128 PG/PRO
603 5048 Rage 128 PH/PRO AGP 2x
604 5049 Rage 128 PI/PRO AGP 4x
605 504a Rage 128 PJ/PRO TMDS
606 504b Rage 128 PK/PRO AGP 2x TMDS
607 504c Rage 128 PL/PRO AGP 4x TMDS
608 504d Rage 128 PM/PRO
609 504e Rage 128 PN/PRO AGP 2x
610 504f Rage 128 PO/PRO AGP 4x
611 5050 Rage 128 PP/PRO TMDS [Xpert 128]
612 1002 0008 Xpert 128
613 5051 Rage 128 PQ/PRO AGP 2x TMDS
614 5052 Rage 128 PR/PRO AGP 4x TMDS
615 5053 Rage 128 PS/PRO
616 5054 Rage 128 PT/PRO AGP 2x
617 5055 Rage 128 PU/PRO AGP 4x
618 5056 Rage 128 PV/PRO TMDS
619 5057 Rage 128 PW/PRO AGP 2x TMDS
620 5058 Rage 128 PX/PRO AGP 4x TMDS
621 5144 Radeon R100 QD [Radeon 7200]
622 1002 0008 Radeon 7000/Radeon VE
623 1002 0009 Radeon 7000/Radeon
624 1002 000a Radeon 7000/Radeon
625 1002 001a Radeon 7000/Radeon
626 1002 0029 Radeon AIW
627 1002 0038 Radeon 7000/Radeon
628 1002 0039 Radeon 7000/Radeon
629 1002 008a Radeon 7000/Radeon
630 1002 00ba Radeon 7000/Radeon
631 1002 0139 Radeon 7000/Radeon
632 1002 028a Radeon 7000/Radeon
633 1002 02aa Radeon AIW
634 1002 053a Radeon 7000/Radeon
635 5145 Radeon R100 QE
636 5146 Radeon R100 QF
637 5147 Radeon R100 QG
638 5148 Radeon R200 QH [Radeon 8500]
639 1002 010a FireGL 8800 64Mb
640 1002 0152 FireGL 8800 128Mb
641 1002 0162 FireGL 8700 32Mb
642 1002 0172 FireGL 8700 64Mb
643 5149 Radeon R200 QI
644 514a Radeon R200 QJ
645 514b Radeon R200 QK
646 514c Radeon R200 QL [Radeon 8500 LE]
647 1002 003a Radeon R200 QL [Radeon 8500 LE]
648 1002 013a Radeon 8500
649 148c 2026 R200 QL [Radeon 8500 Evil Master II Multi Display Edition]
650 1681 0010 Radeon 8500 [3D Prophet 8500 128Mb]
651 174b 7149 Radeon R200 QL [Sapphire Radeon 8500 LE]
652 514d Radeon R200 QM [Radeon 9100]
653 514e Radeon R200 QN [Radeon 8500LE]
654 514f Radeon R200 QO [Radeon 8500LE]
655 5154 R200 QT [Radeon 8500]
656 5155 R200 QU [Radeon 9100]
657 5157 Radeon RV200 QW [Radeon 7500]
658 1002 013a Radeon 7500
659 1002 103a Dell Optiplex GX260
660 1458 4000 RV200 QW [RADEON 7500 PRO MAYA AR]
661 148c 2024 RV200 QW [Radeon 7500LE Dual Display]
662 148c 2025 RV200 QW [Radeon 7500 Evil Master Multi Display Edition]
663 148c 2036 RV200 QW [Radeon 7500 PCI Dual Display]
664 174b 7146 RV200 QW [Radeon 7500 LE]
665 174b 7147 RV200 QW [Sapphire Radeon 7500LE]
666 174b 7161 Radeon RV200 QW [Radeon 7500 LE]
667 17af 0202 RV200 QW [Excalibur Radeon 7500LE]
668 5158 Radeon RV200 QX [Radeon 7500]
669 5159 Radeon RV100 QY [Radeon 7000/VE]
670 1002 000a Radeon 7000/Radeon VE
671 1002 000b Radeon 7000
672 1002 0038 Radeon 7000/Radeon VE
673 1002 003a Radeon 7000/Radeon VE
674 1002 00ba Radeon 7000/Radeon VE
675 1002 013a Radeon 7000/Radeon VE
676 1458 4002 RV100 QY [RADEON 7000 PRO MAYA AV Series]
677 148c 2003 RV100 QY [Radeon 7000 Multi-Display Edition]
678 148c 2023 RV100 QY [Radeon 7000 Evil Master Multi-Display]
679 174b 7112 RV100 QY [Sapphire Radeon VE 7000]
680 174b 7c28 Sapphire Radeon VE 7000 DDR
681 1787 0202 RV100 QY [Excalibur Radeon 7000]
682 515a Radeon RV100 QZ [Radeon 7000/VE]
683 5168 Radeon R200 Qh
684 5169 Radeon R200 Qi
685 516a Radeon R200 Qj
686 516b Radeon R200 Qk
687# This one is not in ATI documentation, but is in XFree86 source code
688 516c Radeon R200 Ql
689 5245 Rage 128 RE/SG
690 1002 0008 Xpert 128
691 1002 0028 Rage 128 AIW
692 1002 0029 Rage 128 AIW
693 1002 0068 Rage 128 AIW
694 5246 Rage 128 RF/SG AGP
695 1002 0004 Magnum/Xpert 128/Xpert 99
696 1002 0008 Magnum/Xpert128/X99/Xpert2000
697 1002 0028 Rage 128 AIW AGP
698 1002 0044 Rage Fury/Xpert 128/Xpert 2000
699 1002 0068 Rage 128 AIW AGP
700 1002 0448 Rage Fury
701 5247 Rage 128 RG
702 524b Rage 128 RK/VR
703 524c Rage 128 RL/VR AGP
704 1002 0008 Xpert 99/Xpert 2000
705 1002 0088 Xpert 99
706 5345 Rage 128 SE/4x
707 5346 Rage 128 SF/4x AGP 2x
708 1002 0048 RAGE 128 16MB VGA TVOUT AMC PAL
709 5347 Rage 128 SG/4x AGP 4x
710 5348 Rage 128 SH
711 534b Rage 128 SK/4x
712 534c Rage 128 SL/4x AGP 2x
713 534d Rage 128 SM/4x AGP 4x
714 1002 0008 Xpert 99/Xpert 2000
715 1002 0018 Xpert 2000
716 534e Rage 128 4x
717 5354 Mach 64 VT
718 1002 5654 Mach 64 reference
719 5446 Rage 128 Pro Ultra TF
720 1002 0004 Rage Fury Pro
721 1002 0008 Rage Fury Pro/Xpert 2000 Pro
722 1002 0018 Rage Fury Pro/Xpert 2000 Pro
723 1002 0028 Rage 128 AIW Pro AGP
724 1002 0029 Rage 128 AIW
725 1002 002a Rage 128 AIW Pro AGP
726 1002 002b Rage 128 AIW
727 1002 0048 Xpert 2000 Pro
728 544c Rage 128 Pro Ultra TL
729 5452 Rage 128 Pro Ultra TR
730 1002 001c Rage 128 Pro 4XL
731 103c 1279 Rage 128 Pro 4XL
732 5453 Rage 128 Pro Ultra TS
733 5454 Rage 128 Pro Ultra TT
734 5455 Rage 128 Pro Ultra TU
735 5460 M22 [Radeon Mobility M300]
736 5464 M22 [FireGL GL]
737 5548 R423 UH [Radeon X800 (PCIE)]
738 5549 R423 UI [Radeon X800PRO (PCIE)]
739 554a R423 UJ [Radeon X800LE (PCIE)]
740 554b R423 UK [Radeon X800SE (PCIE)]
741 5551 R423 UQ [FireGL V7200 (PCIE)]
742 5552 R423 UR [FireGL V5100 (PCIE)]
743 5554 R423 UT [FireGL V7100 (PCIE)]
744 556b Radeon R423 UK (PCIE) [X800 SE] (Secondary)
745 5654 264VT [Mach64 VT]
746 1002 5654 Mach64VT Reference
747 5655 264VT3 [Mach64 VT3]
748 5656 264VT4 [Mach64 VT4]
749 5830 RS300 Host Bridge
750 5831 RS300 Host Bridge
751 5832 RS300 Host Bridge
752 5833 Radeon 9100 IGP Host Bridge
753 5834 Radeon 9100 IGP
754 5835 RS300M AGP [Radeon Mobility 9100IGP]
755 5838 Radeon 9100 IGP AGP Bridge
756 5941 RV280 [Radeon 9200] (Secondary)
757 1458 4019 Gigabyte Radeon 9200
758 174b 7c12 Sapphire Radeon 9200
759# http://www.hightech.com.hk/html/9200.htm
760 17af 200d Excalibur Radeon 9200
761 18bc 0050 GeXcube GC-R9200-C3 (Secondary)
762 5944 RV280 [Radeon 9200 SE (PCI)]
763 5960 RV280 [Radeon 9200 PRO]
764 5961 RV280 [Radeon 9200]
765 1002 2f72 All-in-Wonder 9200 Series
766 1019 4c30 Radeon 9200 VIVO
767 12ab 5961 YUAN SMARTVGA Radeon 9200
768 1458 4018 Gigabyte Radeon 9200
769 174b 7c13 Sapphire Radeon 9200
770# http://www.hightech.com.hk/html/9200.htm
771 17af 200c Excalibur Radeon 9200
772 18bc 0050 Radeon 9200 Game Buster
773 18bc 0051 GeXcube GC-R9200-C3
774 18bc 0053 Radeon 9200 Game Buster VIVO
775 5962 RV280 [Radeon 9200]
776 5964 RV280 [Radeon 9200 SE]
777 1043 c006 ASUS Radeon 9200 SE / TD / 128M
778 1458 4018 Radeon 9200 SE
779 148c 2073 CN-AG92E
780 174b 7c13 Sapphire Radeon 9200 SE
781 1787 5964 Excalibur 9200SE VIVO 128M
782 17af 2012 Radeon 9200 SE Excalibur
783 18bc 0170 Sapphire Radeon 9200 SE 128MB Game Buster
784# 128MB DDR, DVI/VGA/TV out
785 18bc 0173 GC-R9200L(SE)-C3H [Radeon 9200 Game Buster]
786 5b60 RV370 5B60 [Radeon X300 (PCIE)]
787 1043 002a Extreme AX300SE-X
788 1043 032e Extreme AX300/TD
789 5b62 RV370 5B62 [Radeon X600 (PCIE)]
790 5b64 RV370 5B64 [FireGL V3100 (PCIE)]
791 5b65 RV370 5B65 [FireGL D1100 (PCIE)]
792 5c61 M9+ 5C61 [Radeon Mobility 9200 (AGP)]
793 5c63 M9+ 5C63 [Radeon Mobility 9200 (AGP)]
794 5d44 RV280 [Radeon 9200 SE] (Secondary)
795 1458 4019 Radeon 9200 SE (Secondary)
796 174b 7c12 Sapphire Radeon 9200 SE (Secondary)
797 1787 5965 Excalibur 9200SE VIVO 128M (Secondary)
798 17af 2013 Radeon 9200 SE Excalibur (Secondary)
799 18bc 0171 Radeon 9200 SE 128MB Game Buster (Secondary)
800 18bc 0172 GC-R9200L(SE)-C3H [Radeon 9200 Game Buster]
801 5d4d R480 [Radeon X850XT Platinum]
802 5d57 R423 5F57 [Radeon X800XT (PCIE)]
803 700f PCI Bridge [IGP 320M]
804 7010 PCI Bridge [IGP 340M]
805 7834 Radeon 9100 PRO IGP
806 7835 Radeon Mobility 9200 IGP
807 7c37 RV350 AQ [Radeon 9600 SE]
808 cab0 AGP Bridge [IGP 320M]
809 cab2 RS200/RS200M AGP Bridge [IGP 340M]
810 cbb2 RS200/RS200M AGP Bridge [IGP 340M]
8111003 ULSI Systems
812 0201 US201
8131004 VLSI Technology Inc
814 0005 82C592-FC1
815 0006 82C593-FC1
816 0007 82C594-AFC2
817 0008 82C596/7 [Wildcat]
818 0009 82C597-AFC2
819 000c 82C541 [Lynx]
820 000d 82C543 [Lynx]
821 0101 82C532
822 0102 82C534 [Eagle]
823 0103 82C538
824 0104 82C535
825 0105 82C147
826 0200 82C975
827 0280 82C925
828 0304 QSound ThunderBird PCI Audio
829 1004 0304 QSound ThunderBird PCI Audio
830 122d 1206 DSP368 Audio
831 1483 5020 XWave Thunder 3D Audio
832 0305 QSound ThunderBird PCI Audio Gameport
833 1004 0305 QSound ThunderBird PCI Audio Gameport
834 122d 1207 DSP368 Audio Gameport
835 1483 5021 XWave Thunder 3D Audio Gameport
836 0306 QSound ThunderBird PCI Audio Support Registers
837 1004 0306 QSound ThunderBird PCI Audio Support Registers
838 122d 1208 DSP368 Audio Support Registers
839 1483 5022 XWave Thunder 3D Audio Support Registers
840 0307 Thunderbird
841 0308 Thunderbird
842 0702 VAS96011 [Golden Gate II]
843 0703 Tollgate
8441005 Avance Logic Inc. [ALI]
845 2064 ALG2032/2064
846 2128 ALG2364A
847 2301 ALG2301
848 2302 ALG2302
849 2364 ALG2364
850 2464 ALG2364A
851 2501 ALG2564A/25128A
8521006 Reply Group
8531007 NetFrame Systems Inc
8541008 Epson
855100a Phoenix Technologies
856100b National Semiconductor Corporation
857 0001 DP83810
858 0002 87415/87560 IDE
859 000e 87560 Legacy I/O
860 000f FireWire Controller
861 0011 NS87560 National PCI System I/O
862 0012 USB Controller
863 0020 DP83815 (MacPhyter) Ethernet Controller
864 103c 0024 Pavilion ze4400 builtin Network
865 1385 f311 FA311 / FA312 (FA311 with WoL HW)
866 0022 DP83820 10/100/1000 Ethernet Controller
867 0028 Geode GX2 Host Bridge
868 002a CS5535 South Bridge
869 002b CS5535 ISA bridge
870 002d CS5535 IDE
871 002e CS5535 Audio
872 002f CS5535 USB
873 0030 Geode GX2 Graphics Processor
874 0035 DP83065 [Saturn] 10/100/1000 Ethernet Controller
875 0500 SCx200 Bridge
876 0501 SCx200 SMI
877 0502 SCx200 IDE
878 0503 SCx200 Audio
879 0504 SCx200 Video
880 0505 SCx200 XBus
881 0510 SC1100 Bridge
882 0511 SC1100 SMI
883 0515 SC1100 XBus
884 d001 87410 IDE
885100c Tseng Labs Inc
886 3202 ET4000/W32p rev A
887 3205 ET4000/W32p rev B
888 3206 ET4000/W32p rev C
889 3207 ET4000/W32p rev D
890 3208 ET6000
891 4702 ET6300
892100d AST Research Inc
893100e Weitek
894 9000 P9000 Viper
895 9001 P9000 Viper
896 9002 P9000 Viper
897 9100 P9100 Viper Pro/SE
8981010 Video Logic, Ltd.
8991011 Digital Equipment Corporation
900 0001 DECchip 21050
901 0002 DECchip 21040 [Tulip]
902 0004 DECchip 21030 [TGA]
903 0007 NVRAM [Zephyr NVRAM]
904 0008 KZPSA [KZPSA]
905 0009 DECchip 21140 [FasterNet]
906 1025 0310 21140 Fast Ethernet
907 10b8 2001 SMC9332BDT EtherPower 10/100
908 10b8 2002 SMC9332BVT EtherPower T4 10/100
909 10b8 2003 SMC9334BDT EtherPower 10/100 (1-port)
910 1109 2400 ANA-6944A/TX Fast Ethernet
911 1112 2300 RNS2300 Fast Ethernet
912 1112 2320 RNS2320 Fast Ethernet
913 1112 2340 RNS2340 Fast Ethernet
914 1113 1207 EN-1207-TX Fast Ethernet
915 1186 1100 DFE-500TX Fast Ethernet
916 1186 1112 DFE-570TX Fast Ethernet
917 1186 1140 DFE-660 Cardbus Ethernet 10/100
918 1186 1142 DFE-660 Cardbus Ethernet 10/100
919 11f6 0503 Freedomline Fast Ethernet
920 1282 9100 AEF-380TXD Fast Ethernet
921 1385 1100 FA310TX Fast Ethernet
922 2646 0001 KNE100TX Fast Ethernet
923 000a 21230 Video Codec
924 000d PBXGB [TGA2]
925 000f DEFPA
926 0014 DECchip 21041 [Tulip Pass 3]
927 1186 0100 DE-530+
928 0016 DGLPB [OPPO]
929 0017 PV-PCI Graphics Controller (ZLXp-L)
930 0019 DECchip 21142/43
931 1011 500a DE500A Fast Ethernet
932 1011 500b DE500B Fast Ethernet
933 1014 0001 10/100 EtherJet Cardbus
934 1025 0315 ALN315 Fast Ethernet
935 1033 800c PC-9821-CS01 100BASE-TX Interface Card
936 1033 800d PC-9821NR-B06 100BASE-TX Interface Card
937 108d 0016 Rapidfire 2327 10/100 Ethernet
938 108d 0017 GoCard 2250 Ethernet 10/100 Cardbus
939 10b8 2005 SMC8032DT Extreme Ethernet 10/100
940 10b8 8034 SMC8034 Extreme Ethernet 10/100
941 10ef 8169 Cardbus Fast Ethernet
942 1109 2a00 ANA-6911A/TX Fast Ethernet
943 1109 2b00 ANA-6911A/TXC Fast Ethernet
944 1109 3000 ANA-6922/TX Fast Ethernet
945 1113 1207 Cheetah Fast Ethernet
946 1113 2220 Cardbus Fast Ethernet
947 115d 0002 Cardbus Ethernet 10/100
948 1179 0203 Fast Ethernet
949 1179 0204 Cardbus Fast Ethernet
950 1186 1100 DFE-500TX Fast Ethernet
951 1186 1101 DFE-500TX Fast Ethernet
952 1186 1102 DFE-500TX Fast Ethernet
953 1186 1112 DFE-570TX Quad Fast Ethernet
954 1259 2800 AT-2800Tx Fast Ethernet
955 1266 0004 Eagle Fast EtherMAX
956 12af 0019 NetFlyer Cardbus Fast Ethernet
957 1374 0001 Cardbus Ethernet Card 10/100
958 1374 0002 Cardbus Ethernet Card 10/100
959 1374 0007 Cardbus Ethernet Card 10/100
960 1374 0008 Cardbus Ethernet Card 10/100
961 1385 2100 FA510
962 1395 0001 10/100 Ethernet CardBus PC Card
963 13d1 ab01 EtherFast 10/100 Cardbus (PCMPC200)
964 14cb 0100 LNDL-100N 100Base-TX Ethernet PC Card
965 8086 0001 EtherExpress PRO/100 Mobile CardBus 32
966 001a Farallon PN9000SX Gigabit Ethernet
967 0021 DECchip 21052
968 0022 DECchip 21150
969 0023 DECchip 21150
970 0024 DECchip 21152
971 0025 DECchip 21153
972 0026 DECchip 21154
973 0034 56k Modem Cardbus
974 1374 0003 56k Modem Cardbus
975 0045 DECchip 21553
976 0046 DECchip 21554
977 0e11 4050 Integrated Smart Array
978 0e11 4051 Integrated Smart Array
979 0e11 4058 Integrated Smart Array
980 103c 10c2 Hewlett-Packard NetRAID-4M
981 12d9 000a IP Telephony card
982 4c53 1050 CT7 mainboard
983 4c53 1051 CE7 mainboard
984 9005 0364 5400S (Mustang)
985 9005 0365 5400S (Mustang)
986 9005 1364 Dell PowerEdge RAID Controller 2
987 9005 1365 Dell PowerEdge RAID Controller 2
988 e4bf 1000 CC8-1-BLUES
989 1065 StrongARM DC21285
990 1069 0020 DAC960P / DAC1164P
9911012 Micronics Computers Inc
9921013 Cirrus Logic
993 0038 GD 7548
994 0040 GD 7555 Flat Panel GUI Accelerator
995 004c GD 7556 Video/Graphics LCD/CRT Ctrlr
996 00a0 GD 5430/40 [Alpine]
997 00a2 GD 5432 [Alpine]
998 00a4 GD 5434-4 [Alpine]
999 00a8 GD 5434-8 [Alpine]
1000 00ac GD 5436 [Alpine]
1001 00b0 GD 5440
1002 00b8 GD 5446
1003 00bc GD 5480
1004 1013 00bc CL-GD5480
1005 00d0 GD 5462
1006 00d2 GD 5462 [Laguna I]
1007 00d4 GD 5464 [Laguna]
1008 00d5 GD 5464 BD [Laguna]
1009 00d6 GD 5465 [Laguna]
1010 13ce 8031 Barco Metheus 2 Megapixel, Dual Head
1011 13cf 8031 Barco Metheus 2 Megapixel, Dual Head
1012 00e8 GD 5436U
1013 1100 CL 6729
1014 1110 PD 6832 PCMCIA/CardBus Ctrlr
1015 1112 PD 6834 PCMCIA/CardBus Ctrlr
1016 1113 PD 6833 PCMCIA/CardBus Ctrlr
1017 1200 GD 7542 [Nordic]
1018 1202 GD 7543 [Viking]
1019 1204 GD 7541 [Nordic Light]
1020 4000 MD 5620 [CLM Data Fax Voice]
1021 4400 CD 4400
1022 6001 CS 4610/11 [CrystalClear SoundFusion Audio Accelerator]
1023 1014 1010 CS4610 SoundFusion Audio Accelerator
1024 6003 CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator]
1025 1013 4280 Crystal SoundFusion PCI Audio Accelerator
1026 153b 1136 SiXPack 5.1+
1027 1681 0050 Game Theater XP
1028 1681 a011 Fortissimo III 7.1
1029 6004 CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator]
1030 6005 Crystal CS4281 PCI Audio
1031 1013 4281 Crystal CS4281 PCI Audio
1032 10cf 10a8 Crystal CS4281 PCI Audio
1033 10cf 10a9 Crystal CS4281 PCI Audio
1034 10cf 10aa Crystal CS4281 PCI Audio
1035 10cf 10ab Crystal CS4281 PCI Audio
1036 10cf 10ac Crystal CS4281 PCI Audio
1037 10cf 10ad Crystal CS4281 PCI Audio
1038 10cf 10b4 Crystal CS4281 PCI Audio
1039 1179 0001 Crystal CS4281 PCI Audio
1040 14c0 000c Crystal CS4281 PCI Audio
10411014 IBM
1042 0002 PCI to MCA Bridge
1043 0005 Alta Lite
1044 0007 Alta MP
1045 000a Fire Coral
1046 0017 CPU to PCI Bridge
1047 0018 TR Auto LANstreamer
1048 001b GXT-150P
1049 001c Carrera
1050 001d 82G2675
1051 0020 GXT1000 Graphics Adapter
1052 0022 IBM27-82351
1053 002d Python
1054# [official name in AIX 5]
1055 002e SCSI RAID Adapter [ServeRAID]
1056 1014 002e ServeRAID-3x
1057 1014 022e ServeRAID-4H
1058 0031 2 Port Serial Adapter
1059# AS400 iSeries PCI sync serial card
1060 1014 0031 2721 WAN IOA - 2 Port Sync Serial Adapter
1061 0036 Miami
1062 0037 82660 CPU to PCI Bridge
1063 003a CPU to PCI Bridge
1064 003c GXT250P/GXT255P Graphics Adapter
1065 003e 16/4 Token ring UTP/STP controller
1066 1014 003e Token-Ring Adapter
1067 1014 00cd Token-Ring Adapter + Wake-On-LAN
1068 1014 00ce 16/4 Token-Ring Adapter 2
1069 1014 00cf 16/4 Token-Ring Adapter Special
1070 1014 00e4 High-Speed 100/16/4 Token-Ring Adapter
1071 1014 00e5 16/4 Token-Ring Adapter 2 + Wake-On-LAN
1072 1014 016d iSeries 2744 Card
1073 0045 SSA Adapter
1074 0046 MPIC interrupt controller
1075 0047 PCI to PCI Bridge
1076 0048 PCI to PCI Bridge
1077 0049 Warhead SCSI Controller
1078 004e ATM Controller (14104e00)
1079 004f ATM Controller (14104f00)
1080 0050 ATM Controller (14105000)
1081 0053 25 MBit ATM Controller
1082 0054 GXT500P/GXT550P Graphics Adapter
1083 0057 MPEG PCI Bridge
1084 005c i82557B 10/100
1085 005e GXT800P Graphics Adapter
1086 007c ATM Controller (14107c00)
1087 007d 3780IDSP [MWave]
1088 008b EADS PCI to PCI Bridge
1089 008e GXT3000P Graphics Adapter
1090 0090 GXT 3000P
1091 1014 008e GXT-3000P
1092 0091 SSA Adapter
1093 0095 20H2999 PCI Docking Bridge
1094 0096 Chukar chipset SCSI controller
1095 1014 0097 iSeries 2778 DASD IOA
1096 1014 0098 iSeries 2763 DASD IOA
1097 1014 0099 iSeries 2748 DASD IOA
1098 009f PCI 4758 Cryptographic Accelerator
1099 00a5 ATM Controller (1410a500)
1100 00a6 ATM 155MBPS MM Controller (1410a600)
1101 00b7 256-bit Graphics Rasterizer [Fire GL1]
1102 1092 00b8 FireGL1 AGP 32Mb
1103 00b8 GXT2000P Graphics Adapter
1104 00be ATM 622MBPS Controller (1410be00)
1105 00dc Advanced Systems Management Adapter (ASMA)
1106 00fc CPC710 Dual Bridge and Memory Controller (PCI-64)
1107 0104 Gigabit Ethernet-SX Adapter
1108 0105 CPC710 Dual Bridge and Memory Controller (PCI-32)
1109 010f Remote Supervisor Adapter (RSA)
1110 0142 Yotta Video Compositor Input
1111 1014 0143 Yotta Input Controller (ytin)
1112 0144 Yotta Video Compositor Output
1113 1014 0145 Yotta Output Controller (ytout)
1114 0156 405GP PLB to PCI Bridge
1115 015e 622Mbps ATM PCI Adapter
1116 0160 64bit/66MHz PCI ATM 155 MMF
1117 016e GXT4000P Graphics Adapter
1118 0170 GXT6000P Graphics Adapter
1119 017d GXT300P Graphics Adapter
1120 0180 Snipe chipset SCSI controller
1121 1014 0241 iSeries 2757 DASD IOA
1122 1014 0264 Quad Channel PCI-X U320 SCSI RAID Adapter (2780)
1123 0188 EADS-X PCI-X to PCI-X Bridge
1124 01a7 PCI-X to PCI-X Bridge
1125 01bd ServeRAID Controller
1126 1014 01be ServeRAID-4M
1127 1014 01bf ServeRAID-4L
1128 1014 0208 ServeRAID-4Mx
1129 1014 020e ServeRAID-4Lx
1130 1014 022e ServeRAID-4H
1131 1014 0258 ServeRAID-5i
1132 1014 0259 ServeRAID-5i
1133 01c1 64bit/66MHz PCI ATM 155 UTP
1134 01e6 Cryptographic Accelerator
1135 01ff 10/100 Mbps Ethernet
1136 0219 Multiport Serial Adapter
1137 1014 021a Dual RVX
1138 1014 0251 Internal Modem/RVX
1139 1014 0252 Quad Internal Modem
1140 021b GXT6500P Graphics Adapter
1141 021c GXT4500P Graphics Adapter
1142 0233 GXT135P Graphics Adapter
1143 0266 PCI-X Dual Channel SCSI
1144 0268 Gigabit Ethernet-SX Adapter (PCI-X)
1145 0269 10/100/1000 Base-TX Ethernet Adapter (PCI-X)
1146 028c Citrine chipset SCSI controller
1147 1014 028D Dual Channel PCI-X DDR SAS RAID Adapter (572E)
1148 1014 02BE Dual Channel PCI-X DDR U320 SCSI RAID Adapter (571B)
1149 1014 02C0 Dual Channel PCI-X DDR U320 SCSI Adapter (571A)
1150 0302 X-Architecture Bridge [Summit]
1151 0314 ZISC 036 Neural accelerator card
1152 ffff MPIC-2 interrupt controller
11531015 LSI Logic Corp of Canada
11541016 ICL Personal Systems
11551017 SPEA Software AG
1156 5343 SPEA 3D Accelerator
11571018 Unisys Systems
11581019 Elitegroup Computer Systems
1159101a AT&T GIS (NCR)
1160 0005 100VG ethernet
1161101b Vitesse Semiconductor
1162101c Western Digital
1163 0193 33C193A
1164 0196 33C196A
1165 0197 33C197A
1166 0296 33C296A
1167 3193 7193
1168 3197 7197
1169 3296 33C296A
1170 4296 34C296
1171 9710 Pipeline 9710
1172 9712 Pipeline 9712
1173 c24a 90C
1174101e American Megatrends Inc.
1175 1960 MegaRAID
1176 101e 0471 MegaRAID 471 Enterprise 1600 RAID Controller
1177 101e 0475 MegaRAID 475 Express 500/500LC RAID Controller
1178 101e 0477 MegaRAID 477 Elite 3100 RAID Controller
1179 101e 0493 MegaRAID 493 Elite 1600 RAID Controller
1180 101e 0494 MegaRAID 494 Elite 1650 RAID Controller
1181 101e 0503 MegaRAID 503 Enterprise 1650 RAID Controller
1182 101e 0511 MegaRAID 511 i4 IDE RAID Controller
1183 101e 0522 MegaRAID 522 i4133 RAID Controller
1184 1028 0471 PowerEdge RAID Controller 3/QC
1185 1028 0475 PowerEdge RAID Controller 3/SC
1186 1028 0493 PowerEdge RAID Controller 3/DC
1187 1028 0511 PowerEdge Cost Effective RAID Controller ATA100/4Ch
1188 9010 MegaRAID 428 Ultra RAID Controller
1189 9030 EIDE Controller
1190 9031 EIDE Controller
1191 9032 EIDE & SCSI Controller
1192 9033 SCSI Controller
1193 9040 Multimedia card
1194 9060 MegaRAID 434 Ultra GT RAID Controller
1195 9063 MegaRAC
1196 101e 0767 Dell Remote Assistant Card 2
1197101f PictureTel
11981020 Hitachi Computer Products
11991021 OKI Electric Industry Co. Ltd.
12001022 Advanced Micro Devices [AMD]
1201 1100 K8 [Athlon64/Opteron] HyperTransport Technology Configuration
1202 1101 K8 [Athlon64/Opteron] Address Map
1203 1102 K8 [Athlon64/Opteron] DRAM Controller
1204 1103 K8 [Athlon64/Opteron] Miscellaneous Control
1205 2000 79c970 [PCnet32 LANCE]
1206 1014 2000 NetFinity 10/100 Fast Ethernet
1207 1022 2000 PCnet - Fast 79C971
1208 103c 104c Ethernet with LAN remote power Adapter
1209 103c 1064 Ethernet with LAN remote power Adapter
1210 103c 1065 Ethernet with LAN remote power Adapter
1211 103c 106c Ethernet with LAN remote power Adapter
1212 103c 106e Ethernet with LAN remote power Adapter
1213 103c 10ea Ethernet with LAN remote power Adapter
1214 1113 1220 EN1220 10/100 Fast Ethernet
1215 1259 2450 AT-2450 10/100 Fast Ethernet
1216 1259 2454 AT-2450v4 10Mb Ethernet Adapter
1217 1259 2700 AT-2700TX 10/100 Fast Ethernet
1218 1259 2701 AT-2700FX 100Mb Ethernet
1219 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
1220 4c53 1010 CP5/CR6 mainboard
1221 4c53 1020 VR6 mainboard
1222 4c53 1030 PC5 mainboard
1223 4c53 1040 CL7 mainboard
1224 4c53 1060 PC7 mainboard
1225 2001 79c978 [HomePNA]
1226 1092 0a78 Multimedia Home Network Adapter
1227 1668 0299 ActionLink Home Network Adapter
1228 2003 Am 1771 MBW [Alchemy]
1229 2020 53c974 [PCscsi]
1230 2040 79c974
1231 3000 ELanSC520 Microcontroller
1232 7006 AMD-751 [Irongate] System Controller
1233 7007 AMD-751 [Irongate] AGP Bridge
1234 700a AMD-IGR4 AGP Host to PCI Bridge
1235 700b AMD-IGR4 PCI to PCI Bridge
1236 700c AMD-760 MP [IGD4-2P] System Controller
1237 700d AMD-760 MP [IGD4-2P] AGP Bridge
1238 700e AMD-760 [IGD4-1P] System Controller
1239 700f AMD-760 [IGD4-1P] AGP Bridge
1240 7400 AMD-755 [Cobra] ISA
1241 7401 AMD-755 [Cobra] IDE
1242 7403 AMD-755 [Cobra] ACPI
1243 7404 AMD-755 [Cobra] USB
1244 7408 AMD-756 [Viper] ISA
1245 7409 AMD-756 [Viper] IDE
1246 740b AMD-756 [Viper] ACPI
1247 740c AMD-756 [Viper] USB
1248 7410 AMD-766 [ViperPlus] ISA
1249 7411 AMD-766 [ViperPlus] IDE
1250 7413 AMD-766 [ViperPlus] ACPI
1251 7414 AMD-766 [ViperPlus] USB
1252 7440 AMD-768 [Opus] ISA
1253 1043 8044 A7M-D Mainboard
1254 7441 AMD-768 [Opus] IDE
1255 7443 AMD-768 [Opus] ACPI
1256 1043 8044 A7M-D Mainboard
1257 7445 AMD-768 [Opus] Audio
1258 7446 AMD-768 [Opus] MC97 Modem (Smart Link HAMR5600 compatible)
1259 7448 AMD-768 [Opus] PCI
1260 7449 AMD-768 [Opus] USB
1261 7450 AMD-8131 PCI-X Bridge
1262 7451 AMD-8131 PCI-X APIC
1263 7454 AMD-8151 System Controller
1264 7455 AMD-8151 AGP Bridge
1265 7460 AMD-8111 PCI
1266 161f 3017 HDAMB
1267 7461 AMD-8111 USB
1268 7462 AMD-8111 Ethernet
1269 7464 AMD-8111 USB
1270 161f 3017 HDAMB
1271 7468 AMD-8111 LPC
1272 161f 3017 HDAMB
1273 7469 AMD-8111 IDE
1274 161f 3017 HDAMB
1275 746a AMD-8111 SMBus 2.0
1276 746b AMD-8111 ACPI
1277 161f 3017 HDAMB
1278 746d AMD-8111 AC97 Audio
1279 161f 3017 HDAMB
1280 746e AMD-8111 MC97 Modem
1281 756b AMD-8111 ACPI
12821023 Trident Microsystems
1283 0194 82C194
1284 2000 4DWave DX
1285 2001 4DWave NX
1286 122d 1400 Trident PCI288-Q3DII (NX)
1287 2100 CyberBlade XP4m32
1288 2200 XGI Volari XP5
1289 8400 CyberBlade/i7
1290 1023 8400 CyberBlade i7 AGP
1291 8420 CyberBlade/i7d
1292 0e11 b15a CyberBlade i7 AGP
1293 8500 CyberBlade/i1
1294 8520 CyberBlade i1
1295 0e11 b16e CyberBlade i1 AGP
1296 1023 8520 CyberBlade i1 AGP
1297 8620 CyberBlade/i1
1298 1014 0502 ThinkPad R30/T30
1299 8820 CyberBlade XPAi1
1300 9320 TGUI 9320
1301 9350 GUI Accelerator
1302 9360 Flat panel GUI Accelerator
1303 9382 Cyber 9382 [Reference design]
1304 9383 Cyber 9383 [Reference design]
1305 9385 Cyber 9385 [Reference design]
1306 9386 Cyber 9386
1307 9388 Cyber 9388
1308 9397 Cyber 9397
1309 939a Cyber 9397DVD
1310 9420 TGUI 9420
1311 9430 TGUI 9430
1312 9440 TGUI 9440
1313 9460 TGUI 9460
1314 9470 TGUI 9470
1315 9520 Cyber 9520
1316 9525 Cyber 9525
1317 10cf 1094 Lifebook C6155
1318 9540 Cyber 9540
1319 9660 TGUI 9660/938x/968x
1320 9680 TGUI 9680
1321 9682 TGUI 9682
1322 9683 TGUI 9683
1323 9685 ProVIDIA 9685
1324 9750 3DImage 9750
1325 1014 9750 3DImage 9750
1326 1023 9750 3DImage 9750
1327 9753 TGUI 9753
1328 9754 TGUI 9754
1329 9759 TGUI 975
1330 9783 TGUI 9783
1331 9785 TGUI 9785
1332 9850 3DImage 9850
1333 9880 Blade 3D PCI/AGP
1334 1023 9880 Blade 3D
1335 9910 CyberBlade/XP
1336 9930 CyberBlade/XPm
13371024 Zenith Data Systems
13381025 Acer Incorporated [ALI]
1339 1435 M1435
1340 1445 M1445
1341 1449 M1449
1342 1451 M1451
1343 1461 M1461
1344 1489 M1489
1345 1511 M1511
1346 1512 ALI M1512 Aladdin
1347 1513 M1513
1348 1521 ALI M1521 Aladdin III CPU Bridge
1349 10b9 1521 ALI M1521 Aladdin III CPU Bridge
1350 1523 ALI M1523 ISA Bridge
1351 10b9 1523 ALI M1523 ISA Bridge
1352 1531 M1531 Northbridge [Aladdin IV/IV+]
1353 1533 M1533 PCI-to-ISA Bridge
1354 10b9 1533 ALI M1533 Aladdin IV/V ISA South Bridge
1355 1535 M1535 PCI Bridge + Super I/O + FIR
1356 1541 M1541 Northbridge [Aladdin V]
1357 10b9 1541 ALI M1541 Aladdin V/V+ AGP+PCI North Bridge
1358 1542 M1542 Northbridge [Aladdin V]
1359 1543 M1543 PCI-to-ISA Bridge + Super I/O + FIR
1360 1561 M1561 Northbridge [Aladdin 7]
1361 1621 M1621 Northbridge [Aladdin-Pro II]
1362 1631 M1631 Northbridge+3D Graphics [Aladdin TNT2]
1363 1641 M1641 Northbridge [Aladdin-Pro IV]
1364 1647 M1647 [MaGiK1] PCI North Bridge
1365 1671 M1671 Northbridge [ALADDiN-P4]
1366 1672 Northbridge [CyberALADDiN-P4]
1367 3141 M3141
1368 3143 M3143
1369 3145 M3145
1370 3147 M3147
1371 3149 M3149
1372 3151 M3151
1373 3307 M3307 MPEG-I Video Controller
1374 3309 M3309 MPEG-II Video w/ Software Audio Decoder
1375 3321 M3321 MPEG-II Audio/Video Decoder
1376 5212 M4803
1377 5215 ALI PCI EIDE Controller
1378 5217 M5217H
1379 5219 M5219
1380 5225 M5225
1381 5229 M5229
1382 5235 M5235
1383 5237 M5237 PCI USB Host Controller
1384 5240 EIDE Controller
1385 5241 PCMCIA Bridge
1386 5242 General Purpose Controller
1387 5243 PCI to PCI Bridge Controller
1388 5244 Floppy Disk Controller
1389 5247 M1541 PCI to PCI Bridge
1390 5251 M5251 P1394 Controller
1391 5427 PCI to AGP Bridge
1392 5451 M5451 PCI AC-Link Controller Audio Device
1393 5453 M5453 PCI AC-Link Controller Modem Device
1394 7101 M7101 PCI PMU Power Management Controller
1395 10b9 7101 M7101 PCI PMU Power Management Controller
13961028 Dell
1397 0001 PowerEdge Expandable RAID Controller 2/Si
1398 1028 0001 PowerEdge 2400
1399 0002 PowerEdge Expandable RAID Controller 3/Di
1400 1028 0002 PowerEdge 4400
1401 0003 PowerEdge Expandable RAID Controller 3/Si
1402 1028 0003 PowerEdge 2450
1403 0006 PowerEdge Expandable RAID Controller 3/Di
1404 0007 Remote Access Card III
1405 0008 Remote Access Card III
1406 0009 Remote Access Card III: BMC/SMIC device not present
1407 000a PowerEdge Expandable RAID Controller 3/Di
1408 000c Embedded Remote Access or ERA/O
1409 000d Embedded Remote Access: BMC/SMIC device
1410 000e PowerEdge Expandable RAID controller 4/Di
1411 000f PowerEdge Expandable RAID controller 4/Di
1412 0010 Remote Access Card 4
1413 0011 Remote Access Card 4 Daughter Card
1414 0012 Remote Access Card 4 Daughter Card Virtual UART
1415 0013 PowerEdge Expandable RAID controller 4
1416 1028 016c PowerEdge Expandable RAID Controller 4e/Si
1417 1028 016d PowerEdge Expandable RAID Controller 4e/Di
1418 1028 016e PowerEdge Expandable RAID Controller 4e/Di
1419 1028 016f PowerEdge Expandable RAID Controller 4e/Di
1420 1028 0170 PowerEdge Expandable RAID Controller 4e/Di
1421 0014 Remote Access Card 4 Daughter Card SMIC interface
14221029 Siemens Nixdorf IS
1423102a LSI Logic
1424 0000 HYDRA
1425 0010 ASPEN
1426 001f AHA-2940U2/U2W /7890/7891 SCSI Controllers
1427 9005 000f 2940U2W SCSI Controller
1428 9005 0106 2940U2W SCSI Controller
1429 9005 a180 2940U2W SCSI Controller
1430 00c5 AIC-7899 U160/m SCSI Controller
1431 1028 00c5 PowerEdge 2550/2650/4600
1432 00cf AIC-7899P U160/m
1433 1028 0106 PowerEdge 4600
1434 1028 0121 PowerEdge 2650
1435102b Matrox Graphics, Inc.
1436# DJ: I've a suspicion that 0010 is a duplicate of 0d10.
1437 0010 MGA-I [Impression?]
1438 0100 MGA 1064SG [Mystique]
1439 0518 MGA-II [Athena]
1440 0519 MGA 2064W [Millennium]
1441 051a MGA 1064SG [Mystique]
1442 102b 0100 MGA-1064SG Mystique
1443 102b 1100 MGA-1084SG Mystique
1444 102b 1200 MGA-1084SG Mystique
1445 1100 102b MGA-1084SG Mystique
1446 110a 0018 Scenic Pro C5 (D1025)
1447 051b MGA 2164W [Millennium II]
1448 102b 051b MGA-2164W Millennium II
1449 102b 1100 MGA-2164W Millennium II
1450 102b 1200 MGA-2164W Millennium II
1451 051e MGA 1064SG [Mystique] AGP
1452 051f MGA 2164W [Millennium II] AGP
1453 0520 MGA G200
1454 102b dbc2 G200 Multi-Monitor
1455 102b dbc8 G200 Multi-Monitor
1456 102b dbe2 G200 Multi-Monitor
1457 102b dbe8 G200 Multi-Monitor
1458 102b ff03 Millennium G200 SD
1459 102b ff04 Marvel G200
1460 0521 MGA G200 AGP
1461 1014 ff03 Millennium G200 AGP
1462 102b 48e9 Mystique G200 AGP
1463 102b 48f8 Millennium G200 SD AGP
1464 102b 4a60 Millennium G200 LE AGP
1465 102b 4a64 Millennium G200 AGP
1466 102b c93c Millennium G200 AGP
1467 102b c9b0 Millennium G200 AGP
1468 102b c9bc Millennium G200 AGP
1469 102b ca60 Millennium G250 LE AGP
1470 102b ca6c Millennium G250 AGP
1471 102b dbbc Millennium G200 AGP
1472 102b dbc2 Millennium G200 MMS (Dual G200)
1473 102b dbc3 G200 Multi-Monitor
1474 102b dbc8 Millennium G200 MMS (Dual G200)
1475 102b dbd2 G200 Multi-Monitor
1476 102b dbd3 G200 Multi-Monitor
1477 102b dbd4 G200 Multi-Monitor
1478 102b dbd5 G200 Multi-Monitor
1479 102b dbd8 G200 Multi-Monitor
1480 102b dbd9 G200 Multi-Monitor
1481 102b dbe2 Millennium G200 MMS (Quad G200)
1482 102b dbe3 G200 Multi-Monitor
1483 102b dbe8 Millennium G200 MMS (Quad G200)
1484 102b dbf2 G200 Multi-Monitor
1485 102b dbf3 G200 Multi-Monitor
1486 102b dbf4 G200 Multi-Monitor
1487 102b dbf5 G200 Multi-Monitor
1488 102b dbf8 G200 Multi-Monitor
1489 102b dbf9 G200 Multi-Monitor
1490 102b f806 Mystique G200 Video AGP
1491 102b ff00 MGA-G200 AGP
1492 102b ff02 Mystique G200 AGP
1493 102b ff03 Millennium G200 AGP
1494 102b ff04 Marvel G200 AGP
1495 110a 0032 MGA-G200 AGP
1496 0525 MGA G400 AGP
1497 0e11 b16f MGA-G400 AGP
1498 102b 0328 Millennium G400 16Mb SDRAM
1499 102b 0338 Millennium G400 16Mb SDRAM
1500 102b 0378 Millennium G400 32Mb SDRAM
1501 102b 0541 Millennium G450 Dual Head
1502 102b 0542 Millennium G450 Dual Head LX
1503 102b 0543 Millennium G450 Single Head LX
1504 102b 0641 Millennium G450 32Mb SDRAM Dual Head
1505 102b 0642 Millennium G450 32Mb SDRAM Dual Head LX
1506 102b 0643 Millennium G450 32Mb SDRAM Single Head LX
1507 102b 07c0 Millennium G450 Dual Head LE
1508 102b 07c1 Millennium G450 SDR Dual Head LE
1509 102b 0d41 Millennium G450 Dual Head PCI
1510 102b 0d42 Millennium G450 Dual Head LX PCI
1511 102b 0d43 Millennium G450 32Mb Dual Head PCI
1512 102b 0e00 Marvel G450 eTV
1513 102b 0e01 Marvel G450 eTV
1514 102b 0e02 Marvel G450 eTV
1515 102b 0e03 Marvel G450 eTV
1516 102b 0f80 Millennium G450 Low Profile
1517 102b 0f81 Millennium G450 Low Profile
1518 102b 0f82 Millennium G450 Low Profile DVI
1519 102b 0f83 Millennium G450 Low Profile DVI
1520 102b 19d8 Millennium G400 16Mb SGRAM
1521 102b 19f8 Millennium G400 32Mb SGRAM
1522 102b 2159 Millennium G400 Dual Head 16Mb
1523 102b 2179 Millennium G400 MAX/Dual Head 32Mb
1524 102b 217d Millennium G400 Dual Head Max
1525 102b 23c0 Millennium G450
1526 102b 23c1 Millennium G450
1527 102b 23c2 Millennium G450 DVI
1528 102b 23c3 Millennium G450 DVI
1529 102b 2f58 Millennium G400
1530 102b 2f78 Millennium G400
1531 102b 3693 Marvel G400 AGP
1532 102b 5dd0 4Sight II
1533 102b 5f50 4Sight II
1534 102b 5f51 4Sight II
1535 102b 5f52 4Sight II
1536 102b 9010 Millennium G400 Dual Head
1537 1458 0400 GA-G400
1538 1705 0001 Millennium G450 32MB SGRAM
1539 1705 0002 Millennium G450 16MB SGRAM
1540 1705 0003 Millennium G450 32MB
1541 1705 0004 Millennium G450 16MB
1542 0527 MGA Parhelia AGP
1543 102b 0840 Parhelia 128Mb
1544 0d10 MGA Ultima/Impression
1545 1000 MGA G100 [Productiva]
1546 102b ff01 Productiva G100
1547 102b ff05 Productiva G100 Multi-Monitor
1548 1001 MGA G100 [Productiva] AGP
1549 102b 1001 MGA-G100 AGP
1550 102b ff00 MGA-G100 AGP
1551 102b ff01 MGA-G100 Productiva AGP
1552 102b ff03 Millennium G100 AGP
1553 102b ff04 MGA-G100 AGP
1554 102b ff05 MGA-G100 Productiva AGP Multi-Monitor
1555 110a 001e MGA-G100 AGP
1556 2007 MGA Mistral
1557 2527 MGA G550 AGP
1558 102b 0f83 Millennium G550
1559 102b 0f84 Millennium G550 Dual Head DDR 32Mb
1560 102b 1e41 Millennium G550
1561 2537 MGA G650 AGP
1562 4536 VIA Framegrabber
1563 6573 Shark 10/100 Multiport SwitchNIC
1564102c Chips and Technologies
1565 00b8 F64310
1566 00c0 F69000 HiQVideo
1567 102c 00c0 F69000 HiQVideo
1568 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
1569 4c53 1010 CP5/CR6 mainboard
1570 4c53 1020 VR6 mainboard
1571 4c53 1030 PC5 mainboard
1572 4c53 1050 CT7 mainboard
1573 4c53 1051 CE7 mainboard
1574 00d0 F65545
1575 00d8 F65545
1576 00dc F65548
1577 00e0 F65550
1578 00e4 F65554
1579 00e5 F65555 HiQVPro
1580 0e11 b049 Armada 1700 Laptop Display Controller
1581 00f0 F68554
1582 00f4 F68554 HiQVision
1583 00f5 F68555
1584 0c30 F69030
1585 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
1586 4c53 1050 CT7 mainboard
1587 4c53 1051 CE7 mainboard
1588# C5C project cancelled
1589 4c53 1080 CT8 mainboard
1590102d Wyse Technology Inc.
1591 50dc 3328 Audio
1592102e Olivetti Advanced Technology
1593102f Toshiba America
1594 0009 r4x00
1595 000a TX3927 MIPS RISC PCI Controller
1596 0020 ATM Meteor 155
1597 102f 00f8 ATM Meteor 155
1598 0030 TC35815CF PCI 10/100 Mbit Ethernet Controller
1599 0031 TC35815CF PCI 10/100 Mbit Ethernet Controller with WOL
1600 0105 TC86C001 [goku-s] IDE
1601 0106 TC86C001 [goku-s] USB 1.1 Host
1602 0107 TC86C001 [goku-s] USB Device Controller
1603 0108 TC86C001 [goku-s] I2C/SIO/GPIO Controller
1604 0180 TX4927/38 MIPS RISC PCI Controller
1605 0181 TX4925 MIPS RISC PCI Controller
1606 0182 TX4937 MIPS RISC PCI Controller
16071030 TMC Research
16081031 Miro Computer Products AG
1609 5601 DC20 ASIC
1610 5607 Video I/O & motion JPEG compressor
1611 5631 Media 3D
1612 6057 MiroVideo DC10/DC30+
16131032 Compaq
16141033 NEC Corporation
1615 0000 Vr4181A USB Host or Function Control Unit
1616 0001 PCI to 486-like bus Bridge
1617 0002 PCI to VL98 Bridge
1618 0003 ATM Controller
1619 0004 R4000 PCI Bridge
1620 0005 PCI to 486-like bus Bridge
1621 0006 PC-9800 Graphic Accelerator
1622 0007 PCI to UX-Bus Bridge
1623 0008 PC-9800 Graphic Accelerator
1624 0009 PCI to PC9800 Core-Graph Bridge
1625 0016 PCI to VL Bridge
1626 001a [Nile II]
1627 0021 Vrc4373 [Nile I]
1628 0029 PowerVR PCX1
1629 002a PowerVR 3D
1630 002c Star Alpha 2
1631 002d PCI to C-bus Bridge
1632 0035 USB
1633 1179 0001 USB
1634 12ee 7000 Root Hub
1635 1799 0001 Root Hub
1636 807d 0035 PCI-USB2 (OHCI subsystem)
1637 003b PCI to C-bus Bridge
1638 003e NAPCCARD Cardbus Controller
1639 0046 PowerVR PCX2 [midas]
1640 005a Vrc5074 [Nile 4]
1641 0063 Firewarden
1642 0067 PowerVR Neon 250 Chipset
1643 1010 0020 PowerVR Neon 250 AGP 32Mb
1644 1010 0080 PowerVR Neon 250 AGP 16Mb
1645 1010 0088 PowerVR Neon 250 16Mb
1646 1010 0090 PowerVR Neon 250 AGP 16Mb
1647 1010 0098 PowerVR Neon 250 16Mb
1648 1010 00a0 PowerVR Neon 250 AGP 32Mb
1649 1010 00a8 PowerVR Neon 250 32Mb
1650 1010 0120 PowerVR Neon 250 AGP 32Mb
1651 0072 uPD72874 IEEE1394 OHCI 1.1 3-port PHY-Link Ctrlr
1652 0074 56k Voice Modem
1653 1033 8014 RCV56ACF 56k Voice Modem
1654 009b Vrc5476
1655 00a5 VRC4173
1656 00a6 VRC5477 AC97
1657 00cd IEEE 1394 [OrangeLink] Host Controller
1658 12ee 8011 Root hub
1659 00ce IEEE 1394 Host Controller
1660 00df Vr4131
1661 00e0 USB 2.0
1662 0ee4 3383 Sitecom IEEE 1394 / USB2.0 Combo Card
1663 12ee 7001 Root hub
1664 1799 0002 Root Hub
1665 807d 1043 PCI-USB2 (EHCI subsystem)
1666 00e7 IEEE 1394 Host Controller
1667 00f2 uPD72874 IEEE1394 OHCI 1.1 3-port PHY-Link Ctrlr
1668 00f3 uPD6113x Multimedia Decoder/Processor [EMMA2]
1669 010c VR7701
16701034 Framatome Connectors USA Inc.
16711035 Comp. & Comm. Research Lab
16721036 Future Domain Corp.
1673 0000 TMC-18C30 [36C70]
16741037 Hitachi Micro Systems
16751038 AMP, Inc
16761039 Silicon Integrated Systems [SiS]
1677 0001 Virtual PCI-to-PCI bridge (AGP)
1678 0002 SG86C202
1679 0006 85C501/2/3
1680 0008 SiS85C503/5513 (LPC Bridge)
1681 0009 ACPI
1682# source: http://members.datafast.net.au/dft0802/downloads/pcidevs.txt
1683 0016 SiS961/2 SMBus Controller
1684 0018 SiS85C503/5513 (LPC Bridge)
1685# Controller for 2 PATA and 2 SATA channels
1686 0180 RAID bus controller 180 SATA/PATA [SiS]
1687 0181 SiS SATA
1688 0200 5597/5598/6326 VGA
1689 1039 0000 SiS5597 SVGA (Shared RAM)
1690 0204 82C204
1691 0205 SG86C205
1692 0300 300/305 PCI/AGP VGA Display Adapter
1693 107d 2720 Leadtek WinFast VR300
1694 0310 315H PCI/AGP VGA Display Adapter
1695 0315 315 PCI/AGP VGA Display Adapter
1696 0325 315PRO PCI/AGP VGA Display Adapter
1697 0330 330 [Xabre] PCI/AGP VGA Display Adapter
1698 0406 85C501/2
1699 0496 85C496
1700 0530 530 Host
1701 0540 540 Host
1702 0550 550 Host
1703 0597 5513C
1704 0601 85C601
1705 0620 620 Host
1706 0630 630 Host
1707 0633 633 Host
1708 0635 635 Host
1709 0645 SiS645 Host & Memory & AGP Controller
1710 0646 SiS645DX Host & Memory & AGP Controller
1711 0648 SiS 645xx
1712 0650 650/M650 Host
1713 0651 651 Host
1714 0655 655 Host
1715 0660 660 Host
1716 0661 661FX/M661FX/M661MX Host
1717 0730 730 Host
1718 0733 733 Host
1719 0735 735 Host
1720 0740 740 Host
1721 0741 741/741GX/M741 Host
1722 0745 745 Host
1723 0746 746 Host
1724 0755 755 Host
1725 0760 760/M760 Host
1726 0900 SiS900 PCI Fast Ethernet
1727 1019 0a14 K7S5A motherboard
1728 1039 0900 SiS900 10/100 Ethernet Adapter
1729 1043 8035 CUSI-FX motherboard
1730 0961 SiS961 [MuTIOL Media IO]
1731 0962 SiS962 [MuTIOL Media IO]
1732 0963 SiS963 [MuTIOL Media IO]
1733 0964 SiS964 [MuTIOL Media IO]
1734 0965 SiS965 [MuTIOL Media IO]
1735 3602 83C602
1736 5107 5107
1737 5300 SiS540 PCI Display Adapter
1738 5315 550 PCI/AGP VGA Display Adapter
1739 5401 486 PCI Chipset
1740 5511 5511/5512
1741 5513 5513 [IDE]
1742 1019 0970 P6STP-FL motherboard
1743 1039 5513 SiS5513 EIDE Controller (A,B step)
1744 1043 8035 CUSI-FX motherboard
1745 5517 5517
1746 5571 5571
1747 5581 5581 Pentium Chipset
1748 5582 5582
1749 5591 5591/5592 Host
1750 5596 5596 Pentium Chipset
1751 5597 5597 [SiS5582]
1752 5600 5600 Host
1753 6204 Video decoder & MPEG interface
1754 6205 VGA Controller
1755 6236 6236 3D-AGP
1756 6300 630/730 PCI/AGP VGA Display Adapter
1757 1019 0970 P6STP-FL motherboard
1758 1043 8035 CUSI-FX motherboard
1759 6306 530/620 PCI/AGP VGA Display Adapter
1760 1039 6306 SiS530,620 GUI Accelerator+3D
1761 6325 65x/M650/740 PCI/AGP VGA Display Adapter
1762 6326 86C326 5598/6326
1763 1039 6326 SiS6326 GUI Accelerator
1764 1092 0a50 SpeedStar A50
1765 1092 0a70 SpeedStar A70
1766 1092 4910 SpeedStar A70
1767 1092 4920 SpeedStar A70
1768 1569 6326 SiS6326 GUI Accelerator
1769 6330 661/741/760 PCI/AGP VGA Display Adapter
1770 1039 6330 [M]661xX/[M]741[GX]/[M]760 PCI/AGP VGA Adapter
1771 7001 USB 1.0 Controller
1772 1019 0a14 K7S5A motherboard
1773 1039 7000 Onboard USB Controller
1774 7002 USB 2.0 Controller
1775 1509 7002 Onboard USB Controller
1776 7007 FireWire Controller
1777 7012 Sound Controller
1778# There are may be different modem codecs here (Intel537 compatible and incompatible)
1779 7013 AC'97 Modem Controller
1780 7016 SiS7016 PCI Fast Ethernet Adapter
1781 1039 7016 SiS7016 10/100 Ethernet Adapter
1782 7018 SiS PCI Audio Accelerator
1783 1014 01b6 SiS PCI Audio Accelerator
1784 1014 01b7 SiS PCI Audio Accelerator
1785 1019 7018 SiS PCI Audio Accelerator
1786 1025 000e SiS PCI Audio Accelerator
1787 1025 0018 SiS PCI Audio Accelerator
1788 1039 7018 SiS PCI Audio Accelerator
1789 1043 800b SiS PCI Audio Accelerator
1790 1054 7018 SiS PCI Audio Accelerator
1791 107d 5330 SiS PCI Audio Accelerator
1792 107d 5350 SiS PCI Audio Accelerator
1793 1170 3209 SiS PCI Audio Accelerator
1794 1462 400a SiS PCI Audio Accelerator
1795 14a4 2089 SiS PCI Audio Accelerator
1796 14cd 2194 SiS PCI Audio Accelerator
1797 14ff 1100 SiS PCI Audio Accelerator
1798 152d 8808 SiS PCI Audio Accelerator
1799 1558 1103 SiS PCI Audio Accelerator
1800 1558 2200 SiS PCI Audio Accelerator
1801 1563 7018 SiS PCI Audio Accelerator
1802 15c5 0111 SiS PCI Audio Accelerator
1803 270f a171 SiS PCI Audio Accelerator
1804 a0a0 0022 SiS PCI Audio Accelerator
1805 7019 SiS7019 Audio Accelerator
1806103a Seiko Epson Corporation
1807103b Tatung Co. of America
1808103c Hewlett-Packard Company
1809 1005 A4977A Visualize EG
1810 1006 Visualize FX6
1811 1008 Visualize FX4
1812 100a Visualize FX2
1813 1028 Tach TL Fibre Channel Host Adapter
1814 1029 Tach XL2 Fibre Channel Host Adapter
1815 107e 000f Interphase 5560 Fibre Channel Adapter
1816 9004 9210 1Gb/2Gb Family Fibre Channel Controller
1817 9004 9211 1Gb/2Gb Family Fibre Channel Controller
1818 102a Tach TS Fibre Channel Host Adapter
1819 107e 000e Interphase 5540/5541 Fibre Channel Adapter
1820 9004 9110 1Gb/2Gb Family Fibre Channel Controller
1821 9004 9111 1Gb/2Gb Family Fibre Channel Controller
1822 1030 J2585A DeskDirect 10/100VG NIC
1823 1031 J2585B HP 10/100VG PCI LAN Adapter
1824 103c 1040 J2973A DeskDirect 10BaseT NIC
1825 103c 1041 J2585B DeskDirect 10/100VG NIC
1826 103c 1042 J2970A DeskDirect 10BaseT/2 NIC
1827 1040 J2973A DeskDirect 10BaseT NIC
1828 1041 J2585B DeskDirect 10/100 NIC
1829 1042 J2970A DeskDirect 10BaseT/2 NIC
1830 1048 Diva Serial [GSP] Multiport UART
1831 103c 1049 Tosca Console
1832 103c 104a Tosca Secondary
1833 103c 104b Maestro SP2
1834 103c 1223 Superdome Console
1835 103c 1226 Keystone SP2
1836 103c 1227 Powerbar SP2
1837 103c 1282 Everest SP2
1838 103c 1301 Diva RMP3
1839 1054 PCI Local Bus Adapter
1840 1064 79C970 PCnet Ethernet Controller
1841 108b Visualize FXe
1842 10c1 NetServer Smart IRQ Router
1843 10ed TopTools Remote Control
1844 10f0 rio System Bus Adapter
1845 10f1 rio I/O Controller
1846 1200 82557B 10/100 NIC
1847 1219 NetServer PCI Hot-Plug Controller
1848 121a NetServer SMIC Controller
1849 121b NetServer Legacy COM Port Decoder
1850 121c NetServer PCI COM Port Decoder
1851 1229 zx1 System Bus Adapter
1852 122a zx1 I/O Controller
1853 122e zx1 Local Bus Adapter
1854 127c sx1000 I/O Controller
1855 1290 Auxiliary Diva Serial Port
1856 12b4 zx1 QuickSilver AGP8x Local Bus Adapter
1857 2910 E2910A PCIBus Exerciser
1858 2925 E2925A 32 Bit, 33 MHzPCI Exerciser & Analyzer
1859103e Solliday Engineering
1860103f Synopsys/Logic Modeling Group
18611040 Accelgraphics Inc.
18621041 Computrend
18631042 Micron
1864 1000 PC Tech RZ1000
1865 1001 PC Tech RZ1001
1866 3000 Samurai_0
1867 3010 Samurai_1
1868 3020 Samurai_IDE
18691043 ASUSTeK Computer Inc.
1870 0675 ISDNLink P-IN100-ST-D
1871 4015 v7100 SDRAM [GeForce2 MX]
1872 4021 v7100 Combo Deluxe [GeForce2 MX + TV tuner]
1873 4057 v8200 GeForce 3
1874 8043 v8240 PAL 128M [P4T] Motherboard
1875 807b v9280/TD [Geforce4 TI4200 8X With TV-Out and DVI]
1876 80bb v9180 Magic/T [GeForce4 MX440 AGP 8x 64MB TV-out]
1877 80c5 nForce3 chipset motherboard [SK8N]
1878 80df v9520 Magic/T
18791044 Adaptec (formerly DPT)
1880 1012 Domino RAID Engine
1881 a400 SmartCache/Raid I-IV Controller
1882 a500 PCI Bridge
1883 a501 SmartRAID V Controller
1884 1044 c001 PM1554U2 Ultra2 Single Channel
1885 1044 c002 PM1654U2 Ultra2 Single Channel
1886 1044 c003 PM1564U3 Ultra3 Single Channel
1887 1044 c004 PM1564U3 Ultra3 Dual Channel
1888 1044 c005 PM1554U2 Ultra2 Single Channel (NON ACPI)
1889 1044 c00a PM2554U2 Ultra2 Single Channel
1890 1044 c00b PM2654U2 Ultra2 Single Channel
1891 1044 c00c PM2664U3 Ultra3 Single Channel
1892 1044 c00d PM2664U3 Ultra3 Dual Channel
1893 1044 c00e PM2554U2 Ultra2 Single Channel (NON ACPI)
1894 1044 c00f PM2654U2 Ultra2 Single Channel (NON ACPI)
1895 1044 c014 PM3754U2 Ultra2 Single Channel (NON ACPI)
1896 1044 c015 PM3755U2B Ultra2 Single Channel (NON ACPI)
1897 1044 c016 PM3755F Fibre Channel (NON ACPI)
1898 1044 c01e PM3757U2 Ultra2 Single Channel
1899 1044 c01f PM3757U2 Ultra2 Dual Channel
1900 1044 c020 PM3767U3 Ultra3 Dual Channel
1901 1044 c021 PM3767U3 Ultra3 Quad Channel
1902 1044 c028 PM2865U3 Ultra3 Single Channel
1903 1044 c029 PM2865U3 Ultra3 Dual Channel
1904 1044 c02a PM2865F Fibre Channel
1905 1044 c03c 2000S Ultra3 Single Channel
1906 1044 c03d 2000S Ultra3 Dual Channel
1907 1044 c03e 2000F Fibre Channel
1908 1044 c046 3000S Ultra3 Single Channel
1909 1044 c047 3000S Ultra3 Dual Channel
1910 1044 c048 3000F Fibre Channel
1911 1044 c050 5000S Ultra3 Single Channel
1912 1044 c051 5000S Ultra3 Dual Channel
1913 1044 c052 5000F Fibre Channel
1914 1044 c05a 2400A UDMA Four Channel
1915 1044 c05b 2400A UDMA Four Channel DAC
1916 1044 c064 3010S Ultra3 Dual Channel
1917 1044 c065 3410S Ultra160 Four Channel
1918 1044 c066 3010S Fibre Channel
1919 a511 SmartRAID V Controller
1920 1044 c032 ASR-2005S I2O Zero Channel
19211045 OPTi Inc.
1922 a0f8 82C750 [Vendetta] USB Controller
1923 c101 92C264
1924 c178 92C178
1925 c556 82X556 [Viper]
1926 c557 82C557 [Viper-M]
1927 c558 82C558 [Viper-M ISA+IDE]
1928 c567 82C750 [Vendetta], device 0
1929 c568 82C750 [Vendetta], device 1
1930 c569 82C579 [Viper XPress+ Chipset]
1931 c621 82C621 [Viper-M/N+]
1932 c700 82C700 [FireStar]
1933 c701 82C701 [FireStar Plus]
1934 c814 82C814 [Firebridge 1]
1935 c822 82C822
1936 c824 82C824
1937 c825 82C825 [Firebridge 2]
1938 c832 82C832
1939 c861 82C861
1940 c895 82C895
1941 c935 EV1935 ECTIVA MachOne PCIAudio
1942 d568 82C825 [Firebridge 2]
1943 d721 IDE [FireStar]
19441046 IPC Corporation, Ltd.
19451047 Genoa Systems Corp
19461048 Elsa AG
1947 0c60 Gladiac MX
1948 0d22 Quadro4 900XGL [ELSA GLoria4 900XGL]
1949 1000 QuickStep 1000
1950 3000 QuickStep 3000
1951 8901 Gloria XL
19521049 Fountain Technologies, Inc.
1953# # nee SGS Thomson Microelectronics
1954104a STMicroelectronics
1955 0008 STG 2000X
1956 0009 STG 1764X
1957 0010 STG4000 [3D Prophet Kyro Series]
1958 0209 STPC Consumer/Industrial North- and Southbridge
1959 020a STPC Atlas/ConsumerS/Consumer IIA Northbridge
1960# From <http://gatekeeper.dec.com/pub/BSD/FreeBSD/FreeBSD-stable/src/share/misc/pci_vendors>
1961 0210 STPC Atlas ISA Bridge
1962 021a STPC Consumer S Southbridge
1963 021b STPC Consumer IIA Southbridge
1964 0500 ST70137 [Unicorn] ADSL DMT Transceiver
1965 0564 STPC Client Northbridge
1966 0981 21x4x DEC-Tulip compatible 10/100 Ethernet
1967 1746 STG 1764X
1968 2774 21x4x DEC-Tulip compatible 10/100 Ethernet
1969 3520 MPEG-II decoder card
1970 55cc STPC Client Southbridge
1971104b BusLogic
1972 0140 BT-946C (old) [multimaster 01]
1973 1040 BT-946C (BA80C30) [MultiMaster 10]
1974 8130 Flashpoint LT
1975104c Texas Instruments
1976 0500 100 MBit LAN Controller
1977 0508 TMS380C2X Compressor Interface
1978 1000 Eagle i/f AS
1979 104c PCI1510 PC card Cardbus Controller
1980 3d04 TVP4010 [Permedia]
1981 3d07 TVP4020 [Permedia 2]
1982 1011 4d10 Comet
1983 1040 000f AccelStar II
1984 1040 0011 AccelStar II
1985 1048 0a31 WINNER 2000
1986 1048 0a32 GLoria Synergy
1987 1048 0a35 GLoria Synergy
1988 107d 2633 WinFast 3D L2300
1989 1092 0127 FIRE GL 1000 PRO
1990 1092 0136 FIRE GL 1000 PRO
1991 1092 0141 FIRE GL 1000 PRO
1992 1092 0146 FIRE GL 1000 PRO
1993 1092 0148 FIRE GL 1000 PRO
1994 1092 0149 FIRE GL 1000 PRO
1995 1092 0152 FIRE GL 1000 PRO
1996 1092 0154 FIRE GL 1000 PRO
1997 1092 0155 FIRE GL 1000 PRO
1998 1092 0156 FIRE GL 1000 PRO
1999 1092 0157 FIRE GL 1000 PRO
2000 1097 3d01 Jeronimo Pro
2001 1102 100f Graphics Blaster Extreme
2002 3d3d 0100 Reference Permedia 2 3D
2003 8000 PCILynx/PCILynx2 IEEE 1394 Link Layer Controller
2004 e4bf 1010 CF1-1-SNARE
2005 e4bf 1020 CF1-2-SNARE
2006 8009 FireWire Controller
2007 104d 8032 8032 OHCI i.LINK (IEEE 1394) Controller
2008 8017 PCI4410 FireWire Controller
2009 8019 TSB12LV23 IEEE-1394 Controller
2010 11bd 000a Studio DV500-1394
2011 11bd 000e Studio DV
2012 e4bf 1010 CF2-1-CYMBAL
2013 8020 TSB12LV26 IEEE-1394 Controller (Link)
2014 11bd 000f Studio DV500-1394
2015 8021 TSB43AA22 IEEE-1394 Controller (PHY/Link Integrated)
2016 104d 80df Vaio PCG-FX403
2017 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
2018 8022 TSB43AB22 IEEE-1394a-2000 Controller (PHY/Link)
2019 8023 TSB43AB22/A IEEE-1394a-2000 Controller (PHY/Link)
2020 103c 088c nc8000 laptop
2021 8024 TSB43AB23 IEEE-1394a-2000 Controller (PHY/Link)
2022 8025 TSB82AA2 IEEE-1394b Link Layer Controller
2023 55aa 55aa FireWire 800 PCI Card
2024 8026 TSB43AB21 IEEE-1394a-2000 Controller (PHY/Link)
2025 8027 PCI4451 IEEE-1394 Controller
2026 1028 00e6 PCI4451 IEEE-1394 Controller (Dell Inspiron 8100)
2027 8029 PCI4510 IEEE-1394 Controller
2028 1028 0163 Latitude D505
2029 1071 8160 MIM2900
2030 802b PCI7410,7510,7610 OHCI-Lynx Controller
2031 1028 014e PCI7410,7510,7610 OHCI-Lynx Controller (Dell Latitude D800)
2032 802e PCI7x20 1394a-2000 OHCI Two-Port PHY/Link-Layer Controller
2033 8031 Texas Instruments PCIxx21/x515 Cardbus Controller
2034 8032 Texas Instruments OHCI Compliant IEEE 1394 Host Controller
2035 8033 Texas Instruments PCIxx21 Integrated FlashMedia Controller
2036 8034 Texas Instruments PCI6411, PCI6421, PCI6611, PCI6621, PCI7411, PCI7421, PCI7611, PCI7621 Secure Digital (SD) Controller
2037 8035 Texas Instruments PCI6411, PCI6421, PCI6611, PCI6621, PCI7411, PCI7421, PCI7611, PCI7621 Smart Card Controller (SMC)
2038 8201 PCI1620 Firmware Loading Function
2039 8204 PCI7410,7510,7610 PCI Firmware Loading Function
2040 1028 014e Latitude D800
2041 8400 ACX 100 22Mbps Wireless Interface
2042 00fc 16ec U.S. Robotics 22 Mbps Wireless PC Card (model 2210)
2043 00fd 16ec U.S. Robotics 22Mbps Wireless PCI Adapter (model 2216)
2044 1186 3b00 DWL-650+ PC Card cardbus 22Mbs Wireless Adapter [AirPlus]
2045 1186 3b01 DWL-520+ 22Mbps PCI Wireless Adapter
2046 8401 ACX 100 22Mbps Wireless Interface
2047# OK, this info is almost useless as is, but at least it's known that it's a wireless card. More info requested from reporter (whi
2048 9000 Wireless Interface (of unknown type)
2049 9066 ACX 111 54Mbps Wireless Interface
2050 a001 TDC1570
2051 a100 TDC1561
2052 a102 TNETA1575 HyperSAR Plus w/PCI Host i/f & UTOPIA i/f
2053 a106 TMS320C6205 Fixed Point DSP
2054 175c 5000 ASI50xx Audio Adapter
2055 175c 8700 ASI87xx Radio Tuner card
2056 ac10 PCI1050
2057 ac11 PCI1053
2058 ac12 PCI1130
2059 ac13 PCI1031
2060 ac15 PCI1131
2061 ac16 PCI1250
2062 1014 0092 ThinkPad 600
2063 ac17 PCI1220
2064 ac18 PCI1260
2065 ac19 PCI1221
2066 ac1a PCI1210
2067 ac1b PCI1450
2068 0e11 b113 Armada M700
2069 ac1c PCI1225
2070 0e11 b121 Armada E500
2071 1028 0088 Dell Computer Corporation Latitude CPi A400XT
2072 ac1d PCI1251A
2073 ac1e PCI1211
2074 ac1f PCI1251B
2075 ac20 TI 2030
2076 ac21 PCI2031
2077 ac22 PCI2032 PCI Docking Bridge
2078 ac23 PCI2250 PCI-to-PCI Bridge
2079 ac28 PCI2050 PCI-to-PCI Bridge
2080 ac30 PCI1260 PC card Cardbus Controller
2081 ac40 PCI4450 PC card Cardbus Controller
2082 ac41 PCI4410 PC card Cardbus Controller
2083 ac42 PCI4451 PC card Cardbus Controller
2084 1028 00e6 PCI4451 PC card CardBus Controller (Dell Inspiron 8100)
2085 ac44 PCI4510 PC card Cardbus Controller
2086 1028 0163 Latitude D505
2087 1071 8160 MIM2000
2088 ac46 PCI4520 PC card Cardbus Controller
2089 ac47 PCI7510 PC card Cardbus Controller
2090 1028 014e Latitude D800
2091 ac4a PCI7510,7610 PC card Cardbus Controller
2092 1028 014e Latitude D800
2093 ac50 PCI1410 PC card Cardbus Controller
2094 ac51 PCI1420
2095 1014 023b ThinkPad T23 (2647-4MG)
2096 1028 00b1 Latitude C600
2097 1028 012a Latitude C640
2098 1033 80cd Versa Note VXi
2099 10cf 1095 Lifebook C6155
2100 e4bf 1000 CP2-2-HIPHOP
2101 ac52 PCI1451 PC card Cardbus Controller
2102 ac53 PCI1421 PC card Cardbus Controller
2103 ac54 PCI1620 PC Card Controller
2104 ac55 PCI1520 PC card Cardbus Controller
2105 1014 0512 ThinkPad T30/T40
2106 ac56 PCI1510 PC card Cardbus Controller
2107 1014 0528 ThinkPad R40e (2684-HVG) Cardbus Controller
2108 ac60 PCI2040 PCI to DSP Bridge Controller
2109 175c 5100 ASI51xx Audio Adapter
2110 175c 6100 ASI61xx Audio Adapter
2111 175c 6200 ASI62xx Audio Adapter
2112 ac8d PCI 7620
2113 ac8e PCI7420 CardBus Controller
2114 ac8f PCI7420/PCI7620 Dual Socket CardBus and Smart Card Cont. w/ 1394a-2000 OHCI Two-Port PHY/Link-Layer Cont. and SD/MS-Pro Sockets
2115 fe00 FireWire Host Controller
2116 fe03 12C01A FireWire Host Controller
2117104d Sony Corporation
2118 8004 DTL-H2500 [Playstation development board]
2119 8009 CXD1947Q i.LINK Controller
2120 8039 CXD3222 i.LINK Controller
2121 8056 Rockwell HCF 56K modem
2122 808a Memory Stick Controller
2123104e Oak Technology, Inc
2124 0017 OTI-64017
2125 0107 OTI-107 [Spitfire]
2126 0109 Video Adapter
2127 0111 OTI-64111 [Spitfire]
2128 0217 OTI-64217
2129 0317 OTI-64317
2130104f Co-time Computer Ltd
21311050 Winbond Electronics Corp
2132 0000 NE2000
2133 0001 W83769F
2134 0105 W82C105
2135 0840 W89C840
2136 1050 0001 W89C840 Ethernet Adapter
2137 1050 0840 W89C840 Ethernet Adapter
2138 0940 W89C940
2139 5a5a W89C940F
2140 6692 W6692
2141 9921 W99200F MPEG-1 Video Encoder
2142 9922 W99200F/W9922PF MPEG-1/2 Video Encoder
2143 9970 W9970CF
21441051 Anigma, Inc.
21451052 ?Young Micro Systems
21461053 Young Micro Systems
21471054 Hitachi, Ltd
21481055 Efar Microsystems
2149 9130 SLC90E66 [Victory66] IDE
2150 9460 SLC90E66 [Victory66] ISA
2151 9462 SLC90E66 [Victory66] USB
2152 9463 SLC90E66 [Victory66] ACPI
21531056 ICL
2154# Motorola made a mistake and used 1507 instead of 1057 in some chips. Please look at the 1507 entry as well when updating this.
21551057 Motorola
2156 0001 MPC105 [Eagle]
2157 0002 MPC106 [Grackle]
2158 0003 MPC8240 [Kahlua]
2159 0004 MPC107
2160 0006 MPC8245 [Unity]
2161 0008 MPC8540
2162 0009 MPC8560
2163 0100 MC145575 [HFC-PCI]
2164 0431 KTI829c 100VG
2165 1801 DSP56301 Digital Signal Processor
2166 14fb 0101 Transas Radar Imitator Board [RIM]
2167 14fb 0102 Transas Radar Imitator Board [RIM-2]
2168 14fb 0202 Transas Radar Integrator Board [RIB-2]
2169 14fb 0611 1 channel CAN bus Controller [CanPci-1]
2170 14fb 0612 2 channels CAN bus Controller [CanPci-2]
2171 14fb 0613 3 channels CAN bus Controller [CanPci-3]
2172 14fb 0614 4 channels CAN bus Controller [CanPci-4]
2173 14fb 0621 1 channel CAN bus Controller [CanPci2-1]
2174 14fb 0622 2 channels CAN bus Controller [CanPci2-2]
2175 14fb 0810 Transas VTS Radar Integrator Board [RIB-4]
2176 175c 4200 ASI4215 Audio Adapter
2177 175c 4300 ASI43xx Audio Adapter
2178 175c 4400 ASI4401 Audio Adapter
2179 ecc0 0010 Darla
2180 ecc0 0020 Gina
2181 ecc0 0030 Layla rev.0
2182 ecc0 0031 Layla rev.1
2183 ecc0 0040 Darla24 rev.0
2184 ecc0 0041 Darla24 rev.1
2185 ecc0 0050 Gina24 rev.0
2186 ecc0 0051 Gina24 rev.1
2187 ecc0 0070 Mona rev.0
2188 ecc0 0071 Mona rev.1
2189 ecc0 0072 Mona rev.2
2190 18c0 MPC8265A/MPC8266
2191 18c1 MPC8271/MPC8272
2192 3410 DSP56361 Digital Signal Processor
2193 ecc0 0050 Gina24 rev.0
2194 ecc0 0051 Gina24 rev.1
2195 ecc0 0060 Layla24
2196 ecc0 0070 Mona rev.0
2197 ecc0 0071 Mona rev.1
2198 ecc0 0072 Mona rev.2
2199 ecc0 0080 Mia rev.0
2200 ecc0 0081 Mia rev.1
2201 ecc0 0090 Indigo
2202 ecc0 00a0 Indigo IO
2203 ecc0 00b0 Indigo DJ
2204 ecc0 0100 3G
2205 4801 Raven
2206 4802 Falcon
2207 4803 Hawk
2208 4806 CPX8216
2209 4d68 20268
2210 5600 SM56 PCI Modem
2211 1057 0300 SM56 PCI Speakerphone Modem
2212 1057 0301 SM56 PCI Voice Modem
2213 1057 0302 SM56 PCI Fax Modem
2214 1057 5600 SM56 PCI Voice modem
2215 13d2 0300 SM56 PCI Speakerphone Modem
2216 13d2 0301 SM56 PCI Voice modem
2217 13d2 0302 SM56 PCI Fax Modem
2218 1436 0300 SM56 PCI Speakerphone Modem
2219 1436 0301 SM56 PCI Voice modem
2220 1436 0302 SM56 PCI Fax Modem
2221 144f 100c SM56 PCI Fax Modem
2222 1494 0300 SM56 PCI Speakerphone Modem
2223 1494 0301 SM56 PCI Voice modem
2224 14c8 0300 SM56 PCI Speakerphone Modem
2225 14c8 0302 SM56 PCI Fax Modem
2226 1668 0300 SM56 PCI Speakerphone Modem
2227 1668 0302 SM56 PCI Fax Modem
2228 5803 MPC5200
2229 6400 MPC190 Security Processor (S1 family, encryption)
2230 6405 MPC184 Security Processor (S1 family)
22311058 Electronics & Telecommunications RSH
22321059 Teknor Industrial Computers Inc
2233105a Promise Technology, Inc.
2234# more correct description from promise linux sources
2235 0d30 PDC20265 (FastTrak100 Lite/Ultra100)
2236 105a 4d33 Ultra100
2237 0d38 20263
2238 105a 4d39 Fasttrak66
2239 1275 20275
2240 3318 PDC20318 (SATA150 TX4)
2241 3319 PDC20319 (FastTrak S150 TX4)
2242 8086 3427 S875WP1-E mainboard
2243 3371 PDC20371 (FastTrak S150 TX2plus)
2244 3373 PDC20378 (FastTrak 378/SATA 378)
2245 1043 80f5 K8V Deluxe/PC-DL Deluxe motherboard
2246 1462 702e K8T NEO FIS2R motherboard
2247 3375 PDC20375 (SATA150 TX2plus)
2248 3376 PDC20376 (FastTrak 376)
2249 1043 809e A7V8X motherboard
2250 3574 PDC20579 SATAII 150 IDE Controller
2251 3d18 PDC20518/PDC40518 (SATAII 150 TX4)
2252 3d75 PDC20575 (SATAII150 TX2plus)
2253 4d30 PDC20267 (FastTrak100/Ultra100)
2254 105a 4d33 Ultra100
2255 105a 4d39 FastTrak100
2256 4d33 20246
2257 105a 4d33 20246 IDE Controller
2258 4d38 PDC20262 (FastTrak66/Ultra66)
2259 105a 4d30 Ultra Device on SuperTrak
2260 105a 4d33 Ultra66
2261 105a 4d39 FastTrak66
2262 4d68 PDC20268 (Ultra100 TX2)
2263 105a 4d68 Ultra100TX2
2264 4d69 20269
2265 105a 4d68 Ultra133TX2
2266 5275 PDC20276 (MBFastTrak133 Lite)
2267 105a 0275 SuperTrak SX6000 IDE
2268 105a 1275 MBFastTrak133 Lite (tm) Controller (RAID mode)
2269 1458 b001 MBUltra 133
2270 5300 DC5300
2271 6268 PDC20270 (FastTrak100 LP/TX2/TX4)
2272 105a 4d68 FastTrak100 TX2
2273 6269 PDC20271 (FastTrak TX2000)
2274 105a 6269 FastTrak TX2/TX2000
2275 6621 PDC20621 (FastTrak S150 SX4/FastTrak SX4000 lite)
2276 6622 PDC20621 [SATA150 SX4] 4 Channel IDE RAID Controller
2277 6626 PDC20618 (Ultra 618)
2278 6629 PDC20619 (FastTrak TX4000)
2279 7275 PDC20277 (SBFastTrak133 Lite)
2280105b Foxconn International, Inc.
2281105c Wipro Infotech Limited
2282105d Number 9 Computer Company
2283 2309 Imagine 128
2284 2339 Imagine 128-II
2285 105d 0000 Imagine 128 series 2 4Mb VRAM
2286 105d 0001 Imagine 128 series 2 4Mb VRAM
2287 105d 0002 Imagine 128 series 2 4Mb VRAM
2288 105d 0003 Imagine 128 series 2 4Mb VRAM
2289 105d 0004 Imagine 128 series 2 4Mb VRAM
2290 105d 0005 Imagine 128 series 2 4Mb VRAM
2291 105d 0006 Imagine 128 series 2 4Mb VRAM
2292 105d 0007 Imagine 128 series 2 4Mb VRAM
2293 105d 0008 Imagine 128 series 2e 4Mb DRAM
2294 105d 0009 Imagine 128 series 2e 4Mb DRAM
2295 105d 000a Imagine 128 series 2 8Mb VRAM
2296 105d 000b Imagine 128 series 2 8Mb H-VRAM
2297 11a4 000a Barco Metheus 5 Megapixel
2298 13cc 0000 Barco Metheus 5 Megapixel
2299 13cc 0004 Barco Metheus 5 Megapixel
2300 13cc 0005 Barco Metheus 5 Megapixel
2301 13cc 0006 Barco Metheus 5 Megapixel
2302 13cc 0008 Barco Metheus 5 Megapixel
2303 13cc 0009 Barco Metheus 5 Megapixel
2304 13cc 000a Barco Metheus 5 Megapixel
2305 13cc 000c Barco Metheus 5 Megapixel
2306 493d Imagine 128 T2R [Ticket to Ride]
2307 11a4 000a Barco Metheus 5 Megapixel, Dual Head
2308 11a4 000b Barco Metheus 5 Megapixel, Dual Head
2309 13cc 0002 Barco Metheus 4 Megapixel, Dual Head
2310 13cc 0003 Barco Metheus 5 Megapixel, Dual Head
2311 13cc 0007 Barco Metheus 5 Megapixel, Dual Head
2312 13cc 0008 Barco Metheus 5 Megapixel, Dual Head
2313 13cc 0009 Barco Metheus 5 Megapixel, Dual Head
2314 13cc 000a Barco Metheus 5 Megapixel, Dual Head
2315 5348 Revolution 4
2316 105d 0037 Revolution IV-FP AGP (For SGI 1600SW)
2317105e Vtech Computers Ltd
2318105f Infotronic America Inc
23191060 United Microelectronics [UMC]
2320 0001 UM82C881
2321 0002 UM82C886
2322 0101 UM8673F
2323 0881 UM8881
2324 0886 UM8886F
2325 0891 UM8891A
2326 1001 UM886A
2327 673a UM8886BF
2328 673b EIDE Master/DMA
2329 8710 UM8710
2330 886a UM8886A
2331 8881 UM8881F
2332 8886 UM8886F
2333 888a UM8886A
2334 8891 UM8891A
2335 9017 UM9017F
2336 9018 UM9018
2337 9026 UM9026
2338 e881 UM8881N
2339 e886 UM8886N
2340 e88a UM8886N
2341 e891 UM8891N
23421061 I.I.T.
2343 0001 AGX016
2344 0002 IIT3204/3501
23451062 Maspar Computer Corp
23461063 Ocean Office Automation
23471064 Alcatel
23481065 Texas Microsystems
23491066 PicoPower Technology
2350 0000 PT80C826
2351 0001 PT86C521 [Vesuvius v1] Host Bridge
2352 0002 PT86C523 [Vesuvius v3] PCI-ISA Bridge Master
2353 0003 PT86C524 [Nile] PCI-to-PCI Bridge
2354 0004 PT86C525 [Nile-II] PCI-to-PCI Bridge
2355 0005 National PC87550 System Controller
2356 8002 PT86C523 [Vesuvius v3] PCI-ISA Bridge Slave
23571067 Mitsubishi Electric
2358 0301 AccelGraphics AccelECLIPSE
2359 0304 AccelGALAXY A2100 [OEM Evans & Sutherland]
2360 0308 Tornado 3000 [OEM Evans & Sutherland]
2361 1002 VG500 [VolumePro Volume Rendering Accelerator]
23621068 Diversified Technology
23631069 Mylex Corporation
2364 0001 DAC960P
2365 0002 DAC960PD
2366 0010 DAC960PG
2367 0020 DAC960LA
2368 0050 AcceleRAID 352/170/160 support Device
2369 b166 Gemstone chipset SCSI controller
2370 1014 0242 iSeries 2872 DASD IOA
2371 1014 0266 Dual Channel PCI-X U320 SCSI Adapter
2372 1014 0278 Dual Channel PCI-X U320 SCSI RAID Adapter
2373 1014 02d3 Dual Channel PCI-X U320 SCSI Adapter
2374 1014 02d4 Dual Channel PCI-X U320 SCSI RAID Adapter
2375 ba55 eXtremeRAID 1100 support Device
2376 ba56 eXtremeRAID 2000/3000 support Device
2377106a Aten Research Inc
2378106b Apple Computer Inc.
2379 0001 Bandit PowerPC host bridge
2380 0002 Grand Central I/O
2381 0003 Control Video
2382 0004 PlanB Video-In
2383 0007 O'Hare I/O
2384 000c DOS on Mac
2385 000e Hydra Mac I/O
2386 0010 Heathrow Mac I/O
2387 0017 Paddington Mac I/O
2388 0018 UniNorth FireWire
2389 0019 KeyLargo USB
2390 001e UniNorth Internal PCI
2391 001f UniNorth PCI
2392 0020 UniNorth AGP
2393 0021 UniNorth GMAC (Sun GEM)
2394 0022 KeyLargo Mac I/O
2395 0024 UniNorth/Pangea GMAC (Sun GEM)
2396 0025 KeyLargo/Pangea Mac I/O
2397 0026 KeyLargo/Pangea USB
2398 0027 UniNorth/Pangea AGP
2399 0028 UniNorth/Pangea PCI
2400 0029 UniNorth/Pangea Internal PCI
2401 002d UniNorth 1.5 AGP
2402 002e UniNorth 1.5 PCI
2403 002f UniNorth 1.5 Internal PCI
2404 0030 UniNorth/Pangea FireWire
2405 0031 UniNorth 2 FireWire
2406 0032 UniNorth 2 GMAC (Sun GEM)
2407 0033 UniNorth 2 ATA/100
2408 0034 UniNorth 2 AGP
2409 0035 UniNorth 2 PCI
2410 0036 UniNorth 2 Internal PCI
2411 003b UniNorth/Intrepid ATA/100
2412 003e KeyLargo/Intrepid Mac I/O
2413 003f KeyLargo/Intrepid USB
2414 0040 K2 KeyLargo USB
2415 0041 K2 KeyLargo Mac/IO
2416 0042 K2 FireWire
2417 0043 K2 ATA/100
2418 0045 K2 HT-PCI Bridge
2419 0046 K2 HT-PCI Bridge
2420 0047 K2 HT-PCI Bridge
2421 0048 K2 HT-PCI Bridge
2422 0049 K2 HT-PCI Bridge
2423 004b U3 AGP
2424 004c K2 GMAC (Sun GEM)
2425 004f Shasta Mac I/O
2426 0050 Shasta IDE
2427 0051 Shasta (Sun GEM)
2428 0052 Shasta Firewire
2429 0053 Shasta PCI Bridge
2430 0054 Shasta PCI Bridge
2431 0055 Shasta PCI Bridge
2432 0058 U3L AGP Bridge
2433 1645 Tigon3 Gigabit Ethernet NIC (BCM5701)
2434106c Hynix Semiconductor
2435 8801 Dual Pentium ISA/PCI Motherboard
2436 8802 PowerPC ISA/PCI Motherboard
2437 8803 Dual Window Graphics Accelerator
2438 8804 LAN Controller
2439 8805 100-BaseT LAN
2440106d Sequent Computer Systems
2441106e DFI, Inc
2442106f City Gate Development Ltd
24431070 Daewoo Telecom Ltd
24441071 Mitac
2445 8160 Mitac 8060B Mobile Platform
24461072 GIT Co Ltd
24471073 Yamaha Corporation
2448 0001 3D GUI Accelerator
2449 0002 YGV615 [RPA3 3D-Graphics Controller]
2450 0003 YMF-740
2451 0004 YMF-724
2452 1073 0004 YMF724-Based PCI Audio Adapter
2453 0005 DS1 Audio
2454 1073 0005 DS-XG PCI Audio CODEC
2455 0006 DS1 Audio
2456 0008 DS1 Audio
2457 1073 0008 DS-XG PCI Audio CODEC
2458 000a DS1L Audio
2459 1073 0004 DS-XG PCI Audio CODEC
2460 1073 000a DS-XG PCI Audio CODEC
2461 000c YMF-740C [DS-1L Audio Controller]
2462 107a 000c DS-XG PCI Audio CODEC
2463 000d YMF-724F [DS-1 Audio Controller]
2464 1073 000d DS-XG PCI Audio CODEC
2465 0010 YMF-744B [DS-1S Audio Controller]
2466 1073 0006 DS-XG PCI Audio CODEC
2467 1073 0010 DS-XG PCI Audio CODEC
2468 0012 YMF-754 [DS-1E Audio Controller]
2469 1073 0012 DS-XG PCI Audio Codec
2470 0020 DS-1 Audio
2471 2000 DS2416 Digital Mixing Card
2472 1073 2000 DS2416 Digital Mixing Card
24731074 NexGen Microsystems
2474 4e78 82c500/1
24751075 Advanced Integrations Research
24761076 Chaintech Computer Co. Ltd
24771077 QLogic Corp.
2478 1016 ISP10160 Single Channel Ultra3 SCSI Processor
2479 1020 ISP1020 Fast-wide SCSI
2480 1022 ISP1022 Fast-wide SCSI
2481 1080 ISP1080 SCSI Host Adapter
2482 1216 ISP12160 Dual Channel Ultra3 SCSI Processor
2483 101e 8471 QLA12160 on AMI MegaRAID
2484 101e 8493 QLA12160 on AMI MegaRAID
2485 1240 ISP1240 SCSI Host Adapter
2486 1280 ISP1280 SCSI Host Adapter
2487 2020 ISP2020A Fast!SCSI Basic Adapter
2488 2100 QLA2100 64-bit Fibre Channel Adapter
2489 1077 0001 QLA2100 64-bit Fibre Channel Adapter
2490 2200 QLA2200 64-bit Fibre Channel Adapter
2491 1077 0002 QLA2200
2492 2300 QLA2300 64-bit Fibre Channel Adapter
2493 2312 QLA2312 Fibre Channel Adapter
24941078 Cyrix Corporation
2495 0000 5510 [Grappa]
2496 0001 PCI Master
2497 0002 5520 [Cognac]
2498 0100 5530 Legacy [Kahlua]
2499 0101 5530 SMI [Kahlua]
2500 0102 5530 IDE [Kahlua]
2501 0103 5530 Audio [Kahlua]
2502 0104 5530 Video [Kahlua]
2503 0400 ZFMicro PCI Bridge
2504 0401 ZFMicro Chipset SMI
2505 0402 ZFMicro Chipset IDE
2506 0403 ZFMicro Expansion Bus
25071079 I-Bus
2508107a NetWorth
2509107b Gateway 2000
2510107c LG Electronics [Lucky Goldstar Co. Ltd]
2511107d LeadTek Research Inc.
2512 0000 P86C850
2513 2134 WinFast 3D S320 II
2514 2971 [GeForce FX 5900] WinFast A350 TDH MyViVo
2515107e Interphase Corporation
2516 0001 5515 ATM Adapter [Flipper]
2517 0002 100 VG AnyLan Controller
2518 0004 5526 Fibre Channel Host Adapter
2519 0005 x526 Fibre Channel Host Adapter
2520 0008 5525/5575 ATM Adapter (155 Mbit) [Atlantic]
2521 9003 5535-4P-BRI-ST
2522 9007 5535-4P-BRI-U
2523 9008 5535-1P-SR
2524 900c 5535-1P-SR-ST
2525 900e 5535-1P-SR-U
2526 9011 5535-1P-PRI
2527 9013 5535-2P-PRI
2528 9023 5536-4P-BRI-ST
2529 9027 5536-4P-BRI-U
2530 9031 5536-1P-PRI
2531 9033 5536-2P-PRI
2532107f Data Technology Corporation
2533 0802 SL82C105
25341080 Contaq Microsystems
2535 0600 82C599
2536 c691 Cypress CY82C691
2537 c693 82c693
25381081 Supermac Technology
2539 0d47 Radius PCI to NuBUS Bridge
25401082 EFA Corporation of America
25411083 Forex Computer Corporation
2542 0001 FR710
25431084 Parador
25441085 Tulip Computers Int.B.V.
25451086 J. Bond Computer Systems
25461087 Cache Computer
25471088 Microcomputer Systems (M) Son
25481089 Data General Corporation
2549# Formerly Bit3 Computer Corp.
2550108a SBS Technologies
2551 0001 VME Bridge Model 617
2552 0010 VME Bridge Model 618
2553 0040 dataBLIZZARD
2554 3000 VME Bridge Model 2706
2555108c Oakleigh Systems Inc.
2556108d Olicom
2557 0001 Token-Ring 16/4 PCI Adapter (3136/3137)
2558 0002 16/4 Token Ring
2559 0004 RapidFire 3139 Token-Ring 16/4 PCI Adapter
2560 108d 0004 OC-3139/3140 RapidFire Token-Ring 16/4 Adapter
2561 0005 GoCard 3250 Token-Ring 16/4 CardBus PC Card
2562 0006 OC-3530 RapidFire Token-Ring 100
2563 0007 RapidFire 3141 Token-Ring 16/4 PCI Fiber Adapter
2564 108d 0007 OC-3141 RapidFire Token-Ring 16/4 Adapter
2565 0008 RapidFire 3540 HSTR 100/16/4 PCI Adapter
2566 108d 0008 OC-3540 RapidFire HSTR 100/16/4 Adapter
2567 0011 OC-2315
2568 0012 OC-2325
2569 0013 OC-2183/2185
2570 0014 OC-2326
2571 0019 OC-2327/2250 10/100 Ethernet Adapter
2572 108d 0016 OC-2327 Rapidfire 10/100 Ethernet Adapter
2573 108d 0017 OC-2250 GoCard 10/100 Ethernet Adapter
2574 0021 OC-6151/6152 [RapidFire ATM 155]
2575 0022 ATM Adapter
2576108e Sun Microsystems Computer Corp.
2577 0001 EBUS
2578 1000 EBUS
2579 1001 Happy Meal
2580 1100 RIO EBUS
2581 1101 RIO GEM
2582 1102 RIO 1394
2583 1103 RIO USB
2584 1648 [bge] Gigabit Ethernet
2585 2bad GEM
2586 5000 Simba Advanced PCI Bridge
2587 5043 SunPCI Co-processor
2588 8000 Psycho PCI Bus Module
2589 8001 Schizo PCI Bus Module
2590 8002 Schizo+ PCI Bus Module
2591 a000 Ultra IIi
2592 a001 Ultra IIe
2593 a801 Tomatillo PCI Bus Module
2594 abba Cassini 10/100/1000
2595108f Systemsoft
25961090 Encore Computer Corporation
25971091 Intergraph Corporation
2598 0020 3D graphics processor
2599 0021 3D graphics processor w/Texturing
2600 0040 3D graphics frame buffer
2601 0041 3D graphics frame buffer
2602 0060 Proprietary bus bridge
2603 00e4 Powerstorm 4D50T
2604 0720 Motion JPEG codec
2605 07a0 Sun Expert3D-Lite Graphics Accelerator
2606 1091 Sun Expert3D Graphics Accelerator
26071092 Diamond Multimedia Systems
2608 00a0 Speedstar Pro SE
2609 00a8 Speedstar 64
2610 0550 Viper V550
2611 08d4 Supra 2260 Modem
2612 094c SupraExpress 56i Pro
2613 1092 Viper V330
2614 6120 Maximum DVD
2615 8810 Stealth SE
2616 8811 Stealth 64/SE
2617 8880 Stealth
2618 8881 Stealth
2619 88b0 Stealth 64
2620 88b1 Stealth 64
2621 88c0 Stealth 64
2622 88c1 Stealth 64
2623 88d0 Stealth 64
2624 88d1 Stealth 64
2625 88f0 Stealth 64
2626 88f1 Stealth 64
2627 9999 DMD-I0928-1 "Monster sound" sound chip
26281093 National Instruments
2629 0160 PCI-DIO-96
2630 0162 PCI-MIO-16XE-50
2631 1170 PCI-MIO-16XE-10
2632 1180 PCI-MIO-16E-1
2633 1190 PCI-MIO-16E-4
2634 1310 PCI-6602
2635 1330 PCI-6031E
2636 1350 PCI-6071E
2637 14e0 PCI-6110
2638 14f0 PCI-6111
2639 17d0 PCI-6503
2640 1870 PCI-6713
2641 1880 PCI-6711
2642 18b0 PCI-6052E
2643 2410 PCI-6733
2644 2890 PCI-6036E
2645 2a60 PCI-6023E
2646 2a70 PCI-6024E
2647 2a80 PCI-6025E
2648 2c80 PCI-6035E
2649 2ca0 PCI-6034E
2650 70b8 PCI-6251 [M Series - High Speed Multifunction DAQ]
2651 b001 IMAQ-PCI-1408
2652 b011 IMAQ-PXI-1408
2653 b021 IMAQ-PCI-1424
2654 b031 IMAQ-PCI-1413
2655 b041 IMAQ-PCI-1407
2656 b051 IMAQ-PXI-1407
2657 b061 IMAQ-PCI-1411
2658 b071 IMAQ-PCI-1422
2659 b081 IMAQ-PXI-1422
2660 b091 IMAQ-PXI-1411
2661 c801 PCI-GPIB
2662 c831 PCI-GPIB bridge
26631094 First International Computers [FIC]
26641095 Silicon Image, Inc. (formerly CMD Technology Inc)
2665 0240 Adaptec AAR-1210SA SATA HostRAID Controller
2666 0640 PCI0640
2667 0643 PCI0643
2668 0646 PCI0646
2669 0647 PCI0647
2670 0648 PCI0648
2671 0649 SiI 0649 Ultra ATA/100 PCI to ATA Host Controller
2672 0e11 005d Integrated Ultra ATA-100 Dual Channel Controller
2673 0e11 007e Integrated Ultra ATA-100 IDE RAID Controller
2674 101e 0649 AMI MegaRAID IDE 100 Controller
2675 0650 PBC0650A
2676 0670 USB0670
2677 1095 0670 USB0670
2678 0673 USB0673
2679 0680 PCI0680 Ultra ATA-133 Host Controller
2680 1095 3680 Winic W-680 (Silicon Image 680 based)
2681 3112 SiI 3112 [SATALink/SATARaid] Serial ATA Controller
2682 1095 3112 SiI 3112 SATALink Controller
2683 1095 6112 SiI 3112 SATARaid Controller
2684 3114 SiI 3114 [SATALink/SATARaid] Serial ATA Controller
2685 1095 3114 SiI 3114 SATALink Controller
2686 1095 6114 SiI 3114 SATARaid Controller
2687 3124 SiI 3124 PCI-X Serial ATA Controller
2688 1095 3124 SiI 3124 PCI-X Serial ATA Controller
2689 3512 SiI 3512 [SATALink/SATARaid] Serial ATA Controller
2690 1095 3512 SiI 3512 SATALink Controller
2691 1095 6512 SiI 3512 SATARaid Controller
26921096 Alacron
26931097 Appian Technology
26941098 Quantum Designs (H.K.) Ltd
2695 0001 QD-8500
2696 0002 QD-8580
26971099 Samsung Electronics Co., Ltd
2698109a Packard Bell
2699109b Gemlight Computer Ltd.
2700109c Megachips Corporation
2701109d Zida Technologies Ltd.
2702109e Brooktree Corporation
2703 0350 Bt848 Video Capture
2704 0351 Bt849A Video capture
2705 0369 Bt878 Video Capture
2706 1002 0001 TV-Wonder
2707 1002 0003 TV-Wonder/VE
2708 036c Bt879(??) Video Capture
2709 13e9 0070 Win/TV (Video Section)
2710 036e Bt878 Video Capture
2711 0070 13eb WinTV Series
2712 0070 ff01 Viewcast Osprey 200
2713 0071 0101 DigiTV PCI
2714 107d 6606 WinFast TV 2000
2715 11bd 0012 PCTV pro (TV + FM stereo receiver)
2716 11bd 001c PCTV Sat (DBC receiver)
2717 127a 0001 Bt878 Mediastream Controller NTSC
2718 127a 0002 Bt878 Mediastream Controller PAL BG
2719 127a 0003 Bt878a Mediastream Controller PAL BG
2720 127a 0048 Bt878/832 Mediastream Controller
2721 144f 3000 MagicTView CPH060 - Video
2722 1461 0002 TV98 Series (TV/No FM/Remote)
2723 1461 0003 AverMedia UltraTV PCI 350
2724 1461 0004 AVerTV WDM Video Capture
2725 1461 0761 AverTV DVB-T
2726 14f1 0001 Bt878 Mediastream Controller NTSC
2727 14f1 0002 Bt878 Mediastream Controller PAL BG
2728 14f1 0003 Bt878a Mediastream Controller PAL BG
2729 14f1 0048 Bt878/832 Mediastream Controller
2730 1822 0001 VisionPlus DVB card
2731 1851 1850 FlyVideo'98 - Video
2732 1851 1851 FlyVideo II
2733 1852 1852 FlyVideo'98 - Video (with FM Tuner)
2734 270f fc00 Digitop DTT-1000
2735 bd11 1200 PCTV pro (TV + FM stereo receiver)
2736 036f Bt879 Video Capture
2737 127a 0044 Bt879 Video Capture NTSC
2738 127a 0122 Bt879 Video Capture PAL I
2739 127a 0144 Bt879 Video Capture NTSC
2740 127a 0222 Bt879 Video Capture PAL BG
2741 127a 0244 Bt879a Video Capture NTSC
2742 127a 0322 Bt879 Video Capture NTSC
2743 127a 0422 Bt879 Video Capture NTSC
2744 127a 1122 Bt879 Video Capture PAL I
2745 127a 1222 Bt879 Video Capture PAL BG
2746 127a 1322 Bt879 Video Capture NTSC
2747 127a 1522 Bt879a Video Capture PAL I
2748 127a 1622 Bt879a Video Capture PAL BG
2749 127a 1722 Bt879a Video Capture NTSC
2750 14f1 0044 Bt879 Video Capture NTSC
2751 14f1 0122 Bt879 Video Capture PAL I
2752 14f1 0144 Bt879 Video Capture NTSC
2753 14f1 0222 Bt879 Video Capture PAL BG
2754 14f1 0244 Bt879a Video Capture NTSC
2755 14f1 0322 Bt879 Video Capture NTSC
2756 14f1 0422 Bt879 Video Capture NTSC
2757 14f1 1122 Bt879 Video Capture PAL I
2758 14f1 1222 Bt879 Video Capture PAL BG
2759 14f1 1322 Bt879 Video Capture NTSC
2760 14f1 1522 Bt879a Video Capture PAL I
2761 14f1 1622 Bt879a Video Capture PAL BG
2762 14f1 1722 Bt879a Video Capture NTSC
2763 1851 1850 FlyVideo'98 - Video
2764 1851 1851 FlyVideo II
2765 1852 1852 FlyVideo'98 - Video (with FM Tuner)
2766 0370 Bt880 Video Capture
2767 1851 1850 FlyVideo'98
2768 1851 1851 FlyVideo'98 EZ - video
2769 1852 1852 FlyVideo'98 (with FM Tuner)
2770 0878 Bt878 Audio Capture
2771 0070 13eb WinTV Series
2772 0070 ff01 Viewcast Osprey 200
2773 0071 0101 DigiTV PCI
2774 1002 0001 TV-Wonder
2775 1002 0003 TV-Wonder/VE
2776 11bd 0012 PCTV pro (TV + FM stereo receiver, audio section)
2777 11bd 001c PCTV Sat (DBC receiver)
2778 127a 0001 Bt878 Video Capture (Audio Section)
2779 127a 0002 Bt878 Video Capture (Audio Section)
2780 127a 0003 Bt878 Video Capture (Audio Section)
2781 127a 0048 Bt878 Video Capture (Audio Section)
2782 13e9 0070 Win/TV (Audio Section)
2783 144f 3000 MagicTView CPH060 - Audio
2784 1461 0004 AVerTV WDM Audio Capture
2785 1461 0761 AVerTV DVB-T
2786 14f1 0001 Bt878 Video Capture (Audio Section)
2787 14f1 0002 Bt878 Video Capture (Audio Section)
2788 14f1 0003 Bt878 Video Capture (Audio Section)
2789 14f1 0048 Bt878 Video Capture (Audio Section)
2790 1822 0001 VisionPlus DVB Card
2791 270f fc00 Digitop DTT-1000
2792 bd11 1200 PCTV pro (TV + FM stereo receiver, audio section)
2793 0879 Bt879 Audio Capture
2794 127a 0044 Bt879 Video Capture (Audio Section)
2795 127a 0122 Bt879 Video Capture (Audio Section)
2796 127a 0144 Bt879 Video Capture (Audio Section)
2797 127a 0222 Bt879 Video Capture (Audio Section)
2798 127a 0244 Bt879 Video Capture (Audio Section)
2799 127a 0322 Bt879 Video Capture (Audio Section)
2800 127a 0422 Bt879 Video Capture (Audio Section)
2801 127a 1122 Bt879 Video Capture (Audio Section)
2802 127a 1222 Bt879 Video Capture (Audio Section)
2803 127a 1322 Bt879 Video Capture (Audio Section)
2804 127a 1522 Bt879 Video Capture (Audio Section)
2805 127a 1622 Bt879 Video Capture (Audio Section)
2806 127a 1722 Bt879 Video Capture (Audio Section)
2807 14f1 0044 Bt879 Video Capture (Audio Section)
2808 14f1 0122 Bt879 Video Capture (Audio Section)
2809 14f1 0144 Bt879 Video Capture (Audio Section)
2810 14f1 0222 Bt879 Video Capture (Audio Section)
2811 14f1 0244 Bt879 Video Capture (Audio Section)
2812 14f1 0322 Bt879 Video Capture (Audio Section)
2813 14f1 0422 Bt879 Video Capture (Audio Section)
2814 14f1 1122 Bt879 Video Capture (Audio Section)
2815 14f1 1222 Bt879 Video Capture (Audio Section)
2816 14f1 1322 Bt879 Video Capture (Audio Section)
2817 14f1 1522 Bt879 Video Capture (Audio Section)
2818 14f1 1622 Bt879 Video Capture (Audio Section)
2819 14f1 1722 Bt879 Video Capture (Audio Section)
2820 0880 Bt880 Audio Capture
2821 2115 BtV 2115 Mediastream controller
2822 2125 BtV 2125 Mediastream controller
2823 2164 BtV 2164
2824 2165 BtV 2165
2825 8230 Bt8230 ATM Segment/Reassembly Ctrlr (SRC)
2826 8472 Bt8472
2827 8474 Bt8474
2828109f Trigem Computer Inc.
282910a0 Meidensha Corporation
283010a1 Juko Electronics Ind. Co. Ltd
283110a2 Quantum Corporation
283210a3 Everex Systems Inc
283310a4 Globe Manufacturing Sales
283410a5 Smart Link Ltd.
2835 3052 SmartPCI562 56K Modem
2836 5449 SmartPCI561 modem
283710a6 Informtech Industrial Ltd.
283810a7 Benchmarq Microelectronics
283910a8 Sierra Semiconductor
2840 0000 STB Horizon 64
284110a9 Silicon Graphics, Inc.
2842 0001 Crosstalk to PCI Bridge
2843 0002 Linc I/O controller
2844 0003 IOC3 I/O controller
2845 0004 O2 MACE
2846 0005 RAD Audio
2847 0006 HPCEX
2848 0007 RPCEX
2849 0008 DiVO VIP
2850 0009 AceNIC Gigabit Ethernet
2851 10a9 8002 AceNIC Gigabit Ethernet
2852 0010 AMP Video I/O
2853 0011 GRIP
2854 0012 SGH PSHAC GSN
2855 1001 Magic Carpet
2856 1002 Lithium
2857 1003 Dual JPEG 1
2858 1004 Dual JPEG 2
2859 1005 Dual JPEG 3
2860 1006 Dual JPEG 4
2861 1007 Dual JPEG 5
2862 1008 Cesium
2863 100a IOC4 I/O controller
2864 2001 Fibre Channel
2865 2002 ASDE
2866 8001 O2 1394
2867 8002 G-net NT
286810aa ACC Microelectronics
2869 0000 ACCM 2188
287010ab Digicom
287110ac Honeywell IAC
287210ad Symphony Labs
2873 0001 W83769F
2874 0003 SL82C103
2875 0005 SL82C105
2876 0103 SL82c103
2877 0105 SL82c105
2878 0565 W83C553
287910ae Cornerstone Technology
288010af Micro Computer Systems Inc
288110b0 CardExpert Technology
288210b1 Cabletron Systems Inc
288310b2 Raytheon Company
288410b3 Databook Inc
2885 3106 DB87144
2886 b106 DB87144
288710b4 STB Systems Inc
2888 1b1d Velocity 128 3D
2889 10b4 237e Velocity 4400
289010b5 PLX Technology, Inc.
2891 0001 i960 PCI bus interface
2892 1076 VScom 800 8 port serial adaptor
2893 1077 VScom 400 4 port serial adaptor
2894 1078 VScom 210 2 port serial and 1 port parallel adaptor
2895 1103 VScom 200 2 port serial adaptor
2896 1146 VScom 010 1 port parallel adaptor
2897 1147 VScom 020 2 port parallel adaptor
2898 2724 Thales PCSM Security Card
2899 8516 PEX 8516 Versatile PCI Express Switch
2900 8532 PEX 8532 Versatile PCI Express Switch
2901 9030 PCI <-> IOBus Bridge Hot Swap
2902 10b5 2862 Alpermann+Velte PCL PCI LV (3V/5V): Timecode Reader Board
2903 10b5 2906 Alpermann+Velte PCI TS (3V/5V): Time Synchronisation Board
2904 10b5 2940 Alpermann+Velte PCL PCI D (3V/5V): Timecode Reader Board
2905 10b5 3025 Alpermann+Velte PCL PCI L (3V/5V): Timecode Reader Board
2906 10b5 3068 Alpermann+Velte PCL PCI HD (3V/5V): Timecode Reader Board
2907 15ed 1002 MCCS 8-port Serial Hot Swap
2908 15ed 1003 MCCS 16-port Serial Hot Swap
2909 9036 9036
2910 9050 PCI <-> IOBus Bridge
2911 10b5 1067 IXXAT CAN i165
2912 10b5 1172 IK220 (Heidenhain)
2913 10b5 2036 SatPak GPS
2914 10b5 2221 Alpermann+Velte PCL PCI LV: Timecode Reader Board
2915 10b5 2273 SH-ARC SoHard ARCnet card
2916 10b5 2431 Alpermann+Velte PCL PCI D: Timecode Reader Board
2917 10b5 2905 Alpermann+Velte PCI TS: Time Synchronisation Board
2918 10b5 9050 MP9050
2919 1498 0362 TPMC866 8 Channel Serial Card
2920 1522 0001 RockForce 4 Port V.90 Data/Fax/Voice Modem
2921 1522 0002 RockForce 2 Port V.90 Data/Fax/Voice Modem
2922 1522 0003 RockForce 6 Port V.90 Data/Fax/Voice Modem
2923 1522 0004 RockForce 8 Port V.90 Data/Fax/Voice Modem
2924 1522 0010 RockForce2000 4 Port V.90 Data/Fax/Voice Modem
2925 1522 0020 RockForce2000 2 Port V.90 Data/Fax/Voice Modem
2926 15ed 1000 Macrolink MCCS 8-port Serial
2927 15ed 1001 Macrolink MCCS 16-port Serial
2928 15ed 1002 Macrolink MCCS 8-port Serial Hot Swap
2929 15ed 1003 Macrolink MCCS 16-port Serial Hot Swap
2930# Sorry, there was a typo
2931 5654 2036 OpenSwitch 6 Telephony card
2932# Sorry, there was a typo
2933 5654 3132 OpenSwitch 12 Telephony card
2934 5654 5634 OpenLine4 Telephony Card
2935 d531 c002 PCIntelliCAN 2xSJA1000 CAN bus
2936 d84d 4006 EX-4006 1P
2937 d84d 4008 EX-4008 1P EPP/ECP
2938 d84d 4014 EX-4014 2P
2939 d84d 4018 EX-4018 3P EPP/ECP
2940 d84d 4025 EX-4025 1S(16C550) RS-232
2941 d84d 4027 EX-4027 1S(16C650) RS-232
2942 d84d 4028 EX-4028 1S(16C850) RS-232
2943 d84d 4036 EX-4036 2S(16C650) RS-232
2944 d84d 4037 EX-4037 2S(16C650) RS-232
2945 d84d 4038 EX-4038 2S(16C850) RS-232
2946 d84d 4052 EX-4052 1S(16C550) RS-422/485
2947 d84d 4053 EX-4053 2S(16C550) RS-422/485
2948 d84d 4055 EX-4055 4S(16C550) RS-232
2949 d84d 4058 EX-4055 4S(16C650) RS-232
2950 d84d 4065 EX-4065 8S(16C550) RS-232
2951 d84d 4068 EX-4068 8S(16C650) RS-232
2952 d84d 4078 EX-4078 2S(16C552) RS-232+1P
2953 9054 PCI <-> IOBus Bridge
2954 10b5 2455 Wessex Techology PHIL-PCI
2955 10b5 2696 Innes Corp AM Radcap card
2956 10b5 2717 Innes Corp Auricon card
2957 10b5 2844 Innes Corp TVS Encoder card
2958 12d9 0002 PCI Prosody Card rev 1.5
2959 16df 0011 PIKA PrimeNet MM PCI
2960 16df 0012 PIKA PrimeNet MM cPCI 8
2961 16df 0013 PIKA PrimeNet MM cPCI 8 (without CAS Signaling Option)
2962 16df 0014 PIKA PrimeNet MM cPCI 4
2963 16df 0015 PIKA Daytona MM
2964 16df 0016 PIKA InLine MM
2965 9056 Francois
2966 10b5 2979 CellinkBlade 11 - CPCI board VoATM AAL1
2967 9060 9060
2968 906d 9060SD
2969 125c 0640 Aries 16000P
2970 906e 9060ES
2971 9080 9080
2972 103c 10eb (Agilent) E2777B 83K Series PCI based Optical Communication Interface
2973 103c 10ec (Agilent) E6978-66442 PCI CIC
2974 10b5 9080 9080 [real subsystem ID not set]
2975 129d 0002 Aculab PCI Prosidy card
2976 12d9 0002 PCI Prosody Card
2977 12df 4422 4422PCI ["Do-All" Telemetry Data Aquisition System]
2978 bb04 B&B 3PCIOSD1A Isolated PCI Serial
297910b6 Madge Networks
2980 0001 Smart 16/4 PCI Ringnode
2981 0002 Smart 16/4 PCI Ringnode Mk2
2982 10b6 0002 Smart 16/4 PCI Ringnode Mk2
2983 10b6 0006 16/4 CardBus Adapter
2984 0003 Smart 16/4 PCI Ringnode Mk3
2985 0e11 b0fd Compaq NC4621 PCI, 4/16, WOL
2986 10b6 0003 Smart 16/4 PCI Ringnode Mk3
2987 10b6 0007 Presto PCI Plus Adapter
2988 0004 Smart 16/4 PCI Ringnode Mk1
2989 0006 16/4 Cardbus Adapter
2990 10b6 0006 16/4 CardBus Adapter
2991 0007 Presto PCI Adapter
2992 10b6 0007 Presto PCI
2993 0009 Smart 100/16/4 PCI-HS Ringnode
2994 10b6 0009 Smart 100/16/4 PCI-HS Ringnode
2995 000a Smart 100/16/4 PCI Ringnode
2996 10b6 000a Smart 100/16/4 PCI Ringnode
2997 000b 16/4 CardBus Adapter Mk2
2998 10b6 0008 16/4 CardBus Adapter Mk2
2999 10b6 000b 16/4 Cardbus Adapter Mk2
3000 000c RapidFire 3140V2 16/4 TR Adapter
3001 10b6 000c RapidFire 3140V2 16/4 TR Adapter
3002 1000 Collage 25/155 ATM Client Adapter
3003 1001 Collage 155 ATM Server Adapter
300410b7 3Com Corporation
3005 0001 3c985 1000BaseSX (SX/TX)
3006 0013 AR5212 802.11abg NIC (3CRDAG675)
3007 10b7 2031 3CRDAG675 11a/b/g Wireless PCI Adapter
3008 0910 3C910-A01
3009 1006 MINI PCI type 3B Data Fax Modem
3010 1007 Mini PCI 56k Winmodem
3011 10b7 615c Mini PCI 56K Modem
3012 1201 3c982-TXM 10/100baseTX Dual Port A [Hydra]
3013 1202 3c982-TXM 10/100baseTX Dual Port B [Hydra]
3014 1700 3c940 10/100/1000Base-T [Marvell]
3015 1043 80eb P4P800/K8V Deluxe motherboard
3016 10b7 0010 3C940 Gigabit LOM Ethernet Adapter
3017 10b7 0020 3C941 Gigabit LOM Ethernet Adapter
3018 147b 1407 KV8-MAX3 motherboard
3019 3390 3c339 TokenLink Velocity
3020 3590 3c359 TokenLink Velocity XL
3021 10b7 3590 TokenLink Velocity XL Adapter (3C359/359B)
3022 4500 3c450 HomePNA [Tornado]
3023 5055 3c555 Laptop Hurricane
3024 5057 3c575 Megahertz 10/100 LAN CardBus [Boomerang]
3025 10b7 5a57 3C575 Megahertz 10/100 LAN Cardbus PC Card
3026 5157 3cCFE575BT Megahertz 10/100 LAN CardBus [Cyclone]
3027 10b7 5b57 3C575 Megahertz 10/100 LAN Cardbus PC Card
3028 5257 3cCFE575CT CardBus [Cyclone]
3029 10b7 5c57 FE575C-3Com 10/100 LAN CardBus-Fast Ethernet
3030 5900 3c590 10BaseT [Vortex]
3031 5920 3c592 EISA 10mbps Demon/Vortex
3032 5950 3c595 100BaseTX [Vortex]
3033 5951 3c595 100BaseT4 [Vortex]
3034 5952 3c595 100Base-MII [Vortex]
3035 5970 3c597 EISA Fast Demon/Vortex
3036 5b57 3c595 Megahertz 10/100 LAN CardBus [Boomerang]
3037 10b7 5b57 3C575 Megahertz 10/100 LAN Cardbus PC Card
3038 6000 3CRSHPW796 [OfficeConnect Wireless CardBus]
3039 6001 3com 3CRWE154G72 [Office Connect Wireless LAN Adapter]
3040 6055 3c556 Hurricane CardBus [Cyclone]
3041 6056 3c556B CardBus [Tornado]
3042 10b7 6556 10/100 Mini PCI Ethernet Adapter
3043 6560 3cCFE656 CardBus [Cyclone]
3044 10b7 656a 3CCFEM656 10/100 LAN+56K Modem CardBus
3045 6561 3cCFEM656 10/100 LAN+56K Modem CardBus
3046 10b7 656b 3CCFEM656 10/100 LAN+56K Modem CardBus
3047 6562 3cCFEM656B 10/100 LAN+Winmodem CardBus [Cyclone]
3048 10b7 656b 3CCFEM656B 10/100 LAN+56K Modem CardBus
3049 6563 3cCFEM656B 10/100 LAN+56K Modem CardBus
3050 10b7 656b 3CCFEM656 10/100 LAN+56K Modem CardBus
3051 6564 3cXFEM656C 10/100 LAN+Winmodem CardBus [Tornado]
3052 7646 3cSOHO100-TX Hurricane
3053 7770 3CRWE777 PCI(PLX) Wireless Adaptor [Airconnect]
3054 7940 3c803 FDDILink UTP Controller
3055 7980 3c804 FDDILink SAS Controller
3056 7990 3c805 FDDILink DAS Controller
3057 80eb 3c940B 10/100/1000Base-T
3058 8811 Token ring
3059 9000 3c900 10BaseT [Boomerang]
3060 9001 3c900 10Mbps Combo [Boomerang]
3061 9004 3c900B-TPO Etherlink XL [Cyclone]
3062 10b7 9004 3C900B-TPO Etherlink XL TPO 10Mb
3063 9005 3c900B-Combo Etherlink XL [Cyclone]
3064 10b7 9005 3C900B-Combo Etherlink XL Combo
3065 9006 3c900B-TPC Etherlink XL [Cyclone]
3066 900a 3c900B-FL 10base-FL [Cyclone]
3067 9050 3c905 100BaseTX [Boomerang]
3068 9051 3c905 100BaseT4 [Boomerang]
3069 9055 3c905B 100BaseTX [Cyclone]
3070 1028 0080 3C905B Fast Etherlink XL 10/100
3071 1028 0081 3C905B Fast Etherlink XL 10/100
3072 1028 0082 3C905B Fast Etherlink XL 10/100
3073 1028 0083 3C905B Fast Etherlink XL 10/100
3074 1028 0084 3C905B Fast Etherlink XL 10/100
3075 1028 0085 3C905B Fast Etherlink XL 10/100
3076 1028 0086 3C905B Fast Etherlink XL 10/100
3077 1028 0087 3C905B Fast Etherlink XL 10/100
3078 1028 0088 3C905B Fast Etherlink XL 10/100
3079 1028 0089 3C905B Fast Etherlink XL 10/100
3080 1028 0090 3C905B Fast Etherlink XL 10/100
3081 1028 0091 3C905B Fast Etherlink XL 10/100
3082 1028 0092 3C905B Fast Etherlink XL 10/100
3083 1028 0093 3C905B Fast Etherlink XL 10/100
3084 1028 0094 3C905B Fast Etherlink XL 10/100
3085 1028 0095 3C905B Fast Etherlink XL 10/100
3086 1028 0096 3C905B Fast Etherlink XL 10/100
3087 1028 0097 3C905B Fast Etherlink XL 10/100
3088 1028 0098 3C905B Fast Etherlink XL 10/100
3089 1028 0099 3C905B Fast Etherlink XL 10/100
3090 10b7 9055 3C905B Fast Etherlink XL 10/100
3091 9056 3c905B-T4 Fast EtherLink XL [Cyclone]
3092 9058 3c905B Deluxe Etherlink 10/100/BNC [Cyclone]
3093 905a 3c905B-FX Fast Etherlink XL FX 100baseFx [Cyclone]
3094 9200 3c905C-TX/TX-M [Tornado]
3095 1028 0095 3C920 Integrated Fast Ethernet Controller
3096 1028 0097 3C920 Integrated Fast Ethernet Controller
3097 1028 00fe Optiplex GX240
3098 1028 012a 3C920 Integrated Fast Ethernet Controller [Latitude C640]
3099 10b7 1000 3C905C-TX Fast Etherlink for PC Management NIC
3100 10b7 7000 10/100 Mini PCI Ethernet Adapter
3101 10f1 2466 Tiger MPX S2466 (3C920 Integrated Fast Ethernet Controller)
3102 9201 3C920B-EMB Integrated Fast Ethernet Controller [Tornado]
3103 1043 80ab A7N8X Deluxe onboard 3C920B-EMB Integrated Fast Ethernet Controller
3104 9202 3Com 3C920B-EMB-WNM Integrated Fast Ethernet Controller
3105 9210 3C920B-EMB-WNM Integrated Fast Ethernet Controller
3106 9300 3CSOHO100B-TX 910-A01 [tulip]
3107 9800 3c980-TX Fast Etherlink XL Server Adapter [Cyclone]
3108 10b7 9800 3c980-TX Fast Etherlink XL Server Adapter
3109 9805 3c980-C 10/100baseTX NIC [Python-T]
3110 10b7 1201 EtherLink Server 10/100 Dual Port A
3111 10b7 1202 EtherLink Server 10/100 Dual Port B
3112 10b7 9805 3c980 10/100baseTX NIC [Python-T]
3113 10f1 2462 Thunder K7 S2462
3114 9900 3C990-TX [Typhoon]
3115 9902 3CR990-TX-95 [Typhoon 56-bit]
3116 9903 3CR990-TX-97 [Typhoon 168-bit]
3117 9904 3C990B-TX-M/3C990BSVR [Typhoon2]
3118 10b7 1000 3CR990B-TX-M [Typhoon2]
3119 10b7 2000 3CR990BSVR [Typhoon2 Server]
3120 9905 3CR990-FX-95/97/95 [Typhon Fiber]
3121 10b7 1101 3CR990-FX-95 [Typhoon Fiber 56-bit]
3122 10b7 1102 3CR990-FX-97 [Typhoon Fiber 168-bit]
3123 10b7 2101 3CR990-FX-95 Server [Typhoon Fiber 56-bit]
3124 10b7 2102 3CR990-FX-97 Server [Typhoon Fiber 168-bit]
3125 9908 3CR990SVR95 [Typhoon Server 56-bit]
3126 9909 3CR990SVR97 [Typhoon Server 168-bit]
3127 990a 3C990SVR [Typhoon Server]
3128 990b 3C990SVR [Typhoon Server]
312910b8 Standard Microsystems Corp [SMC]
3130 0005 83c170 EPIC/100 Fast Ethernet Adapter
3131 1055 e000 LANEPIC 10/100 [EVB171Q-PCI]
3132 1055 e002 LANEPIC 10/100 [EVB171G-PCI]
3133 10b8 a011 EtherPower II 10/100
3134 10b8 a014 EtherPower II 10/100
3135 10b8 a015 EtherPower II 10/100
3136 10b8 a016 EtherPower II 10/100
3137 10b8 a017 EtherPower II 10/100
3138 0006 83c175 EPIC/100 Fast Ethernet Adapter
3139 1055 e100 LANEPIC Cardbus Fast Ethernet Adapter
3140 1055 e102 LANEPIC Cardbus Fast Ethernet Adapter
3141 1055 e300 LANEPIC Cardbus Fast Ethernet Adapter
3142 1055 e302 LANEPIC Cardbus Fast Ethernet Adapter
3143 10b8 a012 LANEPIC Cardbus Fast Ethernet Adapter
3144 13a2 8002 LANEPIC Cardbus Fast Ethernet Adapter
3145 13a2 8006 LANEPIC Cardbus Fast Ethernet Adapter
3146 1000 FDC 37c665
3147 1001 FDC 37C922
3148# 802.11g card
3149 2802 SMC2802W [EZ Connect g]
3150 a011 83C170QF
3151 b106 SMC34C90
315210b9 ALi Corporation
3153 0101 CMI8338/C3DX PCI Audio Device
3154 0111 C-Media CMI8738/C3DX Audio Device (OEM)
3155 10b9 0111 C-Media CMI8738/C3DX Audio Device (OEM)
3156 0780 Multi-IO Card
3157 0782 Multi-IO Card
3158 1435 M1435
3159 1445 M1445
3160 1449 M1449
3161 1451 M1451
3162 1461 M1461
3163 1489 M1489
3164 1511 M1511 [Aladdin]
3165 1512 M1512 [Aladdin]
3166 1513 M1513 [Aladdin]
3167 1521 M1521 [Aladdin III]
3168 10b9 1521 ALI M1521 Aladdin III CPU Bridge
3169 1523 M1523
3170 10b9 1523 ALI M1523 ISA Bridge
3171 1531 M1531 [Aladdin IV]
3172 1533 M1533 PCI to ISA Bridge [Aladdin IV]
3173 1014 053b ThinkPad R40e (2684-HVG) PCI to ISA Bridge
3174 10b9 1533 ALI M1533 Aladdin IV ISA Bridge
3175 1541 M1541
3176 10b9 1541 ALI M1541 Aladdin V/V+ AGP System Controller
3177 1543 M1543
3178 1563 M1563 HyperTransport South Bridge
3179 1621 M1621
3180 1631 ALI M1631 PCI North Bridge Aladdin Pro III
3181 1632 M1632M Northbridge+Trident
3182 1641 ALI M1641 PCI North Bridge Aladdin Pro IV
3183 1644 M1644/M1644T Northbridge+Trident
3184 1646 M1646 Northbridge+Trident
3185 1647 M1647 Northbridge [MAGiK 1 / MobileMAGiK 1]
3186 1651 M1651/M1651T Northbridge [Aladdin-Pro 5/5M,Aladdin-Pro 5T/5TM]
3187 1671 M1671 Super P4 Northbridge [AGP4X,PCI and SDR/DDR]
3188 1672 M1672 Northbridge [CyberALADDiN-P4]
3189 1681 M1681 P4 Northbridge [AGP8X,HyperTransport and SDR/DDR]
3190 1687 M1687 K8 Northbridge [AGP8X and HyperTransport]
3191 1689 M1689 K8 Northbridge [Super K8 Single Chip]
3192 3141 M3141
3193 3143 M3143
3194 3145 M3145
3195 3147 M3147
3196 3149 M3149
3197 3151 M3151
3198 3307 M3307
3199 3309 M3309
3200 3323 M3325 Video/Audio Decoder
3201 5212 M4803
3202 5215 MS4803
3203 5217 M5217H
3204 5219 M5219
3205 5225 M5225
3206 5228 M5228 ALi ATA/RAID Controller
3207 5229 M5229 IDE
3208 1014 050f ThinkPad R30
3209 1014 053d ThinkPad R40e (2684-HVG) builtin IDE
3210 103c 0024 Pavilion ze4400 builtin IDE
3211 1043 8053 A7A266 Motherboard IDE
3212 5235 M5225
3213 5237 USB 1.1 Controller
3214 1014 0540 ThinkPad R40e (2684-HVG) builtin USB
3215 103c 0024 Pavilion ze4400 builtin USB
3216 5239 USB 2.0 Controller
3217 5243 M1541 PCI to AGP Controller
3218 5246 AGP8X Controller
3219 5247 PCI to AGP Controller
3220 5249 M5249 HTT to PCI Bridge
3221 5251 M5251 P1394 OHCI 1.0 Controller
3222 5253 M5253 P1394 OHCI 1.1 Controller
3223 5261 M5261 Ethernet Controller
3224 5263 M5263 Ethernet Controller
3225 5281 ALi M5281 Serial ATA / RAID Host Controller
3226 5287 ULi 5287 SATA
3227 5289 ULi 5289 SATA
3228 5450 Lucent Technologies Soft Modem AMR
3229 5451 M5451 PCI AC-Link Controller Audio Device
3230 1014 0506 ThinkPad R30
3231 1014 053e ThinkPad R40e (2684-HVG) builtin Audio
3232 103c 0024 Pavilion ze4400 builtin Audio
3233 10b9 5451 HP Compaq nc4010 (DY885AA#ABN)
3234 5453 M5453 PCI AC-Link Controller Modem Device
3235 5455 M5455 PCI AC-Link Controller Audio Device
3236 5457 M5457 AC'97 Modem Controller
3237 1014 0535 ThinkPad R40e (2684-HVG) builtin modem
3238 103c 0024 Pavilion ze4400 builtin Modem Device
3239# Same but more usefull for driver's lookup
3240 5459 SmartLink SmartPCI561 56K Modem
3241# SmartLink PCI SoftModem
3242 545a SmartLink SmartPCI563 56K Modem
3243 5471 M5471 Memory Stick Controller
3244 5473 M5473 SD-MMC Controller
3245 7101 M7101 Power Management Controller [PMU]
3246 1014 0510 ThinkPad R30
3247 1014 053c ThinkPad R40e (2684-HVG) Power Management Controller
3248 103c 0024 Pavilion ze4400
324910ba Mitsubishi Electric Corp.
3250 0301 AccelGraphics AccelECLIPSE
3251 0304 AccelGALAXY A2100 [OEM Evans & Sutherland]
3252 0308 Tornado 3000 [OEM Evans & Sutherland]
3253 1002 VG500 [VolumePro Volume Rendering Accelerator]
325410bb Dapha Electronics Corporation
325510bc Advanced Logic Research
325610bd Surecom Technology
3257 0e34 NE-34
325810be Tseng Labs International Co.
325910bf Most Inc
326010c0 Boca Research Inc.
326110c1 ICM Co., Ltd.
326210c2 Auspex Systems Inc.
326310c3 Samsung Semiconductors, Inc.
3264 1100 Smartether100 SC1100 LAN Adapter (i82557B)
326510c4 Award Software International Inc.
326610c5 Xerox Corporation
326710c6 Rambus Inc.
326810c7 Media Vision
326910c8 Neomagic Corporation
3270 0001 NM2070 [MagicGraph 128]
3271 0002 NM2090 [MagicGraph 128V]
3272 0003 NM2093 [MagicGraph 128ZV]
3273 0004 NM2160 [MagicGraph 128XD]
3274 1014 00ba MagicGraph 128XD
3275 1025 1007 MagicGraph 128XD
3276 1028 0074 MagicGraph 128XD
3277 1028 0075 MagicGraph 128XD
3278 1028 007d MagicGraph 128XD
3279 1028 007e MagicGraph 128XD
3280 1033 802f MagicGraph 128XD
3281 104d 801b MagicGraph 128XD
3282 104d 802f MagicGraph 128XD
3283 104d 830b MagicGraph 128XD
3284 10ba 0e00 MagicGraph 128XD
3285 10c8 0004 MagicGraph 128XD
3286 10cf 1029 MagicGraph 128XD
3287 10f7 8308 MagicGraph 128XD
3288 10f7 8309 MagicGraph 128XD
3289 10f7 830b MagicGraph 128XD
3290 10f7 830d MagicGraph 128XD
3291 10f7 8312 MagicGraph 128XD
3292 0005 NM2200 [MagicGraph 256AV]
3293 1014 00dd ThinkPad 570
3294 1028 0088 Latitude CPi A
3295 0006 NM2360 [MagicMedia 256ZX]
3296 0016 NM2380 [MagicMedia 256XL+]
3297 10c8 0016 MagicMedia 256XL+
3298 0025 NM2230 [MagicGraph 256AV+]
3299 0083 NM2093 [MagicGraph 128ZV+]
3300 8005 NM2200 [MagicMedia 256AV Audio]
3301 0e11 b0d1 MagicMedia 256AV Audio Device on Discovery
3302 0e11 b126 MagicMedia 256AV Audio Device on Durango
3303 1014 00dd MagicMedia 256AV Audio Device on BlackTip Thinkpad
3304 1025 1003 MagicMedia 256AV Audio Device on TravelMate 720
3305 1028 0088 Latitude CPi A
3306 1028 008f MagicMedia 256AV Audio Device on Colorado Inspiron
3307 103c 0007 MagicMedia 256AV Audio Device on Voyager II
3308 103c 0008 MagicMedia 256AV Audio Device on Voyager III
3309 103c 000d MagicMedia 256AV Audio Device on Omnibook 900
3310 10c8 8005 MagicMedia 256AV Audio Device on FireAnt
3311 110a 8005 MagicMedia 256AV Audio Device
3312 14c0 0004 MagicMedia 256AV Audio Device
3313 8006 NM2360 [MagicMedia 256ZX Audio]
3314 8016 NM2380 [MagicMedia 256XL+ Audio]
331510c9 Dataexpert Corporation
331610ca Fujitsu Microelectr., Inc.
331710cb Omron Corporation
3318# nee Mentor ARC Inc
331910cc Mai Logic Incorporated
3320 0660 Articia S Host Bridge
3321 0661 Articia S PCI Bridge
332210cd Advanced System Products, Inc
3323 1100 ASC1100
3324 1200 ASC1200 [(abp940) Fast SCSI-II]
3325 1300 ABP940-U / ABP960-U
3326 10cd 1310 ASC1300 SCSI Adapter
3327 2300 ABP940-UW
3328 2500 ABP940-U2W
332910ce Radius
3330# nee Citicorp TTI
333110cf Fujitsu Limited.
3332 2001 mb86605
333310d1 FuturePlus Systems Corp.
333410d2 Molex Incorporated
333510d3 Jabil Circuit Inc
333610d4 Hualon Microelectronics
333710d5 Autologic Inc.
333810d6 Cetia
333910d7 BCM Advanced Research
334010d8 Advanced Peripherals Labs
334110d9 Macronix, Inc. [MXIC]
3342 0431 MX98715
3343 0512 MX98713
3344 0531 MX987x5
3345 1186 1200 DFE-540TX ProFAST 10/100 Adapter
3346 8625 MX86250
3347 8888 MX86200
334810da Compaq IPG-Austin
3349 0508 TC4048 Token Ring 4/16
3350 3390 Tl3c3x9
335110db Rohm LSI Systems, Inc.
335210dc CERN/ECP/EDU
3353 0001 STAR/RD24 SCI-PCI (PMC)
3354 0002 TAR/RD24 SCI-PCI (PMC)
3355 0021 HIPPI destination
3356 0022 HIPPI source
3357 10dc ATT2C15-3 FPGA
335810dd Evans & Sutherland
335910de nVidia Corporation
3360 0008 NV1 [EDGE 3D]
3361 0009 NV1 [EDGE 3D]
3362 0010 NV2 [Mutara V08]
3363 0020 NV4 [RIVA TNT]
3364 1043 0200 V3400 TNT
3365 1048 0c18 Erazor II SGRAM
3366 1048 0c1b Erazor II
3367 1092 0550 Viper V550
3368 1092 0552 Viper V550
3369 1092 4804 Viper V550
3370 1092 4808 Viper V550
3371 1092 4810 Viper V550
3372 1092 4812 Viper V550
3373 1092 4815 Viper V550
3374 1092 4820 Viper V550 with TV out
3375 1092 4822 Viper V550
3376 1092 4904 Viper V550
3377 1092 4914 Viper V550
3378 1092 8225 Viper V550
3379 10b4 273d Velocity 4400
3380 10b4 273e Velocity 4400
3381 10b4 2740 Velocity 4400
3382 10de 0020 Riva TNT
3383 1102 1015 Graphics Blaster CT6710
3384 1102 1016 Graphics Blaster RIVA TNT
3385 0028 NV5 [RIVA TNT2/TNT2 Pro]
3386 1043 0200 AGP-V3800 SGRAM
3387 1043 0201 AGP-V3800 SDRAM
3388 1043 0205 PCI-V3800
3389 1043 4000 AGP-V3800PRO
3390 1048 0c21 Synergy II
3391 1048 0c31 Erazor III
3392 107d 2134 WinFast 3D S320 II + TV-Out
3393 1092 4804 Viper V770
3394 1092 4a00 Viper V770
3395 1092 4a02 Viper V770 Ultra
3396 1092 5a00 RIVA TNT2/TNT2 Pro
3397 1092 6a02 Viper V770 Ultra
3398 1092 7a02 Viper V770 Ultra
3399 10de 0005 RIVA TNT2 Pro
3400 10de 000f Compaq NVIDIA TNT2 Pro
3401 1102 1020 3D Blaster RIVA TNT2
3402 1102 1026 3D Blaster RIVA TNT2 Digital
3403 14af 5810 Maxi Gamer Xentor
3404 0029 NV5 [RIVA TNT2 Ultra]
3405 1043 0200 AGP-V3800 Deluxe
3406 1043 0201 AGP-V3800 Ultra SDRAM
3407 1043 0205 PCI-V3800 Ultra
3408 1102 1021 3D Blaster RIVA TNT2 Ultra
3409 1102 1029 3D Blaster RIVA TNT2 Ultra
3410 1102 102f 3D Blaster RIVA TNT2 Ultra
3411 14af 5820 Maxi Gamer Xentor 32
3412 002a NV5 [Riva TnT2]
3413 002b NV5 [Riva TnT2]
3414 002c NV6 [Vanta/Vanta LT]
3415 1043 0200 AGP-V3800 Combat SDRAM
3416 1043 0201 AGP-V3800 Combat
3417 1092 6820 Viper V730
3418 1102 1031 CT6938 VANTA 8MB
3419 1102 1034 CT6894 VANTA 16MB
3420 14af 5008 Maxi Gamer Phoenix 2
3421 002d NV5M64 [RIVA TNT2 Model 64/Model 64 Pro]
3422 1043 0200 AGP-V3800M
3423 1043 0201 AGP-V3800M
3424 1048 0c3a Erazor III LT
3425 10de 001e M64 AGP4x
3426 1102 1023 CT6892 RIVA TNT2 Value
3427 1102 1024 CT6932 RIVA TNT2 Value 32Mb
3428 1102 102c CT6931 RIVA TNT2 Value [Jumper]
3429 1462 8808 MSI-8808
3430 1554 1041 Pixelview RIVA TNT2 M64
3431 1569 002d Palit Microsystems Daytona TNT2 M64
3432 002e NV6 [Vanta]
3433 002f NV6 [Vanta]
3434 0034 MCP04 SMBus
3435 0035 MCP04 IDE
3436 0036 MCP04 Serial ATA Controller
3437 0037 MCP04 Ethernet Controller
3438 0038 MCP04 Ethernet Controller
3439 003a MCP04 AC'97 Audio Controller
3440 003b MCP04 USB Controller
3441 003c MCP04 USB Controller
3442 003d MCP04 PCI Bridge
3443 003e MCP04 Serial ATA Controller
3444 0040 nv40 [GeForce 6800 Ultra]
3445 0041 NV40 [GeForce 6800]
3446 0042 NV40.2
3447 0043 NV40.3
3448 0045 NV40 [GeForce 6800 GT]
3449 0049 NV40GL
3450 004e NV40GL [Quadro FX 4000]
3451 0051 CK804 ISA Bridge
3452 0052 CK804 SMBus
3453 0053 CK804 IDE
3454 0054 CK804 Serial ATA Controller
3455 0055 CK804 Serial ATA Controller
3456 0056 CK804 Ethernet Controller
3457 0057 CK804 Ethernet Controller
3458 0059 CK804 AC'97 Audio Controller
3459 005a CK804 USB Controller
3460 005b CK804 USB Controller
3461 005c CK804 PCI Bridge
3462 005d CK804 PCIE Bridge
3463 005e CK804 Memory Controller
3464 0060 nForce2 ISA Bridge
3465 1043 80ad A7N8X Mainboard
3466 0064 nForce2 SMBus (MCP)
3467 0065 nForce2 IDE
3468 0066 nForce2 Ethernet Controller
3469 1043 80a7 A7N8X Mainboard onboard nForce2 Ethernet
3470 0067 nForce2 USB Controller
3471 1043 0c11 A7N8X Mainboard
3472 0068 nForce2 USB Controller
3473 1043 0c11 A7N8X Mainboard
3474 006a nForce2 AC97 Audio Controler (MCP)
3475 006b nForce Audio Processing Unit
3476 10de 006b nForce2 MCP Audio Processing Unit
3477 006c nForce2 External PCI Bridge
3478 006d nForce2 PCI Bridge
3479 006e nForce2 FireWire (IEEE 1394) Controller
3480 0084 MCP2A SMBus
3481 0085 MCP2A IDE
3482 0086 MCP2A Ethernet Controller
3483 0087 MCP2A USB Controller
3484 0088 MCP2A USB Controller
3485 008a MCP2S AC'97 Audio Controller
3486 008b MCP2A PCI Bridge
3487 008c MCP2A Ethernet Controller
3488 008e nForce2 Serial ATA Controller
3489 00a0 NV5 [Aladdin TNT2]
3490 14af 5810 Maxi Gamer Xentor
3491 00c0 NV41.0
3492 00c1 NV41.1
3493 00c2 NV41.2
3494 00c8 NV41.8
3495 00ce NV41GL
3496 00d0 nForce3 LPC Bridge
3497 00d1 nForce3 Host Bridge
3498 00d2 nForce3 AGP Bridge
3499 00d3 CK804 Memory Controller
3500 00d4 nForce3 SMBus
3501 00d5 nForce3 IDE
3502 00d6 nForce3 Ethernet
3503 00d7 nForce3 USB 1.1
3504 00d8 nForce3 USB 2.0
3505 00da nForce3 Audio
3506 00dd nForce3 PCI Bridge
3507 00df CK8S Ethernet Controller
3508 00e0 nForce3 250Gb LPC Bridge
3509 00e1 nForce3 250Gb Host Bridge
3510 00e2 nForce3 250Gb AGP Host to PCI Bridge
3511 00e3 CK8S Serial ATA Controller (v2.5)
3512 00e4 nForce 250Gb PCI System Management
3513 00e5 CK8S Parallel ATA Controller (v2.5)
3514 00e6 CK8S Ethernet Controller
3515 00e7 CK8S USB Controller
3516 00e8 nForce3 EHCI USB 2.0 Controller
3517 00ea nForce3 250Gb AC'97 Audio Controller
3518 00ed nForce3 250Gb PCI-to-PCI Bridge
3519 00ee CK8S Serial ATA Controller (v2.5)
3520 00f0 NV40 [GeForce 6800/GeForce 6800 Ultra]
3521 00f1 NV43 [GeForce 6600/GeForce 6600 GT]
3522 00f2 NV43 [GeForce 6600 GT]
3523 00f8 NV45GL [Quadro FX 3400]
3524 00f9 NV40 [GeForce 6800 Ultra/GeForce 6800 GT]
3525 1682 2120 GEFORCE 6800 GT PCI-E
3526 00fa NV36 [GeForce PCX 5750]
3527 00fb NV35 [GeForce PCX 5900]
3528 00fc NV37GL [Quadro FX 330/GeForce PCX 5300]
3529 00fd NV37GL [Quadro FX 330]
3530 00fe NV38GL [Quadro FX 1300]
3531 00ff NV18 [GeForce PCX 4300]
3532 0100 NV10 [GeForce 256 SDR]
3533 1043 0200 AGP-V6600 SGRAM
3534 1043 0201 AGP-V6600 SDRAM
3535 1043 4008 AGP-V6600 SGRAM
3536 1043 4009 AGP-V6600 SDRAM
3537 1102 102d CT6941 GeForce 256
3538 14af 5022 3D Prophet SE
3539 0101 NV10DDR [GeForce 256 DDR]
3540 1043 0202 AGP-V6800 DDR
3541 1043 400a AGP-V6800 DDR SGRAM
3542 1043 400b AGP-V6800 DDR SDRAM
3543 107d 2822 WinFast GeForce 256
3544 1102 102e CT6971 GeForce 256 DDR
3545 14af 5021 3D Prophet DDR-DVI
3546 0103 NV10GL [Quadro]
3547 0110 NV11 [GeForce2 MX/MX 400]
3548 1043 4015 AGP-V7100 Pro
3549 1043 4031 V7100 Pro with TV output
3550 10de 0091 Dell OEM GeForce 2 MX 400
3551 1462 8817 MSI GeForce2 MX400 Pro32S [MS-8817]
3552 14af 7102 3D Prophet II MX
3553 14af 7103 3D Prophet II MX Dual-Display
3554 0111 NV11DDR [GeForce2 MX 100 DDR/200 DDR]
3555 0112 NV11 [GeForce2 Go]
3556 0113 NV11GL [Quadro2 MXR/EX]
3557 0140 NV43 [MSI NX6600GT-TD128E]
3558 014f NV43 [GeForce 6200]
3559 0150 NV15 [GeForce2 GTS/Pro]
3560 1043 4016 V7700 AGP Video Card
3561 107d 2840 WinFast GeForce2 GTS with TV output
3562 107d 2842 WinFast GeForce 2 Pro
3563 1462 8831 Creative GeForce2 Pro
3564 0151 NV15DDR [GeForce2 Ti]
3565 1043 405f V7700Ti
3566 1462 5506 Creative 3D Blaster Geforce2 Titanium
3567 0152 NV15BR [GeForce2 Ultra, Bladerunner]
3568 1048 0c56 GLADIAC Ultra
3569 0153 NV15GL [Quadro2 Pro]
3570 0170 NV17 [GeForce4 MX 460]
3571 0171 NV17 [GeForce4 MX 440]
3572 10b0 0002 Gainward Pro/600 TV
3573 1462 8661 G4MX440-VTP
3574 1462 8730 MX440SES-T (MS-8873)
3575 147b 8f00 Abit Siluro GeForce4MX440
3576 0172 NV17 [GeForce4 MX 420]
3577 0173 NV17 [GeForce4 MX 440-SE]
3578 0174 NV17 [GeForce4 440 Go]
3579 0175 NV17 [GeForce4 420 Go]
3580 0176 NV17 [GeForce4 420 Go 32M]
3581 4c53 1090 Cx9 / Vx9 mainboard
3582 0177 NV17 [GeForce4 460 Go]
3583 0178 NV17GL [Quadro4 550 XGL]
3584 0179 NV17 [GeForce4 440 Go 64M]
3585 10de 0179 GeForce4 MX (Mac)
3586 017a NV17GL [Quadro4 200/400 NVS]
3587 017b NV17GL [Quadro4 550 XGL]
3588 017c NV17GL [Quadro4 550 GoGL]
3589 017d NV17 [GeForce4 410 Go 16M]
3590 0181 NV18 [GeForce4 MX 440 AGP 8x]
3591 1043 806f V9180 Magic
3592 1462 8880 MS-StarForce GeForce4 MX 440 with AGP8X
3593 1462 8900 MS-8890 GeForce 4 MX440 AGP8X
3594 1462 9350 MSI Geforce4 MX T8X with AGP8X
3595 147b 8f0d Siluro GF4 MX-8X
3596 0182 NV18 [GeForce4 MX 440SE AGP 8x]
3597 0183 NV18 [GeForce4 MX 420 AGP 8x]
3598 0185 NV18 [GeForce4 MX 4000 AGP 8x]
3599 0186 NV18M [GeForce4 448 Go]
3600 0187 NV18M [GeForce4 488 Go]
3601 0188 NV18GL [Quadro4 580 XGL]
3602 018a NV18GL [Quadro4 NVS AGP 8x]
3603 018b NV18GL [Quadro4 380 XGL]
3604 018d NV18M [GeForce4 448 Go]
3605 01a0 NVCrush11 [GeForce2 MX Integrated Graphics]
3606 01a4 nForce CPU bridge
3607 01ab nForce 420 Memory Controller (DDR)
3608 01ac nForce 220/420 Memory Controller
3609 01ad nForce 220/420 Memory Controller
3610 01b0 nForce Audio
3611 01b1 nForce Audio
3612 01b2 nForce ISA Bridge
3613 01b4 nForce PCI System Management
3614 01b7 nForce AGP to PCI Bridge
3615 01b8 nForce PCI-to-PCI bridge
3616 01bc nForce IDE
3617 01c1 nForce AC'97 Modem Controller
3618 01c2 nForce USB Controller
3619 01c3 nForce Ethernet Controller
3620 01e0 nForce2 AGP (different version?)
3621 01e8 nForce2 AGP
3622 01ea nForce2 Memory Controller 0
3623 01eb nForce2 Memory Controller 1
3624 01ec nForce2 Memory Controller 2
3625 01ed nForce2 Memory Controller 3
3626 01ee nForce2 Memory Controller 4
3627 01ef nForce2 Memory Controller 5
3628 01f0 NV18 [GeForce4 MX - nForce GPU]
3629 0200 NV20 [GeForce3]
3630 1043 402f AGP-V8200 DDR
3631 0201 NV20 [GeForce3 Ti 200]
3632 0202 NV20 [GeForce3 Ti 500]
3633 1043 405b V8200 T5
3634 1545 002f Xtasy 6964
3635 0203 NV20DCC [Quadro DCC]
3636 0240 C51 PCI Express Bridge
3637 0241 C51 PCI Express Bridge
3638 0242 C51 PCI Express Bridge
3639 0243 C51 PCI Express Bridge
3640 0244 C51 PCI Express Bridge
3641 0245 C51 PCI Express Bridge
3642 0246 C51 PCI Express Bridge
3643 0247 C51 PCI Express Bridge
3644 0248 C51 PCI Express Bridge
3645 0249 C51 PCI Express Bridge
3646 024a C51 PCI Express Bridge
3647 024b C51 PCI Express Bridge
3648 024c C51 PCI Express Bridge
3649 024d C51 PCI Express Bridge
3650 024e C51 PCI Express Bridge
3651 024f C51 PCI Express Bridge
3652 0250 NV25 [GeForce4 Ti 4600]
3653 0251 NV25 [GeForce4 Ti 4400]
3654 1043 8023 v8440 GeForce 4 Ti4400
3655 0252 NV25 [GeForce4 Ti]
3656 0253 NV25 [GeForce4 Ti 4200]
3657 107d 2896 WinFast A250 LE TD (Dual VGA/TV-out/DVI)
3658 147b 8f09 Siluro (Dual VGA/TV-out/DVI)
3659 0258 NV25GL [Quadro4 900 XGL]
3660 0259 NV25GL [Quadro4 750 XGL]
3661 025b NV25GL [Quadro4 700 XGL]
3662 0260 MCP51 LPC Bridge
3663 0261 MCP51 LPC Bridge
3664 0262 MCP51 LPC Bridge
3665 0263 MCP51 LPC Bridge
3666 0264 MCP51 SMBus
3667 0265 MCP51 IDE
3668 0266 MCP51 Serial ATA Controller
3669 0267 MCP51 Serial ATA Controller
3670 0268 MCP51 Ethernet Controller
3671 0269 MCP51 Ethernet Controller
3672 026a MCP51 MCI
3673 026b MCP51 AC97 Audio Controller
3674 026c MCP51 High Definition Audio
3675 026d MCP51 USB Controller
3676 026e MCP51 USB Controller
3677 026f MCP51 PCI Bridge
3678 0270 MCP51 Host Bridge
3679 0271 MCP51 PMU
3680 0272 MCP51 Memory Controller 0
3681 027e C51 Memory Controller 2
3682 027f C51 Memory Controller 3
3683 0280 NV28 [GeForce4 Ti 4800]
3684 0281 NV28 [GeForce4 Ti 4200 AGP 8x]
3685 0282 NV28 [GeForce4 Ti 4800 SE]
3686 0286 NV28 [GeForce4 Ti 4200 Go AGP 8x]
3687 0288 NV28GL [Quadro4 980 XGL]
3688 0289 NV28GL [Quadro4 780 XGL]
3689 028c NV28GLM [Quadro4 700 GoGL]
3690 02f0 C51 Host Bridge
3691 02f1 C51 Host Bridge
3692 02f2 C51 Host Bridge
3693 02f3 C51 Host Bridge
3694 02f4 C51 Host Bridge
3695 02f5 C51 Host Bridge
3696 02f6 C51 Host Bridge
3697 02f7 C51 Host Bridge
3698 02f8 C51 Memory Controller 5
3699 02f9 C51 Memory Controller 4
3700 02fa C51 Memory Controller 0
3701 02fb C51 PCI Express Bridge
3702 02fc C51 PCI Express Bridge
3703 02fd C51 PCI Express Bridge
3704 02fe C51 Memory Controller 1
3705 02ff C51 Host Bridge
3706 0300 NV30 [GeForce FX]
3707 0301 NV30 [GeForce FX 5800 Ultra]
3708 0302 NV30 [GeForce FX 5800]
3709 0308 NV30GL [Quadro FX 2000]
3710 0309 NV30GL [Quadro FX 1000]
3711 0311 NV31 [GeForce FX 5600 Ultra]
3712 0312 NV31 [GeForce FX 5600]
3713 0313 NV31
3714 0314 NV31 [GeForce FX 5600XT]
3715 1043 814a V9560XT/TD
3716 0316 NV31
3717 0317 NV31
3718 031a NV31M [GeForce FX Go 5600]
3719 031b NV31M [GeForce FX Go5650]
3720 031c NVIDIA Quadro FX 700 Go
3721 031d NV31
3722 031e NV31
3723 031f NV31
3724 0320 NV34 [GeForce FX 5200]
3725 0321 NV34 [GeForce FX 5200 Ultra]
3726 0322 NV34 [GeForce FX 5200]
3727 1462 9171 MS-8917 (FX5200-T128)
3728 0323 NV34 [GeForce FX 5200LE]
3729 0324 NV34M [GeForce FX Go 5200]
3730 1071 8160 MIM2000
3731 0325 NV34M [GeForce FX Go5250]
3732 0326 NV34 [GeForce FX 5500]
3733 0327 NV34 [GeForce FX 5100]
3734 0328 NV34M [GeForce FX Go 5200]
3735 0329 NV34M [GeForce FX Go5200]
3736 032a NV34GL [Quadro NVS 280 PCI]
3737 032b NV34GL [Quadro FX 500/600 PCI]
3738 032c NV34GLM [GeForce FX Go 5300]
3739 032d NV34 [GeForce FX Go5100]
3740 032f NV34
3741 0330 NV35 [GeForce FX 5900 Ultra]
3742 0331 NV35 [GeForce FX 5900]
3743 1043 8145 V9950GE
3744 0332 NV35 [GeForce FX 5900XT]
3745 0333 NV38 [GeForce FX 5950 Ultra]
3746 0334 NV35 [GeForce FX 5900ZT]
3747 0338 NV35GL [Quadro FX 3000]
3748 033f NV35GL [Quadro FX 700]
3749 0341 NV36.1 [GeForce FX 5700 Ultra]
3750 0342 NV36.2 [GeForce FX 5700]
3751 0343 NV36 [GeForce FX 5700LE]
3752 0344 NV36.4 [GeForce FX 5700VE]
3753 0345 NV36.5
3754 0347 NV36 [GeForce FX Go5700]
3755 0348 NV36 [GeForce FX Go5700]
3756 0349 NV36
3757 034b NV36
3758 034c NV36 [Quadro FX Go1000]
3759 034e NV36GL [Quadro FX 1100]
3760 034f NV36GL
376110df Emulex Corporation
3762 1ae5 LP6000 Fibre Channel Host Adapter
3763 1ae6 LP 8000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
3764 1ae7 LP 8000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:2-3)
3765 f005 LP1150e Fibre Channel Host Adapter
3766 f085 LP850 Fibre Channel Host Adapter
3767 f095 LP952 Fibre Channel Host Adapter
3768 f098 LP982 Fibre Channel Host Adapter
3769 f0a5 LP1050 Fibre Channel Host Adapter
3770 f0d5 LP1150 Fibre Channel Host Adapter
3771 f100 LP11000e Fibre Channel Host Adapter
3772 f700 LP7000 Fibre Channel Host Adapter
3773 f701 LP 7000EFibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
3774 f800 LP8000 Fibre Channel Host Adapter
3775 f801 LP 8000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
3776 f900 LP9000 Fibre Channel Host Adapter
3777 f901 LP 9000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2)
3778 f980 LP9802 Fibre Channel Host Adapter
3779 f981 LP 9802 Fibre Channel Host Adapter Alternate ID
3780 f982 LP 9802 Fibre Channel Host Adapter Alternate ID
3781 fa00 LP10000 Fibre Channel Host Adapter
3782 fa01 LP101 Fibre Channel Host Adapter
3783 fd00 LP11000 Fibre Channel Host Adapter
378410e0 Integrated Micro Solutions Inc.
3785 5026 IMS5026/27/28
3786 5027 IMS5027
3787 5028 IMS5028
3788 8849 IMS8849
3789 8853 IMS8853
3790 9128 IMS9128 [Twin turbo 128]
379110e1 Tekram Technology Co.,Ltd.
3792 0391 TRM-S1040
3793 10e1 0391 DC-315U SCSI-3 Host Adapter
3794 690c DC-690c
3795 dc29 DC-290
379610e2 Aptix Corporation
379710e3 Tundra Semiconductor Corp.
3798 0000 CA91C042 [Universe]
3799 0860 CA91C860 [QSpan]
3800 0862 CA91C862A [QSpan-II]
3801 8260 CA91L8200B [Dual PCI PowerSpan II]
3802 8261 CA91L8260B [Single PCI PowerSpan II]
380310e4 Tandem Computers
380410e5 Micro Industries Corporation
380510e6 Gainbery Computer Products Inc.
380610e7 Vadem
380710e8 Applied Micro Circuits Corp.
3808 1072 INES GPIB-PCI (AMCC5920 based)
3809 2011 Q-Motion Video Capture/Edit board
3810 4750 S5930 [Matchmaker]
3811 5920 S5920
3812 8043 LANai4.x [Myrinet LANai interface chip]
3813 8062 S5933_PARASTATION
3814 807d S5933 [Matchmaker]
3815 8088 Kongsberg Spacetec Format Synchronizer
3816 8089 Kongsberg Spacetec Serial Output Board
3817 809c S5933_HEPC3
3818 80d7 PCI-9112
3819 80d9 PCI-9118
3820 80da PCI-9812
3821 811a PCI-IEEE1355-DS-DE Interface
3822 814c Fastcom ESCC-PCI (Commtech, Inc.)
3823 8170 S5933 [Matchmaker] (Chipset Development Tool)
3824# sold with Roper Scientifc(Photometrics) CoolSnap HQ camera
3825 81e6 Multimedia video controller
3826 8291 Fastcom 232/8-PCI (Commtech, Inc.)
3827 82c4 Fastcom 422/4-PCI (Commtech, Inc.)
3828 82c5 Fastcom 422/2-PCI (Commtech, Inc.)
3829 82c6 Fastcom IG422/1-PCI (Commtech, Inc.)
3830 82c7 Fastcom IG232/2-PCI (Commtech, Inc.)
3831 82ca Fastcom 232/4-PCI (Commtech, Inc.)
3832 82db AJA HDNTV HD SDI Framestore
3833 82e2 Fastcom DIO24H-PCI (Commtech, Inc.)
3834 8851 S5933 on Innes Corp FM Radio Capture card
383510e9 Alps Electric Co., Ltd.
383610ea Intergraphics Systems
3837 1680 IGA-1680
3838 1682 IGA-1682
3839 1683 IGA-1683
3840 2000 CyberPro 2000
3841 2010 CyberPro 2000A
3842 5000 CyberPro 5000
3843 5050 CyberPro 5050
3844 5202 CyberPro 5202
3845# CyberPro5202 Audio Function
3846 5252 CyberPro5252
384710eb Artists Graphics
3848 0101 3GA
3849 8111 Twist3 Frame Grabber
385010ec Realtek Semiconductor Co., Ltd.
3851 8029 RTL-8029(AS)
3852 10b8 2011 EZ-Card (SMC1208)
3853 10ec 8029 RTL-8029(AS)
3854 1113 1208 EN1208
3855 1186 0300 DE-528
3856 1259 2400 AT-2400
3857 8129 RTL-8129
3858 10ec 8129 RT8129 Fast Ethernet Adapter
3859 8138 RT8139 (B/C) Cardbus Fast Ethernet Adapter
3860 10ec 8138 RT8139 (B/C) Fast Ethernet Adapter
3861 8139 RTL-8139/8139C/8139C+
3862 0357 000a TTP-Monitoring Card V2.0
3863 1025 005a TravelMate 290
3864 1025 8920 ALN-325
3865 1025 8921 ALN-325
3866 1071 8160 MIM2000
3867 10bd 0320 EP-320X-R
3868 10ec 8139 RT8139
3869 1113 ec01 FNC-0107TX
3870 1186 1300 DFE-538TX
3871 1186 1320 SN5200
3872 1186 8139 DRN-32TX
3873 11f6 8139 FN22-3(A) LinxPRO Ethernet Adapter
3874 1259 2500 AT-2500TX
3875 1259 2503 AT-2500TX/ACPI
3876 1429 d010 ND010
3877 1432 9130 EN-9130TX
3878 1436 8139 RT8139
3879 1458 e000 GA-7VM400M/7VT600 Motherboard
3880 146c 1439 FE-1439TX
3881 1489 6001 GF100TXRII
3882 1489 6002 GF100TXRA
3883 149c 139a LFE-8139ATX
3884 149c 8139 LFE-8139TX
3885 14cb 0200 LNR-100 Family 10/100 Base-TX Ethernet
3886 1799 5000 F5D5000 PCI Card/Desktop Network PCI Card
3887 2646 0001 EtheRx
3888 8e2e 7000 KF-230TX
3889 8e2e 7100 KF-230TX/2
3890 a0a0 0007 ALN-325C
3891 8169 RTL-8169 Gigabit Ethernet
3892 1259 c107 CG-LAPCIGT
3893 1371 434e ProG-2000L
3894 1458 e000 GA-K8VT800 Pro Motherboard
3895 1462 702c K8T NEO 2 motherboard
3896 8180 RTL8180L 802.11b MAC
3897 8197 SmartLAN56 56K Modem
389810ed Ascii Corporation
3899 7310 V7310
390010ee Xilinx Corporation
3901 3fc0 RME Digi96
3902 3fc1 RME Digi96/8
3903 3fc2 RME Digi96/8 Pro
3904 3fc3 RME Digi96/8 Pad
3905 3fc4 RME Digi9652 (Hammerfall)
3906 3fc5 RME Hammerfall DSP
3907 3fc6 RME Hammerfall DSP MADI
3908 8381 Ellips Santos Frame Grabber
390910ef Racore Computer Products, Inc.
3910 8154 M815x Token Ring Adapter
391110f0 Peritek Corporation
391210f1 Tyan Computer
391310f2 Achme Computer, Inc.
391410f3 Alaris, Inc.
391510f4 S-MOS Systems, Inc.
391610f5 NKK Corporation
3917 a001 NDR4000 [NR4600 Bridge]
391810f6 Creative Electronic Systems SA
391910f7 Matsushita Electric Industrial Co., Ltd.
392010f8 Altos India Ltd
392110f9 PC Direct
392210fa Truevision
3923 000c TARGA 1000
392410fb Thesys Gesellschaft für Mikroelektronik mbH
3925 186f TH 6255
392610fc I-O Data Device, Inc.
3927# What's in the cardbus end of a Sony ACR-A01 card, comes with newer Vaio CD-RW drives
3928 0003 Cardbus IDE Controller
3929 0005 Cardbus SCSI CBSC II
393010fd Soyo Computer, Inc
393110fe Fast Multimedia AG
393210ff NCube
39331100 Jazz Multimedia
39341101 Initio Corporation
3935 1060 INI-A100U2W
3936 9100 INI-9100/9100W
3937 9400 INI-940
3938 9401 INI-950
3939 9500 360P
3940 9502 Initio INI-9100UW Ultra Wide SCSI Controller INIC-950P chip
39411102 Creative Labs
3942 0002 SB Live! EMU10k1
3943 1102 0020 CT4850 SBLive! Value
3944 1102 0021 CT4620 SBLive!
3945 1102 002f SBLive! mainboard implementation
3946 1102 4001 E-mu APS
3947 1102 8022 CT4780 SBLive! Value
3948 1102 8023 CT4790 SoundBlaster PCI512
3949 1102 8024 CT4760 SBLive!
3950 1102 8025 SBLive! Mainboard Implementation
3951 1102 8026 CT4830 SBLive! Value
3952 1102 8027 CT4832 SBLive! Value
3953 1102 8028 CT4760 SBLive! OEM version
3954 1102 8031 CT4831 SBLive! Value
3955 1102 8040 CT4760 SBLive!
3956 1102 8051 CT4850 SBLive! Value
3957 1102 8061 SBLive! Player 5.1
3958 1102 8064 SB Live! 5.1 Model SB0100
3959 1102 8065 SBLive! 5.1 Digital Model SB0220
3960 1102 8067 SBLive! 5.1 eMicro 28028
3961 0004 SB Audigy
3962 1102 0051 SB0090 Audigy Player
3963 1102 0053 SB0090 Audigy Player/OEM
3964 1102 0058 SB0090 Audigy Player/OEM
3965 1102 1007 SB0240 Audigy 2 Platinum 6.1
3966 1102 2002 SB Audigy 2 ZS (SB0350)
3967 0006 [SB Live! Value] EMU10k1X
3968 0007 SB Audigy LS
3969 1102 1001 SB0310 Audigy LS
3970 1102 1002 SB0312 Audigy LS
3971 1102 1006 SB0410 SBLive! 24-bit
3972 0008 SB0400 Audigy2 Value
3973 4001 SB Audigy FireWire Port
3974 1102 0010 SB Audigy FireWire Port
3975 7002 SB Live! MIDI/Game Port
3976 1102 0020 Gameport Joystick
3977 7003 SB Audigy MIDI/Game port
3978 1102 0040 SB Audigy MIDI/Game Port
3979 7004 [SB Live! Value] Input device controller
3980 7005 SB Audigy LS MIDI/Game port
3981 1102 1001 SB0310 Audigy LS MIDI/Game port
3982 1102 1002 SB0312 Audigy LS MIDI/Game port
3983 8064 SB0100 [SBLive! 5.1 OEM]
3984 8938 Ectiva EV1938
3985 1033 80e5 SlimTower-Jim (NEC)
3986 1071 7150 Mitac 7150
3987 110a 5938 Siemens Scenic Mobile 510PIII
3988 13bd 100c Ceres-C (Sharp, Intel BX)
3989 13bd 100d Sharp, Intel Banister
3990 13bd 100e TwinHead P09S/P09S3 (Sharp)
3991 13bd f6f1 Marlin (Sharp)
3992 14ff 0e70 P88TE (TWINHEAD INTERNATIONAL Corp)
3993 14ff c401 Notebook 9100/9200/2000 (TWINHEAD INTERNATIONAL Corp)
3994 156d b400 G400 - Geo (AlphaTop (Taiwan))
3995 156d b550 G560 (AlphaTop (Taiwan))
3996 156d b560 G560 (AlphaTop (Taiwan))
3997 156d b700 G700/U700 (AlphaTop (Taiwan))
3998 156d b795 G795 (AlphaTop (Taiwan))
3999 156d b797 G797 (AlphaTop (Taiwan))
40001103 Triones Technologies, Inc.
4001 0003 HPT343
4002 0004 HPT366/368/370/370A/372/372N
4003 1103 0001 HPT370A
4004 1103 0003 HPT343 / HPT345 / HPT363 UDMA33
4005 1103 0004 HPT366 UDMA66 (r1) / HPT368 UDMA66 (r2) / HPT370 UDMA100 (r3) / HPT370 UDMA100 RAID (r4)
4006 1103 0005 HPT370 UDMA100
4007 1103 0006 HPT302
4008 1103 0007 HPT371 UDMA133
4009 1103 0008 HPT374 UDMA/ATA133 RAID Controller
4010 0005 HPT372A/372N
4011 0006 HPT302
4012 0007 HPT371/371N
4013 0008 HPT374
4014 0009 HPT372N
40151104 RasterOps Corp.
40161105 Sigma Designs, Inc.
4017 1105 REALmagic Xcard MPEG 1/2/3/4 DVD Decoder
4018 8300 REALmagic Hollywood Plus DVD Decoder
4019 8400 EM840x REALmagic DVD/MPEG-2 Audio/Video Decoder
4020 8401 EM8401 REALmagic DVD/MPEG-2 A/V Decoder
4021 8470 EM8470 REALmagic DVD/MPEG-4 A/V Decoder
4022 8471 EM8471 REALmagic DVD/MPEG-4 A/V Decoder
4023 8475 EM8475 REALmagic DVD/MPEG-4 A/V Decoder
4024 8476 EM8476 REALmagic DVD/MPEG-4 A/V Decoder
4025 8485 EM8485 REALmagic DVD/MPEG-4 A/V Decoder
4026 8486 EM8486 REALmagic DVD/MPEG-4 A/V Decoder
40271106 VIA Technologies, Inc.
4028 0102 Embedded VIA Ethernet Controller
4029 0130 VT6305 1394.A Controller
4030 0305 VT8363/8365 [KT133/KM133]
4031 1043 8033 A7V Mainboard
4032 1043 803e A7V-E Mainboard
4033 1043 8042 A7V133/A7V133-C Mainboard
4034 147b a401 KT7/KT7-RAID/KT7A/KT7A-RAID Mainboard
4035 0391 VT8371 [KX133]
4036 0501 VT8501 [Apollo MVP4]
4037 0505 VT82C505
4038# Shares chip with :0576. The VT82C576M has :1571 instead of :0561.
4039 0561 VT82C576MV
4040 0571 VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE
4041 1019 0985 P6VXA Motherboard
4042 1019 0a81 L7VTA v1.0 Motherboard (KT400-8235)
4043 1043 8052 VT8233A Bus Master ATA100/66/33 IDE
4044 1043 808c A7V8X motherboard
4045 1043 80a1 A7V8X-X motherboard rev. 1.01
4046 1043 80ed A7V600 motherboard
4047 1106 0571 VT82C586/B/VT82C686/A/B/VT8233/A/C/VT8235 PIPC Bus Master IDE
4048 1179 0001 Magnia Z310
4049 1297 f641 FX41 motherboard
4050 1458 5002 GA-7VAX Mainboard
4051 1462 7020 K8T NEO 2 motherboard
4052 147b 1407 KV8-MAX3 motherboard
4053 1849 0571 K7VT2 motherboard
4054 0576 VT82C576 3V [Apollo Master]
4055 0585 VT82C585VP [Apollo VP1/VPX]
4056 0586 VT82C586/A/B PCI-to-ISA [Apollo VP]
4057 1106 0000 MVP3 ISA Bridge
4058 0595 VT82C595 [Apollo VP2]
4059 0596 VT82C596 ISA [Mobile South]
4060 1106 0000 VT82C596/A/B PCI to ISA Bridge
4061 1458 0596 VT82C596/A/B PCI to ISA Bridge
4062 0597 VT82C597 [Apollo VP3]
4063 0598 VT82C598 [Apollo MVP3]
4064 0601 VT8601 [Apollo ProMedia]
4065 0605 VT8605 [ProSavage PM133]
4066 1043 802c CUV4X mainboard
4067 0680 VT82C680 [Apollo P6]
4068 0686 VT82C686 [Apollo Super South]
4069 1019 0985 P6VXA Motherboard
4070 1043 802c CUV4X mainboard
4071 1043 8033 A7V Mainboard
4072 1043 803e A7V-E Mainboard
4073 1043 8040 A7M266 Mainboard
4074 1043 8042 A7V133/A7V133-C Mainboard
4075 1106 0000 VT82C686/A PCI to ISA Bridge
4076 1106 0686 VT82C686/A PCI to ISA Bridge
4077 1179 0001 Magnia Z310
4078 147b a702 KG7-Lite Mainboard
4079 0691 VT82C693A/694x [Apollo PRO133x]
4080 1019 0985 P6VXA Motherboard
4081 1179 0001 Magnia Z310
4082 1458 0691 VT82C691 Apollo Pro System Controller
4083 0693 VT82C693 [Apollo Pro Plus]
4084 0698 VT82C693A [Apollo Pro133 AGP]
4085 0926 VT82C926 [Amazon]
4086 1000 VT82C570MV
4087 1106 VT82C570MV
4088 1571 VT82C576M/VT82C586
4089 1595 VT82C595/97 [Apollo VP2/97]
4090 3022 CLE266
4091# This is *not* USB 2.0 as the existing entry suggests
4092 3038 VT82xxxxx UHCI USB 1.1 Controller
4093 0925 1234 USB Controller
4094 1019 0985 P6VXA Motherboard
4095 1019 0a81 L7VTA v1.0 Motherboard (KT400-8235)
4096 1043 808c VT6202 USB2.0 4 port controller
4097 1043 80a1 A7V8X-X motherboard
4098 1043 80ed A7V600 motherboard
4099 1179 0001 Magnia Z310
4100 1458 5004 GA-7VAX Mainboard
4101 1462 7020 K8T NEO 2 motherboard
4102 147b 1407 KV8-MAX3 motherboard
4103 182d 201d CN-029 USB2.0 4 port PCI Card
4104 3040 VT82C586B ACPI
4105 3043 VT86C100A [Rhine]
4106 10bd 0000 VT86C100A Fast Ethernet Adapter
4107 1106 0100 VT86C100A Fast Ethernet Adapter
4108 1186 1400 DFE-530TX rev A
4109 3044 IEEE 1394 Host Controller
4110 1025 005a TravelMate 290
4111 1458 1000 GA-7VT600-1394 Motherboard
4112 1462 702d K8T NEO 2 motherboard
4113 3050 VT82C596 Power Management
4114 3051 VT82C596 Power Management
4115 3053 VT6105M [Rhine-III]
4116 3057 VT82C686 [Apollo Super ACPI]
4117 1019 0985 P6VXA Motherboard
4118 1043 8033 A7V Mainboard
4119 1043 803e A7V-E Mainboard
4120 1043 8040 A7M266 Mainboard
4121 1043 8042 A7V133/A7V133-C Mainboard
4122 1179 0001 Magnia Z310
4123 3058 VT82C686 AC97 Audio Controller
4124 0e11 0097 SoundMax Digital Integrated Audio
4125 0e11 b194 Soundmax integrated digital audio
4126 1019 0985 P6VXA Motherboard
4127 1043 1106 A7V133/A7V133-C Mainboard
4128 1106 4511 Onboard Audio on EP7KXA
4129 1458 7600 Onboard Audio
4130 1462 3091 MS-6309 Onboard Audio
4131 1462 3300 MS-6330 Onboard Audio
4132 15dd 7609 Onboard Audio
4133 3059 VT8233/A/8235/8237 AC97 Audio Controller
4134 1019 0a81 L7VTA v1.0 Motherboard (KT400-8235)
4135 1043 8095 A7V8X Motherboard (Realtek ALC650 codec)
4136 1043 80a1 A7V8X-X Motherboard
4137 1043 80b0 A7V600/K8V Deluxe motherboard (ADI AD1980 codec [SoundMAX])
4138 1106 3059 L7VMM2 Motherboard
4139 1106 4161 K7VT2 motherboard
4140 1297 c160 FX41 motherboard (Realtek ALC650 codec)
4141 1458 a002 GA-7VAX Onboard Audio (Realtek ALC650)
4142 1462 0080 K8T NEO 2 motherboard
4143 1462 3800 KT266 onboard audio
4144 147b 1407 KV8-MAX3 motherboard
4145 3065 VT6102 [Rhine-II]
4146 1043 80a1 A7V8X-X Motherboard
4147 1106 0102 VT6102 [Rhine II] Embeded Ethernet Controller on VT8235
4148 1186 1400 DFE-530TX rev A
4149 1186 1401 DFE-530TX rev B
4150 13b9 1421 LD-10/100AL PCI Fast Ethernet Adapter (rev.B)
4151# This hosts more than just the Intel 537 codec, it also hosts PCtel (SIL33) and SmartLink (SIL34) codecs
4152 3068 AC'97 Modem Controller
4153 1462 309e MS-6309 Saturn Motherboard
4154 3074 VT8233 PCI to ISA Bridge
4155 1043 8052 VT8233A
4156 3091 VT8633 [Apollo Pro266]
4157 3099 VT8366/A/7 [Apollo KT266/A/333]
4158 1043 8064 A7V266-E Mainboard
4159 1043 807f A7V333 Mainboard
4160 1849 3099 K7VT2 motherboard
4161 3101 VT8653 Host Bridge
4162 3102 VT8662 Host Bridge
4163 3103 VT8615 Host Bridge
4164 3104 USB 2.0
4165 1019 0a81 L7VTA v1.0 Motherboard (KT400-8235)
4166 1043 808c A7V8X motherboard
4167 1043 80a1 A7V8X-X motherboard rev 1.01
4168 1043 80ed A7V600 motherboard
4169 1297 f641 FX41 motherboard
4170 1458 5004 GA-7VAX Mainboard
4171 1462 7020 K8T NEO 2 motherboard
4172 147b 1407 KV8-MAX3 motherboard
4173 182d 201d CN-029 USB 2.0 4 port PCI Card
4174 3106 VT6105 [Rhine-III]
4175 1186 1403 DFE-530TX rev C
4176 3108 S3 Unichrome Pro VGA Adapter
4177 3109 VT8233C PCI to ISA Bridge
4178 3112 VT8361 [KLE133] Host Bridge
4179 3116 VT8375 [KM266/KL266] Host Bridge
4180 1297 f641 FX41 motherboard
4181 3118 S3 Unichrome Pro VGA Adapter
4182 3119 VT6120/VT6121/VT6122 Gigabit Ethernet Adapter
4183# found on EPIA M6000/9000 mainboard
4184 3122 VT8623 [Apollo CLE266] integrated CastleRock graphics
4185# found on EPIA M6000/9000 mainboard
4186 3123 VT8623 [Apollo CLE266]
4187 3128 VT8753 [P4X266 AGP]
4188 3133 VT3133 Host Bridge
4189 3147 VT8233A ISA Bridge
4190 3148 P4M266 Host Bridge
4191 3149 VIA VT6420 SATA RAID Controller
4192 1043 80ed A7V600/K8V Deluxe motherboard
4193 1458 b003 GA-7VM400AM(F) Motherboard
4194 1462 7020 K8T Neo 2 Motherboard
4195 147b 1407 KV8-MAX3 motherboard
4196 3156 P/KN266 Host Bridge
4197# on ASUS P4P800
4198 3164 VT6410 ATA133 RAID controller
4199 3168 VT8374 P4X400 Host Controller/AGP Bridge
4200 3177 VT8235 ISA Bridge
4201 1019 0a81 L7VTA v1.0 Motherboard (KT400-8235)
4202 1043 808c A7V8X motherboard
4203 1043 80a1 A7V8X-X motherboard
4204 1297 f641 FX41 motherboard
4205 1458 5001 GA-7VAX Mainboard
4206 1849 3177 K7VT2 motherboard
4207 3178 ProSavageDDR P4N333 Host Bridge
4208 3188 VT8385 [K8T800 AGP] Host Bridge
4209 1043 80a3 K8V Deluxe motherboard
4210 147b 1407 KV8-MAX3 motherboard
4211 3189 VT8377 [KT400/KT600 AGP] Host Bridge
4212 1043 807f A7V8X motherboard
4213 1458 5000 GA-7VAX Mainboard
4214 3204 K8M800
4215 3205 VT8378 [KM400/A] Chipset Host Bridge
4216 1458 5000 GA-7VM400M Motherboard
4217 3218 K8T800M Host Bridge
4218 3227 VT8237 ISA bridge [KT600/K8T800 South]
4219 1043 80ed A7V600 motherboard
4220 1106 3227 DFI KT600-AL Motherboard
4221 1458 5001 GA-7VT600 Motherboard
4222 147b 1407 KV8-MAX3 motherboard
4223 3249 VT6421 IDE RAID Controller
4224 4149 VIA VT6420 (ATA133) Controller
4225 5030 VT82C596 ACPI [Apollo PRO]
4226 6100 VT85C100A [Rhine II]
4227 7204 K8M800
4228# S3 Graphics UniChromeâ„¢ 2D/3D Graphics with motion compensation
4229 7205 VT8378 [S3 UniChrome] Integrated Video
4230 1458 d000 Gigabyte GA-7VM400(A)M(F) Motherboard
4231 8231 VT8231 [PCI-to-ISA Bridge]
4232 8235 VT8235 ACPI
4233 8305 VT8363/8365 [KT133/KM133 AGP]
4234 8391 VT8371 [KX133 AGP]
4235 8501 VT8501 [Apollo MVP4 AGP]
4236 8596 VT82C596 [Apollo PRO AGP]
4237 8597 VT82C597 [Apollo VP3 AGP]
4238 8598 VT82C598/694x [Apollo MVP3/Pro133x AGP]
4239 1019 0985 P6VXA Motherboard
4240 8601 VT8601 [Apollo ProMedia AGP]
4241 8605 VT8605 [PM133 AGP]
4242 8691 VT82C691 [Apollo Pro]
4243 8693 VT82C693 [Apollo Pro Plus] PCI Bridge
4244 b091 VT8633 [Apollo Pro266 AGP]
4245 b099 VT8366/A/7 [Apollo KT266/A/333 AGP]
4246 b101 VT8653 AGP Bridge
4247 b102 VT8362 AGP Bridge
4248 b103 VT8615 AGP Bridge
4249 b112 VT8361 [KLE133] AGP Bridge
4250 b168 VT8235 PCI Bridge
4251 b188 VT8237 PCI bridge [K8T800 South]
4252 147b 1407 KV8-MAX3 motherboard
4253 b198 VT8237 PCI Bridge
4254# 32-Bit PCI bus master Ethernet MAC with standard MII interface
4255 d104 VT8237 Integrated Fast Ethernet Controller
42561107 Stratus Computers
4257 0576 VIA VT82C570MV [Apollo] (Wrong vendor ID!)
42581108 Proteon, Inc.
4259 0100 p1690plus_AA
4260 0101 p1690plus_AB
4261 0105 P1690Plus
4262 0108 P1690Plus
4263 0138 P1690Plus
4264 0139 P1690Plus
4265 013c P1690Plus
4266 013d P1690Plus
42671109 Cogent Data Technologies, Inc.
4268 1400 EM110TX [EX110TX]
4269110a Siemens Nixdorf AG
4270 0002 Pirahna 2-port
4271 0005 Tulip controller, power management, switch extender
4272 0006 FSC PINC (I/O-APIC)
4273 0015 FSC Multiprocessor Interrupt Controller
4274 001d FSC Copernicus Management Controller
4275 007b FSC Remote Service Controller, mailbox device
4276 007c FSC Remote Service Controller, shared memory device
4277 007d FSC Remote Service Controller, SMIC device
4278# Superfastcom-PCI (Commtech, Inc.) or DSCC4 WAN Adapter
4279 2102 DSCC4 PEB/PEF 20534 DMA Supported Serial Communication Controller with 4 Channels
4280 2104 Eicon Diva 2.02 compatible passive ISDN card
4281 3142 SIMATIC NET CP 5613A1 (Profibus Adapter)
4282 4021 SIMATIC NET CP 5512 (Profibus and MPI Cardbus Adapter)
4283 4029 SIMATIC NET CP 5613A2 (Profibus Adapter)
4284 4942 FPGA I-Bus Tracer for MBD
4285 6120 SZB6120
4286110b Chromatic Research Inc.
4287 0001 Mpact Media Processor
4288 0004 Mpact 2
4289110c Mini-Max Technology, Inc.
4290110d Znyx Advanced Systems
4291110e CPU Technology
4292110f Ross Technology
42931110 Powerhouse Systems
4294 6037 Firepower Powerized SMP I/O ASIC
4295 6073 Firepower Powerized SMP I/O ASIC
42961111 Santa Cruz Operation
4297# Also claimed to be RNS or Rockwell International, current PCISIG records list Osicom
42981112 Osicom Technologies Inc
4299 2200 FDDI Adapter
4300 2300 Fast Ethernet Adapter
4301 2340 4 Port Fast Ethernet Adapter
4302 2400 ATM Adapter
43031113 Accton Technology Corporation
4304 1211 SMC2-1211TX
4305 103c 1207 EN-1207D Fast Ethernet Adapter
4306 1113 1211 EN-1207D Fast Ethernet Adapter
4307 1216 EN-1216 Ethernet Adapter
4308 1113 2242 EN2242 10/100 Ethernet Mini-PCI Card
4309 111a 1020 SpeedStream 1020 PCI 10/100 Ethernet Adaptor [EN-1207F-TX ?]
4310 1217 EN-1217 Ethernet Adapter
4311 5105 10Mbps Network card
4312 9211 EN-1207D Fast Ethernet Adapter
4313 1113 9211 EN-1207D Fast Ethernet Adapter
4314 9511 21x4x DEC-Tulip compatible Fast Ethernet
4315 d301 CPWNA100 (Philips wireless PCMCIA)
4316 ec02 SMC 1244TX v3
43171114 Atmel Corporation
4318 0506 802.11b Wireless Network Adaptor (at76c506)
43191115 3D Labs
43201116 Data Translation
4321 0022 DT3001
4322 0023 DT3002
4323 0024 DT3003
4324 0025 DT3004
4325 0026 DT3005
4326 0027 DT3001-PGL
4327 0028 DT3003-PGL
43281117 Datacube, Inc
4329 9500 Max-1C SVGA card
4330 9501 Max-1C image processing
43311118 Berg Electronics
43321119 ICP Vortex Computersysteme GmbH
4333 0000 GDT 6000/6020/6050
4334 0001 GDT 6000B/6010
4335 0002 GDT 6110/6510
4336 0003 GDT 6120/6520
4337 0004 GDT 6530
4338 0005 GDT 6550
4339 0006 GDT 6117/6517
4340 0007 GDT 6127/6527
4341 0008 GDT 6537
4342 0009 GDT 6557/6557-ECC
4343 000a GDT 6115/6515
4344 000b GDT 6125/6525
4345 000c GDT 6535
4346 000d GDT 6555
4347 0010 GDT 6115/6515
4348 0011 GDT 6125/6525
4349 0012 GDT 6535
4350 0013 GDT 6555/6555-ECC
4351 0100 GDT 6117RP/6517RP
4352 0101 GDT 6127RP/6527RP
4353 0102 GDT 6537RP
4354 0103 GDT 6557RP
4355 0104 GDT 6111RP/6511RP
4356 0105 GDT 6121RP/6521RP
4357 0110 GDT 6117RD/6517RD
4358 0111 GDT 6127RD/6527RD
4359 0112 GDT 6537RD
4360 0113 GDT 6557RD
4361 0114 GDT 6111RD/6511RD
4362 0115 GDT 6121RD/6521RD
4363 0118 GDT 6118RD/6518RD/6618RD
4364 0119 GDT 6128RD/6528RD/6628RD
4365 011a GDT 6538RD/6638RD
4366 011b GDT 6558RD/6658RD
4367 0120 GDT 6117RP2/6517RP2
4368 0121 GDT 6127RP2/6527RP2
4369 0122 GDT 6537RP2
4370 0123 GDT 6557RP2
4371 0124 GDT 6111RP2/6511RP2
4372 0125 GDT 6121RP2/6521RP2
4373 0136 GDT 6113RS/6513RS
4374 0137 GDT 6123RS/6523RS
4375 0138 GDT 6118RS/6518RS/6618RS
4376 0139 GDT 6128RS/6528RS/6628RS
4377 013a GDT 6538RS/6638RS
4378 013b GDT 6558RS/6658RS
4379 013c GDT 6533RS/6633RS
4380 013d GDT 6543RS/6643RS
4381 013e GDT 6553RS/6653RS
4382 013f GDT 6563RS/6663RS
4383 0166 GDT 7113RN/7513RN/7613RN
4384 0167 GDT 7123RN/7523RN/7623RN
4385 0168 GDT 7118RN/7518RN/7518RN
4386 0169 GDT 7128RN/7528RN/7628RN
4387 016a GDT 7538RN/7638RN
4388 016b GDT 7558RN/7658RN
4389 016c GDT 7533RN/7633RN
4390 016d GDT 7543RN/7643RN
4391 016e GDT 7553RN/7653RN
4392 016f GDT 7563RN/7663RN
4393 01d6 GDT 4x13RZ
4394 01d7 GDT 4x23RZ
4395 01f6 GDT 8x13RZ
4396 01f7 GDT 8x23RZ
4397 01fc GDT 8x33RZ
4398 01fd GDT 8x43RZ
4399 01fe GDT 8x53RZ
4400 01ff GDT 8x63RZ
4401 0210 GDT 6519RD/6619RD
4402 0211 GDT 6529RD/6629RD
4403 0260 GDT 7519RN/7619RN
4404 0261 GDT 7529RN/7629RN
4405 02ff GDT MAXRP
4406 0300 GDT NEWRX
4407111a Efficient Networks, Inc
4408 0000 155P-MF1 (FPGA)
4409 0002 155P-MF1 (ASIC)
4410 0003 ENI-25P ATM
4411 111a 0000 ENI-25p Miniport ATM Adapter
4412 0005 SpeedStream (LANAI)
4413 111a 0001 ENI-3010 ATM
4414 111a 0009 ENI-3060 ADSL (VPI=0)
4415 111a 0101 ENI-3010 ATM
4416 111a 0109 ENI-3060CO ADSL (VPI=0)
4417 111a 0809 ENI-3060 ADSL (VPI=0 or 8)
4418 111a 0909 ENI-3060CO ADSL (VPI=0 or 8)
4419 111a 0a09 ENI-3060 ADSL (VPI=<0..15>)
4420 0007 SpeedStream ADSL
4421 111a 1001 ENI-3061 ADSL [ASIC]
4422 1203 SpeedStream 1023 Wireless PCI Adapter
4423111b Teledyne Electronic Systems
4424111c Tricord Systems Inc.
4425 0001 Powerbis Bridge
4426111d Integrated Device Technology, Inc.
4427 0001 IDT77201/77211 155Mbps ATM SAR Controller [NICStAR]
4428 0003 IDT77222/77252 155Mbps ATM MICRO ABR SAR Controller
4429 0004 IDT77V252 155Mbps ATM MICRO ABR SAR Controller
4430 0005 IDT77V222 155Mbps ATM MICRO ABR SAR Controller
4431111e Eldec
4432111f Precision Digital Images
4433 4a47 Precision MX Video engine interface
4434 5243 Frame capture bus interface
44351120 EMC Corporation
44361121 Zilog
44371122 Multi-tech Systems, Inc.
44381123 Excellent Design, Inc.
44391124 Leutron Vision AG
44401125 Eurocore
44411126 Vigra
44421127 FORE Systems Inc
4443 0200 ForeRunner PCA-200 ATM
4444 0210 PCA-200PC
4445 0250 ATM
4446 0300 ForeRunner PCA-200EPC ATM
4447 0310 ATM
4448 0400 ForeRunnerHE ATM Adapter
4449 1127 0400 ForeRunnerHE ATM
44501129 Firmworks
4451112a Hermes Electronics Company, Ltd.
4452112b Linotype - Hell AG
4453112c Zenith Data Systems
4454112d Ravicad
4455112e Infomedia Microelectronics Inc.
4456112f Imaging Technology Inc
4457 0000 MVC IC-PCI
4458 0001 MVC IM-PCI Video frame grabber/processor
44591130 Computervision
44601131 Philips Semiconductors
4461 1561 USB 1.1 Host Controller
4462 1562 USB 2.0 Host Controller
4463 3400 SmartPCI56(UCB1500) 56K Modem
4464 5400 TriMedia TM1000/1100
4465 5402 TriMedia TM-1300
4466 1244 0f00 Fritz!Card DSL
4467 7130 SAA7130 Video Broadcast Decoder
4468 5168 0138 LiveView FlyVideo 2000
4469 7133 SAA713X Audio+video broadcast decoder
4470 5168 0138 LifeView FlyVideo 3000
4471 5168 0212 LifeView FlyTV Platinum mini
4472 5168 0502 LifeView FlyDVB-T Duo CardBus
4473# PCI audio and video broadcast decoder (http://www.semiconductors.philips.com/pip/saa7134hl)
4474 7134 SAA7134
4475 1043 4842 TV-FM Card 7134
4476 7135 SAA7135 Audio+video broadcast decoder
4477 7145 SAA7145
4478 7146 SAA7146
4479 110a 0000 Fujitsu/Siemens DVB-C card rev1.5
4480 110a ffff Fujitsu/Siemens DVB-C card rev1.5
4481 1131 4f56 KNC1 DVB-S Budget
4482 1131 4f61 Fujitsu-Siemens Activy DVB-S Budget
4483 114b 2003 DVRaptor Video Edit/Capture Card
4484 11bd 0006 DV500 Overlay
4485 11bd 000a DV500 Overlay
4486 11bd 000f DV500 Overlay
4487 13c2 0000 Siemens/Technotrend/Hauppauge DVB card rev1.3 or rev1.5
4488 13c2 0001 Technotrend/Hauppauge DVB card rev1.3 or rev1.6
4489 13c2 0002 Technotrend/Hauppauge DVB card rev2.1
4490 13c2 0003 Technotrend/Hauppauge DVB card rev2.1
4491 13c2 0004 Technotrend/Hauppauge DVB card rev2.1
4492 13c2 0006 Technotrend/Hauppauge DVB card rev1.3 or rev1.6
4493 13c2 0008 Technotrend/Hauppauge DVB-T
4494 13c2 000a Octal/Technotrend DVB-C for iTV
4495 13c2 1003 Technotrend-Budget / Hauppauge WinTV-NOVA-S DVB card
4496 13c2 1004 Technotrend-Budget / Hauppauge WinTV-NOVA-C DVB card
4497 13c2 1005 Technotrend-Budget / Hauppauge WinTV-NOVA-T DVB card
4498 13c2 100c Technotrend-Budget / Hauppauge WinTV-NOVA-CI DVB card
4499 13c2 100f Technotrend-Budget / Hauppauge WinTV-NOVA-CI DVB card
4500 13c2 1011 Technotrend-Budget / Hauppauge WinTV-NOVA-T DVB card
4501 13c2 1013 SATELCO Multimedia DVB
4502 13c2 1102 Technotrend/Hauppauge DVB card rev2.1
45031132 Mitel Corp.
4504# This is the new official company name. See disclaimer on www.eicon.com for details!
45051133 Eicon Networks Corporation
4506 7901 EiconCard S90
4507 7902 EiconCard S90
4508 7911 EiconCard S91
4509 7912 EiconCard S91
4510 7941 EiconCard S94
4511 7942 EiconCard S94
4512 7943 EiconCard S94
4513 7944 EiconCard S94
4514 b921 EiconCard P92
4515 b922 EiconCard P92
4516 b923 EiconCard P92
4517 e001 Diva Pro 2.0 S/T
4518 e002 Diva 2.0 S/T PCI
4519 e003 Diva Pro 2.0 U
4520 e004 Diva 2.0 U PCI
4521 e005 Diva 2.01 S/T PCI
4522 e006 Diva CT S/T PCI
4523 e007 Diva CT U PCI
4524 e008 Diva CT Lite S/T PCI
4525 e009 Diva CT Lite U PCI
4526 e00a Diva ISDN+V.90 PCI
4527 e00b Diva 2.02 PCI S/T
4528 e00c Diva 2.02 PCI U
4529 e00d Diva ISDN Pro 3.0 PCI
4530 e00e Diva ISDN+CT S/T PCI Rev 2
4531 e010 Diva Server BRI-2M PCI
4532 110a 0021 Fujitsu Siemens ISDN S0
4533 8001 0014 Diva Server BRI-2M PCI Cornet NQ
4534 e011 Diva Server BRI S/T Rev 2
4535 e012 Diva Server 4BRI-8M PCI
4536 8001 0014 Diva Server 4BRI-8M PCI Cornet NQ
4537 e013 Diva Server 4BRI Rev 2
4538 1133 1300 Diva Server V-4BRI-8
4539 1133 e013 Diva Server 4BRI-8M 2.0 PCI
4540 8001 0014 Diva Server 4BRI-8M 2.0 PCI Cornet NQ
4541 e014 Diva Server PRI-30M PCI
4542 0008 0100 Diva Server PRI-30M PCI
4543 8001 0014 Diva Server PRI-30M PCI Cornet NQ
4544 e015 DIVA Server PRI Rev 2
4545 1133 e015 Diva Server PRI 2.0 PCI
4546 8001 0014 Diva Server PRI 2.0 PCI Cornet NQ
4547 e016 Diva Server Voice 4BRI PCI
4548 8001 0014 Diva Server PRI Cornet NQ
4549 e017 Diva Server Voice 4BRI Rev 2
4550 1133 e017 Diva Server Voice 4BRI-8M 2.0 PCI
4551 8001 0014 Diva Server Voice 4BRI-8M 2.0 PCI Cornet NQ
4552 e018 Diva Server BRI-2M 2.0 PCI
4553 1133 1800 Diva Server V-BRI-2
4554 1133 e018 Diva Server BRI-2M 2.0 PCI
4555 8001 0014 Diva Server BRI-2M 2.0 PCI Cornet NQ
4556 e019 Diva Server Voice PRI Rev 2
4557 1133 e019 Diva Server Voice PRI 2.0 PCI
4558 8001 0014 Diva Server Voice PRI 2.0 PCI Cornet NQ
4559 e01a Diva Server 2FX
4560 e01b Diva Server Voice BRI-2M 2.0 PCI
4561 1133 e01b Diva Server Voice BRI-2M 2.0 PCI
4562 8001 0014 Diva Server Voice BRI-2M 2.0 PCI Cornet NQ
4563 e01c Diva Server PRI Rev 3
4564 1133 1c01 Diva Server PRI/E1/T1-8
4565 1133 1c02 Diva Server PRI/T1-24
4566 1133 1c03 Diva Server PRI/E1-30
4567 1133 1c04 Diva Server PRI/E1/T1
4568 1133 1c05 Diva Server V-PRI/T1-24
4569 1133 1c06 Diva Server V-PRI/E1-30
4570 1133 1c07 Diva Server PRI/E1/T1-8 Cornet NQ
4571 1133 1c08 Diva Server PRI/T1-24 Cornet NQ
4572 1133 1c09 Diva Server PRI/E1-30 Cornet NQ
4573 1133 1c0a Diva Server PRI/E1/T1 Cornet NQ
4574 1133 1c0b Diva Server V-PRI/T1-24 Cornet NQ
4575 1133 1c0c Diva Server V-PRI/E1-30 Cornet NQ
4576 e01e Diva Server 2PRI
4577 1133 1e00 Diva Server V-2PRI/E1-60
4578 1133 1e01 Diva Server V-2PRI/T1-48
4579 1133 1e02 Diva Server 2PRI/E1-60
4580 1133 1e03 Diva Server 2PRI/T1-48
4581 e020 Diva Server 4PRI
4582 1133 2000 Diva Server V-4PRI/E1-120
4583 1133 2001 Diva Server V-4PRI/T1-96
4584 1133 2002 Diva Server 4PRI/E1-120
4585 1133 2003 Diva Server 4PRI/T1-96
4586 e024 Diva Server Analog-4P
4587 1133 2400 Diva Server V-Analog-4P
4588 1133 e024 Diva Server Analog-4P
4589 e028 Diva Server Analog-8P
4590 1133 2800 Diva Server V-Analog-8P
4591 1133 e028 Diva Server Analog-8P
45921134 Mercury Computer Systems
4593 0001 Raceway Bridge
4594 0002 Dual PCI to RapidIO Bridge
45951135 Fuji Xerox Co Ltd
4596 0001 Printer controller
45971136 Momentum Data Systems
45981137 Cisco Systems Inc
45991138 Ziatech Corporation
4600 8905 8905 [STD 32 Bridge]
46011139 Dynamic Pictures, Inc
4602 0001 VGA Compatable 3D Graphics
4603113a FWB Inc
4604113b Network Computing Devices
4605113c Cyclone Microsystems, Inc.
4606 0000 PCI-9060 i960 Bridge
4607 0001 PCI-SDK [PCI i960 Evaluation Platform]
4608 0911 PCI-911 [i960Jx-based Intelligent I/O Controller]
4609 0912 PCI-912 [i960CF-based Intelligent I/O Controller]
4610 0913 PCI-913
4611 0914 PCI-914 [I/O Controller w/ secondary PCI bus]
4612113d Leading Edge Products Inc
4613113e Sanyo Electric Co - Computer Engineering Dept
4614113f Equinox Systems, Inc.
4615 0808 SST-64P Adapter
4616 1010 SST-128P Adapter
4617 80c0 SST-16P DB Adapter
4618 80c4 SST-16P RJ Adapter
4619 80c8 SST-16P Adapter
4620 8888 SST-4P Adapter
4621 9090 SST-8P Adapter
46221140 Intervoice Inc
46231141 Crest Microsystem Inc
46241142 Alliance Semiconductor Corporation
4625 3210 AP6410
4626 6422 ProVideo 6422
4627 6424 ProVideo 6424
4628 6425 ProMotion AT25
4629 643d ProMotion AT3D
46301143 NetPower, Inc
46311144 Cincinnati Milacron
4632 0001 Noservo controller
46331145 Workbit Corporation
4634 8007 NinjaSCSI-32 Workbit
4635 f007 NinjaSCSI-32 KME
4636 f010 NinjaSCSI-32 Workbit
4637 f012 NinjaSCSI-32 Logitec
4638 f013 NinjaSCSI-32 Logitec
4639 f015 NinjaSCSI-32 Melco
46401146 Force Computers
46411147 Interface Corp
4642# Formerly (Schneider & Koch)
46431148 SysKonnect
4644 4000 FDDI Adapter
4645 0e11 b03b Netelligent 100 FDDI DAS Fibre SC
4646 0e11 b03c Netelligent 100 FDDI SAS Fibre SC
4647 0e11 b03d Netelligent 100 FDDI DAS UTP
4648 0e11 b03e Netelligent 100 FDDI SAS UTP
4649 0e11 b03f Netelligent 100 FDDI SAS Fibre MIC
4650 1148 5521 FDDI SK-5521 (SK-NET FDDI-UP)
4651 1148 5522 FDDI SK-5522 (SK-NET FDDI-UP DAS)
4652 1148 5541 FDDI SK-5541 (SK-NET FDDI-FP)
4653 1148 5543 FDDI SK-5543 (SK-NET FDDI-LP)
4654 1148 5544 FDDI SK-5544 (SK-NET FDDI-LP DAS)
4655 1148 5821 FDDI SK-5821 (SK-NET FDDI-UP64)
4656 1148 5822 FDDI SK-5822 (SK-NET FDDI-UP64 DAS)
4657 1148 5841 FDDI SK-5841 (SK-NET FDDI-FP64)
4658 1148 5843 FDDI SK-5843 (SK-NET FDDI-LP64)
4659 1148 5844 FDDI SK-5844 (SK-NET FDDI-LP64 DAS)
4660 4200 Token Ring adapter
4661 4300 SK-98xx Gigabit Ethernet Server Adapter
4662 1148 9821 SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T)
4663 1148 9822 SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link)
4664 1148 9841 SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX)
4665 1148 9842 SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link)
4666 1148 9843 SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX)
4667 1148 9844 SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link)
4668 1148 9861 SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition)
4669 1148 9862 SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link)
4670 1148 9871 SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX)
4671 1148 9872 SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
4672 1259 2970 AT-2970SX Gigabit Ethernet Adapter
4673 1259 2971 AT-2970LX Gigabit Ethernet Adapter
4674 1259 2972 AT-2970TX Gigabit Ethernet Adapter
4675 1259 2973 AT-2971SX Gigabit Ethernet Adapter
4676 1259 2974 AT-2971T Gigabit Ethernet Adapter
4677 1259 2975 AT-2970SX/2SC Gigabit Ethernet Adapter
4678 1259 2976 AT-2970LX/2SC Gigabit Ethernet Adapter
4679 1259 2977 AT-2970TX/2TX Gigabit Ethernet Adapter
4680 4320 SK-98xx V2.0 Gigabit Ethernet Adapter
4681 1148 0121 Marvell RDK-8001 Adapter
4682 1148 0221 Marvell RDK-8002 Adapter
4683 1148 0321 Marvell RDK-8003 Adapter
4684 1148 0421 Marvell RDK-8004 Adapter
4685 1148 0621 Marvell RDK-8006 Adapter
4686 1148 0721 Marvell RDK-8007 Adapter
4687 1148 0821 Marvell RDK-8008 Adapter
4688 1148 0921 Marvell RDK-8009 Adapter
4689 1148 1121 Marvell RDK-8011 Adapter
4690 1148 1221 Marvell RDK-8012 Adapter
4691 1148 3221 SK-9521 V2.0 10/100/1000Base-T Adapter
4692 1148 5021 SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter
4693 1148 5041 SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter
4694 1148 5043 SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter
4695 1148 5051 SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter
4696 1148 5061 SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
4697 1148 5071 SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
4698 1148 9521 SK-9521 10/100/1000Base-T Adapter
4699 4400 SK-9Dxx Gigabit Ethernet Adapter
4700 4500 SK-9Mxx Gigabit Ethernet Adapter
4701 9000 SK-9Sxx Gigabit Ethernet Server Adapter PCI-X
4702 9843 [Fujitsu] Gigabit Ethernet
4703 9e00 SK-9Exx 10/100/1000Base-T Adapter
4704 1148 2100 SK-9E21 Server Adapter
4705 1148 21d0 SK-9E21D 10/100/1000Base-T Adapter
4706 1148 2200 SK-9E22 Server Adapter
4707 1148 8100 SK-9E81 Server Adapter
4708 1148 8200 SK-9E82 Server Adapter
4709 1148 9100 SK-9E91 Server Adapter
4710 1148 9200 SK-9E92 Server Adapter
47111149 Win System Corporation
4712114a VMIC
4713 5579 VMIPCI-5579 (Reflective Memory Card)
4714 5587 VMIPCI-5587 (Reflective Memory Card)
4715 6504 VMIC PCI 7755 FPGA
4716 7587 VMIVME-7587
4717114b Canopus Co., Ltd
4718114c Annabooks
4719114d IC Corporation
4720114e Nikon Systems Inc
4721114f Digi International
4722 0002 AccelePort EPC
4723 0003 RightSwitch SE-6
4724 0004 AccelePort Xem
4725 0005 AccelePort Xr
4726 0006 AccelePort Xr,C/X
4727 0009 AccelePort Xr/J
4728 000a AccelePort EPC/J
4729 000c DataFirePRIme T1 (1-port)
4730 000d SyncPort 2-Port (x.25/FR)
4731 0011 AccelePort 8r EIA-232 (IBM)
4732 0012 AccelePort 8r EIA-422
4733 0013 AccelePort Xr
4734 0014 AccelePort 8r EIA-422
4735 0015 AccelePort Xem
4736 0016 AccelePort EPC/X
4737 0017 AccelePort C/X
4738 001a DataFirePRIme E1 (1-port)
4739 001b AccelePort C/X (IBM)
4740 001d DataFire RAS T1/E1/PRI
4741 114f 0050 DataFire RAS E1 Adapter
4742 114f 0051 DataFire RAS Dual E1 Adapter
4743 114f 0052 DataFire RAS T1 Adapter
4744 114f 0053 DataFire RAS Dual T1 Adapter
4745 0023 AccelePort RAS
4746 0024 DataFire RAS B4 ST/U
4747 114f 0030 DataFire RAS BRI U Adapter
4748 114f 0031 DataFire RAS BRI S/T Adapter
4749 0026 AccelePort 4r 920
4750 0027 AccelePort Xr 920
4751 0028 ClassicBoard 4
4752 0029 ClassicBoard 8
4753 0034 AccelePort 2r 920
4754 0035 DataFire DSP T1/E1/PRI cPCI
4755 0040 AccelePort Xp
4756 0042 AccelePort 2p
4757 0043 AccelePort 4p
4758 0044 AccelePort 8p
4759 0045 AccelePort 16p
4760 004e AccelePort 32p
4761 0070 Datafire Micro V IOM2 (Europe)
4762 0071 Datafire Micro V (Europe)
4763 0072 Datafire Micro V IOM2 (North America)
4764 0073 Datafire Micro V (North America)
4765 00b0 Digi Neo 4
4766 00b1 Digi Neo 8
4767 00c8 Digi Neo 2 DB9
4768 00c9 Digi Neo 2 DB9 PRI
4769 00ca Digi Neo 2 RJ45
4770 00cb Digi Neo 2 RJ45 PRI
4771 00d0 ClassicBoard 4 422
4772 00d1 ClassicBoard 8 422
4773 6001 Avanstar
47741150 Thinking Machines Corp
47751151 JAE Electronics Inc.
47761152 Megatek
47771153 Land Win Electronic Corp
47781154 Melco Inc
47791155 Pine Technology Ltd
47801156 Periscope Engineering
47811157 Avsys Corporation
47821158 Voarx R & D Inc
4783 3011 Tokenet/vg 1001/10m anylan
4784 9050 Lanfleet/Truevalue
4785 9051 Lanfleet/Truevalue
47861159 Mutech Corp
4787 0001 MV-1000
4788115a Harlequin Ltd
4789115b Parallax Graphics
4790115c Photron Ltd.
4791115d Xircom
4792 0003 Cardbus Ethernet 10/100
4793 1014 0181 10/100 EtherJet Cardbus Adapter
4794 1014 1181 10/100 EtherJet Cardbus Adapter
4795 1014 8181 10/100 EtherJet Cardbus Adapter
4796 1014 9181 10/100 EtherJet Cardbus Adapter
4797 115d 0181 Cardbus Ethernet 10/100
4798 115d 1181 Cardbus Ethernet 10/100
4799 1179 0181 Cardbus Ethernet 10/100
4800 8086 8181 EtherExpress PRO/100 Mobile CardBus 32 Adapter
4801 8086 9181 EtherExpress PRO/100 Mobile CardBus 32 Adapter
4802 0005 Cardbus Ethernet 10/100
4803 1014 0182 10/100 EtherJet Cardbus Adapter
4804 1014 1182 10/100 EtherJet Cardbus Adapter
4805 115d 0182 Cardbus Ethernet 10/100
4806 115d 1182 Cardbus Ethernet 10/100
4807 0007 Cardbus Ethernet 10/100
4808 1014 0182 10/100 EtherJet Cardbus Adapter
4809 1014 1182 10/100 EtherJet Cardbus Adapter
4810 115d 0182 Cardbus Ethernet 10/100
4811 115d 1182 Cardbus Ethernet 10/100
4812 000b Cardbus Ethernet 10/100
4813 1014 0183 10/100 EtherJet Cardbus Adapter
4814 115d 0183 Cardbus Ethernet 10/100
4815 000c Mini-PCI V.90 56k Modem
4816 000f Cardbus Ethernet 10/100
4817 1014 0183 10/100 EtherJet Cardbus Adapter
4818 115d 0183 Cardbus Ethernet 10/100
4819 00d4 Mini-PCI K56Flex Modem
4820 0101 Cardbus 56k modem
4821 115d 1081 Cardbus 56k Modem
4822 0103 Cardbus Ethernet + 56k Modem
4823 1014 9181 Cardbus 56k Modem
4824 1115 1181 Cardbus Ethernet 100 + 56k Modem
4825 115d 1181 CBEM56G-100 Ethernet + 56k Modem
4826 8086 9181 PRO/100 LAN + Modem56 CardBus
4827115e Peer Protocols Inc
4828115f Maxtor Corporation
48291160 Megasoft Inc
48301161 PFU Limited
48311162 OA Laboratory Co Ltd
48321163 Rendition
4833 0001 Verite 1000
4834 2000 Verite V2000/V2100/V2200
4835 1092 2000 Stealth II S220
48361164 Advanced Peripherals Technologies
48371165 Imagraph Corporation
4838 0001 Motion TPEG Recorder/Player with audio
48391166 ServerWorks
4840 0000 CMIC-LE
4841 0005 CNB20-LE Host Bridge
4842 0006 CNB20HE Host Bridge
4843 0007 CNB20-LE Host Bridge
4844 0008 CNB20HE Host Bridge
4845 0009 CNB20LE Host Bridge
4846 0010 CIOB30
4847 0011 CMIC-HE
4848 0012 CMIC-WS Host Bridge (GC-LE chipset)
4849 0013 CNB20-HE Host Bridge
4850 0014 CMIC-LE Host Bridge (GC-LE chipset)
4851 0015 CMIC-GC Host Bridge
4852 0016 CMIC-GC Host Bridge
4853 0017 GCNB-LE Host Bridge
4854 0101 CIOB-X2 PCI-X I/O Bridge
4855 0110 CIOB-E I/O Bridge with Gigabit Ethernet
4856 0200 OSB4 South Bridge
4857 0201 CSB5 South Bridge
4858 4c53 1080 CT8 mainboard
4859 0203 CSB6 South Bridge
4860 0211 OSB4 IDE Controller
4861 0212 CSB5 IDE Controller
4862 4c53 1080 CT8 mainboard
4863 0213 CSB6 RAID/IDE Controller
4864 0217 CSB6 IDE Controller
4865 0220 OSB4/CSB5 OHCI USB Controller
4866 4c53 1080 CT8 mainboard
4867 0221 CSB6 OHCI USB Controller
4868 0225 CSB5 LPC bridge
4869# cancelled
4870 4c53 1080 CT8 mainboard
4871 0227 GCLE-2 Host Bridge
4872 0230 CSB5 LPC bridge
4873 4c53 1080 CT8 mainboard
4874 0240 K2 SATA
4875 0241 K2 SATA
4876 0242 K2 SATA
48771167 Mutoh Industries Inc
48781168 Thine Electronics Inc
48791169 Centre for Development of Advanced Computing
4880116a Polaris Communications
4881 6100 Bus/Tag Channel
4882 6800 Escon Channel
4883 7100 Bus/Tag Channel
4884 7800 Escon Channel
4885116b Connectware Inc
4886116c Intelligent Resources Integrated Systems
4887116d Martin-Marietta
4888116e Electronics for Imaging
4889116f Workstation Technology
48901170 Inventec Corporation
48911171 Loughborough Sound Images Plc
48921172 Altera Corporation
48931173 Adobe Systems, Inc
48941174 Bridgeport Machines
48951175 Mitron Computer Inc.
48961176 SBE Incorporated
48971177 Silicon Engineering
48981178 Alfa, Inc.
4899 afa1 Fast Ethernet Adapter
49001179 Toshiba America Info Systems
4901 0103 EX-IDE Type-B
4902 0404 DVD Decoder card
4903 0406 Tecra Video Capture device
4904 0407 DVD Decoder card (Version 2)
4905 0601 CPU to PCI bridge
4906 0603 ToPIC95 PCI to CardBus Bridge for Notebooks
4907 060a ToPIC95
4908 060f ToPIC97
4909 0617 ToPIC100 PCI to Cardbus Bridge with ZV Support
4910 0618 CPU to PCI and PCI to ISA bridge
4911# Claimed to be Lucent DSP1645 [Mars], but that's apparently incorrect. Does anyone know the correct ID?
4912 0701 FIR Port
4913 0804 TC6371AF SmartMedia Controller
4914 0805 SD TypA Controller
4915 0d01 FIR Port Type-DO
4916 1179 0001 FIR Port Type-DO
4917117a A-Trend Technology
4918117b L G Electronics, Inc.
4919117c Atto Technology
4920117d Becton & Dickinson
4921117e T/R Systems
4922117f Integrated Circuit Systems
49231180 Ricoh Co Ltd
4924 0465 RL5c465
4925 0466 RL5c466
4926 0475 RL5c475
4927 144d c006 vpr Matrix 170B4 CardBus bridge
4928 0476 RL5c476 II
4929 1014 0185 ThinkPad A/T/X Series
4930 104d 80df Vaio PCG-FX403
4931 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
4932 14ef 0220 PCD-RP-220S
4933 0477 RL5c477
4934 0478 RL5c478
4935 1014 0184 ThinkPad A30p (2653-64G)
4936 0522 R5C522 IEEE 1394 Controller
4937 1014 01cf ThinkPad A30p (2653-64G)
4938 0551 R5C551 IEEE 1394 Controller
4939 144d c006 vpr Matrix 170B4
4940 0552 R5C552 IEEE 1394 Controller
4941 1014 0511 ThinkPad A/T/X Series
4942 0576 R5C576 SD Bus Host Adapter
4943 0592 R5C592 Memory Stick Bus Host Adapter
49441181 Telmatics International
49451183 Fujikura Ltd
49461184 Forks Inc
49471185 Dataworld International Ltd
49481186 D-Link System Inc
4949 0100 DC21041
4950 1002 DL10050 Sundance Ethernet
4951 1186 1002 DFE-550TX
4952 1186 1012 DFE-580TX
4953 1025 AirPlus Xtreme G DWL-G650 Adapter
4954 1026 AirXpert DWL-AG650 Wireless Cardbus Adapter
4955 1043 AirXpert DWL-AG650 Wireless Cardbus Adapter
4956 1300 RTL8139 Ethernet
4957 1186 1300 DFE-538TX 10/100 Ethernet Adapter
4958 1186 1301 DFE-530TX+ 10/100 Ethernet Adapter
4959 1340 DFE-690TXD CardBus PC Card
4960 1541 DFE-680TXD CardBus PC Card
4961 1561 DRP-32TXD Cardbus PC Card
4962 2027 AirPlus Xtreme G DWL-G520 Adapter
4963 3203 AirPlus Xtreme G DWL-G520 Adapter
4964 3300 DWL-510 2.4GHz Wireless PCI Adapter
4965 3a03 AirPro DWL-A650 Wireless Cardbus Adapter(rev.B)
4966 3a04 AirPro DWL-AB650 Multimode Wireless Cardbus Adapter
4967 3a05 AirPro DWL-AB520 Multimode Wireless PCI Adapter
4968 3a07 AirXpert DWL-AG650 Wireless Cardbus Adapter
4969 3a08 AirXpert DWL-AG520 Wireless PCI Adapter
4970 3a10 AirXpert DWL-AG650 Wireless Cardbus Adapter(rev.B)
4971 3a11 AirXpert DWL-AG520 Wireless PCI Adapter(rev.B)
4972 3a12 AirPlus DWL-G650 Wireless Cardbus Adapter(rev.C)
4973 3a13 AirPlus DWL-G520 Wireless PCI Adapter(rev.B)
4974 3a14 AirPremier DWL-AG530 Wireless PCI Adapter
4975 3a63 AirXpert DWL-AG660 Wireless Cardbus Adapter
4976 3b05 DWL-G650+ CardBus PC Card
4977 4000 DL2000-based Gigabit Ethernet
4978 4300 DGE-528T Gigabit Ethernet Adapter
4979 4c00 Gigabit Ethernet Adapter
4980 1186 4c00 DGE-530T Gigabit Ethernet Adapter
4981 8400 D-Link DWL-650+ CardBus PC Card
49821187 Advanced Technology Laboratories, Inc.
49831188 Shima Seiki Manufacturing Ltd.
49841189 Matsushita Electronics Co Ltd
4985118a Hilevel Technology
4986118b Hypertec Pty Limited
4987118c Corollary, Inc
4988 0014 PCIB [C-bus II to PCI bus host bridge chip]
4989 1117 Intel 8-way XEON Profusion Chipset [Cache Coherency Filter]
4990118d BitFlow Inc
4991 0001 Raptor-PCI framegrabber
4992 0012 Model 12 Road Runner Frame Grabber
4993 0014 Model 14 Road Runner Frame Grabber
4994 0024 Model 24 Road Runner Frame Grabber
4995 0044 Model 44 Road Runner Frame Grabber
4996 0112 Model 12 Road Runner Frame Grabber
4997 0114 Model 14 Road Runner Frame Grabber
4998 0124 Model 24 Road Runner Frame Grabber
4999 0144 Model 44 Road Runner Frame Grabber
5000 0212 Model 12 Road Runner Frame Grabber
5001 0214 Model 14 Road Runner Frame Grabber
5002 0224 Model 24 Road Runner Frame Grabber
5003 0244 Model 44 Road Runner Frame Grabber
5004 0312 Model 12 Road Runner Frame Grabber
5005 0314 Model 14 Road Runner Frame Grabber
5006 0324 Model 24 Road Runner Frame Grabber
5007 0344 Model 44 Road Runner Frame Grabber
5008118e Hermstedt GmbH
5009118f Green Logic
50101190 Tripace
5011 c731 TP-910/920/940 PCI Ultra(Wide) SCSI Adapter
50121191 Artop Electronic Corp
5013 0003 SCSI Cache Host Adapter
5014 0004 ATP8400
5015 0005 ATP850UF
5016 0006 ATP860 NO-BIOS
5017 0007 ATP860
5018 0008 ATP865 NO-ROM
5019 0009 ATP865
5020 8002 AEC6710 SCSI-2 Host Adapter
5021 8010 AEC6712UW SCSI
5022 8020 AEC6712U SCSI
5023 8030 AEC6712S SCSI
5024 8040 AEC6712D SCSI
5025 8050 AEC6712SUW SCSI
5026 8060 AEC6712 SCSI
5027 8080 AEC67160 SCSI
5028 8081 AEC67160S SCSI
5029 808a AEC67162 2-ch. LVD SCSI
50301192 Densan Company Ltd
50311193 Zeitnet Inc.
5032 0001 1221
5033 0002 1225
50341194 Toucan Technology
50351195 Ratoc System Inc
50361196 Hytec Electronics Ltd
50371197 Gage Applied Sciences, Inc.
5038 010c CompuScope 82G 8bit 2GS/s Analog Input Card
50391198 Lambda Systems Inc
50401199 Attachmate Corporation
5041119a Mind Share, Inc.
5042119b Omega Micro Inc.
5043 1221 82C092G
5044119c Information Technology Inst.
5045119d Bug, Inc. Sapporo Japan
5046119e Fujitsu Microelectronics Ltd.
5047 0001 FireStream 155
5048 0003 FireStream 50
5049119f Bull HN Information Systems
505011a0 Convex Computer Corporation
505111a1 Hamamatsu Photonics K.K.
505211a2 Sierra Research and Technology
505311a3 Deuretzbacher GmbH & Co. Eng. KG
505411a4 Barco Graphics NV
505511a5 Microunity Systems Eng. Inc
505611a6 Pure Data Ltd.
505711a7 Power Computing Corp.
505811a8 Systech Corp.
505911a9 InnoSys Inc.
5060 4240 AMCC S933Q Intelligent Serial Card
506111aa Actel
5062# Formerly Galileo Technology, Inc.
506311ab Marvell Technology Group Ltd.
5064 0146 GT-64010/64010A System Controller
5065 138f W8300 802.11 Adapter (rev 07)
5066 1fa6 Marvell W8300 802.11 Adapter
5067 1fa7 88W8310 and 88W8000G [Libertas] 802.11g client chipset
5068 4320 Gigabit Ethernet Controller
5069 1019 0f38 Marvell 88E8001 Gigabit Ethernet Controller (ECS)
5070 1019 8001 Marvell 88E8001 Gigabit Ethernet Controller (ECS)
5071 1043 173c Marvell 88E8001 Gigabit Ethernet Controller (Asus)
5072 1043 811a Marvell 88E8001 Gigabit Ethernet Controller (Asus)
5073 105b 0c19 Marvell 88E8001 Gigabit Ethernet Controller (Foxconn)
5074 10b8 b452 SMC EZ Card 1000 (SMC9452TXV.2)
5075 11ab 0121 Marvell RDK-8001
5076 11ab 0321 Marvell RDK-8003
5077 11ab 1021 Marvell RDK-8010
5078 11ab 5021 Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (64 bit)
5079 11ab 9521 Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (32 bit)
5080 1458 e000 Marvell 88E8001 Gigabit Ethernet Controller (Gigabyte)
5081 147b 1406 Marvell 88E8001 Gigabit Ethernet Controller (Abit)
5082 15d4 0047 Marvell 88E8001 Gigabit Ethernet Controller (Iwill)
5083 1695 9025 Marvell 88E8001 Gigabit Ethernet Controller (Epox)
5084 17f2 1c03 Marvell 88E8001 Gigabit Ethernet Controller (Albatron)
5085 270f 2803 Marvell 88E8001 Gigabit Ethernet Controller (Chaintech)
5086 4350 Fast Ethernet Controller
5087 1179 0001 Marvell 88E8035 Fast Ethernet Controller (Toshiba)
5088 11ab 3521 Marvell RDK-8035
5089 1854 000d Marvell 88E8035 Fast Ethernet Controller (LGE)
5090 1854 000e Marvell 88E8035 Fast Ethernet Controller (LGE)
5091 1854 000f Marvell 88E8035 Fast Ethernet Controller (LGE)
5092 1854 0011 Marvell 88E8035 Fast Ethernet Controller (LGE)
5093 1854 0012 Marvell 88E8035 Fast Ethernet Controller (LGE)
5094 1854 0016 Marvell 88E8035 Fast Ethernet Controller (LGE)
5095 1854 0017 Marvell 88E8035 Fast Ethernet Controller (LGE)
5096 1854 0018 Marvell 88E8035 Fast Ethernet Controller (LGE)
5097 1854 0019 Marvell 88E8035 Fast Ethernet Controller (LGE)
5098 1854 001c Marvell 88E8035 Fast Ethernet Controller (LGE)
5099 1854 001e Marvell 88E8035 Fast Ethernet Controller (LGE)
5100 1854 0020 Marvell 88E8035 Fast Ethernet Controller (LGE)
5101 4351 Fast Ethernet Controller
5102 107b 4009 Marvell 88E8036 Fast Ethernet Controller (Wistron)
5103 10f7 8338 Marvell 88E8036 Fast Ethernet Controller (Panasonic)
5104 1179 0001 Marvell 88E8036 Fast Ethernet Controller (Toshiba)
5105 1179 ff00 Marvell 88E8036 Fast Ethernet Controller (Compal)
5106 1179 ff10 Marvell 88E8036 Fast Ethernet Controller (Inventec)
5107 11ab 3621 Marvell RDK-8036
5108 13d1 ac12 Abocom EFE3K - 10/100 Ethernet Expresscard
5109 161f 203d Marvell 88E8036 Fast Ethernet Controller (Arima)
5110 1854 000d Marvell 88E8036 Fast Ethernet Controller (LGE)
5111 1854 000e Marvell 88E8036 Fast Ethernet Controller (LGE)
5112 1854 000f Marvell 88E8036 Fast Ethernet Controller (LGE)
5113 1854 0011 Marvell 88E8036 Fast Ethernet Controller (LGE)
5114 1854 0012 Marvell 88E8036 Fast Ethernet Controller (LGE)
5115 1854 0016 Marvell 88E8036 Fast Ethernet Controller (LGE)
5116 1854 0017 Marvell 88E8036 Fast Ethernet Controller (LGE)
5117 1854 0018 Marvell 88E8036 Fast Ethernet Controller (LGE)
5118 1854 0019 Marvell 88E8036 Fast Ethernet Controller (LGE)
5119 1854 001c Marvell 88E8036 Fast Ethernet Controller (LGE)
5120 1854 001e Marvell 88E8036 Fast Ethernet Controller (LGE)
5121 1854 0020 Marvell 88E8036 Fast Ethernet Controller (LGE)
5122 4360 Gigabit Ethernet Controller
5123 1043 8134 Marvell 88E8052 Gigabit Ethernet Controller (Asus)
5124 107b 4009 Marvell 88E8052 Gigabit Ethernet Controller (Wistron)
5125 11ab 5221 Marvell RDK-8052
5126 1458 e000 Marvell 88E8052 Gigabit Ethernet Controller (Gigabyte)
5127 1462 052c Marvell 88E8052 Gigabit Ethernet Controller (MSI)
5128 1849 8052 Marvell 88E8052 Gigabit Ethernet Controller (ASRock)
5129 1940 e000 Marvell 88E8052 Gigabit Ethernet Controller (Gigabyte)
5130 a0a0 0509 Marvell 88E8052 Gigabit Ethernet Controller (Aopen)
5131 4361 Gigabit Ethernet Controller
5132 107b 3015 Marvell 88E8050 Gigabit Ethernet Controller (Gateway)
5133 11ab 5021 Marvell 88E8050 Gigabit Ethernet Controller (Intel)
5134 8086 3063 D925XCVLK mainboard
5135 4362 Gigabit Ethernet Controller
5136 103c 2a0d Marvell 88E8053 Gigabit Ethernet Controller (Asus)
5137 1043 8142 Marvell 88E8053 Gigabit Ethernet Controller (Asus)
5138 109f 3197 Marvell 88E8053 Gigabit Ethernet Controller (Trigem)
5139 10f7 8338 Marvell 88E8053 Gigabit Ethernet Controller (Panasonic)
5140 10fd a430 Marvell 88E8053 Gigabit Ethernet Controller (SOYO)
5141 1179 0001 Marvell 88E8053 Gigabit Ethernet Controller (Toshiba)
5142 1179 ff00 Marvell 88E8053 Gigabit Ethernet Controller (Compal)
5143 1179 ff10 Marvell 88E8053 Gigabit Ethernet Controller (Inventec)
5144 11ab 5321 Marvell RDK-8053
5145 1297 c240 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
5146 1297 c241 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
5147 1297 c242 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
5148 1297 c243 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
5149 1297 c244 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
5150 13d1 ac11 Abocom EGE5K - Giga Ethernet Expresscard
5151 1458 e000 Marvell 88E8053 Gigabit Ethernet Controller (Gigabyte)
5152 1462 058c Marvell 88E8053 Gigabit Ethernet Controller (MSI)
5153 14c0 0012 Marvell 88E8053 Gigabit Ethernet Controller (Compal)
5154 1558 04a0 Marvell 88E8053 Gigabit Ethernet Controller (Clevo)
5155 15bd 1003 Marvell 88E8053 Gigabit Ethernet Controller (DFI)
5156 161f 203c Marvell 88E8053 Gigabit Ethernet Controller (Arima)
5157 161f 203d Marvell 88E8053 Gigabit Ethernet Controller (Arima)
5158 1695 9029 Marvell 88E8053 Gigabit Ethernet Controller (Epox)
5159 17f2 2c08 Marvell 88E8053 Gigabit Ethernet Controller (Albatron)
5160 17ff 0585 Marvell 88E8053 Gigabit Ethernet Controller (Quanta)
5161 1849 8053 Marvell 88E8053 Gigabit Ethernet Controller (ASRock)
5162 1854 000b Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5163 1854 000c Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5164 1854 0010 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5165 1854 0013 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5166 1854 0014 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5167 1854 0015 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5168 1854 001a Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5169 1854 001b Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5170 1854 001d Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5171 1854 001f Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5172 1854 0021 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5173 1854 0022 Marvell 88E8053 Gigabit Ethernet Controller (LGE)
5174 1940 e000 Marvell 88E8053 Gigabit Ethernet Controller (Gigabyte)
5175 270f 2801 Marvell 88E8053 Gigabit Ethernet Controller (Chaintech)
5176 a0a0 0506 Marvell 88E8053 Gigabit Ethernet Controller (Aopen)
5177 4611 GT-64115 System Controller
5178 4620 GT-64120/64120A/64121A System Controller
5179 4801 GT-48001
5180 5005 Belkin F5D5005 Gigabit Desktop Network PCI Card
5181 5040 MV88SX5040 4-port SATA I PCI-X Controller
5182 5041 MV88SX5041 4-port SATA I PCI-X Controller
5183 5080 MV88SX5080 8-port SATA I PCI-X Controller
5184 5081 MV88SX5081 8-port SATA I PCI-X Controller
5185 6041 MV88SX6041 4-port SATA II PCI-X Controller
5186 6081 MV88SX6081 8-port SATA II PCI-X Controller
5187 6460 MV64360/64361/64362 System Controller
5188 f003 GT-64010 Primary Image Piranha Image Generator
518911ac Canon Information Systems Research Aust.
519011ad Lite-On Communications Inc
5191 0002 LNE100TX
5192 11ad 0002 LNE100TX
5193 11ad 0003 LNE100TX
5194 11ad f003 LNE100TX
5195 11ad ffff LNE100TX
5196 1385 f004 FA310TX
5197 c115 LNE100TX [Linksys EtherFast 10/100]
5198 11ad c001 LNE100TX [ver 2.0]
519911ae Aztech System Ltd
520011af Avid Technology Inc.
5201 0001 [Cinema]
520211b0 V3 Semiconductor Inc.
5203 0002 V300PSC
5204 0292 V292PBC [Am29030/40 Bridge]
5205 0960 V96xPBC
5206 c960 V96DPC
520711b1 Apricot Computers
520811b2 Eastman Kodak
520911b3 Barr Systems Inc.
521011b4 Leitch Technology International
521111b5 Radstone Technology Plc
521211b6 United Video Corp
521311b7 Motorola
521411b8 XPoint Technologies, Inc
5215 0001 Quad PeerMaster
521611b9 Pathlight Technology Inc.
5217 c0ed SSA Controller
521811ba Videotron Corp
521911bb Pyramid Technology
522011bc Network Peripherals Inc
5221 0001 NP-PCI
522211bd Pinnacle Systems Inc.
522311be International Microcircuits Inc
522411bf Astrodesign, Inc.
522511c0 Hewlett Packard
522611c1 Agere Systems (former Lucent Microelectronics)
5227 0440 56k WinModem
5228 1033 8015 LT WinModem 56k Data+Fax+Voice+Dsvd
5229 1033 8047 LT WinModem 56k Data+Fax+Voice+Dsvd
5230 1033 804f LT WinModem 56k Data+Fax+Voice+Dsvd
5231 10cf 102c LB LT Modem V.90 56k
5232 10cf 104a BIBLO LT Modem 56k
5233 10cf 105f LB2 LT Modem V.90 56k
5234 1179 0001 Internal V.90 Modem
5235 11c1 0440 LT WinModem 56k Data+Fax+Voice+Dsvd
5236 122d 4101 MDP7800-U Modem
5237 122d 4102 MDP7800SP-U Modem
5238 13e0 0040 LT WinModem 56k Data+Fax+Voice+Dsvd
5239 13e0 0440 LT WinModem 56k Data+Fax+Voice+Dsvd
5240 13e0 0441 LT WinModem 56k Data+Fax+Voice+Dsvd
5241 13e0 0450 LT WinModem 56k Data+Fax+Voice+Dsvd
5242 13e0 f100 LT WinModem 56k Data+Fax+Voice+Dsvd
5243 13e0 f101 LT WinModem 56k Data+Fax+Voice+Dsvd
5244 144d 2101 LT56PV Modem
5245 149f 0440 LT WinModem 56k Data+Fax+Voice+Dsvd
5246 0441 56k WinModem
5247 1033 804d LT WinModem 56k Data+Fax
5248 1033 8065 LT WinModem 56k Data+Fax
5249 1092 0440 Supra 56i
5250 1179 0001 Internal V.90 Modem
5251 11c1 0440 LT WinModem 56k Data+Fax
5252 11c1 0441 LT WinModem 56k Data+Fax
5253 122d 4100 MDP7800-U Modem
5254 13e0 0040 LT WinModem 56k Data+Fax
5255 13e0 0100 LT WinModem 56k Data+Fax
5256 13e0 0410 LT WinModem 56k Data+Fax
5257 13e0 0420 TelePath Internet 56k WinModem
5258 13e0 0440 LT WinModem 56k Data+Fax
5259 13e0 0443 LT WinModem 56k Data+Fax
5260 13e0 f102 LT WinModem 56k Data+Fax
5261 1416 9804 CommWave 56k Modem
5262 141d 0440 LT WinModem 56k Data+Fax
5263 144f 0441 Lucent 56k V.90 DF Modem
5264 144f 0449 Lucent 56k V.90 DF Modem
5265 144f 110d Lucent Win Modem
5266 1468 0441 Presario 56k V.90 DF Modem
5267 1668 0440 Lucent Win Modem
5268 0442 56k WinModem
5269 11c1 0440 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5270 11c1 0442 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5271 13e0 0412 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5272 13e0 0442 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5273 13fc 2471 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5274 144d 2104 LT56PT Modem
5275 144f 1104 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5276 149f 0440 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5277 1668 0440 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5278 0443 LT WinModem
5279 0444 LT WinModem
5280 0445 LT WinModem
5281 8086 2203 PRO/100+ MiniPCI (probably an Ambit U98.003.C.00 combo card)
5282 8086 2204 PRO/100+ MiniPCI on Armada E500
5283 0446 LT WinModem
5284 0447 LT WinModem
5285 0448 WinModem 56k
5286 1014 0131 Lucent Win Modem
5287 1033 8066 LT WinModem 56k Data+Fax+Voice+Dsvd
5288 13e0 0030 56k Voice Modem
5289 13e0 0040 LT WinModem 56k Data+Fax+Voice+Dsvd
5290# Actiontech eth+modem card as used by Dell &c.
5291 1668 2400 LT WinModem 56k (MiniPCI Ethernet+Modem)
5292 0449 WinModem 56k
5293 0e11 b14d 56k V.90 Modem
5294 13e0 0020 LT WinModem 56k Data+Fax
5295 13e0 0041 TelePath Internet 56k WinModem
5296 1436 0440 Lucent Win Modem
5297 144f 0449 Lucent 56k V.90 DFi Modem
5298 1468 0410 IBM ThinkPad T23 (2647-4MG)
5299 1468 0440 Lucent Win Modem
5300 1468 0449 Presario 56k V.90 DFi Modem
5301 044a F-1156IV WinModem (V90, 56KFlex)
5302 10cf 1072 LB Global LT Modem
5303 13e0 0012 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5304 13e0 0042 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5305 144f 1005 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
5306 044b LT WinModem
5307 044c LT WinModem
5308 044d LT WinModem
5309 044e LT WinModem
5310 044f V90 WildWire Modem
5311 0450 LT WinModem
5312 1033 80a8 Versa Note Vxi
5313 144f 4005 Magnia SG20
5314 0451 LT WinModem
5315 0452 LT WinModem
5316 0453 LT WinModem
5317 0454 LT WinModem
5318 0455 LT WinModem
5319 0456 LT WinModem
5320 0457 LT WinModem
5321 0458 LT WinModem
5322 0459 LT WinModem
5323 045a LT WinModem
5324 045c LT WinModem
5325 0461 V90 WildWire Modem
5326 0462 V90 WildWire Modem
5327 0480 Venus Modem (V90, 56KFlex)
5328 048c V.92 56K WinModem
5329# InPorte Home Internal 56k Modem/fax/answering machine/SMS Features
5330 048f V.92 56k WinModem
5331 5801 USB
5332 5802 USS-312 USB Controller
5333# 4 port PCI USB Controller made by Agere (formely Lucent)
5334 5803 USS-344S USB Controller
5335 5811 FW323
5336 8086 524c D865PERL mainboard
5337 dead 0800 FireWire Host Bus Adapter
5338 ab10 WL60010 Wireless LAN MAC
5339 ab11 WL60040 Multimode Wireles LAN MAC
5340 11c1 ab12 WaveLAN 11abg Cardbus card (Model 1102)
5341 11c1 ab13 WaveLAN 11abg MiniPCI card (Model 0512)
5342 11c1 ab15 WaveLAN 11abg Cardbus card (Model 1106)
5343 11c1 ab16 WaveLAN 11abg MiniPCI card (Model 0516)
5344 ab20 ORiNOCO PCI Adapter
5345 ab21 Agere Wireless PCI Adapter
5346 ab30 Hermes2 Mini-PCI WaveLAN a/b/g
5347 14cd 2012 Hermes2 Mini-PCI WaveLAN a/b/g
534811c2 Sand Microelectronics
534911c3 NEC Corporation
535011c4 Document Technologies, Inc
535111c5 Shiva Corporation
535211c6 Dainippon Screen Mfg. Co. Ltd
535311c7 D.C.M. Data Systems
535411c8 Dolphin Interconnect Solutions AS
5355 0658 PSB32 SCI-Adapter D31x
5356 d665 PSB64 SCI-Adapter D32x
5357 d667 PSB66 SCI-Adapter D33x
535811c9 Magma
5359 0010 16-line serial port w/- DMA
5360 0011 4-line serial port w/- DMA
536111ca LSI Systems, Inc
536211cb Specialix Research Ltd.
5363 2000 PCI_9050
5364 11cb 0200 SX
5365 11cb b008 I/O8+
5366 4000 SUPI_1
5367 8000 T225
536811cc Michels & Kleberhoff Computer GmbH
536911cd HAL Computer Systems, Inc.
537011ce Netaccess
537111cf Pioneer Electronic Corporation
537211d0 Lockheed Martin Federal Systems-Manassas
537311d1 Auravision
5374 01f7 VxP524
537511d2 Intercom Inc.
537611d3 Trancell Systems Inc
537711d4 Analog Devices
5378 1535 Blackfin BF535 processor
5379 1805 SM56 PCI modem
5380 1889 AD1889 sound chip
538111d5 Ikon Corporation
5382 0115 10115
5383 0117 10117
538411d6 Tekelec Telecom
538511d7 Trenton Technology, Inc.
538611d8 Image Technologies Development
538711d9 TEC Corporation
538811da Novell
538911db Sega Enterprises Ltd
539011dc Questra Corporation
539111dd Crosfield Electronics Limited
539211de Zoran Corporation
5393 6057 ZR36057PQC Video cutting chipset
5394 1031 7efe DC10 Plus
5395 1031 fc00 MiroVIDEO DC50, Motion JPEG Capture/CODEC Board
5396 13ca 4231 JPEG/TV Card
5397 6120 ZR36120
5398 1328 f001 Cinemaster C DVD Decoder
539911df New Wave PDG
540011e0 Cray Communications A/S
540111e1 GEC Plessey Semi Inc.
540211e2 Samsung Information Systems America
540311e3 Quicklogic Corporation
5404 5030 PC Watchdog
540511e4 Second Wave Inc
540611e5 IIX Consulting
540711e6 Mitsui-Zosen System Research
540811e7 Toshiba America, Elec. Company
540911e8 Digital Processing Systems Inc.
541011e9 Highwater Designs Ltd.
541111ea Elsag Bailey
541211eb Formation Inc.
541311ec Coreco Inc
541411ed Mediamatics
541511ee Dome Imaging Systems Inc
541611ef Nicolet Technologies B.V.
541711f0 Compu-Shack
5418 4231 FDDI
5419 4232 FASTline UTP Quattro
5420 4233 FASTline FO
5421 4234 FASTline UTP
5422 4235 FASTline-II UTP
5423 4236 FASTline-II FO
5424 4731 GIGAline
542511f1 Symbios Logic Inc
542611f2 Picture Tel Japan K.K.
542711f3 Keithley Metrabyte
542811f4 Kinetic Systems Corporation
5429 2915 CAMAC controller
543011f5 Computing Devices International
543111f6 Compex
5432 0112 ENet100VG4
5433 0113 FreedomLine 100
5434 1401 ReadyLink 2000
5435 2011 RL100-ATX 10/100
5436 11f6 2011 RL100-ATX
5437 2201 ReadyLink 100TX (Winbond W89C840)
5438 11f6 2011 ReadyLink 100TX
5439 9881 RL100TX Fast Ethernet
544011f7 Scientific Atlanta
544111f8 PMC-Sierra Inc.
5442 7375 PM7375 [LASAR-155 ATM SAR]
544311f9 I-Cube Inc
544411fa Kasan Electronics Company, Ltd.
544511fb Datel Inc
544611fc Silicon Magic
544711fd High Street Consultants
544811fe Comtrol Corporation
5449 0001 RocketPort 32 port w/external I/F
5450 0002 RocketPort 8 port w/external I/F
5451 0003 RocketPort 16 port w/external I/F
5452 0004 RocketPort 4 port w/quad cable
5453 0005 RocketPort 8 port w/octa cable
5454 0006 RocketPort 8 port w/RJ11 connectors
5455 0007 RocketPort 4 port w/RJ11 connectors
5456 0008 RocketPort 8 port w/ DB78 SNI (Siemens) connector
5457 0009 RocketPort 16 port w/ DB78 SNI (Siemens) connector
5458 000a RocketPort Plus 4 port
5459 000b RocketPort Plus 8 port
5460 000c RocketModem 6 port
5461 000d RocketModem 4-port
5462 000e RocketPort Plus 2 port RS232
5463 000f RocketPort Plus 2 port RS422
5464 0801 RocketPort UPCI 32 port w/external I/F
5465 0802 RocketPort UPCI 8 port w/external I/F
5466 0803 RocketPort UPCI 16 port w/external I/F
5467 0805 RocketPort UPCI 8 port w/octa cable
5468 080c RocketModem III 8 port
5469 080d RocketModem III 4 port
5470 0903 RocketPort Compact PCI 16 port w/external I/F
5471 8015 RocketPort 4-port UART 16954
547211ff Scion Corporation
5473 0003 AG-5
54741200 CSS Corporation
54751201 Vista Controls Corp
54761202 Network General Corp.
5477 4300 Gigabit Ethernet Adapter
5478 1202 9841 SK-9841 LX
5479 1202 9842 SK-9841 LX dual link
5480 1202 9843 SK-9843 SX
5481 1202 9844 SK-9843 SX dual link
54821203 Bayer Corporation, Agfa Division
54831204 Lattice Semiconductor Corporation
54841205 Array Corporation
54851206 Amdahl Corporation
54861208 Parsytec GmbH
5487 4853 HS-Link Device
54881209 SCI Systems Inc
5489120a Synaptel
5490120b Adaptive Solutions
5491120c Technical Corp.
5492120d Compression Labs, Inc.
5493120e Cyclades Corporation
5494 0100 Cyclom-Y below first megabyte
5495 0101 Cyclom-Y above first megabyte
5496 0102 Cyclom-4Y below first megabyte
5497 0103 Cyclom-4Y above first megabyte
5498 0104 Cyclom-8Y below first megabyte
5499 0105 Cyclom-8Y above first megabyte
5500 0200 Cyclades-Z below first megabyte
5501 0201 Cyclades-Z above first megabyte
5502 0300 PC300/RSV or /X21 (2 ports)
5503 0301 PC300/RSV or /X21 (1 port)
5504 0310 PC300/TE (2 ports)
5505 0311 PC300/TE (1 port)
5506 0320 PC300/TE-M (2 ports)
5507 0321 PC300/TE-M (1 port)
5508 0400 PC400
5509120f Essential Communications
5510 0001 Roadrunner serial HIPPI
55111210 Hyperparallel Technologies
55121211 Braintech Inc
55131212 Kingston Technology Corp.
55141213 Applied Intelligent Systems, Inc.
55151214 Performance Technologies, Inc.
55161215 Interware Co., Ltd
55171216 Purup Prepress A/S
55181217 O2 Micro, Inc.
5519 6729 OZ6729
5520 673a OZ6730
5521 6832 OZ6832/6833 CardBus Controller
5522 6836 OZ6836/6860 CardBus Controller
5523 6872 OZ6812 CardBus Controller
5524 6925 OZ6922 CardBus Controller
5525 6933 OZ6933/711E1 CardBus/SmartCardBus Controller
5526 1025 1016 Travelmate 612 TX
5527 6972 OZ601/6912/711E0 CardBus/SmartCardBus Controller
5528 1014 020c ThinkPad R30
5529 1179 0001 Magnia Z310
5530 7110 OZ711Mx 4-in-1 MemoryCardBus Accelerator
5531 103c 088c nc8000 laptop
5532 103c 0890 nc6000 laptop
5533 7112 OZ711EC1/M1 SmartCardBus/MemoryCardBus Controller
5534 7113 OZ711EC1 SmartCardBus Controller
5535 7114 OZ711M1/MC1 4-in-1 MemoryCardBus Controller
5536 7134 OZ711MP1/MS1 MemoryCardBus Controller
5537 71e2 OZ711E2 SmartCardBus Controller
5538 7212 OZ711M2 4-in-1 MemoryCardBus Controller
5539 7213 OZ6933E CardBus Controller
5540 7223 OZ711M3/MC3 4-in-1 MemoryCardBus Controller
5541 103c 088c nc8000 laptop
5542 103c 0890 nc6000 laptop
5543 7233 OZ711MP3/MS3 4-in-1 MemoryCardBus Controller
55441218 Hybricon Corp.
55451219 First Virtual Corporation
5546121a 3Dfx Interactive, Inc.
5547 0001 Voodoo
5548 0002 Voodoo 2
5549 0003 Voodoo Banshee
5550 1092 0003 Monster Fusion
5551 1092 4000 Monster Fusion
5552 1092 4002 Monster Fusion
5553 1092 4801 Monster Fusion AGP
5554 1092 4803 Monster Fusion AGP
5555 1092 8030 Monster Fusion
5556 1092 8035 Monster Fusion AGP
5557 10b0 0001 Dragon 4000
5558 1102 1018 3D Blaster Banshee VE
5559 121a 0001 Voodoo Banshee AGP
5560 121a 0003 Voodoo Banshee AGP SGRAM
5561 121a 0004 Voodoo Banshee
5562 139c 0016 Raven
5563 139c 0017 Raven
5564 14af 0002 Maxi Gamer Phoenix
5565 0004 Voodoo Banshee [Velocity 100]
5566 0005 Voodoo 3
5567 121a 0004 Voodoo3 AGP
5568 121a 0030 Voodoo3 AGP
5569 121a 0031 Voodoo3 AGP
5570 121a 0034 Voodoo3 AGP
5571 121a 0036 Voodoo3 2000 PCI
5572 121a 0037 Voodoo3 AGP
5573 121a 0038 Voodoo3 AGP
5574 121a 003a Voodoo3 AGP
5575 121a 0044 Voodoo3
5576 121a 004b Velocity 100
5577 121a 004c Velocity 200
5578 121a 004d Voodoo3 AGP
5579 121a 004e Voodoo3 AGP
5580 121a 0051 Voodoo3 AGP
5581 121a 0052 Voodoo3 AGP
5582 121a 0060 Voodoo3 3500 TV (NTSC)
5583 121a 0061 Voodoo3 3500 TV (PAL)
5584 121a 0062 Voodoo3 3500 TV (SECAM)
5585 0009 Voodoo 4 / Voodoo 5
5586 121a 0003 Voodoo5 PCI 5500
5587 121a 0009 Voodoo5 AGP 5500/6000
5588 0057 Voodoo 3/3000 [Avenger]
5589121b Advanced Telecommunications Modules
5590121c Nippon Texaco., Ltd
5591121d Lippert Automationstechnik GmbH
5592121e CSPI
5593121f Arcus Technology, Inc.
55941220 Ariel Corporation
5595 1220 AMCC 5933 TMS320C80 DSP/Imaging board
55961221 Contec Co., Ltd
55971222 Ancor Communications, Inc.
55981223 Artesyn Communication Products
5599 0003 PM/Link
5600 0004 PM/T1
5601 0005 PM/E1
5602 0008 PM/SLS
5603 0009 BajaSpan Resource Target
5604 000a BajaSpan Section 0
5605 000b BajaSpan Section 1
5606 000c BajaSpan Section 2
5607 000d BajaSpan Section 3
5608 000e PM/PPC
56091224 Interactive Images
56101225 Power I/O, Inc.
56111227 Tech-Source
5612 0006 Raptor GFX 8P
56131228 Norsk Elektro Optikk A/S
56141229 Data Kinesis Inc.
5615122a Integrated Telecom
5616122b LG Industrial Systems Co., Ltd
5617122c Sican GmbH
5618122d Aztech System Ltd
5619 1206 368DSP
5620 1400 Trident PCI288-Q3DII (NX)
5621 50dc 3328 Audio
5622 122d 0001 3328 Audio
5623 80da 3328 Audio
5624 122d 0001 3328 Audio
5625122e Xyratex
5626122f Andrew Corporation
56271230 Fishcamp Engineering
56281231 Woodward McCoach, Inc.
56291232 GPT Limited
56301233 Bus-Tech, Inc.
56311234 Technical Corp.
56321235 Risq Modular Systems, Inc.
56331236 Sigma Designs Corporation
5634 0000 RealMagic64/GX
5635 6401 REALmagic 64/GX (SD 6425)
56361237 Alta Technology Corporation
56371238 Adtran
56381239 3DO Company
5639123a Visicom Laboratories, Inc.
5640123b Seeq Technology, Inc.
5641123c Century Systems, Inc.
5642123d Engineering Design Team, Inc.
5643 0000 EasyConnect 8/32
5644 0002 EasyConnect 8/64
5645 0003 EasyIO
5646123e Simutech, Inc.
5647123f C-Cube Microsystems
5648 00e4 MPEG
5649 8120 E4?
5650 11bd 0006 DV500 E4
5651 11bd 000a DV500 E4
5652 11bd 000f DV500 E4
5653 8888 Cinemaster C 3.0 DVD Decoder
5654 1002 0001 Cinemaster C 3.0 DVD Decoder
5655 1002 0002 Cinemaster C 3.0 DVD Decoder
5656 1328 0001 Cinemaster C 3.0 DVD Decoder
56571240 Marathon Technologies Corp.
56581241 DSC Communications
5659# Formerly Jaycor Networks, Inc.
56601242 JNI Corporation
5661 1560 JNIC-1560 PCI-X Fibre Channel Controller
5662 1242 6562 FCX2-6562 Dual Channel PCI-X Fibre Channel Adapter
5663 1242 656a FCX-6562 PCI-X Fibre Channel Adapter
5664 4643 FCI-1063 Fibre Channel Adapter
5665 6562 FCX2-6562 Dual Channel PCI-X Fibre Channel Adapter
5666 656a FCX-6562 PCI-X Fibre Channel Adapter
56671243 Delphax
56681244 AVM Audiovisuelles MKTG & Computer System GmbH
5669 0700 B1 ISDN
5670 0800 C4 ISDN
5671 0a00 A1 ISDN [Fritz]
5672 1244 0a00 FRITZ!Card ISDN Controller
5673 0e00 Fritz!PCI v2.0 ISDN
5674 1100 C2 ISDN
5675 1200 T1 ISDN
5676 2700 Fritz!Card DSL SL
5677 2900 Fritz!Card DSL v2.0
56781245 A.P.D., S.A.
56791246 Dipix Technologies, Inc.
56801247 Xylon Research, Inc.
56811248 Central Data Corporation
56821249 Samsung Electronics Co., Ltd.
5683124a AEG Electrocom GmbH
5684124b SBS/Greenspring Modular I/O
5685 0040 PCI-40A or cPCI-200 Quad IndustryPack carrier
5686 124b 9080 PCI9080 Bridge
5687124c Solitron Technologies, Inc.
5688124d Stallion Technologies, Inc.
5689 0000 EasyConnection 8/32
5690 0002 EasyConnection 8/64
5691 0003 EasyIO
5692 0004 EasyConnection/RA
5693124e Cylink
5694124f Infortrend Technology, Inc.
5695 0041 IFT-2000 Series RAID Controller
56961250 Hitachi Microcomputer System Ltd
56971251 VLSI Solutions Oy
56981253 Guzik Technical Enterprises
56991254 Linear Systems Ltd.
57001255 Optibase Ltd
5701 1110 MPEG Forge
5702 1210 MPEG Fusion
5703 2110 VideoPlex
5704 2120 VideoPlex CC
5705 2130 VideoQuest
57061256 Perceptive Solutions, Inc.
5707 4201 PCI-2220I
5708 4401 PCI-2240I
5709 5201 PCI-2000
57101257 Vertex Networks, Inc.
57111258 Gilbarco, Inc.
57121259 Allied Telesyn International
5713 2560 AT-2560 Fast Ethernet Adapter (i82557B)
5714 a117 RTL81xx Fast Ethernet
5715 a120 21x4x DEC-Tulip compatible 10/100 Ethernet
5716125a ABB Power Systems
5717125b Asix Electronics Corporation
5718 1400 ALFA GFC2204 Fast Ethernet
5719125c Aurora Technologies, Inc.
5720 0101 Saturn 4520P
5721 0640 Aries 16000P
5722125d ESS Technology
5723 0000 ES336H Fax Modem (Early Model)
5724 1948 Solo?
5725 1968 ES1968 Maestro 2
5726 1028 0085 ES1968 Maestro-2 PCI
5727 1033 8051 ES1968 Maestro-2 Audiodrive
5728 1969 ES1969 Solo-1 Audiodrive
5729 1014 0166 ES1969 SOLO-1 AudioDrive on IBM Aptiva Mainboard
5730 125d 8888 Solo-1 Audio Adapter
5731 153b 111b Terratec 128i PCI
5732 1978 ES1978 Maestro 2E
5733 0e11 b112 Armada M700/E500
5734 1033 803c ES1978 Maestro-2E Audiodrive
5735 1033 8058 ES1978 Maestro-2E Audiodrive
5736 1092 4000 Monster Sound MX400
5737 1179 0001 ES1978 Maestro-2E Audiodrive
5738 1988 ES1988 Allegro-1
5739 1092 4100 Sonic Impact S100
5740 125d 1988 ESS Allegro-1 Audiodrive
5741 1989 ESS Modem
5742 125d 1989 ESS Modem
5743 1998 ES1983S Maestro-3i PCI Audio Accelerator
5744 1028 00b1 Latitude C600
5745 1028 00e6 ES1983S Maestro-3i (Dell Inspiron 8100)
5746 1999 ES1983S Maestro-3i PCI Modem Accelerator
5747 199a ES1983S Maestro-3i PCI Audio Accelerator
5748 199b ES1983S Maestro-3i PCI Modem Accelerator
5749 2808 ES336H Fax Modem (Later Model)
5750 2838 ES2838/2839 SuperLink Modem
5751 2898 ES2898 Modem
5752 125d 0424 ES56-PI Data Fax Modem
5753 125d 0425 ES56T-PI Data Fax Modem
5754 125d 0426 ES56V-PI Data Fax Modem
5755 125d 0427 VW-PI Data Fax Modem
5756 125d 0428 ES56ST-PI Data Fax Modem
5757 125d 0429 ES56SV-PI Data Fax Modem
5758 147a c001 ES56-PI Data Fax Modem
5759 14fe 0428 ES56-PI Data Fax Modem
5760 14fe 0429 ES56-PI Data Fax Modem
5761125e Specialvideo Engineering SRL
5762125f Concurrent Technologies, Inc.
57631260 Intersil Corporation
5764 3872 Prism 2.5 Wavelan chipset
5765 1468 0202 LAN-Express IEEE 802.11b Wireless LAN
5766 3873 Prism 2.5 Wavelan chipset
5767 1186 3501 DWL-520 Wireless PCI Adapter
5768 1186 3700 DWL-520 Wireless PCI Adapter, Rev E1
5769 1385 4105 MA311 802.11b wireless adapter
5770 1668 0414 HWP01170-01 802.11b PCI Wireless Adapter
5771 16a5 1601 AIR.mate PC-400 PCI Wireless LAN Adapter
5772 1737 3874 WMP11 Wireless 802.11b PCI Adapter
5773 8086 2513 Wireless 802.11b MiniPCI Adapter
5774 3886 ISL3886 [Prism Javelin/Prism Xbow]
5775 17cf 0037 Z-Com XG-901 and clones Wireless Adapter
5776 3890 Intersil ISL3890 [Prism GT/Prism Duette]
5777 10b8 2802 SMC2802W Wireless PCI Adapter
5778 10b8 2835 SMC2835W Wireless Cardbus Adapter
5779 10b8 a835 SMC2835W V2 Wireless Cardbus Adapter
5780 1113 ee03 SMC2802W V2 Wireless PCI Adapter
5781 1113 ee08 SMC2835W V3 EU Wireless Cardbus Adapter
5782 1186 3202 DWL-G650 A1 Wireless Adapter
5783 1259 c104 CG-WLCB54GT Wireless Adapter
5784 1385 4800 WG511 Wireless Adapter
5785 16a5 1605 ALLNET ALL0271 Wireless PCI Adapter
5786 17cf 0014 Z-Com XG-600 and clones Wireless Adapter
5787 17cf 0020 Z-Com XG-900 and clones Wireless Adapter
5788 8130 HMP8130 NTSC/PAL Video Decoder
5789 8131 HMP8131 NTSC/PAL Video Decoder
57901261 Matsushita-Kotobuki Electronics Industries, Ltd.
57911262 ES Computer Company, Ltd.
57921263 Sonic Solutions
57931264 Aval Nagasaki Corporation
57941265 Casio Computer Co., Ltd.
57951266 Microdyne Corporation
5796 0001 NE10/100 Adapter (i82557B)
5797 1910 NE2000Plus (RT8029) Ethernet Adapter
5798 1266 1910 NE2000Plus Ethernet Adapter
57991267 S. A. Telecommunications
5800 5352 PCR2101
5801 5a4b Telsat Turbo
58021268 Tektronix
58031269 Thomson-CSF/TTM
5804126a Lexmark International, Inc.
5805126b Adax, Inc.
5806126c Northern Telecom
5807 1211 10/100BaseTX [RTL81xx]
5808 126c 802.11b Wireless Ethernet Adapter
5809126d Splash Technology, Inc.
5810126e Sumitomo Metal Industries, Ltd.
5811126f Silicon Motion, Inc.
5812 0501 SM501 VoyagerGX
5813 0710 SM710 LynxEM
5814 0712 SM712 LynxEM+
5815 0720 SM720 Lynx3DM
5816 0730 SM731 Cougar3DR
5817 0810 SM810 LynxE
5818 0811 SM811 LynxE
5819 0820 SM820 Lynx3D
5820 0910 SM910
58211270 Olympus Optical Co., Ltd.
58221271 GW Instruments
58231272 Telematics International
58241273 Hughes Network Systems
5825 0002 DirecPC
58261274 Ensoniq
5827 1171 ES1373 [AudioPCI] (also Creative Labs CT5803)
5828 1371 ES1371 [AudioPCI-97]
5829 0e11 0024 AudioPCI on Motherboard Compaq Deskpro
5830 0e11 b1a7 ES1371, ES1373 AudioPCI
5831 1033 80ac ES1371, ES1373 AudioPCI
5832 1042 1854 Tazer
5833 107b 8054 Tabor2
5834 1274 1371 Creative Sound Blaster AudioPCI64V, AudioPCI128
5835 1462 6470 ES1371, ES1373 AudioPCI On Motherboard MS-6147 1.1A
5836 1462 6560 ES1371, ES1373 AudioPCI On Motherboard MS-6156 1.10
5837 1462 6630 ES1371, ES1373 AudioPCI On Motherboard MS-6163BX 1.0A
5838 1462 6631 ES1371, ES1373 AudioPCI On Motherboard MS-6163VIA 1.0A
5839 1462 6632 ES1371, ES1373 AudioPCI On Motherboard MS-6163BX 2.0A
5840 1462 6633 ES1371, ES1373 AudioPCI On Motherboard MS-6163VIA 2.0A
5841 1462 6820 ES1371, ES1373 AudioPCI On Motherboard MS-6182 1.00
5842 1462 6822 ES1371, ES1373 AudioPCI On Motherboard MS-6182 1.00A
5843 1462 6830 ES1371, ES1373 AudioPCI On Motherboard MS-6183 1.00
5844 1462 6880 ES1371, ES1373 AudioPCI On Motherboard MS-6188 1.00
5845 1462 6900 ES1371, ES1373 AudioPCI On Motherboard MS-6190 1.00
5846 1462 6910 ES1371, ES1373 AudioPCI On Motherboard MS-6191
5847 1462 6930 ES1371, ES1373 AudioPCI On Motherboard MS-6193
5848 1462 6990 ES1371, ES1373 AudioPCI On Motherboard MS-6199BX 2.0A
5849 1462 6991 ES1371, ES1373 AudioPCI On Motherboard MS-6199VIA 2.0A
5850 14a4 2077 ES1371, ES1373 AudioPCI On Motherboard KR639
5851 14a4 2105 ES1371, ES1373 AudioPCI On Motherboard MR800
5852 14a4 2107 ES1371, ES1373 AudioPCI On Motherboard MR801
5853 14a4 2172 ES1371, ES1373 AudioPCI On Motherboard DR739
5854 1509 9902 ES1371, ES1373 AudioPCI On Motherboard KW11
5855 1509 9903 ES1371, ES1373 AudioPCI On Motherboard KW31
5856 1509 9904 ES1371, ES1373 AudioPCI On Motherboard KA11
5857 1509 9905 ES1371, ES1373 AudioPCI On Motherboard KC13
5858 152d 8801 ES1371, ES1373 AudioPCI On Motherboard CP810E
5859 152d 8802 ES1371, ES1373 AudioPCI On Motherboard CP810
5860 152d 8803 ES1371, ES1373 AudioPCI On Motherboard P3810E
5861 152d 8804 ES1371, ES1373 AudioPCI On Motherboard P3810-S
5862 152d 8805 ES1371, ES1373 AudioPCI On Motherboard P3820-S
5863 270f 2001 ES1371, ES1373 AudioPCI On Motherboard 6CTR
5864 270f 2200 ES1371, ES1373 AudioPCI On Motherboard 6WTX
5865 270f 3000 ES1371, ES1373 AudioPCI On Motherboard 6WSV
5866 270f 3100 ES1371, ES1373 AudioPCI On Motherboard 6WIV2
5867 270f 3102 ES1371, ES1373 AudioPCI On Motherboard 6WIV
5868 270f 7060 ES1371, ES1373 AudioPCI On Motherboard 6ASA2
5869 8086 4249 ES1371, ES1373 AudioPCI On Motherboard BI440ZX
5870 8086 424c ES1371, ES1373 AudioPCI On Motherboard BL440ZX
5871 8086 425a ES1371, ES1373 AudioPCI On Motherboard BZ440ZX
5872 8086 4341 ES1371, ES1373 AudioPCI On Motherboard Cayman
5873 8086 4343 ES1371, ES1373 AudioPCI On Motherboard Cape Cod
5874 8086 4649 ES1371, ES1373 AudioPCI On Motherboard Fire Island
5875 8086 464a ES1371, ES1373 AudioPCI On Motherboard FJ440ZX
5876 8086 4d4f ES1371, ES1373 AudioPCI On Motherboard Montreal
5877 8086 4f43 ES1371, ES1373 AudioPCI On Motherboard OC440LX
5878 8086 5243 ES1371, ES1373 AudioPCI On Motherboard RC440BX
5879 8086 5352 ES1371, ES1373 AudioPCI On Motherboard SunRiver
5880 8086 5643 ES1371, ES1373 AudioPCI On Motherboard Vancouver
5881 8086 5753 ES1371, ES1373 AudioPCI On Motherboard WS440BX
5882 5000 ES1370 [AudioPCI]
5883 5880 5880 AudioPCI
5884 1274 2000 Creative Sound Blaster AudioPCI128
5885 1274 2003 Creative SoundBlaster AudioPCI 128
5886 1274 5880 Creative Sound Blaster AudioPCI128
5887 1274 8001 Sound Blaster 16PCI 4.1ch
5888 1458 a000 5880 AudioPCI On Motherboard 6OXET
5889 1462 6880 5880 AudioPCI On Motherboard MS-6188 1.00
5890 270f 2001 5880 AudioPCI On Motherboard 6CTR
5891 270f 2200 5880 AudioPCI On Motherboard 6WTX
5892 270f 7040 5880 AudioPCI On Motherboard 6ATA4
58931275 Network Appliance Corporation
58941276 Switched Network Technologies, Inc.
58951277 Comstream
58961278 Transtech Parallel Systems Ltd.
5897 0701 TPE3/TM3 PowerPC Node
5898 0710 TPE5 PowerPC PCI board
58991279 Transmeta Corporation
5900 0295 Northbridge
5901 0395 LongRun Northbridge
5902 0396 SDRAM controller
5903 0397 BIOS scratchpad
5904127a Rockwell International
5905 1002 HCF 56k Data/Fax Modem
5906 1092 094c SupraExpress 56i PRO [Diamond SUP2380]
5907 122d 4002 HPG / MDP3858-U
5908 122d 4005 MDP3858-E
5909 122d 4007 MDP3858-A/-NZ
5910 122d 4012 MDP3858-SA
5911 122d 4017 MDP3858-W
5912 122d 4018 MDP3858-W
5913 127a 1002 Rockwell 56K D/F HCF Modem
5914 1003 HCF 56k Data/Fax Modem
5915 0e11 b0bc 229-DF Zephyr
5916 0e11 b114 229-DF Cheetah
5917 1033 802b 229-DF
5918 13df 1003 PCI56RX Modem
5919 13e0 0117 IBM
5920 13e0 0147 IBM F-1156IV+/R3 Spain V.90 Modem
5921 13e0 0197 IBM
5922 13e0 01c7 IBM F-1156IV+/R3 WW V.90 Modem
5923 13e0 01f7 IBM
5924 1436 1003 IBM
5925 1436 1103 IBM 5614PM3G V.90 Modem
5926 1436 1602 Compaq 229-DF Ducati
5927 1004 HCF 56k Data/Fax/Voice Modem
5928 1048 1500 MicroLink 56k Modem
5929 10cf 1059 Fujitsu 229-DFRT
5930 1005 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
5931 1005 127a AOpen FM56-P
5932 1033 8029 229-DFSV
5933 1033 8054 Modem
5934 10cf 103c Fujitsu
5935 10cf 1055 Fujitsu 229-DFSV
5936 10cf 1056 Fujitsu 229-DFSV
5937 122d 4003 MDP3858SP-U
5938 122d 4006 Packard Bell MDP3858V-E
5939 122d 4008 MDP3858SP-A/SP-NZ
5940 122d 4009 MDP3858SP-E
5941 122d 4010 MDP3858V-U
5942 122d 4011 MDP3858SP-SA
5943 122d 4013 MDP3858V-A/V-NZ
5944 122d 4015 MDP3858SP-W
5945 122d 4016 MDP3858V-W
5946 122d 4019 MDP3858V-SA
5947 13df 1005 PCI56RVP Modem
5948 13e0 0187 IBM
5949 13e0 01a7 IBM
5950 13e0 01b7 IBM DF-1156IV+/R3 Spain V.90 Modem
5951 13e0 01d7 IBM DF-1156IV+/R3 WW V.90 Modem
5952 1436 1005 IBM
5953 1436 1105 IBM
5954 1437 1105 IBM 5614PS3G V.90 Modem
5955 1022 HCF 56k Modem
5956 1436 1303 M3-5614PM3G V.90 Modem
5957 1023 HCF 56k Data/Fax Modem
5958 122d 4020 Packard Bell MDP3858-WE
5959 122d 4023 MDP3858-UE
5960 13e0 0247 IBM F-1156IV+/R6 Spain V.90 Modem
5961 13e0 0297 IBM
5962 13e0 02c7 IBM F-1156IV+/R6 WW V.90 Modem
5963 1436 1203 IBM
5964 1436 1303 IBM
5965 1024 HCF 56k Data/Fax/Voice Modem
5966 1025 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
5967 10cf 106a Fujitsu 235-DFSV
5968 122d 4021 Packard Bell MDP3858V-WE
5969 122d 4022 MDP3858SP-WE
5970 122d 4024 MDP3858V-UE
5971 122d 4025 MDP3858SP-UE
5972 1026 HCF 56k PCI Speakerphone Modem
5973 1032 HCF 56k Modem
5974 1033 HCF 56k Modem
5975 1034 HCF 56k Modem
5976 1035 HCF 56k PCI Speakerphone Modem
5977 1036 HCF 56k Modem
5978 1085 HCF 56k Volcano PCI Modem
5979 2005 HCF 56k Data/Fax Modem
5980 104d 8044 229-DFSV
5981 104d 8045 229-DFSV
5982 104d 8055 PBE/Aztech 235W-DFSV
5983 104d 8056 235-DFSV
5984 104d 805a Modem
5985 104d 805f Modem
5986 104d 8074 Modem
5987 2013 HSF 56k Data/Fax Modem
5988 1179 0001 Modem
5989 1179 ff00 Modem
5990 2014 HSF 56k Data/Fax/Voice Modem
5991 10cf 1057 Fujitsu Citicorp III
5992 122d 4050 MSP3880-U
5993 122d 4055 MSP3880-W
5994 2015 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
5995 10cf 1063 Fujitsu
5996 10cf 1064 Fujitsu
5997 1468 2015 Fujitsu
5998 2016 HSF 56k Data/Fax/Voice/Spkp Modem
5999 122d 4051 MSP3880V-W
6000 122d 4052 MSP3880SP-W
6001 122d 4054 MSP3880V-U
6002 122d 4056 MSP3880SP-U
6003 122d 4057 MSP3880SP-A
6004 4311 Riptide HSF 56k PCI Modem
6005 127a 4311 Ring Modular? Riptide HSF RT HP Dom
6006 13e0 0210 HP-GVC
6007 4320 Riptide PCI Audio Controller
6008 1235 4320 Riptide PCI Audio Controller
6009 4321 Riptide HCF 56k PCI Modem
6010 1235 4321 Hewlett Packard DF
6011 1235 4324 Hewlett Packard DF
6012 13e0 0210 Hewlett Packard DF
6013 144d 2321 Riptide
6014 4322 Riptide PCI Game Controller
6015 1235 4322 Riptide PCI Game Controller
6016 8234 RapidFire 616X ATM155 Adapter
6017 108d 0022 RapidFire 616X ATM155 Adapter
6018 108d 0027 RapidFire 616X ATM155 Adapter
6019127b Pixera Corporation
6020127c Crosspoint Solutions, Inc.
6021127d Vela Research
6022127e Winnov, L.P.
6023127f Fujifilm
60241280 Photoscript Group Ltd.
60251281 Yokogawa Electric Corporation
60261282 Davicom Semiconductor, Inc.
6027 9009 Ethernet 100/10 MBit
6028 9100 21x4x DEC-Tulip compatible 10/100 Ethernet
6029 9102 21x4x DEC-Tulip compatible 10/100 Ethernet
6030 9132 Ethernet 100/10 MBit
60311283 Integrated Technology Express, Inc.
6032 673a IT8330G
6033 8212 IT/ITE8212 Dual channel ATA RAID controller (PCI version seems to be IT8212, embedded seems to be ITE8212)
6034 1283 0001 IT/ITE8212 Dual channel ATA RAID controller
6035 8330 IT8330G
6036 8872 IT8874F PCI Dual Serial Port Controller
6037 8888 IT8888F PCI to ISA Bridge with SMB
6038 8889 IT8889F PCI to ISA Bridge
6039 e886 IT8330G
60401284 Sahara Networks, Inc.
60411285 Platform Technologies, Inc.
6042 0100 AGOGO sound chip (aka ESS Maestro 1)
60431286 Mazet GmbH
60441287 M-Pact, Inc.
6045 001e LS220D DVD Decoder
6046 001f LS220C DVD Decoder
60471288 Timestep Corporation
60481289 AVC Technology, Inc.
6049128a Asante Technologies, Inc.
6050128b Transwitch Corporation
6051128c Retix Corporation
6052128d G2 Networks, Inc.
6053 0021 ATM155 Adapter
6054128e Hoontech Corporation/Samho Multi Tech Ltd.
6055 0008 ST128 WSS/SB
6056 0009 ST128 SAM9407
6057 000a ST128 Game Port
6058 000b ST128 MPU Port
6059 000c ST128 Ctrl Port
6060128f Tateno Dennou, Inc.
60611290 Sord Computer Corporation
60621291 NCS Computer Italia
60631292 Tritech Microelectronics Inc
60641293 Media Reality Technology
60651294 Rhetorex, Inc.
60661295 Imagenation Corporation
60671296 Kofax Image Products
60681297 Holco Enterprise Co, Ltd/Shuttle Computer
60691298 Spellcaster Telecommunications Inc.
60701299 Knowledge Technology Lab.
6071129a VMetro, inc.
6072 0615 PBT-615 PCI-X Bus Analyzer
6073129b Image Access
6074129c Jaycor
6075129d Compcore Multimedia, Inc.
6076129e Victor Company of Japan, Ltd.
6077129f OEC Medical Systems, Inc.
607812a0 Allen-Bradley Company
607912a1 Simpact Associates, Inc.
608012a2 Newgen Systems Corporation
608112a3 Lucent Technologies
6082 8105 T8105 H100 Digital Switch
608312a4 NTT Electronics Technology Company
608412a5 Vision Dynamics Ltd.
608512a6 Scalable Networks, Inc.
608612a7 AMO GmbH
608712a8 News Datacom
608812a9 Xiotech Corporation
608912aa SDL Communications, Inc.
609012ab Yuan Yuan Enterprise Co., Ltd.
6091 0002 AU8830 [Vortex2] Based Sound Card With A3D Support
6092 3000 MPG-200C PCI DVD Decoder Card
609312ac Measurex Corporation
609412ad Multidata GmbH
609512ae Alteon Networks Inc.
6096 0001 AceNIC Gigabit Ethernet
6097 1014 0104 Gigabit Ethernet-SX PCI Adapter
6098 12ae 0001 Gigabit Ethernet-SX (Universal)
6099 1410 0104 Gigabit Ethernet-SX PCI Adapter
6100 0002 AceNIC Gigabit Ethernet (Copper)
6101 10a9 8002 Acenic Gigabit Ethernet
6102 12ae 0002 Gigabit Ethernet-T (3C986-T)
6103 00fa Farallon PN9100-T Gigabit Ethernet
610412af TDK USA Corp
610512b0 Jorge Scientific Corp
610612b1 GammaLink
610712b2 General Signal Networks
610812b3 Inter-Face Co Ltd
610912b4 FutureTel Inc
611012b5 Granite Systems Inc.
611112b6 Natural Microsystems
611212b7 Cognex Modular Vision Systems Div. - Acumen Inc.
611312b8 Korg
611412b9 3Com Corp, Modem Division (formerly US Robotics)
6115 1006 WinModem
6116 12b9 005c USR 56k Internal Voice WinModem (Model 3472)
6117 12b9 005e USR 56k Internal WinModem (Models 662975)
6118 12b9 0062 USR 56k Internal Voice WinModem (Model 662978)
6119 12b9 0068 USR 56k Internal Voice WinModem (Model 5690)
6120 12b9 007a USR 56k Internal Voice WinModem (Model 662974)
6121 12b9 007f USR 56k Internal WinModem (Models 5698, 5699)
6122 12b9 0080 USR 56k Internal WinModem (Models 2975, 3528)
6123 12b9 0081 USR 56k Internal Voice WinModem (Models 2974, 3529)
6124 12b9 0091 USR 56k Internal Voice WinModem (Model 2978)
6125 1007 USR 56k Internal WinModem
6126 12b9 00a3 USR 56k Internal WinModem (Model 3595)
6127 1008 56K FaxModem Model 5610
6128 12b9 00a2 USR 56k Internal FAX Modem (Model 2977)
6129 12b9 00aa USR 56k Internal Voice Modem (Model 2976)
6130 12b9 00ab USR 56k Internal Voice Modem (Model 5609)
6131 12b9 00ac USR 56k Internal Voice Modem (Model 3298)
6132 12b9 00ad USR 56k Internal FAX Modem (Model 5610)
613312ba BittWare, Inc.
613412bb Nippon Unisoft Corporation
613512bc Array Microsystems
613612bd Computerm Corp.
613712be Anchor Chips Inc.
6138 3041 AN3041Q CO-MEM
6139 3042 AN3042Q CO-MEM Lite
6140 12be 3042 Anchor Chips Lite Evaluation Board
614112bf Fujifilm Microdevices
614212c0 Infimed
614312c1 GMM Research Corp
614412c2 Mentec Limited
614512c3 Holtek Microelectronics Inc
6146 0058 PCI NE2K Ethernet
6147 5598 PCI NE2K Ethernet
614812c4 Connect Tech Inc
6149 0001 Blue HEAT/PCI 8 (RS232/CL/RJ11)
6150 0002 Blue HEAT/PCI 4 (RS232)
6151 0003 Blue HEAT/PCI 2 (RS232)
6152 0004 Blue HEAT/PCI 8 (UNIV, RS485)
6153 0005 Blue HEAT/PCI 4+4/6+2 (UNIV, RS232/485)
6154 0006 Blue HEAT/PCI 4 (OPTO, RS485)
6155 0007 Blue HEAT/PCI 2+2 (RS232/485)
6156 0008 Blue HEAT/PCI 2 (OPTO, Tx, RS485)
6157 0009 Blue HEAT/PCI 2+6 (RS232/485)
6158 000a Blue HEAT/PCI 8 (Tx, RS485)
6159 000b Blue HEAT/PCI 4 (Tx, RS485)
6160 000c Blue HEAT/PCI 2 (20 MHz, RS485)
6161 000d Blue HEAT/PCI 2 PTM
6162 0100 NT960/PCI
6163 0201 cPCI Titan - 2 Port
6164 0202 cPCI Titan - 4 Port
6165 0300 CTI PCI UART 2 (RS232)
6166 0301 CTI PCI UART 4 (RS232)
6167 0302 CTI PCI UART 8 (RS232)
6168 0310 CTI PCI UART 1+1 (RS232/485)
6169 0311 CTI PCI UART 2+2 (RS232/485)
6170 0312 CTI PCI UART 4+4 (RS232/485)
6171 0320 CTI PCI UART 2
6172 0321 CTI PCI UART 4
6173 0322 CTI PCI UART 8
6174 0330 CTI PCI UART 2 (RS485)
6175 0331 CTI PCI UART 4 (RS485)
6176 0332 CTI PCI UART 8 (RS485)
617712c5 Picture Elements Incorporated
6178 007e Imaging/Scanning Subsystem Engine
6179 007f Imaging/Scanning Subsystem Engine
6180 0081 PCIVST [Grayscale Thresholding Engine]
6181 0085 Video Simulator/Sender
6182 0086 THR2 Multi-scale Thresholder
618312c6 Mitani Corporation
618412c7 Dialogic Corp
618512c8 G Force Co, Ltd
618612c9 Gigi Operations
618712ca Integrated Computing Engines
618812cb Antex Electronics Corporation
618912cc Pluto Technologies International
619012cd Aims Lab
619112ce Netspeed Inc.
619212cf Prophet Systems, Inc.
619312d0 GDE Systems, Inc.
619412d1 PSITech
619512d2 NVidia / SGS Thomson (Joint Venture)
6196 0008 NV1
6197 0009 DAC64
6198 0018 Riva128
6199 1048 0c10 VICTORY Erazor
6200 107b 8030 STB Velocity 128
6201 1092 0350 Viper V330
6202 1092 1092 Viper V330
6203 10b4 1b1b STB Velocity 128
6204 10b4 1b1d STB Velocity 128
6205 10b4 1b1e STB Velocity 128, PAL TV-Out
6206 10b4 1b20 STB Velocity 128 Sapphire
6207 10b4 1b21 STB Velocity 128
6208 10b4 1b22 STB Velocity 128 AGP, NTSC TV-Out
6209 10b4 1b23 STB Velocity 128 AGP, PAL TV-Out
6210 10b4 1b27 STB Velocity 128 DVD
6211 10b4 1b88 MVP Pro 128
6212 10b4 222a STB Velocity 128 AGP
6213 10b4 2230 STB Velocity 128
6214 10b4 2232 STB Velocity 128
6215 10b4 2235 STB Velocity 128 AGP
6216 2a15 54a3 3DVision-SAGP / 3DexPlorer 3000
6217 0019 Riva128ZX
6218 0020 TNT
6219 0028 TNT2
6220 0029 UTNT2
6221 002c VTNT2
6222 00a0 ITNT2
622312d3 Vingmed Sound A/S
622412d4 Ulticom (Formerly DGM&S)
6225 0200 T1 Card
622612d5 Equator Technologies Inc
6227 0003 BSP16
6228 1000 BSP15
622912d6 Analogic Corp
623012d7 Biotronic SRL
623112d8 Pericom Semiconductor
623212d9 Aculab PLC
6233 0002 PCI Prosody
6234 0004 cPCI Prosody
6235 0005 Aculab E1/T1 PCI card
623612da True Time Inc.
623712db Annapolis Micro Systems, Inc
623812dc Symicron Computer Communication Ltd.
623912dd Management Graphics
624012de Rainbow Technologies
6241 0200 CryptoSwift CS200
624212df SBS Technologies Inc
624312e0 Chase Research
6244 0010 ST16C654 Quad UART
6245 0020 ST16C654 Quad UART
6246 0030 ST16C654 Quad UART
624712e1 Nintendo Co, Ltd
624812e2 Datum Inc. Bancomm-Timing Division
624912e3 Imation Corp - Medical Imaging Systems
625012e4 Brooktrout Technology Inc
625112e5 Apex Semiconductor Inc
625212e6 Cirel Systems
625312e7 Sunsgroup Corporation
625412e8 Crisc Corp
625512e9 GE Spacenet
625612ea Zuken
625712eb Aureal Semiconductor
6258 0001 Vortex 1
6259 104d 8036 AU8820 Vortex Digital Audio Processor
6260 1092 2000 Sonic Impact A3D
6261 1092 2100 Sonic Impact A3D
6262 1092 2110 Sonic Impact A3D
6263 1092 2200 Sonic Impact A3D
6264 122d 1002 AU8820 Vortex Digital Audio Processor
6265 12eb 0001 AU8820 Vortex Digital Audio Processor
6266 5053 3355 Montego
6267 0002 Vortex 2
6268 104d 8049 AU8830 Vortex 3D Digital Audio Processor
6269 104d 807b AU8830 Vortex 3D Digital Audio Processor
6270 1092 3000 Monster Sound II
6271 1092 3001 Monster Sound II
6272 1092 3002 Monster Sound II
6273 1092 3003 Monster Sound II
6274 1092 3004 Monster Sound II
6275 12eb 0001 AU8830 Vortex 3D Digital Audio Processor
6276 12eb 0002 AU8830 Vortex 3D Digital Audio Processor
6277 12eb 0088 AU8830 Vortex 3D Digital Audio Processor
6278 144d 3510 AU8830 Vortex 3D Digital Audio Processor
6279 5053 3356 Montego II
6280 0003 AU8810 Vortex Digital Audio Processor
6281 104d 8049 AU8810 Vortex Digital Audio Processor
6282 104d 8077 AU8810 Vortex Digital Audio Processor
6283 109f 1000 AU8810 Vortex Digital Audio Processor
6284 12eb 0003 AU8810 Vortex Digital Audio Processor
6285 1462 6780 AU8810 Vortex Digital Audio Processor
6286 14a4 2073 AU8810 Vortex Digital Audio Processor
6287 14a4 2091 AU8810 Vortex Digital Audio Processor
6288 14a4 2104 AU8810 Vortex Digital Audio Processor
6289 14a4 2106 AU8810 Vortex Digital Audio Processor
6290 8803 Vortex 56k Software Modem
6291 12eb 8803 Vortex 56k Software Modem
629212ec 3A International, Inc.
629312ed Optivision Inc.
629412ee Orange Micro
629512ef Vienna Systems
629612f0 Pentek
629712f1 Sorenson Vision Inc
629812f2 Gammagraphx, Inc.
629912f3 Radstone Technology
630012f4 Megatel
630112f5 Forks
630212f6 Dawson France
630312f7 Cognex
630412f8 Electronic Design GmbH
6305 0002 VideoMaker
630612f9 Four Fold Ltd
630712fb Spectrum Signal Processing
630812fc Capital Equipment Corp
630912fd I2S
631012fe ESD Electronic System Design GmbH
631112ff Lexicon
63121300 Harman International Industries Inc
63131302 Computer Sciences Corp
63141303 Innovative Integration
63151304 Juniper Networks
63161305 Netphone, Inc
63171306 Duet Technologies
6318# Formerly ComputerBoards
63191307 Measurement Computing
6320 0001 PCI-DAS1602/16
6321 000b PCI-DIO48H
6322 000c PCI-PDISO8
6323 000d PCI-PDISO16
6324 000f PCI-DAS1200
6325 0010 PCI-DAS1602/12
6326 0014 PCI-DIO24H
6327 0015 PCI-DIO24H/CTR3
6328 0016 PCI-DIO48H/CTR15
6329 0017 PCI-DIO96H
6330 0018 PCI-CTR05
6331 0019 PCI-DAS1200/JR
6332 001a PCI-DAS1001
6333 001b PCI-DAS1002
6334 001c PCI-DAS1602JR/16
6335 001d PCI-DAS6402/16
6336 001e PCI-DAS6402/12
6337 001f PCI-DAS16/M1
6338 0020 PCI-DDA02/12
6339 0021 PCI-DDA04/12
6340 0022 PCI-DDA08/12
6341 0023 PCI-DDA02/16
6342 0024 PCI-DDA04/16
6343 0025 PCI-DDA08/16
6344 0026 PCI-DAC04/12-HS
6345 0027 PCI-DAC04/16-HS
6346 0028 PCI-DIO24
6347 0029 PCI-DAS08
6348 002c PCI-INT32
6349 0033 PCI-DUAL-AC5
6350 0034 PCI-DAS-TC
6351 0035 PCI-DAS64/M1/16
6352 0036 PCI-DAS64/M2/16
6353 0037 PCI-DAS64/M3/16
6354 004c PCI-DAS1000
6355 004d PCI-QUAD04
6356 0052 PCI-DAS4020/12
6357 005e PCI-DAS6025
63581308 Jato Technologies Inc.
6359 0001 NetCelerator Adapter
6360 1308 0001 NetCelerator Adapter
63611309 AB Semiconductor Ltd
6362130a Mitsubishi Electric Microcomputer
6363130b Colorgraphic Communications Corp
6364130c Ambex Technologies, Inc
6365130d Accelerix Inc
6366130e Yamatake-Honeywell Co. Ltd
6367130f Advanet Inc
63681310 Gespac
63691311 Videoserver, Inc
63701312 Acuity Imaging, Inc
63711313 Yaskawa Electric Co.
63721316 Teradyne Inc
63731317 Linksys
6374 0981 21x4x DEC-Tulip compatible 10/100 Ethernet
6375 0985 NC100 Network Everywhere Fast Ethernet 10/100
6376 1985 21x4x DEC-Tulip compatible 10/100 Ethernet
6377 2850 HSP MicroModem 56
6378 8201 ADMtek ADM8211 802.11b Wireless Interface
6379 10b8 2635 SMC2635W 802.11b (11Mbps) wireless lan pcmcia (cardbus) card
6380 1317 8201 SMC2635W 802.11b (11mbps) wireless lan pcmcia (cardbus) card
6381 8211 ADMtek ADM8211 802.11b Wireless Interface
6382 9511 21x4x DEC-Tulip compatible 10/100 Ethernet
63831318 Packet Engines Inc.
6384 0911 GNIC-II PCI Gigabit Ethernet [Hamachi]
63851319 Fortemedia, Inc
6386 0801 Xwave QS3000A [FM801]
6387 0802 Xwave QS3000A [FM801 game port]
6388 1000 FM801 PCI Audio
6389 1001 FM801 PCI Joystick
6390131a Finisar Corp.
6391131c Nippon Electro-Sensory Devices Corp
6392131d Sysmic, Inc.
6393131e Xinex Networks Inc
6394131f Siig Inc
6395 1000 CyberSerial (1-port) 16550
6396 1001 CyberSerial (1-port) 16650
6397 1002 CyberSerial (1-port) 16850
6398 1010 Duet 1S(16550)+1P
6399 1011 Duet 1S(16650)+1P
6400 1012 Duet 1S(16850)+1P
6401 1020 CyberParallel (1-port)
6402 1021 CyberParallel (2-port)
6403 1030 CyberSerial (2-port) 16550
6404 1031 CyberSerial (2-port) 16650
6405 1032 CyberSerial (2-port) 16850
6406 1034 Trio 2S(16550)+1P
6407 1035 Trio 2S(16650)+1P
6408 1036 Trio 2S(16850)+1P
6409 1050 CyberSerial (4-port) 16550
6410 1051 CyberSerial (4-port) 16650
6411 1052 CyberSerial (4-port) 16850
6412 2000 CyberSerial (1-port) 16550
6413 2001 CyberSerial (1-port) 16650
6414 2002 CyberSerial (1-port) 16850
6415 2010 Duet 1S(16550)+1P
6416 2011 Duet 1S(16650)+1P
6417 2012 Duet 1S(16850)+1P
6418 2020 CyberParallel (1-port)
6419 2021 CyberParallel (2-port)
6420 2030 CyberSerial (2-port) 16550
6421 131f 2030 PCI Serial Card
6422 2031 CyberSerial (2-port) 16650
6423 2032 CyberSerial (2-port) 16850
6424 2040 Trio 1S(16550)+2P
6425 2041 Trio 1S(16650)+2P
6426 2042 Trio 1S(16850)+2P
6427 2050 CyberSerial (4-port) 16550
6428 2051 CyberSerial (4-port) 16650
6429 2052 CyberSerial (4-port) 16850
6430 2060 Trio 2S(16550)+1P
6431 2061 Trio 2S(16650)+1P
6432 2062 Trio 2S(16850)+1P
6433 2081 CyberSerial (8-port) ST16654
64341320 Crypto AG
64351321 Arcobel Graphics BV
64361322 MTT Co., Ltd
64371323 Dome Inc
64381324 Sphere Communications
64391325 Salix Technologies, Inc
64401326 Seachange international
64411327 Voss scientific
64421328 quadrant international
64431329 Productivity Enhancement
6444132a Microcom Inc.
6445132b Broadband Technologies
6446132c Micrel Inc
6447132d Integrated Silicon Solution, Inc.
64481330 MMC Networks
64491331 Radisys Corp.
6450 0030 ENP-2611
6451 8200 82600 Host Bridge
6452 8201 82600 IDE
6453 8202 82600 USB
6454 8210 82600 PCI Bridge
64551332 Micro Memory
6456 5415 MM-5415CN PCI Memory Module with Battery Backup
6457 5425 MM-5425CN PCI 64/66 Memory Module with Battery Backup
64581334 Redcreek Communications, Inc
64591335 Videomail, Inc
64601337 Third Planet Publishing
64611338 BT Electronics
6462133a Vtel Corp
6463133b Softcom Microsystems
6464133c Holontech Corp
6465133d SS Technologies
6466133e Virtual Computer Corp
6467133f SCM Microsystems
64681340 Atalla Corp
64691341 Kyoto Microcomputer Co
64701342 Promax Systems Inc
64711343 Phylon Communications Inc
64721344 Crucial Technology
64731345 Arescom Inc
64741347 Odetics
64751349 Sumitomo Electric Industries, Ltd.
6476134a DTC Technology Corp.
6477 0001 Domex 536
6478 0002 Domex DMX3194UP SCSI Adapter
6479134b ARK Research Corp.
6480134c Chori Joho System Co. Ltd
6481134d PCTel Inc
6482 2189 HSP56 MicroModem
6483 2486 2304WT V.92 MDC Modem
6484 7890 HSP MicroModem 56
6485 134d 0001 PCT789 adapter
6486 7891 HSP MicroModem 56
6487 134d 0001 HSP MicroModem 56
6488 7892 HSP MicroModem 56
6489 7893 HSP MicroModem 56
6490 7894 HSP MicroModem 56
6491 7895 HSP MicroModem 56
6492 7896 HSP MicroModem 56
6493 7897 HSP MicroModem 56
6494134e CSTI
6495134f Algo System Co Ltd
64961350 Systec Co. Ltd
64971351 Sonix Inc
64981353 Thales Idatys
6499 0002 Proserver
6500 0003 PCI-FUT
6501 0004 PCI-S0
6502 0005 PCI-FUT-S0
65031354 Dwave System Inc
65041355 Kratos Analytical Ltd
65051356 The Logical Co
65061359 Prisa Networks
6507135a Brain Boxes
6508135b Giganet Inc
6509135c Quatech Inc
6510 0010 QSC-100
6511 0020 DSC-100
6512 0030 DSC-200/300
6513 0040 QSC-200/300
6514 0050 ESC-100D
6515 0060 ESC-100M
6516 00f0 MPAC-100 Syncronous Serial Card (Zilog 85230)
6517 0170 QSCLP-100
6518 0180 DSCLP-100
6519 0190 SSCLP-100
6520 01a0 QSCLP-200/300
6521 01b0 DSCLP-200/300
6522 01c0 SSCLP-200/300
6523135d ABB Network Partner AB
6524135e Sealevel Systems Inc
6525 5101 Route 56.PCI - Multi-Protocol Serial Interface (Zilog Z16C32)
6526 7101 Single Port RS-232/422/485/530
6527 7201 Dual Port RS-232/422/485 Interface
6528 7202 Dual Port RS-232 Interface
6529 7401 Four Port RS-232 Interface
6530 7402 Four Port RS-422/485 Interface
6531 7801 Eight Port RS-232 Interface
6532 7804 Eight Port RS-232/422/485 Interface
6533 8001 8001 Digital I/O Adapter
6534135f I-Data International A-S
65351360 Meinberg Funkuhren
6536 0101 PCI32 DCF77 Radio Clock
6537 0102 PCI509 DCF77 Radio Clock
6538 0103 PCI510 DCF77 Radio Clock
6539 0201 GPS167PCI GPS Receiver
6540 0202 GPS168PCI GPS Receiver
6541 0203 GPS169PCI GPS Receiver
6542 0301 TCR510PCI IRIG Receiver
65431361 Soliton Systems K.K.
65441362 Fujifacom Corporation
65451363 Phoenix Technology Ltd
65461364 ATM Communications Inc
65471365 Hypercope GmbH
65481366 Teijin Seiki Co. Ltd
65491367 Hitachi Zosen Corporation
65501368 Skyware Corporation
65511369 Digigram
6552136a High Soft Tech
6553136b Kawasaki Steel Corporation
6554 ff01 KL5A72002 Motion JPEG
6555136c Adtek System Science Co Ltd
6556136d Gigalabs Inc
6557136f Applied Magic Inc
65581370 ATL Products
65591371 CNet Technology Inc
6560 434e GigaCard Network Adapter
6561 1371 434e N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
65621373 Silicon Vision Inc
65631374 Silicom Ltd
65641375 Argosystems Inc
65651376 LMC
65661377 Electronic Equipment Production & Distribution GmbH
65671378 Telemann Co. Ltd
65681379 Asahi Kasei Microsystems Co Ltd
6569137a Mark of the Unicorn Inc
6570 0001 PCI-324 Audiowire Interface
6571137b PPT Vision
6572137c Iwatsu Electric Co Ltd
6573137d Dynachip Corporation
6574137e Patriot Scientific Corporation
6575137f Japan Satellite Systems Inc
65761380 Sanritz Automation Co Ltd
65771381 Brains Co. Ltd
65781382 Marian - Electronic & Software
6579 0001 ARC88 audio recording card
6580 2008 Prodif 96 Pro sound system
6581 2088 Marc 8 Midi sound system
6582 20c8 Marc A sound system
6583 4008 Marc 2 sound system
6584 4010 Marc 2 Pro sound system
6585 4048 Marc 4 MIDI sound system
6586 4088 Marc 4 Digi sound system
6587 4248 Marc X sound system
65881383 Controlnet Inc
65891384 Reality Simulation Systems Inc
65901385 Netgear
6591# Note: This lists as Atheros Communications, Inc. AR5212 802.11abg NIC because of Madwifi
6592 0013 WG311T
6593 311a GA511 Gigabit Ethernet
6594 4100 802.11b Wireless Adapter (MA301)
6595 4105 MA311 802.11b wireless adapter
6596 4400 WAG511 802.11a/b/g Dual Band Wireless PC Card
6597 4600 WAG511 802.11a/b/g Dual Band Wireless PC Card
6598 4601 WAG511 802.11a/b/g Dual Band Wireless PC Card
6599 4610 WAG511 802.11a/b/g Dual Band Wireless PC Card
6600 4a00 WAG311 802.11a/g Wireless PCI Adapter
6601 4c00 WG311v2 54 Mbps Wireless PCI Adapter
6602 620a GA620 Gigabit Ethernet
6603 622a GA622
6604 630a GA630 Gigabit Ethernet
6605 f004 FA310TX
66061386 Video Domain Technologies
66071387 Systran Corp
66081388 Hitachi Information Technology Co Ltd
66091389 Applicom International
6610 0001 PCI1500PFB [Intelligent fieldbus adaptor]
6611138a Fusion Micromedia Corp
6612138b Tokimec Inc
6613138c Silicon Reality
6614138d Future Techno Designs pte Ltd
6615138e Basler GmbH
6616138f Patapsco Designs Inc
66171390 Concept Development Inc
66181391 Development Concepts Inc
66191392 Medialight Inc
66201393 Moxa Technologies Co Ltd
6621 1040 Smartio C104H/PCI
6622 1141 Industrio CP-114
6623 1680 Smartio C168H/PCI
6624 2040 Intellio CP-204J
6625 2180 Intellio C218 Turbo PCI
6626 3200 Intellio C320 Turbo PCI
66271394 Level One Communications
6628 0001 LXT1001 Gigabit Ethernet
6629 1394 0001 NetCelerator Adapter
66301395 Ambicom Inc
66311396 Cipher Systems Inc
66321397 Cologne Chip Designs GmbH
6633 2bd0 ISDN network controller [HFC-PCI]
6634 1397 2bd0 ISDN Board
6635 e4bf 1000 CI1-1-Harp
66361398 Clarion co. Ltd
66371399 Rios systems Co Ltd
6638139a Alacritech Inc
6639 0001 Quad Port 10/100 Server Accelerator
6640 0003 Single Port 10/100 Server Accelerator
6641 0005 Single Port Gigabit Server Accelerator
6642139b Mediasonic Multimedia Systems Ltd
6643139c Quantum 3d Inc
6644139d EPL limited
6645139e Media4
6646139f Aethra s.r.l.
664713a0 Crystal Group Inc
664813a1 Kawasaki Heavy Industries Ltd
664913a2 Ositech Communications Inc
665013a3 Hifn Inc.
6651 0005 7751 Security Processor
6652 0006 6500 Public Key Processor
6653 0007 7811 Security Processor
6654 0012 7951 Security Processor
6655 0014 78XX Security Processor
6656 0016 8065 Security Processor
6657 0017 8165 Security Processor
6658 0018 8154 Security Processor
6659 001d 7956 Security Processor
6660 0020 7955 Security Processor
666113a4 Rascom Inc
666213a5 Audio Digital Imaging Inc
666313a6 Videonics Inc
666413a7 Teles AG
666513a8 Exar Corp.
6666 0154 XR17C154 Quad UART
6667 0158 XR17C158 Octal UART
666813a9 Siemens Medical Systems, Ultrasound Group
666913aa Broadband Networks Inc
667013ab Arcom Control Systems Ltd
667113ac Motion Media Technology Ltd
667213ad Nexus Inc
667313ae ALD Technology Ltd
667413af T.Sqware
667513b0 Maxspeed Corp
667613b1 Tamura corporation
667713b2 Techno Chips Co. Ltd
667813b3 Lanart Corporation
667913b4 Wellbean Co Inc
668013b5 ARM
668113b6 Dlog GmbH
668213b7 Logic Devices Inc
668313b8 Nokia Telecommunications oy
668413b9 Elecom Co Ltd
668513ba Oxford Instruments
668613bb Sanyo Technosound Co Ltd
668713bc Bitran Corporation
668813bd Sharp corporation
668913be Miroku Jyoho Service Co. Ltd
669013bf Sharewave Inc
669113c0 Microgate Corporation
6692 0010 SyncLink Adapter v1
6693 0020 SyncLink SCC Adapter
6694 0030 SyncLink Multiport Adapter
6695 0210 SyncLink Adapter v2
669613c1 3ware Inc
6697 1000 3ware Inc 3ware 5xxx/6xxx-series PATA-RAID
6698 1001 3ware Inc 3ware 7xxx/8xxx-series PATA/SATA-RAID
6699 13c1 1001 3ware Inc 3ware 7xxx/8xxx-series PATA/SATA-RAID
6700 1002 3ware Inc 3ware 9xxx-series SATA-RAID
670113c2 Technotrend Systemtechnik GmbH
670213c3 Janz Computer AG
670313c4 Phase Metrics
670413c5 Alphi Technology Corp
670513c6 Condor Engineering Inc
6706 0520 CEI-520 A429 Card
6707 0620 CEI-620 A429 Card
6708 0820 CEI-820 A429 Card
670913c7 Blue Chip Technology Ltd
671013c8 Apptech Inc
671113c9 Eaton Corporation
671213ca Iomega Corporation
671313cb Yano Electric Co Ltd
671413cc Metheus Corporation
671513cd Compatible Systems Corporation
671613ce Cocom A/S
671713cf Studio Audio & Video Ltd
671813d0 Techsan Electronics Co Ltd
6719 2103 B2C2 FlexCopII DVB chip / Technisat SkyStar2 DVB card
6720 2200 B2C2 FlexCopIII DVB chip / Technisat SkyStar2 DVB card
672113d1 Abocom Systems Inc
6722 ab02 ADMtek Centaur-C rev 17 [D-Link DFE-680TX] CardBus Fast Ethernet Adapter
6723 ab03 21x4x DEC-Tulip compatible 10/100 Ethernet
6724 ab06 RTL8139 [FE2000VX] CardBus Fast Ethernet Attached Port Adapter
6725 ab08 21x4x DEC-Tulip compatible 10/100 Ethernet
672613d2 Shark Multimedia Inc
672713d3 IMC Networks
672813d4 Graphics Microsystems Inc
672913d5 Media 100 Inc
673013d6 K.I. Technology Co Ltd
673113d7 Toshiba Engineering Corporation
673213d8 Phobos corporation
673313d9 Apex PC Solutions Inc
673413da Intresource Systems pte Ltd
673513db Janich & Klass Computertechnik GmbH
673613dc Netboost Corporation
673713dd Multimedia Bundle Inc
673813de ABB Robotics Products AB
673913df E-Tech Inc
6740 0001 PCI56RVP Modem
6741 13df 0001 PCI56RVP Modem
674213e0 GVC Corporation
674313e1 Silicom Multimedia Systems Inc
674413e2 Dynamics Research Corporation
674513e3 Nest Inc
674613e4 Calculex Inc
674713e5 Telesoft Design Ltd
674813e6 Argosy research Inc
674913e7 NAC Incorporated
675013e8 Chip Express Corporation
675113e9 Intraserver Technology Inc
675213ea Dallas Semiconductor
675313eb Hauppauge Computer Works Inc
675413ec Zydacron Inc
675513ed Raytheion E-Systems
675613ee Hayes Microcomputer Products Inc
675713ef Coppercom Inc
675813f0 Sundance Technology Inc
6759 0201 ST201 Sundance Ethernet
676013f1 Oce' - Technologies B.V.
676113f2 Ford Microelectronics Inc
676213f3 Mcdata Corporation
676313f4 Troika Networks, Inc.
6764 1401 Zentai Fibre Channel Adapter
676513f5 Kansai Electric Co. Ltd
676613f6 C-Media Electronics Inc
6767 0011 CMI8738
6768 0100 CM8338A
6769 13f6 ffff CMI8338/C3DX PCI Audio Device
6770 0101 CM8338B
6771 13f6 0101 CMI8338-031 PCI Audio Device
6772 0111 CM8738
6773 1019 0970 P6STP-FL motherboard
6774 1043 8035 CUSI-FX motherboard
6775 1043 8077 CMI8738 6-channel audio controller
6776 1043 80e2 CMI8738 6ch-MX
6777 13f6 0111 CMI8738/C3DX PCI Audio Device
6778 1681 a000 Gamesurround MUSE XL
6779 0211 CM8738
678013f7 Wildfire Communications
678113f8 Ad Lib Multimedia Inc
678213f9 NTT Advanced Technology Corp.
678313fa Pentland Systems Ltd
678413fb Aydin Corp
678513fc Computer Peripherals International
678613fd Micro Science Inc
678713fe Advantech Co. Ltd
6788 1240 PCI-1240 4-channel stepper motor controller card w. Nova Electronics MCX314
6789 1600 PCI-1612 4-port RS-232/422/485 PCI Communication Card
6790 1752 PCI-1752
6791 1754 PCI-1754
6792 1756 PCI-1756
679313ff Silicon Spice Inc
67941400 Artx Inc
6795 1401 9432 TX
67961401 CR-Systems A/S
67971402 Meilhaus Electronic GmbH
67981403 Ascor Inc
67991404 Fundamental Software Inc
68001405 Excalibur Systems Inc
68011406 Oce' Printing Systems GmbH
68021407 Lava Computer mfg Inc
6803 0100 Lava Dual Serial
6804 0101 Lava Quatro A
6805 0102 Lava Quatro B
6806 0110 Lava DSerial-PCI Port A
6807 0111 Lava DSerial-PCI Port B
6808 0120 Quattro-PCI A
6809 0121 Quattro-PCI B
6810 0180 Lava Octo A
6811 0181 Lava Octo B
6812 0200 Lava Port Plus
6813 0201 Lava Quad A
6814 0202 Lava Quad B
6815 0220 Lava Quattro PCI Ports A/B
6816 0221 Lava Quattro PCI Ports C/D
6817 0500 Lava Single Serial
6818 0600 Lava Port 650
6819 8000 Lava Parallel
6820 8001 Dual parallel port controller A
6821 8002 Lava Dual Parallel port A
6822 8003 Lava Dual Parallel port B
6823 8800 BOCA Research IOPPAR
68241408 Aloka Co. Ltd
68251409 Timedia Technology Co Ltd
6826 7168 PCI2S550 (Dual 16550 UART)
6827140a DSP Research Inc
6828140b Ramix Inc
6829140c Elmic Systems Inc
6830140d Matsushita Electric Works Ltd
6831140e Goepel Electronic GmbH
6832140f Salient Systems Corp
68331410 Midas lab Inc
68341411 Ikos Systems Inc
6835# formerly IC Ensemble Inc.
68361412 VIA Technologies Inc.
6837 1712 ICE1712 [Envy24] PCI Multi-Channel I/O Controller
6838 1412 1712 Hoontech ST Audio DSP 24
6839 1412 d630 M-Audio Delta 1010
6840 1412 d631 M-Audio Delta DiO
6841 1412 d632 M-Audio Delta 66
6842 1412 d633 M-Audio Delta 44
6843 1412 d634 M-Audio Delta Audiophile
6844 1412 d635 M-Audio Delta TDIF
6845 1412 d637 M-Audio Delta RBUS
6846 1412 d638 M-Audio Delta 410
6847 1412 d63b M-Audio Delta 1010LT
6848 1412 d63c Digigram VX442
6849 1416 1712 Hoontech ST Audio DSP 24 Media 7.1
6850 153b 1115 EWS88 MT
6851 153b 1125 EWS88 MT (Master)
6852 153b 112b EWS88 D
6853 153b 112c EWS88 D (Master)
6854 153b 1130 EWX 24/96
6855 153b 1138 DMX 6fire 24/96
6856 153b 1151 PHASE88
6857 16ce 1040 Edirol DA-2496
6858 1724 VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller
6859 1412 1724 AMP Ltd AUDIO2000
6860 1412 3630 M-Audio Revolution 7.1
6861 153b 1145 Aureon 7.1 Space
6862 153b 1147 Aureon 5.1 Sky
6863 153b 1153 Aureon 7.1 Universe
6864 270f f641 ZNF3-150
6865 270f f645 ZNF3-250
68661413 Addonics
68671414 Microsoft Corporation
68681415 Oxford Semiconductor Ltd
6869 8403 VScom 011H-EP1 1 port parallel adaptor
6870 9501 OX16PCI954 (Quad 16950 UART) function 0
6871 131f 2050 CyberPro (4-port)
6872# Model IO1085, Part No: JJ-P46012
6873 131f 2051 CyberSerial 4S Plus
6874 15ed 2000 MCCR Serial p0-3 of 8
6875 15ed 2001 MCCR Serial p0-3 of 16
6876 950a EXSYS EX-41092 Dual 16950 Serial adapter
6877 950b OXCB950 Cardbus 16950 UART
6878 9510 OX16PCI954 (Quad 16950 UART) function 1 (Disabled)
6879 9511 OX16PCI954 (Quad 16950 UART) function 1
6880 15ed 2000 MCCR Serial p4-7 of 8
6881 15ed 2001 MCCR Serial p4-15 of 16
6882 9521 OX16PCI952 (Dual 16950 UART)
68831416 Multiwave Innovation pte Ltd
68841417 Convergenet Technologies Inc
68851418 Kyushu electronics systems Inc
68861419 Excel Switching Corp
6887141a Apache Micro Peripherals Inc
6888141b Zoom Telephonics Inc
6889141d Digitan Systems Inc
6890141e Fanuc Ltd
6891141f Visiontech Ltd
68921420 Psion Dacom plc
6893 8002 Gold Card NetGlobal 56k+10/100Mb CardBus (Ethernet part)
6894 8003 Gold Card NetGlobal 56k+10/100Mb CardBus (Modem part)
68951421 Ads Technologies Inc
68961422 Ygrec Systems Co Ltd
68971423 Custom Technology Corp.
68981424 Videoserver Connections
68991425 Chelsio Communications Inc
69001426 Storage Technology Corp.
69011427 Better On-Line Solutions
69021428 Edec Co Ltd
69031429 Unex Technology Corp.
6904142a Kingmax Technology Inc
6905142b Radiolan
6906142c Minton Optic Industry Co Ltd
6907142d Pix stream Inc
6908142e Vitec Multimedia
6909 4020 VM2-2 [Video Maker 2] MPEG1/2 Encoder
6910142f Radicom Research Inc
69111430 ITT Aerospace/Communications Division
69121431 Gilat Satellite Networks
69131432 Edimax Computer Co.
6914 9130 RTL81xx Fast Ethernet
69151433 Eltec Elektronik GmbH
69161435 Real Time Devices US Inc.
69171436 CIS Technology Inc
69181437 Nissin Inc Co
69191438 Atmel-dream
69201439 Outsource Engineering & Mfg. Inc
6921143a Stargate Solutions Inc
6922143b Canon Research Center, America
6923143c Amlogic Inc
6924143d Tamarack Microelectronics Inc
6925143e Jones Futurex Inc
6926143f Lightwell Co Ltd - Zax Division
69271440 ALGOL Corp.
69281441 AGIE Ltd
69291442 Phoenix Contact GmbH & Co.
69301443 Unibrain S.A.
69311444 TRW
69321445 Logical DO Ltd
69331446 Graphin Co Ltd
69341447 AIM GmBH
69351448 Alesis Studio Electronics
69361449 TUT Systems Inc
6937144a Adlink Technology
6938 7296 PCI-7296
6939 7432 PCI-7432
6940 7433 PCI-7433
6941 7434 PCI-7434
6942 7841 PCI-7841
6943 8133 PCI-8133
6944 8164 PCI-8164
6945 8554 PCI-8554
6946 9111 PCI-9111
6947 9113 PCI-9113
6948 9114 PCI-9114
6949144b Loronix Information Systems Inc
6950144c Catalina Research Inc
6951144d Samsung Electronics Co Ltd
6952144e OLITEC
6953144f Askey Computer Corp.
69541450 Octave Communications Ind.
69551451 SP3D Chip Design GmBH
69561453 MYCOM Inc
69571454 Altiga Networks
69581455 Logic Plus Plus Inc
69591456 Advanced Hardware Architectures
69601457 Nuera Communications Inc
69611458 Giga-byte Technology
6962 0c11 K8NS Pro Mainboard
69631459 DOOIN Electronics
6964145a Escalate Networks Inc
6965145b PRAIM SRL
6966145c Cryptek
6967145d Gallant Computer Inc
6968145e Aashima Technology B.V.
6969145f Baldor Electric Company
6970 0001 NextMove PCI
69711460 DYNARC INC
69721461 Avermedia Technologies Inc
69731462 Micro-Star International Co., Ltd.
6974# MSI CB54G Wireless PC Card that seems to use the Broadcom 4306 Chipset
6975 6819 Broadcom Corporation BCM4306 802.11b/g Wireless LAN Controller [MSI CB54G]
6976 6825 PCI Card wireless 11g [PC54G]
6977 8725 NVIDIA NV25 [GeForce4 Ti 4600] VGA Adapter
6978# MSI G4Ti4800, 128MB DDR SDRAM, TV-Out, DVI-I
6979 9000 NVIDIA NV28 [GeForce4 Ti 4800] VGA Adapter
6980 9110 GeFORCE FX5200
6981 9119 NVIDIA NV31 [GeForce FX 5600XT] VGA Adapter
6982 9591 nVidia Corporation NV36 [GeForce FX 5700LE]
69831463 Fast Corporation
69841464 Interactive Circuits & Systems Ltd
69851465 GN NETTEST Telecom DIV.
69861466 Designpro Inc.
69871467 DIGICOM SPA
69881468 AMBIT Microsystem Corp.
69891469 Cleveland Motion Controls
6990146a IFR
6991146b Parascan Technologies Ltd
6992146c Ruby Tech Corp.
6993 1430 FE-1430TX Fast Ethernet PCI Adapter
6994146d Tachyon, INC.
6995146e Williams Electronics Games, Inc.
6996146f Multi Dimensional Consulting Inc
69971470 Bay Networks
69981471 Integrated Telecom Express Inc
69991472 DAIKIN Industries, Ltd
70001473 ZAPEX Technologies Inc
70011474 Doug Carson & Associates
70021475 PICAZO Communications
70031476 MORTARA Instrument Inc
70041477 Net Insight
70051478 DIATREND Corporation
70061479 TORAY Industries Inc
7007147a FORMOSA Industrial Computing
7008147b ABIT Computer Corp.
7009147c AWARE, Inc.
7010147d Interworks Computer Products
7011147e Matsushita Graphic Communication Systems, Inc.
7012147f NIHON UNISYS, Ltd.
70131480 SCII Telecom
70141481 BIOPAC Systems Inc
70151482 ISYTEC - Integrierte Systemtechnik GmBH
70161483 LABWAY Corporation
70171484 Logic Corporation
70181485 ERMA - Electronic GmBH
70191486 L3 Communications Telemetry & Instrumentation
70201487 MARQUETTE Medical Systems
70211488 KONTRON Electronik GmBH
70221489 KYE Systems Corporation
7023148a OPTO
7024148b INNOMEDIALOGIC Inc.
7025148c C.P. Technology Co. Ltd
7026148d DIGICOM Systems, Inc.
7027 1003 HCF 56k Data/Fax Modem
7028148e OSI Plus Corporation
7029148f Plant Equipment, Inc.
70301490 Stone Microsystems PTY Ltd.
70311491 ZEAL Corporation
70321492 Time Logic Corporation
70331493 MAKER Communications
70341494 WINTOP Technology, Inc.
70351495 TOKAI Communications Industry Co. Ltd
70361496 JOYTECH Computer Co., Ltd.
70371497 SMA Regelsysteme GmBH
70381498 TEWS Datentechnik GmBH
7039 30c8 TPCI200
70401499 EMTEC CO., Ltd
7041149a ANDOR Technology Ltd
7042149b SEIKO Instruments Inc
7043149c OVISLINK Corp.
7044149d NEWTEK Inc
7045 0001 Video Toaster for PC
7046149e Mapletree Networks Inc.
7047149f LECTRON Co Ltd
704814a0 SOFTING GmBH
704914a1 Systembase Co Ltd
705014a2 Millennium Engineering Inc
705114a3 Maverick Networks
705214a4 GVC/BCM Advanced Research
705314a5 XIONICS Document Technologies Inc
705414a6 INOVA Computers GmBH & Co KG
705514a7 MYTHOS Systems Inc
705614a8 FEATRON Technologies Corporation
705714a9 HIVERTEC Inc
705814aa Advanced MOS Technology Inc
705914ab Mentor Graphics Corp.
706014ac Novaweb Technologies Inc
706114ad Time Space Radio AB
706214ae CTI, Inc
706314af Guillemot Corporation
7064 7102 3D Prophet II MX
706514b0 BST Communication Technology Ltd
706614b1 Nextcom K.K.
706714b2 ENNOVATE Networks Inc
706814b3 XPEED Inc
7069 0000 DSL NIC
707014b4 PHILIPS Business Electronics B.V.
707114b5 Creamware GmBH
7072 0200 Scope
7073 0300 Pulsar
7074 0400 PulsarSRB
7075 0600 Pulsar2
7076 0800 DSP-Board
7077 0900 DSP-Board
7078 0a00 DSP-Board
7079 0b00 DSP-Board
708014b6 Quantum Data Corp.
708114b7 PROXIM Inc
7082 0001 Symphony 4110
708314b8 Techsoft Technology Co Ltd
708414b9 AIRONET Wireless Communications
7085 0001 PC4800
7086 0340 PC4800
7087 0350 PC4800
7088 4500 PC4500
7089 4800 Cisco Aironet 340 802.11b Wireless LAN Adapter/Aironet PC4800
7090 a504 Cisco Aironet Wireless 802.11b
7091 a505 Cisco Aironet CB20a 802.11a Wireless LAN Adapter
7092 a506 Cisco Aironet Mini PCI b/g
709314ba INTERNIX Inc.
709414bb SEMTECH Corporation
709514bc Globespan Semiconductor Inc.
709614bd CARDIO Control N.V.
709714be L3 Communications
709814bf SPIDER Communications Inc.
709914c0 COMPAL Electronics Inc
710014c1 MYRICOM Inc.
7101 8043 Myrinet 2000 Scalable Cluster Interconnect
710214c2 DTK Computer
710314c3 MEDIATEK Corp.
710414c4 IWASAKI Information Systems Co Ltd
710514c5 Automation Products AB
710614c6 Data Race Inc
710714c7 Modular Technology Holdings Ltd
710814c8 Turbocomm Tech. Inc.
710914c9 ODIN Telesystems Inc
711014ca PE Logic Corp.
711114cb Billionton Systems Inc
711214cc NAKAYO Telecommunications Inc
711314cd Universal Scientific Ind.
711414ce Whistle Communications
711514cf TEK Microsystems Inc.
711614d0 Ericsson Axe R & D
711714d1 Computer Hi-Tech Co Ltd
711814d2 Titan Electronics Inc
7119 8001 VScom 010L 1 port parallel adaptor
7120 8002 VScom 020L 2 port parallel adaptor
7121 8010 VScom 100L 1 port serial adaptor
7122 8011 VScom 110L 1 port serial and 1 port parallel adaptor
7123 8020 VScom 200L 1 port serial adaptor
7124 8021 VScom 210L 2 port serial and 1 port parallel adaptor
7125 8040 VScom 400L 4 port serial adaptor
7126 8080 VScom 800L 8 port serial adaptor
7127 a000 VScom 010H 1 port parallel adaptor
7128 a001 VScom 100H 1 port serial adaptor
7129 a003 VScom 400H 4 port serial adaptor
7130 a004 VScom 400HF1 4 port serial adaptor
7131 a005 VScom 200H 2 port serial adaptor
7132 e001 VScom 010HV2 1 port parallel adaptor
7133 e010 VScom 100HV2 1 port serial adaptor
7134 e020 VScom 200HV2 2 port serial adaptor
713514d3 CIRTECH (UK) Ltd
713614d4 Panacom Technology Corp
713714d5 Nitsuko Corporation
713814d6 Accusys Inc
713914d7 Hirakawa Hewtech Corp
714014d8 HOPF Elektronik GmBH
7141# Formerly SiPackets, Inc., formerly API NetWorks, Inc., formerly Alpha Processor, Inc.
714214d9 Alliance Semiconductor Corporation
7143 0010 AP1011/SP1011 HyperTransport-PCI Bridge [Sturgeon]
7144 9000 AS90L10204/10208 HyperTransport to PCI-X Bridge
714514da National Aerospace Laboratories
714614db AFAVLAB Technology Inc
7147 2120 TK9902
714814dc Amplicon Liveline Ltd
7149 0000 PCI230
7150 0001 PCI242
7151 0002 PCI244
7152 0003 PCI247
7153 0004 PCI248
7154 0005 PCI249
7155 0006 PCI260
7156 0007 PCI224
7157 0008 PCI234
7158 0009 PCI236
7159 000a PCI272
7160 000b PCI215
716114dd Boulder Design Labs Inc
716214de Applied Integration Corporation
716314df ASIC Communications Corp
716414e1 INVERTEX
716514e2 INFOLIBRIA
716614e3 AMTELCO
716714e4 Broadcom Corporation
7168 0800 Sentry5 Chipcommon I/O Controller
7169 0804 Sentry5 PCI Bridge
7170 0805 Sentry5 MIPS32 CPU
7171 0806 Sentry5 Ethernet Controller
7172 080b Sentry5 Crypto Accelerator
7173 080f Sentry5 DDR/SDR RAM Controller
7174 0811 Sentry5 External Interface Core
7175 0816 BCM3302 Sentry5 MIPS32 CPU
7176 1644 NetXtreme BCM5700 Gigabit Ethernet
7177 1014 0277 Broadcom Vigil B5700 1000Base-T
7178 1028 00d1 Broadcom BCM5700
7179 1028 0106 Broadcom BCM5700
7180 1028 0109 Broadcom BCM5700 1000Base-T
7181 1028 010a Broadcom BCM5700 1000BaseTX
7182 10b7 1000 3C996-T 1000Base-T
7183 10b7 1001 3C996B-T 1000Base-T
7184 10b7 1002 3C996C-T 1000Base-T
7185 10b7 1003 3C997-T 1000Base-T Dual Port
7186 10b7 1004 3C996-SX 1000Base-SX
7187 10b7 1005 3C997-SX 1000Base-SX Dual Port
7188 10b7 1008 3C942 Gigabit LOM (31X31)
7189 14e4 0002 NetXtreme 1000Base-SX
7190 14e4 0003 NetXtreme 1000Base-SX
7191 14e4 0004 NetXtreme 1000Base-T
7192 14e4 1028 NetXtreme 1000BaseTX
7193 14e4 1644 BCM5700 1000Base-T
7194 1645 NetXtreme BCM5701 Gigabit Ethernet
7195 0e11 007c NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
7196 0e11 007d NC6770 Gigabit Server Adapter (PCI-X, 1000-SX)
7197 0e11 0085 NC7780 Gigabit Server Adapter (embedded, WOL)
7198 0e11 0099 NC7780 Gigabit Server Adapter (embedded, WOL)
7199 0e11 009a NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
7200 0e11 00c1 NC6770 Gigabit Server Adapter (PCI-X, 1000-SX)
7201 1028 0121 Broadcom BCM5701 1000Base-T
7202 103c 128a HP 1000Base-T (PCI) [A7061A]
7203 103c 128b HP 1000Base-SX (PCI) [A7073A]
7204 103c 12a4 HP Core Lan 1000Base-T
7205 103c 12c1 HP IOX Core Lan 1000Base-T [A7109AX]
7206 10a9 8010 SGI IO9 Gigabit Ethernet (Copper)
7207 10a9 8011 SGI Gigabit Ethernet (Copper)
7208 10a9 8012 SGI Gigabit Ethernet (Fiber)
7209 10b7 1004 3C996-SX 1000Base-SX
7210 10b7 1006 3C996B-T 1000Base-T
7211 10b7 1007 3C1000-T 1000Base-T
7212 10b7 1008 3C940-BR01 1000Base-T
7213 14e4 0001 BCM5701 1000Base-T
7214 14e4 0005 BCM5701 1000Base-T
7215 14e4 0006 BCM5701 1000Base-T
7216 14e4 0007 BCM5701 1000Base-SX
7217 14e4 0008 BCM5701 1000Base-T
7218 14e4 8008 BCM5701 1000Base-T
7219 1646 NetXtreme BCM5702 Gigabit Ethernet
7220 0e11 00bb NC7760 1000BaseTX
7221 1028 0126 Broadcom BCM5702 1000BaseTX
7222 14e4 8009 BCM5702 1000BaseTX
7223 1647 NetXtreme BCM5703 Gigabit Ethernet
7224 0e11 0099 NC7780 1000BaseTX
7225 0e11 009a NC7770 1000BaseTX
7226 10a9 8010 SGI IO9 Gigabit Ethernet (Copper)
7227 14e4 0009 BCM5703 1000BaseTX
7228 14e4 000a BCM5703 1000BaseSX
7229 14e4 000b BCM5703 1000BaseTX
7230 14e4 8009 BCM5703 1000BaseTX
7231 14e4 800a BCM5703 1000BaseTX
7232 1648 NetXtreme BCM5704 Gigabit Ethernet
7233 0e11 00cf NC7772 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
7234 0e11 00d0 NC7782 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
7235 0e11 00d1 NC7783 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
7236 10b7 2000 3C998-T Dual Port 10/100/1000 PCI-X
7237 10b7 3000 3C999-T Quad Port 10/100/1000 PCI-X
7238 1166 1648 NetXtreme CIOB-E 1000Base-T
7239 164a NetXtreme II BCM5706 Gigabit Ethernet
7240 164d NetXtreme BCM5702FE Gigabit Ethernet
7241 1653 NetXtreme BCM5705 Gigabit Ethernet
7242 0e11 00e3 NC7761 Gigabit Server Adapter
7243 1654 NetXtreme BCM5705_2 Gigabit Ethernet
7244 0e11 00e3 NC7761 Gigabit Server Adapter
7245 103c 3100 NC1020 HP ProLiant Gigabit Server Adapter 32 PCI
7246 1659 NetXtreme BCM5721 Gigabit Ethernet PCI Express
7247 165d NetXtreme BCM5705M Gigabit Ethernet
7248 165e NetXtreme BCM5705M_2 Gigabit Ethernet
7249 103c 088c nc8000 laptop
7250 103c 0890 nc6000 laptop
7251 166e 570x 10/100 Integrated Controller
7252 1677 NetXtreme BCM5751 Gigabit Ethernet PCI Express
7253 1028 0179 Optiplex GX280
7254 167d NetXtreme BCM5751M Gigabit Ethernet PCI Express
7255 167e NetXtreme BCM5751F Fast Ethernet PCI Express
7256 1696 NetXtreme BCM5782 Gigabit Ethernet
7257 103c 12bc HP d530 CMT (DG746A)
7258 14e4 000d NetXtreme BCM5782 1000Base-T
7259 169c NetXtreme BCM5788 Gigabit Ethernet
7260 169d NetLink BCM5789 Gigabit Ethernet PCI Express
7261 16a6 NetXtreme BCM5702X Gigabit Ethernet
7262 0e11 00bb NC7760 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
7263 1028 0126 BCM5702 1000Base-T
7264 14e4 000c BCM5702 1000Base-T
7265 14e4 8009 BCM5702 1000Base-T
7266 16a7 NetXtreme BCM5703X Gigabit Ethernet
7267 0e11 00ca NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
7268 0e11 00cb NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
7269 14e4 0009 NetXtreme BCM5703 1000Base-T
7270 14e4 000a NetXtreme BCM5703 1000Base-SX
7271 14e4 000b NetXtreme BCM5703 1000Base-T
7272 14e4 800a NetXtreme BCM5703 1000Base-T
7273 16a8 NetXtreme BCM5704S Gigabit Ethernet
7274 10b7 2001 3C998-SX Dual Port 1000-SX PCI-X
7275 16aa NetXtreme II BCM5706S Gigabit Ethernet
7276 16c6 NetXtreme BCM5702A3 Gigabit Ethernet
7277 10b7 1100 3C1000B-T 10/100/1000 PCI
7278 14e4 000c BCM5702 1000Base-T
7279 14e4 8009 BCM5702 1000Base-T
7280 16c7 NetXtreme BCM5703 Gigabit Ethernet
7281 0e11 00ca NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
7282 0e11 00cb NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
7283 103c 12c3 HP Combo FC/GigE-SX [A9782A]
7284 103c 12ca HP Combo FC/GigE-T [A9784A]
7285 14e4 0009 NetXtreme BCM5703 1000Base-T
7286 14e4 000a NetXtreme BCM5703 1000Base-SX
7287 16dd NetLink BCM5781 Gigabit Ethernet PCI Express
7288 16f7 NetXtreme BCM5753 Gigabit Ethernet PCI Express
7289 16fd NetXtreme BCM5753M Gigabit Ethernet PCI Express
7290 16fe NetXtreme BCM5753F Fast Ethernet PCI Express
7291 170c BCM4401-B0 100Base-TX
7292 170d NetXtreme BCM5901 100Base-TX
7293 1014 0545 ThinkPad R40e (2684-HVG) builtin ethernet controller
7294 170e NetXtreme BCM5901 100Base-TX
7295 3352 BCM3352
7296 3360 BCM3360
7297 4210 BCM4210 iLine10 HomePNA 2.0
7298 4211 BCM4211 iLine10 HomePNA 2.0 + V.90 56k modem
7299 4212 BCM4212 v.90 56k modem
7300 4301 BCM4303 802.11b Wireless LAN Controller
7301 1028 0407 TrueMobile 1180 Onboard WLAN
7302 1043 0120 WL-103b Wireless LAN PC Card
7303 4305 BCM4307 V.90 56k Modem
7304 4306 BCM4307 Ethernet Controller
7305 4307 BCM4307 802.11b Wireless LAN Controller
7306 4310 BCM4310 Chipcommon I/OController
7307 4312 BCM4310 UART
7308 4313 BCM4310 Ethernet Controller
7309 4315 BCM4310 USB Controller
7310 4320 BCM4306 802.11b/g Wireless LAN Controller
7311 1028 0001 TrueMobile 1300 WLAN Mini-PCI Card
7312 1028 0003 Wireless 1350 WLAN Mini-PCI Card
7313 1043 100f WL-100G
7314 14e4 4320 Linksys WMP54G PCI
7315 1737 4320 WPC54G
7316 1799 7010 Belkin F5D7010 54g Wireless Network card
7317 4321 BCM4306 802.11a Wireless LAN Controller
7318 4322 BCM4306 UART
7319 4324 BCM4309 802.11a/b/g
7320 1028 0001 Truemobile 1400
7321 1028 0003 Truemobile 1450 MiniPCI
7322 4325 BCM43xG 802.11b/g
7323 1414 0003 Wireless Notebook Adapter MN-720
7324 1414 0004 Wireless PCI Adapter MN-730
7325# probably this is a correct ID...
7326 4326 BCM4307 Chipcommon I/O Controller?
7327 4401 BCM4401 100Base-T
7328 1043 80a8 A7V8X motherboard
7329 4402 BCM4402 Integrated 10/100BaseT
7330 4403 BCM4402 V.90 56k Modem
7331 4410 BCM4413 iLine32 HomePNA 2.0
7332 4411 BCM4413 V.90 56k modem
7333 4412 BCM4412 10/100BaseT
7334 4430 BCM44xx CardBus iLine32 HomePNA 2.0
7335 4432 BCM4432 CardBus 10/100BaseT
7336 4610 BCM4610 Sentry5 PCI to SB Bridge
7337 4611 BCM4610 Sentry5 iLine32 HomePNA 1.0
7338 4612 BCM4610 Sentry5 V.90 56k Modem
7339 4613 BCM4610 Sentry5 Ethernet Controller
7340 4614 BCM4610 Sentry5 External Interface
7341 4615 BCM4610 Sentry5 USB Controller
7342 4704 BCM4704 PCI to SB Bridge
7343 4705 BCM4704 Sentry5 802.11b Wireless LAN Controller
7344 4706 BCM4704 Sentry5 Ethernet Controller
7345 4707 BCM4704 Sentry5 USB Controller
7346 4708 BCM4704 Crypto Accelerator
7347 4710 BCM4710 Sentry5 PCI to SB Bridge
7348 4711 BCM47xx Sentry5 iLine32 HomePNA 2.0
7349 4712 BCM47xx V.92 56k modem
7350 4713 Sentry5 Ethernet Controller
7351 4714 BCM47xx Sentry5 External Interface
7352 4715 Sentry5 USB Controller
7353 4716 BCM47xx Sentry5 USB Host Controller
7354 4717 BCM47xx Sentry5 USB Device Controller
7355 4718 Sentry5 Crypto Accelerator
7356 4720 BCM4712 MIPS CPU
7357 5365 BCM5365P Sentry5 Host Bridge
7358 5600 BCM5600 StrataSwitch 24+2 Ethernet Switch Controller
7359 5605 BCM5605 StrataSwitch 24+2 Ethernet Switch Controller
7360 5615 BCM5615 StrataSwitch 24+2 Ethernet Switch Controller
7361 5625 BCM5625 StrataSwitch 24+2 Ethernet Switch Controller
7362 5645 BCM5645 StrataSwitch 24+2 Ethernet Switch Controller
7363 5670 BCM5670 8-Port 10GE Ethernet Switch Fabric
7364 5680 BCM5680 G-Switch 8 Port Gigabit Ethernet Switch Controller
7365 5690 BCM5690 12-port Multi-Layer Gigabit Ethernet Switch
7366 5691 BCM5691 GE/10GE 8+2 Gigabit Ethernet Switch Controller
7367 5820 BCM5820 Crypto Accelerator
7368 5821 BCM5821 Crypto Accelerator
7369 5822 BCM5822 Crypto Accelerator
7370 5823 BCM5823 Crypto Accelerator
7371 5824 BCM5824 Crypto Accelerator
7372 5840 BCM5840 Crypto Accelerator
7373 5841 BCM5841 Crypto Accelerator
7374 5850 BCM5850 Crypto Accelerator
737514e5 Pixelfusion Ltd
737614e6 SHINING Technology Inc
737714e7 3CX
737814e8 RAYCER Inc
737914e9 GARNETS System CO Ltd
738014ea Planex Communications, Inc
7381 ab06 FNW-3603-TX CardBus Fast Ethernet
7382 ab07 RTL81xx RealTek Ethernet
738314eb SEIKO EPSON Corp
738414ec ACQIRIS
738514ed DATAKINETICS Ltd
738614ee MASPRO KENKOH Corp
738714ef CARRY Computer ENG. CO Ltd
738814f0 CANON RESEACH CENTRE FRANCE
738914f1 Conexant
7390 1002 HCF 56k Modem
7391 1003 HCF 56k Modem
7392 1004 HCF 56k Modem
7393 1005 HCF 56k Modem
7394 1006 HCF 56k Modem
7395 1022 HCF 56k Modem
7396 1023 HCF 56k Modem
7397 1024 HCF 56k Modem
7398 1025 HCF 56k Modem
7399 1026 HCF 56k Modem
7400 1032 HCF 56k Modem
7401 1033 HCF 56k Data/Fax Modem
7402 1033 8077 NEC
7403 122d 4027 Dell Zeus - MDP3880-W(B) Data Fax Modem
7404 122d 4030 Dell Mercury - MDP3880-U(B) Data Fax Modem
7405 122d 4034 Dell Thor - MDP3880-W(U) Data Fax Modem
7406 13e0 020d Dell Copper
7407 13e0 020e Dell Silver
7408 13e0 0261 IBM
7409 13e0 0290 Compaq Goldwing
7410 13e0 02a0 IBM
7411 13e0 02b0 IBM
7412 13e0 02c0 Compaq Scooter
7413 13e0 02d0 IBM
7414 144f 1500 IBM P85-DF (1)
7415 144f 1501 IBM P85-DF (2)
7416 144f 150a IBM P85-DF (3)
7417 144f 150b IBM P85-DF Low Profile (1)
7418 144f 1510 IBM P85-DF Low Profile (2)
7419 1034 HCF 56k Data/Fax/Voice Modem
7420 1035 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
7421 10cf 1098 Fujitsu P85-DFSV
7422 1036 HCF 56k Data/Fax/Voice/Spkp Modem
7423 104d 8067 HCF 56k Modem
7424 122d 4029 MDP3880SP-W
7425 122d 4031 MDP3880SP-U
7426 13e0 0209 Dell Titanium
7427 13e0 020a Dell Graphite
7428 13e0 0260 Gateway Red Owl
7429 13e0 0270 Gateway White Horse
7430 1052 HCF 56k Data/Fax Modem (Worldwide)
7431 1053 HCF 56k Data/Fax Modem (Worldwide)
7432 1054 HCF 56k Data/Fax/Voice Modem (Worldwide)
7433 1055 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Worldwide)
7434 1056 HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide)
7435 1057 HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide)
7436 1059 HCF 56k Data/Fax/Voice Modem (Worldwide)
7437 1063 HCF 56k Data/Fax Modem
7438 1064 HCF 56k Data/Fax/Voice Modem
7439 1065 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
7440 1066 HCF 56k Data/Fax/Voice/Spkp Modem
7441 122d 4033 Dell Athena - MDP3900V-U
7442 1433 HCF 56k Data/Fax Modem
7443 1434 HCF 56k Data/Fax/Voice Modem
7444 1435 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
7445 1436 HCF 56k Data/Fax Modem
7446 1453 HCF 56k Data/Fax Modem
7447 13e0 0240 IBM
7448 13e0 0250 IBM
7449 144f 1502 IBM P95-DF (1)
7450 144f 1503 IBM P95-DF (2)
7451 1454 HCF 56k Data/Fax/Voice Modem
7452 1455 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
7453 1456 HCF 56k Data/Fax/Voice/Spkp Modem
7454 122d 4035 Dell Europa - MDP3900V-W
7455 122d 4302 Dell MP3930V-W(C) MiniPCI
7456 1610 ADSL AccessRunner PCI Arbitration Device
7457 1611 AccessRunner PCI ADSL Interface Device
7458 1620 ADSL AccessRunner V2 PCI Arbitration Device
7459 1621 AccessRunner V2 PCI ADSL Interface Device
7460 1622 AccessRunner V2 PCI ADSL Yukon WAN Adapter
7461 1803 HCF 56k Modem
7462 0e11 0023 623-LAN Grizzly
7463 0e11 0043 623-LAN Yogi
7464 1815 HCF 56k Modem
7465 0e11 0022 Grizzly
7466 0e11 0042 Yogi
7467 2003 HSF 56k Data/Fax Modem
7468 2004 HSF 56k Data/Fax/Voice Modem
7469 2005 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
7470 2006 HSF 56k Data/Fax/Voice/Spkp Modem
7471 2013 HSF 56k Data/Fax Modem
7472 0e11 b195 Bear
7473 0e11 b196 Seminole 1
7474 0e11 b1be Seminole 2
7475 1025 8013 Acer
7476 1033 809d NEC
7477 1033 80bc NEC
7478 155d 6793 HP
7479 155d 8850 E Machines
7480 2014 HSF 56k Data/Fax/Voice Modem
7481 2015 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
7482 2016 HSF 56k Data/Fax/Voice/Spkp Modem
7483 2043 HSF 56k Data/Fax Modem (WorldW SmartDAA)
7484 2044 HSF 56k Data/Fax/Voice Modem (WorldW SmartDAA)
7485 2045 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (WorldW SmartDAA)
7486 2046 HSF 56k Data/Fax/Voice/Spkp Modem (WorldW SmartDAA)
7487 2063 HSF 56k Data/Fax Modem (SmartDAA)
7488 2064 HSF 56k Data/Fax/Voice Modem (SmartDAA)
7489 2065 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (SmartDAA)
7490 2066 HSF 56k Data/Fax/Voice/Spkp Modem (SmartDAA)
7491 2093 HSF 56k Modem
7492 155d 2f07 Legend
7493 2143 HSF 56k Data/Fax/Cell Modem (Mob WorldW SmartDAA)
7494 2144 HSF 56k Data/Fax/Voice/Cell Modem (Mob WorldW SmartDAA)
7495 2145 HSF 56k Data/Fax/Voice/Spkp (w/HS)/Cell Modem (Mob WorldW SmartDAA)
7496 2146 HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mob WorldW SmartDAA)
7497 2163 HSF 56k Data/Fax/Cell Modem (Mob SmartDAA)
7498 2164 HSF 56k Data/Fax/Voice/Cell Modem (Mob SmartDAA)
7499 2165 HSF 56k Data/Fax/Voice/Spkp (w/HS)/Cell Modem (Mob SmartDAA)
7500 2166 HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mob SmartDAA)
7501 2343 HSF 56k Data/Fax CardBus Modem (Mob WorldW SmartDAA)
7502 2344 HSF 56k Data/Fax/Voice CardBus Modem (Mob WorldW SmartDAA)
7503 2345 HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob WorldW SmartDAA)
7504 2346 HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mob WorldW SmartDAA)
7505 2363 HSF 56k Data/Fax CardBus Modem (Mob SmartDAA)
7506 2364 HSF 56k Data/Fax/Voice CardBus Modem (Mob SmartDAA)
7507 2365 HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob SmartDAA)
7508 2366 HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mob SmartDAA)
7509 2443 HSF 56k Data/Fax Modem (Mob WorldW SmartDAA)
7510 104d 8075 Modem
7511 104d 8083 Modem
7512 104d 8097 Modem
7513 2444 HSF 56k Data/Fax/Voice Modem (Mob WorldW SmartDAA)
7514 2445 HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mob WorldW SmartDAA)
7515 2446 HSF 56k Data/Fax/Voice/Spkp Modem (Mob WorldW SmartDAA)
7516 2463 HSF 56k Data/Fax Modem (Mob SmartDAA)
7517 2464 HSF 56k Data/Fax/Voice Modem (Mob SmartDAA)
7518 2465 HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mob SmartDAA)
7519 2466 HSF 56k Data/Fax/Voice/Spkp Modem (Mob SmartDAA)
7520 2f00 HSF 56k HSFi Modem
7521 13e0 8d84 IBM HSFi V.90
7522 13e0 8d85 Compaq Stinger
7523 14f1 2004 Dynalink 56PMi
7524 2f02 HSF 56k HSFi Data/Fax
7525 2f11 HSF 56k HSFi Modem
7526 8234 RS8234 ATM SAR Controller [ServiceSAR Plus]
7527 8800 CX22702 DVB-T 2k/8k
7528 17de 08a1 XPert DVB-T PCI BDA DVBT 23880 Video Capture
7529 8802 CX23883 Broadcast Decoder
7530 17de 08a1 Xpert DVB-T PCI 2388x Transport Stream Capture
753114f2 MOBILITY Electronics
7532 0120 EV1000 bridge
7533 0121 EV1000 Parallel port
7534 0122 EV1000 Serial port
7535 0123 EV1000 Keyboard controller
7536 0124 EV1000 Mouse controller
753714f3 BroadLogic
7538 2030 2030 DVB-S Satellite Reciever
7539 2050 2050 DVB-T Terrestrial (Cable) Reciever
7540 2060 2060 ATSC Terrestrial (Cable) Reciever
754114f4 TOKYO Electronic Industry CO Ltd
754214f5 SOPAC Ltd
754314f6 COYOTE Technologies LLC
754414f7 WOLF Technology Inc
754514f8 AUDIOCODES Inc
7546 2077 TP-240 dual span E1 VoIP PCI card
754714f9 AG COMMUNICATIONS
754814fa WANDEL & GOCHERMANN
754914fb TRANSAS MARINE (UK) Ltd
755014fc Quadrics Ltd
7551 0000 QsNet Elan3 Network Adapter
7552 0001 QsNetII Elan4 Network Adapter
755314fd JAPAN Computer Industry Inc
755414fe ARCHTEK TELECOM Corp
755514ff TWINHEAD INTERNATIONAL Corp
75561500 DELTA Electronics, Inc
7557 1360 RTL81xx RealTek Ethernet
75581501 BANKSOFT CANADA Ltd
75591502 MITSUBISHI ELECTRIC LOGISTICS SUPPORT Co Ltd
75601503 KAWASAKI LSI USA Inc
75611504 KAISER Electronics
75621505 ITA INGENIEURBURO FUR TESTAUFGABEN GmbH
75631506 CHAMELEON Systems Inc
7564# Should be HTEC Ltd, but there are no known HTEC chips and 1507 is already used by mistake by Motorola (see vendor ID 1057).
75651507 Motorola ?? / HTEC
7566 0001 MPC105 [Eagle]
7567 0002 MPC106 [Grackle]
7568 0003 MPC8240 [Kahlua]
7569 0100 MC145575 [HFC-PCI]
7570 0431 KTI829c 100VG
7571 4801 Raven
7572 4802 Falcon
7573 4803 Hawk
7574 4806 CPX8216
75751508 HONDA CONNECTORS/MHOTRONICS Inc
75761509 FIRST INTERNATIONAL Computer Inc
7577150a FORVUS RESEARCH Inc
7578150b YAMASHITA Systems Corp
7579150c KYOPAL CO Ltd
7580150d WARPSPPED Inc
7581150e C-PORT Corp
7582150f INTEC GmbH
75831510 BEHAVIOR TECH Computer Corp
75841511 CENTILLIUM Technology Corp
75851512 ROSUN Technologies Inc
75861513 Raychem
75871514 TFL LAN Inc
75881515 Advent design
75891516 MYSON Technology Inc
7590 0800 MTD-8xx 100/10M Ethernet PCI Adapter
7591 0803 SURECOM EP-320X-S 100/10M Ethernet PCI Adapter
7592 1320 10bd SURECOM EP-320X-S 100/10M Ethernet PCI Adapter
7593 0891 MTD-8xx 100/10M Ethernet PCI Adapter
75941517 ECHOTEK Corp
75951518 PEP MODULAR Computers GmbH
75961519 TELEFON AKTIEBOLAGET LM Ericsson
7597151a Globetek
7598 1002 PCI-1002
7599 1004 PCI-1004
7600 1008 PCI-1008
7601151b COMBOX Ltd
7602151c DIGITAL AUDIO LABS Inc
7603 0003 Prodif T 2496
7604 4000 Prodif 88
7605151d Fujitsu Computer Products Of America
7606151e MATRIX Corp
7607151f TOPIC SEMICONDUCTOR Corp
7608 0000 TP560 Data/Fax/Voice 56k modem
76091520 CHAPLET System Inc
76101521 BELL Corp
76111522 MainPine Ltd
7612 0100 PCI <-> IOBus Bridge
7613 1522 0200 RockForceDUO 2 Port V.92/V.44 Data/Fax/Voice Modem
7614 1522 0300 RockForceQUATRO 4 Port V.92/V.44 Data/Fax/Voice Modem
7615 1522 0400 RockForceDUO+ 2 Port V.92/V.44 Data/Fax/Voice Modem
7616 1522 0500 RockForceQUATRO+ 4 Port V.92/V.44 Data/Fax/Voice Modem
7617 1522 0600 RockForce+ 2 Port V.90 Data/Fax/Voice Modem
7618 1522 0700 RockForce+ 4 Port V.90 Data/Fax/Voice Modem
7619 1522 0800 RockForceOCTO+ 8 Port V.92/V.44 Data/Fax/Voice Modem
7620 1522 0c00 RockForceDUO+ 2 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
7621 1522 0d00 RockForceQUATRO+ 4 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
7622# this is a correction to a recent entry. 1522:0E00 should be 1522:1D00
7623 1522 1d00 RockForceOCTO+ 8 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
76241523 MUSIC Semiconductors
76251524 ENE Technology Inc
7626 0510 CB710 Memory Card Reader Controller
7627 0610 PCI Smart Card Reader Controller
7628 1211 CB1211 Cardbus Controller
7629 1225 CB1225 Cardbus Controller
7630 1410 CB1410 Cardbus Controller
7631 1025 005a TravelMate 290
7632 1411 CB-710/2/4 Cardbus Controller
7633 1412 CB-712/4 Cardbus Controller
7634 1420 CB1420 Cardbus Controller
7635 1421 CB-720/2/4 Cardbus Controller
7636 1422 CB-722/4 Cardbus Controller
76371525 IMPACT Technologies
76381526 ISS, Inc
76391527 SOLECTRON
76401528 ACKSYS
76411529 AMERICAN MICROSystems Inc
7642152a QUICKTURN DESIGN Systems
7643152b FLYTECH Technology CO Ltd
7644152c MACRAIGOR Systems LLC
7645152d QUANTA Computer Inc
7646152e MELEC Inc
7647152f PHILIPS - CRYPTO
76481530 ACQIS Technology Inc
76491531 CHRYON Corp
76501532 ECHELON Corp
76511533 BALTIMORE
76521534 ROAD Corp
76531535 EVERGREEN Technologies Inc
76541537 DATALEX COMMUNCATIONS
76551538 ARALION Inc
7656 0303 ARS106S Ultra ATA 133/100/66 Host Controller
76571539 ATELIER INFORMATIQUES et ELECTRONIQUE ETUDES S.A.
7658153a ONO SOKKI
7659153b TERRATEC Electronic GmbH
7660 1144 Aureon 5.1
7661# Terratec seems to use several IDs for the same card.
7662 1147 Aureon 5.1 Sky
7663 1158 Philips Semiconductors SAA7134 (rev 01) [Terratec Cinergy 600 TV]
7664153c ANTAL Electronic
7665153d FILANET Corp
7666153e TECHWELL Inc
7667153f MIPS DENMARK
76681540 PROVIDEO MULTIMEDIA Co Ltd
76691541 MACHONE Communications
76701542 VIVID Technology Inc
76711543 SILICON Laboratories
7672 3052 Intel 537 [Winmodem]
7673 4c22 Si3036 MC'97 DAA
76741544 DCM DATA Systems
76751545 VISIONTEK
76761546 IOI Technology Corp
76771547 MITUTOYO Corp
76781548 JET PROPULSION Laboratory
76791549 INTERCONNECT Systems Solutions
7680154a MAX Technologies Inc
7681154b COMPUTEX Co Ltd
7682154c VISUAL Technology Inc
7683154d PAN INTERNATIONAL Industrial Corp
7684154e SERVOTEST Ltd
7685154f STRATABEAM Technology
76861550 OPEN NETWORK Co Ltd
76871551 SMART Electronic DEVELOPMENT GmBH
76881552 RACAL AIRTECH Ltd
76891553 CHICONY Electronics Co Ltd
76901554 PROLINK Microsystems Corp
76911555 GESYTEC GmBH
76921556 PLD APPLICATIONS
76931557 MEDIASTAR Co Ltd
76941558 CLEVO/KAPOK Computer
76951559 SI LOGIC Ltd
7696155a INNOMEDIA Inc
7697155b PROTAC INTERNATIONAL Corp
7698155c Cemax-Icon Inc
7699155d Mac System Co Ltd
7700155e LP Elektronik GmbH
7701155f Perle Systems Ltd
77021560 Terayon Communications Systems
77031561 Viewgraphics Inc
77041562 Symbol Technologies
77051563 A-Trend Technology Co Ltd
77061564 Yamakatsu Electronics Industry Co Ltd
77071565 Biostar Microtech Int'l Corp
77081566 Ardent Technologies Inc
77091567 Jungsoft
77101568 DDK Electronics Inc
77111569 Palit Microsystems Inc.
7712156a Avtec Systems
7713156b 2wire Inc
7714156c Vidac Electronics GmbH
7715156d Alpha-Top Corp
7716156e Alfa Inc
7717156f M-Systems Flash Disk Pioneers Ltd
77181570 Lecroy Corp
77191571 Contemporary Controls
7720 a001 CCSI PCI20-485 ARCnet
7721 a002 CCSI PCI20-485D ARCnet
7722 a003 CCSI PCI20-485X ARCnet
7723 a004 CCSI PCI20-CXB ARCnet
7724 a005 CCSI PCI20-CXS ARCnet
7725 a006 CCSI PCI20-FOG-SMA ARCnet
7726 a007 CCSI PCI20-FOG-ST ARCnet
7727 a008 CCSI PCI20-TB5 ARCnet
7728 a009 CCSI PCI20-5-485 5Mbit ARCnet
7729 a00a CCSI PCI20-5-485D 5Mbit ARCnet
7730 a00b CCSI PCI20-5-485X 5Mbit ARCnet
7731 a00c CCSI PCI20-5-FOG-ST 5Mbit ARCnet
7732 a00d CCSI PCI20-5-FOG-SMA 5Mbit ARCnet
7733 a201 CCSI PCI22-485 10Mbit ARCnet
7734 a202 CCSI PCI22-485D 10Mbit ARCnet
7735 a203 CCSI PCI22-485X 10Mbit ARCnet
7736 a204 CCSI PCI22-CHB 10Mbit ARCnet
7737 a205 CCSI PCI22-FOG_ST 10Mbit ARCnet
7738 a206 CCSI PCI22-THB 10Mbit ARCnet
77391572 Otis Elevator Company
77401573 Lattice - Vantis
77411574 Fairchild Semiconductor
77421575 Voltaire Advanced Data Security Ltd
77431576 Viewcast COM
77441578 HITT
7745 5615 VPMK3 [Video Processor Mk III]
77461579 Dual Technology Corp
7747157a Japan Elecronics Ind Inc
7748157b Star Multimedia Corp
7749157c Eurosoft (UK)
7750 8001 Fix2000 PCI Y2K Compliance Card
7751157d Gemflex Networks
7752157e Transition Networks
7753157f PX Instruments Technology Ltd
77541580 Primex Aerospace Co
77551581 SEH Computertechnik GmbH
77561582 Cytec Corp
77571583 Inet Technologies Inc
77581584 Uniwill Computer Corp
77591585 Logitron
77601586 Lancast Inc
77611587 Konica Corp
77621588 Solidum Systems Corp
77631589 Atlantek Microsystems Pty Ltd
7764158a Digalog Systems Inc
7765158b Allied Data Technologies
7766158c Hitachi Semiconductor & Devices Sales Co Ltd
7767158d Point Multimedia Systems
7768158e Lara Technology Inc
7769158f Ditect Coop
77701590 3pardata Inc
77711591 ARN
77721592 Syba Tech Ltd
7773 0781 Multi-IO Card
7774 0782 Parallel Port Card 2xEPP
7775 0783 Multi-IO Card
7776 0785 Multi-IO Card
7777 0786 Multi-IO Card
7778 0787 Multi-IO Card
7779 0788 Multi-IO Card
7780 078a Multi-IO Card
77811593 Bops Inc
77821594 Netgame Ltd
77831595 Diva Systems Corp
77841596 Folsom Research Inc
77851597 Memec Design Services
77861598 Granite Microsystems
77871599 Delta Electronics Inc
7788159a General Instrument
7789159b Faraday Technology Corp
7790159c Stratus Computer Systems
7791159d Ningbo Harrison Electronics Co Ltd
7792159e A-Max Technology Co Ltd
7793159f Galea Network Security
779415a0 Compumaster SRL
779515a1 Geocast Network Systems
779615a2 Catalyst Enterprises Inc
7797 0001 TA700 PCI Bus Analyzer/Exerciser
779815a3 Italtel
779915a4 X-Net OY
780015a5 Toyota Macs Inc
780115a6 Sunlight Ultrasound Technologies Ltd
780215a7 SSE Telecom Inc
780315a8 Shanghai Communications Technologies Center
780415aa Moreton Bay
780515ab Bluesteel Networks Inc
780615ac North Atlantic Instruments
780715ad VMware Inc
7808 0405 [VMware SVGA II] PCI Display Adapter
7809 0710 Virtual SVGA
7810 0720 VMware High-Speed Virtual NIC [vmxnet]
781115ae Amersham Pharmacia Biotech
781215b0 Zoltrix International Ltd
781315b1 Source Technology Inc
781415b2 Mosaid Technologies Inc
781515b3 Mellanox Technologies
7816 5274 MT21108 InfiniBridge
7817 5a44 MT23108 InfiniHost
7818 5a45 MT23108 [Infinihost HCA Flash Recovery]
7819 5a46 MT23108 PCI Bridge
7820 5e8c MT24204 [InfiniHost III Lx HCA]
7821 5e8d MT24204 [InfiniHost III Lx HCA Flash Recovery]
7822 6278 MT25208 InfiniHost III Ex (Tavor compatibility mode)
7823 6279 MT25208 [InfiniHost III Ex HCA Flash Recovery]
7824 6282 MT25208 InfiniHost III Ex
782515b4 CCI/TRIAD
782615b5 Cimetrics Inc
782715b6 Texas Memory Systems Inc
782815b7 Sandisk Corp
782915b8 ADDI-DATA GmbH
783015b9 Maestro Digital Communications
783115ba Impacct Technology Corp
783215bb Portwell Inc
783315bc Agilent Technologies
7834 2922 64 Bit, 133MHz PCI-X Exerciser & Protocol Checker
7835 2928 64 Bit, 66MHz PCI Exerciser & Analyzer
7836 2929 64 Bit, 133MHz PCI-X Analyzer & Exerciser
783715bd DFI Inc
783815be Sola Electronics
783915bf High Tech Computer Corp (HTC)
784015c0 BVM Ltd
784115c1 Quantel
784215c2 Newer Technology Inc
784315c3 Taiwan Mycomp Co Ltd
784415c4 EVSX Inc
784515c5 Procomp Informatics Ltd
7846 8010 1394b - 1394 Firewire 3-Port Host Adapter Card
784715c6 Technical University of Budapest
784815c7 Tateyama System Laboratory Co Ltd
7849 0349 Tateyama C-PCI PLC/NC card Rev.01A
785015c8 Penta Media Co Ltd
785115c9 Serome Technology Inc
785215ca Bitboys OY
785315cb AG Electronics Ltd
785415cc Hotrail Inc
785515cd Dreamtech Co Ltd
785615ce Genrad Inc
785715cf Hilscher GmbH
785815d1 Infineon Technologies AG
785915d2 FIC (First International Computer Inc)
786015d3 NDS Technologies Israel Ltd
786115d4 Iwill Corp
786215d5 Tatung Co
786315d6 Entridia Corp
786415d7 Rockwell-Collins Inc
786515d8 Cybernetics Technology Co Ltd
786615d9 Super Micro Computer Inc
786715da Cyberfirm Inc
786815db Applied Computing Systems Inc
786915dc Litronic Inc
7870 0001 Argus 300 PCI Cryptography Module
787115dd Sigmatel Inc
787215de Malleable Technologies Inc
787315df Infinilink Corp
787415e0 Cacheflow Inc
787515e1 Voice Technologies Group Inc
787615e2 Quicknet Technologies Inc
787715e3 Networth Technologies Inc
787815e4 VSN Systemen BV
787915e5 Valley technologies Inc
788015e6 Agere Inc
788115e7 Get Engineering Corp
788215e8 National Datacomm Corp
7883 0130 Wireless PCI Card
788415e9 Pacific Digital Corp
7885 1841 ADMA-100 DiscStaQ ATA Controller
788615ea Tokyo Denshi Sekei K.K.
788715eb Drsearch GmbH
788815ec Beckhoff GmbH
7889 3101 FC3101 Profibus DP 1 Channel PCI
7890 5102 FC5102
789115ed Macrolink Inc
789215ee In Win Development Inc
789315ef Intelligent Paradigm Inc
789415f0 B-Tree Systems Inc
789515f1 Times N Systems Inc
789615f2 Diagnostic Instruments Inc
789715f3 Digitmedia Corp
789815f4 Valuesoft
789915f5 Power Micro Research
790015f6 Extreme Packet Device Inc
790115f7 Banctec
790215f8 Koga Electronics Co
790315f9 Zenith Electronics Corp
790415fa J.P. Axzam Corp
790515fb Zilog Inc
790615fc Techsan Electronics Co Ltd
790715fd N-CUBED.NET
790815fe Kinpo Electronics Inc
790915ff Fastpoint Technologies Inc
79101600 Northrop Grumman - Canada Ltd
79111601 Tenta Technology
79121602 Prosys-tec Inc
79131603 Nokia Wireless Communications
79141604 Central System Research Co Ltd
79151605 Pairgain Technologies
79161606 Europop AG
79171607 Lava Semiconductor Manufacturing Inc
79181608 Automated Wagering International
79191609 Scimetric Instruments Inc
79201612 Telesynergy Research Inc.
79211619 FarSite Communications Ltd
7922 0400 FarSync T2P (2 port X.21/V.35/V.24)
7923 0440 FarSync T4P (4 port X.21/V.35/V.24)
7924# www.rioworks.com
7925161f Rioworks
79261626 TDK Semiconductor Corp.
7927 8410 RTL81xx Fast Ethernet
79281629 Kongsberg Spacetec AS
7929 1003 Format synchronizer v3.0
7930 2002 Fast Universal Data Output
7931# This seems to occur on their 802.11b Wireless card WMP-11
79321637 Linksys
7933 3874 Linksys 802.11b WMP11 PCI Wireless card
79341638 Standard Microsystems Corp [SMC]
7935 1100 SMC2602W EZConnect / Addtron AWA-100 / Eumitcom PCI WL11000
7936163c Smart Link Ltd.
7937 3052 SmartLink SmartPCI562 56K Modem
7938 5449 SmartPCI561 Modem
79391657 Brocade Communications Systems, Inc.
7940165a Epix Inc
7941 c100 PIXCI(R) CL1 Camera Link Video Capture Board [custom QL5232]
7942 d200 PIXCI(R) D2X Digital Video Capture Board [custom QL5232]
7943 d300 PIXCI(R) D3X Digital Video Capture Board [custom QL5232]
7944165d Hsing Tech. Enterprise Co., Ltd.
79451661 Worldspace Corp.
79461668 Actiontec Electronics Inc
7947 0100 Mini-PCI bridge
7948# Formerly SiByte, Inc.
7949166d Broadcom Corporation
7950 0001 SiByte BCM1125/1125H/1250 System-on-a-Chip PCI
7951 0002 SiByte BCM1125H/1250 System-on-a-Chip HyperTransport
79521677 Bernecker + Rainer
7953 104e 5LS172.6 B&R Dual CAN Interface Card
7954 12d7 5LS172.61 B&R Dual CAN Interface Card
7955167b ZyDAS Technology Corp.
7956 2102 ZyDAS ZD1202
7957 187e 3406 ZyAIR B-122 CardBus 11Mbs Wireless LAN Card
79581681 Hercules
7959# More specs, more accurate desc.
7960 0010 Hercules 3d Prophet II Ultra 64MB [ 350 MHz NV15BR core, 128-bit DDR @ 460 MHz, 1.5v AGP4x ]
79611682 XFX Pine Group Inc.
79621688 CastleNet Technology Inc.
7963 1170 WLAN 802.11b card
7964168c Atheros Communications, Inc.
7965 0007 AR5000 802.11a Wireless Adapter
7966 0011 AR5210 802.11a NIC
7967 0012 AR5211 802.11ab NIC
7968 0013 AR5212 802.11abg NIC
7969 1113 d301 Philips CPWNA100 Wireless CardBus adapter
7970 1186 3202 D-link DWL-G650 B3 Wireless cardbus adapter
7971 1186 3203 DWL-G520 Wireless PCI Adapter
7972 1186 3a13 DWL-G520 Wireless PCI Adapter rev. B
7973 1186 3a94 C54C Wireless 801.11g cardbus
7974 1385 4d00 Netgear WG311T Wireless PCI Adapter
7975 14b7 0a60 8482-WD ORiNOCO 11a/b/g Wireless PCI Adapter
7976 168c 0013 WG511T Wireless CardBus Adapter
7977 168c 1025 DWL-G650B2 Wireless CardBus Adapter
7978 168c 1027 Netgate NL-3054CB ARIES b/g CardBus Adapter
7979 168c 2026 Netgate 5354MP ARIES a(108Mb turbo)/b/g MiniPCI Adapter
7980 168c 2041 Netgate 5354MP Plus ARIES2 b/g MiniPCI Adapter
7981 168c 2042 Netgate 5354MP Plus ARIES2 a/b/g MiniPCI Adapter
7982 1014 AR5212 802.11abg NIC
7983169c Netcell Corporation
7984 0044 SyncRAID SR3000/5000 Series SATA RAID Controllers
798516a5 Tekram Technology Co.,Ltd.
798616ab Global Sun Technology Inc
7987 1100 GL24110P
7988 1101 PLX9052 PCMCIA-to-PCI Wireless LAN
7989 1102 PCMCIA-to-PCI Wireless Network Bridge
7990 8501 WL-8305 Wireless LAN PCI Adapter
799116ae Safenet Inc
7992 1141 SafeXcel-1141
799316b4 Aspex Semiconductor Ltd
799416be Creatix Polymedia GmbH
799516ca CENATEK Inc
7996 0001 Rocket Drive DL
799716cd Densitron Technologies
799816ce Roland Corp.
7999# www.pikatechnologies.com
800016df PIKA Technologies Inc.
800116e3 European Space Agency
8002 1e0f LEON2FT Processor
800316ec U.S. Robotics
8004 00ff USR997900 10/100 Mbps PCI Network Card
8005 0116 USR997902 10/100/1000 Mbps PCI Network Card
8006 3685 Wireless Access PCI Adapter Model 022415
800716ed Sycron N. V.
8008 1001 UMIO communication card
800916f3 Jetway Information Co., Ltd.
801016f4 Vweb Corp
8011 8000 VW2010
801216f6 VideoTele.com, Inc.
8013# www.internetmachines.com
80141702 Internet Machines Corporation (IMC)
80151705 Digital First, Inc.
8016170b NetOctave
8017 0100 NSP2000-SSL crypto accelerator
8018170c YottaYotta Inc.
8019# Seems to be a 2nd ID for Vitesse Semiconductor
80201725 Vitesse Semiconductor
8021 7174 VSC7174 PCI/PCI-X Serial ATA Host Bus Controller
8022172a Accelerated Encryption
80231734 Fujitsu Siemens Computer GmbH
80241737 Linksys
8025 0013 WMP54G Wireless Pci Card
8026 0015 WMP54GS Wireless Pci Card
8027 1032 Gigabit Network Adapter
8028 1737 0015 EG1032 v2 Instant Gigabit Network Adapter
8029 1064 Gigabit Network Adapter
8030 1737 0016 EG1064 v2 Instant Gigabit Network Adapter
8031 ab08 21x4x DEC-Tulip compatible 10/100 Ethernet
8032 ab09 21x4x DEC-Tulip compatible 10/100 Ethernet
8033173b Altima (nee Broadcom)
8034 03e8 AC1000 Gigabit Ethernet
8035 03e9 AC1001 Gigabit Ethernet
8036 03ea AC9100 Gigabit Ethernet
8037 173b 0001 AC1002
8038 03eb AC1003 Gigabit Ethernet
80391743 Peppercon AG
8040 8139 ROL/F-100 Fast Ethernet Adapter with ROL
80411749 RLX Technologies
8042174b PC Partner Limited
8043174d WellX Telecom SA
8044175c AudioScience Inc
8045175e Sanera Systems, Inc.
80461787 Hightech Information System Ltd.
8047# also used by Struck Innovative Systeme for joint developments
80481796 Research Centre Juelich
8049 0001 SIS1100 [Gigabit link]
8050 0002 HOTlink
8051 0003 Counter Timer
8052 0004 CAMAC Controller
8053 0005 PROFIBUS
8054 0006 AMCC HOTlink
80551797 JumpTec h, GMBH
80561799 Belkin
8057 6001 Wireless PCI Card - F5D6001
8058 6020 Wireless PCMCIA Card - F5D6020
8059 6060 Wireless PDA Card - F5D6060
8060 7000 Wireless PCI Card - F5D7000
806117a0 Genesys Logic, Inc
8062 8033 GL880S USB 1.1 controller
8063 8034 GL880S USB 2.0 controller
806417af Hightech Information System Ltd.
806517b3 Hawking Technologies
8066 ab08 PN672TX 10/100 Ethernet
806717b4 Indra Networks, Inc.
8068 0011 WebEnhance 100 GZIP Compression Card
806917c0 Wistron Corp.
807017c2 Newisys, Inc.
807117cc NetChip Technology, Inc
8072 2280 USB 2.0
807317d3 Areca Technology Corp.
8074 1110 ARC-1110 4-Port PCI-X to SATA RAID Controller
8075 1120 ARC-1120 8-Port PCI-X to SATA RAID Controller
8076 1130 ARC-1130 12-Port PCI-X to SATA RAID Controller
8077 1160 ARC-1160 16-Port PCI-X to SATA RAID Controller
8078 1210 ARC-1210 4-Port PCI-Express to SATA RAID Controller
8079 1220 ARC-1220 8-Port PCI-Express to SATA RAID Controller
8080 1230 ARC-1230 12-Port PCI-Express to SATA RAID Controller
8081 1260 ARC-1260 16-Port PCI-Express to SATA RAID Controller
8082# S2io ships 10Gb PCI-X Ethernet adapters www.s2io.com
808317d5 S2io Inc.
8084 5831 Xframe 10 Gigabit Ethernet PCI-X
8085 103c 12d5 HP PCI-X 133MHz 10GbE SR Fiber [AB287A]
808617de KWorld Computer Co. Ltd.
8087# http://www.connect3d.com
808817ee Connect Components Ltd
808917fe Linksys, A Division of Cisco Systems
8090 2120 WMP11v4 802.11b PCI card
8091 2220 [AirConn] INPROCOMM IPN 2220 Wireless LAN Adapter (rev 01)
80921813 Ambient Technologies Inc
8093 4000 HaM controllerless modem
8094 16be 0001 V9x HAM Data Fax Modem
8095 4100 HaM plus Data Fax Modem
8096 16be 0002 V9x HAM 1394
80971814 RaLink
8098 0101 Wireless PCI Adpator RT2400 / RT2460
8099 3306 1113 Quidway WL100M
8100 0201 Ralink RT2500 802.11 Cardbus Reference Card
8101 1371 001e CWC-854 Wireless-G CardBus Adapter
8102 1371 001f CWM-854 Wireless-G Mini PCI Adapter
8103 1371 0020 CWP-854 Wireless-G PCI Adapter
8104 1458 e381 GN-WMKG 802.11b/g Wireless CardBus Adapter
81051820 InfiniCon Systems Inc.
81061822 Twinhan Technology Co. Ltd
8107182d SiteCom Europe BV
8108# HFC-based ISDN card
8109 3069 ISDN PCI DC-105V2
8110 9790 WL-121 Wireless Network Adapter 100g+ [Ver.3]
81111830 Credence Systems Corporation
8112183b MikroM GmbH
8113 08a7 MVC100 DVI
8114 08a8 MVC101 SDI
8115 08a9 MVC102 DVI+Audio
81161849 ASRock Incorporation
81171851 Microtune, Inc.
81181852 Anritsu Corp.
8119185f Wistron NeWeb Corp.
81201867 Topspin Communications
8121 5a44 MT23108 PCI-X HCA
8122 5a45 MT23108 PCI-X HCA flash recovery
8123 5a46 MT23108 PCI-X HCA bridge
8124 6278 MT25208 InfiniHost III Ex (Tavor compatibility mode)
8125 6282 MT25208 InfiniHost III Ex
8126187e ZyXEL Communication Corporation
81271888 Varisys Ltd
8128 0301 VMFX1 FPGA PMC module
8129 0601 VSM2 dual PMC carrier
8130 0710 VS14x series PowerPC PCI board
8131 0720 VS24x series PowerPC PCI board
8132# found e.g. on KNC DVB-S card
81331894 KNC One
81341896 B&B Electronics Manufacturing Company, Inc.
813518a1 Astute Networks Inc.
813618ac DViCO Corporation
8137 d810 FusionHDTV 3 Gold
813818b8 Ammasso
8139 b001 AMSO 1100 iWARP/RDMA Gigabit Ethernet Coprocessor
814018bc Info-Tek Corp.
8141# assigned to Octigabay System, which has been acquired by Cray
814218c8 Cray Inc
814318c9 ARVOO Engineering BV
814418ca XGI - Xabre Graphics Inc
8145 0040 Volari V8
814618e6 MPL AG
8147 0001 OSCI [Octal Serial Communication Interface]
814818f7 Commtech, Inc.
8149 0001 Fastcom ESCC-PCI-335
8150 0002 Fastcom 422/4-PCI-335
8151 0004 Fastcom 422/2-PCI-335
8152 0005 Fastcom IGESCC-PCI-ISO/1
8153 000a Fastcom 232/4-PCI-335
815418fb Resilience Corporation
81551924 Level 5 Networks Inc.
81561966 Orad Hi-Tec Systems
8157 1975 DVG64 family
81581993 Innominate Security Technologies AG
8159# http://www.progeny.net
816019ae Progeny Systems Corporation
81611a08 Sierra semiconductor
8162 0000 SC15064
81631b13 Jaton Corp
81641c1c Symphony
8165 0001 82C101
81661d44 DPT
8167 a400 PM2x24/PM3224
81681de1 Tekram Technology Co.,Ltd.
8169 0391 TRM-S1040
8170 2020 DC-390
8171 690c 690c
8172 dc29 DC290
81731fc0 Tumsan Oy
8174 0300 E2200 Dual E1/Rawpipe Card
81752000 Smart Link Ltd.
81762001 Temporal Research Ltd
81772003 Smart Link Ltd.
81782004 Smart Link Ltd.
817921c3 21st Century Computer Corp.
81802348 Racore
8181 2010 8142 100VG/AnyLAN
81822646 Kingston Technologies
8183270b Xantel Corporation
8184270f Chaintech Computer Co. Ltd
81852711 AVID Technology Inc.
81862a15 3D Vision(???)
81873000 Hansol Electronics Inc.
81883142 Post Impression Systems.
81893388 Hint Corp
8190 0013 HiNT HC4 PCI to ISDN bridge, Multimedia audio controller
8191 0014 HiNT HC4 PCI to ISDN bridge, Network controller
8192 0020 HB6 Universal PCI-PCI bridge (transparent mode)
8193 0021 HB6 Universal PCI-PCI bridge (non-transparent mode)
8194 4c53 1050 CT7 mainboard
8195 4c53 1080 CT8 mainboard
8196 4c53 10a0 CA3/CR3 mainboard
8197 4c53 3010 PPCI mezzanine (32-bit PMC)
8198 4c53 3011 PPCI mezzanine (64-bit PMC)
8199 0022 HiNT HB4 PCI-PCI Bridge (PCI6150)
8200 0026 HB2 PCI-PCI Bridge
8201 101a E.Band [AudioTrak Inca88]
8202 101b E.Band [AudioTrak Inca88]
8203 8011 VXPro II Chipset
8204 3388 8011 VXPro II Chipset CPU to PCI Bridge
8205 8012 VXPro II Chipset
8206 3388 8012 VXPro II Chipset PCI to ISA Bridge
8207 8013 VXPro II IDE
8208 3388 8013 VXPro II Chipset EIDE Controller
82093411 Quantum Designs (H.K.) Inc
82103513 ARCOM Control Systems Ltd
82113842 eVga.com. Corp.
821238ef 4Links
82133d3d 3DLabs
8214 0001 GLINT 300SX
8215 0002 GLINT 500TX
8216 0003 GLINT Delta
8217 0004 Permedia
8218 0005 Permedia
8219 0006 GLINT MX
8220 0007 3D Extreme
8221 0008 GLINT Gamma G1
8222 0009 Permedia II 2D+3D
8223 1040 0011 AccelStar II
8224 13e9 1000 6221L-4U
8225 3d3d 0100 AccelStar II 3D Accelerator
8226 3d3d 0111 Permedia 3:16
8227 3d3d 0114 Santa Ana
8228 3d3d 0116 Oxygen GVX1
8229 3d3d 0119 Scirocco
8230 3d3d 0120 Santa Ana PCL
8231 3d3d 0125 Oxygen VX1
8232 3d3d 0127 Permedia3 Create!
8233 000a GLINT R3
8234 3d3d 0121 Oxygen VX1
8235 000c GLINT R3 [Oxygen VX1]
8236 3d3d 0144 Oxygen VX1-4X AGP [Permedia 4]
8237 000d GLint R4 rev A
8238 0011 GLint R4 rev B
8239 0012 GLint R5 rev A
8240 0013 GLint R5 rev B
8241 0020 VP10 visual processor
8242# P10 generic II
8243 0022 VP10 visual processor
8244 0024 VP9 visual processor
8245 0100 Permedia II 2D+3D
8246 07a1 Wildcat III 6210
8247 07a2 Sun XVR-500 Graphics Accelerator
8248 07a3 Wildcat IV 7210
8249 1004 Permedia
8250 3d04 Permedia
8251 ffff Glint VGA
82524005 Avance Logic Inc.
8253 0300 ALS300 PCI Audio Device
8254 0308 ALS300+ PCI Audio Device
8255 0309 PCI Input Controller
8256 1064 ALG-2064
8257 2064 ALG-2064i
8258 2128 ALG-2364A GUI Accelerator
8259 2301 ALG-2301
8260 2302 ALG-2302
8261 2303 AVG-2302 GUI Accelerator
8262 2364 ALG-2364A
8263 2464 ALG-2464
8264 2501 ALG-2564A/25128A
8265 4000 ALS4000 Audio Chipset
8266 4005 4000 ALS4000 Audio Chipset
8267 4710 ALC200/200P
82684033 Addtron Technology Co, Inc.
8269 1360 RTL8139 Ethernet
82704143 Digital Equipment Corp
82714144 Alpha Data
8272 0044 ADM-XRCIIPro
8273416c Aladdin Knowledge Systems
8274 0100 AladdinCARD
8275 0200 CPC
82764444 Internext Compression Inc
8277 0016 iTVC16 (CX23416) MPEG-2 Encoder
8278 0070 4009 WinTV PVR 250
8279 0070 8003 WinTV PVR 150
8280 0803 iTVC15 MPEG-2 Encoder
8281 0070 4000 WinTV PVR-350
8282 0070 4001 WinTV PVR-250
8283# video capture card
8284 1461 a3cf M179
82854468 Bridgeport machines
82864594 Cogetec Informatique Inc
828745fb Baldor Electric Company
82884680 Umax Computer Corp
82894843 Hercules Computer Technology Inc
82904916 RedCreek Communications Inc
8291 1960 RedCreek PCI adapter
82924943 Growth Networks
8293494f ACCES I/O Products, Inc.
8294 10e8 LPCI-COM-8SM
82954978 Axil Computer Inc
82964a14 NetVin
8297 5000 NV5000SC
8298 4a14 5000 RT8029-Based Ethernet Adapter
82994b10 Buslogic Inc.
83004c48 LUNG HWA Electronics
83014c53 SBS Technologies
8302 0000 PLUSTEST device
8303 4c53 3000 PLUSTEST card (PC104+)
8304 4c53 3001 PLUSTEST card (PMC)
8305 0001 PLUSTEST-MM device
8306 4c53 3002 PLUSTEST-MM card (PMC)
83074ca1 Seanix Technology Inc
83084d51 MediaQ Inc.
8309 0200 MQ-200
83104d54 Microtechnica Co Ltd
83114ddc ILC Data Device Corp
8312 0100 DD-42924I5-300 (ARINC 429 Data Bus)
8313 0801 BU-65570I1 MIL-STD-1553 Test and Simulation
8314 0802 BU-65570I2 MIL-STD-1553 Test and Simulation
8315 0811 BU-65572I1 MIL-STD-1553 Test and Simulation
8316 0812 BU-65572I2 MIL-STD-1553 Test and Simulation
8317 0881 BU-65570T1 MIL-STD-1553 Test and Simulation
8318 0882 BU-65570T2 MIL-STD-1553 Test and Simulation
8319 0891 BU-65572T1 MIL-STD-1553 Test and Simulation
8320 0892 BU-65572T2 MIL-STD-1553 Test and Simulation
8321 0901 BU-65565C1 MIL-STD-1553 Data Bus
8322 0902 BU-65565C2 MIL-STD-1553 Data Bus
8323 0903 BU-65565C3 MIL-STD-1553 Data Bus
8324 0904 BU-65565C4 MIL-STD-1553 Data Bus
8325 0b01 BU-65569I1 MIL-STD-1553 Data Bus
8326 0b02 BU-65569I2 MIL-STD-1553 Data Bus
8327 0b03 BU-65569I3 MIL-STD-1553 Data Bus
8328 0b04 BU-65569I4 MIL-STD-1553 Data Bus
83295046 GemTek Technology Corporation
8330 1001 PCI Radio
83315053 Voyetra Technologies
8332 2010 Daytona Audio Adapter
83335136 S S Technologies
83345143 Qualcomm Inc
83355145 Ensoniq (Old)
8336 3031 Concert AudioPCI
83375168 Animation Technologies Inc.
83385301 Alliance Semiconductor Corp.
8339 0001 ProMotion aT3D
83405333 S3 Inc.
8341 0551 Plato/PX (system)
8342 5631 86c325 [ViRGE]
8343 8800 86c866 [Vision 866]
8344 8801 86c964 [Vision 964]
8345 8810 86c764_0 [Trio 32 vers 0]
8346 8811 86c764/765 [Trio32/64/64V+]
8347 8812 86cM65 [Aurora64V+]
8348 8813 86c764_3 [Trio 32/64 vers 3]
8349 8814 86c767 [Trio 64UV+]
8350 8815 86cM65 [Aurora 128]
8351 883d 86c988 [ViRGE/VX]
8352 8870 FireGL
8353 8880 86c868 [Vision 868 VRAM] vers 0
8354 8881 86c868 [Vision 868 VRAM] vers 1
8355 8882 86c868 [Vision 868 VRAM] vers 2
8356 8883 86c868 [Vision 868 VRAM] vers 3
8357 88b0 86c928 [Vision 928 VRAM] vers 0
8358 88b1 86c928 [Vision 928 VRAM] vers 1
8359 88b2 86c928 [Vision 928 VRAM] vers 2
8360 88b3 86c928 [Vision 928 VRAM] vers 3
8361 88c0 86c864 [Vision 864 DRAM] vers 0
8362 88c1 86c864 [Vision 864 DRAM] vers 1
8363 88c2 86c864 [Vision 864-P DRAM] vers 2
8364 88c3 86c864 [Vision 864-P DRAM] vers 3
8365 88d0 86c964 [Vision 964 VRAM] vers 0
8366 88d1 86c964 [Vision 964 VRAM] vers 1
8367 88d2 86c964 [Vision 964-P VRAM] vers 2
8368 88d3 86c964 [Vision 964-P VRAM] vers 3
8369 88f0 86c968 [Vision 968 VRAM] rev 0
8370 88f1 86c968 [Vision 968 VRAM] rev 1
8371 88f2 86c968 [Vision 968 VRAM] rev 2
8372 88f3 86c968 [Vision 968 VRAM] rev 3
8373 8900 86c755 [Trio 64V2/DX]
8374 5333 8900 86C775 Trio64V2/DX
8375 8901 86c775/86c785 [Trio 64V2/DX or /GX]
8376 5333 8901 86C775 Trio64V2/DX, 86C785 Trio64V2/GX
8377 8902 Plato/PX
8378 8903 Trio 3D business multimedia
8379 8904 Trio 64 3D
8380 1014 00db Integrated Trio3D
8381 5333 8904 86C365 Trio3D AGP
8382 8905 Trio 64V+ family
8383 8906 Trio 64V+ family
8384 8907 Trio 64V+ family
8385 8908 Trio 64V+ family
8386 8909 Trio 64V+ family
8387 890a Trio 64V+ family
8388 890b Trio 64V+ family
8389 890c Trio 64V+ family
8390 890d Trio 64V+ family
8391 890e Trio 64V+ family
8392 890f Trio 64V+ family
8393 8a01 ViRGE/DX or /GX
8394 0e11 b032 ViRGE/GX
8395 10b4 1617 Nitro 3D
8396 10b4 1717 Nitro 3D
8397 5333 8a01 ViRGE/DX
8398 8a10 ViRGE/GX2
8399 1092 8a10 Stealth 3D 4000
8400 8a13 86c368 [Trio 3D/2X]
8401 5333 8a13 Trio3D/2X
8402 8a20 86c794 [Savage 3D]
8403 5333 8a20 86C391 Savage3D
8404 8a21 86c390 [Savage 3D/MV]
8405 5333 8a21 86C390 Savage3D/MV
8406 8a22 Savage 4
8407 1033 8068 Savage 4
8408 1033 8069 Savage 4
8409 1033 8110 Savage4 LT
8410 105d 0018 SR9 8Mb SDRAM
8411 105d 002a SR9 Pro 16Mb SDRAM
8412 105d 003a SR9 Pro 32Mb SDRAM
8413 105d 092f SR9 Pro+ 16Mb SGRAM
8414 1092 4207 Stealth III S540
8415 1092 4800 Stealth III S540
8416 1092 4807 SpeedStar A90
8417 1092 4808 Stealth III S540
8418 1092 4809 Stealth III S540
8419 1092 480e Stealth III S540
8420 1092 4904 Stealth III S520
8421 1092 4905 SpeedStar A200
8422 1092 4a09 Stealth III S540
8423 1092 4a0b Stealth III S540 Xtreme
8424 1092 4a0f Stealth III S540
8425 1092 4e01 Stealth III S540
8426 1102 101d 3d Blaster Savage 4
8427 1102 101e 3d Blaster Savage 4
8428 5333 8100 86C394-397 Savage4 SDRAM 100
8429 5333 8110 86C394-397 Savage4 SDRAM 110
8430 5333 8125 86C394-397 Savage4 SDRAM 125
8431 5333 8143 86C394-397 Savage4 SDRAM 143
8432 5333 8a22 86C394-397 Savage4
8433 5333 8a2e 86C394-397 Savage4 32bit
8434 5333 9125 86C394-397 Savage4 SGRAM 125
8435 5333 9143 86C394-397 Savage4 SGRAM 143
8436 8a23 Savage 4
8437 8a25 ProSavage PM133
8438 8a26 ProSavage KM133
8439 8c00 ViRGE/M3
8440 8c01 ViRGE/MX
8441 1179 0001 ViRGE/MX
8442 8c02 ViRGE/MX+
8443 8c03 ViRGE/MX+MV
8444 8c10 86C270-294 Savage/MX-MV
8445 8c11 82C270-294 Savage/MX
8446 8c12 86C270-294 Savage/IX-MV
8447 1014 017f ThinkPad T20
8448 1179 0001 86C584 SuperSavage/IXC Toshiba
8449 8c13 86C270-294 Savage/IX
8450 1179 0001 Magnia Z310
8451 8c22 SuperSavage MX/128
8452 8c24 SuperSavage MX/64
8453 8c26 SuperSavage MX/64C
8454 8c2a SuperSavage IX/128 SDR
8455 8c2b SuperSavage IX/128 DDR
8456 8c2c SuperSavage IX/64 SDR
8457 8c2d SuperSavage IX/64 DDR
8458 8c2e SuperSavage IX/C SDR
8459 1014 01fc ThinkPad T23 (2647-4MG)
8460 8c2f SuperSavage IX/C DDR
8461 8d01 86C380 [ProSavageDDR K4M266]
8462 8d02 VT8636A [ProSavage KN133] AGP4X VGA Controller (TwisterK)
8463 8d03 VT8751 [ProSavageDDR P4M266]
8464 8d04 VT8375 [ProSavage8 KM266/KL266]
8465 9102 86C410 Savage 2000
8466 1092 5932 Viper II Z200
8467 1092 5934 Viper II Z200
8468 1092 5952 Viper II Z200
8469 1092 5954 Viper II Z200
8470 1092 5a35 Viper II Z200
8471 1092 5a37 Viper II Z200
8472 1092 5a55 Viper II Z200
8473 1092 5a57 Viper II Z200
8474 ca00 SonicVibes
8475544c Teralogic Inc
8476 0350 TL880-based HDTV/ATSC tuner
84775455 Technische University Berlin
8478 4458 S5933
84795519 Cnet Technologies, Inc.
84805544 Dunord Technologies
8481 0001 I-30xx Scanner Interface
84825555 Genroco, Inc
8483 0003 TURBOstor HFP-832 [HiPPI NIC]
84845654 VoiceTronix Pty Ltd
8485 3132 OpenSwitch12
84865700 Netpower
84875851 Exacq Technologies
84886356 UltraStor
84896374 c't Magazin für Computertechnik
8490 6773 GPPCI
84916409 Logitec Corp.
84926666 Decision Computer International Co.
8493 0001 PCCOM4
8494 0002 PCCOM8
84957604 O.N. Electronic Co Ltd.
84967bde MIDAC Corporation
84977fed PowerTV
84988008 Quancom Electronic GmbH
8499 0010 WDOG1 [PCI-Watchdog 1]
8500 0011 PWDOG2 [PCI-Watchdog 2]
8501# Wrong ID used in subsystem ID of AsusTek PCI-USB2 PCI card.
8502807d Asustek Computer, Inc.
85038086 Intel Corporation
8504 0007 82379AB
8505 0008 Extended Express System Support Controller
8506 0008 1000 WorldMark 4300 INCA ASIC
8507 0039 21145 Fast Ethernet
8508 0122 82437FX
8509 0309 80303 I/O Processor PCI-to-PCI Bridge
8510 030d 80312 I/O Companion Chip PCI-to-PCI Bridge
8511 0326 6700/6702PXH I/OxAPIC Interrupt Controller A
8512 0327 6700PXH I/OxAPIC Interrupt Controller B
8513 0329 6700PXH PCI Express-to-PCI Bridge A
8514 032a 6700PXH PCI Express-to-PCI Bridge B
8515 032c 6702PXH PCI Express-to-PCI Bridge A
8516# A-segment bridge
8517 0330 80332 [Dobson] I/O processor
8518# A-segment IOAPIC
8519 0331 80332 [Dobson] I/O processor
8520# B-segment bridge
8521 0332 80332 [Dobson] I/O processor
8522# B-segment IOAPIC
8523 0333 80332 [Dobson] I/O processor
8524# Address Translation Unit (ATU)
8525 0334 80332 [Dobson] I/O processor
8526# PCI-X bridge
8527 0335 80331 [Lindsay] I/O processor
8528# Address Translation Unit (ATU)
8529 0336 80331 [Lindsay] I/O processor
8530# A-segment bridge
8531 0340 41210 [Lanai] Serial to Parallel PCI Bridge
8532# B-segment bridge
8533 0341 41210 [Lanai] Serial to Parallel PCI Bridge
8534 0482 82375EB/SB PCI to EISA Bridge
8535 0483 82424TX/ZX [Saturn] CPU to PCI bridge
8536 0484 82378ZB/IB, 82379AB (SIO, SIO.A) PCI to ISA Bridge
8537 0486 82425EX/ZX [Aries] PCIset with ISA bridge
8538 04a3 82434LX/NX [Mercury/Neptune] Processor to PCI bridge
8539 04d0 82437FX [Triton FX]
8540 0500 E8870 Processor bus control
8541 0501 E8870 Memory controller
8542# and registers common to both SPs
8543 0502 E8870 Scalability Port 0
8544# and global performance monitoring
8545 0503 E8870 Scalability Port 1
8546 0510 E8870IO Hub Interface Port 0 registers (8-bit compatibility port)
8547 0511 E8870IO Hub Interface Port 1 registers
8548 0512 E8870IO Hub Interface Port 2 registers
8549 0513 E8870IO Hub Interface Port 3 registers
8550 0514 E8870IO Hub Interface Port 4 registers
8551 0515 E8870IO General SIOH registers
8552 0516 E8870IO RAS registers
8553 0530 E8870SP Scalability Port 0 registers
8554 0531 E8870SP Scalability Port 1 registers
8555 0532 E8870SP Scalability Port 2 registers
8556 0533 E8870SP Scalability Port 3 registers
8557 0534 E8870SP Scalability Port 4 registers
8558 0535 E8870SP Scalability Port 5 registers
8559# (bi-interleave 0) and global registers that are neither per-port nor per-interleave
8560 0536 E8870SP Interleave registers 0 and 1
8561# (bi-interleave 1)
8562 0537 E8870SP Interleave registers 2 and 3
8563 0600 RAID Controller
8564 8086 01c1 ICP Vortex GDT8546RZ
8565 8086 01f7 SCRU32
8566# uninitialized SRCU32 RAID Controller
8567 061f 80303 I/O Processor
8568 0960 80960RP [i960 RP Microprocessor/Bridge]
8569 0962 80960RM [i960RM Bridge]
8570 0964 80960RP [i960 RP Microprocessor/Bridge]
8571 1000 82542 Gigabit Ethernet Controller
8572 0e11 b0df NC1632 Gigabit Ethernet Adapter (1000-SX)
8573 0e11 b0e0 NC1633 Gigabit Ethernet Adapter (1000-LX)
8574 0e11 b123 NC1634 Gigabit Ethernet Adapter (1000-SX)
8575 1014 0119 Netfinity Gigabit Ethernet SX Adapter
8576 8086 1000 PRO/1000 Gigabit Server Adapter
8577 1001 82543GC Gigabit Ethernet Controller (Fiber)
8578 0e11 004a NC6136 Gigabit Server Adapter
8579 1014 01ea Netfinity Gigabit Ethernet SX Adapter
8580 8086 1002 PRO/1000 F Server Adapter
8581 8086 1003 PRO/1000 F Server Adapter
8582 1002 Pro 100 LAN+Modem 56 Cardbus II
8583 8086 200e Pro 100 LAN+Modem 56 Cardbus II
8584 8086 2013 Pro 100 SR Mobile Combo Adapter
8585 8086 2017 Pro 100 S Combo Mobile Adapter
8586 1004 82543GC Gigabit Ethernet Controller (Copper)
8587 0e11 0049 NC7132 Gigabit Upgrade Module
8588 0e11 b1a4 NC7131 Gigabit Server Adapter
8589 1014 10f2 Gigabit Ethernet Server Adapter
8590 8086 1004 PRO/1000 T Server Adapter
8591 8086 2004 PRO/1000 T Server Adapter
8592 1008 82544EI Gigabit Ethernet Controller (Copper)
8593 1014 0269 iSeries 1000/100/10 Ethernet Adapter
8594 1028 011c PRO/1000 XT Network Connection
8595 8086 1107 PRO/1000 XT Server Adapter
8596 8086 2107 PRO/1000 XT Server Adapter
8597 8086 2110 PRO/1000 XT Server Adapter
8598 8086 3108 PRO/1000 XT Network Connection
8599 1009 82544EI Gigabit Ethernet Controller (Fiber)
8600 1014 0268 iSeries Gigabit Ethernet Adapter
8601 8086 1109 PRO/1000 XF Server Adapter
8602 8086 2109 PRO/1000 XF Server Adapter
8603 100c 82544GC Gigabit Ethernet Controller (Copper)
8604 8086 1112 PRO/1000 T Desktop Adapter
8605 8086 2112 PRO/1000 T Desktop Adapter
8606 100d 82544GC Gigabit Ethernet Controller (LOM)
8607 1028 0123 PRO/1000 XT Network Connection
8608 1079 891f 82544GC Based Network Connection
8609 4c53 1080 CT8 mainboard
8610 8086 110d 82544GC Based Network Connection
8611 100e 82540EM Gigabit Ethernet Controller
8612 1014 0265 PRO/1000 MT Network Connection
8613 1014 0267 PRO/1000 MT Network Connection
8614 1014 026a PRO/1000 MT Network Connection
8615 1028 002e Optiplex GX260
8616 1028 0151 PRO/1000 MT Network Connection
8617 107b 8920 PRO/1000 MT Desktop Adapter
8618 8086 001e PRO/1000 MT Desktop Adapter
8619 8086 002e PRO/1000 MT Desktop Adapter
8620 100f 82545EM Gigabit Ethernet Controller (Copper)
8621 1014 0269 iSeries 1000/100/10 Ethernet Adapter
8622 1014 028e PRO/1000 MT Network Connection
8623 8086 1000 PRO/1000 MT Network Connection
8624 8086 1001 PRO/1000 MT Server Adapter
8625 1010 82546EB Gigabit Ethernet Controller (Copper)
8626 1014 027c PRO/1000 MT Dual Port Network Adapter
8627 18fb 7872 RESlink-X
8628 4c53 1080 CT8 mainboard
8629 4c53 10a0 CA3/CR3 mainboard
8630 8086 1011 PRO/1000 MT Dual Port Server Adapter
8631 8086 101a PRO/1000 MT Dual Port Network Adapter
8632 8086 3424 SE7501HG2 Mainboard
8633 1011 82545EM Gigabit Ethernet Controller (Fiber)
8634 1014 0268 iSeries Gigabit Ethernet Adapter
8635 8086 1002 PRO/1000 MF Server Adapter
8636 8086 1003 PRO/1000 MF Server Adapter (LX)
8637 1012 82546EB Gigabit Ethernet Controller (Fiber)
8638 8086 1012 PRO/1000 MF Dual Port Server Adapter
8639 1013 82541EI Gigabit Ethernet Controller (Copper)
8640 8086 0013 PRO/1000 MT Network Connection
8641 8086 1013 IBM ThinkCentre Network Card
8642 8086 1113 PRO/1000 MT Desktop Adapter
8643 1014 82541ER Gigabit Ethernet Controller
8644 1015 82540EM Gigabit Ethernet Controller (LOM)
8645 1016 82540EP Gigabit Ethernet Controller (LOM)
8646 1014 052c PRO/1000 MT Mobile Connection
8647 1179 0001 PRO/1000 MT Mobile Connection
8648 8086 1016 PRO/1000 MT Mobile Connection
8649 1017 82540EP Gigabit Ethernet Controller (LOM)
8650 8086 1017 PR0/1000 MT Desktop Connection
8651# Update controller name from 82541EP to 82541EI
8652 1018 82541EI Gigabit Ethernet Controller
8653 8086 1018 PRO/1000 MT Desktop Adapter
8654 1019 82547EI Gigabit Ethernet Controller (LOM)
8655 1458 1019 GA-8IPE1000 Pro2 motherboard (865PE)
8656 1458 e000 Intel Gigabit Ethernet (Kenai II)
8657 8086 1019 PRO/1000 CT Desktop Connection
8658 8086 301f D865PERL mainboard
8659 8086 3427 S875WP1-E mainboard
8660 101d 82546EB Gigabit Ethernet Controller
8661 8086 1000 PRO/1000 MT Quad Port Server Adapter
8662 101e 82540EP Gigabit Ethernet Controller (Mobile)
8663 1014 0549 PRO/1000 MT Mobile Connection
8664 1179 0001 PRO/1000 MT Mobile Connection
8665 8086 101e PRO/1000 MT Mobile Connection
8666 1026 82545GM Gigabit Ethernet Controller
8667 8086 1000 PRO/1000 MT Server Connection
8668 8086 1001 PRO/1000 MT Server Adapter
8669 8086 1002 PRO/1000 MT Server Adapter
8670 8086 1026 PRO/1000 MT Server Connection
8671 1027 82545GM Gigabit Ethernet Controller
8672 8086 1001 PRO/1000 MF Server Adapter(LX)
8673 8086 1002 PRO/1000 MF Server Adapter(LX)
8674 8086 1003 PRO/1000 MF Server Adapter(LX)
8675 8086 1027 PRO/1000 MF Server Adapter
8676 1028 82545GM Gigabit Ethernet Controller
8677 8086 1028 PRO/1000 MB Server Adapter
8678 1029 82559 Ethernet Controller
8679 1030 82559 InBusiness 10/100
8680 1031 82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller
8681 1014 0209 ThinkPad A/T/X Series
8682 104d 80e7 Vaio PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
8683 107b 5350 EtherExpress PRO/100 VE
8684 1179 0001 EtherExpress PRO/100 VE
8685 144d c000 EtherExpress PRO/100 VE
8686 144d c001 EtherExpress PRO/100 VE
8687 144d c003 EtherExpress PRO/100 VE
8688 144d c006 vpr Matrix 170B4
8689 1032 82801CAM (ICH3) PRO/100 VE Ethernet Controller
8690 1033 82801CAM (ICH3) PRO/100 VM (LOM) Ethernet Controller
8691 1034 82801CAM (ICH3) PRO/100 VM Ethernet Controller
8692 1035 82801CAM (ICH3)/82562EH (LOM) Ethernet Controller
8693 1036 82801CAM (ICH3) 82562EH Ethernet Controller
8694 1037 82801CAM (ICH3) Chipset Ethernet Controller
8695 1038 82801CAM (ICH3) PRO/100 VM (KM) Ethernet Controller
8696 1039 82801DB PRO/100 VE (LOM) Ethernet Controller
8697 1014 0267 NetVista A30p
8698 103a 82801DB PRO/100 VE (CNR) Ethernet Controller
8699 103b 82801DB PRO/100 VM (LOM) Ethernet Controller
8700 103c 82801DB PRO/100 VM (CNR) Ethernet Controller
8701 103d 82801DB PRO/100 VE (MOB) Ethernet Controller
8702 103e 82801DB PRO/100 VM (MOB) Ethernet Controller
8703 1040 536EP Data Fax Modem
8704 16be 1040 V.9X DSP Data Fax Modem
8705 1043 PRO/Wireless LAN 2100 3B Mini PCI Adapter
8706 8086 2527 MIM2000/Centrino
8707 1048 PRO/10GbE LR Server Adapter
8708 8086 a01f PRO/10GbE LR Server Adapter
8709 8086 a11f PRO/10GbE LR Server Adapter
8710 1050 82562EZ 10/100 Ethernet Controller
8711 1462 728c 865PE Neo2 (MS-6728)
8712 1462 758c MS-6758 (875P Neo)
8713 8086 3020 D865PERL mainboard
8714 8086 3427 S875WP1-E mainboard
8715 1051 82801EB/ER (ICH5/ICH5R) integrated LAN Controller
8716 1059 82551QM Ethernet Controller
8717# ICH-6 Component
8718 1064 82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller
8719# ICH-6 Component
8720 1065 82562ET/EZ/GT/GZ - PRO/100 VE Ethernet Controller
8721# ICH-6 Component
8722 1066 82562 EM/EX/GX - PRO/100 VM (LOM) Ethernet Controller
8723# ICH-6 Component
8724 1067 82562 EM/EX/GX - PRO/100 VM Ethernet Controller
8725# ICH-6 Component
8726 1068 82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller Mobile
8727# ICH-6 Component
8728 1069 82562 EM/EX/GX - PRO/100 VM (LOM) Ethernet Controller Mobile
8729# ICH-6 Component
8730 106a 82562G \t- PRO/100 VE (LOM) Ethernet Controller
8731# ICH-6 Component
8732 106b 82562G \t- PRO/100 VE Ethernet Controller Mobile
8733 1075 82547GI Gigabit Ethernet Controller
8734 1028 0165 PowerEdge 750
8735 8086 0075 PRO/1000 CT Network Connection
8736 8086 1075 PRO/1000 CT Network Connection
8737 1076 82541GI/PI Gigabit Ethernet Controller
8738 1028 0165 PowerEdge 750
8739 8086 0076 PRO/1000 MT Network Connection
8740 8086 1076 PRO/1000 MT Network Connection
8741 8086 1176 PRO/1000 MT Desktop Adapter
8742 8086 1276 PRO/1000 MT Desktop Adapter
8743 1077 82541GI Gigabit Ethernet Controller
8744 1179 0001 PRO/1000 MT Mobile Connection
8745 8086 0077 PRO/1000 MT Mobile Connection
8746 8086 1077 PRO/1000 MT Mobile Connection
8747 1078 82541EI Gigabit Ethernet Controller
8748 8086 1078 PRO/1000 MT Network Connection
8749 1079 82546GB Gigabit Ethernet Controller
8750 103c 12a6 HP Dual Port 1000Base-T [A9900A]
8751 103c 12cf HP Core Dual Port 1000Base-T [AB352A]
8752 4c53 1090 Cx9 / Vx9 mainboard
8753 4c53 10b0 CL9 mainboard
8754 8086 0079 PRO/1000 MT Dual Port Network Connection
8755 8086 1079 PRO/1000 MT Dual Port Network Connection
8756 8086 1179 PRO/1000 MT Dual Port Network Connection
8757 8086 117a PRO/1000 MT Dual Port Server Adapter
8758 107a 82546GB Gigabit Ethernet Controller
8759 103c 12a8 HP Dual Port 1000base-SX [A9899A]
8760 8086 107a PRO/1000 MF Dual Port Server Adapter
8761 8086 127a PRO/1000 MF Dual Port Server Adapter
8762 107b 82546GB Gigabit Ethernet Controller
8763 8086 007b PRO/1000 MB Dual Port Server Connection
8764 8086 107b PRO/1000 MB Dual Port Server Connection
8765 1107 PRO/1000 MF Server Adapter (LX)
8766 1130 82815 815 Chipset Host Bridge and Memory Controller Hub
8767 1025 1016 Travelmate 612 TX
8768 1043 8027 TUSL2-C Mainboard
8769 104d 80df Vaio PCG-FX403
8770 8086 4532 D815EEA2 mainboard
8771 8086 4557 D815EGEW Mainboard
8772 1131 82815 815 Chipset AGP Bridge
8773 1132 82815 CGC [Chipset Graphics Controller]
8774 1025 1016 Travelmate 612 TX
8775 104d 80df Vaio PCG-FX403
8776 8086 4532 D815EEA2 Mainboard
8777 8086 4557 D815EGEW Mainboard
8778 1161 82806AA PCI64 Hub Advanced Programmable Interrupt Controller
8779 8086 1161 82806AA PCI64 Hub APIC
8780 1162 Xscale 80200 Big Endian Companion Chip
8781 1200 Intel IXP1200 Network Processor
8782 172a 0000 AEP SSL Accelerator
8783 1209 8255xER/82551IT Fast Ethernet Controller
8784 4c53 1050 CT7 mainboard
8785 4c53 1051 CE7 mainboard
8786 4c53 1070 PC6 mainboard
8787 1221 82092AA PCI to PCMCIA Bridge
8788 1222 82092AA IDE Controller
8789 1223 SAA7116
8790 1225 82452KX/GX [Orion]
8791 1226 82596 PRO/10 PCI
8792 1227 82865 EtherExpress PRO/100A
8793 1228 82556 EtherExpress PRO/100 Smart
8794# the revision field differentiates between them (1-3 is 82557, 4-5 is 82558, 6-8 is 82559, 9 is 82559ER)
8795 1229 82557/8/9 [Ethernet Pro 100]
8796 0e11 3001 82559 Fast Ethernet LOM with Alert on LAN*
8797 0e11 3002 82559 Fast Ethernet LOM with Alert on LAN*
8798 0e11 3003 82559 Fast Ethernet LOM with Alert on LAN*
8799 0e11 3004 82559 Fast Ethernet LOM with Alert on LAN*
8800 0e11 3005 82559 Fast Ethernet LOM with Alert on LAN*
8801 0e11 3006 82559 Fast Ethernet LOM with Alert on LAN*
8802 0e11 3007 82559 Fast Ethernet LOM with Alert on LAN*
8803 0e11 b01e NC3120 Fast Ethernet NIC
8804 0e11 b01f NC3122 Fast Ethernet NIC (dual port)
8805 0e11 b02f NC1120 Ethernet NIC
8806 0e11 b04a Netelligent 10/100TX NIC with Wake on LAN
8807 0e11 b0c6 NC3161 Fast Ethernet NIC (embedded, WOL)
8808 0e11 b0c7 NC3160 Fast Ethernet NIC (embedded)
8809 0e11 b0d7 NC3121 Fast Ethernet NIC (WOL)
8810 0e11 b0dd NC3131 Fast Ethernet NIC (dual port)
8811 0e11 b0de NC3132 Fast Ethernet Module (dual port)
8812 0e11 b0e1 NC3133 Fast Ethernet Module (100-FX)
8813 0e11 b134 NC3163 Fast Ethernet NIC (embedded, WOL)
8814 0e11 b13c NC3162 Fast Ethernet NIC (embedded)
8815 0e11 b144 NC3123 Fast Ethernet NIC (WOL)
8816 0e11 b163 NC3134 Fast Ethernet NIC (dual port)
8817 0e11 b164 NC3135 Fast Ethernet Upgrade Module (dual port)
8818 0e11 b1a4 NC7131 Gigabit Server Adapter
8819 1014 005c 82558B Ethernet Pro 10/100
8820 1014 01bc 82559 Fast Ethernet LAN On Motherboard
8821 1014 01f1 10/100 Ethernet Server Adapter
8822 1014 01f2 10/100 Ethernet Server Adapter
8823 1014 0207 Ethernet Pro/100 S
8824 1014 0232 10/100 Dual Port Server Adapter
8825 1014 023a ThinkPad R30
8826 1014 105c Netfinity 10/100
8827 1014 2205 ThinkPad A22p
8828 1014 305c 10/100 EtherJet Management Adapter
8829 1014 405c 10/100 EtherJet Adapter with Alert on LAN
8830 1014 505c 10/100 EtherJet Secure Management Adapter
8831 1014 605c 10/100 EtherJet Secure Management Adapter
8832 1014 705c 10/100 Netfinity 10/100 Ethernet Security Adapter
8833 1014 805c 10/100 Netfinity 10/100 Ethernet Security Adapter
8834 1028 009b PowerEdge 2500/2550
8835 1028 00ce PowerEdge 1400
8836 1033 8000 PC-9821X-B06
8837 1033 8016 PK-UG-X006
8838 1033 801f PK-UG-X006
8839 1033 8026 PK-UG-X006
8840 1033 8063 82559-based Fast Ethernet Adapter
8841 1033 8064 82559-based Fast Ethernet Adapter
8842 103c 10c0 NetServer 10/100TX
8843 103c 10c3 NetServer 10/100TX
8844 103c 10ca NetServer 10/100TX
8845 103c 10cb NetServer 10/100TX
8846 103c 10e3 NetServer 10/100TX
8847 103c 10e4 NetServer 10/100TX
8848 103c 1200 NetServer 10/100TX
8849 10c3 1100 SmartEther100 SC1100
8850 10cf 1115 8255x-based Ethernet Adapter (10/100)
8851 10cf 1143 8255x-based Ethernet Adapter (10/100)
8852 1179 0001 8255x-based Ethernet Adapter (10/100)
8853 1179 0002 PCI FastEther LAN on Docker
8854 1179 0003 8255x-based Fast Ethernet
8855 1259 2560 AT-2560 100
8856 1259 2561 AT-2560 100 FX Ethernet Adapter
8857 1266 0001 NE10/100 Adapter
8858 13e9 1000 6221L-4U
8859 144d 2501 SEM-2000 MiniPCI LAN Adapter
8860 144d 2502 SEM-2100IL MiniPCI LAN Adapter
8861 1668 1100 EtherExpress PRO/100B (TX) (MiniPCI Ethernet+Modem)
8862 4c53 1080 CT8 mainboard
8863 8086 0001 EtherExpress PRO/100B (TX)
8864 8086 0002 EtherExpress PRO/100B (T4)
8865 8086 0003 EtherExpress PRO/10+
8866 8086 0004 EtherExpress PRO/100 WfM
8867 8086 0005 82557 10/100
8868 8086 0006 82557 10/100 with Wake on LAN
8869 8086 0007 82558 10/100 Adapter
8870 8086 0008 82558 10/100 with Wake on LAN
8871 8086 0009 EtherExpress PRO/100+
8872 8086 000a EtherExpress PRO/100+ Management Adapter
8873 8086 000b EtherExpress PRO/100+
8874 8086 000c EtherExpress PRO/100+ Management Adapter
8875 8086 000d EtherExpress PRO/100+ Alert On LAN II* Adapter
8876 8086 000e EtherExpress PRO/100+ Management Adapter with Alert On LAN*
8877 8086 000f EtherExpress PRO/100 Desktop Adapter
8878 8086 0010 EtherExpress PRO/100 S Management Adapter
8879 8086 0011 EtherExpress PRO/100 S Management Adapter
8880 8086 0012 EtherExpress PRO/100 S Advanced Management Adapter (D)
8881 8086 0013 EtherExpress PRO/100 S Advanced Management Adapter (E)
8882 8086 0030 EtherExpress PRO/100 Management Adapter with Alert On LAN* GC
8883 8086 0031 EtherExpress PRO/100 Desktop Adapter
8884 8086 0040 EtherExpress PRO/100 S Desktop Adapter
8885 8086 0041 EtherExpress PRO/100 S Desktop Adapter
8886 8086 0042 EtherExpress PRO/100 Desktop Adapter
8887 8086 0050 EtherExpress PRO/100 S Desktop Adapter
8888 8086 1009 EtherExpress PRO/100+ Server Adapter
8889 8086 100c EtherExpress PRO/100+ Server Adapter (PILA8470B)
8890 8086 1012 EtherExpress PRO/100 S Server Adapter (D)
8891 8086 1013 EtherExpress PRO/100 S Server Adapter (E)
8892 8086 1015 EtherExpress PRO/100 S Dual Port Server Adapter
8893 8086 1017 EtherExpress PRO/100+ Dual Port Server Adapter
8894 8086 1030 EtherExpress PRO/100+ Management Adapter with Alert On LAN* G Server
8895 8086 1040 EtherExpress PRO/100 S Server Adapter
8896 8086 1041 EtherExpress PRO/100 S Server Adapter
8897 8086 1042 EtherExpress PRO/100 Server Adapter
8898 8086 1050 EtherExpress PRO/100 S Server Adapter
8899 8086 1051 EtherExpress PRO/100 Server Adapter
8900 8086 1052 EtherExpress PRO/100 Server Adapter
8901 8086 10f0 EtherExpress PRO/100+ Dual Port Adapter
8902 8086 2009 EtherExpress PRO/100 S Mobile Adapter
8903 8086 200d EtherExpress PRO/100 Cardbus
8904 8086 200e EtherExpress PRO/100 LAN+V90 Cardbus Modem
8905 8086 200f EtherExpress PRO/100 SR Mobile Adapter
8906 8086 2010 EtherExpress PRO/100 S Mobile Combo Adapter
8907 8086 2013 EtherExpress PRO/100 SR Mobile Combo Adapter
8908 8086 2016 EtherExpress PRO/100 S Mobile Adapter
8909 8086 2017 EtherExpress PRO/100 S Combo Mobile Adapter
8910 8086 2018 EtherExpress PRO/100 SR Mobile Adapter
8911 8086 2019 EtherExpress PRO/100 SR Combo Mobile Adapter
8912 8086 2101 EtherExpress PRO/100 P Mobile Adapter
8913 8086 2102 EtherExpress PRO/100 SP Mobile Adapter
8914 8086 2103 EtherExpress PRO/100 SP Mobile Adapter
8915 8086 2104 EtherExpress PRO/100 SP Mobile Adapter
8916 8086 2105 EtherExpress PRO/100 SP Mobile Adapter
8917 8086 2106 EtherExpress PRO/100 P Mobile Adapter
8918 8086 2107 EtherExpress PRO/100 Network Connection
8919 8086 2108 EtherExpress PRO/100 Network Connection
8920 8086 2200 EtherExpress PRO/100 P Mobile Combo Adapter
8921 8086 2201 EtherExpress PRO/100 P Mobile Combo Adapter
8922 8086 2202 EtherExpress PRO/100 SP Mobile Combo Adapter
8923 8086 2203 EtherExpress PRO/100+ MiniPCI
8924 8086 2204 EtherExpress PRO/100+ MiniPCI
8925 8086 2205 EtherExpress PRO/100 SP Mobile Combo Adapter
8926 8086 2206 EtherExpress PRO/100 SP Mobile Combo Adapter
8927 8086 2207 EtherExpress PRO/100 SP Mobile Combo Adapter
8928 8086 2208 EtherExpress PRO/100 P Mobile Combo Adapter
8929 8086 2402 EtherExpress PRO/100+ MiniPCI
8930 8086 2407 EtherExpress PRO/100+ MiniPCI
8931 8086 2408 EtherExpress PRO/100+ MiniPCI
8932 8086 2409 EtherExpress PRO/100+ MiniPCI
8933 8086 240f EtherExpress PRO/100+ MiniPCI
8934 8086 2410 EtherExpress PRO/100+ MiniPCI
8935 8086 2411 EtherExpress PRO/100+ MiniPCI
8936 8086 2412 EtherExpress PRO/100+ MiniPCI
8937 8086 2413 EtherExpress PRO/100+ MiniPCI
8938 8086 3000 82559 Fast Ethernet LAN on Motherboard
8939 8086 3001 82559 Fast Ethernet LOM with Basic Alert on LAN*
8940 8086 3002 82559 Fast Ethernet LOM with Alert on LAN II*
8941 8086 3006 EtherExpress PRO/100 S Network Connection
8942 8086 3007 EtherExpress PRO/100 S Network Connection
8943 8086 3008 EtherExpress PRO/100 Network Connection
8944 8086 3010 EtherExpress PRO/100 S Network Connection
8945 8086 3011 EtherExpress PRO/100 S Network Connection
8946 8086 3012 EtherExpress PRO/100 Network Connection
8947 8086 3411 SDS2 Mainboard
8948 122d 430FX - 82437FX TSC [Triton I]
8949 122e 82371FB PIIX ISA [Triton I]
8950 1230 82371FB PIIX IDE [Triton I]
8951 1231 DSVD Modem
8952 1234 430MX - 82371MX Mobile PCI I/O IDE Xcelerator (MPIIX)
8953 1235 430MX - 82437MX Mob. System Ctrlr (MTSC) & 82438MX Data Path (MTDP)
8954 1237 440FX - 82441FX PMC [Natoma]
8955 1239 82371FB PIIX IDE Interface
8956 123b 82380PB PCI to PCI Docking Bridge
8957 123c 82380AB (MISA) Mobile PCI-to-ISA Bridge
8958 123d 683053 Programmable Interrupt Device
8959# in" hidden" mode
8960 123e 82466GX (IHPC) Integrated Hot-Plug Controller
8961 123f 82466GX Integrated Hot-Plug Controller (IHPC)
8962 1240 82752 (752) AGP Graphics Accelerator
8963 124b 82380FB (MPCI2) Mobile Docking Controller
8964 1250 430HX - 82439HX TXC [Triton II]
8965 1360 82806AA PCI64 Hub PCI Bridge
8966 1361 82806AA PCI64 Hub Controller (HRes)
8967 8086 1361 82806AA PCI64 Hub Controller (HRes)
8968 8086 8000 82806AA PCI64 Hub Controller (HRes)
8969 1460 82870P2 P64H2 Hub PCI Bridge
8970 1461 82870P2 P64H2 I/OxAPIC
8971 15d9 3480 P4DP6
8972 4c53 1090 Cx9 / Vx9 mainboard
8973 1462 82870P2 P64H2 Hot Plug Controller
8974 1960 80960RP [i960RP Microprocessor]
8975 101e 0431 MegaRAID 431 RAID Controller
8976 101e 0438 MegaRAID 438 Ultra2 LVD RAID Controller
8977 101e 0466 MegaRAID 466 Express Plus RAID Controller
8978 101e 0467 MegaRAID 467 Enterprise 1500 RAID Controller
8979 101e 0490 MegaRAID 490 Express 300 RAID Controller
8980 101e 0762 MegaRAID 762 Express RAID Controller
8981 101e 09a0 PowerEdge Expandable RAID Controller 2/SC
8982 1028 0467 PowerEdge Expandable RAID Controller 2/DC
8983 1028 1111 PowerEdge Expandable RAID Controller 2/SC
8984 103c 03a2 MegaRAID
8985 103c 10c6 MegaRAID 438, HP NetRAID-3Si
8986 103c 10c7 MegaRAID T5, Integrated HP NetRAID
8987 103c 10cc MegaRAID, Integrated HP NetRAID
8988 103c 10cd HP NetRAID-1Si
8989 105a 0000 SuperTrak
8990 105a 2168 SuperTrak Pro
8991 105a 5168 SuperTrak66/100
8992 1111 1111 MegaRAID 466, PowerEdge Expandable RAID Controller 2/SC
8993 1111 1112 PowerEdge Expandable RAID Controller 2/SC
8994 113c 03a2 MegaRAID
8995 e4bf 1010 CG1-RADIO
8996 e4bf 1020 CU2-QUARTET
8997 e4bf 1040 CU1-CHORUS
8998 e4bf 3100 CX1-BAND
8999 1962 80960RM [i960RM Microprocessor]
9000 105a 0000 SuperTrak SX6000 I2O CPU
9001 1a21 82840 840 (Carmel) Chipset Host Bridge (Hub A)
9002 1a23 82840 840 (Carmel) Chipset AGP Bridge
9003 1a24 82840 840 (Carmel) Chipset PCI Bridge (Hub B)
9004 1a30 82845 845 (Brookdale) Chipset Host Bridge
9005 1028 010e Optiplex GX240
9006 1a31 82845 845 (Brookdale) Chipset AGP Bridge
9007 2410 82801AA ISA Bridge (LPC)
9008 2411 82801AA IDE
9009 2412 82801AA USB
9010 2413 82801AA SMBus
9011 2415 82801AA AC'97 Audio
9012 1028 0095 Precision Workstation 220 Integrated Digital Audio
9013 11d4 0040 SoundMAX Integrated Digital Audio
9014 11d4 0048 SoundMAX Integrated Digital Audio
9015 11d4 5340 SoundMAX Integrated Digital Audio
9016 2416 82801AA AC'97 Modem
9017 2418 82801AA PCI Bridge
9018 2420 82801AB ISA Bridge (LPC)
9019 2421 82801AB IDE
9020 2422 82801AB USB
9021 2423 82801AB SMBus
9022 2425 82801AB AC'97 Audio
9023 11d4 0040 SoundMAX Integrated Digital Audio
9024 11d4 0048 SoundMAX Integrated Digital Audio
9025 2426 82801AB AC'97 Modem
9026 2428 82801AB PCI Bridge
9027 2440 82801BA ISA Bridge (LPC)
9028 2442 82801BA/BAM USB (Hub #1)
9029 1014 01c6 Netvista A40/A40p
9030 1025 1016 Travelmate 612 TX
9031 1028 010e Optiplex GX240
9032 1043 8027 TUSL2-C Mainboard
9033 104d 80df Vaio PCG-FX403
9034 147b 0507 TH7II-RAID
9035 8086 4532 D815EEA2 mainboard
9036 8086 4557 D815EGEW Mainboard
9037 2443 82801BA/BAM SMBus
9038 1014 01c6 Netvista A40/A40p
9039 1025 1016 Travelmate 612 TX
9040 1028 010e Optiplex GX240
9041 1043 8027 TUSL2-C Mainboard
9042 104d 80df Vaio PCG-FX403
9043 147b 0507 TH7II-RAID
9044 8086 4532 D815EEA2 mainboard
9045 8086 4557 D815EGEW Mainboard
9046 2444 82801BA/BAM USB (Hub #2)
9047 1025 1016 Travelmate 612 TX
9048 1028 010e Optiplex GX240
9049 1043 8027 TUSL2-C Mainboard
9050 104d 80df Vaio PCG-FX403
9051 147b 0507 TH7II-RAID
9052 8086 4532 D815EEA2 mainboard
9053 2445 82801BA/BAM AC'97 Audio
9054 1014 01c6 Netvista A40/A40p
9055 1025 1016 Travelmate 612 TX
9056 104d 80df Vaio PCG-FX403
9057 1462 3370 STAC9721 AC
9058 147b 0507 TH7II-RAID
9059 8086 4557 D815EGEW Mainboard
9060 2446 82801BA/BAM AC'97 Modem
9061 1025 1016 Travelmate 612 TX
9062 104d 80df Vaio PCG-FX403
9063 2448 82801 Mobile PCI Bridge
9064 2449 82801BA/BAM/CA/CAM Ethernet Controller
9065 0e11 0012 EtherExpress PRO/100 VM
9066 0e11 0091 EtherExpress PRO/100 VE
9067 1014 01ce EtherExpress PRO/100 VE
9068 1014 01dc EtherExpress PRO/100 VE
9069 1014 01eb EtherExpress PRO/100 VE
9070 1014 01ec EtherExpress PRO/100 VE
9071 1014 0202 EtherExpress PRO/100 VE
9072 1014 0205 EtherExpress PRO/100 VE
9073 1014 0217 EtherExpress PRO/100 VE
9074 1014 0234 EtherExpress PRO/100 VE
9075 1014 023d EtherExpress PRO/100 VE
9076 1014 0244 EtherExpress PRO/100 VE
9077 1014 0245 EtherExpress PRO/100 VE
9078 1014 0265 PRO/100 VE Desktop Connection
9079 1014 0267 PRO/100 VE Desktop Connection
9080 1014 026a PRO/100 VE Desktop Connection
9081 109f 315d EtherExpress PRO/100 VE
9082 109f 3181 EtherExpress PRO/100 VE
9083 1179 ff01 PRO/100 VE Network Connection
9084 1186 7801 EtherExpress PRO/100 VE
9085 144d 2602 HomePNA 1M CNR
9086 8086 3010 EtherExpress PRO/100 VE
9087 8086 3011 EtherExpress PRO/100 VM
9088 8086 3012 82562EH based Phoneline
9089 8086 3013 EtherExpress PRO/100 VE
9090 8086 3014 EtherExpress PRO/100 VM
9091 8086 3015 82562EH based Phoneline
9092 8086 3016 EtherExpress PRO/100 P Mobile Combo
9093 8086 3017 EtherExpress PRO/100 P Mobile
9094 8086 3018 EtherExpress PRO/100
9095 244a 82801BAM IDE U100
9096 1025 1016 Travelmate 612TX
9097 104d 80df Vaio PCG-FX403
9098 244b 82801BA IDE U100
9099 1014 01c6 Netvista A40/A40p
9100 1028 010e Optiplex GX240
9101 1043 8027 TUSL2-C Mainboard
9102 147b 0507 TH7II-RAID
9103 8086 4532 D815EEA2 mainboard
9104 8086 4557 D815EGEW Mainboard
9105 244c 82801BAM ISA Bridge (LPC)
9106 244e 82801 PCI Bridge
9107 1014 0267 NetVista A30p
9108 2450 82801E ISA Bridge (LPC)
9109 2452 82801E USB
9110 2453 82801E SMBus
9111 2459 82801E Ethernet Controller 0
9112 245b 82801E IDE U100
9113 245d 82801E Ethernet Controller 1
9114 245e 82801E PCI Bridge
9115 2480 82801CA LPC Interface Controller
9116 2482 82801CA/CAM USB (Hub #1)
9117 1014 0220 ThinkPad A/T/X Series
9118 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
9119 15d9 3480 P4DP6
9120 8086 1958 vpr Matrix 170B4
9121 8086 3424 SE7501HG2 Mainboard
9122 8086 4541 Latitude C640
9123 2483 82801CA/CAM SMBus Controller
9124 1014 0220 ThinkPad A/T/X Series
9125 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
9126 15d9 3480 P4DP6
9127 8086 1958 vpr Matrix 170B4
9128 2484 82801CA/CAM USB (Hub #2)
9129 1014 0220 ThinkPad A/T/X Series
9130 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
9131 15d9 3480 P4DP6
9132 8086 1958 vpr Matrix 170B4
9133 2485 82801CA/CAM AC'97 Audio Controller
9134 1013 5959 Crystal WMD Audio Codec
9135 1014 0222 ThinkPad T23 (2647-4MG) or A30/A30p (2652/2653)
9136 1014 0508 ThinkPad T30
9137 1014 051c ThinkPad A/T/X Series
9138 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
9139 144d c006 vpr Matrix 170B4
9140 2486 82801CA/CAM AC'97 Modem Controller
9141 1014 0223 ThinkPad A/T/X Series
9142 1014 0503 ThinkPad R31 2656BBG
9143 1014 051a ThinkPad A/T/X Series
9144 101f 1025 Acer 620 Series
9145 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
9146 1179 0001 Toshiba Satellite 1110 Z15 internal Modem
9147 134d 4c21 Dell Inspiron 2100 internal modem
9148 144d 2115 vpr Matrix 170B4 internal modem
9149 14f1 5421 MD56ORD V.92 MDC Modem
9150 2487 82801CA/CAM USB (Hub #3)
9151 1014 0220 ThinkPad A/T/X Series
9152 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
9153 15d9 3480 P4DP6
9154 8086 1958 vpr Matrix 170B4
9155 248a 82801CAM IDE U100
9156 1014 0220 ThinkPad A/T/X Series
9157 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
9158 8086 1958 vpr Matrix 170B4
9159 8086 4541 Latitude C640
9160 248b 82801CA Ultra ATA Storage Controller
9161 15d9 3480 P4DP6
9162 248c 82801CAM ISA Bridge (LPC)
9163 24c0 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge
9164 1014 0267 NetVista A30p
9165 1462 5800 845PE Max (MS-6580)
9166 24c1 82801DBL (ICH4-L) IDE Controller
9167 24c2 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1
9168 1014 0267 NetVista A30p
9169 1025 005a TravelMate 290
9170 1028 0126 Optiplex GX260
9171 1028 0163 Latitude D505
9172 103c 088c nc8000 laptop
9173 103c 0890 nc6000 laptop
9174 1071 8160 MIM2000
9175 1462 5800 845PE Max (MS-6580)
9176 1509 2990 Averatec 5110H laptop
9177 4c53 1090 Cx9 / Vx9 mainboard
9178 24c3 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller
9179 1014 0267 NetVista A30p
9180 1025 005a TravelMate 290
9181 1028 0126 Optiplex GX260
9182 103c 088c nc8000 laptop
9183 103c 0890 nc6000 laptop
9184 1071 8160 MIM2000
9185 1458 24c2 GA-8PE667 Ultra
9186 1462 5800 845PE Max (MS-6580)
9187 4c53 1090 Cx9 / Vx9 mainboard
9188 24c4 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2
9189 1014 0267 NetVista A30p
9190 1025 005a TravelMate 290
9191 1028 0126 Optiplex GX260
9192 1028 0163 Latitude D505
9193 103c 088c nc8000 laptop
9194 103c 0890 nc6000 laptop
9195 1071 8160 MIM2000
9196 1462 5800 845PE Max (MS-6580)
9197 1509 2990 Averatec 5110H
9198 4c53 1090 Cx9 / Vx9 mainboard
9199 24c5 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller
9200 0e11 00b8 Analog Devices Inc. codec [SoundMAX]
9201 1014 0267 NetVista A30p
9202 1025 005a TravelMate 290
9203 1028 0163 Latitude D505
9204 103c 088c nc8000 laptop
9205 103c 0890 nc6000 laptop
9206 1071 8160 MIM2000
9207 1458 a002 GA-8PE667 Ultra
9208 1462 5800 845PE Max (MS-6580)
9209 24c6 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller
9210 1025 005a TravelMate 290
9211 103c 088c nc8000 laptop
9212 103c 0890 nc6000 laptop
9213 1071 8160 MIM2000
9214 24c7 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3
9215 1014 0267 NetVista A30p
9216 1025 005a TravelMate 290
9217 1028 0126 Optiplex GX260
9218 1028 0163 Latitude D505
9219 103c 088c nc8000 laptop
9220 103c 0890 nc6000 laptop
9221 1071 8160 MIM2000
9222 1462 5800 845PE Max (MS-6580)
9223 1509 2990 Averatec 5110H
9224 4c53 1090 Cx9 / Vx9 mainboard
9225 24ca 82801DBM (ICH4-M) IDE Controller
9226 1025 005a TravelMate 290
9227 1028 0163 Latitude D505
9228 103c 088c nc8000 laptop
9229 103c 0890 nc6000 laptop
9230 1071 8160 MIM2000
9231 24cb 82801DB (ICH4) IDE Controller
9232 1014 0267 NetVista A30p
9233 1028 0126 Optiplex GX260
9234 1458 24c2 GA-8PE667 Ultra
9235 1462 5800 845PE Max (MS-6580)
9236 4c53 1090 Cx9 / Vx9 mainboard
9237 24cc 82801DBM (ICH4-M) LPC Interface Bridge
9238 24cd 82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller
9239 1014 0267 NetVista A30p
9240 1025 005a TravelMate 290
9241 1028 0126 Optiplex GX260
9242 1028 0163 Latitude D505
9243 103c 088c nc8000 laptop
9244 103c 0890 nc6000 laptop
9245 1071 8160 MIM2000
9246 1462 3981 845PE Max (MS-6580)
9247 1509 1968 Averatec 5110H
9248 4c53 1090 Cx9 / Vx9 mainboard
9249 24d0 82801EB/ER (ICH5/ICH5R) LPC Interface Bridge
9250 24d1 82801EB (ICH5) SATA Controller
9251 103c 12bc d530 CMT (DG746A)
9252 1458 24d1 GA-8IPE1000 Pro2 motherboard (865PE)
9253 1462 7280 865PE Neo2 (MS-6728)
9254 8086 3427 S875WP1-E mainboard
9255 8086 524c D865PERL mainboard
9256 24d2 82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1
9257 1028 0183 PowerEdge 1800
9258 103c 12bc d530 CMT (DG746A)
9259 1043 80a6 P4P800 Mainboard
9260 1458 24d2 GA-8IPE1000/8KNXP motherboard
9261 1462 7280 865PE Neo2 (MS-6728)
9262 8086 3427 S875WP1-E mainboard
9263 8086 524c D865PERL mainboard
9264 24d3 82801EB/ER (ICH5/ICH5R) SMBus Controller
9265 1043 80a6 P4P800 Mainboard
9266 1458 24d2 GA-8IPE1000 Pro2 motherboard (865PE)
9267 1462 7280 865PE Neo2 (MS-6728)
9268 8086 3427 S875WP1-E mainboard
9269 8086 524c D865PERL mainboard
9270 24d4 82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2
9271 1028 0183 PowerEdge 1800
9272 103c 12bc d530 CMT (DG746A)
9273 1043 80a6 P4P800 Mainboard
9274 1458 24d2 GA-8IPE1000 Pro2 motherboard (865PE)
9275 1462 7280 865PE Neo2 (MS-6728)
9276 8086 3427 S875WP1-E mainboard
9277 8086 524c D865PERL mainboard
9278 24d5 82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller
9279 103c 12bc Analog Devices codec [SoundMAX Integrated Digital Audio]
9280 1043 80f3 P4P800 Mainboard
9281# Again, I suppose they use the same in different subsystems
9282 1458 a002 GA-8IPE1000/8KNXP motherboard
9283 1462 7280 865PE Neo2 (MS-6728)
9284 8086 a000 D865PERL mainboard
9285 8086 e000 D865PERL mainboard
9286 24d6 82801EB/ER (ICH5/ICH5R) AC'97 Modem Controller
9287 24d7 82801EB/ER (ICH5/ICH5R) USB UHCI #3
9288 1028 0183 PowerEdge 1800
9289 103c 12bc d530 CMT (DG746A)
9290 1043 80a6 P4P800 Mainboard
9291 1458 24d2 GA-8IPE1000 Pro2 motherboard (865PE)
9292 1462 7280 865PE Neo2 (MS-6728)
9293 8086 3427 S875WP1-E mainboard
9294 8086 524c D865PERL mainboard
9295 24db 82801EB/ER (ICH5/ICH5R) IDE Controller
9296 103c 12bc d530 CMT (DG746A)
9297 1043 80a6 P4P800 Mainboard
9298 1458 24d2 GA-8IPE1000 Pro2 motherboard (865PE)
9299 1462 7280 865PE Neo2 (MS-6728)
9300 1462 7580 MSI 875P
9301 8086 24db P4C800 Mainboard
9302 8086 3427 S875WP1-E mainboard
9303 8086 524c D865PERL mainboard
9304 24dc 82801EB (ICH5) LPC Interface Bridge
9305 24dd 82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller
9306 1028 0183 PowerEdge 1800
9307 103c 12bc d530 CMT (DG746A)
9308 1043 80a6 P4P800 Mainboard
9309 1458 5006 GA-8IPE1000 Pro2 motherboard (865PE)
9310 1462 7280 865PE Neo2 (MS-6728)
9311 8086 3427 S875WP1-E mainboard
9312 8086 524c D865PERL mainboard
9313 24de 82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4
9314 1043 80a6 P4P800 Mainboard
9315 1458 24d2 GA-8IPE1000 Pro2 motherboard (865PE)
9316 1462 7280 865PE Neo2 (MS-6728)
9317 8086 3427 S875WP1-E mainboard
9318 8086 524c D865PERL mainboard
9319 24df 82801ER (ICH5R) SATA Controller
9320 2500 82820 820 (Camino) Chipset Host Bridge (MCH)
9321 1028 0095 Precision Workstation 220 Chipset
9322 1043 801c P3C-2000 system chipset
9323 2501 82820 820 (Camino) Chipset Host Bridge (MCH)
9324 1043 801c P3C-2000 system chipset
9325 250b 82820 820 (Camino) Chipset Host Bridge
9326 250f 82820 820 (Camino) Chipset AGP Bridge
9327 2520 82805AA MTH Memory Translator Hub
9328 2521 82804AA MRH-S Memory Repeater Hub for SDRAM
9329 2530 82850 850 (Tehama) Chipset Host Bridge (MCH)
9330 147b 0507 TH7II-RAID
9331 2531 82860 860 (Wombat) Chipset Host Bridge (MCH)
9332 2532 82850 850 (Tehama) Chipset AGP Bridge
9333 2533 82860 860 (Wombat) Chipset AGP Bridge
9334 2534 82860 860 (Wombat) Chipset PCI Bridge
9335 2540 E7500 Memory Controller Hub
9336 15d9 3480 P4DP6
9337 2541 E7500/E7501 Host RASUM Controller
9338 15d9 3480 P4DP6
9339 4c53 1090 Cx9 / Vx9 mainboard
9340 8086 3424 SE7501HG2 Mainboard
9341 2543 E7500/E7501 Hub Interface B PCI-to-PCI Bridge
9342 2544 E7500/E7501 Hub Interface B RASUM Controller
9343 4c53 1090 Cx9 / Vx9 mainboard
9344 2545 E7500/E7501 Hub Interface C PCI-to-PCI Bridge
9345 2546 E7500/E7501 Hub Interface C RASUM Controller
9346 2547 E7500/E7501 Hub Interface D PCI-to-PCI Bridge
9347 2548 E7500/E7501 Hub Interface D RASUM Controller
9348 254c E7501 Memory Controller Hub
9349 4c53 1090 Cx9 / Vx9 mainboard
9350 8086 3424 SE7501HG2 Mainboard
9351 2550 E7505 Memory Controller Hub
9352 2551 E7505/E7205 Series RAS Controller
9353 2552 E7505/E7205 PCI-to-AGP Bridge
9354 2553 E7505 Hub Interface B PCI-to-PCI Bridge
9355 2554 E7505 Hub Interface B PCI-to-PCI Bridge RAS Controller
9356 255d E7205 Memory Controller Hub
9357 2560 82845G/GL[Brookdale-G]/GE/PE DRAM Controller/Host-Hub Interface
9358 1028 0126 Optiplex GX260
9359 1458 2560 GA-8PE667 Ultra
9360 1462 5800 845PE Max (MS-6580)
9361 2561 82845G/GL[Brookdale-G]/GE/PE Host-to-AGP Bridge
9362 2562 82845G/GL[Brookdale-G]/GE Chipset Integrated Graphics Device
9363 1014 0267 NetVista A30p
9364 2570 82865G/PE/P DRAM Controller/Host-Hub Interface
9365 1043 80f2 P4P800 Mainboard
9366 1458 2570 GA-8IPE1000 Pro2 motherboard (865PE)
9367 2571 82865G/PE/P PCI to AGP Controller
9368 2572 82865G Integrated Graphics Controller
9369 2573 82865G/PE/P PCI to CSA Bridge
9370 2576 82865G/PE/P Processor to I/O Memory Interface
9371 2578 82875P/E7210 Memory Controller Hub
9372 1458 2578 GA-8KNXP motherboard (875P)
9373 1462 7580 MS-6758 (875P Neo)
9374# Motherboard P4SCE
9375 15d9 4580 Super Micro Computer Inc. P4SCE
9376 2579 82875P Processor to AGP Controller
9377 257b 82875P/E7210 Processor to PCI to CSA Bridge
9378 257e 82875P/E7210 Processor to I/O Memory Interface
9379 2580 915G/P/GV/GL/PL/910GL Processor to I/O Controller
9380 2581 915G/P/GV/GL/PL/910GL PCI Express Root Port
9381 2582 82915G/GV/910GL Express Chipset Family Graphics Controller
9382 1028 1079 Optiplex GX280
9383 2584 925X/XE Memory Controller Hub
9384 2585 925X/XE PCI Express Root Port
9385 2588 E7220/E7221 Memory Controller Hub
9386 2589 E7220/E7221 PCI Express Root Port
9387 258a E7221 Integrated Graphics Controller
9388 2590 Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller
9389 2591 Mobile 915GM/PM Express PCI Express Root Port
9390 2592 Mobile 915GM/GMS/910GML Express Graphics Controller
9391 25a1 6300ESB LPC Interface Controller
9392 25a2 6300ESB PATA Storage Controller
9393 4c53 10b0 CL9 mainboard
9394 25a3 6300ESB SATA Storage Controller
9395 4c53 10b0 CL9 mainboard
9396 25a4 6300ESB SMBus Controller
9397 4c53 10b0 CL9 mainboard
9398 25a6 6300ESB AC'97 Audio Controller
9399 4c53 10b0 CL9 mainboard
9400 25a7 6300ESB AC'97 Modem Controller
9401 25a9 6300ESB USB Universal Host Controller
9402 4c53 10b0 CL9 mainboard
9403 25aa 6300ESB USB Universal Host Controller
9404 4c53 10b0 CL9 mainboard
9405 25ab 6300ESB Watchdog Timer
9406 4c53 10b0 CL9 mainboard
9407 25ac 6300ESB I/O Advanced Programmable Interrupt Controller
9408 4c53 10b0 CL9 mainboard
9409 25ad 6300ESB USB2 Enhanced Host Controller
9410 25ae 6300ESB 64-bit PCI-X Bridge
9411 25b0 6300ESB SATA RAID Controller
9412 2600 E8500 Hub Interface
9413 2601 E8500 PCI Express x4 Port D
9414 2602 E8500 PCI Express x4 Port C0
9415 2603 E8500 PCI Express x4 Port C1
9416 2604 E8500 PCI Express x4 Port B0
9417 2605 E8500 PCI Express x4 Port B1
9418 2606 E8500 PCI Express x4 Port A0
9419 2607 E8500 PCI Express x4 Port A1
9420 2608 E8500 PCI Express x8 Port C
9421 2609 E8500 PCI Express x8 Port B
9422 260a E8500 PCI Express x8 Port A
9423 260c E8500 IMI Registers
9424 2610 E8500 System Bus, Boot, and Interrupt Registers
9425 2611 E8500 Address Mapping Registers
9426 2612 E8500 RAS Registers
9427 2613 E8500 Reserved Registers
9428 2614 E8500 Reserved Registers
9429 2615 E8500 Miscellaneous Registers
9430 2617 E8500 Reserved Registers
9431 2618 E8500 Reserved Registers
9432 2619 E8500 Reserved Registers
9433 261a E8500 Reserved Registers
9434 261b E8500 Reserved Registers
9435 261c E8500 Reserved Registers
9436 261d E8500 Reserved Registers
9437 261e E8500 Reserved Registers
9438 2620 E8500 eXternal Memory Bridge
9439 2621 E8500 XMB Miscellaneous Registers
9440 2622 E8500 XMB Memory Interleaving Registers
9441 2623 E8500 XMB DDR Initialization and Calibration
9442 2624 E8500 XMB Reserved Registers
9443 2625 E8500 XMB Reserved Registers
9444 2626 E8500 XMB Reserved Registers
9445 2627 E8500 XMB Reserved Registers
9446 2640 82801FB/FR (ICH6/ICH6R) LPC Interface Bridge
9447 2641 82801FBM (ICH6M) LPC Interface Bridge
9448 2642 82801FW/FRW (ICH6W/ICH6RW) LPC Interface Bridge
9449 2651 82801FB/FW (ICH6/ICH6W) SATA Controller
9450 1028 0179 Optiplex GX280
9451 2652 82801FR/FRW (ICH6R/ICH6RW) SATA Controller
9452 2653 82801FBM (ICH6M) SATA Controller
9453 2658 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1
9454 1028 0179 Optiplex GX280
9455 2659 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2
9456 1028 0179 Optiplex GX280
9457 265a 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3
9458 1028 0179 Optiplex GX280
9459 265b 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4
9460 1028 0179 Optiplex GX280
9461 265c 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller
9462 1028 0179 Optiplex GX280
9463 2660 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 1
9464 2662 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 2
9465 2664 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 3
9466 2666 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 4
9467 2668 82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller
9468 266a 82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller
9469 1028 0179 Optiplex GX280
9470 266c 82801FB/FBM/FR/FW/FRW (ICH6 Family) LAN Controller
9471 266d 82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Modem Controller
9472 266e 82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller
9473 1028 0179 Optiplex GX280
9474 266f 82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller
9475 2770 Memory Controller Hub
9476 2771 PCI Express Graphics Port
9477 2772 Integrated Graphics Controller
9478 2774 Workstation Memory Controller Hub
9479 2775 PCI Express Graphics Port
9480 2776 Integrated Graphics Controller
9481 2778 Server Memory Controller Hub
9482 2779 PCI Express Root Port
9483 2782 82915G Express Chipset Family Graphics Controller
9484 2792 Mobile 915GM/GMS/910GML Express Graphics Controller
9485 27b8 I/O Controller Hub LPC
9486 27b9 Mobile I/O Controller Hub LPC
9487 27c0 I/O Controller Hub SATA cc=IDE
9488 27c1 I/O Controller Hub SATA cc=AHCI
9489 27c3 I/O Controller Hub SATA cc=RAID
9490 27c4 Mobile I/O Controller Hub SATA cc=IDE
9491 27c5 Mobile I/O Controller Hub SATA cc=AHCI
9492 27c8 I/O Controller Hub UHCI USB #1
9493 27c9 I/O Controller Hub UHCI USB #2
9494 27ca I/O Controller Hub UHCI USB #3
9495 27cb I/O Controller Hub UHCI USB #4
9496 27cc I/O Controller Hub EHCI USB
9497 27d0 I/O Controller Hub PCI Express Port 1
9498 27d2 I/O Controller Hub PCI Express Port 2
9499 27d4 I/O Controller Hub PCI Express Port 3
9500 27d6 I/O Controller Hub PCI Express Port 4
9501 27d8 I/O Controller Hub High Definition Audio
9502 27da I/O Controller Hub SMBus
9503 27dc I/O Controller Hub LAN
9504 27dd I/O Controller Hub AC'97 Modem
9505 27de I/O Controller Hub AC'97 Audio
9506 27df I/O Controller Hub PATA
9507 27e0 I/O Controller Hub PCI Express Port 5
9508 27e2 I/O Controller Hub PCI Express Port 6
9509 3092 Integrated RAID
9510 3200 GD31244 PCI-X SATA HBA
9511 3340 82855PM Processor to I/O Controller
9512 1025 005a TravelMate 290
9513 103c 088c nc8000 laptop
9514 103c 0890 nc6000 laptop
9515 3341 82855PM Processor to AGP Controller
9516 3575 82830 830 Chipset Host Bridge
9517 1014 021d ThinkPad A/T/X Series
9518 104d 80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
9519 3576 82830 830 Chipset AGP Bridge
9520 3577 82830 CGC [Chipset Graphics Controller]
9521 1014 0513 ThinkPad A/T/X Series
9522 3578 82830 830 Chipset Host Bridge
9523 3580 82852/82855 GM/GME/PM/GMV Processor to I/O Controller
9524 1028 0163 Latitude D505
9525 4c53 10b0 CL9 mainboard
9526 3581 82852/82855 GM/GME/PM/GMV Processor to AGP Controller
9527 3582 82852/855GM Integrated Graphics Device
9528 1028 0163 Latitude D505
9529 4c53 10b0 CL9 mainboard
9530 3584 82852/82855 GM/GME/PM/GMV Processor to I/O Controller
9531 1028 0163 Latitude D505
9532 4c53 10b0 CL9 mainboard
9533 3585 82852/82855 GM/GME/PM/GMV Processor to I/O Controller
9534 1028 0163 Latitude D505
9535 4c53 10b0 CL9 mainboard
9536 3590 E7520 Memory Controller Hub
9537 3591 E7525/E7520 Error Reporting Registers
9538 3592 E7320 Memory Controller Hub
9539 3593 E7320 Error Reporting Registers
9540 3594 E7520 DMA Controller
9541 3595 E7525/E7520/E7320 PCI Express Port A
9542 3596 E7525/E7520/E7320 PCI Express Port A1
9543 3597 E7525/E7520 PCI Express Port B
9544 3598 E7520 PCI Express Port B1
9545 3599 E7520 PCI Express Port C
9546 359a E7520 PCI Express Port C1
9547 359b E7525/E7520/E7320 Extended Configuration Registers
9548 359e E7525 Memory Controller Hub
9549 4220 PRO/Wireless 2200BG
9550 4223 PRO/Wireless 2915ABG MiniPCI Adapter
9551 5200 EtherExpress PRO/100 Intelligent Server
9552 5201 EtherExpress PRO/100 Intelligent Server
9553 8086 0001 EtherExpress PRO/100 Server Ethernet Adapter
9554 530d 80310 IOP [IO Processor]
9555 7000 82371SB PIIX3 ISA [Natoma/Triton II]
9556 7010 82371SB PIIX3 IDE [Natoma/Triton II]
9557 7020 82371SB PIIX3 USB [Natoma/Triton II]
9558 7030 430VX - 82437VX TVX [Triton VX]
9559 7050 Intel Intercast Video Capture Card
9560 7100 430TX - 82439TX MTXC
9561 7110 82371AB/EB/MB PIIX4 ISA
9562 15ad 1976 virtualHW v3
9563 7111 82371AB/EB/MB PIIX4 IDE
9564 15ad 1976 virtualHW v3
9565 7112 82371AB/EB/MB PIIX4 USB
9566 15ad 1976 virtualHW v3
9567 7113 82371AB/EB/MB PIIX4 ACPI
9568 15ad 1976 virtualHW v3
9569 7120 82810 GMCH [Graphics Memory Controller Hub]
9570 4c53 1040 CL7 mainboard
9571 4c53 1060 PC7 mainboard
9572 7121 82810 CGC [Chipset Graphics Controller]
9573 4c53 1040 CL7 mainboard
9574 4c53 1060 PC7 mainboard
9575 8086 4341 Cayman (CA810) Mainboard
9576 7122 82810 DC-100 GMCH [Graphics Memory Controller Hub]
9577 7123 82810 DC-100 CGC [Chipset Graphics Controller]
9578 7124 82810E DC-133 GMCH [Graphics Memory Controller Hub]
9579 7125 82810E DC-133 CGC [Chipset Graphics Controller]
9580 7126 82810 DC-133 System and Graphics Controller
9581 7128 82810-M DC-100 System and Graphics Controller
9582 712a 82810-M DC-133 System and Graphics Controller
9583 7180 440LX/EX - 82443LX/EX Host bridge
9584 7181 440LX/EX - 82443LX/EX AGP bridge
9585 7190 440BX/ZX/DX - 82443BX/ZX/DX Host bridge
9586 0e11 0500 Armada 1750 Laptop System Chipset
9587 0e11 b110 Armada M700/E500
9588 1179 0001 Toshiba Tecra 8100 Laptop System Chipset
9589 15ad 1976 virtualHW v3
9590 4c53 1050 CT7 mainboard
9591 4c53 1051 CE7 mainboard
9592 7191 440BX/ZX/DX - 82443BX/ZX/DX AGP bridge
9593 7192 440BX/ZX/DX - 82443BX/ZX/DX Host bridge (AGP disabled)
9594 0e11 0460 Armada 1700 Laptop System Chipset
9595 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
9596 7194 82440MX Host Bridge
9597 1033 0000 Versa Note Vxi
9598 4c53 10a0 CA3/CR3 mainboard
9599 7195 82440MX AC'97 Audio Controller
9600 1033 80cc Versa Note VXi
9601 10cf 1099 QSound_SigmaTel Stac97 PCI Audio
9602 11d4 0040 SoundMAX Integrated Digital Audio
9603 11d4 0048 SoundMAX Integrated Digital Audio
9604 7196 82440MX AC'97 Modem Controller
9605 7198 82440MX ISA Bridge
9606 7199 82440MX EIDE Controller
9607 719a 82440MX USB Universal Host Controller
9608 719b 82440MX Power Management Controller
9609 71a0 440GX - 82443GX Host bridge
9610 4c53 1050 CT7 mainboard
9611 4c53 1051 CE7 mainboard
9612 71a1 440GX - 82443GX AGP bridge
9613 71a2 440GX - 82443GX Host bridge (AGP disabled)
9614 4c53 1000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard
9615 7600 82372FB PIIX5 ISA
9616 7601 82372FB PIIX5 IDE
9617 7602 82372FB PIIX5 USB
9618 7603 82372FB PIIX5 SMBus
9619 7800 82740 (i740) AGP Graphics Accelerator
9620 003d 0008 Starfighter AGP
9621 003d 000b Starfighter AGP
9622 1092 0100 Stealth II G460
9623 10b4 201a Lightspeed 740
9624 10b4 202f Lightspeed 740
9625 8086 0000 Terminator 2x/i
9626 8086 0100 Intel740 Graphics Accelerator
9627 84c4 450KX/GX [Orion] - 82454KX/GX PCI bridge
9628 84c5 450KX/GX [Orion] - 82453KX/GX Memory controller
9629 84ca 450NX - 82451NX Memory & I/O Controller
9630 84cb 450NX - 82454NX/84460GX PCI Expander Bridge
9631 84e0 460GX - 84460GX System Address Controller (SAC)
9632 84e1 460GX - 84460GX System Data Controller (SDC)
9633 84e2 460GX - 84460GX AGP Bridge (GXB function 2)
9634 84e3 460GX - 84460GX Memory Address Controller (MAC)
9635 84e4 460GX - 84460GX Memory Data Controller (MDC)
9636 84e6 460GX - 82466GX Wide and fast PCI eXpander Bridge (WXB)
9637 84ea 460GX - 84460GX AGP Bridge (GXB function 1)
9638 8500 IXP4XX - Intel Network Processor family. IXP420, IXP421, IXP422, IXP425 and IXC1100
9639 1993 0dee mGuard-PCI AV#1
9640 1993 0def mGuard-PCI AV#0
9641 9000 IXP2000 Family Network Processor
9642 9001 IXP2400 Network Processor
9643 9004 IXP2800 Network Processor
9644 9621 Integrated RAID
9645 9622 Integrated RAID
9646 9641 Integrated RAID
9647 96a1 Integrated RAID
9648# retail verson
9649 a01f PRO/10GbE LR Server Adapter
9650# OEM version
9651 a11f PRO/10GbE LR Server Adapter
9652 b152 21152 PCI-to-PCI Bridge
9653# observed, and documented in Intel revision note; new mask of 1011:0026
9654 b154 21154 PCI-to-PCI Bridge
9655 b555 21555 Non transparent PCI-to-PCI Bridge
9656 12d9 000a PCI VoIP Gateway
9657 4c53 1050 CT7 mainboard
9658 4c53 1051 CE7 mainboard
9659 e4bf 1000 CC8-1-BLUES
9660 ffff 450NX/GX [Orion] - 82453KX/GX Memory controller [BUG]
96618401 TRENDware International Inc.
96628800 Trigem Computer Inc.
9663 2008 Video assistent component
96648866 T-Square Design Inc.
96658888 Silicon Magic
9666# 8c4a is not Winbond but there is a board misprogrammed
96678c4a Winbond
9668 1980 W89C940 misprogrammed [ne2k]
96698e0e Computone Corporation
96708e2e KTI
9671 3000 ET32P2
96729004 Adaptec
9673 0078 AHA-2940U_CN
9674 1078 AIC-7810
9675 1160 AIC-1160 [Family Fibre Channel Adapter]
9676 2178 AIC-7821
9677 3860 AHA-2930CU
9678 3b78 AHA-4844W/4844UW
9679 5075 AIC-755x
9680 5078 AHA-7850
9681 9004 7850 AHA-2904/Integrated AIC-7850
9682 5175 AIC-755x
9683 5178 AIC-7851
9684 5275 AIC-755x
9685 5278 AIC-7852
9686 5375 AIC-755x
9687 5378 AIC-7850
9688 5475 AIC-755x
9689 5478 AIC-7850
9690 5575 AVA-2930
9691 5578 AIC-7855
9692 5647 ANA-7711 TCP Offload Engine
9693 9004 7710 ANA-7711F TCP Offload Engine - Optical
9694 9004 7711 ANA-7711LP TCP Offload Engine - Copper
9695 5675 AIC-755x
9696 5678 AIC-7856
9697 5775 AIC-755x
9698 5778 AIC-7850
9699 5800 AIC-5800
9700 5900 ANA-5910/5930/5940 ATM155 & 25 LAN Adapter
9701 5905 ANA-5910A/5930A/5940A ATM Adapter
9702 6038 AIC-3860
9703 6075 AIC-1480 / APA-1480
9704 9004 7560 AIC-1480 / APA-1480 Cardbus
9705 6078 AIC-7860
9706 6178 AIC-7861
9707 9004 7861 AHA-2940AU Single
9708 6278 AIC-7860
9709 6378 AIC-7860
9710 6478 AIC-786x
9711 6578 AIC-786x
9712 6678 AIC-786x
9713 6778 AIC-786x
9714 6915 ANA620xx/ANA69011A
9715 9004 0008 ANA69011A/TX 10/100
9716 9004 0009 ANA69011A/TX 10/100
9717 9004 0010 ANA62022 2-port 10/100
9718 9004 0018 ANA62044 4-port 10/100
9719 9004 0019 ANA62044 4-port 10/100
9720 9004 0020 ANA62022 2-port 10/100
9721 9004 0028 ANA69011A/TX 10/100
9722 9004 8008 ANA69011A/TX 64 bit 10/100
9723 9004 8009 ANA69011A/TX 64 bit 10/100
9724 9004 8010 ANA62022 2-port 64 bit 10/100
9725 9004 8018 ANA62044 4-port 64 bit 10/100
9726 9004 8019 ANA62044 4-port 64 bit 10/100
9727 9004 8020 ANA62022 2-port 64 bit 10/100
9728 9004 8028 ANA69011A/TX 64 bit 10/100
9729 7078 AHA-294x / AIC-7870
9730 7178 AHA-2940/2940W / AIC-7871
9731 7278 AHA-3940/3940W / AIC-7872
9732 7378 AHA-3985 / AIC-7873
9733 7478 AHA-2944/2944W / AIC-7874
9734 7578 AHA-3944/3944W / AIC-7875
9735 7678 AHA-4944W/UW / AIC-7876
9736 7710 ANA-7711F Network Accelerator Card (NAC) - Optical
9737 7711 ANA-7711C Network Accelerator Card (NAC) - Copper
9738 7778 AIC-787x
9739 7810 AIC-7810
9740 7815 AIC-7815 RAID+Memory Controller IC
9741 9004 7815 ARO-1130U2 RAID Controller
9742 9004 7840 AIC-7815 RAID+Memory Controller IC
9743 7850 AIC-7850
9744 7855 AHA-2930
9745 7860 AIC-7860
9746 7870 AIC-7870
9747 7871 AHA-2940
9748 7872 AHA-3940
9749 7873 AHA-3980
9750 7874 AHA-2944
9751 7880 AIC-7880P
9752 7890 AIC-7890
9753 7891 AIC-789x
9754 7892 AIC-789x
9755 7893 AIC-789x
9756 7894 AIC-789x
9757 7895 AHA-2940U/UW / AHA-39xx / AIC-7895
9758 9004 7890 AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
9759 9004 7891 AHA-2940U/2940UW Dual
9760 9004 7892 AHA-3940AU/AUW/AUWD/UWD
9761 9004 7894 AHA-3944AUWD
9762 9004 7895 AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
9763 9004 7896 AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
9764 9004 7897 AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
9765 7896 AIC-789x
9766 7897 AIC-789x
9767 8078 AIC-7880U
9768 9004 7880 AIC-7880P Ultra/Ultra Wide SCSI Chipset
9769 8178 AHA-2940U/UW/D / AIC-7881U
9770 9004 7881 AHA-2940UW SCSI Host Adapter
9771 8278 AHA-3940U/UW/UWD / AIC-7882U
9772 8378 AHA-3940U/UW / AIC-7883U
9773 8478 AHA-2944UW / AIC-7884U
9774 8578 AHA-3944U/UWD / AIC-7885
9775 8678 AHA-4944UW / AIC-7886
9776 8778 AHA-2940UW Pro / AIC-788x
9777 9004 7887 2940UW Pro Ultra-Wide SCSI Controller
9778 8878 AHA-2930UW / AIC-7888
9779 9004 7888 AHA-2930UW SCSI Controller
9780 8b78 ABA-1030
9781 ec78 AHA-4944W/UW
97829005 Adaptec
9783 0010 AHA-2940U2/U2W
9784 9005 2180 AHA-2940U2 SCSI Controller
9785 9005 8100 AHA-2940U2B SCSI Controller
9786 9005 a100 AHA-2940U2B SCSI Controller
9787 9005 a180 AHA-2940U2W SCSI Controller
9788 9005 e100 AHA-2950U2B SCSI Controller
9789 0011 AHA-2930U2
9790 0013 78902
9791 9005 0003 AAA-131U2 Array1000 1 Channel RAID Controller
9792 9005 000f AIC7890_ARO
9793 001f AHA-2940U2/U2W / 7890/7891
9794 9005 000f 2940U2W SCSI Controller
9795 9005 a180 2940U2W SCSI Controller
9796 0020 AIC-7890
9797 002f AIC-7890
9798 0030 AIC-7890
9799 003f AIC-7890
9800 0050 AHA-3940U2x/395U2x
9801 9005 f500 AHA-3950U2B
9802 9005 ffff AHA-3950U2B
9803 0051 AHA-3950U2D
9804 9005 b500 AHA-3950U2D
9805 0053 AIC-7896 SCSI Controller
9806 9005 ffff AIC-7896 SCSI Controller mainboard implementation
9807 005f AIC-7896U2/7897U2
9808 0080 AIC-7892A U160/m
9809 0e11 e2a0 Compaq 64-Bit/66MHz Wide Ultra3 SCSI Adapter
9810 9005 6220 AHA-29160C
9811 9005 62a0 29160N Ultra160 SCSI Controller
9812 9005 e220 29160LP Low Profile Ultra160 SCSI Controller
9813 9005 e2a0 29160 Ultra160 SCSI Controller
9814 0081 AIC-7892B U160/m
9815 9005 62a1 19160 Ultra160 SCSI Controller
9816 0083 AIC-7892D U160/m
9817 008f AIC-7892P U160/m
9818 1179 0001 Magnia Z310
9819 15d9 9005 Onboard SCSI Host Adapter
9820 00c0 AHA-3960D / AIC-7899A U160/m
9821 0e11 f620 Compaq 64-Bit/66MHz Dual Channel Wide Ultra3 SCSI Adapter
9822 9005 f620 AHA-3960D U160/m
9823 00c1 AIC-7899B U160/m
9824 00c3 AIC-7899D U160/m
9825 00c5 RAID subsystem HBA
9826 1028 00c5 PowerEdge 2400,2500,2550,4400
9827 00cf AIC-7899P U160/m
9828 1028 00ce PowerEdge 1400
9829 1028 00d1 PowerEdge 2550
9830 1028 00d9 PowerEdge 2500
9831 10f1 2462 Thunder K7 S2462
9832 15d9 9005 Onboard SCSI Host Adapter
9833 8086 3411 SDS2 Mainboard
9834 0250 ServeRAID Controller
9835 1014 0279 ServeRAID-xx
9836 1014 028c ServeRAID-xx
9837# from kernel sources
9838 0279 ServeRAID 6M
9839 0283 AAC-RAID
9840 9005 0283 Catapult
9841 0284 AAC-RAID
9842 9005 0284 Tomcat
9843 0285 AAC-RAID
9844 0e11 0295 SATA 6Ch (Bearcat)
9845 1014 02f2 ServeRAID 8i
9846 1028 0287 PowerEdge Expandable RAID Controller 320/DC
9847 1028 0291 CERC SATA RAID 2 PCI SATA 6ch (DellCorsair)
9848 103c 3227 AAR-2610SA
9849 17aa 0286 Legend S220 (Legend Crusader)
9850 17aa 0287 Legend S230 (Legend Vulcan)
9851 9005 0285 2200S (Vulcan)
9852 9005 0286 2120S (Crusader)
9853 9005 0287 2200S (Vulcan-2m)
9854 9005 0288 3230S (Harrier)
9855 9005 0289 3240S (Tornado)
9856 9005 028a ASR-2020S PCI-X ZCR (Skyhawk)
9857 9005 028b ASR-2020S SO-DIMM PCI-X ZCR (Terminator)
9858 9005 0290 AAR-2410SA PCI SATA 4ch (Jaguar II)
9859 9005 0292 AAR-2810SA PCI SATA 8ch (Corsair-8)
9860 9005 0293 AAR-21610SA PCI SATA 16ch (Corsair-16)
9861 9005 0294 ESD SO-DIMM PCI-X SATA ZCR (Prowler)
9862 0286 AAC-RAID (Rocket)
9863 9005 028c ASR-2230S + ASR-2230SLP PCI-X (Lancer)
9864 0503 Scamp chipset SCSI controller
9865 1014 02BF Quad Channel PCI-X DDR U320 SCSI RAID Adapter (571E)
9866 8000 ASC-29320A U320
9867 800f AIC-7901 U320
9868 8010 ASC-39320 U320
9869 8011 ASC-32320D U320
9870 0e11 00ac ASC-39320D U320
9871 9005 0041 ASC-39320D U320
9872 8012 ASC-29320 U320
9873 8013 ASC-29320B U320
9874 8014 ASC-29320LP U320
9875 8015 ASC-39320B U320
9876 8016 ASC-39320A U320
9877 8017 ASC-29320ALP U320
9878 801c ASC-39320D U320
9879 801d AIC-7902B U320
9880 801e AIC-7901A U320
9881 801f AIC-7902 U320
9882 8080 ASC-29320A U320 w/HostRAID
9883 808f AIC-7901 U320 w/HostRAID
9884 8090 ASC-39320 U320 w/HostRAID
9885 8091 ASC-39320D U320 w/HostRAID
9886 8092 ASC-29320 U320 w/HostRAID
9887 8093 ASC-29320B U320 w/HostRAID
9888 8094 ASC-29320LP U320 w/HostRAID
9889 8095 ASC-39320(B) U320 w/HostRAID
9890 8096 ASC-39320A U320 w/HostRAID
9891 8097 ASC-29320ALP U320 w/HostRAID
9892 809c ASC-39320D(B) U320 w/HostRAID
9893 809d AIC-7902(B) U320 w/HostRAID
9894 809e AIC-7901A U320 w/HostRAID
9895 809f AIC-7902 U320 w/HostRAID
9896907f Atronics
9897 2015 IDE-2015PL
9898919a Gigapixel Corp
98999412 Holtek
9900 6565 6565
99019699 Omni Media Technology Inc
9902 6565 6565
99039710 NetMos Technology
9904 7780 USB IRDA-port
9905 9705 PCI 9705 Parallel Port
9906 9715 PCI 9715 Dual Parallel Port
9907 9735 PCI 9735 Multi-I/O Controller
9908 1000 0002 0P2S (2 serial)
9909 1000 0012 1P2S (1 parallel + 2 serial)
9910 9745 PCI 9745 Multi-I/O Controller
9911 1000 0002 0P2S (2 serial)
9912 1000 0012 1P2S (1 parallel + 2 serial)
9913 9755 PCI 9755 Parallel Port and ISA Bridge
9914 9805 PCI 9805 Parallel Port
9915 9815 PCI 9815 Dual Parallel Port
9916 1000 0020 2P0S (2 port parallel adaptor)
9917 9835 PCI 9835 Multi-I/O Controller
9918 1000 0002 0P2S (16C550 UART)
9919 1000 0012 1P2S
9920 9845 PCI 9845 Multi-I/O Controller
9921 1000 0004 0P4S (4 port 16550A serial card)
9922 1000 0006 0P6S (6 port 16550A serial card)
9923 1000 0014 1P4S (4 port 16550A serial card + parallel)
9924 9855 PCI 9855 Multi-I/O Controller
9925 1000 0014 1P4S
99269902 Stargen Inc.
9927 0001 SG2010 PCI over Starfabric Bridge
9928 0002 SG2010 PCI to Starfabric Gateway
9929 0003 SG1010 Starfabric Switch and PCI Bridge
9930a0a0 AOPEN Inc.
9931a0f1 UNISYS Corporation
9932a200 NEC Corporation
9933a259 Hewlett Packard
9934a25b Hewlett Packard GmbH PL24-MKT
9935a304 Sony
9936a727 3Com Corporation
9937 0013 3CRPAG175 Wireless PC Card
9938aa42 Scitex Digital Video
9939ac1e Digital Receiver Technology Inc
9940ac3d Actuality Systems
9941aecb Adrienne Electronics Corporation
9942b1b3 Shiva Europe Limited
9943# Pinnacle should be 11bd, but they got it wrong several times --mj
9944bd11 Pinnacle Systems, Inc. (Wrong ID)
9945c001 TSI Telsys
9946c0a9 Micron/Crucial Technology
9947c0de Motorola
9948c0fe Motion Engineering, Inc.
9949ca50 Varian Australia Pty Ltd
9950cafe Chrysalis-ITS
9951cccc Catapult Communications
9952cddd Tyzx, Inc.
9953 0101 DeepSea 1 High Speed Stereo Vision Frame Grabber
9954 0200 DeepSea 2 High Speed Stereo Vision Frame Grabber
9955d4d4 Dy4 Systems Inc
9956 0601 PCI Mezzanine Card
9957d531 I+ME ACTIA GmbH
9958d84d Exsys
9959dead Indigita Corporation
9960deaf Middle Digital Inc.
9961 9050 PC Weasel Virtual VGA
9962 9051 PC Weasel Serial Port
9963 9052 PC Weasel Watchdog Timer
9964e000 Winbond
9965 e000 W89C940
9966# see also : http://www.schoenfeld.de/inside/Inside_CWMK3.txt maybe a misuse of TJN id or it use the TJN 3XX chip for other applic
9967e159 Tiger Jet Network Inc.
9968 0001 Tiger3XX Modem/ISDN interface
9969 0059 0001 128k ISDN-S/T Adapter
9970 0059 0003 128k ISDN-U Adapter
9971 0002 Tiger100APC ISDN chipset
9972e4bf EKF Elektronik GmbH
9973# Innovative and scalable network IC vendor
9974e55e Essence Technology, Inc.
9975ea01 Eagle Technology
9976# The main chip of all these devices is by Xilinx -> It could also be a Xilinx ID.
9977ea60 RME
9978 9896 Digi32
9979 9897 Digi32 Pro
9980 9898 Digi32/8
9981eabb Aashima Technology B.V.
9982eace Endace Measurement Systems, Ltd
9983 3100 DAG 3.10 OC-3/OC-12
9984 3200 DAG 3.2x OC-3/OC-12
9985 320e DAG 3.2E Fast Ethernet
9986 340e DAG 3.4E Fast Ethernet
9987 341e DAG 3.41E Fast Ethernet
9988 3500 DAG 3.5 OC-3/OC-12
9989 351c DAG 3.5ECM Fast Ethernet
9990 4100 DAG 4.10 OC-48
9991 4110 DAG 4.11 OC-48
9992 4220 DAG 4.2 OC-48
9993 422e DAG 4.2E Dual Gigabit Ethernet
9994ec80 Belkin Corporation
9995 ec00 F5D6000
9996ecc0 Echo Digital Audio Corporation
9997edd8 ARK Logic Inc
9998 a091 1000PV [Stingray]
9999 a099 2000PV [Stingray]
10000 a0a1 2000MT
10001 a0a9 2000MI
10002f1d0 AJA Video
10003# All boards I have seen have this ID not efac, though all docs say efac...
10004 cafe KONA SD SMPTE 259M I/O
10005 efac KONA SD SMPTE 259M I/O
10006 facd KONA HD SMPTE 292M I/O
10007fa57 Interagon AS
10008 0001 PMC [Pattern Matching Chip]
10009febd Ultraview Corp.
10010feda Broadcom Inc (nee Epigram)
10011 a0fa BCM4210 iLine10 HomePNA 2.0
10012 a10e BCM4230 iLine10 HomePNA 2.0
10013# IT & Telecom company, develops PCI Trunk cards <www.fedetec.es>
10014fede Fedetec Inc.
10015 0003 TABIC PCI v3
10016fffe VMWare Inc
10017 0405 Virtual SVGA 4.0
10018 0710 Virtual SVGA
10019ffff Illegal Vendor ID
10020
10021
10022# List of known device classes, subclasses and programming interfaces
10023
10024# Syntax:
10025# C class class_name
10026# subclass subclass_name <-- single tab
10027# prog-if prog-if_name <-- two tabs
10028
10029C 00 Unclassified device
10030 00 Non-VGA unclassified device
10031 01 VGA compatible unclassified device
10032C 01 Mass storage controller
10033 00 SCSI storage controller
10034 01 IDE interface
10035 02 Floppy disk controller
10036 03 IPI bus controller
10037 04 RAID bus controller
10038 80 Unknown mass storage controller
10039C 02 Network controller
10040 00 Ethernet controller
10041 01 Token ring network controller
10042 02 FDDI network controller
10043 03 ATM network controller
10044 04 ISDN controller
10045 80 Network controller
10046C 03 Display controller
10047 00 VGA compatible controller
10048 00 VGA
10049 01 8514
10050 01 XGA compatible controller
10051 02 3D controller
10052 80 Display controller
10053C 04 Multimedia controller
10054 00 Multimedia video controller
10055 01 Multimedia audio controller
10056 02 Computer telephony device
10057 80 Multimedia controller
10058C 05 Memory controller
10059 00 RAM memory
10060 01 FLASH memory
10061 80 Memory controller
10062C 06 Bridge
10063 00 Host bridge
10064 01 ISA bridge
10065 02 EISA bridge
10066 03 MicroChannel bridge
10067 04 PCI bridge
10068 00 Normal decode
10069 01 Subtractive decode
10070 05 PCMCIA bridge
10071 06 NuBus bridge
10072 07 CardBus bridge
10073 08 RACEway bridge
10074 00 Transparent mode
10075 01 Endpoint mode
10076 09 Semi-transparent PCI-to-PCI bridge
10077 40 Primary bus towards host CPU
10078 80 Secondary bus towards host CPU
10079 0a InfiniBand to PCI host bridge
10080 80 Bridge
10081C 07 Communication controller
10082 00 Serial controller
10083 00 8250
10084 01 16450
10085 02 16550
10086 03 16650
10087 04 16750
10088 05 16850
10089 06 16950
10090 01 Parallel controller
10091 00 SPP
10092 01 BiDir
10093 02 ECP
10094 03 IEEE1284
10095 fe IEEE1284 Target
10096 02 Multiport serial controller
10097 03 Modem
10098 00 Generic
10099 01 Hayes/16450
10100 02 Hayes/16550
10101 03 Hayes/16650
10102 04 Hayes/16750
10103 80 Communication controller
10104C 08 Generic system peripheral
10105 00 PIC
10106 00 8259
10107 01 ISA PIC
10108 02 EISA PIC
10109 10 IO-APIC
10110 20 IO(X)-APIC
10111 01 DMA controller
10112 00 8237
10113 01 ISA DMA
10114 02 EISA DMA
10115 02 Timer
10116 00 8254
10117 01 ISA Timer
10118 02 EISA Timers
10119 03 RTC
10120 00 Generic
10121 01 ISA RTC
10122 04 PCI Hot-plug controller
10123 80 System peripheral
10124C 09 Input device controller
10125 00 Keyboard controller
10126 01 Digitizer Pen
10127 02 Mouse controller
10128 03 Scanner controller
10129 04 Gameport controller
10130 00 Generic
10131 10 Extended
10132 80 Input device controller
10133C 0a Docking station
10134 00 Generic Docking Station
10135 80 Docking Station
10136C 0b Processor
10137 00 386
10138 01 486
10139 02 Pentium
10140 10 Alpha
10141 20 Power PC
10142 30 MIPS
10143 40 Co-processor
10144C 0c Serial bus controller
10145 00 FireWire (IEEE 1394)
10146 00 Generic
10147 10 OHCI
10148 01 ACCESS Bus
10149 02 SSA
10150 03 USB Controller
10151 00 UHCI
10152 10 OHCI
10153 20 EHCI
10154 80 Unspecified
10155 fe USB Device
10156 04 Fibre Channel
10157 05 SMBus
10158 06 InfiniBand
10159C 0d Wireless controller
10160 00 IRDA controller
10161 01 Consumer IR controller
10162 10 RF controller
10163 80 Wireless controller
10164C 0e Intelligent controller
10165 00 I2O
10166C 0f Satellite communications controller
10167 00 Satellite TV controller
10168 01 Satellite audio communication controller
10169 03 Satellite voice communication controller
10170 04 Satellite data communication controller
10171C 10 Encryption controller
10172 00 Network and computing encryption device
10173 10 Entertainment encryption device
10174 80 Encryption controller
10175C 11 Signal processing controller
10176 00 DPIO module
10177 01 Performance counters
10178 10 Communication synchronizer
10179 80 Signal processing controller
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig
new file mode 100644
index 000000000000..1012db8b8b2c
--- /dev/null
+++ b/drivers/pci/pcie/Kconfig
@@ -0,0 +1,36 @@
1#
2# PCI Express Port Bus Configuration
3#
4config PCIEPORTBUS
5 bool "PCI Express support"
6 depends on PCI
7 help
8 This automatically enables PCI Express Port Bus support. Users can
9 choose Native Hot-Plug support, Advanced Error Reporting support,
10 Power Management Event support and Virtual Channel support to run
11 on PCI Express Ports (Root or Switch).
12
13#
14# Include service Kconfig here
15#
16config HOTPLUG_PCI_PCIE
17 tristate "PCI Express Hotplug driver"
18 depends on HOTPLUG_PCI && PCIEPORTBUS
19 help
20 Say Y here if you have a motherboard that supports PCI Express Native
21 Hotplug
22
23 To compile this driver as a module, choose M here: the
24 module will be called pciehp.
25
26 When in doubt, say N.
27
28config HOTPLUG_PCI_PCIE_POLL_EVENT_MODE
29 bool "Use polling mechanism for hot-plug events (for testing purpose)"
30 depends on HOTPLUG_PCI_PCIE
31 help
32 Say Y here if you want to use the polling mechanism for hot-plug
33 events for early platform testing.
34
35 When in doubt, say N.
36
diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile
new file mode 100644
index 000000000000..984fa87283e3
--- /dev/null
+++ b/drivers/pci/pcie/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for PCI-Express PORT Driver
3#
4
5pcieportdrv-y := portdrv_core.o portdrv_pci.o portdrv_bus.o
6
7obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h
new file mode 100644
index 000000000000..6c3ad8918667
--- /dev/null
+++ b/drivers/pci/pcie/portdrv.h
@@ -0,0 +1,41 @@
1/*
2 * File: portdrv.h
3 * Purpose: PCI Express Port Bus Driver's Internal Data Structures
4 *
5 * Copyright (C) 2004 Intel
6 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
7 */
8
9#ifndef _PORTDRV_H_
10#define _PORTDRV_H_
11
12#if !defined(PCI_CAP_ID_PME)
13#define PCI_CAP_ID_PME 1
14#endif
15
16#if !defined(PCI_CAP_ID_EXP)
17#define PCI_CAP_ID_EXP 0x10
18#endif
19
20#define PORT_TYPE_MASK 0xf
21#define PORT_TO_SLOT_MASK 0x100
22#define SLOT_HP_CAPABLE_MASK 0x40
23#define PCIE_CAPABILITIES_REG 0x2
24#define PCIE_SLOT_CAPABILITIES_REG 0x14
25#define PCIE_PORT_DEVICE_MAXSERVICES 4
26#define PCI_CFG_SPACE_SIZE 256
27
28#define get_descriptor_id(type, service) (((type - 4) << 4) | service)
29
30extern struct bus_type pcie_port_bus_type;
31extern int pcie_port_device_probe(struct pci_dev *dev);
32extern int pcie_port_device_register(struct pci_dev *dev);
33#ifdef CONFIG_PM
34extern int pcie_port_device_suspend(struct pci_dev *dev, u32 state);
35extern int pcie_port_device_resume(struct pci_dev *dev);
36#endif
37extern void pcie_port_device_remove(struct pci_dev *dev);
38extern void pcie_port_bus_register(void);
39extern void pcie_port_bus_unregister(void);
40
41#endif /* _PORTDRV_H_ */
diff --git a/drivers/pci/pcie/portdrv_bus.c b/drivers/pci/pcie/portdrv_bus.c
new file mode 100644
index 000000000000..9a02f28ed05f
--- /dev/null
+++ b/drivers/pci/pcie/portdrv_bus.c
@@ -0,0 +1,77 @@
1/*
2 * File: portdrv_bus.c
3 * Purpose: PCI Express Port Bus Driver's Bus Overloading Functions
4 *
5 * Copyright (C) 2004 Intel
6 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
7 */
8
9#include <linux/module.h>
10#include <linux/pci.h>
11#include <linux/kernel.h>
12#include <linux/errno.h>
13#include <linux/pm.h>
14
15#include <linux/pcieport_if.h>
16
17static int pcie_port_bus_match(struct device *dev, struct device_driver *drv);
18static int pcie_port_bus_suspend(struct device *dev, u32 state);
19static int pcie_port_bus_resume(struct device *dev);
20
21struct bus_type pcie_port_bus_type = {
22 .name = "pci_express",
23 .match = pcie_port_bus_match,
24 .suspend = pcie_port_bus_suspend,
25 .resume = pcie_port_bus_resume,
26};
27
28static int pcie_port_bus_match(struct device *dev, struct device_driver *drv)
29{
30 struct pcie_device *pciedev;
31 struct pcie_port_service_driver *driver;
32
33 if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type)
34 return 0;
35
36 pciedev = to_pcie_device(dev);
37 driver = to_service_driver(drv);
38 if ( (driver->id_table->vendor != PCI_ANY_ID &&
39 driver->id_table->vendor != pciedev->id.vendor) ||
40 (driver->id_table->device != PCI_ANY_ID &&
41 driver->id_table->device != pciedev->id.device) ||
42 driver->id_table->port_type != pciedev->id.port_type ||
43 driver->id_table->service_type != pciedev->id.service_type )
44 return 0;
45
46 return 1;
47}
48
49static int pcie_port_bus_suspend(struct device *dev, u32 state)
50{
51 struct pcie_device *pciedev;
52 struct pcie_port_service_driver *driver;
53
54 if (!dev || !dev->driver)
55 return 0;
56
57 pciedev = to_pcie_device(dev);
58 driver = to_service_driver(dev->driver);
59 if (driver && driver->suspend)
60 driver->suspend(pciedev, state);
61 return 0;
62}
63
64static int pcie_port_bus_resume(struct device *dev)
65{
66 struct pcie_device *pciedev;
67 struct pcie_port_service_driver *driver;
68
69 if (!dev || !dev->driver)
70 return 0;
71
72 pciedev = to_pcie_device(dev);
73 driver = to_service_driver(dev->driver);
74 if (driver && driver->resume)
75 driver->resume(pciedev);
76 return 0;
77}
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
new file mode 100644
index 000000000000..127f64f85dc5
--- /dev/null
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -0,0 +1,434 @@
1/*
2 * File: portdrv_core.c
3 * Purpose: PCI Express Port Bus Driver's Core Functions
4 *
5 * Copyright (C) 2004 Intel
6 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
7 */
8
9#include <linux/module.h>
10#include <linux/pci.h>
11#include <linux/kernel.h>
12#include <linux/errno.h>
13#include <linux/pm.h>
14#include <linux/pcieport_if.h>
15
16#include "portdrv.h"
17
18extern int pcie_mch_quirk; /* MSI-quirk Indicator */
19
20static int pcie_port_probe_service(struct device *dev)
21{
22 struct pcie_device *pciedev;
23 struct pcie_port_service_driver *driver;
24 int status = -ENODEV;
25
26 if (!dev || !dev->driver)
27 return status;
28
29 driver = to_service_driver(dev->driver);
30 if (!driver || !driver->probe)
31 return status;
32
33 pciedev = to_pcie_device(dev);
34 status = driver->probe(pciedev, driver->id_table);
35 if (!status) {
36 printk(KERN_DEBUG "Load service driver %s on pcie device %s\n",
37 driver->name, dev->bus_id);
38 get_device(dev);
39 }
40 return status;
41}
42
43static int pcie_port_remove_service(struct device *dev)
44{
45 struct pcie_device *pciedev;
46 struct pcie_port_service_driver *driver;
47
48 if (!dev || !dev->driver)
49 return 0;
50
51 pciedev = to_pcie_device(dev);
52 driver = to_service_driver(dev->driver);
53 if (driver && driver->remove) {
54 printk(KERN_DEBUG "Unload service driver %s on pcie device %s\n",
55 driver->name, dev->bus_id);
56 driver->remove(pciedev);
57 put_device(dev);
58 }
59 return 0;
60}
61
62static void pcie_port_shutdown_service(struct device *dev) {}
63
64static int pcie_port_suspend_service(struct device *dev, u32 state, u32 level)
65{
66 struct pcie_device *pciedev;
67 struct pcie_port_service_driver *driver;
68
69 if (!dev || !dev->driver)
70 return 0;
71
72 pciedev = to_pcie_device(dev);
73 driver = to_service_driver(dev->driver);
74 if (driver && driver->suspend)
75 driver->suspend(pciedev, state);
76 return 0;
77}
78
79static int pcie_port_resume_service(struct device *dev, u32 state)
80{
81 struct pcie_device *pciedev;
82 struct pcie_port_service_driver *driver;
83
84 if (!dev || !dev->driver)
85 return 0;
86
87 pciedev = to_pcie_device(dev);
88 driver = to_service_driver(dev->driver);
89
90 if (driver && driver->resume)
91 driver->resume(pciedev);
92 return 0;
93}
94
95/*
96 * release_pcie_device
97 *
98 * Being invoked automatically when device is being removed
99 * in response to device_unregister(dev) call.
100 * Release all resources being claimed.
101 */
102static void release_pcie_device(struct device *dev)
103{
104 printk(KERN_DEBUG "Free Port Service[%s]\n", dev->bus_id);
105 kfree(to_pcie_device(dev));
106}
107
108static int is_msi_quirked(struct pci_dev *dev)
109{
110 int port_type, quirk = 0;
111 u16 reg16;
112
113 pci_read_config_word(dev,
114 pci_find_capability(dev, PCI_CAP_ID_EXP) +
115 PCIE_CAPABILITIES_REG, &reg16);
116 port_type = (reg16 >> 4) & PORT_TYPE_MASK;
117 switch(port_type) {
118 case PCIE_RC_PORT:
119 if (pcie_mch_quirk == 1)
120 quirk = 1;
121 break;
122 case PCIE_SW_UPSTREAM_PORT:
123 case PCIE_SW_DOWNSTREAM_PORT:
124 default:
125 break;
126 }
127 return quirk;
128}
129
130static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
131{
132 int i, pos, nvec, status = -EINVAL;
133 int interrupt_mode = PCIE_PORT_INTx_MODE;
134
135 /* Set INTx as default */
136 for (i = 0, nvec = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
137 if (mask & (1 << i))
138 nvec++;
139 vectors[i] = dev->irq;
140 }
141
142 /* Check MSI quirk */
143 if (is_msi_quirked(dev))
144 return interrupt_mode;
145
146 /* Select MSI-X over MSI if supported */
147 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
148 if (pos) {
149 struct msix_entry msix_entries[PCIE_PORT_DEVICE_MAXSERVICES] =
150 {{0, 0}, {0, 1}, {0, 2}, {0, 3}};
151 printk("%s Found MSIX capability\n", __FUNCTION__);
152 status = pci_enable_msix(dev, msix_entries, nvec);
153 if (!status) {
154 int j = 0;
155
156 interrupt_mode = PCIE_PORT_MSIX_MODE;
157 for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
158 if (mask & (1 << i))
159 vectors[i] = msix_entries[j++].vector;
160 }
161 }
162 }
163 if (status) {
164 pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
165 if (pos) {
166 printk("%s Found MSI capability\n", __FUNCTION__);
167 status = pci_enable_msi(dev);
168 if (!status) {
169 interrupt_mode = PCIE_PORT_MSI_MODE;
170 for (i = 0;i < PCIE_PORT_DEVICE_MAXSERVICES;i++)
171 vectors[i] = dev->irq;
172 }
173 }
174 }
175 return interrupt_mode;
176}
177
178static int get_port_device_capability(struct pci_dev *dev)
179{
180 int services = 0, pos;
181 u16 reg16;
182 u32 reg32;
183
184 pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
185 pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg16);
186 /* Hot-Plug Capable */
187 if (reg16 & PORT_TO_SLOT_MASK) {
188 pci_read_config_dword(dev,
189 pos + PCIE_SLOT_CAPABILITIES_REG, &reg32);
190 if (reg32 & SLOT_HP_CAPABLE_MASK)
191 services |= PCIE_PORT_SERVICE_HP;
192 }
193 /* PME Capable */
194 pos = pci_find_capability(dev, PCI_CAP_ID_PME);
195 if (pos)
196 services |= PCIE_PORT_SERVICE_PME;
197
198 pos = PCI_CFG_SPACE_SIZE;
199 while (pos) {
200 pci_read_config_dword(dev, pos, &reg32);
201 switch (reg32 & 0xffff) {
202 case PCI_EXT_CAP_ID_ERR:
203 services |= PCIE_PORT_SERVICE_AER;
204 pos = reg32 >> 20;
205 break;
206 case PCI_EXT_CAP_ID_VC:
207 services |= PCIE_PORT_SERVICE_VC;
208 pos = reg32 >> 20;
209 break;
210 default:
211 pos = 0;
212 break;
213 }
214 }
215
216 return services;
217}
218
219static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev,
220 int port_type, int service_type, int irq, int irq_mode)
221{
222 struct device *device;
223
224 dev->port = parent;
225 dev->interrupt_mode = irq_mode;
226 dev->irq = irq;
227 dev->id.vendor = parent->vendor;
228 dev->id.device = parent->device;
229 dev->id.port_type = port_type;
230 dev->id.service_type = (1 << service_type);
231
232 /* Initialize generic device interface */
233 device = &dev->device;
234 memset(device, 0, sizeof(struct device));
235 INIT_LIST_HEAD(&device->node);
236 INIT_LIST_HEAD(&device->children);
237 INIT_LIST_HEAD(&device->bus_list);
238 device->bus = &pcie_port_bus_type;
239 device->driver = NULL;
240 device->driver_data = NULL;
241 device->release = release_pcie_device; /* callback to free pcie dev */
242 sprintf(&device->bus_id[0], "pcie%02x",
243 get_descriptor_id(port_type, service_type));
244 device->parent = &parent->dev;
245}
246
247static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,
248 int port_type, int service_type, int irq, int irq_mode)
249{
250 struct pcie_device *device;
251
252 device = kmalloc(sizeof(struct pcie_device), GFP_KERNEL);
253 if (!device)
254 return NULL;
255
256 memset(device, 0, sizeof(struct pcie_device));
257 pcie_device_init(parent, device, port_type, service_type, irq,irq_mode);
258 printk(KERN_DEBUG "Allocate Port Service[%s]\n", device->device.bus_id);
259 return device;
260}
261
262int pcie_port_device_probe(struct pci_dev *dev)
263{
264 int pos, type;
265 u16 reg;
266
267 if (!(pos = pci_find_capability(dev, PCI_CAP_ID_EXP)))
268 return -ENODEV;
269
270 pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg);
271 type = (reg >> 4) & PORT_TYPE_MASK;
272 if ( type == PCIE_RC_PORT || type == PCIE_SW_UPSTREAM_PORT ||
273 type == PCIE_SW_DOWNSTREAM_PORT )
274 return 0;
275
276 return -ENODEV;
277}
278
279int pcie_port_device_register(struct pci_dev *dev)
280{
281 int status, type, capabilities, irq_mode, i;
282 int vectors[PCIE_PORT_DEVICE_MAXSERVICES];
283 u16 reg16;
284
285 /* Get port type */
286 pci_read_config_word(dev,
287 pci_find_capability(dev, PCI_CAP_ID_EXP) +
288 PCIE_CAPABILITIES_REG, &reg16);
289 type = (reg16 >> 4) & PORT_TYPE_MASK;
290
291 /* Now get port services */
292 capabilities = get_port_device_capability(dev);
293 irq_mode = assign_interrupt_mode(dev, vectors, capabilities);
294
295 /* Allocate child services if any */
296 for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
297 struct pcie_device *child;
298
299 if (capabilities & (1 << i)) {
300 child = alloc_pcie_device(
301 dev, /* parent */
302 type, /* port type */
303 i, /* service type */
304 vectors[i], /* irq */
305 irq_mode /* interrupt mode */);
306 if (child) {
307 status = device_register(&child->device);
308 if (status) {
309 kfree(child);
310 continue;
311 }
312 get_device(&child->device);
313 }
314 }
315 }
316 return 0;
317}
318
319#ifdef CONFIG_PM
320int pcie_port_device_suspend(struct pci_dev *dev, u32 state)
321{
322 struct list_head *head, *tmp;
323 struct device *parent, *child;
324 struct device_driver *driver;
325 struct pcie_port_service_driver *service_driver;
326
327 parent = &dev->dev;
328 head = &parent->children;
329 tmp = head->next;
330 while (head != tmp) {
331 child = container_of(tmp, struct device, node);
332 tmp = tmp->next;
333 if (child->bus != &pcie_port_bus_type)
334 continue;
335 driver = child->driver;
336 if (!driver)
337 continue;
338 service_driver = to_service_driver(driver);
339 if (service_driver->suspend)
340 service_driver->suspend(to_pcie_device(child), state);
341 }
342 return 0;
343}
344
345int pcie_port_device_resume(struct pci_dev *dev)
346{
347 struct list_head *head, *tmp;
348 struct device *parent, *child;
349 struct device_driver *driver;
350 struct pcie_port_service_driver *service_driver;
351
352 parent = &dev->dev;
353 head = &parent->children;
354 tmp = head->next;
355 while (head != tmp) {
356 child = container_of(tmp, struct device, node);
357 tmp = tmp->next;
358 if (child->bus != &pcie_port_bus_type)
359 continue;
360 driver = child->driver;
361 if (!driver)
362 continue;
363 service_driver = to_service_driver(driver);
364 if (service_driver->resume)
365 service_driver->resume(to_pcie_device(child));
366 }
367 return 0;
368
369}
370#endif
371
372void pcie_port_device_remove(struct pci_dev *dev)
373{
374 struct list_head *head, *tmp;
375 struct device *parent, *child;
376 struct device_driver *driver;
377 struct pcie_port_service_driver *service_driver;
378 int interrupt_mode = PCIE_PORT_INTx_MODE;
379
380 parent = &dev->dev;
381 head = &parent->children;
382 tmp = head->next;
383 while (head != tmp) {
384 child = container_of(tmp, struct device, node);
385 tmp = tmp->next;
386 if (child->bus != &pcie_port_bus_type)
387 continue;
388 driver = child->driver;
389 if (driver) {
390 service_driver = to_service_driver(driver);
391 if (service_driver->remove)
392 service_driver->remove(to_pcie_device(child));
393 }
394 interrupt_mode = (to_pcie_device(child))->interrupt_mode;
395 put_device(child);
396 device_unregister(child);
397 }
398 /* Switch to INTx by default if MSI enabled */
399 if (interrupt_mode == PCIE_PORT_MSIX_MODE)
400 pci_disable_msix(dev);
401 else if (interrupt_mode == PCIE_PORT_MSI_MODE)
402 pci_disable_msi(dev);
403}
404
405void pcie_port_bus_register(void)
406{
407 bus_register(&pcie_port_bus_type);
408}
409
410void pcie_port_bus_unregister(void)
411{
412 bus_unregister(&pcie_port_bus_type);
413}
414
415int pcie_port_service_register(struct pcie_port_service_driver *new)
416{
417 new->driver.name = (char *)new->name;
418 new->driver.bus = &pcie_port_bus_type;
419 new->driver.probe = pcie_port_probe_service;
420 new->driver.remove = pcie_port_remove_service;
421 new->driver.shutdown = pcie_port_shutdown_service;
422 new->driver.suspend = pcie_port_suspend_service;
423 new->driver.resume = pcie_port_resume_service;
424
425 return driver_register(&new->driver);
426}
427
428void pcie_port_service_unregister(struct pcie_port_service_driver *new)
429{
430 driver_unregister(&new->driver);
431}
432
433EXPORT_SYMBOL(pcie_port_service_register);
434EXPORT_SYMBOL(pcie_port_service_unregister);
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
new file mode 100644
index 000000000000..3184843c3649
--- /dev/null
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -0,0 +1,122 @@
1/*
2 * File: portdrv_pci.c
3 * Purpose: PCI Express Port Bus Driver
4 *
5 * Copyright (C) 2004 Intel
6 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
7 */
8
9#include <linux/module.h>
10#include <linux/pci.h>
11#include <linux/kernel.h>
12#include <linux/errno.h>
13#include <linux/pm.h>
14#include <linux/init.h>
15#include <linux/pcieport_if.h>
16
17#include "portdrv.h"
18
19/*
20 * Version Information
21 */
22#define DRIVER_VERSION "v1.0"
23#define DRIVER_AUTHOR "tom.l.nguyen@intel.com"
24#define DRIVER_DESC "PCIE Port Bus Driver"
25MODULE_AUTHOR(DRIVER_AUTHOR);
26MODULE_DESCRIPTION(DRIVER_DESC);
27MODULE_LICENSE("GPL");
28
29/* global data */
30static const char device_name[] = "pcieport-driver";
31
32/*
33 * pcie_portdrv_probe - Probe PCI-Express port devices
34 * @dev: PCI-Express port device being probed
35 *
36 * If detected invokes the pcie_port_device_register() method for
37 * this port device.
38 *
39 */
40static int __devinit pcie_portdrv_probe (struct pci_dev *dev,
41 const struct pci_device_id *id )
42{
43 int status;
44
45 status = pcie_port_device_probe(dev);
46 if (status)
47 return status;
48
49 if (pci_enable_device(dev) < 0)
50 return -ENODEV;
51
52 pci_set_master(dev);
53 if (!dev->irq) {
54 printk(KERN_WARNING
55 "%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n",
56 __FUNCTION__, dev->device, dev->vendor);
57 }
58 if (pcie_port_device_register(dev))
59 return -ENOMEM;
60
61 return 0;
62}
63
64static void pcie_portdrv_remove (struct pci_dev *dev)
65{
66 pcie_port_device_remove(dev);
67}
68
69#ifdef CONFIG_PM
70static int pcie_portdrv_suspend (struct pci_dev *dev, u32 state)
71{
72 return pcie_port_device_suspend(dev, state);
73}
74
75static int pcie_portdrv_resume (struct pci_dev *dev)
76{
77 return pcie_port_device_resume(dev);
78}
79#endif
80
81/*
82 * LINUX Device Driver Model
83 */
84static const struct pci_device_id port_pci_ids[] = { {
85 /* handle any PCI-Express port */
86 PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
87 }, { /* end: all zeroes */ }
88};
89MODULE_DEVICE_TABLE(pci, port_pci_ids);
90
91static struct pci_driver pcie_portdrv = {
92 .name = (char *)device_name,
93 .id_table = &port_pci_ids[0],
94
95 .probe = pcie_portdrv_probe,
96 .remove = pcie_portdrv_remove,
97
98#ifdef CONFIG_PM
99 .suspend = pcie_portdrv_suspend,
100 .resume = pcie_portdrv_resume,
101#endif /* PM */
102};
103
104static int __init pcie_portdrv_init(void)
105{
106 int retval = 0;
107
108 pcie_port_bus_register();
109 retval = pci_register_driver(&pcie_portdrv);
110 if (retval)
111 pcie_port_bus_unregister();
112 return retval;
113}
114
115static void __exit pcie_portdrv_exit(void)
116{
117 pci_unregister_driver(&pcie_portdrv);
118 pcie_port_bus_unregister();
119}
120
121module_init(pcie_portdrv_init);
122module_exit(pcie_portdrv_exit);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
new file mode 100644
index 000000000000..6f0edadd132c
--- /dev/null
+++ b/drivers/pci/probe.c
@@ -0,0 +1,939 @@
1/*
2 * probe.c - PCI detection and setup code
3 */
4
5#include <linux/kernel.h>
6#include <linux/delay.h>
7#include <linux/init.h>
8#include <linux/pci.h>
9#include <linux/slab.h>
10#include <linux/module.h>
11#include <linux/cpumask.h>
12
13#define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */
14#define CARDBUS_RESERVE_BUSNR 3
15#define PCI_CFG_SPACE_SIZE 256
16#define PCI_CFG_SPACE_EXP_SIZE 4096
17
18/* Ugh. Need to stop exporting this to modules. */
19LIST_HEAD(pci_root_buses);
20EXPORT_SYMBOL(pci_root_buses);
21
22LIST_HEAD(pci_devices);
23
24#ifdef HAVE_PCI_LEGACY
25/**
26 * pci_create_legacy_files - create legacy I/O port and memory files
27 * @b: bus to create files under
28 *
29 * Some platforms allow access to legacy I/O port and ISA memory space on
30 * a per-bus basis. This routine creates the files and ties them into
31 * their associated read, write and mmap files from pci-sysfs.c
32 */
33static void pci_create_legacy_files(struct pci_bus *b)
34{
35 b->legacy_io = kmalloc(sizeof(struct bin_attribute) * 2,
36 GFP_ATOMIC);
37 if (b->legacy_io) {
38 memset(b->legacy_io, 0, sizeof(struct bin_attribute) * 2);
39 b->legacy_io->attr.name = "legacy_io";
40 b->legacy_io->size = 0xffff;
41 b->legacy_io->attr.mode = S_IRUSR | S_IWUSR;
42 b->legacy_io->attr.owner = THIS_MODULE;
43 b->legacy_io->read = pci_read_legacy_io;
44 b->legacy_io->write = pci_write_legacy_io;
45 class_device_create_bin_file(&b->class_dev, b->legacy_io);
46
47 /* Allocated above after the legacy_io struct */
48 b->legacy_mem = b->legacy_io + 1;
49 b->legacy_mem->attr.name = "legacy_mem";
50 b->legacy_mem->size = 1024*1024;
51 b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
52 b->legacy_mem->attr.owner = THIS_MODULE;
53 b->legacy_mem->mmap = pci_mmap_legacy_mem;
54 class_device_create_bin_file(&b->class_dev, b->legacy_mem);
55 }
56}
57
58void pci_remove_legacy_files(struct pci_bus *b)
59{
60 if (b->legacy_io) {
61 class_device_remove_bin_file(&b->class_dev, b->legacy_io);
62 class_device_remove_bin_file(&b->class_dev, b->legacy_mem);
63 kfree(b->legacy_io); /* both are allocated here */
64 }
65}
66#else /* !HAVE_PCI_LEGACY */
67static inline void pci_create_legacy_files(struct pci_bus *bus) { return; }
68void pci_remove_legacy_files(struct pci_bus *bus) { return; }
69#endif /* HAVE_PCI_LEGACY */
70
71/*
72 * PCI Bus Class Devices
73 */
74static ssize_t pci_bus_show_cpuaffinity(struct class_device *class_dev, char *buf)
75{
76 cpumask_t cpumask = pcibus_to_cpumask(to_pci_bus(class_dev));
77 int ret;
78
79 ret = cpumask_scnprintf(buf, PAGE_SIZE, cpumask);
80 if (ret < PAGE_SIZE)
81 buf[ret++] = '\n';
82 return ret;
83}
84CLASS_DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpuaffinity, NULL);
85
86/*
87 * PCI Bus Class
88 */
89static void release_pcibus_dev(struct class_device *class_dev)
90{
91 struct pci_bus *pci_bus = to_pci_bus(class_dev);
92
93 if (pci_bus->bridge)
94 put_device(pci_bus->bridge);
95 kfree(pci_bus);
96}
97
98static struct class pcibus_class = {
99 .name = "pci_bus",
100 .release = &release_pcibus_dev,
101};
102
103static int __init pcibus_class_init(void)
104{
105 return class_register(&pcibus_class);
106}
107postcore_initcall(pcibus_class_init);
108
109/*
110 * Translate the low bits of the PCI base
111 * to the resource type
112 */
113static inline unsigned int pci_calc_resource_flags(unsigned int flags)
114{
115 if (flags & PCI_BASE_ADDRESS_SPACE_IO)
116 return IORESOURCE_IO;
117
118 if (flags & PCI_BASE_ADDRESS_MEM_PREFETCH)
119 return IORESOURCE_MEM | IORESOURCE_PREFETCH;
120
121 return IORESOURCE_MEM;
122}
123
124/*
125 * Find the extent of a PCI decode..
126 */
127static u32 pci_size(u32 base, u32 maxbase, unsigned long mask)
128{
129 u32 size = mask & maxbase; /* Find the significant bits */
130 if (!size)
131 return 0;
132
133 /* Get the lowest of them to find the decode size, and
134 from that the extent. */
135 size = (size & ~(size-1)) - 1;
136
137 /* base == maxbase can be valid only if the BAR has
138 already been programmed with all 1s. */
139 if (base == maxbase && ((base | size) & mask) != mask)
140 return 0;
141
142 return size;
143}
144
145static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
146{
147 unsigned int pos, reg, next;
148 u32 l, sz;
149 struct resource *res;
150
151 for(pos=0; pos<howmany; pos = next) {
152 next = pos+1;
153 res = &dev->resource[pos];
154 res->name = pci_name(dev);
155 reg = PCI_BASE_ADDRESS_0 + (pos << 2);
156 pci_read_config_dword(dev, reg, &l);
157 pci_write_config_dword(dev, reg, ~0);
158 pci_read_config_dword(dev, reg, &sz);
159 pci_write_config_dword(dev, reg, l);
160 if (!sz || sz == 0xffffffff)
161 continue;
162 if (l == 0xffffffff)
163 l = 0;
164 if ((l & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY) {
165 sz = pci_size(l, sz, PCI_BASE_ADDRESS_MEM_MASK);
166 if (!sz)
167 continue;
168 res->start = l & PCI_BASE_ADDRESS_MEM_MASK;
169 res->flags |= l & ~PCI_BASE_ADDRESS_MEM_MASK;
170 } else {
171 sz = pci_size(l, sz, PCI_BASE_ADDRESS_IO_MASK & 0xffff);
172 if (!sz)
173 continue;
174 res->start = l & PCI_BASE_ADDRESS_IO_MASK;
175 res->flags |= l & ~PCI_BASE_ADDRESS_IO_MASK;
176 }
177 res->end = res->start + (unsigned long) sz;
178 res->flags |= pci_calc_resource_flags(l);
179 if ((l & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK))
180 == (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)) {
181 pci_read_config_dword(dev, reg+4, &l);
182 next++;
183#if BITS_PER_LONG == 64
184 res->start |= ((unsigned long) l) << 32;
185 res->end = res->start + sz;
186 pci_write_config_dword(dev, reg+4, ~0);
187 pci_read_config_dword(dev, reg+4, &sz);
188 pci_write_config_dword(dev, reg+4, l);
189 sz = pci_size(l, sz, 0xffffffff);
190 if (sz) {
191 /* This BAR needs > 4GB? Wow. */
192 res->end |= (unsigned long)sz<<32;
193 }
194#else
195 if (l) {
196 printk(KERN_ERR "PCI: Unable to handle 64-bit address for device %s\n", pci_name(dev));
197 res->start = 0;
198 res->flags = 0;
199 continue;
200 }
201#endif
202 }
203 }
204 if (rom) {
205 dev->rom_base_reg = rom;
206 res = &dev->resource[PCI_ROM_RESOURCE];
207 res->name = pci_name(dev);
208 pci_read_config_dword(dev, rom, &l);
209 pci_write_config_dword(dev, rom, ~PCI_ROM_ADDRESS_ENABLE);
210 pci_read_config_dword(dev, rom, &sz);
211 pci_write_config_dword(dev, rom, l);
212 if (l == 0xffffffff)
213 l = 0;
214 if (sz && sz != 0xffffffff) {
215 sz = pci_size(l, sz, PCI_ROM_ADDRESS_MASK);
216 if (sz) {
217 res->flags = (l & IORESOURCE_ROM_ENABLE) |
218 IORESOURCE_MEM | IORESOURCE_PREFETCH |
219 IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
220 res->start = l & PCI_ROM_ADDRESS_MASK;
221 res->end = res->start + (unsigned long) sz;
222 }
223 }
224 }
225}
226
227void __devinit pci_read_bridge_bases(struct pci_bus *child)
228{
229 struct pci_dev *dev = child->self;
230 u8 io_base_lo, io_limit_lo;
231 u16 mem_base_lo, mem_limit_lo;
232 unsigned long base, limit;
233 struct resource *res;
234 int i;
235
236 if (!dev) /* It's a host bus, nothing to read */
237 return;
238
239 if (dev->transparent) {
240 printk(KERN_INFO "PCI: Transparent bridge - %s\n", pci_name(dev));
241 for(i = 0; i < PCI_BUS_NUM_RESOURCES; i++)
242 child->resource[i] = child->parent->resource[i];
243 return;
244 }
245
246 for(i=0; i<3; i++)
247 child->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
248
249 res = child->resource[0];
250 pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo);
251 pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo);
252 base = (io_base_lo & PCI_IO_RANGE_MASK) << 8;
253 limit = (io_limit_lo & PCI_IO_RANGE_MASK) << 8;
254
255 if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
256 u16 io_base_hi, io_limit_hi;
257 pci_read_config_word(dev, PCI_IO_BASE_UPPER16, &io_base_hi);
258 pci_read_config_word(dev, PCI_IO_LIMIT_UPPER16, &io_limit_hi);
259 base |= (io_base_hi << 16);
260 limit |= (io_limit_hi << 16);
261 }
262
263 if (base <= limit) {
264 res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
265 res->start = base;
266 res->end = limit + 0xfff;
267 }
268
269 res = child->resource[1];
270 pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo);
271 pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo);
272 base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16;
273 limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16;
274 if (base <= limit) {
275 res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
276 res->start = base;
277 res->end = limit + 0xfffff;
278 }
279
280 res = child->resource[2];
281 pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo);
282 pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo);
283 base = (mem_base_lo & PCI_PREF_RANGE_MASK) << 16;
284 limit = (mem_limit_lo & PCI_PREF_RANGE_MASK) << 16;
285
286 if ((mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) {
287 u32 mem_base_hi, mem_limit_hi;
288 pci_read_config_dword(dev, PCI_PREF_BASE_UPPER32, &mem_base_hi);
289 pci_read_config_dword(dev, PCI_PREF_LIMIT_UPPER32, &mem_limit_hi);
290
291 /*
292 * Some bridges set the base > limit by default, and some
293 * (broken) BIOSes do not initialize them. If we find
294 * this, just assume they are not being used.
295 */
296 if (mem_base_hi <= mem_limit_hi) {
297#if BITS_PER_LONG == 64
298 base |= ((long) mem_base_hi) << 32;
299 limit |= ((long) mem_limit_hi) << 32;
300#else
301 if (mem_base_hi || mem_limit_hi) {
302 printk(KERN_ERR "PCI: Unable to handle 64-bit address space for bridge %s\n", pci_name(dev));
303 return;
304 }
305#endif
306 }
307 }
308 if (base <= limit) {
309 res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
310 res->start = base;
311 res->end = limit + 0xfffff;
312 }
313}
314
315static struct pci_bus * __devinit pci_alloc_bus(void)
316{
317 struct pci_bus *b;
318
319 b = kmalloc(sizeof(*b), GFP_KERNEL);
320 if (b) {
321 memset(b, 0, sizeof(*b));
322 INIT_LIST_HEAD(&b->node);
323 INIT_LIST_HEAD(&b->children);
324 INIT_LIST_HEAD(&b->devices);
325 }
326 return b;
327}
328
329static struct pci_bus * __devinit
330pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr)
331{
332 struct pci_bus *child;
333 int i;
334
335 /*
336 * Allocate a new bus, and inherit stuff from the parent..
337 */
338 child = pci_alloc_bus();
339 if (!child)
340 return NULL;
341
342 child->self = bridge;
343 child->parent = parent;
344 child->ops = parent->ops;
345 child->sysdata = parent->sysdata;
346 child->bridge = get_device(&bridge->dev);
347
348 child->class_dev.class = &pcibus_class;
349 sprintf(child->class_dev.class_id, "%04x:%02x", pci_domain_nr(child), busnr);
350 class_device_register(&child->class_dev);
351 class_device_create_file(&child->class_dev, &class_device_attr_cpuaffinity);
352
353 /*
354 * Set up the primary, secondary and subordinate
355 * bus numbers.
356 */
357 child->number = child->secondary = busnr;
358 child->primary = parent->secondary;
359 child->subordinate = 0xff;
360
361 /* Set up default resource pointers and names.. */
362 for (i = 0; i < 4; i++) {
363 child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i];
364 child->resource[i]->name = child->name;
365 }
366 bridge->subordinate = child;
367
368 return child;
369}
370
371struct pci_bus * __devinit pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr)
372{
373 struct pci_bus *child;
374
375 child = pci_alloc_child_bus(parent, dev, busnr);
376 if (child)
377 list_add_tail(&child->node, &parent->children);
378 return child;
379}
380
381static void pci_enable_crs(struct pci_dev *dev)
382{
383 u16 cap, rpctl;
384 int rpcap = pci_find_capability(dev, PCI_CAP_ID_EXP);
385 if (!rpcap)
386 return;
387
388 pci_read_config_word(dev, rpcap + PCI_CAP_FLAGS, &cap);
389 if (((cap & PCI_EXP_FLAGS_TYPE) >> 4) != PCI_EXP_TYPE_ROOT_PORT)
390 return;
391
392 pci_read_config_word(dev, rpcap + PCI_EXP_RTCTL, &rpctl);
393 rpctl |= PCI_EXP_RTCTL_CRSSVE;
394 pci_write_config_word(dev, rpcap + PCI_EXP_RTCTL, rpctl);
395}
396
397unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus);
398
399/*
400 * If it's a bridge, configure it and scan the bus behind it.
401 * For CardBus bridges, we don't scan behind as the devices will
402 * be handled by the bridge driver itself.
403 *
404 * We need to process bridges in two passes -- first we scan those
405 * already configured by the BIOS and after we are done with all of
406 * them, we proceed to assigning numbers to the remaining buses in
407 * order to avoid overlaps between old and new bus numbers.
408 */
409int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass)
410{
411 struct pci_bus *child;
412 int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
413 u32 buses;
414 u16 bctl;
415
416 pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
417
418 pr_debug("PCI: Scanning behind PCI bridge %s, config %06x, pass %d\n",
419 pci_name(dev), buses & 0xffffff, pass);
420
421 /* Disable MasterAbortMode during probing to avoid reporting
422 of bus errors (in some architectures) */
423 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bctl);
424 pci_write_config_word(dev, PCI_BRIDGE_CONTROL,
425 bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT);
426
427 pci_enable_crs(dev);
428
429 if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus) {
430 unsigned int cmax, busnr;
431 /*
432 * Bus already configured by firmware, process it in the first
433 * pass and just note the configuration.
434 */
435 if (pass)
436 return max;
437 busnr = (buses >> 8) & 0xFF;
438
439 /*
440 * If we already got to this bus through a different bridge,
441 * ignore it. This can happen with the i450NX chipset.
442 */
443 if (pci_find_bus(pci_domain_nr(bus), busnr)) {
444 printk(KERN_INFO "PCI: Bus %04x:%02x already known\n",
445 pci_domain_nr(bus), busnr);
446 return max;
447 }
448
449 child = pci_alloc_child_bus(bus, dev, busnr);
450 if (!child)
451 return max;
452 child->primary = buses & 0xFF;
453 child->subordinate = (buses >> 16) & 0xFF;
454 child->bridge_ctl = bctl;
455
456 cmax = pci_scan_child_bus(child);
457 if (cmax > max)
458 max = cmax;
459 if (child->subordinate > max)
460 max = child->subordinate;
461 } else {
462 /*
463 * We need to assign a number to this bus which we always
464 * do in the second pass.
465 */
466 if (!pass)
467 return max;
468
469 /* Clear errors */
470 pci_write_config_word(dev, PCI_STATUS, 0xffff);
471
472 child = pci_alloc_child_bus(bus, dev, ++max);
473 buses = (buses & 0xff000000)
474 | ((unsigned int)(child->primary) << 0)
475 | ((unsigned int)(child->secondary) << 8)
476 | ((unsigned int)(child->subordinate) << 16);
477
478 /*
479 * yenta.c forces a secondary latency timer of 176.
480 * Copy that behaviour here.
481 */
482 if (is_cardbus) {
483 buses &= ~0xff000000;
484 buses |= CARDBUS_LATENCY_TIMER << 24;
485 }
486
487 /*
488 * We need to blast all three values with a single write.
489 */
490 pci_write_config_dword(dev, PCI_PRIMARY_BUS, buses);
491
492 if (!is_cardbus) {
493 child->bridge_ctl = PCI_BRIDGE_CTL_NO_ISA;
494
495 /* Now we can scan all subordinate buses... */
496 max = pci_scan_child_bus(child);
497 } else {
498 /*
499 * For CardBus bridges, we leave 4 bus numbers
500 * as cards with a PCI-to-PCI bridge can be
501 * inserted later.
502 */
503 max += CARDBUS_RESERVE_BUSNR;
504 }
505 /*
506 * Set the subordinate bus number to its real value.
507 */
508 child->subordinate = max;
509 pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max);
510 }
511
512 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl);
513
514 sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number);
515
516 return max;
517}
518
519/*
520 * Read interrupt line and base address registers.
521 * The architecture-dependent code can tweak these, of course.
522 */
523static void pci_read_irq(struct pci_dev *dev)
524{
525 unsigned char irq;
526
527 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq);
528 if (irq)
529 pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
530 dev->irq = irq;
531}
532
533/**
534 * pci_setup_device - fill in class and map information of a device
535 * @dev: the device structure to fill
536 *
537 * Initialize the device structure with information about the device's
538 * vendor,class,memory and IO-space addresses,IRQ lines etc.
539 * Called at initialisation of the PCI subsystem and by CardBus services.
540 * Returns 0 on success and -1 if unknown type of device (not normal, bridge
541 * or CardBus).
542 */
543static int pci_setup_device(struct pci_dev * dev)
544{
545 u32 class;
546
547 sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus),
548 dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
549
550 pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
551 class >>= 8; /* upper 3 bytes */
552 dev->class = class;
553 class >>= 8;
554
555 pr_debug("PCI: Found %s [%04x/%04x] %06x %02x\n", pci_name(dev),
556 dev->vendor, dev->device, class, dev->hdr_type);
557
558 /* "Unknown power state" */
559 dev->current_state = 4;
560
561 /* Early fixups, before probing the BARs */
562 pci_fixup_device(pci_fixup_early, dev);
563 class = dev->class >> 8;
564
565 switch (dev->hdr_type) { /* header type */
566 case PCI_HEADER_TYPE_NORMAL: /* standard header */
567 if (class == PCI_CLASS_BRIDGE_PCI)
568 goto bad;
569 pci_read_irq(dev);
570 pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
571 pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor);
572 pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device);
573 break;
574
575 case PCI_HEADER_TYPE_BRIDGE: /* bridge header */
576 if (class != PCI_CLASS_BRIDGE_PCI)
577 goto bad;
578 /* The PCI-to-PCI bridge spec requires that subtractive
579 decoding (i.e. transparent) bridge must have programming
580 interface code of 0x01. */
581 dev->transparent = ((dev->class & 0xff) == 1);
582 pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
583 break;
584
585 case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */
586 if (class != PCI_CLASS_BRIDGE_CARDBUS)
587 goto bad;
588 pci_read_irq(dev);
589 pci_read_bases(dev, 1, 0);
590 pci_read_config_word(dev, PCI_CB_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor);
591 pci_read_config_word(dev, PCI_CB_SUBSYSTEM_ID, &dev->subsystem_device);
592 break;
593
594 default: /* unknown header */
595 printk(KERN_ERR "PCI: device %s has unknown header type %02x, ignoring.\n",
596 pci_name(dev), dev->hdr_type);
597 return -1;
598
599 bad:
600 printk(KERN_ERR "PCI: %s: class %x doesn't match header type %02x. Ignoring class.\n",
601 pci_name(dev), class, dev->hdr_type);
602 dev->class = PCI_CLASS_NOT_DEFINED;
603 }
604
605 /* We found a fine healthy device, go go go... */
606 return 0;
607}
608
609/**
610 * pci_release_dev - free a pci device structure when all users of it are finished.
611 * @dev: device that's been disconnected
612 *
613 * Will be called only by the device core when all users of this pci device are
614 * done.
615 */
616static void pci_release_dev(struct device *dev)
617{
618 struct pci_dev *pci_dev;
619
620 pci_dev = to_pci_dev(dev);
621 kfree(pci_dev);
622}
623
624/**
625 * pci_cfg_space_size - get the configuration space size of the PCI device.
626 *
627 * Regular PCI devices have 256 bytes, but PCI-X 2 and PCI Express devices
628 * have 4096 bytes. Even if the device is capable, that doesn't mean we can
629 * access it. Maybe we don't have a way to generate extended config space
630 * accesses, or the device is behind a reverse Express bridge. So we try
631 * reading the dword at 0x100 which must either be 0 or a valid extended
632 * capability header.
633 */
634static int pci_cfg_space_size(struct pci_dev *dev)
635{
636 int pos;
637 u32 status;
638
639 pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
640 if (!pos) {
641 pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
642 if (!pos)
643 goto fail;
644
645 pci_read_config_dword(dev, pos + PCI_X_STATUS, &status);
646 if (!(status & (PCI_X_STATUS_266MHZ | PCI_X_STATUS_533MHZ)))
647 goto fail;
648 }
649
650 if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL)
651 goto fail;
652 if (status == 0xffffffff)
653 goto fail;
654
655 return PCI_CFG_SPACE_EXP_SIZE;
656
657 fail:
658 return PCI_CFG_SPACE_SIZE;
659}
660
661static void pci_release_bus_bridge_dev(struct device *dev)
662{
663 kfree(dev);
664}
665
666/*
667 * Read the config data for a PCI device, sanity-check it
668 * and fill in the dev structure...
669 */
670static struct pci_dev * __devinit
671pci_scan_device(struct pci_bus *bus, int devfn)
672{
673 struct pci_dev *dev;
674 u32 l;
675 u8 hdr_type;
676 int delay = 1;
677
678 if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l))
679 return NULL;
680
681 /* some broken boards return 0 or ~0 if a slot is empty: */
682 if (l == 0xffffffff || l == 0x00000000 ||
683 l == 0x0000ffff || l == 0xffff0000)
684 return NULL;
685
686 /* Configuration request Retry Status */
687 while (l == 0xffff0001) {
688 msleep(delay);
689 delay *= 2;
690 if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l))
691 return NULL;
692 /* Card hasn't responded in 60 seconds? Must be stuck. */
693 if (delay > 60 * 1000) {
694 printk(KERN_WARNING "Device %04x:%02x:%02x.%d not "
695 "responding\n", pci_domain_nr(bus),
696 bus->number, PCI_SLOT(devfn),
697 PCI_FUNC(devfn));
698 return NULL;
699 }
700 }
701
702 if (pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type))
703 return NULL;
704
705 dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
706 if (!dev)
707 return NULL;
708
709 memset(dev, 0, sizeof(struct pci_dev));
710 dev->bus = bus;
711 dev->sysdata = bus->sysdata;
712 dev->dev.parent = bus->bridge;
713 dev->dev.bus = &pci_bus_type;
714 dev->devfn = devfn;
715 dev->hdr_type = hdr_type & 0x7f;
716 dev->multifunction = !!(hdr_type & 0x80);
717 dev->vendor = l & 0xffff;
718 dev->device = (l >> 16) & 0xffff;
719 dev->cfg_size = pci_cfg_space_size(dev);
720
721 /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
722 set this higher, assuming the system even supports it. */
723 dev->dma_mask = 0xffffffff;
724 if (pci_setup_device(dev) < 0) {
725 kfree(dev);
726 return NULL;
727 }
728 device_initialize(&dev->dev);
729 dev->dev.release = pci_release_dev;
730 pci_dev_get(dev);
731
732 pci_name_device(dev);
733
734 dev->dev.dma_mask = &dev->dma_mask;
735 dev->dev.coherent_dma_mask = 0xffffffffull;
736
737 return dev;
738}
739
740struct pci_dev * __devinit
741pci_scan_single_device(struct pci_bus *bus, int devfn)
742{
743 struct pci_dev *dev;
744
745 dev = pci_scan_device(bus, devfn);
746 pci_scan_msi_device(dev);
747
748 if (!dev)
749 return NULL;
750
751 /* Fix up broken headers */
752 pci_fixup_device(pci_fixup_header, dev);
753
754 /*
755 * Add the device to our list of discovered devices
756 * and the bus list for fixup functions, etc.
757 */
758 INIT_LIST_HEAD(&dev->global_list);
759 list_add_tail(&dev->bus_list, &bus->devices);
760
761 return dev;
762}
763
764/**
765 * pci_scan_slot - scan a PCI slot on a bus for devices.
766 * @bus: PCI bus to scan
767 * @devfn: slot number to scan (must have zero function.)
768 *
769 * Scan a PCI slot on the specified PCI bus for devices, adding
770 * discovered devices to the @bus->devices list. New devices
771 * will have an empty dev->global_list head.
772 */
773int __devinit pci_scan_slot(struct pci_bus *bus, int devfn)
774{
775 int func, nr = 0;
776 int scan_all_fns;
777
778 scan_all_fns = pcibios_scan_all_fns(bus, devfn);
779
780 for (func = 0; func < 8; func++, devfn++) {
781 struct pci_dev *dev;
782
783 dev = pci_scan_single_device(bus, devfn);
784 if (dev) {
785 nr++;
786
787 /*
788 * If this is a single function device,
789 * don't scan past the first function.
790 */
791 if (!dev->multifunction) {
792 if (func > 0) {
793 dev->multifunction = 1;
794 } else {
795 break;
796 }
797 }
798 } else {
799 if (func == 0 && !scan_all_fns)
800 break;
801 }
802 }
803 return nr;
804}
805
806unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
807{
808 unsigned int devfn, pass, max = bus->secondary;
809 struct pci_dev *dev;
810
811 pr_debug("PCI: Scanning bus %04x:%02x\n", pci_domain_nr(bus), bus->number);
812
813 /* Go find them, Rover! */
814 for (devfn = 0; devfn < 0x100; devfn += 8)
815 pci_scan_slot(bus, devfn);
816
817 /*
818 * After performing arch-dependent fixup of the bus, look behind
819 * all PCI-to-PCI bridges on this bus.
820 */
821 pr_debug("PCI: Fixups for bus %04x:%02x\n", pci_domain_nr(bus), bus->number);
822 pcibios_fixup_bus(bus);
823 for (pass=0; pass < 2; pass++)
824 list_for_each_entry(dev, &bus->devices, bus_list) {
825 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
826 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
827 max = pci_scan_bridge(bus, dev, max, pass);
828 }
829
830 /*
831 * We've scanned the bus and so we know all about what's on
832 * the other side of any bridges that may be on this bus plus
833 * any devices.
834 *
835 * Return how far we've got finding sub-buses.
836 */
837 pr_debug("PCI: Bus scan for %04x:%02x returning with max=%02x\n",
838 pci_domain_nr(bus), bus->number, max);
839 return max;
840}
841
842unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus)
843{
844 unsigned int max;
845
846 max = pci_scan_child_bus(bus);
847
848 /*
849 * Make the discovered devices available.
850 */
851 pci_bus_add_devices(bus);
852
853 return max;
854}
855
856struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata)
857{
858 int error;
859 struct pci_bus *b;
860 struct device *dev;
861
862 b = pci_alloc_bus();
863 if (!b)
864 return NULL;
865
866 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
867 if (!dev){
868 kfree(b);
869 return NULL;
870 }
871
872 b->sysdata = sysdata;
873 b->ops = ops;
874
875 if (pci_find_bus(pci_domain_nr(b), bus)) {
876 /* If we already got to this bus through a different bridge, ignore it */
877 pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus);
878 goto err_out;
879 }
880 list_add_tail(&b->node, &pci_root_buses);
881
882 memset(dev, 0, sizeof(*dev));
883 dev->parent = parent;
884 dev->release = pci_release_bus_bridge_dev;
885 sprintf(dev->bus_id, "pci%04x:%02x", pci_domain_nr(b), bus);
886 error = device_register(dev);
887 if (error)
888 goto dev_reg_err;
889 b->bridge = get_device(dev);
890
891 b->class_dev.class = &pcibus_class;
892 sprintf(b->class_dev.class_id, "%04x:%02x", pci_domain_nr(b), bus);
893 error = class_device_register(&b->class_dev);
894 if (error)
895 goto class_dev_reg_err;
896 error = class_device_create_file(&b->class_dev, &class_device_attr_cpuaffinity);
897 if (error)
898 goto class_dev_create_file_err;
899
900 /* Create legacy_io and legacy_mem files for this bus */
901 pci_create_legacy_files(b);
902
903 error = sysfs_create_link(&b->class_dev.kobj, &b->bridge->kobj, "bridge");
904 if (error)
905 goto sys_create_link_err;
906
907 b->number = b->secondary = bus;
908 b->resource[0] = &ioport_resource;
909 b->resource[1] = &iomem_resource;
910
911 b->subordinate = pci_scan_child_bus(b);
912
913 pci_bus_add_devices(b);
914
915 return b;
916
917sys_create_link_err:
918 class_device_remove_file(&b->class_dev, &class_device_attr_cpuaffinity);
919class_dev_create_file_err:
920 class_device_unregister(&b->class_dev);
921class_dev_reg_err:
922 device_unregister(dev);
923dev_reg_err:
924 list_del(&b->node);
925err_out:
926 kfree(dev);
927 kfree(b);
928 return NULL;
929}
930EXPORT_SYMBOL(pci_scan_bus_parented);
931
932#ifdef CONFIG_HOTPLUG
933EXPORT_SYMBOL(pci_add_new_bus);
934EXPORT_SYMBOL(pci_do_scan_bus);
935EXPORT_SYMBOL(pci_scan_slot);
936EXPORT_SYMBOL(pci_scan_bridge);
937EXPORT_SYMBOL(pci_scan_single_device);
938EXPORT_SYMBOL_GPL(pci_scan_child_bus);
939#endif
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
new file mode 100644
index 000000000000..84cc4f620d8d
--- /dev/null
+++ b/drivers/pci/proc.c
@@ -0,0 +1,619 @@
1/*
2 * $Id: proc.c,v 1.13 1998/05/12 07:36:07 mj Exp $
3 *
4 * Procfs interface for the PCI bus.
5 *
6 * Copyright (c) 1997--1999 Martin Mares <mj@ucw.cz>
7 */
8
9#include <linux/init.h>
10#include <linux/pci.h>
11#include <linux/module.h>
12#include <linux/proc_fs.h>
13#include <linux/seq_file.h>
14#include <linux/smp_lock.h>
15
16#include <asm/uaccess.h>
17#include <asm/byteorder.h>
18
19static int proc_initialized; /* = 0 */
20
21static loff_t
22proc_bus_pci_lseek(struct file *file, loff_t off, int whence)
23{
24 loff_t new = -1;
25 struct inode *inode = file->f_dentry->d_inode;
26
27 down(&inode->i_sem);
28 switch (whence) {
29 case 0:
30 new = off;
31 break;
32 case 1:
33 new = file->f_pos + off;
34 break;
35 case 2:
36 new = inode->i_size + off;
37 break;
38 }
39 if (new < 0 || new > inode->i_size)
40 new = -EINVAL;
41 else
42 file->f_pos = new;
43 up(&inode->i_sem);
44 return new;
45}
46
47static ssize_t
48proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
49{
50 const struct inode *ino = file->f_dentry->d_inode;
51 const struct proc_dir_entry *dp = PDE(ino);
52 struct pci_dev *dev = dp->data;
53 unsigned int pos = *ppos;
54 unsigned int cnt, size;
55
56 /*
57 * Normal users can read only the standardized portion of the
58 * configuration space as several chips lock up when trying to read
59 * undefined locations (think of Intel PIIX4 as a typical example).
60 */
61
62 if (capable(CAP_SYS_ADMIN))
63 size = dev->cfg_size;
64 else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
65 size = 128;
66 else
67 size = 64;
68
69 if (pos >= size)
70 return 0;
71 if (nbytes >= size)
72 nbytes = size;
73 if (pos + nbytes > size)
74 nbytes = size - pos;
75 cnt = nbytes;
76
77 if (!access_ok(VERIFY_WRITE, buf, cnt))
78 return -EINVAL;
79
80 if ((pos & 1) && cnt) {
81 unsigned char val;
82 pci_read_config_byte(dev, pos, &val);
83 __put_user(val, buf);
84 buf++;
85 pos++;
86 cnt--;
87 }
88
89 if ((pos & 3) && cnt > 2) {
90 unsigned short val;
91 pci_read_config_word(dev, pos, &val);
92 __put_user(cpu_to_le16(val), (unsigned short __user *) buf);
93 buf += 2;
94 pos += 2;
95 cnt -= 2;
96 }
97
98 while (cnt >= 4) {
99 unsigned int val;
100 pci_read_config_dword(dev, pos, &val);
101 __put_user(cpu_to_le32(val), (unsigned int __user *) buf);
102 buf += 4;
103 pos += 4;
104 cnt -= 4;
105 }
106
107 if (cnt >= 2) {
108 unsigned short val;
109 pci_read_config_word(dev, pos, &val);
110 __put_user(cpu_to_le16(val), (unsigned short __user *) buf);
111 buf += 2;
112 pos += 2;
113 cnt -= 2;
114 }
115
116 if (cnt) {
117 unsigned char val;
118 pci_read_config_byte(dev, pos, &val);
119 __put_user(val, buf);
120 buf++;
121 pos++;
122 cnt--;
123 }
124
125 *ppos = pos;
126 return nbytes;
127}
128
129static ssize_t
130proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, loff_t *ppos)
131{
132 const struct inode *ino = file->f_dentry->d_inode;
133 const struct proc_dir_entry *dp = PDE(ino);
134 struct pci_dev *dev = dp->data;
135 int pos = *ppos;
136 int size = dev->cfg_size;
137 int cnt;
138
139 if (pos >= size)
140 return 0;
141 if (nbytes >= size)
142 nbytes = size;
143 if (pos + nbytes > size)
144 nbytes = size - pos;
145 cnt = nbytes;
146
147 if (!access_ok(VERIFY_READ, buf, cnt))
148 return -EINVAL;
149
150 if ((pos & 1) && cnt) {
151 unsigned char val;
152 __get_user(val, buf);
153 pci_write_config_byte(dev, pos, val);
154 buf++;
155 pos++;
156 cnt--;
157 }
158
159 if ((pos & 3) && cnt > 2) {
160 unsigned short val;
161 __get_user(val, (unsigned short __user *) buf);
162 pci_write_config_word(dev, pos, le16_to_cpu(val));
163 buf += 2;
164 pos += 2;
165 cnt -= 2;
166 }
167
168 while (cnt >= 4) {
169 unsigned int val;
170 __get_user(val, (unsigned int __user *) buf);
171 pci_write_config_dword(dev, pos, le32_to_cpu(val));
172 buf += 4;
173 pos += 4;
174 cnt -= 4;
175 }
176
177 if (cnt >= 2) {
178 unsigned short val;
179 __get_user(val, (unsigned short __user *) buf);
180 pci_write_config_word(dev, pos, le16_to_cpu(val));
181 buf += 2;
182 pos += 2;
183 cnt -= 2;
184 }
185
186 if (cnt) {
187 unsigned char val;
188 __get_user(val, buf);
189 pci_write_config_byte(dev, pos, val);
190 buf++;
191 pos++;
192 cnt--;
193 }
194
195 *ppos = pos;
196 return nbytes;
197}
198
199struct pci_filp_private {
200 enum pci_mmap_state mmap_state;
201 int write_combine;
202};
203
204static int proc_bus_pci_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
205{
206 const struct proc_dir_entry *dp = PDE(inode);
207 struct pci_dev *dev = dp->data;
208#ifdef HAVE_PCI_MMAP
209 struct pci_filp_private *fpriv = file->private_data;
210#endif /* HAVE_PCI_MMAP */
211 int ret = 0;
212
213 switch (cmd) {
214 case PCIIOC_CONTROLLER:
215 ret = pci_domain_nr(dev->bus);
216 break;
217
218#ifdef HAVE_PCI_MMAP
219 case PCIIOC_MMAP_IS_IO:
220 fpriv->mmap_state = pci_mmap_io;
221 break;
222
223 case PCIIOC_MMAP_IS_MEM:
224 fpriv->mmap_state = pci_mmap_mem;
225 break;
226
227 case PCIIOC_WRITE_COMBINE:
228 if (arg)
229 fpriv->write_combine = 1;
230 else
231 fpriv->write_combine = 0;
232 break;
233
234#endif /* HAVE_PCI_MMAP */
235
236 default:
237 ret = -EINVAL;
238 break;
239 };
240
241 return ret;
242}
243
244#ifdef HAVE_PCI_MMAP
245static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
246{
247 struct inode *inode = file->f_dentry->d_inode;
248 const struct proc_dir_entry *dp = PDE(inode);
249 struct pci_dev *dev = dp->data;
250 struct pci_filp_private *fpriv = file->private_data;
251 int ret;
252
253 if (!capable(CAP_SYS_RAWIO))
254 return -EPERM;
255
256 ret = pci_mmap_page_range(dev, vma,
257 fpriv->mmap_state,
258 fpriv->write_combine);
259 if (ret < 0)
260 return ret;
261
262 return 0;
263}
264
265static int proc_bus_pci_open(struct inode *inode, struct file *file)
266{
267 struct pci_filp_private *fpriv = kmalloc(sizeof(*fpriv), GFP_KERNEL);
268
269 if (!fpriv)
270 return -ENOMEM;
271
272 fpriv->mmap_state = pci_mmap_io;
273 fpriv->write_combine = 0;
274
275 file->private_data = fpriv;
276
277 return 0;
278}
279
280static int proc_bus_pci_release(struct inode *inode, struct file *file)
281{
282 kfree(file->private_data);
283 file->private_data = NULL;
284
285 return 0;
286}
287#endif /* HAVE_PCI_MMAP */
288
289static struct file_operations proc_bus_pci_operations = {
290 .llseek = proc_bus_pci_lseek,
291 .read = proc_bus_pci_read,
292 .write = proc_bus_pci_write,
293 .ioctl = proc_bus_pci_ioctl,
294#ifdef HAVE_PCI_MMAP
295 .open = proc_bus_pci_open,
296 .release = proc_bus_pci_release,
297 .mmap = proc_bus_pci_mmap,
298#ifdef HAVE_ARCH_PCI_GET_UNMAPPED_AREA
299 .get_unmapped_area = get_pci_unmapped_area,
300#endif /* HAVE_ARCH_PCI_GET_UNMAPPED_AREA */
301#endif /* HAVE_PCI_MMAP */
302};
303
304#if BITS_PER_LONG == 32
305#define LONG_FORMAT "\t%08lx"
306#else
307#define LONG_FORMAT "\t%16lx"
308#endif
309
310/* iterator */
311static void *pci_seq_start(struct seq_file *m, loff_t *pos)
312{
313 struct pci_dev *dev = NULL;
314 loff_t n = *pos;
315
316 for_each_pci_dev(dev) {
317 if (!n--)
318 break;
319 }
320 return dev;
321}
322
323static void *pci_seq_next(struct seq_file *m, void *v, loff_t *pos)
324{
325 struct pci_dev *dev = v;
326
327 (*pos)++;
328 dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
329 return dev;
330}
331
332static void pci_seq_stop(struct seq_file *m, void *v)
333{
334 if (v) {
335 struct pci_dev *dev = v;
336 pci_dev_put(dev);
337 }
338}
339
340static int show_device(struct seq_file *m, void *v)
341{
342 const struct pci_dev *dev = v;
343 const struct pci_driver *drv;
344 int i;
345
346 if (dev == NULL)
347 return 0;
348
349 drv = pci_dev_driver(dev);
350 seq_printf(m, "%02x%02x\t%04x%04x\t%x",
351 dev->bus->number,
352 dev->devfn,
353 dev->vendor,
354 dev->device,
355 dev->irq);
356 /* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */
357 for(i=0; i<7; i++)
358 seq_printf(m, LONG_FORMAT,
359 dev->resource[i].start |
360 (dev->resource[i].flags & PCI_REGION_FLAG_MASK));
361 for(i=0; i<7; i++)
362 seq_printf(m, LONG_FORMAT,
363 dev->resource[i].start < dev->resource[i].end ?
364 dev->resource[i].end - dev->resource[i].start + 1 : 0);
365 seq_putc(m, '\t');
366 if (drv)
367 seq_printf(m, "%s", drv->name);
368 seq_putc(m, '\n');
369 return 0;
370}
371
372static struct seq_operations proc_bus_pci_devices_op = {
373 .start = pci_seq_start,
374 .next = pci_seq_next,
375 .stop = pci_seq_stop,
376 .show = show_device
377};
378
379static struct proc_dir_entry *proc_bus_pci_dir;
380
381int pci_proc_attach_device(struct pci_dev *dev)
382{
383 struct pci_bus *bus = dev->bus;
384 struct proc_dir_entry *e;
385 char name[16];
386
387 if (!proc_initialized)
388 return -EACCES;
389
390 if (!bus->procdir) {
391 if (pci_proc_domain(bus)) {
392 sprintf(name, "%04x:%02x", pci_domain_nr(bus),
393 bus->number);
394 } else {
395 sprintf(name, "%02x", bus->number);
396 }
397 bus->procdir = proc_mkdir(name, proc_bus_pci_dir);
398 if (!bus->procdir)
399 return -ENOMEM;
400 }
401
402 sprintf(name, "%02x.%x", PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
403 e = create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR, bus->procdir);
404 if (!e)
405 return -ENOMEM;
406 e->proc_fops = &proc_bus_pci_operations;
407 e->data = dev;
408 e->size = dev->cfg_size;
409 dev->procent = e;
410
411 return 0;
412}
413
414int pci_proc_detach_device(struct pci_dev *dev)
415{
416 struct proc_dir_entry *e;
417
418 if ((e = dev->procent)) {
419 if (atomic_read(&e->count))
420 return -EBUSY;
421 remove_proc_entry(e->name, dev->bus->procdir);
422 dev->procent = NULL;
423 }
424 return 0;
425}
426
427int pci_proc_attach_bus(struct pci_bus* bus)
428{
429 struct proc_dir_entry *de = bus->procdir;
430
431 if (!proc_initialized)
432 return -EACCES;
433
434 if (!de) {
435 char name[16];
436 sprintf(name, "%02x", bus->number);
437 de = bus->procdir = proc_mkdir(name, proc_bus_pci_dir);
438 if (!de)
439 return -ENOMEM;
440 }
441 return 0;
442}
443
444int pci_proc_detach_bus(struct pci_bus* bus)
445{
446 struct proc_dir_entry *de = bus->procdir;
447 if (de)
448 remove_proc_entry(de->name, proc_bus_pci_dir);
449 return 0;
450}
451
452#ifdef CONFIG_PCI_LEGACY_PROC
453
454/*
455 * Backward compatible /proc/pci interface.
456 */
457
458/*
459 * Convert some of the configuration space registers of the device at
460 * address (bus,devfn) into a string (possibly several lines each).
461 * The configuration string is stored starting at buf[len]. If the
462 * string would exceed the size of the buffer (SIZE), 0 is returned.
463 */
464static int show_dev_config(struct seq_file *m, void *v)
465{
466 struct pci_dev *dev = v;
467 struct pci_dev *first_dev;
468 struct pci_driver *drv;
469 u32 class_rev;
470 unsigned char latency, min_gnt, max_lat, *class;
471 int reg;
472
473 first_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
474 if (dev == first_dev)
475 seq_puts(m, "PCI devices found:\n");
476 pci_dev_put(first_dev);
477
478 drv = pci_dev_driver(dev);
479
480 pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
481 pci_read_config_byte (dev, PCI_LATENCY_TIMER, &latency);
482 pci_read_config_byte (dev, PCI_MIN_GNT, &min_gnt);
483 pci_read_config_byte (dev, PCI_MAX_LAT, &max_lat);
484 seq_printf(m, " Bus %2d, device %3d, function %2d:\n",
485 dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
486 class = pci_class_name(class_rev >> 16);
487 if (class)
488 seq_printf(m, " %s", class);
489 else
490 seq_printf(m, " Class %04x", class_rev >> 16);
491#ifdef CONFIG_PCI_NAMES
492 seq_printf(m, ": %s", dev->pretty_name);
493#else
494 seq_printf(m, ": PCI device %04x:%04x", dev->vendor, dev->device);
495#endif
496 seq_printf(m, " (rev %d).\n", class_rev & 0xff);
497
498 if (dev->irq)
499 seq_printf(m, " IRQ %d.\n", dev->irq);
500
501 if (latency || min_gnt || max_lat) {
502 seq_printf(m, " Master Capable. ");
503 if (latency)
504 seq_printf(m, "Latency=%d. ", latency);
505 else
506 seq_puts(m, "No bursts. ");
507 if (min_gnt)
508 seq_printf(m, "Min Gnt=%d.", min_gnt);
509 if (max_lat)
510 seq_printf(m, "Max Lat=%d.", max_lat);
511 seq_putc(m, '\n');
512 }
513
514 for (reg = 0; reg < 6; reg++) {
515 struct resource *res = dev->resource + reg;
516 unsigned long base, end, flags;
517
518 base = res->start;
519 end = res->end;
520 flags = res->flags;
521 if (!end)
522 continue;
523
524 if (flags & PCI_BASE_ADDRESS_SPACE_IO) {
525 seq_printf(m, " I/O at 0x%lx [0x%lx].\n",
526 base, end);
527 } else {
528 const char *pref, *type = "unknown";
529
530 if (flags & PCI_BASE_ADDRESS_MEM_PREFETCH)
531 pref = "P";
532 else
533 pref = "Non-p";
534 switch (flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
535 case PCI_BASE_ADDRESS_MEM_TYPE_32:
536 type = "32 bit"; break;
537 case PCI_BASE_ADDRESS_MEM_TYPE_1M:
538 type = "20 bit"; break;
539 case PCI_BASE_ADDRESS_MEM_TYPE_64:
540 type = "64 bit"; break;
541 }
542 seq_printf(m, " %srefetchable %s memory at "
543 "0x%lx [0x%lx].\n", pref, type,
544 base,
545 end);
546 }
547 }
548 return 0;
549}
550
551static struct seq_operations proc_pci_op = {
552 .start = pci_seq_start,
553 .next = pci_seq_next,
554 .stop = pci_seq_stop,
555 .show = show_dev_config
556};
557
558static int proc_pci_open(struct inode *inode, struct file *file)
559{
560 return seq_open(file, &proc_pci_op);
561}
562static struct file_operations proc_pci_operations = {
563 .open = proc_pci_open,
564 .read = seq_read,
565 .llseek = seq_lseek,
566 .release = seq_release,
567};
568
569static void legacy_proc_init(void)
570{
571 struct proc_dir_entry * entry = create_proc_entry("pci", 0, NULL);
572 if (entry)
573 entry->proc_fops = &proc_pci_operations;
574}
575
576#else
577
578static void legacy_proc_init(void)
579{
580
581}
582
583#endif /* CONFIG_PCI_LEGACY_PROC */
584
585static int proc_bus_pci_dev_open(struct inode *inode, struct file *file)
586{
587 return seq_open(file, &proc_bus_pci_devices_op);
588}
589static struct file_operations proc_bus_pci_dev_operations = {
590 .open = proc_bus_pci_dev_open,
591 .read = seq_read,
592 .llseek = seq_lseek,
593 .release = seq_release,
594};
595
596static int __init pci_proc_init(void)
597{
598 struct proc_dir_entry *entry;
599 struct pci_dev *dev = NULL;
600 proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
601 entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
602 if (entry)
603 entry->proc_fops = &proc_bus_pci_dev_operations;
604 proc_initialized = 1;
605 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
606 pci_proc_attach_device(dev);
607 }
608 legacy_proc_init();
609 return 0;
610}
611
612__initcall(pci_proc_init);
613
614#ifdef CONFIG_HOTPLUG
615EXPORT_SYMBOL(pci_proc_attach_device);
616EXPORT_SYMBOL(pci_proc_attach_bus);
617EXPORT_SYMBOL(pci_proc_detach_bus);
618#endif
619
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
new file mode 100644
index 000000000000..1cfe9538fd19
--- /dev/null
+++ b/drivers/pci/quirks.c
@@ -0,0 +1,1352 @@
1/*
2 * This file contains work-arounds for many known PCI hardware
3 * bugs. Devices present only on certain architectures (host
4 * bridges et cetera) should be handled in arch-specific code.
5 *
6 * Note: any quirks for hotpluggable devices must _NOT_ be declared __init.
7 *
8 * Copyright (c) 1999 Martin Mares <mj@ucw.cz>
9 *
10 * The bridge optimization stuff has been removed. If you really
11 * have a silly BIOS which is unable to set your host bridge right,
12 * use the PowerTweak utility (see http://powertweak.sourceforge.net).
13 */
14
15#include <linux/config.h>
16#include <linux/types.h>
17#include <linux/kernel.h>
18#include <linux/pci.h>
19#include <linux/init.h>
20#include <linux/delay.h>
21
22/* Deal with broken BIOS'es that neglect to enable passive release,
23 which can cause problems in combination with the 82441FX/PPro MTRRs */
24static void __devinit quirk_passive_release(struct pci_dev *dev)
25{
26 struct pci_dev *d = NULL;
27 unsigned char dlc;
28
29 /* We have to make sure a particular bit is set in the PIIX3
30 ISA bridge, so we have to go out and find it. */
31 while ((d = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) {
32 pci_read_config_byte(d, 0x82, &dlc);
33 if (!(dlc & 1<<1)) {
34 printk(KERN_ERR "PCI: PIIX3: Enabling Passive Release on %s\n", pci_name(d));
35 dlc |= 1<<1;
36 pci_write_config_byte(d, 0x82, dlc);
37 }
38 }
39}
40DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_passive_release );
41
42/* The VIA VP2/VP3/MVP3 seem to have some 'features'. There may be a workaround
43 but VIA don't answer queries. If you happen to have good contacts at VIA
44 ask them for me please -- Alan
45
46 This appears to be BIOS not version dependent. So presumably there is a
47 chipset level fix */
48int isa_dma_bridge_buggy; /* Exported */
49
50static void __devinit quirk_isa_dma_hangs(struct pci_dev *dev)
51{
52 if (!isa_dma_bridge_buggy) {
53 isa_dma_bridge_buggy=1;
54 printk(KERN_INFO "Activating ISA DMA hang workarounds.\n");
55 }
56}
57 /*
58 * Its not totally clear which chipsets are the problematic ones
59 * We know 82C586 and 82C596 variants are affected.
60 */
61DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, quirk_isa_dma_hangs );
62DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596, quirk_isa_dma_hangs );
63DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, quirk_isa_dma_hangs );
64DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, quirk_isa_dma_hangs );
65DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_1, quirk_isa_dma_hangs );
66DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_2, quirk_isa_dma_hangs );
67DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs );
68
69int pci_pci_problems;
70
71/*
72 * Chipsets where PCI->PCI transfers vanish or hang
73 */
74static void __devinit quirk_nopcipci(struct pci_dev *dev)
75{
76 if ((pci_pci_problems & PCIPCI_FAIL)==0) {
77 printk(KERN_INFO "Disabling direct PCI/PCI transfers.\n");
78 pci_pci_problems |= PCIPCI_FAIL;
79 }
80}
81DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, quirk_nopcipci );
82DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, quirk_nopcipci );
83
84/*
85 * Triton requires workarounds to be used by the drivers
86 */
87static void __devinit quirk_triton(struct pci_dev *dev)
88{
89 if ((pci_pci_problems&PCIPCI_TRITON)==0) {
90 printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n");
91 pci_pci_problems |= PCIPCI_TRITON;
92 }
93}
94DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437, quirk_triton );
95DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX, quirk_triton );
96DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82439, quirk_triton );
97DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82439TX, quirk_triton );
98
99/*
100 * VIA Apollo KT133 needs PCI latency patch
101 * Made according to a windows driver based patch by George E. Breese
102 * see PCI Latency Adjust on http://www.viahardware.com/download/viatweak.shtm
103 * Also see http://www.au-ja.org/review-kt133a-1-en.phtml for
104 * the info on which Mr Breese based his work.
105 *
106 * Updated based on further information from the site and also on
107 * information provided by VIA
108 */
109static void __devinit quirk_vialatency(struct pci_dev *dev)
110{
111 struct pci_dev *p;
112 u8 rev;
113 u8 busarb;
114 /* Ok we have a potential problem chipset here. Now see if we have
115 a buggy southbridge */
116
117 p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, NULL);
118 if (p!=NULL) {
119 pci_read_config_byte(p, PCI_CLASS_REVISION, &rev);
120 /* 0x40 - 0x4f == 686B, 0x10 - 0x2f == 686A; thanks Dan Hollis */
121 /* Check for buggy part revisions */
122 if (rev < 0x40 || rev > 0x42)
123 goto exit;
124 } else {
125 p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, NULL);
126 if (p==NULL) /* No problem parts */
127 goto exit;
128 pci_read_config_byte(p, PCI_CLASS_REVISION, &rev);
129 /* Check for buggy part revisions */
130 if (rev < 0x10 || rev > 0x12)
131 goto exit;
132 }
133
134 /*
135 * Ok we have the problem. Now set the PCI master grant to
136 * occur every master grant. The apparent bug is that under high
137 * PCI load (quite common in Linux of course) you can get data
138 * loss when the CPU is held off the bus for 3 bus master requests
139 * This happens to include the IDE controllers....
140 *
141 * VIA only apply this fix when an SB Live! is present but under
142 * both Linux and Windows this isnt enough, and we have seen
143 * corruption without SB Live! but with things like 3 UDMA IDE
144 * controllers. So we ignore that bit of the VIA recommendation..
145 */
146
147 pci_read_config_byte(dev, 0x76, &busarb);
148 /* Set bit 4 and bi 5 of byte 76 to 0x01
149 "Master priority rotation on every PCI master grant */
150 busarb &= ~(1<<5);
151 busarb |= (1<<4);
152 pci_write_config_byte(dev, 0x76, busarb);
153 printk(KERN_INFO "Applying VIA southbridge workaround.\n");
154exit:
155 pci_dev_put(p);
156}
157DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency );
158DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency );
159DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency );
160
161/*
162 * VIA Apollo VP3 needs ETBF on BT848/878
163 */
164static void __devinit quirk_viaetbf(struct pci_dev *dev)
165{
166 if ((pci_pci_problems&PCIPCI_VIAETBF)==0) {
167 printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n");
168 pci_pci_problems |= PCIPCI_VIAETBF;
169 }
170}
171DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_viaetbf );
172
173static void __devinit quirk_vsfx(struct pci_dev *dev)
174{
175 if ((pci_pci_problems&PCIPCI_VSFX)==0) {
176 printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n");
177 pci_pci_problems |= PCIPCI_VSFX;
178 }
179}
180DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576, quirk_vsfx );
181
182/*
183 * Ali Magik requires workarounds to be used by the drivers
184 * that DMA to AGP space. Latency must be set to 0xA and triton
185 * workaround applied too
186 * [Info kindly provided by ALi]
187 */
188static void __init quirk_alimagik(struct pci_dev *dev)
189{
190 if ((pci_pci_problems&PCIPCI_ALIMAGIK)==0) {
191 printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n");
192 pci_pci_problems |= PCIPCI_ALIMAGIK|PCIPCI_TRITON;
193 }
194}
195DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1647, quirk_alimagik );
196DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1651, quirk_alimagik );
197
198/*
199 * Natoma has some interesting boundary conditions with Zoran stuff
200 * at least
201 */
202static void __devinit quirk_natoma(struct pci_dev *dev)
203{
204 if ((pci_pci_problems&PCIPCI_NATOMA)==0) {
205 printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n");
206 pci_pci_problems |= PCIPCI_NATOMA;
207 }
208}
209DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_natoma );
210DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443LX_0, quirk_natoma );
211DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443LX_1, quirk_natoma );
212DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_0, quirk_natoma );
213DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_1, quirk_natoma );
214DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_2, quirk_natoma );
215
216/*
217 * This chip can cause PCI parity errors if config register 0xA0 is read
218 * while DMAs are occurring.
219 */
220static void __devinit quirk_citrine(struct pci_dev *dev)
221{
222 dev->cfg_size = 0xA0;
223}
224DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, quirk_citrine );
225
226/*
227 * S3 868 and 968 chips report region size equal to 32M, but they decode 64M.
228 * If it's needed, re-allocate the region.
229 */
230static void __devinit quirk_s3_64M(struct pci_dev *dev)
231{
232 struct resource *r = &dev->resource[0];
233
234 if ((r->start & 0x3ffffff) || r->end != r->start + 0x3ffffff) {
235 r->start = 0;
236 r->end = 0x3ffffff;
237 }
238}
239DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_868, quirk_s3_64M );
240DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_968, quirk_s3_64M );
241
242static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, unsigned size, int nr)
243{
244 region &= ~(size-1);
245 if (region) {
246 struct resource *res = dev->resource + nr;
247
248 res->name = pci_name(dev);
249 res->start = region;
250 res->end = region + size - 1;
251 res->flags = IORESOURCE_IO;
252 pci_claim_resource(dev, nr);
253 }
254}
255
256/*
257 * ATI Northbridge setups MCE the processor if you even
258 * read somewhere between 0x3b0->0x3bb or read 0x3d3
259 */
260static void __devinit quirk_ati_exploding_mce(struct pci_dev *dev)
261{
262 printk(KERN_INFO "ATI Northbridge, reserving I/O ports 0x3b0 to 0x3bb.\n");
263 /* Mae rhaid i ni beidio ag edrych ar y lleoliadiau I/O hyn */
264 request_region(0x3b0, 0x0C, "RadeonIGP");
265 request_region(0x3d3, 0x01, "RadeonIGP");
266}
267DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, quirk_ati_exploding_mce );
268
269/*
270 * Let's make the southbridge information explicit instead
271 * of having to worry about people probing the ACPI areas,
272 * for example.. (Yes, it happens, and if you read the wrong
273 * ACPI register it will put the machine to sleep with no
274 * way of waking it up again. Bummer).
275 *
276 * ALI M7101: Two IO regions pointed to by words at
277 * 0xE0 (64 bytes of ACPI registers)
278 * 0xE2 (32 bytes of SMB registers)
279 */
280static void __devinit quirk_ali7101_acpi(struct pci_dev *dev)
281{
282 u16 region;
283
284 pci_read_config_word(dev, 0xE0, &region);
285 quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES);
286 pci_read_config_word(dev, 0xE2, &region);
287 quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1);
288}
289DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, quirk_ali7101_acpi );
290
291/*
292 * PIIX4 ACPI: Two IO regions pointed to by longwords at
293 * 0x40 (64 bytes of ACPI registers)
294 * 0x90 (32 bytes of SMB registers)
295 */
296static void __devinit quirk_piix4_acpi(struct pci_dev *dev)
297{
298 u32 region;
299
300 pci_read_config_dword(dev, 0x40, &region);
301 quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES);
302 pci_read_config_dword(dev, 0x90, &region);
303 quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1);
304}
305DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, quirk_piix4_acpi );
306
307/*
308 * ICH4, ICH4-M, ICH5, ICH5-M ACPI: Three IO regions pointed to by longwords at
309 * 0x40 (128 bytes of ACPI, GPIO & TCO registers)
310 * 0x58 (64 bytes of GPIO I/O space)
311 */
312static void __devinit quirk_ich4_lpc_acpi(struct pci_dev *dev)
313{
314 u32 region;
315
316 pci_read_config_dword(dev, 0x40, &region);
317 quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES);
318
319 pci_read_config_dword(dev, 0x58, &region);
320 quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1);
321}
322DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, quirk_ich4_lpc_acpi );
323DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, quirk_ich4_lpc_acpi );
324DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, quirk_ich4_lpc_acpi );
325DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10, quirk_ich4_lpc_acpi );
326DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, quirk_ich4_lpc_acpi );
327DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, quirk_ich4_lpc_acpi );
328DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, quirk_ich4_lpc_acpi );
329DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, quirk_ich4_lpc_acpi );
330DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, quirk_ich4_lpc_acpi );
331
332/*
333 * VIA ACPI: One IO region pointed to by longword at
334 * 0x48 or 0x20 (256 bytes of ACPI registers)
335 */
336static void __devinit quirk_vt82c586_acpi(struct pci_dev *dev)
337{
338 u8 rev;
339 u32 region;
340
341 pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev);
342 if (rev & 0x10) {
343 pci_read_config_dword(dev, 0x48, &region);
344 region &= PCI_BASE_ADDRESS_IO_MASK;
345 quirk_io_region(dev, region, 256, PCI_BRIDGE_RESOURCES);
346 }
347}
348DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_vt82c586_acpi );
349
350/*
351 * VIA VT82C686 ACPI: Three IO region pointed to by (long)words at
352 * 0x48 (256 bytes of ACPI registers)
353 * 0x70 (128 bytes of hardware monitoring register)
354 * 0x90 (16 bytes of SMB registers)
355 */
356static void __devinit quirk_vt82c686_acpi(struct pci_dev *dev)
357{
358 u16 hm;
359 u32 smb;
360
361 quirk_vt82c586_acpi(dev);
362
363 pci_read_config_word(dev, 0x70, &hm);
364 hm &= PCI_BASE_ADDRESS_IO_MASK;
365 quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1);
366
367 pci_read_config_dword(dev, 0x90, &smb);
368 smb &= PCI_BASE_ADDRESS_IO_MASK;
369 quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2);
370}
371DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt82c686_acpi );
372
373
374#ifdef CONFIG_X86_IO_APIC
375
376#include <asm/io_apic.h>
377
378/*
379 * VIA 686A/B: If an IO-APIC is active, we need to route all on-chip
380 * devices to the external APIC.
381 *
382 * TODO: When we have device-specific interrupt routers,
383 * this code will go away from quirks.
384 */
385static void __devinit quirk_via_ioapic(struct pci_dev *dev)
386{
387 u8 tmp;
388
389 if (nr_ioapics < 1)
390 tmp = 0; /* nothing routed to external APIC */
391 else
392 tmp = 0x1f; /* all known bits (4-0) routed to external APIC */
393
394 printk(KERN_INFO "PCI: %sbling Via external APIC routing\n",
395 tmp == 0 ? "Disa" : "Ena");
396
397 /* Offset 0x58: External APIC IRQ output control */
398 pci_write_config_byte (dev, 0x58, tmp);
399}
400DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic );
401
402/*
403 * The AMD io apic can hang the box when an apic irq is masked.
404 * We check all revs >= B0 (yet not in the pre production!) as the bug
405 * is currently marked NoFix
406 *
407 * We have multiple reports of hangs with this chipset that went away with
408 * noapic specified. For the moment we assume its the errata. We may be wrong
409 * of course. However the advice is demonstrably good even if so..
410 */
411static void __devinit quirk_amd_ioapic(struct pci_dev *dev)
412{
413 u8 rev;
414
415 pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
416 if (rev >= 0x02) {
417 printk(KERN_WARNING "I/O APIC: AMD Errata #22 may be present. In the event of instability try\n");
418 printk(KERN_WARNING " : booting with the \"noapic\" option.\n");
419 }
420}
421DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, quirk_amd_ioapic );
422
423static void __init quirk_ioapic_rmw(struct pci_dev *dev)
424{
425 if (dev->devfn == 0 && dev->bus->number == 0)
426 sis_apic_bug = 1;
427}
428DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_ANY_ID, quirk_ioapic_rmw );
429
430int pci_msi_quirk;
431
432#define AMD8131_revA0 0x01
433#define AMD8131_revB0 0x11
434#define AMD8131_MISC 0x40
435#define AMD8131_NIOAMODE_BIT 0
436static void __init quirk_amd_8131_ioapic(struct pci_dev *dev)
437{
438 unsigned char revid, tmp;
439
440 pci_msi_quirk = 1;
441 printk(KERN_WARNING "PCI: MSI quirk detected. pci_msi_quirk set.\n");
442
443 if (nr_ioapics == 0)
444 return;
445
446 pci_read_config_byte(dev, PCI_REVISION_ID, &revid);
447 if (revid == AMD8131_revA0 || revid == AMD8131_revB0) {
448 printk(KERN_INFO "Fixing up AMD8131 IOAPIC mode\n");
449 pci_read_config_byte( dev, AMD8131_MISC, &tmp);
450 tmp &= ~(1 << AMD8131_NIOAMODE_BIT);
451 pci_write_config_byte( dev, AMD8131_MISC, tmp);
452 }
453}
454DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_APIC, quirk_amd_8131_ioapic );
455
456#endif /* CONFIG_X86_IO_APIC */
457
458
459/*
460 * Via 686A/B: The PCI_INTERRUPT_LINE register for the on-chip
461 * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature:
462 * when written, it makes an internal connection to the PIC.
463 * For these devices, this register is defined to be 4 bits wide.
464 * Normally this is fine. However for IO-APIC motherboards, or
465 * non-x86 architectures (yes Via exists on PPC among other places),
466 * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get
467 * interrupts delivered properly.
468 *
469 * TODO: When we have device-specific interrupt routers,
470 * quirk_via_irqpic will go away from quirks.
471 */
472
473/*
474 * FIXME: it is questionable that quirk_via_acpi
475 * is needed. It shows up as an ISA bridge, and does not
476 * support the PCI_INTERRUPT_LINE register at all. Therefore
477 * it seems like setting the pci_dev's 'irq' to the
478 * value of the ACPI SCI interrupt is only done for convenience.
479 * -jgarzik
480 */
481static void __devinit quirk_via_acpi(struct pci_dev *d)
482{
483 /*
484 * VIA ACPI device: SCI IRQ line in PCI config byte 0x42
485 */
486 u8 irq;
487 pci_read_config_byte(d, 0x42, &irq);
488 irq &= 0xf;
489 if (irq && (irq != 2))
490 d->irq = irq;
491}
492DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi );
493DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi );
494
495/*
496 * PIIX3 USB: We have to disable USB interrupts that are
497 * hardwired to PIRQD# and may be shared with an
498 * external device.
499 *
500 * Legacy Support Register (LEGSUP):
501 * bit13: USB PIRQ Enable (USBPIRQDEN),
502 * bit4: Trap/SMI On IRQ Enable (USBSMIEN).
503 *
504 * We mask out all r/wc bits, too.
505 */
506static void __devinit quirk_piix3_usb(struct pci_dev *dev)
507{
508 u16 legsup;
509
510 pci_read_config_word(dev, 0xc0, &legsup);
511 legsup &= 0x50ef;
512 pci_write_config_word(dev, 0xc0, legsup);
513}
514DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_2, quirk_piix3_usb );
515DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_2, quirk_piix3_usb );
516
517/*
518 * VIA VT82C598 has its device ID settable and many BIOSes
519 * set it to the ID of VT82C597 for backward compatibility.
520 * We need to switch it off to be able to recognize the real
521 * type of the chip.
522 */
523static void __devinit quirk_vt82c598_id(struct pci_dev *dev)
524{
525 pci_write_config_byte(dev, 0xfc, 0);
526 pci_read_config_word(dev, PCI_DEVICE_ID, &dev->device);
527}
528DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_vt82c598_id );
529
530/*
531 * CardBus controllers have a legacy base address that enables them
532 * to respond as i82365 pcmcia controllers. We don't want them to
533 * do this even if the Linux CardBus driver is not loaded, because
534 * the Linux i82365 driver does not (and should not) handle CardBus.
535 */
536static void __devinit quirk_cardbus_legacy(struct pci_dev *dev)
537{
538 if ((PCI_CLASS_BRIDGE_CARDBUS << 8) ^ dev->class)
539 return;
540 pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0);
541}
542DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
543
544/*
545 * Following the PCI ordering rules is optional on the AMD762. I'm not
546 * sure what the designers were smoking but let's not inhale...
547 *
548 * To be fair to AMD, it follows the spec by default, its BIOS people
549 * who turn it off!
550 */
551static void __devinit quirk_amd_ordering(struct pci_dev *dev)
552{
553 u32 pcic;
554 pci_read_config_dword(dev, 0x4C, &pcic);
555 if ((pcic&6)!=6) {
556 pcic |= 6;
557 printk(KERN_WARNING "BIOS failed to enable PCI standards compliance, fixing this error.\n");
558 pci_write_config_dword(dev, 0x4C, pcic);
559 pci_read_config_dword(dev, 0x84, &pcic);
560 pcic |= (1<<23); /* Required in this mode */
561 pci_write_config_dword(dev, 0x84, pcic);
562 }
563}
564DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering );
565
566/*
567 * DreamWorks provided workaround for Dunord I-3000 problem
568 *
569 * This card decodes and responds to addresses not apparently
570 * assigned to it. We force a larger allocation to ensure that
571 * nothing gets put too close to it.
572 */
573static void __devinit quirk_dunord ( struct pci_dev * dev )
574{
575 struct resource *r = &dev->resource [1];
576 r->start = 0;
577 r->end = 0xffffff;
578}
579DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DUNORD, PCI_DEVICE_ID_DUNORD_I3000, quirk_dunord );
580
581/*
582 * i82380FB mobile docking controller: its PCI-to-PCI bridge
583 * is subtractive decoding (transparent), and does indicate this
584 * in the ProgIf. Unfortunately, the ProgIf value is wrong - 0x80
585 * instead of 0x01.
586 */
587static void __devinit quirk_transparent_bridge(struct pci_dev *dev)
588{
589 dev->transparent = 1;
590}
591DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82380FB, quirk_transparent_bridge );
592DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA, 0x605, quirk_transparent_bridge );
593
594/*
595 * Common misconfiguration of the MediaGX/Geode PCI master that will
596 * reduce PCI bandwidth from 70MB/s to 25MB/s. See the GXM/GXLV/GX1
597 * datasheets found at http://www.national.com/ds/GX for info on what
598 * these bits do. <christer@weinigel.se>
599 */
600static void __init quirk_mediagx_master(struct pci_dev *dev)
601{
602 u8 reg;
603 pci_read_config_byte(dev, 0x41, &reg);
604 if (reg & 2) {
605 reg &= ~2;
606 printk(KERN_INFO "PCI: Fixup for MediaGX/Geode Slave Disconnect Boundary (0x41=0x%02x)\n", reg);
607 pci_write_config_byte(dev, 0x41, reg);
608 }
609}
610DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master );
611
612/*
613 * As per PCI spec, ignore base address registers 0-3 of the IDE controllers
614 * running in Compatible mode (bits 0 and 2 in the ProgIf for primary and
615 * secondary channels respectively). If the device reports Compatible mode
616 * but does use BAR0-3 for address decoding, we assume that firmware has
617 * programmed these BARs with standard values (0x1f0,0x3f4 and 0x170,0x374).
618 * Exceptions (if they exist) must be handled in chip/architecture specific
619 * fixups.
620 *
621 * Note: for non x86 people. You may need an arch specific quirk to handle
622 * moving IDE devices to native mode as well. Some plug in card devices power
623 * up in compatible mode and assume the BIOS will adjust them.
624 *
625 * Q: should we load the 0x1f0,0x3f4 into the registers or zap them as
626 * we do now ? We don't want is pci_enable_device to come along
627 * and assign new resources. Both approaches work for that.
628 */
629static void __devinit quirk_ide_bases(struct pci_dev *dev)
630{
631 struct resource *res;
632 int first_bar = 2, last_bar = 0;
633
634 if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
635 return;
636
637 res = &dev->resource[0];
638
639 /* primary channel: ProgIf bit 0, BAR0, BAR1 */
640 if (!(dev->class & 1) && (res[0].flags || res[1].flags)) {
641 res[0].start = res[0].end = res[0].flags = 0;
642 res[1].start = res[1].end = res[1].flags = 0;
643 first_bar = 0;
644 last_bar = 1;
645 }
646
647 /* secondary channel: ProgIf bit 2, BAR2, BAR3 */
648 if (!(dev->class & 4) && (res[2].flags || res[3].flags)) {
649 res[2].start = res[2].end = res[2].flags = 0;
650 res[3].start = res[3].end = res[3].flags = 0;
651 last_bar = 3;
652 }
653
654 if (!last_bar)
655 return;
656
657 printk(KERN_INFO "PCI: Ignoring BAR%d-%d of IDE controller %s\n",
658 first_bar, last_bar, pci_name(dev));
659}
660DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_ide_bases);
661
662/*
663 * Ensure C0 rev restreaming is off. This is normally done by
664 * the BIOS but in the odd case it is not the results are corruption
665 * hence the presence of a Linux check
666 */
667static void __init quirk_disable_pxb(struct pci_dev *pdev)
668{
669 u16 config;
670 u8 rev;
671
672 pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
673 if (rev != 0x04) /* Only C0 requires this */
674 return;
675 pci_read_config_word(pdev, 0x40, &config);
676 if (config & (1<<6)) {
677 config &= ~(1<<6);
678 pci_write_config_word(pdev, 0x40, config);
679 printk(KERN_INFO "PCI: C0 revision 450NX. Disabling PCI restreaming.\n");
680 }
681}
682DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb );
683
684/*
685 * VIA northbridges care about PCI_INTERRUPT_LINE
686 */
687int via_interrupt_line_quirk;
688
689static void __devinit quirk_via_bridge(struct pci_dev *pdev)
690{
691 if(pdev->devfn == 0) {
692 printk(KERN_INFO "PCI: Via IRQ fixup\n");
693 via_interrupt_line_quirk = 1;
694 }
695}
696DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_bridge );
697
698/*
699 * Serverworks CSB5 IDE does not fully support native mode
700 */
701static void __devinit quirk_svwks_csb5ide(struct pci_dev *pdev)
702{
703 u8 prog;
704 pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog);
705 if (prog & 5) {
706 prog &= ~5;
707 pdev->class &= ~5;
708 pci_write_config_byte(pdev, PCI_CLASS_PROG, prog);
709 /* need to re-assign BARs for compat mode */
710 quirk_ide_bases(pdev);
711 }
712}
713DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, quirk_svwks_csb5ide );
714
715/*
716 * Intel 82801CAM ICH3-M datasheet says IDE modes must be the same
717 */
718static void __init quirk_ide_samemode(struct pci_dev *pdev)
719{
720 u8 prog;
721
722 pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog);
723
724 if (((prog & 1) && !(prog & 4)) || ((prog & 4) && !(prog & 1))) {
725 printk(KERN_INFO "PCI: IDE mode mismatch; forcing legacy mode\n");
726 prog &= ~5;
727 pdev->class &= ~5;
728 pci_write_config_byte(pdev, PCI_CLASS_PROG, prog);
729 /* need to re-assign BARs for compat mode */
730 quirk_ide_bases(pdev);
731 }
732}
733DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, quirk_ide_samemode);
734
735/* This was originally an Alpha specific thing, but it really fits here.
736 * The i82375 PCI/EISA bridge appears as non-classified. Fix that.
737 */
738static void __init quirk_eisa_bridge(struct pci_dev *dev)
739{
740 dev->class = PCI_CLASS_BRIDGE_EISA << 8;
741}
742DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, quirk_eisa_bridge );
743
744/*
745 * On ASUS P4B boards, the SMBus PCI Device within the ICH2/4 southbridge
746 * is not activated. The myth is that Asus said that they do not want the
747 * users to be irritated by just another PCI Device in the Win98 device
748 * manager. (see the file prog/hotplug/README.p4b in the lm_sensors
749 * package 2.7.0 for details)
750 *
751 * The SMBus PCI Device can be activated by setting a bit in the ICH LPC
752 * bridge. Unfortunately, this device has no subvendor/subdevice ID. So it
753 * becomes necessary to do this tweak in two steps -- I've chosen the Host
754 * bridge as trigger.
755 */
756static int __initdata asus_hides_smbus = 0;
757
758static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
759{
760 if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK)) {
761 if (dev->device == PCI_DEVICE_ID_INTEL_82845_HB)
762 switch(dev->subsystem_device) {
763 case 0x8070: /* P4B */
764 case 0x8088: /* P4B533 */
765 case 0x1626: /* L3C notebook */
766 asus_hides_smbus = 1;
767 }
768 if (dev->device == PCI_DEVICE_ID_INTEL_82845G_HB)
769 switch(dev->subsystem_device) {
770 case 0x80b1: /* P4GE-V */
771 case 0x80b2: /* P4PE */
772 case 0x8093: /* P4B533-V */
773 asus_hides_smbus = 1;
774 }
775 if (dev->device == PCI_DEVICE_ID_INTEL_82850_HB)
776 switch(dev->subsystem_device) {
777 case 0x8030: /* P4T533 */
778 asus_hides_smbus = 1;
779 }
780 if (dev->device == PCI_DEVICE_ID_INTEL_7205_0)
781 switch (dev->subsystem_device) {
782 case 0x8070: /* P4G8X Deluxe */
783 asus_hides_smbus = 1;
784 }
785 if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB)
786 switch (dev->subsystem_device) {
787 case 0x1751: /* M2N notebook */
788 case 0x1821: /* M5N notebook */
789 asus_hides_smbus = 1;
790 }
791 if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
792 switch (dev->subsystem_device) {
793 case 0x184b: /* W1N notebook */
794 case 0x186a: /* M6Ne notebook */
795 asus_hides_smbus = 1;
796 }
797 } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_HP)) {
798 if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
799 switch(dev->subsystem_device) {
800 case 0x088C: /* HP Compaq nc8000 */
801 case 0x0890: /* HP Compaq nc6000 */
802 asus_hides_smbus = 1;
803 }
804 if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB)
805 switch (dev->subsystem_device) {
806 case 0x12bc: /* HP D330L */
807 asus_hides_smbus = 1;
808 }
809 } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_TOSHIBA)) {
810 if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB)
811 switch(dev->subsystem_device) {
812 case 0x0001: /* Toshiba Satellite A40 */
813 asus_hides_smbus = 1;
814 }
815 } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG)) {
816 if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
817 switch(dev->subsystem_device) {
818 case 0xC00C: /* Samsung P35 notebook */
819 asus_hides_smbus = 1;
820 }
821 }
822}
823DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845_HB, asus_hides_smbus_hostbridge );
824DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_HB, asus_hides_smbus_hostbridge );
825DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82850_HB, asus_hides_smbus_hostbridge );
826DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB, asus_hides_smbus_hostbridge );
827DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_7205_0, asus_hides_smbus_hostbridge );
828DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855PM_HB, asus_hides_smbus_hostbridge );
829DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge );
830
831static void __init asus_hides_smbus_lpc(struct pci_dev *dev)
832{
833 u16 val;
834
835 if (likely(!asus_hides_smbus))
836 return;
837
838 pci_read_config_word(dev, 0xF2, &val);
839 if (val & 0x8) {
840 pci_write_config_word(dev, 0xF2, val & (~0x8));
841 pci_read_config_word(dev, 0xF2, &val);
842 if (val & 0x8)
843 printk(KERN_INFO "PCI: i801 SMBus device continues to play 'hide and seek'! 0x%x\n", val);
844 else
845 printk(KERN_INFO "PCI: Enabled i801 SMBus device\n");
846 }
847}
848DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc );
849DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc );
850DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc );
851DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc );
852DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc );
853
854/*
855 * SiS 96x south bridge: BIOS typically hides SMBus device...
856 */
857static void __init quirk_sis_96x_smbus(struct pci_dev *dev)
858{
859 u8 val = 0;
860 printk(KERN_INFO "Enabling SiS 96x SMBus.\n");
861 pci_read_config_byte(dev, 0x77, &val);
862 pci_write_config_byte(dev, 0x77, val & ~0x10);
863 pci_read_config_byte(dev, 0x77, &val);
864}
865
866
867#define UHCI_USBLEGSUP 0xc0 /* legacy support */
868#define UHCI_USBCMD 0 /* command register */
869#define UHCI_USBSTS 2 /* status register */
870#define UHCI_USBINTR 4 /* interrupt register */
871#define UHCI_USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */
872#define UHCI_USBCMD_RUN (1 << 0) /* RUN/STOP bit */
873#define UHCI_USBCMD_GRESET (1 << 2) /* Global reset */
874#define UHCI_USBCMD_CONFIGURE (1 << 6) /* config semaphore */
875#define UHCI_USBSTS_HALTED (1 << 5) /* HCHalted bit */
876
877#define OHCI_CONTROL 0x04
878#define OHCI_CMDSTATUS 0x08
879#define OHCI_INTRSTATUS 0x0c
880#define OHCI_INTRENABLE 0x10
881#define OHCI_INTRDISABLE 0x14
882#define OHCI_OCR (1 << 3) /* ownership change request */
883#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
884#define OHCI_INTR_OC (1 << 30) /* ownership change */
885
886#define EHCI_HCC_PARAMS 0x08 /* extended capabilities */
887#define EHCI_USBCMD 0 /* command register */
888#define EHCI_USBCMD_RUN (1 << 0) /* RUN/STOP bit */
889#define EHCI_USBSTS 4 /* status register */
890#define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */
891#define EHCI_USBINTR 8 /* interrupt register */
892#define EHCI_USBLEGSUP 0 /* legacy support register */
893#define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */
894#define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */
895#define EHCI_USBLEGCTLSTS 4 /* legacy control/status */
896#define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */
897
898int usb_early_handoff __devinitdata = 0;
899static int __init usb_handoff_early(char *str)
900{
901 usb_early_handoff = 1;
902 return 0;
903}
904__setup("usb-handoff", usb_handoff_early);
905
906static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
907{
908 unsigned long base = 0;
909 int wait_time, delta;
910 u16 val, sts;
911 int i;
912
913 for (i = 0; i < PCI_ROM_RESOURCE; i++)
914 if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) {
915 base = pci_resource_start(pdev, i);
916 break;
917 }
918
919 if (!base)
920 return;
921
922 /*
923 * stop controller
924 */
925 sts = inw(base + UHCI_USBSTS);
926 val = inw(base + UHCI_USBCMD);
927 val &= ~(u16)(UHCI_USBCMD_RUN | UHCI_USBCMD_CONFIGURE);
928 outw(val, base + UHCI_USBCMD);
929
930 /*
931 * wait while it stops if it was running
932 */
933 if ((sts & UHCI_USBSTS_HALTED) == 0)
934 {
935 wait_time = 1000;
936 delta = 100;
937
938 do {
939 outw(0x1f, base + UHCI_USBSTS);
940 udelay(delta);
941 wait_time -= delta;
942 val = inw(base + UHCI_USBSTS);
943 if (val & UHCI_USBSTS_HALTED)
944 break;
945 } while (wait_time > 0);
946 }
947
948 /*
949 * disable interrupts & legacy support
950 */
951 outw(0, base + UHCI_USBINTR);
952 outw(0x1f, base + UHCI_USBSTS);
953 pci_read_config_word(pdev, UHCI_USBLEGSUP, &val);
954 if (val & 0xbf)
955 pci_write_config_word(pdev, UHCI_USBLEGSUP, UHCI_USBLEGSUP_DEFAULT);
956
957}
958
959static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
960{
961 void __iomem *base;
962 int wait_time;
963
964 base = ioremap_nocache(pci_resource_start(pdev, 0),
965 pci_resource_len(pdev, 0));
966 if (base == NULL) return;
967
968 if (readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) {
969 wait_time = 500; /* 0.5 seconds */
970 writel(OHCI_INTR_OC, base + OHCI_INTRENABLE);
971 writel(OHCI_OCR, base + OHCI_CMDSTATUS);
972 while (wait_time > 0 &&
973 readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) {
974 wait_time -= 10;
975 msleep(10);
976 }
977 }
978
979 /*
980 * disable interrupts
981 */
982 writel(~(u32)0, base + OHCI_INTRDISABLE);
983 writel(~(u32)0, base + OHCI_INTRSTATUS);
984
985 iounmap(base);
986}
987
988static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
989{
990 int wait_time, delta;
991 void __iomem *base, *op_reg_base;
992 u32 hcc_params, val, temp;
993 u8 cap_length;
994
995 base = ioremap_nocache(pci_resource_start(pdev, 0),
996 pci_resource_len(pdev, 0));
997 if (base == NULL) return;
998
999 cap_length = readb(base);
1000 op_reg_base = base + cap_length;
1001 hcc_params = readl(base + EHCI_HCC_PARAMS);
1002 hcc_params = (hcc_params >> 8) & 0xff;
1003 if (hcc_params) {
1004 pci_read_config_dword(pdev,
1005 hcc_params + EHCI_USBLEGSUP,
1006 &val);
1007 if (((val & 0xff) == 1) && (val & EHCI_USBLEGSUP_BIOS)) {
1008 /*
1009 * Ok, BIOS is in smm mode, try to hand off...
1010 */
1011 pci_read_config_dword(pdev,
1012 hcc_params + EHCI_USBLEGCTLSTS,
1013 &temp);
1014 pci_write_config_dword(pdev,
1015 hcc_params + EHCI_USBLEGCTLSTS,
1016 temp | EHCI_USBLEGCTLSTS_SOOE);
1017 val |= EHCI_USBLEGSUP_OS;
1018 pci_write_config_dword(pdev,
1019 hcc_params + EHCI_USBLEGSUP,
1020 val);
1021
1022 wait_time = 500;
1023 do {
1024 msleep(10);
1025 wait_time -= 10;
1026 pci_read_config_dword(pdev,
1027 hcc_params + EHCI_USBLEGSUP,
1028 &val);
1029 } while (wait_time && (val & EHCI_USBLEGSUP_BIOS));
1030 if (!wait_time) {
1031 /*
1032 * well, possibly buggy BIOS...
1033 */
1034 printk(KERN_WARNING "EHCI early BIOS handoff "
1035 "failed (BIOS bug ?)\n");
1036 pci_write_config_dword(pdev,
1037 hcc_params + EHCI_USBLEGSUP,
1038 EHCI_USBLEGSUP_OS);
1039 pci_write_config_dword(pdev,
1040 hcc_params + EHCI_USBLEGCTLSTS,
1041 0);
1042 }
1043 }
1044 }
1045
1046 /*
1047 * halt EHCI & disable its interrupts in any case
1048 */
1049 val = readl(op_reg_base + EHCI_USBSTS);
1050 if ((val & EHCI_USBSTS_HALTED) == 0) {
1051 val = readl(op_reg_base + EHCI_USBCMD);
1052 val &= ~EHCI_USBCMD_RUN;
1053 writel(val, op_reg_base + EHCI_USBCMD);
1054
1055 wait_time = 2000;
1056 delta = 100;
1057 do {
1058 writel(0x3f, op_reg_base + EHCI_USBSTS);
1059 udelay(delta);
1060 wait_time -= delta;
1061 val = readl(op_reg_base + EHCI_USBSTS);
1062 if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) {
1063 break;
1064 }
1065 } while (wait_time > 0);
1066 }
1067 writel(0, op_reg_base + EHCI_USBINTR);
1068 writel(0x3f, op_reg_base + EHCI_USBSTS);
1069
1070 iounmap(base);
1071
1072 return;
1073}
1074
1075
1076
1077static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
1078{
1079 if (!usb_early_handoff)
1080 return;
1081
1082 if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x00)) { /* UHCI */
1083 quirk_usb_handoff_uhci(pdev);
1084 } else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10)) { /* OHCI */
1085 quirk_usb_handoff_ohci(pdev);
1086 } else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x20)) { /* EHCI */
1087 quirk_usb_disable_ehci(pdev);
1088 }
1089
1090 return;
1091}
1092DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff);
1093
1094/*
1095 * ... This is further complicated by the fact that some SiS96x south
1096 * bridges pretend to be 85C503/5513 instead. In that case see if we
1097 * spotted a compatible north bridge to make sure.
1098 * (pci_find_device doesn't work yet)
1099 *
1100 * We can also enable the sis96x bit in the discovery register..
1101 */
1102static int __devinitdata sis_96x_compatible = 0;
1103
1104#define SIS_DETECT_REGISTER 0x40
1105
1106static void __init quirk_sis_503(struct pci_dev *dev)
1107{
1108 u8 reg;
1109 u16 devid;
1110
1111 pci_read_config_byte(dev, SIS_DETECT_REGISTER, &reg);
1112 pci_write_config_byte(dev, SIS_DETECT_REGISTER, reg | (1 << 6));
1113 pci_read_config_word(dev, PCI_DEVICE_ID, &devid);
1114 if (((devid & 0xfff0) != 0x0960) && (devid != 0x0018)) {
1115 pci_write_config_byte(dev, SIS_DETECT_REGISTER, reg);
1116 return;
1117 }
1118
1119 /* Make people aware that we changed the config.. */
1120 printk(KERN_WARNING "Uncovering SIS%x that hid as a SIS503 (compatible=%d)\n", devid, sis_96x_compatible);
1121
1122 /*
1123 * Ok, it now shows up as a 96x.. The 96x quirks are after
1124 * the 503 quirk in the quirk table, so they'll automatically
1125 * run and enable things like the SMBus device
1126 */
1127 dev->device = devid;
1128}
1129
1130static void __init quirk_sis_96x_compatible(struct pci_dev *dev)
1131{
1132 sis_96x_compatible = 1;
1133}
1134DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_645, quirk_sis_96x_compatible );
1135DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_646, quirk_sis_96x_compatible );
1136DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_648, quirk_sis_96x_compatible );
1137DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650, quirk_sis_96x_compatible );
1138DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_651, quirk_sis_96x_compatible );
1139DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_735, quirk_sis_96x_compatible );
1140
1141DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 );
1142
1143DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus );
1144DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus );
1145DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus );
1146DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus );
1147
1148#ifdef CONFIG_X86_IO_APIC
1149static void __init quirk_alder_ioapic(struct pci_dev *pdev)
1150{
1151 int i;
1152
1153 if ((pdev->class >> 8) != 0xff00)
1154 return;
1155
1156 /* the first BAR is the location of the IO APIC...we must
1157 * not touch this (and it's already covered by the fixmap), so
1158 * forcibly insert it into the resource tree */
1159 if (pci_resource_start(pdev, 0) && pci_resource_len(pdev, 0))
1160 insert_resource(&iomem_resource, &pdev->resource[0]);
1161
1162 /* The next five BARs all seem to be rubbish, so just clean
1163 * them out */
1164 for (i=1; i < 6; i++) {
1165 memset(&pdev->resource[i], 0, sizeof(pdev->resource[i]));
1166 }
1167
1168}
1169DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EESSC, quirk_alder_ioapic );
1170#endif
1171
1172#ifdef CONFIG_SCSI_SATA
1173static void __devinit quirk_intel_ide_combined(struct pci_dev *pdev)
1174{
1175 u8 prog, comb, tmp;
1176 int ich = 0;
1177
1178 /*
1179 * Narrow down to Intel SATA PCI devices.
1180 */
1181 switch (pdev->device) {
1182 /* PCI ids taken from drivers/scsi/ata_piix.c */
1183 case 0x24d1:
1184 case 0x24df:
1185 case 0x25a3:
1186 case 0x25b0:
1187 ich = 5;
1188 break;
1189 case 0x2651:
1190 case 0x2652:
1191 case 0x2653:
1192 ich = 6;
1193 break;
1194 case 0x27c0:
1195 case 0x27c4:
1196 ich = 7;
1197 break;
1198 default:
1199 /* we do not handle this PCI device */
1200 return;
1201 }
1202
1203 /*
1204 * Read combined mode register.
1205 */
1206 pci_read_config_byte(pdev, 0x90, &tmp); /* combined mode reg */
1207
1208 if (ich == 5) {
1209 tmp &= 0x6; /* interesting bits 2:1, PATA primary/secondary */
1210 if (tmp == 0x4) /* bits 10x */
1211 comb = (1 << 0); /* SATA port 0, PATA port 1 */
1212 else if (tmp == 0x6) /* bits 11x */
1213 comb = (1 << 2); /* PATA port 0, SATA port 1 */
1214 else
1215 return; /* not in combined mode */
1216 } else {
1217 WARN_ON((ich != 6) && (ich != 7));
1218 tmp &= 0x3; /* interesting bits 1:0 */
1219 if (tmp & (1 << 0))
1220 comb = (1 << 2); /* PATA port 0, SATA port 1 */
1221 else if (tmp & (1 << 1))
1222 comb = (1 << 0); /* SATA port 0, PATA port 1 */
1223 else
1224 return; /* not in combined mode */
1225 }
1226
1227 /*
1228 * Read programming interface register.
1229 * (Tells us if it's legacy or native mode)
1230 */
1231 pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog);
1232
1233 /* if SATA port is in native mode, we're ok. */
1234 if (prog & comb)
1235 return;
1236
1237 /* SATA port is in legacy mode. Reserve port so that
1238 * IDE driver does not attempt to use it. If request_region
1239 * fails, it will be obvious at boot time, so we don't bother
1240 * checking return values.
1241 */
1242 if (comb == (1 << 0))
1243 request_region(0x1f0, 8, "libata"); /* port 0 */
1244 else
1245 request_region(0x170, 8, "libata"); /* port 1 */
1246}
1247DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_intel_ide_combined );
1248#endif /* CONFIG_SCSI_SATA */
1249
1250
1251int pcie_mch_quirk;
1252
1253static void __devinit quirk_pcie_mch(struct pci_dev *pdev)
1254{
1255 pcie_mch_quirk = 1;
1256}
1257DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_pcie_mch );
1258DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_pcie_mch );
1259DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_pcie_mch );
1260
1261static void __devinit quirk_netmos(struct pci_dev *dev)
1262{
1263 unsigned int num_parallel = (dev->subsystem_device & 0xf0) >> 4;
1264 unsigned int num_serial = dev->subsystem_device & 0xf;
1265
1266 /*
1267 * These Netmos parts are multiport serial devices with optional
1268 * parallel ports. Even when parallel ports are present, they
1269 * are identified as class SERIAL, which means the serial driver
1270 * will claim them. To prevent this, mark them as class OTHER.
1271 * These combo devices should be claimed by parport_serial.
1272 *
1273 * The subdevice ID is of the form 0x00PS, where <P> is the number
1274 * of parallel ports and <S> is the number of serial ports.
1275 */
1276 switch (dev->device) {
1277 case PCI_DEVICE_ID_NETMOS_9735:
1278 case PCI_DEVICE_ID_NETMOS_9745:
1279 case PCI_DEVICE_ID_NETMOS_9835:
1280 case PCI_DEVICE_ID_NETMOS_9845:
1281 case PCI_DEVICE_ID_NETMOS_9855:
1282 if ((dev->class >> 8) == PCI_CLASS_COMMUNICATION_SERIAL &&
1283 num_parallel) {
1284 printk(KERN_INFO "PCI: Netmos %04x (%u parallel, "
1285 "%u serial); changing class SERIAL to OTHER "
1286 "(use parport_serial)\n",
1287 dev->device, num_parallel, num_serial);
1288 dev->class = (PCI_CLASS_COMMUNICATION_OTHER << 8) |
1289 (dev->class & 0xff);
1290 }
1291 }
1292}
1293DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos);
1294
1295static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end)
1296{
1297 while (f < end) {
1298 if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) &&
1299 (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) {
1300 pr_debug("PCI: Calling quirk %p for %s\n", f->hook, pci_name(dev));
1301 f->hook(dev);
1302 }
1303 f++;
1304 }
1305}
1306
1307extern struct pci_fixup __start_pci_fixups_early[];
1308extern struct pci_fixup __end_pci_fixups_early[];
1309extern struct pci_fixup __start_pci_fixups_header[];
1310extern struct pci_fixup __end_pci_fixups_header[];
1311extern struct pci_fixup __start_pci_fixups_final[];
1312extern struct pci_fixup __end_pci_fixups_final[];
1313extern struct pci_fixup __start_pci_fixups_enable[];
1314extern struct pci_fixup __end_pci_fixups_enable[];
1315
1316
1317void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
1318{
1319 struct pci_fixup *start, *end;
1320
1321 switch(pass) {
1322 case pci_fixup_early:
1323 start = __start_pci_fixups_early;
1324 end = __end_pci_fixups_early;
1325 break;
1326
1327 case pci_fixup_header:
1328 start = __start_pci_fixups_header;
1329 end = __end_pci_fixups_header;
1330 break;
1331
1332 case pci_fixup_final:
1333 start = __start_pci_fixups_final;
1334 end = __end_pci_fixups_final;
1335 break;
1336
1337 case pci_fixup_enable:
1338 start = __start_pci_fixups_enable;
1339 end = __end_pci_fixups_enable;
1340 break;
1341
1342 default:
1343 /* stupid compiler warning, you would think with an enum... */
1344 return;
1345 }
1346 pci_do_fixups(dev, start, end);
1347}
1348
1349EXPORT_SYMBOL(pcie_mch_quirk);
1350#ifdef CONFIG_HOTPLUG
1351EXPORT_SYMBOL(pci_fixup_device);
1352#endif
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
new file mode 100644
index 000000000000..96f077f9a659
--- /dev/null
+++ b/drivers/pci/remove.c
@@ -0,0 +1,118 @@
1#include <linux/pci.h>
2#include <linux/module.h>
3#include "pci.h"
4
5static void pci_free_resources(struct pci_dev *dev)
6{
7 int i;
8
9 msi_remove_pci_irq_vectors(dev);
10
11 pci_cleanup_rom(dev);
12 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
13 struct resource *res = dev->resource + i;
14 if (res->parent)
15 release_resource(res);
16 }
17}
18
19static void pci_destroy_dev(struct pci_dev *dev)
20{
21 pci_proc_detach_device(dev);
22 pci_remove_sysfs_dev_files(dev);
23 device_unregister(&dev->dev);
24
25 /* Remove the device from the device lists, and prevent any further
26 * list accesses from this device */
27 spin_lock(&pci_bus_lock);
28 list_del(&dev->bus_list);
29 list_del(&dev->global_list);
30 dev->bus_list.next = dev->bus_list.prev = NULL;
31 dev->global_list.next = dev->global_list.prev = NULL;
32 spin_unlock(&pci_bus_lock);
33
34 pci_free_resources(dev);
35 pci_dev_put(dev);
36}
37
38/**
39 * pci_remove_device_safe - remove an unused hotplug device
40 * @dev: the device to remove
41 *
42 * Delete the device structure from the device lists and
43 * notify userspace (/sbin/hotplug), but only if the device
44 * in question is not being used by a driver.
45 * Returns 0 on success.
46 */
47int pci_remove_device_safe(struct pci_dev *dev)
48{
49 if (pci_dev_driver(dev))
50 return -EBUSY;
51 pci_destroy_dev(dev);
52 return 0;
53}
54EXPORT_SYMBOL(pci_remove_device_safe);
55
56void pci_remove_bus(struct pci_bus *pci_bus)
57{
58 pci_proc_detach_bus(pci_bus);
59
60 spin_lock(&pci_bus_lock);
61 list_del(&pci_bus->node);
62 spin_unlock(&pci_bus_lock);
63 pci_remove_legacy_files(pci_bus);
64 class_device_remove_file(&pci_bus->class_dev,
65 &class_device_attr_cpuaffinity);
66 sysfs_remove_link(&pci_bus->class_dev.kobj, "bridge");
67 class_device_unregister(&pci_bus->class_dev);
68}
69EXPORT_SYMBOL(pci_remove_bus);
70
71/**
72 * pci_remove_bus_device - remove a PCI device and any children
73 * @dev: the device to remove
74 *
75 * Remove a PCI device from the device lists, informing the drivers
76 * that the device has been removed. We also remove any subordinate
77 * buses and children in a depth-first manner.
78 *
79 * For each device we remove, delete the device structure from the
80 * device lists, remove the /proc entry, and notify userspace
81 * (/sbin/hotplug).
82 */
83void pci_remove_bus_device(struct pci_dev *dev)
84{
85 if (dev->subordinate) {
86 struct pci_bus *b = dev->subordinate;
87
88 pci_remove_behind_bridge(dev);
89 pci_remove_bus(b);
90 dev->subordinate = NULL;
91 }
92
93 pci_destroy_dev(dev);
94}
95
96/**
97 * pci_remove_behind_bridge - remove all devices behind a PCI bridge
98 * @dev: PCI bridge device
99 *
100 * Remove all devices on the bus, except for the parent bridge.
101 * This also removes any child buses, and any devices they may
102 * contain in a depth-first manner.
103 */
104void pci_remove_behind_bridge(struct pci_dev *dev)
105{
106 struct list_head *l, *n;
107
108 if (dev->subordinate) {
109 list_for_each_safe(l, n, &dev->subordinate->devices) {
110 struct pci_dev *dev = pci_dev_b(l);
111
112 pci_remove_bus_device(dev);
113 }
114 }
115}
116
117EXPORT_SYMBOL(pci_remove_bus_device);
118EXPORT_SYMBOL(pci_remove_behind_bridge);
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
new file mode 100644
index 000000000000..3e64ff64b38c
--- /dev/null
+++ b/drivers/pci/rom.c
@@ -0,0 +1,227 @@
1/*
2 * drivers/pci/rom.c
3 *
4 * (C) Copyright 2004 Jon Smirl <jonsmirl@yahoo.com>
5 * (C) Copyright 2004 Silicon Graphics, Inc. Jesse Barnes <jbarnes@sgi.com>
6 *
7 * PCI ROM access routines
8 */
9#include <linux/config.h>
10#include <linux/kernel.h>
11#include <linux/pci.h>
12
13#include "pci.h"
14
15/**
16 * pci_enable_rom - enable ROM decoding for a PCI device
17 * @dev: PCI device to enable
18 *
19 * Enable ROM decoding on @dev. This involves simply turning on the last
20 * bit of the PCI ROM BAR. Note that some cards may share address decoders
21 * between the ROM and other resources, so enabling it may disable access
22 * to MMIO registers or other card memory.
23 */
24static void pci_enable_rom(struct pci_dev *pdev)
25{
26 u32 rom_addr;
27
28 pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
29 rom_addr |= PCI_ROM_ADDRESS_ENABLE;
30 pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
31}
32
33/**
34 * pci_disable_rom - disable ROM decoding for a PCI device
35 * @dev: PCI device to disable
36 *
37 * Disable ROM decoding on a PCI device by turning off the last bit in the
38 * ROM BAR.
39 */
40static void pci_disable_rom(struct pci_dev *pdev)
41{
42 u32 rom_addr;
43 pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
44 rom_addr &= ~PCI_ROM_ADDRESS_ENABLE;
45 pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
46}
47
48/**
49 * pci_map_rom - map a PCI ROM to kernel space
50 * @dev: pointer to pci device struct
51 * @size: pointer to receive size of pci window over ROM
52 * @return: kernel virtual pointer to image of ROM
53 *
54 * Map a PCI ROM into kernel space. If ROM is boot video ROM,
55 * the shadow BIOS copy will be returned instead of the
56 * actual ROM.
57 */
58void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
59{
60 struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
61 loff_t start;
62 void __iomem *rom;
63 void __iomem *image;
64 int last_image;
65
66 /* IORESOURCE_ROM_SHADOW only set on x86 */
67 if (res->flags & IORESOURCE_ROM_SHADOW) {
68 /* primary video rom always starts here */
69 start = (loff_t)0xC0000;
70 *size = 0x20000; /* cover C000:0 through E000:0 */
71 } else {
72 if (res->flags & IORESOURCE_ROM_COPY) {
73 *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
74 return (void __iomem *)pci_resource_start(pdev, PCI_ROM_RESOURCE);
75 } else {
76 /* assign the ROM an address if it doesn't have one */
77 if (res->parent == NULL)
78 pci_assign_resource(pdev, PCI_ROM_RESOURCE);
79
80 start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
81 *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
82 if (*size == 0)
83 return NULL;
84
85 /* Enable ROM space decodes */
86 pci_enable_rom(pdev);
87 }
88 }
89
90 rom = ioremap(start, *size);
91 if (!rom) {
92 /* restore enable if ioremap fails */
93 if (!(res->flags & (IORESOURCE_ROM_ENABLE |
94 IORESOURCE_ROM_SHADOW |
95 IORESOURCE_ROM_COPY)))
96 pci_disable_rom(pdev);
97 return NULL;
98 }
99
100 /*
101 * Try to find the true size of the ROM since sometimes the PCI window
102 * size is much larger than the actual size of the ROM.
103 * True size is important if the ROM is going to be copied.
104 */
105 image = rom;
106 do {
107 void __iomem *pds;
108 /* Standard PCI ROMs start out with these bytes 55 AA */
109 if (readb(image) != 0x55)
110 break;
111 if (readb(image + 1) != 0xAA)
112 break;
113 /* get the PCI data structure and check its signature */
114 pds = image + readw(image + 24);
115 if (readb(pds) != 'P')
116 break;
117 if (readb(pds + 1) != 'C')
118 break;
119 if (readb(pds + 2) != 'I')
120 break;
121 if (readb(pds + 3) != 'R')
122 break;
123 last_image = readb(pds + 21) & 0x80;
124 /* this length is reliable */
125 image += readw(pds + 16) * 512;
126 } while (!last_image);
127
128 *size = image - rom;
129
130 return rom;
131}
132
133/**
134 * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy
135 * @dev: pointer to pci device struct
136 * @size: pointer to receive size of pci window over ROM
137 * @return: kernel virtual pointer to image of ROM
138 *
139 * Map a PCI ROM into kernel space. If ROM is boot video ROM,
140 * the shadow BIOS copy will be returned instead of the
141 * actual ROM.
142 */
143void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size)
144{
145 struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
146 void __iomem *rom;
147
148 rom = pci_map_rom(pdev, size);
149 if (!rom)
150 return NULL;
151
152 if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_SHADOW))
153 return rom;
154
155 res->start = (unsigned long)kmalloc(*size, GFP_KERNEL);
156 if (!res->start)
157 return rom;
158
159 res->end = res->start + *size;
160 memcpy_fromio((void*)res->start, rom, *size);
161 pci_unmap_rom(pdev, rom);
162 res->flags |= IORESOURCE_ROM_COPY;
163
164 return (void __iomem *)res->start;
165}
166
167/**
168 * pci_unmap_rom - unmap the ROM from kernel space
169 * @dev: pointer to pci device struct
170 * @rom: virtual address of the previous mapping
171 *
172 * Remove a mapping of a previously mapped ROM
173 */
174void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
175{
176 struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
177
178 if (res->flags & IORESOURCE_ROM_COPY)
179 return;
180
181 iounmap(rom);
182
183 /* Disable again before continuing, leave enabled if pci=rom */
184 if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW)))
185 pci_disable_rom(pdev);
186}
187
188/**
189 * pci_remove_rom - disable the ROM and remove its sysfs attribute
190 * @dev: pointer to pci device struct
191 *
192 * Remove the rom file in sysfs and disable ROM decoding.
193 */
194void pci_remove_rom(struct pci_dev *pdev)
195{
196 struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
197
198 if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
199 sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
200 if (!(res->flags & (IORESOURCE_ROM_ENABLE |
201 IORESOURCE_ROM_SHADOW |
202 IORESOURCE_ROM_COPY)))
203 pci_disable_rom(pdev);
204}
205
206/**
207 * pci_cleanup_rom - internal routine for freeing the ROM copy created
208 * by pci_map_rom_copy called from remove.c
209 * @dev: pointer to pci device struct
210 *
211 * Free the copied ROM if we allocated one.
212 */
213void pci_cleanup_rom(struct pci_dev *pdev)
214{
215 struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
216 if (res->flags & IORESOURCE_ROM_COPY) {
217 kfree((void*)res->start);
218 res->flags &= ~IORESOURCE_ROM_COPY;
219 res->start = 0;
220 res->end = 0;
221 }
222}
223
224EXPORT_SYMBOL(pci_map_rom);
225EXPORT_SYMBOL(pci_map_rom_copy);
226EXPORT_SYMBOL(pci_unmap_rom);
227EXPORT_SYMBOL(pci_remove_rom);
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
new file mode 100644
index 000000000000..a90a533eba0f
--- /dev/null
+++ b/drivers/pci/search.c
@@ -0,0 +1,388 @@
1/*
2 * PCI searching functions.
3 *
4 * Copyright (C) 1993 -- 1997 Drew Eckhardt, Frederic Potter,
5 * David Mosberger-Tang
6 * Copyright (C) 1997 -- 2000 Martin Mares <mj@ucw.cz>
7 * Copyright (C) 2003 -- 2004 Greg Kroah-Hartman <greg@kroah.com>
8 */
9
10#include <linux/init.h>
11#include <linux/pci.h>
12#include <linux/module.h>
13#include <linux/interrupt.h>
14#include "pci.h"
15
16DEFINE_SPINLOCK(pci_bus_lock);
17
18static struct pci_bus * __devinit
19pci_do_find_bus(struct pci_bus* bus, unsigned char busnr)
20{
21 struct pci_bus* child;
22 struct list_head *tmp;
23
24 if(bus->number == busnr)
25 return bus;
26
27 list_for_each(tmp, &bus->children) {
28 child = pci_do_find_bus(pci_bus_b(tmp), busnr);
29 if(child)
30 return child;
31 }
32 return NULL;
33}
34
35/**
36 * pci_find_bus - locate PCI bus from a given domain and bus number
37 * @domain: number of PCI domain to search
38 * @busnr: number of desired PCI bus
39 *
40 * Given a PCI bus number and domain number, the desired PCI bus is located
41 * in the global list of PCI buses. If the bus is found, a pointer to its
42 * data structure is returned. If no bus is found, %NULL is returned.
43 */
44struct pci_bus * __devinit pci_find_bus(int domain, int busnr)
45{
46 struct pci_bus *bus = NULL;
47 struct pci_bus *tmp_bus;
48
49 while ((bus = pci_find_next_bus(bus)) != NULL) {
50 if (pci_domain_nr(bus) != domain)
51 continue;
52 tmp_bus = pci_do_find_bus(bus, busnr);
53 if (tmp_bus)
54 return tmp_bus;
55 }
56 return NULL;
57}
58
59/**
60 * pci_find_next_bus - begin or continue searching for a PCI bus
61 * @from: Previous PCI bus found, or %NULL for new search.
62 *
63 * Iterates through the list of known PCI busses. A new search is
64 * initiated by passing %NULL to the @from argument. Otherwise if
65 * @from is not %NULL, searches continue from next device on the
66 * global list.
67 */
68struct pci_bus *
69pci_find_next_bus(const struct pci_bus *from)
70{
71 struct list_head *n;
72 struct pci_bus *b = NULL;
73
74 WARN_ON(in_interrupt());
75 spin_lock(&pci_bus_lock);
76 n = from ? from->node.next : pci_root_buses.next;
77 if (n != &pci_root_buses)
78 b = pci_bus_b(n);
79 spin_unlock(&pci_bus_lock);
80 return b;
81}
82
83/**
84 * pci_find_slot - locate PCI device from a given PCI slot
85 * @bus: number of PCI bus on which desired PCI device resides
86 * @devfn: encodes number of PCI slot in which the desired PCI
87 * device resides and the logical device number within that slot
88 * in case of multi-function devices.
89 *
90 * Given a PCI bus and slot/function number, the desired PCI device
91 * is located in system global list of PCI devices. If the device
92 * is found, a pointer to its data structure is returned. If no
93 * device is found, %NULL is returned.
94 */
95struct pci_dev *
96pci_find_slot(unsigned int bus, unsigned int devfn)
97{
98 struct pci_dev *dev = NULL;
99
100 while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
101 if (dev->bus->number == bus && dev->devfn == devfn)
102 return dev;
103 }
104 return NULL;
105}
106
107/**
108 * pci_get_slot - locate PCI device for a given PCI slot
109 * @bus: PCI bus on which desired PCI device resides
110 * @devfn: encodes number of PCI slot in which the desired PCI
111 * device resides and the logical device number within that slot
112 * in case of multi-function devices.
113 *
114 * Given a PCI bus and slot/function number, the desired PCI device
115 * is located in the list of PCI devices.
116 * If the device is found, its reference count is increased and this
117 * function returns a pointer to its data structure. The caller must
118 * decrement the reference count by calling pci_dev_put().
119 * If no device is found, %NULL is returned.
120 */
121struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn)
122{
123 struct list_head *tmp;
124 struct pci_dev *dev;
125
126 WARN_ON(in_interrupt());
127 spin_lock(&pci_bus_lock);
128
129 list_for_each(tmp, &bus->devices) {
130 dev = pci_dev_b(tmp);
131 if (dev->devfn == devfn)
132 goto out;
133 }
134
135 dev = NULL;
136 out:
137 pci_dev_get(dev);
138 spin_unlock(&pci_bus_lock);
139 return dev;
140}
141
142/**
143 * pci_find_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id
144 * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
145 * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
146 * @ss_vendor: PCI subsystem vendor id to match, or %PCI_ANY_ID to match all vendor ids
147 * @ss_device: PCI subsystem device id to match, or %PCI_ANY_ID to match all device ids
148 * @from: Previous PCI device found in search, or %NULL for new search.
149 *
150 * Iterates through the list of known PCI devices. If a PCI device is
151 * found with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its
152 * device structure is returned. Otherwise, %NULL is returned.
153 * A new search is initiated by passing %NULL to the @from argument.
154 * Otherwise if @from is not %NULL, searches continue from next device on the global list.
155 *
156 * NOTE: Do not use this function anymore, use pci_get_subsys() instead, as
157 * the pci device returned by this function can disappear at any moment in
158 * time.
159 */
160static struct pci_dev * pci_find_subsys(unsigned int vendor,
161 unsigned int device,
162 unsigned int ss_vendor,
163 unsigned int ss_device,
164 const struct pci_dev *from)
165{
166 struct list_head *n;
167 struct pci_dev *dev;
168
169 WARN_ON(in_interrupt());
170 spin_lock(&pci_bus_lock);
171 n = from ? from->global_list.next : pci_devices.next;
172
173 while (n && (n != &pci_devices)) {
174 dev = pci_dev_g(n);
175 if ((vendor == PCI_ANY_ID || dev->vendor == vendor) &&
176 (device == PCI_ANY_ID || dev->device == device) &&
177 (ss_vendor == PCI_ANY_ID || dev->subsystem_vendor == ss_vendor) &&
178 (ss_device == PCI_ANY_ID || dev->subsystem_device == ss_device))
179 goto exit;
180 n = n->next;
181 }
182 dev = NULL;
183exit:
184 spin_unlock(&pci_bus_lock);
185 return dev;
186}
187
188/**
189 * pci_find_device - begin or continue searching for a PCI device by vendor/device id
190 * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
191 * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
192 * @from: Previous PCI device found in search, or %NULL for new search.
193 *
194 * Iterates through the list of known PCI devices. If a PCI device is
195 * found with a matching @vendor and @device, a pointer to its device structure is
196 * returned. Otherwise, %NULL is returned.
197 * A new search is initiated by passing %NULL to the @from argument.
198 * Otherwise if @from is not %NULL, searches continue from next device on the global list.
199 *
200 * NOTE: Do not use this function anymore, use pci_get_device() instead, as
201 * the pci device returned by this function can disappear at any moment in
202 * time.
203 */
204struct pci_dev *
205pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev *from)
206{
207 return pci_find_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from);
208}
209
210/**
211 * pci_get_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id
212 * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
213 * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
214 * @ss_vendor: PCI subsystem vendor id to match, or %PCI_ANY_ID to match all vendor ids
215 * @ss_device: PCI subsystem device id to match, or %PCI_ANY_ID to match all device ids
216 * @from: Previous PCI device found in search, or %NULL for new search.
217 *
218 * Iterates through the list of known PCI devices. If a PCI device is
219 * found with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its
220 * device structure is returned, and the reference count to the device is
221 * incremented. Otherwise, %NULL is returned. A new search is initiated by
222 * passing %NULL to the @from argument. Otherwise if @from is not %NULL,
223 * searches continue from next device on the global list.
224 * The reference count for @from is always decremented if it is not %NULL.
225 */
226struct pci_dev *
227pci_get_subsys(unsigned int vendor, unsigned int device,
228 unsigned int ss_vendor, unsigned int ss_device,
229 struct pci_dev *from)
230{
231 struct list_head *n;
232 struct pci_dev *dev;
233
234 WARN_ON(in_interrupt());
235 spin_lock(&pci_bus_lock);
236 n = from ? from->global_list.next : pci_devices.next;
237
238 while (n && (n != &pci_devices)) {
239 dev = pci_dev_g(n);
240 if ((vendor == PCI_ANY_ID || dev->vendor == vendor) &&
241 (device == PCI_ANY_ID || dev->device == device) &&
242 (ss_vendor == PCI_ANY_ID || dev->subsystem_vendor == ss_vendor) &&
243 (ss_device == PCI_ANY_ID || dev->subsystem_device == ss_device))
244 goto exit;
245 n = n->next;
246 }
247 dev = NULL;
248exit:
249 pci_dev_put(from);
250 dev = pci_dev_get(dev);
251 spin_unlock(&pci_bus_lock);
252 return dev;
253}
254
255/**
256 * pci_get_device - begin or continue searching for a PCI device by vendor/device id
257 * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
258 * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
259 * @from: Previous PCI device found in search, or %NULL for new search.
260 *
261 * Iterates through the list of known PCI devices. If a PCI device is
262 * found with a matching @vendor and @device, the reference count to the
263 * device is incremented and a pointer to its device structure is returned.
264 * Otherwise, %NULL is returned. A new search is initiated by passing %NULL
265 * to the @from argument. Otherwise if @from is not %NULL, searches continue
266 * from next device on the global list. The reference count for @from is
267 * always decremented if it is not %NULL.
268 */
269struct pci_dev *
270pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from)
271{
272 return pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from);
273}
274
275
276/**
277 * pci_find_device_reverse - begin or continue searching for a PCI device by vendor/device id
278 * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
279 * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
280 * @from: Previous PCI device found in search, or %NULL for new search.
281 *
282 * Iterates through the list of known PCI devices in the reverse order of pci_find_device().
283 * If a PCI device is found with a matching @vendor and @device, a pointer to
284 * its device structure is returned. Otherwise, %NULL is returned.
285 * A new search is initiated by passing %NULL to the @from argument.
286 * Otherwise if @from is not %NULL, searches continue from previous device on the global list.
287 */
288struct pci_dev *
289pci_find_device_reverse(unsigned int vendor, unsigned int device, const struct pci_dev *from)
290{
291 struct list_head *n;
292 struct pci_dev *dev;
293
294 WARN_ON(in_interrupt());
295 spin_lock(&pci_bus_lock);
296 n = from ? from->global_list.prev : pci_devices.prev;
297
298 while (n && (n != &pci_devices)) {
299 dev = pci_dev_g(n);
300 if ((vendor == PCI_ANY_ID || dev->vendor == vendor) &&
301 (device == PCI_ANY_ID || dev->device == device))
302 goto exit;
303 n = n->prev;
304 }
305 dev = NULL;
306exit:
307 spin_unlock(&pci_bus_lock);
308 return dev;
309}
310
311/**
312 * pci_get_class - begin or continue searching for a PCI device by class
313 * @class: search for a PCI device with this class designation
314 * @from: Previous PCI device found in search, or %NULL for new search.
315 *
316 * Iterates through the list of known PCI devices. If a PCI device is
317 * found with a matching @class, the reference count to the device is
318 * incremented and a pointer to its device structure is returned.
319 * Otherwise, %NULL is returned.
320 * A new search is initiated by passing %NULL to the @from argument.
321 * Otherwise if @from is not %NULL, searches continue from next device
322 * on the global list. The reference count for @from is always decremented
323 * if it is not %NULL.
324 */
325struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
326{
327 struct list_head *n;
328 struct pci_dev *dev;
329
330 WARN_ON(in_interrupt());
331 spin_lock(&pci_bus_lock);
332 n = from ? from->global_list.next : pci_devices.next;
333
334 while (n && (n != &pci_devices)) {
335 dev = pci_dev_g(n);
336 if (dev->class == class)
337 goto exit;
338 n = n->next;
339 }
340 dev = NULL;
341exit:
342 pci_dev_put(from);
343 dev = pci_dev_get(dev);
344 spin_unlock(&pci_bus_lock);
345 return dev;
346}
347
348/**
349 * pci_dev_present - Returns 1 if device matching the device list is present, 0 if not.
350 * @ids: A pointer to a null terminated list of struct pci_device_id structures
351 * that describe the type of PCI device the caller is trying to find.
352 *
353 * Obvious fact: You do not have a reference to any device that might be found
354 * by this function, so if that device is removed from the system right after
355 * this function is finished, the value will be stale. Use this function to
356 * find devices that are usually built into a system, or for a general hint as
357 * to if another device happens to be present at this specific moment in time.
358 */
359int pci_dev_present(const struct pci_device_id *ids)
360{
361 struct pci_dev *dev;
362 int found = 0;
363
364 WARN_ON(in_interrupt());
365 spin_lock(&pci_bus_lock);
366 while (ids->vendor || ids->subvendor || ids->class_mask) {
367 list_for_each_entry(dev, &pci_devices, global_list) {
368 if (pci_match_one_device(ids, dev)) {
369 found = 1;
370 goto exit;
371 }
372 }
373 ids++;
374 }
375exit:
376 spin_unlock(&pci_bus_lock);
377 return found;
378}
379EXPORT_SYMBOL(pci_dev_present);
380
381EXPORT_SYMBOL(pci_find_bus);
382EXPORT_SYMBOL(pci_find_device);
383EXPORT_SYMBOL(pci_find_device_reverse);
384EXPORT_SYMBOL(pci_find_slot);
385EXPORT_SYMBOL(pci_get_device);
386EXPORT_SYMBOL(pci_get_subsys);
387EXPORT_SYMBOL(pci_get_slot);
388EXPORT_SYMBOL(pci_get_class);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
new file mode 100644
index 000000000000..1ba84be0b4c0
--- /dev/null
+++ b/drivers/pci/setup-bus.c
@@ -0,0 +1,552 @@
1/*
2 * drivers/pci/setup-bus.c
3 *
4 * Extruded from code written by
5 * Dave Rusling (david.rusling@reo.mts.dec.com)
6 * David Mosberger (davidm@cs.arizona.edu)
7 * David Miller (davem@redhat.com)
8 *
9 * Support routines for initializing a PCI subsystem.
10 */
11
12/*
13 * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
14 * PCI-PCI bridges cleanup, sorted resource allocation.
15 * Feb 2002, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
16 * Converted to allocation in 3 passes, which gives
17 * tighter packing. Prefetchable range support.
18 */
19
20#include <linux/init.h>
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/pci.h>
24#include <linux/errno.h>
25#include <linux/ioport.h>
26#include <linux/cache.h>
27#include <linux/slab.h>
28
29
30#define DEBUG_CONFIG 1
31#if DEBUG_CONFIG
32#define DBG(x...) printk(x)
33#else
34#define DBG(x...)
35#endif
36
37#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1))
38
39/*
40 * FIXME: IO should be max 256 bytes. However, since we may
41 * have a P2P bridge below a cardbus bridge, we need 4K.
42 */
43#define CARDBUS_IO_SIZE (4096)
44#define CARDBUS_MEM_SIZE (32*1024*1024)
45
46static void __devinit
47pbus_assign_resources_sorted(struct pci_bus *bus)
48{
49 struct pci_dev *dev;
50 struct resource *res;
51 struct resource_list head, *list, *tmp;
52 int idx;
53
54 bus->bridge_ctl &= ~PCI_BRIDGE_CTL_VGA;
55
56 head.next = NULL;
57 list_for_each_entry(dev, &bus->devices, bus_list) {
58 u16 class = dev->class >> 8;
59
60 /* Don't touch classless devices and host bridges. */
61 if (class == PCI_CLASS_NOT_DEFINED ||
62 class == PCI_CLASS_BRIDGE_HOST)
63 continue;
64
65 if (class == PCI_CLASS_DISPLAY_VGA ||
66 class == PCI_CLASS_NOT_DEFINED_VGA)
67 bus->bridge_ctl |= PCI_BRIDGE_CTL_VGA;
68
69 pdev_sort_resources(dev, &head);
70 }
71
72 for (list = head.next; list;) {
73 res = list->res;
74 idx = res - &list->dev->resource[0];
75 pci_assign_resource(list->dev, idx);
76 tmp = list;
77 list = list->next;
78 kfree(tmp);
79 }
80}
81
82static void __devinit
83pci_setup_cardbus(struct pci_bus *bus)
84{
85 struct pci_dev *bridge = bus->self;
86 struct pci_bus_region region;
87
88 printk("PCI: Bus %d, cardbus bridge: %s\n",
89 bus->number, pci_name(bridge));
90
91 pcibios_resource_to_bus(bridge, &region, bus->resource[0]);
92 if (bus->resource[0]->flags & IORESOURCE_IO) {
93 /*
94 * The IO resource is allocated a range twice as large as it
95 * would normally need. This allows us to set both IO regs.
96 */
97 printk(" IO window: %08lx-%08lx\n",
98 region.start, region.end);
99 pci_write_config_dword(bridge, PCI_CB_IO_BASE_0,
100 region.start);
101 pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0,
102 region.end);
103 }
104
105 pcibios_resource_to_bus(bridge, &region, bus->resource[1]);
106 if (bus->resource[1]->flags & IORESOURCE_IO) {
107 printk(" IO window: %08lx-%08lx\n",
108 region.start, region.end);
109 pci_write_config_dword(bridge, PCI_CB_IO_BASE_1,
110 region.start);
111 pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1,
112 region.end);
113 }
114
115 pcibios_resource_to_bus(bridge, &region, bus->resource[2]);
116 if (bus->resource[2]->flags & IORESOURCE_MEM) {
117 printk(" PREFETCH window: %08lx-%08lx\n",
118 region.start, region.end);
119 pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0,
120 region.start);
121 pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0,
122 region.end);
123 }
124
125 pcibios_resource_to_bus(bridge, &region, bus->resource[3]);
126 if (bus->resource[3]->flags & IORESOURCE_MEM) {
127 printk(" MEM window: %08lx-%08lx\n",
128 region.start, region.end);
129 pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1,
130 region.start);
131 pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1,
132 region.end);
133 }
134}
135
136/* Initialize bridges with base/limit values we have collected.
137 PCI-to-PCI Bridge Architecture Specification rev. 1.1 (1998)
138 requires that if there is no I/O ports or memory behind the
139 bridge, corresponding range must be turned off by writing base
140 value greater than limit to the bridge's base/limit registers.
141
142 Note: care must be taken when updating I/O base/limit registers
143 of bridges which support 32-bit I/O. This update requires two
144 config space writes, so it's quite possible that an I/O window of
145 the bridge will have some undesirable address (e.g. 0) after the
146 first write. Ditto 64-bit prefetchable MMIO. */
147static void __devinit
148pci_setup_bridge(struct pci_bus *bus)
149{
150 struct pci_dev *bridge = bus->self;
151 struct pci_bus_region region;
152 u32 l, io_upper16;
153
154 DBG(KERN_INFO "PCI: Bridge: %s\n", pci_name(bridge));
155
156 /* Set up the top and bottom of the PCI I/O segment for this bus. */
157 pcibios_resource_to_bus(bridge, &region, bus->resource[0]);
158 if (bus->resource[0]->flags & IORESOURCE_IO) {
159 pci_read_config_dword(bridge, PCI_IO_BASE, &l);
160 l &= 0xffff0000;
161 l |= (region.start >> 8) & 0x00f0;
162 l |= region.end & 0xf000;
163 /* Set up upper 16 bits of I/O base/limit. */
164 io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
165 DBG(KERN_INFO " IO window: %04lx-%04lx\n",
166 region.start, region.end);
167 }
168 else {
169 /* Clear upper 16 bits of I/O base/limit. */
170 io_upper16 = 0;
171 l = 0x00f0;
172 DBG(KERN_INFO " IO window: disabled.\n");
173 }
174 /* Temporarily disable the I/O range before updating PCI_IO_BASE. */
175 pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff);
176 /* Update lower 16 bits of I/O base/limit. */
177 pci_write_config_dword(bridge, PCI_IO_BASE, l);
178 /* Update upper 16 bits of I/O base/limit. */
179 pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, io_upper16);
180
181 /* Set up the top and bottom of the PCI Memory segment
182 for this bus. */
183 pcibios_resource_to_bus(bridge, &region, bus->resource[1]);
184 if (bus->resource[1]->flags & IORESOURCE_MEM) {
185 l = (region.start >> 16) & 0xfff0;
186 l |= region.end & 0xfff00000;
187 DBG(KERN_INFO " MEM window: %08lx-%08lx\n",
188 region.start, region.end);
189 }
190 else {
191 l = 0x0000fff0;
192 DBG(KERN_INFO " MEM window: disabled.\n");
193 }
194 pci_write_config_dword(bridge, PCI_MEMORY_BASE, l);
195
196 /* Clear out the upper 32 bits of PREF limit.
197 If PCI_PREF_BASE_UPPER32 was non-zero, this temporarily
198 disables PREF range, which is ok. */
199 pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
200
201 /* Set up PREF base/limit. */
202 pcibios_resource_to_bus(bridge, &region, bus->resource[2]);
203 if (bus->resource[2]->flags & IORESOURCE_PREFETCH) {
204 l = (region.start >> 16) & 0xfff0;
205 l |= region.end & 0xfff00000;
206 DBG(KERN_INFO " PREFETCH window: %08lx-%08lx\n",
207 region.start, region.end);
208 }
209 else {
210 l = 0x0000fff0;
211 DBG(KERN_INFO " PREFETCH window: disabled.\n");
212 }
213 pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
214
215 /* Clear out the upper 32 bits of PREF base. */
216 pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0);
217
218 pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl);
219}
220
221/* Check whether the bridge supports optional I/O and
222 prefetchable memory ranges. If not, the respective
223 base/limit registers must be read-only and read as 0. */
224static void __devinit
225pci_bridge_check_ranges(struct pci_bus *bus)
226{
227 u16 io;
228 u32 pmem;
229 struct pci_dev *bridge = bus->self;
230 struct resource *b_res;
231
232 b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
233 b_res[1].flags |= IORESOURCE_MEM;
234
235 pci_read_config_word(bridge, PCI_IO_BASE, &io);
236 if (!io) {
237 pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0);
238 pci_read_config_word(bridge, PCI_IO_BASE, &io);
239 pci_write_config_word(bridge, PCI_IO_BASE, 0x0);
240 }
241 if (io)
242 b_res[0].flags |= IORESOURCE_IO;
243 /* DECchip 21050 pass 2 errata: the bridge may miss an address
244 disconnect boundary by one PCI data phase.
245 Workaround: do not use prefetching on this device. */
246 if (bridge->vendor == PCI_VENDOR_ID_DEC && bridge->device == 0x0001)
247 return;
248 pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
249 if (!pmem) {
250 pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE,
251 0xfff0fff0);
252 pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
253 pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0);
254 }
255 if (pmem)
256 b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
257}
258
259/* Helper function for sizing routines: find first available
260 bus resource of a given type. Note: we intentionally skip
261 the bus resources which have already been assigned (that is,
262 have non-NULL parent resource). */
263static struct resource * __devinit
264find_free_bus_resource(struct pci_bus *bus, unsigned long type)
265{
266 int i;
267 struct resource *r;
268 unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
269 IORESOURCE_PREFETCH;
270
271 for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
272 r = bus->resource[i];
273 if (r && (r->flags & type_mask) == type && !r->parent)
274 return r;
275 }
276 return NULL;
277}
278
279/* Sizing the IO windows of the PCI-PCI bridge is trivial,
280 since these windows have 4K granularity and the IO ranges
281 of non-bridge PCI devices are limited to 256 bytes.
282 We must be careful with the ISA aliasing though. */
283static void __devinit
284pbus_size_io(struct pci_bus *bus)
285{
286 struct pci_dev *dev;
287 struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
288 unsigned long size = 0, size1 = 0;
289
290 if (!b_res)
291 return;
292
293 list_for_each_entry(dev, &bus->devices, bus_list) {
294 int i;
295
296 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
297 struct resource *r = &dev->resource[i];
298 unsigned long r_size;
299
300 if (r->parent || !(r->flags & IORESOURCE_IO))
301 continue;
302 r_size = r->end - r->start + 1;
303
304 if (r_size < 0x400)
305 /* Might be re-aligned for ISA */
306 size += r_size;
307 else
308 size1 += r_size;
309 }
310 }
311/* To be fixed in 2.5: we should have sort of HAVE_ISA
312 flag in the struct pci_bus. */
313#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
314 size = (size & 0xff) + ((size & ~0xffUL) << 2);
315#endif
316 size = ROUND_UP(size + size1, 4096);
317 if (!size) {
318 b_res->flags = 0;
319 return;
320 }
321 /* Alignment of the IO window is always 4K */
322 b_res->start = 4096;
323 b_res->end = b_res->start + size - 1;
324}
325
326/* Calculate the size of the bus and minimal alignment which
327 guarantees that all child resources fit in this size. */
328static int __devinit
329pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
330{
331 struct pci_dev *dev;
332 unsigned long min_align, align, size;
333 unsigned long aligns[12]; /* Alignments from 1Mb to 2Gb */
334 int order, max_order;
335 struct resource *b_res = find_free_bus_resource(bus, type);
336
337 if (!b_res)
338 return 0;
339
340 memset(aligns, 0, sizeof(aligns));
341 max_order = 0;
342 size = 0;
343
344 list_for_each_entry(dev, &bus->devices, bus_list) {
345 int i;
346
347 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
348 struct resource *r = &dev->resource[i];
349 unsigned long r_size;
350
351 if (r->parent || (r->flags & mask) != type)
352 continue;
353 r_size = r->end - r->start + 1;
354 /* For bridges size != alignment */
355 align = (i < PCI_BRIDGE_RESOURCES) ? r_size : r->start;
356 order = __ffs(align) - 20;
357 if (order > 11) {
358 printk(KERN_WARNING "PCI: region %s/%d "
359 "too large: %lx-%lx\n",
360 pci_name(dev), i, r->start, r->end);
361 r->flags = 0;
362 continue;
363 }
364 size += r_size;
365 if (order < 0)
366 order = 0;
367 /* Exclude ranges with size > align from
368 calculation of the alignment. */
369 if (r_size == align)
370 aligns[order] += align;
371 if (order > max_order)
372 max_order = order;
373 }
374 }
375
376 align = 0;
377 min_align = 0;
378 for (order = 0; order <= max_order; order++) {
379 unsigned long align1 = 1UL << (order + 20);
380
381 if (!align)
382 min_align = align1;
383 else if (ROUND_UP(align + min_align, min_align) < align1)
384 min_align = align1 >> 1;
385 align += aligns[order];
386 }
387 size = ROUND_UP(size, min_align);
388 if (!size) {
389 b_res->flags = 0;
390 return 1;
391 }
392 b_res->start = min_align;
393 b_res->end = size + min_align - 1;
394 return 1;
395}
396
397static void __devinit
398pci_bus_size_cardbus(struct pci_bus *bus)
399{
400 struct pci_dev *bridge = bus->self;
401 struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
402 u16 ctrl;
403
404 /*
405 * Reserve some resources for CardBus. We reserve
406 * a fixed amount of bus space for CardBus bridges.
407 */
408 b_res[0].start = CARDBUS_IO_SIZE;
409 b_res[0].end = b_res[0].start + CARDBUS_IO_SIZE - 1;
410 b_res[0].flags |= IORESOURCE_IO;
411
412 b_res[1].start = CARDBUS_IO_SIZE;
413 b_res[1].end = b_res[1].start + CARDBUS_IO_SIZE - 1;
414 b_res[1].flags |= IORESOURCE_IO;
415
416 /*
417 * Check whether prefetchable memory is supported
418 * by this bridge.
419 */
420 pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl);
421 if (!(ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0)) {
422 ctrl |= PCI_CB_BRIDGE_CTL_PREFETCH_MEM0;
423 pci_write_config_word(bridge, PCI_CB_BRIDGE_CONTROL, ctrl);
424 pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl);
425 }
426
427 /*
428 * If we have prefetchable memory support, allocate
429 * two regions. Otherwise, allocate one region of
430 * twice the size.
431 */
432 if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) {
433 b_res[2].start = CARDBUS_MEM_SIZE;
434 b_res[2].end = b_res[2].start + CARDBUS_MEM_SIZE - 1;
435 b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
436
437 b_res[3].start = CARDBUS_MEM_SIZE;
438 b_res[3].end = b_res[3].start + CARDBUS_MEM_SIZE - 1;
439 b_res[3].flags |= IORESOURCE_MEM;
440 } else {
441 b_res[3].start = CARDBUS_MEM_SIZE * 2;
442 b_res[3].end = b_res[3].start + CARDBUS_MEM_SIZE * 2 - 1;
443 b_res[3].flags |= IORESOURCE_MEM;
444 }
445}
446
447void __devinit
448pci_bus_size_bridges(struct pci_bus *bus)
449{
450 struct pci_dev *dev;
451 unsigned long mask, prefmask;
452
453 list_for_each_entry(dev, &bus->devices, bus_list) {
454 struct pci_bus *b = dev->subordinate;
455 if (!b)
456 continue;
457
458 switch (dev->class >> 8) {
459 case PCI_CLASS_BRIDGE_CARDBUS:
460 pci_bus_size_cardbus(b);
461 break;
462
463 case PCI_CLASS_BRIDGE_PCI:
464 default:
465 pci_bus_size_bridges(b);
466 break;
467 }
468 }
469
470 /* The root bus? */
471 if (!bus->self)
472 return;
473
474 switch (bus->self->class >> 8) {
475 case PCI_CLASS_BRIDGE_CARDBUS:
476 /* don't size cardbuses yet. */
477 break;
478
479 case PCI_CLASS_BRIDGE_PCI:
480 pci_bridge_check_ranges(bus);
481 default:
482 pbus_size_io(bus);
483 /* If the bridge supports prefetchable range, size it
484 separately. If it doesn't, or its prefetchable window
485 has already been allocated by arch code, try
486 non-prefetchable range for both types of PCI memory
487 resources. */
488 mask = IORESOURCE_MEM;
489 prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH;
490 if (pbus_size_mem(bus, prefmask, prefmask))
491 mask = prefmask; /* Success, size non-prefetch only. */
492 pbus_size_mem(bus, mask, IORESOURCE_MEM);
493 break;
494 }
495}
496EXPORT_SYMBOL(pci_bus_size_bridges);
497
498void __devinit
499pci_bus_assign_resources(struct pci_bus *bus)
500{
501 struct pci_bus *b;
502 struct pci_dev *dev;
503
504 pbus_assign_resources_sorted(bus);
505
506 if (bus->bridge_ctl & PCI_BRIDGE_CTL_VGA) {
507 /* Propagate presence of the VGA to upstream bridges */
508 for (b = bus; b->parent; b = b->parent) {
509 b->bridge_ctl |= PCI_BRIDGE_CTL_VGA;
510 }
511 }
512 list_for_each_entry(dev, &bus->devices, bus_list) {
513 b = dev->subordinate;
514 if (!b)
515 continue;
516
517 pci_bus_assign_resources(b);
518
519 switch (dev->class >> 8) {
520 case PCI_CLASS_BRIDGE_PCI:
521 pci_setup_bridge(b);
522 break;
523
524 case PCI_CLASS_BRIDGE_CARDBUS:
525 pci_setup_cardbus(b);
526 break;
527
528 default:
529 printk(KERN_INFO "PCI: not setting up bridge %s "
530 "for bus %d\n", pci_name(dev), b->number);
531 break;
532 }
533 }
534}
535EXPORT_SYMBOL(pci_bus_assign_resources);
536
537void __init
538pci_assign_unassigned_resources(void)
539{
540 struct pci_bus *bus;
541
542 /* Depth first, calculate sizes and alignments of all
543 subordinate buses. */
544 list_for_each_entry(bus, &pci_root_buses, node) {
545 pci_bus_size_bridges(bus);
546 }
547 /* Depth last, allocate resources and update the hardware. */
548 list_for_each_entry(bus, &pci_root_buses, node) {
549 pci_bus_assign_resources(bus);
550 pci_enable_bridges(bus);
551 }
552}
diff --git a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c
new file mode 100644
index 000000000000..a251289c9958
--- /dev/null
+++ b/drivers/pci/setup-irq.c
@@ -0,0 +1,64 @@
1/*
2 * drivers/pci/setup-irq.c
3 *
4 * Extruded from code written by
5 * Dave Rusling (david.rusling@reo.mts.dec.com)
6 * David Mosberger (davidm@cs.arizona.edu)
7 * David Miller (davem@redhat.com)
8 *
9 * Support routines for initializing a PCI subsystem.
10 */
11
12
13#include <linux/init.h>
14#include <linux/kernel.h>
15#include <linux/pci.h>
16#include <linux/errno.h>
17#include <linux/ioport.h>
18#include <linux/cache.h>
19
20
21static void __init
22pdev_fixup_irq(struct pci_dev *dev,
23 u8 (*swizzle)(struct pci_dev *, u8 *),
24 int (*map_irq)(struct pci_dev *, u8, u8))
25{
26 u8 pin, slot;
27 int irq;
28
29 /* If this device is not on the primary bus, we need to figure out
30 which interrupt pin it will come in on. We know which slot it
31 will come in on 'cos that slot is where the bridge is. Each
32 time the interrupt line passes through a PCI-PCI bridge we must
33 apply the swizzle function. */
34
35 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
36 /* Cope with 0 and illegal. */
37 if (pin == 0 || pin > 4)
38 pin = 1;
39
40 /* Follow the chain of bridges, swizzling as we go. */
41 slot = (*swizzle)(dev, &pin);
42
43 irq = (*map_irq)(dev, slot, pin);
44 if (irq == -1)
45 irq = 0;
46 dev->irq = irq;
47
48 pr_debug("PCI: fixup irq: (%s) got %d\n",
49 dev->dev.kobj.name, dev->irq);
50
51 /* Always tell the device, so the driver knows what is
52 the real IRQ to use; the device does not use it. */
53 pcibios_update_irq(dev, irq);
54}
55
56void __init
57pci_fixup_irqs(u8 (*swizzle)(struct pci_dev *, u8 *),
58 int (*map_irq)(struct pci_dev *, u8, u8))
59{
60 struct pci_dev *dev = NULL;
61 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
62 pdev_fixup_irq(dev, swizzle, map_irq);
63 }
64}
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
new file mode 100644
index 000000000000..1ca21d2ba11c
--- /dev/null
+++ b/drivers/pci/setup-res.c
@@ -0,0 +1,200 @@
1/*
2 * drivers/pci/setup-res.c
3 *
4 * Extruded from code written by
5 * Dave Rusling (david.rusling@reo.mts.dec.com)
6 * David Mosberger (davidm@cs.arizona.edu)
7 * David Miller (davem@redhat.com)
8 *
9 * Support routines for initializing a PCI subsystem.
10 */
11
12/* fixed for multiple pci buses, 1999 Andrea Arcangeli <andrea@suse.de> */
13
14/*
15 * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
16 * Resource sorting
17 */
18
19#include <linux/init.h>
20#include <linux/kernel.h>
21#include <linux/pci.h>
22#include <linux/errno.h>
23#include <linux/ioport.h>
24#include <linux/cache.h>
25#include <linux/slab.h>
26#include "pci.h"
27
28
29static void
30pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
31{
32 struct pci_bus_region region;
33 u32 new, check, mask;
34 int reg;
35
36 pcibios_resource_to_bus(dev, &region, res);
37
38 pr_debug(" got res [%lx:%lx] bus [%lx:%lx] flags %lx for "
39 "BAR %d of %s\n", res->start, res->end,
40 region.start, region.end, res->flags, resno, pci_name(dev));
41
42 new = region.start | (res->flags & PCI_REGION_FLAG_MASK);
43 if (res->flags & IORESOURCE_IO)
44 mask = (u32)PCI_BASE_ADDRESS_IO_MASK;
45 else
46 mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
47
48 if (resno < 6) {
49 reg = PCI_BASE_ADDRESS_0 + 4 * resno;
50 } else if (resno == PCI_ROM_RESOURCE) {
51 new |= res->flags & IORESOURCE_ROM_ENABLE;
52 reg = dev->rom_base_reg;
53 } else {
54 /* Hmm, non-standard resource. */
55
56 return; /* kill uninitialised var warning */
57 }
58
59 pci_write_config_dword(dev, reg, new);
60 pci_read_config_dword(dev, reg, &check);
61
62 if ((new ^ check) & mask) {
63 printk(KERN_ERR "PCI: Error while updating region "
64 "%s/%d (%08x != %08x)\n", pci_name(dev), resno,
65 new, check);
66 }
67
68 if ((new & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) ==
69 (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64)) {
70 new = 0; /* currently everyone zeros the high address */
71 pci_write_config_dword(dev, reg + 4, new);
72 pci_read_config_dword(dev, reg + 4, &check);
73 if (check != new) {
74 printk(KERN_ERR "PCI: Error updating region "
75 "%s/%d (high %08x != %08x)\n",
76 pci_name(dev), resno, new, check);
77 }
78 }
79 res->flags &= ~IORESOURCE_UNSET;
80 pr_debug("PCI: moved device %s resource %d (%lx) to %x\n",
81 pci_name(dev), resno, res->flags,
82 new & ~PCI_REGION_FLAG_MASK);
83}
84
85int __devinit
86pci_claim_resource(struct pci_dev *dev, int resource)
87{
88 struct resource *res = &dev->resource[resource];
89 struct resource *root = NULL;
90 char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge";
91 int err;
92
93 if (res->flags & IORESOURCE_IO)
94 root = &ioport_resource;
95 if (res->flags & IORESOURCE_MEM)
96 root = &iomem_resource;
97
98 err = -EINVAL;
99 if (root != NULL)
100 err = insert_resource(root, res);
101
102 if (err) {
103 printk(KERN_ERR "PCI: %s region %d of %s %s [%lx:%lx]\n",
104 root ? "Address space collision on" :
105 "No parent found for",
106 resource, dtype, pci_name(dev), res->start, res->end);
107 }
108
109 return err;
110}
111
112int pci_assign_resource(struct pci_dev *dev, int resno)
113{
114 struct pci_bus *bus = dev->bus;
115 struct resource *res = dev->resource + resno;
116 unsigned long size, min, align;
117 int ret;
118
119 size = res->end - res->start + 1;
120 min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
121 /* The bridge resources are special, as their
122 size != alignment. Sizing routines return
123 required alignment in the "start" field. */
124 align = (resno < PCI_BRIDGE_RESOURCES) ? size : res->start;
125
126 /* First, try exact prefetching match.. */
127 ret = pci_bus_alloc_resource(bus, res, size, align, min,
128 IORESOURCE_PREFETCH,
129 pcibios_align_resource, dev);
130
131 if (ret < 0 && (res->flags & IORESOURCE_PREFETCH)) {
132 /*
133 * That failed.
134 *
135 * But a prefetching area can handle a non-prefetching
136 * window (it will just not perform as well).
137 */
138 ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,
139 pcibios_align_resource, dev);
140 }
141
142 if (ret) {
143 printk(KERN_ERR "PCI: Failed to allocate %s resource #%d:%lx@%lx for %s\n",
144 res->flags & IORESOURCE_IO ? "I/O" : "mem",
145 resno, size, res->start, pci_name(dev));
146 } else if (resno < PCI_BRIDGE_RESOURCES) {
147 pci_update_resource(dev, res, resno);
148 }
149
150 return ret;
151}
152
153/* Sort resources by alignment */
154void __devinit
155pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
156{
157 int i;
158
159 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
160 struct resource *r;
161 struct resource_list *list, *tmp;
162 unsigned long r_align;
163
164 r = &dev->resource[i];
165 r_align = r->end - r->start;
166
167 if (!(r->flags) || r->parent)
168 continue;
169 if (!r_align) {
170 printk(KERN_WARNING "PCI: Ignore bogus resource %d "
171 "[%lx:%lx] of %s\n",
172 i, r->start, r->end, pci_name(dev));
173 continue;
174 }
175 r_align = (i < PCI_BRIDGE_RESOURCES) ? r_align + 1 : r->start;
176 for (list = head; ; list = list->next) {
177 unsigned long align = 0;
178 struct resource_list *ln = list->next;
179 int idx;
180
181 if (ln) {
182 idx = ln->res - &ln->dev->resource[0];
183 align = (idx < PCI_BRIDGE_RESOURCES) ?
184 ln->res->end - ln->res->start + 1 :
185 ln->res->start;
186 }
187 if (r_align > align) {
188 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
189 if (!tmp)
190 panic("pdev_sort_resources(): "
191 "kmalloc() failed!\n");
192 tmp->next = ln;
193 tmp->res = r;
194 tmp->dev = dev;
195 list->next = tmp;
196 break;
197 }
198 }
199 }
200}
diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c
new file mode 100644
index 000000000000..c071790cc983
--- /dev/null
+++ b/drivers/pci/syscall.c
@@ -0,0 +1,145 @@
1/*
2 * pci_syscall.c
3 *
4 * For architectures where we want to allow direct access
5 * to the PCI config stuff - it would probably be preferable
6 * on PCs too, but there people just do it by hand with the
7 * magic northbridge registers..
8 */
9
10#include <linux/sched.h>
11#include <linux/errno.h>
12#include <linux/pci.h>
13#include <linux/smp_lock.h>
14#include <linux/syscalls.h>
15#include <asm/uaccess.h>
16
17
18asmlinkage long
19sys_pciconfig_read(unsigned long bus, unsigned long dfn,
20 unsigned long off, unsigned long len,
21 void __user *buf)
22{
23 struct pci_dev *dev;
24 u8 byte;
25 u16 word;
26 u32 dword;
27 long err, cfg_ret;
28
29 err = -EPERM;
30 if (!capable(CAP_SYS_ADMIN))
31 goto error;
32
33 err = -ENODEV;
34 dev = pci_find_slot(bus, dfn);
35 if (!dev)
36 goto error;
37
38 lock_kernel();
39 switch (len) {
40 case 1:
41 cfg_ret = pci_read_config_byte(dev, off, &byte);
42 break;
43 case 2:
44 cfg_ret = pci_read_config_word(dev, off, &word);
45 break;
46 case 4:
47 cfg_ret = pci_read_config_dword(dev, off, &dword);
48 break;
49 default:
50 err = -EINVAL;
51 unlock_kernel();
52 goto error;
53 };
54 unlock_kernel();
55
56 err = -EIO;
57 if (cfg_ret != PCIBIOS_SUCCESSFUL)
58 goto error;
59
60 switch (len) {
61 case 1:
62 err = put_user(byte, (unsigned char __user *)buf);
63 break;
64 case 2:
65 err = put_user(word, (unsigned short __user *)buf);
66 break;
67 case 4:
68 err = put_user(dword, (unsigned int __user *)buf);
69 break;
70 };
71 return err;
72
73error:
74 /* ??? XFree86 doesn't even check the return value. They
75 just look for 0xffffffff in the output, since that's what
76 they get instead of a machine check on x86. */
77 switch (len) {
78 case 1:
79 put_user(-1, (unsigned char __user *)buf);
80 break;
81 case 2:
82 put_user(-1, (unsigned short __user *)buf);
83 break;
84 case 4:
85 put_user(-1, (unsigned int __user *)buf);
86 break;
87 };
88 return err;
89}
90
91asmlinkage long
92sys_pciconfig_write(unsigned long bus, unsigned long dfn,
93 unsigned long off, unsigned long len,
94 void __user *buf)
95{
96 struct pci_dev *dev;
97 u8 byte;
98 u16 word;
99 u32 dword;
100 int err = 0;
101
102 if (!capable(CAP_SYS_ADMIN))
103 return -EPERM;
104
105 dev = pci_find_slot(bus, dfn);
106 if (!dev)
107 return -ENODEV;
108
109 lock_kernel();
110 switch(len) {
111 case 1:
112 err = get_user(byte, (u8 __user *)buf);
113 if (err)
114 break;
115 err = pci_write_config_byte(dev, off, byte);
116 if (err != PCIBIOS_SUCCESSFUL)
117 err = -EIO;
118 break;
119
120 case 2:
121 err = get_user(word, (u16 __user *)buf);
122 if (err)
123 break;
124 err = pci_write_config_word(dev, off, word);
125 if (err != PCIBIOS_SUCCESSFUL)
126 err = -EIO;
127 break;
128
129 case 4:
130 err = get_user(dword, (u32 __user *)buf);
131 if (err)
132 break;
133 err = pci_write_config_dword(dev, off, dword);
134 if (err != PCIBIOS_SUCCESSFUL)
135 err = -EIO;
136 break;
137
138 default:
139 err = -EINVAL;
140 break;
141 };
142 unlock_kernel();
143
144 return err;
145}