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

Annotation of sys/dev/isa/tcic2_isa.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: tcic2_isa.c,v 1.7 2005/01/27 17:03:23 millert Exp $   */
                      2: /*     $NetBSD: tcic2_isa.c,v 1.2 1999/04/08 16:14:29 bad Exp $        */
                      3:
                      4: #undef TCICISADEBUG
                      5:
                      6: /*
                      7:  *
                      8:  * Copyright (c) 1998, 1999 Christoph Badura. All rights reserved.
                      9:  * Copyright (c) 1997 Marc Horowitz.  All rights reserved.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *     This product includes software developed by Marc Horowitz.
                     22:  * 4. The name of the author may not be used to endorse or promote products
                     23:  *    derived from this software without specific prior written permission.
                     24:  *
                     25:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     26:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     27:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     28:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     29:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     30:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     31:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     32:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     33:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     34:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     35:  */
                     36:
                     37:
                     38: #include <sys/types.h>
                     39: #include <sys/param.h>
                     40: #include <sys/systm.h>
                     41: #include <sys/device.h>
                     42: #include <sys/extent.h>
                     43: #include <sys/malloc.h>
                     44:
                     45: #include <machine/bus.h>
                     46: #include <machine/intr.h>
                     47:
                     48: #include <dev/isa/isareg.h>
                     49: #include <dev/isa/isavar.h>
                     50:
                     51: #include <dev/pcmcia/pcmciareg.h>
                     52: #include <dev/pcmcia/pcmciavar.h>
                     53: #include <dev/pcmcia/pcmciachip.h>
                     54:
                     55: #include <dev/ic/tcic2reg.h>
                     56: #include <dev/ic/tcic2var.h>
                     57:
                     58: /*****************************************************************************
                     59:  * Configurable parameters.
                     60:  *****************************************************************************/
                     61:
                     62: /*
                     63:  * Default I/O allocation range.  If both are set to non-zero, these
                     64:  * values will be used instead.  Otherwise, the code attempts to probe
                     65:  * the bus width.  Systems with 10 address bits should use 0x300 and 0xff.
                     66:  * Systems with 12 address bits (most) should use 0x400 and 0xbff.
                     67:  */
                     68:
                     69: #ifndef TCIC_ISA_ALLOC_IOBASE
                     70: #define        TCIC_ISA_ALLOC_IOBASE           0
                     71: #endif
                     72:
                     73: #ifndef TCIC_ISA_ALLOC_IOSIZE
                     74: #define        TCIC_ISA_ALLOC_IOSIZE           0
                     75: #endif
                     76:
                     77: int    tcic_isa_alloc_iobase = TCIC_ISA_ALLOC_IOBASE;
                     78: int    tcic_isa_alloc_iosize = TCIC_ISA_ALLOC_IOSIZE;
                     79:
                     80: /*
                     81:  * Default IRQ allocation bitmask.  This defines the range of allowable
                     82:  * IRQs for PCMCIA slots.  Useful if order of probing would screw up other
                     83:  * devices, or if TCIC hardware/cards have trouble with certain interrupt
                     84:  * lines.
                     85:  *
                     86:  * We disable IRQ 10 by default, since some common laptops (namely, the
                     87:  * NEC Versa series) reserve IRQ 10 for the docking station SCSI interface.
                     88:  *
                     89:  * XXX Do we care about this?  the Versa doesn't use a tcic. -chb
                     90:  */
                     91:
                     92: #ifndef TCIC_ISA_INTR_ALLOC_MASK
                     93: #define        TCIC_ISA_INTR_ALLOC_MASK        0xffff
                     94: #endif
                     95:
                     96: int    tcic_isa_intr_alloc_mask = TCIC_ISA_INTR_ALLOC_MASK;
                     97:
                     98: /*****************************************************************************
                     99:  * End of configurable parameters.
                    100:  *****************************************************************************/
                    101:
                    102: #ifdef TCICISADEBUG
                    103: int    tcic_isa_debug = 1;
                    104: #define        DPRINTF(arg) if (tcic_isa_debug) printf arg;
                    105: #else
                    106: #define        DPRINTF(arg)
                    107: #endif
                    108:
                    109: int    tcic_isa_probe(struct device *, void *, void *);
                    110: void   tcic_isa_attach(struct device *, struct device *, void *);
                    111:
                    112: void   *tcic_isa_chip_intr_establish(pcmcia_chipset_handle_t,
                    113:            struct pcmcia_function *, int, int (*) (void *), void *, char *);
                    114: void   tcic_isa_chip_intr_disestablish(pcmcia_chipset_handle_t, void *);
                    115: const char *tcic_isa_chip_intr_string(pcmcia_chipset_handle_t, void *);
                    116:
                    117: struct cfattach tcic_isa_ca = {
                    118:        sizeof(struct tcic_softc), tcic_isa_probe, tcic_isa_attach
                    119: };
                    120:
                    121: static struct pcmcia_chip_functions tcic_isa_functions = {
                    122:        tcic_chip_mem_alloc,
                    123:        tcic_chip_mem_free,
                    124:        tcic_chip_mem_map,
                    125:        tcic_chip_mem_unmap,
                    126:
                    127:        tcic_chip_io_alloc,
                    128:        tcic_chip_io_free,
                    129:        tcic_chip_io_map,
                    130:        tcic_chip_io_unmap,
                    131:
                    132:        tcic_isa_chip_intr_establish,
                    133:        tcic_isa_chip_intr_disestablish,
                    134:        tcic_isa_chip_intr_string,
                    135:
                    136:        tcic_chip_socket_enable,
                    137:        tcic_chip_socket_disable,
                    138: };
                    139:
                    140: int
                    141: tcic_isa_probe(parent, match, aux)
                    142:        struct device *parent;
                    143:        void *match;
                    144:        void *aux;
                    145: {
                    146:        struct isa_attach_args *ia = aux;
                    147:        bus_space_tag_t iot = ia->ia_iot;
                    148:        bus_space_handle_t ioh, memh;
                    149:        int val, found;
                    150:
                    151:        /* Disallow wildcarded i/o address. */
                    152:        if (ia->ia_iobase == -1 /* ISACF_PORT_DEFAULT */)
                    153:                return (0);
                    154:
                    155:        if (bus_space_map(iot, ia->ia_iobase, TCIC_IOSIZE, 0, &ioh))
                    156:                return (0);
                    157:
                    158:        if (ia->ia_msize == 0)
                    159:                ia->ia_msize = TCIC_MEMSIZE;
                    160:
                    161:        if (bus_space_map(ia->ia_memt, ia->ia_maddr, ia->ia_msize, 0, &memh))
                    162:                return (0);
                    163:
                    164:        DPRINTF(("tcic probing 0x%03x\n", ia->ia_iobase));
                    165:        found = 0;
                    166:
                    167:        /*
                    168:         * First, check for the reserved bits to be zero.
                    169:         */
                    170:        if (tcic_check_reserved_bits(iot, ioh)) {
                    171:                DPRINTF(("tcic: reserved bits checked OK\n"));
                    172:                /* Second, check whether the we know how to handle the chip. */
                    173:                if ((val = tcic_chipid(iot, ioh))) {
                    174:                        DPRINTF(("tcic id: 0x%02x\n", val));
                    175:                        if (tcic_chipid_known(val))
                    176:                                found++;
                    177:                }
                    178:        }
                    179:        else
                    180:                DPRINTF(("tcic: reserved bits didn't check OK\n"));
                    181:
                    182:        bus_space_unmap(iot, ioh, TCIC_IOSIZE);
                    183:        bus_space_unmap(ia->ia_memt, memh, ia->ia_msize);
                    184:
                    185:        if (!found)
                    186:                return (0);
                    187:
                    188:        ia->ia_iosize = TCIC_IOSIZE;
                    189:
                    190:        return (1);
                    191: }
                    192:
                    193: void
                    194: tcic_isa_attach(parent, self, aux)
                    195:        struct device *parent, *self;
                    196:        void *aux;
                    197: {
                    198:        struct tcic_softc *sc = (void *) self;
                    199:        struct isa_attach_args *ia = aux;
                    200:        isa_chipset_tag_t ic = ia->ia_ic;
                    201:        bus_space_tag_t iot = ia->ia_iot;
                    202:        bus_space_tag_t memt = ia->ia_memt;
                    203:        bus_space_handle_t ioh;
                    204:        bus_space_handle_t memh;
                    205:
                    206:        /* Map i/o space. */
                    207:        if (bus_space_map(iot, ia->ia_iobase, ia->ia_iosize, 0, &ioh)) {
                    208:                printf(": can't map i/o space\n");
                    209:                return;
                    210:        }
                    211:
                    212:        /* Map mem space. */
                    213:        if (bus_space_map(memt, ia->ia_maddr, ia->ia_msize, 0, &memh)) {
                    214:                printf(": can't map mem space\n");
                    215:                return;
                    216:        }
                    217:
                    218:        sc->membase = ia->ia_maddr;
                    219:        sc->subregionmask = (1 << (ia->ia_msize / TCIC_MEM_PAGESIZE)) - 1;
                    220:        sc->memsize2 = tcic_log2((u_int)ia->ia_msize);
                    221:
                    222:        sc->intr_est = ic;
                    223:        sc->pct = (pcmcia_chipset_tag_t) &tcic_isa_functions;
                    224:
                    225:        sc->iot = iot;
                    226:        sc->ioh = ioh;
                    227:        sc->memt = memt;
                    228:        sc->memh = memh;
                    229:
                    230:        /*
                    231:         * determine chip type and initialise some chip type dependend
                    232:         * parameters in softc.
                    233:         */
                    234:        sc->chipid = tcic_chipid(iot, ioh);
                    235:        sc->validirqs = tcic_validirqs(sc->chipid);
                    236:
                    237:        /*
                    238:         * allocate an irq.  interrupts are relatively
                    239:         * scarce but for TCIC controllers very infrequent.
                    240:         */
                    241:
                    242:        if ((sc->irq = ia->ia_irq) == IRQUNK) {
                    243:                if (isa_intr_alloc(ic,
                    244:                    sc->validirqs & (tcic_isa_intr_alloc_mask & 0xff00),
                    245:                    IST_EDGE, &sc->irq)) {
                    246:                        printf("\n%s: can't allocate interrupt\n",
                    247:                            sc->dev.dv_xname);
                    248:                        return;
                    249:                }
                    250:                printf(": using irq %d", sc->irq);
                    251:        }
                    252:        printf("\n");
                    253:
                    254:        tcic_attach(sc);
                    255:
                    256:
                    257:        /*
                    258:         * XXX mycroft recommends I/O space range 0x400-0xfff.
                    259:         */
                    260:
                    261:        /*
                    262:         * XXX some hardware doesn't seem to grok addresses in 0x400 range--
                    263:         * apparently missing a bit or more of address lines. (e.g.
                    264:         * CIRRUS_PD672X with Linksys EthernetCard ne2000 clone in TI
                    265:         * TravelMate 5000--not clear which is at fault)
                    266:         *
                    267:         * Add a kludge to detect 10 bit wide buses and deal with them,
                    268:         * and also a config file option to override the probe.
                    269:         */
                    270:
                    271: #if 0
                    272:        /*
                    273:         * This is what we'd like to use, but...
                    274:         */
                    275:        sc->iobase = 0x400;
                    276:        sc->iosize = 0xbff;
                    277: #else
                    278:        /*
                    279:         * ...the above bus width probe doesn't always work.
                    280:         * So, experimentation has shown the following range
                    281:         * to not lose on systems that 0x300-0x3ff loses on
                    282:         * (e.g. the NEC Versa 6030X).
                    283:         */
                    284:        sc->iobase = 0x330;
                    285:        sc->iosize = 0x0cf;
                    286: #endif
                    287:
                    288:        DPRINTF(("%s: bus_space_alloc range 0x%04lx-0x%04lx)\n",
                    289:            sc->dev.dv_xname, (long) sc->iobase,
                    290:            (long) sc->iobase + sc->iosize));
                    291:
                    292:        if (tcic_isa_alloc_iobase && tcic_isa_alloc_iosize) {
                    293:                sc->iobase = tcic_isa_alloc_iobase;
                    294:                sc->iosize = tcic_isa_alloc_iosize;
                    295:
                    296:                DPRINTF(("%s: bus_space_alloc range 0x%04lx-0x%04lx "
                    297:                    "(config override)\n", sc->dev.dv_xname, (long) sc->iobase,
                    298:                    (long) sc->iobase + sc->iosize));
                    299:        }
                    300:        sc->ih = isa_intr_establish(ic, sc->irq, IST_EDGE, IPL_TTY,
                    301:            tcic_intr, sc, sc->dev.dv_xname);
                    302:        if (sc->ih == NULL) {
                    303:                printf("%s: can't establish interrupt\n", sc->dev.dv_xname);
                    304:                return;
                    305:        }
                    306:
                    307:        tcic_attach_sockets(sc);
                    308: }
                    309:
                    310: void *
                    311: tcic_isa_chip_intr_establish(pch, pf, ipl, fct, arg, xname)
                    312:        pcmcia_chipset_handle_t pch;
                    313:        struct pcmcia_function *pf;
                    314:        int ipl;
                    315:        int (*fct)(void *);
                    316:        void *arg;
                    317:        char *xname;
                    318: {
                    319:        struct tcic_handle *h = (struct tcic_handle *) pch;
                    320:        int irq, ist, val, reg;
                    321:        void *ih;
                    322:        int irqmap[] = {
                    323:            0, 0, 0, TCIC_SCF1_IRQ3, TCIC_SCF1_IRQ4, TCIC_SCF1_IRQ5,
                    324:            TCIC_SCF1_IRQ6, TCIC_SCF1_IRQ7, 0, TCIC_SCF1_IRQ9,
                    325:            TCIC_SCF1_IRQ10, TCIC_SCF1_IRQ11, TCIC_SCF1_IRQ12, 0,
                    326:            TCIC_SCF1_IRQ14, TCIC_SCF1_IRQ15
                    327:        };
                    328:
                    329:        DPRINTF(("%s: tcic_isa_chip_intr_establish\n", h->sc->dev.dv_xname));
                    330:
                    331:        /* XXX should we convert level to pulse? -chb  */
                    332:        if (pf->cfe->flags & PCMCIA_CFE_IRQLEVEL)
                    333:                ist = IST_LEVEL;
                    334:        else if (pf->cfe->flags & PCMCIA_CFE_IRQPULSE)
                    335:                ist = IST_PULSE;
                    336:        else
                    337:                ist = IST_LEVEL;
                    338:
                    339:        if (isa_intr_alloc(h->sc->intr_est,
                    340:            h->sc->validirqs & tcic_isa_intr_alloc_mask, ist, &irq))
                    341:                return (NULL);
                    342:        if ((ih = isa_intr_establish(h->sc->intr_est, irq, ist, ipl,
                    343:            fct, arg, h->pcmcia->dv_xname)) == NULL)
                    344:                return (NULL);
                    345:
                    346:        DPRINTF(("%s: intr established\n", h->sc->dev.dv_xname));
                    347:
                    348:        h->ih_irq = irq;
                    349:
                    350:        reg = TCIC_IR_SCF1_N(h->sock);
                    351:        val = (tcic_read_ind_2(h, reg) & (~TCIC_SCF1_IRQ_MASK)) | irqmap[irq];
                    352:        tcic_write_ind_2(h, reg, val);
                    353:
                    354:        printf(" irq %d", irq);
                    355:        return (ih);
                    356: }
                    357:
                    358: void
                    359: tcic_isa_chip_intr_disestablish(pch, ih)
                    360:        pcmcia_chipset_handle_t pch;
                    361:        void *ih;
                    362: {
                    363:        struct tcic_handle *h = (struct tcic_handle *) pch;
                    364:        int val, reg;
                    365:
                    366:        DPRINTF(("%s: tcic_isa_chip_intr_disestablish\n", h->sc->dev.dv_xname));
                    367:
                    368:        h->ih_irq = 0;
                    369:
                    370:        reg = TCIC_IR_SCF1_N(h->sock);
                    371:        val = tcic_read_ind_2(h, reg);
                    372:        val &= ~TCIC_SCF1_IRQ_MASK;
                    373:        tcic_write_ind_2(h, reg, val);
                    374:
                    375:        isa_intr_disestablish(h->sc->intr_est, ih);
                    376: }
                    377:
                    378: const char *
                    379: tcic_isa_chip_intr_string(pch, ih)
                    380:        pcmcia_chipset_handle_t pch;
                    381:        void *ih;
                    382: {
                    383:        struct tcic_handle *h = (struct tcic_handle *) pch;
                    384:        static char irqstr[64];
                    385:
                    386:        if (ih == NULL)
                    387:                snprintf(irqstr, sizeof(irqstr), "couldn't establish interrupt");
                    388:        else
                    389:                snprintf(irqstr, sizeof(irqstr), "irq %d", h->ih_irq);
                    390:        return (irqstr);
                    391: }

CVSweb