From 0f106fd324fd22e42fbc6ded1b088ec982d4933f Mon Sep 17 00:00:00 2001 From: Erwan Velu Date: Mon, 16 Feb 2009 13:11:42 +0100 Subject: [PATCH] hdt: Adding more defined values for pci components Enabling mulitple kernel modules per pci device Updating pcitest --- com32/include/sys/pci.h | 20 ++++++++----- com32/lib/pci/scan.c | 47 ++++++++++++++++-------------- com32/modules/pcitest.c | 76 ++++++++++++++++++++++++++++++++++++++++--------- sample/hdt.c | 42 +++++++++++++++++++++++---- 4 files changed, 138 insertions(+), 47 deletions(-) diff --git a/com32/include/sys/pci.h b/com32/include/sys/pci.h index ff45047..feab9e8 100644 --- a/com32/include/sys/pci.h +++ b/com32/include/sys/pci.h @@ -4,9 +4,14 @@ #include #include -#define MAX_PCI_FUNC 8 -#define MAX_PCI_DEVICES 32 -#define MAX_PCI_BUSES 256 +#define MAX_PCI_FUNC 8 +#define MAX_PCI_DEVICES 32 +#define MAX_PCI_BUSES 256 +#define LINUX_KERNEL_MODULE_SIZE 64 +#define PCI_VENDOR_NAME_SIZE 256 +#define PCI_PRODUCT_NAME_SIZE 256 +#define PCI_CLASS_NAME_SIZE 256 +#define MAX_KERNEL_MODULES_PER_PCI_DEVICE 10 typedef uint32_t pciaddr_t; @@ -18,10 +23,11 @@ enum { /* a structure for extended pci information */ /* XXX: use pointers for these? */ struct pci_dev_info { - char vendor_name[256]; - char product_name[256]; - char linux_kernel_module[64]; - char class_name[256]; + char vendor_name[PCI_VENDOR_NAME_SIZE]; + char product_name[PCI_PRODUCT_NAME_SIZE]; + char linux_kernel_module[LINUX_KERNEL_MODULE_SIZE][MAX_KERNEL_MODULES_PER_PCI_DEVICE]; + int linux_kernel_module_count; + char class_name[PCI_CLASS_NAME_SIZE]; }; /* PCI device (really, function) */ diff --git a/com32/lib/pci/scan.c b/com32/lib/pci/scan.c index c1345b8..54b5f54 100644 --- a/com32/lib/pci/scan.c +++ b/com32/lib/pci/scan.c @@ -94,7 +94,9 @@ int get_module_name_from_pci_ids(struct pci_domain *domain) if (!dev->dev_info) return -1; } - strcpy(dev->dev_info->linux_kernel_module, "unknown"); + for (int i=0;idev_info->linux_kernel_module[i], "unknown",7); + } } /* Opening the modules.pcimap (of a linux kernel) from the boot device */ @@ -106,6 +108,7 @@ int get_module_name_from_pci_ids(struct pci_domain *domain) 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) ) { @@ -146,8 +149,10 @@ int get_module_name_from_pci_ids(struct pci_domain *domain) (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, module_name); + == 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); @@ -159,8 +164,8 @@ int get_module_name_from_pci_ids(struct pci_domain *domain) int get_class_name_from_pci_ids(struct pci_domain *domain) { char line[MAX_LINE]; - char class_name[255]; - char sub_class_name[255]; + 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; @@ -176,7 +181,7 @@ int get_class_name_from_pci_ids(struct pci_domain *domain) if (!dev->dev_info) return -1; } - strcpy(dev->dev_info->class_name,"unknown"); + strlcpy(dev->dev_info->class_name,"unknown",7); } /* Opening the pci.ids from the boot device */ @@ -196,7 +201,7 @@ int get_class_name_from_pci_ids(struct pci_domain *domain) class_mode=true; if (class_mode == false) continue; - strncpy(class_name,"unknown",7); + 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') { @@ -205,20 +210,20 @@ int get_class_name_from_pci_ids(struct pci_domain *domain) class_id_str[2]=0; /* the class name is the next field */ - strlcpy(class_name,skipspace(strstr(line," ")),255); + 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,255); + strlcpy(dev->dev_info->class_name,class_name,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," ")),255); + strlcpy(sub_class_name,skipspace(strstr(line," ")),PCI_CLASS_NAME_SIZE-1); remove_eol(sub_class_name); /* the sub class id is first field */ @@ -231,7 +236,7 @@ int get_class_name_from_pci_ids(struct pci_domain *domain) 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,255); + strlcpy(dev->dev_info->class_name,sub_class_name,PCI_CLASS_NAME_SIZE-1); } } @@ -246,9 +251,9 @@ int get_class_name_from_pci_ids(struct pci_domain *domain) int get_name_from_pci_ids(struct pci_domain *domain) { char line[MAX_LINE]; - char vendor[255]; + char vendor[PCI_VENDOR_NAME_SIZE]; char vendor_id[5]; - char product[255]; + char product[PCI_PRODUCT_NAME_SIZE]; char product_id[5]; char sub_product_id[5]; char sub_vendor_id[5]; @@ -298,7 +303,7 @@ int get_name_from_pci_ids(struct pci_domain *domain) /* the vendor name is the next field */ vendor_id[4]=0; - strlcpy(vendor,skipspace(strstr(line," ")),255); + strlcpy(vendor,skipspace(strstr(line," ")),PCI_VENDOR_NAME_SIZE-1); remove_eol(vendor); /* init product_id, sub_product and sub_vendor */ @@ -318,7 +323,7 @@ int get_name_from_pci_ids(struct pci_domain *domain) } else if ((line[0] == '\t') && (line[1] != '\t') && (skip_to_next_vendor == false)) { /* the product name the second field */ - strlcpy(product,skipspace(strstr(line," ")),255); + strlcpy(product,skipspace(strstr(line," ")),PCI_PRODUCT_NAME_SIZE-1); remove_eol(product); /* the product id is first field */ @@ -335,8 +340,8 @@ int get_name_from_pci_ids(struct pci_domain *domain) for_each_pci_func(dev, domain) { if (int_vendor_id == dev->vendor && int_product_id == dev->product) { - strlcpy(dev->dev_info->vendor_name,vendor,255); - strlcpy(dev->dev_info->product_name,product,255); + strlcpy(dev->dev_info->vendor_name,vendor,PCI_VENDOR_NAME_SIZE-1); + strlcpy(dev->dev_info->product_name,product,PCI_PRODUCT_NAME_SIZE-1); } } @@ -344,8 +349,8 @@ int get_name_from_pci_ids(struct pci_domain *domain) } else if ((line[0] == '\t') && (line[1] == '\t') && (skip_to_next_vendor == false)) { /* the product name is last field */ - strlcpy(product,skipspace(strstr(line," ")),255); - strlcpy(product,skipspace(strstr(product," ")),255); + 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 */ @@ -366,8 +371,8 @@ int get_name_from_pci_ids(struct pci_domain *domain) 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,255); - strlcpy(dev->dev_info->product_name,product,255); + strlcpy(dev->dev_info->vendor_name,vendor,PCI_VENDOR_NAME_SIZE-1); + strlcpy(dev->dev_info->product_name,product,PCI_PRODUCT_NAME_SIZE-1); } } } diff --git a/com32/modules/pcitest.c b/com32/modules/pcitest.c index 240f19f..2c71611 100644 --- a/com32/modules/pcitest.c +++ b/com32/modules/pcitest.c @@ -46,7 +46,7 @@ # define dprintf(...) ((void)0) #endif -char display_line; +char display_line=0; #define moreprintf(...) \ do { \ display_line++; \ @@ -61,34 +61,82 @@ char display_line; void display_pci_devices(struct pci_domain *pci_domain) { struct pci_device *pci_device; - int ndev = 0; + char kernel_modules [LINUX_KERNEL_MODULE_SIZE*MAX_KERNEL_MODULES_PER_PCI_DEVICE]; + for_each_pci_func(pci_device, pci_domain) { - printf("[%02x:%02x.%01x]: %s: %04x:%04x[%04x:%04x]) %s:%s\n", - __pci_bus, __pci_slot, __pci_func, - pci_device->dev_info->linux_kernel_module, - pci_device->vendor, pci_device->product, - pci_device->sub_vendor, pci_device->sub_product, - pci_device->dev_info->vendor_name, - pci_device->dev_info->product_name); - ndev++; + + memset(kernel_modules,0,sizeof kernel_modules); + +/* printf("PCI: found %d kernel modules for %04x:%04x[%04x:%04x]\n", + pci_device->dev_info->linux_kernel_module_count, + pci_device->vendor, pci_device->product, + pci_device->sub_vendor, pci_device->sub_product); +*/ + for (int i=0; idev_info->linux_kernel_module_count;i++) { + if (i>0) { + strncat(kernel_modules," | ",3); + } + strncat(kernel_modules, pci_device->dev_info->linux_kernel_module[i],LINUX_KERNEL_MODULE_SIZE-1); + } + + moreprintf("%04x:%04x[%04x:%04x]: %s\n", + pci_device->vendor, pci_device->product, + pci_device->sub_vendor, pci_device->sub_product, + pci_device->dev_info->class_name); + + moreprintf(" Vendor Name : %s\n", pci_device->dev_info->vendor_name); + moreprintf(" Product Name : %s\n", pci_device->dev_info->product_name); + moreprintf(" PCI bus position : %02x:%02x.%01x\n", __pci_bus, __pci_slot, __pci_func); + moreprintf(" Kernel modules : %s\n\n",kernel_modules); } - printf("PCI: %d devices found\n", ndev); } int main(int argc, char *argv[]) { struct pci_domain *pci_domain; + int return_code=0; + int nb_pci_devices=0; - openconsole(&dev_null_r, &dev_stdcon_w); + openconsole(&dev_stdcon_r, &dev_stdcon_w); /* Scanning to detect pci buses and devices */ + printf("PCI: Scanning PCI BUS\n"); pci_domain = pci_scan(); + struct pci_device *pci_device; + for_each_pci_func(pci_device, pci_domain) { + nb_pci_devices++; + } + + printf("PCI: %d PCI devices found\n",nb_pci_devices); + + + printf("PCI: Looking for device name\n"); /* Assigning product & vendor name for each device*/ - get_name_from_pci_ids(pci_domain); + return_code=get_name_from_pci_ids(pci_domain); + if (return_code == -ENOPCIIDS) { + printf("PCI: ERROR !\n"); + printf("PCI: Unable to open pci.ids in the same directory as pcitest.c32.\n"); + printf("PCI: PCI Device names can't be computed.\n"); + } + + printf("PCI: Resolving class names\n"); + /* Assigning class name for each device*/ + return_code=get_class_name_from_pci_ids(pci_domain); + if (return_code == -ENOPCIIDS) { + printf("PCI: ERROR !\n"); + printf("PCI: Unable to open pci.ids in the same directory as pcitest.c32.\n"); + printf("PCI: PCI class names can't be computed.\n"); + } + printf("PCI: Looking for Kernel modules\n"); /* Detecting which kernel module should match each device */ - get_module_name_from_pci_ids(pci_domain); + return_code=get_module_name_from_pci_ids(pci_domain); + if (return_code == -ENOMODULESPCIMAP) { + printf("PCI: ERROR !\n"); + printf("PCI: Unable to open modules.pcimap in the same directory as pcitest.c32.\n"); + printf("PCI: Kernel Module names can't be computed.\n"); + } /* display the pci devices we found */ display_pci_devices(pci_domain); diff --git a/sample/hdt.c b/sample/hdt.c index 8f4389a..fae8f1a 100644 --- a/sample/hdt.c +++ b/sample/hdt.c @@ -423,6 +423,7 @@ void detect_disks(struct diskinfo *disk_info) { void compute_pci_device(unsigned char *menu,struct pci_device *pci_device,int pci_bus, int pci_slot, int pci_func) { char buffer[56]; char statbuffer[STATLEN]; + char kernel_modules [LINUX_KERNEL_MODULE_SIZE*MAX_KERNEL_MODULES_PER_PCI_DEVICE]; *menu = add_menu(" Details ",-1); menu_count++; @@ -448,8 +449,19 @@ void compute_pci_device(unsigned char *menu,struct pci_device *pci_device,int pc snprintf(statbuffer,sizeof statbuffer,"vendor:product[sub_vendor:sub_product] : %04x:%04x[%04x:%04x]",pci_device->vendor, pci_device->product,pci_device->sub_vendor, pci_device->sub_product); add_item(buffer,statbuffer,OPT_INACTIVE,NULL,0); - snprintf(buffer,sizeof buffer,"Module : %s",pci_device->dev_info->linux_kernel_module); - snprintf(statbuffer,sizeof statbuffer,"Kernel Module: %s",pci_device->dev_info->linux_kernel_module); + if (pci_device->dev_info->linux_kernel_module_count>1) { + for (int i=0; idev_info->linux_kernel_module_count;i++) { + if (i>0) { + strncat(kernel_modules," | ",3); + } + strncat(kernel_modules, pci_device->dev_info->linux_kernel_module[i],LINUX_KERNEL_MODULE_SIZE-1); + } + snprintf(buffer,sizeof buffer,"Modules : %s",kernel_modules); + snprintf(statbuffer,sizeof statbuffer,"Kernel Modules: %s",kernel_modules); + } else { + snprintf(buffer,sizeof buffer,"Module : %s",pci_device->dev_info->linux_kernel_module[0]); + snprintf(statbuffer,sizeof statbuffer,"Kernel Module: %s",pci_device->dev_info->linux_kernel_module[0]); + } add_item(buffer,statbuffer,OPT_INACTIVE,NULL,0); } @@ -460,16 +472,27 @@ int compute_PCI(unsigned char *menu, struct pci_domain **pci_domain) { char menuname[255][MENULEN+1]; char infobar[255][STATLEN+1]; struct pci_device *pci_device; + char kernel_modules [LINUX_KERNEL_MODULE_SIZE*MAX_KERNEL_MODULES_PER_PCI_DEVICE]; + printf("MENU: Computing PCI menu\n"); /* For every detected pci device, compute its submenu */ for_each_pci_func(pci_device, *pci_domain) { + memset(kernel_modules,0,sizeof kernel_modules); + for (int i=0; idev_info->linux_kernel_module_count;i++) { + if (i>0) { + strncat(kernel_modules," | ",3); + } + strncat(kernel_modules, pci_device->dev_info->linux_kernel_module[i],LINUX_KERNEL_MODULE_SIZE-1); + } + if (pci_device->dev_info->linux_kernel_module_count==0) strlcpy(kernel_modules,"unknown",7); + compute_pci_device(&PCI_SUBMENU[i],pci_device,__pci_bus,__pci_slot,__pci_func); snprintf(menuname[i],59,"%s|%s",pci_device->dev_info->vendor_name,pci_device->dev_info->product_name); snprintf(infobar[i], STATLEN,"%02x:%02x.%01x # %s # ID:%04x:%04x[%04x:%04x] # Kmod:%s\n", __pci_bus, __pci_slot, __pci_func,pci_device->dev_info->class_name, pci_device->vendor, pci_device->product, - pci_device->sub_vendor, pci_device->sub_product,pci_device->dev_info->linux_kernel_module); + pci_device->sub_vendor, pci_device->sub_product,kernel_modules); i++; } @@ -491,6 +514,7 @@ return 0; void compute_KERNEL(unsigned char *menu,struct pci_domain **pci_domain) { char buffer[SUBMENULEN+1]; char infobar[STATLEN+1]; + char kernel_modules [LINUX_KERNEL_MODULE_SIZE*MAX_KERNEL_MODULES_PER_PCI_DEVICE]; *menu = add_menu(" Kernel Modules ",-1); menu_count++; @@ -506,9 +530,17 @@ void compute_KERNEL(unsigned char *menu,struct pci_domain **pci_domain) { } else { /* For every detected pci device, grab its kernel module to compute this submenu */ for_each_pci_func(pci_device, *pci_domain) { + memset(kernel_modules,0,sizeof kernel_modules); + for (int i=0; idev_info->linux_kernel_module_count;i++) { + if (i>0) { + strncat(kernel_modules," | ",3); + } + strncat(kernel_modules, pci_device->dev_info->linux_kernel_module[i],LINUX_KERNEL_MODULE_SIZE-1); + } + /* No need to add unknown kernel modules*/ - if (strcmp("unknown",pci_device->dev_info->linux_kernel_module)!=0) { - snprintf(buffer,sizeof buffer,"%s (%s)",pci_device->dev_info->linux_kernel_module, pci_device->dev_info->class_name); + if (strlen(kernel_modules)>0) { + snprintf(buffer,sizeof buffer,"%s (%s)",kernel_modules, pci_device->dev_info->class_name); snprintf(infobar, sizeof infobar,"%04x:%04x %s : %s\n", pci_device->vendor, pci_device->product, pci_device->dev_info->vendor_name, -- 2.7.4