Subject: kern/3359: pci support for multifunction devices broken
To: None <gnats-bugs@gnats.netbsd.org>
From: None <brb@brig.com>
List: netbsd-bugs
Date: 03/18/1997 23:33:35
>Number:         3359
>Category:       kern
>Synopsis:       pci support for multifunction devices broken
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Mar 18 23:50:02 1997
>Last-Modified:
>Originator:     Brian Baird
>Organization:
Brian Baird				Brig Systems, Pleasanton CA
brb@brig.com				+1 510 484 1342
>Release:        1.2
>Environment:
System: NetBSD home 1.1 NetBSD 1.1 (EXP) #0: Thu Jan 18 17:51:48 PST 1996 brb@n113:/usr/src/sys/arch/i386/compile/EXP i386


>Description:
	Due to a couple of typos in pcireg.h concerning the BHLC
	register decode, no PCI multi-function device will be
	detected.  Function 0 will work, but functions 1 through 7
	will be ignored.

	While I'm here, I added the other various PCI class and
	subclass designators that I know about (so that you can see a
	USB Serial Bus device on recent Intel motherboard controllers,
	for example).

	I also rearranged the pci_devinfo() class/subclass printing to
	be a little more intuitive:
		(USB serial bus)
	rather than
		(class serial bus, subclass USB)

>How-To-Repeat:
	Enable the USB controller on an Intel 82371 based motherboard,
	reboot, and see that there is no unrecognized USB controller :-)

>Fix:
	This patch is for 1.2 but drops into -current as well.

*** pci_subr.c.dist	Fri Mar  1 18:28:48 1996
--- pci_subr.c	Thu Oct 31 08:15:19 1996
***************
*** 67,72 ****
--- 67,73 ----
  	{ "IDE",		PCI_SUBCLASS_MASS_STORAGE_IDE,		},
  	{ "floppy",		PCI_SUBCLASS_MASS_STORAGE_FLOPPY,	},
  	{ "IPI",		PCI_SUBCLASS_MASS_STORAGE_IPI,		},
+ 	{ "RAID",		PCI_SUBCLASS_MASS_STORAGE_RAID,		},
  	{ "miscellaneous",	PCI_SUBCLASS_MASS_STORAGE_MISC,		},
  	{ 0 },
  };
***************
*** 75,80 ****
--- 76,82 ----
  	{ "ethernet",		PCI_SUBCLASS_NETWORK_ETHERNET,		},
  	{ "token ring",		PCI_SUBCLASS_NETWORK_TOKENRING,		},
  	{ "FDDI",		PCI_SUBCLASS_NETWORK_FDDI,		},
+ 	{ "ATM",		PCI_SUBCLASS_NETWORK_ATM,		},
  	{ "miscellaneous",	PCI_SUBCLASS_NETWORK_MISC,		},
  	{ 0 },
  };
***************
*** 107,116 ****
--- 109,169 ----
  	{ "MicroChannel",	PCI_SUBCLASS_BRIDGE_MC,			},
  	{ "PCI",		PCI_SUBCLASS_BRIDGE_PCI,		},
  	{ "PCMCIA",		PCI_SUBCLASS_BRIDGE_PCMCIA,		},
+ 	{ "NuBus",		PCI_SUBCLASS_BRIDGE_NUBUS,		},
+ 	{ "CardBus",		PCI_SUBCLASS_BRIDGE_CARDBUS,		},
  	{ "miscellaneous",	PCI_SUBCLASS_BRIDGE_MISC,		},
  	{ 0 },
  };
  
