Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci pcimmap: if the requested page is marked prefetc...
details: https://anonhg.NetBSD.org/src/rev/bc82415c3696
branches: trunk
changeset: 761895:bc82415c3696
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Thu Feb 10 12:37:58 2011 +0000
description:
pcimmap: if the requested page is marked prefetchable in a child device's
BAR, pass the BUS_SPACE_MAP_PREFETCHABLE flag down to bus_space_mmap
diffstat:
sys/dev/pci/pci.c | 29 +++++++++++++++++++++++++----
sys/dev/pci/pci_usrreq.c | 29 +++++++++++++++++++++++++----
sys/dev/pci/pcivar.h | 9 ++++++++-
3 files changed, 58 insertions(+), 9 deletions(-)
diffs (149 lines):
diff -r 7926e59aa0d7 -r bc82415c3696 sys/dev/pci/pci.c
--- a/sys/dev/pci/pci.c Thu Feb 10 11:35:20 2011 +0000
+++ b/sys/dev/pci/pci.c Thu Feb 10 12:37:58 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pci.c,v 1.131 2011/02/01 19:37:37 dyoung Exp $ */
+/* $NetBSD: pci.c,v 1.132 2011/02/10 12:37:58 jmcneill Exp $ */
/*
* Copyright (c) 1995, 1996, 1997, 1998
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.131 2011/02/01 19:37:37 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.132 2011/02/10 12:37:58 jmcneill Exp $");
#include "opt_pci.h"
@@ -272,8 +272,8 @@
{
pci_chipset_tag_t pc = sc->sc_pc;
struct pci_attach_args pa;
- pcireg_t id, csr, class, intr, bhlcr;
- int ret, pin, bus, device, function;
+ pcireg_t id, csr, class, intr, bhlcr, bar;
+ int ret, pin, bus, device, function, i, width;
int locs[PCICF_NLOCS];
pci_decompose_tag(pc, tag, &bus, &device, &function);
@@ -297,6 +297,27 @@
if (PCI_VENDOR(id) == 0)
return 0;
+ /* Collect memory range info */
+ memset(sc->PCI_SC_DEVICESC(device, function).c_range, 0,
+ sizeof(sc->PCI_SC_DEVICESC(device, function).c_range));
+ i = 0;
+ for (bar = PCI_MAPREG_START; bar < PCI_MAPREG_END; bar += width) {
+ int type = pci_mapreg_type(pc, tag, bar);
+ struct pci_range *r;
+
+ width = 4;
+ if (PCI_MAPREG_TYPE(type) == PCI_MAPREG_TYPE_MEM) {
+ if (PCI_MAPREG_MEM_TYPE(type) ==
+ PCI_MAPREG_MEM_TYPE_64BIT)
+ width = 8;
+
+ r = &sc->PCI_SC_DEVICESC(device, function).c_range[i++];
+ if (pci_mapreg_info(pc, tag, bar, type,
+ &r->r_offset, &r->r_size, &r->r_flags) != 0)
+ break;
+ }
+ }
+
pa.pa_iot = sc->sc_iot;
pa.pa_memt = sc->sc_memt;
pa.pa_dmat = sc->sc_dmat;
diff -r 7926e59aa0d7 -r bc82415c3696 sys/dev/pci/pci_usrreq.c
--- a/sys/dev/pci/pci_usrreq.c Thu Feb 10 11:35:20 2011 +0000
+++ b/sys/dev/pci/pci_usrreq.c Thu Feb 10 12:37:58 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_usrreq.c,v 1.22 2009/07/30 04:38:24 macallan Exp $ */
+/* $NetBSD: pci_usrreq.c,v 1.23 2011/02/10 12:37:58 jmcneill Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_usrreq.c,v 1.22 2009/07/30 04:38:24 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_usrreq.c,v 1.23 2011/02/10 12:37:58 jmcneill Exp $");
#include <sys/param.h>
#include <sys/conf.h>
@@ -114,6 +114,10 @@
pcimmap(dev_t dev, off_t offset, int prot)
{
struct pci_softc *sc = device_lookup_private(&pci_cd, minor(dev));
+ struct pci_child *c;
+ struct pci_range *r;
+ int flags = 0;
+ int device, range;
if (kauth_authorize_generic(kauth_cred_get(), KAUTH_GENERIC_ISSUSER,
NULL) != 0) {
@@ -124,7 +128,7 @@
* take the offset to be the address on the bus,
* and pass 0 as the offset into that range.
*
- * XXX Need a way to deal with linear/prefetchable/etc.
+ * XXX Need a way to deal with linear/etc.
*
* XXX we rely on MD mmap() methods to enforce limits since these
* are hidden in *_tag_t structs if they exist at all
@@ -145,7 +149,24 @@
0, prot, 0);
}
#endif /* PCI_MAGIC_IO_RANGE */
- return bus_space_mmap(sc->sc_memt, offset, 0, prot, 0);
+
+ for (device = 0; device < __arraycount(sc->sc_devices); device++) {
+ c = &sc->sc_devices[device];
+ if (c->c_dev == NULL)
+ continue;
+ for (range = 0; range < __arraycount(c->c_range); range++) {
+ r = &c->c_range[range];
+ if (r->r_size == 0)
+ break;
+ if (offset >= r->r_offset &&
+ offset < r->r_offset + r->r_size) {
+ flags = r->r_flags;
+ break;
+ }
+ }
+ }
+
+ return bus_space_mmap(sc->sc_memt, offset, 0, prot, flags);
}
const struct cdevsw pci_cdevsw = {
diff -r 7926e59aa0d7 -r bc82415c3696 sys/dev/pci/pcivar.h
--- a/sys/dev/pci/pcivar.h Thu Feb 10 11:35:20 2011 +0000
+++ b/sys/dev/pci/pcivar.h Thu Feb 10 12:37:58 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pcivar.h,v 1.90 2010/06/09 02:39:32 mrg Exp $ */
+/* $NetBSD: pcivar.h,v 1.91 2011/02/10 12:37:58 jmcneill Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@@ -196,11 +196,18 @@
pcireg_t reg[16];
};
+struct pci_range {
+ bus_addr_t r_offset;
+ bus_size_t r_size;
+ int r_flags;
+};
+
struct pci_child {
device_t c_dev;
bool c_psok;
pcireg_t c_powerstate;
struct pci_conf_state c_conf;
+ struct pci_range c_range[8];
};
struct pci_softc {
Home |
Main Index |
Thread Index |
Old Index