|
Lines 55-60
Link Here
|
| 55 |
#include "xf86Priv.h" |
55 |
#include "xf86Priv.h" |
| 56 |
#include "xf86_OSlib.h" |
56 |
#include "xf86_OSlib.h" |
| 57 |
#include "Pci.h" |
57 |
#include "Pci.h" |
|
|
58 |
#include <dirent.h> |
| 58 |
|
59 |
|
| 59 |
/* |
60 |
/* |
| 60 |
* linux platform specific PCI access functions -- using /proc/bus/pci |
61 |
* linux platform specific PCI access functions -- using /proc/bus/pci |
|
Lines 130-167
linuxPciInit()
Link Here
|
| 130 |
static int |
131 |
static int |
| 131 |
linuxPciOpenFile(PCITAG tag, Bool write) |
132 |
linuxPciOpenFile(PCITAG tag, Bool write) |
| 132 |
{ |
133 |
{ |
| 133 |
static int lbus,ldev,lfunc,fd = -1,is_write = 0; |
134 |
static int ldomain, lbus,ldev,lfunc,fd = -1,is_write = 0; |
| 134 |
int bus, dev, func; |
135 |
int domain, bus, dev, func; |
| 135 |
char file[32]; |
136 |
char file[32]; |
| 136 |
struct stat ignored; |
137 |
struct stat ignored; |
| 137 |
|
138 |
|
| 138 |
bus = PCI_BUS_FROM_TAG(tag); |
139 |
domain = PCI_DOM_FROM_TAG(tag); |
|
|
140 |
bus = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(tag)); |
| 139 |
dev = PCI_DEV_FROM_TAG(tag); |
141 |
dev = PCI_DEV_FROM_TAG(tag); |
| 140 |
func = PCI_FUNC_FROM_TAG(tag); |
142 |
func = PCI_FUNC_FROM_TAG(tag); |
| 141 |
if (fd == -1 || (write && (!is_write)) |
143 |
|
| 142 |
|| bus != lbus || dev != ldev || func != lfunc) { |
144 |
if (fd == -1 || (write && (!is_write)) || bus != lbus |
|
|
145 |
|| dev != ldev || func != lfunc || domain != ldomain) { |
| 146 |
|
| 143 |
if (fd != -1) |
147 |
if (fd != -1) |
| 144 |
close(fd); |
148 |
close(fd); |
| 145 |
if (bus < 256) { |
149 |
if (bus < 256) { |
| 146 |
sprintf(file,"/proc/bus/pci/%02x",bus); |
150 |
sprintf(file, "/proc/bus/pci/%04x:%02x", domain, bus); |
| 147 |
if (stat(file, &ignored) < 0) |
151 |
if (stat(file, &ignored) < 0) { |
| 148 |
sprintf(file, "/proc/bus/pci/0000:%02x/%02x.%1x", |
152 |
if (domain == 0) |
| 149 |
bus, dev, func); |
153 |
sprintf(file, "/proc/bus/pci/%02x/%02x.%1x", |
| 150 |
else |
154 |
bus, dev, func); |
| 151 |
sprintf(file, "/proc/bus/pci/%02x/%02x.%1x", |
155 |
else goto bail; |
| 152 |
bus, dev, func); |
156 |
} else |
|
|
157 |
sprintf(file, "/proc/bus/pci/%04x:%02x/%02x.%1x", |
| 158 |
domain, bus, dev, func); |
| 153 |
} else { |
159 |
} else { |
| 154 |
sprintf(file,"/proc/bus/pci/%04x",bus); |
160 |
sprintf(file, "/proc/bus/pci/%04x:%04x", domain, bus); |
| 155 |
if (stat(file, &ignored) < 0) |
161 |
if (stat(file, &ignored) < 0) { |
| 156 |
sprintf(file, "/proc/bus/pci/0000:%04x/%02x.%1x", |
162 |
if (domain == 0) |
| 157 |
bus, dev, func); |
163 |
sprintf(file, "/proc/bus/pci/%04x/%04x.%1x", |
| 158 |
else |
164 |
bus, dev, func); |
| 159 |
sprintf(file, "/proc/bus/pci/%04x/%02x.%1x", |
165 |
else goto bail; |
| 160 |
bus, dev, func); |
166 |
} else |
|
|
167 |
sprintf(file, "/proc/bus/pci/%04x:%04x/%02x.%1x", |
| 168 |
domain, bus, dev, func); |
| 161 |
} |
169 |
} |
| 162 |
if (write) { |
170 |
if (write) { |
| 163 |
fd = open(file,O_RDWR); |
171 |
fd = open(file,O_RDWR); |
| 164 |
if (fd != -1) is_write = TRUE; |
172 |
if (fd != -1) is_write = TRUE; |
| 165 |
} else switch (is_write) { |
173 |
} else switch (is_write) { |
| 166 |
case TRUE: |
174 |
case TRUE: |
| 167 |
fd = open(file,O_RDWR); |
175 |
fd = open(file,O_RDWR); |
|
Lines 171-177
linuxPciOpenFile(PCITAG tag, Bool write)
Link Here
|
| 171 |
fd = open(file,O_RDONLY); |
179 |
fd = open(file,O_RDONLY); |
| 172 |
is_write = FALSE; |
180 |
is_write = FALSE; |
| 173 |
} |
181 |
} |
| 174 |
|
182 |
bail: |
|
|
183 |
ldomain = domain; |
| 175 |
lbus = bus; |
184 |
lbus = bus; |
| 176 |
ldev = dev; |
185 |
ldev = dev; |
| 177 |
lfunc = func; |
186 |
lfunc = func; |
|
Lines 491-497
xf86GetPciDomain(PCITAG Tag)
Link Here
|
| 491 |
pPCI = xf86GetPciHostConfigFromTag(Tag); |
500 |
pPCI = xf86GetPciHostConfigFromTag(Tag); |
| 492 |
|
501 |
|
| 493 |
if (pPCI && (result = PCI_DOM_FROM_BUS(pPCI->busnum))) |
502 |
if (pPCI && (result = PCI_DOM_FROM_BUS(pPCI->busnum))) |
| 494 |
return result; |
503 |
return result + 1; |
| 495 |
|
504 |
|
| 496 |
if (!pPCI || pPCI->fakeDevice) |
505 |
if (!pPCI || pPCI->fakeDevice) |
| 497 |
return 1; /* Domain 0 is reserved */ |
506 |
return 1; /* Domain 0 is reserved */ |
|
Lines 724-730
xf86ReadDomainMemory(PCITAG Tag, ADDRESS
Link Here
|
| 724 |
struct stat st; |
733 |
struct stat st; |
| 725 |
|
734 |
|
| 726 |
dom = PCI_DOM_FROM_TAG(Tag); |
735 |
dom = PCI_DOM_FROM_TAG(Tag); |
| 727 |
bus = PCI_BUS_FROM_TAG(Tag); |
736 |
bus = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(Tag)); |
| 728 |
dev = PCI_DEV_FROM_TAG(Tag); |
737 |
dev = PCI_DEV_FROM_TAG(Tag); |
| 729 |
func = PCI_FUNC_FROM_TAG(Tag); |
738 |
func = PCI_FUNC_FROM_TAG(Tag); |
| 730 |
sprintf(file, "/sys/devices/pci%04x:%02x/%04x:%02x:%02x.%1x/rom", |
739 |
sprintf(file, "/sys/devices/pci%04x:%02x/%04x:%02x:%02x.%1x/rom", |
|
Lines 892-894
xf86AccResFromOS(resPtr pRes)
Link Here
|
| 892 |
} |
901 |
} |
| 893 |
|
902 |
|
| 894 |
#endif /* !INCLUDE_XF86_NO_DOMAIN */ |
903 |
#endif /* !INCLUDE_XF86_NO_DOMAIN */ |
|
|
904 |
|
| 905 |
#ifdef __ia64__ |
| 906 |
static PCITAG ia64linuxPciFindFirst(void); |
| 907 |
static PCITAG ia64linuxPciFindNext(void); |
| 908 |
|
| 909 |
|
| 910 |
void |
| 911 |
ia64linuxPciInit() |
| 912 |
{ |
| 913 |
struct stat st; |
| 914 |
/* Be a little paranoid here and only use this code for Altix systems. |
| 915 |
* It is generic, so it should work on any system, but depends on |
| 916 |
* /proc/bus/pci entries for each domain/bus combination. Altix is |
| 917 |
* guaranteed a recent enough kernel to have them. |
| 918 |
*/ |
| 919 |
if (stat("/proc/sgi_sn/licenseID", &st)) { |
| 920 |
return linuxPciInit(); |
| 921 |
} |
| 922 |
if ((xf86Info.pciFlags == PCIForceNone) || |
| 923 |
(-1 == stat("/proc/bus/pci", &st))) { |
| 924 |
/* when using this as default for all linux architectures, |
| 925 |
we'll need a fallback for 2.0 kernels here */ |
| 926 |
return; |
| 927 |
} |
| 928 |
pciNumBuses = 1; |
| 929 |
pciBusInfo[0] = &linuxPci0; |
| 930 |
pciFindFirstFP = ia64linuxPciFindFirst; |
| 931 |
pciFindNextFP = ia64linuxPciFindNext; |
| 932 |
} |
| 933 |
|
| 934 |
static DIR *busdomdir; |
| 935 |
static DIR *devdir; |
| 936 |
|
| 937 |
static PCITAG |
| 938 |
ia64linuxPciFindFirst(void) |
| 939 |
{ |
| 940 |
busdomdir = opendir("/proc/bus/pci"); |
| 941 |
devdir = NULL; |
| 942 |
|
| 943 |
return ia64linuxPciFindNext(); |
| 944 |
} |
| 945 |
|
| 946 |
static struct dirent *getnextbus(int *domain, int *bus) |
| 947 |
{ |
| 948 |
struct dirent *entry; |
| 949 |
int dombus; |
| 950 |
|
| 951 |
for (;;) { |
| 952 |
entry = readdir(busdomdir); |
| 953 |
if (entry == NULL) { |
| 954 |
*domain = 0; |
| 955 |
*bus = 0; |
| 956 |
closedir(busdomdir); |
| 957 |
return NULL; |
| 958 |
} |
| 959 |
if (sscanf(entry->d_name, "%04x:%02x", domain, bus) != 2) |
| 960 |
continue; |
| 961 |
dombus = PCI_MAKE_BUS(*domain, *bus); |
| 962 |
|
| 963 |
if (pciNumBuses <= dombus) |
| 964 |
pciNumBuses = dombus + 1; |
| 965 |
if (!pciBusInfo[dombus]) { |
| 966 |
pciBusInfo[dombus] = xnfalloc(sizeof(pciBusInfo_t)); |
| 967 |
*pciBusInfo[dombus] = *pciBusInfo[0]; |
| 968 |
} |
| 969 |
|
| 970 |
return entry; |
| 971 |
} |
| 972 |
} |
| 973 |
|
| 974 |
static PCITAG |
| 975 |
ia64linuxPciFindNext(void) |
| 976 |
{ |
| 977 |
struct dirent *entry; |
| 978 |
char file[40]; |
| 979 |
static int bus, dev, func, domain; |
| 980 |
PCITAG pciDeviceTag; |
| 981 |
CARD32 devid; |
| 982 |
|
| 983 |
for (;;) { |
| 984 |
if (devdir == NULL) { |
| 985 |
entry = getnextbus(&domain, &bus); |
| 986 |
if (!entry) |
| 987 |
return PCI_NOT_FOUND; |
| 988 |
snprintf(file, 40, "/proc/bus/pci/%s", entry->d_name); |
| 989 |
devdir = opendir(file); |
| 990 |
if (!devdir) |
| 991 |
return PCI_NOT_FOUND; |
| 992 |
|
| 993 |
} |
| 994 |
|
| 995 |
entry = readdir(devdir); |
| 996 |
|
| 997 |
if (entry == NULL) { |
| 998 |
closedir(devdir); |
| 999 |
devdir = NULL; |
| 1000 |
continue; |
| 1001 |
} |
| 1002 |
|
| 1003 |
if (sscanf(entry->d_name, "%02x . %01x", &dev, &func) == 2) { |
| 1004 |
pciDeviceTag = PCI_MAKE_TAG(PCI_MAKE_BUS(domain, bus), dev, func); |
| 1005 |
devid = pciReadLong(pciDeviceTag, PCI_ID_REG); |
| 1006 |
if ((devid & pciDevidMask) == pciDevid) |
| 1007 |
/* Yes - Return it. Otherwise, next device */ |
| 1008 |
return pciDeviceTag; |
| 1009 |
} |
| 1010 |
} |
| 1011 |
} |
| 1012 |
#endif |