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 <sys/method-ids.h>
15
16#undef __unused
17#define __unused
18
19#undef ASSERT
20	/* private/kernel/debug.h sets it */
21
22typedef struct device *device_t;
23typedef struct devclass *devclass_t;
24
25typedef int (*device_method_signature_t)(device_t dev);
26
27typedef int device_probe_t(device_t dev);
28typedef int device_attach_t(device_t dev);
29typedef int device_detach_t(device_t dev);
30typedef int device_resume_t(device_t dev);
31typedef int device_shutdown_t(device_t dev);
32typedef int device_suspend_t(device_t dev);
33
34typedef int bus_child_location_str_t(device_t dev __unused, device_t child,
35	char *buf, size_t buflen);
36typedef int bus_child_pnpinfo_str_t(device_t dev __unused, device_t child,
37	char *buf, size_t buflen);
38typedef void bus_hinted_child_t(device_t dev, const char *name, int unit);
39typedef int bus_print_child_t(device_t dev, device_t child);
40typedef int bus_read_ivar_t(device_t dev, device_t child __unused, int which,
41    uintptr_t *result);
42
43typedef int miibus_readreg_t(device_t dev, int phy, int reg);
44typedef int miibus_writereg_t(device_t dev, int phy, int reg, int data);
45typedef void miibus_statchg_t(device_t dev);
46typedef void miibus_linkchg_t(device_t dev);
47typedef void miibus_mediainit_t(device_t dev);
48
49
50struct device_method {
51	const char* name;
52	const int32 id;
53		/* interfaces w/o function pointer structs use IDs for method lookups */
54	device_method_signature_t method;
55};
56
57typedef struct device_method device_method_t;
58
59#define DEVMETHOD(name, func) { #name, ID_##name, (device_method_signature_t)&func }
60#define DEVMETHOD_END 		  { 0, 0 }
61
62
63typedef struct {
64	const char* name;
65	device_method_t* methods;
66	size_t size; /* softc size */
67} driver_t;
68
69#define DEFINE_CLASS_0(name, driver, methods, size) \
70	driver_t driver = { #name, methods, size }
71
72#define DRIVER_MODULE(name, busname, driver, devclass, evh, arg) \
73	driver_t *DRIVER_MODULE_NAME(name, busname) = &(driver); \
74	devclass_t *__class_ ## name ## _ ## busname ## _ ## devclass = &(devclass)
75
76#define DRIVER_MODULE_ORDERED(name, busname, driver, devclass, evh, arg, order) \
77	DRIVER_MODULE(name, busname, driver, devclass, evh, arg)
78
79#define DRIVER_MODULE_NAME(name, busname) \
80	__fbsd_ ## name ## _ ## busname
81
82
83status_t _fbsd_init_hardware(driver_t* pci_drivers[], driver_t* uhub_drivers[]);
84status_t _fbsd_init_drivers();
85status_t _fbsd_uninit_drivers();
86
87extern const char *gDriverName;
88driver_t *__haiku_select_miibus_driver(device_t dev);
89driver_t *__haiku_probe_miibus(device_t dev, driver_t *drivers[]);
90status_t __haiku_handle_fbsd_drivers_list(status_t (*handler)(driver_t *[], driver_t *[]));
91
92status_t init_wlan_stack(void);
93void uninit_wlan_stack(void);
94status_t start_wlan(device_t);
95status_t stop_wlan(device_t);
96status_t wlan_control(void*, uint32, void*, size_t);
97status_t wlan_close(void*);
98
99/* we define the driver methods with HAIKU_FBSD_DRIVERS_GLUE to
100 * force the rest of the stuff to be linked back with the driver.
101 * While gcc 2.95 packs everything from the static library onto
102 * the final binary, gcc 4.x rightfuly doesn't. */
103
104#define HAIKU_FBSD_DRIVERS_CORE_GLUE(publicname)						\
105	extern const char *gDeviceNameList[];								\
106	extern device_hooks gDeviceHooks;									\
107	const char *gDriverName = #publicname;								\
108	int32 api_version = B_CUR_DRIVER_API_VERSION;						\
109	status_t init_hardware()											\
110	{																	\
111		return __haiku_handle_fbsd_drivers_list(_fbsd_init_hardware);	\
112	}																	\
113	status_t init_driver()												\
114	{																	\
115		return _fbsd_init_drivers();	\
116	}																	\
117	void uninit_driver()												\
118	{																	\
119		_fbsd_uninit_drivers();			\
120	}																	\
121	const char **publish_devices()										\
122		{ return gDeviceNameList; }										\
123	device_hooks *find_device(const char *name)							\
124		{ return &gDeviceHooks; }
125
126#define HAIKU_FBSD_DRIVERS_GLUE(publicname)								\
127	HAIKU_FBSD_DRIVERS_CORE_GLUE(publicname)							\
128	status_t init_wlan_stack(void)										\
129		{ return B_OK; } 												\
130	void uninit_wlan_stack(void) {}										\
131	status_t start_wlan(device_t dev)									\
132		{ return B_OK; }												\
133	status_t stop_wlan(device_t dev)									\
134		{ return B_OK; }												\
135	status_t wlan_control(void *cookie, uint32 op, void *arg, 			\
136		size_t length)													\
137		{ return B_BAD_VALUE; }											\
138	status_t wlan_close(void* cookie)									\
139		{ return B_OK; }
140
141#define HAIKU_FBSD_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 *[], driver_t *[])) {\
144		driver_t *drivers[] = {											\
145			DRIVER_MODULE_NAME(name, busname),							\
146			NULL														\
147		};																\
148		return (*proc)(drivers, NULL);									\
149	}																	\
150	HAIKU_FBSD_DRIVERS_GLUE(publicname);
151
152#define HAIKU_FBSD_WLAN_DRIVERS_GLUE(publicname)						\
153	HAIKU_FBSD_DRIVERS_CORE_GLUE(publicname)
154
155#define HAIKU_FBSD_WLAN_DRIVER_GLUE(publicname, name, busname)			\
156	extern driver_t *DRIVER_MODULE_NAME(name, busname);					\
157	status_t __haiku_handle_fbsd_drivers_list(status_t (*proc)(driver_t *[], driver_t *[])) {\
158		driver_t *drivers[] = {											\
159			DRIVER_MODULE_NAME(name, busname),							\
160			NULL														\
161		};																\
162		return (*proc)(drivers, NULL);									\
163	}																	\
164	HAIKU_FBSD_WLAN_DRIVERS_GLUE(publicname);
165
166#define HAIKU_FBSD_RETURN_MII_DRIVER(drivers)					\
167	driver_t *__haiku_select_miibus_driver(device_t dev)		\
168	{															\
169		return __haiku_probe_miibus(dev, drivers);				\
170	}
171
172#define HAIKU_FBSD_MII_DRIVER(name)								\
173	extern driver_t *DRIVER_MODULE_NAME(name, miibus);			\
174	driver_t *__haiku_select_miibus_driver(device_t dev)		\
175	{															\
176		driver_t *drivers[] = {									\
177			DRIVER_MODULE_NAME(name, miibus),					\
178			NULL												\
179		};														\
180		return __haiku_probe_miibus(dev, drivers);				\
181	}
182
183#define NO_HAIKU_FBSD_MII_DRIVER()								\
184	HAIKU_FBSD_RETURN_MII_DRIVER(NULL)
185
186extern spinlock __haiku_intr_spinlock;
187extern int __haiku_disable_interrupts(device_t dev);
188extern void __haiku_reenable_interrupts(device_t dev);
189
190#define HAIKU_CHECK_DISABLE_INTERRUPTS		__haiku_disable_interrupts
191#define HAIKU_REENABLE_INTERRUPTS			__haiku_reenable_interrupts
192
193#define NO_HAIKU_CHECK_DISABLE_INTERRUPTS()				\
194	int HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev) {	\
195		panic("should never be called.");				\
196		return -1; \
197	}
198
199#define NO_HAIKU_REENABLE_INTERRUPTS() \
200	void HAIKU_REENABLE_INTERRUPTS(device_t dev) {}
201
202extern int __haiku_driver_requirements;
203
204enum {
205	FBSD_FAST_TASKQUEUE		= 1 << 0,
206	FBSD_SWI_TASKQUEUE		= 1 << 1,
207	FBSD_THREAD_TASKQUEUE	= 1 << 2,
208	FBSD_WLAN_FEATURE		= 1 << 3,
209
210	FBSD_WLAN				= FBSD_WLAN_FEATURE | FBSD_THREAD_TASKQUEUE,
211	OBSD_WLAN				= FBSD_WLAN_FEATURE | FBSD_FAST_TASKQUEUE,
212
213	FBSD_TASKQUEUES = FBSD_FAST_TASKQUEUE | FBSD_SWI_TASKQUEUE | FBSD_THREAD_TASKQUEUE,
214};
215
216#define HAIKU_DRIVER_REQUIREMENTS(flags) \
217	int __haiku_driver_requirements = (flags)
218
219#define HAIKU_DRIVER_REQUIRES(flag) (__haiku_driver_requirements & (flag))
220
221
222/* #pragma mark - firmware loading */
223
224
225/*
226 * Only needed to be specified in the glue code of drivers which actually need
227 * to load firmware. See iprowifi2100 for an example.
228 */
229
230extern const uint __haiku_firmware_version;
231
232/* Use 0 if driver doesn't care about firmware version. */
233#define HAIKU_FIRMWARE_VERSION(version) \
234	const uint __haiku_firmware_version = (version)
235
236extern const uint __haiku_firmware_parts_count;
237extern const char* __haiku_firmware_name_map[][2];
238
239/*
240 * Provide a firmware name mapping as a multi-dimentional const char* array.
241 *
242 * HAIKU_FIRMWARE_NAME_MAP({
243 *   {"name-used-by-driver", "actual-name-of-firmware-file-on-disk"},
244 *   ...
245 * });
246 */
247#define HAIKU_FIRMWARE_NAME_MAP(...) \
248	const char* __haiku_firmware_name_map[][2] = __VA_ARGS__; \
249	const uint __haiku_firmware_parts_count = B_COUNT_OF(__haiku_firmware_name_map)
250
251#define NO_HAIKU_FIRMWARE_NAME_MAP() \
252	const uint __haiku_firmware_parts_count = 0; \
253	const char* __haiku_firmware_name_map[0][2] = {}
254
255
256/* #pragma mark - synchronization */
257
258
259#define HAIKU_INTR_REGISTER_STATE \
260	cpu_status __haiku_cpu_state = 0
261
262#define HAIKU_INTR_REGISTER_ENTER() do {		\
263	__haiku_cpu_state = disable_interrupts();	\
264	acquire_spinlock(&__haiku_intr_spinlock);	\
265} while (0)
266
267#define HAIKU_INTR_REGISTER_LEAVE() do {		\
268	release_spinlock(&__haiku_intr_spinlock);	\
269	restore_interrupts(__haiku_cpu_state);		\
270} while (0)
271
272#define HAIKU_PROTECT_INTR_REGISTER(x) do {		\
273	HAIKU_INTR_REGISTER_STATE;					\
274	HAIKU_INTR_REGISTER_ENTER();				\
275	x;											\
276	HAIKU_INTR_REGISTER_LEAVE();				\
277} while (0)
278
279#define nitems(_a)     (sizeof((_a)) / sizeof((_a)[0]))
280
281#endif	/* _FBSD_COMPAT_SYS_HAIKU_MODULE_H_ */
282