Mercurial > mplayer.hg
annotate vidix/pci.c @ 28615:15e7abed4291
Use the same code to convert fps in float to fraction as used in mencoder,
it ensures all the common frame rates work right.
If this causes issues, it should be changed in the same way in mencoder.c
author | reimar |
---|---|
date | Wed, 18 Feb 2009 16:49:12 +0000 |
parents | 7de310806281 |
children | 0f1b5b68af32 |
rev | line source |
---|---|
3973 | 1 /* |
2 (C) 2002 - library implementation by Nick Kyrshev | |
23734 | 3 XFree86 3.3.3 scanpci.c, modified for GATOS/win/gfxdump by Øyvind Aabling. |
3973 | 4 */ |
5 /* $XConsortium: scanpci.c /main/25 1996/10/27 11:48:40 kaleb $ */ | |
6 /* | |
7 * name: scanpci.c | |
8 * | |
9 * purpose: This program will scan for and print details of | |
10 * devices on the PCI bus. | |
11 | |
12 * author: Robin Cutshaw (robin@xfree86.org) | |
13 * | |
14 * supported O/S's: SVR4, UnixWare, SCO, Solaris, | |
15 * FreeBSD, NetBSD, 386BSD, BSDI BSD/386, | |
16 * Linux, Mach/386, ISC | |
17 * DOS (WATCOM 9.5 compiler) | |
18 * | |
19 * compiling: [g]cc scanpci.c -o scanpci | |
20 * for SVR4 (not Solaris), UnixWare use: | |
21 * [g]cc -DSVR4 scanpci.c -o scanpci | |
22 * for DOS, watcom 9.5: | |
23 * wcc386p -zq -omaxet -7 -4s -s -w3 -d2 name.c | |
24 * and link with PharLap or other dos extender for exe | |
25 * | |
26 */ | |
27 | |
28 /* $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ */ | |
29 | |
30 /* | |
31 * Copyright 1995 by Robin Cutshaw <robin@XFree86.Org> | |
32 * | |
33 * Permission to use, copy, modify, distribute, and sell this software and its | |
34 * documentation for any purpose is hereby granted without fee, provided that | |
35 * the above copyright notice appear in all copies and that both that | |
36 * copyright notice and this permission notice appear in supporting | |
37 * documentation, and that the names of the above listed copyright holder(s) | |
38 * not be used in advertising or publicity pertaining to distribution of | |
39 * the software without specific, written prior permission. The above listed | |
40 * copyright holder(s) make(s) no representations about the suitability of this | |
41 * software for any purpose. It is provided "as is" without express or | |
42 * implied warranty. | |
43 * | |
44 * THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM(S) ALL WARRANTIES WITH REGARD | |
45 * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | |
46 * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE | |
47 * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY | |
48 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |
49 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING | |
50 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
51 * | |
52 */ | |
53 | |
22901 | 54 #include "dha.h" |
4164 | 55 #include <errno.h> |
56 #include <string.h> | |
57 #include <stdio.h> | |
58 #ifdef __unix__ | |
24511 | 59 #define __USE_UNIX98 |
4164 | 60 #include <unistd.h> |
61 #endif | |
62 #include "AsmMacros.h" | |
63 /* OS depended stuff */ | |
27250
dcf62171257b
Remove -std=gnu99/gnu89/default dialect linux define, as it violates the
michael
parents:
27005
diff
changeset
|
64 #if defined (__linux__) |
4164 | 65 #include "sysdep/pci_linux.c" |
21848 | 66 #elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined(__DragonFly__) |
4164 | 67 #include "sysdep/pci_freebsd.c" |
68 #elif defined (__386BSD__) | |
69 #include "sysdep/pci_386bsd.c" | |
70 #elif defined (__NetBSD__) | |
71 #include "sysdep/pci_netbsd.c" | |
72 #elif defined (__OpenBSD__) | |
73 #include "sysdep/pci_openbsd.c" | |
74 #elif defined (__bsdi__) | |
75 #include "sysdep/pci_bsdi.c" | |
76 #elif defined (Lynx) | |
77 #include "sysdep/pci_lynx.c" | |
78 #elif defined (MACH386) | |
79 #include "sysdep/pci_mach386.c" | |
80 #elif defined (__SVR4) | |
3973 | 81 #if !defined(SVR4) |
82 #define SVR4 | |
83 #endif | |
4164 | 84 #include "sysdep/pci_svr4.c" |
85 #elif defined (SCO) | |
86 #include "sysdep/pci_sco.c" | |
87 #elif defined (ISC) | |
88 #include "sysdep/pci_isc.c" | |
89 #elif defined (__EMX__) | |
90 #include "sysdep/pci_os2.c" | |
4173 | 91 #elif defined (_WIN32) || defined(__CYGWIN__) |
4164 | 92 #include "sysdep/pci_win32.c" |
10980 | 93 #ifdef __MINGW32__ |
94 #define ENOTSUP 134 /* Not supported */ | |
95 #endif | |
3973 | 96 #endif |
4164 | 97 |
3973 | 98 #if defined(Lynx) && defined(__powerpc__) |
99 /* let's mimick the Linux Alpha stuff for LynxOS so we don't have | |
100 * to change too much code | |
101 */ | |
102 #include <smem.h> | |
103 | |
104 static unsigned char *pciConfBase; | |
105 | |
106 static __inline__ unsigned long | |
107 static swapl(unsigned long val) | |
108 { | |
109 unsigned char *p = (unsigned char *)&val; | |
26753
502f04b67653
cosmetics: Remove useless parentheses from return statements.
diego
parents:
24511
diff
changeset
|
110 return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | (p[0] << 0); |
3973 | 111 } |
112 | |
113 | |
114 #define BUS(tag) (((tag)>>16)&0xff) | |
115 #define DFN(tag) (((tag)>>8)&0xff) | |
116 | |
117 #define PCIBIOS_DEVICE_NOT_FOUND 0x86 | |
118 #define PCIBIOS_SUCCESSFUL 0x00 | |
119 | |
4174
4cfb6b9a6da3
api changed: enable/disable_os_io returns error-code (or zero if ok) and pciconfig_read exported for mga_vid
alex
parents:
4173
diff
changeset
|
120 int pciconfig_read( |
3973 | 121 unsigned char bus, |
122 unsigned char dev, | |
123 unsigned char offset, | |
124 int len, /* unused, alway 4 */ | |
125 unsigned long *val) | |
126 { | |
127 unsigned long _val; | |
128 unsigned long *ptr; | |
129 | |
130 dev >>= 3; | |
131 if (bus || dev >= 16) { | |
132 *val = 0xFFFFFFFF; | |
133 return PCIBIOS_DEVICE_NOT_FOUND; | |
134 } else { | |
135 ptr = (unsigned long *)(pciConfBase + ((1<<dev) | offset)); | |
136 _val = swapl(*ptr); | |
137 } | |
138 *val = _val; | |
139 return PCIBIOS_SUCCESSFUL; | |
140 } | |
141 | |
4174
4cfb6b9a6da3
api changed: enable/disable_os_io returns error-code (or zero if ok) and pciconfig_read exported for mga_vid
alex
parents:
4173
diff
changeset
|
142 int pciconfig_write( |
3973 | 143 unsigned char bus, |
144 unsigned char dev, | |
145 unsigned char offset, | |
146 int len, /* unused, alway 4 */ | |
147 unsigned long val) | |
148 { | |
149 unsigned long _val; | |
150 unsigned long *ptr; | |
151 | |
152 dev >>= 3; | |
153 _val = swapl(val); | |
154 if (bus || dev >= 16) { | |
155 return PCIBIOS_DEVICE_NOT_FOUND; | |
156 } else { | |
157 ptr = (unsigned long *)(pciConfBase + ((1<<dev) | offset)); | |
158 *ptr = _val; | |
159 } | |
160 return PCIBIOS_SUCCESSFUL; | |
161 } | |
27005
0a7f07b761e1
Add comments to a few #endif preprocessor directives.
diego
parents:
26753
diff
changeset
|
162 #endif /* defined(Lynx) && defined(__powerpc__) */ |
3973 | 163 |
164 #if !defined(__powerpc__) | |
165 struct pci_config_reg { | |
166 /* start of official PCI config space header */ | |
167 union { | |
168 unsigned long device_vendor; | |
169 struct { | |
170 unsigned short vendor; | |
171 unsigned short device; | |
172 } dv; | |
173 } dv_id; | |
174 #define _device_vendor dv_id.device_vendor | |
175 #define _vendor dv_id.dv.vendor | |
176 #define _device dv_id.dv.device | |
177 union { | |
178 unsigned long status_command; | |
179 struct { | |
180 unsigned short command; | |
181 unsigned short status; | |
182 } sc; | |
183 } stat_cmd; | |
184 #define _status_command stat_cmd.status_command | |
185 #define _command stat_cmd.sc.command | |
186 #define _status stat_cmd.sc.status | |
187 union { | |
188 unsigned long class_revision; | |
189 struct { | |
190 unsigned char rev_id; | |
191 unsigned char prog_if; | |
192 unsigned char sub_class; | |
193 unsigned char base_class; | |
194 } cr; | |
195 } class_rev; | |
196 #define _class_revision class_rev.class_revision | |
197 #define _rev_id class_rev.cr.rev_id | |
198 #define _prog_if class_rev.cr.prog_if | |
199 #define _sub_class class_rev.cr.sub_class | |
200 #define _base_class class_rev.cr.base_class | |
201 union { | |
202 unsigned long bist_header_latency_cache; | |
203 struct { | |
204 unsigned char cache_line_size; | |
205 unsigned char latency_timer; | |
206 unsigned char header_type; | |
207 unsigned char bist; | |
208 } bhlc; | |
209 } bhlc; | |
210 #define _bist_header_latency_cache bhlc.bist_header_latency_cache | |
211 #define _cache_line_size bhlc.bhlc.cache_line_size | |
212 #define _latency_timer bhlc.bhlc.latency_timer | |
213 #define _header_type bhlc.bhlc.header_type | |
214 #define _bist bhlc.bhlc.bist | |
215 union { | |
216 struct { | |
217 unsigned long dv_base0; | |
218 unsigned long dv_base1; | |
219 unsigned long dv_base2; | |
220 unsigned long dv_base3; | |
221 unsigned long dv_base4; | |
222 unsigned long dv_base5; | |
223 } dv; | |
224 struct { | |
225 unsigned long bg_rsrvd[2]; | |
226 unsigned char primary_bus_number; | |
227 unsigned char secondary_bus_number; | |
228 unsigned char subordinate_bus_number; | |
229 unsigned char secondary_latency_timer; | |
230 unsigned char io_base; | |
231 unsigned char io_limit; | |
232 unsigned short secondary_status; | |
233 unsigned short mem_base; | |
234 unsigned short mem_limit; | |
235 unsigned short prefetch_mem_base; | |
236 unsigned short prefetch_mem_limit; | |
237 } bg; | |
238 } bc; | |
239 #define _base0 bc.dv.dv_base0 | |
240 #define _base1 bc.dv.dv_base1 | |
241 #define _base2 bc.dv.dv_base2 | |
242 #define _base3 bc.dv.dv_base3 | |
243 #define _base4 bc.dv.dv_base4 | |
244 #define _base5 bc.dv.dv_base5 | |
245 #define _primary_bus_number bc.bg.primary_bus_number | |
246 #define _secondary_bus_number bc.bg.secondary_bus_number | |
247 #define _subordinate_bus_number bc.bg.subordinate_bus_number | |
248 #define _secondary_latency_timer bc.bg.secondary_latency_timer | |
249 #define _io_base bc.bg.io_base | |
250 #define _io_limit bc.bg.io_limit | |
251 #define _secondary_status bc.bg.secondary_status | |
252 #define _mem_base bc.bg.mem_base | |
253 #define _mem_limit bc.bg.mem_limit | |
254 #define _prefetch_mem_base bc.bg.prefetch_mem_base | |
255 #define _prefetch_mem_limit bc.bg.prefetch_mem_limit | |
256 unsigned long rsvd1; | |
257 unsigned long rsvd2; | |
258 unsigned long _baserom; | |
259 unsigned long rsvd3; | |
260 unsigned long rsvd4; | |
261 union { | |
262 unsigned long max_min_ipin_iline; | |
263 struct { | |
264 unsigned char int_line; | |
265 unsigned char int_pin; | |
266 unsigned char min_gnt; | |
267 unsigned char max_lat; | |
268 } mmii; | |
269 } mmii; | |
270 #define _max_min_ipin_iline mmii.max_min_ipin_iline | |
271 #define _int_line mmii.mmii.int_line | |
272 #define _int_pin mmii.mmii.int_pin | |
273 #define _min_gnt mmii.mmii.min_gnt | |
274 #define _max_lat mmii.mmii.max_lat | |
275 /* I don't know how accurate or standard this is (DHD) */ | |
276 union { | |
277 unsigned long user_config; | |
278 struct { | |
279 unsigned char user_config_0; | |
280 unsigned char user_config_1; | |
281 unsigned char user_config_2; | |
282 unsigned char user_config_3; | |
283 } uc; | |
284 } uc; | |
285 #define _user_config uc.user_config | |
286 #define _user_config_0 uc.uc.user_config_0 | |
287 #define _user_config_1 uc.uc.user_config_1 | |
288 #define _user_config_2 uc.uc.user_config_2 | |
289 #define _user_config_3 uc.uc.user_config_3 | |
290 /* end of official PCI config space header */ | |
291 unsigned long _pcibusidx; | |
292 unsigned long _pcinumbus; | |
293 unsigned long _pcibuses[16]; | |
294 unsigned short _configtype; /* config type found */ | |
295 unsigned short _ioaddr; /* config type 1 - private I/O addr */ | |
296 unsigned long _cardnum; /* config type 2 - private card number */ | |
297 }; | |
298 #else | |
299 /* ppc is big endian, swapping bytes is not quite enough | |
300 * to interpret the PCI config registers... | |
301 */ | |
302 struct pci_config_reg { | |
303 /* start of official PCI config space header */ | |
304 union { | |
305 unsigned long device_vendor; | |
306 struct { | |
307 unsigned short device; | |
308 unsigned short vendor; | |
309 } dv; | |
310 } dv_id; | |
311 #define _device_vendor dv_id.device_vendor | |
312 #define _vendor dv_id.dv.vendor | |
313 #define _device dv_id.dv.device | |
314 union { | |
315 unsigned long status_command; | |
316 struct { | |
317 unsigned short status; | |
318 unsigned short command; | |
319 } sc; | |
320 } stat_cmd; | |
321 #define _status_command stat_cmd.status_command | |
322 #define _command stat_cmd.sc.command | |
323 #define _status stat_cmd.sc.status | |
324 union { | |
325 unsigned long class_revision; | |
326 struct { | |
327 unsigned char base_class; | |
328 unsigned char sub_class; | |
329 unsigned char prog_if; | |
330 unsigned char rev_id; | |
331 } cr; | |
332 } class_rev; | |
333 #define _class_revision class_rev.class_revision | |
334 #define _rev_id class_rev.cr.rev_id | |
335 #define _prog_if class_rev.cr.prog_if | |
336 #define _sub_class class_rev.cr.sub_class | |
337 #define _base_class class_rev.cr.base_class | |
338 union { | |
339 unsigned long bist_header_latency_cache; | |
340 struct { | |
341 unsigned char bist; | |
342 unsigned char header_type; | |
343 unsigned char latency_timer; | |
344 unsigned char cache_line_size; | |
345 } bhlc; | |
346 } bhlc; | |
347 #define _bist_header_latency_cache bhlc.bist_header_latency_cache | |
348 #define _cache_line_size bhlc.bhlc.cache_line_size | |
349 #define _latency_timer bhlc.bhlc.latency_timer | |
350 #define _header_type bhlc.bhlc.header_type | |
351 #define _bist bhlc.bhlc.bist | |
352 union { | |
353 struct { | |
354 unsigned long dv_base0; | |
355 unsigned long dv_base1; | |
356 unsigned long dv_base2; | |
357 unsigned long dv_base3; | |
358 unsigned long dv_base4; | |
359 unsigned long dv_base5; | |
360 } dv; | |
361 /* ?? */ | |
362 struct { | |
363 unsigned long bg_rsrvd[2]; | |
364 | |
365 unsigned char secondary_latency_timer; | |
366 unsigned char subordinate_bus_number; | |
367 unsigned char secondary_bus_number; | |
368 unsigned char primary_bus_number; | |
369 | |
370 unsigned short secondary_status; | |
371 unsigned char io_limit; | |
372 unsigned char io_base; | |
373 | |
374 unsigned short mem_limit; | |
375 unsigned short mem_base; | |
376 | |
377 unsigned short prefetch_mem_limit; | |
378 unsigned short prefetch_mem_base; | |
379 } bg; | |
380 } bc; | |
381 #define _base0 bc.dv.dv_base0 | |
382 #define _base1 bc.dv.dv_base1 | |
383 #define _base2 bc.dv.dv_base2 | |
384 #define _base3 bc.dv.dv_base3 | |
385 #define _base4 bc.dv.dv_base4 | |
386 #define _base5 bc.dv.dv_base5 | |
387 #define _primary_bus_number bc.bg.primary_bus_number | |
388 #define _secondary_bus_number bc.bg.secondary_bus_number | |
389 #define _subordinate_bus_number bc.bg.subordinate_bus_number | |
390 #define _secondary_latency_timer bc.bg.secondary_latency_timer | |
391 #define _io_base bc.bg.io_base | |
392 #define _io_limit bc.bg.io_limit | |
393 #define _secondary_status bc.bg.secondary_status | |
394 #define _mem_base bc.bg.mem_base | |
395 #define _mem_limit bc.bg.mem_limit | |
396 #define _prefetch_mem_base bc.bg.prefetch_mem_base | |
397 #define _prefetch_mem_limit bc.bg.prefetch_mem_limit | |
398 unsigned long rsvd1; | |
399 unsigned long rsvd2; | |
400 unsigned long _baserom; | |
401 unsigned long rsvd3; | |
402 unsigned long rsvd4; | |
403 union { | |
404 unsigned long max_min_ipin_iline; | |
405 struct { | |
406 unsigned char max_lat; | |
407 unsigned char min_gnt; | |
408 unsigned char int_pin; | |
409 unsigned char int_line; | |
410 } mmii; | |
411 } mmii; | |
412 #define _max_min_ipin_iline mmii.max_min_ipin_iline | |
413 #define _int_line mmii.mmii.int_line | |
414 #define _int_pin mmii.mmii.int_pin | |
415 #define _min_gnt mmii.mmii.min_gnt | |
416 #define _max_lat mmii.mmii.max_lat | |
417 /* I don't know how accurate or standard this is (DHD) */ | |
418 union { | |
419 unsigned long user_config; | |
420 struct { | |
421 unsigned char user_config_3; | |
422 unsigned char user_config_2; | |
423 unsigned char user_config_1; | |
424 unsigned char user_config_0; | |
425 } uc; | |
426 } uc; | |
427 #define _user_config uc.user_config | |
428 #define _user_config_0 uc.uc.user_config_0 | |
429 #define _user_config_1 uc.uc.user_config_1 | |
430 #define _user_config_2 uc.uc.user_config_2 | |
431 #define _user_config_3 uc.uc.user_config_3 | |
432 /* end of official PCI config space header */ | |
433 unsigned long _pcibusidx; | |
434 unsigned long _pcinumbus; | |
435 unsigned long _pcibuses[16]; | |
436 unsigned short _ioaddr; /* config type 1 - private I/O addr */ | |
437 unsigned short _configtype; /* config type found */ | |
438 unsigned long _cardnum; /* config type 2 - private card number */ | |
439 }; | |
27005
0a7f07b761e1
Add comments to a few #endif preprocessor directives.
diego
parents:
26753
diff
changeset
|
440 #endif /* !defined(__powerpc__) */ |
3973 | 441 |
442 #define NF ((void (*)())NULL), { 0.0, 0, 0, NULL } | |
443 #define PCI_MULTIFUNC_DEV 0x80 | |
444 #define PCI_ID_REG 0x00 | |
445 #define PCI_CMD_STAT_REG 0x04 | |
446 #define PCI_CLASS_REG 0x08 | |
447 #define PCI_HEADER_MISC 0x0C | |
448 #define PCI_MAP_REG_START 0x10 | |
449 #define PCI_MAP_ROM_REG 0x30 | |
450 #define PCI_INTERRUPT_REG 0x3C | |
451 #define PCI_REG_USERCONFIG 0x40 | |
452 | |
453 static int pcibus=-1, pcicard=-1, pcifunc=-1 ; | |
454 /*static struct pci_device *pcidev=NULL ;*/ | |
455 | |
456 #if defined(__alpha__) | |
457 #define PCI_EN 0x00000000 | |
458 #else | |
459 #define PCI_EN 0x80000000 | |
460 #endif | |
461 | |
462 #define PCI_MODE1_ADDRESS_REG 0xCF8 | |
463 #define PCI_MODE1_DATA_REG 0xCFC | |
464 | |
465 #define PCI_MODE2_ENABLE_REG 0xCF8 | |
466 #ifdef PC98 | |
467 #define PCI_MODE2_FORWARD_REG 0xCF9 | |
468 #else | |
469 #define PCI_MODE2_FORWARD_REG 0xCFA | |
470 #endif | |
4164 | 471 |
472 /* cpu depended stuff */ | |
8503
9dbb9c710480
svgalib kernelhelper support (based on patch by Matan Ziv-Av <matan@svgalib.org>) and some reordering/cleanup (part #1 ;)
alex
parents:
5702
diff
changeset
|
473 #ifndef CONFIG_SVGAHELPER |
4164 | 474 #if defined(__alpha__) |
475 #include "sysdep/pci_alpha.c" | |
476 #elif defined(__ia64__) | |
477 #include "sysdep/pci_ia64.c" | |
478 #elif defined(__sparc__) | |
479 #include "sysdep/pci_sparc.c" | |
480 #elif defined( __arm32__ ) | |
481 #include "sysdep/pci_arm32.c" | |
482 #elif defined(__powerpc__) | |
483 #include "sysdep/pci_powerpc.c" | |
27419 | 484 #elif defined(__x86_64__) || defined(__sh__) |
12687 | 485 /* Nothing here right now */ |
4164 | 486 #else |
487 #include "sysdep/pci_x86.c" | |
488 #endif | |
27005
0a7f07b761e1
Add comments to a few #endif preprocessor directives.
diego
parents:
26753
diff
changeset
|
489 #endif /*CONFIG_SVGAHELPER */ |
3973 | 490 |
491 static pciinfo_t *pci_lst; | |
492 | |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
493 static void identify_card(struct pci_config_reg *pcr, int idx) |
3973 | 494 { |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
495 /* local overflow test */ |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
496 if (idx>=MAX_PCI_DEVICES) return ; |
3973 | 497 |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
498 pci_lst[idx].bus = pcibus ; |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
499 pci_lst[idx].card = pcicard ; |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
500 pci_lst[idx].func = pcifunc ; |
9767
f6d2772efca3
Ignore disabled cards. (Jon Burgess <jburgess@uklinux.net>)
ranma
parents:
8776
diff
changeset
|
501 pci_lst[idx].command = pcr->_status_command & 0xFFFF; |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
502 pci_lst[idx].vendor = pcr->_vendor ; |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
503 pci_lst[idx].device = pcr->_device ; |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
504 pci_lst[idx].base0 = 0xFFFFFFFF ; |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
505 pci_lst[idx].base1 = 0xFFFFFFFF ; |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
506 pci_lst[idx].base2 = 0xFFFFFFFF ; |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
507 pci_lst[idx].baserom = 0x000C0000 ; |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
508 if (pcr->_base0) pci_lst[idx].base0 = pcr->_base0 & |
3973 | 509 ((pcr->_base0&0x1) ? 0xFFFFFFFC : 0xFFFFFFF0) ; |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
510 if (pcr->_base1) pci_lst[idx].base1 = pcr->_base1 & |
3973 | 511 ((pcr->_base1&0x1) ? 0xFFFFFFFC : 0xFFFFFFF0) ; |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
512 if (pcr->_base2) pci_lst[idx].base2 = pcr->_base2 & |
3973 | 513 ((pcr->_base2&0x1) ? 0xFFFFFFFC : 0xFFFFFFF0) ; |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
514 if (pcr->_baserom) pci_lst[idx].baserom = pcr->_baserom ; |
3973 | 515 } |
516 | |
517 /*main(int argc, char *argv[])*/ | |
518 int pci_scan(pciinfo_t *pci_list,unsigned *num_pci) | |
519 { | |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
520 unsigned int idx = 0; |
3973 | 521 struct pci_config_reg pcr; |
24510
e7f836a459ea
ifdef one variable that is not used with alpha and powerpc architectures
ben
parents:
23734
diff
changeset
|
522 int do_mode1_scan = 0; |
e7f836a459ea
ifdef one variable that is not used with alpha and powerpc architectures
ben
parents:
23734
diff
changeset
|
523 #if !defined(__alpha__) && !defined(__powerpc__) |
e7f836a459ea
ifdef one variable that is not used with alpha and powerpc architectures
ben
parents:
23734
diff
changeset
|
524 int do_mode2_scan = 0; |
e7f836a459ea
ifdef one variable that is not used with alpha and powerpc architectures
ben
parents:
23734
diff
changeset
|
525 #endif |
3973 | 526 int func, hostbridges=0; |
4174
4cfb6b9a6da3
api changed: enable/disable_os_io returns error-code (or zero if ok) and pciconfig_read exported for mga_vid
alex
parents:
4173
diff
changeset
|
527 int ret = -1; |
3973 | 528 |
529 pci_lst = pci_list; | |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
530 *num_pci = 0; |
3973 | 531 |
4174
4cfb6b9a6da3
api changed: enable/disable_os_io returns error-code (or zero if ok) and pciconfig_read exported for mga_vid
alex
parents:
4173
diff
changeset
|
532 ret = enable_os_io(); |
4cfb6b9a6da3
api changed: enable/disable_os_io returns error-code (or zero if ok) and pciconfig_read exported for mga_vid
alex
parents:
4173
diff
changeset
|
533 if (ret != 0) |
26753
502f04b67653
cosmetics: Remove useless parentheses from return statements.
diego
parents:
24511
diff
changeset
|
534 return ret; |
4164 | 535 |
536 if((pcr._configtype = pci_config_type()) == 0xFFFF) return ENODEV; | |
3973 | 537 |
538 /* Try pci config 1 probe first */ | |
539 | |
540 if ((pcr._configtype == 1) || do_mode1_scan) { | |
541 /*printf("\nPCI probing configuration type 1\n");*/ | |
542 | |
543 pcr._ioaddr = 0xFFFF; | |
544 | |
545 pcr._pcibuses[0] = 0; | |
546 pcr._pcinumbus = 1; | |
547 pcr._pcibusidx = 0; | |
548 | |
549 do { | |
550 /*printf("Probing for devices on PCI bus %d:\n\n", pcr._pcibusidx);*/ | |
551 | |
552 for (pcr._cardnum = 0x0; pcr._cardnum < MAX_PCI_DEVICES_PER_BUS; | |
553 pcr._cardnum += 0x1) { | |
554 func = 0; | |
555 do { /* loop over the different functions, if present */ | |
4164 | 556 pcr._device_vendor = pci_get_vendor(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum, |
557 func); | |
3973 | 558 if ((pcr._vendor == 0xFFFF) || (pcr._device == 0xFFFF)) |
559 break; /* nothing there */ | |
560 | |
561 /*printf("\npci bus 0x%x cardnum 0x%02x function 0x%04x: vendor 0x%04x device 0x%04x\n", | |
562 pcr._pcibuses[pcr._pcibusidx], pcr._cardnum, func, | |
563 pcr._vendor, pcr._device);*/ | |
4164 | 564 pcibus = pcr._pcibuses[pcr._pcibusidx]; |
565 pcicard = pcr._cardnum; | |
566 pcifunc = func; | |
3973 | 567 |
4164 | 568 pcr._status_command = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], |
569 pcr._cardnum,func,PCI_CMD_STAT_REG); | |
570 pcr._class_revision = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
571 pcr._cardnum,func,PCI_CLASS_REG); | |
572 pcr._bist_header_latency_cache = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
573 pcr._cardnum,func,PCI_HEADER_MISC); | |
574 pcr._base0 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
575 pcr._cardnum,func,PCI_MAP_REG_START); | |
576 pcr._base1 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
577 pcr._cardnum,func,PCI_MAP_REG_START+4); | |
578 pcr._base2 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
579 pcr._cardnum,func,PCI_MAP_REG_START+8); | |
580 pcr._base3 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
581 pcr._cardnum,func,PCI_MAP_REG_START+0x0C); | |
582 pcr._base4 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
583 pcr._cardnum,func,PCI_MAP_REG_START+0x10); | |
584 pcr._base5 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
585 pcr._cardnum,func,PCI_MAP_REG_START+0x14); | |
586 pcr._baserom = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
587 pcr._cardnum,func,PCI_MAP_ROM_REG); | |
588 pcr._max_min_ipin_iline = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
589 pcr._cardnum,func,PCI_INTERRUPT_REG); | |
590 pcr._user_config = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
591 pcr._cardnum,func,PCI_REG_USERCONFIG); | |
3973 | 592 /* check for pci-pci bridges */ |
593 #define PCI_CLASS_MASK 0xff000000 | |
594 #define PCI_SUBCLASS_MASK 0x00ff0000 | |
595 #define PCI_CLASS_BRIDGE 0x06000000 | |
596 #define PCI_SUBCLASS_BRIDGE_PCI 0x00040000 | |
597 switch(pcr._class_revision & (PCI_CLASS_MASK|PCI_SUBCLASS_MASK)) { | |
598 case PCI_CLASS_BRIDGE|PCI_SUBCLASS_BRIDGE_PCI: | |
599 if (pcr._secondary_bus_number > 0) { | |
600 pcr._pcibuses[pcr._pcinumbus++] = pcr._secondary_bus_number; | |
601 } | |
602 break; | |
603 case PCI_CLASS_BRIDGE: | |
604 if ( ++hostbridges > 1) { | |
605 pcr._pcibuses[pcr._pcinumbus] = pcr._pcinumbus; | |
606 pcr._pcinumbus++; | |
607 } | |
608 break; | |
609 default: | |
610 break; | |
611 } | |
612 if((func==0) && ((pcr._header_type & PCI_MULTIFUNC_DEV) == 0)) { | |
613 /* not a multi function device */ | |
614 func = 8; | |
615 } else { | |
616 func++; | |
617 } | |
618 | |
619 if (idx++ >= MAX_PCI_DEVICES) | |
620 continue; | |
621 | |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
622 identify_card(&pcr, (*num_pci)++); |
3973 | 623 } while( func < 8 ); |
624 } | |
625 } while (++pcr._pcibusidx < pcr._pcinumbus); | |
626 } | |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
627 |
27419 | 628 #if !defined(__alpha__) && !defined(__powerpc__) && !defined(__sh__) |
3973 | 629 /* Now try pci config 2 probe (deprecated) */ |
630 | |
631 if ((pcr._configtype == 2) || do_mode2_scan) { | |
632 outb(PCI_MODE2_ENABLE_REG, 0xF1); | |
633 outb(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */ | |
634 | |
635 /*printf("\nPCI probing configuration type 2\n");*/ | |
636 | |
637 pcr._pcibuses[0] = 0; | |
638 pcr._pcinumbus = 1; | |
639 pcr._pcibusidx = 0; | |
640 idx = 0; | |
641 | |
642 do { | |
643 for (pcr._ioaddr = 0xC000; pcr._ioaddr < 0xD000; pcr._ioaddr += 0x0100){ | |
644 outb(PCI_MODE2_FORWARD_REG, pcr._pcibuses[pcr._pcibusidx]); /* bus 0 for now */ | |
645 pcr._device_vendor = inl(pcr._ioaddr); | |
646 outb(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */ | |
647 | |
648 if ((pcr._vendor == 0xFFFF) || (pcr._device == 0xFFFF)) | |
649 continue; | |
650 if ((pcr._vendor == 0xF0F0) || (pcr._device == 0xF0F0)) | |
651 continue; /* catch ASUS P55TP4XE motherboards */ | |
652 | |
653 /*printf("\npci bus 0x%x slot at 0x%04x, vendor 0x%04x device 0x%04x\n", | |
654 pcr._pcibuses[pcr._pcibusidx], pcr._ioaddr, pcr._vendor, | |
655 pcr._device);*/ | |
656 pcibus = pcr._pcibuses[pcr._pcibusidx] ; | |
657 pcicard = pcr._ioaddr ; pcifunc = 0 ; | |
658 | |
659 outb(PCI_MODE2_FORWARD_REG, pcr._pcibuses[pcr._pcibusidx]); /* bus 0 for now */ | |
660 pcr._status_command = inl(pcr._ioaddr + 0x04); | |
661 pcr._class_revision = inl(pcr._ioaddr + 0x08); | |
662 pcr._bist_header_latency_cache = inl(pcr._ioaddr + 0x0C); | |
663 pcr._base0 = inl(pcr._ioaddr + 0x10); | |
664 pcr._base1 = inl(pcr._ioaddr + 0x14); | |
665 pcr._base2 = inl(pcr._ioaddr + 0x18); | |
666 pcr._base3 = inl(pcr._ioaddr + 0x1C); | |
667 pcr._base4 = inl(pcr._ioaddr + 0x20); | |
668 pcr._base5 = inl(pcr._ioaddr + 0x24); | |
669 pcr._baserom = inl(pcr._ioaddr + 0x30); | |
670 pcr._max_min_ipin_iline = inl(pcr._ioaddr + 0x3C); | |
671 pcr._user_config = inl(pcr._ioaddr + 0x40); | |
672 outb(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */ | |
673 | |
674 /* check for pci-pci bridges (currently we only know Digital) */ | |
675 if ((pcr._vendor == 0x1011) && (pcr._device == 0x0001)) | |
676 if (pcr._secondary_bus_number > 0) | |
677 pcr._pcibuses[pcr._pcinumbus++] = pcr._secondary_bus_number; | |
678 | |
679 if (idx++ >= MAX_PCI_DEVICES) | |
680 continue; | |
681 | |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
682 identify_card(&pcr, (*num_pci)++); |
3973 | 683 } |
684 } while (++pcr._pcibusidx < pcr._pcinumbus); | |
685 | |
686 outb(PCI_MODE2_ENABLE_REG, 0x00); | |
687 } | |
688 | |
27419 | 689 #endif /* !__alpha__ && !__powerpc__ && !__sh__ */ |
3973 | 690 |
691 disable_os_io(); | |
692 | |
693 return 0 ; | |
694 | |
695 } | |
4174
4cfb6b9a6da3
api changed: enable/disable_os_io returns error-code (or zero if ok) and pciconfig_read exported for mga_vid
alex
parents:
4173
diff
changeset
|
696 |
4cfb6b9a6da3
api changed: enable/disable_os_io returns error-code (or zero if ok) and pciconfig_read exported for mga_vid
alex
parents:
4173
diff
changeset
|
697 #if !defined(ENOTSUP) |
4cfb6b9a6da3
api changed: enable/disable_os_io returns error-code (or zero if ok) and pciconfig_read exported for mga_vid
alex
parents:
4173
diff
changeset
|
698 #if defined(EOPNOTSUPP) |
4cfb6b9a6da3
api changed: enable/disable_os_io returns error-code (or zero if ok) and pciconfig_read exported for mga_vid
alex
parents:
4173
diff
changeset
|
699 #define ENOTSUP EOPNOTSUPP |
4cfb6b9a6da3
api changed: enable/disable_os_io returns error-code (or zero if ok) and pciconfig_read exported for mga_vid
alex
parents:
4173
diff
changeset
|
700 #else |
4cfb6b9a6da3
api changed: enable/disable_os_io returns error-code (or zero if ok) and pciconfig_read exported for mga_vid
alex
parents:
4173
diff
changeset
|
701 #warning "ENOTSUP nor EOPNOTSUPP defined!" |
4cfb6b9a6da3
api changed: enable/disable_os_io returns error-code (or zero if ok) and pciconfig_read exported for mga_vid
alex
parents:
4173
diff
changeset
|
702 #endif |
4cfb6b9a6da3
api changed: enable/disable_os_io returns error-code (or zero if ok) and pciconfig_read exported for mga_vid
alex
parents:
4173
diff
changeset
|
703 #endif |
4cfb6b9a6da3
api changed: enable/disable_os_io returns error-code (or zero if ok) and pciconfig_read exported for mga_vid
alex
parents:
4173
diff
changeset
|
704 |
4277 | 705 int pci_config_read(unsigned char bus, unsigned char dev, unsigned char func, |
706 unsigned char cmd, int len, unsigned long *val) | |
4174
4cfb6b9a6da3
api changed: enable/disable_os_io returns error-code (or zero if ok) and pciconfig_read exported for mga_vid
alex
parents:
4173
diff
changeset
|
707 { |
4277 | 708 int ret; |
709 | |
4174
4cfb6b9a6da3
api changed: enable/disable_os_io returns error-code (or zero if ok) and pciconfig_read exported for mga_vid
alex
parents:
4173
diff
changeset
|
710 if (len != 4) |
4cfb6b9a6da3
api changed: enable/disable_os_io returns error-code (or zero if ok) and pciconfig_read exported for mga_vid
alex
parents:
4173
diff
changeset
|
711 { |
17971 | 712 fprintf(stderr,"pci_config_read: Reading non-dword not supported!\n"); |
26753
502f04b67653
cosmetics: Remove useless parentheses from return statements.
diego
parents:
24511
diff
changeset
|
713 return ENOTSUP; |
4174
4cfb6b9a6da3
api changed: enable/disable_os_io returns error-code (or zero if ok) and pciconfig_read exported for mga_vid
alex
parents:
4173
diff
changeset
|
714 } |
4cfb6b9a6da3
api changed: enable/disable_os_io returns error-code (or zero if ok) and pciconfig_read exported for mga_vid
alex
parents:
4173
diff
changeset
|
715 |
4277 | 716 ret = enable_os_io(); |
717 if (ret != 0) | |
26753
502f04b67653
cosmetics: Remove useless parentheses from return statements.
diego
parents:
24511
diff
changeset
|
718 return ret; |
4277 | 719 ret = pci_config_read_long(bus, dev, func, cmd); |
720 disable_os_io(); | |
721 | |
722 *val = ret; | |
26753
502f04b67653
cosmetics: Remove useless parentheses from return statements.
diego
parents:
24511
diff
changeset
|
723 return 0; |
4174
4cfb6b9a6da3
api changed: enable/disable_os_io returns error-code (or zero if ok) and pciconfig_read exported for mga_vid
alex
parents:
4173
diff
changeset
|
724 } |
4192 | 725 |
726 int enable_app_io( void ) | |
727 { | |
728 return enable_os_io(); | |
729 } | |
730 | |
731 int disable_app_io( void ) | |
732 { | |
733 return disable_os_io(); | |
5702 | 734 } |