示例#1
0
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);
}
示例#2
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"));
	}
}
示例#3
0
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;
		}
	}
}
示例#5
0
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);
}
示例#6
0
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);
}
示例#7
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);
}