Home | History | Annotate | Line # | Download | only in ic
i82365.c revision 1.1.2.10
      1   1.1.2.1     marc #define PCICDEBUG
      2   1.1.2.1     marc 
      3   1.1.2.1     marc #include <sys/types.h>
      4   1.1.2.1     marc #include <sys/param.h>
      5   1.1.2.1     marc #include <sys/systm.h>
      6   1.1.2.1     marc #include <sys/device.h>
      7   1.1.2.1     marc #include <sys/extent.h>
      8   1.1.2.1     marc #include <sys/malloc.h>
      9   1.1.2.1     marc 
     10   1.1.2.1     marc #include <vm/vm.h>
     11   1.1.2.1     marc 
     12   1.1.2.1     marc #include <machine/bus.h>
     13   1.1.2.1     marc #include <machine/intr.h>
     14   1.1.2.1     marc 
     15   1.1.2.1     marc #include <dev/pcmcia/pcmciareg.h>
     16   1.1.2.4  thorpej #include <dev/pcmcia/pcmciavar.h>
     17   1.1.2.1     marc 
     18   1.1.2.1     marc #include <dev/ic/i82365reg.h>
     19   1.1.2.8     marc #include <dev/ic/i82365var.h>
     20   1.1.2.1     marc 
     21   1.1.2.1     marc #ifdef PCICDEBUG
     22   1.1.2.2  thorpej int	pcic_debug = 0;
     23   1.1.2.2  thorpej #define DPRINTF(arg) if (pcic_debug) printf arg;
     24   1.1.2.1     marc #else
     25   1.1.2.1     marc #define DPRINTF(arg)
     26   1.1.2.1     marc #endif
     27   1.1.2.1     marc 
     28   1.1.2.1     marc #define PCIC_VENDOR_UNKNOWN		0
     29   1.1.2.1     marc #define PCIC_VENDOR_I82365SLR0		1
     30   1.1.2.1     marc #define PCIC_VENDOR_I82365SLR1		2
     31   1.1.2.1     marc #define PCIC_VENDOR_CIRRUS_PD6710	3
     32   1.1.2.1     marc #define PCIC_VENDOR_CIRRUS_PD672X	4
     33   1.1.2.1     marc 
     34   1.1.2.1     marc /* Individual drivers will allocate their own memory and io regions.
     35   1.1.2.1     marc    Memory regions must be a multiple of 4k, aligned on a 4k boundary. */
     36   1.1.2.1     marc 
     37   1.1.2.1     marc #define PCIC_MEM_ALIGN	PCIC_MEM_PAGESIZE
     38   1.1.2.1     marc 
     39   1.1.2.1     marc void pcic_attach_socket __P((struct pcic_handle *));
     40   1.1.2.1     marc void pcic_init_socket __P((struct pcic_handle *));
     41   1.1.2.1     marc 
     42   1.1.2.1     marc #ifdef __BROKEN_INDIRECT_CONFIG
     43   1.1.2.1     marc int pcic_submatch __P((struct device *, void *, void *));
     44   1.1.2.1     marc #else
     45   1.1.2.1     marc int pcic_submatch __P((struct device *, struct cfdata *, void *));
     46   1.1.2.1     marc #endif
     47   1.1.2.1     marc int pcic_print __P((void *arg, const char *pnp));
     48   1.1.2.1     marc int pcic_intr_socket __P((struct pcic_handle *));
     49   1.1.2.1     marc 
     50  1.1.2.10     marc void pcic_attach_card __P((struct pcic_handle *));
     51  1.1.2.10     marc void pcic_detach_card __P((struct pcic_handle *));
     52  1.1.2.10     marc 
     53  1.1.2.10     marc void pcic_chip_do_mem_map __P((struct pcic_handle *, int));
     54  1.1.2.10     marc void pcic_chip_do_io_map __P((struct pcic_handle *, int));
     55   1.1.2.1     marc 
     56   1.1.2.1     marc struct cfdriver pcic_cd = {
     57   1.1.2.1     marc 	NULL, "pcic", DV_DULL
     58   1.1.2.1     marc };
     59   1.1.2.1     marc 
     60   1.1.2.1     marc int
     61   1.1.2.1     marc pcic_ident_ok(ident)
     62   1.1.2.1     marc      int ident;
     63   1.1.2.1     marc {
     64   1.1.2.1     marc     /* this is very empirical and heuristic */
     65   1.1.2.1     marc 
     66   1.1.2.1     marc     if ((ident == 0) || (ident == 0xff) || (ident & PCIC_IDENT_ZERO))
     67   1.1.2.1     marc 	return(0);
     68   1.1.2.1     marc 
     69   1.1.2.1     marc     if ((ident & PCIC_IDENT_IFTYPE_MASK) != PCIC_IDENT_IFTYPE_MEM_AND_IO) {
     70   1.1.2.1     marc #ifdef DIAGNOSTIC
     71   1.1.2.1     marc 	printf("pcic: does not support memory and I/O cards, ignored (ident=%0x)\n",
     72   1.1.2.1     marc 	       ident);
     73   1.1.2.1     marc #endif
     74   1.1.2.1     marc 	return(0);
     75   1.1.2.1     marc     }
     76   1.1.2.1     marc 
     77   1.1.2.1     marc     return(1);
     78   1.1.2.1     marc }
     79   1.1.2.1     marc 
     80   1.1.2.1     marc int
     81   1.1.2.1     marc pcic_vendor(h)
     82   1.1.2.1     marc      struct pcic_handle *h;
     83   1.1.2.1     marc {
     84   1.1.2.1     marc     int reg;
     85   1.1.2.1     marc 
     86   1.1.2.8     marc     /* the chip_id of the cirrus toggles between 11 and 00
     87   1.1.2.8     marc        after a write.  weird. */
     88   1.1.2.1     marc 
     89   1.1.2.1     marc     pcic_write(h, PCIC_CIRRUS_CHIP_INFO, 0);
     90   1.1.2.1     marc     reg = pcic_read(h, -1);
     91   1.1.2.1     marc 
     92   1.1.2.1     marc     if ((reg & PCIC_CIRRUS_CHIP_INFO_CHIP_ID) ==
     93   1.1.2.1     marc 	PCIC_CIRRUS_CHIP_INFO_CHIP_ID) {
     94   1.1.2.1     marc 	reg = pcic_read(h, -1);
     95   1.1.2.1     marc 	if ((reg & PCIC_CIRRUS_CHIP_INFO_CHIP_ID) == 0) {
     96   1.1.2.1     marc 	    if (reg & PCIC_CIRRUS_CHIP_INFO_SLOTS)
     97   1.1.2.1     marc 		return(PCIC_VENDOR_CIRRUS_PD672X);
     98   1.1.2.1     marc 	    else
     99   1.1.2.1     marc 		return(PCIC_VENDOR_CIRRUS_PD6710);
    100   1.1.2.1     marc 	}
    101   1.1.2.1     marc     }
    102   1.1.2.1     marc 
    103   1.1.2.8     marc     /* XXX how do I identify the GD6729? */
    104   1.1.2.8     marc 
    105   1.1.2.1     marc     reg = pcic_read(h, PCIC_IDENT);
    106   1.1.2.1     marc 
    107   1.1.2.1     marc     if ((reg & PCIC_IDENT_REV_MASK) == PCIC_IDENT_REV_I82365SLR0)
    108   1.1.2.1     marc 	return(PCIC_VENDOR_I82365SLR0);
    109   1.1.2.1     marc     else
    110   1.1.2.1     marc 	return(PCIC_VENDOR_I82365SLR1);
    111   1.1.2.1     marc 
    112   1.1.2.1     marc     return(PCIC_VENDOR_UNKNOWN);
    113   1.1.2.1     marc }
    114   1.1.2.1     marc 
    115   1.1.2.1     marc char *
    116   1.1.2.1     marc pcic_vendor_to_string(vendor)
    117   1.1.2.1     marc      int vendor;
    118   1.1.2.1     marc {
    119   1.1.2.1     marc     switch (vendor) {
    120   1.1.2.1     marc     case PCIC_VENDOR_I82365SLR0:
    121   1.1.2.1     marc 	return("Intel 82365SL Revision 0");
    122   1.1.2.1     marc     case PCIC_VENDOR_I82365SLR1:
    123   1.1.2.1     marc 	return("Intel 82365SL Revision 1");
    124   1.1.2.1     marc     case PCIC_VENDOR_CIRRUS_PD6710:
    125   1.1.2.1     marc 	return("Cirrus PD6710");
    126   1.1.2.1     marc     case PCIC_VENDOR_CIRRUS_PD672X:
    127   1.1.2.1     marc 	return("Cirrus PD672X");
    128   1.1.2.1     marc     }
    129   1.1.2.1     marc 
    130   1.1.2.1     marc     return("Unknown controller");
    131   1.1.2.1     marc }
    132   1.1.2.1     marc 
    133   1.1.2.1     marc void
    134   1.1.2.8     marc pcic_attach(sc)
    135   1.1.2.8     marc      struct pcic_softc *sc;
    136   1.1.2.1     marc {
    137  1.1.2.10     marc     int vendor, count, i, reg;
    138   1.1.2.1     marc 
    139   1.1.2.1     marc     /* now check for each controller/socket */
    140   1.1.2.1     marc 
    141   1.1.2.1     marc     /* this could be done with a loop, but it would violate the
    142   1.1.2.1     marc        abstraction */
    143   1.1.2.1     marc 
    144   1.1.2.1     marc     count = 0;
    145   1.1.2.1     marc 
    146  1.1.2.10     marc     DPRINTF(("pcic ident regs:"));
    147  1.1.2.10     marc 
    148   1.1.2.1     marc     sc->handle[0].sc = sc;
    149   1.1.2.1     marc     sc->handle[0].sock = C0SA;
    150  1.1.2.10     marc     if (pcic_ident_ok(reg = pcic_read(&sc->handle[0], PCIC_IDENT))) {
    151   1.1.2.1     marc 	sc->handle[0].flags = PCIC_FLAG_SOCKETP;
    152   1.1.2.1     marc 	count++;
    153   1.1.2.1     marc     } else {
    154   1.1.2.1     marc 	sc->handle[0].flags = 0;
    155   1.1.2.1     marc     }
    156   1.1.2.1     marc 
    157  1.1.2.10     marc     DPRINTF((" 0x%02x", reg));
    158  1.1.2.10     marc 
    159   1.1.2.1     marc     sc->handle[1].sc = sc;
    160   1.1.2.1     marc     sc->handle[1].sock = C0SB;
    161  1.1.2.10     marc     if (pcic_ident_ok(reg = pcic_read(&sc->handle[1], PCIC_IDENT))) {
    162   1.1.2.1     marc 	sc->handle[1].flags = PCIC_FLAG_SOCKETP;
    163   1.1.2.1     marc 	count++;
    164   1.1.2.1     marc     } else {
    165   1.1.2.1     marc 	sc->handle[1].flags = 0;
    166   1.1.2.1     marc     }
    167   1.1.2.1     marc 
    168  1.1.2.10     marc     DPRINTF((" 0x%02x", reg));
    169  1.1.2.10     marc 
    170   1.1.2.1     marc     sc->handle[2].sc = sc;
    171   1.1.2.1     marc     sc->handle[2].sock = C1SA;
    172  1.1.2.10     marc     if (pcic_ident_ok(reg = pcic_read(&sc->handle[2], PCIC_IDENT))) {
    173   1.1.2.1     marc 	sc->handle[2].flags = PCIC_FLAG_SOCKETP;
    174   1.1.2.1     marc 	count++;
    175   1.1.2.1     marc     } else {
    176   1.1.2.1     marc 	sc->handle[2].flags = 0;
    177   1.1.2.1     marc     }
    178   1.1.2.1     marc 
    179  1.1.2.10     marc     DPRINTF((" 0x%02x", reg));
    180  1.1.2.10     marc 
    181   1.1.2.1     marc     sc->handle[3].sc = sc;
    182   1.1.2.1     marc     sc->handle[3].sock = C1SB;
    183  1.1.2.10     marc     if (pcic_ident_ok(reg = pcic_read(&sc->handle[3], PCIC_IDENT))) {
    184   1.1.2.1     marc 	sc->handle[3].flags = PCIC_FLAG_SOCKETP;
    185   1.1.2.1     marc 	count++;
    186   1.1.2.1     marc     } else {
    187   1.1.2.1     marc 	sc->handle[3].flags = 0;
    188   1.1.2.1     marc     }
    189   1.1.2.1     marc 
    190  1.1.2.10     marc     DPRINTF((" 0x%02x\n", reg));
    191  1.1.2.10     marc 
    192   1.1.2.1     marc     if (count == 0)
    193   1.1.2.1     marc 	panic("pcic_attach: attach found no sockets");
    194   1.1.2.1     marc 
    195   1.1.2.1     marc     /* establish the interrupt */
    196   1.1.2.1     marc 
    197   1.1.2.1     marc     /* XXX block interrupts? */
    198   1.1.2.1     marc 
    199   1.1.2.1     marc     for (i=0; i<PCIC_NSLOTS; i++) {
    200  1.1.2.10     marc #if 0
    201  1.1.2.10     marc 	/* this should work, but w/o it, setting tty flags
    202  1.1.2.10     marc 	   hangs at boot time. */
    203  1.1.2.10     marc 	if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
    204  1.1.2.10     marc #endif
    205  1.1.2.10     marc 	    {
    206  1.1.2.10     marc 		pcic_write(&sc->handle[i], PCIC_CSC_INTR, 0);
    207  1.1.2.10     marc 		pcic_read(&sc->handle[i], PCIC_CSC);
    208  1.1.2.10     marc 	    }
    209   1.1.2.1     marc     }
    210   1.1.2.1     marc 
    211   1.1.2.1     marc     if ((sc->handle[0].flags & PCIC_FLAG_SOCKETP) ||
    212   1.1.2.1     marc 	(sc->handle[1].flags & PCIC_FLAG_SOCKETP)) {
    213   1.1.2.1     marc 	vendor = pcic_vendor(&sc->handle[0]);
    214   1.1.2.1     marc 
    215   1.1.2.1     marc 	printf("%s: controller 0 (%s) has ", sc->dev.dv_xname,
    216   1.1.2.1     marc 	       pcic_vendor_to_string(vendor));
    217   1.1.2.1     marc 
    218   1.1.2.1     marc 	if ((sc->handle[0].flags & PCIC_FLAG_SOCKETP) &&
    219   1.1.2.1     marc 	    (sc->handle[1].flags & PCIC_FLAG_SOCKETP))
    220   1.1.2.1     marc 	    printf("sockets A and B\n");
    221   1.1.2.1     marc 	else if (sc->handle[0].flags & PCIC_FLAG_SOCKETP)
    222   1.1.2.1     marc 	    printf("socket A only\n");
    223   1.1.2.1     marc 	else
    224   1.1.2.1     marc 	    printf("socket B only\n");
    225   1.1.2.1     marc 
    226   1.1.2.8     marc 	if (sc->handle[0].flags & PCIC_FLAG_SOCKETP)
    227   1.1.2.1     marc 	    sc->handle[0].vendor = vendor;
    228   1.1.2.8     marc 	if (sc->handle[1].flags & PCIC_FLAG_SOCKETP)
    229   1.1.2.1     marc 	    sc->handle[1].vendor = vendor;
    230   1.1.2.1     marc     }
    231   1.1.2.1     marc 
    232   1.1.2.1     marc     if ((sc->handle[2].flags & PCIC_FLAG_SOCKETP) ||
    233   1.1.2.1     marc 	(sc->handle[3].flags & PCIC_FLAG_SOCKETP)) {
    234   1.1.2.1     marc 	vendor = pcic_vendor(&sc->handle[2]);
    235   1.1.2.1     marc 
    236   1.1.2.1     marc 	printf("%s: controller 1 (%s) has ", sc->dev.dv_xname,
    237   1.1.2.1     marc 	       pcic_vendor_to_string(vendor));
    238   1.1.2.1     marc 
    239   1.1.2.1     marc 	if ((sc->handle[2].flags & PCIC_FLAG_SOCKETP) &&
    240   1.1.2.1     marc 	    (sc->handle[3].flags & PCIC_FLAG_SOCKETP))
    241   1.1.2.1     marc 	    printf("sockets A and B\n");
    242   1.1.2.1     marc 	else if (sc->handle[2].flags & PCIC_FLAG_SOCKETP)
    243   1.1.2.1     marc 	    printf("socket A only\n");
    244   1.1.2.1     marc 	else
    245   1.1.2.1     marc 	    printf("socket B only\n");
    246   1.1.2.1     marc 
    247   1.1.2.8     marc 	if (sc->handle[2].flags & PCIC_FLAG_SOCKETP)
    248   1.1.2.1     marc 	    sc->handle[2].vendor = vendor;
    249   1.1.2.8     marc 	if (sc->handle[3].flags & PCIC_FLAG_SOCKETP)
    250   1.1.2.1     marc 	    sc->handle[3].vendor = vendor;
    251   1.1.2.1     marc     }
    252   1.1.2.1     marc }
    253   1.1.2.1     marc 
    254   1.1.2.1     marc void
    255   1.1.2.8     marc pcic_attach_sockets(sc)
    256   1.1.2.8     marc      struct pcic_softc *sc;
    257   1.1.2.8     marc {
    258   1.1.2.8     marc     int i;
    259   1.1.2.8     marc 
    260   1.1.2.8     marc     for (i=0; i<PCIC_NSLOTS; i++)
    261   1.1.2.8     marc 	if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
    262   1.1.2.8     marc 	    pcic_attach_socket(&sc->handle[i]);
    263   1.1.2.8     marc }
    264   1.1.2.8     marc 
    265   1.1.2.8     marc void
    266   1.1.2.1     marc pcic_attach_socket(h)
    267   1.1.2.1     marc      struct pcic_handle *h;
    268   1.1.2.1     marc {
    269   1.1.2.1     marc    struct pcmciabus_attach_args paa;
    270   1.1.2.1     marc 
    271   1.1.2.1     marc    /* initialize the rest of the handle */
    272   1.1.2.1     marc 
    273   1.1.2.1     marc    h->memalloc = 0;
    274   1.1.2.1     marc    h->ioalloc = 0;
    275  1.1.2.10     marc    h->ih_irq = 0;
    276   1.1.2.1     marc 
    277   1.1.2.1     marc    /* now, config one pcmcia device per socket */
    278   1.1.2.1     marc 
    279   1.1.2.8     marc    paa.pct = (pcmcia_chipset_tag_t) h->sc->pct;
    280   1.1.2.1     marc    paa.pch = (pcmcia_chipset_handle_t) h;
    281   1.1.2.1     marc 
    282   1.1.2.1     marc    h->pcmcia = config_found_sm(&h->sc->dev, &paa, pcic_print, pcic_submatch);
    283   1.1.2.1     marc 
    284   1.1.2.1     marc    /* if there's actually a pcmcia device attached, initialize the slot */
    285   1.1.2.1     marc 
    286   1.1.2.1     marc    if (h->pcmcia)
    287   1.1.2.1     marc        pcic_init_socket(h);
    288   1.1.2.1     marc }
    289   1.1.2.1     marc 
    290   1.1.2.1     marc void
    291   1.1.2.1     marc pcic_init_socket(h)
    292   1.1.2.1     marc      struct pcic_handle *h;
    293   1.1.2.1     marc {
    294   1.1.2.1     marc     int reg;
    295   1.1.2.1     marc 
    296   1.1.2.1     marc     /* set up the card to interrupt on card detect */
    297   1.1.2.1     marc 
    298   1.1.2.1     marc     pcic_write(h, PCIC_CSC_INTR,
    299   1.1.2.1     marc 	       (h->sc->irq<<PCIC_CSC_INTR_IRQ_SHIFT)|
    300   1.1.2.1     marc 	       PCIC_CSC_INTR_CD_ENABLE);
    301   1.1.2.1     marc     pcic_write(h, PCIC_INTR, 0);
    302   1.1.2.1     marc     pcic_read(h, PCIC_CSC);
    303   1.1.2.1     marc 
    304   1.1.2.1     marc     /* unsleep the cirrus controller */
    305   1.1.2.1     marc 
    306   1.1.2.1     marc     if ((h->vendor == PCIC_VENDOR_CIRRUS_PD6710) ||
    307   1.1.2.1     marc 	(h->vendor == PCIC_VENDOR_CIRRUS_PD672X)) {
    308   1.1.2.1     marc 	reg = pcic_read(h, PCIC_CIRRUS_MISC_CTL_2);
    309   1.1.2.1     marc 	if (reg & PCIC_CIRRUS_MISC_CTL_2_SUSPEND) {
    310   1.1.2.1     marc 	    DPRINTF(("%s: socket %02x was suspended\n", h->sc->dev.dv_xname,
    311   1.1.2.1     marc 		     h->sock));
    312   1.1.2.1     marc 	    reg &= ~PCIC_CIRRUS_MISC_CTL_2_SUSPEND;
    313   1.1.2.1     marc 	    pcic_write(h, PCIC_CIRRUS_MISC_CTL_2, reg);
    314   1.1.2.1     marc 	}
    315   1.1.2.1     marc     }
    316   1.1.2.1     marc 
    317   1.1.2.1     marc     /* if there's a card there, then attach it. */
    318   1.1.2.1     marc 
    319   1.1.2.1     marc     reg = pcic_read(h, PCIC_IF_STATUS);
    320   1.1.2.1     marc 
    321   1.1.2.1     marc     if ((reg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
    322   1.1.2.1     marc 	PCIC_IF_STATUS_CARDDETECT_PRESENT)
    323   1.1.2.1     marc 	pcic_attach_card(h);
    324   1.1.2.1     marc }
    325   1.1.2.1     marc 
    326   1.1.2.1     marc int
    327   1.1.2.1     marc #ifdef __BROKEN_INDIRECT_CONFIG
    328   1.1.2.1     marc pcic_submatch(parent, match, aux)
    329   1.1.2.1     marc #else
    330   1.1.2.1     marc pcic_submatch(parent, cf, aux)
    331   1.1.2.1     marc #endif
    332   1.1.2.1     marc      struct device *parent;
    333   1.1.2.1     marc #ifdef __BROKEN_INDIRECT_CONFIG
    334   1.1.2.1     marc      void *match;
    335   1.1.2.1     marc #else
    336   1.1.2.1     marc      struct cfdata *cf;
    337   1.1.2.1     marc #endif
    338   1.1.2.1     marc      void *aux;
    339   1.1.2.1     marc {
    340   1.1.2.1     marc #ifdef __BROKEN_INDIRECT_CONFIG
    341   1.1.2.1     marc     struct cfdata *cf = match;
    342   1.1.2.1     marc #endif
    343   1.1.2.1     marc 
    344   1.1.2.1     marc     struct pcmciabus_attach_args *paa = (struct pcmciabus_attach_args *) aux;
    345   1.1.2.1     marc     struct pcic_handle *h = (struct pcic_handle *) paa->pch;
    346   1.1.2.1     marc 
    347   1.1.2.1     marc     switch (h->sock) {
    348   1.1.2.1     marc     case C0SA:
    349   1.1.2.1     marc 	if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 0)
    350   1.1.2.1     marc 	    return 0;
    351   1.1.2.1     marc 	if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != 0)
    352   1.1.2.1     marc 	    return 0;
    353   1.1.2.1     marc 
    354   1.1.2.1     marc 	break;
    355   1.1.2.1     marc     case C0SB:
    356   1.1.2.1     marc 	if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 0)
    357   1.1.2.1     marc 	    return 0;
    358   1.1.2.1     marc 	if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != 1)
    359   1.1.2.1     marc 	    return 0;
    360   1.1.2.1     marc 
    361   1.1.2.1     marc 	break;
    362   1.1.2.1     marc     case C1SA:
    363   1.1.2.1     marc 	if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 1)
    364   1.1.2.1     marc 	    return 0;
    365   1.1.2.1     marc 	if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != 0)
    366   1.1.2.1     marc 	    return 0;
    367   1.1.2.1     marc 
    368   1.1.2.1     marc 	break;
    369   1.1.2.1     marc     case C1SB:
    370   1.1.2.1     marc 	if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 1)
    371   1.1.2.1     marc 	    return 0;
    372   1.1.2.1     marc 	if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != 1)
    373   1.1.2.1     marc 	    return 0;
    374   1.1.2.1     marc 
    375   1.1.2.1     marc 	break;
    376   1.1.2.1     marc     default:
    377   1.1.2.1     marc 	panic("unknown pcic socket");
    378   1.1.2.1     marc     }
    379   1.1.2.1     marc 
    380   1.1.2.1     marc     return ((*cf->cf_attach->ca_match)(parent, cf, aux));
    381   1.1.2.1     marc }
    382   1.1.2.1     marc 
    383   1.1.2.1     marc int
    384   1.1.2.1     marc pcic_print(arg, pnp)
    385   1.1.2.1     marc      void *arg;
    386   1.1.2.1     marc      const char *pnp;
    387   1.1.2.1     marc {
    388   1.1.2.1     marc     struct pcmciabus_attach_args *paa = (struct pcmciabus_attach_args *) arg;
    389   1.1.2.1     marc     struct pcic_handle *h = (struct pcic_handle *) paa->pch;
    390   1.1.2.1     marc 
    391   1.1.2.1     marc     if (pnp)
    392   1.1.2.1     marc 	printf("pcmcia at %s", pnp);
    393   1.1.2.1     marc 
    394   1.1.2.1     marc     switch (h->sock) {
    395   1.1.2.1     marc     case C0SA:
    396   1.1.2.1     marc 	printf(" controller 0 socket 0");
    397   1.1.2.1     marc 	break;
    398   1.1.2.1     marc     case C0SB:
    399   1.1.2.1     marc 	printf(" controller 0 socket 1");
    400   1.1.2.1     marc 	break;
    401   1.1.2.1     marc     case C1SA:
    402   1.1.2.1     marc 	printf(" controller 1 socket 0");
    403   1.1.2.1     marc 	break;
    404   1.1.2.1     marc     case C1SB:
    405   1.1.2.1     marc 	printf(" controller 1 socket 1");
    406   1.1.2.1     marc 	break;
    407   1.1.2.1     marc     default:
    408   1.1.2.1     marc 	panic("unknown pcic socket");
    409   1.1.2.1     marc     }
    410   1.1.2.1     marc 
    411   1.1.2.1     marc     return(UNCONF);
    412   1.1.2.1     marc }
    413   1.1.2.1     marc 
    414   1.1.2.1     marc int
    415   1.1.2.1     marc pcic_intr(arg)
    416   1.1.2.1     marc      void *arg;
    417   1.1.2.1     marc {
    418   1.1.2.1     marc     struct pcic_softc *sc = (struct pcic_softc *) arg;
    419   1.1.2.1     marc     int i, ret = 0;
    420   1.1.2.1     marc 
    421   1.1.2.1     marc     DPRINTF(("%s: intr\n", sc->dev.dv_xname));
    422   1.1.2.1     marc 
    423   1.1.2.1     marc     for (i=0; i<PCIC_NSLOTS; i++)
    424   1.1.2.1     marc 	if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
    425   1.1.2.1     marc 	    ret += pcic_intr_socket(&sc->handle[i]);
    426   1.1.2.1     marc 
    427   1.1.2.1     marc     return(ret?1:0);
    428   1.1.2.1     marc }
    429   1.1.2.1     marc 
    430   1.1.2.1     marc int
    431   1.1.2.1     marc pcic_intr_socket(h)
    432   1.1.2.1     marc      struct pcic_handle *h;
    433   1.1.2.1     marc {
    434   1.1.2.1     marc     int cscreg;
    435   1.1.2.1     marc 
    436   1.1.2.1     marc     cscreg = pcic_read(h, PCIC_CSC);
    437   1.1.2.1     marc 
    438   1.1.2.1     marc     cscreg &= (PCIC_CSC_GPI |
    439   1.1.2.1     marc 	       PCIC_CSC_CD |
    440   1.1.2.1     marc 	       PCIC_CSC_READY |
    441   1.1.2.1     marc 	       PCIC_CSC_BATTWARN |
    442   1.1.2.1     marc 	       PCIC_CSC_BATTDEAD);
    443   1.1.2.1     marc 
    444   1.1.2.1     marc     if (cscreg & PCIC_CSC_GPI) {
    445   1.1.2.1     marc 	DPRINTF(("%s: %02x GPI\n", h->sc->dev.dv_xname, h->sock));
    446   1.1.2.1     marc     }
    447   1.1.2.1     marc     if (cscreg & PCIC_CSC_CD) {
    448   1.1.2.1     marc 	int statreg;
    449   1.1.2.1     marc 
    450   1.1.2.1     marc 	statreg = pcic_read(h, PCIC_IF_STATUS);
    451   1.1.2.1     marc 
    452   1.1.2.1     marc 	DPRINTF(("%s: %02x CD %x\n", h->sc->dev.dv_xname, h->sock,
    453   1.1.2.1     marc 		 statreg));
    454   1.1.2.1     marc 
    455   1.1.2.8     marc 	/* XXX This should probably schedule something to happen after
    456   1.1.2.8     marc 	   the interrupt handler completes */
    457   1.1.2.8     marc 
    458   1.1.2.1     marc 	if ((statreg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
    459   1.1.2.1     marc 	    PCIC_IF_STATUS_CARDDETECT_PRESENT) {
    460   1.1.2.1     marc 	    if (!(h->flags & PCIC_FLAG_CARDP))
    461   1.1.2.1     marc 		pcic_attach_card(h);
    462   1.1.2.1     marc 	} else {
    463   1.1.2.1     marc 	    if (h->flags & PCIC_FLAG_CARDP)
    464   1.1.2.1     marc 		pcic_detach_card(h);
    465   1.1.2.1     marc 	}
    466   1.1.2.1     marc     }
    467   1.1.2.1     marc     if (cscreg & PCIC_CSC_READY) {
    468   1.1.2.1     marc 	DPRINTF(("%s: %02x READY\n", h->sc->dev.dv_xname, h->sock));
    469   1.1.2.1     marc 	/* shouldn't happen */
    470   1.1.2.1     marc     }
    471   1.1.2.1     marc     if (cscreg & PCIC_CSC_BATTWARN) {
    472   1.1.2.1     marc 	DPRINTF(("%s: %02x BATTWARN\n", h->sc->dev.dv_xname, h->sock));
    473   1.1.2.1     marc     }
    474   1.1.2.1     marc     if (cscreg & PCIC_CSC_BATTDEAD) {
    475   1.1.2.1     marc 	DPRINTF(("%s: %02x BATTDEAD\n", h->sc->dev.dv_xname, h->sock));
    476   1.1.2.1     marc     }
    477   1.1.2.1     marc 
    478   1.1.2.1     marc     return(cscreg?1:0);
    479   1.1.2.1     marc }
    480   1.1.2.1     marc 
    481   1.1.2.1     marc void
    482   1.1.2.1     marc pcic_attach_card(h)
    483   1.1.2.1     marc      struct pcic_handle *h;
    484   1.1.2.1     marc {
    485   1.1.2.1     marc     if (h->flags & PCIC_FLAG_CARDP)
    486   1.1.2.1     marc 	panic("pcic_attach_card: already attached");
    487   1.1.2.1     marc 
    488   1.1.2.1     marc     /* call the MI attach function */
    489   1.1.2.1     marc 
    490  1.1.2.10     marc     pcmcia_card_attach(h->pcmcia);
    491   1.1.2.1     marc 
    492   1.1.2.1     marc     h->flags |= PCIC_FLAG_CARDP;
    493   1.1.2.1     marc }
    494   1.1.2.1     marc 
    495   1.1.2.1     marc void
    496   1.1.2.1     marc pcic_detach_card(h)
    497   1.1.2.1     marc      struct pcic_handle *h;
    498   1.1.2.1     marc {
    499   1.1.2.1     marc     if (!(h->flags & PCIC_FLAG_CARDP))
    500   1.1.2.9      jtk 	panic("pcic_attach_card: already detached");
    501   1.1.2.1     marc 
    502   1.1.2.1     marc     h->flags &= ~PCIC_FLAG_CARDP;
    503   1.1.2.1     marc 
    504   1.1.2.1     marc     /* call the MI attach function */
    505   1.1.2.1     marc 
    506  1.1.2.10     marc     pcmcia_card_detach(h->pcmcia);
    507   1.1.2.1     marc 
    508   1.1.2.1     marc     /* disable card detect resume and configuration reset */
    509   1.1.2.1     marc 
    510   1.1.2.1     marc     /* power down the socket */
    511   1.1.2.1     marc 
    512   1.1.2.1     marc     pcic_write(h, PCIC_PWRCTL, 0);
    513   1.1.2.1     marc 
    514   1.1.2.1     marc     /* reset the card */
    515   1.1.2.1     marc 
    516   1.1.2.1     marc     pcic_write(h, PCIC_INTR, 0);
    517   1.1.2.1     marc }
    518   1.1.2.1     marc 
    519   1.1.2.4  thorpej int pcic_chip_mem_alloc(pch, size, pcmhp)
    520   1.1.2.1     marc      pcmcia_chipset_handle_t pch;
    521   1.1.2.1     marc      bus_size_t size;
    522   1.1.2.4  thorpej      struct pcmcia_mem_handle *pcmhp;
    523   1.1.2.1     marc {
    524   1.1.2.1     marc     struct pcic_handle *h = (struct pcic_handle *) pch;
    525   1.1.2.4  thorpej     bus_space_handle_t memh;
    526   1.1.2.4  thorpej     bus_addr_t addr;
    527   1.1.2.4  thorpej     bus_size_t sizepg;
    528   1.1.2.4  thorpej     int i, mask, mhandle;
    529   1.1.2.1     marc 
    530   1.1.2.1     marc     /* out of sc->memh, allocate as many pages as necessary */
    531   1.1.2.1     marc 
    532   1.1.2.4  thorpej     /* convert size to PCIC pages */
    533   1.1.2.4  thorpej     sizepg = (size + (PCIC_MEM_ALIGN - 1)) / PCIC_MEM_ALIGN;
    534   1.1.2.1     marc 
    535   1.1.2.4  thorpej     mask = (1 << sizepg) - 1;
    536   1.1.2.1     marc 
    537   1.1.2.4  thorpej     addr = 0;		/* XXX gcc -Wuninitialized */
    538   1.1.2.4  thorpej     mhandle = 0;	/* XXX gcc -Wuninitialized */
    539   1.1.2.8     marc 
    540   1.1.2.4  thorpej     for (i=0; i<(PCIC_MEM_PAGES+1-sizepg); i++) {
    541   1.1.2.1     marc 	if ((h->sc->subregionmask & (mask<<i)) == (mask<<i)) {
    542   1.1.2.1     marc 	    if (bus_space_subregion(h->sc->memt, h->sc->memh,
    543   1.1.2.1     marc 				    i*PCIC_MEM_PAGESIZE,
    544   1.1.2.4  thorpej 				    sizepg*PCIC_MEM_PAGESIZE, &memh))
    545   1.1.2.1     marc 		return(1);
    546   1.1.2.4  thorpej 	    mhandle = mask << i;
    547   1.1.2.4  thorpej 	    addr = h->sc->membase + (i * PCIC_MEM_PAGESIZE);
    548   1.1.2.4  thorpej 	    h->sc->subregionmask &= ~(mhandle);
    549   1.1.2.1     marc 	    break;
    550   1.1.2.1     marc 	}
    551   1.1.2.1     marc     }
    552   1.1.2.1     marc 
    553   1.1.2.1     marc     if (i == (PCIC_MEM_PAGES+1-size))
    554   1.1.2.1     marc 	return(1);
    555   1.1.2.1     marc 
    556   1.1.2.4  thorpej     DPRINTF(("pcic_chip_mem_alloc bus addr 0x%lx+0x%lx\n", (u_long)addr,
    557   1.1.2.4  thorpej              (u_long)size));
    558   1.1.2.4  thorpej 
    559   1.1.2.4  thorpej     pcmhp->memt = h->sc->memt;
    560   1.1.2.4  thorpej     pcmhp->memh = memh;
    561   1.1.2.4  thorpej     pcmhp->addr = addr;
    562   1.1.2.4  thorpej     pcmhp->size = size;
    563   1.1.2.4  thorpej     pcmhp->mhandle = mhandle;
    564   1.1.2.4  thorpej     pcmhp->realsize = sizepg * PCIC_MEM_PAGESIZE;
    565   1.1.2.1     marc 
    566   1.1.2.1     marc     return(0);
    567   1.1.2.1     marc }
    568   1.1.2.1     marc 
    569   1.1.2.4  thorpej void pcic_chip_mem_free(pch, pcmhp)
    570   1.1.2.1     marc      pcmcia_chipset_handle_t pch;
    571   1.1.2.4  thorpej      struct pcmcia_mem_handle *pcmhp;
    572   1.1.2.1     marc {
    573   1.1.2.1     marc     struct pcic_handle *h = (struct pcic_handle *) pch;
    574   1.1.2.1     marc 
    575   1.1.2.4  thorpej     h->sc->subregionmask |= pcmhp->mhandle;
    576   1.1.2.1     marc }
    577   1.1.2.1     marc 
    578   1.1.2.1     marc static struct mem_map_index_st {
    579   1.1.2.1     marc     int sysmem_start_lsb;
    580   1.1.2.1     marc     int sysmem_start_msb;
    581   1.1.2.1     marc     int sysmem_stop_lsb;
    582   1.1.2.1     marc     int sysmem_stop_msb;
    583   1.1.2.1     marc     int cardmem_lsb;
    584   1.1.2.1     marc     int cardmem_msb;
    585   1.1.2.1     marc     int memenable;
    586   1.1.2.1     marc } mem_map_index[] = {
    587   1.1.2.1     marc     {
    588   1.1.2.1     marc 	PCIC_SYSMEM_ADDR0_START_LSB,
    589   1.1.2.1     marc 	PCIC_SYSMEM_ADDR0_START_MSB,
    590   1.1.2.1     marc 	PCIC_SYSMEM_ADDR0_STOP_LSB,
    591   1.1.2.1     marc 	PCIC_SYSMEM_ADDR0_STOP_MSB,
    592   1.1.2.1     marc 	PCIC_CARDMEM_ADDR0_LSB,
    593   1.1.2.1     marc 	PCIC_CARDMEM_ADDR0_MSB,
    594   1.1.2.1     marc 	PCIC_ADDRWIN_ENABLE_MEM0,
    595   1.1.2.1     marc     },
    596   1.1.2.1     marc     {
    597   1.1.2.1     marc 	PCIC_SYSMEM_ADDR1_START_LSB,
    598   1.1.2.1     marc 	PCIC_SYSMEM_ADDR1_START_MSB,
    599   1.1.2.1     marc 	PCIC_SYSMEM_ADDR1_STOP_LSB,
    600   1.1.2.1     marc 	PCIC_SYSMEM_ADDR1_STOP_MSB,
    601   1.1.2.1     marc 	PCIC_CARDMEM_ADDR1_LSB,
    602   1.1.2.1     marc 	PCIC_CARDMEM_ADDR1_MSB,
    603   1.1.2.1     marc 	PCIC_ADDRWIN_ENABLE_MEM1,
    604   1.1.2.1     marc     },
    605   1.1.2.1     marc     {
    606   1.1.2.1     marc 	PCIC_SYSMEM_ADDR2_START_LSB,
    607   1.1.2.1     marc 	PCIC_SYSMEM_ADDR2_START_MSB,
    608   1.1.2.1     marc 	PCIC_SYSMEM_ADDR2_STOP_LSB,
    609   1.1.2.1     marc 	PCIC_SYSMEM_ADDR2_STOP_MSB,
    610   1.1.2.1     marc 	PCIC_CARDMEM_ADDR2_LSB,
    611   1.1.2.1     marc 	PCIC_CARDMEM_ADDR2_MSB,
    612   1.1.2.1     marc 	PCIC_ADDRWIN_ENABLE_MEM2,
    613   1.1.2.1     marc     },
    614   1.1.2.1     marc     {
    615   1.1.2.1     marc 	PCIC_SYSMEM_ADDR3_START_LSB,
    616   1.1.2.1     marc 	PCIC_SYSMEM_ADDR3_START_MSB,
    617   1.1.2.1     marc 	PCIC_SYSMEM_ADDR3_STOP_LSB,
    618   1.1.2.1     marc 	PCIC_SYSMEM_ADDR3_STOP_MSB,
    619   1.1.2.1     marc 	PCIC_CARDMEM_ADDR3_LSB,
    620   1.1.2.1     marc 	PCIC_CARDMEM_ADDR3_MSB,
    621   1.1.2.1     marc 	PCIC_ADDRWIN_ENABLE_MEM3,
    622   1.1.2.1     marc     },
    623   1.1.2.1     marc     {
    624   1.1.2.1     marc 	PCIC_SYSMEM_ADDR4_START_LSB,
    625   1.1.2.1     marc 	PCIC_SYSMEM_ADDR4_START_MSB,
    626   1.1.2.1     marc 	PCIC_SYSMEM_ADDR4_STOP_LSB,
    627   1.1.2.1     marc 	PCIC_SYSMEM_ADDR4_STOP_MSB,
    628   1.1.2.1     marc 	PCIC_CARDMEM_ADDR4_LSB,
    629   1.1.2.1     marc 	PCIC_CARDMEM_ADDR4_MSB,
    630   1.1.2.1     marc 	PCIC_ADDRWIN_ENABLE_MEM4,
    631   1.1.2.1     marc     },
    632   1.1.2.1     marc };
    633   1.1.2.1     marc 
    634  1.1.2.10     marc void pcic_chip_do_mem_map(h, win)
    635  1.1.2.10     marc      struct pcic_handle *h;
    636  1.1.2.10     marc      int win;
    637  1.1.2.10     marc {
    638  1.1.2.10     marc     int reg;
    639  1.1.2.10     marc 
    640  1.1.2.10     marc     pcic_write(h, mem_map_index[win].sysmem_start_lsb,
    641  1.1.2.10     marc 	       (h->mem[win].addr >> PCIC_SYSMEM_ADDRX_SHIFT) & 0xff);
    642  1.1.2.10     marc     pcic_write(h, mem_map_index[win].sysmem_start_msb,
    643  1.1.2.10     marc 	       ((h->mem[win].addr >> (PCIC_SYSMEM_ADDRX_SHIFT + 8)) &
    644  1.1.2.10     marc 		PCIC_SYSMEM_ADDRX_START_MSB_ADDR_MASK));
    645  1.1.2.10     marc 
    646  1.1.2.10     marc #if 0
    647  1.1.2.10     marc     /* XXX do I want 16 bit all the time? */
    648  1.1.2.10     marc     PCIC_SYSMEM_ADDRX_START_MSB_DATASIZE_16BIT;
    649  1.1.2.10     marc #endif
    650  1.1.2.10     marc 
    651  1.1.2.10     marc     pcic_write(h, mem_map_index[win].sysmem_stop_lsb,
    652  1.1.2.10     marc 	       ((h->mem[win].addr + h->mem[win].size) >>
    653  1.1.2.10     marc 		PCIC_SYSMEM_ADDRX_SHIFT) & 0xff);
    654  1.1.2.10     marc     pcic_write(h, mem_map_index[win].sysmem_stop_msb,
    655  1.1.2.10     marc 	       (((h->mem[win].addr + h->mem[win].size) >>
    656  1.1.2.10     marc 		 (PCIC_SYSMEM_ADDRX_SHIFT + 8)) &
    657  1.1.2.10     marc 		PCIC_SYSMEM_ADDRX_STOP_MSB_ADDR_MASK) |
    658  1.1.2.10     marc 	       PCIC_SYSMEM_ADDRX_STOP_MSB_WAIT2);
    659  1.1.2.10     marc 
    660  1.1.2.10     marc     pcic_write(h, mem_map_index[win].cardmem_lsb,
    661  1.1.2.10     marc 	       (h->mem[win].offset >> PCIC_CARDMEM_ADDRX_SHIFT) & 0xff);
    662  1.1.2.10     marc     pcic_write(h, mem_map_index[win].cardmem_msb,
    663  1.1.2.10     marc 	       ((h->mem[win].offset >> (PCIC_CARDMEM_ADDRX_SHIFT + 8)) &
    664  1.1.2.10     marc 		PCIC_CARDMEM_ADDRX_MSB_ADDR_MASK) |
    665  1.1.2.10     marc 	       ((h->mem[win].kind == PCMCIA_MEM_ATTR)?
    666  1.1.2.10     marc 		PCIC_CARDMEM_ADDRX_MSB_REGACTIVE_ATTR:0));
    667  1.1.2.10     marc 
    668  1.1.2.10     marc     reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
    669  1.1.2.10     marc     reg |= (mem_map_index[win].memenable | PCIC_ADDRWIN_ENABLE_MEMCS16 );
    670  1.1.2.10     marc     pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
    671  1.1.2.10     marc 
    672  1.1.2.10     marc #ifdef PCICDEBUG
    673  1.1.2.10     marc     {
    674  1.1.2.10     marc 	int r1,r2,r3,r4,r5,r6;
    675  1.1.2.10     marc 
    676  1.1.2.10     marc 	r1 = pcic_read(h, mem_map_index[win].sysmem_start_msb);
    677  1.1.2.10     marc 	r2 = pcic_read(h, mem_map_index[win].sysmem_start_lsb);
    678  1.1.2.10     marc 	r3 = pcic_read(h, mem_map_index[win].sysmem_stop_msb);
    679  1.1.2.10     marc 	r4 = pcic_read(h, mem_map_index[win].sysmem_stop_lsb);
    680  1.1.2.10     marc 	r5 = pcic_read(h, mem_map_index[win].cardmem_msb);
    681  1.1.2.10     marc 	r6 = pcic_read(h, mem_map_index[win].cardmem_lsb);
    682  1.1.2.10     marc 
    683  1.1.2.10     marc 	DPRINTF(("pcic_chip_do_mem_map window %d: %02x%02x %02x%02x %02x%02x\n",
    684  1.1.2.10     marc 		 win, r1, r2, r3, r4, r5, r6));
    685  1.1.2.10     marc     }
    686  1.1.2.10     marc #endif
    687  1.1.2.10     marc }
    688  1.1.2.10     marc 
    689   1.1.2.4  thorpej int pcic_chip_mem_map(pch, kind, card_addr, size, pcmhp, offsetp, windowp)
    690   1.1.2.1     marc      pcmcia_chipset_handle_t pch;
    691   1.1.2.1     marc      int kind;
    692   1.1.2.4  thorpej      bus_addr_t card_addr;
    693   1.1.2.1     marc      bus_size_t size;
    694   1.1.2.4  thorpej      struct pcmcia_mem_handle *pcmhp;
    695   1.1.2.4  thorpej      bus_addr_t *offsetp;
    696   1.1.2.4  thorpej      int *windowp;
    697   1.1.2.1     marc {
    698   1.1.2.1     marc     struct pcic_handle *h = (struct pcic_handle *) pch;
    699   1.1.2.4  thorpej     bus_addr_t busaddr;
    700   1.1.2.1     marc     long card_offset;
    701   1.1.2.1     marc     int i, win;
    702   1.1.2.1     marc 
    703   1.1.2.1     marc     win = -1;
    704   1.1.2.1     marc     for (i=0; i<(sizeof(mem_map_index)/sizeof(mem_map_index[0])); i++) {
    705   1.1.2.1     marc 	if ((h->memalloc & (1<<i)) == 0) {
    706   1.1.2.1     marc 	    win = i;
    707   1.1.2.1     marc 	    h->memalloc |= (1<<i);
    708   1.1.2.1     marc 	    break;
    709   1.1.2.1     marc 	}
    710   1.1.2.1     marc     }
    711   1.1.2.1     marc 
    712   1.1.2.1     marc     if (win == -1)
    713   1.1.2.1     marc 	return(1);
    714   1.1.2.1     marc 
    715   1.1.2.4  thorpej     *windowp = win;
    716   1.1.2.1     marc 
    717   1.1.2.1     marc     /* XXX this is pretty gross */
    718   1.1.2.1     marc 
    719   1.1.2.4  thorpej     if (h->sc->memt != pcmhp->memt)
    720   1.1.2.1     marc 	panic("pcic_chip_mem_map memt is bogus");
    721   1.1.2.1     marc 
    722   1.1.2.4  thorpej     busaddr = pcmhp->addr;
    723   1.1.2.1     marc 
    724   1.1.2.1     marc     /* compute the address offset to the pcmcia address space for the
    725   1.1.2.1     marc        pcic.  this is intentionally signed.  The masks and shifts
    726   1.1.2.1     marc        below will cause TRT to happen in the pcic registers.  Deal with
    727   1.1.2.1     marc        making sure the address is aligned, and return the alignment
    728   1.1.2.1     marc        offset.  */
    729   1.1.2.1     marc 
    730   1.1.2.4  thorpej     *offsetp = card_addr % PCIC_MEM_ALIGN;
    731   1.1.2.4  thorpej     card_addr -= *offsetp;
    732   1.1.2.1     marc 
    733   1.1.2.4  thorpej     DPRINTF(("pcic_chip_mem_map window %d bus %lx+%lx+%lx at card addr %lx\n",
    734   1.1.2.4  thorpej 	     win, (u_long)busaddr, (u_long)*offsetp, (u_long)size,
    735   1.1.2.4  thorpej 	     (u_long)card_addr));
    736   1.1.2.1     marc 
    737   1.1.2.1     marc     /* include the offset in the size, and decrement size by one,
    738   1.1.2.1     marc        since the hw wants start/stop */
    739   1.1.2.4  thorpej     size += *offsetp - 1;
    740   1.1.2.1     marc 
    741   1.1.2.4  thorpej     card_offset = (((long) card_addr) - ((long) busaddr));
    742   1.1.2.1     marc 
    743  1.1.2.10     marc     h->mem[win].addr = busaddr;
    744  1.1.2.10     marc     h->mem[win].size = size;
    745  1.1.2.10     marc     h->mem[win].offset = card_offset;
    746  1.1.2.10     marc     h->mem[win].kind = kind;
    747   1.1.2.1     marc 
    748  1.1.2.10     marc     pcic_chip_do_mem_map(h, win);
    749   1.1.2.1     marc 
    750   1.1.2.1     marc     return(0);
    751   1.1.2.1     marc }
    752   1.1.2.1     marc 
    753   1.1.2.1     marc void pcic_chip_mem_unmap(pch, window)
    754   1.1.2.1     marc      pcmcia_chipset_handle_t pch;
    755   1.1.2.1     marc      int window;
    756   1.1.2.1     marc {
    757   1.1.2.1     marc     struct pcic_handle *h = (struct pcic_handle *) pch;
    758   1.1.2.1     marc     int reg;
    759   1.1.2.1     marc 
    760   1.1.2.1     marc     if (window >= (sizeof(mem_map_index)/sizeof(mem_map_index[0])))
    761   1.1.2.1     marc 	panic("pcic_chip_mem_unmap: window out of range");
    762   1.1.2.1     marc 
    763   1.1.2.1     marc     reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
    764   1.1.2.1     marc     reg &= ~mem_map_index[window].memenable;
    765   1.1.2.1     marc     pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
    766   1.1.2.1     marc 
    767   1.1.2.4  thorpej     h->memalloc &= ~(1 << window);
    768   1.1.2.1     marc }
    769   1.1.2.1     marc 
    770   1.1.2.4  thorpej int pcic_chip_io_alloc(pch, start, size, pcihp)
    771   1.1.2.1     marc      pcmcia_chipset_handle_t pch;
    772   1.1.2.1     marc      bus_addr_t start;
    773   1.1.2.1     marc      bus_size_t size;
    774   1.1.2.4  thorpej      struct pcmcia_io_handle *pcihp;
    775   1.1.2.1     marc {
    776   1.1.2.1     marc     struct pcic_handle *h = (struct pcic_handle *) pch;
    777   1.1.2.4  thorpej     bus_space_tag_t iot;
    778   1.1.2.4  thorpej     bus_space_handle_t ioh;
    779   1.1.2.1     marc     bus_addr_t ioaddr;
    780   1.1.2.4  thorpej     int flags = 0;
    781   1.1.2.1     marc 
    782   1.1.2.1     marc     /*
    783   1.1.2.8     marc      * Allocate some arbitrary I/O space.
    784   1.1.2.1     marc      */
    785   1.1.2.1     marc 
    786   1.1.2.4  thorpej     iot = h->sc->iot;
    787   1.1.2.1     marc 
    788   1.1.2.1     marc     if (start) {
    789   1.1.2.4  thorpej 	ioaddr = start;
    790   1.1.2.4  thorpej 	if (bus_space_map(iot, start, size, 0, &ioh))
    791   1.1.2.1     marc 	    return(1);
    792   1.1.2.1     marc 	DPRINTF(("pcic_chip_io_alloc map port %lx+%lx\n",
    793   1.1.2.4  thorpej 		 (u_long) ioaddr, (u_long) size));
    794   1.1.2.1     marc     } else {
    795   1.1.2.4  thorpej 	flags |= PCMCIA_IO_ALLOCATED;
    796  1.1.2.10     marc 	if (bus_space_alloc(iot, h->sc->iobase, h->sc->iobase+h->sc->iosize,
    797  1.1.2.10     marc 			    size, size, 0, 0, &ioaddr, &ioh))
    798   1.1.2.1     marc 	    return(1);
    799   1.1.2.1     marc 	DPRINTF(("pcic_chip_io_alloc alloc port %lx+%lx\n",
    800   1.1.2.1     marc 		 (u_long) ioaddr, (u_long) size));
    801   1.1.2.1     marc     }
    802   1.1.2.1     marc 
    803   1.1.2.4  thorpej     pcihp->iot = iot;
    804   1.1.2.4  thorpej     pcihp->ioh = ioh;
    805   1.1.2.4  thorpej     pcihp->addr = ioaddr;
    806   1.1.2.4  thorpej     pcihp->size = size;
    807   1.1.2.4  thorpej     pcihp->flags = flags;
    808   1.1.2.4  thorpej 
    809   1.1.2.1     marc     return(0);
    810   1.1.2.1     marc }
    811   1.1.2.1     marc 
    812   1.1.2.4  thorpej void pcic_chip_io_free(pch, pcihp)
    813   1.1.2.1     marc      pcmcia_chipset_handle_t pch;
    814   1.1.2.4  thorpej      struct pcmcia_io_handle *pcihp;
    815   1.1.2.1     marc {
    816   1.1.2.4  thorpej     bus_space_tag_t iot = pcihp->iot;
    817   1.1.2.4  thorpej     bus_space_handle_t ioh = pcihp->ioh;
    818   1.1.2.4  thorpej     bus_size_t size = pcihp->size;
    819   1.1.2.4  thorpej 
    820   1.1.2.4  thorpej     if (pcihp->flags & PCMCIA_IO_ALLOCATED)
    821   1.1.2.4  thorpej 	bus_space_free(iot, ioh, size);
    822   1.1.2.4  thorpej     else
    823   1.1.2.4  thorpej 	bus_space_unmap(iot, ioh, size);
    824   1.1.2.1     marc }
    825   1.1.2.1     marc 
    826   1.1.2.1     marc 
    827   1.1.2.1     marc static struct io_map_index_st {
    828   1.1.2.1     marc     int start_lsb;
    829   1.1.2.1     marc     int start_msb;
    830   1.1.2.1     marc     int stop_lsb;
    831   1.1.2.1     marc     int stop_msb;
    832   1.1.2.1     marc     int ioenable;
    833   1.1.2.1     marc     int ioctlmask;
    834   1.1.2.1     marc     int ioctl8;
    835   1.1.2.1     marc     int ioctl16;
    836   1.1.2.1     marc } io_map_index[] = {
    837   1.1.2.1     marc     {
    838   1.1.2.1     marc 	PCIC_IOADDR0_START_LSB,
    839   1.1.2.1     marc 	PCIC_IOADDR0_START_MSB,
    840   1.1.2.1     marc 	PCIC_IOADDR0_STOP_LSB,
    841   1.1.2.1     marc 	PCIC_IOADDR0_STOP_MSB,
    842   1.1.2.1     marc 	PCIC_ADDRWIN_ENABLE_IO0,
    843   1.1.2.1     marc 	PCIC_IOCTL_IO0_WAITSTATE | PCIC_IOCTL_IO0_ZEROWAIT |
    844   1.1.2.1     marc 	PCIC_IOCTL_IO0_IOCS16SRC_MASK | PCIC_IOCTL_IO0_DATASIZE_MASK,
    845   1.1.2.1     marc 	PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE | PCIC_IOCTL_IO0_DATASIZE_8BIT,
    846   1.1.2.1     marc 	PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE | PCIC_IOCTL_IO0_DATASIZE_16BIT,
    847   1.1.2.1     marc     },
    848   1.1.2.1     marc     {
    849   1.1.2.1     marc 	PCIC_IOADDR1_START_LSB,
    850   1.1.2.1     marc 	PCIC_IOADDR1_START_MSB,
    851   1.1.2.1     marc 	PCIC_IOADDR1_STOP_LSB,
    852   1.1.2.1     marc 	PCIC_IOADDR1_STOP_MSB,
    853   1.1.2.1     marc 	PCIC_ADDRWIN_ENABLE_IO1,
    854   1.1.2.1     marc 	PCIC_IOCTL_IO1_WAITSTATE | PCIC_IOCTL_IO1_ZEROWAIT |
    855   1.1.2.1     marc 	PCIC_IOCTL_IO1_IOCS16SRC_MASK | PCIC_IOCTL_IO1_DATASIZE_MASK,
    856   1.1.2.1     marc 	PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE | PCIC_IOCTL_IO1_DATASIZE_8BIT,
    857   1.1.2.1     marc 	PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE | PCIC_IOCTL_IO1_DATASIZE_16BIT,
    858   1.1.2.1     marc     },
    859   1.1.2.1     marc };
    860   1.1.2.1     marc 
    861  1.1.2.10     marc void pcic_chip_do_io_map(h, win)
    862  1.1.2.10     marc      struct pcic_handle *h;
    863  1.1.2.10     marc      int win;
    864  1.1.2.10     marc {
    865  1.1.2.10     marc     int reg;
    866  1.1.2.10     marc 
    867  1.1.2.10     marc     DPRINTF(("pcic_chip_do_io_map win %d addr %lx size %lx width %d\n",
    868  1.1.2.10     marc 	     win, (long) h->io[win].addr, (long) h->io[win].size,
    869  1.1.2.10     marc 	     h->io[win].width*8));
    870  1.1.2.10     marc 
    871  1.1.2.10     marc     pcic_write(h, io_map_index[win].start_lsb, h->io[win].addr & 0xff);
    872  1.1.2.10     marc     pcic_write(h, io_map_index[win].start_msb, (h->io[win].addr >> 8) & 0xff);
    873  1.1.2.10     marc 
    874  1.1.2.10     marc     pcic_write(h, io_map_index[win].stop_lsb,
    875  1.1.2.10     marc 	       (h->io[win].addr + h->io[win].size - 1) & 0xff);
    876  1.1.2.10     marc     pcic_write(h, io_map_index[win].stop_msb,
    877  1.1.2.10     marc     	       ((h->io[win].addr + h->io[win].size - 1) >> 8) & 0xff);
    878  1.1.2.10     marc 
    879  1.1.2.10     marc     reg = pcic_read(h, PCIC_IOCTL);
    880  1.1.2.10     marc     reg &= ~io_map_index[win].ioctlmask;
    881  1.1.2.10     marc     if (h->io[win].width == PCMCIA_WIDTH_IO8)
    882  1.1.2.10     marc 	reg |= io_map_index[win].ioctl8;
    883  1.1.2.10     marc     else
    884  1.1.2.10     marc 	reg |= io_map_index[win].ioctl16;
    885  1.1.2.10     marc     pcic_write(h, PCIC_IOCTL, reg);
    886  1.1.2.10     marc 
    887  1.1.2.10     marc     reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
    888  1.1.2.10     marc     reg |= io_map_index[win].ioenable;
    889  1.1.2.10     marc     pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
    890  1.1.2.10     marc }
    891  1.1.2.10     marc 
    892   1.1.2.4  thorpej int pcic_chip_io_map(pch, width, offset, size, pcihp, windowp)
    893   1.1.2.1     marc      pcmcia_chipset_handle_t pch;
    894   1.1.2.1     marc      int width;
    895   1.1.2.4  thorpej      bus_addr_t offset;
    896   1.1.2.1     marc      bus_size_t size;
    897   1.1.2.4  thorpej      struct pcmcia_io_handle *pcihp;
    898   1.1.2.4  thorpej      int *windowp;
    899   1.1.2.1     marc {
    900   1.1.2.1     marc     struct pcic_handle *h = (struct pcic_handle *) pch;
    901   1.1.2.4  thorpej     bus_addr_t ioaddr = pcihp->addr + offset;
    902   1.1.2.1     marc     int i, win;
    903   1.1.2.1     marc 
    904   1.1.2.4  thorpej     /* XXX Sanity check offset/size. */
    905   1.1.2.4  thorpej 
    906   1.1.2.1     marc     win = -1;
    907   1.1.2.1     marc     for (i=0; i<(sizeof(io_map_index)/sizeof(io_map_index[0])); i++) {
    908   1.1.2.1     marc 	if ((h->ioalloc & (1<<i)) == 0) {
    909   1.1.2.1     marc 	    win = i;
    910   1.1.2.1     marc 	    h->ioalloc |= (1<<i);
    911   1.1.2.1     marc 	    break;
    912   1.1.2.1     marc 	}
    913   1.1.2.1     marc     }
    914   1.1.2.1     marc 
    915   1.1.2.1     marc     if (win == -1)
    916   1.1.2.1     marc 	return(1);
    917   1.1.2.1     marc 
    918   1.1.2.4  thorpej     *windowp = win;
    919   1.1.2.1     marc 
    920   1.1.2.1     marc     /* XXX this is pretty gross */
    921   1.1.2.1     marc 
    922   1.1.2.4  thorpej     if (h->sc->iot != pcihp->iot)
    923   1.1.2.1     marc 	panic("pcic_chip_io_map iot is bogus");
    924   1.1.2.1     marc 
    925   1.1.2.1     marc     DPRINTF(("pcic_chip_io_map window %d %s port %lx+%lx\n",
    926   1.1.2.1     marc 	     win, (width == PCMCIA_WIDTH_IO8)?"io8":"io16",
    927   1.1.2.4  thorpej 	     (u_long) ioaddr, (u_long) size));
    928   1.1.2.1     marc 
    929  1.1.2.10     marc     /* XXX wtf is this doing here? */
    930  1.1.2.10     marc 
    931   1.1.2.6      jtk     printf(" port 0x%lx", (u_long)ioaddr);
    932   1.1.2.6      jtk     if (size > 1)
    933   1.1.2.6      jtk 	printf("-0x%lx", (u_long)ioaddr + (u_long)size - 1);
    934   1.1.2.6      jtk 
    935  1.1.2.10     marc     h->io[win].addr = ioaddr;
    936  1.1.2.10     marc     h->io[win].size = size;
    937  1.1.2.10     marc     h->io[win].width = width;
    938   1.1.2.1     marc 
    939  1.1.2.10     marc     pcic_chip_do_io_map(h, win);
    940   1.1.2.1     marc 
    941   1.1.2.1     marc     return(0);
    942   1.1.2.1     marc }
    943   1.1.2.1     marc 
    944   1.1.2.1     marc void pcic_chip_io_unmap(pch, window)
    945   1.1.2.1     marc      pcmcia_chipset_handle_t pch;
    946   1.1.2.1     marc      int window;
    947   1.1.2.1     marc {
    948   1.1.2.1     marc     struct pcic_handle *h = (struct pcic_handle *) pch;
    949   1.1.2.1     marc     int reg;
    950   1.1.2.1     marc 
    951   1.1.2.1     marc     if (window >= (sizeof(io_map_index)/sizeof(io_map_index[0])))
    952   1.1.2.1     marc 	panic("pcic_chip_io_unmap: window out of range");
    953   1.1.2.1     marc 
    954   1.1.2.1     marc     reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
    955   1.1.2.1     marc     reg &= ~io_map_index[window].ioenable;
    956   1.1.2.1     marc     pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
    957   1.1.2.1     marc 
    958   1.1.2.8     marc     h->ioalloc &= ~(1<<window);
    959   1.1.2.7  thorpej }
    960   1.1.2.7  thorpej 
    961   1.1.2.7  thorpej void
    962   1.1.2.7  thorpej pcic_chip_socket_enable(pch)
    963   1.1.2.7  thorpej      pcmcia_chipset_handle_t pch;
    964   1.1.2.7  thorpej {
    965  1.1.2.10     marc     struct pcic_handle *h = (struct pcic_handle *) pch;
    966  1.1.2.10     marc     int cardtype, reg, win;
    967  1.1.2.10     marc 
    968  1.1.2.10     marc     /* this bit is mostly stolen from pcic_attach_card */
    969  1.1.2.10     marc 
    970  1.1.2.10     marc     /* power down the socket to reset it, clear the card reset pin */
    971  1.1.2.10     marc 
    972  1.1.2.10     marc     pcic_write(h, PCIC_PWRCTL, 0);
    973  1.1.2.10     marc 
    974  1.1.2.10     marc     /* power up the socket */
    975  1.1.2.10     marc 
    976  1.1.2.10     marc     pcic_write(h, PCIC_PWRCTL, PCIC_PWRCTL_PWR_ENABLE);
    977  1.1.2.10     marc     delay(10000);
    978  1.1.2.10     marc     pcic_write(h, PCIC_PWRCTL, PCIC_PWRCTL_PWR_ENABLE | PCIC_PWRCTL_OE);
    979  1.1.2.10     marc 
    980  1.1.2.10     marc     /* clear the reset flag */
    981  1.1.2.10     marc 
    982  1.1.2.10     marc     pcic_write(h, PCIC_INTR, PCIC_INTR_RESET);
    983  1.1.2.10     marc 
    984  1.1.2.10     marc     /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */
    985  1.1.2.10     marc 
    986  1.1.2.10     marc     delay(20000);
    987  1.1.2.10     marc 
    988  1.1.2.10     marc     /* wait for the chip to finish initializing */
    989  1.1.2.10     marc 
    990  1.1.2.10     marc     pcic_wait_ready(h);
    991  1.1.2.10     marc 
    992  1.1.2.10     marc     /* zero out the address windows */
    993  1.1.2.10     marc 
    994  1.1.2.10     marc     pcic_write(h, PCIC_ADDRWIN_ENABLE, 0);
    995  1.1.2.10     marc 
    996  1.1.2.10     marc     /* set the card type */
    997  1.1.2.10     marc 
    998  1.1.2.10     marc     cardtype = pcmcia_card_gettype(h->pcmcia);
    999  1.1.2.10     marc 
   1000  1.1.2.10     marc     reg = pcic_read(h, PCIC_INTR);
   1001  1.1.2.10     marc     reg &= ~PCIC_INTR_CARDTYPE_MASK;
   1002  1.1.2.10     marc     reg |= ((cardtype == PCMCIA_IFTYPE_IO)?
   1003  1.1.2.10     marc 	    PCIC_INTR_CARDTYPE_IO:
   1004  1.1.2.10     marc 	    PCIC_INTR_CARDTYPE_MEM);
   1005  1.1.2.10     marc     reg |= h->ih_irq;
   1006  1.1.2.10     marc     pcic_write(h, PCIC_INTR, reg);
   1007  1.1.2.10     marc 
   1008  1.1.2.10     marc     DPRINTF(("%s: pcic_chip_socket_enable %02x cardtype %s %02x\n",
   1009  1.1.2.10     marc 	     h->sc->dev.dv_xname, h->sock,
   1010  1.1.2.10     marc 	     ((cardtype == PCMCIA_IFTYPE_IO)?"io":"mem"), reg));
   1011  1.1.2.10     marc 
   1012  1.1.2.10     marc     /* reinstall all the memory and io mappings */
   1013  1.1.2.10     marc 
   1014  1.1.2.10     marc     for (win=0; win<PCIC_MEM_WINS; win++)
   1015  1.1.2.10     marc 	if (h->memalloc & (1<<win))
   1016  1.1.2.10     marc 	    pcic_chip_do_mem_map(h, win);
   1017  1.1.2.10     marc 
   1018  1.1.2.10     marc     for (win=0; win<PCIC_IO_WINS; win++)
   1019  1.1.2.10     marc 	if (h->ioalloc & (1<<win))
   1020  1.1.2.10     marc 	    pcic_chip_do_io_map(h, win);
   1021   1.1.2.7  thorpej }
   1022   1.1.2.7  thorpej 
   1023   1.1.2.7  thorpej void
   1024   1.1.2.7  thorpej pcic_chip_socket_disable(pch)
   1025   1.1.2.7  thorpej      pcmcia_chipset_handle_t pch;
   1026   1.1.2.7  thorpej {
   1027  1.1.2.10     marc     struct pcic_handle *h = (struct pcic_handle *) pch;
   1028  1.1.2.10     marc 
   1029  1.1.2.10     marc     DPRINTF(("pcic_chip_socket_disable\n"));
   1030  1.1.2.10     marc 
   1031  1.1.2.10     marc     /* power down the socket */
   1032  1.1.2.10     marc 
   1033  1.1.2.10     marc     pcic_write(h, PCIC_PWRCTL, 0);
   1034   1.1.2.1     marc }
   1035