1/* 2 * PCI Class and Device Name Tables 3 * 4 * Copyright 1993--1999 Drew Eckhardt, Frederic Potter, 5 * David Mosberger-Tang, Martin Mares 6 */ 7 8#include <linux/config.h> 9#include <linux/types.h> 10#include <linux/kernel.h> 11#include <linux/pci.h> 12#include <linux/init.h> 13 14#ifdef CONFIG_PCI_NAMES 15 16struct pci_device_info { 17 unsigned short device; 18 unsigned short seen; 19 const char *name; 20}; 21 22struct pci_vendor_info { 23 unsigned short vendor; 24 unsigned short nr; 25 const char *name; 26 struct pci_device_info *devices; 27}; 28 29/* 30 * This is ridiculous, but we want the strings in 31 * the .init section so that they don't take up 32 * real memory.. Parse the same file multiple times 33 * to get all the info. 34 */ 35#define VENDOR( vendor, name ) static char __vendorstr_##vendor[] __devinitdata = name; 36#define ENDVENDOR() 37#define DEVICE( vendor, device, name ) static char __devicestr_##vendor##device[] __devinitdata = name; 38#include "devlist.h" 39 40 41#define VENDOR( vendor, name ) static struct pci_device_info __devices_##vendor[] __devinitdata = { 42#define ENDVENDOR() }; 43#define DEVICE( vendor, device, name ) { 0x##device, 0, __devicestr_##vendor##device }, 44#include "devlist.h" 45 46static struct pci_vendor_info __devinitdata pci_vendor_list[] = { 47#define VENDOR( vendor, name ) { 0x##vendor, sizeof(__devices_##vendor) / sizeof(struct pci_device_info), __vendorstr_##vendor, __devices_##vendor }, 48#define ENDVENDOR() 49#define DEVICE( vendor, device, name ) 50#include "devlist.h" 51}; 52 53#define VENDORS (sizeof(pci_vendor_list)/sizeof(struct pci_vendor_info)) 54 55void __devinit pci_name_device(struct pci_dev *dev) 56{ 57 const struct pci_vendor_info *vendor_p = pci_vendor_list; 58 int i = VENDORS; 59 char *name = dev->name; 60 61 do { 62 if (vendor_p->vendor == dev->vendor) 63 goto match_vendor; 64 vendor_p++; 65 } while (--i); 66 67 /* Couldn't find either the vendor nor the device */ 68 sprintf(name, "PCI device %04x:%04x", dev->vendor, dev->device); 69 return; 70 71 match_vendor: { 72 struct pci_device_info *device_p = vendor_p->devices; 73 int i = vendor_p->nr; 74 75 while (i > 0) { 76 if (device_p->device == dev->device) 77 goto match_device; 78 device_p++; 79 i--; 80 } 81 82 /* Ok, found the vendor, but unknown device */ 83 sprintf(name, "PCI device %04x:%04x (%s)", dev->vendor, dev->device, vendor_p->name); 84 return; 85 86 /* Full match */ 87 match_device: { 88 char *n = name + sprintf(name, "%s %s", vendor_p->name, device_p->name); 89 int nr = device_p->seen + 1; 90 device_p->seen = nr; 91 if (nr > 1) 92 sprintf(n, " (#%d)", nr); 93 } 94 } 95} 96 97/* 98 * Class names. Not in .init section as they are needed in runtime. 99 */ 100 101static u16 pci_class_numbers[] = { 102#define CLASS(x,y) 0x##x, 103#include "classlist.h" 104}; 105 106static char *pci_class_names[] = { 107#define CLASS(x,y) y, 108#include "classlist.h" 109}; 110 111char * 112pci_class_name(u32 class) 113{ 114 int i; 115 116 for(i=0; i<sizeof(pci_class_numbers)/sizeof(pci_class_numbers[0]); i++) 117 if (pci_class_numbers[i] == class) 118 return pci_class_names[i]; 119 return NULL; 120} 121 122#else 123 124void __devinit pci_name_device(struct pci_dev *dev) 125{ 126} 127 128char * 129pci_class_name(u32 class) 130{ 131 return NULL; 132} 133 134#endif /* CONFIG_PCI_NAMES */ 135 136