source: rtems/c/src/lib/libbsp/powerpc/shared/bootloader/pci.c @ da3b8d3

4.104.114.84.95
Last change on this file since da3b8d3 was da3b8d3, checked in by Joel Sherrill <joel.sherrill@…>, on Mar 5, 2004 at 6:09:14 PM

2004-03-05 Joel Sherrill <joel@…>

  • bootloader/pci.c: Remove warnings by adding include <string.h>.
  • irq/irq.c: Clean up includes to remove warnings.
  • pci/pci.c, pci/pci.h, startup/bspstart.c: Better use of const on struct _int_map.
  • Property mode set to 100644
File size: 40.2 KB
Line 
1/*
2 *  pci.c -- Crude pci handling for early boot.
3 *
4 *  Copyright (C) 1998, 1999 Gabriel Paubert, paubert@iram.es
5 *
6 *  Modified to compile in RTEMS development environment
7 *  by Eric Valette
8 *
9 *  Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
10 *
11 *  The license and distribution terms for this file may be
12 *  found in found in the file LICENSE in this distribution or at
13 *  http://www.rtems.com/license/LICENSE.
14 *
15 * $Id$
16 */
17
18
19#include <sys/types.h>
20#include <rtems/bspIo.h>
21#include <libcpu/spr.h>
22#include "bootldr.h"
23#include "pci.h"
24#include <libcpu/io.h>
25#include <libcpu/page.h>
26#include <bsp/consoleIo.h>
27
28#include <string.h>
29
30
31typedef unsigned int u32;
32
33
34/*
35#define DEBUG
36#define PCI_DEBUG
37*/
38
39
40/* Used to reorganize PCI space on stupid machines which spread resources
41 * across a wide address space. This is bad when P2P bridges are present
42 * or when it limits the mappings that a resource hog like a PCI<->VME
43 * bridge can use.
44 */
45
46typedef struct _pci_resource {
47      struct _pci_resource *next;
48      struct pci_dev *dev; 
49      u_long base;    /* will be 64 bits on 64 bits machines */
50      u_long size;
51      u_char type;      /* 1 is I/O else low order 4 bits of the memory type */
52      u_char reg;       /* Register # in conf space header */
53      u_short cmd;    /* Original cmd byte */
54} pci_resource;
55
56typedef struct _pci_area {
57      struct _pci_area *next;
58      u_long start;
59      u_long end;
60      struct pci_bus *bus;
61      u_int flags;
62} pci_area;
63
64typedef struct _pci_area_head {
65      pci_area *head;
66      u_long mask;
67      int high; /* To allocate from top */
68} pci_area_head;
69
70#define PCI_AREA_PREFETCHABLE 0
71#define PCI_AREA_MEMORY 1
72#define PCI_AREA_IO 2
73
74struct _pci_private {
75      volatile u_int * config_addr;
76      volatile u_char * config_data;
77      struct pci_dev **last_dev_p;
78      struct pci_bus pci_root;
79      pci_resource *resources;
80      pci_area_head io, mem;
81
82} pci_private = {
83   config_addr: NULL, 
84   config_data: (volatile u_char *) 0x80800000, 
85   last_dev_p: NULL, 
86   resources: NULL,
87   io: {NULL, 0xfff, 0},
88   mem: {NULL, 0xfffff, 0}
89};
90
91#define pci ((struct _pci_private *)(bd->pci_private))
92#define pci_root pci->pci_root
93
94#if !defined(DEBUG)
95#undef PCI_DEBUG
96/*
97  #else
98  #define PCI_DEBUG
99*/
100#endif
101
102#if defined(PCI_DEBUG)
103static void 
104print_pci_resources(const char *s) {
105   pci_resource *p;
106   printk("%s", s);
107   for (p=pci->resources; p; p=p->next) {
108/*
109      printk("  %p:%p %06x %08lx %08lx %d\n",
110             p, p->next,
111             (p->dev->devfn<<8)+(p->dev->bus->number<<16)
112             +0x10+p->reg*4,
113             p->base,
114             p->size,
115             p->type);
116*/
117
118      printk("  %p:%p %d:%02x (%04x:%04x) %08lx %08lx %d\n", 
119             p, p->next,
120             p->dev->bus->number, PCI_SLOT(p->dev->devfn), 
121             p->dev->vendor, p->dev->device,
122             p->base,
123             p->size,
124             p->type); 
125
126   }
127}
128
129static void 
130print_pci_area(pci_area *p) {
131   for (; p; p=p->next) {
132      printk("    %p:%p %p %08lx %08lx\n",
133             p, p->next, p->bus, p->start, p->end);
134   }
135}
136
137static void 
138print_pci_areas(const char *s) {
139   printk("%s  PCI I/O areas:\n",s);
140   print_pci_area(pci->io.head);
141   printk("  PCI memory areas:\n");
142   print_pci_area(pci->mem.head);
143}
144#else
145#define print_pci_areas(x)
146#define print_pci_resources(x)
147#endif
148
149/* Maybe there are some devices who use a size different
150 * from the alignment. For now we assume both are the same.
151 * The blacklist might be used for other weird things in the future too,
152 * since weird non PCI complying devices seem to proliferate these days.
153 */
154
155struct blacklist_entry {
156      u_short vendor, device;
157      u_char reg;
158      u_long actual_size;
159};
160
161#define BLACKLIST(vid, did, breg, actual_size) \
162        {PCI_VENDOR_ID_##vid, PCI_DEVICE_ID_##vid##_##did, breg, actual_size}
163
164static struct blacklist_entry blacklist[] = {
165   BLACKLIST(S3, TRIO, 0, 0x04000000),
166   {0xffff, 0, 0, 0}
167};
168
169
170/* This function filters resources and then inserts them into a list of
171 * configurable pci resources.
172 */
173
174
175#define AREA(r) \
176(((r->type&PCI_BASE_ADDRESS_SPACE)==PCI_BASE_ADDRESS_SPACE_IO) ? PCI_AREA_IO :\
177          ((r->type&PCI_BASE_ADDRESS_MEM_PREFETCH) ? PCI_AREA_PREFETCHABLE :\
178           PCI_AREA_MEMORY))
179
180
181
182static int insert_before(pci_resource *e, pci_resource *t) {
183   if (e->dev->bus->number != t->dev->bus->number) 
184      return e->dev->bus->number > t->dev->bus->number;
185   if (AREA(e) != AREA(t)) return AREA(e)<AREA(t);
186   return (e->size > t->size);
187}
188
189
190
191
192
193static void insert_resource(pci_resource *r) {
194   struct blacklist_entry *b;
195   pci_resource *p;
196   if (!r) return;
197
198   /* First fixup in case we have a blacklist entry. Note that this
199    * may temporarily leave a resource in an inconsistent state: with
200    * (base & (size-1)) !=0. This is harmless.
201    */
202   for (b=blacklist; b->vendor!=0xffff; b++) {
203      if ((r->dev->vendor==b->vendor) &&
204          (r->dev->device==b->device) &&
205          (r->reg==b->reg)) {
206         r->size=b->actual_size;
207         break;
208      }
209   }
210       
211   /* Motorola NT firmware does not configure pci devices which are not
212    * required for booting, others do. For now:
213    * - allocated devices in the ISA range (64kB I/O, 16Mb memory)
214    *   but non zero base registers are left as is.
215    * - all other registers, whether already allocated or not, are
216    *   reallocated unless they require an inordinate amount of
217    *   resources (>256 Mb for memory >64kB for I/O). These
218    *   devices with too large mapping requirements are simply ignored
219    *   and their bases are set to 0. This should disable the
220    *   corresponding decoders according to the PCI specification.
221    *   Many devices are buggy in this respect, however, but the
222    *   limits have hopefully been set high enough to avoid problems.
223    */
224
225   /*
226   ** This is little ugly below.  It seems that at least on the MCP750,
227   ** the PBC has some default IO space mappings that the bsp #defines
228   ** that read/write to PCI I/O space assume, particuarly the i8259
229   ** manipulation code.  So, if we allow the small IO spaces on PCI bus
230   ** 0 and 1 to be remapped, the registers can shift out from under the
231   ** #defines.  This is particuarly awful, but short of redefining the
232   ** PCI I/O primitives to be functions with base addresses read from
233   ** the hardware, we are stuck with the kludge below.  Note that
234   ** everything is remapped on the CPCI backplane and any downstream
235   ** hardware, its just the builtin stuff we're tiptoeing around.
236   **
237   ** Gregm, 7/16/2003
238   */
239   if( r->dev->bus->number <= 1 )
240   {
241   if ((r->type==PCI_BASE_ADDRESS_SPACE_IO) 
242       ? (r->base && r->base <0x10000)
243       : (r->base && r->base <0x1000000)) {
244
245#ifdef PCI_DEBUG
246         printk("freeing region;  %p:%p %d:%02x (%04x:%04x) %08lx %08lx %d\n", 
247                r, r->next,
248                r->dev->bus->number, PCI_SLOT(r->dev->devfn), 
249                r->dev->vendor, r->dev->device,
250                r->base,
251                r->size,
252                r->type); 
253#endif
254      sfree(r);
255      return;
256   }
257   }
258
259   if ((r->type==PCI_BASE_ADDRESS_SPACE_IO) 
260       ? (r->size >= 0x10000)
261       : (r->size >= 0x10000000)) {
262      r->size  = 0;
263      r->base  = 0;
264   }
265
266   /* Now insert into the list sorting by
267    * 1) decreasing bus number
268    * 2) space: prefetchable memory, non-prefetchable and finally I/O
269    * 3) decreasing size
270    */
271   if (!pci->resources || insert_before(r, pci->resources)) {
272      r->next = pci->resources;
273      pci->resources=r;
274   } else {
275      for (p=pci->resources; p->next; p=p->next) {
276         if (insert_before(r, p->next)) break;
277      }
278      r->next=p->next;
279      p->next=r;
280   }
281}
282
283
284
285
286
287/* This version only works for bus 0. I don't have any P2P bridges to test
288 * a more sophisticated version which has therefore not been implemented.
289 * Prefetchable memory is not yet handled correctly either.
290 * And several levels of PCI bridges much less even since there must be
291 * allocated together to be able to setup correctly the top bridge.
292 */
293
294static u_long find_range(u_char bus, u_char type, 
295                         pci_resource **first,
296                         pci_resource **past, u_int *flags) {
297   pci_resource *p;
298   u_long total=0;
299   u_int fl=0;
300
301   for (p=pci->resources; p; p=p->next) 
302   {
303      if ((p->dev->bus->number == bus) &&
304          AREA(p)==type) break;
305   }
306
307   *first = p;
308
309   for (; p; p=p->next) 
310   {
311      if ((p->dev->bus->number != bus) ||
312          AREA(p)!=type || p->size == 0) break;
313      total = total+p->size;
314      fl |= 1<<p->type; 
315   }
316
317   *past = p;
318   /* This will be used later to tell whether there are any 32 bit
319    * devices in an area which could be mapped higher than 4Gb
320    * on 64 bits architectures
321    */
322   *flags = fl;
323   return total;
324}
325
326
327
328
329
330
331static inline void init_free_area(pci_area_head *h, u_long start, 
332                                  u_long end, u_int mask, int high) {
333   pci_area *p;
334   p = salloc(sizeof(pci_area));
335   if (!p) return;
336   h->head = p;
337   p->next = NULL;
338   p->start = (start+mask)&~mask;
339   p->end = (end-mask)|mask;
340   p->bus = NULL;
341   h->mask = mask;
342   h->high = high;
343}
344
345
346
347
348
349
350static void insert_area(pci_area_head *h, pci_area *p) {
351   pci_area *q = h->head;
352   if (!p) return;
353   if (q && (q->start< p->start)) {
354      for(;q->next && q->next->start<p->start; q = q->next);
355      if ((q->end >= p->start) ||
356          (q->next && p->end>=q->next->start)) {
357         sfree(p);
358         printk("Overlapping pci areas!\n");
359         return;
360      }
361      p->next = q->next;
362      q->next = p;
363   } else { /* Insert at head */
364      if (q && (p->end >= q->start)) {
365         sfree(p);
366         printk("Overlapping pci areas!\n");
367         return;
368      }
369      p->next = q;
370      h->head = p;
371   }
372}
373
374
375
376
377
378static
379void remove_area(pci_area_head *h, pci_area *p) 
380{
381   pci_area *q = h->head;
382
383   if (!p || !q) return;
384   if (q==p) 
385   {
386      h->head = q->next;
387      return;
388   }
389   for(;q && q->next!=p; q=q->next);
390   if (q) q->next=p->next;
391}
392
393
394
395
396
397
398static pci_area * alloc_area(pci_area_head *h, struct pci_bus *bus,
399                             u_long required, u_long mask, u_int flags) {
400   pci_area *p;
401   pci_area *from, *split, *new;
402
403   required = (required+h->mask) & ~h->mask;
404   for (p=h->head, from=NULL; p; p=p->next) 
405   {
406      u_long l1 = ((p->start+required+mask)&~mask)-1;
407      u_long l2 = ((p->start+mask)&~mask)+required-1;
408      /* Allocated areas point to the bus to which they pertain */
409      if (p->bus) continue;
410      if ((p->end)>=l1 || (p->end)>=l2) from=p;
411      if (from && !h->high) break;
412   }
413   if (!from) return NULL;
414
415   split = salloc(sizeof(pci_area));
416   new = salloc(sizeof(pci_area));
417   /* If allocation of new succeeds then allocation of split has
418    * also been successful (given the current mm algorithms) !
419    */
420   if (!new) { 
421      sfree(split); 
422      return NULL; 
423   }
424   new->bus = bus;
425   new->flags = flags;
426   /* Now allocate pci_space taking alignment into account ! */
427   if (h->high) 
428   {
429      u_long l1 = ((from->end+1)&~mask)-required;
430      u_long l2 = (from->end+1-required)&~mask; 
431      new->start = (l1>l2) ? l1 : l2;
432      split->end = from->end;
433      from->end = new->start-1;
434      split->start = new->start+required;
435      new->end = new->start+required-1;
436   } 
437   else 
438   {
439      u_long l1 = ((from->start+mask)&~mask)+required-1;
440      u_long l2 = ((from->start+required+mask)&~mask)-1; 
441      new->end = (l1<l2) ? l1 : l2;
442      split->start = from->start;
443      from->start = new->end+1;
444      new->start = new->end+1-required;
445      split->end = new->start-1;
446   }
447       
448   if (from->end+1 == from->start) remove_area(h, from);
449   if (split->end+1 != split->start) 
450   {
451      split->bus = NULL;
452      insert_area(h, split);
453   } 
454   else 
455   {
456      sfree(split);
457   }
458   insert_area(h, new);
459   print_pci_areas("alloc_area called:\n");
460   return new;
461}
462
463
464
465
466
467static inline
468void alloc_space(pci_area *p, pci_resource *r) 
469{
470   if (p->start & (r->size-1)) {
471      r->base = p->end+1-r->size;
472      p->end -= r->size;
473   } else {
474      r->base = p->start;
475      p->start += r->size;
476   }
477}
478
479
480
481
482
483static void reconfigure_bus_space(u_char bus, u_char type, pci_area_head *h) 
484{
485   pci_resource *first, *past, *r;
486   pci_area *area, tmp;
487   u_int flags;
488   u_int required = find_range(bus, type, &first, &past, &flags);
489
490   if (required==0) return;
491
492   area = alloc_area(h, first->dev->bus, required, first->size-1, flags);
493
494   if (!area) return;
495
496   tmp = *area;
497   for (r=first; r!=past; r=r->next) 
498   {
499      alloc_space(&tmp, r);
500   }
501}
502
503
504
505
506
507
508
509#define BUS0_IO_START           0x10000
510#define BUS0_IO_END             0x1ffff
511#define BUS0_MEM_START          0x1000000
512#define BUS0_MEM_END            0xaffffff
513
514#define BUSREST_IO_START        0x20000
515#define BUSREST_IO_END          0x7ffff
516#define BUSREST_MEM_START       0xb000000
517#define BUSREST_MEM_END        0x10000000
518
519
520
521
522
523static void reconfigure_pci(void) {
524   pci_resource *r;
525   struct pci_dev *dev;
526
527   /* FIXME: for now memory is relocated from low, it's better
528    * to start from higher addresses.
529    */
530   /*
531   init_free_area(&pci->io, 0x10000, 0x7fffff, 0xfff, 0);
532   init_free_area(&pci->mem, 0x1000000, 0x3cffffff, 0xfffff, 0);
533   */
534
535   init_free_area(&pci->io, BUS0_IO_START, BUS0_IO_END, 0xfff, 0);
536   init_free_area(&pci->mem, BUS0_MEM_START, BUS0_MEM_END, 0xfffff, 0);
537
538
539   /* First reconfigure the I/O space, this will be more
540    * complex when there is more than 1 bus. And 64 bits
541    * devices are another kind of problems.
542    */
543   reconfigure_bus_space(0, PCI_AREA_IO, &pci->io);
544   reconfigure_bus_space(0, PCI_AREA_MEMORY, &pci->mem);
545   reconfigure_bus_space(0, PCI_AREA_PREFETCHABLE, &pci->mem);
546
547   /* Now we have to touch the configuration space of all
548    * the devices to remap them better than they are right now.
549    * This is done in 3 steps:
550    * 1) first disable I/O and memory response of all devices
551    * 2) modify the base registers
552    * 3) restore the original PCI_COMMAND register.
553    */
554   for (r=pci->resources; r; r= r->next) {
555      if (!r->dev->sysdata) {
556         r->dev->sysdata=r;
557         pci_read_config_word(r->dev, PCI_COMMAND, &r->cmd);
558         pci_write_config_word(r->dev, PCI_COMMAND,
559                               r->cmd & ~(PCI_COMMAND_IO|
560                                          PCI_COMMAND_MEMORY));
561      }
562   }
563
564   for (r=pci->resources; r; r= r->next) {
565      pci_write_config_dword(r->dev, 
566                             PCI_BASE_ADDRESS_0+(r->reg<<2),
567                             r->base);
568      if ((r->type&
569           (PCI_BASE_ADDRESS_SPACE|
570            PCI_BASE_ADDRESS_MEM_TYPE_MASK)) == 
571          (PCI_BASE_ADDRESS_SPACE_MEMORY|
572           PCI_BASE_ADDRESS_MEM_TYPE_64)) {
573         pci_write_config_dword(r->dev,
574                                PCI_BASE_ADDRESS_1+
575                                (r->reg<<2),
576                                0);
577      }
578   }
579   for (dev=bd->pci_devices; dev; dev= dev->next) {
580      if (dev->sysdata) {
581         pci_write_config_word(dev, PCI_COMMAND,
582                               ((pci_resource *)dev->sysdata)
583                               ->cmd);
584         dev->sysdata=NULL;
585      }
586   }
587}
588
589
590
591
592
593
594static int
595indirect_pci_read_config_byte(unsigned char bus, unsigned char dev_fn, 
596                              unsigned char offset, unsigned char *val) {
597   out_be32(pci->config_addr, 
598            0x80|(bus<<8)|(dev_fn<<16)|((offset&~3)<<24));
599   *val=in_8(pci->config_data + (offset&3));
600   return PCIBIOS_SUCCESSFUL;
601}
602
603static int
604indirect_pci_read_config_word(unsigned char bus, unsigned char dev_fn, 
605                              unsigned char offset, unsigned short *val) {
606   *val = 0xffff; 
607   if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;
608   out_be32(pci->config_addr, 
609            0x80|(bus<<8)|(dev_fn<<16)|((offset&~3)<<24));
610   *val=in_le16((volatile u_short *)(pci->config_data + (offset&3)));
611   return PCIBIOS_SUCCESSFUL;
612}
613
614static int
615indirect_pci_read_config_dword(unsigned char bus, unsigned char dev_fn, 
616                               unsigned char offset, unsigned int *val) {
617   *val = 0xffffffff; 
618   if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;
619   out_be32(pci->config_addr, 
620            0x80|(bus<<8)|(dev_fn<<16)|(offset<<24));
621   *val=in_le32((volatile u_int *)pci->config_data);
622   return PCIBIOS_SUCCESSFUL;
623}
624
625static int
626indirect_pci_write_config_byte(unsigned char bus, unsigned char dev_fn, 
627                               unsigned char offset, unsigned char val) {
628   out_be32(pci->config_addr, 
629            0x80|(bus<<8)|(dev_fn<<16)|((offset&~3)<<24));
630   out_8(pci->config_data + (offset&3), val);
631   return PCIBIOS_SUCCESSFUL;
632}
633
634static int
635indirect_pci_write_config_word(unsigned char bus, unsigned char dev_fn, 
636                               unsigned char offset, unsigned short val) {
637   if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;
638   out_be32(pci->config_addr, 
639            0x80|(bus<<8)|(dev_fn<<16)|((offset&~3)<<24));
640   out_le16((volatile u_short *)(pci->config_data + (offset&3)), val);
641   return PCIBIOS_SUCCESSFUL;
642}
643
644static int
645indirect_pci_write_config_dword(unsigned char bus, unsigned char dev_fn, 
646                                unsigned char offset, unsigned int val) {
647   if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;
648   out_be32(pci->config_addr, 
649            0x80|(bus<<8)|(dev_fn<<16)|(offset<<24));
650   out_le32((volatile u_int *)pci->config_data, val);
651   return PCIBIOS_SUCCESSFUL;
652}
653
654static const struct pci_config_access_functions indirect_functions = {
655   indirect_pci_read_config_byte,
656   indirect_pci_read_config_word,
657   indirect_pci_read_config_dword,
658   indirect_pci_write_config_byte,
659   indirect_pci_write_config_word,
660   indirect_pci_write_config_dword
661};
662
663
664static int
665direct_pci_read_config_byte(unsigned char bus, unsigned char dev_fn, 
666                            unsigned char offset, unsigned char *val) {
667   if (bus != 0 || (1<<PCI_SLOT(dev_fn) & 0xff8007fe)) {
668      *val=0xff;
669      return PCIBIOS_DEVICE_NOT_FOUND;
670   }
671   *val=in_8(pci->config_data + ((1<<PCI_SLOT(dev_fn))&~1) 
672             + (PCI_FUNC(dev_fn)<<8) + offset);
673   return PCIBIOS_SUCCESSFUL;
674}
675
676static int
677direct_pci_read_config_word(unsigned char bus, unsigned char dev_fn, 
678                            unsigned char offset, unsigned short *val) {
679   *val = 0xffff; 
680   if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;
681   if (bus != 0 || (1<<PCI_SLOT(dev_fn) & 0xff8007fe)) {
682      return PCIBIOS_DEVICE_NOT_FOUND;
683   }
684   *val=in_le16((volatile u_short *)
685                (pci->config_data + ((1<<PCI_SLOT(dev_fn))&~1)
686                 + (PCI_FUNC(dev_fn)<<8) + offset));
687   return PCIBIOS_SUCCESSFUL;
688}
689
690static int
691direct_pci_read_config_dword(unsigned char bus, unsigned char dev_fn, 
692                             unsigned char offset, unsigned int *val) {
693   *val = 0xffffffff; 
694   if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;
695   if (bus != 0 || (1<<PCI_SLOT(dev_fn) & 0xff8007fe)) {
696      return PCIBIOS_DEVICE_NOT_FOUND;
697   }
698   *val=in_le32((volatile u_int *)
699                (pci->config_data + ((1<<PCI_SLOT(dev_fn))&~1)
700                 + (PCI_FUNC(dev_fn)<<8) + offset));
701   return PCIBIOS_SUCCESSFUL;
702}
703
704static int
705direct_pci_write_config_byte(unsigned char bus, unsigned char dev_fn, 
706                             unsigned char offset, unsigned char val) {
707   if (bus != 0 || (1<<PCI_SLOT(dev_fn) & 0xff8007fe)) {
708      return PCIBIOS_DEVICE_NOT_FOUND;
709   }
710   out_8(pci->config_data + ((1<<PCI_SLOT(dev_fn))&~1) 
711         + (PCI_FUNC(dev_fn)<<8) + offset, 
712         val);
713   return PCIBIOS_SUCCESSFUL;
714}
715
716static int
717direct_pci_write_config_word(unsigned char bus, unsigned char dev_fn, 
718                             unsigned char offset, unsigned short val) {
719   if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;
720   if (bus != 0 || (1<<PCI_SLOT(dev_fn) & 0xff8007fe)) {
721      return PCIBIOS_DEVICE_NOT_FOUND;
722   }
723   out_le16((volatile u_short *)
724            (pci->config_data + ((1<<PCI_SLOT(dev_fn))&~1)
725             + (PCI_FUNC(dev_fn)<<8) + offset),
726            val);
727   return PCIBIOS_SUCCESSFUL;
728}
729
730static int
731direct_pci_write_config_dword(unsigned char bus, unsigned char dev_fn, 
732                              unsigned char offset, unsigned int val) {
733   if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;
734   if (bus != 0 || (1<<PCI_SLOT(dev_fn) & 0xff8007fe)) {
735      return PCIBIOS_DEVICE_NOT_FOUND;
736   }
737   out_le32((volatile u_int *)
738            (pci->config_data + ((1<<PCI_SLOT(dev_fn))&~1)
739             + (PCI_FUNC(dev_fn)<<8) + offset),
740            val);
741   return PCIBIOS_SUCCESSFUL;
742}
743
744static const struct pci_config_access_functions direct_functions = {
745   direct_pci_read_config_byte,
746   direct_pci_read_config_word,
747   direct_pci_read_config_dword,
748   direct_pci_write_config_byte,
749   direct_pci_write_config_word,
750   direct_pci_write_config_dword
751};
752
753
754
755
756
757
758void pci_read_bases(struct pci_dev *dev, unsigned int howmany)
759{
760   unsigned int reg, nextreg;
761
762#define REG (PCI_BASE_ADDRESS_0 + (reg<<2))
763
764   u_short cmd;
765   u32 l, ml;
766   pci_read_config_word(dev, PCI_COMMAND, &cmd);
767
768   for(reg=0; reg<howmany; reg=nextreg) 
769   {
770      pci_resource *r;
771
772      nextreg=reg+1;
773      pci_read_config_dword(dev, REG, &l);
774#if 0
775      if (l == 0xffffffff /*AJF || !l*/) continue;
776#endif
777      /* Note that disabling the memory response of a host bridge
778       * would lose data if a DMA transfer were in progress. In a
779       * bootloader we don't care however. Also we can't print any
780       * message for a while since we might just disable the console.
781       */
782      pci_write_config_word(dev, PCI_COMMAND, cmd & 
783                            ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY));
784      pci_write_config_dword(dev, REG, ~0);
785      pci_read_config_dword(dev, REG, &ml);
786      pci_write_config_dword(dev, REG, l);
787
788      /* Reenable the device now that we've played with
789       * base registers.
790       */
791      pci_write_config_word(dev, PCI_COMMAND, cmd);
792
793      /* seems to be an unused entry skip it */
794      if ( ml == 0 || ml == 0xffffffff ) continue;
795
796      if ((l & 
797           (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK))
798          == (PCI_BASE_ADDRESS_MEM_TYPE_64
799              |PCI_BASE_ADDRESS_SPACE_MEMORY)) {
800         nextreg=reg+2;
801      }
802      dev->base_address[reg] = l;
803      r = salloc(sizeof(pci_resource));
804      if (!r) {
805         printk("Error allocating pci_resource struct.\n");
806         continue;
807      }
808      r->dev = dev;
809      r->reg = reg;
810      if ((l&PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
811         r->type = l&~PCI_BASE_ADDRESS_IO_MASK;
812         r->base = l&PCI_BASE_ADDRESS_IO_MASK;
813         r->size = ~(ml&PCI_BASE_ADDRESS_IO_MASK)+1;
814      } else {
815         r->type = l&~PCI_BASE_ADDRESS_MEM_MASK;
816         r->base = l&PCI_BASE_ADDRESS_MEM_MASK;
817         r->size = ~(ml&PCI_BASE_ADDRESS_MEM_MASK)+1;
818      }
819      /* Check for the blacklisted entries */
820      insert_resource(r);
821   }
822}
823
824
825
826
827
828
829
830
831u_int pci_scan_bus(struct pci_bus *bus)
832{
833   unsigned int devfn, l, max, class;
834   unsigned char irq, hdr_type, is_multi = 0;
835   struct pci_dev *dev, **bus_last;
836   struct pci_bus *child;
837
838#if 0
839   printk("scanning pci bus %d\n", bus->number );
840#endif
841
842   bus_last = &bus->devices;
843   max = bus->secondary;
844   for (devfn = 0; devfn < 0xff; ++devfn) {
845      if (PCI_FUNC(devfn) && !is_multi) {
846         /* not a multi-function device */
847         continue;
848      }
849      if (pcibios_read_config_byte(bus->number, devfn, PCI_HEADER_TYPE, &hdr_type))
850         continue;
851      if (!PCI_FUNC(devfn))
852         is_multi = hdr_type & 0x80;
853
854      if (pcibios_read_config_dword(bus->number, devfn, PCI_VENDOR_ID, &l) ||
855          /* some broken boards return 0 if a slot is empty: */
856          l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || l == 0xffff0000) {
857         is_multi = 0;
858         continue;
859      }
860
861      dev = salloc(sizeof(*dev));
862      dev->bus = bus;
863      dev->devfn  = devfn;
864      dev->vendor = l & 0xffff;
865      dev->device = (l >> 16) & 0xffff;
866
867      pcibios_read_config_dword(bus->number, devfn, 
868                                PCI_CLASS_REVISION, &class);
869      class >>= 8;                                  /* upper 3 bytes */
870      dev->class = class;
871      class >>= 8;
872      dev->hdr_type = hdr_type;
873
874      switch (hdr_type & 0x7f) {                    /* header type */
875         case PCI_HEADER_TYPE_NORMAL:               /* standard header */
876            if (class == PCI_CLASS_BRIDGE_PCI)
877               goto bad;
878            /*
879             * If the card generates interrupts, read IRQ number
880             * (some architectures change it during pcibios_fixup())
881             */
882            pcibios_read_config_byte(bus->number, dev->devfn, PCI_INTERRUPT_PIN, &irq);
883            if (irq)
884               pcibios_read_config_byte(bus->number, dev->devfn, PCI_INTERRUPT_LINE, &irq);
885            dev->irq = irq;
886            /*
887             * read base address registers, again pcibios_fixup() can
888             * tweak these
889             */
890            pci_read_bases(dev, 6);
891            pcibios_read_config_dword(bus->number, devfn, PCI_ROM_ADDRESS, &l);
892            dev->rom_address = (l == 0xffffffff) ? 0 : l;
893            break;
894         case PCI_HEADER_TYPE_BRIDGE:               /* bridge header */
895            if (class != PCI_CLASS_BRIDGE_PCI)
896               goto bad;
897            pci_read_bases(dev, 2);
898            pcibios_read_config_dword(bus->number, devfn, PCI_ROM_ADDRESS1, &l);
899            dev->rom_address = (l == 0xffffffff) ? 0 : l;
900            break;
901         case PCI_HEADER_TYPE_CARDBUS:              /* CardBus bridge header */
902            if (class != PCI_CLASS_BRIDGE_CARDBUS)
903               goto bad;
904            pci_read_bases(dev, 1);
905            break;
906
907         default:                                   /* unknown header */
908        bad:
909            printk("PCI device with unknown header type %d ignored.\n",
910                   hdr_type&0x7f);
911            continue;
912      }
913
914      /*
915       * Put it into the global PCI device chain. It's used to
916       * find devices once everything is set up.
917       */
918      *pci->last_dev_p = dev;
919      pci->last_dev_p = &dev->next;
920
921      /*
922       * Now insert it into the list of devices held
923       * by the parent bus.
924       */
925      *bus_last = dev;
926      bus_last = &dev->sibling;
927
928   }
929
930   /*
931    * After performing arch-dependent fixup of the bus, look behind
932    * all PCI-to-PCI bridges on this bus.
933    */
934   for(dev=bus->devices; dev; dev=dev->sibling)
935      /*
936       * If it's a bridge, scan the bus behind it.
937       */
938      if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
939         unsigned int buses;
940         unsigned int devfn = dev->devfn;
941         unsigned short cr;
942
943         /*
944          * Insert it into the tree of buses.
945          */
946         child = salloc(sizeof(*child));
947         child->next = bus->children;
948         bus->children = child;
949         child->self = dev;
950         child->parent = bus;
951
952         /*
953          * Set up the primary, secondary and subordinate
954          * bus numbers.
955          */
956         child->number = child->secondary = ++max;
957         child->primary = bus->secondary;
958         child->subordinate = 0xff;
959         /*
960          * Clear all status bits and turn off memory,
961          * I/O and master enables.
962          */
963         pcibios_read_config_word(bus->number, devfn, PCI_COMMAND, &cr);
964         pcibios_write_config_word(bus->number, devfn, PCI_COMMAND, 0x0000);
965         pcibios_write_config_word(bus->number, devfn, PCI_STATUS, 0xffff);
966         /*
967          * Read the existing primary/secondary/subordinate bus
968          * number configuration to determine if the PCI bridge
969          * has already been configured by the system.  If so,
970          * do not modify the configuration, merely note it.
971          */
972         pcibios_read_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, &buses);
973         if ((buses & 0xFFFFFF) != 0)
974         {
975            unsigned int cmax;
976
977            child->primary = buses & 0xFF;
978            child->secondary = (buses >> 8) & 0xFF;
979            child->subordinate = (buses >> 16) & 0xFF;
980            child->number = child->secondary;
981            cmax = pci_scan_bus(child);
982            if (cmax > max) max = cmax;
983         }
984         else
985         {
986            /*
987             * Configure the bus numbers for this bridge:
988             */
989            buses &= 0xff000000;
990            buses |=
991               (((unsigned int)(child->primary)     <<  0) |
992                ((unsigned int)(child->secondary)   <<  8) |
993                ((unsigned int)(child->subordinate) << 16));
994            pcibios_write_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, buses);
995            /*
996             * Now we can scan all subordinate buses:
997             */
998            max = pci_scan_bus(child);
999            /*
1000             * Set the subordinate bus number to its real
1001             * value:
1002             */
1003            child->subordinate = max;
1004            buses = (buses & 0xff00ffff)
1005               | ((unsigned int)(child->subordinate) << 16);
1006            pcibios_write_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, buses);
1007         }
1008         pcibios_write_config_word(bus->number, devfn, PCI_COMMAND, cr );
1009      }
1010
1011   /*
1012    * We've scanned the bus and so we know all about what's on
1013    * the other side of any bridges that may be on this bus plus
1014    * any devices.
1015    *
1016    * Return how far we've got finding sub-buses.
1017    */
1018   return max;
1019}
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030#if 0
1031
1032void
1033pci_fixup(void)
1034{
1035   struct pci_dev *p;
1036   struct pci_bus *bus;
1037
1038   for (bus = &pci_root; bus; bus=bus->next)
1039   {
1040      for (p=bus->devices; p; p=p->sibling)
1041      {
1042      }
1043   }
1044}
1045
1046
1047
1048
1049
1050
1051static void print_pci_info()
1052{
1053   pci_resource *r;
1054   struct pci_bus *pb = &pci_root;
1055
1056   printk("\n");
1057   printk("PCI busses:\n");
1058
1059   for(pb= &pci_root; pb; pb=pb->children )
1060   {
1061      printk("   number %d, primary %d, secondary %d, subordinate %d\n",
1062             pb->number,
1063             pb->primary,
1064             pb->secondary,
1065             pb->subordinate );
1066      printk("   bridge; vendor %04x, device %04x\n",
1067             pb->self->vendor,
1068             pb->self->device );
1069
1070      {
1071         struct pci_dev *pd;
1072
1073         for(pd= pb->devices; pd; pd=pd->sibling )
1074         {
1075            printk("       vendor %04x, device %04x, irq %d\n",
1076                   pd->vendor,
1077                   pd->device,
1078                   pd->irq );
1079           
1080         }
1081         printk("\n");
1082      }
1083
1084   }
1085   printk("\n");
1086
1087   printk("PCI resources:\n");
1088   for (r=pci->resources; r; r= r->next)
1089   {
1090      printk("   bus %d, vendor %04x, device %04x, base %08x, size %08x, type %d\n",
1091             r->dev->bus->number,
1092             r->dev->vendor,
1093             r->dev->device,
1094             r->base,
1095             r->size,
1096             r->type );
1097   }
1098   printk("\n");
1099
1100   return;
1101}
1102
1103#endif
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116static struct _addr_start
1117{
1118      unsigned32 start_pcimem;
1119      unsigned32 start_pciio;
1120      unsigned32 start_prefetch;
1121} astart;
1122
1123
1124
1125
1126
1127static pci_resource *enum_device_resources( struct pci_dev *pdev, int i )
1128{
1129   pci_resource *r;
1130
1131   for(r= pci->resources; r; r= r->next )
1132   {
1133      if( r->dev == pdev )
1134      {
1135         if( i-- == 0 ) break;
1136      }
1137   }
1138   return r;
1139}
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149static void recursive_bus_reconfigure( struct pci_bus *pbus )
1150{
1151   struct pci_dev       *pdev;
1152   struct pci_bus       *childbus;
1153   int  isroot = 0;
1154
1155
1156   if( !pbus )
1157   {
1158      /* start with the root bus */
1159      astart.start_pcimem   = BUSREST_MEM_START;
1160      astart.start_pciio    = BUSREST_IO_START;
1161      astart.start_prefetch = ((BUSREST_MEM_END >> 16) << 16);
1162
1163      pbus = &pci_root;
1164      isroot = -1;
1165   }
1166
1167
1168#define WRITE_BRIDGE_IO
1169#define WRITE_BRIDGE_MEM
1170#define WRITE_BRIDGE_PF
1171#define WRITE_BRIDGE_ENABLE
1172
1173
1174/*
1175** Run thru the p2p bridges on this bus and recurse into subordinate busses
1176*/
1177   for( childbus= pbus->children; childbus; childbus= childbus->next )
1178   {
1179      pdev= childbus->self;
1180
1181      {
1182         struct _addr_start   addrhold;
1183         unsigned8            base8, limit8;
1184         unsigned16           base16, limit16, ubase16, ulimit16;
1185
1186         /* save the base address values */
1187         memcpy( &addrhold, &astart, sizeof(struct _addr_start));
1188
1189         recursive_bus_reconfigure( childbus );
1190
1191#ifdef PCI_DEBUG
1192         printk("pci: configuring bus %d bridge (%04x:%04x), bus %d : (%d-%d)\n",
1193                pdev->bus->number,
1194                pdev->vendor,
1195                pdev->device,
1196                childbus->primary,
1197                childbus->secondary,
1198                childbus->subordinate );
1199#endif
1200
1201   
1202
1203         /*
1204         **use the current values & the saved ones to figure out
1205         ** the address spaces for the bridge
1206         */
1207
1208         if( addrhold.start_pciio == astart.start_pciio )
1209         {
1210            base8 = limit8 = 0xff;
1211            ubase16 = ulimit16 = 0xffff;
1212         }
1213         else
1214         {
1215            base8    = (unsigned8) ((addrhold.start_pciio >> 8) & 0xf0);
1216            ubase16  = (unsigned16)(addrhold.start_pciio >> 16);
1217            limit8   = (unsigned8) ((astart.start_pciio >> 8 ) & 0xf0);
1218            ulimit16 = (unsigned16)(astart.start_pciio >> 16);
1219            astart.start_pciio += 0x1000;
1220         }
1221
1222#ifdef PCI_DEBUG
1223         printk("pci:     io base %08x limit %08x\n", (base8<<8)+(ubase16<<16), (limit8<<8)+(ulimit16<<16));
1224#endif
1225#ifdef WRITE_BRIDGE_IO
1226         pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_IO_BASE_UPPER16, ubase16 );
1227         pcibios_write_config_byte(pdev->bus->number, pdev->devfn, PCI_IO_BASE, base8 );
1228
1229         pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_IO_LIMIT_UPPER16, ulimit16 );
1230         pcibios_write_config_byte(pdev->bus->number, pdev->devfn, PCI_IO_LIMIT, limit8 );
1231#endif
1232
1233
1234
1235
1236         if( addrhold.start_pcimem == astart.start_pcimem )
1237         {
1238            limit16 = 0;
1239            base16 = 0xffff;
1240         }
1241         else
1242         {
1243            limit16= (unsigned16)((astart.start_pcimem >> 16) & 0xfff0);
1244            base16 = (unsigned16)((addrhold.start_pcimem >> 16) & 0xfff0);
1245            astart.start_pcimem += 0x100000;
1246         }
1247#ifdef PCI_DEBUG
1248         printk("pci:      memory %04x, limit %04x\n", base16, limit16);
1249#endif
1250#ifdef WRITE_BRIDGE_MEM
1251         pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_MEMORY_BASE, base16 );
1252         pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_MEMORY_LIMIT, limit16 );
1253#endif
1254
1255
1256
1257         if( astart.start_prefetch == addrhold.start_prefetch )
1258         {
1259            limit16 = 0;
1260            base16 = 0xffff;
1261         }
1262         else
1263         {
1264            limit16= (unsigned16)((addrhold.start_prefetch >> 16) & 0xfff0);
1265            base16 = (unsigned16)((astart.start_prefetch >> 16) & 0xfff0);
1266            astart.start_prefetch -= 0x100000;
1267         }
1268#ifdef PCI_DEBUG
1269         printk("pci:   pf memory %04x, limit %04x\n", base16, limit16);
1270#endif
1271#ifdef WRITE_BRIDGE_PF
1272         pcibios_write_config_dword(pdev->bus->number, pdev->devfn, PCI_PREF_BASE_UPPER32, 0); 
1273         pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_PREF_MEMORY_BASE, base16 );
1274         pcibios_write_config_dword(pdev->bus->number, pdev->devfn, PCI_PREF_LIMIT_UPPER32, 0);
1275         pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_PREF_MEMORY_LIMIT, limit16 );
1276
1277#endif
1278
1279#ifdef WRITE_BRIDGE_ENABLE
1280         pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_BRIDGE_CONTROL, (unsigned16)( PCI_BRIDGE_CTL_PARITY |
1281                                                                                                     PCI_BRIDGE_CTL_SERR ));
1282
1283         pcibios_write_config_word(pdev->bus->number, pdev->devfn, PCI_COMMAND, (unsigned16)( PCI_COMMAND_IO | 
1284                                                                                              PCI_COMMAND_MEMORY |
1285                                                                                              PCI_COMMAND_MASTER |
1286                                                                                              PCI_COMMAND_PARITY |
1287                                                                                              PCI_COMMAND_SERR ));
1288#endif
1289      }
1290   }
1291
1292
1293
1294
1295
1296
1297   if( !isroot )
1298   {
1299#ifdef PCI_DEBUG
1300      printk("pci: Configuring devices on bus %d\n", pbus->number);
1301#endif
1302      /*
1303      ** Run thru this bus and set up addresses for all the non-bridge devices
1304      */
1305      for( pdev = pbus->devices; pdev; pdev= pdev->sibling )
1306      {
1307         if( (pdev->class >> 8) != PCI_CLASS_BRIDGE_PCI )
1308         {
1309            pci_resource *r;
1310            int i = 0;
1311            unsigned alloc;
1312
1313            /* enumerate all the resources defined by this device & reserve space
1314            ** for each of their defined regions.
1315            */
1316
1317#ifdef PCI_DEBUG
1318            printk("pci: configuring; vendor %04x, device %04x\n", pdev->vendor, pdev->device );
1319#endif
1320
1321            while( (r= enum_device_resources( pdev, i++ )) )
1322            {
1323               if( r->type & PCI_BASE_ADDRESS_MEM_PREFETCH )
1324               {
1325                  /* prefetchable space */
1326
1327                  /* shift base pointer down to an integer multiple of the size of the desired region */
1328                  astart.start_prefetch -= (alloc= ((r->size / PAGE_SIZE) + 1) * PAGE_SIZE);
1329                  /* shift base pointer down to an integer multiple of the size of the desired region */
1330                  astart.start_prefetch = (astart.start_prefetch / r->size) * r->size;
1331
1332                  r->base = astart.start_prefetch;
1333#ifdef PCI_DEBUG
1334                  printk("pci:       pf %08X, size %08X, alloc %08X\n", r->base, r->size, alloc );
1335#endif
1336               }
1337               else if( r->type & PCI_BASE_ADDRESS_SPACE_IO )
1338               {
1339                  /* io space */
1340
1341                  /* shift base pointer up to an integer multiple of the size of the desired region */
1342                  if( astart.start_pciio % r->size )
1343                     astart.start_pciio = (((astart.start_pciio / r->size) + 1) * r->size);
1344
1345                  r->base = astart.start_pciio;
1346                  astart.start_pciio += (alloc= ((r->size / PAGE_SIZE) + 1) * PAGE_SIZE);
1347#ifdef PCI_DEBUG
1348                  printk("pci:      io  %08X, size %08X, alloc %08X\n", r->base, r->size, alloc );
1349#endif
1350               }
1351               else
1352               {
1353                  /* memory space */
1354                 
1355                  /* shift base pointer up to an integer multiple of the size of the desired region */
1356                  if( astart.start_pcimem % r->size )
1357                     astart.start_pcimem = (((astart.start_pcimem / r->size) + 1) * r->size);
1358
1359                  r->base = astart.start_pcimem;
1360                  astart.start_pcimem += (alloc= ((r->size / PAGE_SIZE) + 1) * PAGE_SIZE);
1361#ifdef PCI_DEBUG
1362                  printk("pci:      mem %08X, size %08X, alloc %08X\n", r->base, r->size, alloc );
1363#endif
1364               }
1365            }
1366
1367         }
1368      }
1369   }
1370
1371}
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382void pci_init(void) 
1383{
1384   PPC_DEVICE *hostbridge;
1385
1386   if (pci->last_dev_p) {
1387      printk("Two or more calls to pci_init!\n");
1388      return;
1389   }
1390   pci->last_dev_p = &(bd->pci_devices);
1391   hostbridge=residual_find_device(PROCESSORDEVICE, NULL, 
1392                                   BridgeController,
1393                                   PCIBridge, -1, 0);
1394   if (hostbridge) {
1395      if (hostbridge->DeviceId.Interface==PCIBridgeIndirect) {
1396         bd->pci_functions=&indirect_functions;
1397         /* Should be extracted from residual data,
1398          * indeed MPC106 in CHRP mode is different,
1399          * but we should not use residual data in
1400          * this case anyway.
1401          */
1402         pci->config_addr = ((volatile u_int *) 
1403                             (ptr_mem_map->io_base+0xcf8));
1404         pci->config_data = ptr_mem_map->io_base+0xcfc;
1405      } else if(hostbridge->DeviceId.Interface==PCIBridgeDirect) {
1406         bd->pci_functions=&direct_functions;
1407         pci->config_data=(u_char *) 0x80800000;
1408      } else {
1409      }
1410   } else {
1411      /* Let us try by experimentation at our own risk! */
1412      u_int id0;
1413      bd->pci_functions = &direct_functions;
1414      /* On all direct bridges I know the host bridge itself
1415       * appears as device 0 function 0.
1416       */
1417      pcibios_read_config_dword(0, 0, PCI_VENDOR_ID, &id0);
1418      if (id0==~0U) {
1419         bd->pci_functions = &indirect_functions;
1420         pci->config_addr = ((volatile u_int *)
1421                             (ptr_mem_map->io_base+0xcf8));
1422         pci->config_data = ptr_mem_map->io_base+0xcfc;
1423      }
1424      /* Here we should check that the host bridge is actually
1425       * present, but if it not, we are in such a desperate
1426       * situation, that we probably can't even tell it.
1427       */
1428   }
1429   /* Now build a small database of all found PCI devices */
1430   printk("\nPCI: Probing PCI hardware\n");
1431   pci_root.subordinate=pci_scan_bus(&pci_root);
1432
1433   print_pci_resources("Installed PCI resources:\n");
1434
1435   recursive_bus_reconfigure(NULL);
1436
1437   reconfigure_pci();
1438
1439   print_pci_resources("Allocated PCI resources:\n");
1440}
1441
1442
1443/* eof */
Note: See TracBrowser for help on using the repository browser.