hdt: Adding more defined values for pci components Enabling mulitple kernel modules...
authorErwan Velu <erwan.velu@free.fr>
Mon, 16 Feb 2009 12:11:42 +0000 (13:11 +0100)
committerH. Peter Anvin <hpa@zytor.com>
Thu, 26 Feb 2009 04:58:41 +0000 (20:58 -0800)
com32/include/sys/pci.h
com32/lib/pci/scan.c
com32/modules/pcitest.c
sample/hdt.c

index ff45047..feab9e8 100644 (file)
@@ -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) */
index c1345b8..54b5f54 100644 (file)
@@ -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);
        }
       }
     }
index 240f19f..2c71611 100644 (file)
@@ -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);
index 8f4389a..fae8f1a 100644 (file)
@@ -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,