1/*
2 * Copyright 2009, Colin Günther. All Rights Reserved.
3 * Copyright 2007, Hugo Santos. All Rights Reserved.
4 * Distributed under the terms of the MIT License.
5 */
6#ifndef _FBSD_COMPAT_SYS_HAIKU_MODULE_H_
7#define _FBSD_COMPAT_SYS_HAIKU_MODULE_H_
8
9
10#include <Drivers.h>
11#include <KernelExport.h>
12
13#include <kernel/lock.h>
14#include <net_stack.h>
15
16
17#undef ASSERT
18	/* private/kernel/debug.h sets it */
19
20typedef struct device *device_t;
21typedef struct devclass *devclass_t;
22
23typedef int (*device_method_signature_t)(device_t dev);
24
25typedef int device_probe_t(device_t dev);
26typedef int device_attach_t(device_t dev);
27typedef int device_detach_t(device_t dev);
28typedef int device_resume_t(device_t dev);
29typedef int device_suspend_t(device_t dev);
30
31struct device_method {
32	const char *name;
33	device_method_signature_t method;
34};
35
36typedef struct device_method device_method_t;
37
38#define DEVMETHOD(name, func)	{ #name, (device_method_signature_t)&func }
39#define DEVMETHOD_END	{ 0, 0 }
40
41typedef struct {
42	const char *name;
43	device_method_t *methods;
44	size_t softc_size;
45} driver_t;
46
47#define DRIVER_MODULE_NAME(name, busname) \
48	__fbsd_ ## name ## _ ## busname
49
50status_t _fbsd_init_hardware(driver_t *driver[]);
51status_t _fbsd_init_drivers(driver_t *driver[]);
52status_t _fbsd_uninit_drivers(driver_t *driver[]);
53
54extern const char *gDriverName;
55driver_t *__haiku_select_miibus_driver(device_t dev);
56driver_t *__haiku_probe_miibus(device_t dev, driver_t *drivers[]);
57status_t __haiku_handle_fbsd_drivers_list(status_t (*handler)(driver_t *[]));
58
59status_t init_wlan_stack(void);
60void uninit_wlan_stack(void);
61status_t start_wlan(device_t);
62status_t stop_wlan(device_t);
63status_t wlan_control(void*, uint32, void*, size_t);
64status_t wlan_close(void*);
65status_t wlan_if_l2com_alloc(void*);
66
67/* we define the driver methods with HAIKU_FBSD_DRIVERS_GLUE to
68 * force the rest of the stuff to be linked back with the driver.
69 * While gcc 2.95 packs everything from the static library onto
70 * the final binary, gcc 4.x rightfuly doesn't. */
71
72#define HAIKU_FBSD_DRIVERS_GLUE(publicname)								\
73	extern const char *gDeviceNameList[];								\
74	extern device_hooks gDeviceHooks;									\
75	const char *gDriverName = #publicname;								\
76	int32 api_version = B_CUR_DRIVER_API_VERSION;						\
77	status_t init_hardware()											\
78	{																	\
79		return __haiku_handle_fbsd_drivers_list(_fbsd_init_hardware);	\
80	}																	\
81	status_t init_driver()												\
82	{																	\
83		return __haiku_handle_fbsd_drivers_list(_fbsd_init_drivers);	\
84	}																	\
85	void uninit_driver()												\
86	{																	\
87		__haiku_handle_fbsd_drivers_list(_fbsd_uninit_drivers);			\
88	}																	\
89	const char **publish_devices()										\
90		{ return gDeviceNameList; }										\
91	device_hooks *find_device(const char *name)							\
92		{ return &gDeviceHooks; }										\
93	status_t init_wlan_stack(void)										\
94		{ return B_OK; } 												\
95	void uninit_wlan_stack(void) {}										\
96	status_t start_wlan(device_t dev)									\
97		{ return B_OK; }												\
98	status_t stop_wlan(device_t dev)									\
99		{ return B_OK; }												\
100	status_t wlan_control(void *cookie, uint32 op, void *arg, 			\
101		size_t length)													\
102		{ return B_BAD_VALUE; }											\
103	status_t wlan_close(void* cookie)									\
104		{ return B_OK; }												\
105	status_t wlan_if_l2com_alloc(void* ifp)								\
106		{ return B_OK; }
107
108#define HAIKU_FBSD_DRIVER_GLUE(publicname, name, busname)				\
109	extern driver_t *DRIVER_MODULE_NAME(name, busname);					\
110	status_t __haiku_handle_fbsd_drivers_list(status_t (*proc)(driver_t *[])) {\
111		driver_t *drivers[] = {											\
112			DRIVER_MODULE_NAME(name, busname),							\
113			NULL														\
114		};																\
115		return (*proc)(drivers);										\
116	}																	\
117	HAIKU_FBSD_DRIVERS_GLUE(publicname);
118
119#define HAIKU_FBSD_WLAN_DRIVERS_GLUE(publicname)						\
120	extern const char *gDeviceNameList[];								\
121	extern device_hooks gDeviceHooks;									\
122	const char *gDriverName = #publicname;								\
123	int32 api_version = B_CUR_DRIVER_API_VERSION;						\
124	status_t init_hardware()											\
125	{																	\
126		return __haiku_handle_fbsd_drivers_list(_fbsd_init_hardware);	\
127	}																	\
128	status_t init_driver()												\
129	{																	\
130		return __haiku_handle_fbsd_drivers_list(_fbsd_init_drivers);	\
131	}																	\
132	void uninit_driver()												\
133	{																	\
134		__haiku_handle_fbsd_drivers_list(_fbsd_uninit_drivers);			\
135	}																	\
136	const char **publish_devices()										\
137		{ return gDeviceNameList; }										\
138	device_hooks *find_device(const char *name)							\
139		{ return &gDeviceHooks; }
140
141#define HAIKU_FBSD_WLAN_DRIVER_GLUE(publicname, name, busname)			\
142	extern driver_t *DRIVER_MODULE_NAME(name, busname);					\
143	status_t __haiku_handle_fbsd_drivers_list(status_t (*proc)(driver_t *[])) {\
144		driver_t *drivers[] = {											\
145			DRIVER_MODULE_NAME(name, busname),							\
146			NULL														\
147		};																\
148		return (*proc)(drivers);										\
149	}																	\
150	HAIKU_FBSD_WLAN_DRIVERS_GLUE(publicname);
151
152#define HAIKU_FBSD_RETURN_MII_DRIVER(drivers)					\
153	driver_t *__haiku_select_miibus_driver(device_t dev)		\
154	{															\
155		return __haiku_probe_miibus(dev, drivers);				\
156	}
157
158#define HAIKU_FBSD_MII_DRIVER(name)								\
159	extern driver_t *DRIVER_MODULE_NAME(name, miibus);			\
160	driver_t *__haiku_select_miibus_driver(device_t dev)		\
161	{															\
162		driver_t *drivers[] = {									\
163			DRIVER_MODULE_NAME(name, miibus),					\
164			NULL												\
165		};														\
166		return __haiku_probe_miibus(dev, drivers);				\
167	}
168
169#define NO_HAIKU_FBSD_MII_DRIVER()								\
170	HAIKU_FBSD_RETURN_MII_DRIVER(NULL)
171
172extern spinlock __haiku_intr_spinlock;
173extern int __haiku_disable_interrupts(device_t dev);
174extern void __haiku_reenable_interrupts(device_t dev);
175
176#define HAIKU_CHECK_DISABLE_INTERRUPTS		__haiku_disable_interrupts
177#define HAIKU_REENABLE_INTERRUPTS			__haiku_reenable_interrupts
178
179#define NO_HAIKU_CHECK_DISABLE_INTERRUPTS()				\
180	int HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev) {	\
181		panic("should never be called.");				\
182		return -1; \
183	}
184
185#define NO_HAIKU_REENABLE_INTERRUPTS() \
186	void HAIKU_REENABLE_INTERRUPTS(device_t dev) {}
187
188extern int __haiku_driver_requirements;
189
190enum {
191	FBSD_TASKQUEUES		= 1 << 0,
192	FBSD_FAST_TASKQUEUE	= 1 << 1,
193	FBSD_SWI_TASKQUEUE	= 1 << 2,
194	FBSD_WLAN			= 1 << 3,
195};
196
197#define HAIKU_DRIVER_REQUIREMENTS(flags) \
198	int __haiku_driver_requirements = (flags)
199
200#define HAIKU_DRIVER_REQUIRES(flag) (__haiku_driver_requirements & (flag))
201
202
203/* #pragma mark - firmware loading */
204
205
206/*
207 * Only needed to be specified in the glue code of drivers which actually need
208 * to load firmware. See iprowifi2100 for an example.
209 */
210
211extern const uint __haiku_firmware_version;
212
213/* Use 0 if driver doesn't care about firmware version. */
214#define HAIKU_FIRMWARE_VERSION(version) \
215	const uint __haiku_firmware_version = (version)
216
217extern const uint __haiku_firmware_parts_count;
218extern const char* __haiku_firmware_name_map[][2];
219
220#define HAIKU_FIRMWARE_NAME_MAP(firmwarePartsCount) \
221	const uint __haiku_firmware_parts_count = firmwarePartsCount; \
222	const char* __haiku_firmware_name_map[firmwarePartsCount][2]
223
224#define NO_HAIKU_FIRMWARE_NAME_MAP() \
225	const uint __haiku_firmware_parts_count = 0; \
226	const char* __haiku_firmware_name_map[0][2] = {}
227
228
229/* #pragma mark - synchronization */
230
231
232#define HAIKU_INTR_REGISTER_STATE \
233	cpu_status __haiku_cpu_state = 0
234
235#define HAIKU_INTR_REGISTER_ENTER() do {		\
236	__haiku_cpu_state = disable_interrupts();	\
237	acquire_spinlock(&__haiku_intr_spinlock);	\
238} while (0)
239
240#define HAIKU_INTR_REGISTER_LEAVE() do {		\
241	release_spinlock(&__haiku_intr_spinlock);	\
242	restore_interrupts(__haiku_cpu_state);		\
243} while (0)
244
245#define HAIKU_PROTECT_INTR_REGISTER(x) do {		\
246	HAIKU_INTR_REGISTER_STATE;					\
247	HAIKU_INTR_REGISTER_ENTER();				\
248	x;											\
249	HAIKU_INTR_REGISTER_LEAVE();				\
250} while (0)
251
252#define DEFINE_CLASS_0(name, driver, methods, size) \
253	driver_t driver = { #name, methods, size }
254
255#define DRIVER_MODULE(name, busname, driver, devclass, evh, arg) \
256	driver_t *DRIVER_MODULE_NAME(name, busname) = &(driver); \
257	devclass_t *__class_ ## name ## _ ## busname ## _ ## devclass = &(devclass)
258
259#define DRIVER_MODULE_ORDERED(name, busname, driver, devclass, evh, arg, order) \
260	DRIVER_MODULE(name, busname, driver, devclass, evh, arg)
261
262#define nitems(_a)     (sizeof((_a)) / sizeof((_a)[0]))
263
264#endif	/* _FBSD_COMPAT_SYS_HAIKU_MODULE_H_ */
265