blob: b1651f39228b49162b8ec945931a02dcca1b0cee [file] [log] [blame]
Eric Biederman8ca8d762003-04-22 19:02:15 +00001/*
2 * PCI Bus Services, see include/linux/pci.h for further explanation.
3 *
4 * Copyright 1993 -- 1997 Drew Eckhardt, Frederic Potter,
5 * David Mosberger-Tang
6 *
7 * Copyright 1997 -- 1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
8 *
9 * Copyright 2003 -- Eric Biederman <ebiederman@lnxi.com>
10 */
11
12#include <console/console.h>
13#include <stdlib.h>
14#include <stdint.h>
15#include <bitops.h>
Eric Biederman8ca8d762003-04-22 19:02:15 +000016#include <string.h>
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +000017#include <arch/io.h>
Eric Biederman5899fd82003-04-24 06:25:08 +000018#include <device/device.h>
19#include <device/pci.h>
20#include <device/pci_ids.h>
Eric Biedermane9a271e32003-09-02 03:36:25 +000021#include <part/hard_reset.h>
Eric Biederman30e143a2003-09-01 23:45:32 +000022#include <part/fallback_boot.h>
Eric Biederman03acab62004-10-14 21:25:53 +000023#include <delay.h>
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000024#if CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT == 1
25#include <device/hypertransport.h>
26#endif
27#if CONFIG_PCIX_PLUGIN_SUPPORT == 1
28#include <device/pcix.h>
29#endif
30#if CONFIG_PCIEXP_PLUGIN_SUPPORT == 1
31#include <device/pciexp.h>
32#endif
33#if CONFGI_AGP_PLUGIN_SUPPORT == 1
34#include <device/agp.h>
35#endif
36#if CONFIG_CARDBUS_PLUGIN_SUPPORT == 1
37#include <device/cardbus.h>
38#endif
Eric Biederman03acab62004-10-14 21:25:53 +000039
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000040uint8_t pci_moving_config8(struct device *dev, unsigned reg)
Eric Biederman03acab62004-10-14 21:25:53 +000041{
42 uint8_t value, ones, zeroes;
43 value = pci_read_config8(dev, reg);
44
45 pci_write_config8(dev, reg, 0xff);
46 ones = pci_read_config8(dev, reg);
47
48 pci_write_config8(dev, reg, 0x00);
49 zeroes = pci_read_config8(dev, reg);
50
51 pci_write_config8(dev, reg, value);
52
53 return ones ^ zeroes;
54}
Li-Ta Lo9a5b4962004-12-23 21:48:01 +000055
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000056uint16_t pci_moving_config16(struct device *dev, unsigned reg)
Eric Biederman03acab62004-10-14 21:25:53 +000057{
58 uint16_t value, ones, zeroes;
59 value = pci_read_config16(dev, reg);
60
61 pci_write_config16(dev, reg, 0xffff);
62 ones = pci_read_config16(dev, reg);
63
64 pci_write_config16(dev, reg, 0x0000);
65 zeroes = pci_read_config16(dev, reg);
66
67 pci_write_config16(dev, reg, value);
68
69 return ones ^ zeroes;
70}
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +000071
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000072uint32_t pci_moving_config32(struct device *dev, unsigned reg)
Eric Biederman03acab62004-10-14 21:25:53 +000073{
74 uint32_t value, ones, zeroes;
75 value = pci_read_config32(dev, reg);
76
77 pci_write_config32(dev, reg, 0xffffffff);
78 ones = pci_read_config32(dev, reg);
79
80 pci_write_config32(dev, reg, 0x00000000);
81 zeroes = pci_read_config32(dev, reg);
82
83 pci_write_config32(dev, reg, value);
84
85 return ones ^ zeroes;
86}
87
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000088unsigned pci_find_next_capability(device_t dev, unsigned cap, unsigned last)
Eric Biederman03acab62004-10-14 21:25:53 +000089{
90 unsigned pos;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000091 unsigned status;
92 unsigned reps = 48;
Eric Biederman03acab62004-10-14 21:25:53 +000093 pos = 0;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000094 status = pci_read_config16(dev, PCI_STATUS);
95 if (!(status & PCI_STATUS_CAP_LIST)) {
96 return 0;
97 }
Eric Biederman03acab62004-10-14 21:25:53 +000098 switch(dev->hdr_type & 0x7f) {
99 case PCI_HEADER_TYPE_NORMAL:
100 case PCI_HEADER_TYPE_BRIDGE:
101 pos = PCI_CAPABILITY_LIST;
102 break;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000103 case PCI_HEADER_TYPE_CARDBUS:
104 pos = PCI_CB_CAPABILITY_LIST;
105 break;
106 default:
107 return 0;
Eric Biederman03acab62004-10-14 21:25:53 +0000108 }
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000109 pos = pci_read_config8(dev, pos);
110 while(reps-- && (pos >= 0x40)) { /* loop through the linked list */
Eric Biederman03acab62004-10-14 21:25:53 +0000111 int this_cap;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000112 pos &= ~3;
Eric Biederman03acab62004-10-14 21:25:53 +0000113 this_cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000114 printk_spew("Capability: 0x%02x @ 0x%02x\n", cap, pos);
115 if (this_cap == 0xff) {
116 break;
117 }
118 if (!last && (this_cap == cap)) {
Eric Biederman03acab62004-10-14 21:25:53 +0000119 return pos;
120 }
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000121 if (last == pos) {
122 last = 0;
123 }
124 pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT);
Eric Biederman03acab62004-10-14 21:25:53 +0000125 }
126 return 0;
127}
128
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000129unsigned pci_find_capability(device_t dev, unsigned cap)
130{
131 return pci_find_next_capability(dev, cap, 0);
132
133}
134
Eric Biederman8ca8d762003-04-22 19:02:15 +0000135/** Given a device and register, read the size of the BAR for that register.
136 * @param dev Pointer to the device structure
137 * @param resource Pointer to the resource structure
138 * @param index Address of the pci configuration register
139 */
Eric Biederman03acab62004-10-14 21:25:53 +0000140struct resource *pci_get_resource(struct device *dev, unsigned long index)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000141{
Eric Biederman5cd81732004-03-11 15:01:31 +0000142 struct resource *resource;
Eric Biederman03acab62004-10-14 21:25:53 +0000143 unsigned long value, attr;
144 resource_t moving, limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000145
146 /* Initialize the resources to nothing */
Eric Biederman03acab62004-10-14 21:25:53 +0000147 resource = new_resource(dev, index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000148
Eric Biederman03acab62004-10-14 21:25:53 +0000149 /* Get the initial value */
150 value = pci_read_config32(dev, index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000151
Eric Biederman03acab62004-10-14 21:25:53 +0000152 /* See which bits move */
153 moving = pci_moving_config32(dev, index);
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000154
Eric Biederman03acab62004-10-14 21:25:53 +0000155 /* Initialize attr to the bits that do not move */
156 attr = value & ~moving;
157
158 /* If it is a 64bit resource look at the high half as well */
159 if (((attr & PCI_BASE_ADDRESS_SPACE_IO) == 0) &&
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000160 ((attr & PCI_BASE_ADDRESS_MEM_LIMIT_MASK) == PCI_BASE_ADDRESS_MEM_LIMIT_64))
Eric Biederman03acab62004-10-14 21:25:53 +0000161 {
162 /* Find the high bits that move */
163 moving |= ((resource_t)pci_moving_config32(dev, index + 4)) << 32;
164 }
165 /* Find the resource constraints.
166 *
167 * Start by finding the bits that move. From there:
168 * - Size is the least significant bit of the bits that move.
169 * - Limit is all of the bits that move plus all of the lower bits.
170 * See PCI Spec 6.2.5.1 ...
Eric Biederman8ca8d762003-04-22 19:02:15 +0000171 */
Eric Biederman03acab62004-10-14 21:25:53 +0000172 limit = 0;
173 if (moving) {
174 resource->size = 1;
175 resource->align = resource->gran = 0;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000176 while(!(moving & resource->size)) {
Eric Biederman03acab62004-10-14 21:25:53 +0000177 resource->size <<= 1;
178 resource->align += 1;
179 resource->gran += 1;
180 }
181 resource->limit = limit = moving | (resource->size - 1);
182 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000183 /*
184 * some broken hardware has read-only registers that do not
Eric Biederman03acab62004-10-14 21:25:53 +0000185 * really size correctly.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000186 * Example: the acer m7229 has BARs 1-4 normally read-only.
187 * so BAR1 at offset 0x10 reads 0x1f1. If you size that register
188 * by writing 0xffffffff to it, it will read back as 0x1f1 -- a
189 * violation of the spec.
Eric Biederman03acab62004-10-14 21:25:53 +0000190 * We catch this case and ignore it by observing which bits move,
191 * This also catches the common case unimplemented registers
192 * that always read back as 0.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000193 */
Eric Biederman03acab62004-10-14 21:25:53 +0000194 if (moving == 0) {
195 if (value != 0) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000196 printk_debug(
197 "%s register %02x(%08x), read-only ignoring it\n",
198 dev_path(dev), index, value);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000199 }
200 resource->flags = 0;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000201 }
202 else if (attr & PCI_BASE_ADDRESS_SPACE_IO) {
Eric Biederman03acab62004-10-14 21:25:53 +0000203 /* An I/O mapped base address */
204 attr &= PCI_BASE_ADDRESS_IO_ATTR_MASK;
Eric Biederman5cd81732004-03-11 15:01:31 +0000205 resource->flags |= IORESOURCE_IO;
Eric Biederman03acab62004-10-14 21:25:53 +0000206 /* I don't want to deal with 32bit I/O resources */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000207 resource->limit = 0xffff;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000208 }
209 else {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000210 /* A Memory mapped base address */
Eric Biederman03acab62004-10-14 21:25:53 +0000211 attr &= PCI_BASE_ADDRESS_MEM_ATTR_MASK;
Eric Biederman5cd81732004-03-11 15:01:31 +0000212 resource->flags |= IORESOURCE_MEM;
Eric Biederman03acab62004-10-14 21:25:53 +0000213 if (attr & PCI_BASE_ADDRESS_MEM_PREFETCH) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000214 resource->flags |= IORESOURCE_PREFETCH;
215 }
Eric Biederman03acab62004-10-14 21:25:53 +0000216 attr &= PCI_BASE_ADDRESS_MEM_LIMIT_MASK;
217 if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_32) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000218 /* 32bit limit */
219 resource->limit = 0xffffffffUL;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000220 }
221 else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_1M) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000222 /* 1MB limit */
223 resource->limit = 0x000fffffUL;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000224 }
225 else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_64) {
Eric Biederman03acab62004-10-14 21:25:53 +0000226 /* 64bit limit */
227 resource->limit = 0xffffffffffffffffULL;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000228 resource->flags |= IORESOURCE_PCI64;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000229 }
230 else {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000231 /* Invalid value */
232 resource->flags = 0;
233 }
234 }
Eric Biederman03acab62004-10-14 21:25:53 +0000235 /* Don't let the limit exceed which bits can move */
236 if (resource->limit > limit) {
237 resource->limit = limit;
238 }
239#if 0
240 if (resource->flags) {
241 printk_debug("%s %02x ->",
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000242 dev_path(dev), resource->index);
Eric Biederman03acab62004-10-14 21:25:53 +0000243 printk_debug(" value: 0x%08Lx zeroes: 0x%08Lx ones: 0x%08Lx attr: %08lx\n",
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000244 value, zeroes, ones, attr);
Eric Biederman03acab62004-10-14 21:25:53 +0000245 printk_debug(
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000246 "%s %02x -> size: 0x%08Lx max: 0x%08Lx %s\n ",
Eric Biederman03acab62004-10-14 21:25:53 +0000247 dev_path(dev),
248 resource->index,
249 resource->size, resource->limit,
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000250 resource_type(resource));
Eric Biederman03acab62004-10-14 21:25:53 +0000251 }
252#endif
253
Eric Biederman5cd81732004-03-11 15:01:31 +0000254 return resource;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000255}
256
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000257static void pci_get_rom_resource(struct device *dev, unsigned long index)
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000258{
259 struct resource *resource;
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000260 unsigned long value;
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000261 resource_t moving, limit;
262
Li-Ta Lobec039c2005-01-19 23:19:26 +0000263 if ((dev->on_mainboard) && (dev->rom_address == 0)) {
264 //skip it if rom_address is not set in MB Config.lb
Yinghai Lubcde1612005-01-14 05:34:09 +0000265 return;
266 }
267
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000268 /* Initialize the resources to nothing */
269 resource = new_resource(dev, index);
270
271 /* Get the initial value */
272 value = pci_read_config32(dev, index);
273
274 /* See which bits move */
275 moving = pci_moving_config32(dev, index);
276 /* clear the Enable bit */
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000277 moving = moving & ~PCI_ROM_ADDRESS_ENABLE;
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000278
279 /* Find the resource constraints.
280 *
281 * Start by finding the bits that move. From there:
282 * - Size is the least significant bit of the bits that move.
283 * - Limit is all of the bits that move plus all of the lower bits.
284 * See PCI Spec 6.2.5.1 ...
285 */
286 limit = 0;
287
288 if (moving) {
289 resource->size = 1;
290 resource->align = resource->gran = 0;
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000291 while (!(moving & resource->size)) {
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000292 resource->size <<= 1;
293 resource->align += 1;
294 resource->gran += 1;
295 }
296 resource->limit = limit = moving | (resource->size - 1);
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000297 }
298
299 if (moving == 0) {
300 if (value != 0) {
301 printk_debug("%s register %02x(%08x), read-only ignoring it\n",
302 dev_path(dev), index, value);
303 }
304 resource->flags = 0;
305 } else {
306 resource->flags |= IORESOURCE_MEM | IORESOURCE_READONLY;
307 }
Yinghai Luc7870ac2005-01-13 19:14:52 +0000308
309 /* for on board device with embedded ROM image, the ROM image is at
310 * fixed address specified in the Config.lb, the dev->rom_address is
311 * inited by driver_pci_onboard_ops::enable_dev() */
Yinghai Lubcde1612005-01-14 05:34:09 +0000312 if ((dev->on_mainboard) && (dev->rom_address != 0)) {
Yinghai Luc7870ac2005-01-13 19:14:52 +0000313 resource->base = dev->rom_address;
314 resource->flags |= IORESOURCE_MEM | IORESOURCE_READONLY |
315 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
316 }
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000317
318 compact_resources(dev);
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000319}
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000320
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000321/** Read the base address registers for a given device.
322 * @param dev Pointer to the dev structure
323 * @param howmany How many registers to read (6 for device, 2 for bridge)
324 */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000325static void pci_read_bases(struct device *dev, unsigned int howmany)
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000326{
327 unsigned long index;
328
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000329 for(index = PCI_BASE_ADDRESS_0; (index < PCI_BASE_ADDRESS_0 + (howmany << 2)); ) {
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000330 struct resource *resource;
331 resource = pci_get_resource(dev, index);
332 index += (resource->flags & IORESOURCE_PCI64)?8:4;
333 }
Li-Ta Loe8b1c9d2004-12-27 04:25:41 +0000334
335 compact_resources(dev);
Li-Ta Lo9a5b4962004-12-23 21:48:01 +0000336}
337
Eric Biederman03acab62004-10-14 21:25:53 +0000338static void pci_set_resource(struct device *dev, struct resource *resource);
339
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000340static void pci_record_bridge_resource(
341 struct device *dev, resource_t moving,
342 unsigned index, unsigned long mask, unsigned long type)
Eric Biederman03acab62004-10-14 21:25:53 +0000343{
344 /* Initiliaze the constraints on the current bus */
345 struct resource *resource;
346 resource = 0;
347 if (moving) {
348 unsigned long gran;
349 resource_t step;
350 resource = new_resource(dev, index);
351 resource->size = 0;
352 gran = 0;
353 step = 1;
354 while((moving & step) == 0) {
355 gran += 1;
356 step <<= 1;
357 }
358 resource->gran = gran;
359 resource->align = gran;
360 resource->limit = moving | (step - 1);
361 resource->flags = type | IORESOURCE_PCI_BRIDGE;
362 compute_allocate_resource(&dev->link[0], resource, mask, type);
363 /* If there is nothing behind the resource,
364 * clear it and forget it.
365 */
366 if (resource->size == 0) {
367 resource->base = moving;
368 resource->flags |= IORESOURCE_ASSIGNED;
369 resource->flags &= ~IORESOURCE_STORED;
370 pci_set_resource(dev, resource);
371 resource->flags = 0;
372 }
373 }
374 return;
375}
376
Eric Biederman8ca8d762003-04-22 19:02:15 +0000377static void pci_bridge_read_bases(struct device *dev)
378{
Eric Biederman03acab62004-10-14 21:25:53 +0000379 resource_t moving_base, moving_limit, moving;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000380
Eric Biederman03acab62004-10-14 21:25:53 +0000381 /* See if the bridge I/O resources are implemented */
382 moving_base = ((uint32_t)pci_moving_config8(dev, PCI_IO_BASE)) << 8;
383 moving_base |= ((uint32_t)pci_moving_config16(dev, PCI_IO_BASE_UPPER16)) << 16;
384
385 moving_limit = ((uint32_t)pci_moving_config8(dev, PCI_IO_LIMIT)) << 8;
386 moving_limit |= ((uint32_t)pci_moving_config16(dev, PCI_IO_LIMIT_UPPER16)) << 16;
387
388 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000389
390 /* Initialize the io space constraints on the current bus */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000391 pci_record_bridge_resource(
392 dev, moving, PCI_IO_BASE,
393 IORESOURCE_IO, IORESOURCE_IO);
394
Eric Biederman03acab62004-10-14 21:25:53 +0000395
396 /* See if the bridge prefmem resources are implemented */
397 moving_base = ((resource_t)pci_moving_config16(dev, PCI_PREF_MEMORY_BASE)) << 16;
398 moving_base |= ((resource_t)pci_moving_config32(dev, PCI_PREF_BASE_UPPER32)) << 32;
399
400 moving_limit = ((resource_t)pci_moving_config16(dev, PCI_PREF_MEMORY_LIMIT)) << 16;
401 moving_limit |= ((resource_t)pci_moving_config32(dev, PCI_PREF_LIMIT_UPPER32)) << 32;
402
403 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000404 /* Initiliaze the prefetchable memory constraints on the current bus */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000405 pci_record_bridge_resource(
406 dev, moving, PCI_PREF_MEMORY_BASE,
407 IORESOURCE_MEM | IORESOURCE_PREFETCH,
408 IORESOURCE_MEM | IORESOURCE_PREFETCH);
409
Eric Biederman03acab62004-10-14 21:25:53 +0000410
411 /* See if the bridge mem resources are implemented */
412 moving_base = ((uint32_t)pci_moving_config16(dev, PCI_MEMORY_BASE)) << 16;
413 moving_limit = ((uint32_t)pci_moving_config16(dev, PCI_MEMORY_LIMIT)) << 16;
414
415 moving = moving_base & moving_limit;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000416
417 /* Initialize the memory resources on the current bus */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000418 pci_record_bridge_resource(
419 dev, moving, PCI_MEMORY_BASE,
420 IORESOURCE_MEM | IORESOURCE_PREFETCH,
421 IORESOURCE_MEM);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000422
Eric Biederman5cd81732004-03-11 15:01:31 +0000423 compact_resources(dev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000424}
425
Eric Biederman5899fd82003-04-24 06:25:08 +0000426void pci_dev_read_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000427{
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000428 pci_read_bases(dev, 6);
429 pci_get_rom_resource(dev, PCI_ROM_ADDRESS);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000430}
431
Eric Biederman5899fd82003-04-24 06:25:08 +0000432void pci_bus_read_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000433{
Eric Biederman8ca8d762003-04-22 19:02:15 +0000434 pci_bridge_read_bases(dev);
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000435 pci_read_bases(dev, 2);
436 pci_get_rom_resource(dev, PCI_ROM_ADDRESS1);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000437}
438
Eric Biederman8ca8d762003-04-22 19:02:15 +0000439static void pci_set_resource(struct device *dev, struct resource *resource)
440{
Eric Biederman03acab62004-10-14 21:25:53 +0000441 resource_t base, end;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000442
Eric Biederman8ca8d762003-04-22 19:02:15 +0000443 /* Make certain the resource has actually been set */
Eric Biederman5cd81732004-03-11 15:01:31 +0000444 if (!(resource->flags & IORESOURCE_ASSIGNED)) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000445 printk_err("ERROR: %s %02x %s size: 0x%010Lx not assigned\n",
446 dev_path(dev), resource->index,
447 resource_type(resource),
448 resource->size);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000449 return;
450 }
451
Eric Biederman5cd81732004-03-11 15:01:31 +0000452 /* If I have already stored this resource don't worry about it */
453 if (resource->flags & IORESOURCE_STORED) {
454 return;
455 }
456
Eric Biederman03acab62004-10-14 21:25:53 +0000457 /* If the resources is substractive don't worry about it */
458 if (resource->flags & IORESOURCE_SUBTRACTIVE) {
459 return;
460 }
461
Eric Biederman8ca8d762003-04-22 19:02:15 +0000462 /* Only handle PCI memory and IO resources for now */
463 if (!(resource->flags & (IORESOURCE_MEM |IORESOURCE_IO)))
464 return;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000465
Eric Biederman03acab62004-10-14 21:25:53 +0000466 /* Enable the resources in the command register */
467 if (resource->size) {
468 if (resource->flags & IORESOURCE_MEM) {
469 dev->command |= PCI_COMMAND_MEMORY;
470 }
471 if (resource->flags & IORESOURCE_IO) {
472 dev->command |= PCI_COMMAND_IO;
473 }
474 if (resource->flags & IORESOURCE_PCI_BRIDGE) {
475 dev->command |= PCI_COMMAND_MASTER;
476 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000477 }
478 /* Get the base address */
479 base = resource->base;
Eric Biederman5cd81732004-03-11 15:01:31 +0000480
Eric Biederman03acab62004-10-14 21:25:53 +0000481 /* Get the end */
482 end = resource_end(resource);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000483
Eric Biederman5cd81732004-03-11 15:01:31 +0000484 /* Now store the resource */
485 resource->flags |= IORESOURCE_STORED;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000486 if (!(resource->flags & IORESOURCE_PCI_BRIDGE)) {
Eric Biederman03acab62004-10-14 21:25:53 +0000487 unsigned long base_lo, base_hi;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000488 /*
489 * some chipsets allow us to set/clear the IO bit.
490 * (e.g. VIA 82c686a.) So set it to be safe)
491 */
Eric Biederman03acab62004-10-14 21:25:53 +0000492 base_lo = base & 0xffffffff;
493 base_hi = (base >> 32) & 0xffffffff;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000494 if (resource->flags & IORESOURCE_IO) {
Eric Biederman03acab62004-10-14 21:25:53 +0000495 base_lo |= PCI_BASE_ADDRESS_SPACE_IO;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000496 }
Eric Biederman03acab62004-10-14 21:25:53 +0000497 pci_write_config32(dev, resource->index, base_lo);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000498 if (resource->flags & IORESOURCE_PCI64) {
Eric Biederman03acab62004-10-14 21:25:53 +0000499 pci_write_config32(dev, resource->index + 4, base_hi);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000500 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000501 }
502 else if (resource->index == PCI_IO_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000503 /* set the IO ranges */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000504 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000505 IORESOURCE_IO, IORESOURCE_IO);
Eric Biederman03acab62004-10-14 21:25:53 +0000506 pci_write_config8(dev, PCI_IO_BASE, base >> 8);
507 pci_write_config16(dev, PCI_IO_BASE_UPPER16, base >> 16);
508 pci_write_config8(dev, PCI_IO_LIMIT, end >> 8);
509 pci_write_config16(dev, PCI_IO_LIMIT_UPPER16, end >> 16);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000510 }
511 else if (resource->index == PCI_MEMORY_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000512 /* set the memory range */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000513 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000514 IORESOURCE_MEM | IORESOURCE_PREFETCH,
515 IORESOURCE_MEM);
Eric Biederman7a5416a2003-06-12 19:23:51 +0000516 pci_write_config16(dev, PCI_MEMORY_BASE, base >> 16);
Eric Biederman03acab62004-10-14 21:25:53 +0000517 pci_write_config16(dev, PCI_MEMORY_LIMIT, end >> 16);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000518 }
519 else if (resource->index == PCI_PREF_MEMORY_BASE) {
Eric Biederman03acab62004-10-14 21:25:53 +0000520 /* set the prefetchable memory range */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000521 compute_allocate_resource(&dev->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +0000522 IORESOURCE_MEM | IORESOURCE_PREFETCH,
523 IORESOURCE_MEM | IORESOURCE_PREFETCH);
Eric Biederman03acab62004-10-14 21:25:53 +0000524 pci_write_config16(dev, PCI_PREF_MEMORY_BASE, base >> 16);
525 pci_write_config32(dev, PCI_PREF_BASE_UPPER32, base >> 32);
526 pci_write_config16(dev, PCI_PREF_MEMORY_LIMIT, end >> 16);
527 pci_write_config32(dev, PCI_PREF_LIMIT_UPPER32, end >> 32);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000528 }
529 else {
Eric Biederman5cd81732004-03-11 15:01:31 +0000530 /* Don't let me think I stored the resource */
531 resource->flags &= ~IORESOURCE_STORED;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000532 printk_err("ERROR: invalid resource->index %x\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000533 resource->index);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000534 }
Eric Biederman03acab62004-10-14 21:25:53 +0000535 report_resource_stored(dev, resource, "");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000536 return;
537}
538
Eric Biederman5899fd82003-04-24 06:25:08 +0000539void pci_dev_set_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000540{
541 struct resource *resource, *last;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000542 unsigned link;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000543 uint8_t line;
544
545 last = &dev->resource[dev->resources];
Eric Biedermanb78c1972004-10-14 20:54:17 +0000546
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000547 for(resource = &dev->resource[0]; resource < last; resource++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000548 pci_set_resource(dev, resource);
549 }
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000550 for(link = 0; link < dev->links; link++) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000551 struct bus *bus;
552 bus = &dev->link[link];
553 if (bus->children) {
554 assign_resources(bus);
555 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000556 }
557
558 /* set a default latency timer */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000559 pci_write_config8(dev, PCI_LATENCY_TIMER, 0x40);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000560
561 /* set a default secondary latency timer */
562 if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
Eric Biederman7a5416a2003-06-12 19:23:51 +0000563 pci_write_config8(dev, PCI_SEC_LATENCY_TIMER, 0x40);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000564 }
565
566 /* zero the irq settings */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000567 line = pci_read_config8(dev, PCI_INTERRUPT_PIN);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000568 if (line) {
Eric Biederman7a5416a2003-06-12 19:23:51 +0000569 pci_write_config8(dev, PCI_INTERRUPT_LINE, 0);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000570 }
571 /* set the cache line size, so far 64 bytes is good for everyone */
Eric Biederman7a5416a2003-06-12 19:23:51 +0000572 pci_write_config8(dev, PCI_CACHE_LINE_SIZE, 64 >> 2);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000573}
574
Eric Biedermane9a271e32003-09-02 03:36:25 +0000575void pci_dev_enable_resources(struct device *dev)
576{
Eric Biedermana9e632c2004-11-18 22:38:08 +0000577 const struct pci_operations *ops;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000578 uint16_t command;
Eric Biederman03acab62004-10-14 21:25:53 +0000579
580 /* Set the subsystem vendor and device id for mainboard devices */
581 ops = ops_pci(dev);
Eric Biedermandbec2d42004-10-21 10:44:08 +0000582 if (dev->on_mainboard && ops && ops->set_subsystem) {
Eric Biederman03acab62004-10-14 21:25:53 +0000583 printk_debug("%s subsystem <- %02x/%02x\n",
584 dev_path(dev),
585 MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
586 MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
587 ops->set_subsystem(dev,
588 MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
589 MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
590 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000591 command = pci_read_config16(dev, PCI_COMMAND);
592 command |= dev->command;
Eric Biederman5cd81732004-03-11 15:01:31 +0000593 command |= (PCI_COMMAND_PARITY + PCI_COMMAND_SERR); /* error check */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000594 printk_debug("%s cmd <- %02x\n", dev_path(dev), command);
595 pci_write_config16(dev, PCI_COMMAND, command);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000596}
597
598void pci_bus_enable_resources(struct device *dev)
599{
600 uint16_t ctrl;
Li-Ta Lo515f6c72005-01-11 22:48:54 +0000601 /* enable IO in command register if there is VGA card
602 * connected with (even it does not claim IO resource) */
603 if (dev->link[0].bridge_ctrl & PCI_BRIDGE_CTL_VGA)
604 dev->command |= PCI_COMMAND_IO;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000605 ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
606 ctrl |= dev->link[0].bridge_ctrl;
Eric Biederman5cd81732004-03-11 15:01:31 +0000607 ctrl |= (PCI_BRIDGE_CTL_PARITY + PCI_BRIDGE_CTL_SERR); /* error check */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000608 printk_debug("%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
609 pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
610
611 pci_dev_enable_resources(dev);
Eric Biedermandbec2d42004-10-21 10:44:08 +0000612
613 enable_childrens_resources(dev);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000614}
615
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000616void pci_bus_reset(struct bus *bus)
617{
618 unsigned ctl;
619 ctl = pci_read_config16(bus->dev, PCI_BRIDGE_CONTROL);
620 ctl |= PCI_BRIDGE_CTL_BUS_RESET;
621 pci_write_config16(bus->dev, PCI_BRIDGE_CONTROL, ctl);
622 mdelay(10);
623 ctl &= ~PCI_BRIDGE_CTL_BUS_RESET;
624 pci_write_config16(bus->dev, PCI_BRIDGE_CONTROL, ctl);
625 delay(1);
626}
627
Eric Biedermandbec2d42004-10-21 10:44:08 +0000628void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device)
Eric Biederman03acab62004-10-14 21:25:53 +0000629{
630 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
631 ((device & 0xffff) << 16) | (vendor & 0xffff));
632}
633
Li-Ta Lo883b8792005-01-10 23:16:22 +0000634void pci_dev_init(struct device *dev)
635{
Roman Kononov778a42b2007-04-06 18:34:39 +0000636#if CONFIG_CONSOLE_VGA == 1
637 extern int vga_inited;
638#endif
639#if CONFIG_PCI_ROM_RUN == 1 || CONFIG_CONSOLE_VGA == 1
Li-Ta Lo883b8792005-01-10 23:16:22 +0000640 struct rom_header *rom, *ram;
641
Roman Kononov778a42b2007-04-06 18:34:39 +0000642#if CONFIG_PCI_ROM_RUN != 1
643 /* We want to execute VGA option ROMs when CONFIG_CONSOLE_VGA
644 * is set but CONFIG_PCI_ROM_RUN is not. In this case we skip
645 * all other option ROM types.
646 */
647 if (dev->class!=PCI_CLASS_DISPLAY_VGA)
648 return;
649#endif
650
Li-Ta Lo883b8792005-01-10 23:16:22 +0000651 rom = pci_rom_probe(dev);
652 if (rom == NULL)
653 return;
Roman Kononov778a42b2007-04-06 18:34:39 +0000654
Li-Ta Lo883b8792005-01-10 23:16:22 +0000655 ram = pci_rom_load(dev, rom);
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000656 if (ram == NULL)
657 return;
Li-Ta Lo883b8792005-01-10 23:16:22 +0000658
659 run_bios(dev, ram);
Roman Kononov778a42b2007-04-06 18:34:39 +0000660
661#if CONFIG_CONSOLE_VGA == 1
662 /* vga_inited is a trigger of the VGA console code.
663 *
664 * Only set it if we enabled VGA console, and if we
665 * just initialized a VGA card.
666 */
667 vga_inited|=dev->class==PCI_CLASS_DISPLAY_VGA;
668#endif
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000669#endif
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000670}
Li-Ta Lo883b8792005-01-10 23:16:22 +0000671
Li-Ta Loe5266692004-03-23 21:28:05 +0000672/** Default device operation for PCI devices */
Eric Biedermana9e632c2004-11-18 22:38:08 +0000673static struct pci_operations pci_dev_ops_pci = {
Eric Biederman03acab62004-10-14 21:25:53 +0000674 .set_subsystem = pci_dev_set_subsystem,
675};
676
Eric Biederman8ca8d762003-04-22 19:02:15 +0000677struct device_operations default_pci_ops_dev = {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000678 .read_resources = pci_dev_read_resources,
679 .set_resources = pci_dev_set_resources,
680 .enable_resources = pci_dev_enable_resources,
Li-Ta Lo883b8792005-01-10 23:16:22 +0000681 .init = pci_dev_init,
Li-Ta Loe5266692004-03-23 21:28:05 +0000682 .scan_bus = 0,
Eric Biederman03acab62004-10-14 21:25:53 +0000683 .enable = 0,
Eric Biedermana9e632c2004-11-18 22:38:08 +0000684 .ops_pci = &pci_dev_ops_pci,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000685};
Li-Ta Loe5266692004-03-23 21:28:05 +0000686
687/** Default device operations for PCI bridges */
Eric Biedermana9e632c2004-11-18 22:38:08 +0000688static struct pci_operations pci_bus_ops_pci = {
Eric Biederman03acab62004-10-14 21:25:53 +0000689 .set_subsystem = 0,
690};
Li-Ta Lo883b8792005-01-10 23:16:22 +0000691
Eric Biederman8ca8d762003-04-22 19:02:15 +0000692struct device_operations default_pci_ops_bus = {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000693 .read_resources = pci_bus_read_resources,
694 .set_resources = pci_dev_set_resources,
695 .enable_resources = pci_bus_enable_resources,
Li-Ta Loe5266692004-03-23 21:28:05 +0000696 .init = 0,
697 .scan_bus = pci_scan_bridge,
Eric Biederman03acab62004-10-14 21:25:53 +0000698 .enable = 0,
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000699 .reset_bus = pci_bus_reset,
Eric Biedermana9e632c2004-11-18 22:38:08 +0000700 .ops_pci = &pci_bus_ops_pci,
Eric Biederman8ca8d762003-04-22 19:02:15 +0000701};
Li-Ta Loe5266692004-03-23 21:28:05 +0000702
703/**
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000704 * @brief Detect the type of downstream bridge
705 *
706 * This function is a heuristic to detect which type
707 * of bus is downstream of a pci to pci bridge. This
708 * functions by looking for various capability blocks
709 * to figure out the type of downstream bridge. PCI-X
710 * PCI-E, and Hypertransport all seem to have appropriate
711 * capabilities.
712 *
713 * When only a PCI-Express capability is found the type
714 * is examined to see which type of bridge we have.
715 *
716 * @param dev
717 *
718 * @return appropriate bridge operations
719 */
720static struct device_operations *get_pci_bridge_ops(device_t dev)
721{
722 unsigned pos;
723
724#if CONFIG_PCIX_PLUGIN_SUPPORT == 1
725 pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
726 if (pos) {
727 printk_debug("%s subbordinate bus PCI-X\n", dev_path(dev));
728 return &default_pcix_ops_bus;
729 }
730#endif
731#if CONFIG_AGP_PLUGIN_SUPPORT == 1
732 /* How do I detect an PCI to AGP bridge? */
733#endif
734#if CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT == 1
735 pos = 0;
736 while((pos = pci_find_next_capability(dev, PCI_CAP_ID_HT, pos))) {
737 unsigned flags;
738 flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
739 if ((flags >> 13) == 1) {
740 /* Host or Secondary Interface */
741 printk_debug("%s subbordinate bus Hypertransport\n",
742 dev_path(dev));
743 return &default_ht_ops_bus;
744 }
745 }
746#endif
747#if CONFIG_PCIEXP_PLUGIN_SUPPORT == 1
748 pos = pci_find_capability(dev, PCI_CAP_ID_PCIE);
749 if (pos) {
750 unsigned flags;
751 flags = pci_read_config16(dev, pos + PCI_EXP_FLAGS);
752 switch((flags & PCI_EXP_FLAGS_TYPE) >> 4) {
753 case PCI_EXP_TYPE_ROOT_PORT:
754 case PCI_EXP_TYPE_UPSTREAM:
755 case PCI_EXP_TYPE_DOWNSTREAM:
756 printk_debug("%s subbordinate bus PCI Express\n",
757 dev_path(dev));
758 return &default_pciexp_ops_bus;
759 case PCI_EXP_TYPE_PCI_BRIDGE:
760 printk_debug("%s subbordinate PCI\n",
761 dev_path(dev));
762 return &default_pci_ops_bus;
763 default:
764 break;
765 }
766 }
767#endif
768 return &default_pci_ops_bus;
769}
770
771/**
Li-Ta Loe5266692004-03-23 21:28:05 +0000772 * @brief Set up PCI device operation
773 *
774 *
775 * @param dev
776 *
777 * @see pci_drivers
778 */
Eric Biederman8ca8d762003-04-22 19:02:15 +0000779static void set_pci_ops(struct device *dev)
780{
781 struct pci_driver *driver;
782 if (dev->ops) {
783 return;
784 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000785
Yinghai Lu5f9624d2006-10-04 22:56:21 +0000786 /* Look through the list of setup drivers and find one for
Eric Biedermanb78c1972004-10-14 20:54:17 +0000787 * this pci device
788 */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000789 for(driver = &pci_drivers[0]; driver != &epci_drivers[0]; driver++) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000790 if ((driver->vendor == dev->vendor) &&
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000791 (driver->device == dev->device))
Eric Biedermanb78c1972004-10-14 20:54:17 +0000792 {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000793 dev->ops = driver->ops;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000794 printk_spew("%s [%04x/%04x] %sops\n",
Eric Biedermanb78c1972004-10-14 20:54:17 +0000795 dev_path(dev),
796 driver->vendor, driver->device,
797 (driver->ops->scan_bus?"bus ":""));
Eric Biederman5899fd82003-04-24 06:25:08 +0000798 return;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000799 }
800 }
Li-Ta Loe5266692004-03-23 21:28:05 +0000801
Eric Biederman8ca8d762003-04-22 19:02:15 +0000802 /* If I don't have a specific driver use the default operations */
803 switch(dev->hdr_type & 0x7f) { /* header type */
804 case PCI_HEADER_TYPE_NORMAL: /* standard header */
805 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)
806 goto bad;
807 dev->ops = &default_pci_ops_dev;
808 break;
809 case PCI_HEADER_TYPE_BRIDGE:
810 if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
811 goto bad;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000812 dev->ops = get_pci_bridge_ops(dev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000813 break;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000814#if CONFIG_CARDBUS_PLUGIN_SUPPORT == 1
815 case PCI_HEADER_TYPE_CARDBUS:
816 dev->ops = &default_cardbus_ops_bus;
817 break;
818#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +0000819 default:
820 bad:
Li-Ta Lo69c5a902004-04-29 20:08:54 +0000821 if (dev->enabled) {
Eric Biederman83b991a2003-10-11 06:20:25 +0000822 printk_err("%s [%04x/%04x/%06x] has unknown header "
Eric Biedermanb78c1972004-10-14 20:54:17 +0000823 "type %02x, ignoring.\n",
824 dev_path(dev),
825 dev->vendor, dev->device,
826 dev->class >> 8, dev->hdr_type);
Eric Biederman83b991a2003-10-11 06:20:25 +0000827 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000828 }
829 return;
830}
831
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000832
833
Eric Biederman8ca8d762003-04-22 19:02:15 +0000834/**
Eric Biederman03acab62004-10-14 21:25:53 +0000835 * @brief See if we have already allocated a device structure for a given devfn.
Li-Ta Loe5266692004-03-23 21:28:05 +0000836 *
837 * Given a linked list of PCI device structures and a devfn number, find the
Li-Ta Lo3a812852004-12-03 22:39:34 +0000838 * device structure correspond to the devfn, if present. This function also
839 * removes the device structure from the linked list.
Li-Ta Loe5266692004-03-23 21:28:05 +0000840 *
841 * @param list the device structure list
Eric Biederman8ca8d762003-04-22 19:02:15 +0000842 * @param devfn a device/function number
Li-Ta Loe5266692004-03-23 21:28:05 +0000843 *
Li-Ta Lo3a812852004-12-03 22:39:34 +0000844 * @return pointer to the device structure found or null of we have not
845 * allocated a device for this devfn yet.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000846 */
Eric Biedermanb78c1972004-10-14 20:54:17 +0000847static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000848{
Eric Biedermanb78c1972004-10-14 20:54:17 +0000849 struct device *dev;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000850 dev = 0;
851 for(; *list; list = &(*list)->sibling) {
Eric Biedermanad1b35a2003-10-14 02:36:51 +0000852 if ((*list)->path.type != DEVICE_PATH_PCI) {
Li-Ta Loe5266692004-03-23 21:28:05 +0000853 printk_err("child %s not a pci device\n",
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000854 dev_path(*list));
Eric Biedermanad1b35a2003-10-14 02:36:51 +0000855 continue;
856 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000857 if ((*list)->path.u.pci.devfn == devfn) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000858 /* Unlink from the list */
859 dev = *list;
860 *list = (*list)->sibling;
861 dev->sibling = 0;
862 break;
863 }
864 }
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000865 /* Just like alloc_dev add the device to the list of device on the bus.
866 * When the list of devices was formed we removed all of the parents
867 * children, and now we are interleaving static and dynamic devices in
Li-Ta Lo3a812852004-12-03 22:39:34 +0000868 * order on the bus.
Eric Biedermanb78c1972004-10-14 20:54:17 +0000869 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000870 if (dev) {
871 device_t child;
872 /* Find the last child of our parent */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000873 for(child = dev->bus->children; child && child->sibling; ) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000874 child = child->sibling;
875 }
876 /* Place the device on the list of children of it's parent. */
877 if (child) {
878 child->sibling = dev;
879 } else {
880 dev->bus->children = dev;
881 }
882 }
883
Eric Biederman8ca8d762003-04-22 19:02:15 +0000884 return dev;
885}
886
Eric Biedermanb78c1972004-10-14 20:54:17 +0000887/**
888 * @brief Scan a PCI bus.
Li-Ta Loe5266692004-03-23 21:28:05 +0000889 *
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000890 * Determine the existence of a given PCI device.
891 *
892 * @param bus pointer to the bus structure
893 * @param devfn to look at
894 *
895 * @return The device structure for hte device (if found)
896 * or the NULL if no device is found.
897 */
898device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn)
899{
900 uint32_t id, class;
901 uint8_t hdr_type;
902
903 /* Detect if a device is present */
904 if (!dev) {
905 struct device dummy;
906 dummy.bus = bus;
907 dummy.path.type = DEVICE_PATH_PCI;
908 dummy.path.u.pci.devfn = devfn;
909 id = pci_read_config32(&dummy, PCI_VENDOR_ID);
910 /* Have we found somthing?
911 * Some broken boards return 0 if a slot is empty.
912 */
913 if ( (id == 0xffffffff) || (id == 0x00000000) ||
914 (id == 0x0000ffff) || (id == 0xffff0000))
915 {
916 printk_spew("PCI: devfn 0x%x, bad id 0x%x\n", devfn, id);
917 return NULL;
918 }
919 dev = alloc_dev(bus, &dummy.path);
920 }
921 else {
922 /* Enable/disable the device. Once we have
923 * found the device specific operations this
924 * operations we will disable the device with
925 * those as well.
926 *
927 * This is geared toward devices that have subfunctions
928 * that do not show up by default.
929 *
930 * If a device is a stuff option on the motherboard
931 * it may be absent and enable_dev must cope.
932 *
933 */
934 /* Run the magice enable sequence for the device */
935 if (dev->chip_ops && dev->chip_ops->enable_dev) {
936 dev->chip_ops->enable_dev(dev);
937 }
938 /* Now read the vendor and device id */
939 id = pci_read_config32(dev, PCI_VENDOR_ID);
940
941
942 /* If the device does not have a pci id disable it.
943 * Possibly this is because we have already disabled
944 * the device. But this also handles optional devices
945 * that may not always show up.
946 */
947 /* If the chain is fully enumerated quit */
948 if ( (id == 0xffffffff) || (id == 0x00000000) ||
949 (id == 0x0000ffff) || (id == 0xffff0000))
950 {
951 if (dev->enabled) {
952 printk_info("Disabling static device: %s\n",
953 dev_path(dev));
954 dev->enabled = 0;
955 }
956 return dev;
957 }
958 }
959 /* Read the rest of the pci configuration information */
960 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
961 class = pci_read_config32(dev, PCI_CLASS_REVISION);
962
963 /* Store the interesting information in the device structure */
964 dev->vendor = id & 0xffff;
965 dev->device = (id >> 16) & 0xffff;
966 dev->hdr_type = hdr_type;
967 /* class code, the upper 3 bytes of PCI_CLASS_REVISION */
968 dev->class = class >> 8;
969
970
971 /* Architectural/System devices always need to
972 * be bus masters.
973 */
974 if ((dev->class >> 16) == PCI_BASE_CLASS_SYSTEM) {
975 dev->command |= PCI_COMMAND_MASTER;
976 }
977 /* Look at the vendor and device id, or at least the
978 * header type and class and figure out which set of
979 * configuration methods to use. Unless we already
980 * have some pci ops.
981 */
982 set_pci_ops(dev);
983
984 /* Now run the magic enable/disable sequence for the device */
985 if (dev->ops && dev->ops->enable) {
986 dev->ops->enable(dev);
987 }
988
989
990 /* Display the device and error if we don't have some pci operations
991 * for it.
992 */
993 printk_debug("%s [%04x/%04x] %s%s\n",
994 dev_path(dev),
995 dev->vendor, dev->device,
996 dev->enabled?"enabled": "disabled",
997 dev->ops?"" : " No operations"
998 );
999
1000 return dev;
1001}
1002
1003/**
1004 * @brief Scan a PCI bus.
1005 *
Li-Ta Loe5266692004-03-23 21:28:05 +00001006 * Determine the existence of devices and bridges on a PCI bus. If there are
1007 * bridges on the bus, recursively scan the buses behind the bridges.
1008 *
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001009 * This function is the default scan_bus() method for the root device
1010 * 'dev_root'.
1011 *
Eric Biedermane9a271e32003-09-02 03:36:25 +00001012 * @param bus pointer to the bus structure
1013 * @param min_devfn minimum devfn to look at in the scan usually 0x00
1014 * @param max_devfn maximum devfn to look at in the scan usually 0xff
Eric Biederman8ca8d762003-04-22 19:02:15 +00001015 * @param max current bus number
Li-Ta Loe5266692004-03-23 21:28:05 +00001016 *
Eric Biederman8ca8d762003-04-22 19:02:15 +00001017 * @return The maximum bus number found, after scanning all subordinate busses
1018 */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001019unsigned int pci_scan_bus(struct bus *bus,
1020 unsigned min_devfn, unsigned max_devfn,
1021 unsigned int max)
Eric Biederman8ca8d762003-04-22 19:02:15 +00001022{
1023 unsigned int devfn;
Eric Biedermane9a271e32003-09-02 03:36:25 +00001024 device_t old_devices;
1025 device_t child;
Eric Biederman8ca8d762003-04-22 19:02:15 +00001026
Yinghai Lu5f9624d2006-10-04 22:56:21 +00001027#if PCI_BUS_SEGN_BITS
1028 printk_debug("PCI: pci_scan_bus for bus %04x:%02x\n", bus->secondary >> 8, bus->secondary & 0xff);
1029#else
1030 printk_debug("PCI: pci_scan_bus for bus %02x\n", bus->secondary);
1031#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +00001032
1033 old_devices = bus->children;
1034 bus->children = 0;
Eric Biederman8ca8d762003-04-22 19:02:15 +00001035
1036 post_code(0x24);
Li-Ta Lo9782f752004-05-05 21:15:42 +00001037 /* probe all devices/functions on this bus with some optimization for
Eric Biedermanb78c1972004-10-14 20:54:17 +00001038 * non-existence and single funcion devices
1039 */
Eric Biedermane9a271e32003-09-02 03:36:25 +00001040 for (devfn = min_devfn; devfn <= max_devfn; devfn++) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001041 device_t dev;
Eric Biederman8ca8d762003-04-22 19:02:15 +00001042
Eric Biederman03acab62004-10-14 21:25:53 +00001043 /* First thing setup the device structure */
Eric Biederman8ca8d762003-04-22 19:02:15 +00001044 dev = pci_scan_get_dev(&old_devices, devfn);
Li-Ta Lo9782f752004-05-05 21:15:42 +00001045
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001046 /* See if a device is present and setup the device
1047 * structure.
Eric Biederman03acab62004-10-14 21:25:53 +00001048 */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001049 dev = pci_probe_dev(dev, bus, devfn);
Eric Biederman03acab62004-10-14 21:25:53 +00001050
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001051 /* if this is not a multi function device,
1052 * or the device is not present don't waste
1053 * time probing another function.
1054 * Skip to next device.
Eric Biederman8ca8d762003-04-22 19:02:15 +00001055 */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001056 if ((PCI_FUNC(devfn) == 0x00) &&
1057 (!dev || (dev->enabled && ((dev->hdr_type & 0x80) != 0x80))))
1058 {
Eric Biederman8ca8d762003-04-22 19:02:15 +00001059 devfn += 0x07;
1060 }
1061 }
1062 post_code(0x25);
1063
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001064 /* Die if any leftover Static devices are are found.
1065 * There's probably a problem in the Config.lb.
1066 */
1067 if(old_devices) {
1068 device_t left;
1069 for(left = old_devices; left; left = left->sibling) {
Ronald G. Minniche800b912006-01-17 21:12:03 +00001070 printk_err("%s\n", dev_path(left));
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001071 }
Stefan Reinauer7ce8c542005-12-02 21:52:30 +00001072 die("PCI: Left over static devices. Check your Config.lb\n");
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001073 }
1074
Eric Biedermanb78c1972004-10-14 20:54:17 +00001075 /* For all children that implement scan_bus (i.e. bridges)
1076 * scan the bus behind that child.
1077 */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001078 for(child = bus->children; child; child = child->sibling) {
1079 max = scan_bus(child, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +00001080 }
Li-Ta Loe5266692004-03-23 21:28:05 +00001081
Eric Biederman8ca8d762003-04-22 19:02:15 +00001082 /*
1083 * We've scanned the bus and so we know all about what's on
1084 * the other side of any bridges that may be on this bus plus
1085 * any devices.
1086 *
1087 * Return how far we've got finding sub-buses.
1088 */
Yinghai Lu5f9624d2006-10-04 22:56:21 +00001089 printk_debug("PCI: pci_scan_bus returning with max=%03x\n", max);
Eric Biederman8ca8d762003-04-22 19:02:15 +00001090 post_code(0x55);
1091 return max;
1092}
1093
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001094
Li-Ta Loe5266692004-03-23 21:28:05 +00001095/**
1096 * @brief Scan a PCI bridge and the buses behind the bridge.
1097 *
1098 * Determine the existence of buses behind the bridge. Set up the bridge
1099 * according to the result of the scan.
1100 *
1101 * This function is the default scan_bus() method for PCI bridge devices.
1102 *
1103 * @param dev pointer to the bridge device
1104 * @param max the highest bus number assgined up to now
1105 *
Eric Biederman8ca8d762003-04-22 19:02:15 +00001106 * @return The maximum bus number found, after scanning all subordinate busses
1107 */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001108unsigned int do_pci_scan_bridge(struct device *dev, unsigned int max,
1109 unsigned int (*do_scan_bus)(struct bus *bus,
1110 unsigned min_devfn, unsigned max_devfn, unsigned int max))
Eric Biederman8ca8d762003-04-22 19:02:15 +00001111{
Eric Biedermane9a271e32003-09-02 03:36:25 +00001112 struct bus *bus;
Eric Biederman8ca8d762003-04-22 19:02:15 +00001113 uint32_t buses;
1114 uint16_t cr;
Eric Biederman83b991a2003-10-11 06:20:25 +00001115
Li-Ta Lo3a812852004-12-03 22:39:34 +00001116 printk_spew("%s for %s\n", __func__, dev_path(dev));
1117
Eric Biedermane9a271e32003-09-02 03:36:25 +00001118 bus = &dev->link[0];
Eric Biedermana9e632c2004-11-18 22:38:08 +00001119 bus->dev = dev;
Eric Biedermane9a271e32003-09-02 03:36:25 +00001120 dev->links = 1;
1121
Eric Biederman8ca8d762003-04-22 19:02:15 +00001122 /* Set up the primary, secondary and subordinate bus numbers. We have
1123 * no idea how many buses are behind this bridge yet, so we set the
Eric Biedermanb78c1972004-10-14 20:54:17 +00001124 * subordinate bus number to 0xff for the moment.
1125 */
Eric Biederman8ca8d762003-04-22 19:02:15 +00001126 bus->secondary = ++max;
1127 bus->subordinate = 0xff;
Li-Ta Loe5266692004-03-23 21:28:05 +00001128
Eric Biederman8ca8d762003-04-22 19:02:15 +00001129 /* Clear all status bits and turn off memory, I/O and master enables. */
Eric Biedermane9a271e32003-09-02 03:36:25 +00001130 cr = pci_read_config16(dev, PCI_COMMAND);
1131 pci_write_config16(dev, PCI_COMMAND, 0x0000);
1132 pci_write_config16(dev, PCI_STATUS, 0xffff);
Eric Biederman8ca8d762003-04-22 19:02:15 +00001133
Eric Biedermanb78c1972004-10-14 20:54:17 +00001134 /*
1135 * Read the existing primary/secondary/subordinate bus
1136 * number configuration.
1137 */
Eric Biedermane9a271e32003-09-02 03:36:25 +00001138 buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
Eric Biederman8ca8d762003-04-22 19:02:15 +00001139
1140 /* Configure the bus numbers for this bridge: the configuration
1141 * transactions will not be propagated by the bridge if it is not
Eric Biedermanb78c1972004-10-14 20:54:17 +00001142 * correctly configured.
1143 */
Eric Biederman8ca8d762003-04-22 19:02:15 +00001144 buses &= 0xff000000;
Eric Biedermane9a271e32003-09-02 03:36:25 +00001145 buses |= (((unsigned int) (dev->bus->secondary) << 0) |
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001146 ((unsigned int) (bus->secondary) << 8) |
1147 ((unsigned int) (bus->subordinate) << 16));
Eric Biedermane9a271e32003-09-02 03:36:25 +00001148 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
Li-Ta Lo3a812852004-12-03 22:39:34 +00001149
Eric Biedermanb78c1972004-10-14 20:54:17 +00001150 /* Now we can scan all subordinate buses
1151 * i.e. the bus behind the bridge.
1152 */
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001153 max = do_scan_bus(bus, 0x00, 0xff, max);
Li-Ta Lo3a812852004-12-03 22:39:34 +00001154
Eric Biederman8ca8d762003-04-22 19:02:15 +00001155 /* We know the number of buses behind this bridge. Set the subordinate
Eric Biedermanb78c1972004-10-14 20:54:17 +00001156 * bus number to its real value.
1157 */
Eric Biederman8ca8d762003-04-22 19:02:15 +00001158 bus->subordinate = max;
1159 buses = (buses & 0xff00ffff) |
1160 ((unsigned int) (bus->subordinate) << 16);
Eric Biedermane9a271e32003-09-02 03:36:25 +00001161 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
1162 pci_write_config16(dev, PCI_COMMAND, cr);
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001163
Eric Biedermanb78c1972004-10-14 20:54:17 +00001164 printk_spew("%s returns max %d\n", __func__, max);
Eric Biederman8ca8d762003-04-22 19:02:15 +00001165 return max;
1166}
Li-Ta Loe5266692004-03-23 21:28:05 +00001167
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001168/**
1169 * @brief Scan a PCI bridge and the buses behind the bridge.
1170 *
1171 * Determine the existence of buses behind the bridge. Set up the bridge
1172 * according to the result of the scan.
1173 *
1174 * This function is the default scan_bus() method for PCI bridge devices.
1175 *
1176 * @param dev pointer to the bridge device
1177 * @param max the highest bus number assgined up to now
1178 *
1179 * @return The maximum bus number found, after scanning all subordinate busses
1180 */
1181unsigned int pci_scan_bridge(struct device *dev, unsigned int max)
1182{
1183 return do_pci_scan_bridge(dev, max, pci_scan_bus);
1184}
1185
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001186/*
1187 Tell the EISA int controller this int must be level triggered
1188 THIS IS A KLUDGE -- sorry, this needs to get cleaned up.
1189*/
Ronald G. Minnich88fb1a62006-06-22 04:37:27 +00001190void pci_level_irq(unsigned char intNum)
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001191{
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001192 unsigned short intBits = inb(0x4d0) | (((unsigned) inb(0x4d1)) << 8);
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001193
Eric Biedermanb78c1972004-10-14 20:54:17 +00001194 printk_spew("%s: current ints are 0x%x\n", __func__, intBits);
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001195 intBits |= (1 << intNum);
1196
Eric Biedermanb78c1972004-10-14 20:54:17 +00001197 printk_spew("%s: try to set ints 0x%x\n", __func__, intBits);
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001198
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001199 // Write new values
1200 outb((unsigned char) intBits, 0x4d0);
1201 outb((unsigned char) (intBits >> 8), 0x4d1);
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001202
Ronald G. Minnichb56ef072003-10-15 20:05:11 +00001203 /* this seems like an error but is not ... */
Ronald G. Minnich02fa3b22004-10-06 17:33:54 +00001204#if 1
Ronald G. Minnich2cf779d2006-09-18 22:50:51 +00001205 if (inb(0x4d0) != (intBits & 0xff)) {
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001206 printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
Ronald G. Minnich2cf779d2006-09-18 22:50:51 +00001207 __func__, intBits &0xff, inb(0x4d0));
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001208 }
Ronald G. Minnich2cf779d2006-09-18 22:50:51 +00001209 if (inb(0x4d1) != ((intBits >> 8) & 0xff)) {
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001210 printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
Ronald G. Minnich2cf779d2006-09-18 22:50:51 +00001211 __func__, (intBits>>8) &0xff, inb(0x4d1));
Ronald G. Minnichcb3f4982003-10-02 18:16:07 +00001212 }
Ronald G. Minnichb56ef072003-10-15 20:05:11 +00001213#endif
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001214}
1215
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001216/*
1217 This function assigns IRQs for all functions contained within
1218 the indicated device address. If the device does not exist or does
1219 not require interrupts then this function has no effect.
1220
1221 This function should be called for each PCI slot in your system.
1222
1223 pIntAtoD is an array of IRQ #s that are assigned to PINTA through PINTD of
1224 this slot.
1225 The particular irq #s that are passed in depend on the routing inside
1226 your southbridge and on your motherboard.
1227
1228 -kevinh@ispiri.com
1229*/
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001230void pci_assign_irqs(unsigned bus, unsigned slot,
1231 const unsigned char pIntAtoD[4])
Ronald G. Minnich6dd6c6852003-10-02 00:08:42 +00001232{
1233 unsigned functNum;
1234 device_t pdev;
1235 unsigned char line;
1236 unsigned char irq;
1237 unsigned char readback;
1238
1239 /* Each slot may contain up to eight functions */
1240 for (functNum = 0; functNum < 8; functNum++) {
1241 pdev = dev_find_slot(bus, (slot << 3) + functNum);
1242
1243 if (pdev) {
1244 line = pci_read_config8(pdev, PCI_INTERRUPT_PIN);
1245
1246 // PCI spec says all other values are reserved
1247 if ((line >= 1) && (line <= 4)) {
1248 irq = pIntAtoD[line - 1];
1249
1250 printk_debug("Assigning IRQ %d to %d:%x.%d\n", \
1251 irq, bus, slot, functNum);
1252
1253 pci_write_config8(pdev, PCI_INTERRUPT_LINE,\
1254 pIntAtoD[line - 1]);
1255
1256 readback = pci_read_config8(pdev, PCI_INTERRUPT_LINE);
1257 printk_debug(" Readback = %d\n", readback);
1258
1259 // Change to level triggered
1260 pci_level_irq(pIntAtoD[line - 1]);
1261 }
1262 }
1263 }
1264}