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