xenocara/xserver/hw/xfree86/os-support/bus/freebsdPci.c

167 lines
5.1 KiB
C
Raw Normal View History

2006-11-26 11:13:41 -07:00
/*
* 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.
*/
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#include <stdio.h>
#include "compiler.h"
#include "xf86.h"
#include "xf86Priv.h"
#include "xf86_OSlib.h"
#include "Pci.h"
#include <sys/pciio.h>
/*
* freebsd platform specific PCI access functions -- using /dev/pci
* needs kernel version 2.2.x
*/
static CARD32 freebsdPciCfgRead(PCITAG tag, int off);
static void freebsdPciCfgWrite(PCITAG, int off, CARD32 val);
static void freebsdPciCfgSetBits(PCITAG tag, int off, CARD32 mask, CARD32 bits);
static pciBusFuncs_t freebsdFuncs0 = {
/* pciReadLong */ freebsdPciCfgRead,
/* pciWriteLong */ freebsdPciCfgWrite,
/* pciSetBitsLong */ freebsdPciCfgSetBits,
/* pciAddrHostToBus */ pciAddrNOOP,
/* pciAddrBusToHost */ pciAddrNOOP
};
static pciBusInfo_t freebsdPci0 = {
/* configMech */ PCI_CFG_MECH_OTHER,
/* numDevices */ 32,
/* secondary */ FALSE,
/* primary_bus */ 0,
/* funcs */ &freebsdFuncs0,
/* pciBusPriv */ NULL,
/* bridge */ NULL
};
#if !defined(__OpenBSD__) && !defined(__FreeBSD__)
#if X_BYTE_ORDER == X_BIG_ENDIAN
#ifdef __sparc__
#ifndef ASI_PL
#define ASI_PL 0x88
#endif
#define PCI_CPU(val) ({ \
int __ret; \
__asm__ __volatile__("lduwa [%1] %2, %0" : "=r" (__ret) : "r" (&val), "i" (ASI_PL)); \
__ret; \
})
#else
#define PCI_CPU(val) (((val >> 24) & 0x000000ff) | \
((val >> 8) & 0x0000ff00) | \
((val << 8) & 0x00ff0000) | \
((val << 24) & 0xff000000))
#endif
#else
#define PCI_CPU(val) (val)
#endif
#else /* ! OpenBSD */
/* OpenBSD has already the bytes in the right order
for all architectures */
#define PCI_CPU(val) (val)
#endif
#define BUS(tag) (((tag)>>16)&0xff)
#define DFN(tag) (((tag)>>8)&0xff)
static int pciFd = -1;
void
freebsdPciInit()
{
pciFd = open("/dev/pci", O_RDWR);
if (pciFd < 0)
return;
pciNumBuses = 1;
pciBusInfo[0] = &freebsdPci0;
pciFindFirstFP = pciGenFindFirst;
pciFindNextFP = pciGenFindNext;
}
static CARD32
freebsdPciCfgRead(PCITAG tag, int off)
{
struct pci_io io;
int error;
io.pi_sel.pc_bus = BUS(tag);
io.pi_sel.pc_dev = DFN(tag) >> 3;
io.pi_sel.pc_func = DFN(tag) & 7;
io.pi_reg = off;
io.pi_width = 4;
error = ioctl(pciFd, PCIOCREAD, &io);
if (error)
return ~0;
return PCI_CPU(io.pi_data);
}
static void
freebsdPciCfgWrite(PCITAG tag, int off, CARD32 val)
{
struct pci_io io;
io.pi_sel.pc_bus = BUS(tag);
io.pi_sel.pc_dev = DFN(tag) >> 3;
io.pi_sel.pc_func = DFN(tag) & 7;
io.pi_reg = off;
io.pi_width = 4;
io.pi_data = PCI_CPU(val);
ioctl(pciFd, PCIOCWRITE, &io);
}
static void
freebsdPciCfgSetBits(PCITAG tag, int off, CARD32 mask, CARD32 bits)
{
CARD32 val = freebsdPciCfgRead(tag, off);
val = (val & ~mask) | (bits & mask);
freebsdPciCfgWrite(tag, off, val);
}