Mercurial > mplayer.hg
annotate libdha/pci.c @ 20752:0617c67ad68f
Fix code that cuts audio data if the filters produce too much.
It incorrectly used the channel count and sample size values from the
decoder even though the filters can change those.
author | uau |
---|---|
date | Tue, 07 Nov 2006 23:16:55 +0000 |
parents | fd0d4b94b5ec |
children | 3ff1eade91f9 |
rev | line source |
---|---|
3973 | 1 /* |
2 (C) 2002 - library implementation by Nick Kyrshev | |
3 XFree86 3.3.3 scanpci.c, modified for GATOS/win/gfxdump by Øyvind Aabling. | |
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 | |
4164 | 54 #include "libdha.h" |
55 #include <errno.h> | |
56 #include <string.h> | |
57 #include <stdio.h> | |
58 #ifdef __unix__ | |
59 #include <unistd.h> | |
60 #endif | |
61 #include "AsmMacros.h" | |
62 /* OS depended stuff */ | |
63 #if defined (linux) | |
64 #include "sysdep/pci_linux.c" | |
15566 | 65 #elif defined (__FreeBSD__) || defined(__DragonFly__) |
4164 | 66 #include "sysdep/pci_freebsd.c" |
67 #elif defined (__386BSD__) | |
68 #include "sysdep/pci_386bsd.c" | |
69 #elif defined (__NetBSD__) | |
70 #include "sysdep/pci_netbsd.c" | |
71 #elif defined (__OpenBSD__) | |
72 #include "sysdep/pci_openbsd.c" | |
73 #elif defined (__bsdi__) | |
74 #include "sysdep/pci_bsdi.c" | |
75 #elif defined (Lynx) | |
76 #include "sysdep/pci_lynx.c" | |
77 #elif defined (MACH386) | |
78 #include "sysdep/pci_mach386.c" | |
79 #elif defined (__SVR4) | |
3973 | 80 #if !defined(SVR4) |
81 #define SVR4 | |
82 #endif | |
4164 | 83 #include "sysdep/pci_svr4.c" |
84 #elif defined (SCO) | |
85 #include "sysdep/pci_sco.c" | |
86 #elif defined (ISC) | |
87 #include "sysdep/pci_isc.c" | |
88 #elif defined (__EMX__) | |
89 #include "sysdep/pci_os2.c" | |
4173 | 90 #elif defined (_WIN32) || defined(__CYGWIN__) |
4164 | 91 #include "sysdep/pci_win32.c" |
10980 | 92 #ifdef __MINGW32__ |
93 #define ENOTSUP 134 /* Not supported */ | |
94 #endif | |
3973 | 95 #endif |
4164 | 96 |
97 #if 0 | |
3973 | 98 #if defined(__SUNPRO_C) || defined(sun) || defined(__sun) |
99 #include <sys/psw.h> | |
100 #else | |
101 #include <sys/seg.h> | |
102 #endif | |
103 #include <sys/v86.h> | |
104 #endif | |
105 | |
106 #if defined(Lynx) && defined(__powerpc__) | |
107 /* let's mimick the Linux Alpha stuff for LynxOS so we don't have | |
108 * to change too much code | |
109 */ | |
110 #include <smem.h> | |
111 | |
112 static unsigned char *pciConfBase; | |
113 | |
114 static __inline__ unsigned long | |
115 static swapl(unsigned long val) | |
116 { | |
117 unsigned char *p = (unsigned char *)&val; | |
118 return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | (p[0] << 0)); | |
119 } | |
120 | |
121 | |
122 #define BUS(tag) (((tag)>>16)&0xff) | |
123 #define DFN(tag) (((tag)>>8)&0xff) | |
124 | |
125 #define PCIBIOS_DEVICE_NOT_FOUND 0x86 | |
126 #define PCIBIOS_SUCCESSFUL 0x00 | |
127 | |
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
|
128 int pciconfig_read( |
3973 | 129 unsigned char bus, |
130 unsigned char dev, | |
131 unsigned char offset, | |
132 int len, /* unused, alway 4 */ | |
133 unsigned long *val) | |
134 { | |
135 unsigned long _val; | |
136 unsigned long *ptr; | |
137 | |
138 dev >>= 3; | |
139 if (bus || dev >= 16) { | |
140 *val = 0xFFFFFFFF; | |
141 return PCIBIOS_DEVICE_NOT_FOUND; | |
142 } else { | |
143 ptr = (unsigned long *)(pciConfBase + ((1<<dev) | offset)); | |
144 _val = swapl(*ptr); | |
145 } | |
146 *val = _val; | |
147 return PCIBIOS_SUCCESSFUL; | |
148 } | |
149 | |
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
|
150 int pciconfig_write( |
3973 | 151 unsigned char bus, |
152 unsigned char dev, | |
153 unsigned char offset, | |
154 int len, /* unused, alway 4 */ | |
155 unsigned long val) | |
156 { | |
157 unsigned long _val; | |
158 unsigned long *ptr; | |
159 | |
160 dev >>= 3; | |
161 _val = swapl(val); | |
162 if (bus || dev >= 16) { | |
163 return PCIBIOS_DEVICE_NOT_FOUND; | |
164 } else { | |
165 ptr = (unsigned long *)(pciConfBase + ((1<<dev) | offset)); | |
166 *ptr = _val; | |
167 } | |
168 return PCIBIOS_SUCCESSFUL; | |
169 } | |
170 #endif | |
171 | |
172 #if !defined(__powerpc__) | |
173 struct pci_config_reg { | |
174 /* start of official PCI config space header */ | |
175 union { | |
176 unsigned long device_vendor; | |
177 struct { | |
178 unsigned short vendor; | |
179 unsigned short device; | |
180 } dv; | |
181 } dv_id; | |
182 #define _device_vendor dv_id.device_vendor | |
183 #define _vendor dv_id.dv.vendor | |
184 #define _device dv_id.dv.device | |
185 union { | |
186 unsigned long status_command; | |
187 struct { | |
188 unsigned short command; | |
189 unsigned short status; | |
190 } sc; | |
191 } stat_cmd; | |
192 #define _status_command stat_cmd.status_command | |
193 #define _command stat_cmd.sc.command | |
194 #define _status stat_cmd.sc.status | |
195 union { | |
196 unsigned long class_revision; | |
197 struct { | |
198 unsigned char rev_id; | |
199 unsigned char prog_if; | |
200 unsigned char sub_class; | |
201 unsigned char base_class; | |
202 } cr; | |
203 } class_rev; | |
204 #define _class_revision class_rev.class_revision | |
205 #define _rev_id class_rev.cr.rev_id | |
206 #define _prog_if class_rev.cr.prog_if | |
207 #define _sub_class class_rev.cr.sub_class | |
208 #define _base_class class_rev.cr.base_class | |
209 union { | |
210 unsigned long bist_header_latency_cache; | |
211 struct { | |
212 unsigned char cache_line_size; | |
213 unsigned char latency_timer; | |
214 unsigned char header_type; | |
215 unsigned char bist; | |
216 } bhlc; | |
217 } bhlc; | |
218 #define _bist_header_latency_cache bhlc.bist_header_latency_cache | |
219 #define _cache_line_size bhlc.bhlc.cache_line_size | |
220 #define _latency_timer bhlc.bhlc.latency_timer | |
221 #define _header_type bhlc.bhlc.header_type | |
222 #define _bist bhlc.bhlc.bist | |
223 union { | |
224 struct { | |
225 unsigned long dv_base0; | |
226 unsigned long dv_base1; | |
227 unsigned long dv_base2; | |
228 unsigned long dv_base3; | |
229 unsigned long dv_base4; | |
230 unsigned long dv_base5; | |
231 } dv; | |
232 struct { | |
233 unsigned long bg_rsrvd[2]; | |
234 unsigned char primary_bus_number; | |
235 unsigned char secondary_bus_number; | |
236 unsigned char subordinate_bus_number; | |
237 unsigned char secondary_latency_timer; | |
238 unsigned char io_base; | |
239 unsigned char io_limit; | |
240 unsigned short secondary_status; | |
241 unsigned short mem_base; | |
242 unsigned short mem_limit; | |
243 unsigned short prefetch_mem_base; | |
244 unsigned short prefetch_mem_limit; | |
245 } bg; | |
246 } bc; | |
247 #define _base0 bc.dv.dv_base0 | |
248 #define _base1 bc.dv.dv_base1 | |
249 #define _base2 bc.dv.dv_base2 | |
250 #define _base3 bc.dv.dv_base3 | |
251 #define _base4 bc.dv.dv_base4 | |
252 #define _base5 bc.dv.dv_base5 | |
253 #define _primary_bus_number bc.bg.primary_bus_number | |
254 #define _secondary_bus_number bc.bg.secondary_bus_number | |
255 #define _subordinate_bus_number bc.bg.subordinate_bus_number | |
256 #define _secondary_latency_timer bc.bg.secondary_latency_timer | |
257 #define _io_base bc.bg.io_base | |
258 #define _io_limit bc.bg.io_limit | |
259 #define _secondary_status bc.bg.secondary_status | |
260 #define _mem_base bc.bg.mem_base | |
261 #define _mem_limit bc.bg.mem_limit | |
262 #define _prefetch_mem_base bc.bg.prefetch_mem_base | |
263 #define _prefetch_mem_limit bc.bg.prefetch_mem_limit | |
264 unsigned long rsvd1; | |
265 unsigned long rsvd2; | |
266 unsigned long _baserom; | |
267 unsigned long rsvd3; | |
268 unsigned long rsvd4; | |
269 union { | |
270 unsigned long max_min_ipin_iline; | |
271 struct { | |
272 unsigned char int_line; | |
273 unsigned char int_pin; | |
274 unsigned char min_gnt; | |
275 unsigned char max_lat; | |
276 } mmii; | |
277 } mmii; | |
278 #define _max_min_ipin_iline mmii.max_min_ipin_iline | |
279 #define _int_line mmii.mmii.int_line | |
280 #define _int_pin mmii.mmii.int_pin | |
281 #define _min_gnt mmii.mmii.min_gnt | |
282 #define _max_lat mmii.mmii.max_lat | |
283 /* I don't know how accurate or standard this is (DHD) */ | |
284 union { | |
285 unsigned long user_config; | |
286 struct { | |
287 unsigned char user_config_0; | |
288 unsigned char user_config_1; | |
289 unsigned char user_config_2; | |
290 unsigned char user_config_3; | |
291 } uc; | |
292 } uc; | |
293 #define _user_config uc.user_config | |
294 #define _user_config_0 uc.uc.user_config_0 | |
295 #define _user_config_1 uc.uc.user_config_1 | |
296 #define _user_config_2 uc.uc.user_config_2 | |
297 #define _user_config_3 uc.uc.user_config_3 | |
298 /* end of official PCI config space header */ | |
299 unsigned long _pcibusidx; | |
300 unsigned long _pcinumbus; | |
301 unsigned long _pcibuses[16]; | |
302 unsigned short _configtype; /* config type found */ | |
303 unsigned short _ioaddr; /* config type 1 - private I/O addr */ | |
304 unsigned long _cardnum; /* config type 2 - private card number */ | |
305 }; | |
306 #else | |
307 /* ppc is big endian, swapping bytes is not quite enough | |
308 * to interpret the PCI config registers... | |
309 */ | |
310 struct pci_config_reg { | |
311 /* start of official PCI config space header */ | |
312 union { | |
313 unsigned long device_vendor; | |
314 struct { | |
315 unsigned short device; | |
316 unsigned short vendor; | |
317 } dv; | |
318 } dv_id; | |
319 #define _device_vendor dv_id.device_vendor | |
320 #define _vendor dv_id.dv.vendor | |
321 #define _device dv_id.dv.device | |
322 union { | |
323 unsigned long status_command; | |
324 struct { | |
325 unsigned short status; | |
326 unsigned short command; | |
327 } sc; | |
328 } stat_cmd; | |
329 #define _status_command stat_cmd.status_command | |
330 #define _command stat_cmd.sc.command | |
331 #define _status stat_cmd.sc.status | |
332 union { | |
333 unsigned long class_revision; | |
334 struct { | |
335 unsigned char base_class; | |
336 unsigned char sub_class; | |
337 unsigned char prog_if; | |
338 unsigned char rev_id; | |
339 } cr; | |
340 } class_rev; | |
341 #define _class_revision class_rev.class_revision | |
342 #define _rev_id class_rev.cr.rev_id | |
343 #define _prog_if class_rev.cr.prog_if | |
344 #define _sub_class class_rev.cr.sub_class | |
345 #define _base_class class_rev.cr.base_class | |
346 union { | |
347 unsigned long bist_header_latency_cache; | |
348 struct { | |
349 unsigned char bist; | |
350 unsigned char header_type; | |
351 unsigned char latency_timer; | |
352 unsigned char cache_line_size; | |
353 } bhlc; | |
354 } bhlc; | |
355 #define _bist_header_latency_cache bhlc.bist_header_latency_cache | |
356 #define _cache_line_size bhlc.bhlc.cache_line_size | |
357 #define _latency_timer bhlc.bhlc.latency_timer | |
358 #define _header_type bhlc.bhlc.header_type | |
359 #define _bist bhlc.bhlc.bist | |
360 union { | |
361 struct { | |
362 unsigned long dv_base0; | |
363 unsigned long dv_base1; | |
364 unsigned long dv_base2; | |
365 unsigned long dv_base3; | |
366 unsigned long dv_base4; | |
367 unsigned long dv_base5; | |
368 } dv; | |
369 /* ?? */ | |
370 struct { | |
371 unsigned long bg_rsrvd[2]; | |
372 | |
373 unsigned char secondary_latency_timer; | |
374 unsigned char subordinate_bus_number; | |
375 unsigned char secondary_bus_number; | |
376 unsigned char primary_bus_number; | |
377 | |
378 unsigned short secondary_status; | |
379 unsigned char io_limit; | |
380 unsigned char io_base; | |
381 | |
382 unsigned short mem_limit; | |
383 unsigned short mem_base; | |
384 | |
385 unsigned short prefetch_mem_limit; | |
386 unsigned short prefetch_mem_base; | |
387 } bg; | |
388 } bc; | |
389 #define _base0 bc.dv.dv_base0 | |
390 #define _base1 bc.dv.dv_base1 | |
391 #define _base2 bc.dv.dv_base2 | |
392 #define _base3 bc.dv.dv_base3 | |
393 #define _base4 bc.dv.dv_base4 | |
394 #define _base5 bc.dv.dv_base5 | |
395 #define _primary_bus_number bc.bg.primary_bus_number | |
396 #define _secondary_bus_number bc.bg.secondary_bus_number | |
397 #define _subordinate_bus_number bc.bg.subordinate_bus_number | |
398 #define _secondary_latency_timer bc.bg.secondary_latency_timer | |
399 #define _io_base bc.bg.io_base | |
400 #define _io_limit bc.bg.io_limit | |
401 #define _secondary_status bc.bg.secondary_status | |
402 #define _mem_base bc.bg.mem_base | |
403 #define _mem_limit bc.bg.mem_limit | |
404 #define _prefetch_mem_base bc.bg.prefetch_mem_base | |
405 #define _prefetch_mem_limit bc.bg.prefetch_mem_limit | |
406 unsigned long rsvd1; | |
407 unsigned long rsvd2; | |
408 unsigned long _baserom; | |
409 unsigned long rsvd3; | |
410 unsigned long rsvd4; | |
411 union { | |
412 unsigned long max_min_ipin_iline; | |
413 struct { | |
414 unsigned char max_lat; | |
415 unsigned char min_gnt; | |
416 unsigned char int_pin; | |
417 unsigned char int_line; | |
418 } mmii; | |
419 } mmii; | |
420 #define _max_min_ipin_iline mmii.max_min_ipin_iline | |
421 #define _int_line mmii.mmii.int_line | |
422 #define _int_pin mmii.mmii.int_pin | |
423 #define _min_gnt mmii.mmii.min_gnt | |
424 #define _max_lat mmii.mmii.max_lat | |
425 /* I don't know how accurate or standard this is (DHD) */ | |
426 union { | |
427 unsigned long user_config; | |
428 struct { | |
429 unsigned char user_config_3; | |
430 unsigned char user_config_2; | |
431 unsigned char user_config_1; | |
432 unsigned char user_config_0; | |
433 } uc; | |
434 } uc; | |
435 #define _user_config uc.user_config | |
436 #define _user_config_0 uc.uc.user_config_0 | |
437 #define _user_config_1 uc.uc.user_config_1 | |
438 #define _user_config_2 uc.uc.user_config_2 | |
439 #define _user_config_3 uc.uc.user_config_3 | |
440 /* end of official PCI config space header */ | |
441 unsigned long _pcibusidx; | |
442 unsigned long _pcinumbus; | |
443 unsigned long _pcibuses[16]; | |
444 unsigned short _ioaddr; /* config type 1 - private I/O addr */ | |
445 unsigned short _configtype; /* config type found */ | |
446 unsigned long _cardnum; /* config type 2 - private card number */ | |
447 }; | |
448 #endif | |
449 | |
450 #define MAX_DEV_PER_VENDOR_CFG1 64 | |
451 #define MAX_PCI_DEVICES_PER_BUS 32 | |
452 #define MAX_PCI_DEVICES 64 | |
453 #define NF ((void (*)())NULL), { 0.0, 0, 0, NULL } | |
454 #define PCI_MULTIFUNC_DEV 0x80 | |
455 #define PCI_ID_REG 0x00 | |
456 #define PCI_CMD_STAT_REG 0x04 | |
457 #define PCI_CLASS_REG 0x08 | |
458 #define PCI_HEADER_MISC 0x0C | |
459 #define PCI_MAP_REG_START 0x10 | |
460 #define PCI_MAP_ROM_REG 0x30 | |
461 #define PCI_INTERRUPT_REG 0x3C | |
462 #define PCI_REG_USERCONFIG 0x40 | |
463 | |
464 static int pcibus=-1, pcicard=-1, pcifunc=-1 ; | |
465 /*static struct pci_device *pcidev=NULL ;*/ | |
466 | |
467 #if defined(__alpha__) | |
468 #define PCI_EN 0x00000000 | |
469 #else | |
470 #define PCI_EN 0x80000000 | |
471 #endif | |
472 | |
473 #define PCI_MODE1_ADDRESS_REG 0xCF8 | |
474 #define PCI_MODE1_DATA_REG 0xCFC | |
475 | |
476 #define PCI_MODE2_ENABLE_REG 0xCF8 | |
477 #ifdef PC98 | |
478 #define PCI_MODE2_FORWARD_REG 0xCF9 | |
479 #else | |
480 #define PCI_MODE2_FORWARD_REG 0xCFA | |
481 #endif | |
4164 | 482 |
483 /* 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
|
484 #ifndef CONFIG_SVGAHELPER |
4164 | 485 #if defined(__alpha__) |
486 #include "sysdep/pci_alpha.c" | |
487 #elif defined(__ia64__) | |
488 #include "sysdep/pci_ia64.c" | |
489 #elif defined(__sparc__) | |
490 #include "sysdep/pci_sparc.c" | |
491 #elif defined( __arm32__ ) | |
492 #include "sysdep/pci_arm32.c" | |
493 #elif defined(__powerpc__) | |
494 #include "sysdep/pci_powerpc.c" | |
12687 | 495 #elif defined(__x86_64__) |
496 /* Nothing here right now */ | |
4164 | 497 #else |
498 #include "sysdep/pci_x86.c" | |
499 #endif | |
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
|
500 #endif |
3973 | 501 |
502 static pciinfo_t *pci_lst; | |
503 | |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
504 static void identify_card(struct pci_config_reg *pcr, int idx) |
3973 | 505 { |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
506 /* local overflow test */ |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
507 if (idx>=MAX_PCI_DEVICES) return ; |
3973 | 508 |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
509 pci_lst[idx].bus = pcibus ; |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
510 pci_lst[idx].card = pcicard ; |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
511 pci_lst[idx].func = pcifunc ; |
9767
f6d2772efca3
Ignore disabled cards. (Jon Burgess <jburgess@uklinux.net>)
ranma
parents:
8776
diff
changeset
|
512 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
|
513 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
|
514 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
|
515 pci_lst[idx].base0 = 0xFFFFFFFF ; |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
516 pci_lst[idx].base1 = 0xFFFFFFFF ; |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
517 pci_lst[idx].base2 = 0xFFFFFFFF ; |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
518 pci_lst[idx].baserom = 0x000C0000 ; |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
519 if (pcr->_base0) pci_lst[idx].base0 = pcr->_base0 & |
3973 | 520 ((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
|
521 if (pcr->_base1) pci_lst[idx].base1 = pcr->_base1 & |
3973 | 522 ((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
|
523 if (pcr->_base2) pci_lst[idx].base2 = pcr->_base2 & |
3973 | 524 ((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
|
525 if (pcr->_baserom) pci_lst[idx].baserom = pcr->_baserom ; |
3973 | 526 } |
527 | |
528 /*main(int argc, char *argv[])*/ | |
529 int pci_scan(pciinfo_t *pci_list,unsigned *num_pci) | |
530 { | |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
531 unsigned int idx = 0; |
3973 | 532 struct pci_config_reg pcr; |
533 int do_mode1_scan = 0, do_mode2_scan = 0; | |
534 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
|
535 int ret = -1; |
3973 | 536 |
537 pci_lst = pci_list; | |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
538 *num_pci = 0; |
3973 | 539 |
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
|
540 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
|
541 if (ret != 0) |
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
|
542 return(ret); |
4164 | 543 |
544 if((pcr._configtype = pci_config_type()) == 0xFFFF) return ENODEV; | |
3973 | 545 |
546 /* Try pci config 1 probe first */ | |
547 | |
548 if ((pcr._configtype == 1) || do_mode1_scan) { | |
549 /*printf("\nPCI probing configuration type 1\n");*/ | |
550 | |
551 pcr._ioaddr = 0xFFFF; | |
552 | |
553 pcr._pcibuses[0] = 0; | |
554 pcr._pcinumbus = 1; | |
555 pcr._pcibusidx = 0; | |
556 | |
557 do { | |
558 /*printf("Probing for devices on PCI bus %d:\n\n", pcr._pcibusidx);*/ | |
559 | |
560 for (pcr._cardnum = 0x0; pcr._cardnum < MAX_PCI_DEVICES_PER_BUS; | |
561 pcr._cardnum += 0x1) { | |
562 func = 0; | |
563 do { /* loop over the different functions, if present */ | |
4164 | 564 pcr._device_vendor = pci_get_vendor(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum, |
565 func); | |
3973 | 566 if ((pcr._vendor == 0xFFFF) || (pcr._device == 0xFFFF)) |
567 break; /* nothing there */ | |
568 | |
569 /*printf("\npci bus 0x%x cardnum 0x%02x function 0x%04x: vendor 0x%04x device 0x%04x\n", | |
570 pcr._pcibuses[pcr._pcibusidx], pcr._cardnum, func, | |
571 pcr._vendor, pcr._device);*/ | |
4164 | 572 pcibus = pcr._pcibuses[pcr._pcibusidx]; |
573 pcicard = pcr._cardnum; | |
574 pcifunc = func; | |
3973 | 575 |
4164 | 576 pcr._status_command = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], |
577 pcr._cardnum,func,PCI_CMD_STAT_REG); | |
578 pcr._class_revision = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
579 pcr._cardnum,func,PCI_CLASS_REG); | |
580 pcr._bist_header_latency_cache = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
581 pcr._cardnum,func,PCI_HEADER_MISC); | |
582 pcr._base0 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
583 pcr._cardnum,func,PCI_MAP_REG_START); | |
584 pcr._base1 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
585 pcr._cardnum,func,PCI_MAP_REG_START+4); | |
586 pcr._base2 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
587 pcr._cardnum,func,PCI_MAP_REG_START+8); | |
588 pcr._base3 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
589 pcr._cardnum,func,PCI_MAP_REG_START+0x0C); | |
590 pcr._base4 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
591 pcr._cardnum,func,PCI_MAP_REG_START+0x10); | |
592 pcr._base5 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
593 pcr._cardnum,func,PCI_MAP_REG_START+0x14); | |
594 pcr._baserom = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
595 pcr._cardnum,func,PCI_MAP_ROM_REG); | |
596 pcr._max_min_ipin_iline = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
597 pcr._cardnum,func,PCI_INTERRUPT_REG); | |
598 pcr._user_config = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
599 pcr._cardnum,func,PCI_REG_USERCONFIG); | |
3973 | 600 /* check for pci-pci bridges */ |
601 #define PCI_CLASS_MASK 0xff000000 | |
602 #define PCI_SUBCLASS_MASK 0x00ff0000 | |
603 #define PCI_CLASS_BRIDGE 0x06000000 | |
604 #define PCI_SUBCLASS_BRIDGE_PCI 0x00040000 | |
605 switch(pcr._class_revision & (PCI_CLASS_MASK|PCI_SUBCLASS_MASK)) { | |
606 case PCI_CLASS_BRIDGE|PCI_SUBCLASS_BRIDGE_PCI: | |
607 if (pcr._secondary_bus_number > 0) { | |
608 pcr._pcibuses[pcr._pcinumbus++] = pcr._secondary_bus_number; | |
609 } | |
610 break; | |
611 case PCI_CLASS_BRIDGE: | |
612 if ( ++hostbridges > 1) { | |
613 pcr._pcibuses[pcr._pcinumbus] = pcr._pcinumbus; | |
614 pcr._pcinumbus++; | |
615 } | |
616 break; | |
617 default: | |
618 break; | |
619 } | |
620 if((func==0) && ((pcr._header_type & PCI_MULTIFUNC_DEV) == 0)) { | |
621 /* not a multi function device */ | |
622 func = 8; | |
623 } else { | |
624 func++; | |
625 } | |
626 | |
627 if (idx++ >= MAX_PCI_DEVICES) | |
628 continue; | |
629 | |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
630 identify_card(&pcr, (*num_pci)++); |
3973 | 631 } while( func < 8 ); |
632 } | |
633 } while (++pcr._pcibusidx < pcr._pcinumbus); | |
634 } | |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
635 |
3973 | 636 #if !defined(__alpha__) && !defined(__powerpc__) |
637 /* Now try pci config 2 probe (deprecated) */ | |
638 | |
639 if ((pcr._configtype == 2) || do_mode2_scan) { | |
640 outb(PCI_MODE2_ENABLE_REG, 0xF1); | |
641 outb(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */ | |
642 | |
643 /*printf("\nPCI probing configuration type 2\n");*/ | |
644 | |
645 pcr._pcibuses[0] = 0; | |
646 pcr._pcinumbus = 1; | |
647 pcr._pcibusidx = 0; | |
648 idx = 0; | |
649 | |
650 do { | |
651 for (pcr._ioaddr = 0xC000; pcr._ioaddr < 0xD000; pcr._ioaddr += 0x0100){ | |
652 outb(PCI_MODE2_FORWARD_REG, pcr._pcibuses[pcr._pcibusidx]); /* bus 0 for now */ | |
653 pcr._device_vendor = inl(pcr._ioaddr); | |
654 outb(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */ | |
655 | |
656 if ((pcr._vendor == 0xFFFF) || (pcr._device == 0xFFFF)) | |
657 continue; | |
658 if ((pcr._vendor == 0xF0F0) || (pcr._device == 0xF0F0)) | |
659 continue; /* catch ASUS P55TP4XE motherboards */ | |
660 | |
661 /*printf("\npci bus 0x%x slot at 0x%04x, vendor 0x%04x device 0x%04x\n", | |
662 pcr._pcibuses[pcr._pcibusidx], pcr._ioaddr, pcr._vendor, | |
663 pcr._device);*/ | |
664 pcibus = pcr._pcibuses[pcr._pcibusidx] ; | |
665 pcicard = pcr._ioaddr ; pcifunc = 0 ; | |
666 | |
667 outb(PCI_MODE2_FORWARD_REG, pcr._pcibuses[pcr._pcibusidx]); /* bus 0 for now */ | |
668 pcr._status_command = inl(pcr._ioaddr + 0x04); | |
669 pcr._class_revision = inl(pcr._ioaddr + 0x08); | |
670 pcr._bist_header_latency_cache = inl(pcr._ioaddr + 0x0C); | |
671 pcr._base0 = inl(pcr._ioaddr + 0x10); | |
672 pcr._base1 = inl(pcr._ioaddr + 0x14); | |
673 pcr._base2 = inl(pcr._ioaddr + 0x18); | |
674 pcr._base3 = inl(pcr._ioaddr + 0x1C); | |
675 pcr._base4 = inl(pcr._ioaddr + 0x20); | |
676 pcr._base5 = inl(pcr._ioaddr + 0x24); | |
677 pcr._baserom = inl(pcr._ioaddr + 0x30); | |
678 pcr._max_min_ipin_iline = inl(pcr._ioaddr + 0x3C); | |
679 pcr._user_config = inl(pcr._ioaddr + 0x40); | |
680 outb(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */ | |
681 | |
682 /* check for pci-pci bridges (currently we only know Digital) */ | |
683 if ((pcr._vendor == 0x1011) && (pcr._device == 0x0001)) | |
684 if (pcr._secondary_bus_number > 0) | |
685 pcr._pcibuses[pcr._pcinumbus++] = pcr._secondary_bus_number; | |
686 | |
687 if (idx++ >= MAX_PCI_DEVICES) | |
688 continue; | |
689 | |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
690 identify_card(&pcr, (*num_pci)++); |
3973 | 691 } |
692 } while (++pcr._pcibusidx < pcr._pcinumbus); | |
693 | |
694 outb(PCI_MODE2_ENABLE_REG, 0x00); | |
695 } | |
696 | |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
697 #endif /* !__alpha__ && !__powerpc__ */ |
3973 | 698 |
699 disable_os_io(); | |
700 | |
701 return 0 ; | |
702 | |
703 } | |
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
|
704 |
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
|
705 #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
|
706 #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
|
707 #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
|
708 #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
|
709 #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
|
710 #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
|
711 #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
|
712 |
4277 | 713 int pci_config_read(unsigned char bus, unsigned char dev, unsigned char func, |
714 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
|
715 { |
4277 | 716 int ret; |
717 | |
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
|
718 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
|
719 { |
17971 | 720 fprintf(stderr,"pci_config_read: Reading non-dword not supported!\n"); |
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
|
721 return(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
|
722 } |
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
|
723 |
4277 | 724 ret = enable_os_io(); |
725 if (ret != 0) | |
726 return(ret); | |
727 ret = pci_config_read_long(bus, dev, func, cmd); | |
728 disable_os_io(); | |
729 | |
730 *val = ret; | |
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
|
731 return(0); |
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
|
732 } |
4192 | 733 |
734 int enable_app_io( void ) | |
735 { | |
736 return enable_os_io(); | |
737 } | |
738 | |
739 int disable_app_io( void ) | |
740 { | |
741 return disable_os_io(); | |
5702 | 742 } |