[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     ! 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