Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
428 | 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 <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 | |||
16 | struct pci_device_info { |
||
17 | unsigned short device; |
||
18 | unsigned short seen; |
||
19 | const char *name; |
||
20 | }; |
||
21 | |||
22 | struct 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 | |||
46 | static 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 | |||
55 | void __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, "%." PCI_NAME_HALF |
||
90 | "s %." PCI_NAME_HALF "s", |
||
91 | vendor_p->name, device_p->name); |
||
92 | int nr = device_p->seen + 1; |
||
93 | device_p->seen = nr; |
||
94 | if (nr > 1) |
||
95 | sprintf(n, " (#%d)", nr); |
||
96 | } |
||
97 | } |
||
98 | } |
||
99 | |||
100 | /* |
||
101 | * Class names. Not in .init section as they are needed in runtime. |
||
102 | */ |
||
103 | |||
104 | static u16 pci_class_numbers[] = { |
||
105 | #define CLASS(x,y) 0x##x, |
||
106 | #include "classlist.h" |
||
107 | }; |
||
108 | |||
109 | static char *pci_class_names[] = { |
||
110 | #define CLASS(x,y) y, |
||
111 | #include "classlist.h" |
||
112 | }; |
||
113 | |||
114 | char * |
||
115 | pci_class_name(u32 class) |
||
116 | { |
||
117 | int i; |
||
118 | |||
119 | for(i=0; i<sizeof(pci_class_numbers)/sizeof(pci_class_numbers[0]); i++) |
||
120 | if (pci_class_numbers[i] == class) |
||
121 | return pci_class_names[i]; |
||
122 | return NULL; |
||
123 | } |
||
124 | |||
125 | #else |
||
126 | |||
127 | void __devinit pci_name_device(struct pci_dev *dev) |
||
128 | { |
||
129 | } |
||
130 | |||
131 | char * |
||
132 | pci_class_name(u32 class) |
||
133 | { |
||
134 | return NULL; |
||
135 | } |
||
136 | |||
137 | #endif /* CONFIG_PCI_NAMES */ |
||
138 |