]>
Commit | Line | Data |
---|---|---|
c7de829c WD |
1 | /* |
2 | * (C) Copyright 2002 | |
3 | * Hyperion Entertainment, [email protected] | |
4 | * | |
5 | * See file CREDITS for list of people who contributed to this | |
6 | * project. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License as | |
10 | * published by the Free Software Foundation; either version 2 of | |
11 | * the License, or (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | * MA 02111-1307 USA | |
22 | */ | |
23 | ||
24 | #include <common.h> | |
25 | #include <pci.h> | |
26 | #include "memio.h" | |
27 | #include "articiaS.h" | |
28 | ||
29 | //#define ARTICIA_PCI_DEBUG | |
30 | ||
31 | #ifdef ARTICIA_PCI_DEBUG | |
32 | #define PRINTF(fmt,args...) printf (fmt ,##args) | |
33 | #else | |
34 | #define PRINTF(fmt,args...) | |
35 | #endif | |
36 | ||
37 | struct pci_controller articiaS_hose; | |
38 | ||
39 | long irq_alloc(long wanted); | |
40 | ||
41 | static pci_dev_t pci_hose_find_class(struct pci_controller *hose, int bus, short find_class, int index); | |
42 | static int articiaS_init_vga(void); | |
43 | static void pci_cfgfunc_dummy(struct pci_controller *host, pci_dev_t dev, struct pci_config_table *table); | |
44 | unsigned char pci_irq_alloc(void); | |
45 | ||
46 | extern void via_cfgfunc_via686(struct pci_controller * host, pci_dev_t dev, struct pci_config_table *table); | |
47 | extern void via_cfgfunc_ide_init(struct pci_controller *host, pci_dev_t dev, struct pci_config_table *table); | |
48 | extern void via_init_irq_routing(uint8 []); | |
49 | extern void via_init_afterscan(void); | |
50 | ||
51 | #define cfgfunc_via686 1 | |
52 | #define cfgfunc_dummy 2 | |
53 | #define cfgfunc_ide_init 3 | |
54 | ||
55 | static struct pci_config_table config_table[] = | |
56 | { | |
57 | { | |
58 | 0x1106, PCI_ANY_ID, PCI_CLASS_BRIDGE_ISA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | |
59 | (void *)cfgfunc_via686, {0, 0, 0} | |
60 | }, | |
61 | { | |
62 | 0x1106, PCI_ANY_ID, PCI_ANY_ID, 0,7,4, | |
63 | (void *)cfgfunc_dummy, {0,0,0} | |
64 | }, | |
65 | { | |
66 | 0x1106, 0x3068, PCI_ANY_ID, 0, 7, PCI_ANY_ID, | |
67 | (void *)cfgfunc_dummy, {0,0,0} | |
68 | }, | |
69 | { | |
70 | 0x1106, PCI_ANY_ID, PCI_ANY_ID, 0,7,1, | |
71 | (void *)cfgfunc_ide_init, {0,0,0} | |
72 | }, | |
73 | { | |
74 | 0, | |
75 | } | |
76 | }; | |
77 | ||
78 | ||
79 | void pci_cfgfunc_dummy(struct pci_controller *host, pci_dev_t dev, struct pci_config_table *table) | |
80 | { | |
81 | ||
82 | ||
83 | } | |
84 | ||
85 | unsigned long irq_penalties[16] = | |
86 | { | |
87 | 1000, /* 0:timer */ | |
88 | 1000, /* 1:keyboard */ | |
89 | 1000, /* 2:cascade */ | |
90 | 50, /* 3:serial (COM2) */ | |
91 | 50, /* 4:serial (COM1) */ | |
92 | 4, /* 5:USB2 */ | |
93 | 100, /* 6:floppy */ | |
94 | 3, /* 7:parallel */ | |
95 | 50, /* 8:AC97/MC97 */ | |
96 | 0, /* 9: */ | |
97 | 3, /* 10:: */ | |
98 | 0, /* 11: */ | |
99 | 3, /* 12: USB1 */ | |
100 | 0, /* 13: */ | |
101 | 100, /* 14: ide0 */ | |
102 | 100, /* 15: ide1 */ | |
103 | }; | |
104 | ||
105 | ||
106 | /* | |
107 | * The following defines a hard-coded interrupt mapping for the | |
108 | * know devices on the board. | |
109 | * If a device isn't found here, assumed to be a device that's | |
110 | * plugged into a PCI or AGP slot | |
111 | * NOTE: This table is machine dependant. | |
112 | */ | |
113 | ||
114 | struct pci_irq_fixup_table | |
115 | { | |
116 | uint8 bus; /* Bus number */ | |
117 | uint8 device; /* Device number */ | |
118 | uint8 func; /* Function number */ | |
119 | uint8 interrupt; /* Interrupt to use (0xff to disable) */ | |
120 | }; | |
121 | ||
122 | struct pci_irq_fixup_table fixuptab [] = | |
123 | { | |
124 | { 0, 0, 0, 0xff}, /* Articia S host bridge */ | |
125 | { 0, 1, 0, 0xff}, /* Articia S AGP bridge */ | |
126 | // { 0, 6, 0, 0x05}, /* 3COM ethernet */ | |
127 | { 0, 7, 0, 0xff}, /* VIA southbridge */ | |
128 | { 0, 7, 1, 0x0e}, /* IDE controller in legacy mode */ | |
129 | // { 0, 7, 2, 0x05}, /* First USB controller */ | |
130 | // { 0, 7, 3, 0x0c}, /* Second USB controller (shares interrupt with ethernet) */ | |
131 | { 0, 7, 4, 0xff}, /* ACPI Power Management */ | |
132 | // { 0, 7, 5, 0x08}, /* AC97 */ | |
133 | // { 0, 7, 6, 0x08}, /* MC97 */ | |
134 | { 0xff, 0xff, 0xff, 0xff} | |
135 | }; | |
136 | ||
137 | ||
138 | /* | |
139 | * This table maps IRQ's to PCI interrupts | |
140 | */ | |
141 | ||
142 | uint8 pci_intmap[4] = {0, 0, 0, 0}; | |
143 | ||
144 | /* | |
145 | * Map PCI slots to interrupt routings | |
146 | * This table lists the device number assigned to a card inserted | |
147 | * into the slot, along with a permutation for the slot's IRQ routing. | |
148 | * NOTE: This table is machine dependant. | |
149 | */ | |
150 | ||
151 | struct pci_slot_irq_routing | |
152 | { | |
153 | uint8 bus; | |
154 | uint8 device; | |
155 | ||
156 | uint8 ints[4]; | |
157 | }; | |
158 | ||
159 | struct pci_slot_irq_routing amigaone_pci_routing[] = | |
160 | { | |
161 | {0, 8, {0, 1, 2, 3}}, /* Slot 1 (left of riser slot) */ | |
162 | {0, 9, {1, 2, 3, 0}}, /* Slot 2 (middle slot) */ | |
163 | {0, 10, {2, 3, 0, 1}}, /* Slot 3 (leftmost slot) */ | |
164 | {1, 0, {1, 0, 2, 3}}, /* AGP slot (only IRQA and IRQB) */ | |
165 | {1, 1, {1, 2, 3, 0}}, /* PCI slot on AGP bus */ | |
166 | {0, 6, {3, 3, 3, 3}}, /* On board ethernet */ | |
167 | {0, 7, {0, 1, 2, 3}}, /* Southbridge */ | |
168 | {0xff, 0, {0, 0, 0, 0}} | |
169 | }; | |
170 | ||
171 | void articiaS_pci_irq_init(void) | |
172 | { | |
173 | char *s; | |
174 | ||
175 | s = getenv("pci_irqa"); | |
176 | if (s) | |
177 | pci_intmap[0] = simple_strtoul (s, NULL, 10); | |
178 | else | |
179 | pci_intmap[0] = pci_irq_alloc(); | |
180 | ||
181 | s = getenv("pci_irqb"); | |
182 | if (s) | |
183 | pci_intmap[1] = simple_strtoul (s, NULL, 10); | |
184 | else | |
185 | pci_intmap[1] = pci_irq_alloc(); | |
186 | ||
187 | s = getenv("pci_irqc"); | |
188 | if (s) | |
189 | pci_intmap[2] = simple_strtoul (s, NULL, 10); | |
190 | else | |
191 | pci_intmap[2] = pci_irq_alloc(); | |
192 | ||
193 | s = getenv("pci_irqd"); | |
194 | if (s) | |
195 | pci_intmap[3] = simple_strtoul (s, NULL, 10); | |
196 | else | |
197 | pci_intmap[3] = pci_irq_alloc(); | |
198 | } | |
199 | ||
200 | ||
201 | unsigned char pci_irq_alloc(void) | |
202 | { | |
203 | int i; | |
204 | int interrupt = 10; | |
205 | unsigned long min_penalty = 1000; | |
206 | ||
207 | /* Search for the minimal penalty, favoring interrupts at the end */ | |
208 | for (i = 0; i < 16; i++) | |
209 | { | |
210 | if (irq_penalties[i] <= min_penalty) | |
211 | { | |
212 | interrupt = i; | |
213 | min_penalty = irq_penalties[i]; | |
214 | } | |
215 | } | |
216 | ||
217 | PRINTF("pci_irq_alloc: Minimal penalty is %ld for %d\n", min_penalty, interrupt); | |
218 | ||
219 | irq_penalties[interrupt]++; | |
220 | ||
221 | return interrupt; | |
222 | } | |
223 | ||
224 | ||
225 | void articiaS_pci_fixup_irq(struct pci_controller *hose, pci_dev_t dev) | |
226 | { | |
227 | int8 bus, device, func, pin, line; | |
228 | int i; | |
229 | ||
230 | bus = PCI_BUS(dev); | |
231 | device = PCI_DEV(dev); | |
232 | func = PCI_FUNC(dev); | |
233 | ||
234 | PRINTF("Fixup irq of %d:%d.%d\n", bus, device, func); | |
235 | ||
236 | /* Search for the device in the table */ | |
237 | for (i = 0; fixuptab[i].bus != 0xff; i++) | |
238 | { | |
239 | if (bus == fixuptab[i].bus && device == fixuptab[i].device && func == fixuptab[i].func) | |
240 | { | |
241 | /* If the device needs an interrupt, write it */ | |
242 | if (fixuptab[i].interrupt != 0xff) | |
243 | { | |
244 | PRINTF("Assigning IRQ %d (fixed)\n", fixuptab[i].interrupt); | |
245 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, fixuptab[i].interrupt); | |
246 | } | |
247 | else | |
248 | { | |
249 | /* Otherwise, see if it wants an interrupt, and disable it if needed */ | |
250 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); | |
251 | if (pin) | |
252 | { | |
253 | PRINTF("Disabling IRQ\n"); | |
254 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 0xff); | |
255 | } | |
256 | } | |
257 | ||
258 | return; | |
259 | } | |
260 | } | |
261 | ||
262 | /* If we get here, we have another PCI device in a slot... find the appropriate IRQ */ | |
263 | ||
264 | /* Find matching pin */ | |
265 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); | |
266 | pin--; | |
267 | ||
268 | /* Search for it's map */ | |
269 | for (i = 0; amigaone_pci_routing[i].bus != 0xff; i++) | |
270 | { | |
271 | if (bus == amigaone_pci_routing[i].bus && device == amigaone_pci_routing[i].device) | |
272 | { | |
273 | line = pci_intmap[amigaone_pci_routing[i].ints[pin]]; | |
274 | PRINTF("Assigning IRQ %d (pin %d)\n", line, pin); | |
275 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, line); | |
276 | return; | |
277 | } | |
278 | } | |
279 | ||
280 | PRINTF("Unkonwn PCI device found\n"); | |
281 | } | |
282 | ||
283 | void articiaS_pci_init (void) | |
284 | { | |
285 | int i; | |
286 | char *s; | |
287 | ||
288 | PRINTF("atriciaS_pci_init\n"); | |
289 | ||
290 | // Why aren't these relocated?? | |
291 | for (i=0; config_table[i].config_device; i++) | |
292 | { | |
293 | switch((int)config_table[i].config_device) | |
294 | { | |
295 | case cfgfunc_via686: config_table[i].config_device = via_cfgfunc_via686; break; | |
296 | case cfgfunc_dummy: config_table[i].config_device = pci_cfgfunc_dummy; break; | |
297 | case cfgfunc_ide_init: config_table[i].config_device = via_cfgfunc_ide_init; break; | |
298 | default: PRINTF("Error: Unknown constant\n"); | |
299 | } | |
300 | } | |
301 | ||
302 | articiaS_hose.first_busno = 0; | |
303 | articiaS_hose.last_busno = 0xff; | |
304 | articiaS_hose.config_table = config_table; | |
305 | articiaS_hose.fixup_irq = articiaS_pci_fixup_irq; | |
306 | ||
307 | articiaS_pci_irq_init(); | |
308 | ||
309 | /* System memory */ | |
310 | pci_set_region(articiaS_hose.regions + 0, | |
311 | ARTICIAS_SYS_BUS, | |
312 | ARTICIAS_SYS_PHYS, | |
313 | ARTICIAS_SYS_MAXSIZE, | |
314 | PCI_REGION_MEM | PCI_REGION_MEMORY); | |
315 | ||
316 | /* PCI memory space */ | |
317 | pci_set_region(articiaS_hose.regions + 1, | |
318 | ARTICIAS_PCI_BUS, | |
319 | ARTICIAS_PCI_PHYS, | |
320 | ARTICIAS_PCI_MAXSIZE, | |
321 | PCI_REGION_MEM); | |
322 | ||
323 | /* PCI io space */ | |
324 | pci_set_region(articiaS_hose.regions + 2, | |
325 | ARTICIAS_PCIIO_BUS, | |
326 | ARTICIAS_PCIIO_PHYS, | |
327 | ARTICIAS_PCIIO_MAXSIZE, | |
328 | PCI_REGION_IO); | |
329 | ||
330 | /* PCI/ISA io space */ | |
331 | pci_set_region(articiaS_hose.regions + 3, | |
332 | ARTICIAS_ISAIO_BUS, | |
333 | ARTICIAS_ISAIO_PHYS, | |
334 | ARTICIAS_ISAIO_MAXSIZE, | |
335 | PCI_REGION_IO); | |
336 | ||
337 | ||
338 | ||
339 | articiaS_hose.region_count = 4; | |
340 | ||
341 | pci_setup_indirect(&articiaS_hose, ARTICIAS_PCI_CFGADDR, ARTICIAS_PCI_CFGDATA); | |
342 | PRINTF("Registering articia hose...\n"); | |
343 | pci_register_hose(&articiaS_hose); | |
344 | PRINTF("Enabling AGP...\n"); | |
345 | pci_write_config_byte(PCI_BDF(0,0,0), 0x58, 0x01); | |
346 | PRINTF("Scanning bus...\n"); | |
347 | articiaS_hose.last_busno = pci_hose_scan(&articiaS_hose); | |
348 | ||
349 | via_init_irq_routing(pci_intmap); | |
350 | ||
351 | PRINTF("After-Scan results:\n"); | |
352 | PRINTF("Bus range: %d - %d\n", articiaS_hose.first_busno , articiaS_hose.last_busno); | |
353 | ||
354 | via_init_afterscan(); | |
355 | ||
356 | pci_write_config_byte(PCI_BDF(0,1,0), PCI_INTERRUPT_LINE, 0xFF); | |
357 | ||
358 | s = getenv("as_irq"); | |
359 | if (s) | |
360 | { | |
361 | pci_write_config_byte(PCI_BDF(0,0,0), PCI_INTERRUPT_LINE, simple_strtoul (s, NULL, 10)); | |
362 | } | |
363 | ||
364 | s = getenv("x86_run_bios"); | |
365 | if (!s || (s && strcmp(s, "on")==0)) | |
366 | { | |
367 | if (articiaS_init_vga() == -1) | |
368 | { | |
369 | /* If the VGA didn't init and we have stdout set to VGA, reset to serial */ | |
370 | /* s = getenv("stdout"); */ | |
371 | /* if (s && strcmp(s, "vga") == 0) */ | |
372 | /* { */ | |
373 | /* setenv("stdout", "serial"); */ | |
374 | /* } */ | |
375 | } | |
376 | } | |
377 | pci_write_config_byte(PCI_BDF(0,1,0), PCI_INTERRUPT_LINE, 0xFF); | |
378 | ||
379 | } | |
380 | ||
381 | pci_dev_t pci_hose_find_class(struct pci_controller *hose, int bus, short find_class, int index) | |
382 | { | |
383 | unsigned int sub_bus, found_multi=0; | |
384 | unsigned short vendor, class; | |
385 | unsigned char header_type; | |
386 | pci_dev_t dev; | |
387 | u8 c1, c2; | |
388 | ||
389 | sub_bus = bus; | |
390 | ||
391 | for (dev = PCI_BDF(bus,0,0); | |
392 | dev < PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1); | |
393 | dev += PCI_BDF(0,0,1)) | |
394 | { | |
395 | if ( dev == PCI_BDF(hose->first_busno,0,0) ) | |
396 | continue; | |
397 | ||
398 | if (PCI_FUNC(dev) && !found_multi) | |
399 | continue; | |
400 | ||
401 | pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type); | |
402 | ||
403 | pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor); | |
404 | ||
405 | if (vendor != 0xffff && vendor != 0x0000) | |
406 | { | |
407 | ||
408 | if (!PCI_FUNC(dev)) | |
409 | found_multi = header_type & 0x80; | |
410 | pci_hose_read_config_byte(hose, dev, 0x0B, &c1); | |
411 | pci_hose_read_config_byte(hose, dev, 0x0A, &c2); | |
412 | class = c1<<8 | c2; | |
413 | //printf("At %02x:%02x:%02x: class %x\n", | |
414 | // PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev), class); | |
415 | if (class == find_class) | |
416 | { | |
417 | if (index == 0) | |
418 | return dev; | |
419 | else index--; | |
420 | } | |
421 | } | |
422 | } | |
423 | ||
424 | return ~0; | |
425 | } | |
426 | ||
427 | ||
428 | /* | |
429 | * For a given bus number, find the bridge on this hose that provides this | |
430 | * bus number. The function scans for bridges and peeks config space offset | |
431 | * 0x19 (PCI_SECONDARY_BUS). | |
432 | */ | |
433 | pci_dev_t pci_find_bridge_for_bus(struct pci_controller *hose, int busnr) | |
434 | { | |
435 | pci_dev_t dev; | |
436 | int bus; | |
437 | unsigned int found_multi=0; | |
438 | unsigned char header_type; | |
439 | unsigned short vendor; | |
440 | unsigned char secondary_bus; | |
441 | ||
442 | if (hose == NULL) hose = &articiaS_hose; | |
443 | ||
444 | if (busnr < hose->first_busno || busnr > hose->last_busno) return PCI_ANY_ID; // Not in range | |
445 | ||
446 | /* | |
447 | * The bridge must be on a lower bus number | |
448 | */ | |
449 | for (bus = hose->first_busno; bus < busnr; bus++) | |
450 | { | |
451 | for (dev = PCI_BDF(bus,0,0); | |
452 | dev < PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1); | |
453 | dev += PCI_BDF(0,0,1)) | |
454 | { | |
455 | if ( dev == PCI_BDF(hose->first_busno,0,0) ) | |
456 | continue; | |
457 | ||
458 | if (PCI_FUNC(dev) && !found_multi) | |
459 | continue; | |
460 | ||
461 | pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type); | |
462 | ||
463 | pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor); | |
464 | ||
465 | if (vendor != 0xffff && vendor != 0x0000) | |
466 | { | |
467 | ||
468 | if (!PCI_FUNC(dev)) | |
469 | found_multi = header_type & 0x80; | |
470 | if (header_type == 1) // Bridge device header | |
471 | { | |
472 | pci_hose_read_config_byte(hose, dev, PCI_SECONDARY_BUS, &secondary_bus); | |
473 | if ((int)secondary_bus == busnr) return dev; | |
474 | } | |
475 | ||
476 | } | |
477 | } | |
478 | } | |
479 | return PCI_ANY_ID; | |
480 | } | |
481 | ||
482 | static short classes[] = | |
483 | { | |
484 | PCI_CLASS_DISPLAY_VGA, | |
485 | PCI_CLASS_DISPLAY_XGA, | |
486 | PCI_CLASS_DISPLAY_3D, | |
487 | PCI_CLASS_DISPLAY_OTHER, | |
488 | ~0 | |
489 | }; | |
490 | ||
491 | extern int execute_bios(pci_dev_t gr_dev, void *); | |
492 | ||
493 | pci_dev_t video_dev; | |
494 | ||
495 | int articiaS_init_vga (void) | |
496 | { | |
497 | DECLARE_GLOBAL_DATA_PTR; | |
498 | ||
499 | extern void shutdown_bios(void); | |
500 | pci_dev_t dev = ~0; | |
501 | int busnr = 0; | |
502 | int classnr = 0; | |
503 | ||
504 | video_dev = PCI_ANY_ID; | |
505 | ||
506 | printf("VGA: "); | |
507 | ||
508 | PRINTF("Trying to initialize x86 VGA Card(s)\n"); | |
509 | ||
510 | while (dev == ~0) | |
511 | { | |
512 | PRINTF("Searching for class 0x%x on bus %d\n", classes[classnr], busnr); | |
513 | /* Find the first of this class on this bus */ | |
514 | dev = pci_hose_find_class(&articiaS_hose, busnr, classes[classnr], 0); | |
515 | if (dev != ~0) break; | |
516 | busnr++; | |
517 | if (busnr > articiaS_hose.last_busno) | |
518 | { | |
519 | busnr = 0; | |
520 | classnr ++; | |
521 | if (classes[classnr] == ~0) | |
522 | { | |
523 | printf("NOT PRESENT\n"); | |
524 | return -1; | |
525 | } | |
526 | } | |
527 | } | |
528 | ||
529 | /* | |
530 | * If we get here we have found the first graphics card. | |
531 | * If the bus number is not 0, then it is probably behind a bridge, and the | |
532 | * bridge needs to be told to forward VGA access. | |
533 | */ | |
534 | ||
535 | if (PCI_BUS(dev) != 0) | |
536 | { | |
537 | pci_dev_t bridge; | |
538 | PRINTF("Behind bridge, looking for bridge\n"); | |
539 | bridge = pci_find_bridge_for_bus(&articiaS_hose, PCI_BUS(dev)); | |
540 | if (dev != PCI_ANY_ID) | |
541 | { | |
542 | unsigned char agp_control_0; | |
543 | PRINTF("Got the bridge at %02x:%02x:%02x\n", | |
544 | PCI_BUS(bridge), PCI_DEV(bridge), PCI_FUNC(bridge)); | |
545 | pci_hose_read_config_byte(&articiaS_hose, bridge, 0x3E, &agp_control_0); | |
546 | agp_control_0 |= 0x18; | |
547 | pci_hose_write_config_byte(&articiaS_hose, bridge, 0x3E, agp_control_0); | |
548 | PRINTF("Configured for VGA forwarding\n"); | |
549 | } | |
550 | } | |
551 | ||
552 | /* | |
553 | * Now try to run the bios | |
554 | */ | |
555 | ||
556 | if (execute_bios(dev, gd->relocaddr)) | |
557 | { | |
558 | printf("OK\n"); | |
559 | video_dev = dev; | |
560 | } | |
561 | else | |
562 | { | |
563 | printf("ERROR\n"); | |
564 | } | |
565 | ||
566 | PRINTF("Done scanning.\n"); | |
567 | ||
568 | shutdown_bios(); | |
569 | ||
570 | if (dev == PCI_ANY_ID) return -1; | |
571 | else return 0; | |
572 | ||
573 | } |