Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
587 | giacomo | 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 <linuxcomp.h> |
||
9 | |||
10 | #include <linux/config.h> |
||
11 | #include <linux/types.h> |
||
12 | #include <linux/kernel.h> |
||
13 | #include <linux/pci.h> |
||
14 | #include <linux/init.h> |
||
15 | |||
16 | #ifdef CONFIG_PCI_NAMES |
||
17 | |||
18 | struct pci_device_info { |
||
19 | unsigned short device; |
||
20 | unsigned short seen; |
||
21 | const char *name; |
||
22 | }; |
||
23 | |||
24 | struct pci_vendor_info { |
||
25 | unsigned short vendor; |
||
26 | unsigned short nr; |
||
27 | const char *name; |
||
28 | struct pci_device_info *devices; |
||
29 | }; |
||
30 | |||
31 | /* |
||
32 | * This is ridiculous, but we want the strings in |
||
33 | * the .init section so that they don't take up |
||
34 | * real memory.. Parse the same file multiple times |
||
35 | * to get all the info. |
||
36 | */ |
||
37 | #define VENDOR( vendor, name ) static char __vendorstr_##vendor[] __devinitdata = name; |
||
38 | #define ENDVENDOR() |
||
39 | #define DEVICE( vendor, device, name ) static char __devicestr_##vendor##device[] __devinitdata = name; |
||
40 | #include "devlist.h" |
||
41 | |||
42 | |||
43 | #define VENDOR( vendor, name ) static struct pci_device_info __devices_##vendor[] __devinitdata = { |
||
44 | #define ENDVENDOR() }; |
||
45 | #define DEVICE( vendor, device, name ) { 0x##device, 0, __devicestr_##vendor##device }, |
||
46 | #include "devlist.h" |
||
47 | |||
48 | static struct pci_vendor_info __devinitdata pci_vendor_list[] = { |
||
49 | #define VENDOR( vendor, name ) { 0x##vendor, sizeof(__devices_##vendor) / sizeof(struct pci_device_info), __vendorstr_##vendor, __devices_##vendor }, |
||
50 | #define ENDVENDOR() |
||
51 | #define DEVICE( vendor, device, name ) |
||
52 | #include "devlist.h" |
||
53 | }; |
||
54 | |||
55 | #define VENDORS (sizeof(pci_vendor_list)/sizeof(struct pci_vendor_info)) |
||
56 | |||
57 | void __devinit pci_name_device(struct pci_dev *dev) |
||
58 | { |
||
59 | const struct pci_vendor_info *vendor_p = pci_vendor_list; |
||
60 | int i = VENDORS; |
||
61 | char *name = dev->pretty_name; |
||
62 | |||
63 | do { |
||
64 | if (vendor_p->vendor == dev->vendor) |
||
65 | goto match_vendor; |
||
66 | vendor_p++; |
||
67 | } while (--i); |
||
68 | |||
69 | /* Couldn't find either the vendor nor the device */ |
||
70 | sprintf(name, "PCI device %04x:%04x", dev->vendor, dev->device); |
||
71 | return; |
||
72 | |||
73 | match_vendor: { |
||
74 | struct pci_device_info *device_p = vendor_p->devices; |
||
75 | int i = vendor_p->nr; |
||
76 | |||
77 | while (i > 0) { |
||
78 | if (device_p->device == dev->device) |
||
79 | goto match_device; |
||
80 | device_p++; |
||
81 | i--; |
||
82 | } |
||
83 | |||
84 | /* Ok, found the vendor, but unknown device */ |
||
85 | sprintf(name, "PCI device %04x:%04x (%." PCI_NAME_HALF "s)", |
||
86 | dev->vendor, dev->device, vendor_p->name); |
||
87 | return; |
||
88 | |||
89 | /* Full match */ |
||
90 | match_device: { |
||
91 | char *n = name + sprintf(name, "%." PCI_NAME_HALF |
||
92 | "s %." PCI_NAME_HALF "s", |
||
93 | vendor_p->name, device_p->name); |
||
94 | int nr = device_p->seen + 1; |
||
95 | device_p->seen = nr; |
||
96 | if (nr > 1) |
||
97 | sprintf(n, " (#%d)", nr); |
||
98 | } |
||
99 | } |
||
100 | } |
||
101 | |||
102 | /* |
||
103 | * Class names. Not in .init section as they are needed in runtime. |
||
104 | */ |
||
105 | |||
106 | static u16 pci_class_numbers[] = { |
||
107 | #define CLASS(x,y) 0x##x, |
||
108 | #include "classlist.h" |
||
109 | }; |
||
110 | |||
111 | static char *pci_class_names[] = { |
||
112 | #define CLASS(x,y) y, |
||
113 | #include "classlist.h" |
||
114 | }; |
||
115 | |||
116 | char * |
||
117 | pci_class_name(u32 class) |
||
118 | { |
||
119 | int i; |
||
120 | |||
121 | for(i=0; i<sizeof(pci_class_numbers)/sizeof(pci_class_numbers[0]); i++) |
||
122 | if (pci_class_numbers[i] == class) |
||
123 | return pci_class_names[i]; |
||
124 | return NULL; |
||
125 | } |
||
126 | |||
127 | #else |
||
128 | |||
129 | void __devinit pci_name_device(struct pci_dev *dev) |
||
130 | { |
||
131 | } |
||
132 | |||
133 | char * |
||
134 | pci_class_name(u32 class) |
||
135 | { |
||
136 | return NULL; |
||
137 | } |
||
138 | |||
139 | #endif /* CONFIG_PCI_NAMES */ |
||
140 |