Home | History | Annotate | Line # | Download | only in pci
pccbb.c revision 1.21
      1  1.21      haya /*	$NetBSD: pccbb.c,v 1.21 2000/01/26 09:02:41 haya Exp $	*/
      2   1.2      haya 
      3   1.1      haya /*
      4  1.21      haya  * Copyright (c) 1998, 1999 and 2000
      5  1.21      haya  *      HAYAKAWA Koichi.  All rights reserved.
      6   1.1      haya  *
      7   1.1      haya  * Redistribution and use in source and binary forms, with or without
      8   1.1      haya  * modification, are permitted provided that the following conditions
      9   1.1      haya  * are met:
     10   1.1      haya  * 1. Redistributions of source code must retain the above copyright
     11   1.1      haya  *    notice, this list of conditions and the following disclaimer.
     12   1.1      haya  * 2. Redistributions in binary form must reproduce the above copyright
     13   1.1      haya  *    notice, this list of conditions and the following disclaimer in the
     14   1.1      haya  *    documentation and/or other materials provided with the distribution.
     15   1.1      haya  * 3. All advertising materials mentioning features or use of this software
     16   1.1      haya  *    must display the following acknowledgement:
     17   1.1      haya  *	This product includes software developed by HAYAKAWA Koichi.
     18   1.1      haya  * 4. The name of the author may not be used to endorse or promote products
     19   1.1      haya  *    derived from this software without specific prior written permission.
     20   1.1      haya  *
     21   1.1      haya  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     22   1.1      haya  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     23   1.1      haya  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     24   1.1      haya  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     25   1.1      haya  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     26   1.1      haya  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27   1.1      haya  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28   1.1      haya  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29   1.1      haya  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     30   1.1      haya  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31   1.1      haya  */
     32   1.1      haya 
     33   1.1      haya /*
     34   1.1      haya #define CBB_DEBUG
     35   1.1      haya #define SHOW_REGS
     36   1.1      haya #define PCCBB_PCMCIA_POLL
     37   1.1      haya */
     38  1.16   mycroft /* #define CBB_DEBUG */
     39   1.1      haya 
     40   1.1      haya /*
     41   1.1      haya #define CB_PCMCIA_POLL
     42   1.1      haya #define CB_PCMCIA_POLL_ONLY
     43   1.1      haya #define LEVEL2
     44   1.1      haya */
     45   1.1      haya 
     46   1.1      haya #include <sys/types.h>
     47   1.1      haya #include <sys/param.h>
     48   1.1      haya #include <sys/systm.h>
     49   1.1      haya #include <sys/kernel.h>
     50   1.1      haya #include <sys/errno.h>
     51   1.1      haya #include <sys/ioctl.h>
     52   1.1      haya #include <sys/syslog.h>
     53   1.1      haya #include <sys/device.h>
     54   1.1      haya #include <sys/malloc.h>
     55   1.1      haya 
     56   1.1      haya #include <machine/intr.h>
     57   1.1      haya #include <machine/bus.h>
     58   1.1      haya 
     59   1.1      haya #include <dev/pci/pcivar.h>
     60   1.1      haya #include <dev/pci/pcireg.h>
     61   1.1      haya #include <dev/pci/pcidevs.h>
     62   1.1      haya 
     63   1.1      haya #include <dev/pci/pccbbreg.h>
     64   1.1      haya 
     65   1.1      haya #include <dev/cardbus/cardslotvar.h>
     66   1.1      haya 
     67   1.1      haya #include <dev/cardbus/cardbusvar.h>
     68   1.1      haya 
     69   1.1      haya #include <dev/pcmcia/pcmciareg.h>
     70   1.1      haya #include <dev/pcmcia/pcmciavar.h>
     71   1.1      haya 
     72   1.1      haya #include <dev/ic/i82365reg.h>
     73   1.1      haya #include <dev/ic/i82365var.h>
     74   1.1      haya #include <dev/pci/pccbbvar.h>
     75   1.1      haya 
     76   1.1      haya #include "locators.h"
     77   1.1      haya 
     78   1.1      haya 
     79   1.1      haya #ifndef __NetBSD_Version__
     80   1.1      haya struct cfdriver cbb_cd = {
     81   1.1      haya   NULL, "cbb", DV_DULL
     82   1.1      haya };
     83   1.1      haya #endif
     84   1.1      haya 
     85   1.1      haya #if defined CBB_DEBUG
     86   1.1      haya #define DPRINTF(x) printf x
     87   1.1      haya #define STATIC
     88   1.1      haya #else
     89   1.1      haya #define DPRINTF(x)
     90   1.1      haya #define STATIC static
     91   1.1      haya #endif
     92   1.1      haya 
     93   1.1      haya 
     94   1.1      haya #ifdef __BROKEN_INDIRECT_CONFIG
     95   1.1      haya int pcicbbmatch __P((struct device *, void *, void *));
     96   1.1      haya #else
     97   1.1      haya int pcicbbmatch __P((struct device *, struct cfdata *, void *));
     98   1.1      haya #endif
     99   1.1      haya void pccbbattach __P((struct device *, struct device *, void *));
    100   1.1      haya int pccbbintr __P((void *));
    101   1.1      haya static void pci113x_insert __P((void *));
    102  1.21      haya static int pccbbintr_function __P((struct pccbb_softc *));
    103   1.1      haya 
    104   1.1      haya static int pccbb_detect_card __P((struct pccbb_softc *));
    105   1.1      haya 
    106   1.1      haya static void pccbb_pcmcia_write __P((struct pcic_handle *, int, u_int8_t));
    107   1.1      haya static u_int8_t pccbb_pcmcia_read __P((struct pcic_handle *, int));
    108   1.1      haya #define Pcic_read(ph, reg) ((ph)->ph_read((ph), (reg)))
    109   1.1      haya #define Pcic_write(ph, reg, val) ((ph)->ph_write((ph), (reg), (val)))
    110   1.1      haya 
    111   1.1      haya 
    112   1.1      haya STATIC int cb_reset __P((struct pccbb_softc *));
    113   1.1      haya STATIC int cb_detect_voltage __P((struct pccbb_softc *));
    114   1.1      haya STATIC int cbbprint __P((void *, const char *));
    115   1.1      haya 
    116  1.20      joda static int cb_chipset __P((u_int32_t, int *));
    117   1.1      haya STATIC void pccbb_pcmcia_attach_setup __P((struct pccbb_softc *, struct pcmciabus_attach_args *));
    118   1.1      haya #if 0
    119   1.1      haya STATIC void pccbb_pcmcia_attach_card __P((struct pcic_handle *));
    120   1.1      haya STATIC void pccbb_pcmcia_detach_card __P((struct pcic_handle *, int));
    121   1.1      haya STATIC void pccbb_pcmcia_deactivate_card __P((struct pcic_handle *));
    122   1.1      haya #endif
    123   1.1      haya 
    124   1.1      haya STATIC int pccbb_ctrl __P((cardbus_chipset_tag_t, int));
    125   1.1      haya STATIC int pccbb_power __P((cardbus_chipset_tag_t, int));
    126   1.1      haya STATIC int pccbb_cardenable __P((struct pccbb_softc *sc, int function));
    127   1.1      haya #if !rbus
    128   1.1      haya static int pccbb_io_open __P((cardbus_chipset_tag_t, int, u_int32_t, u_int32_t));
    129   1.1      haya static int pccbb_io_close __P((cardbus_chipset_tag_t, int));
    130   1.1      haya static int pccbb_mem_open __P((cardbus_chipset_tag_t, int, u_int32_t, u_int32_t));
    131   1.1      haya static int pccbb_mem_close __P((cardbus_chipset_tag_t, int));
    132   1.1      haya #endif /* !rbus */
    133   1.1      haya static void *pccbb_intr_establish __P((cardbus_chipset_tag_t, int irq, int level, int (* ih)(void *), void *sc));
    134   1.1      haya static void pccbb_intr_disestablish __P((cardbus_chipset_tag_t ct, void *ih));
    135   1.1      haya 
    136   1.1      haya static cardbustag_t pccbb_make_tag __P((cardbus_chipset_tag_t, int, int, int));
    137   1.1      haya static void pccbb_free_tag __P((cardbus_chipset_tag_t, cardbustag_t));
    138   1.1      haya static cardbusreg_t pccbb_conf_read __P((cardbus_chipset_tag_t, cardbustag_t, int));
    139   1.1      haya static void pccbb_conf_write __P((cardbus_chipset_tag_t, cardbustag_t, int, cardbusreg_t));
    140   1.1      haya static void pccbb_chipinit __P((struct pccbb_softc *));
    141   1.1      haya 
    142   1.1      haya 
    143   1.1      haya STATIC int pccbb_pcmcia_mem_alloc __P((pcmcia_chipset_handle_t, bus_size_t,
    144   1.1      haya 				       struct pcmcia_mem_handle *));
    145   1.1      haya STATIC void pccbb_pcmcia_mem_free __P((pcmcia_chipset_handle_t,
    146   1.1      haya 	    struct pcmcia_mem_handle *));
    147   1.1      haya STATIC int pccbb_pcmcia_mem_map __P((pcmcia_chipset_handle_t, int, bus_addr_t,
    148   1.1      haya             bus_size_t, struct pcmcia_mem_handle *, bus_addr_t *, int *));
    149   1.1      haya STATIC void pccbb_pcmcia_mem_unmap __P((pcmcia_chipset_handle_t, int));
    150   1.1      haya STATIC int pccbb_pcmcia_io_alloc __P((pcmcia_chipset_handle_t, bus_addr_t,
    151   1.1      haya 	    bus_size_t, bus_size_t, struct pcmcia_io_handle *));
    152   1.1      haya STATIC void pccbb_pcmcia_io_free __P((pcmcia_chipset_handle_t,
    153   1.1      haya 	    struct pcmcia_io_handle *));
    154   1.1      haya STATIC int pccbb_pcmcia_io_map __P((pcmcia_chipset_handle_t, int, bus_addr_t,
    155   1.1      haya 	    bus_size_t, struct pcmcia_io_handle *, int *));
    156   1.1      haya STATIC void pccbb_pcmcia_io_unmap __P((pcmcia_chipset_handle_t, int));
    157   1.1      haya STATIC void *pccbb_pcmcia_intr_establish __P((pcmcia_chipset_handle_t,
    158   1.1      haya 	    struct pcmcia_function *, int, int (*) (void *), void *));
    159   1.1      haya STATIC void pccbb_pcmcia_intr_disestablish __P((pcmcia_chipset_handle_t, void *));
    160   1.1      haya STATIC void pccbb_pcmcia_socket_enable __P((pcmcia_chipset_handle_t));
    161   1.1      haya STATIC void pccbb_pcmcia_socket_disable __P((pcmcia_chipset_handle_t));
    162   1.1      haya STATIC int pccbb_pcmcia_card_detect __P((pcmcia_chipset_handle_t pch));
    163   1.1      haya 
    164   1.1      haya static void pccbb_pcmcia_do_io_map __P((struct pcic_handle *, int));
    165   1.1      haya static void pccbb_pcmcia_wait_ready __P((struct pcic_handle *));
    166   1.1      haya static void pccbb_pcmcia_do_mem_map __P((struct pcic_handle *, int));
    167   1.1      haya 
    168   1.1      haya /* bus-space allocation and disallocation functions */
    169   1.1      haya #if rbus
    170   1.1      haya 
    171   1.1      haya static int pccbb_rbus_cb_space_alloc __P((cardbus_chipset_tag_t, rbus_tag_t,
    172   1.1      haya 					  bus_addr_t addr, bus_size_t size,
    173   1.1      haya 					  bus_addr_t mask, bus_size_t align,
    174   1.1      haya 					  int flags, bus_addr_t *addrp,
    175   1.1      haya 					  bus_space_handle_t *bshp));
    176   1.1      haya static int pccbb_rbus_cb_space_free __P((cardbus_chipset_tag_t, rbus_tag_t,
    177   1.1      haya 					 bus_space_handle_t, bus_size_t));
    178   1.1      haya 
    179   1.1      haya #endif /* rbus */
    180   1.1      haya 
    181   1.1      haya #if rbus
    182   1.1      haya 
    183   1.1      haya static int pccbb_open_win __P((struct pccbb_softc *, bus_space_tag_t, bus_addr_t, bus_size_t, bus_space_handle_t, int flags));
    184   1.1      haya static int pccbb_close_win __P((struct pccbb_softc *, bus_space_tag_t, bus_space_handle_t, bus_size_t));
    185   1.1      haya static int pccbb_winlist_insert __P((struct pccbb_win_chain **, bus_addr_t,
    186   1.1      haya 				     bus_size_t, bus_space_handle_t, int));
    187   1.1      haya static int pccbb_winlist_delete __P((struct pccbb_win_chain **,
    188   1.1      haya 				     bus_space_handle_t, bus_size_t));
    189   1.1      haya static void pccbb_winset __P((bus_addr_t align, struct pccbb_softc *,
    190   1.1      haya 			      bus_space_tag_t));
    191   1.1      haya void pccbb_winlist_show(struct pccbb_win_chain *);
    192   1.1      haya 
    193   1.1      haya #endif /* rbus */
    194   1.1      haya 
    195   1.1      haya /* for config_defer */
    196   1.1      haya static void pccbb_pci_callback __P((struct device *));
    197   1.1      haya 
    198   1.1      haya 
    199   1.1      haya #if defined SHOW_REGS
    200   1.1      haya static void cb_show_regs __P((pci_chipset_tag_t pc, pcitag_t tag, bus_space_tag_t memt, bus_space_handle_t memh));
    201   1.1      haya #endif
    202   1.1      haya 
    203   1.1      haya 
    204   1.1      haya 
    205   1.1      haya struct cfattach cbb_pci_ca = {
    206   1.1      haya 	sizeof(struct pccbb_softc), pcicbbmatch, pccbbattach
    207   1.1      haya };
    208   1.1      haya 
    209   1.1      haya 
    210   1.1      haya static struct pcmcia_chip_functions pccbb_pcmcia_funcs = {
    211   1.1      haya   pccbb_pcmcia_mem_alloc,
    212   1.1      haya   pccbb_pcmcia_mem_free,
    213   1.1      haya   pccbb_pcmcia_mem_map,
    214   1.1      haya   pccbb_pcmcia_mem_unmap,
    215   1.1      haya   pccbb_pcmcia_io_alloc,
    216   1.1      haya   pccbb_pcmcia_io_free,
    217   1.1      haya   pccbb_pcmcia_io_map,
    218   1.1      haya   pccbb_pcmcia_io_unmap,
    219   1.1      haya   pccbb_pcmcia_intr_establish,
    220   1.1      haya   pccbb_pcmcia_intr_disestablish,
    221   1.1      haya   pccbb_pcmcia_socket_enable,
    222   1.1      haya   pccbb_pcmcia_socket_disable,
    223   1.1      haya   pccbb_pcmcia_card_detect
    224   1.1      haya };
    225   1.1      haya 
    226   1.1      haya #if rbus
    227   1.1      haya static struct cardbus_functions pccbb_funcs = {
    228   1.1      haya   pccbb_rbus_cb_space_alloc,
    229   1.1      haya   pccbb_rbus_cb_space_free,
    230   1.1      haya   pccbb_intr_establish,
    231   1.1      haya   pccbb_intr_disestablish,
    232   1.1      haya   pccbb_ctrl,
    233   1.1      haya   pccbb_power,
    234   1.1      haya   pccbb_make_tag,
    235   1.1      haya   pccbb_free_tag,
    236   1.1      haya   pccbb_conf_read,
    237   1.1      haya   pccbb_conf_write,
    238   1.1      haya };
    239   1.1      haya #else
    240   1.1      haya static struct cardbus_functions pccbb_funcs = {
    241   1.1      haya   pccbb_ctrl,
    242   1.1      haya   pccbb_power,
    243   1.1      haya   pccbb_mem_open,
    244   1.1      haya   pccbb_mem_close,
    245   1.1      haya   pccbb_io_open,
    246   1.1      haya   pccbb_io_close,
    247   1.1      haya   pccbb_intr_establish,
    248   1.1      haya   pccbb_intr_disestablish,
    249   1.1      haya   pccbb_make_tag,
    250   1.1      haya   pccbb_conf_read,
    251   1.1      haya   pccbb_conf_write,
    252   1.1      haya };
    253   1.1      haya #endif
    254   1.1      haya 
    255   1.1      haya 
    256   1.1      haya 
    257   1.1      haya 
    258   1.1      haya int
    259   1.1      haya pcicbbmatch(parent, match, aux)
    260   1.1      haya      struct device *parent;
    261   1.1      haya #ifdef __BROKEN_INDIRECT_CONFIG
    262   1.1      haya      void *match;
    263   1.1      haya #else
    264   1.1      haya      struct cfdata *match;
    265   1.1      haya #endif
    266   1.1      haya      void *aux;
    267   1.1      haya {
    268  1.11      joda     struct pci_attach_args *pa = (struct pci_attach_args *)aux;
    269   1.1      haya 
    270  1.11      joda     if(PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
    271  1.11      joda        PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_CARDBUS &&
    272  1.11      joda        PCI_INTERFACE(pa->pa_class) == 0) {
    273  1.11      joda 	return 1;
    274  1.11      joda     }
    275   1.1      haya 
    276  1.11      joda     return 0;
    277   1.1      haya }
    278   1.1      haya 
    279   1.1      haya 
    280   1.1      haya #define MAKEID(vendor, prod) (((vendor) << PCI_VENDOR_SHIFT) \
    281   1.1      haya                               | ((prod) << PCI_PRODUCT_SHIFT))
    282   1.1      haya 
    283   1.1      haya 
    284   1.1      haya struct yenta_chipinfo {
    285   1.1      haya   pcireg_t yc_id;		/* vendor tag | product tag */
    286   1.1      haya   int yc_chiptype;
    287   1.1      haya   int yc_flags;
    288   1.1      haya } yc_chipsets[] = {
    289   1.1      haya   /* Texas Instruments chips */
    290  1.20      joda   {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1130), CB_TI113X,
    291   1.1      haya      PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
    292  1.20      joda   {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1131), CB_TI113X,
    293   1.1      haya      PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
    294   1.1      haya 
    295  1.20      joda   {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1250), CB_TI12XX,
    296   1.1      haya      PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
    297  1.20      joda   {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1220), CB_TI12XX,
    298   1.1      haya      PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
    299  1.20      joda   {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1221), CB_TI12XX,
    300   1.1      haya      PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
    301  1.20      joda   {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1225), CB_TI12XX,
    302   1.1      haya      PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
    303  1.20      joda   {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1251), CB_TI12XX,
    304   1.1      haya      PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
    305  1.20      joda   {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1251B), CB_TI12XX,
    306   1.1      haya      PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
    307  1.20      joda   {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1211), CB_TI12XX,
    308   1.1      haya      PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
    309  1.20      joda   {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1420), CB_TI12XX,
    310   1.1      haya      PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
    311  1.20      joda   {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1450), CB_TI12XX,
    312   1.1      haya      PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
    313  1.20      joda   {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1451), CB_TI12XX,
    314  1.19      haya      PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
    315   1.1      haya 
    316   1.1      haya   /* Ricoh chips */
    317  1.20      joda   {MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_Rx5C475), CB_RX5C47X,
    318  1.20      joda    PCCBB_PCMCIA_MEM_32},
    319  1.20      joda   {MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_RL5C476), CB_RX5C47X,
    320  1.20      joda    PCCBB_PCMCIA_MEM_32},
    321  1.20      joda   {MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_Rx5C477), CB_RX5C47X,
    322  1.20      joda    PCCBB_PCMCIA_MEM_32},
    323  1.20      joda   {MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_Rx5C478), CB_RX5C47X,
    324  1.20      joda    PCCBB_PCMCIA_MEM_32},
    325  1.20      joda 
    326  1.20      joda   {MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_Rx5C465), CB_RX5C46X,
    327  1.20      joda    PCCBB_PCMCIA_MEM_32},
    328  1.20      joda   {MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_Rx5C466), CB_RX5C46X,
    329  1.20      joda    PCCBB_PCMCIA_MEM_32},
    330   1.1      haya 
    331   1.1      haya   /* Toshiba products */
    332  1.20      joda   {MAKEID(PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_ToPIC95), CB_TOPIC95,
    333  1.20      joda    PCCBB_PCMCIA_MEM_32},
    334  1.20      joda   {MAKEID(PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_ToPIC95B), CB_TOPIC95B,
    335  1.20      joda    PCCBB_PCMCIA_MEM_32},
    336  1.20      joda   {MAKEID(PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_ToPIC97), CB_TOPIC97,
    337  1.20      joda    PCCBB_PCMCIA_MEM_32},
    338  1.20      joda   {MAKEID(PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_ToPIC100), CB_TOPIC97,
    339  1.20      joda    PCCBB_PCMCIA_MEM_32},
    340   1.1      haya 
    341   1.1      haya   /* Cirrus Logic products */
    342  1.20      joda   {MAKEID(PCI_VENDOR_CIRRUS, PCI_PRODUCT_CIRRUS_CL_PD6832), CB_CIRRUS,
    343  1.20      joda    PCCBB_PCMCIA_MEM_32},
    344  1.20      joda   {MAKEID(PCI_VENDOR_CIRRUS, PCI_PRODUCT_CIRRUS_CL_PD6833), CB_CIRRUS,
    345  1.20      joda    PCCBB_PCMCIA_MEM_32},
    346   1.1      haya 
    347   1.1      haya   /* sentinel, or Generic chip */
    348  1.20      joda   {0 /* null id */,  CB_UNKNOWN, PCCBB_PCMCIA_MEM_32},
    349   1.1      haya };
    350   1.1      haya 
    351   1.1      haya 
    352   1.1      haya 
    353   1.1      haya static int
    354  1.20      joda cb_chipset(pci_id, flagp)
    355   1.1      haya      u_int32_t pci_id;
    356   1.1      haya      int *flagp;
    357   1.1      haya {
    358   1.1      haya   int loopend = sizeof(yc_chipsets)/sizeof(yc_chipsets[0]);
    359   1.1      haya   struct yenta_chipinfo *ycp, *ycend;
    360   1.1      haya 
    361   1.1      haya   ycend = yc_chipsets + loopend;
    362   1.1      haya 
    363   1.1      haya   for (ycp =yc_chipsets; ycp < ycend && pci_id != ycp->yc_id; ++ycp);
    364   1.1      haya 
    365   1.1      haya   if (ycp == ycend) {
    366   1.1      haya     /* not found */
    367   1.1      haya     ycp = yc_chipsets + loopend - 1; /* to point the sentinel */
    368   1.1      haya   }
    369   1.1      haya 
    370   1.1      haya   if (flagp != NULL) {
    371   1.1      haya     *flagp = ycp->yc_flags;
    372   1.1      haya   }
    373   1.1      haya 
    374   1.1      haya   return ycp->yc_chiptype;
    375   1.1      haya }
    376   1.1      haya 
    377   1.1      haya 
    378   1.1      haya 
    379  1.14      joda static void
    380  1.14      joda pccbb_shutdown(void *arg)
    381  1.14      joda {
    382  1.14      joda     struct pccbb_softc *sc = arg;
    383  1.14      joda     pcireg_t command;
    384   1.1      haya 
    385  1.14      joda     DPRINTF(("%s: shutdown\n", sc->sc_dev.dv_xname));
    386  1.14      joda     bus_space_write_4(sc->sc_base_memt, sc->sc_base_memh, CB_SOCKET_MASK, 0);
    387  1.14      joda 
    388  1.14      joda     command = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG);
    389  1.14      joda 
    390  1.14      joda     command &= ~(PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
    391  1.14      joda 		 PCI_COMMAND_MASTER_ENABLE);
    392  1.14      joda     pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG, command);
    393  1.14      joda 
    394  1.14      joda }
    395   1.1      haya 
    396   1.1      haya void
    397   1.1      haya pccbbattach(parent, self, aux)
    398   1.1      haya      struct device *parent;
    399   1.1      haya      struct device *self;
    400   1.1      haya      void *aux;
    401   1.1      haya {
    402   1.1      haya   struct pccbb_softc *sc = (void *)self;
    403   1.1      haya   struct pci_attach_args *pa = aux;
    404   1.1      haya   pci_chipset_tag_t pc = pa->pa_pc;
    405   1.4      haya   pcireg_t sock_base, busreg;
    406   1.1      haya   bus_addr_t sockbase;
    407  1.20      joda   char devinfo[256];
    408   1.1      haya   int flags;
    409   1.1      haya 
    410  1.20      joda   sc->sc_chipset = cb_chipset(pa->pa_id, &flags);
    411  1.20      joda 
    412  1.20      joda   pci_devinfo(pa->pa_id, 0, 0, devinfo);
    413  1.20      joda   printf(": %s (rev. 0x%02x)", devinfo, PCI_REVISION(pa->pa_class));
    414  1.20      joda #ifdef CBB_DEBUG
    415  1.20      joda   printf(" (chipflags %x)", flags);
    416  1.20      joda #endif
    417  1.20      joda   printf("\n");
    418   1.1      haya 
    419   1.1      haya #if rbus
    420   1.1      haya   sc->sc_rbus_iot = rbus_pccbb_parent_io(pa);
    421   1.1      haya   sc->sc_rbus_memt = rbus_pccbb_parent_mem(pa);
    422   1.1      haya #endif /* rbus */
    423   1.1      haya 
    424   1.1      haya   sc->sc_base_memh = 0;
    425   1.1      haya 
    426   1.4      haya   /*
    427   1.4      haya    * MAP socket registers and ExCA registers on memory-space
    428   1.4      haya    * When no valid address is set on socket base registers (on pci
    429   1.4      haya    * config space), get it not polite way.
    430   1.4      haya    */
    431   1.1      haya   sock_base = pci_conf_read(pc, pa->pa_tag, PCI_SOCKBASE);
    432   1.1      haya 
    433   1.1      haya   if (PCI_MAPREG_MEM_ADDR(sock_base) >= 0x100000 &&
    434   1.1      haya       PCI_MAPREG_MEM_ADDR(sock_base) != 0xfffffff0) {
    435   1.1      haya     /* The address must be valid. */
    436   1.1      haya     if (pci_mapreg_map(pa, PCI_SOCKBASE, PCI_MAPREG_TYPE_MEM, 0,
    437   1.1      haya 		       &sc->sc_base_memt, &sc->sc_base_memh, &sockbase,
    438   1.1      haya 		       NULL)) {
    439   1.1      haya       printf("%s: can't map socket base address 0x%x\n", sc->sc_dev.dv_xname,
    440   1.1      haya 	     sock_base);
    441   1.1      haya       /* I think it's funny: socket base registers must be mapped on
    442   1.1      haya 	 memory space, but ... */
    443   1.1      haya       if (pci_mapreg_map(pa, PCI_SOCKBASE, PCI_MAPREG_TYPE_IO, 0,
    444   1.1      haya 			 &sc->sc_base_memt, &sc->sc_base_memh,
    445   1.1      haya 			 &sockbase, NULL)) {
    446   1.1      haya 	printf("%s: can't map socket base address 0x%lx: io mode\n",
    447   1.1      haya 	       sc->sc_dev.dv_xname, sockbase);
    448   1.5      haya 	/* give up... allocate register space via rbus. */
    449   1.5      haya 	sc->sc_base_memh = 0;
    450   1.5      haya 	pci_conf_write(pc, pa->pa_tag, PCI_SOCKBASE, 0);
    451   1.1      haya       }
    452   1.1      haya     } else {
    453  1.11      joda       DPRINTF(("%s: socket base address 0x%lx\n",
    454  1.11      joda 	       sc->sc_dev.dv_xname, sockbase));
    455   1.1      haya     }
    456   1.1      haya   }
    457   1.1      haya 
    458   1.1      haya 
    459   1.1      haya   sc->sc_mem_start = 0;		/* XXX */
    460   1.1      haya   sc->sc_mem_end = 0xffffffff;	/* XXX */
    461   1.1      haya 
    462   1.4      haya   /*
    463   1.4      haya    * When interrupt isn't routed correctly, give up probing cbb and do
    464   1.4      haya    * not kill pcic-compatible port.
    465   1.4      haya    */
    466   1.1      haya   if ((0 == pa->pa_intrline) || (255 == pa->pa_intrline)) {
    467   1.4      haya     printf(" Do not use %s because of intr unconfig.\n", sc->sc_dev.dv_xname);
    468   1.4      haya     return;
    469   1.1      haya   }
    470   1.1      haya 
    471   1.4      haya   /*
    472   1.4      haya    * When bus number isn't set correctly, give up using 32-bit CardBus
    473   1.4      haya    * mode.
    474   1.4      haya    */
    475   1.4      haya   busreg = pci_conf_read(pc, pa->pa_tag, PCI_BUSNUM);
    476   1.4      haya #if notyet
    477   1.4      haya   if (((busreg >> 8) & 0xff) == 0) {
    478   1.4      haya     printf(" CardBus on %s will not be configured, because of bus no unconfig.\n", sc->sc_dev.dv_xname);
    479   1.4      haya     flags |= PCCBB_PCMCIA_16BITONLY;
    480   1.4      haya   }
    481   1.4      haya #endif
    482   1.4      haya 
    483   1.1      haya   /* pccbb_machdep.c end */
    484   1.1      haya 
    485   1.1      haya 
    486   1.1      haya #if defined CBB_DEBUG
    487   1.1      haya   {
    488   1.1      haya     static char *intrname[5] = {"NON", "A", "B", "C", "D"};
    489   1.1      haya     printf(" intrpin %s, intrtag %d\n", intrname[pa->pa_intrpin],
    490   1.1      haya 	     pa->pa_intrline);
    491   1.1      haya   }
    492   1.1      haya #endif
    493   1.1      haya 
    494   1.1      haya 
    495   1.4      haya   /* setup softc */
    496   1.1      haya   sc->sc_pc = pc;
    497   1.1      haya   sc->sc_iot = pa->pa_iot;
    498   1.1      haya   sc->sc_memt = pa->pa_memt;
    499   1.1      haya   sc->sc_dmat = pa->pa_dmat;
    500   1.1      haya   sc->sc_tag = pa->pa_tag;
    501   1.1      haya   sc->sc_function = pa->pa_function;
    502   1.1      haya 
    503   1.1      haya   sc->sc_intrline = pa->pa_intrline;
    504   1.1      haya   sc->sc_intrtag = pa->pa_intrtag;
    505   1.1      haya   sc->sc_intrpin = pa->pa_intrpin;
    506   1.1      haya 
    507   1.1      haya   sc->sc_pcmcia_flags = flags;	/* set PCMCIA facility */
    508   1.1      haya 
    509  1.14      joda   shutdownhook_establish(pccbb_shutdown, sc);
    510   1.4      haya 
    511   1.1      haya #if __NetBSD_Version__ > 103060000
    512   1.1      haya   config_defer(self, pccbb_pci_callback);
    513   1.1      haya #else
    514   1.1      haya   pccbb_pci_callback(self);
    515   1.1      haya #endif
    516   1.1      haya }
    517   1.1      haya 
    518   1.1      haya 
    519   1.1      haya 
    520   1.1      haya 
    521   1.1      haya static void
    522   1.1      haya pccbb_pci_callback(self)
    523   1.1      haya      struct device *self;
    524   1.1      haya {
    525   1.1      haya   struct pccbb_softc *sc = (void *)self;
    526   1.1      haya   pci_chipset_tag_t pc = sc->sc_pc;
    527   1.1      haya   bus_space_tag_t base_memt;
    528   1.1      haya   bus_space_handle_t base_memh;
    529   1.1      haya   u_int32_t maskreg;
    530   1.1      haya   pci_intr_handle_t ih;
    531   1.1      haya   const char *intrstr = NULL;
    532   1.1      haya   bus_addr_t sockbase;
    533   1.1      haya   struct cbslot_attach_args cba;
    534   1.1      haya   struct pcmciabus_attach_args paa;
    535   1.1      haya   struct cardslot_attach_args caa;
    536   1.1      haya   struct cardslot_softc *csc;
    537   1.1      haya 
    538   1.1      haya   if (0 == sc->sc_base_memh) {
    539   1.1      haya     /* The socket registers aren't mapped correctly. */
    540   1.1      haya #if rbus
    541   1.1      haya     if (rbus_space_alloc(sc->sc_rbus_memt,
    542   1.1      haya 			 0, /* address: I don't mind where it is mapped */
    543   1.1      haya 			 0x1000, /* size */
    544   1.1      haya 			 0x0fff, /* mask */
    545   1.9      haya 			 (sc->sc_chipset == CB_RX5C47X || sc->sc_chipset == CB_TI113X) ? 0x10000 : 0x1000, /* align */
    546   1.1      haya 			 0, /* flags */
    547   1.1      haya 			 &sockbase, &sc->sc_base_memh)) {
    548   1.1      haya       return;
    549   1.1      haya     }
    550   1.1      haya     sc->sc_base_memt = sc->sc_memt;
    551   1.1      haya     pci_conf_write(pc, sc->sc_tag, PCI_SOCKBASE, sockbase);
    552   1.1      haya     DPRINTF(("%s: CardBus resister address 0x%lx -> 0x%x\n",
    553   1.1      haya 	     sc->sc_dev.dv_xname, sockbase, pci_conf_read(pc, sc->sc_tag, PCI_SOCKBASE)));
    554   1.1      haya #else
    555   1.1      haya     sc->sc_base_memt = sc->sc_memt;
    556   1.1      haya #if !defined CBB_PCI_BASE
    557   1.1      haya #define CBB_PCI_BASE 0x20000000
    558   1.1      haya #endif
    559   1.1      haya     if (bus_space_alloc(sc->sc_base_memt, CBB_PCI_BASE, 0xffffffff,
    560   1.1      haya 			0x1000, /* size */
    561   1.1      haya 			0x1000, /* alignment */
    562   1.1      haya 			0,      /* boundary */
    563   1.1      haya 			0,      /* flags */
    564   1.1      haya 			&sockbase, &sc->sc_base_memh)) {
    565   1.1      haya       /* cannot allocate memory space */
    566   1.1      haya       return;
    567   1.1      haya     }
    568   1.1      haya     pci_conf_write(pc, sc->sc_tag, PCI_SOCKBASE, sockbase);
    569   1.1      haya     DPRINTF(("%s: CardBus resister address 0x%x -> 0x%x\n",sc->sc_dev.dv_xname,
    570   1.1      haya 	     sock_base, pci_conf_read(pc, sc->sc_tag, PCI_SOCKBASE)));
    571   1.1      haya #endif
    572   1.1      haya   }
    573  1.19      haya 
    574  1.19      haya   /* bus bridge initialisation */
    575  1.19      haya   pccbb_chipinit(sc);
    576   1.1      haya 
    577   1.1      haya   base_memt = sc->sc_base_memt;	/* socket regs memory tag */
    578   1.1      haya   base_memh = sc->sc_base_memh;	/* socket regs memory handle */
    579   1.1      haya 
    580   1.1      haya 
    581   1.1      haya   /* CSC Interrupt: Card detect interrupt on */
    582   1.1      haya   maskreg = bus_space_read_4(base_memt, base_memh, CB_SOCKET_MASK);
    583   1.1      haya   maskreg |= CB_SOCKET_MASK_CD;	/* Card detect intr is turned on. */
    584   1.1      haya   bus_space_write_4(base_memt, base_memh, CB_SOCKET_MASK, maskreg);
    585   1.1      haya   /* reset interrupt */
    586   1.1      haya   bus_space_write_4(base_memt, base_memh, CB_SOCKET_EVENT,
    587   1.1      haya 		    bus_space_read_4(base_memt, base_memh, CB_SOCKET_EVENT));
    588   1.1      haya 
    589   1.1      haya 
    590   1.1      haya   /* Map and establish the interrupt. */
    591   1.1      haya   if (pci_intr_map(pc, sc->sc_intrtag, sc->sc_intrpin,
    592   1.1      haya 		   sc->sc_intrline, &ih)) {
    593   1.1      haya     printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
    594   1.1      haya     return;
    595   1.1      haya   }
    596   1.1      haya   intrstr = pci_intr_string(pc, ih);
    597   1.1      haya   sc->sc_ih = pci_intr_establish(pc, ih, IPL_BIO, pccbbintr, sc);
    598   1.1      haya 
    599   1.1      haya   if (sc->sc_ih == NULL) {
    600   1.1      haya     printf("%s: couldn't establish interrupt", sc->sc_dev.dv_xname);
    601   1.1      haya     if (intrstr != NULL) {
    602   1.1      haya       printf(" at %s", intrstr);
    603   1.1      haya     }
    604   1.1      haya     printf("\n");
    605   1.1      haya     return;
    606   1.1      haya   }
    607   1.1      haya 
    608   1.1      haya   printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
    609   1.1      haya 
    610   1.1      haya   {
    611   1.1      haya     u_int32_t sockstat = bus_space_read_4(base_memt,base_memh, CB_SOCKET_STAT);
    612   1.1      haya     if (0 == (sockstat & CB_SOCKET_STAT_CD)) { /* card exist */
    613   1.1      haya       sc->sc_flags |= CBB_CARDEXIST;
    614   1.1      haya     }
    615   1.1      haya   }
    616   1.1      haya 
    617   1.4      haya   /*
    618   1.4      haya    * attach cardbus
    619   1.4      haya    */
    620   1.4      haya   if (!(sc->sc_pcmcia_flags & PCCBB_PCMCIA_16BITONLY)) {
    621   1.1      haya     pcireg_t busreg = pci_conf_read(pc, sc->sc_tag, PCI_BUSNUM);
    622   1.1      haya     pcireg_t bhlc = pci_conf_read(pc, sc->sc_tag, PCI_BHLC_REG);
    623   1.1      haya 
    624   1.1      haya     /* initialise cbslot_attach */
    625   1.1      haya     cba.cba_busname = "cardbus";
    626   1.1      haya     cba.cba_iot = sc->sc_iot;
    627   1.1      haya     cba.cba_memt = sc->sc_memt;
    628   1.1      haya     cba.cba_dmat = sc->sc_dmat;
    629   1.1      haya     cba.cba_function = 0;
    630   1.1      haya     cba.cba_bus = (busreg >> 8) & 0x0ff;
    631   1.1      haya     cba.cba_cc = (void *)sc;
    632   1.1      haya     cba.cba_cf = &pccbb_funcs;
    633   1.1      haya     cba.cba_intrline = sc->sc_intrline;
    634   1.1      haya 
    635   1.1      haya #if rbus
    636   1.1      haya     cba.cba_rbus_iot = sc->sc_rbus_iot;
    637   1.1      haya     cba.cba_rbus_memt = sc->sc_rbus_memt;
    638   1.1      haya #endif
    639   1.1      haya 
    640   1.1      haya     cba.cba_cacheline = PCI_CACHELINE(bhlc);
    641   1.8      joda     cba.cba_lattimer = PCI_CB_LATENCY(busreg);
    642   1.1      haya 
    643   1.1      haya     printf("%s: cacheline 0x%x lattimer 0x%x\n", sc->sc_dev.dv_xname,
    644   1.1      haya 	   cba.cba_cacheline, cba.cba_lattimer);
    645   1.1      haya     printf("%s: bhlc 0x%x lscp 0x%x\n", sc->sc_dev.dv_xname,
    646   1.8      joda 	   bhlc, busreg);
    647   1.1      haya #if defined SHOW_REGS
    648   1.1      haya     cb_show_regs(sc->sc_pc, sc->sc_tag, sc->sc_base_memt, sc->sc_base_memh);
    649   1.1      haya #endif
    650   1.1      haya   }
    651   1.1      haya 
    652   1.1      haya   pccbb_pcmcia_attach_setup(sc, &paa);
    653   1.4      haya   caa.caa_cb_attach = NULL;
    654   1.4      haya   if (!(sc->sc_pcmcia_flags & PCCBB_PCMCIA_16BITONLY)) {
    655   1.4      haya     caa.caa_cb_attach = &cba;
    656   1.4      haya   }
    657   1.1      haya   caa.caa_16_attach = &paa;
    658   1.1      haya   caa.caa_ph = &sc->sc_pcmcia_h;
    659   1.1      haya 
    660   1.1      haya   if (NULL != (csc = (void *)config_found(self, &caa, cbbprint))) {
    661   1.1      haya     DPRINTF(("pccbbattach: found cardslot\n"));
    662   1.1      haya     sc->sc_csc = csc;
    663   1.1      haya   }
    664   1.1      haya 
    665   1.1      haya   return;
    666   1.1      haya }
    667   1.1      haya 
    668   1.1      haya 
    669   1.1      haya 
    670   1.1      haya static void
    671   1.1      haya pccbb_chipinit(sc)
    672   1.1      haya      struct pccbb_softc *sc;
    673   1.1      haya {
    674   1.1      haya   pci_chipset_tag_t pc = sc->sc_pc;
    675   1.1      haya   pcitag_t tag = sc->sc_tag;
    676   1.1      haya   bus_space_tag_t base_memt = sc->sc_base_memt;	/* socket regs memory tag */
    677   1.1      haya   bus_space_handle_t base_memh = sc->sc_base_memh; /* socket regs memory handle */
    678   1.1      haya   pcireg_t cbctrl;
    679   1.1      haya 
    680   1.1      haya   /*
    681   1.4      haya    * Set PCI command reg.
    682   1.4      haya    * Some laptop's BIOSes (i.e. TICO) do not enable CardBus chip.
    683   1.1      haya    */
    684   1.1      haya   {
    685   1.1      haya     pcireg_t command = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
    686   1.1      haya 
    687   1.1      haya     /* I believe it is harmless. */
    688   1.1      haya     command |= (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
    689   1.1      haya 		PCI_COMMAND_MASTER_ENABLE);
    690   1.1      haya     pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, command);
    691   1.1      haya   }
    692   1.1      haya 
    693   1.1      haya   /*
    694   1.4      haya    * Set CardBus latency timer
    695   1.1      haya    */
    696   1.1      haya   {
    697   1.1      haya     pcireg_t pci_lscp = pci_conf_read(pc, tag, PCI_CB_LSCP_REG);
    698   1.1      haya     if (PCI_CB_LATENCY(pci_lscp) < 0x20) {
    699   1.1      haya       pci_lscp &= ~(PCI_CB_LATENCY_MASK << PCI_CB_LATENCY_SHIFT);
    700   1.1      haya       pci_lscp |= (0x20 << PCI_CB_LATENCY_SHIFT);
    701   1.1      haya       pci_conf_write(pc, tag, PCI_CB_LSCP_REG, pci_lscp);
    702   1.1      haya     }
    703   1.3  augustss     DPRINTF(("CardBus latency timer 0x%x (%x)\n", PCI_CB_LATENCY(pci_lscp),
    704   1.3  augustss 	     pci_conf_read(pc, tag, PCI_CB_LSCP_REG)));
    705   1.1      haya   }
    706   1.1      haya 
    707   1.1      haya   /*
    708   1.4      haya    * Set PCI latency timer
    709   1.1      haya    */
    710   1.1      haya   {
    711   1.1      haya     pcireg_t pci_bhlc = pci_conf_read(pc, tag, PCI_BHLC_REG);
    712   1.1      haya     if (PCI_LATTIMER(pci_bhlc) < 0x10) {
    713   1.1      haya       pci_bhlc &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT);
    714   1.1      haya       pci_bhlc |= (0x10 << PCI_LATTIMER_SHIFT);
    715   1.1      haya       pci_conf_write(pc, tag, PCI_BHLC_REG, pci_bhlc);
    716   1.1      haya     }
    717   1.3  augustss     DPRINTF(("PCI latency timer 0x%x (%x)\n", PCI_LATTIMER(pci_bhlc),
    718   1.3  augustss 	     pci_conf_read(pc, tag, PCI_BHLC_REG)));
    719   1.1      haya   }
    720   1.1      haya 
    721   1.1      haya   /* disable Legacy IO */
    722   1.1      haya 
    723   1.1      haya   switch (sc->sc_chipset) {
    724   1.7      haya   case CB_RX5C46X:		/* fallthrogh */
    725   1.9      haya #if 0
    726   1.7      haya   case CB_RX5C47X:
    727   1.9      haya #endif
    728   1.4      haya     /*
    729   1.4      haya      * The legacy pcic io-port on Ricoh CardBus bridges cannot be
    730   1.4      haya      * disabled by substituting 0 into PCI_LEGACY register.  Ricoh
    731   1.4      haya      * CardBus bridges have special bits on Bridge control reg (addr
    732   1.4      haya      * 0x3e on PCI config space).
    733   1.4      haya      */
    734   1.1      haya     {
    735   1.1      haya       pcireg_t bcri = pci_conf_read(pc, tag, PCI_BCR_INTR);
    736   1.1      haya       bcri &= ~(CB_BCRI_RL_3E0_ENA | CB_BCRI_RL_3E2_ENA);
    737   1.1      haya       pci_conf_write(pc, tag, PCI_BCR_INTR, bcri);
    738   1.1      haya     }
    739   1.1      haya     break;
    740   1.1      haya   default:
    741   1.1      haya     /* XXX: I don't know proper way to kill Legacy IO properly. */
    742   1.1      haya     pci_conf_write(pc, tag, PCI_LEGACY, 0x0);
    743   1.1      haya     break;
    744   1.1      haya   }
    745   1.1      haya 
    746   1.1      haya 
    747   1.1      haya 
    748   1.4      haya   /*
    749   1.4      haya    * Interrupt routing: use PCI interrupt
    750   1.4      haya    */
    751   1.1      haya   {
    752   1.1      haya     u_int32_t bcr = pci_conf_read(pc, tag, PCI_BCR_INTR);
    753   1.1      haya     bcr &= ~CB_BCR_INTR_IREQ_ENABLE; /* use PCI Intr */
    754   1.1      haya     bcr |= CB_BCR_WRITE_POST_ENABLE; /* enable write post */
    755   1.1      haya     pci_conf_write(pc, tag, PCI_BCR_INTR, bcr);
    756   1.1      haya   }
    757   1.1      haya 
    758   1.1      haya   if (CB_TI113X == sc->sc_chipset) {
    759   1.1      haya     cbctrl = pci_conf_read(pc, tag, PCI_CBCTRL);
    760   1.1      haya     if (0 == sc->sc_function) {
    761   1.1      haya       cbctrl |= PCI113X_CBCTRL_PCI_IRQ_ENA;
    762   1.1      haya     }
    763   1.1      haya     cbctrl |= PCI113X_CBCTRL_PCI_IRQ_ENA;	/* XXX: bug in PCI113X */
    764   1.1      haya     cbctrl |= PCI113X_CBCTRL_PCI_CSC; /* CSC intr enable */
    765   1.1      haya     cbctrl &= ~PCI113X_CBCTRL_PCI_INTR; /* functional intr prohibit */
    766   1.1      haya     cbctrl &= ~PCI113X_CBCTRL_INT_MASK;	/* prohibit ISA routing */
    767   1.1      haya     pci_conf_write(pc, tag, PCI_CBCTRL, cbctrl);
    768   1.1      haya 
    769   1.1      haya     /* set ExCA regs: PCI113X required to be set bit 4 at Interrupt
    770   1.1      haya        and General Register, which is IRQ Enable Register, and clear
    771   1.1      haya        bit 3:0 to zero in order to route CSC interrupt to PCI
    772   1.1      haya        interrupt pin. */
    773   1.1      haya     bus_space_write_1(base_memt, base_memh, 0x0803, 0x10);
    774   1.1      haya     /* set ExCA regs: prohibit all pcmcia-style CSC intr. */
    775   1.1      haya     bus_space_write_1(base_memt, base_memh, 0x0805, 0x00);
    776   1.1      haya #if 1
    777   1.1      haya     DPRINTF(("ExCA regs:"));
    778   1.1      haya     DPRINTF((" 0x803: %02x", bus_space_read_1(base_memt, base_memh, 0x803)));
    779   1.1      haya     DPRINTF((" 0x805: %02x", bus_space_read_1(base_memt, base_memh, 0x805)));
    780   1.1      haya     DPRINTF((" 0x81e: %02x\n", bus_space_read_1(base_memt,base_memh,0x81e)));
    781   1.1      haya #endif
    782   1.1      haya   } else if (sc->sc_chipset == CB_TI12XX) {
    783   1.1      haya     cbctrl = pci_conf_read(pc, tag, PCI_CBCTRL);
    784   1.1      haya     cbctrl &= ~PCI12XX_CBCTRL_INT_MASK;	/* intr routing reset */
    785   1.1      haya     pci_conf_write(pc, tag, PCI_CBCTRL, cbctrl);
    786   1.4      haya     /*
    787   1.4      haya      * set ExCA regs: PCI12XX required to be set bit 4 at Interrupt
    788   1.4      haya      * and General Register, which is IRQ Enable Register, and clear
    789   1.4      haya      * bit 3:0 to zero in order to route CSC interrupt to PCI
    790   1.4      haya      * interrupt pin.
    791   1.4      haya      */
    792   1.1      haya     bus_space_write_1(base_memt, base_memh, 0x0803, 0x10);
    793   1.1      haya     /* set ExCA regs: prohibit all pcmcia-style CSC intr. */
    794   1.1      haya     bus_space_write_1(base_memt, base_memh, 0x0805, 0x00);
    795   1.1      haya   } else if (sc->sc_chipset == CB_TOPIC95B) {
    796   1.1      haya     cardbusreg_t sock_ctrl, slot_ctrl;
    797   1.1      haya 
    798   1.1      haya     sock_ctrl = pci_conf_read(pc, tag, TOPIC_SOCKET_CTRL);
    799   1.1      haya     pci_conf_write(pc, tag, TOPIC_SOCKET_CTRL,
    800   1.1      haya 		   sock_ctrl | TOPIC_SOCKET_CTRL_SCR_IRQSEL);
    801   1.1      haya 
    802   1.1      haya     slot_ctrl = pci_conf_read(pc, tag, TOPIC_SLOT_CTRL);
    803   1.1      haya     DPRINTF(("%s: topic slot ctrl reg 0x%x -> ", sc->sc_dev.dv_xname,
    804   1.1      haya 	     slot_ctrl));
    805   1.1      haya     slot_ctrl |= (TOPIC_SLOT_CTRL_SLOTON | TOPIC_SLOT_CTRL_SLOTEN |
    806   1.1      haya 		  TOPIC_SLOT_CTRL_ID_LOCK);
    807   1.1      haya     slot_ctrl |= TOPIC_SLOT_CTRL_CARDBUS;
    808   1.1      haya     slot_ctrl &= ~TOPIC_SLOT_CTRL_SWDETECT;
    809   1.1      haya     pci_conf_write(pc, tag, TOPIC_SLOT_CTRL, slot_ctrl);
    810   1.1      haya     DPRINTF(("0x%x\n", slot_ctrl));
    811   1.1      haya   }
    812   1.1      haya 
    813   1.1      haya   /* close all memory and io windows */
    814   1.1      haya   pci_conf_write(pc, tag, PCI_CB_MEMBASE0, 0xffffffff);
    815   1.1      haya   pci_conf_write(pc, tag, PCI_CB_MEMLIMIT0, 0);
    816   1.1      haya   pci_conf_write(pc, tag, PCI_CB_MEMBASE1, 0xffffffff);
    817   1.1      haya   pci_conf_write(pc, tag, PCI_CB_MEMLIMIT1, 0);
    818   1.1      haya   pci_conf_write(pc, tag, PCI_CB_IOBASE0, 0xffffffff);
    819   1.1      haya   pci_conf_write(pc, tag, PCI_CB_IOLIMIT0, 0);
    820   1.1      haya   pci_conf_write(pc, tag, PCI_CB_IOBASE1, 0xffffffff);
    821   1.1      haya   pci_conf_write(pc, tag, PCI_CB_IOLIMIT1, 0);
    822   1.1      haya 
    823   1.1      haya   return;
    824   1.1      haya }
    825   1.1      haya 
    826   1.1      haya 
    827   1.1      haya 
    828   1.4      haya /*
    829   1.4      haya  * attach pccard bus
    830   1.4      haya  */
    831   1.1      haya STATIC void
    832   1.1      haya pccbb_pcmcia_attach_setup(sc, paa)
    833   1.1      haya      struct pccbb_softc *sc;
    834   1.1      haya      struct pcmciabus_attach_args *paa;
    835   1.1      haya {
    836   1.1      haya   struct pcic_handle *ph = &sc->sc_pcmcia_h;
    837  1.10      haya #if rbus
    838  1.10      haya   rbus_tag_t rb;
    839  1.10      haya #endif
    840   1.1      haya 
    841   1.1      haya   /* initialise pcmcia part in pccbb_softc */
    842   1.1      haya   ph->ph_parent = (struct device *)sc;
    843   1.1      haya   ph->sock = sc->sc_function;
    844   1.1      haya   ph->flags = 0;
    845   1.1      haya   ph->shutdown = 0;
    846   1.1      haya   ph->ih_irq = sc->sc_intrline;
    847   1.1      haya   ph->ph_bus_t = sc->sc_base_memt;
    848   1.1      haya   ph->ph_bus_h = sc->sc_base_memh;
    849   1.1      haya   ph->ph_read = pccbb_pcmcia_read;
    850   1.1      haya   ph->ph_write = pccbb_pcmcia_write;
    851   1.1      haya   sc->sc_pct = &pccbb_pcmcia_funcs;
    852   1.1      haya 
    853   1.1      haya   Pcic_write(ph, PCIC_CSC_INTR, 0);
    854   1.1      haya   Pcic_read(ph, PCIC_CSC);
    855   1.1      haya 
    856   1.1      haya   /* initialise pcmcia bus attachment */
    857   1.1      haya   paa->paa_busname = "pcmcia";
    858   1.1      haya   paa->pct = sc->sc_pct;
    859   1.1      haya   paa->pch = ph;
    860   1.1      haya   paa->iobase = 0;		/* I don't use them */
    861   1.1      haya   paa->iosize = 0;
    862  1.10      haya #if rbus
    863  1.10      haya   rb = ((struct pccbb_softc *)(ph->ph_parent))->sc_rbus_iot;
    864  1.10      haya   paa->iobase = rb->rb_start + rb->rb_offset;
    865  1.10      haya   paa->iosize = rb->rb_end - rb->rb_start;
    866  1.10      haya #endif
    867   1.1      haya 
    868   1.1      haya   return;
    869   1.1      haya }
    870   1.1      haya 
    871   1.1      haya 
    872   1.1      haya #if 0
    873   1.1      haya STATIC void
    874   1.1      haya pccbb_pcmcia_attach_card(ph)
    875   1.1      haya      struct pcic_handle *ph;
    876   1.1      haya {
    877   1.1      haya   if (ph->flags & PCIC_FLAG_CARDP) {
    878   1.1      haya     panic("pccbb_pcmcia_attach_card: already attached");
    879   1.1      haya   }
    880   1.1      haya 
    881   1.1      haya   /* call the MI attach function */
    882   1.1      haya   pcmcia_card_attach(ph->pcmcia);
    883   1.1      haya 
    884   1.1      haya   ph->flags |= PCIC_FLAG_CARDP;
    885   1.1      haya }
    886   1.1      haya 
    887   1.1      haya 
    888   1.1      haya STATIC void
    889   1.1      haya pccbb_pcmcia_detach_card(ph, flags)
    890   1.1      haya      struct pcic_handle *ph;
    891   1.1      haya      int flags;
    892   1.1      haya {
    893   1.1      haya   if (!(ph->flags & PCIC_FLAG_CARDP)) {
    894   1.1      haya     panic("pccbb_pcmcia_detach_card: already detached");
    895   1.1      haya   }
    896   1.1      haya 
    897   1.1      haya   ph->flags &= ~PCIC_FLAG_CARDP;
    898   1.1      haya 
    899   1.1      haya   /* call the MI detach function */
    900   1.1      haya   pcmcia_card_detach(ph->pcmcia, flags);
    901   1.1      haya }
    902   1.1      haya #endif
    903   1.1      haya 
    904   1.1      haya 
    905   1.1      haya 
    906   1.1      haya 
    907   1.4      haya /*
    908   1.4      haya  * int pccbbintr(arg)
    909   1.4      haya  *    void *arg;
    910   1.4      haya  *   This routine handles the interrupt from Yenta PCI-CardBus bridge
    911   1.4      haya  *   itself.
    912   1.4      haya  */
    913   1.1      haya int
    914   1.1      haya pccbbintr(arg)
    915   1.1      haya      void *arg;
    916   1.1      haya {
    917   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)arg;
    918   1.1      haya   u_int32_t sockevent;
    919   1.1      haya   bus_space_tag_t memt = sc->sc_base_memt;
    920   1.1      haya   bus_space_handle_t memh = sc->sc_base_memh;
    921   1.1      haya   u_int32_t sockstate;
    922   1.1      haya 
    923   1.1      haya   sockevent = bus_space_read_4(memt, memh, CB_SOCKET_EVENT);
    924   1.1      haya   if (0 == sockevent) {		/* not for me */
    925  1.21      haya     /* This interrupt is not for me: it may be for my child devices. */
    926  1.21      haya     return pccbbintr_function(sc);
    927   1.1      haya   } else {
    928   1.1      haya     bus_space_write_4(memt, memh, CB_SOCKET_EVENT, sockevent); /* reset bit */
    929   1.1      haya   }
    930   1.1      haya   sockstate = bus_space_read_4(memt, memh, CB_SOCKET_STAT);
    931   1.1      haya 
    932   1.1      haya   if (sockevent & CB_SOCKET_EVENT_CD) {
    933   1.1      haya     if (CB_SOCKET_STAT_CD == (sockstate & CB_SOCKET_STAT_CD)) {
    934   1.1      haya       /* A card should be removed. */
    935   1.1      haya       if (sc->sc_flags & CBB_CARDEXIST) {
    936   1.1      haya 	DPRINTF(("%s: 0x%08x", sc->sc_dev.dv_xname, sockevent));
    937   1.1      haya 	DPRINTF((" card removed, 0x%08x\n", sockstate));
    938   1.1      haya 	sc->sc_flags &= ~CBB_CARDEXIST;
    939   1.1      haya 	if (sc->sc_csc->sc_status & CARDSLOT_STATUS_CARD_16) {
    940   1.1      haya #if 0
    941   1.1      haya 	  struct pcic_handle *ph = &sc->sc_pcmcia_h;
    942   1.1      haya 
    943   1.1      haya 	  pcmcia_card_deactivate(ph->pcmcia);
    944   1.1      haya 	  pccbb_pcmcia_socket_disable(ph);
    945   1.1      haya 	  pccbb_pcmcia_detach_card(ph, DETACH_FORCE);
    946   1.1      haya #endif
    947   1.1      haya 	  cardslot_event_throw(sc->sc_csc, CARDSLOT_EVENT_REMOVAL_16);
    948   1.1      haya 	} else if (sc->sc_csc->sc_status & CARDSLOT_STATUS_CARD_CB) {
    949   1.1      haya 	  /* Cardbus intr removed */
    950   1.1      haya 	  cardslot_event_throw(sc->sc_csc, CARDSLOT_EVENT_REMOVAL_CB);
    951   1.1      haya 	}
    952   1.1      haya       }
    953   1.1      haya     } else if (0x00 == (sockstate & CB_SOCKET_STAT_CD)) {
    954   1.1      haya       if (sc->sc_flags & CBB_INSERTING) {
    955   1.1      haya 	untimeout(pci113x_insert, sc);
    956   1.1      haya       }
    957   1.1      haya       timeout(pci113x_insert, sc, hz/10);
    958   1.1      haya       sc->sc_flags |= CBB_INSERTING;
    959   1.1      haya     }
    960   1.1      haya   } else {
    961  1.11      joda     DPRINTF(("%s: sockevent = %b\n",
    962  1.11      joda 	     sc->sc_dev.dv_xname, sockevent, PCCBB_SOCKEVENT_BITS));
    963  1.11      joda     DPRINTF(("%s: sockstate = %b\n",
    964  1.11      joda 	     sc->sc_dev.dv_xname,
    965  1.11      joda 	     sockstate, PCCBB_SOCKSTATE_BITS));
    966   1.1      haya   }
    967   1.1      haya 
    968   1.1      haya   return 1;
    969   1.1      haya }
    970   1.1      haya 
    971   1.1      haya 
    972   1.1      haya 
    973  1.21      haya /*
    974  1.21      haya  * static int pccbbintr_function(struct pccbb_softc *sc)
    975  1.21      haya  *
    976  1.21      haya  *    This function calls each interrupt handler registered at the
    977  1.21      haya  *    bridge.  The interrupt handlers are called in registerd order.
    978  1.21      haya  */
    979  1.21      haya static int
    980  1.21      haya pccbbintr_function(sc)
    981  1.21      haya     struct pccbb_softc *sc;
    982  1.21      haya {
    983  1.21      haya     int retval = 0, val;
    984  1.21      haya     struct pccbb_intrhand_list *pil;
    985  1.21      haya 
    986  1.21      haya     for (pil = sc->sc_pil; pil != NULL; pil = pil->pil_next) {
    987  1.21      haya 	val = (*pil->pil_func)(pil->pil_arg);
    988  1.21      haya 	retval = retval == 1 ? 1 :
    989  1.21      haya 		 retval == 0 ? val :
    990  1.21      haya 		 val != 0 ? val : retval;
    991  1.21      haya     }
    992  1.21      haya 
    993  1.21      haya     return retval;
    994  1.21      haya }
    995  1.21      haya 
    996  1.21      haya 
    997  1.21      haya 
    998  1.21      haya 
    999  1.21      haya 
   1000   1.1      haya static void
   1001   1.1      haya pci113x_insert(arg)
   1002   1.1      haya      void *arg;
   1003   1.1      haya {
   1004   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)arg;
   1005   1.1      haya   u_int32_t sockevent, sockstate;
   1006   1.1      haya 
   1007   1.1      haya   sockevent = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh,
   1008   1.1      haya 			       CB_SOCKET_EVENT);
   1009   1.1      haya   sockstate = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh,
   1010   1.1      haya 			       CB_SOCKET_STAT);
   1011   1.1      haya 
   1012   1.1      haya   if (0 == (sockstate & CB_SOCKET_STAT_CD)) { /* card exist */
   1013   1.1      haya     DPRINTF(("%s: 0x%08x", sc->sc_dev.dv_xname, sockevent));
   1014   1.1      haya     DPRINTF((" card inserted, 0x%08x\n", sockstate));
   1015   1.1      haya     sc->sc_flags |= CBB_CARDEXIST;
   1016   1.1      haya     /* call pccard intterupt handler here */
   1017   1.1      haya     if (sockstate & CB_SOCKET_STAT_16BIT) {
   1018   1.1      haya       /* 16-bit card found */
   1019   1.1      haya /*      pccbb_pcmcia_attach_card(&sc->sc_pcmcia_h); */
   1020   1.1      haya       cardslot_event_throw(sc->sc_csc, CARDSLOT_EVENT_INSERTION_16);
   1021   1.1      haya     } else if (sockstate & CB_SOCKET_STAT_CB) {
   1022   1.1      haya       /* cardbus card fuond */
   1023   1.1      haya /*      cardbus_attach_card(sc->sc_csc); */
   1024   1.1      haya       cardslot_event_throw(sc->sc_csc, CARDSLOT_EVENT_INSERTION_CB);
   1025   1.1      haya     } else {
   1026   1.1      haya       /* who are you? */
   1027   1.1      haya     }
   1028   1.1      haya   } else {
   1029   1.1      haya     timeout(pci113x_insert, sc, hz/10);
   1030   1.1      haya   }
   1031   1.1      haya }
   1032   1.1      haya 
   1033   1.1      haya 
   1034   1.1      haya 
   1035   1.1      haya 
   1036   1.1      haya #define PCCBB_PCMCIA_OFFSET 0x800
   1037   1.1      haya static u_int8_t
   1038   1.1      haya pccbb_pcmcia_read(ph, reg)
   1039   1.1      haya      struct pcic_handle *ph;
   1040   1.1      haya      int reg;
   1041   1.1      haya {
   1042   1.1      haya   return bus_space_read_1(ph->ph_bus_t, ph->ph_bus_h, PCCBB_PCMCIA_OFFSET + reg);
   1043   1.1      haya }
   1044   1.1      haya 
   1045   1.1      haya 
   1046   1.1      haya 
   1047   1.1      haya static void
   1048   1.1      haya pccbb_pcmcia_write(ph, reg, val)
   1049   1.1      haya      struct pcic_handle *ph;
   1050   1.1      haya      int reg;
   1051   1.1      haya      u_int8_t val;
   1052   1.1      haya {
   1053   1.1      haya   bus_space_write_1(ph->ph_bus_t, ph->ph_bus_h, PCCBB_PCMCIA_OFFSET + reg, val);
   1054   1.1      haya }
   1055   1.1      haya 
   1056   1.1      haya 
   1057   1.1      haya 
   1058   1.1      haya 
   1059   1.4      haya /*
   1060   1.4      haya  * STATIC int pccbb_ctrl(cardbus_chipset_tag_t, int)
   1061   1.4      haya  */
   1062   1.1      haya STATIC int
   1063   1.1      haya pccbb_ctrl(ct, command)
   1064   1.1      haya      cardbus_chipset_tag_t ct;
   1065   1.1      haya      int command;
   1066   1.1      haya {
   1067   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)ct;
   1068   1.1      haya 
   1069   1.1      haya   switch(command) {
   1070   1.1      haya   case CARDBUS_CD:
   1071   1.1      haya     if (2 == pccbb_detect_card(sc)) {
   1072   1.1      haya       int retval = 0;
   1073   1.1      haya       int status = cb_detect_voltage(sc);
   1074   1.1      haya       if (PCCARD_VCC_5V & status) {
   1075   1.1      haya 	retval |= CARDBUS_5V_CARD;
   1076   1.1      haya       }
   1077   1.1      haya       if (PCCARD_VCC_3V & status) {
   1078   1.1      haya 	retval |= CARDBUS_3V_CARD;
   1079   1.1      haya       }
   1080   1.1      haya       if (PCCARD_VCC_XV & status) {
   1081   1.1      haya 	retval |= CARDBUS_XV_CARD;
   1082   1.1      haya       }
   1083   1.1      haya       if (PCCARD_VCC_YV & status) {
   1084   1.1      haya 	retval |= CARDBUS_YV_CARD;
   1085   1.1      haya       }
   1086   1.1      haya       return retval;
   1087   1.1      haya     } else {
   1088   1.1      haya       return 0;
   1089   1.1      haya     }
   1090   1.1      haya     break;
   1091   1.1      haya   case CARDBUS_RESET:
   1092   1.1      haya     return cb_reset(sc);
   1093   1.1      haya     break;
   1094   1.1      haya   case CARDBUS_IO_ENABLE:	/* fallthrough */
   1095   1.1      haya   case CARDBUS_IO_DISABLE:	/* fallthrough */
   1096   1.1      haya   case CARDBUS_MEM_ENABLE:	/* fallthrough */
   1097   1.1      haya   case CARDBUS_MEM_DISABLE:	/* fallthrough */
   1098   1.1      haya   case CARDBUS_BM_ENABLE:	/* fallthrough */
   1099   1.1      haya   case CARDBUS_BM_DISABLE:	/* fallthrough */
   1100   1.1      haya     return pccbb_cardenable(sc, command);
   1101   1.1      haya     break;
   1102   1.1      haya   }
   1103   1.1      haya 
   1104   1.1      haya   return 0;
   1105   1.1      haya }
   1106   1.1      haya 
   1107   1.1      haya 
   1108   1.1      haya 
   1109   1.4      haya /*
   1110   1.4      haya  * STATIC int pccbb_power(cardbus_chipset_tag_t, int)
   1111   1.4      haya  *   This function returns true when it succeeds and returns false when
   1112   1.4      haya  *   it fails.
   1113   1.4      haya  */
   1114   1.1      haya STATIC int
   1115   1.1      haya pccbb_power(ct, command)
   1116   1.1      haya      cardbus_chipset_tag_t ct;
   1117   1.1      haya      int command;
   1118   1.1      haya {
   1119   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)ct;
   1120   1.1      haya 
   1121   1.1      haya   u_int32_t status, sock_ctrl;
   1122   1.1      haya   bus_space_tag_t memt = sc->sc_base_memt;
   1123   1.1      haya   bus_space_handle_t memh = sc->sc_base_memh;
   1124   1.1      haya 
   1125   1.1      haya   DPRINTF(("pccbb_power: %s and %s [%x]\n",
   1126   1.1      haya 	   (command & CARDBUS_VCCMASK) == CARDBUS_VCC_UC ? "CARDBUS_VCC_UC" :
   1127   1.1      haya 	   (command & CARDBUS_VCCMASK) == CARDBUS_VCC_5V ? "CARDBUS_VCC_5V" :
   1128   1.1      haya 	   (command & CARDBUS_VCCMASK) == CARDBUS_VCC_3V ? "CARDBUS_VCC_3V" :
   1129   1.1      haya 	   (command & CARDBUS_VCCMASK) == CARDBUS_VCC_XV ? "CARDBUS_VCC_XV" :
   1130   1.1      haya 	   (command & CARDBUS_VCCMASK) == CARDBUS_VCC_YV ? "CARDBUS_VCC_YV" :
   1131   1.1      haya 	   (command & CARDBUS_VCCMASK) == CARDBUS_VCC_0V ? "CARDBUS_VCC_0V" :
   1132   1.1      haya 	   "UNKNOWN",
   1133   1.1      haya 	   (command & CARDBUS_VPPMASK) == CARDBUS_VPP_UC ? "CARDBUS_VPP_UC" :
   1134   1.1      haya 	   (command & CARDBUS_VPPMASK) == CARDBUS_VPP_12V ? "CARDBUS_VPP_12V" :
   1135   1.1      haya 	   (command & CARDBUS_VPPMASK) == CARDBUS_VPP_VCC ? "CARDBUS_VPP_VCC" :
   1136   1.1      haya 	   (command & CARDBUS_VPPMASK) == CARDBUS_VPP_0V ? "CARDBUS_VPP_0V" :
   1137   1.1      haya 	   "UNKNOWN",
   1138   1.1      haya 	   command));
   1139   1.1      haya 
   1140   1.1      haya   status = bus_space_read_4(memt, memh, CB_SOCKET_STAT);
   1141   1.1      haya   sock_ctrl = bus_space_read_4(memt, memh, CB_SOCKET_CTRL);
   1142   1.1      haya 
   1143   1.1      haya   switch (command & CARDBUS_VCCMASK) {
   1144   1.1      haya   case CARDBUS_VCC_UC:
   1145   1.1      haya     break;
   1146   1.1      haya   case CARDBUS_VCC_5V:
   1147   1.1      haya     if (CB_SOCKET_STAT_5VCARD & status) { /* check 5 V card */
   1148   1.1      haya       sock_ctrl &= ~CB_SOCKET_CTRL_VCCMASK;
   1149   1.1      haya       sock_ctrl |= CB_SOCKET_CTRL_VCC_5V;
   1150   1.1      haya     } else {
   1151   1.1      haya       printf("%s: BAD voltage request: no 5 V card\n", sc->sc_dev.dv_xname);
   1152   1.1      haya     }
   1153   1.1      haya     break;
   1154   1.1      haya   case CARDBUS_VCC_3V:
   1155   1.1      haya     if (CB_SOCKET_STAT_3VCARD & status) {
   1156   1.1      haya       sock_ctrl &= ~CB_SOCKET_CTRL_VCCMASK;
   1157   1.1      haya       sock_ctrl |= CB_SOCKET_CTRL_VCC_3V;
   1158   1.1      haya     } else {
   1159   1.1      haya       printf("%s: BAD voltage request: no 3.3 V card\n", sc->sc_dev.dv_xname);
   1160   1.1      haya     }
   1161   1.1      haya     break;
   1162   1.1      haya   case CARDBUS_VCC_0V:
   1163   1.1      haya     sock_ctrl &= ~CB_SOCKET_CTRL_VCCMASK;
   1164   1.1      haya     break;
   1165   1.1      haya   default:
   1166   1.1      haya     return 0;			/* power NEVER changed */
   1167   1.1      haya     break;
   1168   1.1      haya   }
   1169   1.1      haya 
   1170   1.1      haya   switch (command & CARDBUS_VPPMASK) {
   1171   1.1      haya   case CARDBUS_VPP_UC:
   1172   1.1      haya     break;
   1173   1.1      haya   case CARDBUS_VPP_0V:
   1174   1.1      haya     sock_ctrl &= ~CB_SOCKET_CTRL_VPPMASK;
   1175   1.1      haya     break;
   1176   1.1      haya   case CARDBUS_VPP_VCC:
   1177   1.1      haya     sock_ctrl &= ~CB_SOCKET_CTRL_VPPMASK;
   1178   1.1      haya     sock_ctrl |= ((sock_ctrl >> 4) & 0x07);
   1179   1.1      haya     break;
   1180   1.1      haya   case CARDBUS_VPP_12V:
   1181   1.1      haya     sock_ctrl &= ~CB_SOCKET_CTRL_VPPMASK;
   1182   1.1      haya     sock_ctrl |= CB_SOCKET_CTRL_VPP_12V;
   1183   1.1      haya     break;
   1184   1.1      haya   }
   1185   1.1      haya 
   1186   1.1      haya #if 0
   1187   1.1      haya   DPRINTF(("sock_ctrl: %x\n", sock_ctrl));
   1188   1.1      haya #endif
   1189   1.1      haya   bus_space_write_4(memt, memh, CB_SOCKET_CTRL, sock_ctrl);
   1190   1.1      haya   status = bus_space_read_4(memt, memh, CB_SOCKET_STAT);
   1191   1.1      haya 
   1192   1.1      haya   delay(20*1000);			/* wait 20 ms: Vcc setup time */
   1193   1.1      haya   /* XXX
   1194   1.1      haya      delay 200 ms: though the standard defines that the Vcc set-up time
   1195   1.1      haya      is 20 ms, some PC-Card bridge requires longer duration.
   1196   1.1      haya   */
   1197   1.1      haya   delay(200*1000);
   1198   1.1      haya 
   1199   1.1      haya 
   1200   1.1      haya   if (status & CB_SOCKET_STAT_BADVCC) {		/* bad Vcc request */
   1201   1.1      haya     printf("%s: bad Vcc request. sock_ctrl 0x%x, sock_status 0x%x\n",
   1202   1.1      haya 	   sc->sc_dev.dv_xname, sock_ctrl ,status);
   1203   1.1      haya     DPRINTF(("pccbb_power: %s and %s [%x]\n",
   1204   1.1      haya 	     (command & CARDBUS_VCCMASK) == CARDBUS_VCC_UC ? "CARDBUS_VCC_UC" :
   1205   1.1      haya 	     (command & CARDBUS_VCCMASK) == CARDBUS_VCC_5V ? "CARDBUS_VCC_5V":
   1206   1.1      haya 	     (command & CARDBUS_VCCMASK) == CARDBUS_VCC_3V ? "CARDBUS_VCC_3V":
   1207   1.1      haya 	     (command & CARDBUS_VCCMASK) == CARDBUS_VCC_XV ? "CARDBUS_VCC_XV":
   1208   1.1      haya 	     (command & CARDBUS_VCCMASK) == CARDBUS_VCC_YV ? "CARDBUS_VCC_YV":
   1209   1.1      haya 	     (command & CARDBUS_VCCMASK) == CARDBUS_VCC_0V ? "CARDBUS_VCC_0V":
   1210   1.1      haya 	     "UNKNOWN",
   1211   1.1      haya 	     (command & CARDBUS_VPPMASK) == CARDBUS_VPP_UC ? "CARDBUS_VPP_UC":
   1212   1.1      haya 	     (command & CARDBUS_VPPMASK) == CARDBUS_VPP_12V ?"CARDBUS_VPP_12V":
   1213   1.1      haya 	     (command & CARDBUS_VPPMASK) == CARDBUS_VPP_VCC ?"CARDBUS_VPP_VCC":
   1214   1.1      haya 	     (command & CARDBUS_VPPMASK) == CARDBUS_VPP_0V ? "CARDBUS_VPP_0V" :
   1215   1.1      haya 	     "UNKNOWN",
   1216   1.1      haya 	     command));
   1217   1.1      haya #if 0
   1218   1.1      haya     if (command == (CARDBUS_VCC_0V | CARDBUS_VPP_0V)) {
   1219   1.1      haya       u_int32_t force = bus_space_read_4(memt, memh, CB_SOCKET_FORCE);
   1220   1.1      haya       /* Reset Bad Vcc request */
   1221   1.1      haya       force &= ~CB_SOCKET_FORCE_BADVCC;
   1222   1.1      haya       bus_space_write_4(memt, memh, CB_SOCKET_FORCE, force);
   1223   1.1      haya       printf("new status 0x%x\n", bus_space_read_4(memt, memh,CB_SOCKET_STAT));
   1224   1.1      haya       return 1;
   1225   1.1      haya     }
   1226   1.1      haya #endif
   1227   1.1      haya     return 0;
   1228   1.1      haya   }
   1229   1.1      haya   return 1;		/* power changed correctly */
   1230   1.1      haya }
   1231   1.1      haya 
   1232   1.1      haya 
   1233   1.1      haya 
   1234   1.1      haya 
   1235   1.1      haya 
   1236   1.1      haya 
   1237   1.1      haya #if defined CB_PCMCIA_POLL
   1238   1.1      haya struct cb_poll_str {
   1239   1.1      haya   void *arg;
   1240   1.1      haya   int (* func) __P((void *));
   1241   1.1      haya   int level;
   1242   1.1      haya   pccard_chipset_tag_t ct;
   1243   1.1      haya   int count;
   1244   1.1      haya };
   1245   1.1      haya 
   1246   1.1      haya static struct cb_poll_str cb_poll[10];
   1247   1.1      haya static int cb_poll_n = 0;
   1248   1.1      haya 
   1249   1.1      haya static void cb_pcmcia_poll __P((void *arg));
   1250   1.1      haya 
   1251   1.1      haya static void
   1252   1.1      haya cb_pcmcia_poll(arg)
   1253   1.1      haya      void *arg;
   1254   1.1      haya {
   1255   1.1      haya   struct cb_poll_str *poll = arg;
   1256   1.1      haya   struct cbb_pcmcia_softc *psc = (void *)poll->ct->v;
   1257   1.1      haya   struct pccbb_softc *sc = psc->cpc_parent;
   1258   1.1      haya   int s;
   1259   1.1      haya   u_int32_t spsr;		/* socket present-state reg */
   1260   1.1      haya 
   1261   1.1      haya   timeout(cb_pcmcia_poll, arg, hz/10);
   1262   1.1      haya   switch (poll->level) {
   1263   1.1      haya   case IPL_NET:
   1264   1.1      haya     s = splnet();
   1265   1.1      haya     break;
   1266   1.1      haya   case IPL_BIO:
   1267   1.1      haya     s = splbio();
   1268   1.1      haya     break;
   1269   1.1      haya   case IPL_TTY:			/* fallthrough */
   1270   1.1      haya   default:
   1271   1.1      haya     s = spltty();
   1272   1.1      haya     break;
   1273   1.1      haya   }
   1274   1.1      haya 
   1275   1.1      haya   spsr = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh, CB_SOCKET_STAT);
   1276   1.1      haya 
   1277   1.1      haya #if defined CB_PCMCIA_POLL_ONLY && defined LEVEL2
   1278   1.1      haya   if (!(spsr & 0x40)) {		/* CINT low */
   1279   1.1      haya #else
   1280   1.1      haya   if (1) {
   1281   1.1      haya #endif
   1282   1.1      haya     if ((*poll->func)(poll->arg) == 1) {
   1283   1.1      haya       ++poll->count;
   1284   1.1      haya 	printf("intr: reported from poller, 0x%x\n", spsr);
   1285   1.1      haya #if defined LEVEL2
   1286   1.1      haya     } else {
   1287   1.1      haya       printf("intr: miss! 0x%x\n", spsr);
   1288   1.1      haya #endif
   1289   1.1      haya     }
   1290   1.1      haya   }
   1291   1.1      haya   splx(s);
   1292   1.1      haya }
   1293   1.1      haya #endif /* defined CB_PCMCIA_POLL */
   1294   1.1      haya 
   1295   1.1      haya 
   1296   1.1      haya 
   1297   1.1      haya 
   1298   1.4      haya /*
   1299   1.4      haya  * static int pccbb_detect_card(struct pccbb_softc *sc)
   1300   1.4      haya  *   return value:  0 if no card exists.
   1301   1.4      haya  *                  1 if 16-bit card exists.
   1302   1.4      haya  *                  2 if cardbus card exists.
   1303   1.4      haya  */
   1304   1.1      haya static int
   1305   1.1      haya pccbb_detect_card(sc)
   1306   1.1      haya      struct pccbb_softc *sc;
   1307   1.1      haya {
   1308   1.1      haya   bus_space_handle_t base_memh = sc->sc_base_memh;
   1309   1.1      haya   bus_space_tag_t base_memt = sc->sc_base_memt;
   1310   1.1      haya   u_int32_t sockstat = bus_space_read_4(base_memt,base_memh, CB_SOCKET_STAT);
   1311   1.1      haya   int retval = 0;
   1312   1.1      haya 
   1313   1.1      haya   if (0x00 == (sockstat & CB_SOCKET_STAT_CD)) { /* CD1 and CD2 asserted */
   1314   1.1      haya     /* card must be present */
   1315   1.1      haya     if (!(CB_SOCKET_STAT_NOTCARD & sockstat)) {	/* NOTACARD DEASSERTED */
   1316   1.1      haya       if (CB_SOCKET_STAT_CB & sockstat) {	/* CardBus mode */
   1317   1.1      haya 	retval = 2;
   1318   1.1      haya       } else if (CB_SOCKET_STAT_16BIT & sockstat) { /* 16-bit mode */
   1319   1.1      haya 	retval = 1;
   1320   1.1      haya       }
   1321   1.1      haya     }
   1322   1.1      haya   }
   1323   1.1      haya   return retval;
   1324   1.1      haya }
   1325   1.1      haya 
   1326   1.1      haya 
   1327   1.1      haya 
   1328   1.1      haya 
   1329   1.4      haya /*
   1330   1.4      haya  * STATIC int cb_reset(struct pccbb_softc *sc)
   1331   1.4      haya  *   This function resets CardBus card.
   1332   1.4      haya  */
   1333   1.1      haya STATIC int
   1334   1.1      haya cb_reset(sc)
   1335   1.1      haya      struct pccbb_softc *sc;
   1336   1.1      haya {
   1337   1.9      haya   /*
   1338   1.9      haya    * Reset Assert at least 20 ms
   1339   1.9      haya    * Some machines request longer duration.
   1340   1.9      haya    */
   1341   1.9      haya   int reset_duration = (sc->sc_chipset == CB_RX5C47X ? 400*1000 : 40*1000);
   1342   1.1      haya   u_int32_t bcr = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR);
   1343   1.9      haya 
   1344   1.1      haya   bcr |= (0x40 << 16);		/* Reset bit Assert (bit 6 at 0x3E) */
   1345   1.1      haya   pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR, bcr);
   1346   1.9      haya   delay(reset_duration);
   1347   1.1      haya 
   1348   1.1      haya   if (CBB_CARDEXIST & sc->sc_flags) { /* A card exists.  Reset it! */
   1349   1.1      haya     bcr &= ~(0x40 << 16);	/* Reset bit Deassert (bit 6 at 0x3E) */
   1350   1.1      haya     pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR, bcr);
   1351   1.9      haya     delay(reset_duration);
   1352   1.1      haya   }
   1353   1.1      haya 				/* No card found on the slot. Keep Reset. */
   1354   1.1      haya   return 1;
   1355   1.1      haya }
   1356   1.1      haya 
   1357   1.1      haya 
   1358   1.1      haya 
   1359   1.1      haya 
   1360   1.4      haya /*
   1361   1.4      haya  * STATIC int cb_detect_voltage(struct pccbb_softc *sc)
   1362   1.4      haya  *  This function detect card Voltage.
   1363   1.4      haya  */
   1364   1.1      haya STATIC int
   1365   1.1      haya cb_detect_voltage(sc)
   1366   1.1      haya      struct pccbb_softc *sc;
   1367   1.1      haya {
   1368   1.1      haya   u_int32_t psr;		/* socket present-state reg */
   1369   1.1      haya   bus_space_tag_t iot = sc->sc_base_memt;
   1370   1.1      haya   bus_space_handle_t ioh = sc->sc_base_memh;
   1371   1.1      haya   int vol = PCCARD_VCC_UKN;	/* set 0 */
   1372   1.1      haya 
   1373   1.1      haya   psr = bus_space_read_4(iot, ioh, CB_SOCKET_STAT);
   1374   1.1      haya 
   1375   1.1      haya   if (0x400u & psr) {
   1376   1.1      haya     vol |= PCCARD_VCC_5V;
   1377   1.1      haya   }
   1378   1.1      haya   if (0x800u & psr) {
   1379   1.1      haya     vol |= PCCARD_VCC_3V;
   1380   1.1      haya   }
   1381   1.1      haya 
   1382   1.1      haya   return vol;
   1383   1.1      haya }
   1384   1.1      haya 
   1385   1.1      haya 
   1386   1.1      haya 
   1387   1.1      haya 
   1388   1.1      haya 
   1389   1.1      haya 
   1390   1.1      haya STATIC int
   1391   1.1      haya cbbprint(aux, pcic)
   1392   1.1      haya      void *aux;
   1393   1.1      haya      const char *pcic;
   1394   1.1      haya {
   1395   1.1      haya /*
   1396   1.1      haya   struct cbslot_attach_args *cba = aux;
   1397   1.1      haya 
   1398   1.1      haya   if (cba->cba_slot >= 0) {
   1399   1.1      haya     printf(" slot %d", cba->cba_slot);
   1400   1.1      haya   }
   1401   1.1      haya */
   1402   1.1      haya   return UNCONF;
   1403   1.1      haya }
   1404   1.1      haya 
   1405   1.1      haya 
   1406   1.1      haya 
   1407   1.1      haya 
   1408   1.4      haya /*
   1409   1.4      haya  * STATIC int pccbb_cardenable(struct pccbb_softc *sc, int function)
   1410   1.4      haya  *   This function enables and disables the card
   1411   1.4      haya  */
   1412   1.1      haya STATIC int
   1413   1.1      haya pccbb_cardenable(sc, function)
   1414   1.1      haya      struct pccbb_softc *sc;
   1415   1.1      haya      int function;
   1416   1.1      haya {
   1417   1.1      haya   u_int32_t command = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG);
   1418   1.1      haya 
   1419   1.1      haya   DPRINTF(("pccbb_cardenable:"));
   1420   1.1      haya   switch (function) {
   1421   1.1      haya   case CARDBUS_IO_ENABLE:
   1422   1.1      haya     command |= PCI_COMMAND_IO_ENABLE;
   1423   1.1      haya     break;
   1424   1.1      haya   case CARDBUS_IO_DISABLE:
   1425   1.1      haya     command &= ~PCI_COMMAND_IO_ENABLE;
   1426   1.1      haya     break;
   1427   1.1      haya   case CARDBUS_MEM_ENABLE:
   1428   1.1      haya     command |= PCI_COMMAND_MEM_ENABLE;
   1429   1.1      haya     break;
   1430   1.1      haya   case CARDBUS_MEM_DISABLE:
   1431   1.1      haya     command &= ~PCI_COMMAND_MEM_ENABLE;
   1432   1.1      haya     break;
   1433   1.1      haya   case CARDBUS_BM_ENABLE:
   1434   1.1      haya     command |= PCI_COMMAND_MASTER_ENABLE;
   1435   1.1      haya     break;
   1436   1.1      haya   case CARDBUS_BM_DISABLE:
   1437   1.1      haya     command &= ~PCI_COMMAND_MASTER_ENABLE;
   1438   1.1      haya     break;
   1439   1.1      haya   default:
   1440   1.1      haya     return 0;
   1441   1.1      haya   }
   1442   1.1      haya 
   1443   1.1      haya   pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG, command);
   1444   1.1      haya   DPRINTF((" command reg 0x%x\n", command));
   1445   1.1      haya   return 1;
   1446   1.1      haya }
   1447   1.1      haya 
   1448   1.1      haya 
   1449   1.1      haya 
   1450   1.1      haya 
   1451   1.1      haya 
   1452   1.1      haya 
   1453   1.1      haya #if !rbus
   1454   1.4      haya /*
   1455   1.4      haya  * int pccbb_io_open(cardbus_chipset_tag_t, int, u_int32_t, u_int32_t)
   1456   1.4      haya  */
   1457   1.1      haya static int
   1458   1.1      haya pccbb_io_open(ct, win, start, end)
   1459   1.1      haya      cardbus_chipset_tag_t ct;
   1460   1.1      haya      int win;
   1461   1.1      haya      u_int32_t start, end;
   1462   1.1      haya {
   1463   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)ct;
   1464   1.1      haya   int basereg;
   1465   1.1      haya   int limitreg;
   1466   1.1      haya 
   1467   1.1      haya   if ((win < 0) || (win > 2)) {
   1468   1.1      haya #if defined DIAGNOSTIC
   1469   1.1      haya     printf("cardbus_io_open: window out of range %d\n", win);
   1470   1.1      haya #endif
   1471   1.1      haya     return 0;
   1472   1.1      haya   }
   1473   1.1      haya 
   1474   1.1      haya   basereg = win*8 + 0x2c;
   1475   1.1      haya   limitreg = win*8 + 0x30;
   1476   1.1      haya 
   1477   1.1      haya   DPRINTF(("pccbb_io_open: 0x%x[0x%x] - 0x%x[0x%x]\n",
   1478   1.1      haya 	   start, basereg, end, limitreg));
   1479   1.1      haya 
   1480   1.1      haya   pci_conf_write(sc->sc_pc, sc->sc_tag, basereg, start);
   1481   1.1      haya   pci_conf_write(sc->sc_pc, sc->sc_tag, limitreg, end);
   1482   1.1      haya   return 1;
   1483   1.1      haya }
   1484   1.1      haya 
   1485   1.4      haya /*
   1486   1.4      haya  * int pccbb_io_close(cardbus_chipset_tag_t, int)
   1487   1.4      haya  */
   1488   1.1      haya static int
   1489   1.1      haya pccbb_io_close(ct, win)
   1490   1.1      haya      cardbus_chipset_tag_t ct;
   1491   1.1      haya      int win;
   1492   1.1      haya {
   1493   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)ct;
   1494   1.1      haya   int basereg;
   1495   1.1      haya   int limitreg;
   1496   1.1      haya 
   1497   1.1      haya   if ((win < 0) || (win > 2)) {
   1498   1.1      haya #if defined DIAGNOSTIC
   1499   1.1      haya     printf("cardbus_io_close: window out of range %d\n", win);
   1500   1.1      haya #endif
   1501   1.1      haya     return 0;
   1502   1.1      haya   }
   1503   1.1      haya 
   1504   1.1      haya   basereg = win*8 + 0x2c;
   1505   1.1      haya   limitreg = win*8 + 0x30;
   1506   1.1      haya 
   1507   1.1      haya   pci_conf_write(sc->sc_pc, sc->sc_tag, basereg, 0);
   1508   1.1      haya   pci_conf_write(sc->sc_pc, sc->sc_tag, limitreg, 0);
   1509   1.1      haya   return 1;
   1510   1.1      haya }
   1511   1.1      haya 
   1512   1.4      haya /*
   1513   1.4      haya  * int pccbb_mem_open(cardbus_chipset_tag_t, int, u_int32_t, u_int32_t)
   1514   1.4      haya  */
   1515   1.1      haya static int
   1516   1.1      haya pccbb_mem_open(ct, win, start, end)
   1517   1.1      haya      cardbus_chipset_tag_t ct;
   1518   1.1      haya      int win;
   1519   1.1      haya      u_int32_t start, end;
   1520   1.1      haya {
   1521   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)ct;
   1522   1.1      haya   int basereg;
   1523   1.1      haya   int limitreg;
   1524   1.1      haya 
   1525   1.1      haya   if ((win < 0) || (win > 2)) {
   1526   1.1      haya #if defined DIAGNOSTIC
   1527   1.1      haya     printf("cardbus_mem_open: window out of range %d\n", win);
   1528   1.1      haya #endif
   1529   1.1      haya     return 0;
   1530   1.1      haya   }
   1531   1.1      haya 
   1532   1.1      haya   basereg = win*8 + 0x1c;
   1533   1.1      haya   limitreg = win*8 + 0x20;
   1534   1.1      haya 
   1535   1.1      haya   pci_conf_write(sc->sc_pc, sc->sc_tag, basereg, start);
   1536   1.1      haya   pci_conf_write(sc->sc_pc, sc->sc_tag, limitreg, end);
   1537   1.1      haya   return 1;
   1538   1.1      haya }
   1539   1.1      haya 
   1540   1.1      haya 
   1541   1.4      haya /*
   1542   1.4      haya  * int pccbb_mem_close(cardbus_chipset_tag_t, int)
   1543   1.4      haya  */
   1544   1.1      haya static int
   1545   1.1      haya pccbb_mem_close(ct, win)
   1546   1.1      haya      cardbus_chipset_tag_t ct;
   1547   1.1      haya      int win;
   1548   1.1      haya {
   1549   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)ct;
   1550   1.1      haya   int basereg;
   1551   1.1      haya   int limitreg;
   1552   1.1      haya 
   1553   1.1      haya   if ((win < 0) || (win > 2)) {
   1554   1.1      haya #if defined DIAGNOSTIC
   1555   1.1      haya     printf("cardbus_mem_close: window out of range %d\n", win);
   1556   1.1      haya #endif
   1557   1.1      haya     return 0;
   1558   1.1      haya   }
   1559   1.1      haya 
   1560   1.1      haya   basereg = win*8 + 0x1c;
   1561   1.1      haya   limitreg = win*8 + 0x20;
   1562   1.1      haya 
   1563   1.1      haya   pci_conf_write(sc->sc_pc, sc->sc_tag, basereg, 0);
   1564   1.1      haya   pci_conf_write(sc->sc_pc, sc->sc_tag, limitreg, 0);
   1565   1.1      haya   return 1;
   1566   1.1      haya }
   1567   1.1      haya #endif
   1568   1.1      haya 
   1569   1.1      haya 
   1570   1.1      haya 
   1571  1.21      haya /*
   1572  1.21      haya  * static void *pccbb_intr_establish(cardbus_chipset_tag_t ct,
   1573  1.21      haya  *				     int irq,
   1574  1.21      haya  *				     int level,
   1575  1.21      haya  *				     int (* func) __P((void *)),
   1576  1.21      haya  *				     void *arg)
   1577  1.21      haya  *
   1578  1.21      haya  *   This function registers an interrupt handler at the bridge, in
   1579  1.21      haya  *   order not to call the interrput handlers of child devices when
   1580  1.21      haya  *   a card-deletion interrput occurs.
   1581  1.21      haya  *
   1582  1.21      haya  *   The arguments irq and level are not used.
   1583  1.21      haya  */
   1584   1.1      haya static void *
   1585   1.1      haya pccbb_intr_establish(ct, irq, level, func, arg)
   1586  1.21      haya     cardbus_chipset_tag_t ct;
   1587  1.21      haya     int irq, level;
   1588  1.21      haya     int (* func) __P((void *));
   1589  1.21      haya     void *arg;
   1590  1.21      haya {
   1591  1.21      haya     struct pccbb_softc *sc = (struct pccbb_softc *)ct;
   1592  1.21      haya     struct pccbb_intrhand_list *pil, *newpil;
   1593  1.21      haya 
   1594  1.21      haya     if (sc->sc_pil == NULL) {
   1595  1.21      haya 	/* initialise bridge intr routing */
   1596  1.21      haya 
   1597  1.21      haya 	switch (sc->sc_chipset) {
   1598  1.21      haya 	case CB_TI113X:
   1599  1.21      haya 	{
   1600  1.21      haya 	    pcireg_t cbctrl = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CBCTRL);
   1601  1.21      haya 	    cbctrl |= PCI113X_CBCTRL_PCI_INTR; /* functional intr enabled */
   1602  1.21      haya 	    pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_CBCTRL, cbctrl);
   1603  1.21      haya 	    break;
   1604  1.21      haya 	}
   1605  1.21      haya 	default:
   1606  1.21      haya 	    break;
   1607  1.21      haya 	}
   1608  1.21      haya     }
   1609   1.1      haya 
   1610  1.21      haya     /*
   1611  1.21      haya      * Allocate a room for interrut handler structure.
   1612  1.21      haya      */
   1613  1.21      haya     if (NULL == (newpil = (struct pccbb_intrhand_list *)malloc(sizeof(struct pccbb_intrhand_list), M_DEVBUF, M_WAITOK))) {
   1614  1.21      haya 	return NULL;
   1615   1.1      haya     }
   1616   1.1      haya 
   1617  1.21      haya     newpil->pil_func = func;
   1618  1.21      haya     newpil->pil_arg = arg;
   1619  1.21      haya     newpil->pil_next = NULL;
   1620  1.21      haya 
   1621  1.21      haya     if (sc->sc_pil == NULL) {
   1622  1.21      haya 	sc->sc_pil = newpil;
   1623  1.21      haya     } else {
   1624  1.21      haya 	for (pil = sc->sc_pil; pil->pil_next != NULL; pil = pil->pil_next);
   1625  1.21      haya 	pil->pil_next = newpil;
   1626  1.21      haya     }
   1627  1.21      haya 
   1628  1.21      haya     return newpil;
   1629   1.1      haya }
   1630   1.1      haya 
   1631   1.1      haya 
   1632   1.1      haya 
   1633   1.1      haya 
   1634  1.21      haya /*
   1635  1.21      haya  * static void *pccbb_intr_disestablish(cardbus_chipset_tag_t ct,
   1636  1.21      haya  *					void *ih)
   1637  1.21      haya  *
   1638  1.21      haya  *   This function removes an interrupt handler pointed by ih.
   1639  1.21      haya  */
   1640   1.1      haya static void
   1641   1.1      haya pccbb_intr_disestablish(ct, ih)
   1642  1.21      haya     cardbus_chipset_tag_t ct;
   1643  1.21      haya     void *ih;
   1644   1.1      haya {
   1645  1.21      haya     struct pccbb_softc *sc = (struct pccbb_softc *)ct;
   1646  1.21      haya     struct pccbb_intrhand_list *pil, **pil_prev;
   1647  1.21      haya 
   1648  1.21      haya     pil_prev = &sc->sc_pil;
   1649   1.1      haya 
   1650  1.21      haya     for (pil = sc->sc_pil; pil != NULL; pil = pil->pil_next) {
   1651  1.21      haya 	if (pil == ih) {
   1652  1.21      haya 	    *pil_prev = pil->pil_next;
   1653  1.21      haya 	    free(pil, M_DEVBUF);
   1654  1.21      haya 	    break;
   1655  1.21      haya 	}
   1656  1.21      haya 	pil_prev = &pil->pil_next;
   1657  1.21      haya     }
   1658  1.21      haya 
   1659  1.21      haya     if (sc->sc_pil == NULL) {
   1660  1.21      haya 	/* No interrupt handlers */
   1661  1.21      haya 
   1662  1.21      haya 	switch (sc->sc_chipset) {
   1663  1.21      haya 	case CB_TI113X:
   1664  1.21      haya 	{
   1665  1.21      haya 	    pcireg_t cbctrl = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CBCTRL);
   1666  1.21      haya 	    cbctrl &= ~PCI113X_CBCTRL_PCI_INTR; /* functional intr disabled */
   1667  1.21      haya 	    pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_CBCTRL, cbctrl);
   1668  1.21      haya 	    break;
   1669  1.21      haya 	}
   1670  1.21      haya 	default:
   1671  1.21      haya 	    break;
   1672  1.21      haya 	}
   1673   1.1      haya     }
   1674   1.1      haya }
   1675   1.1      haya 
   1676   1.1      haya 
   1677   1.1      haya 
   1678   1.1      haya 
   1679   1.1      haya 
   1680   1.1      haya #if defined SHOW_REGS
   1681   1.1      haya static void
   1682   1.1      haya cb_show_regs(pc, tag, memt, memh)
   1683   1.1      haya      pci_chipset_tag_t pc;
   1684   1.1      haya      pcitag_t tag;
   1685   1.1      haya      bus_space_tag_t memt;
   1686   1.1      haya      bus_space_handle_t memh;
   1687   1.1      haya {
   1688   1.1      haya   int i;
   1689   1.1      haya   printf("PCI config regs:");
   1690   1.1      haya   for (i = 0; i < 0x50; i += 4) {
   1691   1.1      haya     if (i % 16 == 0) {
   1692   1.1      haya       printf("\n 0x%02x:", i);
   1693   1.1      haya     }
   1694   1.1      haya     printf(" %08x", pci_conf_read(pc, tag, i));
   1695   1.1      haya   }
   1696   1.1      haya   for (i = 0x80; i < 0xb0; i += 4) {
   1697   1.1      haya     if (i % 16 == 0) {
   1698   1.1      haya       printf("\n 0x%02x:", i);
   1699   1.1      haya     }
   1700   1.1      haya     printf(" %08x", pci_conf_read(pc, tag, i));
   1701   1.1      haya   }
   1702   1.1      haya 
   1703   1.1      haya   if (memh == 0) {
   1704   1.1      haya     printf("\n");
   1705   1.1      haya     return;
   1706   1.1      haya   }
   1707   1.1      haya 
   1708   1.1      haya   printf("\nsocket regs:");
   1709   1.1      haya   for (i = 0; i <= 0x10; i += 0x04) {
   1710   1.1      haya     printf(" %08x", bus_space_read_4(memt, memh, i));
   1711   1.1      haya   }
   1712   1.1      haya   printf("\nExCA regs:");
   1713   1.1      haya   for (i = 0; i < 0x08; ++i) {
   1714   1.1      haya     printf(" %02x", bus_space_read_1(memt, memh, 0x800 + i));
   1715   1.1      haya   }
   1716   1.1      haya   printf("\n");
   1717   1.1      haya   return;
   1718   1.1      haya }
   1719   1.1      haya #endif
   1720   1.1      haya 
   1721   1.1      haya 
   1722   1.1      haya 
   1723   1.4      haya /*
   1724   1.4      haya  * static cardbustag_t pccbb_make_tag(cardbus_chipset_tag_t cc,
   1725   1.4      haya  *                                    int busno, int devno, int function)
   1726   1.4      haya  *   This is the function to make a tag to access config space of
   1727   1.4      haya  *  a CardBus Card.  It works same as pci_conf_read.
   1728   1.4      haya  */
   1729   1.1      haya static cardbustag_t
   1730   1.1      haya pccbb_make_tag(cc, busno, devno, function)
   1731   1.1      haya      cardbus_chipset_tag_t cc;
   1732   1.1      haya      int busno, devno, function;
   1733   1.1      haya {
   1734   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)cc;
   1735   1.1      haya 
   1736   1.1      haya   return pci_make_tag(sc->sc_pc, busno, devno, function);
   1737   1.1      haya }
   1738   1.1      haya 
   1739   1.1      haya 
   1740   1.1      haya static void
   1741   1.1      haya pccbb_free_tag(cc, tag)
   1742   1.1      haya      cardbus_chipset_tag_t cc;
   1743   1.1      haya      cardbustag_t tag;
   1744   1.1      haya {
   1745   1.1      haya }
   1746   1.1      haya 
   1747   1.1      haya 
   1748   1.4      haya /*
   1749   1.4      haya  * static cardbusreg_t pccbb_conf_read(cardbus_chipset_tag_t cc,
   1750   1.4      haya  *                                     cardbustag_t tag, int offset)
   1751   1.4      haya  *   This is the function to read the config space of a CardBus Card.
   1752   1.4      haya  *  It works same as pci_conf_read.
   1753   1.4      haya  */
   1754   1.1      haya static cardbusreg_t
   1755   1.1      haya pccbb_conf_read(cc, tag, offset)
   1756   1.1      haya      cardbus_chipset_tag_t cc;
   1757   1.1      haya      cardbustag_t tag;
   1758   1.1      haya      int offset;		/* register offset */
   1759   1.1      haya {
   1760   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)cc;
   1761   1.1      haya 
   1762   1.1      haya   return pci_conf_read(sc->sc_pc, tag, offset);
   1763   1.1      haya }
   1764   1.1      haya 
   1765   1.1      haya 
   1766   1.1      haya 
   1767   1.4      haya /*
   1768   1.4      haya  * static void pccbb_conf_write(cardbus_chipset_tag_t cc, cardbustag_t tag,
   1769   1.4      haya  *                              int offs, cardbusreg_t val)
   1770   1.4      haya  *   This is the function to write the config space of a CardBus Card.
   1771   1.4      haya  *  It works same as pci_conf_write.
   1772   1.4      haya  */
   1773   1.1      haya static void
   1774   1.1      haya pccbb_conf_write(cc, tag, reg, val)
   1775   1.1      haya      cardbus_chipset_tag_t cc;
   1776   1.1      haya      cardbustag_t tag;
   1777   1.1      haya      int reg;			/* register offset */
   1778   1.1      haya      cardbusreg_t val;
   1779   1.1      haya {
   1780   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)cc;
   1781   1.1      haya 
   1782   1.1      haya   pci_conf_write(sc->sc_pc, tag, reg, val);
   1783   1.1      haya }
   1784   1.1      haya 
   1785   1.1      haya 
   1786   1.1      haya 
   1787   1.1      haya 
   1788   1.1      haya 
   1789   1.1      haya #if 0
   1790   1.1      haya STATIC int
   1791   1.1      haya pccbb_new_pcmcia_io_alloc(pcmcia_chipset_handle_t pch,
   1792   1.1      haya                           bus_addr_t start, bus_size_t size,
   1793   1.1      haya                           bus_size_t align, bus_addr_t mask, /* address line width */
   1794   1.1      haya                           int speed, int flags,	/* bus width */
   1795   1.1      haya                           bus_space_handle_t *iohp)
   1796   1.1      haya #endif
   1797   1.1      haya 
   1798   1.1      haya 
   1799   1.4      haya /*
   1800   1.4      haya  * STATIC int pccbb_pcmcia_io_alloc(pcmcia_chipset_handle_t pch,
   1801   1.4      haya  *                                  bus_addr_t start, bus_size_t size,
   1802   1.4      haya  *                                  bus_size_t align,
   1803   1.4      haya  *                                  struct pcmcia_io_handle *pcihp
   1804   1.4      haya  *
   1805   1.4      haya  * This function only allocates I/O region for pccard. This function
   1806   1.4      haya  * never maps the allcated region to pccard I/O area.
   1807   1.4      haya  *
   1808   1.4      haya  * XXX: The interface of this function is not very good, I believe.
   1809   1.4      haya  */
   1810   1.1      haya STATIC int
   1811   1.1      haya pccbb_pcmcia_io_alloc(pch, start, size, align, pcihp)
   1812   1.1      haya      pcmcia_chipset_handle_t pch;
   1813   1.1      haya      bus_addr_t start;	/* start address */
   1814   1.1      haya      bus_size_t size;
   1815   1.1      haya      bus_size_t align;
   1816   1.1      haya      struct pcmcia_io_handle *pcihp;
   1817   1.1      haya {
   1818   1.1      haya   struct pcic_handle *ph = (struct pcic_handle *)pch;
   1819   1.1      haya   bus_addr_t ioaddr;
   1820   1.1      haya   int flags = 0;
   1821   1.1      haya   bus_space_tag_t iot;
   1822   1.1      haya   bus_space_handle_t ioh;
   1823   1.1      haya #if rbus
   1824   1.1      haya   rbus_tag_t rb;
   1825   1.1      haya #endif
   1826   1.1      haya   if (align == 0) {
   1827   1.1      haya     align = size;		/* XXX: funny??? */
   1828   1.1      haya   }
   1829   1.1      haya 
   1830   1.1      haya 
   1831   1.1      haya   /*
   1832   1.1      haya    * Allocate some arbitrary I/O space.
   1833   1.1      haya    */
   1834   1.1      haya 
   1835   1.1      haya   iot = ((struct pccbb_softc *)(ph->ph_parent))->sc_iot;
   1836   1.1      haya 
   1837   1.1      haya #if rbus
   1838   1.1      haya   rb = ((struct pccbb_softc *)(ph->ph_parent))->sc_rbus_iot;
   1839   1.1      haya   if (rbus_space_alloc(rb, start, size, 0x3ff /* XXX: I assume all card decode lower 10 bits by its hardware */,
   1840   1.1      haya 		       align, 0, &ioaddr, &ioh)) {
   1841   1.1      haya     return 1;
   1842   1.1      haya   }
   1843   1.1      haya #else
   1844   1.1      haya   if (start) {
   1845   1.1      haya     ioaddr = start;
   1846   1.1      haya     if (bus_space_map(iot, start, size, 0, &ioh)) {
   1847   1.1      haya       return 1;
   1848   1.1      haya     }
   1849   1.1      haya     DPRINTF(("pccbb_pcmcia_io_alloc map port %lx+%lx\n",
   1850   1.1      haya 	     (u_long) ioaddr, (u_long) size));
   1851   1.1      haya   } else {
   1852   1.1      haya     flags |= PCMCIA_IO_ALLOCATED;
   1853   1.1      haya     if (bus_space_alloc(iot, 0x700/* ph->sc->sc_iobase */,
   1854   1.1      haya 			0x800/* ph->sc->sc_iobase + ph->sc->sc_iosize*/,
   1855   1.1      haya 			size, align, 0, 0, &ioaddr, &ioh)) {
   1856   1.1      haya       /* No room be able to be get. */
   1857   1.1      haya       return 1;
   1858   1.1      haya     }
   1859   1.1      haya     DPRINTF(("pccbb_pcmmcia_io_alloc alloc port 0x%lx+0x%lx\n",
   1860   1.1      haya 	     (u_long) ioaddr, (u_long) size));
   1861   1.1      haya   }
   1862   1.1      haya #endif
   1863   1.1      haya 
   1864   1.1      haya   pcihp->iot = iot;
   1865   1.1      haya   pcihp->ioh = ioh;
   1866   1.1      haya   pcihp->addr = ioaddr;
   1867   1.1      haya   pcihp->size = size;
   1868   1.1      haya   pcihp->flags = flags;
   1869   1.1      haya 
   1870   1.1      haya   return 0;
   1871   1.1      haya }
   1872   1.1      haya 
   1873   1.1      haya 
   1874   1.1      haya 
   1875   1.1      haya 
   1876   1.1      haya 
   1877   1.4      haya /*
   1878   1.4      haya  * STATIC int pccbb_pcmcia_io_free(pcmcia_chipset_handle_t pch,
   1879   1.4      haya  *                                 struct pcmcia_io_handle *pcihp)
   1880   1.4      haya  *
   1881   1.4      haya  * This function only frees I/O region for pccard.
   1882   1.4      haya  *
   1883   1.4      haya  * XXX: The interface of this function is not very good, I believe.
   1884   1.4      haya  */
   1885   1.1      haya void
   1886   1.1      haya pccbb_pcmcia_io_free(pch, pcihp)
   1887   1.1      haya      pcmcia_chipset_handle_t pch;
   1888   1.1      haya      struct pcmcia_io_handle *pcihp;
   1889   1.1      haya {
   1890   1.1      haya #if !rbus
   1891   1.1      haya   bus_space_tag_t iot = pcihp->iot;
   1892   1.1      haya #endif
   1893   1.1      haya   bus_space_handle_t ioh = pcihp->ioh;
   1894   1.1      haya   bus_size_t size = pcihp->size;
   1895   1.1      haya 
   1896   1.1      haya #if rbus
   1897   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)((struct pcic_handle *)pch)->ph_parent;
   1898   1.1      haya   rbus_tag_t rb = sc->sc_rbus_iot;
   1899   1.1      haya 
   1900   1.1      haya   rbus_space_free(rb, ioh, size, NULL);
   1901   1.1      haya #else
   1902   1.1      haya   if (pcihp->flags & PCMCIA_IO_ALLOCATED)
   1903   1.1      haya     bus_space_free(iot, ioh, size);
   1904   1.1      haya   else
   1905   1.1      haya     bus_space_unmap(iot, ioh, size);
   1906   1.1      haya #endif
   1907   1.1      haya }
   1908   1.1      haya 
   1909   1.1      haya 
   1910   1.1      haya 
   1911   1.4      haya /*
   1912   1.4      haya  * STATIC int pccbb_pcmcia_io_map(pcmcia_chipset_handle_t pch, int width,
   1913   1.4      haya  *                                bus_addr_t offset, bus_size_t size,
   1914   1.4      haya  *                                struct pcmcia_io_handle *pcihp,
   1915   1.4      haya  *                                int *windowp)
   1916   1.4      haya  *
   1917   1.4      haya  * This function maps the allocated I/O region to pccard. This function
   1918   1.4      haya  * never allocates any I/O region for pccard I/O area.  I don't
   1919   1.4      haya  * understand why the original authors of pcmciabus separated alloc and
   1920   1.4      haya  * map.  I believe the two must be unite.
   1921   1.4      haya  *
   1922   1.4      haya  * XXX: no wait timing control?
   1923   1.4      haya  */
   1924   1.1      haya int
   1925   1.1      haya pccbb_pcmcia_io_map(pch, width, offset, size, pcihp, windowp)
   1926   1.1      haya      pcmcia_chipset_handle_t pch;
   1927   1.1      haya      int width;
   1928   1.1      haya      bus_addr_t offset;
   1929   1.1      haya      bus_size_t size;
   1930   1.1      haya      struct pcmcia_io_handle *pcihp;
   1931   1.1      haya      int *windowp;
   1932   1.1      haya {
   1933   1.1      haya   struct pcic_handle *ph = (struct pcic_handle *) pch;
   1934   1.1      haya   bus_addr_t ioaddr = pcihp->addr + offset;
   1935   1.1      haya   int i, win;
   1936   1.1      haya #if defined CBB_DEBUG
   1937   1.1      haya   static char *width_names[] = { "dynamic", "io8", "io16" };
   1938   1.1      haya #endif
   1939   1.1      haya 
   1940   1.1      haya   /* Sanity check I/O handle. */
   1941   1.1      haya 
   1942   1.1      haya   if (((struct pccbb_softc *)ph->ph_parent)->sc_iot != pcihp->iot) {
   1943   1.1      haya     panic("pccbb_pcmcia_io_map iot is bogus");
   1944   1.1      haya   }
   1945   1.1      haya 
   1946   1.1      haya   /* XXX Sanity check offset/size. */
   1947   1.1      haya 
   1948   1.1      haya   win = -1;
   1949   1.1      haya   for (i = 0; i < PCIC_IO_WINS; i++) {
   1950   1.1      haya     if ((ph->ioalloc & (1 << i)) == 0) {
   1951   1.1      haya       win = i;
   1952   1.1      haya       ph->ioalloc |= (1 << i);
   1953   1.1      haya       break;
   1954   1.1      haya     }
   1955   1.1      haya   }
   1956   1.1      haya 
   1957   1.1      haya   if (win == -1) {
   1958   1.1      haya     return 1;
   1959   1.1      haya   }
   1960   1.1      haya 
   1961   1.1      haya   *windowp = win;
   1962   1.1      haya 
   1963   1.1      haya   /* XXX this is pretty gross */
   1964   1.1      haya 
   1965   1.1      haya   DPRINTF(("pccbb_pcmcia_io_map window %d %s port %lx+%lx\n",
   1966   1.1      haya 	   win, width_names[width], (u_long) ioaddr, (u_long) size));
   1967   1.1      haya 
   1968   1.1      haya   /* XXX wtf is this doing here? */
   1969   1.1      haya 
   1970   1.1      haya #if 0
   1971   1.1      haya   printf(" port 0x%lx", (u_long) ioaddr);
   1972   1.1      haya   if (size > 1) {
   1973   1.1      haya     printf("-0x%lx", (u_long) ioaddr + (u_long) size - 1);
   1974   1.1      haya   }
   1975   1.1      haya #endif
   1976   1.1      haya 
   1977   1.1      haya   ph->io[win].addr = ioaddr;
   1978   1.1      haya   ph->io[win].size = size;
   1979   1.1      haya   ph->io[win].width = width;
   1980   1.1      haya 
   1981   1.1      haya   /* actual dirty register-value changing in the function below. */
   1982   1.1      haya   pccbb_pcmcia_do_io_map(ph, win);
   1983   1.1      haya 
   1984   1.1      haya   return 0;
   1985   1.1      haya }
   1986   1.1      haya 
   1987   1.1      haya 
   1988   1.1      haya 
   1989   1.4      haya /*
   1990   1.4      haya  * STATIC void pccbb_pcmcia_do_io_map(struct pcic_handle *h, int win)
   1991   1.4      haya  *
   1992   1.4      haya  * This function changes register-value to map I/O region for pccard.
   1993   1.4      haya  */
   1994   1.1      haya static void
   1995   1.1      haya pccbb_pcmcia_do_io_map(ph, win)
   1996   1.1      haya      struct pcic_handle *ph;
   1997   1.1      haya      int win;
   1998   1.1      haya {
   1999   1.1      haya   static u_int8_t pcic_iowidth[3] = {
   2000   1.1      haya     PCIC_IOCTL_IO0_IOCS16SRC_CARD,
   2001   1.1      haya     PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE | PCIC_IOCTL_IO0_DATASIZE_8BIT,
   2002   1.1      haya     PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE | PCIC_IOCTL_IO0_DATASIZE_16BIT,
   2003   1.1      haya   };
   2004   1.1      haya 
   2005   1.1      haya #define PCIC_SIA_START_LOW 0
   2006   1.1      haya #define PCIC_SIA_START_HIGH 1
   2007   1.1      haya #define PCIC_SIA_STOP_LOW 2
   2008   1.1      haya #define PCIC_SIA_STOP_HIGH 3
   2009   1.1      haya 
   2010   1.1      haya   int regbase_win = 0x8 + win*0x04;
   2011   1.1      haya   u_int8_t ioctl, enable;
   2012   1.1      haya 
   2013   1.1      haya   DPRINTF(("pccbb_pcmcia_do_io_map win %d addr 0x%lx size 0x%lx width %d\n",
   2014   1.1      haya 	   win, (long) ph->io[win].addr, (long) ph->io[win].size,
   2015   1.1      haya 	   ph->io[win].width * 8));
   2016   1.1      haya 
   2017   1.1      haya   Pcic_write(ph, regbase_win + PCIC_SIA_START_LOW,
   2018   1.1      haya 		     ph->io[win].addr & 0xff);
   2019   1.1      haya   Pcic_write(ph, regbase_win + PCIC_SIA_START_HIGH,
   2020   1.1      haya 		     (ph->io[win].addr >> 8) & 0xff);
   2021   1.1      haya 
   2022   1.1      haya   Pcic_write(ph, regbase_win + PCIC_SIA_STOP_LOW,
   2023   1.1      haya 	     (ph->io[win].addr + ph->io[win].size - 1) & 0xff);
   2024   1.1      haya   Pcic_write(ph, regbase_win + PCIC_SIA_STOP_HIGH,
   2025   1.1      haya 	     ((ph->io[win].addr + ph->io[win].size - 1) >> 8) & 0xff);
   2026   1.1      haya 
   2027   1.1      haya   ioctl = Pcic_read(ph, PCIC_IOCTL);
   2028   1.1      haya   enable = Pcic_read(ph, PCIC_ADDRWIN_ENABLE);
   2029   1.1      haya   switch (win) {
   2030   1.1      haya   case 0:
   2031   1.1      haya     ioctl &= ~(PCIC_IOCTL_IO0_WAITSTATE | PCIC_IOCTL_IO0_ZEROWAIT |
   2032   1.1      haya 		PCIC_IOCTL_IO0_IOCS16SRC_MASK | PCIC_IOCTL_IO0_DATASIZE_MASK);
   2033   1.1      haya     ioctl |= pcic_iowidth[ph->io[win].width];
   2034   1.1      haya     enable |= PCIC_ADDRWIN_ENABLE_IO0;
   2035   1.1      haya     break;
   2036   1.1      haya   case 1:
   2037   1.1      haya     ioctl &= ~(PCIC_IOCTL_IO1_WAITSTATE | PCIC_IOCTL_IO1_ZEROWAIT |
   2038   1.1      haya 		PCIC_IOCTL_IO1_IOCS16SRC_MASK | PCIC_IOCTL_IO1_DATASIZE_MASK);
   2039   1.1      haya     ioctl |= (pcic_iowidth[ph->io[win].width] << 4);
   2040   1.1      haya     enable |= PCIC_ADDRWIN_ENABLE_IO1;
   2041   1.1      haya     break;
   2042   1.1      haya   }
   2043   1.1      haya   Pcic_write(ph, PCIC_IOCTL, ioctl);
   2044   1.1      haya   Pcic_write(ph, PCIC_ADDRWIN_ENABLE, enable);
   2045   1.1      haya #if defined CBB_DEBUG
   2046   1.1      haya   {
   2047   1.1      haya     u_int8_t start_low = Pcic_read(ph, regbase_win + PCIC_SIA_START_LOW);
   2048   1.1      haya     u_int8_t start_high = Pcic_read(ph, regbase_win + PCIC_SIA_START_HIGH);
   2049   1.1      haya     u_int8_t stop_low = Pcic_read(ph, regbase_win + PCIC_SIA_STOP_LOW);
   2050   1.1      haya     u_int8_t stop_high = Pcic_read(ph, regbase_win + PCIC_SIA_STOP_HIGH);
   2051   1.1      haya     printf(" start %02x %02x, stop %02x %02x, ioctl %02x enable %02x\n",
   2052   1.1      haya 	   start_low, start_high, stop_low, stop_high, ioctl, enable);
   2053   1.1      haya   }
   2054   1.1      haya #endif
   2055   1.1      haya }
   2056   1.1      haya 
   2057   1.1      haya 
   2058   1.1      haya 
   2059   1.4      haya /*
   2060   1.4      haya  * STATIC void pccbb_pcmcia_io_unmap(pcmcia_chipset_handle_t *h, int win)
   2061   1.4      haya  *
   2062   1.4      haya  * This function unmapss I/O region.  No return value.
   2063   1.4      haya  */
   2064   1.1      haya STATIC void
   2065   1.1      haya pccbb_pcmcia_io_unmap(pch, win)
   2066   1.1      haya      pcmcia_chipset_handle_t pch;
   2067   1.1      haya      int win;
   2068   1.1      haya {
   2069   1.1      haya   struct pcic_handle *ph = (struct pcic_handle *)pch;
   2070   1.1      haya   int reg;
   2071   1.1      haya 
   2072   1.1      haya   if (win >= PCIC_IO_WINS || win < 0) {
   2073   1.1      haya     panic("pccbb_pcmcia_io_unmap: window out of range");
   2074   1.1      haya   }
   2075   1.1      haya 
   2076   1.1      haya   reg = Pcic_read(ph, PCIC_ADDRWIN_ENABLE);
   2077   1.1      haya   switch (win) {
   2078   1.1      haya   case 0:
   2079   1.1      haya     reg &= ~PCIC_ADDRWIN_ENABLE_IO0;
   2080   1.1      haya     break;
   2081   1.1      haya   case 1:
   2082   1.1      haya     reg &= ~PCIC_ADDRWIN_ENABLE_IO1;
   2083   1.1      haya     break;
   2084   1.1      haya   }
   2085   1.1      haya   Pcic_write(ph, PCIC_ADDRWIN_ENABLE, reg);
   2086   1.1      haya 
   2087   1.1      haya   ph->ioalloc &= ~(1 << win);
   2088   1.1      haya }
   2089   1.1      haya 
   2090   1.1      haya 
   2091   1.1      haya 
   2092   1.1      haya 
   2093   1.1      haya 
   2094   1.4      haya /*
   2095   1.4      haya  * static void pccbb_pcmcia_wait_ready(struct pcic_handle *ph)
   2096   1.4      haya  *
   2097   1.4      haya  * This function enables the card.  All information is stored in
   2098   1.4      haya  * the first argument, pcmcia_chipset_handle_t.
   2099   1.4      haya  */
   2100   1.1      haya static void
   2101   1.1      haya pccbb_pcmcia_wait_ready(ph)
   2102   1.1      haya      struct pcic_handle *ph;
   2103   1.1      haya {
   2104   1.1      haya   int i;
   2105   1.1      haya 
   2106   1.1      haya   DPRINTF(("pccbb_pcmcia_wait_ready: status 0x%02x\n",
   2107   1.1      haya 	   Pcic_read(ph, PCIC_IF_STATUS)));
   2108   1.1      haya 
   2109   1.1      haya   for (i = 0; i < 10000; i++) {
   2110   1.1      haya     if (Pcic_read(ph, PCIC_IF_STATUS) & PCIC_IF_STATUS_READY) {
   2111   1.1      haya       return;
   2112   1.1      haya     }
   2113   1.1      haya     delay(500);
   2114   1.1      haya #ifdef CBB_DEBUG
   2115   1.1      haya     if ((i > 5000) && (i%100 == 99))
   2116   1.1      haya       printf(".");
   2117   1.1      haya #endif
   2118   1.1      haya   }
   2119   1.1      haya 
   2120   1.1      haya #ifdef DIAGNOSTIC
   2121   1.1      haya   printf("pcic_wait_ready: ready never happened, status = %02x\n",
   2122   1.1      haya 	 Pcic_read(ph, PCIC_IF_STATUS));
   2123   1.1      haya #endif
   2124   1.1      haya }
   2125   1.1      haya 
   2126   1.1      haya 
   2127   1.1      haya 
   2128   1.4      haya /*
   2129   1.4      haya  * STATIC void pccbb_pcmcia_socket_enable(pcmcia_chipset_handle_t pch)
   2130   1.4      haya  *
   2131   1.4      haya  * This function enables the card.  All information is stored in
   2132   1.4      haya  * the first argument, pcmcia_chipset_handle_t.
   2133   1.4      haya  */
   2134   1.1      haya STATIC void
   2135   1.1      haya pccbb_pcmcia_socket_enable(pch)
   2136   1.1      haya      pcmcia_chipset_handle_t pch;
   2137   1.1      haya {
   2138   1.1      haya   struct pcic_handle *ph = (struct pcic_handle *)pch;
   2139   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
   2140   1.1      haya   int cardtype, win;
   2141   1.1      haya   u_int8_t power, intr;
   2142   1.1      haya   pcireg_t spsr;
   2143   1.1      haya   int voltage;
   2144   1.1      haya #define PCIC_INTR_PCI PCIC_INTR_ENABLE
   2145   1.1      haya 
   2146   1.1      haya   /* this bit is mostly stolen from pcic_attach_card */
   2147   1.1      haya 
   2148  1.11      joda   DPRINTF(("pccbb_pcmcia_socket_enable: "));
   2149   1.1      haya 
   2150   1.1      haya   /* get card Vcc info */
   2151   1.1      haya 
   2152   1.1      haya   spsr = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh, CB_SOCKET_STAT);
   2153   1.1      haya   if (spsr & CB_SOCKET_STAT_5VCARD) {
   2154   1.4      haya     DPRINTF(("5V card\n"));
   2155   1.1      haya     voltage = CARDBUS_VCC_5V | CARDBUS_VPP_VCC;
   2156   1.1      haya   } else if (spsr & CB_SOCKET_STAT_3VCARD) {
   2157   1.4      haya     DPRINTF(("3V card\n"));
   2158   1.1      haya     voltage = CARDBUS_VCC_3V | CARDBUS_VPP_VCC;
   2159   1.1      haya   } else {
   2160   1.1      haya     printf("?V card, 0x%x\n", spsr);	/* XXX */
   2161   1.1      haya     return;
   2162   1.1      haya   }
   2163   1.1      haya 
   2164   1.1      haya   /* assert reset bit */
   2165  1.18    chopps   intr = Pcic_read(ph, PCIC_INTR);
   2166  1.18    chopps   intr &= ~(PCIC_INTR_RESET|PCIC_INTR_ENABLE|PCIC_INTR_CARDTYPE_MASK);
   2167   1.1      haya   Pcic_write(ph, PCIC_INTR, intr);
   2168   1.1      haya 
   2169   1.1      haya   /* disable socket i/o: negate output enable bit */
   2170   1.1      haya 
   2171   1.1      haya   power = Pcic_read(ph, PCIC_PWRCTL);
   2172   1.1      haya   power &= ~PCIC_PWRCTL_OE;
   2173   1.1      haya   Pcic_write(ph, PCIC_PWRCTL, power);
   2174   1.1      haya 
   2175   1.1      haya   /* power down the socket to reset it, clear the card reset pin */
   2176   1.1      haya 
   2177   1.1      haya   pccbb_power(sc, CARDBUS_VCC_0V | CARDBUS_VPP_0V);
   2178   1.1      haya 
   2179   1.1      haya   /*
   2180   1.1      haya    * wait 200ms until power fails (Tpf).  Then, wait 100ms since
   2181   1.1      haya    * we are changing Vcc (Toff).
   2182   1.1      haya    */
   2183   1.1      haya   /* delay(300*1000); too much */
   2184   1.1      haya 
   2185   1.1      haya   /* power up the socket */
   2186   1.1      haya   pccbb_power(sc, voltage);
   2187   1.1      haya 
   2188   1.1      haya   /*
   2189   1.1      haya    * wait 100ms until power raise (Tpr) and 20ms to become
   2190   1.1      haya    * stable (Tsu(Vcc)).
   2191   1.1      haya    *
   2192   1.1      haya    * some machines require some more time to be settled
   2193   1.1      haya    * (another 200ms is added here).
   2194   1.1      haya    */
   2195   1.1      haya   /* delay((100 + 20 + 200)*1000); too much */
   2196   1.1      haya 
   2197   1.1      haya   power = Pcic_read(ph, PCIC_PWRCTL);
   2198  1.18    chopps   power |= PCIC_PWRCTL_OE;
   2199  1.18    chopps   Pcic_write(ph, PCIC_PWRCTL, power);
   2200   1.1      haya 
   2201   1.1      haya   /*
   2202   1.1      haya    * hold RESET at least 10us.
   2203   1.1      haya    */
   2204   1.1      haya   delay(10);
   2205   1.1      haya   delay(2*1000);		/* XXX: TI1130 requires it. */
   2206   1.1      haya   delay(20*1000);		/* XXX: TI1130 requires it. */
   2207   1.1      haya 
   2208   1.1      haya   /* clear the reset flag */
   2209   1.1      haya 
   2210  1.18    chopps   intr |= PCIC_INTR_RESET;
   2211  1.18    chopps   Pcic_write(ph, PCIC_INTR, intr);
   2212   1.1      haya 
   2213   1.1      haya   /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */
   2214   1.1      haya 
   2215   1.1      haya   delay(20000);
   2216   1.1      haya 
   2217   1.1      haya   /* wait for the chip to finish initializing */
   2218   1.1      haya 
   2219   1.1      haya   pccbb_pcmcia_wait_ready(ph);
   2220   1.1      haya 
   2221   1.1      haya   /* zero out the address windows */
   2222   1.1      haya 
   2223   1.1      haya   Pcic_write(ph, PCIC_ADDRWIN_ENABLE, 0);
   2224   1.1      haya 
   2225   1.1      haya   /* set the card type */
   2226   1.1      haya 
   2227   1.1      haya   cardtype = pcmcia_card_gettype(ph->pcmcia);
   2228   1.1      haya 
   2229  1.18    chopps   intr |= PCIC_INTR_PCI;
   2230   1.1      haya   intr |= ((cardtype == PCMCIA_IFTYPE_IO) ?
   2231   1.1      haya 	   PCIC_INTR_CARDTYPE_IO :
   2232   1.1      haya 	   PCIC_INTR_CARDTYPE_MEM);
   2233   1.1      haya   Pcic_write(ph, PCIC_INTR, intr);
   2234   1.1      haya 
   2235   1.1      haya   DPRINTF(("%s: pccbb_pcmcia_socket_enable %02x cardtype %s %02x\n",
   2236   1.1      haya 	   ph->ph_parent->dv_xname, ph->sock,
   2237   1.1      haya 	   ((cardtype == PCMCIA_IFTYPE_IO) ? "io" : "mem"), intr));
   2238   1.1      haya 
   2239   1.1      haya   /* reinstall all the memory and io mappings */
   2240   1.1      haya 
   2241   1.1      haya   for (win = 0; win < PCIC_MEM_WINS; ++win) {
   2242   1.1      haya     if (ph->memalloc & (1 << win)) {
   2243   1.1      haya       pccbb_pcmcia_do_mem_map(ph, win);
   2244   1.1      haya     }
   2245   1.1      haya   }
   2246   1.1      haya 
   2247   1.1      haya   for (win = 0; win < PCIC_IO_WINS; ++win) {
   2248   1.1      haya     if (ph->ioalloc & (1 << win)) {
   2249   1.1      haya       pccbb_pcmcia_do_io_map(ph, win);
   2250   1.1      haya     }
   2251   1.1      haya   }
   2252   1.1      haya }
   2253   1.1      haya 
   2254   1.1      haya 
   2255   1.1      haya 
   2256   1.4      haya /*
   2257   1.4      haya  * STATIC void pccbb_pcmcia_socket_disable(pcmcia_chipset_handle_t *ph)
   2258   1.4      haya  *
   2259   1.4      haya  * This function disables the card.  All information is stored in
   2260   1.4      haya  * the first argument, pcmcia_chipset_handle_t.
   2261   1.4      haya  */
   2262   1.1      haya STATIC void
   2263   1.1      haya pccbb_pcmcia_socket_disable(pch)
   2264   1.1      haya      pcmcia_chipset_handle_t pch;
   2265   1.1      haya {
   2266   1.1      haya   struct pcic_handle *ph = (struct pcic_handle *)pch;
   2267   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
   2268   1.1      haya   u_int8_t power, intr;
   2269   1.1      haya 
   2270   1.1      haya   DPRINTF(("pccbb_pcmcia_socket_disable\n"));
   2271   1.1      haya 
   2272   1.1      haya   /* reset signal asserting... */
   2273   1.1      haya 
   2274   1.1      haya   intr = Pcic_read(ph, PCIC_INTR);
   2275  1.18    chopps   intr &= ~(PCIC_INTR_RESET|PCIC_INTR_ENABLE|PCIC_INTR_CARDTYPE_MASK);
   2276   1.1      haya   Pcic_write(ph, PCIC_INTR, intr);
   2277   1.1      haya   delay(2*1000);
   2278   1.1      haya 
   2279   1.1      haya   /* power down the socket */
   2280   1.1      haya   power = Pcic_read(ph, PCIC_PWRCTL);
   2281   1.1      haya   power &= ~PCIC_PWRCTL_OE;
   2282   1.1      haya   Pcic_write(ph, PCIC_PWRCTL, power);
   2283   1.1      haya   pccbb_power(sc, CARDBUS_VCC_0V | CARDBUS_VPP_0V);
   2284   1.1      haya   /*
   2285   1.1      haya    * wait 300ms until power fails (Tpf).
   2286   1.1      haya    */
   2287   1.1      haya   delay(300 * 1000);
   2288   1.1      haya }
   2289   1.1      haya 
   2290   1.1      haya 
   2291   1.1      haya 
   2292   1.4      haya /*
   2293   1.1      haya  * STATIC int pccbb_pcmcia_card_detect(pcmcia_chipset_handle_t *ph)
   2294   1.1      haya  *
   2295   1.1      haya  * This function detects whether a card is in the slot or not.
   2296   1.1      haya  * If a card is inserted, return 1.  Otherwise, return 0.
   2297   1.4      haya  */
   2298   1.1      haya STATIC int
   2299   1.1      haya pccbb_pcmcia_card_detect(pch)
   2300   1.1      haya      pcmcia_chipset_handle_t pch;
   2301   1.1      haya {
   2302   1.1      haya   struct pcic_handle *ph = (struct pcic_handle *)pch;
   2303   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
   2304   1.1      haya 
   2305   1.1      haya   DPRINTF(("pccbb_pcmcia_card_detect\n"));
   2306   1.1      haya   return pccbb_detect_card(sc) == 1 ? 1 : 0;
   2307   1.1      haya }
   2308   1.1      haya 
   2309   1.1      haya 
   2310   1.1      haya 
   2311   1.1      haya #if 0
   2312   1.1      haya STATIC int
   2313   1.1      haya pccbb_new_pcmcia_mem_alloc(pcmcia_chipset_handle_t pch,
   2314   1.1      haya 			   bus_addr_t start, bus_size_t size,
   2315   1.1      haya 			   bus_size_t align,
   2316   1.1      haya 			   int speed, int flags,	/* bus width */
   2317   1.1      haya 			   bus_space_tag_t *memtp
   2318   1.1      haya 			   bus_space_handle_t *memhp)
   2319   1.1      haya #endif
   2320   1.1      haya 
   2321   1.1      haya 
   2322   1.4      haya /*
   2323   1.4      haya  * STATIC int pccbb_pcmcia_mem_alloc(pcmcia_chipset_handle_t pch,
   2324   1.4      haya  *                                   bus_size_t size,
   2325   1.4      haya  *                                   struct pcmcia_mem_handle *pcmhp)
   2326   1.4      haya  *
   2327   1.4      haya  * This function only allocates memory region for pccard. This
   2328   1.4      haya  * function never maps the allcated region to pccard memory area.
   2329   1.4      haya  *
   2330   1.4      haya  * XXX: Why the argument of start address is not in?
   2331   1.4      haya  */
   2332   1.1      haya STATIC int
   2333   1.1      haya pccbb_pcmcia_mem_alloc(pch, size, pcmhp)
   2334   1.1      haya      pcmcia_chipset_handle_t pch;
   2335   1.1      haya      bus_size_t size;
   2336   1.1      haya      struct pcmcia_mem_handle *pcmhp;
   2337   1.1      haya {
   2338   1.1      haya   struct pcic_handle *ph = (struct pcic_handle *)pch;
   2339   1.1      haya   bus_space_handle_t memh;
   2340   1.1      haya   bus_addr_t addr;
   2341   1.1      haya   bus_size_t sizepg;
   2342   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
   2343   1.1      haya #if rbus
   2344   1.1      haya   rbus_tag_t rb;
   2345   1.1      haya #endif
   2346   1.1      haya 
   2347   1.1      haya   /* out of sc->memh, allocate as many pages as necessary */
   2348   1.1      haya 
   2349   1.1      haya   /* convert size to PCIC pages */
   2350   1.1      haya   /*
   2351   1.1      haya      This is not enough; when the requested region is on the
   2352   1.1      haya      page boundaries, this may calculate wrong result.
   2353   1.1      haya    */
   2354   1.1      haya   sizepg = (size + (PCIC_MEM_PAGESIZE - 1)) / PCIC_MEM_PAGESIZE;
   2355   1.1      haya #if 0
   2356   1.1      haya   if (sizepg > PCIC_MAX_MEM_PAGES) {
   2357   1.1      haya     return 1;
   2358   1.1      haya   }
   2359   1.1      haya #endif
   2360   1.1      haya 
   2361   1.1      haya   if (!(sc->sc_pcmcia_flags & PCCBB_PCMCIA_MEM_32)) {
   2362   1.1      haya     return 1;
   2363   1.1      haya   }
   2364   1.1      haya 
   2365   1.1      haya   addr = 0;		/* XXX gcc -Wuninitialized */
   2366   1.1      haya 
   2367   1.1      haya #if rbus
   2368   1.1      haya   rb = sc->sc_rbus_memt;
   2369   1.1      haya   if (rbus_space_alloc(rb, 0, sizepg*PCIC_MEM_PAGESIZE,
   2370   1.1      haya 		       sizepg*PCIC_MEM_PAGESIZE - 1, PCIC_MEM_PAGESIZE,
   2371   1.1      haya 		       0, &addr, &memh)) {
   2372   1.1      haya     return 1;
   2373   1.1      haya   }
   2374   1.1      haya 
   2375   1.1      haya #else
   2376   1.1      haya   if (bus_space_alloc(sc->sc_memt, sc->sc_mem_start, sc->sc_mem_end,
   2377   1.1      haya 		      sizepg*PCIC_MEM_PAGESIZE, PCIC_MEM_PAGESIZE,
   2378   1.1      haya 		      0 /* boundary */, 0 /* flags */,
   2379   1.1      haya 		      &addr, &memh)) {
   2380   1.1      haya     return 1;
   2381   1.1      haya   }
   2382   1.1      haya #endif
   2383   1.1      haya 
   2384   1.1      haya   DPRINTF(("pccbb_pcmcia_alloc_mem: addr 0x%lx size 0x%lx, realsize 0x%lx\n",
   2385   1.1      haya 	   addr, size, sizepg*PCIC_MEM_PAGESIZE));
   2386   1.1      haya 
   2387   1.1      haya   pcmhp->memt = sc->sc_memt;
   2388   1.1      haya   pcmhp->memh = memh;
   2389   1.1      haya   pcmhp->addr = addr;
   2390   1.1      haya   pcmhp->size = size;
   2391   1.1      haya   pcmhp->realsize = sizepg * PCIC_MEM_PAGESIZE;
   2392   1.1      haya   /* What is mhandle?  I feel it is very dirty and it must go trush. */
   2393   1.1      haya   pcmhp->mhandle = 0;
   2394   1.1      haya   /* No offset???  Funny. */
   2395   1.1      haya 
   2396   1.1      haya   return 0;
   2397   1.1      haya }
   2398   1.1      haya 
   2399   1.1      haya 
   2400   1.1      haya 
   2401   1.1      haya 
   2402   1.4      haya /*
   2403   1.4      haya  * STATIC void pccbb_pcmcia_mem_free(pcmcia_chipset_handle_t pch,
   2404   1.4      haya  *                                   struct pcmcia_mem_handle *pcmhp)
   2405   1.4      haya  *
   2406   1.4      haya  * This function release the memory space allocated by the fuction
   2407   1.4      haya  * pccbb_pcmcia_mem_alloc().
   2408   1.4      haya  */
   2409   1.1      haya STATIC void
   2410   1.1      haya pccbb_pcmcia_mem_free(pch, pcmhp)
   2411   1.1      haya      pcmcia_chipset_handle_t pch;
   2412   1.1      haya      struct pcmcia_mem_handle *pcmhp;
   2413   1.1      haya {
   2414   1.1      haya #if rbus
   2415   1.1      haya   struct pcic_handle *ph = (struct pcic_handle *)pch;
   2416   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
   2417   1.1      haya 
   2418   1.1      haya   rbus_space_free(sc->sc_rbus_memt, pcmhp->memh, pcmhp->realsize, NULL);
   2419   1.1      haya #else
   2420   1.1      haya   bus_space_free(pcmhp->memt, pcmhp->memh, pcmhp->realsize);
   2421   1.1      haya #endif
   2422   1.1      haya }
   2423   1.1      haya 
   2424   1.1      haya 
   2425   1.1      haya 
   2426   1.1      haya 
   2427   1.4      haya /*
   2428   1.4      haya  * STATIC void pccbb_pcmcia_do_mem_map(struct pcic_handle *ph, int win)
   2429   1.4      haya  *
   2430   1.4      haya  * This function release the memory space allocated by the fuction
   2431   1.4      haya  * pccbb_pcmcia_mem_alloc().
   2432   1.4      haya  */
   2433   1.1      haya STATIC void
   2434   1.1      haya pccbb_pcmcia_do_mem_map(ph, win)
   2435   1.1      haya      struct pcic_handle *ph;
   2436   1.1      haya      int win;
   2437   1.1      haya {
   2438   1.1      haya   int regbase_win;
   2439   1.1      haya   bus_addr_t phys_addr;
   2440   1.1      haya   bus_addr_t phys_end;
   2441   1.1      haya 
   2442   1.1      haya #define PCIC_SMM_START_LOW 0
   2443   1.1      haya #define PCIC_SMM_START_HIGH 1
   2444   1.1      haya #define PCIC_SMM_STOP_LOW 2
   2445   1.1      haya #define PCIC_SMM_STOP_HIGH 3
   2446   1.1      haya #define PCIC_CMA_LOW 4
   2447   1.1      haya #define PCIC_CMA_HIGH 5
   2448   1.1      haya 
   2449   1.1      haya   u_int8_t start_low, start_high = 0;
   2450   1.1      haya   u_int8_t stop_low, stop_high;
   2451   1.1      haya   u_int8_t off_low, off_high;
   2452   1.1      haya   u_int8_t mem_window;
   2453   1.1      haya   int reg;
   2454   1.1      haya 
   2455  1.12      joda   int kind = ph->mem[win].kind & ~PCMCIA_WIDTH_MEM_MASK;
   2456  1.12      joda   int mem8 = (ph->mem[win].kind & PCMCIA_WIDTH_MEM_MASK) == PCMCIA_WIDTH_MEM8;
   2457  1.12      joda 
   2458   1.1      haya   regbase_win = 0x10 + win*0x08;
   2459   1.1      haya 
   2460   1.1      haya   phys_addr = ph->mem[win].addr;
   2461   1.1      haya   phys_end = phys_addr + ph->mem[win].size;
   2462   1.1      haya 
   2463   1.1      haya   DPRINTF(("pccbb_pcmcia_do_mem_map: start 0x%lx end 0x%lx off 0x%lx\n",
   2464   1.1      haya 	   phys_addr, phys_end, ph->mem[win].offset));
   2465   1.1      haya 
   2466   1.1      haya #define PCIC_MEMREG_LSB_SHIFT PCIC_SYSMEM_ADDRX_SHIFT
   2467   1.1      haya #define PCIC_MEMREG_MSB_SHIFT (PCIC_SYSMEM_ADDRX_SHIFT + 8)
   2468   1.1      haya #define PCIC_MEMREG_WIN_SHIFT (PCIC_SYSMEM_ADDRX_SHIFT + 12)
   2469   1.1      haya 
   2470   1.1      haya   start_low = (phys_addr >> PCIC_MEMREG_LSB_SHIFT) & 0xff; /* bit 19:12 */
   2471   1.1      haya   start_high = ((phys_addr >> PCIC_MEMREG_MSB_SHIFT) & 0x0f) /* bit 23:20 */
   2472  1.15  augustss       | (mem8 ? 0 : PCIC_SYSMEM_ADDRX_START_MSB_DATASIZE_16BIT); /* bit 7 on */
   2473   1.1      haya  /* bit 31:24, for 32-bit address */
   2474   1.1      haya   mem_window = (phys_addr >> PCIC_MEMREG_WIN_SHIFT) & 0xff; /* bit 31:24 */
   2475   1.1      haya 
   2476   1.1      haya   Pcic_write(ph, regbase_win + PCIC_SMM_START_LOW, start_low);
   2477   1.1      haya   Pcic_write(ph, regbase_win + PCIC_SMM_START_HIGH, start_high);
   2478   1.1      haya 
   2479   1.1      haya   if (((struct pccbb_softc *)ph->ph_parent)->sc_pcmcia_flags & PCCBB_PCMCIA_MEM_32) {
   2480   1.1      haya     Pcic_write(ph, 0x40 + win, mem_window);
   2481   1.1      haya   }
   2482   1.1      haya 
   2483   1.1      haya   stop_low = (phys_end >> PCIC_MEMREG_LSB_SHIFT) & 0xff;
   2484   1.1      haya   stop_high = ((phys_end >> PCIC_MEMREG_MSB_SHIFT) & 0x0f)
   2485   1.1      haya     | PCIC_SYSMEM_ADDRX_STOP_MSB_WAIT2;	/* wait 2 cycles */
   2486   1.1      haya   /* XXX Geee, WAIT2!! Crazy!!  I must rewrite this routine. */
   2487   1.1      haya 
   2488   1.1      haya   Pcic_write(ph, regbase_win + PCIC_SMM_STOP_LOW, stop_low);
   2489   1.1      haya   Pcic_write(ph, regbase_win + PCIC_SMM_STOP_HIGH, stop_high);
   2490   1.1      haya 
   2491   1.1      haya   off_low = (ph->mem[win].offset >> PCIC_CARDMEM_ADDRX_SHIFT) & 0xff;
   2492   1.1      haya   off_high = ((ph->mem[win].offset >> (PCIC_CARDMEM_ADDRX_SHIFT + 8))
   2493   1.1      haya 	      & PCIC_CARDMEM_ADDRX_MSB_ADDR_MASK)
   2494  1.12      joda     | ((kind == PCMCIA_MEM_ATTR) ?
   2495   1.1      haya        PCIC_CARDMEM_ADDRX_MSB_REGACTIVE_ATTR : 0);
   2496   1.1      haya 
   2497   1.1      haya   Pcic_write(ph, regbase_win + PCIC_CMA_LOW, off_low);
   2498   1.1      haya   Pcic_write(ph, regbase_win + PCIC_CMA_HIGH, off_high);
   2499   1.1      haya 
   2500   1.1      haya   reg = Pcic_read(ph, PCIC_ADDRWIN_ENABLE);
   2501   1.1      haya   reg |= ((1 << win) | PCIC_ADDRWIN_ENABLE_MEMCS16);
   2502   1.1      haya   Pcic_write(ph, PCIC_ADDRWIN_ENABLE, reg);
   2503   1.1      haya 
   2504   1.1      haya #if defined CBB_DEBUG
   2505   1.1      haya   {
   2506   1.1      haya     int r1, r2, r3, r4, r5, r6, r7 = 0;
   2507   1.1      haya 
   2508   1.1      haya     r1 = Pcic_read(ph, regbase_win + PCIC_SMM_START_LOW);
   2509   1.1      haya     r2 = Pcic_read(ph, regbase_win + PCIC_SMM_START_HIGH);
   2510   1.1      haya     r3 = Pcic_read(ph, regbase_win + PCIC_SMM_STOP_LOW);
   2511   1.1      haya     r4 = Pcic_read(ph, regbase_win + PCIC_SMM_STOP_HIGH);
   2512   1.1      haya     r5 = Pcic_read(ph, regbase_win + PCIC_CMA_LOW);
   2513   1.1      haya     r6 = Pcic_read(ph, regbase_win + PCIC_CMA_HIGH);
   2514   1.1      haya     if (((struct pccbb_softc *)(ph->ph_parent))->sc_pcmcia_flags & PCCBB_PCMCIA_MEM_32) {
   2515   1.1      haya       r7 = Pcic_read(ph, 0x40 + win);
   2516   1.1      haya     }
   2517   1.1      haya 
   2518   1.1      haya     DPRINTF(("pccbb_pcmcia_do_mem_map window %d: %02x%02x %02x%02x "
   2519   1.1      haya 	     "%02x%02x", win, r1, r2, r3, r4, r5, r6));
   2520   1.1      haya     if (((struct pccbb_softc *)(ph->ph_parent))->sc_pcmcia_flags & PCCBB_PCMCIA_MEM_32) {
   2521   1.1      haya       DPRINTF((" %02x",r7));
   2522   1.1      haya     }
   2523   1.1      haya     DPRINTF(("\n"));
   2524   1.1      haya   }
   2525   1.1      haya #endif
   2526   1.1      haya }
   2527   1.1      haya 
   2528   1.1      haya 
   2529   1.1      haya 
   2530   1.1      haya 
   2531   1.4      haya /*
   2532   1.4      haya  * STATIC int pccbb_pcmcia_mem_map(pcmcia_chipset_handle_t pch, int kind,
   2533   1.4      haya  *                                 bus_addr_t card_addr, bus_size_t size,
   2534   1.4      haya  *                                 struct pcmcia_mem_handle *pcmhp,
   2535   1.4      haya  *                                 bus_addr_t *offsetp, int *windowp)
   2536   1.4      haya  *
   2537   1.4      haya  * This function maps memory space allocated by the fuction
   2538   1.4      haya  * pccbb_pcmcia_mem_alloc().
   2539   1.4      haya  */
   2540   1.1      haya STATIC int
   2541   1.1      haya pccbb_pcmcia_mem_map(pch, kind, card_addr, size, pcmhp, offsetp, windowp)
   2542   1.1      haya      pcmcia_chipset_handle_t pch;
   2543   1.1      haya      int kind;
   2544   1.1      haya      bus_addr_t card_addr;
   2545   1.1      haya      bus_size_t size;
   2546   1.1      haya      struct pcmcia_mem_handle *pcmhp;
   2547   1.1      haya      bus_addr_t *offsetp;
   2548   1.1      haya      int *windowp;
   2549   1.1      haya {
   2550   1.1      haya   struct pcic_handle *ph = (struct pcic_handle *)pch;
   2551   1.1      haya   bus_addr_t busaddr;
   2552   1.1      haya   long card_offset;
   2553   1.1      haya   int win;
   2554   1.1      haya 
   2555   1.1      haya   for (win = 0; win < PCIC_MEM_WINS; ++win) {
   2556   1.1      haya     if ((ph->memalloc & (1 << win)) == 0) {
   2557   1.1      haya       ph->memalloc |= (1 << win);
   2558   1.1      haya       break;
   2559   1.1      haya     }
   2560   1.1      haya   }
   2561   1.1      haya 
   2562   1.1      haya   if (win == PCIC_MEM_WINS) {
   2563   1.1      haya     return 1;
   2564   1.1      haya   }
   2565   1.1      haya 
   2566   1.1      haya   *windowp = win;
   2567   1.1      haya 
   2568   1.1      haya   /* XXX this is pretty gross */
   2569   1.1      haya 
   2570   1.1      haya   if (((struct pccbb_softc *)ph->ph_parent)->sc_memt != pcmhp->memt) {
   2571   1.1      haya     panic("pccbb_pcmcia_mem_map memt is bogus");
   2572   1.1      haya   }
   2573   1.1      haya 
   2574   1.1      haya   busaddr = pcmhp->addr;
   2575   1.1      haya 
   2576   1.1      haya   /*
   2577   1.1      haya    * compute the address offset to the pcmcia address space for the
   2578   1.1      haya    * pcic.  this is intentionally signed.  The masks and shifts below
   2579   1.1      haya    * will cause TRT to happen in the pcic registers.  Deal with making
   2580   1.1      haya    * sure the address is aligned, and return the alignment offset.
   2581   1.1      haya    */
   2582   1.1      haya 
   2583   1.1      haya   *offsetp = card_addr % PCIC_MEM_PAGESIZE;
   2584   1.1      haya   card_addr -= *offsetp;
   2585   1.1      haya 
   2586   1.1      haya   DPRINTF(("pccbb_pcmcia_mem_map window %d bus %lx+%lx+%lx at card addr "
   2587   1.1      haya 	   "%lx\n", win, (u_long)busaddr, (u_long)*offsetp, (u_long)size,
   2588   1.1      haya 	   (u_long)card_addr));
   2589   1.1      haya 
   2590   1.1      haya   /*
   2591   1.1      haya    * include the offset in the size, and decrement size by one, since
   2592   1.1      haya    * the hw wants start/stop
   2593   1.1      haya    */
   2594   1.1      haya   size += *offsetp - 1;
   2595   1.1      haya 
   2596   1.1      haya   card_offset = (((long) card_addr) - ((long) busaddr));
   2597   1.1      haya 
   2598   1.1      haya   ph->mem[win].addr = busaddr;
   2599   1.1      haya   ph->mem[win].size = size;
   2600   1.1      haya   ph->mem[win].offset = card_offset;
   2601   1.1      haya   ph->mem[win].kind = kind;
   2602   1.1      haya 
   2603   1.1      haya   pccbb_pcmcia_do_mem_map(ph, win);
   2604   1.1      haya 
   2605   1.1      haya   return 0;
   2606   1.1      haya }
   2607   1.1      haya 
   2608   1.1      haya 
   2609   1.1      haya 
   2610   1.4      haya /*
   2611   1.4      haya  * STATIC int pccbb_pcmcia_mem_unmap(pcmcia_chipset_handle_t pch,
   2612   1.4      haya  *                                   int window)
   2613   1.4      haya  *
   2614   1.4      haya  * This function unmaps memory space which mapped by the fuction
   2615   1.4      haya  * pccbb_pcmcia_mem_map().
   2616   1.4      haya  */
   2617   1.1      haya STATIC void
   2618   1.1      haya pccbb_pcmcia_mem_unmap(pch, window)
   2619   1.1      haya      pcmcia_chipset_handle_t pch;
   2620   1.1      haya      int window;
   2621   1.1      haya {
   2622   1.1      haya   struct pcic_handle *ph = (struct pcic_handle *)pch;
   2623   1.1      haya   int reg;
   2624   1.1      haya 
   2625   1.1      haya   if (window >= PCIC_MEM_WINS) {
   2626   1.1      haya     panic("pccbb_pcmcia_mem_unmap: window out of range");
   2627   1.1      haya   }
   2628   1.1      haya 
   2629   1.1      haya   reg = Pcic_read(ph, PCIC_ADDRWIN_ENABLE);
   2630   1.1      haya   reg &= ~(1 << window);
   2631   1.1      haya   Pcic_write(ph, PCIC_ADDRWIN_ENABLE, reg);
   2632   1.1      haya 
   2633   1.1      haya   ph->memalloc &= ~(1 << window);
   2634   1.1      haya }
   2635   1.1      haya 
   2636   1.1      haya 
   2637   1.1      haya 
   2638   1.1      haya #if defined PCCBB_PCMCIA_POLL
   2639   1.1      haya struct pccbb_poll_str {
   2640   1.1      haya   void *arg;
   2641   1.1      haya   int (* func) __P((void *));
   2642   1.1      haya   int level;
   2643   1.1      haya   struct pcic_handle *ph;
   2644   1.1      haya   int count;
   2645   1.1      haya   int num;
   2646   1.1      haya };
   2647   1.1      haya 
   2648   1.1      haya static struct pccbb_poll_str pccbb_poll[10];
   2649   1.1      haya static int pccbb_poll_n = 0;
   2650   1.1      haya 
   2651   1.1      haya static void pccbb_pcmcia_poll __P((void *arg));
   2652   1.1      haya 
   2653   1.1      haya static void
   2654   1.1      haya pccbb_pcmcia_poll(arg)
   2655   1.1      haya      void *arg;
   2656   1.1      haya {
   2657   1.1      haya   struct pccbb_poll_str *poll = arg;
   2658   1.1      haya   struct pcic_handle *ph = poll->ph;
   2659   1.1      haya   struct pccbb_softc *sc = ph->sc;
   2660   1.1      haya   int s;
   2661   1.1      haya   u_int32_t spsr;		/* socket present-state reg */
   2662   1.1      haya 
   2663   1.1      haya   timeout(pccbb_pcmcia_poll, arg, hz*2);
   2664   1.1      haya   switch (poll->level) {
   2665   1.1      haya   case IPL_NET:
   2666   1.1      haya     s = splnet();
   2667   1.1      haya     break;
   2668   1.1      haya   case IPL_BIO:
   2669   1.1      haya     s = splbio();
   2670   1.1      haya     break;
   2671   1.1      haya   case IPL_TTY:			/* fallthrough */
   2672   1.1      haya   default:
   2673   1.1      haya     s = spltty();
   2674   1.1      haya     break;
   2675   1.1      haya   }
   2676   1.1      haya 
   2677   1.1      haya   spsr = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh, CB_SOCKET_STAT);
   2678   1.1      haya 
   2679   1.1      haya #if defined PCCBB_PCMCIA_POLL_ONLY && defined LEVEL2
   2680   1.1      haya   if (!(spsr & 0x40))		/* CINT low */
   2681   1.1      haya #else
   2682   1.1      haya   if (1)
   2683   1.1      haya #endif
   2684   1.1      haya   {
   2685   1.1      haya     if ((*poll->func)(poll->arg) > 0) {
   2686   1.1      haya       ++poll->count;
   2687   1.1      haya //	printf("intr: reported from poller, 0x%x\n", spsr);
   2688   1.1      haya #if defined LEVEL2
   2689   1.1      haya     } else {
   2690   1.1      haya       printf("intr: miss! 0x%x\n", spsr);
   2691   1.1      haya #endif
   2692   1.1      haya     }
   2693   1.1      haya   }
   2694   1.1      haya   splx(s);
   2695   1.1      haya }
   2696   1.1      haya #endif /* defined CB_PCMCIA_POLL */
   2697   1.1      haya 
   2698   1.1      haya 
   2699   1.1      haya 
   2700   1.4      haya /*
   2701   1.4      haya  * STATIC void *pccbb_pcmcia_intr_establish(pcmcia_chipset_handle_t pch,
   2702   1.4      haya  *                                          struct pcmcia_function *pf,
   2703   1.4      haya  *                                          int ipl,
   2704   1.4      haya  *                                          int (*func)(void *),
   2705   1.4      haya  *                                          void *arg);
   2706   1.4      haya  *
   2707   1.4      haya  * This function enables PC-Card interrupt.  PCCBB uses PCI interrupt line.
   2708   1.4      haya  */
   2709   1.1      haya STATIC void *
   2710   1.1      haya pccbb_pcmcia_intr_establish(pch, pf, ipl, func, arg)
   2711   1.1      haya      pcmcia_chipset_handle_t pch;
   2712   1.1      haya      struct pcmcia_function *pf;
   2713   1.1      haya      int ipl;
   2714   1.1      haya      int (*func) __P((void *));
   2715   1.1      haya      void *arg;
   2716   1.1      haya {
   2717   1.1      haya   struct pcic_handle *ph = (struct pcic_handle *)pch;
   2718   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
   2719   1.1      haya   pci_intr_handle_t handle;
   2720   1.1      haya   void *ih;
   2721   1.1      haya 
   2722   1.1      haya   if (!(pf->cfe->flags & PCMCIA_CFE_IRQLEVEL)) {
   2723   1.1      haya     /* what should I do? */
   2724   1.1      haya     if ((pf->cfe->flags & PCMCIA_CFE_IRQLEVEL)) {
   2725   1.1      haya       DPRINTF(("%s does not provide edge nor pulse interrupt\n",
   2726   1.1      haya 	       sc->sc_dev.dv_xname));
   2727   1.1      haya       return NULL;
   2728   1.1      haya     }
   2729   1.4      haya     /*
   2730   1.4      haya      * XXX Noooooo!  The interrupt flag must set properly!!
   2731   1.4      haya      * dumb pcmcia driver!!
   2732   1.4      haya      */
   2733   1.1      haya   }
   2734   1.1      haya 
   2735   1.1      haya   if (pci_intr_map(sc->sc_pc, sc->sc_intrtag, sc->sc_intrpin,
   2736   1.1      haya 		   sc->sc_intrline, &handle)) {
   2737   1.1      haya     printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
   2738   1.1      haya     return NULL;
   2739   1.1      haya   }
   2740   1.1      haya   DPRINTF(("pccbb_pcmcia_intr_establish: line %d, handle %d\n",
   2741   1.1      haya 	   sc->sc_intrline, handle));
   2742   1.1      haya 
   2743   1.1      haya   if (NULL != (ih = pci_intr_establish(sc->sc_pc, handle, ipl, func, arg)))
   2744   1.1      haya     {
   2745   1.1      haya       u_int32_t cbctrl;
   2746   1.1      haya 
   2747   1.1      haya       if ((CB_TI113X == sc->sc_chipset)) {
   2748   1.1      haya 	cbctrl = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CBCTRL);
   2749   1.1      haya 	cbctrl |= PCI113X_CBCTRL_PCI_INTR; /* PCI functional intr req */
   2750   1.1      haya 	pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_CBCTRL, cbctrl);
   2751   1.1      haya       }
   2752   1.1      haya     }
   2753   1.1      haya #if defined PCCBB_PCMCIA_POLL
   2754   1.1      haya     if (pccbb_poll_n < 10) {
   2755   1.1      haya       pccbb_poll[pccbb_poll_n].arg = arg;
   2756   1.1      haya       pccbb_poll[pccbb_poll_n].func = func;
   2757   1.1      haya       pccbb_poll[pccbb_poll_n].level = ipl;
   2758   1.1      haya       pccbb_poll[pccbb_poll_n].count = 0;
   2759   1.1      haya       pccbb_poll[pccbb_poll_n].num = pccbb_poll_n;
   2760   1.1      haya       pccbb_poll[pccbb_poll_n].ph = ph;
   2761   1.1      haya       timeout(pccbb_pcmcia_poll, &pccbb_poll[pccbb_poll_n++], hz*2);
   2762   1.1      haya       printf("polling set\n");
   2763   1.1      haya     }
   2764   1.1      haya #endif
   2765   1.1      haya #if defined SHOW_REGS
   2766   1.1      haya   cb_show_regs(sc->sc_pc, sc->sc_tag, sc->sc_base_memt, sc->sc_base_memh);
   2767   1.1      haya #endif
   2768   1.1      haya 
   2769   1.1      haya   return ih;
   2770   1.1      haya }
   2771   1.1      haya 
   2772   1.1      haya 
   2773   1.1      haya 
   2774   1.1      haya 
   2775   1.4      haya /*
   2776   1.4      haya  * STATIC void pccbb_pcmcia_intr_disestablish(pcmcia_chipset_handle_t pch,
   2777   1.4      haya  *                                            void *ih)
   2778   1.4      haya  *
   2779   1.4      haya  * This function disables PC-Card interrupt.
   2780   1.4      haya  */
   2781   1.1      haya STATIC void
   2782   1.1      haya pccbb_pcmcia_intr_disestablish(pch, ih)
   2783   1.1      haya      pcmcia_chipset_handle_t pch;
   2784   1.1      haya      void *ih;
   2785   1.1      haya {
   2786   1.1      haya   struct pcic_handle *ph = (struct pcic_handle *)pch;
   2787   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
   2788   1.1      haya 
   2789   1.1      haya   pci_intr_disestablish(sc->sc_pc, ih);
   2790   1.1      haya }
   2791   1.1      haya 
   2792   1.1      haya 
   2793   1.1      haya 
   2794   1.1      haya 
   2795   1.1      haya #if rbus
   2796   1.4      haya /*
   2797   1.4      haya  * static int
   2798   1.4      haya  * pccbb_rbus_cb_space_alloc(cardbus_chipset_tag_t ct, rbus_tag_t rb,
   2799   1.4      haya  *			    bus_addr_t addr, bus_size_t size,
   2800   1.4      haya  *			    bus_addr_t mask, bus_size_t align,
   2801   1.4      haya  *			    int flags, bus_addr_t *addrp;
   2802   1.4      haya  *			    bus_space_handle_t *bshp)
   2803   1.4      haya  *
   2804   1.4      haya  *   This function allocates a portion of memory or io space for
   2805   1.4      haya  *   clients.  This function is called from CardBus card drivers.
   2806   1.4      haya  */
   2807   1.1      haya static int
   2808   1.1      haya pccbb_rbus_cb_space_alloc(ct, rb, addr, size, mask, align, flags, addrp, bshp)
   2809   1.1      haya      cardbus_chipset_tag_t ct;
   2810   1.1      haya      rbus_tag_t rb;
   2811   1.1      haya      bus_addr_t addr;
   2812   1.1      haya      bus_size_t size;
   2813   1.1      haya      bus_addr_t mask;
   2814   1.1      haya      bus_size_t align;
   2815   1.1      haya      int flags;
   2816   1.1      haya      bus_addr_t *addrp;
   2817   1.1      haya      bus_space_handle_t *bshp;
   2818   1.1      haya {
   2819   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)ct;
   2820   1.1      haya 
   2821   1.1      haya   DPRINTF(("pccbb_rbus_cb_space_alloc: adr %lx, size %lx, mask %lx, align %lx\n", addr, size, mask, align));
   2822   1.1      haya 
   2823   1.1      haya   if (align == 0) {
   2824   1.1      haya     align = size;
   2825   1.1      haya   }
   2826   1.1      haya 
   2827   1.1      haya   if (rb->rb_bt == sc->sc_memt) {
   2828   1.1      haya     if (align < 16) {
   2829   1.1      haya       return 1;
   2830   1.1      haya     }
   2831   1.1      haya   } else if (rb->rb_bt == sc->sc_iot) {
   2832   1.1      haya     if (align < 4) {
   2833   1.1      haya       return 1;
   2834   1.1      haya     }
   2835   1.1      haya   } else {
   2836   1.1      haya     DPRINTF(("pccbb_rbus_cb_space_alloc: Bus space tag %x is NOT used.\n",
   2837   1.1      haya 	     rb->rb_bt));
   2838   1.1      haya     return 1;
   2839   1.1      haya     /* XXX: panic here? */
   2840   1.1      haya   }
   2841   1.1      haya 
   2842   1.1      haya   /* XXX: hack for avoiding ISA image */
   2843   1.1      haya   if (mask < 0x3ff) {
   2844   1.1      haya     mask = 0x3ff;
   2845   1.1      haya     addr = 0x300;
   2846   1.1      haya   }
   2847   1.1      haya 
   2848   1.1      haya   if (rbus_space_alloc(rb, addr, size, mask, align, flags, addrp, bshp)) {
   2849   1.1      haya     printf("%s: <rbus> no bus space\n", sc->sc_dev.dv_xname);
   2850   1.1      haya     return 1;
   2851   1.1      haya   }
   2852   1.1      haya 
   2853   1.1      haya   pccbb_open_win(sc, rb->rb_bt, *addrp, size, *bshp, 0);
   2854   1.1      haya 
   2855   1.1      haya   return 0;
   2856   1.1      haya }
   2857   1.1      haya 
   2858   1.1      haya 
   2859   1.1      haya 
   2860   1.1      haya 
   2861   1.1      haya 
   2862   1.4      haya /*
   2863   1.4      haya  * static int
   2864   1.4      haya  * pccbb_rbus_cb_space_free(cardbus_chipset_tag_t *ct, rbus_tag_t rb,
   2865   1.4      haya  *			   bus_space_handle_t *bshp, bus_size_t size);
   2866   1.4      haya  *
   2867   1.4      haya  *   This function is called from CardBus card drivers.
   2868   1.4      haya  */
   2869   1.1      haya static int
   2870   1.1      haya pccbb_rbus_cb_space_free(ct, rb, bsh, size)
   2871   1.1      haya      cardbus_chipset_tag_t ct;
   2872   1.1      haya      rbus_tag_t rb;
   2873   1.1      haya      bus_space_handle_t bsh;
   2874   1.1      haya      bus_size_t size;
   2875   1.1      haya {
   2876   1.1      haya   struct pccbb_softc *sc = (struct pccbb_softc *)ct;
   2877   1.1      haya   bus_space_tag_t bt = rb->rb_bt;
   2878   1.1      haya 
   2879   1.1      haya   pccbb_close_win(sc, bt, bsh, size);
   2880   1.1      haya 
   2881   1.1      haya   if (bt == sc->sc_memt) {
   2882   1.1      haya   } else if (bt == sc->sc_iot) {
   2883   1.1      haya   } else {
   2884   1.1      haya     return 1;
   2885   1.1      haya     /* XXX: panic here? */
   2886   1.1      haya   }
   2887   1.1      haya 
   2888   1.1      haya   return rbus_space_free(rb, bsh, size, NULL);
   2889   1.1      haya }
   2890   1.1      haya #endif /* rbus */
   2891   1.1      haya 
   2892   1.1      haya 
   2893   1.1      haya #if rbus
   2894   1.1      haya 
   2895   1.1      haya static int
   2896   1.1      haya pccbb_open_win(sc, bst, addr, size, bsh, flags)
   2897   1.1      haya      struct pccbb_softc *sc;
   2898   1.1      haya      bus_space_tag_t bst;
   2899   1.1      haya      bus_addr_t addr;
   2900   1.1      haya      bus_size_t size;
   2901   1.1      haya      bus_space_handle_t bsh;
   2902   1.1      haya      int flags;
   2903   1.1      haya {
   2904   1.1      haya   struct pccbb_win_chain **top;
   2905   1.1      haya   bus_addr_t align;
   2906   1.1      haya 
   2907   1.1      haya   top = &sc->sc_iowindow;
   2908   1.1      haya   align = 0x04;
   2909   1.1      haya   if (sc->sc_memt == bst) {
   2910   1.1      haya     top = &sc->sc_memwindow;
   2911   1.1      haya     align = 0x1000;
   2912   1.3  augustss     DPRINTF(("using memory window, %x %x %x\n\n",
   2913   1.3  augustss 	     sc->sc_iot, sc->sc_memt, bst));
   2914   1.1      haya   }
   2915   1.1      haya 
   2916   1.1      haya   if (pccbb_winlist_insert(top, addr, size, bsh, flags)) {
   2917   1.1      haya     printf("winlist insert fails:\n");
   2918   1.1      haya   }
   2919   1.1      haya   pccbb_winset(align, sc, bst);
   2920   1.1      haya 
   2921   1.1      haya   return 0;
   2922   1.1      haya }
   2923   1.1      haya 
   2924   1.1      haya 
   2925   1.1      haya 
   2926   1.1      haya static int
   2927   1.1      haya pccbb_close_win(sc, bst, bsh, size)
   2928   1.1      haya      struct pccbb_softc *sc;
   2929   1.1      haya      bus_space_tag_t bst;
   2930   1.1      haya      bus_space_handle_t bsh;
   2931   1.1      haya      bus_size_t size;
   2932   1.1      haya {
   2933   1.1      haya   struct pccbb_win_chain **top;
   2934   1.1      haya   bus_addr_t align;
   2935   1.1      haya 
   2936   1.1      haya   top = &sc->sc_iowindow;
   2937   1.1      haya   align = 0x04;
   2938   1.1      haya   if (sc->sc_memt == bst) {
   2939   1.1      haya     top = &sc->sc_memwindow;
   2940   1.1      haya     align = 0x1000;
   2941   1.1      haya   }
   2942   1.1      haya 
   2943   1.1      haya   if (pccbb_winlist_delete(top, bsh, size)) {
   2944   1.1      haya     printf("winlist delete fails:\n");
   2945   1.1      haya   }
   2946   1.1      haya   pccbb_winset(align, sc, bst);
   2947   1.1      haya 
   2948   1.1      haya   return 0;
   2949   1.1      haya }
   2950   1.1      haya 
   2951   1.1      haya 
   2952   1.1      haya static int
   2953   1.1      haya pccbb_winlist_insert(top, start, size, bsh, flags)
   2954   1.1      haya      struct pccbb_win_chain **top;
   2955   1.1      haya      bus_addr_t start;
   2956   1.1      haya      bus_size_t size;
   2957   1.1      haya      bus_space_handle_t bsh;
   2958   1.1      haya      int flags;
   2959   1.1      haya {
   2960   1.1      haya   struct pccbb_win_chain *chainp = *top;
   2961   1.1      haya   struct pccbb_win_chain *before = *top;
   2962   1.1      haya   struct pccbb_win_chain *elem;
   2963   1.1      haya 
   2964   1.1      haya   if (*top == NULL) {
   2965   1.1      haya     if (NULL == (elem = (struct pccbb_win_chain *)malloc(sizeof(struct pccbb_win_chain), M_DEVBUF, M_NOWAIT))) {
   2966   1.1      haya       return 1;			/* fail */
   2967   1.1      haya     }
   2968   1.1      haya 
   2969   1.1      haya     elem->wc_start = start;
   2970   1.1      haya     elem->wc_end = start + size - 1;
   2971   1.1      haya     elem->wc_handle = bsh;
   2972   1.1      haya     elem->wc_flags = flags;
   2973   1.1      haya 
   2974   1.1      haya     *top = elem;
   2975   1.1      haya     elem->wc_next = NULL;
   2976   1.1      haya     return 0;
   2977   1.1      haya   }
   2978   1.1      haya 
   2979   1.1      haya   for(; chainp && chainp->wc_start <= start; chainp = chainp->wc_next) {
   2980   1.1      haya     before = chainp;
   2981   1.1      haya   }
   2982   1.1      haya 
   2983   1.1      haya   if (chainp != NULL) {
   2984   1.1      haya     if (chainp->wc_start < start + size) {
   2985   1.1      haya       printf("fatal! 0x%lx 0x%lx\n", chainp->wc_start, start+size);
   2986   1.1      haya       return 1;
   2987   1.1      haya     }
   2988   1.1      haya   }
   2989   1.1      haya   if ((before != *top) && (before->wc_end >= start)) {
   2990   1.1      haya     printf("fatal!! 0x%lx 0x%lx\n", before->wc_end, start);
   2991   1.1      haya     return 1;
   2992   1.1      haya   }
   2993   1.1      haya 
   2994   1.1      haya   if (NULL == (elem = (struct pccbb_win_chain *)malloc(sizeof(struct pccbb_win_chain), M_DEVBUF, M_NOWAIT))) {
   2995   1.1      haya     return 1;			/* fail */
   2996   1.1      haya   }
   2997   1.1      haya 
   2998   1.1      haya   elem->wc_start = start;
   2999   1.1      haya   elem->wc_end = start + size - 1;
   3000   1.1      haya   elem->wc_handle = bsh;
   3001   1.1      haya   elem->wc_flags = flags;
   3002   1.1      haya 
   3003   1.1      haya   elem->wc_next = chainp;
   3004   1.1      haya   if (chainp == *top) {
   3005   1.1      haya     *top = elem;
   3006   1.1      haya   } else {
   3007   1.1      haya     before->wc_next = elem;
   3008   1.1      haya   }
   3009   1.1      haya   return 0;
   3010   1.1      haya }
   3011   1.1      haya 
   3012   1.1      haya 
   3013   1.1      haya 
   3014   1.1      haya 
   3015   1.1      haya static int
   3016   1.1      haya pccbb_winlist_delete(top, bsh, size)
   3017   1.1      haya      struct pccbb_win_chain **top;
   3018   1.1      haya      bus_space_handle_t bsh;
   3019   1.1      haya      bus_size_t size;
   3020   1.1      haya {
   3021   1.1      haya   struct pccbb_win_chain *chainp = *top;
   3022   1.1      haya   struct pccbb_win_chain **before = top;
   3023   1.1      haya 
   3024   1.1      haya   for (; chainp && chainp->wc_handle != bsh; chainp = chainp->wc_next) {
   3025   1.1      haya     before = &chainp->wc_next;
   3026   1.1      haya   }
   3027   1.1      haya 
   3028   1.1      haya   if (chainp == NULL) {
   3029   1.1      haya     return 1;			/* fail: no candidate to remove */
   3030   1.1      haya   }
   3031   1.1      haya 
   3032   1.1      haya   if (chainp->wc_end - chainp->wc_start != size - 1) {
   3033   1.1      haya     printf("fatal!!! 0x%lx\n", chainp->wc_start);
   3034   1.1      haya     return 1;			/* fail: no candidate to remove */
   3035   1.1      haya   }
   3036   1.1      haya 
   3037   1.1      haya   *before = chainp->wc_next;
   3038   1.1      haya   free(chainp, M_DEVBUF);
   3039   1.1      haya 
   3040   1.1      haya   return 0;
   3041   1.1      haya }
   3042   1.1      haya 
   3043   1.1      haya 
   3044   1.1      haya 
   3045   1.1      haya static void
   3046   1.1      haya pccbb_winset(align, sc, bst)
   3047   1.1      haya      bus_addr_t align;
   3048   1.1      haya      struct pccbb_softc *sc;
   3049   1.1      haya      bus_space_tag_t bst;
   3050   1.1      haya {
   3051   1.1      haya   pci_chipset_tag_t pc;
   3052   1.1      haya   pcitag_t tag;
   3053   1.1      haya   bus_addr_t mask = ~(align - 1);
   3054   1.1      haya   struct {
   3055   1.1      haya     cardbusreg_t win_start;
   3056   1.1      haya     cardbusreg_t win_limit;
   3057   1.1      haya     int win_flags;
   3058   1.1      haya   } win[2];
   3059   1.1      haya   struct pccbb_win_chain *chainp;
   3060   1.1      haya   int offs;
   3061   1.1      haya 
   3062   1.1      haya   win[0].win_start = 0xffffffff;
   3063   1.1      haya   win[0].win_limit = 0;
   3064   1.1      haya   win[1].win_start = 0xffffffff;
   3065   1.1      haya   win[1].win_limit = 0;
   3066   1.1      haya 
   3067   1.1      haya   chainp = sc->sc_iowindow;
   3068   1.1      haya   offs = 0x2c;
   3069   1.1      haya   if (sc->sc_memt == bst) {
   3070   1.1      haya     chainp = sc->sc_memwindow;
   3071   1.1      haya     offs = 0x1c;
   3072   1.1      haya   }
   3073   1.1      haya 
   3074   1.1      haya   if (chainp) {
   3075   1.1      haya     win[0].win_start = chainp->wc_start & mask;
   3076   1.1      haya     win[0].win_limit = chainp->wc_end & mask;
   3077   1.1      haya     win[0].win_flags = chainp->wc_flags;
   3078   1.1      haya     chainp = chainp->wc_next;
   3079   1.1      haya   }
   3080   1.1      haya 
   3081   1.1      haya   for(; chainp; chainp = chainp->wc_next) {
   3082   1.1      haya     if (win[1].win_start == 0xffffffff) {
   3083   1.1      haya       /* window 1 is not used */
   3084   1.1      haya       if ((win[0].win_flags == chainp->wc_flags) &&
   3085   1.1      haya 	  (win[0].win_limit + align >= (chainp->wc_start & mask))) {
   3086   1.1      haya 	/* concatinate */
   3087   1.1      haya 	win[0].win_limit = chainp->wc_end & mask;
   3088   1.1      haya       } else {
   3089   1.1      haya 	/* make new window */
   3090   1.1      haya 	win[1].win_start = chainp->wc_start & mask;
   3091   1.1      haya 	win[1].win_limit = chainp->wc_end & mask;
   3092   1.1      haya 	win[1].win_flags = chainp->wc_flags;
   3093   1.1      haya       }
   3094   1.1      haya       continue;
   3095   1.1      haya     }
   3096   1.1      haya 
   3097   1.1      haya     /* Both windows are engagad. */
   3098   1.1      haya     if (win[0].win_flags == win[1].win_flags) {
   3099   1.1      haya       /* same flags */
   3100   1.1      haya       if (win[0].win_flags == chainp->wc_flags) {
   3101   1.1      haya 	if (win[1].win_start - (win[0].win_limit + align)
   3102  1.11      joda 	    < (chainp->wc_start & mask) - ((chainp->wc_end & mask) + align)) {
   3103  1.11      joda 	    /* merge window 0 and 1, and set win1 to chainp */
   3104  1.11      joda 	    win[0].win_limit = win[1].win_limit;
   3105  1.11      joda 	    win[1].win_start = chainp->wc_start & mask;
   3106  1.11      joda 	    win[1].win_limit = chainp->wc_end & mask;
   3107  1.11      joda 	} else {
   3108  1.11      joda 	    win[1].win_limit = chainp->wc_end & mask;
   3109   1.1      haya 	}
   3110   1.1      haya       } else {
   3111   1.1      haya 	/* different flags */
   3112   1.1      haya 
   3113   1.1      haya 	/* concatinate win0 and win1 */
   3114   1.1      haya 	win[0].win_limit = win[1].win_limit;
   3115   1.1      haya 	/* allocate win[1] to new space */
   3116   1.1      haya 	win[1].win_start = chainp->wc_start & mask;
   3117   1.1      haya 	win[1].win_limit = chainp->wc_end & mask;
   3118   1.1      haya 	win[1].win_flags = chainp->wc_flags;
   3119   1.1      haya       }
   3120   1.1      haya     } else {
   3121   1.1      haya       /* the flags of win[0] and win[1] is different */
   3122   1.1      haya       if (win[0].win_flags == chainp->wc_flags) {
   3123  1.11      joda 	  win[0].win_limit = chainp->wc_end & mask;
   3124  1.11      joda 	  /* XXX this creates overlapping windows, so what should the
   3125  1.11      joda              poor bridge do if one is cachable, and the other is not?  */
   3126  1.11      joda 	  printf("%s: overlapping windows\n", sc->sc_dev.dv_xname);
   3127   1.1      haya       } else {
   3128   1.1      haya 	win[1].win_limit = chainp->wc_end & mask;
   3129   1.1      haya       }
   3130   1.1      haya     }
   3131   1.1      haya   }
   3132   1.1      haya 
   3133   1.1      haya   pc = sc->sc_pc;
   3134   1.1      haya   tag = sc->sc_tag;
   3135   1.1      haya   pci_conf_write(pc, tag, offs, win[0].win_start);
   3136   1.1      haya   pci_conf_write(pc, tag, offs+4, win[0].win_limit);
   3137   1.1      haya   pci_conf_write(pc, tag, offs+8, win[1].win_start);
   3138   1.1      haya   pci_conf_write(pc, tag, offs+12, win[1].win_limit);
   3139   1.1      haya   DPRINTF(("--pccbb_winset: win0 [%x, %lx), win1 [%x, %lx)\n",
   3140   1.1      haya 	   pci_conf_read(pc, tag, offs),
   3141   1.1      haya 	   pci_conf_read(pc, tag, offs+4) + align,
   3142   1.1      haya 	   pci_conf_read(pc, tag, offs+8),
   3143   1.1      haya 	   pci_conf_read(pc, tag, offs+12) + align));
   3144   1.1      haya 
   3145   1.1      haya   if (bst == sc->sc_memt) {
   3146  1.11      joda     if (win[0].win_flags & PCCBB_MEM_CACHABLE) {
   3147   1.1      haya       pcireg_t bcr = pci_conf_read(pc, tag, PCI_BCR_INTR);
   3148   1.1      haya       bcr |= CB_BCR_PREFETCH_MEMWIN0;
   3149   1.1      haya       pci_conf_write(pc,tag, PCI_BCR_INTR, bcr);
   3150   1.1      haya     }
   3151  1.11      joda     if (win[1].win_flags & PCCBB_MEM_CACHABLE) {
   3152   1.1      haya       pcireg_t bcr = pci_conf_read(pc, tag, PCI_BCR_INTR);
   3153   1.1      haya       bcr |= CB_BCR_PREFETCH_MEMWIN1;
   3154   1.1      haya       pci_conf_write(pc,tag, PCI_BCR_INTR, bcr);
   3155   1.1      haya     }
   3156   1.1      haya   }
   3157   1.1      haya }
   3158   1.1      haya 
   3159   1.1      haya #endif /* rbus */
   3160