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

Annotation of sys/arch/macppc/dev/mediabay.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: mediabay.c,v 1.3 2006/06/19 22:42:33 miod Exp $       */
                      2: /*     $NetBSD: mediabay.c,v 1.9 2003/07/15 02:43:29 lukem Exp $       */
                      3:
                      4: /*-
                      5:  * Copyright (C) 1999 Tsubai Masanari.  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:  * 3. The name of the author may not be used to endorse or promote products
                     16:  *    derived from this software without specific prior written permission.
                     17:  *
                     18:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     19:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     20:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     21:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     22:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     23:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     24:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     25:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     26:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
                     27:  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     28:  */
                     29:
                     30: #include <sys/cdefs.h>
                     31:
                     32: #include <sys/param.h>
                     33: #include <sys/device.h>
                     34: #include <sys/kernel.h>
                     35: #include <sys/kthread.h>
                     36: #include <sys/systm.h>
                     37:
                     38: #include <uvm/uvm_extern.h>
                     39:
                     40: #include <dev/ofw/openfirm.h>
                     41:
                     42: #include <machine/autoconf.h>
                     43: #include <machine/pio.h>
                     44:
                     45: struct mediabay_softc {
                     46:        struct device sc_dev;
                     47:        int sc_node;
                     48:        u_int *sc_addr;
                     49:        u_int *sc_fcr;
                     50:        u_int sc_baseaddr;
                     51:        bus_space_tag_t sc_iot;
                     52:        bus_dma_tag_t sc_dmat;
                     53:        struct device *sc_content;
                     54:        struct proc *sc_kthread;
                     55: };
                     56:
                     57: void mediabay_attach(struct device *, struct device *, void *);
                     58: int mediabay_match(struct device *, void *, void *);
                     59: int mediabay_print(void *, const char *);
                     60: void mediabay_attach_content(struct mediabay_softc *);
                     61: int mediabay_intr(void *);
                     62: void mediabay_create_kthread(void *);
                     63: void mediabay_kthread(void *);
                     64:
                     65: struct cfattach mediabay_ca = {
                     66:        sizeof(struct mediabay_softc), mediabay_match, mediabay_attach
                     67: };
                     68: struct cfdriver mediabay_cd = {
                     69:        NULL, "mediabay", DV_DULL
                     70: };
                     71:
                     72:
                     73: #ifdef MEDIABAY_DEBUG
                     74: # define DPRINTF printf
                     75: #else
                     76: # define DPRINTF while (0) printf
                     77: #endif
                     78:
                     79: #define FCR_MEDIABAY_RESET     0x00000002
                     80: #define FCR_MEDIABAY_IDE_ENABLE        0x00000008
                     81: #define FCR_MEDIABAY_FD_ENABLE 0x00000010
                     82: #define FCR_MEDIABAY_ENABLE    0x00000080
                     83: #define FCR_MEDIABAY_CD_POWER  0x00800000
                     84:
                     85: #define MEDIABAY_ID(x)         (((x) >> 12) & 0xf)
                     86: #define MEDIABAY_ID_FD         0
                     87: #define MEDIABAY_ID_CD         3
                     88: #define MEDIABAY_ID_NONE       7
                     89:
                     90: int
                     91: mediabay_match(parent, v, aux)
                     92:        struct device *parent;
                     93:        void *v;
                     94:        void *aux;
                     95: {
                     96:        struct confargs *ca = aux;
                     97:
                     98:        if (strcmp(ca->ca_name, "media-bay") == 0 &&
                     99:            ca->ca_nintr >= 4 && ca->ca_nreg >= 8)
                    100:                return 1;
                    101:
                    102:        return 0;
                    103: }
                    104:
                    105: /*
                    106:  * Attach all the sub-devices we can find
                    107:  */
                    108: void
                    109: mediabay_attach(parent, self, aux)
                    110:        struct device *parent, *self;
                    111:        void *aux;
                    112: {
                    113:        struct mediabay_softc *sc = (struct mediabay_softc *)self;
                    114:        struct confargs *ca = aux;
                    115:        int irq, type;
                    116:
                    117:        ca->ca_reg[0] += ca->ca_baseaddr;
                    118:
                    119:        sc->sc_addr = mapiodev(ca->ca_reg[0], PAGE_SIZE);
                    120:        sc->sc_fcr = sc->sc_addr + 1;
                    121:        sc->sc_node = ca->ca_node;
                    122:        sc->sc_baseaddr = ca->ca_baseaddr;
                    123:        sc->sc_iot = ca->ca_iot;
                    124:        sc->sc_dmat = ca->ca_dmat;
                    125:        irq = ca->ca_intr[0];
                    126:        type = IST_LEVEL;
                    127:
                    128:        if (ca->ca_nintr == 8 && ca->ca_intr[1] == 0)
                    129:                type = IST_EDGE;
                    130:
                    131:        printf(" irq %d\n", irq);
                    132:        mac_intr_establish(parent, irq, type, IPL_BIO, mediabay_intr, sc,
                    133:            "mediabay");
                    134:
                    135:        kthread_create_deferred(mediabay_create_kthread, sc);
                    136:
                    137:        sc->sc_content = NULL;
                    138:
                    139:        if (MEDIABAY_ID(in32rb(sc->sc_addr)) != MEDIABAY_ID_NONE)
                    140:                mediabay_attach_content(sc);
                    141: }
                    142:
                    143: void
                    144: mediabay_attach_content(sc)
                    145:        struct mediabay_softc *sc;
                    146: {
                    147:        int child;
                    148:        u_int fcr;
                    149:        struct device *content;
                    150:        struct confargs ca;
                    151:        u_int reg[20], intr[5];
                    152:        char name[32];
                    153:
                    154:        fcr = in32rb(sc->sc_fcr);
                    155:        fcr |= FCR_MEDIABAY_ENABLE | FCR_MEDIABAY_RESET;
                    156:        out32rb(sc->sc_fcr, fcr);
                    157:        delay(50000);
                    158:
                    159:        fcr &= ~FCR_MEDIABAY_RESET;
                    160:        out32rb(sc->sc_fcr, fcr);
                    161:        delay(50000);
                    162:
                    163:        fcr |= FCR_MEDIABAY_IDE_ENABLE | FCR_MEDIABAY_CD_POWER;
                    164:        out32rb(sc->sc_fcr, fcr);
                    165:        delay(50000);
                    166:
                    167:        for (child = OF_child(sc->sc_node); child; child = OF_peer(child)) {
                    168:                memset(name, 0, sizeof(name));
                    169:                if (OF_getprop(child, "name", name, sizeof(name)) == -1)
                    170:                        continue;
                    171:                ca.ca_name = name;
                    172:                ca.ca_node = child;
                    173:                ca.ca_baseaddr = sc->sc_baseaddr;
                    174:                ca.ca_iot = sc->sc_iot;
                    175:                ca.ca_dmat = sc->sc_dmat;
                    176:
                    177:                ca.ca_nreg  = OF_getprop(child, "reg", reg, sizeof(reg));
                    178:                ca.ca_nintr = OF_getprop(child, "AAPL,interrupts", intr,
                    179:                                sizeof(intr));
                    180:                if (ca.ca_nintr == -1)
                    181:                        ca.ca_nintr = OF_getprop(child, "interrupts", intr,
                    182:                                        sizeof(intr));
                    183:                ca.ca_reg = reg;
                    184:                ca.ca_intr = intr;
                    185:
                    186:                content = config_found(&sc->sc_dev, &ca, mediabay_print);
                    187:                if (content) {
                    188:                        sc->sc_content = content;
                    189:                        return;
                    190:                }
                    191:        }
                    192:
                    193:        /* No devices found.  Disable media-bay. */
                    194:        fcr &= ~(FCR_MEDIABAY_ENABLE | FCR_MEDIABAY_IDE_ENABLE |
                    195:                 FCR_MEDIABAY_CD_POWER | FCR_MEDIABAY_FD_ENABLE);
                    196:        out32rb(sc->sc_fcr, fcr);
                    197: }
                    198:
                    199: int
                    200: mediabay_print(aux, mediabay)
                    201:        void *aux;
                    202:        const char *mediabay;
                    203: {
                    204:        struct confargs *ca = aux;
                    205:
                    206:        if (mediabay == NULL && ca->ca_nreg > 0)
                    207:                printf(" offset 0x%x", ca->ca_reg[0]);
                    208:
                    209:        return QUIET;
                    210: }
                    211:
                    212: int
                    213: mediabay_intr(v)
                    214:        void *v;
                    215: {
                    216:        struct mediabay_softc *sc = v;
                    217:
                    218:        wakeup(&sc->sc_kthread);
                    219:        return 1;
                    220: }
                    221:
                    222: void
                    223: mediabay_create_kthread(v)
                    224:        void *v;
                    225: {
                    226:        struct mediabay_softc *sc = v;
                    227:
                    228:        kthread_create(mediabay_kthread, sc, &sc->sc_kthread, "media-bay");
                    229: }
                    230:
                    231: void
                    232: mediabay_kthread(v)
                    233:        void *v;
                    234: {
                    235:        struct mediabay_softc *sc = v;
                    236:        u_int x, fcr;
                    237:
                    238: sleep:
                    239:        tsleep(&sc->sc_kthread, PRIBIO, "mbayev", 0);
                    240:
                    241:        /* sleep 0.25 sec */
                    242:        tsleep(mediabay_kthread, PRIBIO, "mbayev", hz/4);
                    243:
                    244:        DPRINTF("%s: ", sc->sc_dev.dv_xname);
                    245:        x = in32rb(sc->sc_addr);
                    246:
                    247:        switch (MEDIABAY_ID(x)) {
                    248:        case MEDIABAY_ID_NONE:
                    249:                DPRINTF("removed\n");
                    250:                if (sc->sc_content != NULL) {
                    251:                        config_detach(sc->sc_content, DETACH_FORCE);
                    252:                        DPRINTF("%s: detach done\n", sc->sc_dev.dv_xname);
                    253:                        sc->sc_content = NULL;
                    254:
                    255:                        /* disable media-bay */
                    256:                        fcr = in32rb(sc->sc_fcr);
                    257:                        fcr &= ~(FCR_MEDIABAY_ENABLE |
                    258:                                 FCR_MEDIABAY_IDE_ENABLE |
                    259:                                 FCR_MEDIABAY_CD_POWER |
                    260:                                 FCR_MEDIABAY_FD_ENABLE);
                    261:                        out32rb(sc->sc_fcr, fcr);
                    262:                }
                    263:                break;
                    264:        case MEDIABAY_ID_FD:
                    265:                DPRINTF("FD inserted\n");
                    266:                break;
                    267:        case MEDIABAY_ID_CD:
                    268:                DPRINTF("CD inserted\n");
                    269:
                    270:                if (sc->sc_content == NULL)
                    271:                        mediabay_attach_content(sc);
                    272:                break;
                    273:        default:
                    274:                printf("unknown event (0x%x)\n", x);
                    275:        }
                    276:
                    277:        goto sleep;
                    278: }
                    279:
                    280: /* PBG3: 0x7025X0c0 */
                    281: /* 2400: 0x0070X0a8 */

CVSweb