Home | History | Annotate | Download | only in src
      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 */
     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 
     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*/
     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 
    171 LUALIB_API int luaopen_pci (lua_State *L) {
    172   luaL_newlib(L, pcilib);
    173   return 1;
    174 }
    175 
    176