static void eppcic_event_thread(void *arg) { struct eppcic_handle *ph = arg; if (!(ph->ph_status[0] | ph->ph_status[1])) pcmcia_card_attach(ph->ph_card); for (;;) { tsleep(ph, PWAIT, "CSC wait", 0); if (!ph->ph_run) break; DPRINTFN(1, ("eppcic_event_thread: cd1=%d, cd2=%d\n",ph->ph_status[0],ph->ph_status[1])); if (!ph->ph_status[0] && !ph->ph_status[1]) pcmcia_card_attach(ph->ph_card); else if (ph->ph_status[0] && ph->ph_status[1]) pcmcia_card_detach(ph->ph_card, DETACH_FORCE); } DPRINTFN(1, ("eppcic_event_thread: run=%d\n",ph->ph_run)); ph->ph_event_thread = NULL; kthread_exit(0); }
void pcic_detach_card(struct pcic_handle *h, int flags) /* flags: DETACH_* */ { if (h->flags & PCIC_FLAG_CARDP) { h->flags &= ~PCIC_FLAG_CARDP; /* call the MI detach function */ pcmcia_card_detach(h->pcmcia, flags); } else { DPRINTF(("pcic_detach_card: already detached")); } }
void tslot_event_thread(void *v) { struct tslot_softc *sc = v; struct tslot_data *td; int s, status; unsigned int socket; for (;;) { s = splhigh(); if ((socket = ffs(sc->sc_events)) == 0) { splx(s); tsleep(&sc->sc_events, PWAIT, "tslot_event", 0); continue; } socket--; sc->sc_events &= ~(1 << socket); splx(s); if (socket >= TS102_NUM_SLOTS) { #ifdef DEBUG printf("%s: invalid slot number %d\n", sc->sc_dev.dv_xname, te->te_slot); #endif continue; } td = &sc->sc_slot[socket]; status = TSLOT_READ(td, TS102_REG_CARD_A_STS); if (status & TS102_CARD_STS_PRES) { /* Card insertion */ if ((td->td_status & TS_CARD) == 0) { td->td_status |= TS_CARD; tadpole_set_pcmcia(td->td_slot, 1); pcmcia_card_attach(td->td_pcmcia); } } else { /* Card removal */ if ((td->td_status & TS_CARD) != 0) { td->td_status &= ~TS_CARD; tadpole_set_pcmcia(td->td_slot, 0); pcmcia_card_detach(td->td_pcmcia, DETACH_FORCE); } } } }
static void imx_pcic_detach_card(struct imx_pcic_socket *h, int flags) { struct imx_pcic_softc *sc = h->sc; int i; if (h->flags & IMX_PCIC_FLAG_CARDP) { h->flags &= ~IMX_PCIC_FLAG_CARDP; /* call the MI detach function */ pcmcia_card_detach(h->pcmcia, flags); } /* Clear CIT if no other card is present. */ for (i = 0; i < sc->sc_nslots; i++) { if (sc->sc_socket[i].flags & IMX_PCIC_FLAG_CARDP) { return; } } }
void pxapcic_detach_card(struct pxapcic_socket *h, int flags) { struct pxapcic_softc *sc = h->sc; u_int32_t rv; int i; if (h->flags & PXAPCIC_FLAG_CARDP) { h->flags &= ~PXAPCIC_FLAG_CARDP; /* call the MI detach function */ pcmcia_card_detach(h->pcmcia, flags); } /* Clear CIT if no other card is present. */ for (i = 0; i < sc->sc_nslots; i++) if (sc->sc_socket[i].flags & PXAPCIC_FLAG_CARDP) return; rv = bus_space_read_4(sc->sc_iot, sc->sc_memctl_ioh, MEMCTL_MECR); bus_space_write_4(sc->sc_iot, sc->sc_memctl_ioh, MEMCTL_MECR, rv & ~MECR_CIT); }
static void sapcic_event_thread(void *arg) { struct sapcic_socket *so = arg; int newstatus, s; while (so->shutdown == 0) { /* * Serialize event processing on the PCIC. We may * sleep while we hold this lock. */ mutex_enter(&so->sc->sc_lock); /* sleep .25s to be enqueued chatterling interrupts */ (void) tsleep(sapcic_event_thread, PWAIT, "pcicss", hz / 4); s = splhigh(); so->event = 0; /* we don't rely on interrupt type */ newstatus = (so->pcictag->read)(so, SAPCIC_STATUS_CARD); splx(s); if (so->laststatus == newstatus) { /* * No events to process; release the PCIC lock. */ mutex_exit(&so->sc->sc_lock); (void) tsleep(&so->event, PWAIT, "pcicev", hz); continue; } so->laststatus = newstatus; switch (newstatus) { case SAPCIC_CARD_VALID: aprint_normal_dev(so->sc->sc_dev, "insertion event\n"); pcmcia_card_attach(so->pcmcia); break; case SAPCIC_CARD_INVALID: aprint_normal_dev(so->sc->sc_dev, "removal event\n"); pcmcia_card_detach(so->pcmcia, DETACH_FORCE); break; default: panic("sapcic_event_thread: unknown status %d", newstatus); } mutex_exit(&so->sc->sc_lock); } so->event_thread = NULL; /* In case parent is waiting for us to exit. */ wakeup(so->sc); kthread_exit(0); }
/* * static void cardslot_event_thread(void *arg) * * This function is the main routine handing cardslot events such as * insertions and removals. * */ static void cardslot_event_thread(void *arg) { struct cardslot_softc *sc = arg; struct cardslot_event *ce; int s; static int antonym_ev[4] = { CARDSLOT_EVENT_REMOVAL_16, CARDSLOT_EVENT_INSERTION_16, CARDSLOT_EVENT_REMOVAL_CB, CARDSLOT_EVENT_INSERTION_CB }; while (sc->sc_th_enable) { s = spltty(); if ((ce = SIMPLEQ_FIRST(&sc->sc_events)) == NULL) { splx(s); (void) tsleep(&sc->sc_events, PWAIT, "cardslotev", 0); continue; } SIMPLEQ_REMOVE_HEAD(&sc->sc_events, ce_q); splx(s); if (IS_CARDSLOT_INSERT_REMOVE_EV(ce->ce_type)) { /* Chattering suppression */ s = spltty(); while (1) { struct cardslot_event *ce1, *ce2; if ((ce1 = SIMPLEQ_FIRST(&sc->sc_events)) == NULL) break; if (ce1->ce_type != antonym_ev[ce->ce_type]) break; if ((ce2 = SIMPLEQ_NEXT(ce1, ce_q)) == NULL) break; if (ce2->ce_type == ce->ce_type) { SIMPLEQ_REMOVE_HEAD(&sc->sc_events, ce_q); free(ce1, M_TEMP); SIMPLEQ_REMOVE_HEAD(&sc->sc_events, ce_q); free(ce2, M_TEMP); } } splx(s); } switch (ce->ce_type) { case CARDSLOT_EVENT_INSERTION_CB: if ((CARDSLOT_CARDTYPE(sc->sc_status) == CARDSLOT_STATUS_CARD_CB) || (CARDSLOT_CARDTYPE(sc->sc_status) == CARDSLOT_STATUS_CARD_16)) { if (CARDSLOT_WORK(sc->sc_status) == CARDSLOT_STATUS_WORKING) { /* A card has already been inserted * and works. */ break; } } if (sc->sc_cb_softc) { CARDSLOT_SET_CARDTYPE(sc->sc_status, CARDSLOT_STATUS_CARD_CB); if (cardbus_attach_card(sc->sc_cb_softc) > 0) { /* At least one function works */ CARDSLOT_SET_WORK(sc->sc_status, CARDSLOT_STATUS_WORKING); } else { /* No functions work or this card is * not known */ CARDSLOT_SET_WORK(sc->sc_status, CARDSLOT_STATUS_NOTWORK); } } else { panic("no cardbus on %s", sc->sc_dev.dv_xname); } break; case CARDSLOT_EVENT_INSERTION_16: if ((CARDSLOT_CARDTYPE(sc->sc_status) == CARDSLOT_STATUS_CARD_CB) || (CARDSLOT_CARDTYPE(sc->sc_status) == CARDSLOT_STATUS_CARD_16)) { if (CARDSLOT_WORK(sc->sc_status) == CARDSLOT_STATUS_WORKING) { /* A card has already been inserted * and works. */ break; } } if (sc->sc_16_softc) { CARDSLOT_SET_CARDTYPE(sc->sc_status, CARDSLOT_STATUS_CARD_16); if (pcmcia_card_attach( (struct device *)sc->sc_16_softc)) { /* Do not attach */ CARDSLOT_SET_WORK(sc->sc_status, CARDSLOT_STATUS_NOTWORK); } else { /* working */ CARDSLOT_SET_WORK(sc->sc_status, CARDSLOT_STATUS_WORKING); } } else { panic("no 16-bit pcmcia on %s", sc->sc_dev.dv_xname); } break; case CARDSLOT_EVENT_REMOVAL_CB: if (CARDSLOT_CARDTYPE(sc->sc_status) == CARDSLOT_STATUS_CARD_CB) { /* CardBus card has not been inserted. */ if (CARDSLOT_WORK(sc->sc_status) == CARDSLOT_STATUS_WORKING) { cardbus_detach_card(sc->sc_cb_softc); CARDSLOT_SET_WORK(sc->sc_status, CARDSLOT_STATUS_NOTWORK); CARDSLOT_SET_WORK(sc->sc_status, CARDSLOT_STATUS_CARD_NONE); } CARDSLOT_SET_CARDTYPE(sc->sc_status, CARDSLOT_STATUS_CARD_NONE); } else if (CARDSLOT_CARDTYPE(sc->sc_status) != CARDSLOT_STATUS_CARD_16) { /* Unknown card... */ CARDSLOT_SET_CARDTYPE(sc->sc_status, CARDSLOT_STATUS_CARD_NONE); } CARDSLOT_SET_WORK(sc->sc_status, CARDSLOT_STATUS_NOTWORK); break; case CARDSLOT_EVENT_REMOVAL_16: DPRINTF(("%s: removal event\n", sc->sc_dev.dv_xname)); if (CARDSLOT_CARDTYPE(sc->sc_status) != CARDSLOT_STATUS_CARD_16) { /* 16-bit card has not been inserted. */ break; } if ((sc->sc_16_softc != NULL) && (CARDSLOT_WORK(sc->sc_status) == CARDSLOT_STATUS_WORKING)) { struct pcmcia_softc *psc = sc->sc_16_softc; pcmcia_card_deactivate((struct device *)psc); pcmcia_chip_socket_disable(psc->pct, psc->pch); pcmcia_card_detach((struct device *)psc, DETACH_FORCE); } CARDSLOT_SET_CARDTYPE(sc->sc_status, CARDSLOT_STATUS_CARD_NONE); CARDSLOT_SET_WORK(sc->sc_status, CARDSLOT_STATUS_NOTWORK); break; default: panic("cardslot_event_thread: unknown event %d", ce->ce_type); } free(ce, M_TEMP); } sc->sc_event_thread = NULL; /* In case the parent device is waiting for us to exit. */ wakeup(sc); kthread_exit(0); }