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