From 45ff9914bfc89e0757878212fbbb1e87613296bd Mon Sep 17 00:00:00 2001 From: se Date: Thu, 25 Jan 1996 18:32:00 +0000 Subject: [PATCH] Add support for multi-function devices. --- sys/dev/pci/pci.c | 26 +++++++++++++++++++------- sys/dev/pci/pcireg.h | 9 ++++++++- sys/dev/pci/pcivar.h | 8 +++++--- sys/pci/pci.c | 26 +++++++++++++++++++------- sys/pci/pcireg.h | 9 ++++++++- sys/pci/pcivar.h | 8 +++++--- 6 files changed, 64 insertions(+), 22 deletions(-) diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index a73d9c5cc58b..4b40b43916d9 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: pci.c,v 1.40 1996/01/19 19:01:19 se Exp $ +** $Id: pci.c,v 1.41 1996/01/23 21:47:16 se Exp $ ** ** General subroutines for the PCI bus. ** pci_configure () @@ -374,13 +374,15 @@ pci_bus_config (void) }; #endif for (device=0; devicepcicb_seen >> device) & 1) - continue; + if ((pcicb->pcicb_seen >> device) & 1) + continue; - tag = pcibus->pb_tag (pcicb->pcicb_bus, device, 0); + for (func=0; func <= maxfunc; func++) { + tag = pcibus->pb_tag (pcicb->pcicb_bus, device, func); type = pcibus->pb_read (tag, PCI_ID_REG); if ((!type) || (type==0xfffffffful)) continue; @@ -400,6 +402,9 @@ pci_bus_config (void) /* ** check for mirrored devices. */ + if (func != 0) { + goto real_device; + } if (device & 0x10) { mtag=pcibus->pb_tag (pcicb->pcicb_bus, (u_char)(device & ~0x10), 0); @@ -425,6 +430,11 @@ pci_bus_config (void) real_device: + if (func == 0 && (pcibus->pb_read (tag, PCI_HEADER_MISC) + & PCI_HEADER_MULTIFUNCTION)) { + maxfunc = 7; + } + if (dvp==NULL) { #ifndef PCI_QUIET if (pci_conf_count) @@ -551,6 +561,7 @@ pci_bus_config (void) pdcp -> pdc_pi.pi_bus = pcicb->pcicb_bus; pdcp -> pdc_pi.pi_device = device; + pdcp -> pdc_pi.pi_func = func; pdcp -> pdc_kdc.kdc_name = dvp->pd_name; pdcp -> pdc_kdc.kdc_unit = unit; @@ -751,6 +762,7 @@ pci_bus_config (void) break; } + } } #ifndef PCI_QUIET @@ -1099,7 +1111,7 @@ pci_externalize (struct kern_devconf *kdcp, struct sysctl_req *req) pcici_t tag; int i; - tag = pcibus->pb_tag (pip->pi_bus, pip->pi_device, 0); + tag = pcibus->pb_tag (pip->pi_bus, pip->pi_device, pip->pi_func); buffer.peb_pci_info = *pip; diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h index 510a786be90b..ac1003ce91d7 100644 --- a/sys/dev/pci/pcireg.h +++ b/sys/dev/pci/pcireg.h @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: pcireg.h,v 1.5 1995/03/21 23:01:04 se Exp $ +** $Id: pcireg.h,v 1.6 1996/01/19 19:03:47 se Exp $ ** ** Names for PCI configuration space registers. ** @@ -128,6 +128,13 @@ #define PCI_SUBCLASS_BRIDGE_PCMCIA 0x00050000 #define PCI_SUBCLASS_BRIDGE_MISC 0x00800000 +/* +** Header registers +*/ +#define PCI_HEADER_MISC 0x0c + +#define PCI_HEADER_MULTIFUNCTION 0x00800000 + /* ** Mapping registers */ diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h index 50a037fe1671..d69345938a00 100644 --- a/sys/dev/pci/pcivar.h +++ b/sys/dev/pci/pcivar.h @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: pcivar.h,v 1.7 1995/11/21 12:54:55 bde Exp $ +** $Id: pcivar.h,v 1.8 1996/01/23 21:47:17 se Exp $ ** ** Declarations for pci device drivers. ** @@ -157,8 +157,10 @@ extern unsigned pci_maxdevice; */ struct pci_info { - u_short pi_bus; - u_short pi_device; + u_char pi_bus; + u_char pi_device; + u_char pi_func; + u_char pi_dummy; }; #define PCI_EXT_CONF_LEN (16) diff --git a/sys/pci/pci.c b/sys/pci/pci.c index a73d9c5cc58b..4b40b43916d9 100644 --- a/sys/pci/pci.c +++ b/sys/pci/pci.c @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: pci.c,v 1.40 1996/01/19 19:01:19 se Exp $ +** $Id: pci.c,v 1.41 1996/01/23 21:47:16 se Exp $ ** ** General subroutines for the PCI bus. ** pci_configure () @@ -374,13 +374,15 @@ pci_bus_config (void) }; #endif for (device=0; devicepcicb_seen >> device) & 1) - continue; + if ((pcicb->pcicb_seen >> device) & 1) + continue; - tag = pcibus->pb_tag (pcicb->pcicb_bus, device, 0); + for (func=0; func <= maxfunc; func++) { + tag = pcibus->pb_tag (pcicb->pcicb_bus, device, func); type = pcibus->pb_read (tag, PCI_ID_REG); if ((!type) || (type==0xfffffffful)) continue; @@ -400,6 +402,9 @@ pci_bus_config (void) /* ** check for mirrored devices. */ + if (func != 0) { + goto real_device; + } if (device & 0x10) { mtag=pcibus->pb_tag (pcicb->pcicb_bus, (u_char)(device & ~0x10), 0); @@ -425,6 +430,11 @@ pci_bus_config (void) real_device: + if (func == 0 && (pcibus->pb_read (tag, PCI_HEADER_MISC) + & PCI_HEADER_MULTIFUNCTION)) { + maxfunc = 7; + } + if (dvp==NULL) { #ifndef PCI_QUIET if (pci_conf_count) @@ -551,6 +561,7 @@ pci_bus_config (void) pdcp -> pdc_pi.pi_bus = pcicb->pcicb_bus; pdcp -> pdc_pi.pi_device = device; + pdcp -> pdc_pi.pi_func = func; pdcp -> pdc_kdc.kdc_name = dvp->pd_name; pdcp -> pdc_kdc.kdc_unit = unit; @@ -751,6 +762,7 @@ pci_bus_config (void) break; } + } } #ifndef PCI_QUIET @@ -1099,7 +1111,7 @@ pci_externalize (struct kern_devconf *kdcp, struct sysctl_req *req) pcici_t tag; int i; - tag = pcibus->pb_tag (pip->pi_bus, pip->pi_device, 0); + tag = pcibus->pb_tag (pip->pi_bus, pip->pi_device, pip->pi_func); buffer.peb_pci_info = *pip; diff --git a/sys/pci/pcireg.h b/sys/pci/pcireg.h index 510a786be90b..ac1003ce91d7 100644 --- a/sys/pci/pcireg.h +++ b/sys/pci/pcireg.h @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: pcireg.h,v 1.5 1995/03/21 23:01:04 se Exp $ +** $Id: pcireg.h,v 1.6 1996/01/19 19:03:47 se Exp $ ** ** Names for PCI configuration space registers. ** @@ -128,6 +128,13 @@ #define PCI_SUBCLASS_BRIDGE_PCMCIA 0x00050000 #define PCI_SUBCLASS_BRIDGE_MISC 0x00800000 +/* +** Header registers +*/ +#define PCI_HEADER_MISC 0x0c + +#define PCI_HEADER_MULTIFUNCTION 0x00800000 + /* ** Mapping registers */ diff --git a/sys/pci/pcivar.h b/sys/pci/pcivar.h index 50a037fe1671..d69345938a00 100644 --- a/sys/pci/pcivar.h +++ b/sys/pci/pcivar.h @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: pcivar.h,v 1.7 1995/11/21 12:54:55 bde Exp $ +** $Id: pcivar.h,v 1.8 1996/01/23 21:47:17 se Exp $ ** ** Declarations for pci device drivers. ** @@ -157,8 +157,10 @@ extern unsigned pci_maxdevice; */ struct pci_info { - u_short pi_bus; - u_short pi_device; + u_char pi_bus; + u_char pi_device; + u_char pi_func; + u_char pi_dummy; }; #define PCI_EXT_CONF_LEN (16)