diff options
author | se <se@FreeBSD.org> | 1996-01-25 18:32:00 +0000 |
---|---|---|
committer | se <se@FreeBSD.org> | 1996-01-25 18:32:00 +0000 |
commit | 45ff9914bfc89e0757878212fbbb1e87613296bd (patch) | |
tree | 95fee05d62f13f992eed38926cf5e30dd2455034 /sys/dev/pci | |
parent | e764e499b9a4965e34b21e574fa9266b8e3bf4f5 (diff) | |
download | FreeBSD-src-45ff9914bfc89e0757878212fbbb1e87613296bd.zip FreeBSD-src-45ff9914bfc89e0757878212fbbb1e87613296bd.tar.gz |
Add support for multi-function devices.
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/pci.c | 26 | ||||
-rw-r--r-- | sys/dev/pci/pcireg.h | 9 | ||||
-rw-r--r-- | sys/dev/pci/pcivar.h | 8 |
3 files changed, 32 insertions, 11 deletions
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index a73d9c5..4b40b43 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; device<pci_maxdevice; device ++) { - char *name = NULL; - struct pci_device **dvpp; + char *name = NULL; + struct pci_device **dvpp; + int func, maxfunc = 0; - if ((pcicb->pcicb_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 510a786..ac1003c 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. ** @@ -129,6 +129,13 @@ #define PCI_SUBCLASS_BRIDGE_MISC 0x00800000 /* +** Header registers +*/ +#define PCI_HEADER_MISC 0x0c + +#define PCI_HEADER_MULTIFUNCTION 0x00800000 + +/* ** Mapping registers */ #define PCI_MAP_REG_START 0x10 diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h index 50a037f..d693459 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) |