summaryrefslogtreecommitdiffstats
path: root/sys/pci
diff options
context:
space:
mode:
authorse <se@FreeBSD.org>1996-01-25 18:32:00 +0000
committerse <se@FreeBSD.org>1996-01-25 18:32:00 +0000
commit45ff9914bfc89e0757878212fbbb1e87613296bd (patch)
tree95fee05d62f13f992eed38926cf5e30dd2455034 /sys/pci
parente764e499b9a4965e34b21e574fa9266b8e3bf4f5 (diff)
downloadFreeBSD-src-45ff9914bfc89e0757878212fbbb1e87613296bd.zip
FreeBSD-src-45ff9914bfc89e0757878212fbbb1e87613296bd.tar.gz
Add support for multi-function devices.
Diffstat (limited to 'sys/pci')
-rw-r--r--sys/pci/pci.c26
-rw-r--r--sys/pci/pcireg.h9
-rw-r--r--sys/pci/pcivar.h8
3 files changed, 32 insertions, 11 deletions
diff --git a/sys/pci/pci.c b/sys/pci/pci.c
index a73d9c5..4b40b43 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; 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/pci/pcireg.h b/sys/pci/pcireg.h
index 510a786..ac1003c 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.
**
@@ -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/pci/pcivar.h b/sys/pci/pcivar.h
index 50a037f..d693459 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)
OpenPOWER on IntegriCloud