LCOV - code coverage report
Current view: top level - dev/pci - pccbb.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 919 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 51 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13