• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
remove_eol(char * string)14 static 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 
pci_getinfo(lua_State * L)23 static 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*/
pci_getidlist(lua_State * L)74 static 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 
163 static 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 
luaopen_pci(lua_State * L)171 LUALIB_API int luaopen_pci (lua_State *L) {
172   luaL_newlib(L, pcilib);
173   return 1;
174 }
175 
176