freebsd_network: Implement SYSINIT.

Based on the already-existing linkersets framework, which seems to
work pretty well for the atheroswifi driver, so it should work for
this case also.
This commit is contained in:
Augustin Cavalier 2019-01-01 16:39:24 -05:00
parent 8267c19341
commit da60a673b6
5 changed files with 127 additions and 13 deletions

View File

@ -47,6 +47,7 @@ KernelStaticLibrary libfreebsd_network.a :
subr_autoconf.cpp
synch.c
systm.cpp
sysinit.c
taskqueue.c
unit.cpp
;

View File

@ -32,24 +32,45 @@ int32_t get_ticks();
#define usecs_to_ticks(t) (((bigtime_t)t*hz) / 1000000)
typedef void (*system_init_func_t)(void *);
struct __system_init {
system_init_func_t func;
/* sysinit */
enum sysinit_elem_order {
SI_ORDER_FIRST = 0x0000000,
SI_ORDER_SECOND = 0x0000001,
SI_ORDER_THIRD = 0x0000002,
SI_ORDER_FOURTH = 0x0000003,
SI_ORDER_MIDDLE = 0x1000000,
SI_ORDER_ANY = 0xfffffff /* last */
};
/* TODO implement SYSINIT/SYSUNINIT subsystem */
#define SYSINIT(uniquifier, subsystem, order, func, ident) \
struct __system_init __init_##uniquifier = { (system_init_func_t) func }
typedef void (*system_init_func_t)(void *);
#define SYSUNINIT(uniquifier, subsystem, order, func, ident) \
struct __system_init __uninit_##uniquifier = { (system_init_func_t) func }
#define TUNABLE_INT(path, var)
#define TUNABLE_INT_FETCH(path, var)
struct sysinit {
const char* name;
enum sysinit_elem_order order;
system_init_func_t func;
const void* arg;
};
#define SYSINIT(uniquifier, subsystem, _order, _func, ident) \
static struct sysinit sysinit_##uniquifier = { \
.name = #uniquifier, \
.order = _order, \
.func = _func, \
.arg = ident, \
}; \
DATA_SET(__freebsd_sysinit, sysinit_##uniquifier)
#define SYSUNINIT(uniquifier, subsystem, _order, _func, ident) \
static struct sysinit sysuninit_##uniquifier = { \
.name = #uniquifier, \
.order = _order, \
.func = _func, \
.arg = ident, \
}; \
DATA_SET(__freebsd_sysuninit, sysuninit_##uniquifier)
/* confighooks */
typedef void (*ich_func_t)(void *_arg);
struct intr_config_hook {
@ -62,4 +83,9 @@ int config_intrhook_establish(struct intr_config_hook *hook);
void config_intrhook_disestablish(struct intr_config_hook *hook);
/* misc. */
#define TUNABLE_INT(path, var)
#define TUNABLE_INT_FETCH(path, var)
#endif // _FBSD_COMPAT_SYS_KERNEL_H_

View File

@ -13,6 +13,7 @@
#include "device.h"
#include "sysinit.h"
#include <stdlib.h>
#include <sys/sockio.h>
@ -133,6 +134,8 @@ _fbsd_init_drivers(driver_t *drivers[])
goto err5;
}
init_sysinit();
status = init_wlan_stack();
if (status < B_OK)
goto err6;
@ -194,9 +197,11 @@ err7:
uninit_wlan_stack();
err6:
uninit_sysinit();
if (HAIKU_DRIVER_REQUIRES(FBSD_TASKQUEUES))
uninit_taskqueues();
err5:
uninit_bounce_pages();
uninit_callout();
err4:
uninit_mbufs();
@ -224,6 +229,7 @@ _fbsd_uninit_drivers(driver_t *drivers[])
}
uninit_wlan_stack();
uninit_sysinit();
if (HAIKU_DRIVER_REQUIRES(FBSD_TASKQUEUES))
uninit_taskqueues();
uninit_bounce_pages();

View File

@ -0,0 +1,68 @@
/*
* Copyright 2018, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include "sysinit.h"
#include <sys/cdefs.h>
#include <sys/kernel.h>
//#define TRACE_SYSINIT
#ifdef TRACE_SYSINIT
# define TRACE(x...) dprintf(x)
#else
# define TRACE(x...)
#endif
/* linker sets */
SET_DECLARE(__freebsd_sysinit, struct sysinit);
SET_DECLARE(__freebsd_sysuninit, struct sysinit);
/* make sure there's something in both linker sets, so we can link */
SYSINIT(__dummy, 0, 0, NULL, NULL);
SYSUNINIT(__dummy, 0, 0, NULL, NULL);
void
init_sysinit()
{
struct sysinit* const* initee;
const enum sysinit_elem_order orders[6] = {
SI_ORDER_FIRST, SI_ORDER_SECOND, SI_ORDER_THIRD, SI_ORDER_FOURTH,
SI_ORDER_MIDDLE, SI_ORDER_ANY,
};
uint32 i;
for (i = 0; i < 6; i++) {
SET_FOREACH(initee, __freebsd_sysinit) {
if ((*initee)->order != orders[i] || (*initee)->func == NULL)
continue;
TRACE("sysinit: %d, %d, %s\n", orders[i], (*initee)->order,
(*initee)->name);
(*initee)->func((*initee)->arg);
}
}
}
void
uninit_sysinit()
{
struct sysinit* const* initee;
const enum sysinit_elem_order orders[6] = {
SI_ORDER_FIRST, SI_ORDER_SECOND, SI_ORDER_THIRD, SI_ORDER_FOURTH,
SI_ORDER_MIDDLE, SI_ORDER_ANY,
};
uint32 i;
for (i = 5; i >= 0; i--) {
SET_FOREACH(initee, __freebsd_sysuninit) {
if ((*initee)->order != orders[i] || (*initee)->func == NULL)
continue;
TRACE("sysinit: de-initializing %s\n", (*initee)->name);
(*initee)->func((*initee)->arg);
}
}
}

View File

@ -0,0 +1,13 @@
/*
* Copyright 2018, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef SYSINIT_H
#define SYSINIT_H
void init_sysinit();
void uninit_sysinit();
#endif /* SYSINIT_H */