Home | History | Annotate | Line # | Download | only in dev
mmeyepcmcia.c revision 1.11
      1  1.11     perry /*	$NetBSD: mmeyepcmcia.c,v 1.11 2005/12/24 20:07:19 perry Exp $	*/
      2   1.1       uch 
      3   1.1       uch /*
      4   1.1       uch  * Copyright (c) 1997 Marc Horowitz.  All rights reserved.
      5   1.1       uch  *
      6   1.1       uch  * Redistribution and use in source and binary forms, with or without
      7   1.1       uch  * modification, are permitted provided that the following conditions
      8   1.1       uch  * are met:
      9   1.1       uch  * 1. Redistributions of source code must retain the above copyright
     10   1.1       uch  *    notice, this list of conditions and the following disclaimer.
     11   1.1       uch  * 2. Redistributions in binary form must reproduce the above copyright
     12   1.1       uch  *    notice, this list of conditions and the following disclaimer in the
     13   1.1       uch  *    documentation and/or other materials provided with the distribution.
     14   1.1       uch  * 3. All advertising materials mentioning features or use of this software
     15   1.1       uch  *    must display the following acknowledgement:
     16   1.1       uch  *	This product includes software developed by Marc Horowitz.
     17   1.1       uch  * 4. The name of the author may not be used to endorse or promote products
     18   1.1       uch  *    derived from this software without specific prior written permission.
     19   1.1       uch  *
     20   1.1       uch  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     21   1.1       uch  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     22   1.1       uch  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     23   1.1       uch  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     24   1.1       uch  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     25   1.1       uch  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26   1.1       uch  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27   1.1       uch  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28   1.1       uch  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     29   1.1       uch  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30   1.1       uch  */
     31   1.1       uch 
     32   1.1       uch /*
     33   1.1       uch  *  PCMCIA I/F for MMEYE
     34   1.1       uch  *
     35   1.1       uch  *  T.Horiuichi
     36   1.1       uch  *  Brains Corp. 1998.8.25
     37   1.1       uch  */
     38   1.7     lukem 
     39   1.7     lukem #include <sys/cdefs.h>
     40  1.11     perry __KERNEL_RCSID(0, "$NetBSD: mmeyepcmcia.c,v 1.11 2005/12/24 20:07:19 perry Exp $");
     41   1.1       uch 
     42   1.1       uch #include <sys/types.h>
     43   1.1       uch #include <sys/param.h>
     44   1.1       uch #include <sys/systm.h>
     45   1.1       uch #include <sys/kernel.h>
     46   1.1       uch #include <sys/proc.h>
     47   1.1       uch #include <sys/device.h>
     48   1.1       uch #include <sys/extent.h>
     49   1.1       uch #include <sys/malloc.h>
     50   1.1       uch #include <sys/kthread.h>
     51   1.1       uch 
     52   1.1       uch #include <uvm/uvm_extern.h>
     53   1.1       uch 
     54   1.1       uch #include <machine/autoconf.h>
     55   1.1       uch #include <machine/bus.h>
     56   1.1       uch #include <machine/intr.h>
     57   1.1       uch #include <machine/mmeye.h>
     58   1.1       uch 
     59   1.1       uch #include <dev/pcmcia/pcmciareg.h>
     60   1.1       uch #include <dev/pcmcia/pcmciavar.h>
     61   1.1       uch #include <dev/pcmcia/pcmciachip.h>
     62   1.1       uch 
     63   1.1       uch #include <mmeye/dev/mmeyepcmciareg.h>
     64   1.1       uch 
     65   1.1       uch #ifdef MMEYEPCMCIADEBUG
     66   1.1       uch int	mmeyepcmcia_debug = 1;
     67   1.1       uch #define	DPRINTF(arg) if (mmeyepcmcia_debug) printf arg;
     68   1.1       uch #else
     69   1.1       uch #define	DPRINTF(arg)
     70   1.1       uch #endif
     71   1.1       uch 
     72   1.1       uch struct mmeyepcmcia_event {
     73   1.1       uch 	SIMPLEQ_ENTRY(mmeyepcmcia_event) pe_q;
     74   1.1       uch 	int pe_type;
     75   1.1       uch };
     76   1.1       uch 
     77   1.1       uch /* pe_type */
     78   1.1       uch #define MMEYEPCMCIA_EVENT_INSERTION	0
     79   1.1       uch #define MMEYEPCMCIA_EVENT_REMOVAL	1
     80   1.1       uch 
     81   1.1       uch struct mmeyepcmcia_handle {
     82   1.1       uch 	struct mmeyepcmcia_softc *sc;
     83   1.1       uch 	int	flags;
     84   1.1       uch 	int	laststate;
     85   1.1       uch 	int	memalloc;
     86   1.1       uch 	struct {
     87   1.1       uch 		bus_addr_t	addr;
     88   1.1       uch 		bus_size_t	size;
     89   1.1       uch 		long		offset;
     90   1.1       uch 		int		kind;
     91   1.1       uch 	} mem[MMEYEPCMCIA_MEM_WINS];
     92   1.1       uch 	int	ioalloc;
     93   1.1       uch 	struct {
     94   1.1       uch 		bus_addr_t	addr;
     95   1.1       uch 		bus_size_t	size;
     96   1.1       uch 		int		width;
     97   1.1       uch 	} io[MMEYEPCMCIA_IO_WINS];
     98   1.1       uch 	int	ih_irq;
     99   1.1       uch 	struct device *pcmcia;
    100   1.1       uch 
    101   1.1       uch 	int	shutdown;
    102   1.1       uch 	struct proc *event_thread;
    103   1.1       uch 	SIMPLEQ_HEAD(, mmeyepcmcia_event) events;
    104   1.1       uch };
    105   1.1       uch 
    106   1.1       uch /* These four lines are MMTA specific */
    107   1.1       uch #define MMEYEPCMCIA_IRQ1 10
    108   1.1       uch #define MMEYEPCMCIA_IRQ2 9
    109   1.1       uch #define MMEYEPCMCIA_SLOT1_ADDR 0xb8000000
    110   1.1       uch #define MMEYEPCMCIA_SLOT2_ADDR 0xb9000000
    111   1.1       uch 
    112   1.1       uch #define	MMEYEPCMCIA_FLAG_SOCKETP		0x0001
    113   1.1       uch #define	MMEYEPCMCIA_FLAG_CARDP		0x0002
    114   1.1       uch 
    115   1.1       uch #define MMEYEPCMCIA_LASTSTATE_PRESENT	0x0002
    116   1.1       uch #define MMEYEPCMCIA_LASTSTATE_HALF		0x0001
    117   1.1       uch #define MMEYEPCMCIA_LASTSTATE_EMPTY		0x0000
    118   1.1       uch 
    119   1.1       uch /*
    120   1.1       uch  * This is sort of arbitrary.  It merely needs to be "enough". It can be
    121   1.1       uch  * overridden in the conf file, anyway.
    122   1.1       uch  */
    123   1.1       uch 
    124   1.1       uch #define	MMEYEPCMCIA_MEM_PAGES	4
    125   1.1       uch #define	MMEYEPCMCIA_MEMSIZE	MMEYEPCMCIA_MEM_PAGES*MMEYEPCMCIA_MEM_PAGESIZE
    126   1.1       uch 
    127   1.1       uch #define	MMEYEPCMCIA_NSLOTS	1
    128   1.1       uch 
    129   1.1       uch #define MMEYEPCMCIA_WINS	5
    130   1.1       uch #define MMEYEPCMCIA_IOWINS	2
    131   1.1       uch 
    132   1.1       uch struct mmeyepcmcia_softc {
    133   1.1       uch 	struct device dev;
    134   1.1       uch 
    135   1.1       uch 	bus_space_tag_t memt;
    136   1.1       uch 	bus_space_handle_t memh;
    137   1.1       uch 	bus_space_tag_t iot;
    138   1.1       uch 	bus_space_handle_t ioh;
    139   1.1       uch 
    140   1.1       uch 	/* XXX isa_chipset_tag_t, pci_chipset_tag_t, etc. */
    141   1.1       uch 	void	*intr_est;
    142   1.1       uch 
    143   1.1       uch 	pcmcia_chipset_tag_t pct;
    144   1.1       uch 
    145   1.1       uch 	/* this needs to be large enough to hold PCIC_MEM_PAGES bits */
    146   1.1       uch 	int	subregionmask;
    147   1.1       uch #define MMEYEPCMCIA_MAX_MEM_PAGES (8 * sizeof(int))
    148   1.1       uch 
    149   1.1       uch 	/* used by memory window mapping functions */
    150   1.1       uch 	bus_addr_t membase;
    151   1.1       uch 
    152   1.1       uch 	/*
    153   1.1       uch 	 * used by io window mapping functions.  These can actually overlap
    154   1.1       uch 	 * with another pcic, since the underlying extent mapper will deal
    155   1.1       uch 	 * with individual allocations.  This is here to deal with the fact
    156   1.1       uch 	 * that different busses have different real widths (different pc
    157   1.1       uch 	 * hardware seems to use 10 or 12 bits for the I/O bus).
    158   1.1       uch 	 */
    159   1.1       uch 	bus_addr_t iobase;
    160   1.1       uch 	bus_addr_t iosize;
    161   1.1       uch 
    162   1.1       uch 	int	controller_irq;
    163   1.1       uch 	int	card_irq;
    164   1.1       uch 
    165   1.1       uch 	void	*ih;
    166   1.1       uch 
    167   1.1       uch 	struct mmeyepcmcia_handle handle[MMEYEPCMCIA_NSLOTS];
    168   1.1       uch };
    169   1.1       uch 
    170   1.1       uch void	mmeyepcmcia_attach_sockets(struct mmeyepcmcia_softc *);
    171   1.1       uch int	mmeyepcmcia_intr(void *arg);
    172   1.1       uch 
    173   1.1       uch static inline int mmeyepcmcia_read(struct mmeyepcmcia_handle *, int);
    174   1.1       uch static inline void mmeyepcmcia_write(struct mmeyepcmcia_handle *, int, int);
    175   1.1       uch 
    176   1.1       uch int	mmeyepcmcia_chip_mem_alloc(pcmcia_chipset_handle_t, bus_size_t,
    177   1.1       uch 	    struct pcmcia_mem_handle *);
    178   1.1       uch void	mmeyepcmcia_chip_mem_free(pcmcia_chipset_handle_t,
    179   1.1       uch 	    struct pcmcia_mem_handle *);
    180   1.1       uch int	mmeyepcmcia_chip_mem_map(pcmcia_chipset_handle_t, int, bus_addr_t,
    181   1.1       uch 	    bus_size_t, struct pcmcia_mem_handle *, bus_size_t *, int *);
    182   1.1       uch void	mmeyepcmcia_chip_mem_unmap(pcmcia_chipset_handle_t, int);
    183   1.1       uch 
    184   1.1       uch int	mmeyepcmcia_chip_io_alloc(pcmcia_chipset_handle_t, bus_addr_t,
    185   1.1       uch 	    bus_size_t, bus_size_t, struct pcmcia_io_handle *);
    186   1.1       uch void	mmeyepcmcia_chip_io_free(pcmcia_chipset_handle_t,
    187   1.1       uch 	    struct pcmcia_io_handle *);
    188   1.1       uch int	mmeyepcmcia_chip_io_map(pcmcia_chipset_handle_t, int, bus_addr_t,
    189   1.1       uch 	    bus_size_t, struct pcmcia_io_handle *, int *);
    190   1.1       uch void	mmeyepcmcia_chip_io_unmap(pcmcia_chipset_handle_t, int);
    191   1.1       uch 
    192   1.1       uch void	mmeyepcmcia_chip_socket_enable(pcmcia_chipset_handle_t);
    193   1.1       uch void	mmeyepcmcia_chip_socket_disable(pcmcia_chipset_handle_t);
    194   1.1       uch 
    195  1.11     perry static inline int mmeyepcmcia_read(struct mmeyepcmcia_handle *, int);
    196  1.11     perry static inline int
    197   1.1       uch mmeyepcmcia_read(struct mmeyepcmcia_handle *h, int idx)
    198   1.1       uch {
    199   1.1       uch 	static int prev_idx = 0;
    200   1.1       uch 
    201   1.1       uch 	if (idx == -1){
    202   1.1       uch 		idx = prev_idx;
    203   1.1       uch 	}
    204   1.1       uch 	prev_idx = idx;
    205   1.1       uch 	return (bus_space_read_stream_2(h->sc->iot, h->sc->ioh, idx));
    206   1.1       uch }
    207   1.1       uch 
    208  1.11     perry static inline void mmeyepcmcia_write(struct mmeyepcmcia_handle *, int, int);
    209  1.11     perry static inline void
    210   1.1       uch mmeyepcmcia_write(struct mmeyepcmcia_handle *h, int idx, int data)
    211   1.1       uch {
    212   1.1       uch 	static int prev_idx;
    213   1.1       uch 	if (idx == -1){
    214   1.1       uch 		idx = prev_idx;
    215   1.1       uch 	}
    216   1.1       uch 	prev_idx = idx;
    217   1.1       uch 	bus_space_write_stream_2(h->sc->iot, h->sc->ioh, idx, (data));
    218   1.1       uch }
    219   1.1       uch 
    220   1.1       uch void	*mmeyepcmcia_chip_intr_establish(pcmcia_chipset_handle_t,
    221   1.1       uch 	    struct pcmcia_function *, int, int (*) (void *), void *);
    222   1.1       uch void	mmeyepcmcia_chip_intr_disestablish(pcmcia_chipset_handle_t, void *);
    223   1.1       uch void	*mmeyepcmcia_chip_intr_establish(pcmcia_chipset_handle_t,
    224   1.1       uch 	    struct pcmcia_function *, int, int (*) (void *), void *);
    225   1.1       uch void	mmeyepcmcia_chip_intr_disestablish(pcmcia_chipset_handle_t,
    226   1.1       uch 	    void *);
    227   1.1       uch 
    228   1.1       uch void	mmeyepcmcia_attach_socket(struct mmeyepcmcia_handle *);
    229   1.1       uch void	mmeyepcmcia_init_socket(struct mmeyepcmcia_handle *);
    230   1.1       uch int	mmeyepcmcia_print (void *, const char *);
    231   1.1       uch int	mmeyepcmcia_intr_socket(struct mmeyepcmcia_handle *);
    232   1.1       uch void	mmeyepcmcia_attach_card(struct mmeyepcmcia_handle *);
    233   1.1       uch void	mmeyepcmcia_detach_card(struct mmeyepcmcia_handle *, int);
    234   1.1       uch void	mmeyepcmcia_deactivate_card(struct mmeyepcmcia_handle *);
    235   1.1       uch void	mmeyepcmcia_create_event_thread(void *);
    236   1.1       uch void	mmeyepcmcia_event_thread(void *);
    237   1.1       uch void	mmeyepcmcia_queue_event(struct mmeyepcmcia_handle *, int);
    238   1.1       uch 
    239   1.1       uch int	mmeyepcmcia_match(struct device *, struct cfdata *, void *);
    240   1.1       uch void	mmeyepcmcia_attach(struct device *, struct device *, void *);
    241   1.1       uch 
    242   1.5   thorpej CFATTACH_DECL(mmeyepcmcia, sizeof(struct mmeyepcmcia_softc),
    243   1.5   thorpej     mmeyepcmcia_match, mmeyepcmcia_attach, NULL, NULL);
    244   1.1       uch 
    245   1.1       uch static struct pcmcia_chip_functions mmeyepcmcia_functions = {
    246   1.1       uch 	mmeyepcmcia_chip_mem_alloc,
    247   1.1       uch 	mmeyepcmcia_chip_mem_free,
    248   1.1       uch 	mmeyepcmcia_chip_mem_map,
    249   1.1       uch 	mmeyepcmcia_chip_mem_unmap,
    250   1.1       uch 
    251   1.1       uch 	mmeyepcmcia_chip_io_alloc,
    252   1.1       uch 	mmeyepcmcia_chip_io_free,
    253   1.1       uch 	mmeyepcmcia_chip_io_map,
    254   1.1       uch 	mmeyepcmcia_chip_io_unmap,
    255   1.1       uch 
    256   1.1       uch 	mmeyepcmcia_chip_intr_establish,
    257   1.1       uch 	mmeyepcmcia_chip_intr_disestablish,
    258   1.1       uch 
    259   1.1       uch 	mmeyepcmcia_chip_socket_enable,
    260   1.1       uch 	mmeyepcmcia_chip_socket_disable,
    261   1.1       uch };
    262   1.1       uch 
    263   1.1       uch int
    264   1.1       uch mmeyepcmcia_match(struct device *parent, struct cfdata *match, void *aux)
    265   1.1       uch {
    266   1.1       uch 	extern struct cfdriver mmeyepcmcia_cd;
    267   1.1       uch 	struct mainbus_attach_args *ma = aux;
    268   1.1       uch 
    269   1.1       uch 	if (strcmp(ma->ma_name, mmeyepcmcia_cd.cd_name) == 0)
    270   1.1       uch 		return (1);
    271   1.1       uch 
    272   1.1       uch 	return (0);
    273   1.1       uch }
    274   1.1       uch 
    275   1.1       uch void
    276   1.1       uch mmeyepcmcia_attach(struct device *parent, struct device *self, void *aux)
    277   1.1       uch {
    278   1.1       uch 	struct mainbus_attach_args *ma = aux;
    279   1.1       uch 	struct mmeyepcmcia_softc *sc = (void *)self;
    280   1.1       uch 
    281   1.1       uch 	sc->subregionmask = 1;	/* 1999.05.17 T.Horiuchi for R1.4 */
    282   1.1       uch 
    283   1.1       uch 	sc->pct = (pcmcia_chipset_tag_t)&mmeyepcmcia_functions;
    284   1.1       uch 	sc->iot = 0;
    285   1.1       uch 	sc->ioh = ma->ma_addr1;
    286   1.1       uch 	sc->memt = 0;
    287   1.1       uch 	sc->memh = ma->ma_addr2;
    288   1.1       uch 	sc->controller_irq = ma->ma_irq1;
    289   1.1       uch 	sc->card_irq = ma->ma_irq2;
    290   1.1       uch 
    291   1.1       uch 	printf(": using MMTA irq %d\n", sc->controller_irq);
    292   1.1       uch 
    293   1.1       uch 	sc->handle[0].sc = sc;
    294   1.1       uch 	sc->handle[0].flags = MMEYEPCMCIA_FLAG_SOCKETP;
    295   1.1       uch 	sc->handle[0].laststate = MMEYEPCMCIA_LASTSTATE_EMPTY;
    296   1.1       uch 
    297   1.1       uch 	SIMPLEQ_INIT(&sc->handle[0].events);
    298   1.1       uch 
    299   1.1       uch 	mmeye_intr_establish(sc->controller_irq,
    300   1.1       uch 	    IST_LEVEL, IPL_TTY, mmeyepcmcia_intr, sc);
    301   1.1       uch 
    302   1.1       uch 	mmeyepcmcia_attach_sockets(sc);
    303   1.1       uch }
    304   1.1       uch 
    305   1.1       uch void *
    306   1.1       uch mmeyepcmcia_chip_intr_establish(pch, pf, ipl, fct, arg)
    307   1.1       uch 	pcmcia_chipset_handle_t pch;
    308   1.1       uch 	struct pcmcia_function *pf;
    309   1.1       uch 	int ipl;
    310   1.1       uch 	int (*fct)(void *);
    311   1.1       uch 	void *arg;
    312   1.1       uch {
    313   1.1       uch 	struct mmeyepcmcia_handle *h = (struct mmeyepcmcia_handle *) pch;
    314   1.1       uch 	int irq = h->sc->card_irq;
    315   1.1       uch 	void *ih;
    316   1.1       uch 
    317   1.1       uch 	ih = mmeye_intr_establish(irq, IST_LEVEL, ipl, fct, arg);
    318   1.1       uch 	h->ih_irq = irq;
    319   1.1       uch 
    320   1.1       uch 	printf("%s: card irq %d\n", h->pcmcia->dv_xname, irq);
    321   1.1       uch 
    322   1.1       uch 	return (ih);
    323   1.1       uch }
    324   1.1       uch 
    325   1.1       uch void
    326   1.1       uch mmeyepcmcia_chip_intr_disestablish(pcmcia_chipset_handle_t pch, void *ih)
    327   1.1       uch {
    328   1.1       uch 	struct mmeyepcmcia_handle *h = (struct mmeyepcmcia_handle *) pch;
    329   1.1       uch 
    330   1.1       uch 	h->ih_irq = 0;
    331   1.1       uch 	mmeye_intr_disestablish(ih);
    332   1.1       uch }
    333   1.1       uch 
    334   1.1       uch 
    335   1.1       uch void
    336   1.1       uch mmeyepcmcia_attach_sockets(struct mmeyepcmcia_softc *sc)
    337   1.1       uch {
    338   1.1       uch 
    339   1.1       uch 	mmeyepcmcia_attach_socket(&sc->handle[0]);
    340   1.1       uch }
    341   1.1       uch 
    342   1.1       uch void
    343   1.1       uch mmeyepcmcia_attach_socket(struct mmeyepcmcia_handle *h)
    344   1.1       uch {
    345   1.1       uch 	struct pcmciabus_attach_args paa;
    346   1.1       uch 
    347   1.1       uch 	/* initialize the rest of the handle */
    348   1.1       uch 
    349   1.1       uch 	h->shutdown = 0;
    350   1.1       uch 	h->memalloc = 0;
    351   1.1       uch 	h->ioalloc = 0;
    352   1.1       uch 	h->ih_irq = 0;
    353   1.1       uch 
    354   1.1       uch 	/* now, config one pcmcia device per socket */
    355   1.1       uch 
    356   1.1       uch 	paa.paa_busname = "pcmcia";
    357   1.1       uch 	paa.pct = (pcmcia_chipset_tag_t) h->sc->pct;
    358   1.1       uch 	paa.pch = (pcmcia_chipset_handle_t) h;
    359   1.1       uch 	paa.iobase = h->sc->iobase;
    360   1.1       uch 	paa.iosize = h->sc->iosize;
    361   1.1       uch 
    362   1.9  drochner 	h->pcmcia = config_found_ia(&h->sc->dev, "pcmciabus", &paa,
    363   1.9  drochner 				    mmeyepcmcia_print);
    364   1.1       uch 
    365   1.1       uch 	/* if there's actually a pcmcia device attached, initialize the slot */
    366   1.1       uch 
    367   1.1       uch 	if (h->pcmcia)
    368   1.1       uch 		mmeyepcmcia_init_socket(h);
    369   1.1       uch }
    370   1.1       uch 
    371   1.1       uch void
    372   1.1       uch mmeyepcmcia_create_event_thread(void *arg)
    373   1.1       uch {
    374   1.1       uch 	struct mmeyepcmcia_handle *h = arg;
    375   1.1       uch 
    376   1.1       uch 	if (kthread_create1(mmeyepcmcia_event_thread, h, &h->event_thread,
    377   1.1       uch 	    "%s", h->sc->dev.dv_xname)) {
    378   1.1       uch 		printf("%s: unable to create event thread\n",
    379   1.1       uch 		    h->sc->dev.dv_xname);
    380   1.1       uch 		panic("mmeyepcmcia_create_event_thread");
    381   1.1       uch 	}
    382   1.1       uch }
    383   1.1       uch 
    384   1.1       uch void
    385   1.1       uch mmeyepcmcia_event_thread(void *arg)
    386   1.1       uch {
    387   1.1       uch 	struct mmeyepcmcia_handle *h = arg;
    388   1.1       uch 	struct mmeyepcmcia_event *pe;
    389   1.1       uch 	int s;
    390   1.1       uch 
    391   1.1       uch 	while (h->shutdown == 0) {
    392   1.1       uch 		s = splhigh();
    393   1.1       uch 		if ((pe = SIMPLEQ_FIRST(&h->events)) == NULL) {
    394   1.1       uch 			splx(s);
    395   1.1       uch 			(void) tsleep(&h->events, PWAIT, "mmeyepcmciaev", 0);
    396   1.1       uch 			continue;
    397   1.1       uch 		} else {
    398   1.1       uch 			splx(s);
    399   1.1       uch 			/* sleep .25s to be enqueued chatterling interrupts */
    400   1.1       uch 			(void) tsleep((caddr_t)mmeyepcmcia_event_thread, PWAIT,
    401   1.1       uch 			    "mmeyepcmciass", hz/4);
    402   1.1       uch 		}
    403   1.1       uch 		s = splhigh();
    404   1.2     lukem 		SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
    405   1.1       uch 		splx(s);
    406   1.1       uch 
    407   1.1       uch 		switch (pe->pe_type) {
    408   1.1       uch 		case MMEYEPCMCIA_EVENT_INSERTION:
    409   1.1       uch 			s = splhigh();
    410   1.1       uch 			while (1) {
    411   1.1       uch 				struct mmeyepcmcia_event *pe1, *pe2;
    412   1.1       uch 
    413   1.1       uch 				if ((pe1 = SIMPLEQ_FIRST(&h->events)) == NULL)
    414   1.1       uch 					break;
    415   1.1       uch 				if (pe1->pe_type != MMEYEPCMCIA_EVENT_REMOVAL)
    416   1.1       uch 					break;
    417   1.1       uch 				if ((pe2 = SIMPLEQ_NEXT(pe1, pe_q)) == NULL)
    418   1.1       uch 					break;
    419   1.1       uch 				if (pe2->pe_type == MMEYEPCMCIA_EVENT_INSERTION) {
    420   1.2     lukem 					SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
    421   1.1       uch 					free(pe1, M_TEMP);
    422   1.2     lukem 					SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
    423   1.1       uch 					free(pe2, M_TEMP);
    424   1.1       uch 				}
    425   1.1       uch 			}
    426   1.1       uch 			splx(s);
    427   1.1       uch 
    428   1.1       uch 			DPRINTF(("%s: insertion event\n", h->sc->dev.dv_xname));
    429   1.1       uch 			mmeyepcmcia_attach_card(h);
    430   1.1       uch 			break;
    431   1.1       uch 
    432   1.1       uch 		case MMEYEPCMCIA_EVENT_REMOVAL:
    433   1.1       uch 			s = splhigh();
    434   1.1       uch 			while (1) {
    435   1.1       uch 				struct mmeyepcmcia_event *pe1, *pe2;
    436   1.1       uch 
    437   1.1       uch 				if ((pe1 = SIMPLEQ_FIRST(&h->events)) == NULL)
    438   1.1       uch 					break;
    439   1.1       uch 				if (pe1->pe_type != MMEYEPCMCIA_EVENT_INSERTION)
    440   1.1       uch 					break;
    441   1.1       uch 				if ((pe2 = SIMPLEQ_NEXT(pe1, pe_q)) == NULL)
    442   1.1       uch 					break;
    443   1.1       uch 				if (pe2->pe_type == MMEYEPCMCIA_EVENT_REMOVAL) {
    444   1.2     lukem 					SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
    445   1.1       uch 					free(pe1, M_TEMP);
    446   1.2     lukem 					SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
    447   1.1       uch 					free(pe2, M_TEMP);
    448   1.1       uch 				}
    449   1.1       uch 			}
    450   1.1       uch 			splx(s);
    451   1.1       uch 
    452   1.1       uch 			DPRINTF(("%s: removal event\n", h->sc->dev.dv_xname));
    453   1.1       uch 			mmeyepcmcia_detach_card(h, DETACH_FORCE);
    454   1.1       uch 			break;
    455   1.1       uch 
    456   1.1       uch 		default:
    457   1.1       uch 			panic("mmeyepcmcia_event_thread: unknown event %d",
    458   1.1       uch 			    pe->pe_type);
    459   1.1       uch 		}
    460   1.1       uch 		free(pe, M_TEMP);
    461   1.1       uch 	}
    462   1.1       uch 
    463   1.1       uch 	h->event_thread = NULL;
    464   1.1       uch 
    465   1.1       uch 	/* In case parent is waiting for us to exit. */
    466   1.1       uch 	wakeup(h->sc);
    467   1.1       uch 
    468   1.1       uch 	kthread_exit(0);
    469   1.1       uch }
    470   1.1       uch 
    471   1.1       uch void
    472   1.1       uch mmeyepcmcia_init_socket(struct mmeyepcmcia_handle *h)
    473   1.1       uch {
    474   1.1       uch 	int reg;
    475   1.1       uch 
    476   1.1       uch 	/*
    477   1.1       uch 	 * queue creation of a kernel thread to handle insert/removal events.
    478   1.1       uch 	 */
    479   1.1       uch #ifdef DIAGNOSTIC
    480   1.1       uch 	if (h->event_thread != NULL)
    481   1.1       uch 		panic("mmeyepcmcia_attach_socket: event thread");
    482   1.1       uch #endif
    483   1.1       uch 	kthread_create(mmeyepcmcia_create_event_thread, h);
    484   1.1       uch 
    485   1.1       uch 	/* if there's a card there, then attach it. */
    486   1.1       uch 
    487   1.1       uch 	reg = mmeyepcmcia_read(h, MMEYEPCMCIA_IF_STATUS);
    488   1.1       uch 	reg &= ~MMEYEPCMCIA_IF_STATUS_BUSWIDTH; /* Set bus width to 16bit */
    489   1.1       uch 
    490   1.1       uch 	if ((reg & MMEYEPCMCIA_IF_STATUS_CARDDETECT_MASK) ==
    491   1.1       uch 	    MMEYEPCMCIA_IF_STATUS_CARDDETECT_PRESENT) {
    492   1.1       uch 		int i;
    493   1.1       uch 
    494   1.1       uch 		/* reset the card */
    495   1.1       uch 		mmeyepcmcia_write(h, MMEYEPCMCIA_IF_STATUS, reg|MMEYEPCMCIA_IF_STATUS_RESET);
    496   1.1       uch 		delay(1000); /* wait 1000 uSec */
    497   1.1       uch 		mmeyepcmcia_write(h, MMEYEPCMCIA_IF_STATUS,
    498   1.1       uch 			     reg & ~MMEYEPCMCIA_IF_STATUS_RESET);
    499   1.1       uch 		for (i = 0; i < 10000; i++)
    500   1.1       uch 			delay(1000); /* wait 1 mSec */
    501   1.1       uch 
    502   1.1       uch 		mmeyepcmcia_attach_card(h);
    503   1.1       uch 		h->laststate = MMEYEPCMCIA_LASTSTATE_PRESENT;
    504   1.1       uch 	} else {
    505   1.1       uch 		h->laststate = MMEYEPCMCIA_LASTSTATE_EMPTY;
    506   1.1       uch 	}
    507   1.1       uch }
    508   1.1       uch 
    509   1.1       uch int
    510   1.1       uch mmeyepcmcia_print(void *arg, const char *pnp)
    511   1.1       uch {
    512   1.1       uch 
    513   1.1       uch 	if (pnp)
    514   1.6   thorpej 		aprint_normal("pcmcia at %s", pnp);
    515   1.1       uch 
    516   1.1       uch 	return (UNCONF);
    517   1.1       uch }
    518   1.1       uch 
    519   1.1       uch int
    520   1.1       uch mmeyepcmcia_intr(void *arg)
    521   1.1       uch {
    522   1.1       uch 	struct mmeyepcmcia_softc *sc = arg;
    523   1.1       uch 
    524   1.1       uch 	DPRINTF(("%s: intr\n", sc->dev.dv_xname));
    525   1.1       uch 
    526   1.1       uch 	mmeyepcmcia_intr_socket(&sc->handle[0]);
    527   1.1       uch 
    528   1.1       uch 	return (0);
    529   1.1       uch }
    530   1.1       uch 
    531   1.1       uch int
    532   1.1       uch mmeyepcmcia_intr_socket(struct mmeyepcmcia_handle *h)
    533   1.1       uch {
    534   1.1       uch 	int cscreg;
    535   1.1       uch 
    536   1.1       uch 	cscreg = mmeyepcmcia_read(h, MMEYEPCMCIA_CSC);
    537   1.1       uch 
    538   1.1       uch 	cscreg &= (MMEYEPCMCIA_CSC_GPI |
    539   1.1       uch 		   MMEYEPCMCIA_CSC_CD |
    540   1.1       uch 		   MMEYEPCMCIA_CSC_READY |
    541   1.1       uch 		   MMEYEPCMCIA_CSC_BATTWARN |
    542   1.1       uch 		   MMEYEPCMCIA_CSC_BATTDEAD);
    543   1.1       uch 
    544   1.1       uch 	if (cscreg & MMEYEPCMCIA_CSC_GPI) {
    545   1.1       uch 		DPRINTF(("%s: %02x GPI\n", h->sc->dev.dv_xname, h->sock));
    546   1.1       uch 	}
    547   1.1       uch 	if (cscreg & MMEYEPCMCIA_CSC_CD) {
    548   1.1       uch 		int statreg;
    549   1.1       uch 
    550   1.1       uch 		statreg = mmeyepcmcia_read(h, MMEYEPCMCIA_IF_STATUS);
    551   1.1       uch 
    552   1.1       uch 		DPRINTF(("%s: %02x CD %x\n", h->sc->dev.dv_xname, h->sock,
    553   1.1       uch 		    statreg));
    554   1.1       uch 
    555   1.1       uch 		if ((statreg & MMEYEPCMCIA_IF_STATUS_CARDDETECT_MASK) ==
    556   1.1       uch 		    MMEYEPCMCIA_IF_STATUS_CARDDETECT_PRESENT) {
    557   1.1       uch 			if (h->laststate != MMEYEPCMCIA_LASTSTATE_PRESENT) {
    558   1.1       uch 				DPRINTF(("%s: enqueing INSERTION event\n",
    559   1.1       uch 						 h->sc->dev.dv_xname));
    560   1.1       uch 				mmeyepcmcia_queue_event(h, MMEYEPCMCIA_EVENT_INSERTION);
    561   1.1       uch 			}
    562   1.1       uch 			h->laststate = MMEYEPCMCIA_LASTSTATE_PRESENT;
    563   1.1       uch 		} else {
    564   1.1       uch 			if (h->laststate == MMEYEPCMCIA_LASTSTATE_PRESENT) {
    565   1.1       uch 				/* Deactivate the card now. */
    566   1.1       uch 				DPRINTF(("%s: deactivating card\n",
    567   1.1       uch 						 h->sc->dev.dv_xname));
    568   1.1       uch 				mmeyepcmcia_deactivate_card(h);
    569   1.1       uch 
    570   1.1       uch 				DPRINTF(("%s: enqueing REMOVAL event\n",
    571   1.1       uch 						 h->sc->dev.dv_xname));
    572   1.1       uch 				mmeyepcmcia_queue_event(h, MMEYEPCMCIA_EVENT_REMOVAL);
    573   1.1       uch 			}
    574   1.1       uch 			h->laststate = ((statreg & MMEYEPCMCIA_IF_STATUS_CARDDETECT_MASK) == 0)
    575   1.1       uch 				? MMEYEPCMCIA_LASTSTATE_EMPTY : MMEYEPCMCIA_LASTSTATE_HALF;
    576   1.1       uch 		}
    577   1.1       uch 	}
    578   1.1       uch 	if (cscreg & MMEYEPCMCIA_CSC_READY) {
    579   1.1       uch 		DPRINTF(("%s: %02x READY\n", h->sc->dev.dv_xname, h->sock));
    580   1.1       uch 		/* shouldn't happen */
    581   1.1       uch 	}
    582   1.1       uch 	if (cscreg & MMEYEPCMCIA_CSC_BATTWARN) {
    583   1.1       uch 		DPRINTF(("%s: %02x BATTWARN\n", h->sc->dev.dv_xname, h->sock));
    584   1.1       uch 	}
    585   1.1       uch 	if (cscreg & MMEYEPCMCIA_CSC_BATTDEAD) {
    586   1.1       uch 		DPRINTF(("%s: %02x BATTDEAD\n", h->sc->dev.dv_xname, h->sock));
    587   1.1       uch 	}
    588   1.1       uch 	return (cscreg ? 1 : 0);
    589   1.1       uch }
    590   1.1       uch 
    591   1.1       uch void
    592   1.1       uch mmeyepcmcia_queue_event(struct mmeyepcmcia_handle *h, int event)
    593   1.1       uch {
    594   1.1       uch 	struct mmeyepcmcia_event *pe;
    595   1.1       uch 	int s;
    596   1.1       uch 
    597   1.1       uch 	pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT);
    598   1.1       uch 	if (pe == NULL)
    599   1.1       uch 		panic("mmeyepcmcia_queue_event: can't allocate event");
    600   1.1       uch 
    601   1.1       uch 	pe->pe_type = event;
    602   1.1       uch 	s = splhigh();
    603   1.1       uch 	SIMPLEQ_INSERT_TAIL(&h->events, pe, pe_q);
    604   1.1       uch 	splx(s);
    605   1.1       uch 	wakeup(&h->events);
    606   1.1       uch }
    607   1.1       uch 
    608   1.1       uch void
    609   1.1       uch mmeyepcmcia_attach_card(struct mmeyepcmcia_handle *h)
    610   1.1       uch {
    611   1.1       uch 
    612   1.1       uch 	if (!(h->flags & MMEYEPCMCIA_FLAG_CARDP)) {
    613   1.1       uch 		/* call the MI attach function */
    614   1.1       uch 		pcmcia_card_attach(h->pcmcia);
    615   1.1       uch 
    616   1.1       uch 		h->flags |= MMEYEPCMCIA_FLAG_CARDP;
    617   1.1       uch 	} else {
    618   1.1       uch 		DPRINTF(("mmeyepcmcia_attach_card: already attached"));
    619   1.1       uch 	}
    620   1.1       uch }
    621   1.1       uch 
    622   1.1       uch void
    623   1.1       uch mmeyepcmcia_detach_card(struct mmeyepcmcia_handle *h, int flags)
    624   1.1       uch {
    625   1.1       uch 
    626   1.1       uch 	if (h->flags & MMEYEPCMCIA_FLAG_CARDP) {
    627   1.1       uch 		h->flags &= ~MMEYEPCMCIA_FLAG_CARDP;
    628   1.1       uch 
    629   1.1       uch 		/* call the MI detach function */
    630   1.1       uch 		pcmcia_card_detach(h->pcmcia, flags);
    631   1.1       uch 	} else {
    632   1.1       uch 		DPRINTF(("mmeyepcmcia_detach_card: already detached"));
    633   1.1       uch 	}
    634   1.1       uch }
    635   1.1       uch 
    636   1.1       uch void
    637   1.1       uch mmeyepcmcia_deactivate_card(struct mmeyepcmcia_handle *h)
    638   1.1       uch {
    639   1.1       uch 
    640   1.1       uch 	/* call the MI deactivate function */
    641   1.1       uch 	pcmcia_card_deactivate(h->pcmcia);
    642   1.1       uch 
    643   1.1       uch 	/* Power down and reset XXX notyet */
    644   1.1       uch }
    645   1.1       uch 
    646   1.1       uch int
    647   1.1       uch mmeyepcmcia_chip_mem_alloc(pcmcia_chipset_handle_t pch, bus_size_t size,
    648   1.1       uch     struct pcmcia_mem_handle *pcmhp)
    649   1.1       uch {
    650   1.1       uch 	struct mmeyepcmcia_handle *h = (struct mmeyepcmcia_handle *) pch;
    651   1.1       uch 	bus_space_handle_t memh = 0;
    652   1.1       uch 	bus_addr_t addr;
    653   1.1       uch 	bus_size_t sizepg;
    654   1.1       uch 	int i, mask, mhandle;
    655   1.1       uch 
    656   1.1       uch 	/* out of sc->memh, allocate as many pages as necessary */
    657   1.1       uch #define	MMEYEPCMCIA_MEM_ALIGN	MMEYEPCMCIA_MEM_PAGESIZE
    658   1.1       uch 	/* convert size to PCIC pages */
    659   1.1       uch 	sizepg = (size + (MMEYEPCMCIA_MEM_ALIGN - 1)) / MMEYEPCMCIA_MEM_ALIGN;
    660   1.1       uch 	if (sizepg > MMEYEPCMCIA_MAX_MEM_PAGES)
    661   1.1       uch 		return (1);
    662   1.1       uch 
    663   1.1       uch 	mask = (1 << sizepg) - 1;
    664   1.1       uch 
    665   1.1       uch 	addr = 0;		/* XXX gcc -Wuninitialized */
    666   1.1       uch 	mhandle = 0;		/* XXX gcc -Wuninitialized */
    667   1.1       uch 
    668   1.1       uch 	for (i = 0; i <= MMEYEPCMCIA_MAX_MEM_PAGES - sizepg; i++) {
    669   1.1       uch 		if ((h->sc->subregionmask & (mask << i)) == (mask << i)) {
    670   1.1       uch #if 0
    671   1.1       uch 			if (bus_space_subregion(h->sc->memt, h->sc->memh,
    672   1.1       uch 			    i * MMEYEPCMCIA_MEM_PAGESIZE,
    673   1.1       uch 			    sizepg * MMEYEPCMCIA_MEM_PAGESIZE, &memh))
    674   1.1       uch 				return (1);
    675   1.1       uch #endif
    676   1.1       uch 			memh = h->sc->memh;
    677   1.1       uch 			mhandle = mask << i;
    678   1.1       uch 			addr = h->sc->membase + (i * MMEYEPCMCIA_MEM_PAGESIZE);
    679   1.1       uch 			h->sc->subregionmask &= ~(mhandle);
    680   1.1       uch 			pcmhp->memt = h->sc->memt;
    681   1.1       uch 			pcmhp->memh = memh;
    682   1.1       uch 			pcmhp->addr = addr;
    683   1.1       uch 			pcmhp->size = size;
    684   1.1       uch 			pcmhp->mhandle = mhandle;
    685   1.1       uch 			pcmhp->realsize = sizepg * MMEYEPCMCIA_MEM_PAGESIZE;
    686   1.1       uch 			return (0);
    687   1.1       uch 		}
    688   1.1       uch 	}
    689   1.1       uch 
    690   1.1       uch 	return (1);
    691   1.1       uch }
    692   1.1       uch 
    693   1.1       uch void
    694   1.1       uch mmeyepcmcia_chip_mem_free(pcmcia_chipset_handle_t pch,
    695   1.1       uch     struct pcmcia_mem_handle *pcmhp)
    696   1.1       uch {
    697   1.1       uch 	struct mmeyepcmcia_handle *h = (struct mmeyepcmcia_handle *) pch;
    698   1.1       uch 
    699   1.1       uch 	h->sc->subregionmask |= pcmhp->mhandle;
    700   1.1       uch }
    701   1.1       uch 
    702   1.1       uch int
    703   1.1       uch mmeyepcmcia_chip_mem_map(pcmcia_chipset_handle_t pch, int kind,
    704   1.1       uch     bus_addr_t card_addr, bus_size_t size, struct pcmcia_mem_handle *pcmhp,
    705   1.1       uch     bus_size_t *offsetp, int *windowp)
    706   1.1       uch {
    707   1.1       uch 	struct mmeyepcmcia_handle *h = (struct mmeyepcmcia_handle *) pch;
    708   1.1       uch 	bus_addr_t busaddr;
    709   1.1       uch 	long card_offset;
    710   1.1       uch 	int i, win;
    711   1.1       uch 
    712   1.1       uch 	win = -1;
    713   1.1       uch 	for (i = 0; i < MMEYEPCMCIA_WINS;
    714   1.1       uch 	    i++) {
    715   1.1       uch 		if ((h->memalloc & (1 << i)) == 0) {
    716   1.1       uch 			win = i;
    717   1.1       uch 			h->memalloc |= (1 << i);
    718   1.1       uch 			break;
    719   1.1       uch 		}
    720   1.1       uch 	}
    721   1.1       uch 
    722   1.1       uch 	if (win == -1)
    723   1.1       uch 		return (1);
    724   1.1       uch 
    725   1.1       uch 	*windowp = win;
    726   1.1       uch 
    727   1.1       uch 	/* XXX this is pretty gross */
    728   1.1       uch 
    729   1.1       uch 	if (h->sc->memt != pcmhp->memt)
    730   1.1       uch 		panic("mmeyepcmcia_chip_mem_map memt is bogus");
    731   1.1       uch 
    732   1.1       uch 	busaddr = pcmhp->addr;
    733   1.1       uch 
    734   1.1       uch 	/*
    735   1.1       uch 	 * compute the address offset to the pcmcia address space for the
    736   1.1       uch 	 * pcic.  this is intentionally signed.  The masks and shifts below
    737   1.1       uch 	 * will cause TRT to happen in the pcic registers.  Deal with making
    738   1.1       uch 	 * sure the address is aligned, and return the alignment offset.
    739   1.1       uch 	 */
    740   1.1       uch 
    741   1.1       uch 	*offsetp = 0;
    742   1.1       uch 	card_addr -= *offsetp;
    743   1.1       uch 
    744   1.1       uch 	DPRINTF(("mmeyepcmcia_chip_mem_map window %d bus %lx+%lx+%lx at card addr "
    745   1.1       uch 	    "%lx\n", win, (u_long) busaddr, (u_long) * offsetp, (u_long) size,
    746   1.1       uch 	    (u_long) card_addr));
    747   1.1       uch 
    748   1.1       uch 	/*
    749   1.1       uch 	 * include the offset in the size, and decrement size by one, since
    750   1.1       uch 	 * the hw wants start/stop
    751   1.1       uch 	 */
    752   1.1       uch 	size += *offsetp - 1;
    753   1.1       uch 
    754   1.1       uch 	card_offset = (((long) card_addr) - ((long) busaddr));
    755   1.1       uch 
    756   1.1       uch 	h->mem[win].addr = busaddr;
    757   1.1       uch 	h->mem[win].size = size;
    758   1.1       uch 	h->mem[win].offset = card_offset;
    759   1.1       uch 	h->mem[win].kind = kind;
    760   1.1       uch 
    761   1.1       uch 	if (kind == PCMCIA_MEM_ATTR) {
    762   1.1       uch 		pcmhp->memh = h->sc->memh + card_addr;
    763   1.1       uch 	} else {
    764   1.1       uch 		pcmhp->memh = h->sc->memh + card_addr + MMEYEPCMCIA_ATTRMEM_SIZE;
    765   1.1       uch 	}
    766   1.1       uch 
    767   1.1       uch 	return (0);
    768   1.1       uch }
    769   1.1       uch 
    770   1.1       uch void
    771   1.1       uch mmeyepcmcia_chip_mem_unmap(pcmcia_chipset_handle_t pch, int window)
    772   1.1       uch {
    773   1.1       uch 	struct mmeyepcmcia_handle *h = (struct mmeyepcmcia_handle *) pch;
    774   1.1       uch 
    775   1.1       uch 	if (window >= MMEYEPCMCIA_WINS)
    776   1.1       uch 		panic("mmeyepcmcia_chip_mem_unmap: window out of range");
    777   1.1       uch 
    778   1.1       uch 	h->memalloc &= ~(1 << window);
    779   1.1       uch }
    780   1.1       uch 
    781   1.1       uch int
    782   1.1       uch mmeyepcmcia_chip_io_alloc(pcmcia_chipset_handle_t pch, bus_addr_t start,
    783   1.1       uch     bus_size_t size, bus_size_t align, struct pcmcia_io_handle *pcihp)
    784   1.1       uch {
    785   1.1       uch 	struct mmeyepcmcia_handle *h = (struct mmeyepcmcia_handle *) pch;
    786   1.1       uch 	bus_space_tag_t iot;
    787   1.1       uch 	bus_space_handle_t ioh;
    788   1.1       uch 	bus_addr_t ioaddr;
    789   1.1       uch 	int flags = 0;
    790   1.1       uch 
    791   1.1       uch 	/*
    792   1.1       uch 	 * Allocate some arbitrary I/O space.
    793   1.1       uch 	 */
    794   1.1       uch 
    795   1.1       uch 	iot = h->sc->iot;
    796   1.1       uch 
    797   1.1       uch 	if (start) {
    798   1.1       uch 		ioaddr = start;
    799   1.1       uch 		ioh = start;
    800   1.1       uch 		DPRINTF(("mmeyepcmcia_chip_io_alloc map port %lx+%lx\n",
    801   1.1       uch 		    (u_long) ioaddr, (u_long) size));
    802   1.1       uch 	} else {
    803   1.1       uch 		flags |= PCMCIA_IO_ALLOCATED;
    804   1.1       uch 		ioaddr = ioh = h->sc->iobase;
    805   1.1       uch 		DPRINTF(("mmeyepcmcia_chip_io_alloc alloc port %lx+%lx\n",
    806   1.1       uch 		    (u_long) ioaddr, (u_long) size));
    807   1.1       uch 	}
    808   1.1       uch 
    809   1.1       uch 	pcihp->iot = iot;
    810   1.1       uch 	pcihp->ioh = ioh + h->sc->memh + MMEYEPCMCIA_ATTRMEM_SIZE;
    811   1.1       uch 	pcihp->addr = ioaddr;
    812   1.1       uch 	pcihp->size = size;
    813   1.1       uch 	pcihp->flags = flags;
    814   1.1       uch 
    815   1.1       uch 	return (0);
    816   1.1       uch }
    817   1.1       uch 
    818   1.1       uch void
    819   1.1       uch mmeyepcmcia_chip_io_free(pcmcia_chipset_handle_t pch,
    820   1.1       uch     struct pcmcia_io_handle *pcihp)
    821   1.1       uch {
    822   1.1       uch }
    823   1.1       uch 
    824   1.1       uch int
    825   1.1       uch mmeyepcmcia_chip_io_map(pcmcia_chipset_handle_t pch, int width, bus_addr_t offset,
    826   1.1       uch     bus_size_t size, struct pcmcia_io_handle *pcihp, int *windowp)
    827   1.1       uch {
    828   1.1       uch 	struct mmeyepcmcia_handle *h = (struct mmeyepcmcia_handle *) pch;
    829   1.1       uch 	bus_addr_t ioaddr = pcihp->addr + offset;
    830   1.1       uch 	int i, win;
    831   1.1       uch #ifdef MMEYEPCMCIADEBUG
    832   1.1       uch 	static char *width_names[] = { "auto", "io8", "io16" };
    833   1.1       uch #endif
    834   1.1       uch 	int reg;
    835   1.1       uch 
    836   1.1       uch 	/* I/O width is hardwired to 16bit mode on mmeye. */
    837   1.1       uch 	width = PCMCIA_WIDTH_IO16;
    838   1.1       uch 
    839   1.1       uch 	win = -1;
    840   1.1       uch 	for (i = 0; i < MMEYEPCMCIA_IOWINS; i++) {
    841   1.1       uch 		if ((h->ioalloc & (1 << i)) == 0) {
    842   1.1       uch 			win = i;
    843   1.1       uch 			h->ioalloc |= (1 << i);
    844   1.1       uch 			break;
    845   1.1       uch 		}
    846   1.1       uch 	}
    847   1.1       uch 
    848   1.1       uch 	if (win == -1)
    849   1.1       uch 		return (1);
    850   1.1       uch 
    851   1.1       uch 	*windowp = win;
    852   1.1       uch 
    853   1.1       uch 	/* XXX this is pretty gross */
    854   1.1       uch 
    855   1.1       uch 	if (h->sc->iot != pcihp->iot)
    856   1.1       uch 		panic("mmeyepcmcia_chip_io_map iot is bogus");
    857   1.1       uch 
    858   1.1       uch 	DPRINTF(("mmeyepcmcia_chip_io_map window %d %s port %lx+%lx\n",
    859   1.1       uch 		 win, width_names[width], (u_long) ioaddr, (u_long) size));
    860   1.1       uch 
    861   1.1       uch 	/* XXX wtf is this doing here? */
    862   1.1       uch 
    863   1.8  christos 	printf("%s: port 0x%lx", h->sc->dev.dv_xname, (u_long) ioaddr);
    864   1.1       uch 	if (size > 1)
    865   1.1       uch 		printf("-0x%lx", (u_long) ioaddr + (u_long) size - 1);
    866   1.8  christos 	printf("\n");
    867   1.1       uch 
    868   1.1       uch 	h->io[win].addr = ioaddr;
    869   1.1       uch 	h->io[win].size = size;
    870   1.1       uch 	h->io[win].width = width;
    871   1.1       uch 
    872   1.1       uch 	pcihp->ioh = h->sc->memh + MMEYEPCMCIA_ATTRMEM_SIZE;
    873   1.1       uch 
    874   1.1       uch 	if (width == PCMCIA_WIDTH_IO8) { /* IO8 */
    875   1.1       uch 		reg = mmeyepcmcia_read(h, MMEYEPCMCIA_IF_STATUS);
    876   1.1       uch 		reg |= MMEYEPCMCIA_IF_STATUS_BUSWIDTH; /* Set bus width to 8bit */
    877   1.1       uch 		mmeyepcmcia_write(h, MMEYEPCMCIA_IF_STATUS, reg);
    878   1.1       uch 	}
    879   1.1       uch 
    880   1.1       uch 	return (0);
    881   1.1       uch }
    882   1.1       uch 
    883   1.1       uch void
    884   1.1       uch mmeyepcmcia_chip_io_unmap(pcmcia_chipset_handle_t pch, int window)
    885   1.1       uch {
    886   1.1       uch 	struct mmeyepcmcia_handle *h = (struct mmeyepcmcia_handle *) pch;
    887   1.1       uch 
    888   1.1       uch 	if (window >= MMEYEPCMCIA_IOWINS)
    889   1.1       uch 		panic("mmeyepcmcia_chip_io_unmap: window out of range");
    890   1.1       uch 
    891   1.1       uch 	h->ioalloc &= ~(1 << window);
    892   1.1       uch }
    893   1.1       uch 
    894   1.1       uch void
    895   1.1       uch mmeyepcmcia_chip_socket_enable(pcmcia_chipset_handle_t pch)
    896   1.1       uch {
    897   1.1       uch }
    898   1.1       uch 
    899   1.1       uch void
    900   1.1       uch mmeyepcmcia_chip_socket_disable(pcmcia_chipset_handle_t pch)
    901   1.1       uch {
    902   1.1       uch }
    903