Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144312202
D43690.id134054.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D43690.id134054.diff
View Options
diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c
--- a/sys/dev/pci/pci_pci.c
+++ b/sys/dev/pci/pci_pci.c
@@ -66,6 +66,10 @@
#ifdef NEW_PCIB
static bus_adjust_resource_t pcib_adjust_resource;
static bus_release_resource_t pcib_release_resource;
+static bus_activate_resource_t pcib_activate_resource;
+static bus_deactivate_resource_t pcib_deactivate_resource;
+static bus_map_resource_t pcib_map_resource;
+static bus_unmap_resource_t pcib_unmap_resource;
#endif
static int pcib_reset_child(device_t dev, device_t child, int flags);
@@ -108,12 +112,16 @@
#ifdef NEW_PCIB
DEVMETHOD(bus_adjust_resource, pcib_adjust_resource),
DEVMETHOD(bus_release_resource, pcib_release_resource),
+ DEVMETHOD(bus_activate_resource, pcib_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, pcib_deactivate_resource),
+ DEVMETHOD(bus_map_resource, pcib_map_resource),
+ DEVMETHOD(bus_unmap_resource, pcib_unmap_resource),
#else
DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource),
DEVMETHOD(bus_release_resource, bus_generic_release_resource),
-#endif
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+#endif
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
DEVMETHOD(bus_reset_child, pcib_reset_child),
@@ -381,7 +389,7 @@
device_printf(as->sc->dev,
"allocating non-ISA range %#jx-%#jx\n", start, end);
as->res[as->count] = bus_alloc_resource(as->sc->dev, SYS_RES_IOPORT,
- &rid, start, end, end - start + 1, 0);
+ &rid, start, end, end - start + 1, RF_ACTIVE | RF_UNMAPPED);
if (as->res[as->count] == NULL)
as->error = ENXIO;
else
@@ -454,7 +462,7 @@
else {
rid = w->reg;
res = bus_alloc_resource(sc->dev, type, &rid, w->base, w->limit,
- w->limit - w->base + 1, flags);
+ w->limit - w->base + 1, flags | RF_ACTIVE | RF_UNMAPPED);
if (res != NULL)
pcib_add_window_resources(w, &res, 1);
}
@@ -2001,7 +2009,7 @@
count = roundup2(count, (rman_res_t)1 << w->step);
rid = w->reg;
res = bus_alloc_resource(sc->dev, type, &rid, start, end, count,
- flags & ~RF_ACTIVE);
+ flags | RF_ACTIVE | RF_UNMAPPED);
if (res == NULL)
return (ENOSPC);
pcib_add_window_resources(w, &res, 1);
@@ -2452,6 +2460,120 @@
}
return (bus_generic_release_resource(dev, child, type, rid, r));
}
+
+static int
+pcib_activate_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *r)
+{
+ struct pcib_softc *sc = device_get_softc(dev);
+ struct resource_map map;
+ int error;
+
+ if (!pcib_is_resource_managed(sc, type, r))
+ return (bus_generic_activate_resource(dev, child, type, rid,
+ r));
+
+ error = rman_activate_resource(r);
+ if (error != 0)
+ return (error);
+
+ if ((rman_get_flags(r) & RF_UNMAPPED) == 0 &&
+ (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT)) {
+ error = BUS_MAP_RESOURCE(dev, child, type, r, NULL, &map);
+ if (error != 0) {
+ rman_deactivate_resource(r);
+ return (error);
+ }
+
+ rman_set_mapping(r, &map);
+ }
+ return (0);
+}
+
+static int
+pcib_deactivate_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *r)
+{
+ struct pcib_softc *sc = device_get_softc(dev);
+ struct resource_map map;
+ int error;
+
+ if (!pcib_is_resource_managed(sc, type, r))
+ return (bus_generic_deactivate_resource(dev, child, type, rid,
+ r));
+
+ error = rman_deactivate_resource(r);
+ if (error != 0)
+ return (error);
+
+ if ((rman_get_flags(r) & RF_UNMAPPED) == 0 &&
+ (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT)) {
+ rman_get_mapping(r, &map);
+ BUS_UNMAP_RESOURCE(dev, child, type, r, &map);
+ }
+ return (0);
+}
+
+static struct resource *
+pcib_find_parent_resource(struct pcib_window *w, struct resource *r)
+{
+ for (int i = 0; i < w->count; i++) {
+ if (rman_get_start(w->res[i]) <= rman_get_start(r) &&
+ rman_get_end(w->res[i]) >= rman_get_end(r))
+ return (w->res[i]);
+ }
+ return (NULL);
+}
+
+static int
+pcib_map_resource(device_t dev, device_t child, int type, struct resource *r,
+ struct resource_map_request *argsp, struct resource_map *map)
+{
+ struct pcib_softc *sc = device_get_softc(dev);
+ struct resource_map_request args;
+ struct pcib_window *w;
+ struct resource *pres;
+ rman_res_t length, start;
+ int error;
+
+ w = pcib_get_resource_window(sc, type, r);
+ if (w == NULL)
+ return (bus_generic_map_resource(dev, child, type, r, argsp,
+ map));
+
+ /* Resources must be active to be mapped. */
+ if (!(rman_get_flags(r) & RF_ACTIVE))
+ return (ENXIO);
+
+ resource_init_map_request(&args);
+ error = resource_validate_map_request(r, argsp, &args, &start, &length);
+ if (error)
+ return (error);
+
+ pres = pcib_find_parent_resource(w, r);
+ if (pres == NULL)
+ return (ENOENT);
+
+ args.offset = start - rman_get_start(pres);
+ args.length = length;
+ return (bus_generic_map_resource(dev, child, type, pres, &args, map));
+}
+
+static int
+pcib_unmap_resource(device_t dev, device_t child, int type, struct resource *r,
+ struct resource_map *map)
+{
+ struct pcib_softc *sc = device_get_softc(dev);
+ struct pcib_window *w;
+
+ w = pcib_get_resource_window(sc, type, r);
+ if (w != NULL) {
+ r = pcib_find_parent_resource(w, r);
+ if (r == NULL)
+ return (ENOENT);
+ }
+ return (bus_generic_unmap_resource(dev, child, type, r, map));
+}
#else
/*
* We have to trap resource allocation requests and ensure that the bridge
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Feb 8, 7:15 PM (3 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28487469
Default Alt Text
D43690.id134054.diff (5 KB)
Attached To
Mode
D43690: pcib: Refine handling of resources allocated from bridge windows
Attached
Detach File
Event Timeline
Log In to Comment