+ case BPF_WAITING:
+ /*
+ * Waiting for a timeout.
+ * Cancel any timer that has yet to go off,
+ * and mark the state as "closing".
+ * Then drop the lock to allow any timers that
+ * *have* gone off to run to completion, and wait
+ * for them to finish.
+ */
+ if (!bpf_stop_timer(d)) {
+ /*
+ * There was no pending call, so the call must
+ * have been in progress. Wait for the call to
+ * complete; we have to drop the lock while
+ * waiting. to let the in-progrss call complete
+ */
+ d->bd_state = BPF_DRAINING;
+ while (d->bd_state == BPF_DRAINING)
+ msleep((caddr_t)d, bpf_mlock, PRINET,
+ "bpfdraining", NULL);
+ }
+ d->bd_state = BPF_IDLE;
+ break;
+
+ case BPF_TIMED_OUT:
+ /*
+ * Timer went off, and the timeout routine finished.
+ */
+ d->bd_state = BPF_IDLE;
+ break;
+
+ case BPF_DRAINING:
+ /*
+ * Another thread is blocked on a close waiting for
+ * a timeout to finish.
+ * This "shouldn't happen", as the first thread to enter
+ * bpfclose() will set bpf_dtab[minor(dev)] to 1, and
+ * all subsequent threads should see that and fail with
+ * ENXIO.
+ */
+ panic("Two threads blocked in a BPF close");
+ break;
+ }
+
+ if (d->bd_bif)
+ bpf_detachd(d, 1);
+ selthreadclear(&d->bd_sel);
+#if CONFIG_MACF_NET
+ mac_bpfdesc_label_destroy(d);
+#endif
+ thread_call_free(d->bd_thread_call);
+
+ while (d->bd_hbuf_read)
+ msleep((caddr_t)d, bpf_mlock, PRINET, "bpf_reading", NULL);
+
+ bpf_freed(d);
+
+ /* Mark free in same context as bpfopen comes to check */
+ bpf_dtab[minor(dev)] = NULL; /* Mark closed */
+
+ bpf_release_d(d);
+
+ lck_mtx_unlock(bpf_mlock);
+
+ return (0);
+}
+
+
+#define BPF_SLEEP bpf_sleep
+
+static int
+bpf_sleep(struct bpf_d *d, int pri, const char *wmesg, int timo)
+{
+ u_int64_t abstime = 0;
+
+ if(timo)
+ clock_interval_to_deadline(timo, NSEC_PER_SEC / hz, &abstime);
+
+ return msleep1((caddr_t)d, bpf_mlock, pri, wmesg, abstime);
+}
+
+/*
+ * Rotate the packet buffers in descriptor d. Move the store buffer
+ * into the hold slot, and the free buffer into the store slot.
+ * Zero the length of the new store buffer.
+ */
+#define ROTATE_BUFFERS(d) \
+ if (d->bd_hbuf_read) \
+ panic("rotating bpf buffers during read"); \
+ (d)->bd_hbuf = (d)->bd_sbuf; \
+ (d)->bd_hlen = (d)->bd_slen; \
+ (d)->bd_hcnt = (d)->bd_scnt; \