summaryrefslogtreecommitdiffstats
path: root/contrib/syslinux/latest/com32/lib/pci/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/syslinux/latest/com32/lib/pci/scan.c')
-rw-r--r--contrib/syslinux/latest/com32/lib/pci/scan.c751
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;
-}