[BACK]Return to upa.c CVS log [TXT][DIR] Up to [local] / sys / arch / sparc64 / dev

Annotation of sys/arch/sparc64/dev/upa.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: upa.c,v 1.5 2007/03/05 18:58:30 kettenis Exp $        */
                      2:
                      3: /*
                      4:  * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  *
                     16:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     17:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     18:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     19:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     20:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     21:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     22:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     23:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     24:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     25:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     26:  * POSSIBILITY OF SUCH DAMAGE.
                     27:  *
                     28:  * Effort sponsored in part by the Defense Advanced Research Projects
                     29:  * Agency (DARPA) and Air Force Research Laboratory, Air Force
                     30:  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
                     31:  *
                     32:  */
                     33:
                     34: #include <sys/types.h>
                     35: #include <sys/param.h>
                     36: #include <sys/systm.h>
                     37: #include <sys/kernel.h>
                     38: #include <sys/device.h>
                     39: #include <sys/conf.h>
                     40: #include <sys/timeout.h>
                     41: #include <sys/malloc.h>
                     42:
                     43: #define _SPARC_BUS_DMA_PRIVATE
                     44: #include <machine/bus.h>
                     45: #include <machine/autoconf.h>
                     46: #include <machine/openfirm.h>
                     47:
                     48: #include <sparc64/dev/ebusreg.h>
                     49: #include <sparc64/dev/ebusvar.h>
                     50:
                     51: #include "pckbd.h"
                     52: #if NPCKBD > 0
                     53: #include <dev/ic/pckbcvar.h>
                     54: #include <dev/pckbc/pckbdvar.h>
                     55: #endif
                     56:
                     57: struct upa_range {
                     58:        u_int64_t       ur_space;
                     59:        u_int64_t       ur_addr;
                     60:        u_int64_t       ur_len;
                     61: };
                     62:
                     63: struct upa_softc {
                     64:        struct device           sc_dev;
                     65:        bus_space_tag_t         sc_bt;
                     66:        bus_space_handle_t      sc_reg[3];
                     67:        struct upa_range        *sc_range;
                     68:        int                     sc_node;
                     69:        int                     sc_nrange;
                     70:        bus_space_tag_t         sc_cbt;
                     71: };
                     72:
                     73: int    upa_match(struct device *, void *, void *);
                     74: void   upa_attach(struct device *, struct device *, void *);
                     75:
                     76: struct cfattach upa_ca = {
                     77:        sizeof(struct upa_softc), upa_match, upa_attach
                     78: };
                     79:
                     80: struct cfdriver upa_cd = {
                     81:        NULL, "upa", DV_DULL
                     82: };
                     83:
                     84: int upa_print(void *, const char *);
                     85: bus_space_tag_t upa_alloc_bus_tag(struct upa_softc *);
                     86: int upa_bus_map(bus_space_tag_t, bus_space_tag_t, bus_addr_t,
                     87:     bus_size_t, int, bus_space_handle_t *);
                     88: paddr_t upa_bus_mmap(bus_space_tag_t, bus_space_tag_t,
                     89:     bus_addr_t, off_t, int, int);
                     90:
                     91: int
                     92: upa_match(struct device *parent, void *match, void *aux)
                     93: {
                     94:        struct mainbus_attach_args *ma = aux;
                     95:
                     96:        if (strcmp(ma->ma_name, "upa") == 0)
                     97:                return (1);
                     98:        return (0);
                     99: }
                    100:
                    101: void
                    102: upa_attach(struct device *parent, struct device *self, void *aux)
                    103: {
                    104:        struct upa_softc *sc = (void *)self;
                    105:        struct mainbus_attach_args *ma = aux;
                    106:        int i, node;
                    107:
                    108:        sc->sc_bt = ma->ma_bustag;
                    109:        sc->sc_node = ma->ma_node;
                    110:
                    111:        for (i = 0; i < 3; i++) {
                    112:                if (i >= ma->ma_nreg) {
                    113:                        printf(": no register %d\n", i);
                    114:                        return;
                    115:                }
                    116:                if (bus_space_map(sc->sc_bt, ma->ma_reg[i].ur_paddr,
                    117:                    ma->ma_reg[i].ur_len, 0, &sc->sc_reg[i])) {
                    118:                        printf(": failed to map reg%d\n", i);
                    119:                        return;
                    120:                }
                    121:        }
                    122:
                    123:        if (getprop(sc->sc_node, "ranges", sizeof(struct upa_range),
                    124:            &sc->sc_nrange, (void **)&sc->sc_range))
                    125:                panic("upa: can't get ranges");
                    126:
                    127:        printf("\n");
                    128:
                    129:        sc->sc_cbt = upa_alloc_bus_tag(sc);
                    130:
                    131:        for (node = OF_child(sc->sc_node); node; node = OF_peer(node)) {
                    132:                char buf[32];
                    133:                struct mainbus_attach_args map;
                    134:
                    135:                bzero(&map, sizeof(map));
                    136:                if (OF_getprop(node, "device_type", buf, sizeof(buf)) <= 0)
                    137:                        continue;
                    138:                if (getprop(node, "reg", sizeof(*map.ma_reg),
                    139:                    &map.ma_nreg, (void **)&map.ma_reg) != 0)
                    140:                        continue;
                    141:                if (OF_getprop(node, "name", buf, sizeof(buf)) <= 0)
                    142:                        continue;
                    143:                map.ma_node = node;
                    144:                map.ma_name = buf;
                    145:                map.ma_bustag = sc->sc_cbt;
                    146:                map.ma_dmatag = ma->ma_dmatag;
                    147:                config_found(&sc->sc_dev, &map, upa_print);
                    148:        }
                    149: }
                    150:
                    151: int
                    152: upa_print(void *args, const char *name)
                    153: {
                    154:        struct mainbus_attach_args *ma = args;
                    155:
                    156:        if (name)
                    157:                printf("%s at %s", ma->ma_name, name);
                    158:        return (UNCONF);
                    159: }
                    160:
                    161: bus_space_tag_t
                    162: upa_alloc_bus_tag(struct upa_softc *sc)
                    163: {
                    164:        struct sparc_bus_space_tag *bt;
                    165:
                    166:        bt = malloc(sizeof(*bt), M_DEVBUF, M_NOWAIT);
                    167:        if (bt == NULL)
                    168:                panic("upa: couldn't alloc bus tag");
                    169:
                    170:        bzero(bt, sizeof *bt);
                    171:        snprintf(bt->name, sizeof(bt->name), "%s",
                    172:                        sc->sc_dev.dv_xname);
                    173:        bt->cookie = sc;
                    174:        bt->parent = sc->sc_bt;
                    175:        bt->asi = bt->parent->asi;
                    176:        bt->sasi = bt->parent->sasi;
                    177:        bt->sparc_bus_map = upa_bus_map;
                    178:        bt->sparc_bus_mmap = upa_bus_mmap;
                    179:        /* XXX bt->sparc_intr_establish = upa_intr_establish; */
                    180:        return (bt);
                    181: }
                    182:
                    183: int
                    184: upa_bus_map(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t offset,
                    185:     bus_size_t size, int flags, bus_space_handle_t *hp)
                    186: {
                    187:        struct upa_softc *sc = t->cookie;
                    188:        int i;
                    189:
                    190:        if (t->parent == 0 || t->parent->sparc_bus_map == 0) {
                    191:                printf("\n__upa_bus_map: invalid parent");
                    192:                return (EINVAL);
                    193:        }
                    194:
                    195:        t = t->parent;
                    196:
                    197:         if (flags & BUS_SPACE_MAP_PROMADDRESS) {
                    198:                return ((*t->sparc_bus_map)
                    199:                    (t, t0, offset, size, flags, hp));
                    200:        }
                    201:
                    202:        for (i = 0; i < sc->sc_nrange; i++) {
                    203:                if (offset < sc->sc_range[i].ur_space)
                    204:                        continue;
                    205:                if (offset >= (sc->sc_range[i].ur_space +
                    206:                    sc->sc_range[i].ur_space))
                    207:                        continue;
                    208:                break;
                    209:        }
                    210:        if (i == sc->sc_nrange)
                    211:                return (EINVAL);
                    212:
                    213:        offset -= sc->sc_range[i].ur_space;
                    214:        offset += sc->sc_range[i].ur_addr;
                    215:
                    216:        return ((*t->sparc_bus_map)(t, t0, offset, size, flags, hp));
                    217: }
                    218:
                    219: paddr_t
                    220: upa_bus_mmap(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t paddr,
                    221:     off_t off, int prot, int flags)
                    222: {
                    223:        struct upa_softc *sc = t->cookie;
                    224:        int i;
                    225:
                    226:        if (t->parent == 0 || t->parent->sparc_bus_map == 0) {
                    227:                printf("\n__upa_bus_map: invalid parent");
                    228:                return (EINVAL);
                    229:        }
                    230:
                    231:        t = t->parent;
                    232:
                    233:         if (flags & BUS_SPACE_MAP_PROMADDRESS)
                    234:                return ((*t->sparc_bus_mmap)(t, t0, paddr, off, prot, flags));
                    235:
                    236:        for (i = 0; i < sc->sc_nrange; i++) {
                    237:                if (paddr + off < sc->sc_range[i].ur_space)
                    238:                        continue;
                    239:                if (paddr + off >= (sc->sc_range[i].ur_space +
                    240:                    sc->sc_range[i].ur_space))
                    241:                        continue;
                    242:                break;
                    243:        }
                    244:        if (i == sc->sc_nrange)
                    245:                return (EINVAL);
                    246:
                    247:        paddr -= sc->sc_range[i].ur_space;
                    248:        paddr += sc->sc_range[i].ur_addr;
                    249:
                    250:        return ((*t->sparc_bus_mmap)(t, t0, paddr, off, prot, flags));
                    251: }

CVSweb