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