📄 kudzu-support.c
字号:
/* * Compaq Hot Plug Controller Graphical User Interface * Copyright 2000, 2001 Compaq Computer Corporation * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or * NON INFRINGEMENT. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Please send all questions or concerns to linuxhotplug@compaq.com */#include "ctype.h"#include "fcntl.h"#include "setjmp.h"#include "stdio.h"#include "stdlib.h"#include "string.h"#include "sys/stat.h"#include "unistd.h"#include "kudzu-support.h"struct pciDevice * pciDeviceList = NULL;static int numPciDevices = 0;static int devCmp(const void * a, const void * b) { const struct pciDevice * one = a; const struct pciDevice * two = b; int x=0,y=0,z=0; x = (one->vendorId - two->vendorId); y = (one->deviceId - two->deviceId); if (one->pciType && two->pciType) z = (one->pciType - two->pciType); if (x) return x; else if (y) return y; else return z;}int pciReadDrivers(char *filename) { int fd; struct stat sb; char * buf; int numDrivers; int vendid, devid; int merge = 0; char * start; struct pciDevice * nextDevice, *tmpdev = NULL, key; char module[5000]; char descrip[5000]; if (filename) { fd = open(filename, O_RDONLY); if (fd < 0) return -1; } else { fd = open("/usr/share/kudzu/pcitable", O_RDONLY); if (fd < 0) { fd = open("/etc/pcitable", O_RDONLY); if (fd < 0) { fd = open("/modules/pcitable", O_RDONLY); if (fd < 0) { fd = open("./pcitable", O_RDONLY); if (fd < 0) return -1; } } } } fstat(fd, &sb); buf = alloca(sb.st_size + 1); read(fd, buf, sb.st_size); buf[sb.st_size] = '\0'; close(fd); /* upper bound */ numDrivers = 1; start = buf; while ((start = strchr(start, '\n'))) { numDrivers++; start++; } if (pciDeviceList) merge = 1; pciDeviceList = realloc(pciDeviceList, sizeof(*pciDeviceList) * (numPciDevices + numDrivers)); nextDevice = pciDeviceList + numPciDevices; start = buf; while (start && *start) { while (isspace(*start)) start++; if (*start != '#' && *start != '\n') { if (sscanf(start, "%x %x \"%[^\"]\" \"%[^\"]", &vendid, &devid, module, descrip ) == 4) { if (merge) { tmpdev = nextDevice; key.vendorId = vendid; key.deviceId = devid; if (strncmp (module, "CardBus:", 8) == 0) key.pciType = PCI_CARDBUS; else key.pciType = PCI_NORMAL; nextDevice = bsearch(&key,pciDeviceList,numPciDevices, sizeof(struct pciDevice), devCmp); if (!nextDevice) { nextDevice = tmpdev; tmpdev = NULL; numPciDevices++; } else { if (nextDevice->device) free(nextDevice->device); if (nextDevice->desc) free(nextDevice->desc); if (nextDevice->driver) free(nextDevice->driver); } } else numPciDevices++; nextDevice->vendorId = vendid; nextDevice->deviceId = devid; if (strncmp (module, "CardBus:", 8) == 0) { nextDevice->pciType = PCI_CARDBUS; nextDevice->driver = strdup(&module [8]); } else { nextDevice->pciType = PCI_NORMAL; nextDevice->driver = strdup(module); } nextDevice->desc = strdup(descrip); nextDevice->next = NULL; nextDevice->device = NULL; nextDevice->class = 0; nextDevice->bus = BUS_PCI; if (merge && tmpdev) nextDevice = tmpdev; else { nextDevice++; if (merge) qsort(pciDeviceList, numPciDevices, sizeof(*pciDeviceList), devCmp); } } } start = strchr(start, '\n'); if (start) start++; } qsort(pciDeviceList, numPciDevices, sizeof(*pciDeviceList), devCmp); return 0;}void pciFreeDrivers() { int x; if (pciDeviceList) { for (x=0;x<numPciDevices;x++) { if (pciDeviceList[x].device) free (pciDeviceList[x].device); if (pciDeviceList[x].driver) free (pciDeviceList[x].driver); if (pciDeviceList[x].desc) free (pciDeviceList[x].desc); } free(pciDeviceList); pciDeviceList=NULL; numPciDevices=0; }}int lookupDevice(unsigned int vendorId, unsigned int deviceId, char* device, char* driver) { int i; for (i=0; i<numPciDevices; i++) { if (pciDeviceList[i].vendorId != vendorId) continue; if (pciDeviceList[i].deviceId != deviceId) continue; //if (pciDeviceList[i].device) strcpy(device, pciDeviceList[i].device); if(pciDeviceList[i].driver) strcpy(driver, pciDeviceList[i].driver); if(pciDeviceList[i].desc) strcpy(device, pciDeviceList[i].desc); return 1; } return 0;}int lookupDevID(unsigned short bus, unsigned short devfn, unsigned short* vendID, unsigned short* devID) { int fd = 0; char buf[100]; sprintf(buf, "/proc/bus/pci/%2.2x/%2.2x.%x", bus, devfn >> 3, (devfn & 0x7)); fd = open(buf, O_RDONLY); if (fd == -1) return 0; read(fd, vendID, 2); read(fd, devID, 2); close(fd); return 1;}int lookupSubDevID(unsigned short bus, unsigned short devfn, unsigned short* vendID, unsigned short* devID) { int fd = 0; char buf[100]; sprintf(buf, "/proc/bus/pci/%2.2x/%2.2x.%x", bus, devfn >> 3, (devfn & 0x7)); fd = open(buf, O_RDONLY); if (fd == -1) return 0; lseek(fd, 0x2c, SEEK_SET); read(fd, vendID, 2); read(fd, devID, 2); close(fd); return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -