Mercurial > mplayer.hg
annotate vidix/pci.c @ 25317:7f3cb5408f28
Fixed VIDIX color bug that was introduced when Radeon VIDIX driver
was synchronized with vidix.sf.net.
The red color was saturating.
Corrected value fixes the issue and restore the color to the level
it used to have before synchronization.
Meaning of the value remains unknow but was retrieved from
register's value of a Radeon 9000 card, so it may need further testing.
Patch by Guillaume Lecerf (foxcore at gmail dot com)
author | ben |
---|---|
date | Mon, 10 Dec 2007 19:27:46 +0000 |
parents | 263c0b282d90 |
children | 502f04b67653 |
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 */ | |
64 #if defined (linux) | |
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; | |
110 return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | (p[0] << 0)); | |
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 } | |
162 #endif | |
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 }; | |
440 #endif | |
441 | |
442 #define MAX_DEV_PER_VENDOR_CFG1 64 | |
443 #define MAX_PCI_DEVICES_PER_BUS 32 | |
444 #define MAX_PCI_DEVICES 64 | |
445 #define NF ((void (*)())NULL), { 0.0, 0, 0, NULL } | |
446 #define PCI_MULTIFUNC_DEV 0x80 | |
447 #define PCI_ID_REG 0x00 | |
448 #define PCI_CMD_STAT_REG 0x04 | |
449 #define PCI_CLASS_REG 0x08 | |
450 #define PCI_HEADER_MISC 0x0C | |
451 #define PCI_MAP_REG_START 0x10 | |
452 #define PCI_MAP_ROM_REG 0x30 | |
453 #define PCI_INTERRUPT_REG 0x3C | |
454 #define PCI_REG_USERCONFIG 0x40 | |
455 | |
456 static int pcibus=-1, pcicard=-1, pcifunc=-1 ; | |
457 /*static struct pci_device *pcidev=NULL ;*/ | |
458 | |
459 #if defined(__alpha__) | |
460 #define PCI_EN 0x00000000 | |
461 #else | |
462 #define PCI_EN 0x80000000 | |
463 #endif | |
464 | |
465 #define PCI_MODE1_ADDRESS_REG 0xCF8 | |
466 #define PCI_MODE1_DATA_REG 0xCFC | |
467 | |
468 #define PCI_MODE2_ENABLE_REG 0xCF8 | |
469 #ifdef PC98 | |
470 #define PCI_MODE2_FORWARD_REG 0xCF9 | |
471 #else | |
472 #define PCI_MODE2_FORWARD_REG 0xCFA | |
473 #endif | |
4164 | 474 |
475 /* 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
|
476 #ifndef CONFIG_SVGAHELPER |
4164 | 477 #if defined(__alpha__) |
478 #include "sysdep/pci_alpha.c" | |
479 #elif defined(__ia64__) | |
480 #include "sysdep/pci_ia64.c" | |
481 #elif defined(__sparc__) | |
482 #include "sysdep/pci_sparc.c" | |
483 #elif defined( __arm32__ ) | |
484 #include "sysdep/pci_arm32.c" | |
485 #elif defined(__powerpc__) | |
486 #include "sysdep/pci_powerpc.c" | |
12687 | 487 #elif defined(__x86_64__) |
488 /* Nothing here right now */ | |
4164 | 489 #else |
490 #include "sysdep/pci_x86.c" | |
491 #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
|
492 #endif |
3973 | 493 |
494 static pciinfo_t *pci_lst; | |
495 | |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
496 static void identify_card(struct pci_config_reg *pcr, int idx) |
3973 | 497 { |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
498 /* local overflow test */ |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
499 if (idx>=MAX_PCI_DEVICES) return ; |
3973 | 500 |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
501 pci_lst[idx].bus = pcibus ; |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
502 pci_lst[idx].card = pcicard ; |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
503 pci_lst[idx].func = pcifunc ; |
9767
f6d2772efca3
Ignore disabled cards. (Jon Burgess <jburgess@uklinux.net>)
ranma
parents:
8776
diff
changeset
|
504 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
|
505 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
|
506 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
|
507 pci_lst[idx].base0 = 0xFFFFFFFF ; |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
508 pci_lst[idx].base1 = 0xFFFFFFFF ; |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
509 pci_lst[idx].base2 = 0xFFFFFFFF ; |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
510 pci_lst[idx].baserom = 0x000C0000 ; |
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
511 if (pcr->_base0) pci_lst[idx].base0 = pcr->_base0 & |
3973 | 512 ((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
|
513 if (pcr->_base1) pci_lst[idx].base1 = pcr->_base1 & |
3973 | 514 ((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
|
515 if (pcr->_base2) pci_lst[idx].base2 = pcr->_base2 & |
3973 | 516 ((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
|
517 if (pcr->_baserom) pci_lst[idx].baserom = pcr->_baserom ; |
3973 | 518 } |
519 | |
520 /*main(int argc, char *argv[])*/ | |
521 int pci_scan(pciinfo_t *pci_list,unsigned *num_pci) | |
522 { | |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
523 unsigned int idx = 0; |
3973 | 524 struct pci_config_reg pcr; |
24510
e7f836a459ea
ifdef one variable that is not used with alpha and powerpc architectures
ben
parents:
23734
diff
changeset
|
525 int do_mode1_scan = 0; |
e7f836a459ea
ifdef one variable that is not used with alpha and powerpc architectures
ben
parents:
23734
diff
changeset
|
526 #if !defined(__alpha__) && !defined(__powerpc__) |
e7f836a459ea
ifdef one variable that is not used with alpha and powerpc architectures
ben
parents:
23734
diff
changeset
|
527 int do_mode2_scan = 0; |
e7f836a459ea
ifdef one variable that is not used with alpha and powerpc architectures
ben
parents:
23734
diff
changeset
|
528 #endif |
3973 | 529 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
|
530 int ret = -1; |
3973 | 531 |
532 pci_lst = pci_list; | |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
533 *num_pci = 0; |
3973 | 534 |
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 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
|
536 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
|
537 return(ret); |
4164 | 538 |
539 if((pcr._configtype = pci_config_type()) == 0xFFFF) return ENODEV; | |
3973 | 540 |
541 /* Try pci config 1 probe first */ | |
542 | |
543 if ((pcr._configtype == 1) || do_mode1_scan) { | |
544 /*printf("\nPCI probing configuration type 1\n");*/ | |
545 | |
546 pcr._ioaddr = 0xFFFF; | |
547 | |
548 pcr._pcibuses[0] = 0; | |
549 pcr._pcinumbus = 1; | |
550 pcr._pcibusidx = 0; | |
551 | |
552 do { | |
553 /*printf("Probing for devices on PCI bus %d:\n\n", pcr._pcibusidx);*/ | |
554 | |
555 for (pcr._cardnum = 0x0; pcr._cardnum < MAX_PCI_DEVICES_PER_BUS; | |
556 pcr._cardnum += 0x1) { | |
557 func = 0; | |
558 do { /* loop over the different functions, if present */ | |
4164 | 559 pcr._device_vendor = pci_get_vendor(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum, |
560 func); | |
3973 | 561 if ((pcr._vendor == 0xFFFF) || (pcr._device == 0xFFFF)) |
562 break; /* nothing there */ | |
563 | |
564 /*printf("\npci bus 0x%x cardnum 0x%02x function 0x%04x: vendor 0x%04x device 0x%04x\n", | |
565 pcr._pcibuses[pcr._pcibusidx], pcr._cardnum, func, | |
566 pcr._vendor, pcr._device);*/ | |
4164 | 567 pcibus = pcr._pcibuses[pcr._pcibusidx]; |
568 pcicard = pcr._cardnum; | |
569 pcifunc = func; | |
3973 | 570 |
4164 | 571 pcr._status_command = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], |
572 pcr._cardnum,func,PCI_CMD_STAT_REG); | |
573 pcr._class_revision = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
574 pcr._cardnum,func,PCI_CLASS_REG); | |
575 pcr._bist_header_latency_cache = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
576 pcr._cardnum,func,PCI_HEADER_MISC); | |
577 pcr._base0 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
578 pcr._cardnum,func,PCI_MAP_REG_START); | |
579 pcr._base1 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
580 pcr._cardnum,func,PCI_MAP_REG_START+4); | |
581 pcr._base2 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
582 pcr._cardnum,func,PCI_MAP_REG_START+8); | |
583 pcr._base3 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
584 pcr._cardnum,func,PCI_MAP_REG_START+0x0C); | |
585 pcr._base4 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
586 pcr._cardnum,func,PCI_MAP_REG_START+0x10); | |
587 pcr._base5 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
588 pcr._cardnum,func,PCI_MAP_REG_START+0x14); | |
589 pcr._baserom = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
590 pcr._cardnum,func,PCI_MAP_ROM_REG); | |
591 pcr._max_min_ipin_iline = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
592 pcr._cardnum,func,PCI_INTERRUPT_REG); | |
593 pcr._user_config = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], | |
594 pcr._cardnum,func,PCI_REG_USERCONFIG); | |
3973 | 595 /* check for pci-pci bridges */ |
596 #define PCI_CLASS_MASK 0xff000000 | |
597 #define PCI_SUBCLASS_MASK 0x00ff0000 | |
598 #define PCI_CLASS_BRIDGE 0x06000000 | |
599 #define PCI_SUBCLASS_BRIDGE_PCI 0x00040000 | |
600 switch(pcr._class_revision & (PCI_CLASS_MASK|PCI_SUBCLASS_MASK)) { | |
601 case PCI_CLASS_BRIDGE|PCI_SUBCLASS_BRIDGE_PCI: | |
602 if (pcr._secondary_bus_number > 0) { | |
603 pcr._pcibuses[pcr._pcinumbus++] = pcr._secondary_bus_number; | |
604 } | |
605 break; | |
606 case PCI_CLASS_BRIDGE: | |
607 if ( ++hostbridges > 1) { | |
608 pcr._pcibuses[pcr._pcinumbus] = pcr._pcinumbus; | |
609 pcr._pcinumbus++; | |
610 } | |
611 break; | |
612 default: | |
613 break; | |
614 } | |
615 if((func==0) && ((pcr._header_type & PCI_MULTIFUNC_DEV) == 0)) { | |
616 /* not a multi function device */ | |
617 func = 8; | |
618 } else { | |
619 func++; | |
620 } | |
621 | |
622 if (idx++ >= MAX_PCI_DEVICES) | |
623 continue; | |
624 | |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
625 identify_card(&pcr, (*num_pci)++); |
3973 | 626 } while( func < 8 ); |
627 } | |
628 } while (++pcr._pcibusidx < pcr._pcinumbus); | |
629 } | |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
630 |
3973 | 631 #if !defined(__alpha__) && !defined(__powerpc__) |
632 /* Now try pci config 2 probe (deprecated) */ | |
633 | |
634 if ((pcr._configtype == 2) || do_mode2_scan) { | |
635 outb(PCI_MODE2_ENABLE_REG, 0xF1); | |
636 outb(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */ | |
637 | |
638 /*printf("\nPCI probing configuration type 2\n");*/ | |
639 | |
640 pcr._pcibuses[0] = 0; | |
641 pcr._pcinumbus = 1; | |
642 pcr._pcibusidx = 0; | |
643 idx = 0; | |
644 | |
645 do { | |
646 for (pcr._ioaddr = 0xC000; pcr._ioaddr < 0xD000; pcr._ioaddr += 0x0100){ | |
647 outb(PCI_MODE2_FORWARD_REG, pcr._pcibuses[pcr._pcibusidx]); /* bus 0 for now */ | |
648 pcr._device_vendor = inl(pcr._ioaddr); | |
649 outb(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */ | |
650 | |
651 if ((pcr._vendor == 0xFFFF) || (pcr._device == 0xFFFF)) | |
652 continue; | |
653 if ((pcr._vendor == 0xF0F0) || (pcr._device == 0xF0F0)) | |
654 continue; /* catch ASUS P55TP4XE motherboards */ | |
655 | |
656 /*printf("\npci bus 0x%x slot at 0x%04x, vendor 0x%04x device 0x%04x\n", | |
657 pcr._pcibuses[pcr._pcibusidx], pcr._ioaddr, pcr._vendor, | |
658 pcr._device);*/ | |
659 pcibus = pcr._pcibuses[pcr._pcibusidx] ; | |
660 pcicard = pcr._ioaddr ; pcifunc = 0 ; | |
661 | |
662 outb(PCI_MODE2_FORWARD_REG, pcr._pcibuses[pcr._pcibusidx]); /* bus 0 for now */ | |
663 pcr._status_command = inl(pcr._ioaddr + 0x04); | |
664 pcr._class_revision = inl(pcr._ioaddr + 0x08); | |
665 pcr._bist_header_latency_cache = inl(pcr._ioaddr + 0x0C); | |
666 pcr._base0 = inl(pcr._ioaddr + 0x10); | |
667 pcr._base1 = inl(pcr._ioaddr + 0x14); | |
668 pcr._base2 = inl(pcr._ioaddr + 0x18); | |
669 pcr._base3 = inl(pcr._ioaddr + 0x1C); | |
670 pcr._base4 = inl(pcr._ioaddr + 0x20); | |
671 pcr._base5 = inl(pcr._ioaddr + 0x24); | |
672 pcr._baserom = inl(pcr._ioaddr + 0x30); | |
673 pcr._max_min_ipin_iline = inl(pcr._ioaddr + 0x3C); | |
674 pcr._user_config = inl(pcr._ioaddr + 0x40); | |
675 outb(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */ | |
676 | |
677 /* check for pci-pci bridges (currently we only know Digital) */ | |
678 if ((pcr._vendor == 0x1011) && (pcr._device == 0x0001)) | |
679 if (pcr._secondary_bus_number > 0) | |
680 pcr._pcibuses[pcr._pcinumbus++] = pcr._secondary_bus_number; | |
681 | |
682 if (idx++ >= MAX_PCI_DEVICES) | |
683 continue; | |
684 | |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
685 identify_card(&pcr, (*num_pci)++); |
3973 | 686 } |
687 } while (++pcr._pcibusidx < pcr._pcinumbus); | |
688 | |
689 outb(PCI_MODE2_ENABLE_REG, 0x00); | |
690 } | |
691 | |
8776
298208d7a703
pci_scan cleanup, idea and initial patch by Aurelien Jacobs <aurel@gnuage.org>
alex
parents:
8503
diff
changeset
|
692 #endif /* !__alpha__ && !__powerpc__ */ |
3973 | 693 |
694 disable_os_io(); | |
695 | |
696 return 0 ; | |
697 | |
698 } | |
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
|
699 |
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 #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
|
701 #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
|
702 #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
|
703 #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
|
704 #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
|
705 #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
|
706 #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
|
707 |
4277 | 708 int pci_config_read(unsigned char bus, unsigned char dev, unsigned char func, |
709 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
|
710 { |
4277 | 711 int ret; |
712 | |
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
|
713 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
|
714 { |
17971 | 715 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
|
716 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
|
717 } |
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 |
4277 | 719 ret = enable_os_io(); |
720 if (ret != 0) | |
721 return(ret); | |
722 ret = pci_config_read_long(bus, dev, func, cmd); | |
723 disable_os_io(); | |
724 | |
725 *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
|
726 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
|
727 } |
4192 | 728 |
729 int enable_app_io( void ) | |
730 { | |
731 return enable_os_io(); | |
732 } | |
733 | |
734 int disable_app_io( void ) | |
735 { | |
736 return disable_os_io(); | |
5702 | 737 } |