Index: sys/systm.h =================================================================== RCS file: /cvsroot/src/sys/sys/systm.h,v retrieving revision 1.239 diff -u -r1.239 systm.h --- sys/systm.h 31 Jan 2010 02:04:43 -0000 1.239 +++ sys/systm.h 18 May 2010 22:01:26 -0000 @@ -362,6 +362,10 @@ void mountroothook_destroy(void); void domountroothook(struct device *); +void *aftermountroothook_establish(void (*)(struct device *), struct device *); +void aftermountroothook_disestablish(void *); +void doaftermountroothook(void); + /* * Exec hooks. Subsystems may want to do cleanup when a process * execs. Index: kern/init_main.c =================================================================== RCS file: /cvsroot/src/sys/kern/init_main.c,v retrieving revision 1.419 diff -u -r1.419 init_main.c --- kern/init_main.c 21 Apr 2010 16:51:24 -0000 1.419 +++ kern/init_main.c 18 May 2010 22:01:26 -0000 @@ -682,6 +682,8 @@ uvm_aiodone_worker, NULL, PRI_VM, IPL_NONE, WQ_MPSAFE)) panic("fork aiodoned"); + doaftermountroothook(); + /* * Okay, now we can let init(8) exec! It's off to userland! */ Index: kern/kern_hook.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_hook.c,v retrieving revision 1.3 diff -u -r1.3 kern_hook.c --- kern/kern_hook.c 31 Jan 2010 09:27:40 -0000 1.3 +++ kern/kern_hook.c 18 May 2010 22:01:26 -0000 @@ -196,6 +196,37 @@ } } +/* + * "After mountroot hook" types, functions, and variables. + */ + +static hook_list_t aftermountroothook_list = + LIST_HEAD_INITIALIZER(aftermountroothook_list); + +void * +aftermountroothook_establish(void (*fn)(device_t), device_t dev) +{ + return hook_establish(&aftermountroothook_list, (void (*)(void *))fn, dev); +} + +void +aftermountroothook_disestablish(void *vhook) +{ + hook_disestablish(&aftermountroothook_list, vhook); +} + +void +doaftermountroothook(void) +{ + struct hook_desc *hd; + + while ((hd = LIST_FIRST(&aftermountroothook_list)) != NULL) { + LIST_REMOVE(hd, hk_list); + (*hd->hk_fn)(hd->hk_arg); + free(hd, M_DEVBUF); + } +} + static hook_list_t exechook_list = LIST_HEAD_INITIALIZER(exechook_list); void * Index: dev/usb/if_zyd.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/if_zyd.c,v retrieving revision 1.25 diff -u -r1.25 if_zyd.c --- dev/usb/if_zyd.c 5 Apr 2010 07:21:49 -0000 1.25 +++ dev/usb/if_zyd.c 21 May 2010 14:26:49 -0000 @@ -156,7 +156,7 @@ CFATTACH_DECL_NEW(zyd, sizeof(struct zyd_softc), zyd_match, zyd_attach, zyd_detach, zyd_activate); -Static int zyd_attachhook(void *); +Static void zyd_attachhook(device_t); Static int zyd_complete_attach(struct zyd_softc *); Static int zyd_open_pipes(struct zyd_softc *); Static void zyd_close_pipes(struct zyd_softc *); @@ -245,10 +245,10 @@ UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } -Static int -zyd_attachhook(void *xsc) +Static void +zyd_attachhook(device_t dv) { - struct zyd_softc *sc = xsc; + struct zyd_softc *sc = device_private(dv); firmware_handle_t fwh; const char *fwname; u_char *fw; @@ -259,7 +259,7 @@ if ((error = firmware_open("zyd", fwname, &fwh)) != 0) { aprint_error_dev(sc->sc_dev, "failed to open firmware %s (error=%d)\n", fwname, error); - return error; + return; } size = firmware_get_size(fwh); fw = firmware_malloc(size); @@ -267,7 +267,7 @@ aprint_error_dev(sc->sc_dev, "failed to allocate firmware memory\n"); firmware_close(fwh); - return ENOMEM; + return; } error = firmware_read(fwh, 0, fw, size); firmware_close(fwh); @@ -275,7 +275,7 @@ aprint_error_dev(sc->sc_dev, "failed to read firmware (error %d)\n", error); firmware_free(fw, 0); - return error; + return; } error = zyd_loadfirmware(sc, fw, size); @@ -283,16 +283,15 @@ aprint_error_dev(sc->sc_dev, "could not load firmware (error=%d)\n", error); firmware_free(fw, 0); - return ENXIO; + return; } firmware_free(fw, 0); sc->sc_flags |= ZD1211_FWLOADED; /* complete the attach process */ - if ((error = zyd_complete_attach(sc)) == 0) + if (zyd_complete_attach(sc) == 0) sc->attached = 1; - return error; } void @@ -334,13 +333,12 @@ IFQ_SET_READY(&ifp->if_snd); memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); - if_attach(ifp); - /* XXXX: alloc temporarily until the layer2 can be configured. */ - if_alloc_sadl(ifp); - SIMPLEQ_INIT(&sc->sc_rqh); - return; + if (rootvp == NULL) + aftermountroothook_establish(zyd_attachhook, self); + else + zyd_attachhook(self); } Static int @@ -424,7 +422,7 @@ IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ; } - if_free_sadl(ifp); + if_attach(ifp); ieee80211_ifattach(ic); ic->ic_node_alloc = zyd_node_alloc; ic->ic_newassoc = zyd_newassoc; @@ -461,11 +459,8 @@ struct ifnet *ifp = &sc->sc_if; int s; - if (!sc->attached) { - if_free_sadl(ifp); - if_detach(ifp); + if (!sc->attached) return 0; - } s = splusb(); @@ -2450,10 +2445,6 @@ struct ieee80211com *ic = &sc->sc_ic; int i, error; - if ((sc->sc_flags & ZD1211_FWLOADED) == 0) - if ((error = zyd_attachhook(sc)) != 0) - return error; - zyd_stop(ifp, 0); IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));