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