Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/xserver
This commit is contained in:
commit
22ee2e4e1f
|
@ -1398,7 +1398,7 @@ fixPciResource(int prt, memType alignment, pciVideoPtr pvp, unsigned long type)
|
|||
(*p_base) = H2B(tag,range.rBegin,type);
|
||||
#ifdef DEBUG
|
||||
ErrorF("New PCI res %i base: 0x%lx, size: 0x%lx, type %s\n",
|
||||
res_n,(*p_base),(1 << (*p_size)),
|
||||
res_n,(*p_base),(1L << (*p_size)),
|
||||
((type & ResPhysMask) == ResMem) ? "Mem" : "Io");
|
||||
#endif
|
||||
if (res_n != 0xff) {
|
||||
|
@ -1577,8 +1577,8 @@ findPciRange(PCITAG tag, resPtr m, resPtr avoid, CARD32 size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
pciVideoPtr
|
||||
getPciVideoPtr(tag)
|
||||
static pciVideoPtr
|
||||
getPciVideoPtr(PCITAG tag)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
|
|
|
@ -13,8 +13,12 @@ COMMON_SOURCES = \
|
|||
xf86int10.c \
|
||||
xf86int10module.c
|
||||
|
||||
if I386_VIDEO
|
||||
I386_VIDEO_CFLAGS = -D_PC
|
||||
endif
|
||||
|
||||
if INT10_VM86
|
||||
AM_CFLAGS = -D_PC -D_VM86_LINUX $(XORG_CFLAGS) $(EXTRA_CFLAGS)
|
||||
AM_CFLAGS = $(I386_VIDEO_CFLAGS) -D_VM86_LINUX $(XORG_CFLAGS) $(EXTRA_CFLAGS)
|
||||
INCLUDES = $(XORG_INCS)
|
||||
libint10_la_SOURCES = \
|
||||
$(COMMON_SOURCES) \
|
||||
|
@ -23,7 +27,8 @@ libint10_la_SOURCES = \
|
|||
endif
|
||||
|
||||
if INT10_X86EMU
|
||||
AM_CFLAGS = -D_X86EMU -DNO_SYS_HEADERS -D_PC $(XORG_CFLAGS) $(EXTRA_CFLAGS)
|
||||
AM_CFLAGS = $(I386_VIDEO_CFLAGS) -D_X86EMU -DNO_SYS_HEADERS \
|
||||
$(XORG_CFLAGS) $(EXTRA_CFLAGS)
|
||||
INCLUDES = $(XORG_INCS) -I$(srcdir)/../x86emu
|
||||
libint10_la_SOURCES = \
|
||||
$(COMMON_SOURCES) \
|
||||
|
@ -33,7 +38,7 @@ libint10_la_SOURCES = \
|
|||
endif
|
||||
|
||||
if INT10_STUB
|
||||
AM_CFLAGS = -D_PC -D_VM86_LINUX $(XORG_CFLAGS) $(EXTRA_CFLAGS)
|
||||
AM_CFLAGS = $(I386_VIDEO_CFLAGS) -D_VM86_LINUX $(XORG_CFLAGS) $(EXTRA_CFLAGS)
|
||||
libint10_la_SOURCES = stub.c xf86int10module.c
|
||||
endif
|
||||
|
||||
|
|
|
@ -469,7 +469,6 @@ Mem_wl(CARD32 addr, CARD32 val)
|
|||
|
||||
static CARD32 PciCfg1Addr = 0;
|
||||
|
||||
#define TAG(Cfg1Addr) (Cfg1Addr & 0xffff00)
|
||||
#define OFFSET(Cfg1Addr) (Cfg1Addr & 0xff)
|
||||
|
||||
static int
|
||||
|
@ -480,7 +479,7 @@ pciCfg1in(CARD16 addr, CARD32 *val)
|
|||
return 1;
|
||||
}
|
||||
if (addr == 0xCFC) {
|
||||
*val = pciReadLong(TAG(PciCfg1Addr), OFFSET(PciCfg1Addr));
|
||||
*val = pciReadLong(Int10Current->Tag, OFFSET(PciCfg1Addr));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -494,7 +493,7 @@ pciCfg1out(CARD16 addr, CARD32 val)
|
|||
return 1;
|
||||
}
|
||||
if (addr == 0xCFC) {
|
||||
pciWriteLong(TAG(PciCfg1Addr), OFFSET(PciCfg1Addr), val);
|
||||
pciWriteLong(Int10Current->Tag, OFFSET(PciCfg1Addr), val);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -512,7 +511,7 @@ pciCfg1inw(CARD16 addr, CARD16 *val)
|
|||
}
|
||||
if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
|
||||
offset = addr - 0xCFC;
|
||||
*val = pciReadWord(TAG(PciCfg1Addr), OFFSET(PciCfg1Addr) + offset);
|
||||
*val = pciReadWord(Int10Current->Tag, OFFSET(PciCfg1Addr) + offset);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -531,7 +530,7 @@ pciCfg1outw(CARD16 addr, CARD16 val)
|
|||
}
|
||||
if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
|
||||
offset = addr - 0xCFC;
|
||||
pciWriteWord(TAG(PciCfg1Addr), OFFSET(PciCfg1Addr) + offset, val);
|
||||
pciWriteWord(Int10Current->Tag, OFFSET(PciCfg1Addr) + offset, val);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -549,7 +548,7 @@ pciCfg1inb(CARD16 addr, CARD8 *val)
|
|||
}
|
||||
if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
|
||||
offset = addr - 0xCFC;
|
||||
*val = pciReadByte(TAG(PciCfg1Addr), OFFSET(PciCfg1Addr) + offset);
|
||||
*val = pciReadByte(Int10Current->Tag, OFFSET(PciCfg1Addr) + offset);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -568,7 +567,7 @@ pciCfg1outb(CARD16 addr, CARD8 val)
|
|||
}
|
||||
if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
|
||||
offset = addr - 0xCFC;
|
||||
pciWriteByte(TAG(PciCfg1Addr), OFFSET(PciCfg1Addr) + offset, val);
|
||||
pciWriteByte(Int10Current->Tag, OFFSET(PciCfg1Addr) + offset, val);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
* pciSetBitsByte() - Write an 8 bit value against a mask
|
||||
* pciTag() - Return tag for a given PCI bus, device, &
|
||||
* function
|
||||
* pciDomTag() - Return tag for a given PCI domain, 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
|
||||
|
@ -614,6 +616,12 @@ pciTag(int busnum, int devnum, int funcnum)
|
|||
return(PCI_MAKE_TAG(busnum,devnum,funcnum));
|
||||
}
|
||||
|
||||
_X_EXPORT PCITAG
|
||||
pciDomTag(int domnum, int busnum, int devnum, int funcnum)
|
||||
{
|
||||
return(PCI_MAKE_TAG(PCI_MAKE_BUS(domnum,busnum),devnum,funcnum));
|
||||
}
|
||||
|
||||
#if defined(PCI_MFDEV_SUPPORT)
|
||||
|
||||
Bool
|
||||
|
|
|
@ -119,7 +119,7 @@
|
|||
/* by xf86scanpci */
|
||||
#if defined(sun) && defined(SVR4) && defined(sparc)
|
||||
# define MAX_PCI_BUSES 4096 /* Max number of PCI buses */
|
||||
#elif defined(__alpha__) && defined (linux)
|
||||
#elif (defined(__alpha__) || defined(__ia64__)) && defined (linux)
|
||||
# define MAX_PCI_DOMAINS 512
|
||||
# define PCI_DOM_MASK 0x01fful
|
||||
# define MAX_PCI_BUSES (MAX_PCI_DOMAINS*256) /* 256 per domain */
|
||||
|
@ -258,7 +258,7 @@
|
|||
# endif
|
||||
#elif defined(__ia64__)
|
||||
# if defined(linux)
|
||||
# define ARCH_PCI_INIT linuxPciInit
|
||||
# define ARCH_PCI_INIT ia64linuxPciInit
|
||||
# define INCLUDE_XF86_MAP_PCI_MEM
|
||||
# elif defined(FreeBSD)
|
||||
# define ARCH_PCI_INIT freebsdPciInit
|
||||
|
|
|
@ -41,13 +41,14 @@ static pciDevice *get_dev_on_bus(unsigned int segnum, unsigned int busnum)
|
|||
static void get_bridge_info(pciBusInfo_t *bus_info, pciDevice *pdev)
|
||||
{
|
||||
unsigned int parent_segnum, segnum = PCI_DOM_FROM_TAG(pdev->tag);
|
||||
unsigned int parent_busnum, busnum = pdev->busnum;
|
||||
unsigned int parent_busnum, parent_nodombus, busnum = pdev->busnum;
|
||||
unsigned int nodombus = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(pdev->tag));
|
||||
char bridge_path[] = "/sys/class/pci_bus/0000:00/bridge";
|
||||
char bridge_target[] = "../../../devices/pci0000:00";
|
||||
|
||||
/* Path to this device's bridge */
|
||||
sprintf(bridge_path, "/sys/class/pci_bus/%04x:%02x/bridge", segnum,
|
||||
busnum);
|
||||
nodombus);
|
||||
|
||||
if (readlink(bridge_path, bridge_target, strlen(bridge_target)) < 0) {
|
||||
perror("failed to dereference bridge link");
|
||||
|
@ -56,7 +57,9 @@ static void get_bridge_info(pciBusInfo_t *bus_info, pciDevice *pdev)
|
|||
}
|
||||
|
||||
sscanf(bridge_target, "../../../devices/pci%04x:%02x", &parent_segnum,
|
||||
&parent_busnum);
|
||||
&parent_nodombus);
|
||||
|
||||
parent_busnum = PCI_MAKE_BUS(parent_segnum, parent_nodombus);
|
||||
|
||||
/*
|
||||
* If there's no bridge or the bridge points to the device, use
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "xf86Priv.h"
|
||||
#include "xf86_OSlib.h"
|
||||
#include "Pci.h"
|
||||
#include <dirent.h>
|
||||
|
||||
/*
|
||||
* linux platform specific PCI access functions -- using /proc/bus/pci
|
||||
|
@ -73,6 +74,7 @@ static void linuxPciCfgWriteByte(PCITAG tag, int off, CARD8 val);
|
|||
static CARD16 linuxPciCfgReadWord(PCITAG tag, int off);
|
||||
static void linuxPciCfgWriteWord(PCITAG tag, int off, CARD16 val);
|
||||
static int linuxPciHandleBIOS(PCITAG Tag, int basereg, unsigned char *buf, int len);
|
||||
static Bool linuxDomainSupport(void);
|
||||
|
||||
static pciBusFuncs_t linuxFuncs0 = {
|
||||
/* pciReadLong */ linuxPciCfgRead,
|
||||
|
@ -116,6 +118,8 @@ static pciBusInfo_t linuxPci0 = {
|
|||
/* from lnx_pci.c. */
|
||||
extern int lnxPciInit(void);
|
||||
|
||||
static Bool domain_support = FALSE;
|
||||
|
||||
void
|
||||
linuxPciInit()
|
||||
{
|
||||
|
@ -126,6 +130,9 @@ linuxPciInit()
|
|||
we'll need a fallback for 2.0 kernels here */
|
||||
return;
|
||||
}
|
||||
#ifndef INCLUDE_XF86_NO_DOMAIN
|
||||
domain_support = linuxDomainSupport();
|
||||
#endif
|
||||
pciNumBuses = 1;
|
||||
pciBusInfo[0] = &linuxPci0;
|
||||
pciFindFirstFP = pciGenFindFirst;
|
||||
|
@ -137,13 +144,14 @@ linuxPciInit()
|
|||
static int
|
||||
linuxPciOpenFile(PCITAG tag, Bool write)
|
||||
{
|
||||
static int lbus,ldev,lfunc,fd = -1,is_write = 0;
|
||||
int bus, dev, func;
|
||||
static int ldomain, lbus,ldev,lfunc,fd = -1,is_write = 0;
|
||||
int domain, bus, dev, func;
|
||||
char file[64];
|
||||
struct stat ignored;
|
||||
static int is26 = -1;
|
||||
|
||||
bus = PCI_BUS_FROM_TAG(tag);
|
||||
domain = PCI_DOM_FROM_TAG(tag);
|
||||
bus = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(tag));
|
||||
dev = PCI_DEV_FROM_TAG(tag);
|
||||
func = PCI_FUNC_FROM_TAG(tag);
|
||||
if (is26 == -1) {
|
||||
|
@ -153,30 +161,41 @@ linuxPciOpenFile(PCITAG tag, Bool write)
|
|||
is26 = 1;
|
||||
}
|
||||
|
||||
if (fd == -1 || (write && (!is_write))
|
||||
if (!domain_support && domain > 0)
|
||||
return -1;
|
||||
|
||||
if (fd == -1 || (write && (!is_write)) || domain != ldomain
|
||||
|| bus != lbus || dev != ldev || func != lfunc) {
|
||||
if (fd != -1)
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
if (is26)
|
||||
sprintf(file,"/sys/bus/pci/devices/0000:%02x:%02x.%01x/config",
|
||||
bus, dev, func);
|
||||
sprintf(file,"/sys/bus/pci/devices/%04x:%02x:%02x.%01x/config",
|
||||
domain, bus, dev, func);
|
||||
else {
|
||||
if (bus < 256) {
|
||||
sprintf(file,"/proc/bus/pci/%02x",bus);
|
||||
if (stat(file, &ignored) < 0)
|
||||
sprintf(file, "/proc/bus/pci/0000:%02x/%02x.%1x",
|
||||
bus, dev, func);
|
||||
else
|
||||
sprintf(file, "/proc/bus/pci/%02x/%02x.%1x",
|
||||
bus, dev, func);
|
||||
sprintf(file, "/proc/bus/pci/%04x:%02x", domain, bus);
|
||||
if (stat(file, &ignored) < 0) {
|
||||
if (domain == 0)
|
||||
sprintf(file, "/proc/bus/pci/%02x/%02x.%1x",
|
||||
bus, dev, func);
|
||||
else
|
||||
goto bail;
|
||||
} else
|
||||
sprintf(file, "/proc/bus/pci/%04x:%02x/%02x.%1x",
|
||||
domain, bus, dev, func);
|
||||
} else {
|
||||
sprintf(file,"/proc/bus/pci/%04x",bus);
|
||||
if (stat(file, &ignored) < 0)
|
||||
sprintf(file, "/proc/bus/pci/0000:%04x/%02x.%1x",
|
||||
bus, dev, func);
|
||||
else
|
||||
sprintf(file, "/proc/bus/pci/%04x/%02x.%1x",
|
||||
bus, dev, func);
|
||||
sprintf(file, "/proc/bus/pci/%04x:%04x", domain, bus);
|
||||
if (stat(file, &ignored) < 0) {
|
||||
if (domain == 0)
|
||||
sprintf(file, "/proc/bus/pci/%04x/%02x.%1x",
|
||||
bus, dev, func);
|
||||
else
|
||||
goto bail;
|
||||
} else
|
||||
sprintf(file, "/proc/bus/pci/%04x:%04x/%02x.%1x",
|
||||
domain, bus, dev, func);
|
||||
}
|
||||
}
|
||||
if (write) {
|
||||
|
@ -191,7 +210,8 @@ linuxPciOpenFile(PCITAG tag, Bool write)
|
|||
fd = open(file,O_RDONLY);
|
||||
is_write = FALSE;
|
||||
}
|
||||
|
||||
bail:
|
||||
ldomain = domain;
|
||||
lbus = bus;
|
||||
ldev = dev;
|
||||
lfunc = func;
|
||||
|
@ -489,6 +509,32 @@ linuxGetSizes(PCITAG Tag, unsigned long *io_size, unsigned long *mem_size)
|
|||
*mem_size = sizes->mem_size;
|
||||
}
|
||||
|
||||
static Bool
|
||||
linuxDomainSupport(void)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *dirent;
|
||||
char *end;
|
||||
|
||||
if (!(dir = opendir("/proc/bus/pci")))
|
||||
return FALSE;
|
||||
while (1) {
|
||||
if (!(dirent = readdir(dir)))
|
||||
return FALSE;
|
||||
strtol(dirent->d_name,&end,16);
|
||||
/* entry of the form xx or xxxx : x=[0..f] no domain */
|
||||
if (*end == '\0')
|
||||
return FALSE;
|
||||
else if (*end == ':') {
|
||||
/* ':' found immediately after: verify for xxxx:xx or xxxx:xxxx */
|
||||
strtol(end + 1,&end,16);
|
||||
if (*end == '\0')
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_X_EXPORT int
|
||||
xf86GetPciDomain(PCITAG Tag)
|
||||
{
|
||||
|
@ -524,9 +570,7 @@ linuxMapPci(int ScreenNum, int Flags, PCITAG Tag,
|
|||
|
||||
xf86InitVidMem();
|
||||
|
||||
pPCI = xf86GetPciHostConfigFromTag(Tag);
|
||||
|
||||
if (((fd = linuxPciOpenFile(pPCI ? pPCI->tag : 0,FALSE)) < 0) ||
|
||||
if (((fd = linuxPciOpenFile(Tag ,FALSE)) < 0) ||
|
||||
(ioctl(fd, mmap_ioctl, 0) < 0))
|
||||
break;
|
||||
|
||||
|
@ -583,7 +627,6 @@ linuxMapPci(int ScreenNum, int Flags, PCITAG Tag,
|
|||
|
||||
#define MAX_DOMAINS 257
|
||||
static pointer DomainMmappedIO[MAX_DOMAINS];
|
||||
static pointer DomainMmappedMem[MAX_DOMAINS];
|
||||
|
||||
static int
|
||||
linuxOpenLegacy(PCITAG Tag, char *name)
|
||||
|
@ -641,6 +684,7 @@ xf86MapDomainMemory(int ScreenNum, int Flags, PCITAG Tag,
|
|||
{
|
||||
int domain = xf86GetPciDomain(Tag);
|
||||
int fd;
|
||||
pointer addr;
|
||||
|
||||
/*
|
||||
* We use /proc/bus/pci on non-legacy addresses or if the Linux sysfs
|
||||
|
@ -654,20 +698,14 @@ xf86MapDomainMemory(int ScreenNum, int Flags, PCITAG Tag,
|
|||
return linuxMapPci(ScreenNum, Flags, Tag, Base, Size,
|
||||
PCIIOC_MMAP_IS_MEM);
|
||||
|
||||
|
||||
/* If we haven't already mapped this legacy space, try to. */
|
||||
if (!DomainMmappedMem[domain]) {
|
||||
DomainMmappedMem[domain] = mmap(NULL, 1024*1024, PROT_READ|PROT_WRITE,
|
||||
MAP_SHARED, fd, 0);
|
||||
if (DomainMmappedMem[domain] == MAP_FAILED) {
|
||||
close(fd);
|
||||
perror("mmap failure");
|
||||
FatalError("xf86MapDomainMem(): mmap() failure\n");
|
||||
}
|
||||
addr = mmap(NULL, Size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, Base);
|
||||
if (addr == MAP_FAILED) {
|
||||
close (fd);
|
||||
perror("mmap failure");
|
||||
FatalError("xf86MapDomainMem(): mmap() failure\n");
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return (pointer)((char *)DomainMmappedMem[domain] + Base);
|
||||
return addr;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -731,7 +769,7 @@ xf86ReadDomainMemory(PCITAG Tag, ADDRESS Base, int Len, unsigned char *Buf)
|
|||
struct stat st;
|
||||
|
||||
dom = PCI_DOM_FROM_TAG(Tag);
|
||||
bus = PCI_BUS_FROM_TAG(Tag);
|
||||
bus = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(Tag));
|
||||
dev = PCI_DEV_FROM_TAG(Tag);
|
||||
func = PCI_FUNC_FROM_TAG(Tag);
|
||||
sprintf(file, "/sys/devices/pci%04x:%02x/%04x:%02x:%02x.%1x/rom",
|
||||
|
@ -910,7 +948,7 @@ int linuxPciHandleBIOS(PCITAG Tag, int basereg, unsigned char *buf, int len)
|
|||
int sofar = 0;
|
||||
|
||||
dom = PCI_DOM_FROM_TAG(Tag);
|
||||
bus = PCI_BUS_FROM_TAG(Tag);
|
||||
bus = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(Tag));
|
||||
dev = PCI_DEV_FROM_TAG(Tag);
|
||||
func = PCI_FUNC_FROM_TAG(Tag);
|
||||
sprintf(file, "/sys/bus/pci/devices/%04x:%02x:%02x.%1x/rom",
|
||||
|
@ -940,3 +978,106 @@ int linuxPciHandleBIOS(PCITAG Tag, int basereg, unsigned char *buf, int len)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __ia64__
|
||||
static PCITAG ia64linuxPciFindFirst(void);
|
||||
static PCITAG ia64linuxPciFindNext(void);
|
||||
|
||||
void
|
||||
ia64linuxPciInit()
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
linuxPciInit();
|
||||
|
||||
if (!stat("/proc/sgi_sn/licenseID", &st) && pciNumBuses) {
|
||||
/* Be a little paranoid here and only use this code for Altix systems.
|
||||
* It is generic, so it should work on any system, but depends on
|
||||
* /proc/bus/pci entries for each domain/bus combination. Altix is
|
||||
* guaranteed a recent enough kernel to have them.
|
||||
*/
|
||||
pciFindFirstFP = ia64linuxPciFindFirst;
|
||||
pciFindNextFP = ia64linuxPciFindNext;
|
||||
}
|
||||
}
|
||||
|
||||
static DIR *busdomdir;
|
||||
static DIR *devdir;
|
||||
|
||||
static PCITAG
|
||||
ia64linuxPciFindFirst(void)
|
||||
{
|
||||
busdomdir = opendir("/proc/bus/pci");
|
||||
devdir = NULL;
|
||||
|
||||
return ia64linuxPciFindNext();
|
||||
}
|
||||
|
||||
static struct dirent *getnextbus(int *domain, int *bus)
|
||||
{
|
||||
struct dirent *entry;
|
||||
int dombus;
|
||||
|
||||
for (;;) {
|
||||
entry = readdir(busdomdir);
|
||||
if (entry == NULL) {
|
||||
*domain = 0;
|
||||
*bus = 0;
|
||||
closedir(busdomdir);
|
||||
return NULL;
|
||||
}
|
||||
if (sscanf(entry->d_name, "%04x:%02x", domain, bus) != 2)
|
||||
continue;
|
||||
dombus = PCI_MAKE_BUS(*domain, *bus);
|
||||
|
||||
if (pciNumBuses <= dombus)
|
||||
pciNumBuses = dombus + 1;
|
||||
if (!pciBusInfo[dombus]) {
|
||||
pciBusInfo[dombus] = xnfalloc(sizeof(pciBusInfo_t));
|
||||
*pciBusInfo[dombus] = *pciBusInfo[0];
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
static PCITAG
|
||||
ia64linuxPciFindNext(void)
|
||||
{
|
||||
struct dirent *entry;
|
||||
char file[40];
|
||||
static int bus, dev, func, domain;
|
||||
PCITAG pciDeviceTag;
|
||||
CARD32 devid;
|
||||
|
||||
for (;;) {
|
||||
if (devdir == NULL) {
|
||||
entry = getnextbus(&domain, &bus);
|
||||
if (!entry)
|
||||
return PCI_NOT_FOUND;
|
||||
snprintf(file, 40, "/proc/bus/pci/%s", entry->d_name);
|
||||
devdir = opendir(file);
|
||||
if (!devdir)
|
||||
return PCI_NOT_FOUND;
|
||||
|
||||
}
|
||||
|
||||
entry = readdir(devdir);
|
||||
|
||||
if (entry == NULL) {
|
||||
closedir(devdir);
|
||||
devdir = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sscanf(entry->d_name, "%02x . %01x", &dev, &func) == 2) {
|
||||
pciDeviceTag = PCI_MAKE_TAG(PCI_MAKE_BUS(domain, bus), dev, func);
|
||||
devid = pciReadLong(pciDeviceTag, PCI_ID_REG);
|
||||
if ((devid & pciDevidMask) == pciDevid)
|
||||
/* Yes - Return it. Otherwise, next device */
|
||||
return pciDeviceTag;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -766,6 +766,7 @@ void pciSetBitsByte(PCITAG tag, int offset, CARD8 mask, CARD8 val);
|
|||
ADDRESS pciBusAddrToHostAddr(PCITAG tag, PciAddrType type, ADDRESS addr);
|
||||
ADDRESS pciHostAddrToBusAddr(PCITAG tag, PciAddrType type, ADDRESS addr);
|
||||
PCITAG pciTag(int busnum, int devnum, int funcnum);
|
||||
PCITAG pciDomTag(int domnum, int busnum, int devnum, int funcnum);
|
||||
int pciGetBaseSize(PCITAG tag, int indx, Bool destructive, Bool *min);
|
||||
CARD32 pciCheckForBrokenBase(PCITAG tag,int basereg);
|
||||
pointer xf86MapPciMem(int ScreenNum, int Flags, PCITAG Tag,
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
#include <xorg-config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <X11/X.h>
|
||||
#include "os.h"
|
||||
#include "xf86.h"
|
||||
|
@ -25,8 +27,10 @@
|
|||
int lnxPciInit(void);
|
||||
|
||||
struct pci_dev {
|
||||
unsigned int domain;
|
||||
unsigned int bus;
|
||||
unsigned int devfn;
|
||||
unsigned int dev;
|
||||
unsigned int fn;
|
||||
PCIADDR_TYPE offset[7];
|
||||
PCIADDR_TYPE size[7];
|
||||
struct pci_dev *next;
|
||||
|
@ -38,10 +42,53 @@ int xf86OSLinuxNumPciDevs = 0;
|
|||
static struct pci_dev *xf86OSLinuxGetPciDevs(void) {
|
||||
char c[0x200];
|
||||
FILE *file = NULL;
|
||||
DIR *dir;
|
||||
struct dirent *dirent;
|
||||
struct pci_dev *tmp, *ret = NULL;
|
||||
unsigned int num;
|
||||
unsigned int i, num, devfn;
|
||||
unsigned PCIADDR_TYPE begin, end;
|
||||
char *res;
|
||||
|
||||
/* Try 2.6 devices first, with domain support */
|
||||
if ( (dir = opendir ("/sys/bus/pci/devices")) ) {
|
||||
xf86OSLinuxNumPciDevs = 0;
|
||||
while ( (dirent = readdir (dir)) ) {
|
||||
unsigned int domain, bus, dev, fn;
|
||||
if (sscanf (dirent->d_name, "%04x:%02x:%02x.%01x",
|
||||
&domain, &bus, &dev, &fn) == 4) {
|
||||
tmp = xcalloc (sizeof(struct pci_dev), 1);
|
||||
tmp->domain = domain;
|
||||
tmp->bus = bus;
|
||||
tmp->dev = dev;
|
||||
tmp->fn = fn;
|
||||
sprintf (c, "/sys/bus/pci/devices/%12s/resource",
|
||||
dirent->d_name);
|
||||
i = 0;
|
||||
if ( (file = fopen (c, "r")) ) {
|
||||
while (i < 7 && fgets (c, 0x200, file)) {
|
||||
if (sscanf (c, PCIADDR_FMT " " PCIADDR_FMT " "
|
||||
PCIADDR_IGNORE_FMT, &begin, &end) == 2) {
|
||||
tmp->offset[i] = begin;
|
||||
tmp->size[i] = begin ? end-begin+1 : 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
fclose (file);
|
||||
}
|
||||
if (i > 0) {
|
||||
tmp->next = ret;
|
||||
ret = tmp;
|
||||
xf86OSLinuxNumPciDevs++;
|
||||
} else
|
||||
xfree (tmp);
|
||||
}
|
||||
}
|
||||
closedir (dir);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
file = fopen("/proc/bus/pci/devices", "r");
|
||||
if (!file) return NULL;
|
||||
|
||||
|
@ -70,9 +117,11 @@ static struct pci_dev *xf86OSLinuxGetPciDevs(void) {
|
|||
"\t" PCIADDR_FMT
|
||||
"\t" PCIADDR_FMT
|
||||
"\t" PCIADDR_FMT,
|
||||
&tmp->bus,&tmp->devfn,&tmp->offset[0],&tmp->offset[1],&tmp->offset[2],&tmp->offset[3],
|
||||
&tmp->bus,&devfn,&tmp->offset[0],&tmp->offset[1],&tmp->offset[2],&tmp->offset[3],
|
||||
&tmp->offset[4],&tmp->offset[5],&tmp->offset[6], &tmp->size[0], &tmp->size[1], &tmp->size[2],
|
||||
&tmp->size[3], &tmp->size[4], &tmp->size[5], &tmp->size[6]);
|
||||
tmp->dev = devfn >> 3;
|
||||
tmp->fn = devfn & 0x7;
|
||||
if (num != 16) { /* apparantly not 2.3 style */
|
||||
xfree(tmp);
|
||||
fclose(file);
|
||||
|
@ -100,11 +149,10 @@ int lnxPciInit(void) {
|
|||
Bool
|
||||
xf86GetPciSizeFromOS(PCITAG tag, int index, int* bits)
|
||||
{
|
||||
unsigned int dev, fn;
|
||||
signed PCIADDR_TYPE Size;
|
||||
struct pci_dev *device;
|
||||
|
||||
if (index > 7)
|
||||
if (index >= 7)
|
||||
return FALSE;
|
||||
|
||||
if (!xf86OSLinuxPCIDevs) {
|
||||
|
@ -114,10 +162,8 @@ xf86GetPciSizeFromOS(PCITAG tag, int index, int* bits)
|
|||
return FALSE;
|
||||
|
||||
for (device = xf86OSLinuxPCIDevs; device; device = device->next) {
|
||||
dev = device->devfn >> 3;
|
||||
fn = device->devfn & 0x7;
|
||||
if (tag == pciTag(device->bus,dev,fn)) {
|
||||
*bits = 0;
|
||||
if (tag == pciDomTag (device->domain, device->bus,
|
||||
device->dev, device->fn)) {
|
||||
if (device->size[index] != 0) {
|
||||
Size = device->size[index] - ((PCIADDR_TYPE) 1);
|
||||
while (Size & ((PCIADDR_TYPE) 0x01)) {
|
||||
|
@ -134,14 +180,14 @@ xf86GetPciSizeFromOS(PCITAG tag, int index, int* bits)
|
|||
|
||||
|
||||
|
||||
#if 0
|
||||
/* Query the kvirt address (64bit) of a BAR range from TAG */
|
||||
Bool
|
||||
xf86GetPciOffsetFromOS(PCITAG tag, int index, unsigned long* bases)
|
||||
{
|
||||
unsigned int dev, fn;
|
||||
struct pci_dev *device;
|
||||
|
||||
if (index > 7)
|
||||
if (index >= 7)
|
||||
return FALSE;
|
||||
|
||||
if (!xf86OSLinuxPCIDevs) {
|
||||
|
@ -151,9 +197,8 @@ xf86GetPciOffsetFromOS(PCITAG tag, int index, unsigned long* bases)
|
|||
return FALSE;
|
||||
|
||||
for (device = xf86OSLinuxPCIDevs; device; device = device->next) {
|
||||
dev = device->devfn >> 3;
|
||||
fn = device->devfn & 0x7;
|
||||
if (tag == pciTag(device->bus,dev,fn)) {
|
||||
if (tag == pciDomTag (device->domain, device->bus,
|
||||
device->dev, device->fn)) {
|
||||
/* return the offset for the index requested */
|
||||
*bases = device->offset[index];
|
||||
return TRUE;
|
||||
|
@ -162,12 +207,12 @@ xf86GetPciOffsetFromOS(PCITAG tag, int index, unsigned long* bases)
|
|||
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Query the kvirt address (64bit) of a BAR range from size for a given TAG */
|
||||
unsigned long
|
||||
xf86GetOSOffsetFromPCI(PCITAG tag, int space, unsigned long base)
|
||||
{
|
||||
unsigned int dev, fn;
|
||||
unsigned int ndx;
|
||||
struct pci_dev *device;
|
||||
|
||||
|
@ -179,9 +224,8 @@ xf86GetOSOffsetFromPCI(PCITAG tag, int space, unsigned long base)
|
|||
}
|
||||
|
||||
for (device = xf86OSLinuxPCIDevs; device; device = device->next) {
|
||||
dev = device->devfn >> 3;
|
||||
fn = device->devfn & 0x7;
|
||||
if (tag == pciTag(device->bus, dev, fn)) {
|
||||
if (tag == pciDomTag (device->domain, device->bus,
|
||||
device->dev, device->fn)) {
|
||||
/* ok now look through all the BAR values of this device */
|
||||
pciConfigPtr pDev = xf86GetPciConfigFromTag(tag);
|
||||
|
||||
|
|
Loading…
Reference in New Issue