summaryrefslogtreecommitdiffstats
path: root/sys/sparc64/sbus
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2006-06-08 21:02:25 +0000
committermarius <marius@FreeBSD.org>2006-06-08 21:02:25 +0000
commit840beae2395e64eb67a29e868f92da67f15685a7 (patch)
treebec9f3707275567a5befb819ce1c5a81ec48d38f /sys/sparc64/sbus
parentbe9a53a8edfc5be19a43b6766ddec3bb42b86506 (diff)
downloadFreeBSD-src-840beae2395e64eb67a29e868f92da67f15685a7.zip
FreeBSD-src-840beae2395e64eb67a29e868f92da67f15685a7.tar.gz
- Merge sys/sparc64/pci/psycho.c rev. 1.8:
Map the device memory belonging to resources of type SYS_RES_MEMORY into KVA upon activation so that rman_get_virtual() works as expected. - In sbus_alloc_resource() checking whether toffs is 0 as an indication that no applicable child range was found isn't appropriate as it's perfectly valid for the requested SYS_RES_MEMORY resource to start at the beginning of a child range. So check for the RMAN still being NULL instead. - As a minor runtime speed optimization break out of the loop where we search for the applicable child range in sbus_alloc_resource() as soon as it's found. - Let sbus_setup_intr() return ENOMEM rather than 0 if it can't allocate memory for the interrupt clearing info. - Actually do what the comment in sbus_setup_intr() says and disable the respective interrupt while fiddling with it. - Remove some superfluous INTVEC() around inr, which already only contains the interrupt vector, in sbus_setup_intr(). - While here, fix a style(9) bug in sbus_setup_intr() (don't use function calls in initializers). The first two changes are required for a CG6 driver. MFC after: 2 weeks
Diffstat (limited to 'sys/sparc64/sbus')
-rw-r--r--sys/sparc64/sbus/sbus.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/sys/sparc64/sbus/sbus.c b/sys/sparc64/sbus/sbus.c
index 3f5469c..4fc45d9 100644
--- a/sys/sparc64/sbus/sbus.c
+++ b/sys/sparc64/sbus/sbus.c
@@ -655,14 +655,15 @@ sbus_setup_intr(device_t dev, device_t child, struct resource *ires, int flags,
u_int64_t intrmap;
u_int32_t inr, slot;
int error, i;
- long vec = rman_get_start(ires);
+ long vec;
sc = device_get_softc(dev);
scl = (struct sbus_clr *)malloc(sizeof(*scl), M_DEVBUF, M_NOWAIT);
if (scl == NULL)
- return (0);
+ return (ENOMEM);
intrptr = intrmapptr = intrclrptr = 0;
intrmap = 0;
+ vec = rman_get_start(ires);
inr = INTVEC(vec);
if ((inr & INTMAP_OBIO_MASK) == 0) {
/*
@@ -680,10 +681,10 @@ sbus_setup_intr(device_t dev, device_t child, struct resource *ires, int flags,
/* Insert IGN */
inr |= sc->sc_ign << INTMAP_IGN_SHIFT;
for (i = 0; intrptr <= SBR_RESERVED_INT_MAP &&
- INTVEC(intrmap = SYSIO_READ8(sc, intrptr)) !=
- INTVEC(inr); intrptr += 8, i++)
+ INTVEC(intrmap = SYSIO_READ8(sc, intrptr)) != inr;
+ intrptr += 8, i++)
;
- if (INTVEC(intrmap) == INTVEC(inr)) {
+ if (INTVEC(intrmap) == inr) {
/* Register the map and clear intr registers */
intrmapptr = intrptr;
intrclrptr = SBR_SCSI_INT_CLR + i * 8;
@@ -697,7 +698,7 @@ sbus_setup_intr(device_t dev, device_t child, struct resource *ires, int flags,
scl->scl_handler = intr;
scl->scl_clr = intrclrptr;
/* Disable the interrupt while we fiddle with it */
- SYSIO_WRITE8(sc, intrmapptr, intrmap);
+ SYSIO_WRITE8(sc, intrmapptr, intrmap & ~INTMAP_V);
error = BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
sbus_intr_stub, scl, cookiep);
if (error != 0) {
@@ -797,8 +798,9 @@ sbus_alloc_resource(device_t bus, device_t child, int type, int *rid,
tend = end - sc->sc_rd[i].rd_coffset;
rm = &sc->sc_rd[i].rd_rman;
bh = sc->sc_rd[i].rd_bushandle;
+ break;
}
- if (toffs == 0L)
+ if (rm == NULL)
return (NULL);
flags &= ~RF_ACTIVE;
rv = rman_reserve_resource(rm, toffs, tend, count, flags,
@@ -826,11 +828,24 @@ static int
sbus_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
+ void *p;
+ int error;
if (type == SYS_RES_IRQ) {
return (BUS_ACTIVATE_RESOURCE(device_get_parent(bus),
child, type, rid, r));
}
+ if (type == SYS_RES_MEMORY) {
+ /*
+ * Need to memory-map the device space, as some drivers depend
+ * on the virtual address being set and useable.
+ */
+ error = sparc64_bus_mem_map(rman_get_bustag(r),
+ rman_get_bushandle(r), rman_get_size(r), 0, 0, &p);
+ if (error != 0)
+ return (error);
+ rman_set_virtual(r, p);
+ }
return (rman_activate_resource(r));
}
@@ -843,6 +858,10 @@ sbus_deactivate_resource(device_t bus, device_t child, int type, int rid,
return (BUS_DEACTIVATE_RESOURCE(device_get_parent(bus),
child, type, rid, r));
}
+ if (type == SYS_RES_MEMORY) {
+ sparc64_bus_mem_unmap(rman_get_virtual(r), rman_get_size(r));
+ rman_set_virtual(r, NULL);
+ }
return (rman_deactivate_resource(r));
}
OpenPOWER on IntegriCloud