diff options
Diffstat (limited to 'nx-X11/programs/Xserver/hw/xfree86/os-support/bus/Pci.c')
-rw-r--r-- | nx-X11/programs/Xserver/hw/xfree86/os-support/bus/Pci.c | 1453 |
1 files changed, 0 insertions, 1453 deletions
diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/bus/Pci.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/bus/Pci.c deleted file mode 100644 index 4e71eb614..000000000 --- a/nx-X11/programs/Xserver/hw/xfree86/os-support/bus/Pci.c +++ /dev/null @@ -1,1453 +0,0 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c,v 1.82 2004/01/16 15:39:04 tsi Exp $ */ -/* - * Pci.c - New server PCI access functions - * - * The XFree86 server PCI access functions have been reimplemented as a - * framework that allows each supported platform/OS to have their own - * platform/OS specific pci driver. - * - * All of the public PCI access functions exported to the other parts of - * the server are declared in Pci.h and defined herein. These include: - * pciInit() - Initialize PCI access functions - * pciFindFirst() - Find a PCI device by dev/vend id - * pciFindNext() - Find another PCI device by dev/vend id - * pciReadLong() - Read a 32 bit value from a device's cfg space - * pciReadWord() - Read a 16 bit value from a device's cfg space - * pciReadByte() - Read an 8 bit value from a device's cfg space - * pciWriteLong() - Write a 32 bit value to a device's cfg space - * pciWriteWord() - Write a 16 bit value to a device's cfg space - * pciWriteByte() - Write an 8 bit value to a device's cfg space - * pciSetBitsLong() - Write a 32 bit value against a mask - * pciSetBitsByte() - Write an 8 bit value against a mask - * pciTag() - Return tag for a given PCI bus, device, & - * function - * pciBusAddrToHostAddr() - Convert a PCI address to a host address - * pciHostAddrToBusAddr() - Convert a host address to a PCI address - * pciGetBaseSize() - Returns the number of bits in a PCI base - * addr mapping - * xf86MapPciMem() - Like xf86MapVidMem() except function expects - * a PCI address and a PCITAG that identifies - * a PCI device - * xf86ReadPciBIOS() - Like xf86ReadBIOS() but can handle PCI/host - * address translation and BIOS decode enabling - * xf86scanpci() - Return info about all PCI devices - * xf86GetPciDomain() - Return domain number from a PCITAG - * xf86MapDomainMemory() - Like xf86MapPciMem() but can handle - * domain/host address translation - * xf86MapDomainIO() - Maps PCI I/O spaces - * xf86ReadDomainMemory() - Like xf86ReadPciBIOS() but can handle - * domain/host address translation - * - * The actual PCI backend driver is selected by the pciInit() function - * (see below) using either compile time definitions, run-time checks, - * or both. - * - * Certain generic functions are provided that make the implementation - * of certain well behaved platforms (e.g. those supporting PCI config - * mechanism 1 or some thing close to it) very easy. - * - * Less well behaved platforms/OS's can roll their own functions. - * - * To add support for another platform/OS, add a call to fooPciInit() within - * pciInit() below under the correct compile time definition or run-time - * conditional. - * - * The fooPciInit() procedure must do three things: - * 1) Initialize the pciBusTable[] for all primary PCI buses including - * the per domain PCI access functions (readLong, writeLong, - * addrBusToHost, and addrHostToBus). - * - * 2) Add entries to pciBusTable[] for configured secondary buses. This - * step may be skipped if a platform is using the generic findFirst/ - * findNext functions because these procedures will automatically - * discover and add secondary buses dynamically. - * - * 3) Overide default settings for global PCI access functions if - * required. These include pciFindFirstFP, pciFindNextFP, - * Of course, if you choose not to use one of the generic - * functions, you will need to provide a platform specifc replacement. - * - * Gary Barton - * Concurrent Computer Corporation - * garyb@gate.net - * - */ - -/* - * Copyright 1998 by Concurrent Computer Corporation - * - * Permission to use, copy, modify, distribute, and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation, and that the name of Concurrent Computer - * Corporation not be used in advertising or publicity pertaining to - * distribution of the software without specific, written prior - * permission. Concurrent Computer Corporation makes no representations - * about the suitability of this software for any purpose. It is - * provided "as is" without express or implied warranty. - * - * CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD - * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE - * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY - * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - * Copyright 1998 by Metro Link Incorporated - * - * Permission to use, copy, modify, distribute, and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation, and that the name of Metro Link - * Incorporated not be used in advertising or publicity pertaining to - * distribution of the software without specific, written prior - * permission. Metro Link Incorporated makes no representations - * about the suitability of this software for any purpose. It is - * provided "as is" without express or implied warranty. - * - * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD - * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED BE - * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY - * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - * This software is derived from the original XFree86 PCI code - * which includes the following copyright notices as well: - * - * Copyright 1995 by Robin Cutshaw <robin@XFree86.Org> - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the names of the above listed copyright holder(s) - * not be used in advertising or publicity pertaining to distribution of - * the software without specific, written prior permission. The above listed - * copyright holder(s) make(s) no representations about the suitability of this - * software for any purpose. It is provided "as is" without express or - * implied warranty. - * - * THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM(S) ALL WARRANTIES WITH REGARD - * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY - * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * This code is also based heavily on the code in FreeBSD-current, which was - * written by Wolfgang Stanglmeier, and contains the following copyright: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ -/* - * Copyright (c) 1999-2003 by The XFree86 Project, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name of the copyright holder(s) - * and author(s) shall not be used in advertising or otherwise to promote - * the sale, use or other dealings in this Software without prior written - * authorization from the copyright holder(s) and author(s). - */ - -#ifdef HAVE_XORG_CONFIG_H -#include <xorg-config.h> -#endif - -#include <errno.h> -#include <signal.h> -#include <X11/Xarch.h> -#include "compiler.h" -#include "xf86.h" -#include "xf86Priv.h" -#define XF86_OS_PRIVS -#include "xf86_OSproc.h" -#include "Pci.h" - -#define PCI_MFDEV_SUPPORT 1 /* Include PCI multifunction device support */ -#define PCI_BRIDGE_SUPPORT 1 /* Include support for PCI-to-PCI bridges */ - -/* - * Global data - */ -static int pciInitialized = 0; - -CARD32 pciDevid; /* Requested device/vendor ID (after mask) */ -CARD32 pciDevidMask; /* Bit mask applied (AND) before comparison */ - /* of real devid's with requested */ - -int pciBusNum; /* Bus Number of current device */ -int pciDevNum; /* Device number of current device */ -int pciFuncNum; /* Function number of current device */ -PCITAG pciDeviceTag; /* Tag for current device */ - -pciBusInfo_t *pciBusInfo[MAX_PCI_BUSES] = { NULL, }; -int pciNumBuses = 0; /* Actual number of PCI buses */ -int pciMaxBusNum = MAX_PCI_BUSES; -static Bool inProbe = FALSE; - -static pciConfigPtr pci_devp[MAX_PCI_DEVICES + 1] = {NULL, }; - -/* - * Platform specific PCI function pointers. - * - * NOTE: A platform/OS specific pci init procedure can override these defaults - * by setting them to the appropriate platform dependent functions. - */ -PCITAG (*pciFindFirstFP)(void) = pciGenFindFirst; -PCITAG (*pciFindNextFP)(void) = pciGenFindNext; - -/* - * pciInit - choose correct platform/OS specific PCI init routine - */ -void -pciInit() -{ - if (pciInitialized) - return; - - pciInitialized = 1; - - /* XXX */ -#if defined(DEBUGPCI) - if (DEBUGPCI >= xf86Verbose) - xf86Verbose = DEBUGPCI; -#endif - - ARCH_PCI_INIT(); -#if defined(ARCH_PCI_OS_INIT) - if (pciNumBuses <= 0) - ARCH_PCI_OS_INIT(); -#endif -} - -PCITAG -pciFindFirst(CARD32 id, CARD32 mask) -{ -#ifdef DEBUGPCI - ErrorF("pciFindFirst(0x%lx, 0x%lx), pciInit = %d\n", id, mask, pciInitialized); -#endif - pciInit(); - - pciDevid = id & mask; - pciDevidMask = mask; - - return((*pciFindFirstFP)()); -} - -PCITAG -pciFindNext(void) -{ -#ifdef DEBUGPCI - ErrorF("pciFindNext(), pciInit = %d\n", pciInitialized); -#endif - pciInit(); - - return((*pciFindNextFP)()); -} - -CARD32 -pciReadLong(PCITAG tag, int offset) -{ - int bus = PCI_BUS_FROM_TAG(tag); - -#ifdef DEBUGPCI - ErrorF("pciReadLong(0x%lx, %d)\n", tag, offset); -#endif - pciInit(); - - if ((bus >= 0) && ((bus < pciNumBuses) || inProbe) && pciBusInfo[bus] && - pciBusInfo[bus]->funcs->pciReadLong) { - CARD32 rv = (*pciBusInfo[bus]->funcs->pciReadLong)(tag, offset); - - PCITRACE(1, ("pciReadLong: tag=0x%x [b=%d,d=%d,f=%d] returns 0x%08x\n", - tag, bus, PCI_DEV_FROM_TAG(tag), PCI_FUNC_FROM_TAG(tag), rv)); - return(rv); - } - - return(PCI_NOT_FOUND); -} - -CARD16 -pciReadWord(PCITAG tag, int offset) -{ - CARD32 tmp; - int shift = (offset & 3) * 8; - int aligned_offset = offset & ~3; - int bus = PCI_BUS_FROM_TAG(tag); - - if (shift != 0 && shift != 16) - FatalError("pciReadWord: Alignment error: Cannot read 16 bits " - "at offset %d\n", offset); - - pciInit(); - - if ((bus >= 0) && ((bus < pciNumBuses) || inProbe) && pciBusInfo[bus] && - pciBusInfo[bus]->funcs->pciReadWord) { - CARD32 rv = (*pciBusInfo[bus]->funcs->pciReadWord)(tag, offset); - - return(rv); - } else { - tmp = pciReadLong(tag, aligned_offset); - - return((CARD16)((tmp >> shift) & 0xffff)); - } -} - -CARD8 -pciReadByte(PCITAG tag, int offset) -{ - CARD32 tmp; - int shift = (offset & 3) * 8; - int aligned_offset = offset & ~3; - int bus = PCI_BUS_FROM_TAG(tag); - - pciInit(); - - if ((bus >= 0) && ((bus < pciNumBuses) || inProbe) && pciBusInfo[bus] && - pciBusInfo[bus]->funcs->pciReadByte) { - CARD8 rv = (*pciBusInfo[bus]->funcs->pciReadByte)(tag, offset); - - return(rv); - } else { - tmp = pciReadLong(tag, aligned_offset); - - return((CARD8)((tmp >> shift) & 0xff)); - } -} - -void -pciWriteLong(PCITAG tag, int offset, CARD32 val) -{ - int bus = PCI_BUS_FROM_TAG(tag); - - pciInit(); - - if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] && - pciBusInfo[bus]->funcs->pciWriteLong) - (*pciBusInfo[bus]->funcs->pciWriteLong)(tag, offset, val); -} - -void -pciWriteWord(PCITAG tag, int offset, CARD16 val) -{ - CARD32 tmp; - int aligned_offset = offset & ~3; - int shift = (offset & 3) * 8; - int bus = PCI_BUS_FROM_TAG(tag); - - if (shift != 0 && shift != 16) - FatalError("pciWriteWord: Alignment Error: Cannot read 16 bits " - "from offset %d\n", offset); - - pciInit(); - - if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] && - pciBusInfo[bus]->funcs->pciWriteWord) { - (*pciBusInfo[bus]->funcs->pciWriteWord)(tag, offset, val); - } else { - tmp = pciReadLong(tag, aligned_offset); - - tmp &= ~(0xffffL << shift); - tmp |= (((CARD32)val) << shift); - - pciWriteLong(tag, aligned_offset, tmp); - } -} - -void -pciWriteByte(PCITAG tag, int offset, CARD8 val) -{ - CARD32 tmp; - int aligned_offset = offset & ~3; - int shift = (offset & 3) *8 ; - int bus = PCI_BUS_FROM_TAG(tag); - - pciInit(); - - if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] && - pciBusInfo[bus]->funcs->pciWriteByte) { - (*pciBusInfo[bus]->funcs->pciWriteByte)(tag, offset, val); - } else { - - tmp = pciReadLong(tag, aligned_offset); - - tmp &= ~(0xffL << shift); - tmp |= (((CARD32)val) << shift); - - pciWriteLong(tag, aligned_offset, tmp); - } -} - -void -pciSetBitsLong(PCITAG tag, int offset, CARD32 mask, CARD32 val) -{ - int bus = PCI_BUS_FROM_TAG(tag); - -#ifdef DEBUGPCI - ErrorF("pciReadLong(0x%lx, %d)\n", tag, offset); -#endif - pciInit(); - - if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] && - pciBusInfo[bus]->funcs->pciSetBitsLong) { - (*pciBusInfo[bus]->funcs->pciSetBitsLong)(tag, offset, mask, val); - } -} - -void -pciSetBitsByte(PCITAG tag, int offset, CARD8 mask, CARD8 val) -{ - CARD32 tmp_mask, tmp_val; - int aligned_offset = offset & ~3; - int shift = (offset & 3) *8 ; - - tmp_mask = mask << shift; - tmp_val = val << shift; - pciSetBitsLong(tag, aligned_offset, tmp_mask, tmp_val); -} - -ADDRESS -pciBusAddrToHostAddr(PCITAG tag, PciAddrType type, ADDRESS addr) -{ - int bus = PCI_BUS_FROM_TAG(tag); - - pciInit(); - - if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] && - pciBusInfo[bus]->funcs->pciAddrBusToHost) - return (*pciBusInfo[bus]->funcs->pciAddrBusToHost)(tag, type, addr); - else - return(addr); -} - -ADDRESS -pciHostAddrToBusAddr(PCITAG tag, PciAddrType type, ADDRESS addr) -{ - int bus = PCI_BUS_FROM_TAG(tag); - - pciInit(); - - if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] && - pciBusInfo[bus]->funcs->pciAddrHostToBus) - return (*pciBusInfo[bus]->funcs->pciAddrHostToBus)(tag, type, addr); - else - return(addr); -} - -/* - * pciGetBaseSize() returns the size of a PCI base address mapping in bits. - * The index identifies the base register: 0-5 are the six standard registers, - * and 6 is the ROM base register. If destructive is TRUE, it will write - * to the base address register to get an accurate result. Otherwise it - * makes a conservative guess based on the alignment of the already allocated - * address. If the result is accurate (ie, not an over-estimate), this is - * indicated by setting *min to TRUE (when min is non-NULL). This happens - * when either the destructive flag is set, the information is supplied by - * the OS if the OS supports this. - */ - -int -pciGetBaseSize(PCITAG tag, int index, Bool destructive, Bool *min) -{ - int offset; - CARD32 addr1; - CARD32 addr2; - CARD32 mask1; - CARD32 mask2; - int bits = 0; - - /* - * Eventually a function for this should be added to pciBusFuncs_t, but for - * now we'll just use a simple method based on the alignment of the already - * allocated address. - */ - - /* - * silently ignore bogus index values. Valid values are 0-6. 0-5 are - * the 6 base address registers, and 6 is the ROM base address register. - */ - if (index < 0 || index > 6) - return 0; - - pciInit(); - - if (xf86GetPciSizeFromOS(tag, index, &bits)) { - if (min) - *min = TRUE; - return bits; - } - - if (min) - *min = destructive; - - /* Get the PCI offset */ - if (index == 6) - offset = PCI_MAP_ROM_REG; - else - offset = PCI_MAP_REG_START + (index << 2); - - addr1 = pciReadLong(tag, offset); - /* - * Check if this is the second part of a 64 bit address. - * XXX need to check how endianness affects 64 bit addresses. - */ - if (index > 0 && index < 6) { - addr2 = pciReadLong(tag, offset - 4); - if (PCI_MAP_IS_MEM(addr2) && PCI_MAP_IS64BITMEM(addr2)) - return 0; - } - - if (destructive) { - pciWriteLong(tag, offset, 0xffffffff); - mask1 = pciReadLong(tag, offset); - pciWriteLong(tag, offset, addr1); - } else { - mask1 = addr1; - } - - /* Check if this is the first part of a 64 bit address. */ - if (index < 5 && PCI_MAP_IS_MEM(mask1) && PCI_MAP_IS64BITMEM(mask1)) { - if (PCIGETMEMORY(mask1) == 0) { - addr2 = pciReadLong(tag, offset + 4); - if (destructive) { - pciWriteLong(tag, offset + 4, 0xffffffff); - mask2 = pciReadLong(tag, offset + 4); - pciWriteLong(tag, offset + 4, addr2); - } else { - mask2 = addr2; - } - if (mask2 == 0) - return 0; - bits = 32; - while ((mask2 & 1) == 0) { - bits++; - mask2 >>= 1; - } - if (bits > 32) - return bits; - } - } - if (index < 6) - if (PCI_MAP_IS_MEM(mask1)) - mask1 = PCIGETMEMORY(mask1); - else - mask1 = PCIGETIO(mask1); - else - mask1 = PCIGETROM(mask1); - if (mask1 == 0) - return 0; - bits = 0; - while ((mask1 & 1) == 0) { - bits++; - mask1 >>= 1; - } - /* I/O maps can be no larger than 8 bits */ - - if ((index < 6) && PCI_MAP_IS_IO(addr1) && bits > 8) - bits = 8; - /* ROM maps can be no larger than 24 bits */ - if (index == 6 && bits > 24) - bits = 24; - return bits; -} - -PCITAG -pciTag(int busnum, int devnum, int funcnum) -{ - return(PCI_MAKE_TAG(busnum,devnum,funcnum)); -} - -#if defined(PCI_MFDEV_SUPPORT) || defined(PowerMAX_OS) - -Bool -pciMfDev(int busnum, int devnum) -{ - PCITAG tag0, tag1; - CARD32 id0, id1, val; - - /* Detect a multi-function device that complies to the PCI 2.0 spec */ - - tag0 = PCI_MAKE_TAG(busnum, devnum, 0); - id0 = pciReadLong(tag0, PCI_ID_REG); - if ((CARD16)(id0 + 1) <= (CARD16)1UL) - return FALSE; - - val = pciReadLong(tag0, PCI_HEADER_MISC) & 0x00ff0000; - if ((val != 0x00ff0000) && (val & PCI_HEADER_MULTIFUNCTION)) - return TRUE; - - /* - * Now, to find non-compliant devices... - * If there is a valid ID for function 1 and the ID for func 0 and 1 - * are different, or the base0 values of func 0 and 1 are differend, - * then assume there is a multi-function device. - */ - tag1 = PCI_MAKE_TAG(busnum, devnum, 1); - id1 = pciReadLong(tag1, PCI_ID_REG); - if ((CARD16)(id1 + 1) <= (CARD16)1UL) - return FALSE; - - /* Vendor IDs should match */ - if ((id0 ^ id1) & 0x0000ffff) - return FALSE; - - if ((id0 != id1) || - /* Note the following test is valid for header types 0, 1 and 2 */ - (pciReadLong(tag0, PCI_MAP_REG_START) != - pciReadLong(tag1, PCI_MAP_REG_START))) - return TRUE; - - return FALSE; -} - -#endif - -/* - * Generic find/read/write functions - */ -PCITAG -pciGenFindNext(void) -{ - CARD32 devid, tmp; - int sec_bus, pri_bus; - static int previousBus = 0; - Bool speculativeProbe = FALSE; - unsigned char base_class, sub_class; - -#ifdef DEBUGPCI - ErrorF("pciGenFindNext\n"); -#endif - - for (;;) { - -#ifdef DEBUGPCI - ErrorF("pciGenFindNext: pciBusNum %d\n", pciBusNum); -#endif - if (pciBusNum == -1) { - /* - * Start at top of the order - */ - if (pciNumBuses <= 0) - return(PCI_NOT_FOUND); - - /* Skip ahead to the first bus defined by pciInit() */ - for (pciBusNum = 0; !pciBusInfo[pciBusNum]; ++pciBusNum); - pciFuncNum = 0; - pciDevNum = 0; - previousBus = pciBusNum; /* make sure previousBus exists */ - } else { -#ifdef PCI_MFDEV_SUPPORT -#ifdef DEBUGPCI - ErrorF("pciGenFindNext: pciFuncNum %d\n", pciFuncNum); -#endif - /* - * Somewhere in middle of order. Determine who's - * next up - */ - if (pciFuncNum == 0) { - /* - * Is current dev a multifunction device? - */ - if (!speculativeProbe && pciMfDev(pciBusNum, pciDevNum)) - /* Probe for other functions */ - pciFuncNum = 1; - else - /* - * No more functions this device. Next - * device please - */ - pciDevNum ++; - } else if (++pciFuncNum >= 8) { - /* No more functions for this device. Next device please */ - pciFuncNum = 0; - pciDevNum ++; - } -#else - pciDevNum ++; -#endif - if (pciDevNum >= 32 || - !pciBusInfo[pciBusNum] || - pciDevNum >= pciBusInfo[pciBusNum]->numDevices) { -#ifdef DEBUGPCI - ErrorF("pciGenFindNext: next bus\n"); -#endif - /* - * No more devices for this bus. Next bus please - */ - if (speculativeProbe) { - NextSpeculativeBus: - xfree(pciBusInfo[pciBusNum]); - pciBusInfo[pciBusNum] = NULL; - speculativeProbe = FALSE; - } - - if (++pciBusNum >= pciMaxBusNum) { -#ifdef DEBUGPCI - ErrorF("pciGenFindNext: out of buses\n"); -#endif - /* No more buses. All done for now */ - return(PCI_NOT_FOUND); - } - - pciDevNum = 0; - } - } - -#ifdef DEBUGPCI - ErrorF("pciGenFindNext: pciBusInfo[%d] = 0x%lx\n", pciBusNum, pciBusInfo[pciBusNum]); -#endif - if (!pciBusInfo[pciBusNum]) { - pciBusInfo[pciBusNum] = xnfalloc(sizeof(pciBusInfo_t)); - *pciBusInfo[pciBusNum] = *pciBusInfo[previousBus]; - - speculativeProbe = TRUE; - } - - /* - * At this point, pciBusNum, pciDevNum, and pciFuncNum have been - * advanced to the next device. Compute the tag, and read the - * device/vendor ID field. - */ -#ifdef DEBUGPCI - ErrorF("pciGenFindNext: [%d, %d, %d]\n", pciBusNum, pciDevNum, pciFuncNum); -#endif - pciDeviceTag = PCI_MAKE_TAG(pciBusNum, pciDevNum, pciFuncNum); - inProbe = TRUE; - devid = pciReadLong(pciDeviceTag, PCI_ID_REG); - inProbe = FALSE; -#ifdef DEBUGPCI - ErrorF("pciGenFindNext: pciDeviceTag = 0x%lx, devid = 0x%lx\n", pciDeviceTag, devid); -#endif - if ((CARD16)(devid + 1U) <= (CARD16)1UL) - continue; /* Nobody home. Next device please */ - - /* - * Some devices mis-decode configuration cycles in such a way as to - * create phantom buses. - */ - if (speculativeProbe && (pciDevNum == 0) && (pciFuncNum == 0) && - (PCI_BUS_NO_DOMAIN(pciBusNum) > 0)) { - for (;;) { - if (++pciDevNum >= pciBusInfo[pciBusNum]->numDevices) - goto NextSpeculativeBus; - if (devid != - pciReadLong(PCI_MAKE_TAG(pciBusNum, pciDevNum, 0), - PCI_ID_REG)) - break; - } - - pciDevNum = 0; - } - - if (pciNumBuses <= pciBusNum) - pciNumBuses = pciBusNum + 1; - - speculativeProbe = FALSE; - previousBus = pciBusNum; - -#ifdef PCI_BRIDGE_SUPPORT - /* - * Before checking for a specific devid, look for enabled - * PCI to PCI bridge devices. If one is found, create and - * initialize a bus info record (if one does not already exist). - */ - tmp = pciReadLong(pciDeviceTag, PCI_CLASS_REG); - base_class = PCI_CLASS_EXTRACT(tmp); - sub_class = PCI_SUBCLASS_EXTRACT(tmp); - if ((base_class == PCI_CLASS_BRIDGE) && - ((sub_class == PCI_SUBCLASS_BRIDGE_PCI) || - (sub_class == PCI_SUBCLASS_BRIDGE_CARDBUS))) { - tmp = pciReadLong(pciDeviceTag, PCI_PCI_BRIDGE_BUS_REG); - sec_bus = PCI_SECONDARY_BUS_EXTRACT(tmp, pciDeviceTag); - pri_bus = PCI_PRIMARY_BUS_EXTRACT(tmp, pciDeviceTag); -#ifdef DEBUGPCI - ErrorF("pciGenFindNext: pri_bus %d sec_bus %d\n", - pri_bus, sec_bus); -#endif - if (pciBusNum != pri_bus) { - /* Some bridges do not implement the primary bus register */ - if ((PCI_BUS_NO_DOMAIN(pri_bus) != 0) || - (sub_class != PCI_SUBCLASS_BRIDGE_CARDBUS)) - xf86Msg(X_WARNING, - "pciGenFindNext: primary bus mismatch on PCI" - " bridge 0x%08lx (0x%02x, 0x%02x)\n", - pciDeviceTag, pciBusNum, pri_bus); - pri_bus = pciBusNum; - } - if ((pri_bus < sec_bus) && (sec_bus < pciMaxBusNum) && - pciBusInfo[pri_bus]) { - /* - * Found a secondary PCI bus - */ - if (!pciBusInfo[sec_bus]) { - pciBusInfo[sec_bus] = xnfalloc(sizeof(pciBusInfo_t)); - - /* Copy parents settings... */ - *pciBusInfo[sec_bus] = *pciBusInfo[pri_bus]; - } - - /* ...but not everything same as parent */ - pciBusInfo[sec_bus]->primary_bus = pri_bus; - pciBusInfo[sec_bus]->secondary = TRUE; - pciBusInfo[sec_bus]->numDevices = 32; - - if (pciNumBuses <= sec_bus) - pciNumBuses = sec_bus + 1; - } - } -#endif - - /* - * Does this device match the requested devid after - * applying mask? - */ -#ifdef DEBUGPCI - ErrorF("pciGenFindNext: pciDevidMask = 0x%lx, pciDevid = 0x%lx\n", pciDevidMask, pciDevid); -#endif - if ((devid & pciDevidMask) == pciDevid) - /* Yes - Return it. Otherwise, next device */ - return(pciDeviceTag); /* got a match */ - - } /* for */ - /*NOTREACHED*/ -} - -PCITAG -pciGenFindFirst(void) -{ - /* Reset PCI bus number to start from top */ - pciBusNum = -1; - - return pciGenFindNext(); -} - -CARD32 -pciByteSwap(CARD32 u) -{ -#if X_BYTE_ORDER == X_BIG_ENDIAN -# if defined(__powerpc__) && defined(PowerMAX_OS) - CARD32 tmp; - - __inst_stwbrx(u, &tmp, 0); - - return(tmp); - -# else /* !PowerMAX_OS */ - - return lswapl(u); - -# endif /* !PowerMAX_OS */ - -#else /* !BIG_ENDIAN */ - - return(u); - -#endif -} - -ADDRESS -pciAddrNOOP(PCITAG tag, PciAddrType type, ADDRESS addr) -{ - return(addr); -} - -pciConfigPtr * -xf86scanpci(int flags) -{ - pciConfigPtr devp; - pciBusInfo_t *busp; - int idx = 0, i; - PCITAG tag; - static Bool done = FALSE; - - /* - * if we haven't found PCI devices checking for pci_devp may - * result in an endless recursion if platform/OS specific PCI - * bus probing code calls this function from with in it. - */ - if (done || pci_devp[0]) - return pci_devp; - - done = TRUE; - - pciInit(); - -#ifdef XF86SCANPCI_WRAPPER - XF86SCANPCI_WRAPPER(SCANPCI_INIT); -#endif - - tag = pciFindFirst(0,0); /* 0 mask means match any valid device */ - /* Check if no devices, return now */ - if (tag == PCI_NOT_FOUND) { -#ifdef XF86SCANPCI_WRAPPER - XF86SCANPCI_WRAPPER(SCANPCI_TERM); -#endif - return NULL; - } - -#ifdef DEBUGPCI - ErrorF("xf86scanpci: tag = 0x%lx\n", tag); -#endif -#ifndef OLD_FORMAT - xf86MsgVerb(X_INFO, 2, "PCI: PCI scan (all values are in hex)\n"); -#endif - - while (idx < MAX_PCI_DEVICES && tag != PCI_NOT_FOUND) { - devp = xcalloc(1, sizeof(pciDevice)); - if (!devp) { - xf86Msg(X_ERROR, - "xf86scanpci: Out of memory after %d devices!!\n", idx); - return (pciConfigPtr *)NULL; - } - - /* Identify pci device by bus, dev, func, and tag */ - devp->tag = tag; - devp->busnum = PCI_BUS_FROM_TAG(tag); - devp->devnum = PCI_DEV_FROM_TAG(tag); - devp->funcnum = PCI_FUNC_FROM_TAG(tag); - - /* Read config space for this device */ - for (i = 0; i < 17; i++) /* PCI hdr plus 1st dev spec dword */ - devp->cfgspc.dwords[i] = pciReadLong(tag, i * sizeof(CARD32)); - - /* Some broken devices don't implement this field... */ - if (devp->pci_header_type == 0xff) - devp->pci_header_type = 0; - - switch (devp->pci_header_type & 0x7f) { - case 0: - /* Get base address sizes for type 0 headers */ - for (i = 0; i < 7; i++) - devp->basesize[i] = - pciGetBaseSize(tag, i, FALSE, &devp->minBasesize); - break; - - case 1: - case 2: - /* Allow master aborts to complete normally on secondary buses */ - if (!(devp->pci_bridge_control & PCI_PCI_BRIDGE_MASTER_ABORT_EN)) - break; - pciWriteByte(tag, PCI_PCI_BRIDGE_CONTROL_REG, - devp->pci_bridge_control & - ~(PCI_PCI_BRIDGE_MASTER_ABORT_EN | - PCI_PCI_BRIDGE_SECONDARY_RESET)); - break; - - default: - break; - } - -#ifdef OLD_FORMAT - xf86MsgVerb(X_INFO, 2, "PCI: BusID 0x%.2x,0x%02x,0x%1x " - "ID 0x%04x,0x%04x Rev 0x%02x Class 0x%02x,0x%02x\n", - devp->busnum, devp->devnum, devp->funcnum, - devp->pci_vendor, devp->pci_device, devp->pci_rev_id, - devp->pci_base_class, devp->pci_sub_class); -#else - xf86MsgVerb(X_INFO, 2, "PCI: %.2x:%02x:%1x: chip %04x,%04x" - " card %04x,%04x rev %02x class %02x,%02x,%02x hdr %02x\n", - devp->busnum, devp->devnum, devp->funcnum, - devp->pci_vendor, devp->pci_device, - devp->pci_subsys_vendor, devp->pci_subsys_card, - devp->pci_rev_id, devp->pci_base_class, - devp->pci_sub_class, devp->pci_prog_if, - devp->pci_header_type); -#endif - - pci_devp[idx++] = devp; - tag = pciFindNext(); - -#ifdef DEBUGPCI - ErrorF("xf86scanpci: tag = pciFindNext = 0x%lx\n", tag); -#endif - } - - /* Restore modified data (in reverse order), and link buses */ - while (--idx >= 0) { - devp = pci_devp[idx]; - switch (devp->pci_header_type & 0x7f) { - case 0: - if ((devp->pci_base_class != PCI_CLASS_BRIDGE) || - (devp->pci_sub_class != PCI_SUBCLASS_BRIDGE_HOST)) - break; - pciBusInfo[devp->busnum]->bridge = devp; - pciBusInfo[devp->busnum]->primary_bus = devp->busnum; - break; - - case 1: - case 2: - i = PCI_SECONDARY_BUS_EXTRACT(devp->pci_pp_bus_register, devp->tag); - if (i > devp->busnum) { - if (pciBusInfo[i]) { - pciBusInfo[i]->bridge = devp; - /* - * The back link needs to be set here, and is unlikely to - * change. - */ - devp->businfo = pciBusInfo[i]; - } -#ifdef ARCH_PCI_PCI_BRIDGE - ARCH_PCI_PCI_BRIDGE(devp); -#endif - } - if (!(devp->pci_bridge_control & PCI_PCI_BRIDGE_MASTER_ABORT_EN)) - break; - pciWriteByte(devp->tag, PCI_PCI_BRIDGE_CONTROL_REG, - devp->pci_bridge_control & ~PCI_PCI_BRIDGE_SECONDARY_RESET); - break; - - default: - break; - } - } - -#ifdef XF86SCANPCI_WRAPPER - XF86SCANPCI_WRAPPER(SCANPCI_TERM); -#endif - - /* - * Lastly, link bridges to their secondary bus, after the architecture has - * had a chance to modify these assignments. - */ - for (idx = 0; idx < pciNumBuses; idx++) { - if (!(busp = pciBusInfo[idx]) || !(devp = busp->bridge)) - continue; - devp->businfo = busp; - } - -#ifndef OLD_FORMAT - xf86MsgVerb(X_INFO, 2, "PCI: End of PCI scan\n"); -#endif - - return pci_devp; -} - -CARD32 -pciCheckForBrokenBase(PCITAG Tag,int basereg) -{ - pciWriteLong(Tag, PCI_MAP_REG_START + (basereg << 2), 0xffffffff); - return pciReadLong(Tag, PCI_MAP_REG_START + (basereg << 2)); -} - -#if defined(INCLUDE_XF86_MAP_PCI_MEM) - -pointer -xf86MapPciMem(int ScreenNum, int Flags, PCITAG Tag, ADDRESS Base, - unsigned long Size) -{ - ADDRESS hostbase = pciBusAddrToHostAddr(Tag, PCI_MEM,Base); - pointer base; - CARD32 save = 0; - - /* - * If there are possible read side-effects, disable memory while - * doing the mapping. - */ - if (Flags & VIDMEM_READSIDEEFFECT) { - save = pciReadLong(Tag, PCI_CMD_STAT_REG); - pciWriteLong(Tag, PCI_CMD_STAT_REG, - save & ~PCI_CMD_MEM_ENABLE); - } - base = xf86MapDomainMemory(ScreenNum, Flags, Tag, hostbase, Size); - if (!base) { - FatalError("xf86MapPciMem: Could not mmap PCI memory " - "[base=0x%lx,hostbase=0x%lx,size=%lx] (%s)\n", - Base, hostbase, Size, strerror(errno)); - } - /* - * If read side-effects, do whatever might be needed to prevent - * unintended reads, then restore PCI_CMD_STAT_REG. - */ - if (Flags & VIDMEM_READSIDEEFFECT) { - xf86MapReadSideEffects(ScreenNum, Flags, base, Size); - pciWriteLong(Tag, PCI_CMD_STAT_REG, save); - } - return((pointer)base); -} - -static int -handlePciBIOS(PCITAG Tag, int basereg, - int (*func)(PCITAG, CARD8*, ADDRESS, pointer), - pointer args) -{ - CARD32 romsave = 0; - int i; - romBaseSource b_reg; - ADDRESS hostbase; - CARD8 tmp[64]; - int ret = 0; - - romsave = pciReadLong(Tag, PCI_MAP_ROM_REG); - - for (i = ROM_BASE_PRESET; i <= ROM_BASE_FIND; i++) { - memType savebase = 0, newbase, romaddr; - - switch (i) { - case ROM_BASE_PRESET: - /* Does the driver have a preference? */ - if (basereg > ROM_BASE_PRESET && basereg <= ROM_BASE_FIND) - b_reg = basereg; - else - b_reg = ++i; - break; - case ROM_BASE_FIND: - /* - * If we have something that looks like a valid address - * in romsave, it's probably not going to help to try - * to guess a new address and reprogram it. - */ - if (PCIGETROM(romsave)) { - pciWriteLong(Tag, PCI_MAP_ROM_REG, PCI_MAP_ROM_ADDRESS_MASK); - if (romsave != pciReadLong(Tag, PCI_MAP_ROM_REG)) { - pciWriteLong(Tag, PCI_MAP_ROM_REG, romsave); - continue; - } - } - default: - b_reg = i; - } - - if (!(newbase = getValidBIOSBase(Tag, b_reg))) - continue; /* no valid address found */ - - romaddr = PCIGETROM(newbase); - - /* if we use a mem base save it and move it out of the way */ - if (b_reg >= 0 && b_reg <= 5) { - savebase = pciReadLong(Tag, PCI_MAP_REG_START+(b_reg<<2)); - xf86MsgVerb(X_INFO,5,"xf86ReadPciBios: modifying membase[%i]" - " for device %i:%i:%i\n", basereg, - (int)PCI_BUS_FROM_TAG(Tag), (int)PCI_DEV_FROM_TAG(Tag), - (int)PCI_FUNC_FROM_TAG(Tag)); - pciWriteLong(Tag, PCI_MAP_REG_START + (b_reg << 2), - (CARD32)~0); - } - /* Set ROM base address and enable ROM address decoding */ - pciWriteLong(Tag, PCI_MAP_ROM_REG, romaddr - | PCI_MAP_ROM_DECODE_ENABLE); - - hostbase = pciBusAddrToHostAddr(Tag, PCI_MEM, PCIGETROM(romaddr)); - - if ((xf86ReadDomainMemory(Tag, hostbase, sizeof(tmp), tmp) != - sizeof(tmp)) || - (tmp[0] != 0x55) || (tmp[1] != 0xaa) || !tmp[2] ) { - /* Restore the base registers if they were changed. */ - pciWriteLong(Tag, PCI_MAP_ROM_REG, romsave); - if (savebase) pciWriteLong(Tag, PCI_MAP_REG_START + (b_reg << 2), - (CARD32) savebase); - - /* No BIOS found: try another address */ - continue; - } - - ret = (*func)(Tag, tmp, hostbase, args); - - /* Restore the base register if it was changed. */ - if (savebase) pciWriteLong(Tag, PCI_MAP_REG_START + (b_reg << 2), - (CARD32) savebase); - /* Restore ROM address decoding */ - pciWriteLong(Tag, PCI_MAP_ROM_REG, romsave); - - return ret; - } - /* Restore ROM address decoding */ - pciWriteLong(Tag, PCI_MAP_ROM_REG, romsave); - return 0; -} - -typedef struct { - unsigned long Offset; - int Len; - unsigned char *Buf; - PciBiosType BiosType; -} readBios, *readBiosPtr; - -static int -readPciBios(PCITAG Tag, CARD8* tmp, ADDRESS hostbase, pointer args) -{ - unsigned int image_length = 0; - readBiosPtr rd = args; - int ret; - - /* We found a PCI BIOS Image. Now we look for the correct type */ - while ((tmp[0] == 0x55) && (tmp[1] == 0xAA)) { - unsigned short data_off = tmp[0x18] | (tmp[0x19] << 8); - unsigned char data[0x18]; - unsigned char type; - - if ((xf86ReadDomainMemory(Tag, hostbase + data_off, sizeof(data), data) - != sizeof(data)) || - (data[0] != 'P') || - (data[1] != 'C') || - (data[2] != 'I') || - (data[3] != 'R')) - break; - type = data[0x14]; -#ifdef PRINT_PCI - ErrorF("data segment in BIOS: 0x%x, type: 0x%x\n", data_off, type); -#endif - if (type != rd->BiosType) { /* not correct image: find next one */ - unsigned char indicator = data[0x15]; - unsigned int i_length; - if (indicator & 0x80) /* last image */ - break; - i_length = (data[0x10] | (data[0x11] << 8)) << 9; -#ifdef PRINT_PCI - ErrorF("data image length: 0x%x, ind: 0x%x\n", - image_length, indicator); -#endif - hostbase += i_length; - if (xf86ReadDomainMemory(Tag, hostbase, sizeof(tmp), tmp) - != sizeof(tmp)) - break; - continue; - } - /* OK, we have a PCI BIOS Image of the correct type */ - - if (rd->BiosType == PCI_BIOS_PC) - image_length = tmp[2] << 9; - else - image_length = (data[0x10] | (data[0x11] << 8)) << 9; -#ifdef PRINT_PCI - ErrorF("BIOS length: 0x%x\n", image_length); -#endif - break; - } - - ret = 0; - if (image_length) { - - /* - * if no length is given return the full lenght, - * Offset 0. Beware: Area pointed to by Buf must - * be large enough! - */ - if (rd->Len == 0) { - rd->Len = image_length; - rd->Offset = 0; - } - if ((rd->Offset) > (image_length)) { - xf86Msg(X_WARNING,"xf86ReadPciBios: requesting data past " - "end of BIOS %li > %i\n",(rd->Offset) , (image_length)); - } else { - if ((rd->Offset + rd->Len) > (image_length)) { - rd->Len = (image_length) - rd->Offset; - xf86MsgVerb(X_INFO,3,"Truncating PCI BIOS Length to %i\n",rd->Len); - } - } - - /* Read BIOS */ - ret = xf86ReadDomainMemory(Tag, hostbase + rd->Offset, rd->Len, rd->Buf); - } - - return ret; -} - -static int -getPciBIOSTypes(PCITAG Tag, CARD8* tmp, ADDRESS hostbase, pointer arg) -{ - int n = 0; - PciBiosType *Buf = arg; - - /* We found a PCI BIOS Image. Now we collect the types type */ - do { - unsigned short data_off = tmp[0x18] | (tmp[0x19] << 8); - unsigned char data[0x16]; - unsigned int i_length; - - if ((xf86ReadDomainMemory(Tag, hostbase + data_off, sizeof(data), data) - != sizeof(data)) || - (data[0] != 'P') || - (data[1] != 'C') || - (data[2] != 'I') || - (data[3] != 'R')) - break; - - if (data[0x14] >= PCI_BIOS_OTHER) - *Buf++ = PCI_BIOS_OTHER; - else - *Buf++ = data[0x14]; - - n++; - if (data[0x15] & 0x80) /* last image */ - break; -#ifdef PRINT_PCI - ErrorF("data segment in BIOS: 0x%x, type: 0x%x\n", data_off, type); -#endif - i_length = (data[0x10] | (data[0x11] << 8)) << 9; -#ifdef PRINT_PCI - ErrorF("data image length: 0x%x, ind: 0x%x\n", - image_length, indicator); -#endif - hostbase += i_length; - if (xf86ReadDomainMemory(Tag, hostbase, sizeof(tmp), tmp) - != sizeof(tmp)) - break; - continue; - } while ((tmp[0] == 0x55) && (tmp[1] == 0xAA)); - return n; -} - -typedef CARD32 (*ReadProcPtr)(PCITAG, int); -typedef void (*WriteProcPtr)(PCITAG, int, CARD32); - -static int -HandlePciBios(PCITAG Tag, int basereg, - int (*func)(PCITAG, CARD8*, ADDRESS, pointer), - pointer ptr) -{ - int n, num; - CARD32 Acc1, Acc2; - PCITAG *pTag; - int i; - - n = handlePciBIOS(Tag,basereg,func,ptr); - if (n) - return n; - - num = pciTestMultiDeviceCard(PCI_BUS_FROM_TAG(Tag), - PCI_DEV_FROM_TAG(Tag), - PCI_FUNC_FROM_TAG(Tag),&pTag); - - if (!num) return 0; - -#define PCI_ENA (PCI_CMD_MEM_ENABLE | PCI_CMD_IO_ENABLE) - Acc1 = pciReadLong(Tag, PCI_CMD_STAT_REG); - pciWriteLong(Tag, PCI_CMD_STAT_REG, (Acc1 & ~PCI_ENA)); - - for (i = 0; i < num; i++) { - Acc2 = pciReadLong(pTag[i], PCI_CMD_STAT_REG); - pciWriteLong(pTag[i], PCI_CMD_STAT_REG, (Acc2 | PCI_ENA)); - - n = handlePciBIOS(pTag[i],0,func,ptr); - - pciWriteLong(pTag[i], PCI_CMD_STAT_REG, Acc2); - if (n) - break; - } - pciWriteLong(Tag, PCI_CMD_STAT_REG, Acc1); - return n; -} - -int -xf86ReadPciBIOS(unsigned long Offset, PCITAG Tag, int basereg, - unsigned char *Buf, int Len) -{ - return xf86ReadPciBIOSByType(Offset, Tag, basereg, Buf, Len, PCI_BIOS_PC); -} - -int -xf86ReadPciBIOSByType(unsigned long Offset, PCITAG Tag, int basereg, - unsigned char *Buf, int Len, PciBiosType Type) -{ - - readBios rb; - rb.Offset = Offset; - rb.Len = Len; - rb.Buf = Buf; - rb.BiosType = Type; - - return HandlePciBios(Tag, basereg, readPciBios, &rb); -} - -int -xf86GetAvailablePciBIOSTypes(PCITAG Tag, int basereg, PciBiosType *Buf) -{ - return HandlePciBios(Tag, basereg, getPciBIOSTypes, (pointer) Buf); -} - -#endif /* INCLUDE_XF86_MAP_PCI_MEM */ - -#ifdef INCLUDE_XF86_NO_DOMAIN - -int -xf86GetPciDomain(PCITAG Tag) -{ - return 0; -} - -pointer -xf86MapDomainMemory(int ScreenNum, int Flags, PCITAG Tag, - ADDRESS Base, unsigned long Size) -{ - return xf86MapVidMem(ScreenNum, Flags, Base, Size); -} - -IOADDRESS -xf86MapDomainIO(int ScreenNum, int Flags, PCITAG Tag, - IOADDRESS Base, unsigned long Size) -{ - return Base; -} - -int -xf86ReadDomainMemory(PCITAG Tag, ADDRESS Base, int Len, unsigned char *Buf) -{ - int ret, length, rlength; - - /* Read in 64kB chunks */ - ret = 0; - while ((length = Len) > 0) { - if (length > 0x010000) length = 0x010000; - rlength = xf86ReadBIOS(Base, 0, Buf, length); - if (rlength < 0) { - ret = rlength; - break; - } - ret += rlength; - if (rlength < length) break; - Base += rlength; - Buf += rlength; - Len -= rlength; - } - - return ret; -} - -#endif /* INCLUDE_XF86_NO_DOMAIN */ |