diff options
Diffstat (limited to 'contrib/syslinux/latest/com32/lib/pci/scan.c')
-rw-r--r-- | contrib/syslinux/latest/com32/lib/pci/scan.c | 751 |
1 files changed, 0 insertions, 751 deletions
diff --git a/contrib/syslinux/latest/com32/lib/pci/scan.c b/contrib/syslinux/latest/com32/lib/pci/scan.c deleted file mode 100644 index 2577b32..0000000 --- a/contrib/syslinux/latest/com32/lib/pci/scan.c +++ /dev/null @@ -1,751 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2006-2007 Erwan Velu - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall - * be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * ----------------------------------------------------------------------- */ - -/* - * pci.c - * - * A module to extract pci informations - */ - -#include <inttypes.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <console.h> -#include <sys/pci.h> -#include <com32.h> -#include <stdbool.h> -#include <syslinux/zio.h> - -#ifdef DEBUG -# define dprintf printf -#else -# define dprintf(...) ((void)0) -#endif - -#define MAX_LINE 512 - -/* searching the next char that is not a space */ -static char *skipspace(char *p) -{ - while (*p && *p <= ' ') - p++; - - return p; -} - -/* removing any \n found in a string */ -static void remove_eol(char *string) -{ - int j = strlen(string); - int i = 0; - for (i = 0; i < j; i++) - if (string[i] == '\n') - string[i] = 0; -} - -/* converting a hexa string into its numerical value */ -static int hex_to_int(char *hexa) -{ - return strtoul(hexa, NULL, 16); -} - -/* Replace char 'old' by char 'new' in source */ -void chr_replace(char *source, char old, char new) -{ - while (*source) { - source++; - if (source[0] == old) source[0]=new; - } -} - -/* Try to match any pci device to the appropriate kernel module */ -/* it uses the modules.pcimap from the boot device */ -int get_module_name_from_pcimap(struct pci_domain *domain, - char *modules_pcimap_path) -{ - char line[MAX_LINE]; - char module_name[21]; // the module name field is 21 char long - char delims[]=" "; // colums are separated by spaces - char vendor_id[16]; - char product_id[16]; - char sub_vendor_id[16]; - char sub_product_id[16]; - FILE *f; - struct pci_device *dev=NULL; - - /* Intializing the linux_kernel_module for each pci device to "unknown" */ - /* adding a dev_info member if needed */ - for_each_pci_func(dev, domain) { - /* initialize the dev_info structure if it doesn't exist yet. */ - if (! dev->dev_info) { - dev->dev_info = zalloc(sizeof *dev->dev_info); - if (!dev->dev_info) - return -1; - } - for (int i=0;i<MAX_KERNEL_MODULES_PER_PCI_DEVICE;i++) { - if (strlen(dev->dev_info->linux_kernel_module[i])==0) - strlcpy(dev->dev_info->linux_kernel_module[i], "unknown",7); - } - } - - /* Opening the modules.pcimap (of a linux kernel) from the boot device */ - f=zfopen(modules_pcimap_path, "r"); - if (!f) - return -ENOMODULESPCIMAP; - - strcpy(vendor_id,"0000"); - strcpy(product_id,"0000"); - strcpy(sub_product_id,"0000"); - strcpy(sub_vendor_id,"0000"); - - /* for each line we found in the modules.pcimap */ - while ( fgets(line, sizeof line, f) ) { - /* skipping unecessary lines */ - if ((line[0] == '#') || (line[0] == ' ') || (line[0] == 10)) - continue; - - char *result = NULL; - int field=0; - - /* looking for the next field */ - result = strtok(line, delims); - while( result != NULL ) { - /* if the column is larger than 1 char */ - /* multiple spaces generates some empty fields */ - if (strlen(result)>1) { - switch (field) { - /* About case 0, the kernel module name is featuring '_' or '-' - * in the module name whereas modules.alias is only using '_'. - * To avoid kernel modules duplication, let's rename all '-' in '_' - * to match what modules.alias provides */ - case 0:chr_replace(result,'-','_');strcpy(module_name,result); break; - case 1:strcpy(vendor_id,result); break; - case 2:strcpy(product_id,result); break; - case 3:strcpy(sub_vendor_id,result); break; - case 4:strcpy(sub_product_id,result); break; - } - field++; - } - /* Searching the next field */ - result = strtok( NULL, delims ); - } - int int_vendor_id=hex_to_int(vendor_id); - int int_sub_vendor_id=hex_to_int(sub_vendor_id); - int int_product_id=hex_to_int(product_id); - int int_sub_product_id=hex_to_int(sub_product_id); - /* if a pci_device matches an entry, fill the linux_kernel_module with - the appropriate kernel module */ - for_each_pci_func(dev, domain) { - if (int_vendor_id == dev->vendor && - int_product_id == dev->product && - (int_sub_product_id & dev->sub_product) - == dev->sub_product && - (int_sub_vendor_id & dev->sub_vendor) - == dev->sub_vendor) { - bool found=false; - - /* Scan all known kernel modules for this pci device */ - for (int i=0; i<dev->dev_info->linux_kernel_module_count; i++) { - - /* Try to detect if we already knew the same kernel module*/ - if (strstr(dev->dev_info->linux_kernel_module[i], module_name)) { - found=true; - break; - } - } - /* If we don't have this kernel module, let's add it */ - if (!found) { - strcpy(dev->dev_info->linux_kernel_module[dev->dev_info->linux_kernel_module_count], module_name); - dev->dev_info->linux_kernel_module_count++; - } - } - } - } - fclose(f); - return 0; -} - -/* Try to match any pci device to the appropriate class name */ -/* it uses the pci.ids from the boot device */ -int get_class_name_from_pci_ids(struct pci_domain *domain, char *pciids_path) -{ - char line[MAX_LINE]; - char class_name[PCI_CLASS_NAME_SIZE]; - char sub_class_name[PCI_CLASS_NAME_SIZE]; - char class_id_str[5]; - char sub_class_id_str[5]; - FILE *f; - struct pci_device *dev; - bool class_mode = false; - - /* Intializing the vendor/product name for each pci device to "unknown" */ - /* adding a dev_info member if needed */ - for_each_pci_func(dev, domain) { - /* initialize the dev_info structure if it doesn't exist yet. */ - if (!dev->dev_info) { - dev->dev_info = zalloc(sizeof *dev->dev_info); - if (!dev->dev_info) - return -1; - } - strlcpy(dev->dev_info->class_name, "unknown", 7); - } - - /* Opening the pci.ids from the boot device */ - f = zfopen(pciids_path, "r"); - if (!f) - return -ENOPCIIDS; - - /* for each line we found in the pci.ids */ - while (fgets(line, sizeof line, f)) { - /* Skipping uncessary lines */ - if ((line[0] == '#') || (line[0] == ' ') || (line[0] == 10)) - continue; - - /* Until we found a line starting with a 'C', we are not parsing classes */ - if (line[0] == 'C') - class_mode = true; - if (class_mode == false) - continue; - strlcpy(class_name, "unknown", 7); - /* If the line doesn't start with a tab, it means that's a class name */ - if (line[0] != '\t') { - - /* ignore the two first char and then copy 2 chars (class id) */ - strlcpy(class_id_str, &line[2], 2); - class_id_str[2] = 0; - - /* the class name is the next field */ - strlcpy(class_name, skipspace(strstr(line, " ")), - PCI_CLASS_NAME_SIZE - 1); - remove_eol(class_name); - - int int_class_id_str = hex_to_int(class_id_str); - /* assign the class_name to any matching pci device */ - for_each_pci_func(dev, domain) { - if (int_class_id_str == dev->class[2]) { - strlcpy(dev->dev_info->class_name, class_name, - PCI_CLASS_NAME_SIZE - 1); - /* This value is usually the main category */ - strlcpy(dev->dev_info->category_name, class_name + 4, - PCI_CLASS_NAME_SIZE - 1); - } - } - /* if we have a tab + a char, it means this is a sub class name */ - } else if ((line[0] == '\t') && (line[1] != '\t')) { - - /* the sub class name the second field */ - strlcpy(sub_class_name, skipspace(strstr(line, " ")), - PCI_CLASS_NAME_SIZE - 1); - remove_eol(sub_class_name); - - /* the sub class id is first field */ - strlcpy(sub_class_id_str, &line[1], 2); - sub_class_id_str[2] = 0; - - int int_class_id_str = hex_to_int(class_id_str); - int int_sub_class_id_str = hex_to_int(sub_class_id_str); - /* assign the product_name to any matching pci device */ - for_each_pci_func(dev, domain) { - if (int_class_id_str == dev->class[2] && - int_sub_class_id_str == dev->class[1]) - strlcpy(dev->dev_info->class_name, sub_class_name, - PCI_CLASS_NAME_SIZE - 1); - } - - } - } - fclose(f); - return 0; -} - -/* Try to match any pci device to the appropriate vendor and product name */ -/* it uses the pci.ids from the boot device */ -int get_name_from_pci_ids(struct pci_domain *domain, char *pciids_path) -{ - char line[MAX_LINE]; - char vendor[PCI_VENDOR_NAME_SIZE]; - char vendor_id[5]; - char product[PCI_PRODUCT_NAME_SIZE]; - char product_id[5]; - char sub_product_id[5]; - char sub_vendor_id[5]; - FILE *f; - struct pci_device *dev; - bool skip_to_next_vendor = false; - uint16_t int_vendor_id; - uint16_t int_product_id; - uint16_t int_sub_product_id; - uint16_t int_sub_vendor_id; - - /* Intializing the vendor/product name for each pci device to "unknown" */ - /* adding a dev_info member if needed */ - for_each_pci_func(dev, domain) { - /* initialize the dev_info structure if it doesn't exist yet. */ - if (!dev->dev_info) { - dev->dev_info = zalloc(sizeof *dev->dev_info); - if (!dev->dev_info) - return -1; - } - strlcpy(dev->dev_info->vendor_name, "unknown", 7); - strlcpy(dev->dev_info->product_name, "unknown", 7); - } - - /* Opening the pci.ids from the boot device */ - f = zfopen(pciids_path, "r"); - if (!f) - return -ENOPCIIDS; - - strlcpy(vendor_id, "0000", 4); - strlcpy(product_id, "0000", 4); - strlcpy(sub_product_id, "0000", 4); - strlcpy(sub_vendor_id, "0000", 4); - - /* for each line we found in the pci.ids */ - while (fgets(line, sizeof line, f)) { - /* Skipping uncessary lines */ - if ((line[0] == '#') || (line[0] == ' ') || (line[0] == 'C') || - (line[0] == 10)) - continue; - - /* If the line doesn't start with a tab, it means that's a vendor id */ - if (line[0] != '\t') { - - /* the 4 first chars are the vendor_id */ - strlcpy(vendor_id, line, 4); - - /* the vendor name is the next field */ - vendor_id[4] = 0; - strlcpy(vendor, skipspace(strstr(line, " ")), - PCI_VENDOR_NAME_SIZE - 1); - - remove_eol(vendor); - /* init product_id, sub_product and sub_vendor */ - strlcpy(product_id, "0000", 4); - strlcpy(sub_product_id, "0000", 4); - strlcpy(sub_vendor_id, "0000", 4); - - /* Unless we found a matching device, we have to skip to the next vendor */ - skip_to_next_vendor = true; - - int_vendor_id = hex_to_int(vendor_id); - /* Iterate in all pci devices to find a matching vendor */ - for_each_pci_func(dev, domain) { - /* if one device that match this vendor */ - if (int_vendor_id == dev->vendor) { - /* copy the vendor name for this device */ - strlcpy(dev->dev_info->vendor_name, vendor, - PCI_VENDOR_NAME_SIZE - 1); - /* Some pci devices match this vendor, so we have to found them */ - skip_to_next_vendor = false; - /* Let's loop on the other devices as some may have the same vendor */ - } - } - /* if we have a tab + a char, it means this is a product id - * but we only look at it if we own some pci devices of the current vendor*/ - } else if ((line[0] == '\t') && (line[1] != '\t') - && (skip_to_next_vendor == false)) { - - /* the product name the second field */ - strlcpy(product, skipspace(strstr(line, " ")), - PCI_PRODUCT_NAME_SIZE - 1); - remove_eol(product); - - /* the product id is first field */ - strlcpy(product_id, &line[1], 4); - product_id[4] = 0; - - /* init sub_product and sub_vendor */ - strlcpy(sub_product_id, "0000", 4); - strlcpy(sub_vendor_id, "0000", 4); - - int_vendor_id = hex_to_int(vendor_id); - int_product_id = hex_to_int(product_id); - /* assign the product_name to any matching pci device */ - for_each_pci_func(dev, domain) { - if (int_vendor_id == dev->vendor && - int_product_id == dev->product) { - strlcpy(dev->dev_info->vendor_name, vendor, - PCI_VENDOR_NAME_SIZE - 1); - strlcpy(dev->dev_info->product_name, product, - PCI_PRODUCT_NAME_SIZE - 1); - } - } - - /* if we have two tabs, it means this is a sub product - * but we only look at it if we own some pci devices of the current vendor*/ - } else if ((line[0] == '\t') && (line[1] == '\t') - && (skip_to_next_vendor == false)) { - - /* the product name is last field */ - strlcpy(product, skipspace(strstr(line, " ")), - PCI_PRODUCT_NAME_SIZE - 1); - strlcpy(product, skipspace(strstr(product, " ")), - PCI_PRODUCT_NAME_SIZE - 1); - remove_eol(product); - - /* the sub_vendor id is first field */ - strlcpy(sub_vendor_id, &line[2], 4); - sub_vendor_id[4] = 0; - - /* the sub_vendor id is second field */ - strlcpy(sub_product_id, &line[7], 4); - sub_product_id[4] = 0; - - int_vendor_id = hex_to_int(vendor_id); - int_sub_vendor_id = hex_to_int(sub_vendor_id); - int_product_id = hex_to_int(product_id); - int_sub_product_id = hex_to_int(sub_product_id); - /* assign the product_name to any matching pci device */ - for_each_pci_func(dev, domain) { - if (int_vendor_id == dev->vendor && - int_product_id == dev->product && - int_sub_product_id == dev->sub_product && - int_sub_vendor_id == dev->sub_vendor) { - strlcpy(dev->dev_info->vendor_name, vendor, - PCI_VENDOR_NAME_SIZE - 1); - strlcpy(dev->dev_info->product_name, product, - PCI_PRODUCT_NAME_SIZE - 1); - } - } - } - } - fclose(f); - return 0; -} - -/* searching if any pcidevice match our query */ -struct match *find_pci_device(const struct pci_domain *domain, - struct match *list) -{ - uint32_t did, sid; - struct match *m; - const struct pci_device *dev; - - /* for all matches we have to search */ - for (m = list; m; m = m->next) { - /* for each pci device we know */ - for_each_pci_func(dev, domain) { - /* sid & did are the easiest way to compare devices */ - /* they are made of vendor/product subvendor/subproduct ids */ - sid = dev->svid_sdid; - did = dev->vid_did; - /* if the current device match */ - if (((did ^ m->did) & m->did_mask) == 0 && - ((sid ^ m->sid) & m->sid_mask) == 0 && - dev->revision >= m->rid_min && dev->revision <= m->rid_max) { - dprintf - ("PCI Match: Vendor=%04x Product=%04x Sub_vendor=%04x Sub_Product=%04x Release=%02x\n", - dev->vendor, dev->product, dev->sub_vendor, - dev->sub_product, dev->revision); - /* returning the matched pci device */ - return m; - } - } - } - return NULL; -} - -/* scanning the pci bus to find pci devices */ -struct pci_domain *pci_scan(void) -{ - struct pci_domain *domain = NULL; - struct pci_bus *bus = NULL; - struct pci_slot *slot = NULL; - struct pci_device *func = NULL; - unsigned int nbus, ndev, nfunc, maxfunc; - uint32_t did, sid, rcid; - uint8_t hdrtype; - pciaddr_t a; - int cfgtype; - - cfgtype = pci_set_config_type(PCI_CFG_AUTO); - - dprintf("PCI configuration type %d\n", cfgtype); - - if (cfgtype == PCI_CFG_NONE) - return NULL; - - dprintf("Scanning PCI Buses\n"); - - for (nbus = 0; nbus < MAX_PCI_BUSES; nbus++) { - dprintf("Probing bus 0x%02x... \n", nbus); - bus = NULL; - - for (ndev = 0; ndev < MAX_PCI_DEVICES; ndev++) { - maxfunc = 1; /* Assume a single-function device */ - slot = NULL; - - for (nfunc = 0; nfunc < maxfunc; nfunc++) { - a = pci_mkaddr(nbus, ndev, nfunc, 0); - did = pci_readl(a); - - if (did == 0xffffffff || did == 0xffff0000 || - did == 0x0000ffff || did == 0x00000000) - continue; - - hdrtype = pci_readb(a + 0x0e); - - if (hdrtype & 0x80) - maxfunc = MAX_PCI_FUNC; /* Multifunction device */ - - rcid = pci_readl(a + 0x08); - sid = pci_readl(a + 0x2c); - - if (!domain) { - domain = zalloc(sizeof *domain); - if (!domain) - goto bail; - } - if (!bus) { - bus = zalloc(sizeof *bus); - if (!bus) - goto bail; - domain->bus[nbus] = bus; - } - if (!slot) { - slot = zalloc(sizeof *slot); - if (!slot) - goto bail; - bus->slot[ndev] = slot; - } - func = zalloc(sizeof *func); - if (!func) - goto bail; - - slot->func[nfunc] = func; - - func->vid_did = did; - func->svid_sdid = sid; - func->rid_class = rcid; - - dprintf - ("Scanning: BUS %02x DID %08x (%04x:%04x) SID %08x RID %02x\n", - nbus, did, did >> 16, (did << 16) >> 16, sid, rcid & 0xff); - } - } - } - - return domain; - -bail: - free_pci_domain(domain); - return NULL; -} - -/* gathering additional configuration*/ -void gather_additional_pci_config(struct pci_domain *domain) -{ - struct pci_device *dev; - pciaddr_t pci_addr; - int cfgtype; - - cfgtype = pci_set_config_type(PCI_CFG_AUTO); - if (cfgtype == PCI_CFG_NONE) - return; - - for_each_pci_func3(dev, domain, pci_addr) { - if (!dev->dev_info) { - dev->dev_info = zalloc(sizeof *dev->dev_info); - if (!dev->dev_info) { - return; - } - } - dev->dev_info->irq = pci_readb(pci_addr + 0x3c); - dev->dev_info->latency = pci_readb(pci_addr + 0x0d); - } -} - -void free_pci_domain(struct pci_domain *domain) -{ - struct pci_bus *bus; - struct pci_slot *slot; - struct pci_device *func; - unsigned int nbus, ndev, nfunc; - - if (domain) { - for (nbus = 0; nbus < MAX_PCI_BUSES; nbus++) { - bus = domain->bus[nbus]; - if (bus) { - for (ndev = 0; ndev < MAX_PCI_DEVICES; ndev++) { - slot = bus->slot[ndev]; - if (slot) { - for (nfunc = 0; nfunc < MAX_PCI_FUNC; nfunc++) { - func = slot->func[nfunc]; - if (func) { - if (func->dev_info) - free(func->dev_info); - free(func); - } - free(slot); - } - } - free(bus); - } - } - free(domain); - } - } -} - -/* Try to match any pci device to the appropriate kernel module */ -/* it uses the modules.alias from the boot device */ -int get_module_name_from_alias(struct pci_domain *domain, char *modules_alias_path) -{ - char line[MAX_LINE]; - char module_name[21]; // the module name field is 21 char long - char delims[]="*"; // colums are separated by spaces - char vendor_id[16]; - char product_id[16]; - char sub_vendor_id[16]; - char sub_product_id[16]; - FILE *f; - struct pci_device *dev=NULL; - - /* Intializing the linux_kernel_module for each pci device to "unknown" */ - /* adding a dev_info member if needed */ - for_each_pci_func(dev, domain) { - /* initialize the dev_info structure if it doesn't exist yet. */ - if (! dev->dev_info) { - dev->dev_info = zalloc(sizeof *dev->dev_info); - if (!dev->dev_info) - return -1; - } - for (int i=0;i<MAX_KERNEL_MODULES_PER_PCI_DEVICE;i++) { - if (strlen(dev->dev_info->linux_kernel_module[i])==0) - strlcpy(dev->dev_info->linux_kernel_module[i], "unknown",7); - } - } - - /* Opening the modules.pcimap (of a linux kernel) from the boot device */ - f=zfopen(modules_alias_path, "r"); - if (!f) - return -ENOMODULESALIAS; - - /* for each line we found in the modules.pcimap */ - while ( fgets(line, sizeof line, f) ) { - /* skipping unecessary lines */ - if ((line[0] == '#') || (strstr(line,"alias pci:v")==NULL)) - continue; - - /* Resetting temp buffer*/ - memset(module_name,0,sizeof(module_name)); - memset(vendor_id,0,sizeof(vendor_id)); - memset(sub_vendor_id,0,sizeof(sub_vendor_id)); - memset(product_id,0,sizeof(product_id)); - memset(sub_product_id,0,sizeof(sub_product_id)); - strcpy(vendor_id,"0000"); - strcpy(product_id,"0000"); - /* ffff will be used to match any device as in modules.alias - * a missing subvendor/product have to be considered as 0xFFFF*/ - strcpy(sub_product_id,"ffff"); - strcpy(sub_vendor_id,"ffff"); - - char *result = NULL; - int field=0; - - /* looking for the next field */ - result = strtok(line+strlen("alias pci:v"), delims); - while( result != NULL ) { - if (field==0) { - - /* Searching for the vendor separator*/ - char *temp = strstr(result,"d"); - if (temp != NULL) { - strlcpy(vendor_id,result,temp-result); - result+=strlen(vendor_id)+1; - } - - /* Searching for the product separator*/ - temp = strstr(result,"sv"); - if (temp != NULL) { - strlcpy(product_id,result,temp-result); - result+=strlen(product_id)+1; - } - - /* Searching for the sub vendor separator*/ - temp = strstr(result,"sd"); - if (temp != NULL) { - strlcpy(sub_vendor_id,result,temp-result); - result+=strlen(sub_vendor_id)+1; - } - - /* Searching for the sub product separator*/ - temp = strstr(result,"bc"); - if (temp != NULL) { - strlcpy(sub_product_id,result,temp-result); - result+=strlen(sub_product_id)+1; - } - /* That's the module name */ - } else if ((strlen(result)>2) && - (result[0]==0x20)) - strcpy(module_name,result+1); - /* We have to replace \n by \0*/ - module_name[strlen(module_name)-1]='\0'; - field++; - - /* Searching the next field */ - result = strtok( NULL, delims ); - } - - /* Now we have extracted informations from the modules.alias - * Let's compare it with the devices we know*/ - int int_vendor_id=hex_to_int(vendor_id); - int int_sub_vendor_id=hex_to_int(sub_vendor_id); - int int_product_id=hex_to_int(product_id); - int int_sub_product_id=hex_to_int(sub_product_id); - /* if a pci_device matches an entry, fill the linux_kernel_module with - the appropriate kernel module */ - for_each_pci_func(dev, domain) { - if (int_vendor_id == dev->vendor && - int_product_id == dev->product && - (int_sub_product_id & dev->sub_product) - == dev->sub_product && - (int_sub_vendor_id & dev->sub_vendor) - == dev->sub_vendor) { - bool found=false; - - /* Scan all known kernel modules for this pci device */ - for (int i=0; i<dev->dev_info->linux_kernel_module_count; i++) { - - /* Try to detect if we already knew the same kernel module*/ - if (strstr(dev->dev_info->linux_kernel_module[i], module_name)) { - found=true; - break; - } - } - /* If we don't have this kernel module, let's add it */ - if (!found) { - strcpy(dev->dev_info->linux_kernel_module[dev->dev_info->linux_kernel_module_count], module_name); - dev->dev_info->linux_kernel_module_count++; - } - } - } - } - fclose(f); - return 0; -} |