Home | History | Annotate | Line # | Download | only in ic
i82365.c revision 1.1.2.6
      1 #define PCICDEBUG
      2 
      3 #include <sys/types.h>
      4 #include <sys/param.h>
      5 #include <sys/systm.h>
      6 #include <sys/device.h>
      7 #include <sys/extent.h>
      8 #include <sys/malloc.h>
      9 
     10 #include <vm/vm.h>
     11 
     12 #include <machine/bus.h>
     13 #include <machine/intr.h>
     14 
     15 #include <dev/isa/isareg.h>
     16 #include <dev/isa/isavar.h>
     17 
     18 #include <dev/pcmcia/pcmciareg.h>
     19 #include <dev/pcmcia/pcmciavar.h>
     20 
     21 #include <dev/ic/i82365reg.h>
     22 
     23 #ifdef PCICDEBUG
     24 int	pcic_debug = 0;
     25 #define DPRINTF(arg) if (pcic_debug) printf arg;
     26 #else
     27 #define DPRINTF(arg)
     28 #endif
     29 
     30 /* This is sort of arbitrary.  It merely needs to be "enough".
     31    It can be overridden in the conf file, anyway. */
     32 
     33 #define PCIC_MEM_PAGES	4
     34 #define PCIC_MEMSIZE	PCIC_MEM_PAGES*PCIC_MEM_PAGESIZE
     35 
     36 #define PCIC_NSLOTS	4
     37 
     38 #define PCIC_FLAG_SOCKETP	0x0001
     39 #define PCIC_FLAG_CARDP		0x0002
     40 
     41 #define PCIC_VENDOR_UNKNOWN		0
     42 #define PCIC_VENDOR_I82365SLR0		1
     43 #define PCIC_VENDOR_I82365SLR1		2
     44 #define PCIC_VENDOR_CIRRUS_PD6710	3
     45 #define PCIC_VENDOR_CIRRUS_PD672X	4
     46 
     47 struct pcic_handle {
     48     struct pcic_softc *sc;
     49     int vendor;
     50     int sock;
     51     int flags;
     52     int memalloc;
     53     int ioalloc;
     54     struct device *pcmcia;
     55 };
     56 
     57 struct pcic_softc {
     58     struct device dev;
     59 
     60     isa_chipset_tag_t ic;
     61 
     62     bus_space_tag_t memt;
     63     bus_space_tag_t memh;
     64     bus_space_tag_t iot;
     65     bus_space_tag_t ioh;
     66 
     67     /* this needs to be large enough to hold PCIC_MEM_PAGES bits */
     68     int subregionmask;
     69 
     70     /* used by memory window mapping functions */
     71     bus_addr_t membase;
     72 
     73     int irq;
     74     void *ih;
     75 
     76     struct pcic_handle handle[PCIC_NSLOTS];
     77 };
     78 
     79 #define C0SA PCIC_CHIP0_BASE+PCIC_SOCKETA_INDEX
     80 #define C0SB PCIC_CHIP0_BASE+PCIC_SOCKETB_INDEX
     81 #define C1SA PCIC_CHIP1_BASE+PCIC_SOCKETA_INDEX
     82 #define C1SB PCIC_CHIP1_BASE+PCIC_SOCKETB_INDEX
     83 
     84 /* Individual drivers will allocate their own memory and io regions.
     85    Memory regions must be a multiple of 4k, aligned on a 4k boundary. */
     86 
     87 #define PCIC_MEM_ALIGN	PCIC_MEM_PAGESIZE
     88 
     89 int pcic_probe __P((struct device *, void *, void *));
     90 void pcic_attach __P((struct device *, struct device *, void *));
     91 
     92 int pcic_ident_ok __P((int));
     93 int pcic_vendor __P((struct pcic_handle *));
     94 char *pcic_vendor_to_string __P((int));
     95 static inline int pcic_read __P((struct pcic_handle *, int));
     96 static inline void pcic_write __P((struct pcic_handle *, int, int));
     97 static inline void pcic_wait_ready __P((struct pcic_handle *));
     98 void pcic_attach_socket __P((struct pcic_handle *));
     99 void pcic_init_socket __P((struct pcic_handle *));
    100 
    101 #ifdef __BROKEN_INDIRECT_CONFIG
    102 int pcic_submatch __P((struct device *, void *, void *));
    103 #else
    104 int pcic_submatch __P((struct device *, struct cfdata *, void *));
    105 #endif
    106 int pcic_print __P((void *arg, const char *pnp));
    107 int pcic_intr __P((void *arg));
    108 int pcic_intr_socket __P((struct pcic_handle *));
    109 
    110 int pcic_chip_mem_alloc __P((pcmcia_chipset_handle_t, bus_size_t,
    111 			     struct pcmcia_mem_handle *));
    112 void pcic_chip_mem_free __P((pcmcia_chipset_handle_t,
    113 			     struct pcmcia_mem_handle *));
    114 int pcic_chip_mem_map __P((pcmcia_chipset_handle_t, int, bus_addr_t,
    115 			   bus_size_t, struct pcmcia_mem_handle *,
    116 			   bus_addr_t *, int *));
    117 void pcic_chip_mem_unmap __P((pcmcia_chipset_handle_t, int));
    118 
    119 int pcic_chip_io_alloc __P((pcmcia_chipset_handle_t, bus_addr_t, bus_size_t,
    120 			    struct pcmcia_io_handle *));
    121 void pcic_chip_io_free __P((pcmcia_chipset_handle_t,
    122 			    struct pcmcia_io_handle *));
    123 int pcic_chip_io_map __P((pcmcia_chipset_handle_t, int, bus_addr_t, bus_size_t,
    124 			  struct pcmcia_io_handle *, int *));
    125 void pcic_chip_io_unmap __P((pcmcia_chipset_handle_t, int));
    126 
    127 void *pcic_chip_intr_establish __P((pcmcia_chipset_handle_t,
    128 				    struct pcmcia_function *, int,
    129 				    int (*)(void *), void *));
    130 void pcic_chip_intr_disestablish __P((pcmcia_chipset_handle_t, void *));
    131 
    132 
    133 void pcic_attach_card(struct pcic_handle *);
    134 void pcic_detach_card(struct pcic_handle *);
    135 
    136 static struct pcmcia_chip_functions pcic_functions = {
    137     pcic_chip_mem_alloc,
    138     pcic_chip_mem_free,
    139     pcic_chip_mem_map,
    140     pcic_chip_mem_unmap,
    141 
    142     pcic_chip_io_alloc,
    143     pcic_chip_io_free,
    144     pcic_chip_io_map,
    145     pcic_chip_io_unmap,
    146 
    147     pcic_chip_intr_establish,
    148     pcic_chip_intr_disestablish,
    149 };
    150 
    151 struct cfdriver pcic_cd = {
    152 	NULL, "pcic", DV_DULL
    153 };
    154 
    155 struct cfattach pcic_ca = {
    156 	sizeof(struct pcic_softc), pcic_probe, pcic_attach
    157 };
    158 
    159 static inline int
    160 pcic_read(h, idx)
    161      struct pcic_handle *h;
    162      int idx;
    163 {
    164     if (idx != -1)
    165 	bus_space_write_1(h->sc->iot, h->sc->ioh, PCIC_REG_INDEX, h->sock+idx);
    166     return(bus_space_read_1(h->sc->iot, h->sc->ioh, PCIC_REG_DATA));
    167 }
    168 
    169 static inline void
    170 pcic_write(h, idx, data)
    171      struct pcic_handle *h;
    172      int idx;
    173      int data;
    174 {
    175     if (idx != -1)
    176 	bus_space_write_1(h->sc->iot, h->sc->ioh, PCIC_REG_INDEX, h->sock+idx);
    177     bus_space_write_1(h->sc->iot, h->sc->ioh, PCIC_REG_DATA, (data));
    178 }
    179 
    180 static inline void
    181 pcic_wait_ready(h)
    182      struct pcic_handle *h;
    183 {
    184     int i;
    185 
    186     for (i=0; i<10000; i++) {
    187 	if (pcic_read(h, PCIC_IF_STATUS) & PCIC_IF_STATUS_READY)
    188 	    return;
    189 	delay(500);
    190     }
    191 
    192     DPRINTF(("pcic_wait_ready ready never happened\n"));
    193 }
    194 
    195 int
    196 pcic_ident_ok(ident)
    197      int ident;
    198 {
    199     /* this is very empirical and heuristic */
    200 
    201     if ((ident == 0) || (ident == 0xff) || (ident & PCIC_IDENT_ZERO))
    202 	return(0);
    203 
    204     if ((ident & PCIC_IDENT_IFTYPE_MASK) != PCIC_IDENT_IFTYPE_MEM_AND_IO) {
    205 #ifdef DIAGNOSTIC
    206 	printf("pcic: does not support memory and I/O cards, ignored (ident=%0x)\n",
    207 	       ident);
    208 #endif
    209 	return(0);
    210     }
    211 
    212     return(1);
    213 }
    214 
    215 int
    216 pcic_vendor(h)
    217      struct pcic_handle *h;
    218 {
    219     int reg;
    220 
    221     /* I can't claim to understand this; I'm just doing what the
    222        linux driver does */
    223 
    224     pcic_write(h, PCIC_CIRRUS_CHIP_INFO, 0);
    225     reg = pcic_read(h, -1);
    226 
    227     if ((reg & PCIC_CIRRUS_CHIP_INFO_CHIP_ID) ==
    228 	PCIC_CIRRUS_CHIP_INFO_CHIP_ID) {
    229 	reg = pcic_read(h, -1);
    230 	if ((reg & PCIC_CIRRUS_CHIP_INFO_CHIP_ID) == 0) {
    231 	    if (reg & PCIC_CIRRUS_CHIP_INFO_SLOTS)
    232 		return(PCIC_VENDOR_CIRRUS_PD672X);
    233 	    else
    234 		return(PCIC_VENDOR_CIRRUS_PD6710);
    235 	}
    236     }
    237 
    238     reg = pcic_read(h, PCIC_IDENT);
    239 
    240     if ((reg & PCIC_IDENT_REV_MASK) == PCIC_IDENT_REV_I82365SLR0)
    241 	return(PCIC_VENDOR_I82365SLR0);
    242     else
    243 	return(PCIC_VENDOR_I82365SLR1);
    244 
    245     return(PCIC_VENDOR_UNKNOWN);
    246 }
    247 
    248 char *
    249 pcic_vendor_to_string(vendor)
    250      int vendor;
    251 {
    252     switch (vendor) {
    253     case PCIC_VENDOR_I82365SLR0:
    254 	return("Intel 82365SL Revision 0");
    255     case PCIC_VENDOR_I82365SLR1:
    256 	return("Intel 82365SL Revision 1");
    257     case PCIC_VENDOR_CIRRUS_PD6710:
    258 	return("Cirrus PD6710");
    259     case PCIC_VENDOR_CIRRUS_PD672X:
    260 	return("Cirrus PD672X");
    261     }
    262 
    263     return("Unknown controller");
    264 }
    265 
    266 int
    267 pcic_probe(parent, match, aux)
    268 	struct device *parent;
    269 	void *match, *aux;
    270 {
    271     struct isa_attach_args *ia = aux;
    272     bus_space_tag_t iot = ia->ia_iot;
    273     bus_space_handle_t ioh, memh;
    274     int val, found;
    275 
    276     DPRINTF(("pcic_probe %x\n", ia->ia_iobase));
    277 
    278     if (bus_space_map(iot, ia->ia_iobase, PCIC_IOSIZE, 0, &ioh))
    279 	return (0);
    280 
    281     if (ia->ia_msize == -1)
    282 	ia->ia_msize = PCIC_MEMSIZE;
    283 
    284     if (bus_space_map(ia->ia_memt, ia->ia_maddr, ia->ia_msize, 0, &memh))
    285 	return (0);
    286 
    287     found = 0;
    288 
    289     /* this could be done with a loop, but it would violate the
    290        abstraction */
    291 
    292     bus_space_write_1(iot, ioh, PCIC_REG_INDEX, C0SA+PCIC_IDENT);
    293 
    294     val = bus_space_read_1(iot, ioh, PCIC_REG_DATA);
    295 
    296     DPRINTF(("c0sa ident = %02x, ", val));
    297 
    298     if (pcic_ident_ok(val))
    299 	found++;
    300 
    301 
    302     bus_space_write_1(iot, ioh, PCIC_REG_INDEX, C0SB+PCIC_IDENT);
    303 
    304     val = bus_space_read_1(iot, ioh, PCIC_REG_DATA);
    305 
    306     DPRINTF(("c0sb ident = %02x, ", val));
    307 
    308     if (pcic_ident_ok(val))
    309 	found++;
    310 
    311 
    312     bus_space_write_1(iot, ioh, PCIC_REG_INDEX, C1SA+PCIC_IDENT);
    313 
    314     val = bus_space_read_1(iot, ioh, PCIC_REG_DATA);
    315 
    316     DPRINTF(("c1sa ident = %02x, ", val));
    317 
    318     if (pcic_ident_ok(val))
    319 	found++;
    320 
    321 
    322     bus_space_write_1(iot, ioh, PCIC_REG_INDEX, C1SB+PCIC_IDENT);
    323 
    324     val = bus_space_read_1(iot, ioh, PCIC_REG_DATA);
    325 
    326     DPRINTF(("c1sb ident = %02x\n", val));
    327 
    328     if (pcic_ident_ok(val))
    329 	found++;
    330 
    331 
    332     bus_space_unmap(iot, ioh, PCIC_IOSIZE);
    333     bus_space_unmap(ia->ia_memt, memh, ia->ia_msize);
    334 
    335     if (!found)
    336 	return(0);
    337 
    338     ia->ia_iosize = PCIC_IOSIZE;
    339 
    340     return(1);
    341 }
    342 
    343 void
    344 pcic_attach(parent, self, aux)
    345      struct device *parent, *self;
    346      void *aux;
    347 {
    348     struct pcic_softc *sc = (void *)self;
    349     struct isa_attach_args *ia = aux;
    350     isa_chipset_tag_t ic = ia->ia_ic;
    351     bus_space_tag_t iot = ia->ia_iot;
    352     bus_space_tag_t memt = ia->ia_memt;
    353     bus_space_handle_t ioh;
    354     bus_space_handle_t memh;
    355     int vendor, count, i;
    356 
    357     /* Map i/o space. */
    358     if (bus_space_map(iot, ia->ia_iobase, ia->ia_iosize, 0, &ioh))
    359 	panic("pcic_attach: can't map i/o space");
    360 
    361     /* Map mem space. */
    362     if (bus_space_map(memt, ia->ia_maddr, ia->ia_msize, 0, &memh))
    363 	panic("pcic_attach: can't map i/o space");
    364 
    365     sc->subregionmask = (1<<(ia->ia_msize/PCIC_MEM_PAGESIZE))-1;
    366 
    367     sc->ic = ic;
    368 
    369     sc->iot = iot;
    370     sc->ioh = ioh;
    371     sc->memt = memt;
    372     sc->memh = memh;
    373 
    374     sc->membase = ia->ia_maddr;
    375 
    376     /* now check for each controller/socket */
    377 
    378     /* this could be done with a loop, but it would violate the
    379        abstraction */
    380 
    381     count = 0;
    382 
    383     sc->handle[0].sc = sc;
    384     sc->handle[0].sock = C0SA;
    385     if (pcic_ident_ok(pcic_read(&sc->handle[0], PCIC_IDENT))) {
    386 	sc->handle[0].flags = PCIC_FLAG_SOCKETP;
    387 	count++;
    388     } else {
    389 	sc->handle[0].flags = 0;
    390     }
    391 
    392     sc->handle[1].sc = sc;
    393     sc->handle[1].sock = C0SB;
    394     if (pcic_ident_ok(pcic_read(&sc->handle[1], PCIC_IDENT))) {
    395 	sc->handle[1].flags = PCIC_FLAG_SOCKETP;
    396 	count++;
    397     } else {
    398 	sc->handle[1].flags = 0;
    399     }
    400 
    401     sc->handle[2].sc = sc;
    402     sc->handle[2].sock = C1SA;
    403     if (pcic_ident_ok(pcic_read(&sc->handle[2], PCIC_IDENT))) {
    404 	sc->handle[2].flags = PCIC_FLAG_SOCKETP;
    405 	count++;
    406     } else {
    407 	sc->handle[2].flags = 0;
    408     }
    409 
    410     sc->handle[3].sc = sc;
    411     sc->handle[3].sock = C1SB;
    412     if (pcic_ident_ok(pcic_read(&sc->handle[3], PCIC_IDENT))) {
    413 	sc->handle[3].flags = PCIC_FLAG_SOCKETP;
    414 	count++;
    415     } else {
    416 	sc->handle[3].flags = 0;
    417     }
    418 
    419     if (count == 0)
    420 	panic("pcic_attach: attach found no sockets");
    421 
    422     /* allocate an irq.  it will be used by both controllers.  I could
    423        use two different interrupts, but interrupts are relatively
    424        scarce, shareable, and for PCIC controllers, very infrequent. */
    425 
    426     if ((sc->irq = ia->ia_irq) == IRQUNK) {
    427 	/* XXX CHECK RETURN VALUE */
    428 	(void) isa_intr_alloc(ic,
    429 			      PCIC_CSC_INTR_IRQ_VALIDMASK,
    430 			      IST_EDGE, &sc->irq);
    431 	printf(": using irq %d", sc->irq);
    432     }
    433 
    434     printf("\n");
    435 
    436     /* establish the interrupt */
    437 
    438     /* XXX block interrupts? */
    439 
    440     for (i=0; i<PCIC_NSLOTS; i++) {
    441 	pcic_write(&sc->handle[i], PCIC_CSC_INTR, 0);
    442 	pcic_read(&sc->handle[i], PCIC_CSC);
    443     }
    444 
    445     sc->ih = isa_intr_establish(ic, sc->irq, IST_EDGE, IPL_TTY, pcic_intr, sc);
    446 
    447     if ((sc->handle[0].flags & PCIC_FLAG_SOCKETP) ||
    448 	(sc->handle[1].flags & PCIC_FLAG_SOCKETP)) {
    449 	vendor = pcic_vendor(&sc->handle[0]);
    450 
    451 	printf("%s: controller 0 (%s) has ", sc->dev.dv_xname,
    452 	       pcic_vendor_to_string(vendor));
    453 
    454 	if ((sc->handle[0].flags & PCIC_FLAG_SOCKETP) &&
    455 	    (sc->handle[1].flags & PCIC_FLAG_SOCKETP))
    456 	    printf("sockets A and B\n");
    457 	else if (sc->handle[0].flags & PCIC_FLAG_SOCKETP)
    458 	    printf("socket A only\n");
    459 	else
    460 	    printf("socket B only\n");
    461 
    462 #if 0
    463 	pcic_write(&sc->handle[0], PCIC_GLOBAL_CTL,
    464 		   PCIC_GLOBAL_CTL_EXPLICIT_CSC_ACK);
    465 #endif
    466 
    467 	if (sc->handle[0].flags & PCIC_FLAG_SOCKETP) {
    468 	    sc->handle[0].vendor = vendor;
    469 	    pcic_attach_socket(&sc->handle[0]);
    470 	}
    471 	if (sc->handle[1].flags & PCIC_FLAG_SOCKETP) {
    472 	    sc->handle[1].vendor = vendor;
    473 	    pcic_attach_socket(&sc->handle[1]);
    474 	}
    475     }
    476 
    477     if ((sc->handle[2].flags & PCIC_FLAG_SOCKETP) ||
    478 	(sc->handle[3].flags & PCIC_FLAG_SOCKETP)) {
    479 	vendor = pcic_vendor(&sc->handle[2]);
    480 
    481 	printf("%s: controller 1 (%s) has ", sc->dev.dv_xname,
    482 	       pcic_vendor_to_string(vendor));
    483 
    484 	if ((sc->handle[2].flags & PCIC_FLAG_SOCKETP) &&
    485 	    (sc->handle[3].flags & PCIC_FLAG_SOCKETP))
    486 	    printf("sockets A and B\n");
    487 	else if (sc->handle[2].flags & PCIC_FLAG_SOCKETP)
    488 	    printf("socket A only\n");
    489 	else
    490 	    printf("socket B only\n");
    491 
    492 #if 0
    493 	pcic_write(&sc->handle[2], PCIC_GLOBAL_CTL,
    494 		   PCIC_GLOBAL_CTL_EXPLICIT_CSC_ACK);
    495 #endif
    496 
    497 	if (sc->handle[2].flags & PCIC_FLAG_SOCKETP) {
    498 	    pcic_attach_socket(&sc->handle[2]);
    499 	    sc->handle[2].vendor = vendor;
    500 	}
    501 	if (sc->handle[3].flags & PCIC_FLAG_SOCKETP) {
    502 	    pcic_attach_socket(&sc->handle[3]);
    503 	    sc->handle[3].vendor = vendor;
    504 	}
    505     }
    506 }
    507 
    508 void
    509 pcic_attach_socket(h)
    510      struct pcic_handle *h;
    511 {
    512    struct pcmciabus_attach_args paa;
    513 
    514    /* initialize the rest of the handle */
    515 
    516    h->memalloc = 0;
    517    h->ioalloc = 0;
    518 
    519    /* now, config one pcmcia device per socket */
    520 
    521    paa.pct = (pcmcia_chipset_tag_t) &pcic_functions;
    522    paa.pch = (pcmcia_chipset_handle_t) h;
    523 
    524    h->pcmcia = config_found_sm(&h->sc->dev, &paa, pcic_print, pcic_submatch);
    525 
    526    /* if there's actually a pcmcia device attached, initialize the slot */
    527 
    528    if (h->pcmcia)
    529        pcic_init_socket(h);
    530 }
    531 
    532 void
    533 pcic_init_socket(h)
    534      struct pcic_handle *h;
    535 {
    536     int reg;
    537 
    538     /* set up the card to interrupt on card detect */
    539 
    540     pcic_write(h, PCIC_CSC_INTR,
    541 	       (h->sc->irq<<PCIC_CSC_INTR_IRQ_SHIFT)|
    542 	       PCIC_CSC_INTR_CD_ENABLE);
    543     pcic_write(h, PCIC_INTR, 0);
    544     pcic_read(h, PCIC_CSC);
    545 
    546     /* unsleep the cirrus controller */
    547 
    548     if ((h->vendor == PCIC_VENDOR_CIRRUS_PD6710) ||
    549 	(h->vendor == PCIC_VENDOR_CIRRUS_PD672X)) {
    550 	reg = pcic_read(h, PCIC_CIRRUS_MISC_CTL_2);
    551 	if (reg & PCIC_CIRRUS_MISC_CTL_2_SUSPEND) {
    552 	    DPRINTF(("%s: socket %02x was suspended\n", h->sc->dev.dv_xname,
    553 		     h->sock));
    554 	    reg &= ~PCIC_CIRRUS_MISC_CTL_2_SUSPEND;
    555 	    pcic_write(h, PCIC_CIRRUS_MISC_CTL_2, reg);
    556 	}
    557     }
    558 
    559     /* if there's a card there, then attach it. */
    560 
    561     reg = pcic_read(h, PCIC_IF_STATUS);
    562 
    563     if ((reg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
    564 	PCIC_IF_STATUS_CARDDETECT_PRESENT)
    565 	pcic_attach_card(h);
    566 }
    567 
    568 int
    569 #ifdef __BROKEN_INDIRECT_CONFIG
    570 pcic_submatch(parent, match, aux)
    571 #else
    572 pcic_submatch(parent, cf, aux)
    573 #endif
    574      struct device *parent;
    575 #ifdef __BROKEN_INDIRECT_CONFIG
    576      void *match;
    577 #else
    578      struct cfdata *cf;
    579 #endif
    580      void *aux;
    581 {
    582 #ifdef __BROKEN_INDIRECT_CONFIG
    583     struct cfdata *cf = match;
    584 #endif
    585 
    586     struct pcmciabus_attach_args *paa = (struct pcmciabus_attach_args *) aux;
    587     struct pcic_handle *h = (struct pcic_handle *) paa->pch;
    588 
    589     switch (h->sock) {
    590     case C0SA:
    591 	if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 0)
    592 	    return 0;
    593 	if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != 0)
    594 	    return 0;
    595 
    596 	break;
    597     case C0SB:
    598 	if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 0)
    599 	    return 0;
    600 	if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != 1)
    601 	    return 0;
    602 
    603 	break;
    604     case C1SA:
    605 	if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 1)
    606 	    return 0;
    607 	if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != 0)
    608 	    return 0;
    609 
    610 	break;
    611     case C1SB:
    612 	if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 1)
    613 	    return 0;
    614 	if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != 1)
    615 	    return 0;
    616 
    617 	break;
    618     default:
    619 	panic("unknown pcic socket");
    620     }
    621 
    622     return ((*cf->cf_attach->ca_match)(parent, cf, aux));
    623 }
    624 
    625 int
    626 pcic_print(arg, pnp)
    627      void *arg;
    628      const char *pnp;
    629 {
    630     struct pcmciabus_attach_args *paa = (struct pcmciabus_attach_args *) arg;
    631     struct pcic_handle *h = (struct pcic_handle *) paa->pch;
    632 
    633     if (pnp)
    634 	printf("pcmcia at %s", pnp);
    635 
    636     switch (h->sock) {
    637     case C0SA:
    638 	printf(" controller 0 socket 0");
    639 	break;
    640     case C0SB:
    641 	printf(" controller 0 socket 1");
    642 	break;
    643     case C1SA:
    644 	printf(" controller 1 socket 0");
    645 	break;
    646     case C1SB:
    647 	printf(" controller 1 socket 1");
    648 	break;
    649     default:
    650 	panic("unknown pcic socket");
    651     }
    652 
    653     return(UNCONF);
    654 }
    655 
    656 int
    657 pcic_intr(arg)
    658      void *arg;
    659 {
    660     struct pcic_softc *sc = (struct pcic_softc *) arg;
    661     int i, ret = 0;
    662 
    663     DPRINTF(("%s: intr\n", sc->dev.dv_xname));
    664 
    665     for (i=0; i<PCIC_NSLOTS; i++)
    666 	if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
    667 	    ret += pcic_intr_socket(&sc->handle[i]);
    668 
    669     return(ret?1:0);
    670 }
    671 
    672 int
    673 pcic_intr_socket(h)
    674      struct pcic_handle *h;
    675 {
    676     int cscreg;
    677 
    678     cscreg = pcic_read(h, PCIC_CSC);
    679 
    680     cscreg &= (PCIC_CSC_GPI |
    681 	       PCIC_CSC_CD |
    682 	       PCIC_CSC_READY |
    683 	       PCIC_CSC_BATTWARN |
    684 	       PCIC_CSC_BATTDEAD);
    685 
    686     if (cscreg & PCIC_CSC_GPI) {
    687 	DPRINTF(("%s: %02x GPI\n", h->sc->dev.dv_xname, h->sock));
    688     }
    689     if (cscreg & PCIC_CSC_CD) {
    690 	int statreg;
    691 
    692 	statreg = pcic_read(h, PCIC_IF_STATUS);
    693 
    694 	DPRINTF(("%s: %02x CD %x\n", h->sc->dev.dv_xname, h->sock,
    695 		 statreg));
    696 
    697 	if ((statreg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
    698 	    PCIC_IF_STATUS_CARDDETECT_PRESENT) {
    699 	    if (!(h->flags & PCIC_FLAG_CARDP))
    700 		pcic_attach_card(h);
    701 	} else {
    702 	    if (h->flags & PCIC_FLAG_CARDP)
    703 		pcic_detach_card(h);
    704 	}
    705     }
    706     if (cscreg & PCIC_CSC_READY) {
    707 	DPRINTF(("%s: %02x READY\n", h->sc->dev.dv_xname, h->sock));
    708 	/* shouldn't happen */
    709     }
    710     if (cscreg & PCIC_CSC_BATTWARN) {
    711 	DPRINTF(("%s: %02x BATTWARN\n", h->sc->dev.dv_xname, h->sock));
    712     }
    713     if (cscreg & PCIC_CSC_BATTDEAD) {
    714 	DPRINTF(("%s: %02x BATTDEAD\n", h->sc->dev.dv_xname, h->sock));
    715     }
    716 
    717 #if 0
    718     /* ack the interrupt */
    719 
    720     pcic_write(h, PCIC_CSC, cscreg);
    721 #endif
    722 
    723     return(cscreg?1:0);
    724 }
    725 
    726 void
    727 pcic_attach_card(h)
    728      struct pcic_handle *h;
    729 {
    730     int iftype;
    731     int reg;
    732 
    733     if (h->flags & PCIC_FLAG_CARDP)
    734 	panic("pcic_attach_card: already attached");
    735 
    736     /* power down the socket to reset it, clear the card reset pin */
    737 
    738     pcic_write(h, PCIC_PWRCTL, 0);
    739 
    740     /* power up the socket */
    741 
    742     pcic_write(h, PCIC_PWRCTL, PCIC_PWRCTL_PWR_ENABLE);
    743     delay(10000);
    744     pcic_write(h, PCIC_PWRCTL, PCIC_PWRCTL_PWR_ENABLE | PCIC_PWRCTL_OE);
    745 
    746     /* clear the reset flag */
    747 
    748     pcic_write(h, PCIC_INTR, PCIC_INTR_RESET);
    749 
    750     /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */
    751 
    752     delay(20000);
    753 
    754     /* wait for the chip to finish initializing */
    755 
    756     pcic_wait_ready(h);
    757 
    758     /* zero out the address windows */
    759 
    760     pcic_write(h, PCIC_ADDRWIN_ENABLE, 0);
    761 
    762 #if 1
    763     pcic_write(h, PCIC_INTR, PCIC_INTR_RESET | PCIC_INTR_CARDTYPE_IO);
    764 #endif
    765 
    766     reg = pcic_read(h, PCIC_INTR);
    767 
    768     DPRINTF(("%s: %02x PCIC_INTR = %02x\n", h->sc->dev.dv_xname,
    769 	     h->sock, reg));
    770 
    771     /* call the MI attach function */
    772 
    773     pcmcia_attach_card(h->pcmcia, &iftype);
    774 
    775     /* set the card type */
    776 
    777     DPRINTF(("%s: %02x cardtype %s\n", h->sc->dev.dv_xname, h->sock,
    778 	     ((iftype == PCMCIA_IFTYPE_IO)?"io":"mem")));
    779 
    780 #if 0
    781     reg = pcic_read(h, PCIC_INTR);
    782     reg &= PCIC_INTR_CARDTYPE_MASK;
    783     reg |= ((iftype == PCMCIA_IFTYPE_IO)?
    784 	    PCIC_INTR_CARDTYPE_IO:
    785 	    PCIC_INTR_CARDTYPE_MEM);
    786     pcic_write(h, PCIC_INTR, reg);
    787 #endif
    788 
    789     h->flags |= PCIC_FLAG_CARDP;
    790 }
    791 
    792 void
    793 pcic_detach_card(h)
    794      struct pcic_handle *h;
    795 {
    796     if (!(h->flags & PCIC_FLAG_CARDP))
    797 	panic("pcic_attach_card: already attached");
    798 
    799     h->flags &= ~PCIC_FLAG_CARDP;
    800 
    801     /* call the MI attach function */
    802 
    803     pcmcia_detach_card(h->pcmcia);
    804 
    805     /* disable card detect resume and configuration reset */
    806 
    807 #if 0
    808     pcic_write(h, PCIC_CARD_DETECT, 0);
    809 #endif
    810 
    811     /* power down the socket */
    812 
    813     pcic_write(h, PCIC_PWRCTL, 0);
    814 
    815     /* reset the card */
    816 
    817     pcic_write(h, PCIC_INTR, 0);
    818 }
    819 
    820 int pcic_chip_mem_alloc(pch, size, pcmhp)
    821      pcmcia_chipset_handle_t pch;
    822      bus_size_t size;
    823      struct pcmcia_mem_handle *pcmhp;
    824 {
    825     struct pcic_handle *h = (struct pcic_handle *) pch;
    826     bus_space_handle_t memh;
    827     bus_addr_t addr;
    828     bus_size_t sizepg;
    829     int i, mask, mhandle;
    830 
    831     /* out of sc->memh, allocate as many pages as necessary */
    832 
    833     /* convert size to PCIC pages */
    834     sizepg = (size + (PCIC_MEM_ALIGN - 1)) / PCIC_MEM_ALIGN;
    835 
    836     mask = (1 << sizepg) - 1;
    837 
    838     addr = 0;		/* XXX gcc -Wuninitialized */
    839     mhandle = 0;	/* XXX gcc -Wuninitialized */
    840     for (i=0; i<(PCIC_MEM_PAGES+1-sizepg); i++) {
    841 	if ((h->sc->subregionmask & (mask<<i)) == (mask<<i)) {
    842 	    if (bus_space_subregion(h->sc->memt, h->sc->memh,
    843 				    i*PCIC_MEM_PAGESIZE,
    844 				    sizepg*PCIC_MEM_PAGESIZE, &memh))
    845 		return(1);
    846 	    mhandle = mask << i;
    847 	    addr = h->sc->membase + (i * PCIC_MEM_PAGESIZE);
    848 	    h->sc->subregionmask &= ~(mhandle);
    849 	    break;
    850 	}
    851     }
    852 
    853     if (i == (PCIC_MEM_PAGES+1-size))
    854 	return(1);
    855 
    856     DPRINTF(("pcic_chip_mem_alloc bus addr 0x%lx+0x%lx\n", (u_long)addr,
    857              (u_long)size));
    858 
    859     pcmhp->memt = h->sc->memt;
    860     pcmhp->memh = memh;
    861     pcmhp->addr = addr;
    862     pcmhp->size = size;
    863     pcmhp->mhandle = mhandle;
    864     pcmhp->realsize = sizepg * PCIC_MEM_PAGESIZE;
    865 
    866     return(0);
    867 }
    868 
    869 void pcic_chip_mem_free(pch, pcmhp)
    870      pcmcia_chipset_handle_t pch;
    871      struct pcmcia_mem_handle *pcmhp;
    872 {
    873     struct pcic_handle *h = (struct pcic_handle *) pch;
    874 
    875     h->sc->subregionmask |= pcmhp->mhandle;
    876 }
    877 
    878 static struct mem_map_index_st {
    879     int sysmem_start_lsb;
    880     int sysmem_start_msb;
    881     int sysmem_stop_lsb;
    882     int sysmem_stop_msb;
    883     int cardmem_lsb;
    884     int cardmem_msb;
    885     int memenable;
    886 } mem_map_index[] = {
    887     {
    888 	PCIC_SYSMEM_ADDR0_START_LSB,
    889 	PCIC_SYSMEM_ADDR0_START_MSB,
    890 	PCIC_SYSMEM_ADDR0_STOP_LSB,
    891 	PCIC_SYSMEM_ADDR0_STOP_MSB,
    892 	PCIC_CARDMEM_ADDR0_LSB,
    893 	PCIC_CARDMEM_ADDR0_MSB,
    894 	PCIC_ADDRWIN_ENABLE_MEM0,
    895     },
    896     {
    897 	PCIC_SYSMEM_ADDR1_START_LSB,
    898 	PCIC_SYSMEM_ADDR1_START_MSB,
    899 	PCIC_SYSMEM_ADDR1_STOP_LSB,
    900 	PCIC_SYSMEM_ADDR1_STOP_MSB,
    901 	PCIC_CARDMEM_ADDR1_LSB,
    902 	PCIC_CARDMEM_ADDR1_MSB,
    903 	PCIC_ADDRWIN_ENABLE_MEM1,
    904     },
    905     {
    906 	PCIC_SYSMEM_ADDR2_START_LSB,
    907 	PCIC_SYSMEM_ADDR2_START_MSB,
    908 	PCIC_SYSMEM_ADDR2_STOP_LSB,
    909 	PCIC_SYSMEM_ADDR2_STOP_MSB,
    910 	PCIC_CARDMEM_ADDR2_LSB,
    911 	PCIC_CARDMEM_ADDR2_MSB,
    912 	PCIC_ADDRWIN_ENABLE_MEM2,
    913     },
    914     {
    915 	PCIC_SYSMEM_ADDR3_START_LSB,
    916 	PCIC_SYSMEM_ADDR3_START_MSB,
    917 	PCIC_SYSMEM_ADDR3_STOP_LSB,
    918 	PCIC_SYSMEM_ADDR3_STOP_MSB,
    919 	PCIC_CARDMEM_ADDR3_LSB,
    920 	PCIC_CARDMEM_ADDR3_MSB,
    921 	PCIC_ADDRWIN_ENABLE_MEM3,
    922     },
    923     {
    924 	PCIC_SYSMEM_ADDR4_START_LSB,
    925 	PCIC_SYSMEM_ADDR4_START_MSB,
    926 	PCIC_SYSMEM_ADDR4_STOP_LSB,
    927 	PCIC_SYSMEM_ADDR4_STOP_MSB,
    928 	PCIC_CARDMEM_ADDR4_LSB,
    929 	PCIC_CARDMEM_ADDR4_MSB,
    930 	PCIC_ADDRWIN_ENABLE_MEM4,
    931     },
    932 };
    933 
    934 int pcic_chip_mem_map(pch, kind, card_addr, size, pcmhp, offsetp, windowp)
    935      pcmcia_chipset_handle_t pch;
    936      int kind;
    937      bus_addr_t card_addr;
    938      bus_size_t size;
    939      struct pcmcia_mem_handle *pcmhp;
    940      bus_addr_t *offsetp;
    941      int *windowp;
    942 {
    943     struct pcic_handle *h = (struct pcic_handle *) pch;
    944     int reg;
    945     bus_addr_t busaddr;
    946     long card_offset;
    947     int i, win;
    948 
    949     win = -1;
    950     for (i=0; i<(sizeof(mem_map_index)/sizeof(mem_map_index[0])); i++) {
    951 	if ((h->memalloc & (1<<i)) == 0) {
    952 	    win = i;
    953 	    h->memalloc |= (1<<i);
    954 	    break;
    955 	}
    956     }
    957 
    958     if (win == -1)
    959 	return(1);
    960 
    961     *windowp = win;
    962 
    963     /* XXX this is pretty gross */
    964 
    965     if (h->sc->memt != pcmhp->memt)
    966 	panic("pcic_chip_mem_map memt is bogus");
    967 
    968     busaddr = pcmhp->addr;
    969 
    970     /* compute the address offset to the pcmcia address space for the
    971        pcic.  this is intentionally signed.  The masks and shifts
    972        below will cause TRT to happen in the pcic registers.  Deal with
    973        making sure the address is aligned, and return the alignment
    974        offset.  */
    975 
    976     *offsetp = card_addr % PCIC_MEM_ALIGN;
    977     card_addr -= *offsetp;
    978 
    979     DPRINTF(("pcic_chip_mem_map window %d bus %lx+%lx+%lx at card addr %lx\n",
    980 	     win, (u_long)busaddr, (u_long)*offsetp, (u_long)size,
    981 	     (u_long)card_addr));
    982 
    983     /* include the offset in the size, and decrement size by one,
    984        since the hw wants start/stop */
    985     size += *offsetp - 1;
    986 
    987     card_offset = (((long) card_addr) - ((long) busaddr));
    988 
    989     pcic_write(h, mem_map_index[win].sysmem_start_lsb,
    990 	       (busaddr >> PCIC_SYSMEM_ADDRX_SHIFT) & 0xff);
    991     pcic_write(h, mem_map_index[win].sysmem_start_msb,
    992 	       ((busaddr >> (PCIC_SYSMEM_ADDRX_SHIFT + 8)) &
    993 		PCIC_SYSMEM_ADDRX_START_MSB_ADDR_MASK));
    994 
    995 #if 0
    996     /* XXX do I want 16 bit all the time? */
    997     PCIC_SYSMEM_ADDRX_START_MSB_DATASIZE_16BIT;
    998 #endif
    999 
   1000     pcic_write(h, mem_map_index[win].sysmem_stop_lsb,
   1001 	       ((busaddr + size) >> PCIC_SYSMEM_ADDRX_SHIFT) & 0xff);
   1002     pcic_write(h, mem_map_index[win].sysmem_stop_msb,
   1003 	       (((busaddr + size) >> (PCIC_SYSMEM_ADDRX_SHIFT + 8)) &
   1004 		PCIC_SYSMEM_ADDRX_STOP_MSB_ADDR_MASK) |
   1005 	       PCIC_SYSMEM_ADDRX_STOP_MSB_WAIT2);
   1006 
   1007 
   1008     pcic_write(h, mem_map_index[win].cardmem_lsb,
   1009 	       (card_offset >> PCIC_CARDMEM_ADDRX_SHIFT) & 0xff);
   1010     pcic_write(h, mem_map_index[win].cardmem_msb,
   1011 	       ((card_offset >> (PCIC_CARDMEM_ADDRX_SHIFT + 8)) &
   1012 		PCIC_CARDMEM_ADDRX_MSB_ADDR_MASK) |
   1013 	       ((kind == PCMCIA_MEM_ATTR)?
   1014 		PCIC_CARDMEM_ADDRX_MSB_REGACTIVE_ATTR:0));
   1015 
   1016     reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
   1017     reg |= (mem_map_index[win].memenable | PCIC_ADDRWIN_ENABLE_MEMCS16 );
   1018     pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
   1019 
   1020 #ifdef PCICDEBUG
   1021     {
   1022 	int r1,r2,r3,r4,r5,r6;
   1023 
   1024 	r1 = pcic_read(h, mem_map_index[win].sysmem_start_msb);
   1025 	r2 = pcic_read(h, mem_map_index[win].sysmem_start_lsb);
   1026 	r3 = pcic_read(h, mem_map_index[win].sysmem_stop_msb);
   1027 	r4 = pcic_read(h, mem_map_index[win].sysmem_stop_lsb);
   1028 	r5 = pcic_read(h, mem_map_index[win].cardmem_msb);
   1029 	r6 = pcic_read(h, mem_map_index[win].cardmem_lsb);
   1030 
   1031 	DPRINTF(("pcic_chip_mem_map window %d: %02x%02x %02x%02x %02x%02x\n",
   1032 		 win, r1, r2, r3, r4, r5, r6));
   1033     }
   1034 #endif
   1035 
   1036     return(0);
   1037 }
   1038 
   1039 void pcic_chip_mem_unmap(pch, window)
   1040      pcmcia_chipset_handle_t pch;
   1041      int window;
   1042 {
   1043     struct pcic_handle *h = (struct pcic_handle *) pch;
   1044     int reg;
   1045 
   1046     if (window >= (sizeof(mem_map_index)/sizeof(mem_map_index[0])))
   1047 	panic("pcic_chip_mem_unmap: window out of range");
   1048 
   1049     reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
   1050     reg &= ~mem_map_index[window].memenable;
   1051     pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
   1052 
   1053     h->memalloc &= ~(1 << window);
   1054 }
   1055 
   1056 
   1057 /* XXX mycroft recommends this I/O space range.  I should put this
   1058    in a header somewhere */
   1059 
   1060 /* XXX some hardware doesn't seem to grok addresses in 0x400 range--
   1061    apparently missing a bit or more of address lines.
   1062    (e.g. CIRRUS_PD672X with Linksys EthernetCard ne2000 clone in TI
   1063    TravelMate 5000--not clear which is at fault)
   1064 
   1065    Allow them to be overridden by patching a kernel and/or by a config
   1066    file option */
   1067 
   1068 #ifndef PCIC_ALLOC_IOBASE
   1069 #define PCIC_ALLOC_IOBASE 0x400
   1070 #endif
   1071 
   1072 int pcic_alloc_iobase = PCIC_ALLOC_IOBASE;
   1073 
   1074 int pcic_chip_io_alloc(pch, start, size, pcihp)
   1075      pcmcia_chipset_handle_t pch;
   1076      bus_addr_t start;
   1077      bus_size_t size;
   1078      struct pcmcia_io_handle *pcihp;
   1079 {
   1080     struct pcic_handle *h = (struct pcic_handle *) pch;
   1081     bus_space_tag_t iot;
   1082     bus_space_handle_t ioh;
   1083     bus_addr_t ioaddr;
   1084     int flags = 0;
   1085 
   1086     /*
   1087      * Allocate some arbitrary I/O space.  XXX There really should be a
   1088      * generic isa interface to this, but there isn't currently one
   1089      */
   1090 
   1091     iot = h->sc->iot;
   1092 
   1093     if (start) {
   1094 	ioaddr = start;
   1095 	if (bus_space_map(iot, start, size, 0, &ioh))
   1096 	    return(1);
   1097 	DPRINTF(("pcic_chip_io_alloc map port %lx+%lx\n",
   1098 		 (u_long) ioaddr, (u_long) size));
   1099     } else {
   1100 	flags |= PCMCIA_IO_ALLOCATED;
   1101 	if (bus_space_alloc(iot, pcic_alloc_iobase, 0xfff, size, size,
   1102 			    0, 0, &ioaddr, &ioh))
   1103 	    return(1);
   1104 	DPRINTF(("pcic_chip_io_alloc alloc port %lx+%lx\n",
   1105 		 (u_long) ioaddr, (u_long) size));
   1106     }
   1107 
   1108     pcihp->iot = iot;
   1109     pcihp->ioh = ioh;
   1110     pcihp->addr = ioaddr;
   1111     pcihp->size = size;
   1112     pcihp->flags = flags;
   1113 
   1114     return(0);
   1115 }
   1116 
   1117 void pcic_chip_io_free(pch, pcihp)
   1118      pcmcia_chipset_handle_t pch;
   1119      struct pcmcia_io_handle *pcihp;
   1120 {
   1121     bus_space_tag_t iot = pcihp->iot;
   1122     bus_space_handle_t ioh = pcihp->ioh;
   1123     bus_size_t size = pcihp->size;
   1124 
   1125     if (pcihp->flags & PCMCIA_IO_ALLOCATED)
   1126 	bus_space_free(iot, ioh, size);
   1127     else
   1128 	bus_space_unmap(iot, ioh, size);
   1129 }
   1130 
   1131 
   1132 static struct io_map_index_st {
   1133     int start_lsb;
   1134     int start_msb;
   1135     int stop_lsb;
   1136     int stop_msb;
   1137     int ioenable;
   1138     int ioctlmask;
   1139     int ioctl8;
   1140     int ioctl16;
   1141 } io_map_index[] = {
   1142     {
   1143 	PCIC_IOADDR0_START_LSB,
   1144 	PCIC_IOADDR0_START_MSB,
   1145 	PCIC_IOADDR0_STOP_LSB,
   1146 	PCIC_IOADDR0_STOP_MSB,
   1147 	PCIC_ADDRWIN_ENABLE_IO0,
   1148 	PCIC_IOCTL_IO0_WAITSTATE | PCIC_IOCTL_IO0_ZEROWAIT |
   1149 	PCIC_IOCTL_IO0_IOCS16SRC_MASK | PCIC_IOCTL_IO0_DATASIZE_MASK,
   1150 	PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE | PCIC_IOCTL_IO0_DATASIZE_8BIT,
   1151 	PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE | PCIC_IOCTL_IO0_DATASIZE_16BIT,
   1152     },
   1153     {
   1154 	PCIC_IOADDR1_START_LSB,
   1155 	PCIC_IOADDR1_START_MSB,
   1156 	PCIC_IOADDR1_STOP_LSB,
   1157 	PCIC_IOADDR1_STOP_MSB,
   1158 	PCIC_ADDRWIN_ENABLE_IO1,
   1159 	PCIC_IOCTL_IO1_WAITSTATE | PCIC_IOCTL_IO1_ZEROWAIT |
   1160 	PCIC_IOCTL_IO1_IOCS16SRC_MASK | PCIC_IOCTL_IO1_DATASIZE_MASK,
   1161 	PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE | PCIC_IOCTL_IO1_DATASIZE_8BIT,
   1162 	PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE | PCIC_IOCTL_IO1_DATASIZE_16BIT,
   1163     },
   1164 };
   1165 
   1166 int pcic_chip_io_map(pch, width, offset, size, pcihp, windowp)
   1167      pcmcia_chipset_handle_t pch;
   1168      int width;
   1169      bus_addr_t offset;
   1170      bus_size_t size;
   1171      struct pcmcia_io_handle *pcihp;
   1172      int *windowp;
   1173 {
   1174     struct pcic_handle *h = (struct pcic_handle *) pch;
   1175     bus_addr_t ioaddr = pcihp->addr + offset;
   1176     int reg;
   1177     int i, win;
   1178 
   1179     /* XXX Sanity check offset/size. */
   1180 
   1181     win = -1;
   1182     for (i=0; i<(sizeof(io_map_index)/sizeof(io_map_index[0])); i++) {
   1183 	if ((h->ioalloc & (1<<i)) == 0) {
   1184 	    win = i;
   1185 	    h->ioalloc |= (1<<i);
   1186 	    break;
   1187 	}
   1188     }
   1189 
   1190     if (win == -1)
   1191 	return(1);
   1192 
   1193     *windowp = win;
   1194 
   1195     /* XXX this is pretty gross */
   1196 
   1197     if (h->sc->iot != pcihp->iot)
   1198 	panic("pcic_chip_io_map iot is bogus");
   1199 
   1200     DPRINTF(("pcic_chip_io_map window %d %s port %lx+%lx\n",
   1201 	     win, (width == PCMCIA_WIDTH_IO8)?"io8":"io16",
   1202 	     (u_long) ioaddr, (u_long) size));
   1203 
   1204     printf(" port 0x%lx", (u_long)ioaddr);
   1205     if (size > 1)
   1206 	printf("-0x%lx", (u_long)ioaddr + (u_long)size - 1);
   1207 
   1208     pcic_write(h, io_map_index[win].start_lsb, ioaddr & 0xff);
   1209     pcic_write(h, io_map_index[win].start_msb, (ioaddr >> 8) & 0xff);
   1210 
   1211     pcic_write(h, io_map_index[win].stop_lsb, (ioaddr + size - 1) & 0xff);
   1212     pcic_write(h, io_map_index[win].stop_msb,
   1213     	       ((ioaddr + size - 1) >> 8) & 0xff);
   1214 
   1215     reg = pcic_read(h, PCIC_IOCTL);
   1216     reg &= ~io_map_index[win].ioctlmask;
   1217     if (width == PCMCIA_WIDTH_IO8)
   1218 	reg |= io_map_index[win].ioctl8;
   1219     else
   1220 	reg |= io_map_index[win].ioctl16;
   1221     pcic_write(h, PCIC_IOCTL, reg);
   1222 
   1223     reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
   1224     reg |= io_map_index[win].ioenable;
   1225     pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
   1226 
   1227     return(0);
   1228 }
   1229 
   1230 void pcic_chip_io_unmap(pch, window)
   1231      pcmcia_chipset_handle_t pch;
   1232      int window;
   1233 {
   1234     struct pcic_handle *h = (struct pcic_handle *) pch;
   1235     int reg;
   1236 
   1237     if (window >= (sizeof(io_map_index)/sizeof(io_map_index[0])))
   1238 	panic("pcic_chip_io_unmap: window out of range");
   1239 
   1240     reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
   1241     reg &= ~io_map_index[window].ioenable;
   1242     pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
   1243 
   1244     h->ioalloc &= ~(1 << window);
   1245 }
   1246 
   1247 /* allow patching or kernel option file override of available IRQs.
   1248    Useful if order of probing would screw up other devices, or if PCIC
   1249    hardware/cards have trouble with certain interrupt lines. */
   1250 
   1251 #ifndef PCIC_INTR_ALLOC_MASK
   1252 #define	PCIC_INTR_ALLOC_MASK	0xffff
   1253 #endif
   1254 
   1255 int	pcic_intr_alloc_mask = PCIC_INTR_ALLOC_MASK;
   1256 
   1257 void *
   1258 pcic_chip_intr_establish(pch, pf, ipl, fct, arg)
   1259      pcmcia_chipset_handle_t pch;
   1260      struct pcmcia_function *pf;
   1261      int ipl;
   1262      int (*fct)(void *);
   1263      void *arg;
   1264 {
   1265     struct pcic_handle *h = (struct pcic_handle *) pch;
   1266     int irq, ist;
   1267     void *ih;
   1268     int reg;
   1269 
   1270     if (pf->cfe->flags & PCMCIA_CFE_IRQLEVEL)
   1271 	ist = IST_LEVEL;
   1272     else if (pf->cfe->flags & PCMCIA_CFE_IRQPULSE)
   1273 	ist = IST_PULSE;
   1274     else
   1275 	ist = IST_LEVEL;
   1276 
   1277     if (isa_intr_alloc(h->sc->ic,
   1278     		       PCIC_INTR_IRQ_VALIDMASK & pcic_intr_alloc_mask,
   1279     		       ist, &irq))
   1280 	return(NULL);
   1281     if (!(ih = isa_intr_establish(h->sc->ic, irq, ist, ipl, fct, arg)))
   1282 	return(NULL);
   1283 
   1284     reg = pcic_read(h, PCIC_INTR);
   1285     reg &= ~PCIC_INTR_IRQ_MASK;
   1286     reg |= PCIC_INTR_ENABLE;
   1287     reg |= irq;
   1288     pcic_write(h, PCIC_INTR, reg);
   1289 
   1290     printf("%s: card irq %d\n", h->pcmcia->dv_xname, irq);
   1291 
   1292     return(ih);
   1293 }
   1294 
   1295 void pcic_chip_intr_disestablish(pch, ih)
   1296      pcmcia_chipset_handle_t pch;
   1297      void *ih;
   1298 {
   1299     struct pcic_handle *h = (struct pcic_handle *) pch;
   1300     int reg;
   1301 
   1302     reg = pcic_read(h, PCIC_INTR);
   1303     reg &= ~(PCIC_INTR_IRQ_MASK|PCIC_INTR_ENABLE);
   1304     pcic_write(h, PCIC_INTR, reg);
   1305 
   1306     isa_intr_disestablish(h->sc->ic, ih);
   1307 }
   1308