+ struct pci_class pci_subclass_communications[] = {
+ 	{ "serial",		PCI_SUBCLASS_COMMUNICATIONS_SERIAL,	},
+ 	{ "parallel",		PCI_SUBCLASS_COMMUNICATIONS_PARALLEL,	},
+ 	{ "miscellaneous",	PCI_SUBCLASS_COMMUNICATIONS_MISC,	},
+ 	{ 0 },
+ };
+ 
+ struct pci_class pci_subclass_system[] = {
+ 	{ "8259 PIC",		PCI_SUBCLASS_SYSTEM_PIC,		},
+ 	{ "8237 DMA",		PCI_SUBCLASS_SYSTEM_DMA,		},
+ 	{ "8254 timer",		PCI_SUBCLASS_SYSTEM_TIMER,		},
+ 	{ "RTC",		PCI_SUBCLASS_SYSTEM_RTC,		},
+ 	{ "miscellaneous",	PCI_SUBCLASS_SYSTEM_MISC,		},
+ 	{ 0 },
+ };
+ 
+ struct pci_class pci_subclass_input[] = {
+ 	{ "keyboard",		PCI_SUBCLASS_INPUT_KEYBOARD,		},
+ 	{ "digitizer",		PCI_SUBCLASS_INPUT_DIGITIZER,		},
+ 	{ "mouse",		PCI_SUBCLASS_INPUT_MOUSE,		},
+ 	{ "miscellaneous",	PCI_SUBCLASS_INPUT_MISC,		},
+ 	{ 0 },
+ };
+ 
+ struct pci_class pci_subclass_dock[] = {
+ 	{ "generic",		PCI_SUBCLASS_DOCK_GENERIC,		},
+ 	{ "miscellaneous",	PCI_SUBCLASS_DOCK_MISC,			},
+ 	{ 0 },
+ };
+ 
+ struct pci_class pci_subclass_processor[] = {
+ 	{ "386",		PCI_SUBCLASS_PROCESSOR_386,		},
+ 	{ "486",		PCI_SUBCLASS_PROCESSOR_486,		},
+ 	{ "Pentium",		PCI_SUBCLASS_PROCESSOR_PENTIUM,		},
+ 	{ "Alpha",		PCI_SUBCLASS_PROCESSOR_ALPHA,		},
+ 	{ "PowerPC",		PCI_SUBCLASS_PROCESSOR_POWERPC,		},
+ 	{ "Co-processor",	PCI_SUBCLASS_PROCESSOR_COPROC,		},
+ 	{ 0 },
+ };
+ 
+ struct pci_class pci_subclass_serialbus[] = {
+ 	{ "Firewire",		PCI_SUBCLASS_SERIALBUS_FIREWIRE,	},
+ 	{ "ACCESS.bus",		PCI_SUBCLASS_SERIALBUS_ACCESS,		},
+ 	{ "SSA",		PCI_SUBCLASS_SERIALBUS_SSA,		},
+ 	{ "USB",		PCI_SUBCLASS_SERIALBUS_USB,		},
+ 	{ "Fiber Channel",	PCI_SUBCLASS_SERIALBUS_FIBER,		},
+ 	{ 0 },
+ };
+ 
  struct pci_class pci_class[] = {
  	{ "prehistoric",	PCI_CLASS_PREHISTORIC,
  	    pci_subclass_prehistoric,				},
***************
*** 126,131 ****
--- 179,196 ----
  	    pci_subclass_memory,				},
  	{ "bridge",		PCI_CLASS_BRIDGE,
  	    pci_subclass_bridge,				},
+ 	{ "communications",	PCI_CLASS_COMMUNICATIONS,
+ 	    pci_subclass_communications,			},
+ 	{ "system",		PCI_CLASS_SYSTEM,
+ 	    pci_subclass_system,				},
+ 	{ "input",		PCI_CLASS_INPUT,
+ 	    pci_subclass_input,					},
+ 	{ "dock",		PCI_CLASS_DOCK,
+ 	    pci_subclass_dock,					},
+ 	{ "processor",		PCI_CLASS_PROCESSOR,
+ 	    pci_subclass_processor,				},
+ 	{ "serial bus",		PCI_CLASS_SERIALBUS,
+ 	    pci_subclass_serialbus,				},
  	{ "undefined",		PCI_CLASS_UNDEFINED,
  	    0,							},
  	{ 0 },
***************
*** 214,239 ****
  	else if (product_namep != NULL)
  		cp += sprintf(cp, "%s %s", vendor_namep, product_namep);
  	else
! 		cp += sprintf(cp, "vendor %s, unknown product 0x%x",
  		    vendor_namep, product);
  	if (showclass) {
  		cp += sprintf(cp, " (");
  		if (classp->name == NULL)
! 			cp += sprintf(cp,
! 			    "unknown class 0x%2x, subclass 0x%02x",
  			    class, subclass);
  		else {
- 			cp += sprintf(cp, "class %s, ", classp->name);
  			if (subclassp == NULL || subclassp->name == NULL)
! 				cp += sprintf(cp, "unknown subclass 0x%02x",
! 				    subclass);
  			else
! 				cp += sprintf(cp, "subclass %s",
! 				    subclassp->name);
  		}
! #if 0 /* not very useful */
! 		cp += sprintf(cp, ", interface 0x%02x", interface);
! #endif
! 		cp += sprintf(cp, ", revision 0x%02x)", revision);
  	}
  }
