The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/pccbb/pccbb.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2000-2001 Jonathan Chen All rights reserved.
    5  * Copyright (c) 2002-2004 M. Warner Losh <imp@FreeBSD.org>
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  *
   28  */
   29 
   30 /*-
   31  * Copyright (c) 1998, 1999 and 2000
   32  *      HAYAKAWA Koichi.  All rights reserved.
   33  *
   34  * Redistribution and use in source and binary forms, with or without
   35  * modification, are permitted provided that the following conditions
   36  * are met:
   37  * 1. Redistributions of source code must retain the above copyright
   38  *    notice, this list of conditions and the following disclaimer.
   39  * 2. Redistributions in binary form must reproduce the above copyright
   40  *    notice, this list of conditions and the following disclaimer in the
   41  *    documentation and/or other materials provided with the distribution.
   42  * 3. All advertising materials mentioning features or use of this software
   43  *    must display the following acknowledgement:
   44  *      This product includes software developed by HAYAKAWA Koichi.
   45  * 4. The name of the author may not be used to endorse or promote products
   46  *    derived from this software without specific prior written permission.
   47  *
   48  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   49  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   50  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   51  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   52  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   53  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   54  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   55  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   56  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   57  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   58  */
   59 
   60 /*
   61  * Driver for PCI to CardBus Bridge chips
   62  *
   63  * References:
   64  *  TI Datasheets:
   65  *   http://www-s.ti.com/cgi-bin/sc/generic2.cgi?family=PCI+CARDBUS+CONTROLLERS
   66  *
   67  * Written by Jonathan Chen <jon@freebsd.org>
   68  * The author would like to acknowledge:
   69  *  * HAYAKAWA Koichi: Author of the NetBSD code for the same thing
   70  *  * Warner Losh: Newbus/newcard guru and author of the pccard side of things
   71  *  * YAMAMOTO Shigeru: Author of another FreeBSD cardbus driver
   72  *  * David Cross: Author of the initial ugly hack for a specific cardbus card
   73  */
   74 
   75 #include <sys/cdefs.h>
   76 __FBSDID("$FreeBSD$");
   77 
   78 #include <sys/param.h>
   79 #include <sys/bus.h>
   80 #include <sys/condvar.h>
   81 #include <sys/errno.h>
   82 #include <sys/kernel.h>
   83 #include <sys/module.h>
   84 #include <sys/kthread.h>
   85 #include <sys/lock.h>
   86 #include <sys/malloc.h>
   87 #include <sys/mutex.h>
   88 #include <sys/proc.h>
   89 #include <sys/rman.h>
   90 #include <sys/sysctl.h>
   91 #include <sys/systm.h>
   92 #include <machine/bus.h>
   93 #include <machine/resource.h>
   94 
   95 #include <dev/pci/pcireg.h>
   96 #include <dev/pci/pcivar.h>
   97 #include <dev/pci/pcib_private.h>
   98 
   99 #include <dev/pccard/pccardreg.h>
  100 #include <dev/pccard/pccardvar.h>
  101 
  102 #include <dev/exca/excareg.h>
  103 #include <dev/exca/excavar.h>
  104 
  105 #include <dev/pccbb/pccbbreg.h>
  106 #include <dev/pccbb/pccbbvar.h>
  107 
  108 #include "power_if.h"
  109 #include "card_if.h"
  110 #include "pcib_if.h"
  111 
  112 #define DPRINTF(x) do { if (cbb_debug) printf x; } while (0)
  113 #define DEVPRINTF(x) do { if (cbb_debug) device_printf x; } while (0)
  114 
  115 #define PCI_MASK_CONFIG(DEV,REG,MASK,SIZE)                              \
  116         pci_write_config(DEV, REG, pci_read_config(DEV, REG, SIZE) MASK, SIZE)
  117 #define PCI_MASK2_CONFIG(DEV,REG,MASK1,MASK2,SIZE)                      \
  118         pci_write_config(DEV, REG, (                                    \
  119                 pci_read_config(DEV, REG, SIZE) MASK1) MASK2, SIZE)
  120 
  121 #define CBB_CARD_PRESENT(s) ((s & CBB_STATE_CD) == 0)
  122 
  123 #define CBB_START_MEM   0x88000000
  124 #define CBB_START_32_IO 0x1000
  125 #define CBB_START_16_IO 0x100
  126 
  127 /* sysctl vars */
  128 static SYSCTL_NODE(_hw, OID_AUTO, cbb, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
  129     "CBB parameters");
  130 
  131 /* There's no way to say TUNEABLE_LONG to get the right types */
  132 u_long cbb_start_mem = CBB_START_MEM;
  133 SYSCTL_ULONG(_hw_cbb, OID_AUTO, start_memory, CTLFLAG_RWTUN,
  134     &cbb_start_mem, CBB_START_MEM,
  135     "Starting address for memory allocations");
  136 
  137 u_long cbb_start_16_io = CBB_START_16_IO;
  138 SYSCTL_ULONG(_hw_cbb, OID_AUTO, start_16_io, CTLFLAG_RWTUN,
  139     &cbb_start_16_io, CBB_START_16_IO,
  140     "Starting ioport for 16-bit cards");
  141 
  142 u_long cbb_start_32_io = CBB_START_32_IO;
  143 SYSCTL_ULONG(_hw_cbb, OID_AUTO, start_32_io, CTLFLAG_RWTUN,
  144     &cbb_start_32_io, CBB_START_32_IO,
  145     "Starting ioport for 32-bit cards");
  146 
  147 int cbb_debug = 0;
  148 SYSCTL_INT(_hw_cbb, OID_AUTO, debug, CTLFLAG_RWTUN, &cbb_debug, 0,
  149     "Verbose cardbus bridge debugging");
  150 
  151 static void     cbb_insert(struct cbb_softc *sc);
  152 static void     cbb_removal(struct cbb_softc *sc);
  153 static uint32_t cbb_detect_voltage(device_t brdev);
  154 static int      cbb_cardbus_reset_power(device_t brdev, device_t child, int on);
  155 static int      cbb_cardbus_io_open(device_t brdev, int win, uint32_t start,
  156                     uint32_t end);
  157 static int      cbb_cardbus_mem_open(device_t brdev, int win,
  158                     uint32_t start, uint32_t end);
  159 static void     cbb_cardbus_auto_open(struct cbb_softc *sc, int type);
  160 static int      cbb_cardbus_activate_resource(device_t brdev, device_t child,
  161                     int type, int rid, struct resource *res);
  162 static int      cbb_cardbus_deactivate_resource(device_t brdev,
  163                     device_t child, int type, int rid, struct resource *res);
  164 static struct resource  *cbb_cardbus_alloc_resource(device_t brdev,
  165                     device_t child, int type, int *rid, rman_res_t start,
  166                     rman_res_t end, rman_res_t count, u_int flags);
  167 static int      cbb_cardbus_release_resource(device_t brdev, device_t child,
  168                     int type, int rid, struct resource *res);
  169 static int      cbb_cardbus_power_enable_socket(device_t brdev,
  170                     device_t child);
  171 static int      cbb_cardbus_power_disable_socket(device_t brdev,
  172                     device_t child);
  173 static int      cbb_func_filt(void *arg);
  174 static void     cbb_func_intr(void *arg);
  175 
  176 static void
  177 cbb_remove_res(struct cbb_softc *sc, struct resource *res)
  178 {
  179         struct cbb_reslist *rle;
  180 
  181         SLIST_FOREACH(rle, &sc->rl, link) {
  182                 if (rle->res == res) {
  183                         SLIST_REMOVE(&sc->rl, rle, cbb_reslist, link);
  184                         free(rle, M_DEVBUF);
  185                         return;
  186                 }
  187         }
  188 }
  189 
  190 static struct resource *
  191 cbb_find_res(struct cbb_softc *sc, int type, int rid)
  192 {
  193         struct cbb_reslist *rle;
  194 
  195         SLIST_FOREACH(rle, &sc->rl, link)
  196                 if (SYS_RES_MEMORY == rle->type && rid == rle->rid)
  197                         return (rle->res);
  198         return (NULL);
  199 }
  200 
  201 static void
  202 cbb_insert_res(struct cbb_softc *sc, struct resource *res, int type,
  203     int rid)
  204 {
  205         struct cbb_reslist *rle;
  206 
  207         /*
  208          * Need to record allocated resource so we can iterate through
  209          * it later.
  210          */
  211         rle = malloc(sizeof(struct cbb_reslist), M_DEVBUF, M_NOWAIT);
  212         if (rle == NULL)
  213                 panic("cbb_cardbus_alloc_resource: can't record entry!");
  214         rle->res = res;
  215         rle->type = type;
  216         rle->rid = rid;
  217         SLIST_INSERT_HEAD(&sc->rl, rle, link);
  218 }
  219 
  220 static void
  221 cbb_destroy_res(struct cbb_softc *sc)
  222 {
  223         struct cbb_reslist *rle;
  224 
  225         while ((rle = SLIST_FIRST(&sc->rl)) != NULL) {
  226                 device_printf(sc->dev, "Danger Will Robinson: Resource "
  227                     "left allocated!  This is a bug... "
  228                     "(rid=%x, type=%d, addr=%jx)\n", rle->rid, rle->type,
  229                     rman_get_start(rle->res));
  230                 SLIST_REMOVE_HEAD(&sc->rl, link);
  231                 free(rle, M_DEVBUF);
  232         }
  233 }
  234 
  235 /*
  236  * Disable function interrupts by telling the bridge to generate IRQ1
  237  * interrupts.  These interrupts aren't really generated by the chip, since
  238  * IRQ1 is reserved.  Some chipsets assert INTA# inappropriately during
  239  * initialization, so this helps to work around the problem.
  240  *
  241  * XXX We can't do this workaround for all chipsets, because this
  242  * XXX causes interference with the keyboard because somechipsets will
  243  * XXX actually signal IRQ1 over their serial interrupt connections to
  244  * XXX the south bridge.  Disable it it for now.
  245  */
  246 void
  247 cbb_disable_func_intr(struct cbb_softc *sc)
  248 {
  249 #if 0
  250         uint8_t reg;
  251 
  252         reg = (exca_getb(&sc->exca, EXCA_INTR) & ~EXCA_INTR_IRQ_MASK) | 
  253             EXCA_INTR_IRQ_RESERVED1;
  254         exca_putb(&sc->exca, EXCA_INTR, reg);
  255 #endif
  256 }
  257 
  258 /*
  259  * Enable function interrupts.  We turn on function interrupts when the card
  260  * requests an interrupt.  The PCMCIA standard says that we should set
  261  * the lower 4 bits to 0 to route via PCI.  Note: we call this for both
  262  * CardBus and R2 (PC Card) cases, but it should have no effect on CardBus
  263  * cards.
  264  */
  265 static void
  266 cbb_enable_func_intr(struct cbb_softc *sc)
  267 {
  268         uint8_t reg;
  269 
  270         reg = (exca_getb(&sc->exca, EXCA_INTR) & ~EXCA_INTR_IRQ_MASK) | 
  271             EXCA_INTR_IRQ_NONE;
  272         PCI_MASK_CONFIG(sc->dev, CBBR_BRIDGECTRL,
  273             & ~CBBM_BRIDGECTRL_INTR_IREQ_ISA_EN, 2);
  274         exca_putb(&sc->exca, EXCA_INTR, reg);
  275 }
  276 
  277 int
  278 cbb_detach(device_t brdev)
  279 {
  280         struct cbb_softc *sc = device_get_softc(brdev);
  281         device_t *devlist;
  282         int tmp, tries, error, numdevs;
  283 
  284         /*
  285          * Before we delete the children (which we have to do because
  286          * attach doesn't check for children busses correctly), we have
  287          * to detach the children.  Even if we didn't need to delete the
  288          * children, we have to detach them.
  289          */
  290         error = bus_generic_detach(brdev);
  291         if (error != 0)
  292                 return (error);
  293 
  294         /*
  295          * Since the attach routine doesn't search for children before it
  296          * attaches them to this device, we must delete them here in order
  297          * for the kldload/unload case to work.  If we failed to do that, then
  298          * we'd get duplicate devices when cbb.ko was reloaded.
  299          */
  300         tries = 10;
  301         do {
  302                 error = device_get_children(brdev, &devlist, &numdevs);
  303                 if (error == 0)
  304                         break;
  305                 /*
  306                  * Try hard to cope with low memory.
  307                  */
  308                 if (error == ENOMEM) {
  309                         pause("cbbnomem", 1);
  310                         continue;
  311                 }
  312         } while (tries-- > 0);
  313         for (tmp = 0; tmp < numdevs; tmp++)
  314                 device_delete_child(brdev, devlist[tmp]);
  315         free(devlist, M_TEMP);
  316 
  317         /* Turn off the interrupts */
  318         cbb_set(sc, CBB_SOCKET_MASK, 0);
  319 
  320         /* reset 16-bit pcmcia bus */
  321         exca_clrb(&sc->exca, EXCA_INTR, EXCA_INTR_RESET);
  322 
  323         /* turn off power */
  324         cbb_power(brdev, CARD_OFF);
  325 
  326         /* Ack the interrupt */
  327         cbb_set(sc, CBB_SOCKET_EVENT, 0xffffffff);
  328 
  329         /*
  330          * Wait for the thread to die.  kproc_exit will do a wakeup
  331          * on the event thread's struct proc * so that we know it is
  332          * safe to proceed.  IF the thread is running, set the please
  333          * die flag and wait for it to comply.  Since the wakeup on
  334          * the event thread happens only in kproc_exit, we don't
  335          * need to loop here.
  336          */
  337         bus_teardown_intr(brdev, sc->irq_res, sc->intrhand);
  338         mtx_lock(&sc->mtx);
  339         sc->flags |= CBB_KTHREAD_DONE;
  340         while (sc->flags & CBB_KTHREAD_RUNNING) {
  341                 DEVPRINTF((sc->dev, "Waiting for thread to die\n"));
  342                 wakeup(&sc->intrhand);
  343                 msleep(sc->event_thread, &sc->mtx, PWAIT, "cbbun", 0);
  344         }
  345         mtx_unlock(&sc->mtx);
  346 
  347         bus_release_resource(brdev, SYS_RES_IRQ, 0, sc->irq_res);
  348         bus_release_resource(brdev, SYS_RES_MEMORY, CBBR_SOCKBASE,
  349             sc->base_res);
  350         mtx_destroy(&sc->mtx);
  351         return (0);
  352 }
  353 
  354 int
  355 cbb_setup_intr(device_t dev, device_t child, struct resource *irq,
  356   int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
  357    void **cookiep)
  358 {
  359         struct cbb_intrhand *ih;
  360         struct cbb_softc *sc = device_get_softc(dev);
  361         int err;
  362 
  363         if (filt == NULL && intr == NULL)
  364                 return (EINVAL);
  365         ih = malloc(sizeof(struct cbb_intrhand), M_DEVBUF, M_NOWAIT);
  366         if (ih == NULL)
  367                 return (ENOMEM);
  368         *cookiep = ih;
  369         ih->filt = filt;
  370         ih->intr = intr;
  371         ih->arg = arg;
  372         ih->sc = sc;
  373         /*
  374          * XXX need to turn on ISA interrupts, if we ever support them, but
  375          * XXX for now that's all we need to do.
  376          */
  377         err = BUS_SETUP_INTR(device_get_parent(dev), child, irq, flags,
  378             filt ? cbb_func_filt : NULL, intr ? cbb_func_intr : NULL, ih,
  379             &ih->cookie);
  380         if (err != 0) {
  381                 free(ih, M_DEVBUF);
  382                 return (err);
  383         }
  384         cbb_enable_func_intr(sc);
  385         sc->cardok = 1;
  386         return 0;
  387 }
  388 
  389 int
  390 cbb_teardown_intr(device_t dev, device_t child, struct resource *irq,
  391     void *cookie)
  392 {
  393         struct cbb_intrhand *ih;
  394         int err;
  395 
  396         /* XXX Need to do different things for ISA interrupts. */
  397         ih = (struct cbb_intrhand *) cookie;
  398         err = BUS_TEARDOWN_INTR(device_get_parent(dev), child, irq,
  399             ih->cookie);
  400         if (err != 0)
  401                 return (err);
  402         free(ih, M_DEVBUF);
  403         return (0);
  404 }
  405 
  406 void
  407 cbb_driver_added(device_t brdev, driver_t *driver)
  408 {
  409         struct cbb_softc *sc = device_get_softc(brdev);
  410         device_t *devlist;
  411         device_t dev;
  412         int tmp;
  413         int numdevs;
  414         int wake = 0;
  415 
  416         DEVICE_IDENTIFY(driver, brdev);
  417         tmp = device_get_children(brdev, &devlist, &numdevs);
  418         if (tmp != 0) {
  419                 device_printf(brdev, "Cannot get children list, no reprobe\n");
  420                 return;
  421         }
  422         for (tmp = 0; tmp < numdevs; tmp++) {
  423                 dev = devlist[tmp];
  424                 if (device_get_state(dev) == DS_NOTPRESENT &&
  425                     device_probe_and_attach(dev) == 0)
  426                         wake++;
  427         }
  428         free(devlist, M_TEMP);
  429 
  430         if (wake > 0)
  431                 wakeup(&sc->intrhand);
  432 }
  433 
  434 void
  435 cbb_child_detached(device_t brdev, device_t child)
  436 {
  437         struct cbb_softc *sc = device_get_softc(brdev);
  438 
  439         /* I'm not sure we even need this */
  440         if (child != sc->cbdev && child != sc->exca.pccarddev)
  441                 device_printf(brdev, "Unknown child detached: %s\n",
  442                     device_get_nameunit(child));
  443 }
  444 
  445 /************************************************************************/
  446 /* Kthreads                                                             */
  447 /************************************************************************/
  448 
  449 void
  450 cbb_event_thread(void *arg)
  451 {
  452         struct cbb_softc *sc = arg;
  453         uint32_t status;
  454         int err;
  455         int not_a_card = 0;
  456 
  457         /*
  458          * We need to act as a power sequencer on startup.  Delay 2s/channel
  459          * to ensure the other channels have had a chance to come up.  We likely
  460          * should add a lock that's shared on a per-slot basis so that only
  461          * one power event can happen per slot at a time.
  462          */
  463         pause("cbbstart", hz * device_get_unit(sc->dev) * 2);
  464         mtx_lock(&sc->mtx);
  465         sc->flags |= CBB_KTHREAD_RUNNING;
  466         while ((sc->flags & CBB_KTHREAD_DONE) == 0) {
  467                 mtx_unlock(&sc->mtx);
  468                 status = cbb_get(sc, CBB_SOCKET_STATE);
  469                 DPRINTF(("Status is 0x%x\n", status));
  470                 if (!CBB_CARD_PRESENT(status)) {
  471                         not_a_card = 0;         /* We know card type */
  472                         cbb_removal(sc);
  473                 } else if (status & CBB_STATE_NOT_A_CARD) {
  474                         /*
  475                          * Up to 10 times, try to rescan the card when we see
  476                          * NOT_A_CARD.  10 is somehwat arbitrary.  When this
  477                          * pathology hits, there's a ~40% chance each try will
  478                          * fail.  10 tries takes about 5s and results in a
  479                          * 99.99% certainty of the results.
  480                          */
  481                         if (not_a_card++ < 10) {
  482                                 DEVPRINTF((sc->dev,
  483                                     "Not a card bit set, rescanning\n"));
  484                                 cbb_setb(sc, CBB_SOCKET_FORCE, CBB_FORCE_CV_TEST);
  485                         } else {
  486                                 device_printf(sc->dev,
  487                                     "Can't determine card type\n");
  488                         }
  489                 } else {
  490                         not_a_card = 0;         /* We know card type */
  491                         cbb_insert(sc);
  492                 }
  493 
  494                 /*
  495                  * First time through we need to tell mountroot that we're
  496                  * done.
  497                  */
  498                 if (sc->sc_root_token) {
  499                         root_mount_rel(sc->sc_root_token);
  500                         sc->sc_root_token = NULL;
  501                 }
  502 
  503                 /*
  504                  * Wait until it has been 250ms since the last time we
  505                  * get an interrupt.  We handle the rest of the interrupt
  506                  * at the top of the loop.  Although we clear the bit in the
  507                  * ISR, we signal sc->cv from the detach path after we've
  508                  * set the CBB_KTHREAD_DONE bit, so we can't do a simple
  509                  * 250ms sleep here.
  510                  *
  511                  * In our ISR, we turn off the card changed interrupt.  Turn
  512                  * them back on here before we wait for them to happen.  We
  513                  * turn them on/off so that we can tolerate a large latency
  514                  * between the time we signal cbb_event_thread and it gets
  515                  * a chance to run.
  516                  */
  517                 mtx_lock(&sc->mtx);
  518                 cbb_setb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD | CBB_SOCKET_MASK_CSTS);
  519                 msleep(&sc->intrhand, &sc->mtx, 0, "-", 0);
  520                 err = 0;
  521                 while (err != EWOULDBLOCK &&
  522                     (sc->flags & CBB_KTHREAD_DONE) == 0)
  523                         err = msleep(&sc->intrhand, &sc->mtx, 0, "-", hz / 5);
  524         }
  525         DEVPRINTF((sc->dev, "Thread terminating\n"));
  526         sc->flags &= ~CBB_KTHREAD_RUNNING;
  527         mtx_unlock(&sc->mtx);
  528         kproc_exit(0);
  529 }
  530 
  531 /************************************************************************/
  532 /* Insert/removal                                                       */
  533 /************************************************************************/
  534 
  535 static void
  536 cbb_insert(struct cbb_softc *sc)
  537 {
  538         uint32_t sockevent, sockstate;
  539 
  540         sockevent = cbb_get(sc, CBB_SOCKET_EVENT);
  541         sockstate = cbb_get(sc, CBB_SOCKET_STATE);
  542 
  543         DEVPRINTF((sc->dev, "card inserted: event=0x%08x, state=%08x\n",
  544             sockevent, sockstate));
  545 
  546         if (sockstate & CBB_STATE_R2_CARD) {
  547                 if (device_is_attached(sc->exca.pccarddev)) {
  548                         sc->flags |= CBB_16BIT_CARD;
  549                         exca_insert(&sc->exca);
  550                 } else {
  551                         device_printf(sc->dev,
  552                             "16-bit card inserted, but no pccard bus.\n");
  553                 }
  554         } else if (sockstate & CBB_STATE_CB_CARD) {
  555                 if (device_is_attached(sc->cbdev)) {
  556                         sc->flags &= ~CBB_16BIT_CARD;
  557                         CARD_ATTACH_CARD(sc->cbdev);
  558                 } else {
  559                         device_printf(sc->dev,
  560                             "CardBus card inserted, but no cardbus bus.\n");
  561                 }
  562         } else {
  563                 /*
  564                  * We should power the card down, and try again a couple of
  565                  * times if this happens. XXX
  566                  */
  567                 device_printf(sc->dev, "Unsupported card type detected\n");
  568         }
  569 }
  570 
  571 static void
  572 cbb_removal(struct cbb_softc *sc)
  573 {
  574         sc->cardok = 0;
  575         if (sc->flags & CBB_16BIT_CARD) {
  576                 exca_removal(&sc->exca);
  577         } else {
  578                 if (device_is_attached(sc->cbdev))
  579                         CARD_DETACH_CARD(sc->cbdev);
  580         }
  581         cbb_destroy_res(sc);
  582 }
  583 
  584 /************************************************************************/
  585 /* Interrupt Handler                                                    */
  586 /************************************************************************/
  587 
  588 static int
  589 cbb_func_filt(void *arg)
  590 {
  591         struct cbb_intrhand *ih = (struct cbb_intrhand *)arg;
  592         struct cbb_softc *sc = ih->sc;
  593 
  594         /*
  595          * Make sure that the card is really there.
  596          */
  597         if (!sc->cardok)
  598                 return (FILTER_STRAY);
  599         if (!CBB_CARD_PRESENT(cbb_get(sc, CBB_SOCKET_STATE))) {
  600                 sc->cardok = 0;
  601                 return (FILTER_HANDLED);
  602         }
  603 
  604         return ((*ih->filt)(ih->arg));
  605 }
  606 
  607 static void
  608 cbb_func_intr(void *arg)
  609 {
  610         struct cbb_intrhand *ih = (struct cbb_intrhand *)arg;
  611         struct cbb_softc *sc = ih->sc;
  612 
  613         /*
  614          * While this check may seem redundant, it helps close a race
  615          * condition.  If the card is ejected after the filter runs, but
  616          * before this ISR can be scheduled, then we need to do the same
  617          * filtering to prevent the card's ISR from being called.  One could
  618          * argue that the card's ISR should be able to cope, but experience
  619          * has shown they can't always.  This mitigates the problem by making
  620          * the race quite a bit smaller.  Properly written client ISRs should
  621          * cope with the card going away in the middle of the ISR.  We assume
  622          * that drivers that are sophisticated enough to use filters don't
  623          * need our protection.  This also allows us to ensure they *ARE*
  624          * called if their filter said they needed to be called.
  625          */
  626         if (ih->filt == NULL) {
  627                 if (!sc->cardok)
  628                         return;
  629                 if (!CBB_CARD_PRESENT(cbb_get(sc, CBB_SOCKET_STATE))) {
  630                         sc->cardok = 0;
  631                         return;
  632                 }
  633         }
  634 
  635         ih->intr(ih->arg);
  636 }
  637 
  638 /************************************************************************/
  639 /* Generic Power functions                                              */
  640 /************************************************************************/
  641 
  642 static uint32_t
  643 cbb_detect_voltage(device_t brdev)
  644 {
  645         struct cbb_softc *sc = device_get_softc(brdev);
  646         uint32_t psr;
  647         uint32_t vol = CARD_UKN_CARD;
  648 
  649         psr = cbb_get(sc, CBB_SOCKET_STATE);
  650 
  651         if (psr & CBB_STATE_5VCARD && psr & CBB_STATE_5VSOCK)
  652                 vol |= CARD_5V_CARD;
  653         if (psr & CBB_STATE_3VCARD && psr & CBB_STATE_3VSOCK)
  654                 vol |= CARD_3V_CARD;
  655         if (psr & CBB_STATE_XVCARD && psr & CBB_STATE_XVSOCK)
  656                 vol |= CARD_XV_CARD;
  657         if (psr & CBB_STATE_YVCARD && psr & CBB_STATE_YVSOCK)
  658                 vol |= CARD_YV_CARD;
  659 
  660         return (vol);
  661 }
  662 
  663 static uint8_t
  664 cbb_o2micro_power_hack(struct cbb_softc *sc)
  665 {
  666         uint8_t reg;
  667 
  668         /*
  669          * Issue #2: INT# not qualified with IRQ Routing Bit.  An
  670          * unexpected PCI INT# may be generated during PC Card
  671          * initialization even with the IRQ Routing Bit Set with some
  672          * PC Cards.
  673          *
  674          * This is a two part issue.  The first part is that some of
  675          * our older controllers have an issue in which the slot's PCI
  676          * INT# is NOT qualified by the IRQ routing bit (PCI reg. 3Eh
  677          * bit 7).  Regardless of the IRQ routing bit, if NO ISA IRQ
  678          * is selected (ExCA register 03h bits 3:0, of the slot, are
  679          * cleared) we will generate INT# if IREQ# is asserted.  The
  680          * second part is because some PC Cards prematurally assert
  681          * IREQ# before the ExCA registers are fully programmed.  This
  682          * in turn asserts INT# because ExCA register 03h bits 3:0
  683          * (ISA IRQ Select) are not yet programmed.
  684          *
  685          * The fix for this issue, which will work for any controller
  686          * (old or new), is to set ExCA register 03h bits 3:0 = 0001b
  687          * (select IRQ1), of the slot, before turning on slot power.
  688          * Selecting IRQ1 will result in INT# NOT being asserted
  689          * (because IRQ1 is selected), and IRQ1 won't be asserted
  690          * because our controllers don't generate IRQ1.
  691          *
  692          * Other, non O2Micro controllers will generate irq 1 in some
  693          * situations, so we can't do this hack for everybody.  Reports of
  694          * keyboard controller's interrupts being suppressed occurred when
  695          * we did this.
  696          */
  697         reg = exca_getb(&sc->exca, EXCA_INTR);
  698         exca_putb(&sc->exca, EXCA_INTR, (reg & 0xf0) | 1);
  699         return (reg);
  700 }
  701 
  702 /*
  703  * Restore the damage that cbb_o2micro_power_hack does to EXCA_INTR so
  704  * we don't have an interrupt storm on power on.  This has the effect of
  705  * disabling card status change interrupts for the duration of poweron.
  706  */
  707 static void
  708 cbb_o2micro_power_hack2(struct cbb_softc *sc, uint8_t reg)
  709 {
  710         exca_putb(&sc->exca, EXCA_INTR, reg);
  711 }
  712 
  713 int
  714 cbb_power(device_t brdev, int volts)
  715 {
  716         uint32_t status, sock_ctrl, reg_ctrl, mask;
  717         struct cbb_softc *sc = device_get_softc(brdev);
  718         int cnt, sane;
  719         int retval = 0;
  720         int on = 0;
  721         uint8_t reg = 0;
  722 
  723         sock_ctrl = cbb_get(sc, CBB_SOCKET_CONTROL);
  724 
  725         sock_ctrl &= ~CBB_SOCKET_CTRL_VCCMASK;
  726         switch (volts & CARD_VCCMASK) {
  727         case 5:
  728                 sock_ctrl |= CBB_SOCKET_CTRL_VCC_5V;
  729                 on++;
  730                 break;
  731         case 3:
  732                 sock_ctrl |= CBB_SOCKET_CTRL_VCC_3V;
  733                 on++;
  734                 break;
  735         case XV:
  736                 sock_ctrl |= CBB_SOCKET_CTRL_VCC_XV;
  737                 on++;
  738                 break;
  739         case YV:
  740                 sock_ctrl |= CBB_SOCKET_CTRL_VCC_YV;
  741                 on++;
  742                 break;
  743         case 0:
  744                 break;
  745         default:
  746                 return (0);                     /* power NEVER changed */
  747         }
  748 
  749         /* VPP == VCC */
  750         sock_ctrl &= ~CBB_SOCKET_CTRL_VPPMASK;
  751         sock_ctrl |= ((sock_ctrl >> 4) & 0x07);
  752 
  753         if (cbb_get(sc, CBB_SOCKET_CONTROL) == sock_ctrl)
  754                 return (1); /* no change necessary */
  755         DEVPRINTF((sc->dev, "cbb_power: %dV\n", volts));
  756         if (volts != 0 && sc->chipset == CB_O2MICRO)
  757                 reg = cbb_o2micro_power_hack(sc);
  758 
  759         /*
  760          * We have to mask the card change detect interrupt while we're
  761          * messing with the power.  It is allowed to bounce while we're
  762          * messing with power as things settle down.  In addition, we mask off
  763          * the card's function interrupt by routing it via the ISA bus.  This
  764          * bit generally only affects 16-bit cards.  Some bridges allow one to
  765          * set another bit to have it also affect 32-bit cards.  Since 32-bit
  766          * cards are required to be better behaved, we don't bother to get
  767          * into those bridge specific features.
  768          *
  769          * XXX I wonder if we need to enable the READY bit interrupt in the
  770          * EXCA CSC register for 16-bit cards, and disable the CD bit?
  771          */
  772         mask = cbb_get(sc, CBB_SOCKET_MASK);
  773         mask |= CBB_SOCKET_MASK_POWER;
  774         mask &= ~CBB_SOCKET_MASK_CD;
  775         cbb_set(sc, CBB_SOCKET_MASK, mask);
  776         PCI_MASK_CONFIG(brdev, CBBR_BRIDGECTRL,
  777             |CBBM_BRIDGECTRL_INTR_IREQ_ISA_EN, 2);
  778         cbb_set(sc, CBB_SOCKET_CONTROL, sock_ctrl);
  779         if (on) {
  780                 mtx_lock(&sc->mtx);
  781                 cnt = sc->powerintr;
  782                 /*
  783                  * We have a shortish timeout of 500ms here.  Some bridges do
  784                  * not generate a POWER_CYCLE event for 16-bit cards.  In
  785                  * those cases, we have to cope the best we can, and having
  786                  * only a short delay is better than the alternatives.  Others
  787                  * raise the power cycle a smidge before it is really ready.
  788                  * We deal with those below.
  789                  */
  790                 sane = 10;
  791                 while (!(cbb_get(sc, CBB_SOCKET_STATE) & CBB_STATE_POWER_CYCLE) &&
  792                     cnt == sc->powerintr && sane-- > 0)
  793                         msleep(&sc->powerintr, &sc->mtx, 0, "-", hz / 20);
  794                 mtx_unlock(&sc->mtx);
  795 
  796                 /*
  797                  * Relax for 100ms.  Some bridges appear to assert this signal
  798                  * right away, but before the card has stabilized.  Other
  799                  * cards need need more time to cope up reliabily.
  800                  * Experiments with troublesome setups show this to be a
  801                  * "cheap" way to enhance reliabilty.  We need not do this for
  802                  * "off" since we don't touch the card after we turn it off.
  803                  */
  804                 pause("cbbPwr", min(hz / 10, 1));
  805 
  806                 /*
  807                  * The TOPIC95B requires a little bit extra time to get its
  808                  * act together, so delay for an additional 100ms.  Also as
  809                  * documented below, it doesn't seem to set the POWER_CYCLE
  810                  * bit, so don't whine if it never came on.
  811                  */
  812                 if (sc->chipset == CB_TOPIC95)
  813                         pause("cbb95B", hz / 10);
  814                 else if (sane <= 0)
  815                         device_printf(sc->dev, "power timeout, doom?\n");
  816         }
  817 
  818         /*
  819          * After the power is good, we can turn off the power interrupt.
  820          * However, the PC Card standard says that we must delay turning the
  821          * CD bit back on for a bit to allow for bouncyness on power down
  822          * (recall that we don't wait above for a power down, since we don't
  823          * get an interrupt for that).  We're called either from the suspend
  824          * code in which case we don't want to turn card change on again, or
  825          * we're called from the card insertion code, in which case the cbb
  826          * thread will turn it on for us before it waits to be woken by a
  827          * change event.
  828          *
  829          * NB: Topic95B doesn't set the power cycle bit.  we assume that
  830          * both it and the TOPIC95 behave the same.
  831          */
  832         cbb_clrb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_POWER);
  833         status = cbb_get(sc, CBB_SOCKET_STATE);
  834         if (on && sc->chipset != CB_TOPIC95) {
  835                 if ((status & CBB_STATE_POWER_CYCLE) == 0)
  836                         device_printf(sc->dev, "Power not on?\n");
  837         }
  838         if (status & CBB_STATE_BAD_VCC_REQ) {
  839                 device_printf(sc->dev, "Bad Vcc requested\n");  
  840                 /*
  841                  * Turn off the power, and try again.  Retrigger other
  842                  * active interrupts via force register.  From NetBSD
  843                  * PR 36652, coded by me to description there.
  844                  */
  845                 sock_ctrl &= ~CBB_SOCKET_CTRL_VCCMASK;
  846                 sock_ctrl &= ~CBB_SOCKET_CTRL_VPPMASK;
  847                 cbb_set(sc, CBB_SOCKET_CONTROL, sock_ctrl);
  848                 status &= ~CBB_STATE_BAD_VCC_REQ;
  849                 status &= ~CBB_STATE_DATA_LOST;
  850                 status |= CBB_FORCE_CV_TEST;
  851                 cbb_set(sc, CBB_SOCKET_FORCE, status);
  852                 goto done;
  853         }
  854         if (sc->chipset == CB_TOPIC97) {
  855                 reg_ctrl = pci_read_config(sc->dev, TOPIC_REG_CTRL, 4);
  856                 reg_ctrl &= ~TOPIC97_REG_CTRL_TESTMODE;
  857                 if (on)
  858                         reg_ctrl |= TOPIC97_REG_CTRL_CLKRUN_ENA;
  859                 else
  860                         reg_ctrl &= ~TOPIC97_REG_CTRL_CLKRUN_ENA;
  861                 pci_write_config(sc->dev, TOPIC_REG_CTRL, reg_ctrl, 4);
  862         }
  863         retval = 1;
  864 done:;
  865         if (volts != 0 && sc->chipset == CB_O2MICRO)
  866                 cbb_o2micro_power_hack2(sc, reg);
  867         return (retval);
  868 }
  869 
  870 static int
  871 cbb_current_voltage(device_t brdev)
  872 {
  873         struct cbb_softc *sc = device_get_softc(brdev);
  874         uint32_t ctrl;
  875 
  876         ctrl = cbb_get(sc, CBB_SOCKET_CONTROL);
  877         switch (ctrl & CBB_SOCKET_CTRL_VCCMASK) {
  878         case CBB_SOCKET_CTRL_VCC_5V:
  879                 return CARD_5V_CARD;
  880         case CBB_SOCKET_CTRL_VCC_3V:
  881                 return CARD_3V_CARD;
  882         case CBB_SOCKET_CTRL_VCC_XV:
  883                 return CARD_XV_CARD;
  884         case CBB_SOCKET_CTRL_VCC_YV:
  885                 return CARD_YV_CARD;
  886         }
  887         return 0;
  888 }
  889 
  890 /*
  891  * detect the voltage for the card, and set it.  Since the power
  892  * used is the square of the voltage, lower voltages is a big win
  893  * and what Windows does (and what Microsoft prefers).  The MS paper
  894  * also talks about preferring the CIS entry as well, but that has
  895  * to be done elsewhere.  We also optimize power sequencing here
  896  * and don't change things if we're already powered up at a supported
  897  * voltage.
  898  *
  899  * In addition, we power up with OE disabled.  We'll set it later
  900  * in the power up sequence.
  901  */
  902 static int
  903 cbb_do_power(device_t brdev)
  904 {
  905         struct cbb_softc *sc = device_get_softc(brdev);
  906         uint32_t voltage, curpwr;
  907         uint32_t status;
  908 
  909         /* Don't enable OE (output enable) until power stable */
  910         exca_clrb(&sc->exca, EXCA_PWRCTL, EXCA_PWRCTL_OE);
  911 
  912         voltage = cbb_detect_voltage(brdev);
  913         curpwr = cbb_current_voltage(brdev);
  914         status = cbb_get(sc, CBB_SOCKET_STATE);
  915         if ((status & CBB_STATE_POWER_CYCLE) && (voltage & curpwr))
  916                 return 0;
  917         /* Prefer lowest voltage supported */
  918         cbb_power(brdev, CARD_OFF);
  919         if (voltage & CARD_YV_CARD)
  920                 cbb_power(brdev, CARD_VCC(YV));
  921         else if (voltage & CARD_XV_CARD)
  922                 cbb_power(brdev, CARD_VCC(XV));
  923         else if (voltage & CARD_3V_CARD)
  924                 cbb_power(brdev, CARD_VCC(3));
  925         else if (voltage & CARD_5V_CARD)
  926                 cbb_power(brdev, CARD_VCC(5));
  927         else {
  928                 device_printf(brdev, "Unknown card voltage\n");
  929                 return (ENXIO);
  930         }
  931         return (0);
  932 }
  933 
  934 /************************************************************************/
  935 /* CardBus power functions                                              */
  936 /************************************************************************/
  937 
  938 static int
  939 cbb_cardbus_reset_power(device_t brdev, device_t child, int on)
  940 {
  941         struct cbb_softc *sc = device_get_softc(brdev);
  942         uint32_t b, h;
  943         int delay, count, zero_seen, func;
  944 
  945         /*
  946          * Asserting reset for 20ms is necessary for most bridges.  For some
  947          * reason, the Ricoh RF5C47x bridges need it asserted for 400ms.  The
  948          * root cause of this is unknown, and NetBSD does the same thing.
  949          */
  950         delay = sc->chipset == CB_RF5C47X ? 400 : 20;
  951         PCI_MASK_CONFIG(brdev, CBBR_BRIDGECTRL, |CBBM_BRIDGECTRL_RESET, 2);
  952         pause("cbbP3", hz * delay / 1000);
  953 
  954         /*
  955          * If a card exists and we're turning it on, take it out of reset.
  956          * After clearing reset, wait up to 1.1s for the first configuration
  957          * register (vendor/product) configuration register of device 0.0 to
  958          * become != 0xffffffff.  The PCMCIA PC Card Host System Specification
  959          * says that when powering up the card, the PCI Spec v2.1 must be
  960          * followed.  In PCI spec v2.2 Table 4-6, Trhfa (Reset High to first
  961          * Config Access) is at most 2^25 clocks, or just over 1s.  Section
  962          * 2.2.1 states any card not ready to participate in bus transactions
  963          * must tristate its outputs.  Therefore, any access to its
  964          * configuration registers must be ignored.  In that state, the config
  965          * reg will read 0xffffffff.  Section 6.2.1 states a vendor id of
  966          * 0xffff is invalid, so this can never match a real card.  Print a
  967          * warning if it never returns a real id.  The PCMCIA PC Card
  968          * Electrical Spec Section 5.2.7.1 implies only device 0 is present on
  969          * a cardbus bus, so that's the only register we check here.
  970          */
  971         if (on && CBB_CARD_PRESENT(cbb_get(sc, CBB_SOCKET_STATE))) {
  972                 PCI_MASK_CONFIG(brdev, CBBR_BRIDGECTRL,
  973                     &~CBBM_BRIDGECTRL_RESET, 2);
  974                 b = pcib_get_bus(child);
  975                 count = 1100 / 20;
  976                 do {
  977                         pause("cbbP4", hz * 2 / 100);
  978                 } while (PCIB_READ_CONFIG(brdev, b, 0, 0, PCIR_DEVVENDOR, 4) ==
  979                     0xfffffffful && --count >= 0);
  980                 if (count < 0)
  981                         device_printf(brdev, "Warning: Bus reset timeout\n");
  982 
  983                 /*
  984                  * Some cards (so far just an atheros card I have) seem to
  985                  * come out of reset in a funky state. They report they are
  986                  * multi-function cards, but have nonsense for some of the
  987                  * higher functions.  So if the card claims to be MFDEV, and
  988                  * any of the higher functions' ID is 0, then we've hit the
  989                  * bug and we'll try again.
  990                  */
  991                 h = PCIB_READ_CONFIG(brdev, b, 0, 0, PCIR_HDRTYPE, 1);
  992                 if ((h & PCIM_MFDEV) == 0)
  993                         return 0;
  994                 zero_seen = 0;
  995                 for (func = 1; func < 8; func++) {
  996                         h = PCIB_READ_CONFIG(brdev, b, 0, func,
  997                             PCIR_DEVVENDOR, 4);
  998                         if (h == 0)
  999                                 zero_seen++;
 1000                 }
 1001                 if (!zero_seen)
 1002                         return 0;
 1003                 return (EINVAL);
 1004         }
 1005         return 0;
 1006 }
 1007 
 1008 static int
 1009 cbb_cardbus_power_disable_socket(device_t brdev, device_t child)
 1010 {
 1011         cbb_power(brdev, CARD_OFF);
 1012         cbb_cardbus_reset_power(brdev, child, 0);
 1013         return (0);
 1014 }
 1015 
 1016 static int
 1017 cbb_cardbus_power_enable_socket(device_t brdev, device_t child)
 1018 {
 1019         struct cbb_softc *sc = device_get_softc(brdev);
 1020         int err, count;
 1021 
 1022         if (!CBB_CARD_PRESENT(cbb_get(sc, CBB_SOCKET_STATE)))
 1023                 return (ENODEV);
 1024 
 1025         count = 10;
 1026         do {
 1027                 err = cbb_do_power(brdev);
 1028                 if (err)
 1029                         return (err);
 1030                 err = cbb_cardbus_reset_power(brdev, child, 1);
 1031                 if (err) {
 1032                         device_printf(brdev, "Reset failed, trying again.\n");
 1033                         cbb_cardbus_power_disable_socket(brdev, child);
 1034                         pause("cbbErr1", hz / 10); /* wait 100ms */
 1035                 }
 1036         } while (err != 0 && count-- > 0);
 1037         return (0);
 1038 }
 1039 
 1040 /************************************************************************/
 1041 /* CardBus Resource                                                     */
 1042 /************************************************************************/
 1043 
 1044 static void
 1045 cbb_activate_window(device_t brdev, int type)
 1046 {
 1047 
 1048         PCI_ENABLE_IO(device_get_parent(brdev), brdev, type);
 1049 }
 1050 
 1051 static int
 1052 cbb_cardbus_io_open(device_t brdev, int win, uint32_t start, uint32_t end)
 1053 {
 1054         int basereg;
 1055         int limitreg;
 1056 
 1057         if ((win < 0) || (win > 1)) {
 1058                 DEVPRINTF((brdev,
 1059                     "cbb_cardbus_io_open: window out of range %d\n", win));
 1060                 return (EINVAL);
 1061         }
 1062 
 1063         basereg = win * 8 + CBBR_IOBASE0;
 1064         limitreg = win * 8 + CBBR_IOLIMIT0;
 1065 
 1066         pci_write_config(brdev, basereg, start, 4);
 1067         pci_write_config(brdev, limitreg, end, 4);
 1068         cbb_activate_window(brdev, SYS_RES_IOPORT);
 1069         return (0);
 1070 }
 1071 
 1072 static int
 1073 cbb_cardbus_mem_open(device_t brdev, int win, uint32_t start, uint32_t end)
 1074 {
 1075         int basereg;
 1076         int limitreg;
 1077 
 1078         if ((win < 0) || (win > 1)) {
 1079                 DEVPRINTF((brdev,
 1080                     "cbb_cardbus_mem_open: window out of range %d\n", win));
 1081                 return (EINVAL);
 1082         }
 1083 
 1084         basereg = win * 8 + CBBR_MEMBASE0;
 1085         limitreg = win * 8 + CBBR_MEMLIMIT0;
 1086 
 1087         pci_write_config(brdev, basereg, start, 4);
 1088         pci_write_config(brdev, limitreg, end, 4);
 1089         cbb_activate_window(brdev, SYS_RES_MEMORY);
 1090         return (0);
 1091 }
 1092 
 1093 #define START_NONE 0xffffffff
 1094 #define END_NONE 0
 1095 
 1096 static void
 1097 cbb_cardbus_auto_open(struct cbb_softc *sc, int type)
 1098 {
 1099         uint32_t starts[2];
 1100         uint32_t ends[2];
 1101         struct cbb_reslist *rle;
 1102         int align, i;
 1103         uint32_t reg;
 1104 
 1105         starts[0] = starts[1] = START_NONE;
 1106         ends[0] = ends[1] = END_NONE;
 1107 
 1108         if (type == SYS_RES_MEMORY)
 1109                 align = CBB_MEMALIGN;
 1110         else if (type == SYS_RES_IOPORT)
 1111                 align = CBB_IOALIGN;
 1112         else
 1113                 align = 1;
 1114 
 1115         SLIST_FOREACH(rle, &sc->rl, link) {
 1116                 if (rle->type != type)
 1117                         continue;
 1118                 if (rle->res == NULL)
 1119                         continue;
 1120                 if (!(rman_get_flags(rle->res) & RF_ACTIVE))
 1121                         continue;
 1122                 if (rman_get_flags(rle->res) & RF_PREFETCHABLE)
 1123                         i = 1;
 1124                 else
 1125                         i = 0;
 1126                 if (rman_get_start(rle->res) < starts[i])
 1127                         starts[i] = rman_get_start(rle->res);
 1128                 if (rman_get_end(rle->res) > ends[i])
 1129                         ends[i] = rman_get_end(rle->res);
 1130         }
 1131         for (i = 0; i < 2; i++) {
 1132                 if (starts[i] == START_NONE)
 1133                         continue;
 1134                 starts[i] &= ~(align - 1);
 1135                 ends[i] = roundup2(ends[i], align) - 1;
 1136         }
 1137         if (starts[0] != START_NONE && starts[1] != START_NONE) {
 1138                 if (starts[0] < starts[1]) {
 1139                         if (ends[0] > starts[1]) {
 1140                                 device_printf(sc->dev, "Overlapping ranges"
 1141                                     " for prefetch and non-prefetch memory\n");
 1142                                 return;
 1143                         }
 1144                 } else {
 1145                         if (ends[1] > starts[0]) {
 1146                                 device_printf(sc->dev, "Overlapping ranges"
 1147                                     " for prefetch and non-prefetch memory\n");
 1148                                 return;
 1149                         }
 1150                 }
 1151         }
 1152 
 1153         if (type == SYS_RES_MEMORY) {
 1154                 cbb_cardbus_mem_open(sc->dev, 0, starts[0], ends[0]);
 1155                 cbb_cardbus_mem_open(sc->dev, 1, starts[1], ends[1]);
 1156                 reg = pci_read_config(sc->dev, CBBR_BRIDGECTRL, 2);
 1157                 reg &= ~(CBBM_BRIDGECTRL_PREFETCH_0 |
 1158                     CBBM_BRIDGECTRL_PREFETCH_1);
 1159                 if (starts[1] != START_NONE)
 1160                         reg |= CBBM_BRIDGECTRL_PREFETCH_1;
 1161                 pci_write_config(sc->dev, CBBR_BRIDGECTRL, reg, 2);
 1162                 if (bootverbose) {
 1163                         device_printf(sc->dev, "Opening memory:\n");
 1164                         if (starts[0] != START_NONE)
 1165                                 device_printf(sc->dev, "Normal: %#x-%#x\n",
 1166                                     starts[0], ends[0]);
 1167                         if (starts[1] != START_NONE)
 1168                                 device_printf(sc->dev, "Prefetch: %#x-%#x\n",
 1169                                     starts[1], ends[1]);
 1170                 }
 1171         } else if (type == SYS_RES_IOPORT) {
 1172                 cbb_cardbus_io_open(sc->dev, 0, starts[0], ends[0]);
 1173                 cbb_cardbus_io_open(sc->dev, 1, starts[1], ends[1]);
 1174                 if (bootverbose && starts[0] != START_NONE)
 1175                         device_printf(sc->dev, "Opening I/O: %#x-%#x\n",
 1176                             starts[0], ends[0]);
 1177         }
 1178 }
 1179 
 1180 static int
 1181 cbb_cardbus_activate_resource(device_t brdev, device_t child, int type,
 1182     int rid, struct resource *res)
 1183 {
 1184         int ret;
 1185 
 1186         ret = BUS_ACTIVATE_RESOURCE(device_get_parent(brdev), child,
 1187             type, rid, res);
 1188         if (ret != 0)
 1189                 return (ret);
 1190         cbb_cardbus_auto_open(device_get_softc(brdev), type);
 1191         return (0);
 1192 }
 1193 
 1194 static int
 1195 cbb_cardbus_deactivate_resource(device_t brdev, device_t child, int type,
 1196     int rid, struct resource *res)
 1197 {
 1198         int ret;
 1199 
 1200         ret = BUS_DEACTIVATE_RESOURCE(device_get_parent(brdev), child,
 1201             type, rid, res);
 1202         if (ret != 0)
 1203                 return (ret);
 1204         cbb_cardbus_auto_open(device_get_softc(brdev), type);
 1205         return (0);
 1206 }
 1207 
 1208 static struct resource *
 1209 cbb_cardbus_alloc_resource(device_t brdev, device_t child, int type,
 1210     int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
 1211 {
 1212         struct cbb_softc *sc = device_get_softc(brdev);
 1213         int tmp;
 1214         struct resource *res;
 1215         rman_res_t align;
 1216 
 1217         switch (type) {
 1218         case SYS_RES_IRQ:
 1219                 tmp = rman_get_start(sc->irq_res);
 1220                 if (start > tmp || end < tmp || count != 1) {
 1221                         device_printf(child, "requested interrupt %jd-%jd,"
 1222                             "count = %jd not supported by cbb\n",
 1223                             start, end, count);
 1224                         return (NULL);
 1225                 }
 1226                 start = end = tmp;
 1227                 flags |= RF_SHAREABLE;
 1228                 break;
 1229         case SYS_RES_IOPORT:
 1230                 if (start <= cbb_start_32_io)
 1231                         start = cbb_start_32_io;
 1232                 if (end < start)
 1233                         end = start;
 1234                 if (count > (1 << RF_ALIGNMENT(flags)))
 1235                         flags = (flags & ~RF_ALIGNMENT_MASK) | 
 1236                             rman_make_alignment_flags(count);
 1237                 break;
 1238         case SYS_RES_MEMORY:
 1239                 if (start <= cbb_start_mem)
 1240                         start = cbb_start_mem;
 1241                 if (end < start)
 1242                         end = start;
 1243                 if (count < CBB_MEMALIGN)
 1244                         align = CBB_MEMALIGN;
 1245                 else
 1246                         align = count;
 1247                 if (align > (1 << RF_ALIGNMENT(flags)))
 1248                         flags = (flags & ~RF_ALIGNMENT_MASK) | 
 1249                             rman_make_alignment_flags(align);
 1250                 break;
 1251         }
 1252         res = BUS_ALLOC_RESOURCE(device_get_parent(brdev), child, type, rid,
 1253             start, end, count, flags & ~RF_ACTIVE);
 1254         if (res == NULL) {
 1255                 printf("cbb alloc res fail type %d rid %x\n", type, *rid);
 1256                 return (NULL);
 1257         }
 1258         cbb_insert_res(sc, res, type, *rid);
 1259         if (flags & RF_ACTIVE)
 1260                 if (bus_activate_resource(child, type, *rid, res) != 0) {
 1261                         bus_release_resource(child, type, *rid, res);
 1262                         return (NULL);
 1263                 }
 1264 
 1265         return (res);
 1266 }
 1267 
 1268 static int
 1269 cbb_cardbus_release_resource(device_t brdev, device_t child, int type,
 1270     int rid, struct resource *res)
 1271 {
 1272         struct cbb_softc *sc = device_get_softc(brdev);
 1273         int error;
 1274 
 1275         if (rman_get_flags(res) & RF_ACTIVE) {
 1276                 error = bus_deactivate_resource(child, type, rid, res);
 1277                 if (error != 0)
 1278                         return (error);
 1279         }
 1280         cbb_remove_res(sc, res);
 1281         return (BUS_RELEASE_RESOURCE(device_get_parent(brdev), child,
 1282             type, rid, res));
 1283 }
 1284 
 1285 /************************************************************************/
 1286 /* PC Card Power Functions                                              */
 1287 /************************************************************************/
 1288 
 1289 static int
 1290 cbb_pcic_power_enable_socket(device_t brdev, device_t child)
 1291 {
 1292         struct cbb_softc *sc = device_get_softc(brdev);
 1293         int err;
 1294 
 1295         DPRINTF(("cbb_pcic_socket_enable:\n"));
 1296 
 1297         /* power down/up the socket to reset */
 1298         err = cbb_do_power(brdev);
 1299         if (err)
 1300                 return (err);
 1301         exca_reset(&sc->exca, child);
 1302 
 1303         return (0);
 1304 }
 1305 
 1306 static int
 1307 cbb_pcic_power_disable_socket(device_t brdev, device_t child)
 1308 {
 1309         struct cbb_softc *sc = device_get_softc(brdev);
 1310 
 1311         DPRINTF(("cbb_pcic_socket_disable\n"));
 1312 
 1313         /* Turn off the card's interrupt and leave it in reset, wait 10ms */
 1314         exca_putb(&sc->exca, EXCA_INTR, 0);
 1315         pause("cbbP1", hz / 100);
 1316 
 1317         /* power down the socket */
 1318         cbb_power(brdev, CARD_OFF);
 1319         exca_putb(&sc->exca, EXCA_PWRCTL, 0);
 1320 
 1321         /* wait 300ms until power fails (Tpf). */
 1322         pause("cbbP2", hz * 300 / 1000);
 1323 
 1324         /* enable CSC interrupts */
 1325         exca_putb(&sc->exca, EXCA_INTR, EXCA_INTR_ENABLE);
 1326         return (0);
 1327 }
 1328 
 1329 /************************************************************************/
 1330 /* POWER methods                                                        */
 1331 /************************************************************************/
 1332 
 1333 int
 1334 cbb_power_enable_socket(device_t brdev, device_t child)
 1335 {
 1336         struct cbb_softc *sc = device_get_softc(brdev);
 1337 
 1338         if (sc->flags & CBB_16BIT_CARD)
 1339                 return (cbb_pcic_power_enable_socket(brdev, child));
 1340         return (cbb_cardbus_power_enable_socket(brdev, child));
 1341 }
 1342 
 1343 int
 1344 cbb_power_disable_socket(device_t brdev, device_t child)
 1345 {
 1346         struct cbb_softc *sc = device_get_softc(brdev);
 1347         if (sc->flags & CBB_16BIT_CARD)
 1348                 return (cbb_pcic_power_disable_socket(brdev, child));
 1349         return (cbb_cardbus_power_disable_socket(brdev, child));
 1350 }
 1351 
 1352 static int
 1353 cbb_pcic_activate_resource(device_t brdev, device_t child, int type, int rid,
 1354     struct resource *res)
 1355 {
 1356         struct cbb_softc *sc = device_get_softc(brdev);
 1357         int error;
 1358 
 1359         error = exca_activate_resource(&sc->exca, child, type, rid, res);
 1360         if (error == 0)
 1361                 cbb_activate_window(brdev, type);
 1362         return (error);
 1363 }
 1364 
 1365 static int
 1366 cbb_pcic_deactivate_resource(device_t brdev, device_t child, int type,
 1367     int rid, struct resource *res)
 1368 {
 1369         struct cbb_softc *sc = device_get_softc(brdev);
 1370         return (exca_deactivate_resource(&sc->exca, child, type, rid, res));
 1371 }
 1372 
 1373 static struct resource *
 1374 cbb_pcic_alloc_resource(device_t brdev, device_t child, int type, int *rid,
 1375     rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
 1376 {
 1377         struct resource *res = NULL;
 1378         struct cbb_softc *sc = device_get_softc(brdev);
 1379         int align;
 1380         int tmp;
 1381 
 1382         switch (type) {
 1383         case SYS_RES_MEMORY:
 1384                 if (start < cbb_start_mem)
 1385                         start = cbb_start_mem;
 1386                 if (end < start)
 1387                         end = start;
 1388                 if (count < CBB_MEMALIGN)
 1389                         align = CBB_MEMALIGN;
 1390                 else
 1391                         align = count;
 1392                 if (align > (1 << RF_ALIGNMENT(flags)))
 1393                         flags = (flags & ~RF_ALIGNMENT_MASK) | 
 1394                             rman_make_alignment_flags(align);
 1395                 break;
 1396         case SYS_RES_IOPORT:
 1397                 if (start < cbb_start_16_io)
 1398                         start = cbb_start_16_io;
 1399                 if (end < start)
 1400                         end = start;
 1401                 break;
 1402         case SYS_RES_IRQ:
 1403                 tmp = rman_get_start(sc->irq_res);
 1404                 if (start > tmp || end < tmp || count != 1) {
 1405                         device_printf(child, "requested interrupt %jd-%jd,"
 1406                             "count = %jd not supported by cbb\n",
 1407                             start, end, count);
 1408                         return (NULL);
 1409                 }
 1410                 flags |= RF_SHAREABLE;
 1411                 start = end = rman_get_start(sc->irq_res);
 1412                 break;
 1413         }
 1414         res = BUS_ALLOC_RESOURCE(device_get_parent(brdev), child, type, rid,
 1415             start, end, count, flags & ~RF_ACTIVE);
 1416         if (res == NULL)
 1417                 return (NULL);
 1418         cbb_insert_res(sc, res, type, *rid);
 1419         if (flags & RF_ACTIVE) {
 1420                 if (bus_activate_resource(child, type, *rid, res) != 0) {
 1421                         bus_release_resource(child, type, *rid, res);
 1422                         return (NULL);
 1423                 }
 1424         }
 1425 
 1426         return (res);
 1427 }
 1428 
 1429 static int
 1430 cbb_pcic_release_resource(device_t brdev, device_t child, int type,
 1431     int rid, struct resource *res)
 1432 {
 1433         struct cbb_softc *sc = device_get_softc(brdev);
 1434         int error;
 1435 
 1436         if (rman_get_flags(res) & RF_ACTIVE) {
 1437                 error = bus_deactivate_resource(child, type, rid, res);
 1438                 if (error != 0)
 1439                         return (error);
 1440         }
 1441         cbb_remove_res(sc, res);
 1442         return (BUS_RELEASE_RESOURCE(device_get_parent(brdev), child,
 1443             type, rid, res));
 1444 }
 1445 
 1446 /************************************************************************/
 1447 /* PC Card methods                                                      */
 1448 /************************************************************************/
 1449 
 1450 int
 1451 cbb_pcic_set_res_flags(device_t brdev, device_t child, int type, int rid,
 1452     u_long flags)
 1453 {
 1454         struct cbb_softc *sc = device_get_softc(brdev);
 1455         struct resource *res;
 1456 
 1457         if (type != SYS_RES_MEMORY)
 1458                 return (EINVAL);
 1459         res = cbb_find_res(sc, type, rid);
 1460         if (res == NULL) {
 1461                 device_printf(brdev,
 1462                     "set_res_flags: specified rid not found\n");
 1463                 return (ENOENT);
 1464         }
 1465         return (exca_mem_set_flags(&sc->exca, res, flags));
 1466 }
 1467 
 1468 int
 1469 cbb_pcic_set_memory_offset(device_t brdev, device_t child, int rid,
 1470     uint32_t cardaddr, uint32_t *deltap)
 1471 {
 1472         struct cbb_softc *sc = device_get_softc(brdev);
 1473         struct resource *res;
 1474 
 1475         res = cbb_find_res(sc, SYS_RES_MEMORY, rid);
 1476         if (res == NULL) {
 1477                 device_printf(brdev,
 1478                     "set_memory_offset: specified rid not found\n");
 1479                 return (ENOENT);
 1480         }
 1481         return (exca_mem_set_offset(&sc->exca, res, cardaddr, deltap));
 1482 }
 1483 
 1484 /************************************************************************/
 1485 /* BUS Methods                                                          */
 1486 /************************************************************************/
 1487 
 1488 int
 1489 cbb_activate_resource(device_t brdev, device_t child, int type, int rid,
 1490     struct resource *r)
 1491 {
 1492         struct cbb_softc *sc = device_get_softc(brdev);
 1493 
 1494         if (sc->flags & CBB_16BIT_CARD)
 1495                 return (cbb_pcic_activate_resource(brdev, child, type, rid, r));
 1496         else
 1497                 return (cbb_cardbus_activate_resource(brdev, child, type, rid,
 1498                     r));
 1499 }
 1500 
 1501 int
 1502 cbb_deactivate_resource(device_t brdev, device_t child, int type,
 1503     int rid, struct resource *r)
 1504 {
 1505         struct cbb_softc *sc = device_get_softc(brdev);
 1506 
 1507         if (sc->flags & CBB_16BIT_CARD)
 1508                 return (cbb_pcic_deactivate_resource(brdev, child, type,
 1509                     rid, r));
 1510         else
 1511                 return (cbb_cardbus_deactivate_resource(brdev, child, type,
 1512                     rid, r));
 1513 }
 1514 
 1515 struct resource *
 1516 cbb_alloc_resource(device_t brdev, device_t child, int type, int *rid,
 1517     rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
 1518 {
 1519         struct cbb_softc *sc = device_get_softc(brdev);
 1520 
 1521         if (sc->flags & CBB_16BIT_CARD)
 1522                 return (cbb_pcic_alloc_resource(brdev, child, type, rid,
 1523                     start, end, count, flags));
 1524         else
 1525                 return (cbb_cardbus_alloc_resource(brdev, child, type, rid,
 1526                     start, end, count, flags));
 1527 }
 1528 
 1529 int
 1530 cbb_release_resource(device_t brdev, device_t child, int type, int rid,
 1531     struct resource *r)
 1532 {
 1533         struct cbb_softc *sc = device_get_softc(brdev);
 1534 
 1535         if (sc->flags & CBB_16BIT_CARD)
 1536                 return (cbb_pcic_release_resource(brdev, child, type,
 1537                     rid, r));
 1538         else
 1539                 return (cbb_cardbus_release_resource(brdev, child, type,
 1540                     rid, r));
 1541 }
 1542 
 1543 int
 1544 cbb_read_ivar(device_t brdev, device_t child, int which, uintptr_t *result)
 1545 {
 1546         struct cbb_softc *sc = device_get_softc(brdev);
 1547 
 1548         switch (which) {
 1549         case PCIB_IVAR_DOMAIN:
 1550                 *result = sc->domain;
 1551                 return (0);
 1552         case PCIB_IVAR_BUS:
 1553                 *result = sc->bus.sec;
 1554                 return (0);
 1555         case EXCA_IVAR_SLOT:
 1556                 *result = 0;
 1557                 return (0);
 1558         }
 1559         return (ENOENT);
 1560 }
 1561 
 1562 int
 1563 cbb_write_ivar(device_t brdev, device_t child, int which, uintptr_t value)
 1564 {
 1565 
 1566         switch (which) {
 1567         case PCIB_IVAR_DOMAIN:
 1568                 return (EINVAL);
 1569         case PCIB_IVAR_BUS:
 1570                 return (EINVAL);
 1571         case EXCA_IVAR_SLOT:
 1572                 return (EINVAL);
 1573         }
 1574         return (ENOENT);
 1575 }
 1576 
 1577 int
 1578 cbb_child_present(device_t parent, device_t child)
 1579 {
 1580         struct cbb_softc *sc = (struct cbb_softc *)device_get_softc(parent);
 1581         uint32_t sockstate;
 1582 
 1583         sockstate = cbb_get(sc, CBB_SOCKET_STATE);
 1584         return (CBB_CARD_PRESENT(sockstate) && sc->cardok);
 1585 }

Cache object: e53b0cb674bc6624b0298c696f1bcb99


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.