aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--com32/include/sys/pci.h20
-rw-r--r--com32/lib/pci/scan.c47
-rw-r--r--com32/modules/pcitest.c76
-rw-r--r--sample/hdt.c42
4 files changed, 138 insertions, 47 deletions
diff --git a/com32/include/sys/pci.h b/com32/include/sys/pci.h
index ff450477..feab9e82 100644
--- a/com32/include/sys/pci.h
+++ b/com32/include/sys/pci.h
@@ -4,9 +4,14 @@
#include <inttypes.h>
#include <sys/io.h>
-#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 c1345b8e..54b5f54e 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;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 */
@@ -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 240f19f2..2c716110 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; i<pci_device->dev_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 8f4389a7..fae8f1a5 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; i<pci_device->dev_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; i<pci_device->dev_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; i<pci_device->dev_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,