--- 279,304 ----
  	else if (product_namep != NULL)
  		cp += sprintf(cp, "%s %s", vendor_namep, product_namep);
  	else
! 		cp += sprintf(cp, "%s product 0x%04x",
  		    vendor_namep, product);
  	if (showclass) {
  		cp += sprintf(cp, " (");
  		if (classp->name == NULL)
! 			cp += sprintf(cp, "class 0x%02x, subclass 0x%02x",
  			    class, subclass);
  		else {
  			if (subclassp == NULL || subclassp->name == NULL)
! 				cp += sprintf(cp,
! 				    "%s subclass 0x%02x",
! 				    classp->name, subclass);
  			else
! 				cp += sprintf(cp, "%s %s",
! 				    subclassp->name, classp->name);
  		}
! 		if (interface != 0)
! 			cp += sprintf(cp, ", interface 0x%02x", interface);
! 		if (revision != 0)
! 			cp += sprintf(cp, ", revision 0x%02x", revision);
! 		cp += sprintf(cp, ")");
  	}
  }
*** pcireg.h.dist	Tue Mar 26 20:08:27 1996
--- pcireg.h	Tue Oct 29 12:23:22 1996
***************
*** 123,128 ****
--- 123,134 ----
  #define	PCI_CLASS_MULTIMEDIA			0x04
  #define	PCI_CLASS_MEMORY			0x05
  #define	PCI_CLASS_BRIDGE			0x06
+ #define	PCI_CLASS_COMMUNICATIONS		0x07
+ #define	PCI_CLASS_SYSTEM			0x08
+ #define	PCI_CLASS_INPUT				0x09
+ #define	PCI_CLASS_DOCK				0x0A
+ #define	PCI_CLASS_PROCESSOR			0x0B
+ #define	PCI_CLASS_SERIALBUS			0x0C
  #define	PCI_CLASS_UNDEFINED			0xff
  
  /* 0x00 prehistoric subclasses */
***************
*** 134,145 ****
--- 140,153 ----
  #define	PCI_SUBCLASS_MASS_STORAGE_IDE		0x01
  #define	PCI_SUBCLASS_MASS_STORAGE_FLOPPY	0x02
  #define	PCI_SUBCLASS_MASS_STORAGE_IPI		0x03
+ #define	PCI_SUBCLASS_MASS_STORAGE_RAID		0x04
  #define	PCI_SUBCLASS_MASS_STORAGE_MISC		0x80
  
  /* 0x02 network subclasses */
  #define	PCI_SUBCLASS_NETWORK_ETHERNET		0x00
  #define	PCI_SUBCLASS_NETWORK_TOKENRING		0x01
  #define	PCI_SUBCLASS_NETWORK_FDDI		0x02
+ #define	PCI_SUBCLASS_NETWORK_ATM		0x03
  #define	PCI_SUBCLASS_NETWORK_MISC		0x80
  
  /* 0x03 display subclasses */
***************
*** 164,171 ****
--- 172,218 ----
  #define	PCI_SUBCLASS_BRIDGE_MC			0x03
  #define	PCI_SUBCLASS_BRIDGE_PCI			0x04
  #define	PCI_SUBCLASS_BRIDGE_PCMCIA		0x05
+ #define	PCI_SUBCLASS_BRIDGE_NUBUS		0x06
+ #define	PCI_SUBCLASS_BRIDGE_CARDBUS		0x07
  #define	PCI_SUBCLASS_BRIDGE_MISC		0x80
  
