/* * xf86ReadDomainMemory - copy from domain memory into a caller supplied buffer */ int xf86ReadDomainMemory(PCITAG Tag, ADDRESS Base, int Len, unsigned char *Buf) { unsigned char *ptr, *src; ADDRESS offset; unsigned long size; int len, pagemask = getpagesize() - 1; unsigned int i, dom, bus, dev, func; unsigned int fd; char file[256]; struct stat st; dom = PCI_DOM_FROM_TAG(Tag); bus = 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", dom, bus, dom, bus, dev, func); /* * If the caller wants the ROM and the sysfs rom interface exists, * try to use it instead of reading it from /proc/bus/pci. */ if (((Base & 0xfffff) == 0xC0000) && (stat(file, &st) == 0)) { if ((fd = open(file, O_RDWR))) Base = 0x0; /* enable the ROM first */ write(fd, "1", 2); lseek(fd, 0, SEEK_SET); /* copy the ROM until we hit Len, EOF or read error */ for (i = 0; i < Len && read(fd, Buf, 1) > 0; Buf++, i++) ; write(fd, "0", 2); close(fd); return Len; } /* Ensure page boundaries */ offset = Base & ~pagemask; size = ((Base + Len + pagemask) & ~pagemask) - offset; ptr = xf86MapDomainMemory(-1, VIDMEM_READONLY, Tag, offset, size); if (!ptr) return -1; /* Using memcpy() here can hang the system */ src = ptr + (Base - offset); for (len = Len; len-- > 0;) *Buf++ = *src++; xf86UnMapVidMem(-1, ptr, size); return Len; }
static int linuxPciOpenFile(PCITAG tag, Bool write) { static int lbus,ldev,lfunc,fd = -1,is_write = 0; int bus, dev, func; char file[32]; struct stat ignored; bus = PCI_BUS_FROM_TAG(tag); dev = PCI_DEV_FROM_TAG(tag); func = PCI_FUNC_FROM_TAG(tag); if (fd == -1 || (write && (!is_write)) || bus != lbus || dev != ldev || func != lfunc) { if (fd != -1) close(fd); 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); } 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); } if (write) { fd = open(file,O_RDWR); if (fd != -1) is_write = TRUE; } else switch (is_write) { case TRUE: fd = open(file,O_RDWR); if (fd > -1) break; default: fd = open(file,O_RDONLY); is_write = FALSE; } lbus = bus; ldev = dev; lfunc = func; } return fd; }
_X_EXPORT 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); }