[BACK]Return to pccbb.c CVS log [TXT][DIR] Up to [local] / sys / dev / pci

Annotation of sys/dev/pci/pccbb.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: pccbb.c,v 1.47 2006/10/12 16:35:51 grange Exp $       */
                      2: /*     $NetBSD: pccbb.c,v 1.96 2004/03/28 09:49:31 nakayama Exp $      */
                      3:
                      4: /*
                      5:  * Copyright (c) 1998, 1999 and 2000
                      6:  *      HAYAKAWA Koichi.  All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *     This product includes software developed by HAYAKAWA Koichi.
                     19:  * 4. The name of the author may not be used to endorse or promote products
                     20:  *    derived from this software without specific prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     23:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     24:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     25:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     26:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     27:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     28:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     29:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     30:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     31:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     32:  */
                     33:
                     34: /*
                     35: #define CBB_DEBUG
                     36: #define SHOW_REGS
                     37: #define PCCBB_PCMCIA_POLL
                     38: */
                     39:
                     40: /*
                     41: #define CB_PCMCIA_POLL
                     42: #define CB_PCMCIA_POLL_ONLY
                     43: #define LEVEL2
                     44: */
                     45:
                     46: #include <sys/types.h>
                     47: #include <sys/param.h>
                     48: #include <sys/systm.h>
                     49: #include <sys/kernel.h>
                     50: #include <sys/errno.h>
                     51: #include <sys/evcount.h>
                     52: #include <sys/ioctl.h>
                     53: #include <sys/syslog.h>
                     54: #include <sys/device.h>
                     55: #include <sys/malloc.h>
                     56:
                     57: #include <machine/intr.h>
                     58: #include <machine/bus.h>
                     59:
                     60: #include <dev/pci/pcivar.h>
                     61: #include <dev/pci/pcireg.h>
                     62: #include <dev/pci/pcidevs.h>
                     63:
                     64: #include <dev/pci/pccbbreg.h>
                     65:
                     66: #include <dev/cardbus/cardslotvar.h>
                     67:
                     68: #include <dev/cardbus/cardbusvar.h>
                     69:
                     70: #include <dev/pcmcia/pcmciareg.h>
                     71: #include <dev/pcmcia/pcmciavar.h>
                     72:
                     73: #include <dev/ic/i82365reg.h>
                     74: #include <dev/ic/i82365var.h>
                     75: #include <dev/pci/pccbbvar.h>
                     76:
                     77: #ifndef __NetBSD_Version__
                     78: struct cfdriver cbb_cd = {
                     79:        NULL, "cbb", DV_DULL
                     80: };
                     81: #endif
                     82:
                     83: #if defined CBB_DEBUG
                     84: #define DPRINTF(x) printf x
                     85: #else
                     86: #define DPRINTF(x)
                     87: #endif
                     88:
                     89: int    pcicbbmatch(struct device *, void *, void *);
                     90: void   pccbbattach(struct device *, struct device *, void *);
                     91: int    pccbbintr(void *);
                     92: void   pccbb_shutdown(void *);
                     93: void   pci113x_insert(void *);
                     94: int    pccbbintr_function(struct pccbb_softc *);
                     95:
                     96: int    pccbb_detect_card(struct pccbb_softc *);
                     97:
                     98: void   pccbb_pcmcia_write(struct pcic_handle *, int, int);
                     99: u_int8_t pccbb_pcmcia_read(struct pcic_handle *, int);
                    100: #define Pcic_read(ph, reg) ((ph)->ph_read((ph), (reg)))
                    101: #define Pcic_write(ph, reg, val) ((ph)->ph_write((ph), (reg), (val)))
                    102:
                    103: int    cb_reset(struct pccbb_softc *);
                    104: int    cb_detect_voltage(struct pccbb_softc *);
                    105: int    cbbprint(void *, const char *);
                    106:
                    107: int    cb_chipset(u_int32_t, int *);
                    108: void   pccbb_pcmcia_attach_setup(struct pccbb_softc *,
                    109:     struct pcmciabus_attach_args *);
                    110: #if 0
                    111: void   pccbb_pcmcia_attach_card(struct pcic_handle *);
                    112: void   pccbb_pcmcia_detach_card(struct pcic_handle *, int);
                    113: void   pccbb_pcmcia_deactivate_card(struct pcic_handle *);
                    114: #endif
                    115:
                    116: int    pccbb_ctrl(cardbus_chipset_tag_t, int);
                    117: int    pccbb_power(cardbus_chipset_tag_t, int);
                    118: int    pccbb_cardenable(struct pccbb_softc * sc, int function);
                    119: void   *pccbb_intr_establish(struct pccbb_softc *, int irq, int level,
                    120:     int (*ih) (void *), void *sc, const char *);
                    121: void   pccbb_intr_disestablish(struct pccbb_softc *, void *ih);
                    122:
                    123: void   *pccbb_cb_intr_establish(cardbus_chipset_tag_t, int irq, int level,
                    124:     int (*ih) (void *), void *sc, const char *);
                    125: void   pccbb_cb_intr_disestablish(cardbus_chipset_tag_t ct, void *ih);
                    126:
                    127: cardbustag_t pccbb_make_tag(cardbus_chipset_tag_t, int, int, int);
                    128: void   pccbb_free_tag(cardbus_chipset_tag_t, cardbustag_t);
                    129: cardbusreg_t pccbb_conf_read(cardbus_chipset_tag_t, cardbustag_t, int);
                    130: void   pccbb_conf_write(cardbus_chipset_tag_t, cardbustag_t, int,
                    131:     cardbusreg_t);
                    132: void   pccbb_chipinit(struct pccbb_softc *);
                    133:
                    134: int    pccbb_pcmcia_mem_alloc(pcmcia_chipset_handle_t, bus_size_t,
                    135:     struct pcmcia_mem_handle *);
                    136: void   pccbb_pcmcia_mem_free(pcmcia_chipset_handle_t,
                    137:     struct pcmcia_mem_handle *);
                    138: int    pccbb_pcmcia_mem_map(pcmcia_chipset_handle_t, int, bus_addr_t,
                    139:     bus_size_t, struct pcmcia_mem_handle *, bus_size_t *, int *);
                    140: void   pccbb_pcmcia_mem_unmap(pcmcia_chipset_handle_t, int);
                    141: int    pccbb_pcmcia_io_alloc(pcmcia_chipset_handle_t, bus_addr_t,
                    142:     bus_size_t, bus_size_t, struct pcmcia_io_handle *);
                    143: void   pccbb_pcmcia_io_free(pcmcia_chipset_handle_t,
                    144:     struct pcmcia_io_handle *);
                    145: int    pccbb_pcmcia_io_map(pcmcia_chipset_handle_t, int, bus_addr_t,
                    146:     bus_size_t, struct pcmcia_io_handle *, int *);
                    147: void   pccbb_pcmcia_io_unmap(pcmcia_chipset_handle_t, int);
                    148: void   *pccbb_pcmcia_intr_establish(pcmcia_chipset_handle_t,
                    149:     struct pcmcia_function *, int, int (*)(void *), void *, char *);
                    150: void   pccbb_pcmcia_intr_disestablish(pcmcia_chipset_handle_t, void *);
                    151: const char *pccbb_pcmcia_intr_string(pcmcia_chipset_handle_t, void *);
                    152: void   pccbb_pcmcia_socket_enable(pcmcia_chipset_handle_t);
                    153: void   pccbb_pcmcia_socket_disable(pcmcia_chipset_handle_t);
                    154: int    pccbb_pcmcia_card_detect(pcmcia_chipset_handle_t pch);
                    155:
                    156: void   pccbb_pcmcia_do_io_map(struct pcic_handle *, int);
                    157: void   pccbb_pcmcia_wait_ready(struct pcic_handle *);
                    158: void   pccbb_pcmcia_do_mem_map(struct pcic_handle *, int);
                    159: void   pccbb_powerhook(int, void *);
                    160:
                    161: /* bus-space allocation and deallocation functions */
                    162: int    pccbb_rbus_cb_space_alloc(cardbus_chipset_tag_t, rbus_tag_t,
                    163:     bus_addr_t addr, bus_size_t size, bus_addr_t mask, bus_size_t align,
                    164:     int flags, bus_addr_t * addrp, bus_space_handle_t * bshp);
                    165: int    pccbb_rbus_cb_space_free(cardbus_chipset_tag_t, rbus_tag_t,
                    166:     bus_space_handle_t, bus_size_t);
                    167:
                    168: int    pccbb_open_win(struct pccbb_softc *, bus_space_tag_t,
                    169:     bus_addr_t, bus_size_t, bus_space_handle_t, int flags);
                    170: int    pccbb_close_win(struct pccbb_softc *, bus_space_tag_t,
                    171:     bus_space_handle_t, bus_size_t);
                    172: int    pccbb_winlist_insert(struct pccbb_win_chain_head *, bus_addr_t,
                    173:     bus_size_t, bus_space_handle_t, int);
                    174: int    pccbb_winlist_delete(struct pccbb_win_chain_head *,
                    175:     bus_space_handle_t, bus_size_t);
                    176: void   pccbb_winset(bus_addr_t align, struct pccbb_softc *,
                    177:     bus_space_tag_t);
                    178: void   pccbb_winlist_show(struct pccbb_win_chain *);
                    179:
                    180: /* for config_defer */
                    181: void   pccbb_pci_callback(struct device *);
                    182:
                    183: #if defined SHOW_REGS
                    184: void   cb_show_regs(pci_chipset_tag_t, pcitag_t, bus_space_tag_t,
                    185:     bus_space_handle_t memh);
                    186: #endif
                    187:
                    188: struct cfattach cbb_pci_ca = {
                    189:        sizeof(struct pccbb_softc), pcicbbmatch, pccbbattach
                    190: };
                    191:
                    192: static struct pcmcia_chip_functions pccbb_pcmcia_funcs = {
                    193:        pccbb_pcmcia_mem_alloc,
                    194:        pccbb_pcmcia_mem_free,
                    195:        pccbb_pcmcia_mem_map,
                    196:        pccbb_pcmcia_mem_unmap,
                    197:        pccbb_pcmcia_io_alloc,
                    198:        pccbb_pcmcia_io_free,
                    199:        pccbb_pcmcia_io_map,
                    200:        pccbb_pcmcia_io_unmap,
                    201:        pccbb_pcmcia_intr_establish,
                    202:        pccbb_pcmcia_intr_disestablish,
                    203:        pccbb_pcmcia_intr_string,
                    204:        pccbb_pcmcia_socket_enable,
                    205:        pccbb_pcmcia_socket_disable,
                    206:        pccbb_pcmcia_card_detect
                    207: };
                    208:
                    209: static struct cardbus_functions pccbb_funcs = {
                    210:        pccbb_rbus_cb_space_alloc,
                    211:        pccbb_rbus_cb_space_free,
                    212:        pccbb_cb_intr_establish,
                    213:        pccbb_cb_intr_disestablish,
                    214:        pccbb_ctrl,
                    215:        pccbb_power,
                    216:        pccbb_make_tag,
                    217:        pccbb_free_tag,
                    218:        pccbb_conf_read,
                    219:        pccbb_conf_write,
                    220: };
                    221:
                    222: int
                    223: pcicbbmatch(parent, match, aux)
                    224:        struct device *parent;
                    225:        void *match;
                    226:        void *aux;
                    227: {
                    228:        struct pci_attach_args *pa = (struct pci_attach_args *)aux;
                    229:
                    230:        if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
                    231:            PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_CARDBUS &&
                    232:            PCI_INTERFACE(pa->pa_class) == 0) {
                    233:                return 1;
                    234:        }
                    235:
                    236:        return 0;
                    237: }
                    238:
                    239: #define MAKEID(vendor, prod) (((vendor) << PCI_VENDOR_SHIFT) \
                    240:                                | ((prod) << PCI_PRODUCT_SHIFT))
                    241:
                    242: struct yenta_chipinfo {
                    243:        pcireg_t yc_id;                /* vendor tag | product tag */
                    244:        int yc_chiptype;
                    245:        int yc_flags;
                    246: } yc_chipsets[] = {
                    247:        /* Texas Instruments chips */
                    248:        { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1130), CB_TI113X,
                    249:            PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
                    250:        { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1131), CB_TI113X,
                    251:            PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
                    252:        { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1250), CB_TI125X,
                    253:            PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
                    254:        { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1220), CB_TI12XX,
                    255:            PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
                    256:        { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1221), CB_TI12XX,
                    257:            PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
                    258:        { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1225), CB_TI12XX,
                    259:            PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
                    260:        { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1251), CB_TI125X,
                    261:            PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
                    262:        { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1251B), CB_TI125X,
                    263:            PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
                    264:        { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1211), CB_TI12XX,
                    265:            PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
                    266:        { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1410), CB_TI12XX,
                    267:            PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
                    268:        { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1420), CB_TI12XX,
                    269:            PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
                    270:        { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1450), CB_TI125X,
                    271:            PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
                    272:        { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1451), CB_TI12XX,
                    273:            PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
                    274:        { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI7XX1), CB_TI12XX,
                    275:            PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
                    276:
                    277:        /* Ricoh chips */
                    278:        { MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_RF5C475), CB_RX5C47X,
                    279:            PCCBB_PCMCIA_MEM_32},
                    280:        { MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_RF5C476), CB_RX5C47X,
                    281:            PCCBB_PCMCIA_MEM_32},
                    282:        { MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_RF5C477), CB_RX5C47X,
                    283:            PCCBB_PCMCIA_MEM_32},
                    284:        { MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_RF5C478), CB_RX5C47X,
                    285:            PCCBB_PCMCIA_MEM_32},
                    286:        { MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_RF5C465), CB_RX5C46X,
                    287:            PCCBB_PCMCIA_MEM_32},
                    288:        { MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_RF5C466), CB_RX5C46X,
                    289:            PCCBB_PCMCIA_MEM_32},
                    290:
                    291:        /* Toshiba products */
                    292:        { MAKEID(PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_ToPIC95),
                    293:            CB_TOPIC95, PCCBB_PCMCIA_MEM_32},
                    294:        { MAKEID(PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_ToPIC95B),
                    295:            CB_TOPIC95B, PCCBB_PCMCIA_MEM_32},
                    296:        { MAKEID(PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_ToPIC97),
                    297:            CB_TOPIC97, PCCBB_PCMCIA_MEM_32},
                    298:        { MAKEID(PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_ToPIC100),
                    299:            CB_TOPIC97, PCCBB_PCMCIA_MEM_32},
                    300:
                    301:        /* Cirrus Logic products */
                    302:        { MAKEID(PCI_VENDOR_CIRRUS, PCI_PRODUCT_CIRRUS_CL_PD6832),
                    303:            CB_CIRRUS, PCCBB_PCMCIA_MEM_32},
                    304:        { MAKEID(PCI_VENDOR_CIRRUS, PCI_PRODUCT_CIRRUS_CL_PD6833),
                    305:            CB_CIRRUS, PCCBB_PCMCIA_MEM_32},
                    306:
                    307:        /* older O2Micro bridges */
                    308:        { MAKEID(PCI_VENDOR_O2MICRO, PCI_PRODUCT_O2MICRO_OZ6729),
                    309:            CB_OLDO2MICRO, PCCBB_PCMCIA_MEM_32},
                    310:        { MAKEID(PCI_VENDOR_O2MICRO, PCI_PRODUCT_O2MICRO_OZ6730),
                    311:            CB_OLDO2MICRO, PCCBB_PCMCIA_MEM_32},
                    312:        { MAKEID(PCI_VENDOR_O2MICRO, PCI_PRODUCT_O2MICRO_OZ6872), /* 68[71]2 */
                    313:            CB_OLDO2MICRO, PCCBB_PCMCIA_MEM_32},
                    314:        { MAKEID(PCI_VENDOR_O2MICRO, PCI_PRODUCT_O2MICRO_OZ6832),
                    315:            CB_OLDO2MICRO, PCCBB_PCMCIA_MEM_32},
                    316:        { MAKEID(PCI_VENDOR_O2MICRO, PCI_PRODUCT_O2MICRO_OZ6836),
                    317:            CB_OLDO2MICRO, PCCBB_PCMCIA_MEM_32},
                    318:
                    319:        /* sentinel, or Generic chip */
                    320:        { 0 /* null id */ , CB_UNKNOWN, PCCBB_PCMCIA_MEM_32},
                    321: };
                    322:
                    323: int
                    324: cb_chipset(pci_id, flagp)
                    325:        u_int32_t pci_id;
                    326:        int *flagp;
                    327: {
                    328:        struct yenta_chipinfo *yc;
                    329:
                    330:        /* Loop over except the last default entry. */
                    331:        for (yc = yc_chipsets; yc < yc_chipsets +
                    332:            sizeof(yc_chipsets) / sizeof(yc_chipsets[0]) - 1; yc++)
                    333:                if (pci_id == yc->yc_id)
                    334:                        break;
                    335:
                    336:        if (flagp != NULL)
                    337:                *flagp = yc->yc_flags;
                    338:
                    339:        return (yc->yc_chiptype);
                    340: }
                    341:
                    342: void
                    343: pccbb_shutdown(void *arg)
                    344: {
                    345:        struct pccbb_softc *sc = arg;
                    346:        pcireg_t command;
                    347:
                    348:        DPRINTF(("%s: shutdown\n", sc->sc_dev.dv_xname));
                    349:
                    350:        /* turn off power */
                    351:        pccbb_power((cardbus_chipset_tag_t)sc, CARDBUS_VCC_0V | CARDBUS_VPP_0V);
                    352:
                    353:        bus_space_write_4(sc->sc_base_memt, sc->sc_base_memh, CB_SOCKET_MASK,
                    354:            0);
                    355:
                    356:        command = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG);
                    357:
                    358:        command &= ~(PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
                    359:            PCI_COMMAND_MASTER_ENABLE);
                    360:        pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG, command);
                    361: }
                    362:
                    363: void
                    364: pccbbattach(parent, self, aux)
                    365:        struct device *parent;
                    366:        struct device *self;
                    367:        void *aux;
                    368: {
                    369:        struct pccbb_softc *sc = (void *)self;
                    370:        struct pci_attach_args *pa = aux;
                    371:        pci_chipset_tag_t pc = pa->pa_pc;
                    372:        pcireg_t busreg, reg, sock_base;
                    373:        pci_intr_handle_t ih;
                    374:        const char *intrstr = NULL;
                    375:        bus_addr_t sockbase;
                    376:        int flags;
                    377:
                    378: #ifdef __HAVE_PCCBB_ATTACH_HOOK
                    379:        pccbb_attach_hook(parent, self, pa);
                    380: #endif
                    381:
                    382:        sc->sc_chipset = cb_chipset(pa->pa_id, &flags);
                    383:
                    384: #ifdef CBB_DEBUG
                    385:        printf(" (chipflags %x)", flags);
                    386: #endif
                    387:
                    388:        TAILQ_INIT(&sc->sc_memwindow);
                    389:        TAILQ_INIT(&sc->sc_iowindow);
                    390:
                    391:        sc->sc_rbus_iot = rbus_pccbb_parent_io(self, pa);
                    392:        sc->sc_rbus_memt = rbus_pccbb_parent_mem(self, pa);
                    393:
                    394:        sc->sc_flags &= ~CBB_MEMHMAPPED;
                    395:
                    396:        /*
                    397:         * MAP socket registers and ExCA registers on memory-space
                    398:         * When no valid address is set on socket base registers (on pci
                    399:         * config space), get it not polite way.
                    400:         */
                    401:        sock_base = pci_conf_read(pc, pa->pa_tag, PCI_SOCKBASE);
                    402:
                    403:        if (PCI_MAPREG_MEM_ADDR(sock_base) >= 0x100000 &&
                    404:            PCI_MAPREG_MEM_ADDR(sock_base) != 0xfffffff0) {
                    405:                /* The address must be valid. */
                    406:                if (pci_mapreg_map(pa, PCI_SOCKBASE, PCI_MAPREG_TYPE_MEM, 0,
                    407:                    &sc->sc_base_memt, &sc->sc_base_memh, &sockbase, NULL, 0))
                    408:                    {
                    409:                        printf("%s: can't map socket base address 0x%x\n",
                    410:                            sc->sc_dev.dv_xname, sock_base);
                    411:                        /*
                    412:                         * I think it's funny: socket base registers must be
                    413:                         * mapped on memory space, but ...
                    414:                         */
                    415:                        if (pci_mapreg_map(pa, PCI_SOCKBASE,
                    416:                            PCI_MAPREG_TYPE_IO, 0, &sc->sc_base_memt,
                    417:                            &sc->sc_base_memh, &sockbase, NULL, 0)) {
                    418:                                printf("%s: can't map socket base address"
                    419:                                    " 0x%lx: io mode\n", sc->sc_dev.dv_xname,
                    420:                                    sockbase);
                    421:                                /* give up... allocate reg space via rbus. */
                    422:                                pci_conf_write(pc, pa->pa_tag, PCI_SOCKBASE, 0);
                    423:                        } else
                    424:                                sc->sc_flags |= CBB_MEMHMAPPED;
                    425:                } else {
                    426:                        DPRINTF(("%s: socket base address 0x%lx\n",
                    427:                            sc->sc_dev.dv_xname, sockbase));
                    428:                        sc->sc_flags |= CBB_MEMHMAPPED;
                    429:                }
                    430:        }
                    431:
                    432:        sc->sc_mem_start = 0;          /* XXX */
                    433:        sc->sc_mem_end = 0xffffffff;   /* XXX */
                    434:
                    435:        /*
                    436:         * When bus number isn't set correctly, give up using 32-bit CardBus
                    437:         * mode.
                    438:         */
                    439:        busreg = pci_conf_read(pc, pa->pa_tag, PCI_BUSNUM);
                    440: #if notyet
                    441:        if (((busreg >> 8) & 0xff) == 0) {
                    442:                printf(": CardBus support disabled because of unconfigured bus number\n");
                    443:                flags |= PCCBB_PCMCIA_16BITONLY;
                    444:        }
                    445: #endif
                    446:
                    447:        /* pccbb_machdep.c end */
                    448:
                    449: #if defined CBB_DEBUG
                    450:        {
                    451:                static char *intrname[5] = { "NON", "A", "B", "C", "D" };
                    452:                printf(": intrpin %s, intrtag %d\n",
                    453:                    intrname[pa->pa_intrpin], pa->pa_intrline);
                    454:        }
                    455: #endif
                    456:
                    457:        /* setup softc */
                    458:        sc->sc_pc = pc;
                    459:        sc->sc_iot = pa->pa_iot;
                    460:        sc->sc_memt = pa->pa_memt;
                    461:        sc->sc_dmat = pa->pa_dmat;
                    462:        sc->sc_tag = pa->pa_tag;
                    463:        sc->sc_function = pa->pa_function;
                    464:        sc->sc_sockbase = sock_base;
                    465:        sc->sc_busnum = busreg;
                    466:        sc->sc_intrtag = pa->pa_intrtag;
                    467:        sc->sc_intrpin = pa->pa_intrpin;
                    468:
                    469:        sc->sc_pcmcia_flags = flags;   /* set PCMCIA facility */
                    470:
                    471:        /* Map and establish the interrupt. */
                    472:        if (pci_intr_map(pa, &ih)) {
                    473:                printf(": couldn't map interrupt\n");
                    474:                return;
                    475:        }
                    476:        intrstr = pci_intr_string(pc, ih);
                    477:        /* must do this after intr is mapped and established */
                    478:        sc->sc_intrline = pci_intr_line(ih);
                    479:
                    480:        /*
                    481:         * XXX pccbbintr should be called under the priority lower
                    482:         * than any other hard interrupts.
                    483:         */
                    484:        sc->sc_ih = pci_intr_establish(pc, ih, IPL_BIO, pccbbintr, sc,
                    485:            sc->sc_dev.dv_xname);
                    486:
                    487:        if (sc->sc_ih == NULL) {
                    488:                printf(": couldn't establish interrupt");
                    489:                if (intrstr != NULL) {
                    490:                        printf(" at %s", intrstr);
                    491:                }
                    492:                printf("\n");
                    493:                return;
                    494:        }
                    495:        printf(": %s\n", intrstr);
                    496:
                    497:        shutdownhook_establish(pccbb_shutdown, sc);
                    498:
                    499:        /* Disable legacy register mapping. */
                    500:        switch (sc->sc_chipset) {
                    501:        case CB_RX5C46X:               /* fallthrough */
                    502: #if 0
                    503:        /* The RX5C47X-series requires writes to the PCI_LEGACY register. */
                    504:        case CB_RX5C47X:
                    505: #endif
                    506:                /*
                    507:                 * The legacy pcic io-port on Ricoh RX5C46X CardBus bridges
                    508:                 * cannot be disabled by substituting 0 into PCI_LEGACY
                    509:                 * register.  Ricoh CardBus bridges have special bits on Bridge
                    510:                 * control reg (addr 0x3e on PCI config space).
                    511:                 */
                    512:                reg = pci_conf_read(pc, pa->pa_tag, PCI_BCR_INTR);
                    513:                reg &= ~(CB_BCRI_RL_3E0_ENA | CB_BCRI_RL_3E2_ENA);
                    514:                pci_conf_write(pc, pa->pa_tag, PCI_BCR_INTR, reg);
                    515:                break;
                    516:
                    517:        default:
                    518:                /* XXX I don't know proper way to kill legacy I/O. */
                    519:                pci_conf_write(pc, pa->pa_tag, PCI_LEGACY, 0x0);
                    520:                break;
                    521:        }
                    522:
                    523:        timeout_set(&sc->sc_ins_tmo, pci113x_insert, sc);
                    524:        config_defer(self, pccbb_pci_callback);
                    525: }
                    526:
                    527: /*
                    528:  * void pccbb_pci_callback(struct device *self)
                    529:  *
                    530:  *   The actual attach routine: get memory space for YENTA register
                    531:  *   space, setup YENTA register and route interrupt.
                    532:  *
                    533:  *   This function should be deferred because this device may obtain
                    534:  *   memory space dynamically.  This function must avoid obtaining
                    535:  *   memory area which has already kept for another device.  Also,
                    536:  *   this function MUST be done before ISA attach process because this
                    537:  *   function kills pcic compatible port used by ISA pcic.
                    538:  */
                    539: void
                    540: pccbb_pci_callback(self)
                    541:        struct device *self;
                    542: {
                    543:        struct pccbb_softc *sc = (void *)self;
                    544:        pci_chipset_tag_t pc = sc->sc_pc;
                    545:        bus_space_tag_t base_memt;
                    546:        bus_space_handle_t base_memh;
                    547:        u_int32_t maskreg;
                    548:        bus_addr_t sockbase;
                    549:        struct cbslot_attach_args cba;
                    550:        struct pcmciabus_attach_args paa;
                    551:        struct cardslot_attach_args caa;
                    552:        struct cardslot_softc *csc;
                    553:
                    554:        if (!(sc->sc_flags & CBB_MEMHMAPPED)) {
                    555:                /* The socket registers aren't mapped correctly. */
                    556:                if (rbus_space_alloc(sc->sc_rbus_memt, 0, 0x1000, 0x0fff,
                    557:                    (sc->sc_chipset == CB_RX5C47X
                    558:                    || sc->sc_chipset == CB_TI113X) ? 0x10000 : 0x1000,
                    559:                    0, &sockbase, &sc->sc_base_memh)) {
                    560:                        return;
                    561:                }
                    562:                sc->sc_base_memt = sc->sc_memt;
                    563:                pci_conf_write(pc, sc->sc_tag, PCI_SOCKBASE, sockbase);
                    564:                DPRINTF(("%s: CardBus register address 0x%lx -> 0x%x\n",
                    565:                    sc->sc_dev.dv_xname, sockbase, pci_conf_read(pc, sc->sc_tag,
                    566:                    PCI_SOCKBASE)));
                    567:                sc->sc_flags |= CBB_MEMHMAPPED;
                    568:        }
                    569:
                    570:        /* bus bridge initialization */
                    571:        pccbb_chipinit(sc);
                    572:
                    573:        base_memt = sc->sc_base_memt;  /* socket regs memory tag */
                    574:        base_memh = sc->sc_base_memh;  /* socket regs memory handle */
                    575:
                    576:        /* clear data structure for child device interrupt handlers */
                    577:        sc->sc_pil = NULL;
                    578:        sc->sc_pil_intr_enable = 1;
                    579:
                    580:        powerhook_establish(pccbb_powerhook, sc);
                    581:
                    582:        {
                    583:                u_int32_t sockstat =
                    584:                    bus_space_read_4(base_memt, base_memh, CB_SOCKET_STAT);
                    585:                if (0 == (sockstat & CB_SOCKET_STAT_CD)) {
                    586:                        sc->sc_flags |= CBB_CARDEXIST;
                    587:                }
                    588:        }
                    589:
                    590:        /*
                    591:         * attach cardbus
                    592:         */
                    593:        if (!(sc->sc_pcmcia_flags & PCCBB_PCMCIA_16BITONLY)) {
                    594:                pcireg_t busreg = pci_conf_read(pc, sc->sc_tag, PCI_BUSNUM);
                    595:                pcireg_t bhlc = pci_conf_read(pc, sc->sc_tag, PCI_BHLC_REG);
                    596:
                    597:                /* initialize cbslot_attach */
                    598:                cba.cba_busname = "cardbus";
                    599:                cba.cba_iot = sc->sc_iot;
                    600:                cba.cba_memt = sc->sc_memt;
                    601:                cba.cba_dmat = sc->sc_dmat;
                    602:                cba.cba_bus = (busreg >> 8) & 0x0ff;
                    603:                cba.cba_cc = (void *)sc;
                    604:                cba.cba_cf = &pccbb_funcs;
                    605:                cba.cba_intrline = sc->sc_intrline;
                    606:
                    607:                cba.cba_rbus_iot = sc->sc_rbus_iot;
                    608:                cba.cba_rbus_memt = sc->sc_rbus_memt;
                    609:
                    610:                cba.cba_cacheline = PCI_CACHELINE(bhlc);
                    611:                cba.cba_lattimer = PCI_CB_LATENCY(busreg);
                    612:
                    613: #if defined CBB_DEBUG
                    614:                printf("%s: cacheline 0x%x lattimer 0x%x\n",
                    615:                    sc->sc_dev.dv_xname, cba.cba_cacheline, cba.cba_lattimer);
                    616:                printf("%s: bhlc 0x%x lscp 0x%x\n", sc->sc_dev.dv_xname, bhlc,
                    617:                    busreg);
                    618: #endif
                    619: #if defined SHOW_REGS
                    620:                cb_show_regs(sc->sc_pc, sc->sc_tag, sc->sc_base_memt,
                    621:                    sc->sc_base_memh);
                    622: #endif
                    623:        }
                    624:
                    625:        pccbb_pcmcia_attach_setup(sc, &paa);
                    626:        caa.caa_cb_attach = NULL;
                    627:        if (!(sc->sc_pcmcia_flags & PCCBB_PCMCIA_16BITONLY)) {
                    628:                caa.caa_cb_attach = &cba;
                    629:        }
                    630:        caa.caa_16_attach = &paa;
                    631:        caa.caa_ph = &sc->sc_pcmcia_h;
                    632:
                    633:        if (NULL != (csc = (void *)config_found(self, &caa, cbbprint))) {
                    634:                DPRINTF(("pccbbattach: found cardslot\n"));
                    635:                sc->sc_csc = csc;
                    636:        }
                    637:
                    638:        sc->sc_ints_on = 1;
                    639:
                    640:        /* CSC Interrupt: Card detect interrupt on */
                    641:        maskreg = bus_space_read_4(base_memt, base_memh, CB_SOCKET_MASK);
                    642:        maskreg |= CB_SOCKET_MASK_CD;  /* Card detect intr is turned on. */
                    643:        bus_space_write_4(base_memt, base_memh, CB_SOCKET_MASK, maskreg);
                    644:        /* reset interrupt */
                    645:        bus_space_write_4(base_memt, base_memh, CB_SOCKET_EVENT,
                    646:            bus_space_read_4(base_memt, base_memh, CB_SOCKET_EVENT));
                    647:
                    648:        return;
                    649: }
                    650:
                    651: /*
                    652:  * void pccbb_chipinit(struct pccbb_softc *sc)
                    653:  *
                    654:  *   This function initialize YENTA chip registers listed below:
                    655:  *     1) PCI command reg,
                    656:  *     2) PCI and CardBus latency timer,
                    657:  *     3) route PCI interrupt,
                    658:  *     4) close all memory and io windows.
                    659:  */
                    660: void
                    661: pccbb_chipinit(sc)
                    662:        struct pccbb_softc *sc;
                    663: {
                    664:        pci_chipset_tag_t pc = sc->sc_pc;
                    665:        pcitag_t tag = sc->sc_tag;
                    666:        pcireg_t reg;
                    667:
                    668:        /*
                    669:         * Set PCI command reg.
                    670:         * Some laptop's BIOSes (i.e. TICO) do not enable CardBus chip.
                    671:         */
                    672:        reg = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
                    673:        /* I believe it is harmless. */
                    674:        reg |= (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
                    675:            PCI_COMMAND_MASTER_ENABLE);
                    676:        pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, reg);
                    677:
                    678:        /*
                    679:         * Set CardBus latency timer.
                    680:         */
                    681:        reg = pci_conf_read(pc, tag, PCI_CB_LSCP_REG);
                    682:        if (PCI_CB_LATENCY(reg) < 0x20) {
                    683:                reg &= ~(PCI_CB_LATENCY_MASK << PCI_CB_LATENCY_SHIFT);
                    684:                reg |= (0x20 << PCI_CB_LATENCY_SHIFT);
                    685:                pci_conf_write(pc, tag, PCI_CB_LSCP_REG, reg);
                    686:        }
                    687:        DPRINTF(("CardBus latency timer 0x%x (%x)\n",
                    688:            PCI_CB_LATENCY(reg), pci_conf_read(pc, tag, PCI_CB_LSCP_REG)));
                    689:
                    690:        /*
                    691:         * Set PCI latency timer.
                    692:         */
                    693:        reg = pci_conf_read(pc, tag, PCI_BHLC_REG);
                    694:        if (PCI_LATTIMER(reg) < 0x10) {
                    695:                reg &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT);
                    696:                reg |= (0x10 << PCI_LATTIMER_SHIFT);
                    697:                pci_conf_write(pc, tag, PCI_BHLC_REG, reg);
                    698:        }
                    699:        DPRINTF(("PCI latency timer 0x%x (%x)\n",
                    700:            PCI_LATTIMER(reg), pci_conf_read(pc, tag, PCI_BHLC_REG)));
                    701:
                    702:        /* Route functional interrupts to PCI. */
                    703:        reg = pci_conf_read(pc, tag, PCI_BCR_INTR);
                    704:        reg |= CB_BCR_INTR_IREQ_ENABLE;         /* disable PCI Intr */
                    705:        reg |= CB_BCR_WRITE_POST_ENABLE;        /* enable write post */
                    706:        reg |= CB_BCR_RESET_ENABLE;             /* assert reset */
                    707:        pci_conf_write(pc, tag, PCI_BCR_INTR, reg);
                    708:
                    709:        switch (sc->sc_chipset) {
                    710:        case CB_TI113X:
                    711:                reg = pci_conf_read(pc, tag, PCI_CBCTRL);
                    712:                /* This bit is shared, but may read as 0 on some chips, so set
                    713:                   it explicitly on both functions. */
                    714:                reg |= PCI113X_CBCTRL_PCI_IRQ_ENA;
                    715:                /* CSC intr enable */
                    716:                reg |= PCI113X_CBCTRL_PCI_CSC;
                    717:                /* functional intr prohibit | prohibit ISA routing */
                    718:                reg &= ~(PCI113X_CBCTRL_PCI_INTR | PCI113X_CBCTRL_INT_MASK);
                    719:                pci_conf_write(pc, tag, PCI_CBCTRL, reg);
                    720:                break;
                    721:
                    722:        case CB_TI12XX:
                    723:                /*
                    724:                 * Some TI 12xx (and [14][45]xx) based pci cards
                    725:                 * sometimes have issues with the MFUNC register not
                    726:                 * being initialized due to a bad EEPROM on board.
                    727:                 * Laptops that this matters on have this register
                    728:                 * properly initialized.
                    729:                 *
                    730:                 * The TI125X parts have a different register.
                    731:                 */
                    732:                reg = pci_conf_read(pc, tag, PCI12XX_MFUNC);
                    733:                if (reg == 0) {
                    734:                        reg &= ~PCI12XX_MFUNC_PIN0;
                    735:                        reg |= PCI12XX_MFUNC_PIN0_INTA;
                    736:                        if ((pci_conf_read(pc, tag, PCI_SYSCTRL) &
                    737:                             PCI12XX_SYSCTRL_INTRTIE) == 0) {
                    738:                                reg &= ~PCI12XX_MFUNC_PIN1;
                    739:                                reg |= PCI12XX_MFUNC_PIN1_INTB;
                    740:                        }
                    741:                        pci_conf_write(pc, tag, PCI12XX_MFUNC, reg);
                    742:                }
                    743:                /* FALLTHROUGH */
                    744:
                    745:        case CB_TI125X:
                    746:                /*
                    747:                 * Disable zoom video.  Some machines initialize this
                    748:                 * improperly and experience has shown that this helps
                    749:                 * prevent strange behavior.
                    750:                 */
                    751:                pci_conf_write(pc, tag, PCI12XX_MMCTRL, 0);
                    752:
                    753:                reg = pci_conf_read(pc, tag, PCI_SYSCTRL);
                    754:                reg |= PCI12XX_SYSCTRL_VCCPROT;
                    755:                pci_conf_write(pc, tag, PCI_SYSCTRL, reg);
                    756:                reg = pci_conf_read(pc, tag, PCI_CBCTRL);
                    757:                reg |= PCI12XX_CBCTRL_CSC;
                    758:                pci_conf_write(pc, tag, PCI_CBCTRL, reg);
                    759:                break;
                    760:
                    761:        case CB_TOPIC95B:
                    762:                reg = pci_conf_read(pc, tag, TOPIC_SOCKET_CTRL);
                    763:                reg |= TOPIC_SOCKET_CTRL_SCR_IRQSEL;
                    764:                pci_conf_write(pc, tag, TOPIC_SOCKET_CTRL, reg);
                    765:
                    766:                reg = pci_conf_read(pc, tag, TOPIC_SLOT_CTRL);
                    767:                DPRINTF(("%s: topic slot ctrl reg 0x%x -> ",
                    768:                    sc->sc_dev.dv_xname, reg));
                    769:                reg |= (TOPIC_SLOT_CTRL_SLOTON | TOPIC_SLOT_CTRL_SLOTEN |
                    770:                    TOPIC_SLOT_CTRL_ID_LOCK | TOPIC_SLOT_CTRL_CARDBUS);
                    771:                reg &= ~TOPIC_SLOT_CTRL_SWDETECT;
                    772:                DPRINTF(("0x%x\n", reg));
                    773:                pci_conf_write(pc, tag, TOPIC_SLOT_CTRL, reg);
                    774:                break;
                    775:
                    776:        case CB_TOPIC97:
                    777:                reg = pci_conf_read(pc, tag, TOPIC_SLOT_CTRL);
                    778:                DPRINTF(("%s: topic slot ctrl reg 0x%x -> ",
                    779:                    sc->sc_dev.dv_xname, reg));
                    780:                reg |= (TOPIC_SLOT_CTRL_SLOTON | TOPIC_SLOT_CTRL_SLOTEN |
                    781:                    TOPIC_SLOT_CTRL_ID_LOCK | TOPIC_SLOT_CTRL_CARDBUS);
                    782:                reg &= ~TOPIC_SLOT_CTRL_SWDETECT;
                    783:                reg |= TOPIC97_SLOT_CTRL_PCIINT;
                    784:                reg &= ~(TOPIC97_SLOT_CTRL_STSIRQP | TOPIC97_SLOT_CTRL_IRQP);
                    785:                DPRINTF(("0x%x\n", reg));
                    786:                pci_conf_write(pc, tag, TOPIC_SLOT_CTRL, reg);
                    787:
                    788:                /* make sure to assert LV card support bits */
                    789:                bus_space_write_1(sc->sc_base_memt, sc->sc_base_memh,
                    790:                    0x800 + 0x3e, bus_space_read_1(sc->sc_base_memt,
                    791:                    sc->sc_base_memh, 0x800 + 0x3e) | 0x03);
                    792:
                    793:                /* Power on the controller if the BIOS didn't */
                    794:                reg = pci_conf_read(pc, tag, TOPIC100_PMCSR);
                    795:                if ((reg & TOPIC100_PMCSR_MASK) != TOPIC100_PMCSR_D0)
                    796:                        pci_conf_write(pc, tag, TOPIC100_PMCSR,
                    797:                            (reg & ~TOPIC100_PMCSR_MASK) | TOPIC100_PMCSR_D0);
                    798:                break;
                    799:
                    800:        case CB_OLDO2MICRO:
                    801:                /*
                    802:                 * older bridges have problems with both read prefetch and
                    803:                 * write bursting depending on the combination of the chipset,
                    804:                 * bridge and the cardbus card. so disable them to be on the
                    805:                 * safe side. One example is O2Micro 6812 with Atheros AR5012
                    806:                 * chipsets
                    807:                 */
                    808:                DPRINTF(("%s: old O2Micro bridge found\n",
                    809:                    sc->sc_dev.dv_xname, reg));
                    810:                reg = pci_conf_read(pc, tag, O2MICRO_RESERVED1);
                    811:                pci_conf_write(pc, tag, O2MICRO_RESERVED1, reg &
                    812:                    ~(O2MICRO_RES_READ_PREFETCH | O2MICRO_RES_WRITE_BURST));
                    813:                reg = pci_conf_read(pc, tag, O2MICRO_RESERVED2);
                    814:                pci_conf_write(pc, tag, O2MICRO_RESERVED2, reg &
                    815:                    ~(O2MICRO_RES_READ_PREFETCH | O2MICRO_RES_WRITE_BURST));
                    816:                break;
                    817:        }
                    818:
                    819:        /* Close all memory and I/O windows. */
                    820:        pci_conf_write(pc, tag, PCI_CB_MEMBASE0, 0xffffffff);
                    821:        pci_conf_write(pc, tag, PCI_CB_MEMLIMIT0, 0);
                    822:        pci_conf_write(pc, tag, PCI_CB_MEMBASE1, 0xffffffff);
                    823:        pci_conf_write(pc, tag, PCI_CB_MEMLIMIT1, 0);
                    824:        pci_conf_write(pc, tag, PCI_CB_IOBASE0, 0xffffffff);
                    825:        pci_conf_write(pc, tag, PCI_CB_IOLIMIT0, 0);
                    826:        pci_conf_write(pc, tag, PCI_CB_IOBASE1, 0xffffffff);
                    827:        pci_conf_write(pc, tag, PCI_CB_IOLIMIT1, 0);
                    828:
                    829:        /* reset 16-bit pcmcia bus */
                    830:        bus_space_write_1(sc->sc_base_memt, sc->sc_base_memh,
                    831:            0x800 + PCIC_INTR,
                    832:            bus_space_read_1(sc->sc_base_memt, sc->sc_base_memh,
                    833:                0x800 + PCIC_INTR) & ~PCIC_INTR_RESET);
                    834:
                    835:        /* turn off power */
                    836:        pccbb_power((cardbus_chipset_tag_t)sc, CARDBUS_VCC_0V | CARDBUS_VPP_0V);
                    837: }
                    838:
                    839:
                    840:
                    841:
                    842: /*
                    843:  * void pccbb_pcmcia_attach_setup(struct pccbb_softc *sc,
                    844:  *                                      struct pcmciabus_attach_args *paa)
                    845:  *
                    846:  *   This function attaches 16-bit PCcard bus.
                    847:  */
                    848: void
                    849: pccbb_pcmcia_attach_setup(sc, paa)
                    850:        struct pccbb_softc *sc;
                    851:        struct pcmciabus_attach_args *paa;
                    852: {
                    853:        struct pcic_handle *ph = &sc->sc_pcmcia_h;
                    854:        rbus_tag_t rb;
                    855:
                    856:        /* initialize pcmcia part in pccbb_softc */
                    857:        ph->ph_parent = (struct device *)sc;
                    858:        ph->sock = sc->sc_function;
                    859:        ph->flags = 0;
                    860:        ph->shutdown = 0;
                    861:        ph->ih_irq = sc->sc_intrline;
                    862:        ph->ph_bus_t = sc->sc_base_memt;
                    863:        ph->ph_bus_h = sc->sc_base_memh;
                    864:        ph->ph_read = pccbb_pcmcia_read;
                    865:        ph->ph_write = pccbb_pcmcia_write;
                    866:        sc->sc_pct = &pccbb_pcmcia_funcs;
                    867:
                    868:        /*
                    869:         * We need to do a few things here:
                    870:         * 1) Disable routing of CSC and functional interrupts to ISA IRQs by
                    871:         *    setting the IRQ numbers to 0.
                    872:         * 2) Set bit 4 of PCIC_INTR, which is needed on some chips to enable
                    873:         *    routing of CSC interrupts (e.g. card removal) to PCI while in
                    874:         *    PCMCIA mode.  We just leave this set all the time.
                    875:         * 3) Enable card insertion/removal interrupts in case the chip also
                    876:         *    needs that while in PCMCIA mode.
                    877:         * 4) Clear any pending CSC interrupt.
                    878:         */
                    879:        Pcic_write(ph, PCIC_INTR, PCIC_INTR_ENABLE | PCIC_INTR_RESET);
                    880:        if (sc->sc_chipset == CB_TI113X) {
                    881:                Pcic_write(ph, PCIC_CSC_INTR, 0);
                    882:        } else {
                    883:                Pcic_write(ph, PCIC_CSC_INTR, PCIC_CSC_INTR_CD_ENABLE);
                    884:                Pcic_read(ph, PCIC_CSC);
                    885:        }
                    886:
                    887:        /* initialize pcmcia bus attachment */
                    888:        paa->paa_busname = "pcmcia";
                    889:        paa->pct = sc->sc_pct;
                    890:        paa->pch = ph;
                    891:        paa->iobase = 0;               /* I don't use them */
                    892:        paa->iosize = 0;
                    893:        rb = ((struct pccbb_softc *)(ph->ph_parent))->sc_rbus_iot;
                    894:        paa->iobase = rb->rb_start + rb->rb_offset;
                    895:        paa->iosize = rb->rb_end - rb->rb_start;
                    896:
                    897:        return;
                    898: }
                    899:
                    900: #if 0
                    901: void
                    902: pccbb_pcmcia_attach_card(ph)
                    903:        struct pcic_handle *ph;
                    904: {
                    905:        if (ph->flags & PCIC_FLAG_CARDP) {
                    906:                panic("pccbb_pcmcia_attach_card: already attached");
                    907:        }
                    908:
                    909:        /* call the MI attach function */
                    910:        pcmcia_card_attach(ph->pcmcia);
                    911:
                    912:        ph->flags |= PCIC_FLAG_CARDP;
                    913: }
                    914:
                    915: void
                    916: pccbb_pcmcia_detach_card(ph, flags)
                    917:        struct pcic_handle *ph;
                    918:        int flags;
                    919: {
                    920:        if (!(ph->flags & PCIC_FLAG_CARDP)) {
                    921:                panic("pccbb_pcmcia_detach_card: already detached");
                    922:        }
                    923:
                    924:        ph->flags &= ~PCIC_FLAG_CARDP;
                    925:
                    926:        /* call the MI detach function */
                    927:        pcmcia_card_detach(ph->pcmcia, flags);
                    928: }
                    929: #endif
                    930:
                    931: /*
                    932:  * int pccbbintr(arg)
                    933:  *    void *arg;
                    934:  *   This routine handles the interrupt from Yenta PCI-CardBus bridge
                    935:  *   itself.
                    936:  */
                    937: int
                    938: pccbbintr(arg)
                    939:        void *arg;
                    940: {
                    941:        struct pccbb_softc *sc = (struct pccbb_softc *)arg;
                    942:        u_int32_t sockevent, sockstate;
                    943:        bus_space_tag_t memt = sc->sc_base_memt;
                    944:        bus_space_handle_t memh = sc->sc_base_memh;
                    945:        struct pcic_handle *ph = &sc->sc_pcmcia_h;
                    946:
                    947:        if (!sc->sc_ints_on)
                    948:                return 0;
                    949:
                    950:        sockevent = bus_space_read_4(memt, memh, CB_SOCKET_EVENT);
                    951:        bus_space_write_4(memt, memh, CB_SOCKET_EVENT, sockevent);
                    952:        Pcic_read(ph, PCIC_CSC);
                    953:
                    954:        if (sockevent == 0) {
                    955:                /* This intr is not for me: it may be for my child devices. */
                    956:                if (sc->sc_pil_intr_enable) {
                    957:                        return pccbbintr_function(sc);
                    958:                } else {
                    959:                        return 0;
                    960:                }
                    961:        }
                    962:
                    963:        if (sockevent & CB_SOCKET_EVENT_CD) {
                    964:                sockstate = bus_space_read_4(memt, memh, CB_SOCKET_STAT);
                    965:                if (CB_SOCKET_STAT_CD == (sockstate & CB_SOCKET_STAT_CD)) {
                    966:                        /* A card should be removed. */
                    967:                        if (sc->sc_flags & CBB_CARDEXIST) {
                    968:                                DPRINTF(("%s: 0x%08x", sc->sc_dev.dv_xname,
                    969:                                    sockevent));
                    970:                                DPRINTF((" card removed, 0x%08x\n", sockstate));
                    971:                                sc->sc_flags &= ~CBB_CARDEXIST;
                    972:                                if (sc->sc_csc->sc_status &
                    973:                                    CARDSLOT_STATUS_CARD_16) {
                    974: #if 0
                    975:                                        struct pcic_handle *ph =
                    976:                                            &sc->sc_pcmcia_h;
                    977:
                    978:                                        pcmcia_card_deactivate(ph->pcmcia);
                    979:                                        pccbb_pcmcia_socket_disable(ph);
                    980:                                        pccbb_pcmcia_detach_card(ph,
                    981:                                            DETACH_FORCE);
                    982: #endif
                    983:                                        cardslot_event_throw(sc->sc_csc,
                    984:                                            CARDSLOT_EVENT_REMOVAL_16);
                    985:                                } else if (sc->sc_csc->sc_status &
                    986:                                    CARDSLOT_STATUS_CARD_CB) {
                    987:                                        /* Cardbus intr removed */
                    988:                                        cardslot_event_throw(sc->sc_csc,
                    989:                                            CARDSLOT_EVENT_REMOVAL_CB);
                    990:                                }
                    991:                        }
                    992:                } else if (0x00 == (sockstate & CB_SOCKET_STAT_CD) &&
                    993:                    /*
                    994:                     * The pccbbintr may called from powerdown hook when
                    995:                     * the system resumed, to detect the card
                    996:                     * insertion/removal during suspension.
                    997:                     */
                    998:                    (sc->sc_flags & CBB_CARDEXIST) == 0) {
                    999:                        if (sc->sc_flags & CBB_INSERTING) {
                   1000:                                timeout_del(&sc->sc_ins_tmo);
                   1001:                        }
                   1002:                        timeout_add(&sc->sc_ins_tmo, hz / 10);
                   1003:                        sc->sc_flags |= CBB_INSERTING;
                   1004:                }
                   1005:        }
                   1006:
                   1007:        return (1);
                   1008: }
                   1009:
                   1010: /*
                   1011:  * int pccbbintr_function(struct pccbb_softc *sc)
                   1012:  *
                   1013:  *    This function calls each interrupt handler registered at the
                   1014:  *    bridge.  The interrupt handlers are called in registered order.
                   1015:  */
                   1016: int
                   1017: pccbbintr_function(sc)
                   1018:        struct pccbb_softc *sc;
                   1019: {
                   1020:        int retval = 0, val;
                   1021:        struct pccbb_intrhand_list *pil;
                   1022:        int s, splchanged;
                   1023:
                   1024:        for (pil = sc->sc_pil; pil != NULL; pil = pil->pil_next) {
                   1025:                /*
                   1026:                 * XXX priority change.  gross.  I use if-else
                   1027:                 * sentense instead of switch-case sentense because of
                   1028:                 * avoiding duplicate case value error.  More than one
                   1029:                 * IPL_XXX use same value.  It depends on
                   1030:                 * implementation.
                   1031:                 */
                   1032:                splchanged = 1;
                   1033: #if 0
                   1034:                if (pil->pil_level == IPL_SERIAL) {
                   1035:                        s = splserial();
                   1036:                } else if (pil->pil_level == IPL_HIGH) {
                   1037: #endif
                   1038:                if (pil->pil_level == IPL_HIGH) {
                   1039:                        s = splhigh();
                   1040:                } else if (pil->pil_level == IPL_CLOCK) {
                   1041:                        s = splclock();
                   1042:                } else if (pil->pil_level == IPL_AUDIO) {
                   1043:                        s = splaudio();
                   1044:                } else if (pil->pil_level == IPL_VM) {
                   1045:                        s = splvm();
                   1046:                } else if (pil->pil_level == IPL_TTY) {
                   1047:                        s = spltty();
                   1048: #if 0
                   1049:                } else if (pil->pil_level == IPL_SOFTSERIAL) {
                   1050:                        s = splsoftserial();
                   1051: #endif
                   1052:                } else if (pil->pil_level == IPL_NET) {
                   1053:                        s = splnet();
                   1054:                } else {
                   1055:                        splchanged = 0;
                   1056:                        /* XXX: ih lower than IPL_BIO runs w/ IPL_BIO. */
                   1057:                }
                   1058:
                   1059:                val = (*pil->pil_func)(pil->pil_arg);
                   1060:                if (val != 0)
                   1061:                        pil->pil_count.ec_count++;
                   1062:
                   1063:                if (splchanged != 0) {
                   1064:                        splx(s);
                   1065:                }
                   1066:
                   1067:                retval = retval == 1 ? 1 :
                   1068:                    retval == 0 ? val : val != 0 ? val : retval;
                   1069:        }
                   1070:
                   1071:        return retval;
                   1072: }
                   1073:
                   1074: void
                   1075: pci113x_insert(arg)
                   1076:        void *arg;
                   1077: {
                   1078:        struct pccbb_softc *sc = (struct pccbb_softc *)arg;
                   1079:        u_int32_t sockevent, sockstate;
                   1080:
                   1081:        sockevent = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh,
                   1082:            CB_SOCKET_EVENT);
                   1083:        sockstate = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh,
                   1084:            CB_SOCKET_STAT);
                   1085:
                   1086:        if (0 == (sockstate & CB_SOCKET_STAT_CD)) {     /* card exist */
                   1087:                DPRINTF(("%s: 0x%08x", sc->sc_dev.dv_xname, sockevent));
                   1088:                DPRINTF((" card inserted, 0x%08x\n", sockstate));
                   1089:                sc->sc_flags |= CBB_CARDEXIST;
                   1090:                /* call pccard interrupt handler here */
                   1091:                if (sockstate & CB_SOCKET_STAT_16BIT) {
                   1092:                        /* 16-bit card found */
                   1093: /*      pccbb_pcmcia_attach_card(&sc->sc_pcmcia_h); */
                   1094:                        cardslot_event_throw(sc->sc_csc,
                   1095:                            CARDSLOT_EVENT_INSERTION_16);
                   1096:                } else if (sockstate & CB_SOCKET_STAT_CB) {
                   1097:                        /* cardbus card found */
                   1098: /*      cardbus_attach_card(sc->sc_csc); */
                   1099:                        cardslot_event_throw(sc->sc_csc,
                   1100:                            CARDSLOT_EVENT_INSERTION_CB);
                   1101:                } else {
                   1102:                        /* who are you? */
                   1103:                }
                   1104:        } else {
                   1105:                timeout_add(&sc->sc_ins_tmo, hz / 10);
                   1106:        }
                   1107: }
                   1108:
                   1109: #define PCCBB_PCMCIA_OFFSET 0x800
                   1110: u_int8_t
                   1111: pccbb_pcmcia_read(ph, reg)
                   1112:        struct pcic_handle *ph;
                   1113:        int reg;
                   1114: {
                   1115:        bus_space_barrier(ph->ph_bus_t, ph->ph_bus_h,
                   1116:            PCCBB_PCMCIA_OFFSET + reg, 1, BUS_SPACE_BARRIER_READ);
                   1117:
                   1118:        return bus_space_read_1(ph->ph_bus_t, ph->ph_bus_h,
                   1119:            PCCBB_PCMCIA_OFFSET + reg);
                   1120: }
                   1121:
                   1122: void
                   1123: pccbb_pcmcia_write(ph, reg, val)
                   1124:        struct pcic_handle *ph;
                   1125:        int reg;
                   1126:        u_int8_t val;
                   1127: {
                   1128:        bus_space_barrier(ph->ph_bus_t, ph->ph_bus_h,
                   1129:            PCCBB_PCMCIA_OFFSET + reg, 1, BUS_SPACE_BARRIER_WRITE);
                   1130:
                   1131:        bus_space_write_1(ph->ph_bus_t, ph->ph_bus_h, PCCBB_PCMCIA_OFFSET + reg,
                   1132:            val);
                   1133: }
                   1134:
                   1135: /*
                   1136:  * int pccbb_ctrl(cardbus_chipset_tag_t, int)
                   1137:  */
                   1138: int
                   1139: pccbb_ctrl(ct, command)
                   1140:        cardbus_chipset_tag_t ct;
                   1141:        int command;
                   1142: {
                   1143:        struct pccbb_softc *sc = (struct pccbb_softc *)ct;
                   1144:
                   1145:        switch (command) {
                   1146:        case CARDBUS_CD:
                   1147:                if (2 == pccbb_detect_card(sc)) {
                   1148:                        int retval = 0;
                   1149:                        int status = cb_detect_voltage(sc);
                   1150:                        if (PCCARD_VCC_5V & status) {
                   1151:                                retval |= CARDBUS_5V_CARD;
                   1152:                        }
                   1153:                        if (PCCARD_VCC_3V & status) {
                   1154:                                retval |= CARDBUS_3V_CARD;
                   1155:                        }
                   1156:                        if (PCCARD_VCC_XV & status) {
                   1157:                                retval |= CARDBUS_XV_CARD;
                   1158:                        }
                   1159:                        if (PCCARD_VCC_YV & status) {
                   1160:                                retval |= CARDBUS_YV_CARD;
                   1161:                        }
                   1162:                        return retval;
                   1163:                } else {
                   1164:                        return 0;
                   1165:                }
                   1166:                break;
                   1167:        case CARDBUS_RESET:
                   1168:                return cb_reset(sc);
                   1169:                break;
                   1170:        case CARDBUS_IO_ENABLE:       /* fallthrough */
                   1171:        case CARDBUS_IO_DISABLE:      /* fallthrough */
                   1172:        case CARDBUS_MEM_ENABLE:      /* fallthrough */
                   1173:        case CARDBUS_MEM_DISABLE:     /* fallthrough */
                   1174:        case CARDBUS_BM_ENABLE:       /* fallthrough */
                   1175:        case CARDBUS_BM_DISABLE:      /* fallthrough */
                   1176:                return pccbb_cardenable(sc, command);
                   1177:                break;
                   1178:        }
                   1179:
                   1180:        return 0;
                   1181: }
                   1182:
                   1183: /*
                   1184:  * int pccbb_power(cardbus_chipset_tag_t, int)
                   1185:  *   This function returns true when it succeeds and returns false when
                   1186:  *   it fails.
                   1187:  */
                   1188: int
                   1189: pccbb_power(ct, command)
                   1190:        cardbus_chipset_tag_t ct;
                   1191:        int command;
                   1192: {
                   1193:        struct pccbb_softc *sc = (struct pccbb_softc *)ct;
                   1194:
                   1195:        u_int32_t status, sock_ctrl;
                   1196:        bus_space_tag_t memt = sc->sc_base_memt;
                   1197:        bus_space_handle_t memh = sc->sc_base_memh;
                   1198:
                   1199:        DPRINTF(("pccbb_power: %s and %s [%x]\n",
                   1200:            (command & CARDBUS_VCCMASK) == CARDBUS_VCC_UC ? "CARDBUS_VCC_UC" :
                   1201:            (command & CARDBUS_VCCMASK) == CARDBUS_VCC_5V ? "CARDBUS_VCC_5V" :
                   1202:            (command & CARDBUS_VCCMASK) == CARDBUS_VCC_3V ? "CARDBUS_VCC_3V" :
                   1203:            (command & CARDBUS_VCCMASK) == CARDBUS_VCC_XV ? "CARDBUS_VCC_XV" :
                   1204:            (command & CARDBUS_VCCMASK) == CARDBUS_VCC_YV ? "CARDBUS_VCC_YV" :
                   1205:            (command & CARDBUS_VCCMASK) == CARDBUS_VCC_0V ? "CARDBUS_VCC_0V" :
                   1206:            "UNKNOWN",
                   1207:            (command & CARDBUS_VPPMASK) == CARDBUS_VPP_UC ? "CARDBUS_VPP_UC" :
                   1208:            (command & CARDBUS_VPPMASK) == CARDBUS_VPP_12V ? "CARDBUS_VPP_12V" :
                   1209:            (command & CARDBUS_VPPMASK) == CARDBUS_VPP_VCC ? "CARDBUS_VPP_VCC" :
                   1210:            (command & CARDBUS_VPPMASK) == CARDBUS_VPP_0V ? "CARDBUS_VPP_0V" :
                   1211:            "UNKNOWN", command));
                   1212:
                   1213:        status = bus_space_read_4(memt, memh, CB_SOCKET_STAT);
                   1214:        sock_ctrl = bus_space_read_4(memt, memh, CB_SOCKET_CTRL);
                   1215:
                   1216:        switch (command & CARDBUS_VCCMASK) {
                   1217:        case CARDBUS_VCC_UC:
                   1218:                break;
                   1219:        case CARDBUS_VCC_5V:
                   1220:                if (CB_SOCKET_STAT_5VCARD & status) {   /* check 5 V card */
                   1221:                        sock_ctrl &= ~CB_SOCKET_CTRL_VCCMASK;
                   1222:                        sock_ctrl |= CB_SOCKET_CTRL_VCC_5V;
                   1223:                } else {
                   1224:                        printf("%s: BAD voltage request: no 5 V card\n",
                   1225:                            sc->sc_dev.dv_xname);
                   1226:                }
                   1227:                break;
                   1228:        case CARDBUS_VCC_3V:
                   1229:                if (CB_SOCKET_STAT_3VCARD & status) {
                   1230:                        sock_ctrl &= ~CB_SOCKET_CTRL_VCCMASK;
                   1231:                        sock_ctrl |= CB_SOCKET_CTRL_VCC_3V;
                   1232:                } else {
                   1233:                        printf("%s: BAD voltage request: no 3.3 V card\n",
                   1234:                            sc->sc_dev.dv_xname);
                   1235:                }
                   1236:                break;
                   1237:        case CARDBUS_VCC_0V:
                   1238:                sock_ctrl &= ~CB_SOCKET_CTRL_VCCMASK;
                   1239:                break;
                   1240:        default:
                   1241:                return 0;              /* power NEVER changed */
                   1242:                break;
                   1243:        }
                   1244:
                   1245:        switch (command & CARDBUS_VPPMASK) {
                   1246:        case CARDBUS_VPP_UC:
                   1247:                break;
                   1248:        case CARDBUS_VPP_0V:
                   1249:                sock_ctrl &= ~CB_SOCKET_CTRL_VPPMASK;
                   1250:                break;
                   1251:        case CARDBUS_VPP_VCC:
                   1252:                sock_ctrl &= ~CB_SOCKET_CTRL_VPPMASK;
                   1253:                sock_ctrl |= ((sock_ctrl >> 4) & 0x07);
                   1254:                break;
                   1255:        case CARDBUS_VPP_12V:
                   1256:                sock_ctrl &= ~CB_SOCKET_CTRL_VPPMASK;
                   1257:                sock_ctrl |= CB_SOCKET_CTRL_VPP_12V;
                   1258:                break;
                   1259:        }
                   1260:
                   1261: #if 0
                   1262:        DPRINTF(("sock_ctrl: %x\n", sock_ctrl));
                   1263: #endif
                   1264:        bus_space_write_4(memt, memh, CB_SOCKET_CTRL, sock_ctrl);
                   1265:        status = bus_space_read_4(memt, memh, CB_SOCKET_STAT);
                   1266:
                   1267:        if (status & CB_SOCKET_STAT_BADVCC) {   /* bad Vcc request */
                   1268:                printf
                   1269:                    ("%s: bad Vcc request. sock_ctrl 0x%x, sock_status 0x%x\n",
                   1270:                    sc->sc_dev.dv_xname, sock_ctrl, status);
                   1271:                DPRINTF(("pccbb_power: %s and %s [%x]\n",
                   1272:                    (command & CARDBUS_VCCMASK) ==
                   1273:                    CARDBUS_VCC_UC ? "CARDBUS_VCC_UC" : (command &
                   1274:                    CARDBUS_VCCMASK) ==
                   1275:                    CARDBUS_VCC_5V ? "CARDBUS_VCC_5V" : (command &
                   1276:                    CARDBUS_VCCMASK) ==
                   1277:                    CARDBUS_VCC_3V ? "CARDBUS_VCC_3V" : (command &
                   1278:                    CARDBUS_VCCMASK) ==
                   1279:                    CARDBUS_VCC_XV ? "CARDBUS_VCC_XV" : (command &
                   1280:                    CARDBUS_VCCMASK) ==
                   1281:                    CARDBUS_VCC_YV ? "CARDBUS_VCC_YV" : (command &
                   1282:                    CARDBUS_VCCMASK) ==
                   1283:                    CARDBUS_VCC_0V ? "CARDBUS_VCC_0V" : "UNKNOWN",
                   1284:                    (command & CARDBUS_VPPMASK) ==
                   1285:                    CARDBUS_VPP_UC ? "CARDBUS_VPP_UC" : (command &
                   1286:                    CARDBUS_VPPMASK) ==
                   1287:                    CARDBUS_VPP_12V ? "CARDBUS_VPP_12V" : (command &
                   1288:                    CARDBUS_VPPMASK) ==
                   1289:                    CARDBUS_VPP_VCC ? "CARDBUS_VPP_VCC" : (command &
                   1290:                    CARDBUS_VPPMASK) ==
                   1291:                    CARDBUS_VPP_0V ? "CARDBUS_VPP_0V" : "UNKNOWN", command));
                   1292: #if 0
                   1293:                if (command == (CARDBUS_VCC_0V | CARDBUS_VPP_0V)) {
                   1294:                        u_int32_t force =
                   1295:                            bus_space_read_4(memt, memh, CB_SOCKET_FORCE);
                   1296:                        /* Reset Bad Vcc request */
                   1297:                        force &= ~CB_SOCKET_FORCE_BADVCC;
                   1298:                        bus_space_write_4(memt, memh, CB_SOCKET_FORCE, force);
                   1299:                        printf("new status 0x%x\n", bus_space_read_4(memt, memh,
                   1300:                            CB_SOCKET_STAT));
                   1301:                        return 1;
                   1302:                }
                   1303: #endif
                   1304:                return 0;
                   1305:        }
                   1306:
                   1307:        /*
                   1308:         * XXX delay 300 ms: though the standard defines that the Vcc set-up
                   1309:         * time is 20 ms, some PC-Card bridge requires longer duration.
                   1310:         */
                   1311:        delay(300 * 1000);
                   1312:
                   1313:        return 1;                      /* power changed correctly */
                   1314: }
                   1315:
                   1316: #if defined CB_PCMCIA_POLL
                   1317: struct cb_poll_str {
                   1318:        void *arg;
                   1319:        int (*func)(void *);
                   1320:        int level;
                   1321:        pccard_chipset_tag_t ct;
                   1322:        int count;
                   1323: };
                   1324:
                   1325: static struct cb_poll_str cb_poll[10];
                   1326: static int cb_poll_n = 0;
                   1327: static struct timeout cb_poll_timeout;
                   1328:
                   1329: void cb_pcmcia_poll(void *arg);
                   1330:
                   1331: void
                   1332: cb_pcmcia_poll(arg)
                   1333:        void *arg;
                   1334: {
                   1335:        struct cb_poll_str *poll = arg;
                   1336:        struct cbb_pcmcia_softc *psc = (void *)poll->ct->v;
                   1337:        struct pccbb_softc *sc = psc->cpc_parent;
                   1338:        int s;
                   1339:        u_int32_t spsr;                /* socket present-state reg */
                   1340:
                   1341:        timeout_set(&cb_poll_timeout, cb_pcmcia_poll, arg);
                   1342:        timeout_add(&cb_poll_timeout, hz / 10);
                   1343:        switch (poll->level) {
                   1344:        case IPL_NET:
                   1345:                s = splnet();
                   1346:                break;
                   1347:        case IPL_BIO:
                   1348:                s = splbio();
                   1349:                break;
                   1350:        case IPL_TTY:                  /* fallthrough */
                   1351:        default:
                   1352:                s = spltty();
                   1353:                break;
                   1354:        }
                   1355:
                   1356:        spsr =
                   1357:            bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh,
                   1358:            CB_SOCKET_STAT);
                   1359:
                   1360: #if defined CB_PCMCIA_POLL_ONLY && defined LEVEL2
                   1361:        if (!(spsr & 0x40)) {          /* CINT low */
                   1362: #else
                   1363:        if (1) {
                   1364: #endif
                   1365:                if ((*poll->func) (poll->arg) == 1) {
                   1366:                        ++poll->count;
                   1367:                        printf("intr: reported from poller, 0x%x\n", spsr);
                   1368: #if defined LEVEL2
                   1369:                } else {
                   1370:                        printf("intr: miss! 0x%x\n", spsr);
                   1371: #endif
                   1372:                }
                   1373:        }
                   1374:        splx(s);
                   1375: }
                   1376: #endif /* defined CB_PCMCIA_POLL */
                   1377:
                   1378: /*
                   1379:  * int pccbb_detect_card(struct pccbb_softc *sc)
                   1380:  *   return value:  0 if no card exists.
                   1381:  *                  1 if 16-bit card exists.
                   1382:  *                  2 if cardbus card exists.
                   1383:  */
                   1384: int
                   1385: pccbb_detect_card(sc)
                   1386:        struct pccbb_softc *sc;
                   1387: {
                   1388:        bus_space_handle_t base_memh = sc->sc_base_memh;
                   1389:        bus_space_tag_t base_memt = sc->sc_base_memt;
                   1390:        u_int32_t sockstat =
                   1391:            bus_space_read_4(base_memt, base_memh, CB_SOCKET_STAT);
                   1392:        int retval = 0;
                   1393:
                   1394:        /*
                   1395:         * The SCM Microsystems TI1225-based PCI-CardBus dock card that
                   1396:         * ships with some Lucent WaveLAN cards has only one physical slot
                   1397:         * but OpenBSD probes two. The phantom card in the second slot can
                   1398:         * be ignored by punting on unsupported voltages.
                   1399:         */
                   1400:        if (sockstat & CB_SOCKET_STAT_XVCARD)
                   1401:                return 0;
                   1402:
                   1403:        /* CD1 and CD2 asserted */
                   1404:        if (0x00 == (sockstat & CB_SOCKET_STAT_CD)) {
                   1405:                /* card must be present */
                   1406:                if (!(CB_SOCKET_STAT_NOTCARD & sockstat)) {
                   1407:                        /* NOTACARD DEASSERTED */
                   1408:                        if (CB_SOCKET_STAT_CB & sockstat) {
                   1409:                                /* CardBus mode */
                   1410:                                retval = 2;
                   1411:                        } else if (CB_SOCKET_STAT_16BIT & sockstat) {
                   1412:                                /* 16-bit mode */
                   1413:                                retval = 1;
                   1414:                        }
                   1415:                }
                   1416:        }
                   1417:        return retval;
                   1418: }
                   1419:
                   1420: /*
                   1421:  * int cb_reset(struct pccbb_softc *sc)
                   1422:  *   This function resets CardBus card.
                   1423:  */
                   1424: int
                   1425: cb_reset(sc)
                   1426:        struct pccbb_softc *sc;
                   1427: {
                   1428:        /*
                   1429:         * Reset Assert at least 20 ms
                   1430:         * Some machines request longer duration.
                   1431:         */
                   1432:        int reset_duration =
                   1433:            (sc->sc_chipset == CB_RX5C47X ? 400 * 1000 : 40 * 1000);
                   1434:        u_int32_t bcr = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR);
                   1435:
                   1436:        /* Reset bit Assert (bit 6 at 0x3E) */
                   1437:        bcr |= CB_BCR_RESET_ENABLE;
                   1438:        pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR, bcr);
                   1439:        delay(reset_duration);
                   1440:
                   1441:        if (CBB_CARDEXIST & sc->sc_flags) {     /* A card exists.  Reset it! */
                   1442:                /* Reset bit Deassert (bit 6 at 0x3E) */
                   1443:                bcr &= ~CB_BCR_RESET_ENABLE;
                   1444:                pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR, bcr);
                   1445:                delay(reset_duration);
                   1446:        }
                   1447:        /* No card found on the slot. Keep Reset. */
                   1448:        return 1;
                   1449: }
                   1450:
                   1451: /*
                   1452:  * int cb_detect_voltage(struct pccbb_softc *sc)
                   1453:  *  This function detect card Voltage.
                   1454:  */
                   1455: int
                   1456: cb_detect_voltage(sc)
                   1457:        struct pccbb_softc *sc;
                   1458: {
                   1459:        u_int32_t psr;                 /* socket present-state reg */
                   1460:        bus_space_tag_t iot = sc->sc_base_memt;
                   1461:        bus_space_handle_t ioh = sc->sc_base_memh;
                   1462:        int vol = PCCARD_VCC_UKN;      /* set 0 */
                   1463:
                   1464:        psr = bus_space_read_4(iot, ioh, CB_SOCKET_STAT);
                   1465:
                   1466:        if (0x400u & psr) {
                   1467:                vol |= PCCARD_VCC_5V;
                   1468:        }
                   1469:        if (0x800u & psr) {
                   1470:                vol |= PCCARD_VCC_3V;
                   1471:        }
                   1472:
                   1473:        return vol;
                   1474: }
                   1475:
                   1476: int
                   1477: cbbprint(aux, pcic)
                   1478:        void *aux;
                   1479:        const char *pcic;
                   1480: {
                   1481: /*
                   1482:   struct cbslot_attach_args *cba = aux;
                   1483:
                   1484:   if (cba->cba_slot >= 0) {
                   1485:     printf(" slot %d", cba->cba_slot);
                   1486:   }
                   1487: */
                   1488:        return UNCONF;
                   1489: }
                   1490:
                   1491: /*
                   1492:  * int pccbb_cardenable(struct pccbb_softc *sc, int function)
                   1493:  *   This function enables and disables the card
                   1494:  */
                   1495: int
                   1496: pccbb_cardenable(sc, function)
                   1497:        struct pccbb_softc *sc;
                   1498:        int function;
                   1499: {
                   1500:        u_int32_t command =
                   1501:            pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG);
                   1502:
                   1503:        DPRINTF(("pccbb_cardenable:"));
                   1504:        switch (function) {
                   1505:        case CARDBUS_IO_ENABLE:
                   1506:                command |= PCI_COMMAND_IO_ENABLE;
                   1507:                break;
                   1508:        case CARDBUS_IO_DISABLE:
                   1509:                command &= ~PCI_COMMAND_IO_ENABLE;
                   1510:                break;
                   1511:        case CARDBUS_MEM_ENABLE:
                   1512:                command |= PCI_COMMAND_MEM_ENABLE;
                   1513:                break;
                   1514:        case CARDBUS_MEM_DISABLE:
                   1515:                command &= ~PCI_COMMAND_MEM_ENABLE;
                   1516:                break;
                   1517:        case CARDBUS_BM_ENABLE:
                   1518:                command |= PCI_COMMAND_MASTER_ENABLE;
                   1519:                break;
                   1520:        case CARDBUS_BM_DISABLE:
                   1521:                command &= ~PCI_COMMAND_MASTER_ENABLE;
                   1522:                break;
                   1523:        default:
                   1524:                return 0;
                   1525:        }
                   1526:
                   1527:        pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG, command);
                   1528:        DPRINTF((" command reg 0x%x\n", command));
                   1529:        return 1;
                   1530: }
                   1531:
                   1532: /*
                   1533:  * void *pccbb_cb_intr_establish(cardbus_chipset_tag_t ct,
                   1534:  *                                     int irq,
                   1535:  *                                     int level,
                   1536:  *                                     int (* func)(void *),
                   1537:  *                                     void *arg,
                   1538:  *                                     const char *name)
                   1539:  *
                   1540:  *   This function registers an interrupt handler at the bridge, in
                   1541:  *   order not to call the interrupt handlers of child devices when
                   1542:  *   a card-deletion interrupt occurs.
                   1543:  *
                   1544:  *   The arguments irq is not used because pccbb selects intr vector.
                   1545:  */
                   1546: void *
                   1547: pccbb_cb_intr_establish(ct, irq, level, func, arg, name)
                   1548:        cardbus_chipset_tag_t ct;
                   1549:        int irq, level;
                   1550:        int (*func)(void *);
                   1551:        void *arg;
                   1552:        const char *name;
                   1553: {
                   1554:        struct pccbb_softc *sc = (struct pccbb_softc *)ct;
                   1555:
                   1556:        return pccbb_intr_establish(sc, irq, level, func, arg, name);
                   1557: }
                   1558:
                   1559:
                   1560: /*
                   1561:  * void *pccbb_cb_intr_disestablish(cardbus_chipset_tag_t ct,
                   1562:  *                                        void *ih)
                   1563:  *
                   1564:  *   This function removes an interrupt handler pointed by ih.
                   1565:  */
                   1566: void
                   1567: pccbb_cb_intr_disestablish(ct, ih)
                   1568:        cardbus_chipset_tag_t ct;
                   1569:        void *ih;
                   1570: {
                   1571:        struct pccbb_softc *sc = (struct pccbb_softc *)ct;
                   1572:
                   1573:        pccbb_intr_disestablish(sc, ih);
                   1574: }
                   1575:
                   1576:
                   1577: /*
                   1578:  * void *pccbb_intr_establish(struct pccbb_softc *sc,
                   1579:  *                                  int irq,
                   1580:  *                                  int level,
                   1581:  *                                  int (* func)(void *),
                   1582:  *                                  void *arg,
                   1583:  *                                  const char *name)
                   1584:  *
                   1585:  *   This function registers an interrupt handler at the bridge, in
                   1586:  *   order not to call the interrupt handlers of child devices when
                   1587:  *   a card-deletion interrupt occurs.
                   1588:  *
                   1589:  *   The arguments irq and level are not used.
                   1590:  */
                   1591: void *
                   1592: pccbb_intr_establish(sc, irq, level, func, arg, name)
                   1593:        struct pccbb_softc *sc;
                   1594:        int irq, level;
                   1595:        int (*func)(void *);
                   1596:        void *arg;
                   1597:        const char *name;
                   1598: {
                   1599:        struct pccbb_intrhand_list *pil, *newpil;
                   1600:        pcireg_t reg;
                   1601:
                   1602:        DPRINTF(("pccbb_intr_establish start. %p\n", sc->sc_pil));
                   1603:
                   1604:        if (sc->sc_pil == NULL) {
                   1605:                /* initialize bridge intr routing */
                   1606:                reg = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR);
                   1607:                reg &= ~CB_BCR_INTR_IREQ_ENABLE;
                   1608:                pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR, reg);
                   1609:
                   1610:                switch (sc->sc_chipset) {
                   1611:                case CB_TI113X:
                   1612:                        reg = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CBCTRL);
                   1613:                        /* functional intr enabled */
                   1614:                        reg |= PCI113X_CBCTRL_PCI_INTR;
                   1615:                        pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_CBCTRL, reg);
                   1616:                        break;
                   1617:                default:
                   1618:                        break;
                   1619:                }
                   1620:        }
                   1621:
                   1622:        /*
                   1623:         * Allocate a room for interrupt handler structure.
                   1624:         */
                   1625:        newpil = (struct pccbb_intrhand_list *)
                   1626:                malloc(sizeof(struct pccbb_intrhand_list), M_DEVBUF, M_WAITOK);
                   1627:
                   1628:        newpil->pil_func = func;
                   1629:        newpil->pil_arg = arg;
                   1630:        newpil->pil_level = level;
                   1631:        evcount_attach(&newpil->pil_count, name, &sc->sc_intrline,
                   1632:            &evcount_intr);
                   1633:        newpil->pil_next = NULL;
                   1634:
                   1635:        if (sc->sc_pil == NULL) {
                   1636:                sc->sc_pil = newpil;
                   1637:        } else {
                   1638:                for (pil = sc->sc_pil; pil->pil_next != NULL;
                   1639:                    pil = pil->pil_next);
                   1640:                pil->pil_next = newpil;
                   1641:        }
                   1642:
                   1643:        DPRINTF(("pccbb_intr_establish add pil. %p\n", sc->sc_pil));
                   1644:
                   1645:        return newpil;
                   1646: }
                   1647:
                   1648: /*
                   1649:  * void *pccbb_intr_disestablish(struct pccbb_softc *sc,
                   1650:  *                                     void *ih)
                   1651:  *
                   1652:  *   This function removes an interrupt handler pointed by ih.
                   1653:  */
                   1654: void
                   1655: pccbb_intr_disestablish(sc, ih)
                   1656:        struct pccbb_softc *sc;
                   1657:        void *ih;
                   1658: {
                   1659:        struct pccbb_intrhand_list *pil, **pil_prev;
                   1660:        pcireg_t reg;
                   1661:
                   1662:        DPRINTF(("pccbb_intr_disestablish start. %p\n", sc->sc_pil));
                   1663:
                   1664:        pil_prev = &sc->sc_pil;
                   1665:
                   1666:        for (pil = sc->sc_pil; pil != NULL; pil = pil->pil_next) {
                   1667:                if (pil == ih) {
                   1668:                        evcount_detach(&pil->pil_count);
                   1669:                        *pil_prev = pil->pil_next;
                   1670:                        free(pil, M_DEVBUF);
                   1671:                        DPRINTF(("pccbb_intr_disestablish frees one pil\n"));
                   1672:                        break;
                   1673:                }
                   1674:                pil_prev = &pil->pil_next;
                   1675:        }
                   1676:
                   1677:        if (sc->sc_pil == NULL) {
                   1678:                /* No interrupt handlers */
                   1679:
                   1680:                DPRINTF(("pccbb_intr_disestablish: no interrupt handler\n"));
                   1681:
                   1682:                /* stop routing PCI intr */
                   1683:                reg = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR);
                   1684:                reg |= CB_BCR_INTR_IREQ_ENABLE;
                   1685:                pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR, reg);
                   1686:
                   1687:                switch (sc->sc_chipset) {
                   1688:                case CB_TI113X:
                   1689:                        reg = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CBCTRL);
                   1690:                        /* functional intr disabled */
                   1691:                        reg &= ~PCI113X_CBCTRL_PCI_INTR;
                   1692:                        pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_CBCTRL, reg);
                   1693:                        break;
                   1694:                default:
                   1695:                        break;
                   1696:                }
                   1697:        }
                   1698: }
                   1699:
                   1700: #if defined SHOW_REGS
                   1701: void
                   1702: cb_show_regs(pc, tag, memt, memh)
                   1703:        pci_chipset_tag_t pc;
                   1704:        pcitag_t tag;
                   1705:        bus_space_tag_t memt;
                   1706:        bus_space_handle_t memh;
                   1707: {
                   1708:        int i;
                   1709:        printf("PCI config regs:");
                   1710:        for (i = 0; i < 0x50; i += 4) {
                   1711:                if (i % 16 == 0) {
                   1712:                        printf("\n 0x%02x:", i);
                   1713:                }
                   1714:                printf(" %08x", pci_conf_read(pc, tag, i));
                   1715:        }
                   1716:        for (i = 0x80; i < 0xb0; i += 4) {
                   1717:                if (i % 16 == 0) {
                   1718:                        printf("\n 0x%02x:", i);
                   1719:                }
                   1720:                printf(" %08x", pci_conf_read(pc, tag, i));
                   1721:        }
                   1722:
                   1723:        if (memh == 0) {
                   1724:                printf("\n");
                   1725:                return;
                   1726:        }
                   1727:
                   1728:        printf("\nsocket regs:");
                   1729:        for (i = 0; i <= 0x10; i += 0x04) {
                   1730:                printf(" %08x", bus_space_read_4(memt, memh, i));
                   1731:        }
                   1732:        printf("\nExCA regs:");
                   1733:        for (i = 0; i < 0x08; ++i) {
                   1734:                printf(" %02x", bus_space_read_1(memt, memh, 0x800 + i));
                   1735:        }
                   1736:        printf("\n");
                   1737:        return;
                   1738: }
                   1739: #endif
                   1740:
                   1741: /*
                   1742:  * cardbustag_t pccbb_make_tag(cardbus_chipset_tag_t cc,
                   1743:  *                                    int busno, int devno, int function)
                   1744:  *   This is the function to make a tag to access config space of
                   1745:  *  a CardBus Card.  It works same as pci_conf_read.
                   1746:  */
                   1747: cardbustag_t
                   1748: pccbb_make_tag(cc, busno, devno, function)
                   1749:        cardbus_chipset_tag_t cc;
                   1750:        int busno, devno, function;
                   1751: {
                   1752:        struct pccbb_softc *sc = (struct pccbb_softc *)cc;
                   1753:
                   1754:        return pci_make_tag(sc->sc_pc, busno, devno, function);
                   1755: }
                   1756:
                   1757: void
                   1758: pccbb_free_tag(cc, tag)
                   1759:        cardbus_chipset_tag_t cc;
                   1760:        cardbustag_t tag;
                   1761: {
                   1762: }
                   1763:
                   1764: /*
                   1765:  * cardbusreg_t pccbb_conf_read(cardbus_chipset_tag_t cc,
                   1766:  *                                     cardbustag_t tag, int offset)
                   1767:  *   This is the function to read the config space of a CardBus Card.
                   1768:  *  It works same as pci_conf_read.
                   1769:  */
                   1770: cardbusreg_t
                   1771: pccbb_conf_read(cc, tag, offset)
                   1772:        cardbus_chipset_tag_t cc;
                   1773:        cardbustag_t tag;
                   1774:        int offset;                    /* register offset */
                   1775: {
                   1776:        struct pccbb_softc *sc = (struct pccbb_softc *)cc;
                   1777:
                   1778:        return pci_conf_read(sc->sc_pc, tag, offset);
                   1779: }
                   1780:
                   1781: /*
                   1782:  * void pccbb_conf_write(cardbus_chipset_tag_t cc, cardbustag_t tag,
                   1783:  *                              int offs, cardbusreg_t val)
                   1784:  *   This is the function to write the config space of a CardBus Card.
                   1785:  *  It works same as pci_conf_write.
                   1786:  */
                   1787: void
                   1788: pccbb_conf_write(cc, tag, reg, val)
                   1789:        cardbus_chipset_tag_t cc;
                   1790:        cardbustag_t tag;
                   1791:        int reg;                       /* register offset */
                   1792:        cardbusreg_t val;
                   1793: {
                   1794:        struct pccbb_softc *sc = (struct pccbb_softc *)cc;
                   1795:
                   1796:        pci_conf_write(sc->sc_pc, tag, reg, val);
                   1797: }
                   1798:
                   1799: #if 0
                   1800: int
                   1801: pccbb_new_pcmcia_io_alloc(pcmcia_chipset_handle_t pch,
                   1802:     bus_addr_t start, bus_size_t size, bus_size_t align, bus_addr_t mask,
                   1803:     int speed, int flags,
                   1804:     bus_space_handle_t * iohp)
                   1805: #endif
                   1806: /*
                   1807:  * int pccbb_pcmcia_io_alloc(pcmcia_chipset_handle_t pch,
                   1808:  *                                  bus_addr_t start, bus_size_t size,
                   1809:  *                                  bus_size_t align,
                   1810:  *                                  struct pcmcia_io_handle *pcihp
                   1811:  *
                   1812:  * This function only allocates I/O region for pccard. This function
                   1813:  * never maps the allocated region to pccard I/O area.
                   1814:  *
                   1815:  * XXX: The interface of this function is not very good, I believe.
                   1816:  */
                   1817: int
                   1818: pccbb_pcmcia_io_alloc(pch, start, size, align, pcihp)
                   1819:        pcmcia_chipset_handle_t pch;
                   1820:        bus_addr_t start;              /* start address */
                   1821:        bus_size_t size;
                   1822:        bus_size_t align;
                   1823:        struct pcmcia_io_handle *pcihp;
                   1824: {
                   1825:        struct pcic_handle *ph = (struct pcic_handle *)pch;
                   1826:        bus_addr_t ioaddr;
                   1827:        int flags = 0;
                   1828:        bus_space_tag_t iot;
                   1829:        bus_space_handle_t ioh;
                   1830:        bus_addr_t mask;
                   1831:        rbus_tag_t rb;
                   1832:
                   1833:        if (align == 0) {
                   1834:                align = size;          /* XXX: funny??? */
                   1835:        }
                   1836:
                   1837:        if (start != 0) {
                   1838:                /* XXX: assume all card decode lower 10 bits by its hardware */
                   1839:                mask = 0x3ff;
                   1840:                /* enforce to use only masked address */
                   1841:                start &= mask;
                   1842:        } else {
                   1843:                /*
                   1844:                 * calculate mask:
                   1845:                 *  1. get the most significant bit of size (call it msb).
                   1846:                 *  2. compare msb with the value of size.
                   1847:                 *  3. if size is larger, shift msb left once.
                   1848:                 *  4. obtain mask value to decrement msb.
                   1849:                 */
                   1850:                bus_size_t size_tmp = size;
                   1851:                int shifts = 0;
                   1852:
                   1853:                mask = 1;
                   1854:                while (size_tmp) {
                   1855:                        ++shifts;
                   1856:                        size_tmp >>= 1;
                   1857:                }
                   1858:                mask = (1 << shifts);
                   1859:                if (mask < size) {
                   1860:                        mask <<= 1;
                   1861:                }
                   1862:                mask--;
                   1863:        }
                   1864:
                   1865:        /*
                   1866:         * Allocate some arbitrary I/O space.
                   1867:         */
                   1868:
                   1869:        iot = ((struct pccbb_softc *)(ph->ph_parent))->sc_iot;
                   1870:
                   1871:        rb = ((struct pccbb_softc *)(ph->ph_parent))->sc_rbus_iot;
                   1872:        if (rbus_space_alloc(rb, start, size, mask, align, 0, &ioaddr, &ioh)) {
                   1873:                return 1;
                   1874:        }
                   1875:
                   1876:        pcihp->iot = iot;
                   1877:        pcihp->ioh = ioh;
                   1878:        pcihp->addr = ioaddr;
                   1879:        pcihp->size = size;
                   1880:        pcihp->flags = flags;
                   1881:
                   1882:        return 0;
                   1883: }
                   1884:
                   1885: /*
                   1886:  * int pccbb_pcmcia_io_free(pcmcia_chipset_handle_t pch,
                   1887:  *                                 struct pcmcia_io_handle *pcihp)
                   1888:  *
                   1889:  * This function only frees I/O region for pccard.
                   1890:  *
                   1891:  * XXX: The interface of this function is not very good, I believe.
                   1892:  */
                   1893: void
                   1894: pccbb_pcmcia_io_free(pch, pcihp)
                   1895:        pcmcia_chipset_handle_t pch;
                   1896:        struct pcmcia_io_handle *pcihp;
                   1897: {
                   1898:        bus_space_handle_t ioh = pcihp->ioh;
                   1899:        bus_size_t size = pcihp->size;
                   1900:
                   1901:        struct pccbb_softc *sc =
                   1902:            (struct pccbb_softc *)((struct pcic_handle *)pch)->ph_parent;
                   1903:        rbus_tag_t rb = sc->sc_rbus_iot;
                   1904:
                   1905:        rbus_space_free(rb, ioh, size, NULL);
                   1906: }
                   1907:
                   1908: /*
                   1909:  * int pccbb_pcmcia_io_map(pcmcia_chipset_handle_t pch, int width,
                   1910:  *                                bus_addr_t offset, bus_size_t size,
                   1911:  *                                struct pcmcia_io_handle *pcihp,
                   1912:  *                                int *windowp)
                   1913:  *
                   1914:  * This function maps the allocated I/O region to pccard. This function
                   1915:  * never allocates any I/O region for pccard I/O area.  I don't
                   1916:  * understand why the original authors of pcmciabus separated alloc and
                   1917:  * map.  I believe the two must be unite.
                   1918:  *
                   1919:  * XXX: no wait timing control?
                   1920:  */
                   1921: int
                   1922: pccbb_pcmcia_io_map(pch, width, offset, size, pcihp, windowp)
                   1923:        pcmcia_chipset_handle_t pch;
                   1924:        int width;
                   1925:        bus_addr_t offset;
                   1926:        bus_size_t size;
                   1927:        struct pcmcia_io_handle *pcihp;
                   1928:        int *windowp;
                   1929: {
                   1930:        struct pcic_handle *ph = (struct pcic_handle *)pch;
                   1931:        bus_addr_t ioaddr = pcihp->addr + offset;
                   1932:        int i, win;
                   1933: #if defined CBB_DEBUG
                   1934:        static char *width_names[] = { "dynamic", "io8", "io16" };
                   1935: #endif
                   1936:
                   1937:        /* Sanity check I/O handle. */
                   1938:
                   1939:        if (((struct pccbb_softc *)ph->ph_parent)->sc_iot != pcihp->iot) {
                   1940:                panic("pccbb_pcmcia_io_map iot is bogus");
                   1941:        }
                   1942:
                   1943:        /* XXX Sanity check offset/size. */
                   1944:
                   1945:        win = -1;
                   1946:        for (i = 0; i < PCIC_IO_WINS; i++) {
                   1947:                if ((ph->ioalloc & (1 << i)) == 0) {
                   1948:                        win = i;
                   1949:                        ph->ioalloc |= (1 << i);
                   1950:                        break;
                   1951:                }
                   1952:        }
                   1953:
                   1954:        if (win == -1) {
                   1955:                return 1;
                   1956:        }
                   1957:
                   1958:        *windowp = win;
                   1959:
                   1960:        /* XXX this is pretty gross */
                   1961:
                   1962:        DPRINTF(("pccbb_pcmcia_io_map window %d %s port %lx+%lx\n",
                   1963:            win, width_names[width], (u_long) ioaddr, (u_long) size));
                   1964:
                   1965:        /* XXX wtf is this doing here? */
                   1966:
                   1967: #if 0
                   1968:        printf(" port 0x%lx", (u_long) ioaddr);
                   1969:        if (size > 1) {
                   1970:                printf("-0x%lx", (u_long) ioaddr + (u_long) size - 1);
                   1971:        }
                   1972: #endif
                   1973:
                   1974:        ph->io[win].addr = ioaddr;
                   1975:        ph->io[win].size = size;
                   1976:        ph->io[win].width = width;
                   1977:
                   1978:        /* actual dirty register-value changing in the function below. */
                   1979:        pccbb_pcmcia_do_io_map(ph, win);
                   1980:
                   1981:        return 0;
                   1982: }
                   1983:
                   1984: /*
                   1985:  * void pccbb_pcmcia_do_io_map(struct pcic_handle *h, int win)
                   1986:  *
                   1987:  * This function changes register-value to map I/O region for pccard.
                   1988:  */
                   1989: void
                   1990: pccbb_pcmcia_do_io_map(ph, win)
                   1991:        struct pcic_handle *ph;
                   1992:        int win;
                   1993: {
                   1994:        static u_int8_t pcic_iowidth[3] = {
                   1995:                PCIC_IOCTL_IO0_IOCS16SRC_CARD,
                   1996:                PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE |
                   1997:                    PCIC_IOCTL_IO0_DATASIZE_8BIT,
                   1998:                PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE |
                   1999:                    PCIC_IOCTL_IO0_DATASIZE_16BIT,
                   2000:        };
                   2001:
                   2002: #define PCIC_SIA_START_LOW 0
                   2003: #define PCIC_SIA_START_HIGH 1
                   2004: #define PCIC_SIA_STOP_LOW 2
                   2005: #define PCIC_SIA_STOP_HIGH 3
                   2006:
                   2007:        int regbase_win = 0x8 + win * 0x04;
                   2008:        u_int8_t ioctl, enable;
                   2009:
                   2010:        DPRINTF(
                   2011:            ("pccbb_pcmcia_do_io_map win %d addr 0x%lx size 0x%lx width %d\n",
                   2012:            win, (long)ph->io[win].addr, (long)ph->io[win].size,
                   2013:            ph->io[win].width * 8));
                   2014:
                   2015:        Pcic_write(ph, regbase_win + PCIC_SIA_START_LOW,
                   2016:            ph->io[win].addr & 0xff);
                   2017:        Pcic_write(ph, regbase_win + PCIC_SIA_START_HIGH,
                   2018:            (ph->io[win].addr >> 8) & 0xff);
                   2019:
                   2020:        Pcic_write(ph, regbase_win + PCIC_SIA_STOP_LOW,
                   2021:            (ph->io[win].addr + ph->io[win].size - 1) & 0xff);
                   2022:        Pcic_write(ph, regbase_win + PCIC_SIA_STOP_HIGH,
                   2023:            ((ph->io[win].addr + ph->io[win].size - 1) >> 8) & 0xff);
                   2024:
                   2025:        ioctl = Pcic_read(ph, PCIC_IOCTL);
                   2026:        enable = Pcic_read(ph, PCIC_ADDRWIN_ENABLE);
                   2027:        switch (win) {
                   2028:        case 0:
                   2029:                ioctl &= ~(PCIC_IOCTL_IO0_WAITSTATE | PCIC_IOCTL_IO0_ZEROWAIT |
                   2030:                    PCIC_IOCTL_IO0_IOCS16SRC_MASK |
                   2031:                    PCIC_IOCTL_IO0_DATASIZE_MASK);
                   2032:                ioctl |= pcic_iowidth[ph->io[win].width];
                   2033:                enable |= PCIC_ADDRWIN_ENABLE_IO0;
                   2034:                break;
                   2035:        case 1:
                   2036:                ioctl &= ~(PCIC_IOCTL_IO1_WAITSTATE | PCIC_IOCTL_IO1_ZEROWAIT |
                   2037:                    PCIC_IOCTL_IO1_IOCS16SRC_MASK |
                   2038:                    PCIC_IOCTL_IO1_DATASIZE_MASK);
                   2039:                ioctl |= (pcic_iowidth[ph->io[win].width] << 4);
                   2040:                enable |= PCIC_ADDRWIN_ENABLE_IO1;
                   2041:                break;
                   2042:        }
                   2043:        Pcic_write(ph, PCIC_IOCTL, ioctl);
                   2044:        Pcic_write(ph, PCIC_ADDRWIN_ENABLE, enable);
                   2045: #if defined CBB_DEBUG
                   2046:        {
                   2047:                u_int8_t start_low =
                   2048:                    Pcic_read(ph, regbase_win + PCIC_SIA_START_LOW);
                   2049:                u_int8_t start_high =
                   2050:                    Pcic_read(ph, regbase_win + PCIC_SIA_START_HIGH);
                   2051:                u_int8_t stop_low =
                   2052:                    Pcic_read(ph, regbase_win + PCIC_SIA_STOP_LOW);
                   2053:                u_int8_t stop_high =
                   2054:                    Pcic_read(ph, regbase_win + PCIC_SIA_STOP_HIGH);
                   2055:                printf
                   2056:                    (" start %02x %02x, stop %02x %02x, ioctl %02x enable %02x\n",
                   2057:                    start_low, start_high, stop_low, stop_high, ioctl, enable);
                   2058:        }
                   2059: #endif
                   2060: }
                   2061:
                   2062: /*
                   2063:  * void pccbb_pcmcia_io_unmap(pcmcia_chipset_handle_t *h, int win)
                   2064:  *
                   2065:  * This function unmaps I/O region.  No return value.
                   2066:  */
                   2067: void
                   2068: pccbb_pcmcia_io_unmap(pch, win)
                   2069:        pcmcia_chipset_handle_t pch;
                   2070:        int win;
                   2071: {
                   2072:        struct pcic_handle *ph = (struct pcic_handle *)pch;
                   2073:        int reg;
                   2074:
                   2075:        if (win >= PCIC_IO_WINS || win < 0) {
                   2076:                panic("pccbb_pcmcia_io_unmap: window out of range");
                   2077:        }
                   2078:
                   2079:        reg = Pcic_read(ph, PCIC_ADDRWIN_ENABLE);
                   2080:        switch (win) {
                   2081:        case 0:
                   2082:                reg &= ~PCIC_ADDRWIN_ENABLE_IO0;
                   2083:                break;
                   2084:        case 1:
                   2085:                reg &= ~PCIC_ADDRWIN_ENABLE_IO1;
                   2086:                break;
                   2087:        }
                   2088:        Pcic_write(ph, PCIC_ADDRWIN_ENABLE, reg);
                   2089:
                   2090:        ph->ioalloc &= ~(1 << win);
                   2091: }
                   2092:
                   2093: /*
                   2094:  * void pccbb_pcmcia_wait_ready(struct pcic_handle *ph)
                   2095:  *
                   2096:  * This function enables the card.  All information is stored in
                   2097:  * the first argument, pcmcia_chipset_handle_t.
                   2098:  */
                   2099: void
                   2100: pccbb_pcmcia_wait_ready(ph)
                   2101:        struct pcic_handle *ph;
                   2102: {
                   2103:        int i;
                   2104:
                   2105:        DPRINTF(("pccbb_pcmcia_wait_ready: status 0x%02x\n",
                   2106:            Pcic_read(ph, PCIC_IF_STATUS)));
                   2107:
                   2108:        for (i = 0; i < 10000; i++) {
                   2109:                if (Pcic_read(ph, PCIC_IF_STATUS) & PCIC_IF_STATUS_READY) {
                   2110:                        return;
                   2111:                }
                   2112:                delay(500);
                   2113: #ifdef CBB_DEBUG
                   2114:                if ((i > 5000) && (i % 100 == 99))
                   2115:                        printf(".");
                   2116: #endif
                   2117:        }
                   2118:
                   2119: #ifdef DIAGNOSTIC
                   2120:        printf("pcic_wait_ready: ready never happened, status = %02x\n",
                   2121:            Pcic_read(ph, PCIC_IF_STATUS));
                   2122: #endif
                   2123: }
                   2124:
                   2125: /*
                   2126:  * void pccbb_pcmcia_socket_enable(pcmcia_chipset_handle_t pch)
                   2127:  *
                   2128:  * This function enables the card.  All information is stored in
                   2129:  * the first argument, pcmcia_chipset_handle_t.
                   2130:  */
                   2131: void
                   2132: pccbb_pcmcia_socket_enable(pch)
                   2133:        pcmcia_chipset_handle_t pch;
                   2134: {
                   2135:        struct pcic_handle *ph = (struct pcic_handle *)pch;
                   2136:        struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
                   2137:        int cardtype, win;
                   2138:        u_int8_t power, intr;
                   2139:        pcireg_t spsr;
                   2140:        int voltage;
                   2141:
                   2142:        /* this bit is mostly stolen from pcic_attach_card */
                   2143:
                   2144:        DPRINTF(("pccbb_pcmcia_socket_enable: "));
                   2145:
                   2146:        /* get card Vcc info */
                   2147:
                   2148:        spsr =
                   2149:            bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh,
                   2150:            CB_SOCKET_STAT);
                   2151:        if (spsr & CB_SOCKET_STAT_5VCARD) {
                   2152:                DPRINTF(("5V card\n"));
                   2153:                voltage = CARDBUS_VCC_5V | CARDBUS_VPP_VCC;
                   2154:        } else if (spsr & CB_SOCKET_STAT_3VCARD) {
                   2155:                DPRINTF(("3V card\n"));
                   2156:                voltage = CARDBUS_VCC_3V | CARDBUS_VPP_VCC;
                   2157:        } else {
                   2158:                printf("?V card, 0x%x\n", spsr);        /* XXX */
                   2159:                return;
                   2160:        }
                   2161:
                   2162:        /* disable socket i/o: negate output enable bit */
                   2163:
                   2164:        power = 0;
                   2165:        Pcic_write(ph, PCIC_PWRCTL, power);
                   2166:
                   2167:        /* power down the socket to reset it, clear the card reset pin */
                   2168:
                   2169:        pccbb_power(sc, CARDBUS_VCC_0V | CARDBUS_VPP_0V);
                   2170:
                   2171:        /*
                   2172:         * wait 200ms until power fails (Tpf).  Then, wait 100ms since
                   2173:         * we are changing Vcc (Toff).
                   2174:         */
                   2175:        /* delay(300*1000); too much */
                   2176:
                   2177:        /* assert reset bit */
                   2178:        intr = Pcic_read(ph, PCIC_INTR);
                   2179:        intr &= ~(PCIC_INTR_RESET | PCIC_INTR_CARDTYPE_MASK);
                   2180:        Pcic_write(ph, PCIC_INTR, intr);
                   2181:
                   2182:        /* power up the socket and output enable */
                   2183:        power = Pcic_read(ph, PCIC_PWRCTL);
                   2184:        power |= PCIC_PWRCTL_OE;
                   2185:        Pcic_write(ph, PCIC_PWRCTL, power);
                   2186:        pccbb_power(sc, voltage);
                   2187:
                   2188:        /*
                   2189:         * hold RESET at least 10us.
                   2190:         */
                   2191:        delay(10);
                   2192:        delay(2 * 1000);               /* XXX: TI1130 requires it. */
                   2193:        delay(20 * 1000);              /* XXX: TI1130 requires it. */
                   2194:
                   2195:        /* clear the reset flag */
                   2196:
                   2197:        intr |= PCIC_INTR_RESET;
                   2198:        Pcic_write(ph, PCIC_INTR, intr);
                   2199:
                   2200:        /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */
                   2201:
                   2202:        delay(20000);
                   2203:
                   2204:        /* wait for the chip to finish initializing */
                   2205:
                   2206:        pccbb_pcmcia_wait_ready(ph);
                   2207:
                   2208:        /* zero out the address windows */
                   2209:
                   2210:        Pcic_write(ph, PCIC_ADDRWIN_ENABLE, 0);
                   2211:
                   2212:        /* set the card type */
                   2213:
                   2214:        cardtype = pcmcia_card_gettype(ph->pcmcia);
                   2215:
                   2216:        intr |= ((cardtype == PCMCIA_IFTYPE_IO) ?
                   2217:            PCIC_INTR_CARDTYPE_IO : PCIC_INTR_CARDTYPE_MEM);
                   2218:        Pcic_write(ph, PCIC_INTR, intr);
                   2219:
                   2220:        DPRINTF(("%s: pccbb_pcmcia_socket_enable %02x cardtype %s %02x\n",
                   2221:            ph->ph_parent->dv_xname, ph->sock,
                   2222:            ((cardtype == PCMCIA_IFTYPE_IO) ? "io" : "mem"), intr));
                   2223:
                   2224:        /* reinstall all the memory and io mappings */
                   2225:
                   2226:        for (win = 0; win < PCIC_MEM_WINS; ++win) {
                   2227:                if (ph->memalloc & (1 << win)) {
                   2228:                        pccbb_pcmcia_do_mem_map(ph, win);
                   2229:                }
                   2230:        }
                   2231:
                   2232:        for (win = 0; win < PCIC_IO_WINS; ++win) {
                   2233:                if (ph->ioalloc & (1 << win)) {
                   2234:                        pccbb_pcmcia_do_io_map(ph, win);
                   2235:                }
                   2236:        }
                   2237: }
                   2238:
                   2239: /*
                   2240:  * void pccbb_pcmcia_socket_disable(pcmcia_chipset_handle_t *ph)
                   2241:  *
                   2242:  * This function disables the card.  All information is stored in
                   2243:  * the first argument, pcmcia_chipset_handle_t.
                   2244:  */
                   2245: void
                   2246: pccbb_pcmcia_socket_disable(pch)
                   2247:        pcmcia_chipset_handle_t pch;
                   2248: {
                   2249:        struct pcic_handle *ph = (struct pcic_handle *)pch;
                   2250:        struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
                   2251:        u_int8_t power, intr;
                   2252:
                   2253:        DPRINTF(("pccbb_pcmcia_socket_disable\n"));
                   2254:
                   2255:        /* reset signal asserting... */
                   2256:
                   2257:        intr = Pcic_read(ph, PCIC_INTR);
                   2258:        intr &= ~(PCIC_INTR_CARDTYPE_MASK);
                   2259:        Pcic_write(ph, PCIC_INTR, intr);
                   2260:        delay(2 * 1000);
                   2261:
                   2262:        /* power down the socket */
                   2263:        power = Pcic_read(ph, PCIC_PWRCTL);
                   2264:        power &= ~PCIC_PWRCTL_OE;
                   2265:        Pcic_write(ph, PCIC_PWRCTL, power);
                   2266:        pccbb_power(sc, CARDBUS_VCC_0V | CARDBUS_VPP_0V);
                   2267:        /*
                   2268:         * wait 300ms until power fails (Tpf).
                   2269:         */
                   2270:        delay(300 * 1000);
                   2271: }
                   2272:
                   2273: /*
                   2274:  * int pccbb_pcmcia_card_detect(pcmcia_chipset_handle_t *ph)
                   2275:  *
                   2276:  * This function detects whether a card is in the slot or not.
                   2277:  * If a card is inserted, return 1.  Otherwise, return 0.
                   2278:  */
                   2279: int
                   2280: pccbb_pcmcia_card_detect(pch)
                   2281:        pcmcia_chipset_handle_t pch;
                   2282: {
                   2283:        struct pcic_handle *ph = (struct pcic_handle *)pch;
                   2284:        struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
                   2285:
                   2286:        DPRINTF(("pccbb_pcmcia_card_detect\n"));
                   2287:        return pccbb_detect_card(sc) == 1 ? 1 : 0;
                   2288: }
                   2289:
                   2290: #if 0
                   2291: int
                   2292: pccbb_new_pcmcia_mem_alloc(pcmcia_chipset_handle_t pch,
                   2293:     bus_addr_t start, bus_size_t size, bus_size_t align, int speed, int flags,
                   2294:     bus_space_tag_t * memtp bus_space_handle_t * memhp)
                   2295: #endif
                   2296: /*
                   2297:  * int pccbb_pcmcia_mem_alloc(pcmcia_chipset_handle_t pch,
                   2298:  *                                   bus_size_t size,
                   2299:  *                                   struct pcmcia_mem_handle *pcmhp)
                   2300:  *
                   2301:  * This function only allocates memory region for pccard. This
                   2302:  * function never maps the allocated region to pccard memory area.
                   2303:  *
                   2304:  * XXX: Why the argument of start address is not in?
                   2305:  */
                   2306: int
                   2307: pccbb_pcmcia_mem_alloc(pch, size, pcmhp)
                   2308:        pcmcia_chipset_handle_t pch;
                   2309:        bus_size_t size;
                   2310:        struct pcmcia_mem_handle *pcmhp;
                   2311: {
                   2312:        struct pcic_handle *ph = (struct pcic_handle *)pch;
                   2313:        bus_space_handle_t memh;
                   2314:        bus_addr_t addr;
                   2315:        bus_size_t sizepg;
                   2316:        struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
                   2317:        rbus_tag_t rb;
                   2318:
                   2319:        /* out of sc->memh, allocate as many pages as necessary */
                   2320:
                   2321:        /* convert size to PCIC pages */
                   2322:        /*
                   2323:         * This is not enough; when the requested region is on the page
                   2324:         * boundaries, this may calculate wrong result.
                   2325:         */
                   2326:        sizepg = (size + (PCIC_MEM_PAGESIZE - 1)) / PCIC_MEM_PAGESIZE;
                   2327: #if 0
                   2328:        if (sizepg > PCIC_MAX_MEM_PAGES) {
                   2329:                return 1;
                   2330:        }
                   2331: #endif
                   2332:
                   2333:        if (!(sc->sc_pcmcia_flags & PCCBB_PCMCIA_MEM_32)) {
                   2334:                return 1;
                   2335:        }
                   2336:
                   2337:        addr = 0;                      /* XXX gcc -Wuninitialized */
                   2338:
                   2339:        rb = sc->sc_rbus_memt;
                   2340:        if (rbus_space_alloc(rb, 0, sizepg * PCIC_MEM_PAGESIZE,
                   2341:            sizepg * PCIC_MEM_PAGESIZE - 1, PCIC_MEM_PAGESIZE, 0,
                   2342:            &addr, &memh)) {
                   2343:                return 1;
                   2344:        }
                   2345:
                   2346:        DPRINTF(
                   2347:            ("pccbb_pcmcia_alloc_mem: addr 0x%lx size 0x%lx, realsize 0x%lx\n",
                   2348:            addr, size, sizepg * PCIC_MEM_PAGESIZE));
                   2349:
                   2350:        pcmhp->memt = sc->sc_memt;
                   2351:        pcmhp->memh = memh;
                   2352:        pcmhp->addr = addr;
                   2353:        pcmhp->size = size;
                   2354:        pcmhp->realsize = sizepg * PCIC_MEM_PAGESIZE;
                   2355:        /* What is mhandle?  I feel it is very dirty and it must go trush. */
                   2356:        pcmhp->mhandle = 0;
                   2357:        /* No offset???  Funny. */
                   2358:
                   2359:        return 0;
                   2360: }
                   2361:
                   2362: /*
                   2363:  * void pccbb_pcmcia_mem_free(pcmcia_chipset_handle_t pch,
                   2364:  *                                   struct pcmcia_mem_handle *pcmhp)
                   2365:  *
                   2366:  * This function release the memory space allocated by the function
                   2367:  * pccbb_pcmcia_mem_alloc().
                   2368:  */
                   2369: void
                   2370: pccbb_pcmcia_mem_free(pch, pcmhp)
                   2371:        pcmcia_chipset_handle_t pch;
                   2372:        struct pcmcia_mem_handle *pcmhp;
                   2373: {
                   2374:        struct pcic_handle *ph = (struct pcic_handle *)pch;
                   2375:        struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
                   2376:
                   2377:        rbus_space_free(sc->sc_rbus_memt, pcmhp->memh, pcmhp->realsize, NULL);
                   2378: }
                   2379:
                   2380: /*
                   2381:  * void pccbb_pcmcia_do_mem_map(struct pcic_handle *ph, int win)
                   2382:  *
                   2383:  * This function release the memory space allocated by the function
                   2384:  * pccbb_pcmcia_mem_alloc().
                   2385:  */
                   2386: void
                   2387: pccbb_pcmcia_do_mem_map(ph, win)
                   2388:        struct pcic_handle *ph;
                   2389:        int win;
                   2390: {
                   2391:        int regbase_win;
                   2392:        bus_addr_t phys_addr;
                   2393:        bus_addr_t phys_end;
                   2394:
                   2395: #define PCIC_SMM_START_LOW 0
                   2396: #define PCIC_SMM_START_HIGH 1
                   2397: #define PCIC_SMM_STOP_LOW 2
                   2398: #define PCIC_SMM_STOP_HIGH 3
                   2399: #define PCIC_CMA_LOW 4
                   2400: #define PCIC_CMA_HIGH 5
                   2401:
                   2402:        u_int8_t start_low, start_high = 0;
                   2403:        u_int8_t stop_low, stop_high;
                   2404:        u_int8_t off_low, off_high;
                   2405:        u_int8_t mem_window;
                   2406:        int reg;
                   2407:
                   2408:        regbase_win = 0x10 + win * 0x08;
                   2409:
                   2410:        phys_addr = ph->mem[win].addr;
                   2411:        phys_end = phys_addr + ph->mem[win].size;
                   2412:
                   2413:        DPRINTF(("pccbb_pcmcia_do_mem_map: start 0x%lx end 0x%lx off 0x%lx\n",
                   2414:            phys_addr, phys_end, ph->mem[win].offset));
                   2415:
                   2416: #define PCIC_MEMREG_LSB_SHIFT PCIC_SYSMEM_ADDRX_SHIFT
                   2417: #define PCIC_MEMREG_MSB_SHIFT (PCIC_SYSMEM_ADDRX_SHIFT + 8)
                   2418: #define PCIC_MEMREG_WIN_SHIFT (PCIC_SYSMEM_ADDRX_SHIFT + 12)
                   2419:
                   2420:        /* bit 19:12 */
                   2421:        start_low = (phys_addr >> PCIC_MEMREG_LSB_SHIFT) & 0xff;
                   2422:        /* bit 23:20 and bit 7 on */
                   2423:        start_high = ((phys_addr >> PCIC_MEMREG_MSB_SHIFT) & 0x0f)
                   2424:            | PCIC_SYSMEM_ADDRX_START_MSB_DATASIZE_16BIT; /* bit 7 on */
                   2425:        /* bit 31:24, for 32-bit address */
                   2426:        mem_window = (phys_addr >> PCIC_MEMREG_WIN_SHIFT) & 0xff;
                   2427:
                   2428:        Pcic_write(ph, regbase_win + PCIC_SMM_START_LOW, start_low);
                   2429:        Pcic_write(ph, regbase_win + PCIC_SMM_START_HIGH, start_high);
                   2430:
                   2431:        if (((struct pccbb_softc *)ph->
                   2432:            ph_parent)->sc_pcmcia_flags & PCCBB_PCMCIA_MEM_32) {
                   2433:                Pcic_write(ph, 0x40 + win, mem_window);
                   2434:        }
                   2435:
                   2436:        stop_low = (phys_end >> PCIC_MEMREG_LSB_SHIFT) & 0xff;
                   2437:        stop_high = ((phys_end >> PCIC_MEMREG_MSB_SHIFT) & 0x0f)
                   2438:            | PCIC_SYSMEM_ADDRX_STOP_MSB_WAIT2; /* wait 2 cycles */
                   2439:        /* XXX Geee, WAIT2!! Crazy!!  I must rewrite this routine. */
                   2440:
                   2441:        Pcic_write(ph, regbase_win + PCIC_SMM_STOP_LOW, stop_low);
                   2442:        Pcic_write(ph, regbase_win + PCIC_SMM_STOP_HIGH, stop_high);
                   2443:
                   2444:        off_low = (ph->mem[win].offset >> PCIC_CARDMEM_ADDRX_SHIFT) & 0xff;
                   2445:        off_high = ((ph->mem[win].offset >> (PCIC_CARDMEM_ADDRX_SHIFT + 8))
                   2446:            & PCIC_CARDMEM_ADDRX_MSB_ADDR_MASK)
                   2447:            | ((ph->mem[win].kind == PCMCIA_MEM_ATTR) ?
                   2448:            PCIC_CARDMEM_ADDRX_MSB_REGACTIVE_ATTR : 0);
                   2449:
                   2450:        Pcic_write(ph, regbase_win + PCIC_CMA_LOW, off_low);
                   2451:        Pcic_write(ph, regbase_win + PCIC_CMA_HIGH, off_high);
                   2452:
                   2453:        reg = Pcic_read(ph, PCIC_ADDRWIN_ENABLE);
                   2454:        reg |= ((1 << win) | PCIC_ADDRWIN_ENABLE_MEMCS16);
                   2455:        Pcic_write(ph, PCIC_ADDRWIN_ENABLE, reg);
                   2456:
                   2457: #if defined CBB_DEBUG
                   2458:        {
                   2459:                int r1, r2, r3, r4, r5, r6, r7 = 0;
                   2460:
                   2461:                r1 = Pcic_read(ph, regbase_win + PCIC_SMM_START_LOW);
                   2462:                r2 = Pcic_read(ph, regbase_win + PCIC_SMM_START_HIGH);
                   2463:                r3 = Pcic_read(ph, regbase_win + PCIC_SMM_STOP_LOW);
                   2464:                r4 = Pcic_read(ph, regbase_win + PCIC_SMM_STOP_HIGH);
                   2465:                r5 = Pcic_read(ph, regbase_win + PCIC_CMA_LOW);
                   2466:                r6 = Pcic_read(ph, regbase_win + PCIC_CMA_HIGH);
                   2467:                if (((struct pccbb_softc *)(ph->
                   2468:                    ph_parent))->sc_pcmcia_flags & PCCBB_PCMCIA_MEM_32) {
                   2469:                        r7 = Pcic_read(ph, 0x40 + win);
                   2470:                }
                   2471:
                   2472:                DPRINTF(("pccbb_pcmcia_do_mem_map window %d: %02x%02x %02x%02x "
                   2473:                    "%02x%02x", win, r1, r2, r3, r4, r5, r6));
                   2474:                if (((struct pccbb_softc *)(ph->
                   2475:                    ph_parent))->sc_pcmcia_flags & PCCBB_PCMCIA_MEM_32) {
                   2476:                        DPRINTF((" %02x", r7));
                   2477:                }
                   2478:                DPRINTF(("\n"));
                   2479:        }
                   2480: #endif
                   2481: }
                   2482:
                   2483: /*
                   2484:  * int pccbb_pcmcia_mem_map(pcmcia_chipset_handle_t pch, int kind,
                   2485:  *                                 bus_addr_t card_addr, bus_size_t size,
                   2486:  *                                 struct pcmcia_mem_handle *pcmhp,
                   2487:  *                                 bus_size_t *offsetp, int *windowp)
                   2488:  *
                   2489:  * This function maps memory space allocated by the function
                   2490:  * pccbb_pcmcia_mem_alloc().
                   2491:  */
                   2492: int
                   2493: pccbb_pcmcia_mem_map(pch, kind, card_addr, size, pcmhp, offsetp, windowp)
                   2494:        pcmcia_chipset_handle_t pch;
                   2495:        int kind;
                   2496:        bus_addr_t card_addr;
                   2497:        bus_size_t size;
                   2498:        struct pcmcia_mem_handle *pcmhp;
                   2499:        bus_size_t *offsetp;
                   2500:        int *windowp;
                   2501: {
                   2502:        struct pcic_handle *ph = (struct pcic_handle *)pch;
                   2503:        bus_addr_t busaddr;
                   2504:        long card_offset;
                   2505:        int win;
                   2506:
                   2507:        for (win = 0; win < PCIC_MEM_WINS; ++win) {
                   2508:                if ((ph->memalloc & (1 << win)) == 0) {
                   2509:                        ph->memalloc |= (1 << win);
                   2510:                        break;
                   2511:                }
                   2512:        }
                   2513:
                   2514:        if (win == PCIC_MEM_WINS) {
                   2515:                return 1;
                   2516:        }
                   2517:
                   2518:        *windowp = win;
                   2519:
                   2520:        /* XXX this is pretty gross */
                   2521:
                   2522:        if (((struct pccbb_softc *)ph->ph_parent)->sc_memt != pcmhp->memt) {
                   2523:                panic("pccbb_pcmcia_mem_map memt is bogus");
                   2524:        }
                   2525:
                   2526:        busaddr = pcmhp->addr;
                   2527:
                   2528:        /*
                   2529:         * compute the address offset to the pcmcia address space for the
                   2530:         * pcic.  this is intentionally signed.  The masks and shifts below
                   2531:         * will cause TRT to happen in the pcic registers.  Deal with making
                   2532:         * sure the address is aligned, and return the alignment offset.
                   2533:         */
                   2534:
                   2535:        *offsetp = card_addr % PCIC_MEM_PAGESIZE;
                   2536:        card_addr -= *offsetp;
                   2537:
                   2538:        DPRINTF(("pccbb_pcmcia_mem_map window %d bus %lx+%lx+%lx at card addr "
                   2539:            "%lx\n", win, (u_long) busaddr, (u_long) * offsetp, (u_long) size,
                   2540:            (u_long) card_addr));
                   2541:
                   2542:        /*
                   2543:         * include the offset in the size, and decrement size by one, since
                   2544:         * the hw wants start/stop
                   2545:         */
                   2546:        size += *offsetp - 1;
                   2547:
                   2548:        card_offset = (((long)card_addr) - ((long)busaddr));
                   2549:
                   2550:        ph->mem[win].addr = busaddr;
                   2551:        ph->mem[win].size = size;
                   2552:        ph->mem[win].offset = card_offset;
                   2553:        ph->mem[win].kind = kind;
                   2554:
                   2555:        pccbb_pcmcia_do_mem_map(ph, win);
                   2556:
                   2557:        return 0;
                   2558: }
                   2559:
                   2560: /*
                   2561:  * int pccbb_pcmcia_mem_unmap(pcmcia_chipset_handle_t pch,
                   2562:  *                                   int window)
                   2563:  *
                   2564:  * This function unmaps memory space which mapped by the function
                   2565:  * pccbb_pcmcia_mem_map().
                   2566:  */
                   2567: void
                   2568: pccbb_pcmcia_mem_unmap(pch, window)
                   2569:        pcmcia_chipset_handle_t pch;
                   2570:        int window;
                   2571: {
                   2572:        struct pcic_handle *ph = (struct pcic_handle *)pch;
                   2573:        int reg;
                   2574:
                   2575:        if (window >= PCIC_MEM_WINS) {
                   2576:                panic("pccbb_pcmcia_mem_unmap: window out of range");
                   2577:        }
                   2578:
                   2579:        reg = Pcic_read(ph, PCIC_ADDRWIN_ENABLE);
                   2580:        reg &= ~(1 << window);
                   2581:        Pcic_write(ph, PCIC_ADDRWIN_ENABLE, reg);
                   2582:
                   2583:        ph->memalloc &= ~(1 << window);
                   2584: }
                   2585:
                   2586: #if defined PCCBB_PCMCIA_POLL
                   2587: struct pccbb_poll_str {
                   2588:        void *arg;
                   2589:        int (*func)(void *);
                   2590:        int level;
                   2591:        struct pcic_handle *ph;
                   2592:        int count;
                   2593:        int num;
                   2594: };
                   2595:
                   2596: static struct pccbb_poll_str pccbb_poll[10];
                   2597: static int pccbb_poll_n = 0;
                   2598: static struct timeout pccbb_poll_timeout;
                   2599:
                   2600: void pccbb_pcmcia_poll(void *arg);
                   2601:
                   2602: void
                   2603: pccbb_pcmcia_poll(arg)
                   2604:        void *arg;
                   2605: {
                   2606:        struct pccbb_poll_str *poll = arg;
                   2607:        struct pcic_handle *ph = poll->ph;
                   2608:        struct pccbb_softc *sc = ph->sc;
                   2609:        int s;
                   2610:        u_int32_t spsr;                /* socket present-state reg */
                   2611:
                   2612:        timeout_set(&pccbb_poll_timeout, pccbb_pcmcia_poll, arg);
                   2613:        timeout_add(&pccbb_poll_timeout, hz * 2);
                   2614:        switch (poll->level) {
                   2615:        case IPL_NET:
                   2616:                s = splnet();
                   2617:                break;
                   2618:        case IPL_BIO:
                   2619:                s = splbio();
                   2620:                break;
                   2621:        case IPL_TTY:                  /* fallthrough */
                   2622:        default:
                   2623:                s = spltty();
                   2624:                break;
                   2625:        }
                   2626:
                   2627:        spsr =
                   2628:            bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh,
                   2629:            CB_SOCKET_STAT);
                   2630:
                   2631: #if defined PCCBB_PCMCIA_POLL_ONLY && defined LEVEL2
                   2632:        if (!(spsr & 0x40))            /* CINT low */
                   2633: #else
                   2634:        if (1)
                   2635: #endif
                   2636:        {
                   2637:                if ((*poll->func) (poll->arg) > 0) {
                   2638:                        ++poll->count;
                   2639:        /* printf("intr: reported from poller, 0x%x\n", spsr); */
                   2640: #if defined LEVEL2
                   2641:                } else {
                   2642:                        printf("intr: miss! 0x%x\n", spsr);
                   2643: #endif
                   2644:                }
                   2645:        }
                   2646:        splx(s);
                   2647: }
                   2648: #endif /* defined CB_PCMCIA_POLL */
                   2649:
                   2650: /*
                   2651:  * void *pccbb_pcmcia_intr_establish(pcmcia_chipset_handle_t pch,
                   2652:  *                                          struct pcmcia_function *pf,
                   2653:  *                                          int ipl,
                   2654:  *                                          int (*func)(void *),
                   2655:  *                                          void *arg);
                   2656:  *
                   2657:  * This function enables PC-Card interrupt.  PCCBB uses PCI interrupt line.
                   2658:  */
                   2659: void *
                   2660: pccbb_pcmcia_intr_establish(pch, pf, ipl, func, arg, xname)
                   2661:        pcmcia_chipset_handle_t pch;
                   2662:        struct pcmcia_function *pf;
                   2663:        int ipl;
                   2664:        int (*func)(void *);
                   2665:        void *arg;
                   2666:        char *xname;
                   2667: {
                   2668:        struct pcic_handle *ph = (struct pcic_handle *)pch;
                   2669:        struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
                   2670:
                   2671:        if (!(pf->cfe->flags & PCMCIA_CFE_IRQLEVEL)) {
                   2672:                /* what should I do? */
                   2673:                if ((pf->cfe->flags & PCMCIA_CFE_IRQLEVEL)) {
                   2674:                        DPRINTF(
                   2675:                            ("%s does not provide edge nor pulse interrupt\n",
                   2676:                            sc->sc_dev.dv_xname));
                   2677:                        return NULL;
                   2678:                }
                   2679:                /*
                   2680:                 * XXX Noooooo!  The interrupt flag must set properly!!
                   2681:                 * dumb pcmcia driver!!
                   2682:                 */
                   2683:        }
                   2684:
                   2685:        return pccbb_intr_establish(sc, -1, ipl, func, arg, xname);
                   2686: }
                   2687:
                   2688: /*
                   2689:  * void pccbb_pcmcia_intr_disestablish(pcmcia_chipset_handle_t pch,
                   2690:  *                                            void *ih)
                   2691:  *
                   2692:  * This function disables PC-Card interrupt.
                   2693:  */
                   2694: void
                   2695: pccbb_pcmcia_intr_disestablish(pch, ih)
                   2696:        pcmcia_chipset_handle_t pch;
                   2697:        void *ih;
                   2698: {
                   2699:        struct pcic_handle *ph = (struct pcic_handle *)pch;
                   2700:        struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
                   2701:
                   2702:        pccbb_intr_disestablish(sc, ih);
                   2703: }
                   2704:
                   2705: const char *
                   2706: pccbb_pcmcia_intr_string(pch, ih)
                   2707:        pcmcia_chipset_handle_t pch;
                   2708:        void *ih;
                   2709: {
                   2710:        if (ih == NULL)
                   2711:                return "couldn't establish interrupt";
                   2712:        else
                   2713:                return "";      /* card shares interrupt of the bridge */
                   2714: }
                   2715:
                   2716: /*
                   2717:  * int
                   2718:  * pccbb_rbus_cb_space_alloc(cardbus_chipset_tag_t ct, rbus_tag_t rb,
                   2719:  *                         bus_addr_t addr, bus_size_t size,
                   2720:  *                         bus_addr_t mask, bus_size_t align,
                   2721:  *                         int flags, bus_addr_t *addrp;
                   2722:  *                         bus_space_handle_t *bshp)
                   2723:  *
                   2724:  *   This function allocates a portion of memory or io space for
                   2725:  *   clients.  This function is called from CardBus card drivers.
                   2726:  */
                   2727: int
                   2728: pccbb_rbus_cb_space_alloc(ct, rb, addr, size, mask, align, flags, addrp, bshp)
                   2729:        cardbus_chipset_tag_t ct;
                   2730:        rbus_tag_t rb;
                   2731:        bus_addr_t addr;
                   2732:        bus_size_t size;
                   2733:        bus_addr_t mask;
                   2734:        bus_size_t align;
                   2735:        int flags;
                   2736:        bus_addr_t *addrp;
                   2737:        bus_space_handle_t *bshp;
                   2738: {
                   2739:        struct pccbb_softc *sc = (struct pccbb_softc *)ct;
                   2740:
                   2741:        DPRINTF(
                   2742:            ("pccbb_rbus_cb_space_alloc: adr %lx, size %lx, mask %lx, align %lx\n",
                   2743:            addr, size, mask, align));
                   2744:
                   2745:        if (align == 0) {
                   2746:                align = size;
                   2747:        }
                   2748:
                   2749:        if (rb->rb_bt == sc->sc_memt) {
                   2750:                if (align < 16) {
                   2751:                        return 1;
                   2752:                }
                   2753:        } else if (rb->rb_bt == sc->sc_iot) {
                   2754:                if (align < 4) {
                   2755:                        return 1;
                   2756:                }
                   2757:                /* XXX: hack for avoiding ISA image */
                   2758:                if (mask < 0x0100) {
                   2759:                        mask = 0x3ff;
                   2760:                        addr = 0x300;
                   2761:                }
                   2762:
                   2763:        } else {
                   2764:                DPRINTF(
                   2765:                    ("pccbb_rbus_cb_space_alloc: Bus space tag %x is NOT used.\n",
                   2766:                    rb->rb_bt));
                   2767:                return 1;
                   2768:                /* XXX: panic here? */
                   2769:        }
                   2770:
                   2771:        if (rbus_space_alloc(rb, addr, size, mask, align, flags, addrp, bshp)) {
                   2772:                printf("%s: <rbus> no bus space\n", sc->sc_dev.dv_xname);
                   2773:                return 1;
                   2774:        }
                   2775:
                   2776:        pccbb_open_win(sc, rb->rb_bt, *addrp, size, *bshp, 0);
                   2777:
                   2778:        return 0;
                   2779: }
                   2780:
                   2781: /*
                   2782:  * int
                   2783:  * pccbb_rbus_cb_space_free(cardbus_chipset_tag_t *ct, rbus_tag_t rb,
                   2784:  *                        bus_space_handle_t *bshp, bus_size_t size);
                   2785:  *
                   2786:  *   This function is called from CardBus card drivers.
                   2787:  */
                   2788: int
                   2789: pccbb_rbus_cb_space_free(ct, rb, bsh, size)
                   2790:        cardbus_chipset_tag_t ct;
                   2791:        rbus_tag_t rb;
                   2792:        bus_space_handle_t bsh;
                   2793:        bus_size_t size;
                   2794: {
                   2795:        struct pccbb_softc *sc = (struct pccbb_softc *)ct;
                   2796:        bus_space_tag_t bt = rb->rb_bt;
                   2797:
                   2798:        pccbb_close_win(sc, bt, bsh, size);
                   2799:
                   2800:        if (bt == sc->sc_memt) {
                   2801:        } else if (bt == sc->sc_iot) {
                   2802:        } else {
                   2803:                return 1;
                   2804:                /* XXX: panic here? */
                   2805:        }
                   2806:
                   2807:        return rbus_space_free(rb, bsh, size, NULL);
                   2808: }
                   2809:
                   2810: int
                   2811: pccbb_open_win(sc, bst, addr, size, bsh, flags)
                   2812:        struct pccbb_softc *sc;
                   2813:        bus_space_tag_t bst;
                   2814:        bus_addr_t addr;
                   2815:        bus_size_t size;
                   2816:        bus_space_handle_t bsh;
                   2817:        int flags;
                   2818: {
                   2819:        struct pccbb_win_chain_head *head;
                   2820:        bus_addr_t align;
                   2821:
                   2822:        head = &sc->sc_iowindow;
                   2823:        align = 0x04;
                   2824:        if (sc->sc_memt == bst) {
                   2825:                head = &sc->sc_memwindow;
                   2826:                align = 0x1000;
                   2827:                DPRINTF(("using memory window, %x %x %x\n\n",
                   2828:                    sc->sc_iot, sc->sc_memt, bst));
                   2829:        }
                   2830:
                   2831:        if (pccbb_winlist_insert(head, addr, size, bsh, flags)) {
                   2832:                printf("%s: pccbb_open_win: %s winlist insert failed\n",
                   2833:                    sc->sc_dev.dv_xname,
                   2834:                    (head == &sc->sc_memwindow) ? "mem" : "io");
                   2835:        }
                   2836:        pccbb_winset(align, sc, bst);
                   2837:
                   2838:        return 0;
                   2839: }
                   2840:
                   2841: int
                   2842: pccbb_close_win(sc, bst, bsh, size)
                   2843:        struct pccbb_softc *sc;
                   2844:        bus_space_tag_t bst;
                   2845:        bus_space_handle_t bsh;
                   2846:        bus_size_t size;
                   2847: {
                   2848:        struct pccbb_win_chain_head *head;
                   2849:        bus_addr_t align;
                   2850:
                   2851:        head = &sc->sc_iowindow;
                   2852:        align = 0x04;
                   2853:        if (sc->sc_memt == bst) {
                   2854:                head = &sc->sc_memwindow;
                   2855:                align = 0x1000;
                   2856:        }
                   2857:
                   2858:        if (pccbb_winlist_delete(head, bsh, size)) {
                   2859:                printf("%s: pccbb_close_win: %s winlist delete failed\n",
                   2860:                    sc->sc_dev.dv_xname,
                   2861:                    (head == &sc->sc_memwindow) ? "mem" : "io");
                   2862:        }
                   2863:        pccbb_winset(align, sc, bst);
                   2864:
                   2865:        return 0;
                   2866: }
                   2867:
                   2868: int
                   2869: pccbb_winlist_insert(head, start, size, bsh, flags)
                   2870:        struct pccbb_win_chain_head *head;
                   2871:        bus_addr_t start;
                   2872:        bus_size_t size;
                   2873:        bus_space_handle_t bsh;
                   2874:        int flags;
                   2875: {
                   2876:        struct pccbb_win_chain *chainp, *elem;
                   2877:
                   2878:        if ((elem = malloc(sizeof(struct pccbb_win_chain), M_DEVBUF,
                   2879:            M_NOWAIT)) == NULL)
                   2880:                return (1);             /* fail */
                   2881:
                   2882:        elem->wc_start = start;
                   2883:        elem->wc_end = start + (size - 1);
                   2884:        elem->wc_handle = bsh;
                   2885:        elem->wc_flags = flags;
                   2886:
                   2887:        for (chainp = TAILQ_FIRST(head); chainp != NULL;
                   2888:            chainp = TAILQ_NEXT(chainp, wc_list)) {
                   2889:                if (chainp->wc_end < start)
                   2890:                        continue;
                   2891:                TAILQ_INSERT_AFTER(head, chainp, elem, wc_list);
                   2892:                return (0);
                   2893:        }
                   2894:
                   2895:        TAILQ_INSERT_TAIL(head, elem, wc_list);
                   2896:        return (0);
                   2897: }
                   2898:
                   2899: int
                   2900: pccbb_winlist_delete(head, bsh, size)
                   2901:        struct pccbb_win_chain_head *head;
                   2902:        bus_space_handle_t bsh;
                   2903:        bus_size_t size;
                   2904: {
                   2905:        struct pccbb_win_chain *chainp;
                   2906:
                   2907:        for (chainp = TAILQ_FIRST(head); chainp != NULL;
                   2908:             chainp = TAILQ_NEXT(chainp, wc_list)) {
                   2909:                if (memcmp(&chainp->wc_handle, &bsh, sizeof(bsh)))
                   2910:                        continue;
                   2911:                if ((chainp->wc_end - chainp->wc_start) != (size - 1)) {
                   2912:                        printf("pccbb_winlist_delete: window 0x%lx size "
                   2913:                            "inconsistent: 0x%lx, 0x%lx\n",
                   2914:                            chainp->wc_start,
                   2915:                            chainp->wc_end - chainp->wc_start,
                   2916:                            size - 1);
                   2917:                        return 1;
                   2918:                }
                   2919:
                   2920:                TAILQ_REMOVE(head, chainp, wc_list);
                   2921:                free(chainp, M_DEVBUF);
                   2922:
                   2923:                return 0;
                   2924:        }
                   2925:
                   2926:        return 1;              /* fail: no candidate to remove */
                   2927: }
                   2928:
                   2929: void
                   2930: pccbb_winset(align, sc, bst)
                   2931:        bus_addr_t align;
                   2932:        struct pccbb_softc *sc;
                   2933:        bus_space_tag_t bst;
                   2934: {
                   2935:        pci_chipset_tag_t pc;
                   2936:        pcitag_t tag;
                   2937:        bus_addr_t mask = ~(align - 1);
                   2938:        struct {
                   2939:                cardbusreg_t win_start;
                   2940:                cardbusreg_t win_limit;
                   2941:                int win_flags;
                   2942:        } win[2];
                   2943:        struct pccbb_win_chain *chainp;
                   2944:        int offs;
                   2945:
                   2946:        win[0].win_start = win[1].win_start = 0xffffffff;
                   2947:        win[0].win_limit = win[1].win_limit = 0;
                   2948:        win[0].win_flags = win[1].win_flags = 0;
                   2949:
                   2950:        chainp = TAILQ_FIRST(&sc->sc_iowindow);
                   2951:        offs = 0x2c;
                   2952:        if (sc->sc_memt == bst) {
                   2953:                chainp = TAILQ_FIRST(&sc->sc_memwindow);
                   2954:                offs = 0x1c;
                   2955:        }
                   2956:
                   2957:        if (chainp != NULL) {
                   2958:                win[0].win_start = chainp->wc_start & mask;
                   2959:                win[0].win_limit = chainp->wc_end & mask;
                   2960:                win[0].win_flags = chainp->wc_flags;
                   2961:                chainp = TAILQ_NEXT(chainp, wc_list);
                   2962:        }
                   2963:
                   2964:        for (; chainp != NULL; chainp = TAILQ_NEXT(chainp, wc_list)) {
                   2965:                if (win[1].win_start == 0xffffffff) {
                   2966:                        /* window 1 is not used */
                   2967:                        if ((win[0].win_flags == chainp->wc_flags) &&
                   2968:                            (win[0].win_limit + align >=
                   2969:                            (chainp->wc_start & mask))) {
                   2970:                                /* concatenate */
                   2971:                                win[0].win_limit = chainp->wc_end & mask;
                   2972:                        } else {
                   2973:                                /* make new window */
                   2974:                                win[1].win_start = chainp->wc_start & mask;
                   2975:                                win[1].win_limit = chainp->wc_end & mask;
                   2976:                                win[1].win_flags = chainp->wc_flags;
                   2977:                        }
                   2978:                        continue;
                   2979:                }
                   2980:
                   2981:                /* Both windows are engaged. */
                   2982:                if (win[0].win_flags == win[1].win_flags) {
                   2983:                        /* same flags */
                   2984:                        if (win[0].win_flags == chainp->wc_flags) {
                   2985:                                if (win[1].win_start - (win[0].win_limit +
                   2986:                                    align) <
                   2987:                                    (chainp->wc_start & mask) -
                   2988:                                    ((chainp->wc_end & mask) + align)) {
                   2989:                                        /*
                   2990:                                         * merge window 0 and 1, and set win1
                   2991:                                         * to chainp
                   2992:                                         */
                   2993:                                        win[0].win_limit = win[1].win_limit;
                   2994:                                        win[1].win_start =
                   2995:                                            chainp->wc_start & mask;
                   2996:                                        win[1].win_limit =
                   2997:                                            chainp->wc_end & mask;
                   2998:                                } else {
                   2999:                                        win[1].win_limit =
                   3000:                                            chainp->wc_end & mask;
                   3001:                                }
                   3002:                        } else {
                   3003:                                /* different flags */
                   3004:
                   3005:                                /* concatenate win0 and win1 */
                   3006:                                win[0].win_limit = win[1].win_limit;
                   3007:                                /* allocate win[1] to new space */
                   3008:                                win[1].win_start = chainp->wc_start & mask;
                   3009:                                win[1].win_limit = chainp->wc_end & mask;
                   3010:                                win[1].win_flags = chainp->wc_flags;
                   3011:                        }
                   3012:                } else {
                   3013:                        /* the flags of win[0] and win[1] is different */
                   3014:                        if (win[0].win_flags == chainp->wc_flags) {
                   3015:                                win[0].win_limit = chainp->wc_end & mask;
                   3016:                                /*
                   3017:                                 * XXX this creates overlapping windows, so
                   3018:                                 * what should the poor bridge do if one is
                   3019:                                 * cachable, and the other is not?
                   3020:                                 */
                   3021:                                printf("%s: overlapping windows\n",
                   3022:                                    sc->sc_dev.dv_xname);
                   3023:                        } else {
                   3024:                                win[1].win_limit = chainp->wc_end & mask;
                   3025:                        }
                   3026:                }
                   3027:        }
                   3028:
                   3029:        pc = sc->sc_pc;
                   3030:        tag = sc->sc_tag;
                   3031:        pci_conf_write(pc, tag, offs, win[0].win_start);
                   3032:        pci_conf_write(pc, tag, offs + 4, win[0].win_limit);
                   3033:        pci_conf_write(pc, tag, offs + 8, win[1].win_start);
                   3034:        pci_conf_write(pc, tag, offs + 12, win[1].win_limit);
                   3035:        DPRINTF(("--pccbb_winset: win0 [%x, %lx), win1 [%x, %lx)\n",
                   3036:            pci_conf_read(pc, tag, offs),
                   3037:            pci_conf_read(pc, tag, offs + 4) + align,
                   3038:            pci_conf_read(pc, tag, offs + 8),
                   3039:            pci_conf_read(pc, tag, offs + 12) + align));
                   3040:
                   3041:        if (bst == sc->sc_memt) {
                   3042:                pcireg_t bcr = pci_conf_read(pc, tag, PCI_BCR_INTR);
                   3043:
                   3044:                bcr &= ~(CB_BCR_PREFETCH_MEMWIN0 | CB_BCR_PREFETCH_MEMWIN1);
                   3045:                if (win[0].win_flags & PCCBB_MEM_CACHABLE)
                   3046:                        bcr |= CB_BCR_PREFETCH_MEMWIN0;
                   3047:                if (win[1].win_flags & PCCBB_MEM_CACHABLE)
                   3048:                        bcr |= CB_BCR_PREFETCH_MEMWIN1;
                   3049:                pci_conf_write(pc, tag, PCI_BCR_INTR, bcr);
                   3050:        }
                   3051: }
                   3052:
                   3053: void
                   3054: pccbb_powerhook(why, arg)
                   3055:        int why;
                   3056:        void *arg;
                   3057: {
                   3058:        struct pccbb_softc *sc = arg;
                   3059:        u_int32_t reg;
                   3060:        bus_space_tag_t base_memt = sc->sc_base_memt;   /* socket regs memory */
                   3061:        bus_space_handle_t base_memh = sc->sc_base_memh;
                   3062:
                   3063:        DPRINTF(("%s: power: why %d\n", sc->sc_dev.dv_xname, why));
                   3064:
                   3065:        if (why == PWR_SUSPEND || why == PWR_STANDBY) {
                   3066:                DPRINTF(("%s: power: why %d stopping intr\n",
                   3067:                    sc->sc_dev.dv_xname, why));
                   3068:                if (sc->sc_pil_intr_enable) {
                   3069:                        (void)pccbbintr_function(sc);
                   3070:                }
                   3071:                sc->sc_pil_intr_enable = 0;
                   3072:
                   3073:                /* ToDo: deactivate or suspend child devices */
                   3074:
                   3075:        }
                   3076:
                   3077:        if (why == PWR_RESUME) {
                   3078:                if (pci_conf_read (sc->sc_pc, sc->sc_tag, PCI_SOCKBASE) == 0)
                   3079:                        /* BIOS did not recover this register */
                   3080:                        pci_conf_write (sc->sc_pc, sc->sc_tag,
                   3081:                                        PCI_SOCKBASE, sc->sc_sockbase);
                   3082:                if (pci_conf_read (sc->sc_pc, sc->sc_tag, PCI_BUSNUM) == 0)
                   3083:                        /* BIOS did not recover this register */
                   3084:                        pci_conf_write (sc->sc_pc, sc->sc_tag,
                   3085:                                        PCI_BUSNUM, sc->sc_busnum);
                   3086:                /* CSC Interrupt: Card detect interrupt on */
                   3087:                reg = bus_space_read_4(base_memt, base_memh, CB_SOCKET_MASK);
                   3088:                /* Card detect intr is turned on. */
                   3089:                reg |= CB_SOCKET_MASK_CD;
                   3090:                bus_space_write_4(base_memt, base_memh, CB_SOCKET_MASK, reg);
                   3091:                /* reset interrupt */
                   3092:                reg = bus_space_read_4(base_memt, base_memh, CB_SOCKET_EVENT);
                   3093:                bus_space_write_4(base_memt, base_memh, CB_SOCKET_EVENT, reg);
                   3094:
                   3095:                /*
                   3096:                 * check for card insertion or removal during suspend period.
                   3097:                 * XXX: the code can't cope with card swap (remove then
                   3098:                 * insert).  how can we detect such situation?
                   3099:                 */
                   3100:                (void)pccbbintr(sc);
                   3101:
                   3102:                sc->sc_pil_intr_enable = 1;
                   3103:                DPRINTF(("%s: power: RESUME enabling intr\n",
                   3104:                    sc->sc_dev.dv_xname));
                   3105:
                   3106:                /* ToDo: activate or wakeup child devices */
                   3107:        }
                   3108: }

CVSweb