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