Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney...
[linux-2.6] / arch / x86 / pci / direct.c
1 /*
2  * direct.c - Low-level direct PCI config space access
3  */
4
5 #include <linux/pci.h>
6 #include <linux/init.h>
7 #include <linux/dmi.h>
8 #include "pci.h"
9
10 /*
11  * Functions for accessing PCI base (first 256 bytes) and extended
12  * (4096 bytes per PCI function) configuration space with type 1
13  * accesses.
14  */
15
16 #define PCI_CONF1_ADDRESS(bus, devfn, reg) \
17         (0x80000000 | ((reg & 0xF00) << 16) | (bus << 16) \
18         | (devfn << 8) | (reg & 0xFC))
19
20 static int pci_conf1_read(unsigned int seg, unsigned int bus,
21                           unsigned int devfn, int reg, int len, u32 *value)
22 {
23         unsigned long flags;
24
25         if ((bus > 255) || (devfn > 255) || (reg > 4095)) {
26                 *value = -1;
27                 return -EINVAL;
28         }
29
30         spin_lock_irqsave(&pci_config_lock, flags);
31
32         outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8);
33
34         switch (len) {
35         case 1:
36                 *value = inb(0xCFC + (reg & 3));
37                 break;
38         case 2:
39                 *value = inw(0xCFC + (reg & 2));
40                 break;
41         case 4:
42                 *value = inl(0xCFC);
43                 break;
44         }
45
46         spin_unlock_irqrestore(&pci_config_lock, flags);
47
48         return 0;
49 }
50
51 static int pci_conf1_write(unsigned int seg, unsigned int bus,
52                            unsigned int devfn, int reg, int len, u32 value)
53 {
54         unsigned long flags;
55
56         if ((bus > 255) || (devfn > 255) || (reg > 4095))
57                 return -EINVAL;
58
59         spin_lock_irqsave(&pci_config_lock, flags);
60
61         outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8);
62
63         switch (len) {
64         case 1:
65                 outb((u8)value, 0xCFC + (reg & 3));
66                 break;
67         case 2:
68                 outw((u16)value, 0xCFC + (reg & 2));
69                 break;
70         case 4:
71                 outl((u32)value, 0xCFC);
72                 break;
73         }
74
75         spin_unlock_irqrestore(&pci_config_lock, flags);
76
77         return 0;
78 }
79
80 #undef PCI_CONF1_ADDRESS
81
82 struct pci_raw_ops pci_direct_conf1 = {
83         .read =         pci_conf1_read,
84         .write =        pci_conf1_write,
85 };
86
87
88 /*
89  * Functions for accessing PCI configuration space with type 2 accesses
90  */
91
92 #define PCI_CONF2_ADDRESS(dev, reg)     (u16)(0xC000 | (dev << 8) | reg)
93
94 static int pci_conf2_read(unsigned int seg, unsigned int bus,
95                           unsigned int devfn, int reg, int len, u32 *value)
96 {
97         unsigned long flags;
98         int dev, fn;
99
100         if ((bus > 255) || (devfn > 255) || (reg > 255)) {
101                 *value = -1;
102                 return -EINVAL;
103         }
104
105         dev = PCI_SLOT(devfn);
106         fn = PCI_FUNC(devfn);
107
108         if (dev & 0x10) 
109                 return PCIBIOS_DEVICE_NOT_FOUND;
110
111         spin_lock_irqsave(&pci_config_lock, flags);
112
113         outb((u8)(0xF0 | (fn << 1)), 0xCF8);
114         outb((u8)bus, 0xCFA);
115
116         switch (len) {
117         case 1:
118                 *value = inb(PCI_CONF2_ADDRESS(dev, reg));
119                 break;
120         case 2:
121                 *value = inw(PCI_CONF2_ADDRESS(dev, reg));
122                 break;
123         case 4:
124                 *value = inl(PCI_CONF2_ADDRESS(dev, reg));
125                 break;
126         }
127
128         outb(0, 0xCF8);
129
130         spin_unlock_irqrestore(&pci_config_lock, flags);
131
132         return 0;
133 }
134
135 static int pci_conf2_write(unsigned int seg, unsigned int bus,
136                            unsigned int devfn, int reg, int len, u32 value)
137 {
138         unsigned long flags;
139         int dev, fn;
140
141         if ((bus > 255) || (devfn > 255) || (reg > 255)) 
142                 return -EINVAL;
143
144         dev = PCI_SLOT(devfn);
145         fn = PCI_FUNC(devfn);
146
147         if (dev & 0x10) 
148                 return PCIBIOS_DEVICE_NOT_FOUND;
149
150         spin_lock_irqsave(&pci_config_lock, flags);
151
152         outb((u8)(0xF0 | (fn << 1)), 0xCF8);
153         outb((u8)bus, 0xCFA);
154
155         switch (len) {
156         case 1:
157                 outb((u8)value, PCI_CONF2_ADDRESS(dev, reg));
158                 break;
159         case 2:
160                 outw((u16)value, PCI_CONF2_ADDRESS(dev, reg));
161                 break;
162         case 4:
163                 outl((u32)value, PCI_CONF2_ADDRESS(dev, reg));
164                 break;
165         }
166
167         outb(0, 0xCF8);    
168
169         spin_unlock_irqrestore(&pci_config_lock, flags);
170
171         return 0;
172 }
173
174 #undef PCI_CONF2_ADDRESS
175
176 static struct pci_raw_ops pci_direct_conf2 = {
177         .read =         pci_conf2_read,
178         .write =        pci_conf2_write,
179 };
180
181
182 /*
183  * Before we decide to use direct hardware access mechanisms, we try to do some
184  * trivial checks to ensure it at least _seems_ to be working -- we just test
185  * whether bus 00 contains a host bridge (this is similar to checking
186  * techniques used in XFree86, but ours should be more reliable since we
187  * attempt to make use of direct access hints provided by the PCI BIOS).
188  *
189  * This should be close to trivial, but it isn't, because there are buggy
190  * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
191  */
192 static int __init pci_sanity_check(struct pci_raw_ops *o)
193 {
194         u32 x = 0;
195         int devfn;
196
197         if (pci_probe & PCI_NO_CHECKS)
198                 return 1;
199         /* Assume Type 1 works for newer systems.
200            This handles machines that don't have anything on PCI Bus 0. */
201         if (dmi_get_year(DMI_BIOS_DATE) >= 2001)
202                 return 1;
203
204         for (devfn = 0; devfn < 0x100; devfn++) {
205                 if (o->read(0, 0, devfn, PCI_CLASS_DEVICE, 2, &x))
206                         continue;
207                 if (x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)
208                         return 1;
209
210                 if (o->read(0, 0, devfn, PCI_VENDOR_ID, 2, &x))
211                         continue;
212                 if (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ)
213                         return 1;
214         }
215
216         DBG(KERN_WARNING "PCI: Sanity check failed\n");
217         return 0;
218 }
219
220 static int __init pci_check_type1(void)
221 {
222         unsigned long flags;
223         unsigned int tmp;
224         int works = 0;
225
226         local_irq_save(flags);
227
228         outb(0x01, 0xCFB);
229         tmp = inl(0xCF8);
230         outl(0x80000000, 0xCF8);
231         if (inl(0xCF8) == 0x80000000 && pci_sanity_check(&pci_direct_conf1)) {
232                 works = 1;
233         }
234         outl(tmp, 0xCF8);
235         local_irq_restore(flags);
236
237         return works;
238 }
239
240 static int __init pci_check_type2(void)
241 {
242         unsigned long flags;
243         int works = 0;
244
245         local_irq_save(flags);
246
247         outb(0x00, 0xCFB);
248         outb(0x00, 0xCF8);
249         outb(0x00, 0xCFA);
250         if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00 &&
251             pci_sanity_check(&pci_direct_conf2)) {
252                 works = 1;
253         }
254
255         local_irq_restore(flags);
256
257         return works;
258 }
259
260 void __init pci_direct_init(int type)
261 {
262         if (type == 0)
263                 return;
264         printk(KERN_INFO "PCI: Using configuration type %d for base access\n",
265                  type);
266         if (type == 1) {
267                 raw_pci_ops = &pci_direct_conf1;
268                 if (raw_pci_ext_ops)
269                         return;
270                 if (!(pci_probe & PCI_HAS_IO_ECS))
271                         return;
272                 printk(KERN_INFO "PCI: Using configuration type 1 "
273                        "for extended access\n");
274                 raw_pci_ext_ops = &pci_direct_conf1;
275                 return;
276         }
277         raw_pci_ops = &pci_direct_conf2;
278 }
279
280 int __init pci_direct_probe(void)
281 {
282         struct resource *region, *region2;
283
284         if ((pci_probe & PCI_PROBE_CONF1) == 0)
285                 goto type2;
286         region = request_region(0xCF8, 8, "PCI conf1");
287         if (!region)
288                 goto type2;
289
290         if (pci_check_type1()) {
291                 raw_pci_ops = &pci_direct_conf1;
292                 return 1;
293         }
294         release_resource(region);
295
296  type2:
297         if ((pci_probe & PCI_PROBE_CONF2) == 0)
298                 return 0;
299         region = request_region(0xCF8, 4, "PCI conf2");
300         if (!region)
301                 return 0;
302         region2 = request_region(0xC000, 0x1000, "PCI conf2");
303         if (!region2)
304                 goto fail2;
305
306         if (pci_check_type2()) {
307                 raw_pci_ops = &pci_direct_conf2;
308                 return 2;
309         }
310
311         release_resource(region2);
312  fail2:
313         release_resource(region);
314         return 0;
315 }