1#include <stdbool.h> 2#include <stdlib.h> 3#include <string.h> 4#include <ctype.h> 5 6#define lpcilib_c /* Define the library */ 7 8#include "lua.h" 9#include "lauxlib.h" 10#include "lualib.h" 11#include <sys/pci.h> 12 13/* removing any \n found in a string */ 14static void remove_eol(char *string) 15{ 16 int j = strlen(string); 17 int i = 0; 18 for (i = 0; i < j; i++) 19 if (string[i] == '\n') 20 string[i] = 0; 21} 22 23static int pci_getinfo(lua_State *L) 24{ 25 struct pci_domain *pci_domain; 26 struct pci_device *pci_device; 27 int pci_dev = 1; 28 29 pci_domain = pci_scan(); 30 31 lua_newtable(L); /* list of busses */ 32 33 for_each_pci_func(pci_device, pci_domain) { 34 lua_pushnumber(L, pci_dev++); 35 36 lua_newtable(L); /* device infos */ 37 38 lua_pushstring(L, "bus"); 39 lua_pushnumber(L, __pci_bus); 40 lua_settable(L,-3); 41 42 lua_pushstring(L, "slot"); 43 lua_pushnumber(L, __pci_slot); 44 lua_settable(L,-3); 45 46 lua_pushstring(L, "func"); 47 lua_pushnumber(L, __pci_func); 48 lua_settable(L,-3); 49 50 lua_pushstring(L, "vendor"); 51 lua_pushnumber(L, pci_device->vendor); 52 lua_settable(L,-3); 53 54 lua_pushstring(L, "product"); 55 lua_pushnumber(L, pci_device->product); 56 lua_settable(L,-3); 57 58 lua_pushstring(L, "sub_vendor"); 59 lua_pushnumber(L, pci_device->sub_vendor); 60 lua_settable(L,-3); 61 62 lua_pushstring(L, "sub_product"); 63 lua_pushnumber(L, pci_device->sub_product); 64 lua_settable(L,-3); 65 66 lua_settable(L,-3); /* end device infos */ 67 } 68 69 return 1; 70} 71 72/* Try to match any pci device to the appropriate kernel module */ 73/* it uses the modules.pcimap from the boot device*/ 74static int pci_getidlist(lua_State *L) 75{ 76 const char *pciidfile; 77 char line[1024]; 78 char vendor[255]; 79 char vendor_id[5]; 80 char product[255]; 81 char productvendor[9]; 82 char productvendorsub[17]; 83 FILE *f; 84 85 if (lua_gettop(L) == 1) { 86 pciidfile = luaL_checkstring(L, 1); 87 } else { 88 pciidfile = "pci.ids"; 89 } 90 91 lua_newtable(L); /* list of vendors */ 92 93 /* Opening the pci.ids from the boot device*/ 94 f=fopen(pciidfile,"r"); 95 if (!f) 96 return -1; 97 98 /* for each line we found in the pci.ids*/ 99 while ( fgets(line, sizeof line, f) ) { 100 /* Skipping uncessary lines */ 101 if ((line[0] == '#') || (line[0] == ' ') || (line[0] == 'C') || 102 (line[0] == 10)) 103 continue; 104 105 /* If the line doesn't start with a tab, it means that's a vendor id */ 106 if (line[0] != '\t') { 107 108 /* the 4th first chars are the vendor_id */ 109 strlcpy(vendor_id,line,4); 110 111 /* the vendor name is the next field*/ 112 vendor_id[4]=0; 113 strlcpy(vendor,skipspace(strstr(line," ")),255); 114 remove_eol(vendor); 115 116 /* ffff is an invalid vendor id */ 117 if (strstr(vendor_id,"ffff")) break; 118 119 lua_pushstring(L, vendor_id); 120 lua_pushstring(L, vendor); 121 lua_settable(L,-3); 122 123 /* if we have a tab + a char, it means this is a product id */ 124 } else if ((line[0] == '\t') && (line[1] != '\t')) { 125 126 /* the product name the second field */ 127 strlcpy(product,skipspace(strstr(line," ")),255); 128 remove_eol(product); 129 130 /* the 4th first chars are the vendor_id */ 131 strlcpy(productvendor,vendor_id,4); 132 /* the product id is first field */ 133 strlcpy(productvendor+4,&line[1],4); 134 productvendor[8]=0; 135 136 lua_pushstring(L, productvendor); 137 lua_pushstring(L, product); 138 lua_settable(L,-3); 139 140 /* if we have two tabs, it means this is a sub product */ 141 } else if ((line[0] == '\t') && (line[1] == '\t')) { 142 143 /* the product name is last field */ 144 strlcpy(product,skipspace(strstr(line," ")),255); 145 strlcpy(product,skipspace(strstr(product," ")),255); 146 remove_eol(product); 147 148 strlcpy(productvendorsub, productvendor,8); 149 strlcpy(productvendorsub+8, &line[2],4); 150 strlcpy(productvendorsub+12, &line[7],4); 151 productvendorsub[16]=0; 152 153 lua_pushstring(L, productvendorsub); 154 lua_pushstring(L, product); 155 lua_settable(L,-3); 156 157 } 158 } 159 fclose(f); 160 return(1); 161} 162 163static const luaL_Reg pcilib[] = { 164 {"getinfo", pci_getinfo}, 165 {"getidlist", pci_getidlist}, 166 {NULL, NULL} 167}; 168 169/* This defines a function that opens up your library. */ 170 171LUALIB_API int luaopen_pci (lua_State *L) { 172 luaL_newlib(L, pcilib); 173 return 1; 174} 175 176