/* searching the next char that is not a space */
static char *skipspace(char *p)
{
- while (*p && *p <= ' ')
- p++;
+ while (*p && *p <= ' ')
+ p++;
- return 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;
+ 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);
+ return strtoul(hexa, NULL, 16);
}
/* 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)
+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++) {
- strlcpy(dev->dev_info->linux_kernel_module[i], "unknown",7);
- }
- }
-
- /* Opening the modules.pcimap (of a linux kernel) from the boot device */
- f=fopen(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");
- dev->dev_info->linux_kernel_module_count=0;
-
- /* 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) {
- case 0: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 */
+ 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) {
- 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) {
- strcpy(dev->dev_info->linux_kernel_module[dev->dev_info->linux_kernel_module_count], module_name);
- dev->dev_info->linux_kernel_module_count++;
- }
+ /* 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++) {
+ strlcpy(dev->dev_info->linux_kernel_module[i], "unknown", 7);
+ }
+ }
+
+ /* Opening the modules.pcimap (of a linux kernel) from the boot device */
+ f = fopen(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");
+ dev->dev_info->linux_kernel_module_count = 0;
+
+ /* 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) {
+ case 0:
+ 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) {
+ 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;
+ 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 = fopen(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);
+ 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;
}
- }
- /* 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);
- }
+ strlcpy(dev->dev_info->class_name, "unknown", 7);
+ }
+
+ /* Opening the pci.ids from the boot device */
+ f = fopen(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;
+ 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 = fopen(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);
+ 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;
}
- }
-
- /* 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);
+ 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 = fopen(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;
+ 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;
- }
+ 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;
+ 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;
+ 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;
- for (nfunc = 0; nfunc < maxfunc; nfunc++) {
- a = pci_mkaddr(nbus, ndev, nfunc, 0);
- did = pci_readl(a);
+ cfgtype = pci_set_config_type(PCI_CFG_AUTO);
- if (did == 0xffffffff || did == 0xffff0000 ||
- did == 0x0000ffff || did == 0x00000000)
- continue;
+ dprintf("PCI configuration type %d\n", cfgtype);
- hdrtype = pci_readb(a + 0x0e);
+ if (cfgtype == PCI_CFG_NONE)
+ return NULL;
- if (hdrtype & 0x80)
- maxfunc = MAX_PCI_FUNC; /* Multifunction device */
+ dprintf("Scanning PCI Buses\n");
- rcid = pci_readl(a + 0x08);
- sid = pci_readl(a + 0x2c);
+ for (nbus = 0; nbus < MAX_PCI_BUSES; nbus++) {
+ dprintf("Probing bus 0x%02x... \n", nbus);
+ bus = NULL;
- 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;
+ 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);
+ }
}
- 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;
+ return domain;
- bail:
- free_pci_domain(domain);
- return NULL;
+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);
- }
+ 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);
+ 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(bus);
+ free(domain);
}
- }
- free(domain);
}
- }
}