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
This commit is contained in:
parent
b94121255b
commit
61ccff524d
|
@ -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_probe_device(struct pci_softc *sc, pcitag_t tag,
|
|||
{
|
||||
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 @@ pci_probe_device(struct pci_softc *sc, pcitag_t tag,
|
|||
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;
|
||||
|
|
|
@ -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 @@ static paddr_t
|
|||
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 @@ pcimmap(dev_t dev, off_t offset, int prot)
|
|||
* 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 @@ pcimmap(dev_t dev, off_t offset, int prot)
|
|||
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 = {
|
||||
|
|
|
@ -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 @@ struct pci_conf_state {
|
|||
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 {
|
||||
|
|
Loading…
Reference in New Issue