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