The athn(4) USB driver supports dual-band and uses the same broken pattern as run(4). See http://marc.info/?l=openbsd-tech&m=143660130627359&w=2
Index: if_athn_usb.c =================================================================== RCS file: /cvs/src/sys/dev/usb/if_athn_usb.c,v retrieving revision 1.35 diff -u -p -r1.35 if_athn_usb.c --- if_athn_usb.c 9 Jul 2015 13:48:54 -0000 1.35 +++ if_athn_usb.c 11 Jul 2015 08:07:22 -0000 @@ -570,16 +570,20 @@ athn_usb_task(void *arg) struct athn_usb_softc *usc = arg; struct athn_usb_host_cmd_ring *ring = &usc->cmdq; struct athn_usb_host_cmd *cmd; - int s; + int s, generation; /* Process host commands. */ s = splusb(); + generation = ring->generation; while (ring->next != ring->cur) { cmd = &ring->cmd[ring->next]; splx(s); /* Invoke callback. */ cmd->cb(usc, cmd->data); s = splusb(); + /* Abort this task if interface was stopped meanwhile. */ + if (generation != ring->generation) + break; ring->queued--; ring->next = (ring->next + 1) % ATHN_USB_HOST_CMD_RING_COUNT; } @@ -594,12 +598,12 @@ athn_usb_do_async(struct athn_usb_softc struct athn_usb_host_cmd *cmd; int s; + s = splusb(); if (ring->queued == ATHN_USB_HOST_CMD_RING_COUNT) { printf("%s: host cmd queue overrun\n", usc->usb_dev.dv_xname); + splx(s); return; /* XXX */ } - - s = splusb(); cmd = &ring->cmd[ring->cur]; cmd->cb = cb; KASSERT(len <= sizeof(cmd->data)); @@ -2365,6 +2369,10 @@ athn_usb_stop(struct ifnet *ifp) ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); s = splusb(); + + /* Abort athn_usb_task thread. */ + usc->cmdq.generation++; + ieee80211_new_state(ic, IEEE80211_S_INIT, -1); /* Wait for all async commands to complete. */ Index: if_athn_usb.h =================================================================== RCS file: /cvs/src/sys/dev/usb/if_athn_usb.h,v retrieving revision 1.6 diff -u -p -r1.6 if_athn_usb.h --- if_athn_usb.h 2 Mar 2015 14:46:02 -0000 1.6 +++ if_athn_usb.h 11 Jul 2015 08:04:25 -0000 @@ -412,6 +412,7 @@ struct athn_usb_host_cmd_ring { int cur; int next; int queued; + int generation; }; struct athn_usb_softc {