+ /* 0x07 communications subclasses */
+ #define	PCI_SUBCLASS_COMMUNICATIONS_SERIAL	0x00
+ #define	PCI_SUBCLASS_COMMUNICATIONS_PARALLEL	0x01
+ #define	PCI_SUBCLASS_COMMUNICATIONS_MISC	0x80
+ 
+ /* 0x08 system subclasses */
+ #define	PCI_SUBCLASS_SYSTEM_PIC			0x00
+ #define	PCI_SUBCLASS_SYSTEM_DMA			0x01
+ #define	PCI_SUBCLASS_SYSTEM_TIMER		0x02
+ #define	PCI_SUBCLASS_SYSTEM_RTC			0x03
+ #define	PCI_SUBCLASS_SYSTEM_MISC		0x80
+ 
+ /* 0x09 input subclasses */
+ #define	PCI_SUBCLASS_INPUT_KEYBOARD		0x00
+ #define	PCI_SUBCLASS_INPUT_DIGITIZER		0x01
+ #define	PCI_SUBCLASS_INPUT_MOUSE		0x02
+ #define	PCI_SUBCLASS_INPUT_MISC			0x80
+ 
+ /* 0x0A dock subclasses */
+ #define	PCI_SUBCLASS_DOCK_GENERIC		0x00
+ #define	PCI_SUBCLASS_DOCK_MISC			0x80
+ 
+ /* 0x0B processor subclasses */
+ #define	PCI_SUBCLASS_PROCESSOR_386		0x00
+ #define	PCI_SUBCLASS_PROCESSOR_486		0x01
+ #define	PCI_SUBCLASS_PROCESSOR_PENTIUM		0x02
+ #define	PCI_SUBCLASS_PROCESSOR_ALPHA		0x10
+ #define	PCI_SUBCLASS_PROCESSOR_POWERPC		0x20
+ #define	PCI_SUBCLASS_PROCESSOR_COPROC		0x40
+ 
+ /* 0x0C serial bus subclasses */
+ #define	PCI_SUBCLASS_SERIALBUS_FIREWIRE		0x00
+ #define	PCI_SUBCLASS_SERIALBUS_ACCESS		0x01
+ #define	PCI_SUBCLASS_SERIALBUS_SSA		0x02
+ #define	PCI_SUBCLASS_SERIALBUS_USB		0x03
+ #define	PCI_SUBCLASS_SERIALBUS_FIBER		0x04
+ 
  /*
   * PCI BIST/Header Type/Latency Timer/Cache Line Size Register.
   */
***************
*** 176,182 ****
  #define	PCI_BIST(bhlcr) \
  	    (((bhlcr) >> PCI_BIST_SHIFT) & PCI_BIST_MASK)
  
! #define	PCI_HDRTYPE_SHIFT			24
  #define	PCI_HDRTYPE_MASK			0xff
  #define	PCI_HDRTYPE(bhlcr) \
  	    (((bhlcr) >> PCI_HDRTYPE_SHIFT) & PCI_HDRTYPE_MASK)
--- 223,229 ----
  #define	PCI_BIST(bhlcr) \
  	    (((bhlcr) >> PCI_BIST_SHIFT) & PCI_BIST_MASK)
  
! #define	PCI_HDRTYPE_SHIFT			16
  #define	PCI_HDRTYPE_MASK			0xff
  #define	PCI_HDRTYPE(bhlcr) \
  	    (((bhlcr) >> PCI_HDRTYPE_SHIFT) & PCI_HDRTYPE_MASK)
***************
*** 184,195 ****
  #define	PCI_HDRTYPE_MULTIFN(bhlcr) \
  	    ((PCI_HDRTYPE(bhlcr) & 0x80) != 0)
  
! #define	PCI_LATTIMER_SHIFT			24
  #define	PCI_LATTIMER_MASK			0xff
  #define	PCI_LATTIMER(bhlcr) \
  	    (((bhlcr) >> PCI_LATTIMER_SHIFT) & PCI_LATTIMER_MASK)
  
! #define	PCI_CACHELINE_SHIFT			24
  #define	PCI_CACHELINE_MASK			0xff
  #define	PCI_CACHELINE(bhlcr) \
  	    (((bhlcr) >> PCI_CACHELINE_SHIFT) & PCI_CACHELINE_MASK)
--- 231,242 ----
  #define	PCI_HDRTYPE_MULTIFN(bhlcr) \
  	    ((PCI_HDRTYPE(bhlcr) & 0x80) != 0)
  
! #define	PCI_LATTIMER_SHIFT			8
  #define	PCI_LATTIMER_MASK			0xff
  #define	PCI_LATTIMER(bhlcr) \
  	    (((bhlcr) >> PCI_LATTIMER_SHIFT) & PCI_LATTIMER_MASK)
  
! #define	PCI_CACHELINE_SHIFT			0
  #define	PCI_CACHELINE_MASK			0xff
  #define	PCI_CACHELINE(bhlcr) \
  	    (((bhlcr) >> PCI_CACHELINE_SHIFT) & PCI_CACHELINE_MASK)

>Audit-Trail:
>Unformatted: