summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2006-04-07 01:04:50 +0000
committerBrad Smith <brad@cvs.openbsd.org>2006-04-07 01:04:50 +0000
commit2b1cfc3386b297ab81942c33c83f0d3e7793efaa (patch)
tree4cc7fd2eed058f0aeb943e8f05f2f2059e792210 /sys
parentda675f40fefca37deefd78b185bf8d371de83a7a (diff)
implement a check whether a BAR is present at all at a given
configuration space address, pci_mapreg_probe(). From NetBSD ok dlg@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/pci_map.c35
-rw-r--r--sys/dev/pci/pcivar.h3
2 files changed, 29 insertions, 9 deletions
diff --git a/sys/dev/pci/pci_map.c b/sys/dev/pci/pci_map.c
index 06f9136f202..92c73b14ceb 100644
--- a/sys/dev/pci/pci_map.c
+++ b/sys/dev/pci/pci_map.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci_map.c,v 1.13 2006/03/19 22:28:40 brad Exp $ */
+/* $OpenBSD: pci_map.c,v 1.14 2006/04/07 01:04:49 brad Exp $ */
/* $NetBSD: pci_map.c,v 1.7 2000/05/10 16:58:42 thorpej Exp $ */
/*-
@@ -236,17 +236,36 @@ pci_mem_find(pci_chipset_tag_t pc, pcitag_t pcitag, int reg,
cacheablep));
}
+#define _PCI_MAPREG_TYPEBITS(reg) \
+ (PCI_MAPREG_TYPE(reg) == PCI_MAPREG_TYPE_IO ? \
+ reg & PCI_MAPREG_TYPE_MASK : \
+ reg & (PCI_MAPREG_TYPE_MASK|PCI_MAPREG_MEM_TYPE_MASK))
+
pcireg_t
pci_mapreg_type(pci_chipset_tag_t pc, pcitag_t tag, int reg)
{
- pcireg_t rv;
+ return (_PCI_MAPREG_TYPEBITS(pci_conf_read(pc, tag, reg)));
+}
- rv = pci_conf_read(pc, tag, reg);
- if (PCI_MAPREG_TYPE(rv) == PCI_MAPREG_TYPE_IO)
- rv &= PCI_MAPREG_TYPE_MASK;
- else
- rv &= PCI_MAPREG_TYPE_MASK|PCI_MAPREG_MEM_TYPE_MASK;
- return (rv);
+int
+pci_mapreg_probe(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t *typep)
+{
+ pcireg_t address, mask;
+ int s;
+
+ s = splhigh();
+ address = pci_conf_read(pc, tag, reg);
+ pci_conf_write(pc, tag, reg, 0xffffffff);
+ mask = pci_conf_read(pc, tag, reg);
+ pci_conf_write(pc, tag, reg, address);
+ splx(s);
+
+ if (mask == 0) /* unimplemented mapping register */
+ return (0);
+
+ if (typep)
+ *typep = _PCI_MAPREG_TYPEBITS(address);
+ return (1);
}
int
diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h
index cabf04e4946..f2e3f4fc25b 100644
--- a/sys/dev/pci/pcivar.h
+++ b/sys/dev/pci/pcivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcivar.h,v 1.47 2006/03/22 00:36:03 jsg Exp $ */
+/* $OpenBSD: pcivar.h,v 1.48 2006/04/07 01:04:49 brad Exp $ */
/* $NetBSD: pcivar.h,v 1.23 1997/06/06 23:48:05 thorpej Exp $ */
/*
@@ -182,6 +182,7 @@ struct pci_softc {
* Configuration space access and utility functions. (Note that most,
* e.g. make_tag, conf_read, conf_write are declared by pci_machdep.h.)
*/
+int pci_mapreg_probe(pci_chipset_tag_t, pcitag_t, int, pcireg_t *);
pcireg_t pci_mapreg_type(pci_chipset_tag_t, pcitag_t, int);
int pci_mapreg_info(pci_chipset_tag_t, pcitag_t, int, pcireg_t,
bus_addr_t *, bus_size_t *, int *);