diff --git a/sys/dev/cardbus/cardbus.c b/sys/dev/cardbus/cardbus.c index a4c906675109..488a4149d9eb 100644 --- a/sys/dev/cardbus/cardbus.c +++ b/sys/dev/cardbus/cardbus.c @@ -1,7 +1,7 @@ -/* $NetBSD: cardbus.c,v 1.17 2000/01/13 10:27:31 joda Exp $ */ +/* $NetBSD: cardbus.c,v 1.18 2000/01/26 09:04:59 haya Exp $ */ /* - * Copyright (c) 1997, 1998 and 1999 + * Copyright (c) 1997, 1998, 1999 and 2000 * HAYAKAWA Koichi. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -58,7 +58,6 @@ #if defined CARDBUS_DEBUG #define STATIC #define DPRINTF(a) printf a -#define DDELAY(x) delay((x)*1000*1000) #else #define STATIC static #define DPRINTF(a) @@ -623,6 +622,45 @@ cardbusprint(aux, pnp) +/* + * void cardbus_detach_card(struct cardbus_softc *sc) + * + * This function detaches the card on the slot: detach device data + * structure and turns off the power. + * + * This function must not be called under interrupt context. + */ +void +cardbus_detach_card(sc) + struct cardbus_softc *sc; +{ + struct cardbus_devfunc *ct, *ct_next, **prev_next; + + prev_next = &(sc->sc_funcs->ct_next); + + for (ct = sc->sc_funcs; ct != NULL; ct = ct_next) { + struct device *fndev = ct->ct_device; + ct_next = ct->ct_next; + + printf("%s: detaching %s\n", sc->sc_dev.dv_xname, fndev->dv_xname); + /* call device detach function */ + + + if (0 != config_detach(fndev, 0)) { + printf("%s: cannot detaching dev %s, function %d\n", + sc->sc_dev.dv_xname, fndev->dv_xname, ct->ct_func); + prev_next = &(ct->ct_next); + } else { + sc->sc_poweron_func &= ~(1 << ct->ct_func); + *prev_next = ct->ct_next; + free(ct, M_DEVBUF); + } + } +} + + + + /* * void *cardbus_intr_establish(cc, cf, irq, level, func, arg) * Interrupt handler of pccard. @@ -675,6 +713,7 @@ enable_function(sc, cdstatus, function) int cdstatus; int function; { + if(sc->sc_poweron_func == 0) { if (cdstatus & CARDBUS_3V_CARD) { sc->sc_cf->cardbus_power(sc->sc_cc, CARDBUS_VCC_3V); @@ -689,6 +728,7 @@ disable_function(sc, function) struct cardbus_softc *sc; int function; { + sc->sc_poweron_func &= ~(1 << function); if(sc->sc_poweron_func == 0) { /* power-off because no functions are enabled */ diff --git a/sys/dev/cardbus/cardbusvar.h b/sys/dev/cardbus/cardbusvar.h index 38cfda5e70fa..cf563de0c0fe 100644 --- a/sys/dev/cardbus/cardbusvar.h +++ b/sys/dev/cardbus/cardbusvar.h @@ -1,7 +1,7 @@ -/* $NetBSD: cardbusvar.h,v 1.13 1999/12/17 14:06:43 augustss Exp $ */ +/* $NetBSD: cardbusvar.h,v 1.14 2000/01/26 09:04:59 haya Exp $ */ /* - * Copyright (c) 1998 and 1999 + * Copyright (c) 1998, 1999 and 2000 * HAYAKAWA Koichi. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -403,6 +403,7 @@ struct cardbus_attach_args { #define CARDBUS_UNK_FUNCTION CARDBUSCF_FUNCTION_DEFAULT int cardbus_attach_card __P((struct cardbus_softc *)); +void cardbus_detach_card __P((struct cardbus_softc *)); void *cardbus_intr_establish __P((cardbus_chipset_tag_t, cardbus_function_tag_t, cardbus_intr_handle_t irq, int level, int (*func) (void *), void *arg)); void cardbus_intr_disestablish __P((cardbus_chipset_tag_t, cardbus_function_tag_t, void *handler)); diff --git a/sys/dev/cardbus/cardslot.c b/sys/dev/cardbus/cardslot.c index 2c34a7eb9c06..267cc5697cdc 100644 --- a/sys/dev/cardbus/cardslot.c +++ b/sys/dev/cardbus/cardslot.c @@ -1,7 +1,7 @@ -/* $NetBSD: cardslot.c,v 1.6 2000/01/24 18:34:44 thorpej Exp $ */ +/* $NetBSD: cardslot.c,v 1.7 2000/01/26 09:04:59 haya Exp $ */ /* - * Copyright (c) 1999 + * Copyright (c) 1999 and 2000 * HAYAKAWA Koichi. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -55,7 +55,6 @@ #if defined CARDSLOT_DEBUG #define STATIC #define DPRINTF(a) printf a -#define DDELAY(x) delay((x)*1000*1000) #else #define STATIC static #define DPRINTF(a) @@ -426,11 +425,10 @@ cardslot_event_thread(arg) case CARDSLOT_EVENT_REMOVAL_CB: if (CARDSLOT_CARDTYPE(sc->sc_status) == CARDSLOT_STATUS_CARD_CB) { /* CardBus card has not been inserted. */ -#if notyet 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); } -#endif CARDSLOT_SET_CARDTYPE(sc->sc_status, CARDSLOT_STATUS_CARD_NONE); } else if (CARDSLOT_CARDTYPE(sc->sc_status) != CARDSLOT_STATUS_CARD_16) { /* Unknown card... */ diff --git a/sys/dev/cardbus/if_ex_cardbus.c b/sys/dev/cardbus/if_ex_cardbus.c index 53d86c46edc8..c08582f1b1d0 100644 --- a/sys/dev/cardbus/if_ex_cardbus.c +++ b/sys/dev/cardbus/if_ex_cardbus.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_ex_cardbus.c,v 1.9 1999/11/17 08:49:16 thorpej Exp $ */ +/* $NetBSD: if_ex_cardbus.c,v 1.10 2000/01/26 09:04:59 haya Exp $ */ /* * CardBus specific routines for 3Com 3C575-family CardBus ethernet adapter @@ -339,12 +339,15 @@ ex_cardbus_detach(self, arg) struct ex_softc *sc = &psc->sc_softc; cardbus_function_tag_t cf = psc->sc_ct->ct_cf; cardbus_chipset_tag_t cc = psc->sc_ct->ct_cc; + struct ifnet *ifp = &sc->sc_ethercom.ec_if; /* * XXX Currently, no detach. */ printf("- ex_cardbus_detach\n"); + if_down(ifp); + cardbus_intr_disestablish(cc, cf, sc->sc_ih); sc->enabled = 0;