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

          Line data    Source code
       1             : /*      $OpenBSD: cardslot.c,v 1.21 2016/09/15 02:00:17 dlg Exp $       */
       2             : /*      $NetBSD: cardslot.c,v 1.9 2000/03/22 09:35:06 haya Exp $        */
       3             : 
       4             : /*
       5             :  * Copyright (c) 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             :  *
      18             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      19             :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
      20             :  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
      21             :  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
      22             :  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      23             :  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      24             :  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      25             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      26             :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
      27             :  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      28             :  * POSSIBILITY OF SUCH DAMAGE.
      29             :  */
      30             : 
      31             : #include <sys/param.h>
      32             : #include <sys/systm.h>
      33             : #include <sys/device.h>
      34             : #include <sys/malloc.h>
      35             : #include <sys/kernel.h>
      36             : #include <sys/syslog.h>
      37             : #include <sys/kthread.h>
      38             : #include <sys/pool.h>
      39             : #include <sys/task.h>
      40             : 
      41             : #include <dev/cardbus/cardslotvar.h>
      42             : #include <dev/cardbus/cardbusvar.h>
      43             : #include <dev/pcmcia/pcmciavar.h>
      44             : #include <dev/pcmcia/pcmciachip.h>
      45             : #include <dev/ic/i82365var.h>
      46             : 
      47             : #if defined CARDSLOT_DEBUG
      48             : #define STATIC
      49             : #define DPRINTF(a) printf a
      50             : #else
      51             : #ifdef DDB
      52             : #define STATIC
      53             : #else
      54             : #define STATIC static
      55             : #endif
      56             : #define DPRINTF(a)
      57             : #endif
      58             : 
      59             : STATIC void cardslotattach(struct device *, struct device *, void *);
      60             : 
      61             : STATIC int cardslotmatch(struct device *, void *, void *);
      62             : STATIC void cardslot_event(void *arg);
      63             : STATIC void cardslot_process_event(struct cardslot_softc *);
      64             : 
      65             : STATIC int cardslot_cb_print(void *aux, const char *pcic);
      66             : STATIC int cardslot_16_print(void *, const char *);
      67             : STATIC int cardslot_16_submatch(struct device *, void *,void *);
      68             : 
      69             : struct cfattach cardslot_ca = {
      70             :         sizeof(struct cardslot_softc), cardslotmatch, cardslotattach
      71             : };
      72             : 
      73             : struct cfdriver cardslot_cd = {
      74             :         NULL, "cardslot", DV_DULL
      75             : };
      76             : 
      77             : struct pool cardsloteventpool;
      78             : 
      79             : STATIC int
      80           0 : cardslotmatch(struct device *parent, void *match, void *aux)
      81             : {
      82           0 :         struct cardslot_attach_args *caa = aux;
      83             : 
      84           0 :         if (caa->caa_cb_attach == NULL && caa->caa_16_attach == NULL) {
      85             :                 /* Neither CardBus nor 16-bit PCMCIA are defined. */
      86           0 :                 return (0);
      87             :         }
      88             : 
      89           0 :         return (1);
      90           0 : }
      91             : 
      92             : STATIC void
      93           0 : cardslotattach(struct device *parent, struct device *self, void *aux)
      94             : {
      95           0 :         struct cardslot_softc *sc = (struct cardslot_softc *)self;
      96           0 :         struct cardslot_attach_args *caa = aux;
      97             : 
      98           0 :         struct cbslot_attach_args *cba = caa->caa_cb_attach;
      99           0 :         struct pcmciabus_attach_args *pa = caa->caa_16_attach;
     100             : 
     101             :         struct cardbus_softc *csc = NULL;
     102             :         struct pcmcia_softc *psc = NULL;
     103             : 
     104           0 :         if (cardsloteventpool.pr_size == 0) {
     105           0 :                 pool_init(&cardsloteventpool, sizeof(struct cardslot_event),
     106             :                     0, IPL_BIO, 0, "cardslot", NULL);
     107           0 :         }
     108             : 
     109           0 :         sc->sc_slot = sc->sc_dev.dv_unit;
     110           0 :         sc->sc_cb_softc = NULL;
     111           0 :         sc->sc_16_softc = NULL;
     112           0 :         SIMPLEQ_INIT(&sc->sc_events);
     113           0 :         task_set(&sc->sc_event_task, cardslot_event, sc);
     114             : 
     115           0 :         printf(" slot %d flags %x\n", sc->sc_slot,
     116           0 :             sc->sc_dev.dv_cfdata->cf_flags);
     117             : 
     118             :         DPRINTF(("%s attaching CardBus bus...\n", sc->sc_dev.dv_xname));
     119           0 :         if (cba != NULL) {
     120           0 :                 if ((csc = (void *)config_found(self, cba,
     121           0 :                     cardslot_cb_print)) != NULL) {
     122             :                         /* cardbus found */
     123             :                         DPRINTF(("cardslotattach: found cardbus on %s\n",
     124             :                             sc->sc_dev.dv_xname));
     125           0 :                         sc->sc_cb_softc = csc;
     126           0 :                 }
     127             :         }
     128             : 
     129           0 :         if (pa != NULL) {
     130           0 :                 if ((psc = (void *)config_found_sm(self, pa, cardslot_16_print,
     131           0 :                     cardslot_16_submatch)) != NULL) {
     132             :                         /* pcmcia 16-bit bus found */
     133             :                         DPRINTF(("cardslotattach: found 16-bit pcmcia bus\n"));
     134           0 :                         sc->sc_16_softc = psc;
     135             :                         /* XXX: dirty.  This code should be removed
     136             :                          * to achieve MI
     137             :                          */
     138           0 :                         caa->caa_ph->pcmcia = (struct device *)psc;
     139           0 :                 }
     140             :         }
     141             : 
     142           0 :         if (csc && (csc->sc_cf->cardbus_ctrl)(csc->sc_cc, CARDBUS_CD)) {
     143             :                 DPRINTF(("cardslotattach: CardBus card found\n"));
     144             :                 /* attach deferred */
     145           0 :                 cardslot_event_throw(sc, CARDSLOT_EVENT_INSERTION_CB);
     146           0 :         }
     147             : 
     148           0 :         if (psc && (psc->pct->card_detect)(psc->pch)) {
     149             :                 DPRINTF(("cardbusattach: 16-bit card found\n"));
     150             :                 /* attach deferred */
     151           0 :                 cardslot_event_throw(sc, CARDSLOT_EVENT_INSERTION_16);
     152           0 :         }
     153           0 : }
     154             : 
     155             : STATIC int
     156           0 : cardslot_cb_print(void *aux, const char *pnp)
     157             : {
     158           0 :         struct cbslot_attach_args *cba = aux;
     159             : 
     160           0 :         if (pnp)
     161           0 :                 printf("cardbus at %s subordinate bus %d", pnp, cba->cba_bus);
     162             : 
     163           0 :         return (UNCONF);
     164             : }
     165             : 
     166             : STATIC int
     167           0 : cardslot_16_submatch(struct device *parent, void *match, void *aux)
     168             : {
     169           0 :         struct cfdata *cf = match;
     170             : 
     171           0 :         if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 0)
     172           0 :                 return (0);
     173             : 
     174           0 :         if (cf->cf_loc[0] == -1)
     175           0 :                 return ((*cf->cf_attach->ca_match)(parent, cf, aux));
     176             : 
     177           0 :         return (0);
     178           0 : }
     179             : 
     180             : STATIC int
     181           0 : cardslot_16_print(void *arg, const char *pnp)
     182             : {
     183           0 :         if (pnp)
     184           0 :                 printf("pcmciabus at %s", pnp);
     185             : 
     186           0 :         return (UNCONF);
     187             : }
     188             : 
     189             : /*
     190             :  * void cardslot_event_throw(struct cardslot_softc *sc, int ev)
     191             :  *
     192             :  *   This function throws an event to the event handler.  If the state
     193             :  *   of a slot is changed, it should be noticed using this function.
     194             :  */
     195             : void
     196           0 : cardslot_event_throw(struct cardslot_softc *sc, int ev)
     197             : {
     198             :         struct cardslot_event *ce;
     199             :         int s;
     200             : 
     201             :         DPRINTF(("cardslot_event_throw: an event %s comes\n",
     202             :             ev == CARDSLOT_EVENT_INSERTION_CB ? "CardBus Card inserted" :
     203             :             ev == CARDSLOT_EVENT_INSERTION_16 ? "16-bit Card inserted" :
     204             :             ev == CARDSLOT_EVENT_REMOVAL_CB ? "CardBus Card removed" :
     205             :             ev == CARDSLOT_EVENT_REMOVAL_16 ? "16-bit Card removed" : "???"));
     206             : 
     207           0 :         ce = pool_get(&cardsloteventpool, PR_NOWAIT);
     208           0 :         if (ce == NULL)
     209           0 :                 return;
     210           0 :         ce->ce_type = ev;
     211             : 
     212           0 :         s = spltty();
     213           0 :         SIMPLEQ_INSERT_TAIL(&sc->sc_events, ce, ce_q);
     214           0 :         splx(s);
     215             : 
     216           0 :         task_add(systq, &sc->sc_event_task);
     217           0 : }
     218             : 
     219             : /*
     220             :  * STATIC void cardslot_event(void *arg)
     221             :  *
     222             :  *   This function is the main routine handing cardslot events such as
     223             :  *   insertions and removals.
     224             :  *
     225             :  */
     226             : STATIC void
     227           0 : cardslot_event(void *arg1)
     228             : {
     229           0 :         struct cardslot_softc *sc = arg1;
     230             : 
     231           0 :         while (!SIMPLEQ_EMPTY(&sc->sc_events))
     232           0 :                 cardslot_process_event(sc);
     233           0 : }
     234             : 
     235             : 
     236             : STATIC void
     237           0 : cardslot_process_event(struct cardslot_softc *sc)
     238             : {
     239             :         struct cardslot_event *ce;
     240             :         int s, ev;
     241             : 
     242           0 :         s = spltty();
     243           0 :         if ((ce = SIMPLEQ_FIRST(&sc->sc_events)) == NULL) {
     244           0 :                 splx(s);
     245           0 :                 return;
     246             :         }
     247           0 :         SIMPLEQ_REMOVE_HEAD(&sc->sc_events, ce_q);
     248             : 
     249           0 :         if (IS_CARDSLOT_INSERT_REMOVE_EV(ce->ce_type)) {
     250             :                 /* Chattering suppression */
     251             :                 static int antonym_ev[4] = {
     252             :                         CARDSLOT_EVENT_REMOVAL_16,
     253             :                         CARDSLOT_EVENT_INSERTION_16,
     254             :                         CARDSLOT_EVENT_REMOVAL_CB,
     255             :                         CARDSLOT_EVENT_INSERTION_CB
     256             :                 };
     257             : 
     258           0 :                 while (1) {
     259             :                         struct cardslot_event *ce1, *ce2;
     260             : 
     261           0 :                         if ((ce1 = SIMPLEQ_FIRST(&sc->sc_events)) ==
     262             :                             NULL)
     263           0 :                                 break;
     264           0 :                         if (ce1->ce_type != antonym_ev[ce->ce_type])
     265           0 :                                 break;
     266           0 :                         if ((ce2 = SIMPLEQ_NEXT(ce1, ce_q)) == NULL)
     267           0 :                                 break;
     268           0 :                         if (ce2->ce_type == ce->ce_type) {
     269           0 :                                 SIMPLEQ_REMOVE_HEAD(&sc->sc_events, ce_q);
     270           0 :                                 pool_put(&cardsloteventpool, ce1);
     271           0 :                                 SIMPLEQ_REMOVE_HEAD(&sc->sc_events, ce_q);
     272           0 :                                 pool_put(&cardsloteventpool, ce2);
     273           0 :                         }
     274           0 :                 }
     275             :         }
     276           0 :         splx(s);
     277             : 
     278           0 :         ev = ce->ce_type;
     279           0 :         pool_put(&cardsloteventpool, ce);
     280             : 
     281           0 :         switch (ev) {
     282             :         case CARDSLOT_EVENT_INSERTION_CB:
     283           0 :                 if ((CARDSLOT_CARDTYPE(sc->sc_status) ==
     284           0 :                      CARDSLOT_STATUS_CARD_CB) ||
     285           0 :                     (CARDSLOT_CARDTYPE(sc->sc_status) ==
     286             :                      CARDSLOT_STATUS_CARD_16)) {
     287           0 :                         if (CARDSLOT_WORK(sc->sc_status) ==
     288             :                             CARDSLOT_STATUS_WORKING) {
     289             :                                 /* A card has already been inserted
     290             :                                  * and works.
     291             :                                  */
     292             :                                 break;
     293             :                         }
     294             :                 }
     295             : 
     296           0 :                 if (sc->sc_cb_softc) {
     297           0 :                         CARDSLOT_SET_CARDTYPE(sc->sc_status,
     298             :                             CARDSLOT_STATUS_CARD_CB);
     299           0 :                         if (cardbus_attach_card(sc->sc_cb_softc) > 0) {
     300             :                                 /* At least one function works */
     301           0 :                                 CARDSLOT_SET_WORK(sc->sc_status,
     302             :                                     CARDSLOT_STATUS_WORKING);
     303           0 :                         } else {
     304             :                                 /* No functions work or this card is
     305             :                                  * not known
     306             :                                  */
     307           0 :                                 CARDSLOT_SET_WORK(sc->sc_status,
     308             :                                     CARDSLOT_STATUS_NOTWORK);
     309             :                         }
     310             :                 } else {
     311           0 :                         printf("%s: CardBus support disabled\n",
     312           0 :                             sc->sc_dev.dv_xname);
     313             :                 }
     314             :                 break;
     315             : 
     316             :         case CARDSLOT_EVENT_INSERTION_16:
     317           0 :                 if ((CARDSLOT_CARDTYPE(sc->sc_status) ==
     318           0 :                      CARDSLOT_STATUS_CARD_CB) ||
     319           0 :                     (CARDSLOT_CARDTYPE(sc->sc_status) ==
     320             :                      CARDSLOT_STATUS_CARD_16)) {
     321           0 :                         if (CARDSLOT_WORK(sc->sc_status) ==
     322             :                             CARDSLOT_STATUS_WORKING) {
     323             :                                 /* A card has already been inserted
     324             :                                  * and works.
     325             :                                  */
     326             :                                 break;
     327             :                         }
     328             :                 }
     329           0 :                 if (sc->sc_16_softc) {
     330           0 :                         CARDSLOT_SET_CARDTYPE(sc->sc_status,
     331             :                             CARDSLOT_STATUS_CARD_16);
     332           0 :                         if (pcmcia_card_attach(
     333           0 :                             (struct device *)sc->sc_16_softc)) {
     334             :                                 /* Do not attach */
     335           0 :                                 CARDSLOT_SET_WORK(sc->sc_status,
     336             :                                     CARDSLOT_STATUS_NOTWORK);
     337           0 :                         } else {
     338             :                                 /* working */
     339           0 :                                 CARDSLOT_SET_WORK(sc->sc_status,
     340             :                                     CARDSLOT_STATUS_WORKING);
     341             :                         }
     342             :                 } else {
     343           0 :                         panic("no 16-bit pcmcia on %s",
     344           0 :                             sc->sc_dev.dv_xname);
     345             :                 }
     346             :                 break;
     347             : 
     348             :         case CARDSLOT_EVENT_REMOVAL_CB:
     349           0 :                 if (CARDSLOT_CARDTYPE(sc->sc_status) ==
     350             :                     CARDSLOT_STATUS_CARD_CB) {
     351             :                         /* CardBus card has not been inserted. */
     352           0 :                         if (CARDSLOT_WORK(sc->sc_status) ==
     353             :                             CARDSLOT_STATUS_WORKING) {
     354           0 :                                 cardbus_detach_card(sc->sc_cb_softc);
     355           0 :                                 CARDSLOT_SET_WORK(sc->sc_status,
     356             :                                     CARDSLOT_STATUS_NOTWORK);
     357           0 :                                 CARDSLOT_SET_WORK(sc->sc_status,
     358             :                                     CARDSLOT_STATUS_CARD_NONE);
     359           0 :                         }
     360           0 :                         CARDSLOT_SET_CARDTYPE(sc->sc_status,
     361             :                             CARDSLOT_STATUS_CARD_NONE);
     362           0 :                 } else if (CARDSLOT_CARDTYPE(sc->sc_status) !=
     363             :                     CARDSLOT_STATUS_CARD_16) {
     364             :                         /* Unknown card... */
     365           0 :                         CARDSLOT_SET_CARDTYPE(sc->sc_status,
     366             :                             CARDSLOT_STATUS_CARD_NONE);
     367           0 :                 }
     368           0 :                 CARDSLOT_SET_WORK(sc->sc_status,
     369             :                     CARDSLOT_STATUS_NOTWORK);
     370           0 :                 break;
     371             : 
     372             :         case CARDSLOT_EVENT_REMOVAL_16:
     373             :                 DPRINTF(("%s: removal event\n", sc->sc_dev.dv_xname));
     374           0 :                 if (CARDSLOT_CARDTYPE(sc->sc_status) !=
     375             :                     CARDSLOT_STATUS_CARD_16) {
     376             :                         /* 16-bit card has not been inserted. */
     377             :                         break;
     378             :                 }
     379           0 :                 if ((sc->sc_16_softc != NULL) &&
     380           0 :                     (CARDSLOT_WORK(sc->sc_status) ==
     381             :                      CARDSLOT_STATUS_WORKING)) {
     382             :                         struct pcmcia_softc *psc = sc->sc_16_softc;
     383             : 
     384           0 :                         pcmcia_card_deactivate((struct device *)psc);
     385           0 :                         pcmcia_chip_socket_disable(psc->pct, psc->pch);
     386           0 :                         pcmcia_card_detach((struct device *)psc,
     387             :                             DETACH_FORCE);
     388           0 :                 }
     389           0 :                 CARDSLOT_SET_CARDTYPE(sc->sc_status,
     390             :                     CARDSLOT_STATUS_CARD_NONE);
     391           0 :                 CARDSLOT_SET_WORK(sc->sc_status,
     392             :                     CARDSLOT_STATUS_NOTWORK);
     393           0 :                 break;
     394             : 
     395             :         default:
     396           0 :                 panic("cardslot_event_thread: unknown event %d", ev);
     397             :         }
     398           0 : }

Generated by: LCOV version 1.13