Home | History | Annotate | Line # | Download | only in cardbus
cardslot.c revision 1.12
      1  1.12  nathanw /*	$NetBSD: cardslot.c,v 1.12 2001/01/28 01:49:54 nathanw Exp $	*/
      2   1.5     haya 
      3   1.1     haya /*
      4   1.7     haya  * Copyright (c) 1999 and 2000
      5   1.1     haya  *       HAYAKAWA Koichi.  All rights reserved.
      6   1.1     haya  *
      7   1.1     haya  * Redistribution and use in source and binary forms, with or without
      8   1.1     haya  * modification, are permitted provided that the following conditions
      9   1.1     haya  * are met:
     10   1.1     haya  * 1. Redistributions of source code must retain the above copyright
     11   1.1     haya  *    notice, this list of conditions and the following disclaimer.
     12   1.1     haya  * 2. Redistributions in binary form must reproduce the above copyright
     13   1.1     haya  *    notice, this list of conditions and the following disclaimer in the
     14   1.1     haya  *    documentation and/or other materials provided with the distribution.
     15   1.1     haya  * 3. All advertising materials mentioning features or use of this software
     16   1.1     haya  *    must display the following acknowledgement:
     17   1.1     haya  *	This product includes software developed by HAYAKAWA Koichi.
     18   1.1     haya  * 4. The name of the author may not be used to endorse or promote products
     19   1.1     haya  *    derived from this software without specific prior written permission.
     20   1.1     haya  *
     21   1.1     haya  *
     22   1.1     haya  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     23   1.1     haya  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     24   1.1     haya  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     25   1.1     haya  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     26   1.1     haya  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     27   1.1     haya  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     28   1.1     haya  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29   1.1     haya  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     30   1.1     haya  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     31   1.1     haya  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     32   1.1     haya  * POSSIBILITY OF SUCH DAMAGE.
     33   1.1     haya  */
     34   1.1     haya 
     35   1.3     haya #include "opt_cardslot.h"
     36   1.1     haya 
     37   1.1     haya #include <sys/types.h>
     38   1.1     haya #include <sys/param.h>
     39   1.1     haya #include <sys/systm.h>
     40   1.1     haya #include <sys/device.h>
     41   1.1     haya #include <sys/malloc.h>
     42   1.1     haya #include <sys/kernel.h>
     43   1.1     haya #include <sys/syslog.h>
     44   1.1     haya #include <sys/kthread.h>
     45   1.1     haya 
     46   1.1     haya #include <machine/bus.h>
     47   1.1     haya 
     48   1.1     haya #include <dev/cardbus/cardslotvar.h>
     49   1.1     haya #include <dev/cardbus/cardbusvar.h>
     50   1.1     haya #include <dev/pcmcia/pcmciavar.h>
     51   1.1     haya #include <dev/pcmcia/pcmciachip.h>
     52   1.1     haya #include <dev/ic/i82365var.h>
     53   1.1     haya 
     54   1.1     haya 
     55   1.1     haya #if defined CARDSLOT_DEBUG
     56   1.1     haya #define STATIC
     57   1.1     haya #define DPRINTF(a) printf a
     58   1.1     haya #else
     59   1.1     haya #define STATIC static
     60   1.1     haya #define DPRINTF(a)
     61   1.1     haya #endif
     62   1.1     haya 
     63   1.1     haya 
     64   1.1     haya 
     65   1.1     haya STATIC void cardslotattach __P((struct device *, struct device *, void *));
     66   1.1     haya 
     67   1.1     haya STATIC int cardslotmatch __P((struct device *, struct cfdata *, void *));
     68   1.1     haya static void create_slot_manager __P((void *));
     69   1.1     haya static void cardslot_event_thread __P((void *arg));
     70   1.1     haya 
     71   1.1     haya STATIC int cardslot_cb_print __P((void *aux, const char *pcic));
     72   1.1     haya static int cardslot_16_print __P((void *, const char *));
     73   1.1     haya static int cardslot_16_submatch __P((struct device *, struct cfdata *,void *));
     74   1.1     haya 
     75   1.1     haya struct cfattach cardslot_ca = {
     76   1.1     haya 	sizeof(struct cardslot_softc), cardslotmatch, cardslotattach
     77   1.1     haya };
     78   1.1     haya 
     79   1.1     haya #ifndef __NetBSD_Version__
     80   1.1     haya struct cfdriver cardslot_cd = {
     81   1.1     haya 	NULL, "cardslot", DV_DULL
     82   1.1     haya };
     83   1.1     haya #endif
     84   1.1     haya 
     85   1.1     haya 
     86   1.1     haya STATIC int
     87   1.1     haya cardslotmatch(parent, cf, aux)
     88   1.1     haya      struct device *parent;
     89   1.1     haya      struct cfdata *cf;
     90   1.1     haya      void *aux;
     91   1.1     haya {
     92   1.1     haya   struct cardslot_attach_args *caa = aux;
     93   1.1     haya 
     94   1.1     haya   if (caa->caa_cb_attach == NULL && caa->caa_16_attach == NULL) {
     95   1.1     haya     /* Neither CardBus nor 16-bit PCMCIA are defined. */
     96   1.1     haya     return 0;
     97   1.1     haya   }
     98   1.1     haya 
     99   1.1     haya   return 1;
    100   1.1     haya }
    101   1.1     haya 
    102   1.1     haya 
    103   1.1     haya 
    104   1.1     haya STATIC void
    105   1.1     haya cardslotattach(parent, self, aux)
    106   1.1     haya      struct device *parent;
    107   1.1     haya      struct device *self;
    108   1.1     haya      void *aux;
    109   1.1     haya {
    110   1.1     haya   struct cardslot_softc *sc = (struct cardslot_softc *)self;
    111   1.1     haya   struct cardslot_attach_args *caa = aux;
    112   1.1     haya 
    113   1.1     haya   struct cbslot_attach_args *cba = caa->caa_cb_attach;
    114   1.1     haya   struct pcmciabus_attach_args *pa = caa->caa_16_attach;
    115   1.1     haya 
    116   1.1     haya   struct cardbus_softc *csc;
    117   1.1     haya   struct pcmcia_softc *psc;
    118   1.1     haya 
    119   1.1     haya   int card_attach_now;
    120   1.1     haya 
    121   1.1     haya   sc->sc_slot = sc->sc_dev.dv_unit;
    122   1.1     haya   sc->sc_cb_softc = NULL;
    123   1.1     haya   sc->sc_16_softc = NULL;
    124   1.1     haya   SIMPLEQ_INIT(&sc->sc_events);
    125   1.1     haya   sc->sc_th_enable = 0;
    126   1.1     haya 
    127   1.1     haya   printf(" slot %d flags %x\n", sc->sc_slot, sc->sc_dev.dv_cfdata->cf_flags);
    128   1.1     haya 
    129   1.1     haya   DPRINTF(("%s attaching CardBus bus...\n", sc->sc_dev.dv_xname));
    130   1.1     haya   if (cba != NULL) {
    131   1.1     haya     if (NULL != (csc = (void *)config_found(self, cba, cardslot_cb_print))) {
    132   1.1     haya       /* cardbus found */
    133   1.1     haya       DPRINTF(("cardslotattach: found cardbus on %s\n", sc->sc_dev.dv_xname));
    134   1.1     haya       sc->sc_cb_softc = csc;
    135   1.1     haya     }
    136   1.1     haya   }
    137   1.1     haya 
    138   1.1     haya   if (pa != NULL) {
    139   1.1     haya     if (NULL != (psc = (void *)config_found_sm(self, pa, cardslot_16_print,
    140   1.1     haya 				       cardslot_16_submatch))) {
    141   1.1     haya       /* pcmcia 16-bit bus found */
    142   1.1     haya       DPRINTF(("cardslotattach: found 16-bit pcmcia bus\n"));
    143   1.1     haya       sc->sc_16_softc = psc;
    144   1.1     haya       /* XXX: dirty.  This code should be removed to achieve MI */
    145   1.1     haya       caa->caa_ph->pcmcia = (struct device *)psc;
    146   1.1     haya     }
    147   1.1     haya   }
    148   1.1     haya 
    149   1.1     haya   if (csc != NULL || psc != NULL) {
    150   1.1     haya #if __NetBSD_Version__ > 104060000
    151   1.6  thorpej     config_pending_incr();
    152   1.1     haya     kthread_create(create_slot_manager, (void *)sc);
    153   1.1     haya #else
    154   1.1     haya     kthread_create_deferred(create_slot_manager, (void *)sc);
    155   1.1     haya #endif
    156   1.1     haya   }
    157   1.1     haya 
    158   1.1     haya   card_attach_now = sc->sc_dev.dv_cfdata->cf_flags & 0x01;
    159   1.1     haya 
    160   1.1     haya   if (csc && (csc->sc_cf->cardbus_ctrl)(csc->sc_cc, CARDBUS_CD)) {
    161   1.1     haya     DPRINTF(("cardslotattach: CardBus card found\n"));
    162   1.1     haya     if (card_attach_now) {
    163   1.5     haya       if (cardbus_attach_card(sc->sc_cb_softc) > 0) {
    164   1.5     haya 	/* at least one function works */
    165   1.5     haya 	CARDSLOT_SET_WORK(sc->sc_status, CARDSLOT_STATUS_WORKING);
    166   1.5     haya       } else {
    167   1.5     haya 	/* no functions work or this card is not known */
    168   1.5     haya 	CARDSLOT_SET_WORK(sc->sc_status, CARDSLOT_STATUS_NOTWORK);
    169   1.5     haya       }
    170   1.1     haya       CARDSLOT_SET_CARDTYPE(sc->sc_status, CARDSLOT_STATUS_CARD_CB);
    171   1.1     haya     } else {
    172  1.12  nathanw       /* attach deferred */
    173   1.1     haya       cardslot_event_throw(sc, CARDSLOT_EVENT_INSERTION_CB);
    174   1.1     haya     }
    175   1.1     haya   }
    176   1.1     haya 
    177   1.1     haya   if (psc && (psc->pct->card_detect)(psc->pch)) {
    178   1.1     haya     DPRINTF(("cardbusattach: 16-bit card found\n"));
    179   1.1     haya     if (card_attach_now) {
    180   1.1     haya       /* attach now */
    181   1.1     haya       pcmcia_card_attach((struct device *)sc->sc_16_softc);
    182   1.1     haya       CARDSLOT_SET_CARDTYPE(sc->sc_status, CARDSLOT_STATUS_CARD_16);
    183   1.1     haya     } else {
    184  1.12  nathanw       /* attach deferred */
    185   1.1     haya       cardslot_event_throw(sc, CARDSLOT_EVENT_INSERTION_16);
    186   1.1     haya     }
    187   1.1     haya   }
    188   1.1     haya }
    189   1.1     haya 
    190   1.1     haya 
    191   1.1     haya 
    192   1.1     haya STATIC int
    193   1.4     haya cardslot_cb_print(aux, pnp)
    194   1.9     haya 	void *aux;
    195   1.9     haya 	const char *pnp;
    196   1.1     haya {
    197   1.9     haya 	struct cbslot_attach_args *cba = aux;
    198   1.4     haya 
    199   1.9     haya 	if (pnp) {
    200   1.9     haya 		printf("cardbus at %s subordinate bus %d", pnp, cba->cba_bus);
    201   1.9     haya 	}
    202   1.4     haya 
    203   1.9     haya 	return UNCONF;
    204   1.1     haya }
    205   1.1     haya 
    206   1.1     haya 
    207   1.1     haya static int
    208   1.1     haya cardslot_16_submatch(parent, cf, aux)
    209   1.1     haya      struct device *parent;
    210   1.1     haya      struct cfdata *cf;
    211   1.1     haya      void *aux;
    212   1.1     haya {
    213   1.1     haya   if (cf->cf_loc[PCMCIABUSCF_CONTROLLER] != PCMCIABUSCF_CONTROLLER_DEFAULT
    214   1.1     haya       && cf->cf_loc[PCMCIABUSCF_CONTROLLER] != 0) {
    215   1.1     haya     return 0;
    216   1.1     haya   }
    217   1.1     haya 
    218   1.1     haya   if ((cf->cf_loc[PCMCIABUSCF_CONTROLLER] == PCMCIABUSCF_CONTROLLER_DEFAULT)) {
    219   1.1     haya     return ((*cf->cf_attach->ca_match)(parent, cf, aux));
    220   1.1     haya   }
    221   1.1     haya 
    222   1.1     haya   return 0;
    223   1.1     haya }
    224   1.1     haya 
    225   1.1     haya 
    226   1.1     haya 
    227   1.1     haya static int
    228   1.1     haya cardslot_16_print(arg, pnp)
    229   1.1     haya      void *arg;
    230   1.1     haya      const char *pnp;
    231   1.1     haya {
    232   1.4     haya 
    233   1.1     haya   if (pnp) {
    234   1.4     haya     printf("pcmciabus at %s", pnp);
    235   1.1     haya   }
    236   1.1     haya 
    237   1.1     haya   return UNCONF;
    238   1.1     haya }
    239   1.1     haya 
    240   1.1     haya 
    241   1.1     haya 
    242   1.1     haya 
    243   1.1     haya static void
    244   1.1     haya create_slot_manager(arg)
    245   1.1     haya      void *arg;
    246   1.1     haya {
    247   1.1     haya   struct cardslot_softc *sc = (struct cardslot_softc *)arg;
    248   1.1     haya 
    249   1.1     haya   sc->sc_th_enable = 1;
    250   1.1     haya 
    251   1.1     haya #if __NetBSD_Version__ > 104060000
    252   1.1     haya  if (kthread_create1(cardslot_event_thread, sc, &sc->sc_event_thread, "%s",
    253   1.1     haya 		     sc->sc_dev.dv_xname)) {
    254   1.1     haya #else
    255   1.1     haya  if (kthread_create(cardslot_event_thread, sc, &sc->sc_event_thread, "%s",
    256   1.1     haya 		     sc->sc_dev.dv_xname)) {
    257   1.1     haya #endif
    258   1.1     haya     printf("%s: unable to create event thread for slot %d\n",
    259   1.1     haya 	   sc->sc_dev.dv_xname, sc->sc_slot);
    260   1.1     haya     panic("create_slot_manager");
    261   1.1     haya   }
    262   1.1     haya }
    263   1.1     haya 
    264   1.1     haya 
    265   1.1     haya 
    266   1.1     haya 
    267   1.1     haya /*
    268   1.1     haya  * void cardslot_event_throw(struct cardslot_softc *sc, int ev)
    269   1.1     haya  *
    270   1.1     haya  *   This function throws an event to the event handler.  If the state
    271   1.1     haya  *   of a slot is changed, it should be noticed using this function.
    272   1.1     haya  */
    273   1.1     haya void
    274   1.1     haya cardslot_event_throw(sc, ev)
    275   1.1     haya      struct cardslot_softc *sc;
    276   1.1     haya      int ev;
    277   1.1     haya {
    278   1.1     haya   struct cardslot_event *ce;
    279   1.1     haya 
    280   1.1     haya   DPRINTF(("cardslot_event_throw: an event %s comes\n",
    281   1.1     haya 	   ev == CARDSLOT_EVENT_INSERTION_CB ? "CardBus Card inserted" :
    282   1.1     haya 	   ev == CARDSLOT_EVENT_INSERTION_16 ? "16-bit Card inserted" :
    283   1.1     haya 	   ev == CARDSLOT_EVENT_REMOVAL_CB ? "CardBus Card removed" :
    284   1.1     haya 	   ev == CARDSLOT_EVENT_REMOVAL_16 ? "16-bit Card removed" : "???"));
    285   1.1     haya 
    286   1.1     haya   if (NULL == (ce = (struct cardslot_event *)malloc(sizeof (struct cardslot_event), M_TEMP, M_NOWAIT))) {
    287   1.1     haya     panic("cardslot_enevt");
    288   1.1     haya   }
    289   1.1     haya 
    290   1.1     haya   ce->ce_type = ev;
    291   1.1     haya 
    292   1.1     haya   {
    293   1.1     haya     int s = spltty();
    294   1.1     haya     SIMPLEQ_INSERT_TAIL(&sc->sc_events, ce, ce_q);
    295   1.1     haya     splx(s);
    296   1.1     haya   }
    297   1.1     haya 
    298   1.1     haya   wakeup(&sc->sc_events);
    299   1.1     haya 
    300   1.1     haya   return;
    301   1.1     haya }
    302   1.1     haya 
    303   1.1     haya 
    304   1.1     haya /*
    305   1.1     haya  * static void cardslot_event_thread(void *arg)
    306   1.1     haya  *
    307   1.1     haya  *   This function is the main routine handing cardslot events such as
    308   1.1     haya  *   insertions and removals.
    309   1.1     haya  *
    310   1.1     haya  */
    311   1.1     haya static void
    312   1.1     haya cardslot_event_thread(arg)
    313   1.1     haya      void *arg;
    314   1.1     haya {
    315   1.1     haya   struct cardslot_softc *sc = arg;
    316   1.1     haya   struct cardslot_event *ce;
    317   1.6  thorpej   int s, first = 1;
    318   1.1     haya   static int antonym_ev[4] = {
    319   1.1     haya     CARDSLOT_EVENT_REMOVAL_16, CARDSLOT_EVENT_INSERTION_16,
    320   1.1     haya     CARDSLOT_EVENT_REMOVAL_CB, CARDSLOT_EVENT_INSERTION_CB
    321   1.1     haya   };
    322   1.1     haya 
    323   1.1     haya   while (sc->sc_th_enable) {
    324   1.1     haya     s = spltty();
    325   1.1     haya     if ((ce = SIMPLEQ_FIRST(&sc->sc_events)) == NULL) {
    326   1.1     haya       splx(s);
    327   1.6  thorpej       if (first) {
    328   1.6  thorpej         first = 0;
    329   1.6  thorpej         config_pending_decr();
    330   1.6  thorpej       }
    331   1.1     haya       (void) tsleep(&sc->sc_events, PWAIT, "cardslotev", 0);
    332   1.1     haya       continue;
    333   1.1     haya     }
    334   1.1     haya     SIMPLEQ_REMOVE_HEAD(&sc->sc_events, ce, ce_q);
    335   1.1     haya     splx(s);
    336   1.1     haya 
    337   1.1     haya     if (IS_CARDSLOT_INSERT_REMOVE_EV(ce->ce_type)) {
    338   1.1     haya       /* Chattering supression */
    339   1.1     haya       s = spltty();
    340   1.1     haya       while (1) {
    341   1.1     haya 	struct cardslot_event *ce1, *ce2;
    342   1.1     haya 
    343   1.1     haya 	if ((ce1 = SIMPLEQ_FIRST(&sc->sc_events)) == NULL) {
    344   1.1     haya 	  break;
    345   1.1     haya 	}
    346   1.1     haya 	if (ce1->ce_type != antonym_ev[ce->ce_type]) {
    347   1.1     haya 	  break;
    348   1.1     haya 	}
    349   1.1     haya 	if ((ce2 = SIMPLEQ_NEXT(ce1, ce_q)) == NULL) {
    350   1.1     haya 	  break;
    351   1.1     haya 	}
    352   1.1     haya 	if (ce2->ce_type == ce->ce_type) {
    353   1.1     haya 	  SIMPLEQ_REMOVE_HEAD(&sc->sc_events, ce1, ce_q);
    354   1.1     haya 	  free(ce1, M_TEMP);
    355   1.1     haya 	  SIMPLEQ_REMOVE_HEAD(&sc->sc_events, ce2, ce_q);
    356   1.1     haya 	  free(ce2, M_TEMP);
    357   1.1     haya 	}
    358   1.1     haya       }
    359   1.1     haya       splx(s);
    360   1.1     haya     }
    361   1.1     haya 
    362   1.1     haya     switch (ce->ce_type) {
    363   1.1     haya     case CARDSLOT_EVENT_INSERTION_CB:
    364   1.5     haya       if ((CARDSLOT_CARDTYPE(sc->sc_status) == CARDSLOT_STATUS_CARD_CB)
    365   1.5     haya 	  || (CARDSLOT_CARDTYPE(sc->sc_status) == CARDSLOT_STATUS_CARD_16)) {
    366   1.5     haya 	if (CARDSLOT_WORK(sc->sc_status) == CARDSLOT_STATUS_WORKING) {
    367  1.12  nathanw 	  /* A card has already been inserted and works. */
    368   1.5     haya 	  break;
    369   1.5     haya 	}
    370   1.1     haya       }
    371   1.5     haya 
    372   1.1     haya       if (sc->sc_cb_softc) {
    373   1.1     haya 	CARDSLOT_SET_CARDTYPE(sc->sc_status, CARDSLOT_STATUS_CARD_CB);
    374   1.5     haya 	if (cardbus_attach_card(sc->sc_cb_softc) > 0) {
    375   1.5     haya 	  /* at least one function works */
    376   1.5     haya 	  CARDSLOT_SET_WORK(sc->sc_status, CARDSLOT_STATUS_WORKING);
    377   1.5     haya 	} else {
    378   1.5     haya 	  /* no functions work or this card is not known */
    379   1.5     haya 	  CARDSLOT_SET_WORK(sc->sc_status, CARDSLOT_STATUS_NOTWORK);
    380   1.5     haya 	}
    381   1.1     haya       } else {
    382   1.1     haya 	panic("no cardbus on %s", sc->sc_dev.dv_xname);
    383   1.1     haya       }
    384   1.1     haya 
    385   1.1     haya       break;
    386   1.1     haya 
    387   1.1     haya     case CARDSLOT_EVENT_INSERTION_16:
    388   1.5     haya       if ((CARDSLOT_CARDTYPE(sc->sc_status) == CARDSLOT_STATUS_CARD_CB)
    389   1.5     haya 	  || (CARDSLOT_CARDTYPE(sc->sc_status) == CARDSLOT_STATUS_CARD_16)) {
    390   1.5     haya 	if (CARDSLOT_WORK(sc->sc_status) == CARDSLOT_STATUS_WORKING) {
    391   1.5     haya 	  /* A card has already been inserted and work. */
    392   1.5     haya 	  break;
    393   1.5     haya 	}
    394   1.1     haya       }
    395   1.1     haya       if (sc->sc_16_softc) {
    396   1.1     haya 	CARDSLOT_SET_CARDTYPE(sc->sc_status, CARDSLOT_STATUS_CARD_16);
    397   1.5     haya 	if (pcmcia_card_attach((struct device *)sc->sc_16_softc)) {
    398   1.5     haya 	  /* Do not attach */
    399   1.5     haya 	  CARDSLOT_SET_WORK(sc->sc_status, CARDSLOT_STATUS_NOTWORK);
    400   1.5     haya 	} else {
    401   1.5     haya 	  /* working */
    402   1.5     haya 	  CARDSLOT_SET_WORK(sc->sc_status, CARDSLOT_STATUS_WORKING);
    403   1.5     haya 	}
    404   1.1     haya       } else {
    405   1.1     haya 	panic("no 16-bit pcmcia on %s", sc->sc_dev.dv_xname);
    406   1.1     haya       }
    407   1.1     haya 
    408   1.1     haya       break;
    409   1.1     haya 
    410   1.1     haya     case CARDSLOT_EVENT_REMOVAL_CB:
    411   1.5     haya       if (CARDSLOT_CARDTYPE(sc->sc_status) == CARDSLOT_STATUS_CARD_CB) {
    412   1.1     haya 	/* CardBus card has not been inserted. */
    413   1.5     haya 	if (CARDSLOT_WORK(sc->sc_status) == CARDSLOT_STATUS_WORKING) {
    414   1.5     haya 	  cardbus_detach_card(sc->sc_cb_softc);
    415   1.7     haya 	  CARDSLOT_SET_WORK(sc->sc_status, CARDSLOT_STATUS_NOTWORK);
    416   1.8     haya 	  CARDSLOT_SET_WORK(sc->sc_status, CARDSLOT_STATUS_CARD_NONE);
    417   1.5     haya 	}
    418   1.5     haya 	CARDSLOT_SET_CARDTYPE(sc->sc_status, CARDSLOT_STATUS_CARD_NONE);
    419   1.5     haya       } else if (CARDSLOT_CARDTYPE(sc->sc_status) != CARDSLOT_STATUS_CARD_16) {
    420   1.5     haya 	/* Unknown card... */
    421   1.5     haya 	CARDSLOT_SET_CARDTYPE(sc->sc_status, CARDSLOT_STATUS_CARD_NONE);
    422   1.1     haya       }
    423   1.5     haya       CARDSLOT_SET_WORK(sc->sc_status, CARDSLOT_STATUS_NOTWORK);
    424   1.1     haya       break;
    425   1.1     haya 
    426   1.1     haya     case CARDSLOT_EVENT_REMOVAL_16:
    427   1.1     haya       DPRINTF(("%s: removal event\n", sc->sc_dev.dv_xname));
    428   1.1     haya       if (CARDSLOT_CARDTYPE(sc->sc_status) != CARDSLOT_STATUS_CARD_16) {
    429   1.1     haya 	/* 16-bit card has not been inserted. */
    430   1.1     haya 	break;
    431   1.1     haya       }
    432   1.5     haya       if ((sc->sc_16_softc != NULL)
    433   1.5     haya 	  && (CARDSLOT_WORK(sc->sc_status) == CARDSLOT_STATUS_WORKING)) {
    434   1.1     haya 	struct pcmcia_softc *psc = sc->sc_16_softc;
    435   1.1     haya 
    436   1.1     haya 	pcmcia_card_deactivate((struct device *)psc);
    437   1.1     haya 	pcmcia_chip_socket_disable(psc->pct, psc->pch);
    438   1.1     haya 	pcmcia_card_detach((struct device *)psc, DETACH_FORCE);
    439   1.1     haya       }
    440   1.5     haya       CARDSLOT_SET_CARDTYPE(sc->sc_status, CARDSLOT_STATUS_CARD_NONE);
    441   1.5     haya       CARDSLOT_SET_WORK(sc->sc_status, CARDSLOT_STATUS_NOTWORK);
    442   1.1     haya       break;
    443   1.1     haya 
    444   1.1     haya     default:
    445   1.1     haya       panic("cardslot_event_thread: unknown event %d", ce->ce_type);
    446   1.1     haya     }
    447   1.1     haya     free(ce, M_TEMP);
    448   1.1     haya   }
    449   1.1     haya 
    450   1.1     haya   sc->sc_event_thread = NULL;
    451   1.1     haya 
    452  1.12  nathanw   /* In case the parent device is waiting for us to exit. */
    453   1.1     haya   wakeup(sc);
    454   1.1     haya 
    455   1.1     haya   kthread_exit(0);
    456   1.1     haya }
    457