diff --git a/src/libs/compat/freebsd11_network/bus.cpp b/src/libs/compat/freebsd11_network/bus.cpp index cd6d600e24..816878d0b3 100644 --- a/src/libs/compat/freebsd11_network/bus.cpp +++ b/src/libs/compat/freebsd11_network/bus.cpp @@ -447,6 +447,15 @@ bus_bind_intr(device_t dev, struct resource *res, int cpu) return 0; } + +int bus_describe_intr(device_t dev, struct resource *irq, void *cookie, + const char* fmt, ...) +{ + UNIMPLEMENTED(); + return B_ERROR; +} + + // #pragma mark - bus functions diff --git a/src/libs/compat/freebsd11_network/compat/sys/_task.h b/src/libs/compat/freebsd11_network/compat/sys/_task.h index a94e6b8ca9..6ce6c552ff 100644 --- a/src/libs/compat/freebsd11_network/compat/sys/_task.h +++ b/src/libs/compat/freebsd11_network/compat/sys/_task.h @@ -10,11 +10,11 @@ #include -typedef void (*task_handler_t)(void *context, int pending); +typedef void (*task_fn_t)(void *context, int pending); struct task { int ta_priority; - task_handler_t ta_handler; + task_fn_t ta_handler; void *ta_argument; int ta_pending; diff --git a/src/libs/compat/freebsd11_network/compat/sys/bus.h b/src/libs/compat/freebsd11_network/compat/sys/bus.h index 4ec6188528..476c847145 100644 --- a/src/libs/compat/freebsd11_network/compat/sys/bus.h +++ b/src/libs/compat/freebsd11_network/compat/sys/bus.h @@ -109,6 +109,8 @@ int bus_setup_intr(device_t dev, struct resource *r, int flags, driver_filter_t filter, driver_intr_t handler, void *arg, void **_cookie); int bus_teardown_intr(device_t dev, struct resource *r, void *cookie); int bus_bind_intr(device_t dev, struct resource *r, int cpu); +int bus_describe_intr(device_t dev, struct resource *irq, void *cookie, + const char* fmt, ...); const char *device_get_name(device_t dev); const char *device_get_nameunit(device_t dev); diff --git a/src/libs/compat/freebsd11_network/compat/sys/callout.h b/src/libs/compat/freebsd11_network/compat/sys/callout.h index 9d4da3b944..e78fb24e01 100644 --- a/src/libs/compat/freebsd11_network/compat/sys/callout.h +++ b/src/libs/compat/freebsd11_network/compat/sys/callout.h @@ -25,7 +25,8 @@ struct callout { }; -#define CALLOUT_MPSAFE 0x0001 +#define CALLOUT_MPSAFE 0x0008 /* deprecated */ +#define CALLOUT_RETURNUNLOCKED 0x0010 /* handler returns with mtx unlocked */ void callout_init(struct callout *c, int mpsafe); diff --git a/src/libs/compat/freebsd11_network/compat/sys/mbuf-fbsd.h b/src/libs/compat/freebsd11_network/compat/sys/mbuf-fbsd.h index ff60d98d46..59fa9d4062 100644 --- a/src/libs/compat/freebsd11_network/compat/sys/mbuf-fbsd.h +++ b/src/libs/compat/freebsd11_network/compat/sys/mbuf-fbsd.h @@ -114,6 +114,15 @@ *_mmp = _mm; \ } while (0) +static __inline void +m_clrprotoflags(struct mbuf *m) +{ + while (m) { + m->m_flags &= ~M_PROTOFLAGS; + m = m->m_next; + } +} + /* mbufq */ struct mbufq { diff --git a/src/libs/compat/freebsd11_network/compat/sys/mbuf.h b/src/libs/compat/freebsd11_network/compat/sys/mbuf.h index 18c9c76405..302bdbed08 100644 --- a/src/libs/compat/freebsd11_network/compat/sys/mbuf.h +++ b/src/libs/compat/freebsd11_network/compat/sys/mbuf.h @@ -26,26 +26,44 @@ #define MT_DATA 1 -#define M_EXT 0x00000001 -#define M_PKTHDR 0x00000002 -#define M_RDONLY 0x00000008 -#define M_PROTO1 0x00000010 -#define M_PROTO2 0x00000020 -#define M_PROTO3 0x00000040 -#define M_PROTO4 0x00000080 -#define M_PROTO5 0x00000100 -#define M_BCAST 0x00000200 -#define M_MCAST 0x00000400 -#define M_FRAG 0x00000800 -#define M_FIRSTFRAG 0x00001000 -#define M_LASTFRAG 0x00002000 -#define M_VLANTAG 0x00010000 -#define M_PROTO6 0x00080000 -#define M_PROTO7 0x00100000 -#define M_PROTO8 0x00200000 +/* + * mbuf flags of global significance and layer crossing. + * Those of only protocol/layer specific significance are to be mapped + * to M_PROTO[1-12] and cleared at layer handoff boundaries. + * NB: Limited to the lower 24 bits. + */ +#define M_EXT 0x00000001 /* has associated external storage */ +#define M_PKTHDR 0x00000002 /* start of record */ +#define M_EOR 0x00000004 /* end of record */ +#define M_RDONLY 0x00000008 /* associated data is marked read-only */ +#define M_BCAST 0x00000010 /* send/received as link-level broadcast */ +#define M_MCAST 0x00000020 /* send/received as link-level multicast */ +#define M_PROMISC 0x00000040 /* packet was not for us */ +#define M_VLANTAG 0x00000080 /* ether_vtag is valid */ +#define M_UNUSED_8 0x00000100 /* --available-- */ +#define M_NOFREE 0x00000200 /* do not free mbuf, embedded in cluster */ -#define M_COPYFLAGS (M_PKTHDR | M_RDONLY | M_BCAST | M_MCAST | M_FRAG \ - | M_FIRSTFRAG | M_LASTFRAG | M_VLANTAG) +#define M_PROTO1 0x00001000 /* protocol-specific */ +#define M_PROTO2 0x00002000 /* protocol-specific */ +#define M_PROTO3 0x00004000 /* protocol-specific */ +#define M_PROTO4 0x00008000 /* protocol-specific */ +#define M_PROTO5 0x00010000 /* protocol-specific */ +#define M_PROTO6 0x00020000 /* protocol-specific */ +#define M_PROTO7 0x00040000 /* protocol-specific */ +#define M_PROTO8 0x00080000 /* protocol-specific */ +#define M_PROTO9 0x00100000 /* protocol-specific */ +#define M_PROTO10 0x00200000 /* protocol-specific */ +#define M_PROTO11 0x00400000 /* protocol-specific */ +#define M_PROTO12 0x00800000 /* protocol-specific */ + +#define M_PROTOFLAGS \ + (M_PROTO1|M_PROTO2|M_PROTO3|M_PROTO4|M_PROTO5|M_PROTO6|M_PROTO7|M_PROTO8|\ + M_PROTO9|M_PROTO10|M_PROTO11|M_PROTO12) + // Flags to purge when crossing layers. + +#define M_COPYFLAGS \ + (M_PKTHDR|M_EOR|M_RDONLY|M_BCAST|M_MCAST|M_PROMISC|M_VLANTAG| \ + M_PROTOFLAGS) // Flags preserved when copying m_pkthdr #define M_MOVE_PKTHDR(to, from) m_move_pkthdr((to), (from)) @@ -160,6 +178,7 @@ struct mbuf { #define m_dat M_dat.M_databuf +void m_catpkt(struct mbuf *m, struct mbuf *n); void m_adj(struct mbuf*, int); void m_align(struct mbuf*, int); int m_append(struct mbuf*, int, c_caddr_t); @@ -177,6 +196,9 @@ struct mbuf* m_devget(char*, int, int, struct ifnet*, struct mbuf* m_dup(struct mbuf*, int); int m_dup_pkthdr(struct mbuf*, struct mbuf*, int); +void m_demote_pkthdr(struct mbuf *m); +void m_demote(struct mbuf *m0, int all, int flags); + void m_extadd(struct mbuf*, caddr_t, u_int, void(*) (void*, void*), void*, void*, int, int); @@ -184,6 +206,7 @@ u_int m_fixhdr(struct mbuf*); struct mbuf* m_free(struct mbuf*); void m_freem(struct mbuf*); struct mbuf* m_get(int, short); +struct mbuf* m_get2(int size, int how, short type, int flags); struct mbuf* m_gethdr(int, short); struct mbuf* m_getjcl(int, short, int, int); u_int m_length(struct mbuf*, struct mbuf**); diff --git a/src/libs/compat/freebsd11_network/compat/sys/param.h b/src/libs/compat/freebsd11_network/compat/sys/param.h index 51e09e4a6d..55beb81508 100644 --- a/src/libs/compat/freebsd11_network/compat/sys/param.h +++ b/src/libs/compat/freebsd11_network/compat/sys/param.h @@ -17,7 +17,7 @@ /* The version this compatibility layer is based on */ -#define __FreeBSD_version 800107 +#define __FreeBSD_version 1101000 #define MAXBSIZE 0x10000 @@ -49,6 +49,14 @@ #define ALIGN_BYTES (sizeof(unsigned long) - 1) #define ALIGN(x) ((((unsigned long)x) + ALIGN_BYTES) & ~ALIGN_BYTES) +#ifdef __x86_64__ +#define ALIGNED_POINTER(p, t) 1 +#elif defined(__i386__) +#define ALIGNED_POINTER(p, t) 1 +#else +#error Need definition of ALIGNED_POINTER for this arch! +#endif + /* Macros for counting and rounding. */ #ifndef howmany #define howmany(x, y) (((x)+((y)-1))/(y)) diff --git a/src/libs/compat/freebsd11_network/compat/sys/socket.h b/src/libs/compat/freebsd11_network/compat/sys/socket.h index dc83ed2edd..1da6b72147 100644 --- a/src/libs/compat/freebsd11_network/compat/sys/socket.h +++ b/src/libs/compat/freebsd11_network/compat/sys/socket.h @@ -13,6 +13,6 @@ // TODO Should be incorporated into Haikus socket.h with a number below AF_MAX -#define AF_IEEE80211 AF_MAX + 1 /* IEEE 802.11 protocol */ +#define AF_IEEE80211 (AF_MAX + 1) /* IEEE 802.11 protocol */ #endif /* _FBSD_COMPAT_SYS_SOCKET_H_ */ diff --git a/src/libs/compat/freebsd11_network/compat/sys/taskqueue.h b/src/libs/compat/freebsd11_network/compat/sys/taskqueue.h index 64b2e5a8bb..de2592bf88 100644 --- a/src/libs/compat/freebsd11_network/compat/sys/taskqueue.h +++ b/src/libs/compat/freebsd11_network/compat/sys/taskqueue.h @@ -8,11 +8,18 @@ #include #include +#include #define PI_NET (B_REAL_TIME_DISPLAY_PRIORITY - 1) -#define TASK_INIT(taskp, prio, hand, arg) task_init(taskp, prio, hand, arg) + +struct timeout_task { + struct taskqueue *q; + struct task t; + struct callout c; + int f; +}; typedef void (*taskqueue_enqueue_fn)(void *context); @@ -25,9 +32,17 @@ int taskqueue_start_threads(struct taskqueue **tq, int count, int pri, const char *name, ...) __printflike(4, 5); void taskqueue_free(struct taskqueue *tq); void taskqueue_drain(struct taskqueue *tq, struct task *task); +void taskqueue_drain_timeout(struct taskqueue *queue, + struct timeout_task *timeout_task); void taskqueue_block(struct taskqueue *queue); void taskqueue_unblock(struct taskqueue *queue); int taskqueue_enqueue(struct taskqueue *tq, struct task *task); +int taskqueue_enqueue_timeout(struct taskqueue *queue, + struct timeout_task *ttask, int ticks); +int taskqueue_cancel(struct taskqueue *queue, struct task *task, + u_int *pendp); +int taskqueue_cancel_timeout(struct taskqueue *queue, + struct timeout_task *timeout_task, u_int *pendp); void taskqueue_thread_enqueue(void *context); @@ -39,6 +54,12 @@ int taskqueue_enqueue_fast(struct taskqueue *queue, struct task *task); struct taskqueue *taskqueue_create_fast(const char *name, int mflags, taskqueue_enqueue_fn enqueue, void *context); -void task_init(struct task *, int prio, task_handler_t handler, void *arg); +void task_init(struct task *, int prio, task_fn_t handler, void *arg); +#define TASK_INIT(taskp, prio, hand, arg) task_init(taskp, prio, hand, arg) + +void timeout_task_init(struct taskqueue *queue, struct timeout_task *timeout_task, + int priority, task_fn_t func, void *context); +#define TIMEOUT_TASK_INIT(queue, timeout_task, priority, func, context) \ + timeout_task_init(queue, timeout_task, priority, func, context); #endif diff --git a/src/libs/compat/freebsd11_network/fbsd_mbuf.c b/src/libs/compat/freebsd11_network/fbsd_mbuf.c index 7a0e6db63f..ca0cc819a8 100644 --- a/src/libs/compat/freebsd11_network/fbsd_mbuf.c +++ b/src/libs/compat/freebsd11_network/fbsd_mbuf.c @@ -197,6 +197,21 @@ nospace: return (NULL); } +/* + * Concatenate two pkthdr mbuf chains. + */ +void +m_catpkt(struct mbuf *m, struct mbuf *n) +{ + M_ASSERTPKTHDR(m); + M_ASSERTPKTHDR(n); + + m->m_pkthdr.len += n->m_pkthdr.len; + m_demote(n, 1, 0); + + m_cat(m, n); +} + void m_adj(struct mbuf *mp, int req_len) { @@ -647,6 +662,35 @@ mb_dupcl(struct mbuf *n, struct mbuf *m) n->m_flags |= M_EXT; } +void +m_demote_pkthdr(struct mbuf *m) +{ + M_ASSERTPKTHDR(m); + + m_tag_delete_chain(m, NULL); + m->m_flags &= ~M_PKTHDR; + bzero(&m->m_pkthdr, sizeof(struct pkthdr)); +} + +/* + * Clean up mbuf (chain) from any tags and packet headers. + * If "all" is set then the first mbuf in the chain will be + * cleaned too. + */ +void +m_demote(struct mbuf *m0, int all, int flags) +{ + struct mbuf *m; + + for (m = all ? m0 : m0->m_next; m != NULL; m = m->m_next) { + KASSERT(m->m_nextpkt == NULL, ("%s: m_nextpkt in m %p, m0 %p", + __func__, m, m0)); + if (m->m_flags & M_PKTHDR) + m_demote_pkthdr(m); + m->m_flags = m->m_flags & (M_EXT | M_RDONLY | M_NOFREE | flags); + } +} + /* * Partition an mbuf chain in two pieces, returning the tail -- * all but the first len0 bytes. In case of failure, it returns NULL and diff --git a/src/libs/compat/freebsd11_network/mbuf.c b/src/libs/compat/freebsd11_network/mbuf.c index aa0eca497f..b29617f791 100644 --- a/src/libs/compat/freebsd11_network/mbuf.c +++ b/src/libs/compat/freebsd11_network/mbuf.c @@ -154,6 +154,23 @@ m_get(int how, short type) } +struct mbuf * +m_get2(int size, int how, short type, int flags) +{ + if (size <= MHLEN || (size <= MLEN && (flags & M_PKTHDR) == 0)) { + size = MCLBYTES; + } else if (size <= MJUMPAGESIZE) { + size = MJUMPAGESIZE; + } else if (size <= MJUM9BYTES) { + size = MJUM9BYTES; + } else /* (size > MJUM9BYTES) */ { + return NULL; + } + + return m_getjcl(how, type, flags, size); +} + + struct mbuf * m_gethdr(int how, short type) { diff --git a/src/libs/compat/freebsd11_network/taskqueue.c b/src/libs/compat/freebsd11_network/taskqueue.c index fe2feb8512..4574ca50f5 100644 --- a/src/libs/compat/freebsd11_network/taskqueue.c +++ b/src/libs/compat/freebsd11_network/taskqueue.c @@ -12,6 +12,7 @@ #include +#include #include #include @@ -20,10 +21,12 @@ #define TQ_FLAGS_BLOCKED (1 << 1) #define TQ_FLAGS_PENDING (1 << 2) +#define DT_CALLOUT_ARMED (1 << 0) +#define DT_DRAIN_IN_PROGRESS (1 << 1) struct taskqueue { char tq_name[64]; - mutex tq_mutex; + struct mtx tq_mutex; struct list tq_list; taskqueue_enqueue_fn tq_enqueue; void *tq_arg; @@ -34,6 +37,7 @@ struct taskqueue { thread_id tq_thread_storage; int tq_threadcount; int tq_flags; + int tq_callouts; }; struct taskqueue *taskqueue_fast = NULL; @@ -54,7 +58,7 @@ _taskqueue_create(const char *name, int mflags, int fast, if (fast) { B_INITIALIZE_SPINLOCK(&tq->tq_spinlock); } else { - mutex_init_etc(&tq->tq_mutex, name, MUTEX_FLAG_CLONE_NAME); + mtx_init(&tq->tq_mutex, name, NULL, MTX_DEF); } strlcpy(tq->tq_name, name, sizeof(tq->tq_name)); @@ -66,6 +70,7 @@ _taskqueue_create(const char *name, int mflags, int fast, tq->tq_threads = NULL; tq->tq_threadcount = 0; tq->tq_flags = TQ_FLAGS_ACTIVE; + tq->tq_callouts = 0; return tq; } @@ -78,7 +83,7 @@ tq_lock(struct taskqueue *taskQueue, cpu_status *status) *status = disable_interrupts(); acquire_spinlock(&taskQueue->tq_spinlock); } else { - mutex_lock(&taskQueue->tq_mutex); + mtx_lock(&taskQueue->tq_mutex); } } @@ -90,7 +95,7 @@ tq_unlock(struct taskqueue *taskQueue, cpu_status status) release_spinlock(&taskQueue->tq_spinlock); restore_interrupts(status); } else { - mutex_unlock(&taskQueue->tq_mutex); + mtx_unlock(&taskQueue->tq_mutex); } } @@ -218,7 +223,7 @@ taskqueue_free(struct taskqueue *taskQueue) /* lock and drain list? */ taskQueue->tq_flags &= ~TQ_FLAGS_ACTIVE; if (!taskQueue->tq_fast) - mutex_destroy(&taskQueue->tq_mutex); + mtx_destroy(&taskQueue->tq_mutex); if (taskQueue->tq_sem != -1) { int i; @@ -252,6 +257,32 @@ taskqueue_drain(struct taskqueue *taskQueue, struct task *task) } +void +taskqueue_drain_timeout(struct taskqueue *queue, + struct timeout_task *timeout_task) +{ + cpu_status status; + /* + * Set flag to prevent timer from re-starting during drain: + */ + tq_lock(queue, &status); + KASSERT((timeout_task->f & DT_DRAIN_IN_PROGRESS) == 0, + ("Drain already in progress")); + timeout_task->f |= DT_DRAIN_IN_PROGRESS; + tq_unlock(queue, status); + + callout_drain(&timeout_task->c); + taskqueue_drain(queue, &timeout_task->t); + + /* + * Clear flag to allow timer to re-start: + */ + tq_lock(queue, &status); + timeout_task->f &= ~DT_DRAIN_IN_PROGRESS; + tq_unlock(queue, status); +} + + int taskqueue_enqueue(struct taskqueue *taskQueue, struct task *task) { @@ -273,6 +304,109 @@ taskqueue_enqueue(struct taskqueue *taskQueue, struct task *task) } +static void +taskqueue_timeout_func(void *arg) +{ + struct taskqueue *queue; + struct timeout_task *timeout_task; + + timeout_task = arg; + queue = timeout_task->q; + KASSERT((timeout_task->f & DT_CALLOUT_ARMED) != 0, ("Stray timeout")); + timeout_task->f &= ~DT_CALLOUT_ARMED; + queue->tq_callouts--; + taskqueue_enqueue(timeout_task->q, &timeout_task->t); +} + + +int +taskqueue_enqueue_timeout(struct taskqueue *queue, + struct timeout_task *ttask, int ticks) +{ + int res; + cpu_status status; + + tq_lock(queue, &status); + KASSERT(timeout_task->q == NULL || timeout_task->q == queue, + ("Migrated queue")); + ttask->q = queue; + res = ttask->t.ta_pending; + if (ttask->f & DT_DRAIN_IN_PROGRESS) { + /* Do nothing */ + tq_unlock(queue, status); + res = -1; + } else if (ticks == 0) { + tq_unlock(queue, status); + taskqueue_enqueue(queue, &ttask->t); + } else { + if ((ttask->f & DT_CALLOUT_ARMED) != 0) { + res++; + } else { + queue->tq_callouts++; + ttask->f |= DT_CALLOUT_ARMED; + if (ticks < 0) + ticks = -ticks; /* Ignore overflow. */ + } + tq_unlock(queue, status); + if (ticks > 0) { + callout_reset(&ttask->c, ticks, + taskqueue_timeout_func, ttask); + } + } + return (res); +} + + +static int +taskqueue_cancel_locked(struct taskqueue *queue, struct task *task, + u_int *pendp) +{ + if (task->ta_pending > 0) + list_remove_item(&queue->tq_list, task); + if (pendp != NULL) + *pendp = task->ta_pending; + task->ta_pending = 0; + return 0; +} + + +int +taskqueue_cancel(struct taskqueue *queue, struct task *task, u_int *pendp) +{ + int error; + cpu_status status; + + tq_lock(queue, &status); + error = taskqueue_cancel_locked(queue, task, pendp); + tq_unlock(queue, status); + + return (error); +} + + +int +taskqueue_cancel_timeout(struct taskqueue *queue, + struct timeout_task *timeout_task, u_int *pendp) +{ + u_int pending, pending1; + int error; + cpu_status status; + + tq_lock(queue, &status); + pending = !!(callout_stop(&timeout_task->c) > 0); + error = taskqueue_cancel_locked(queue, &timeout_task->t, &pending1); + if ((timeout_task->f & DT_CALLOUT_ARMED) != 0) { + timeout_task->f &= ~DT_CALLOUT_ARMED; + queue->tq_callouts--; + } + tq_unlock(queue, status); + + if (pendp != NULL) + *pendp = pending + pending1; + return (error); +} + + void taskqueue_thread_enqueue(void *context) { @@ -297,7 +431,7 @@ taskqueue_create_fast(const char *name, int mflags, void -task_init(struct task *task, int prio, task_handler_t handler, void *context) +task_init(struct task *task, int prio, task_fn_t handler, void *context) { task->ta_priority = prio; task->ta_handler = handler; @@ -306,6 +440,18 @@ task_init(struct task *task, int prio, task_handler_t handler, void *context) } +void +timeout_task_init(struct taskqueue *queue, struct timeout_task *timeout_task, + int priority, task_fn_t func, void *context) +{ + TASK_INIT(&timeout_task->t, priority, func, context); + callout_init_mtx(&timeout_task->c, &queue->tq_mutex, + CALLOUT_RETURNUNLOCKED); + timeout_task->q = queue; + timeout_task->f = 0; +} + + status_t init_taskqueues() {