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