ntoskrnl_var.h revision 140827
1139743Simp/*-
2123474Swpaul * Copyright (c) 2003
3123474Swpaul *	Bill Paul <wpaul@windriver.com>.  All rights reserved.
4123474Swpaul *
5123474Swpaul * Redistribution and use in source and binary forms, with or without
6123474Swpaul * modification, are permitted provided that the following conditions
7123474Swpaul * are met:
8123474Swpaul * 1. Redistributions of source code must retain the above copyright
9123474Swpaul *    notice, this list of conditions and the following disclaimer.
10123474Swpaul * 2. Redistributions in binary form must reproduce the above copyright
11123474Swpaul *    notice, this list of conditions and the following disclaimer in the
12123474Swpaul *    documentation and/or other materials provided with the distribution.
13123474Swpaul * 3. All advertising materials mentioning features or use of this software
14123474Swpaul *    must display the following acknowledgement:
15123474Swpaul *	This product includes software developed by Bill Paul.
16123474Swpaul * 4. Neither the name of the author nor the names of any co-contributors
17123474Swpaul *    may be used to endorse or promote products derived from this software
18123474Swpaul *    without specific prior written permission.
19123474Swpaul *
20123474Swpaul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21123474Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22123474Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23123474Swpaul * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24123474Swpaul * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25123474Swpaul * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26123474Swpaul * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27123474Swpaul * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28123474Swpaul * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29123474Swpaul * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30123474Swpaul * THE POSSIBILITY OF SUCH DAMAGE.
31123474Swpaul *
32123474Swpaul * $FreeBSD: head/sys/compat/ndis/ntoskrnl_var.h 140827 2005-01-25 17:00:54Z wpaul $
33123474Swpaul */
34123474Swpaul
35123474Swpaul#ifndef _NTOSKRNL_VAR_H_
36123474Swpaul#define _NTOSKRNL_VAR_H_
37123474Swpaul
38140751Swpaul/*
39140751Swpaul * us_buf is really a wchar_t *, but it's inconvenient to include
40140751Swpaul * all the necessary header goop needed to define it, and it's a
41140751Swpaul * pointer anyway, so for now, just make it a uint16_t *.
42140751Swpaul */
43140751Swpaulstruct unicode_string {
44140751Swpaul	uint16_t		us_len;
45140751Swpaul	uint16_t		us_maxlen;
46140751Swpaul	uint16_t		*us_buf;
47140751Swpaul};
48140751Swpaul
49140751Swpaultypedef struct unicode_string unicode_string;
50140751Swpaul
51140751Swpaul/*
52140751Swpaul * Windows memory descriptor list. In Windows, it's possible for
53140751Swpaul * buffers to be passed between user and kernel contexts without
54140751Swpaul * copying. Buffers may also be allocated in either paged or
55140751Swpaul * non-paged memory regions. An MDL describes the pages of memory
56140751Swpaul * used to contain a particular buffer. Note that a single MDL
57140751Swpaul * may describe a buffer that spans multiple pages. An array of
58140751Swpaul * page addresses appears immediately after the MDL structure itself.
59140751Swpaul * MDLs are therefore implicitly variably sized, even though they
60140751Swpaul * don't look it.
61140751Swpaul *
62140751Swpaul * Note that in FreeBSD, we can take many shortcuts in the way
63140751Swpaul * we handle MDLs because:
64140751Swpaul *
65140751Swpaul * - We are only concerned with pages in kernel context. This means
66140751Swpaul *   we will only ever use the kernel's memory map, and remapping
67140751Swpaul *   of buffers is never needed.
68140751Swpaul *
69140751Swpaul * - Kernel pages can never be paged out, so we don't have to worry
70140751Swpaul *   about whether or not a page is actually mapped before going to
71140751Swpaul *   touch it.
72140751Swpaul */
73140751Swpaul
74140751Swpaulstruct mdl {
75140751Swpaul        struct mdl		*mdl_next;
76140751Swpaul	uint16_t		mdl_size;
77140751Swpaul	uint16_t		mdl_flags;
78140751Swpaul	void			*mdl_process;
79140751Swpaul	void			*mdl_mappedsystemva;
80140751Swpaul	void			*mdl_startva;
81140751Swpaul	uint32_t		mdl_bytecount;
82140751Swpaul	uint32_t		mdl_byteoffset;
83140751Swpaul};
84140751Swpaul
85140751Swpaultypedef struct mdl mdl, ndis_buffer;
86140751Swpaul
87140751Swpaul/* MDL flags */
88140751Swpaul
89140751Swpaul#define MDL_MAPPED_TO_SYSTEM_VA		0x0001
90140751Swpaul#define MDL_PAGES_LOCKED		0x0002
91140751Swpaul#define MDL_SOURCE_IS_NONPAGED_POOL	0x0004
92140751Swpaul#define MDL_ALLOCATED_FIXED_SIZE	0x0008
93140751Swpaul#define MDL_PARTIAL			0x0010
94140751Swpaul#define MDL_PARTIAL_HAS_BEEN_MAPPED	0x0020
95140751Swpaul#define MDL_IO_PAGE_READ		0x0040
96140751Swpaul#define MDL_WRITE_OPERATION		0x0080
97140751Swpaul#define MDL_PARENT_MAPPED_SYSTEM_VA	0x0100
98140751Swpaul#define MDL_FREE_EXTRA_PTES		0x0200
99140751Swpaul#define MDL_IO_SPACE			0x0800
100140751Swpaul#define MDL_NETWORK_HEADER		0x1000
101140751Swpaul#define MDL_MAPPING_CAN_FAIL		0x2000
102140751Swpaul#define MDL_ALLOCATED_MUST_SUCCEED	0x4000
103140751Swpaul
104123512Swpaul/* Note: assumes x86 page size of 4K. */
105140751Swpaul
106140751Swpaul#if PAGE_SIZE == 4096
107123512Swpaul#define PAGE_SHIFT	12
108140751Swpaul#elif PAGE_SIZE == 8192
109140751Swpaul#define PAGE_SHIFT	13
110140751Swpaul#else
111140751Swpaul#error PAGE_SHIFT undefined!
112140751Swpaul#endif
113140751Swpaul
114123512Swpaul#define SPAN_PAGES(ptr, len)					\
115140751Swpaul	((uint32_t)((((uintptr_t)(ptr) & (PAGE_SIZE - 1)) +	\
116123512Swpaul	(len) + (PAGE_SIZE - 1)) >> PAGE_SHIFT))
117140751Swpaul
118123757Swpaul#define PAGE_ALIGN(ptr)						\
119123757Swpaul	((void *)((uintptr_t)(ptr) & ~(PAGE_SIZE - 1)))
120140751Swpaul
121123757Swpaul#define BYTE_OFFSET(ptr)					\
122123757Swpaul	((uint32_t)((uintptr_t)(ptr) & (PAGE_SIZE - 1)))
123140751Swpaul
124140751Swpaul#define MDL_PAGES(m)	(vm_offset_t *)(m + 1)
125140751Swpaul
126140751Swpaul#define MmInitializeMdl(b, baseva, len)					\
127140751Swpaul	(b)->mdl_next = NULL;						\
128140751Swpaul	(b)->mdl_size = (uint16_t)(sizeof(mdl) +			\
129123757Swpaul		(sizeof(uint32_t) * SPAN_PAGES((baseva), (len))));	\
130140751Swpaul	(b)->mdl_flags = 0;						\
131140751Swpaul	(b)->mdl_startva = (void *)PAGE_ALIGN((baseva));		\
132140751Swpaul	(b)->mdl_byteoffset = BYTE_OFFSET((baseva));			\
133140751Swpaul	(b)->mdl_bytecount = (uint32_t)(len);
134123512Swpaul
135140751Swpaul#define MmGetMdlByteOffset(mdl)		((mdl)->mdl_byteoffset)
136140751Swpaul#define MmGetMdlByteCount(mdl)		((mdl)->mdl_bytecount)
137140751Swpaul#define MmGetMdlVirtualAddress(mdl)					\
138140751Swpaul	((void *)((char *)((mdl)->mdl_startva) + (mdl)->mdl_byteoffset))
139140751Swpaul#define MmGetMdlStartVa(mdl)		((mdl)->mdl_startva)
140140751Swpaul#define MmGetMdlPfnArray(mdl)		MDL_PAGES(mdl)
141140751Swpaul
142124729Swpaul#define WDM_MAJOR		1
143124729Swpaul#define WDM_MINOR_WIN98		0x00
144124729Swpaul#define WDM_MINOR_WINME		0x05
145124729Swpaul#define WDM_MINOR_WIN2000	0x10
146124729Swpaul#define WDM_MINOR_WINXP		0x20
147124729Swpaul#define WDM_MINOR_WIN2003	0x30
148124729Swpaul
149124582Sobrien/*-
150124582Sobrien * The ndis_kspin_lock type is called KSPIN_LOCK in MS-Windows.
151124582Sobrien * According to the Windows DDK header files, KSPIN_LOCK is defined like this:
152124582Sobrien *	typedef ULONG_PTR KSPIN_LOCK;
153124582Sobrien *
154124582Sobrien * From basetsd.h (SDK, Feb. 2003):
155124582Sobrien * 	typedef [public] unsigned __int3264 ULONG_PTR, *PULONG_PTR;
156124582Sobrien * 	typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
157124582Sobrien * 	typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR;
158124582Sobrien *
159124582Sobrien * The keyword __int3264 specifies an integral type that has the following
160124582Sobrien * properties:
161124582Sobrien *	+ It is 32-bit on 32-bit platforms
162124582Sobrien *	+ It is 64-bit on 64-bit platforms
163124582Sobrien *	+ It is 32-bit on the wire for backward compatibility.
164124582Sobrien *	  It gets truncated on the sending side and extended appropriately
165124582Sobrien *	  (signed or unsigned) on the receiving side.
166124582Sobrien *
167124582Sobrien * Thus register_t seems the proper mapping onto FreeBSD for spin locks.
168124582Sobrien */
169123474Swpaul
170124582Sobrientypedef register_t kspin_lock;
171124582Sobrien
172123474Swpaulstruct slist_entry {
173123474Swpaul	struct slist_entry	*sl_next;
174123474Swpaul};
175123474Swpaul
176123474Swpaultypedef struct slist_entry slist_entry;
177123474Swpaul
178123474Swpaulunion slist_header {
179123474Swpaul	uint64_t		slh_align;
180123474Swpaul	struct {
181123474Swpaul		struct slist_entry	*slh_next;
182123474Swpaul		uint16_t		slh_depth;
183123474Swpaul		uint16_t		slh_seq;
184123474Swpaul	} slh_list;
185123474Swpaul};
186123474Swpaul
187123474Swpaultypedef union slist_header slist_header;
188123474Swpaul
189123507Swpaulstruct list_entry {
190123507Swpaul        struct list_entry *nle_flink;
191123507Swpaul        struct list_entry *nle_blink;
192123507Swpaul};
193123507Swpaul
194123507Swpaultypedef struct list_entry list_entry;
195123507Swpaul
196125551Swpaul#define INIT_LIST_HEAD(l)	\
197125551Swpaul	l->nle_flink = l->nle_blink = l
198125551Swpaul
199125551Swpaul#define REMOVE_LIST_ENTRY(e)			\
200125551Swpaul	do {					\
201125551Swpaul		list_entry		*b;	\
202125551Swpaul		list_entry		*f;	\
203125551Swpaul						\
204125551Swpaul		f = e->nle_flink;		\
205125551Swpaul		b = e->nle_blink;		\
206125551Swpaul		b->nle_flink = f;		\
207125551Swpaul		f->nle_blink = b;		\
208125551Swpaul	} while (0)
209125551Swpaul
210125551Swpaul#define REMOVE_LIST_HEAD(l)			\
211125551Swpaul	do {					\
212125551Swpaul		list_entry		*f;	\
213125551Swpaul		list_entry		*e;	\
214125551Swpaul						\
215125551Swpaul		e = l->nle_flink;		\
216125551Swpaul		f = e->nle_flink;		\
217125551Swpaul		l->nle_flink = f;		\
218125551Swpaul		f->nle_blink = l;		\
219125551Swpaul	} while (0)
220125551Swpaul
221125551Swpaul#define REMOVE_LIST_TAIL(l)			\
222125551Swpaul	do {					\
223125551Swpaul		list_entry		*b;	\
224125551Swpaul		list_entry		*e;	\
225125551Swpaul						\
226125551Swpaul		e = l->nle_blink;		\
227125551Swpaul		b = e->nle_blink;		\
228125551Swpaul		l->nle_blink = b;		\
229125551Swpaul		b->nle_flink = l;		\
230125551Swpaul	} while (0)
231125551Swpaul
232125551Swpaul#define INSERT_LIST_TAIL(l, e)			\
233125551Swpaul	do {					\
234125551Swpaul		list_entry		*b;	\
235125551Swpaul						\
236125551Swpaul		b = l->nle_blink;		\
237125860Swpaul		e->nle_flink = l;		\
238125551Swpaul		e->nle_blink = b;		\
239125551Swpaul		b->nle_flink = e;		\
240125551Swpaul		l->nle_blink = e;		\
241125551Swpaul	} while (0)
242125551Swpaul
243125551Swpaul#define INSERT_LIST_HEAD(l, e)			\
244125551Swpaul	do {					\
245125551Swpaul		list_entry		*f;	\
246125551Swpaul						\
247125551Swpaul		f = l->nle_flink;		\
248125551Swpaul		e->nle_flink = f;		\
249125551Swpaul		e->nle_blink = l;		\
250125551Swpaul		f->nle_blink = e;		\
251125551Swpaul		l->nle_flink = e;		\
252125551Swpaul	} while (0)
253125551Swpaul
254125551Swpaulstruct nt_dispatch_header {
255125551Swpaul	uint8_t			dh_type;
256125551Swpaul	uint8_t			dh_abs;
257125551Swpaul	uint8_t			dh_size;
258125551Swpaul	uint8_t			dh_inserted;
259125551Swpaul	uint32_t		dh_sigstate;
260125551Swpaul	list_entry		dh_waitlisthead;
261125551Swpaul};
262125551Swpaul
263125551Swpaultypedef struct nt_dispatch_header nt_dispatch_header;
264125551Swpaul
265125551Swpaul#define OTYPE_EVENT		0
266125551Swpaul#define OTYPE_MUTEX		1
267125551Swpaul#define OTYPE_THREAD		2
268125551Swpaul#define OTYPE_TIMER		3
269125551Swpaul
270125551Swpaul/* Windows dispatcher levels. */
271125551Swpaul
272125551Swpaul#define PASSIVE_LEVEL		0
273125551Swpaul#define LOW_LEVEL		0
274125551Swpaul#define APC_LEVEL		1
275125551Swpaul#define DISPATCH_LEVEL		2
276128229Swpaul#define DEVICE_LEVEL		(DISPATCH_LEVEL + 1)
277125551Swpaul#define PROFILE_LEVEL		27
278125551Swpaul#define CLOCK1_LEVEL		28
279125551Swpaul#define CLOCK2_LEVEL		28
280125551Swpaul#define IPI_LEVEL		29
281125551Swpaul#define POWER_LEVEL		30
282125551Swpaul#define HIGH_LEVEL		31
283125551Swpaul
284125551Swpaul#define SYNC_LEVEL_UP		DISPATCH_LEVEL
285125551Swpaul#define SYNC_LEVEL_MP		(IPI_LEVEL - 1)
286125551Swpaul
287128229Swpaul#define AT_PASSIVE_LEVEL(td)		\
288128229Swpaul	((td)->td_proc->p_flag & P_KTHREAD == FALSE)
289128229Swpaul
290128229Swpaul#define AT_DISPATCH_LEVEL(td)		\
291128449Swpaul	((td)->td_base_pri == PI_REALTIME)
292128229Swpaul
293128229Swpaul#define AT_DIRQL_LEVEL(td)		\
294128295Swpaul	((td)->td_priority <= PI_NET)
295128229Swpaul
296128229Swpaul#define AT_HIGH_LEVEL(td)		\
297128229Swpaul	((td)->td_critnest != 0)
298128229Swpaul
299125551Swpaulstruct nt_objref {
300125551Swpaul	nt_dispatch_header	no_dh;
301125551Swpaul	void			*no_obj;
302125551Swpaul	TAILQ_ENTRY(nt_objref)	link;
303125551Swpaul};
304125551Swpaul
305125551SwpaulTAILQ_HEAD(nt_objref_head, nt_objref);
306125551Swpaul
307125551Swpaultypedef struct nt_objref nt_objref;
308125551Swpaul
309125551Swpaul#define EVENT_TYPE_NOTIFY	0
310125551Swpaul#define EVENT_TYPE_SYNC		1
311125551Swpaul
312126620Swpaul/*
313126620Swpaul * We need to use the timeout()/untimeout() API for ktimers
314126620Swpaul * since timers can be initialized, but not destroyed (so
315126620Swpaul * malloc()ing our own callout structures would mean a leak,
316126620Swpaul * since there'd be no way to free() them). This means we
317126620Swpaul * need to use struct callout_handle, which is really just a
318126620Swpaul * pointer. To make it easier to deal with, we use a union
319126620Swpaul * to overlay the callout_handle over the k_timerlistentry.
320126620Swpaul * The latter is a list_entry, which is two pointers, so
321126620Swpaul * there's enough space available to hide a callout_handle
322126620Swpaul * there.
323126620Swpaul */
324126620Swpaul
325125551Swpaulstruct ktimer {
326125551Swpaul	nt_dispatch_header	k_header;
327125551Swpaul	uint64_t		k_duetime;
328126620Swpaul	union {
329126620Swpaul		list_entry		k_timerlistentry;
330126620Swpaul		struct callout_handle	k_handle;
331126620Swpaul	} u;
332125551Swpaul	void			*k_dpc;
333125551Swpaul	uint32_t		k_period;
334125551Swpaul};
335125551Swpaul
336126620Swpaul#define k_timerlistentry	u.k_timerlistentry
337126620Swpaul#define k_handle		u.k_handle
338126620Swpaul
339126620Swpaultypedef struct ktimer ktimer;
340126620Swpaul
341125551Swpaulstruct nt_kevent {
342125551Swpaul	nt_dispatch_header	k_header;
343125551Swpaul};
344125551Swpaul
345125551Swpaultypedef struct nt_kevent nt_kevent;
346125551Swpaul
347125551Swpaul/* Kernel defered procedure call (i.e. timer callback) */
348125551Swpaul
349125551Swpaulstruct kdpc;
350125551Swpaultypedef void (*kdpc_func)(struct kdpc *, void *, void *, void *);
351125551Swpaul
352125551Swpaulstruct kdpc {
353125551Swpaul	uint16_t		k_type;
354125551Swpaul	uint8_t			k_num;
355125551Swpaul	uint8_t			k_importance;
356125551Swpaul	list_entry		k_dpclistentry;
357140827Swpaul	void			*k_deferedfunc;
358125551Swpaul	void			*k_deferredctx;
359125551Swpaul	void			*k_sysarg1;
360125551Swpaul	void			*k_sysarg2;
361127552Swpaul	register_t		k_lock;
362125551Swpaul};
363125551Swpaul
364126620Swpaultypedef struct kdpc kdpc;
365126620Swpaul
366125551Swpaul/*
367125551Swpaul * Note: the acquisition count is BSD-specific. The Microsoft
368125551Swpaul * documentation says that mutexes can be acquired recursively
369125551Swpaul * by a given thread, but that you must release the mutex as
370125551Swpaul * many times as you acquired it before it will be set to the
371125551Swpaul * signalled state (i.e. before any other threads waiting on
372125551Swpaul * the object will be woken up). However the Windows KMUTANT
373125551Swpaul * structure has no field for keeping track of the number of
374125551Swpaul * acquisitions, so we need to add one ourselves. As long as
375125551Swpaul * driver code treats the mutex as opaque, we should be ok.
376125551Swpaul */
377125551Swpaulstruct kmutant {
378125551Swpaul	nt_dispatch_header	km_header;
379126620Swpaul	union {
380126620Swpaul		list_entry		km_listentry;
381126620Swpaul		uint32_t		km_acquirecnt;
382126620Swpaul	} u;
383125551Swpaul	void			*km_ownerthread;
384125551Swpaul	uint8_t			km_abandoned;
385125551Swpaul	uint8_t			km_apcdisable;
386125551Swpaul};
387125551Swpaul
388126620Swpaul#define km_listentry		u.km_listentry
389126620Swpaul#define km_acquirecnt		u.km_acquirecnt
390126620Swpaul
391125551Swpaultypedef struct kmutant kmutant;
392125551Swpaul
393125860Swpaul#define LOOKASIDE_DEPTH 256
394125860Swpaul
395123474Swpaulstruct general_lookaside {
396123474Swpaul	slist_header		gl_listhead;
397123474Swpaul	uint16_t		gl_depth;
398123474Swpaul	uint16_t		gl_maxdepth;
399123474Swpaul	uint32_t		gl_totallocs;
400123474Swpaul	union {
401123474Swpaul		uint32_t		gl_allocmisses;
402123474Swpaul		uint32_t		gl_allochits;
403123474Swpaul	} u_a;
404123474Swpaul	uint32_t		gl_totalfrees;
405123474Swpaul	union {
406123474Swpaul		uint32_t		gl_freemisses;
407123474Swpaul		uint32_t		gl_freehits;
408123474Swpaul	} u_m;
409123474Swpaul	uint32_t		gl_type;
410123474Swpaul	uint32_t		gl_tag;
411123474Swpaul	uint32_t		gl_size;
412123474Swpaul	void			*gl_allocfunc;
413123474Swpaul	void			*gl_freefunc;
414123507Swpaul	list_entry		gl_listent;
415123474Swpaul	uint32_t		gl_lasttotallocs;
416123474Swpaul	union {
417123474Swpaul		uint32_t		gl_lastallocmisses;
418123474Swpaul		uint32_t		gl_lastallochits;
419123474Swpaul	} u_l;
420123474Swpaul	uint32_t		gl_rsvd[2];
421123474Swpaul};
422123474Swpaul
423123474Swpaultypedef struct general_lookaside general_lookaside;
424123474Swpaul
425123474Swpaulstruct npaged_lookaside_list {
426123474Swpaul	general_lookaside	nll_l;
427123474Swpaul	kspin_lock		nll_obsoletelock;
428123474Swpaul};
429123474Swpaul
430123474Swpaultypedef struct npaged_lookaside_list npaged_lookaside_list;
431123474Swpaultypedef struct npaged_lookaside_list paged_lookaside_list;
432123474Swpaul
433123474Swpaultypedef void * (*lookaside_alloc_func)(uint32_t, size_t, uint32_t);
434123474Swpaultypedef void (*lookaside_free_func)(void *);
435123474Swpaul
436125551Swpaulstruct irp;
437123474Swpaul
438125551Swpaulstruct kdevice_qentry {
439125551Swpaul	list_entry		kqe_devlistent;
440125551Swpaul	uint32_t		kqe_sortkey;
441125551Swpaul	uint8_t			kqe_inserted;
442125551Swpaul};
443125551Swpaul
444125551Swpaultypedef struct kdevice_qentry kdevice_qentry;
445125551Swpaul
446125551Swpaulstruct kdevice_queue {
447125551Swpaul	uint16_t		kq_type;
448125551Swpaul	uint16_t		kq_size;
449125551Swpaul	list_entry		kq_devlisthead;
450125551Swpaul	kspin_lock		kq_lock;
451125551Swpaul	uint8_t			kq_busy;
452125551Swpaul};
453125551Swpaul
454125551Swpaultypedef struct kdevice_queue kdevice_queue;
455125551Swpaul
456125551Swpaulstruct wait_ctx_block {
457125551Swpaul	kdevice_qentry		wcb_waitqueue;
458125551Swpaul	void			*wcb_devfunc;
459125551Swpaul	void			*wcb_devctx;
460125551Swpaul	uint32_t		wcb_mapregcnt;
461125551Swpaul	void			*wcb_devobj;
462125551Swpaul	void			*wcb_curirp;
463125551Swpaul	void			*wcb_bufchaindpc;
464125551Swpaul};
465125551Swpaul
466125551Swpaultypedef struct wait_ctx_block wait_ctx_block;
467125551Swpaul
468125551Swpaulstruct wait_block {
469125551Swpaul	list_entry		wb_waitlist;
470125551Swpaul	void			*wb_kthread;
471125551Swpaul	nt_dispatch_header	*wb_object;
472125551Swpaul	struct wait_block	*wb_next;
473125551Swpaul	uint16_t		wb_waitkey;
474125551Swpaul	uint16_t		wb_waittype;
475125551Swpaul};
476125551Swpaul
477125551Swpaultypedef struct wait_block wait_block;
478125551Swpaul
479125551Swpaul#define THREAD_WAIT_OBJECTS	3
480125551Swpaul#define MAX_WAIT_OBJECTS	64
481125551Swpaul
482125551Swpaul#define WAITTYPE_ALL		0
483125551Swpaul#define WAITTYPE_ANY		1
484125551Swpaul
485125551Swpaulstruct thread_context {
486125551Swpaul	void			*tc_thrctx;
487125551Swpaul	void			*tc_thrfunc;
488125551Swpaul};
489125551Swpaul
490125551Swpaultypedef struct thread_context thread_context;
491125551Swpaul
492140751Swpaul/* Forward declaration */
493140751Swpaulstruct driver_object;
494140751Swpaulstruct devobj_extension;
495140751Swpaul
496140751Swpaulstruct driver_extension {
497140751Swpaul	struct driver_object	*dre_driverobj;
498140751Swpaul	void			*dre_adddevicefunc;
499140751Swpaul	uint32_t		dre_reinitcnt;
500140751Swpaul	unicode_string		dre_srvname;
501140751Swpaul};
502140751Swpaul
503140751Swpaultypedef struct driver_extension driver_extension;
504140751Swpaul
505140751Swpaul/*
506140751Swpaul * In Windows, there are Physical Device Objects (PDOs) and
507140751Swpaul * Functional Device Objects (FDOs). Physical Device Objects are
508140751Swpaul * created and maintained by bus drivers. For example, the PCI
509140751Swpaul * bus driver might detect two PCI ethernet cards on a given
510140751Swpaul * bus. The PCI bus driver will then allocate two device_objects
511140751Swpaul * for its own internal bookeeping purposes. This is analagous
512140751Swpaul * to the device_t that the FreeBSD PCI code allocates and passes
513140751Swpaul * into each PCI driver's probe and attach routines.
514140751Swpaul *
515140751Swpaul * When an ethernet driver claims one of the ethernet cards
516140751Swpaul * on the bus, it will create its own device_object. This is
517140751Swpaul * the Functional Device Object. This object is analagous to the
518140751Swpaul * device-specific softc structure.
519140751Swpaul */
520140751Swpaul
521125551Swpaulstruct device_object {
522125551Swpaul	uint16_t		do_type;
523125551Swpaul	uint16_t		do_size;
524125551Swpaul	uint32_t		do_refcnt;
525125551Swpaul	struct device_object	*do_drvobj;
526125551Swpaul	struct device_object	*do_nextdev;
527125551Swpaul	struct device_object	*do_attacheddev;
528125551Swpaul	struct irp		*do_currirp;
529125551Swpaul	void			*do_iotimer;
530125551Swpaul	uint32_t		do_flags;
531125551Swpaul	uint32_t		do_characteristics;
532125551Swpaul	void			*do_vpb;
533125551Swpaul	void			*do_devext;
534125551Swpaul	uint8_t			do_stacksize;
535125551Swpaul	union {
536125551Swpaul		list_entry		do_listent;
537125551Swpaul		wait_ctx_block		do_wcb;
538125551Swpaul	} queue;
539125551Swpaul	uint32_t		do_alignreq;
540125551Swpaul	kdevice_queue		do_devqueue;
541125551Swpaul	struct kdpc		do_dpc;
542125551Swpaul	uint32_t		do_activethreads;
543125551Swpaul	void			*do_securitydesc;
544125551Swpaul	struct nt_kevent	do_devlock;
545125551Swpaul	uint16_t		do_sectorsz;
546125551Swpaul	uint16_t		do_spare1;
547140751Swpaul	struct devobj_extension	*do_devobj_ext;
548125551Swpaul	void			*do_rsvd;
549125551Swpaul};
550125551Swpaul
551125551Swpaultypedef struct device_object device_object;
552125551Swpaul
553140751Swpaulstruct devobj_extension {
554140751Swpaul	uint16_t		dve_type;
555140751Swpaul	uint16_t		dve_size;
556140751Swpaul	device_object		*dve_devobj;
557140751Swpaul};
558140751Swpaul
559140751Swpaultypedef struct devobj_extension devobj_extension;
560140751Swpaul
561140751Swpaul#define IO_NO_INCREMENT			0
562140751Swpaul#define IO_CD_ROM_INCREMENT		1
563140751Swpaul#define IO_DISK_INCREMENT		1
564140751Swpaul#define IO_KEYBOARD_INCREMENT		6
565140751Swpaul#define IO_MAILSLOT_INCREMENT		2
566140751Swpaul#define IO_MOUSE_INCREMENT		6
567140751Swpaul#define IO_NAMED_PIPE_INCREMENT		2
568140751Swpaul#define IO_NETWORK_INCREMENT		2
569140751Swpaul#define IO_PARALLEL_INCREMENT		1
570140751Swpaul#define IO_SERIAL_INCREMENT		2
571140751Swpaul#define IO_SOUND_INCREMENT		8
572140751Swpaul#define IO_VIDEO_INCREMENT		1
573140751Swpaul
574140751Swpaul/* IRP major codes */
575140751Swpaul
576140751Swpaul#define IRP_MJ_CREATE                   0x00
577140751Swpaul#define IRP_MJ_CREATE_NAMED_PIPE        0x01
578140751Swpaul#define IRP_MJ_CLOSE                    0x02
579140751Swpaul#define IRP_MJ_READ                     0x03
580140751Swpaul#define IRP_MJ_WRITE                    0x04
581140751Swpaul#define IRP_MJ_QUERY_INFORMATION        0x05
582140751Swpaul#define IRP_MJ_SET_INFORMATION          0x06
583140751Swpaul#define IRP_MJ_QUERY_EA                 0x07
584140751Swpaul#define IRP_MJ_SET_EA                   0x08
585140751Swpaul#define IRP_MJ_FLUSH_BUFFERS            0x09
586140751Swpaul#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a
587140751Swpaul#define IRP_MJ_SET_VOLUME_INFORMATION   0x0b
588140751Swpaul#define IRP_MJ_DIRECTORY_CONTROL        0x0c
589140751Swpaul#define IRP_MJ_FILE_SYSTEM_CONTROL      0x0d
590140751Swpaul#define IRP_MJ_DEVICE_CONTROL           0x0e
591140751Swpaul#define IRP_MJ_INTERNAL_DEVICE_CONTROL  0x0f
592140751Swpaul#define IRP_MJ_SHUTDOWN                 0x10
593140751Swpaul#define IRP_MJ_LOCK_CONTROL             0x11
594140751Swpaul#define IRP_MJ_CLEANUP                  0x12
595140751Swpaul#define IRP_MJ_CREATE_MAILSLOT          0x13
596140751Swpaul#define IRP_MJ_QUERY_SECURITY           0x14
597140751Swpaul#define IRP_MJ_SET_SECURITY             0x15
598140751Swpaul#define IRP_MJ_POWER                    0x16
599140751Swpaul#define IRP_MJ_SYSTEM_CONTROL           0x17
600140751Swpaul#define IRP_MJ_DEVICE_CHANGE            0x18
601140751Swpaul#define IRP_MJ_QUERY_QUOTA              0x19
602140751Swpaul#define IRP_MJ_SET_QUOTA                0x1a
603140751Swpaul#define IRP_MJ_PNP                      0x1b
604140751Swpaul#define IRP_MJ_PNP_POWER                IRP_MJ_PNP      // Obsolete....
605140751Swpaul#define IRP_MJ_MAXIMUM_FUNCTION         0x1b
606140751Swpaul#define IRP_MJ_SCSI                     IRP_MJ_INTERNAL_DEVICE_CONTROL
607140751Swpaul
608140751Swpaul/* IRP minor codes */
609140751Swpaul
610140751Swpaul#define IRP_MN_QUERY_DIRECTORY          0x01
611140751Swpaul#define IRP_MN_NOTIFY_CHANGE_DIRECTORY  0x02
612140751Swpaul#define IRP_MN_USER_FS_REQUEST          0x00
613140751Swpaul
614140751Swpaul#define IRP_MN_MOUNT_VOLUME             0x01
615140751Swpaul#define IRP_MN_VERIFY_VOLUME            0x02
616140751Swpaul#define IRP_MN_LOAD_FILE_SYSTEM         0x03
617140751Swpaul#define IRP_MN_TRACK_LINK               0x04    // To be obsoleted soon
618140751Swpaul#define IRP_MN_KERNEL_CALL              0x04
619140751Swpaul
620140751Swpaul#define IRP_MN_LOCK                     0x01
621140751Swpaul#define IRP_MN_UNLOCK_SINGLE            0x02
622140751Swpaul#define IRP_MN_UNLOCK_ALL               0x03
623140751Swpaul#define IRP_MN_UNLOCK_ALL_BY_KEY        0x04
624140751Swpaul
625140751Swpaul#define IRP_MN_NORMAL                   0x00
626140751Swpaul#define IRP_MN_DPC                      0x01
627140751Swpaul#define IRP_MN_MDL                      0x02
628140751Swpaul#define IRP_MN_COMPLETE                 0x04
629140751Swpaul#define IRP_MN_COMPRESSED               0x08
630140751Swpaul
631140751Swpaul#define IRP_MN_MDL_DPC                  (IRP_MN_MDL | IRP_MN_DPC)
632140751Swpaul#define IRP_MN_COMPLETE_MDL             (IRP_MN_COMPLETE | IRP_MN_MDL)
633140751Swpaul#define IRP_MN_COMPLETE_MDL_DPC         (IRP_MN_COMPLETE_MDL | IRP_MN_DPC)
634140751Swpaul
635140751Swpaul#define IRP_MN_SCSI_CLASS               0x01
636140751Swpaul
637140751Swpaul#define IRP_MN_START_DEVICE                 0x00
638140751Swpaul#define IRP_MN_QUERY_REMOVE_DEVICE          0x01
639140751Swpaul#define IRP_MN_REMOVE_DEVICE                0x02
640140751Swpaul#define IRP_MN_CANCEL_REMOVE_DEVICE         0x03
641140751Swpaul#define IRP_MN_STOP_DEVICE                  0x04
642140751Swpaul#define IRP_MN_QUERY_STOP_DEVICE            0x05
643140751Swpaul#define IRP_MN_CANCEL_STOP_DEVICE           0x06
644140751Swpaul
645140751Swpaul#define IRP_MN_QUERY_DEVICE_RELATIONS       0x07
646140751Swpaul#define IRP_MN_QUERY_INTERFACE              0x08
647140751Swpaul#define IRP_MN_QUERY_CAPABILITIES           0x09
648140751Swpaul#define IRP_MN_QUERY_RESOURCES              0x0A
649140751Swpaul#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS  0x0B
650140751Swpaul#define IRP_MN_QUERY_DEVICE_TEXT            0x0C
651140751Swpaul#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS 0x0D
652140751Swpaul
653140751Swpaul#define IRP_MN_READ_CONFIG                  0x0F
654140751Swpaul#define IRP_MN_WRITE_CONFIG                 0x10
655140751Swpaul#define IRP_MN_EJECT                        0x11
656140751Swpaul#define IRP_MN_SET_LOCK                     0x12
657140751Swpaul#define IRP_MN_QUERY_ID                     0x13
658140751Swpaul#define IRP_MN_QUERY_PNP_DEVICE_STATE       0x14
659140751Swpaul#define IRP_MN_QUERY_BUS_INFORMATION        0x15
660140751Swpaul#define IRP_MN_DEVICE_USAGE_NOTIFICATION    0x16
661140751Swpaul#define IRP_MN_SURPRISE_REMOVAL             0x17
662140751Swpaul#define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18
663140751Swpaul
664140751Swpaul#define IRP_MN_WAIT_WAKE                    0x00
665140751Swpaul#define IRP_MN_POWER_SEQUENCE               0x01
666140751Swpaul#define IRP_MN_SET_POWER                    0x02
667140751Swpaul#define IRP_MN_QUERY_POWER                  0x03
668140751Swpaul
669140751Swpaul#define IRP_MN_QUERY_ALL_DATA               0x00
670140751Swpaul#define IRP_MN_QUERY_SINGLE_INSTANCE        0x01
671140751Swpaul#define IRP_MN_CHANGE_SINGLE_INSTANCE       0x02
672140751Swpaul#define IRP_MN_CHANGE_SINGLE_ITEM           0x03
673140751Swpaul#define IRP_MN_ENABLE_EVENTS                0x04
674140751Swpaul#define IRP_MN_DISABLE_EVENTS               0x05
675140751Swpaul#define IRP_MN_ENABLE_COLLECTION            0x06
676140751Swpaul#define IRP_MN_DISABLE_COLLECTION           0x07
677140751Swpaul#define IRP_MN_REGINFO                      0x08
678140751Swpaul#define IRP_MN_EXECUTE_METHOD               0x09
679140751Swpaul#define IRP_MN_REGINFO_EX                   0x0b
680140751Swpaul
681140751Swpaul/* IRP flags */
682140751Swpaul
683140751Swpaul#define IRP_NOCACHE                     0x00000001
684140751Swpaul#define IRP_PAGING_IO                   0x00000002
685140751Swpaul#define IRP_MOUNT_COMPLETION            0x00000002
686140751Swpaul#define IRP_SYNCHRONOUS_API             0x00000004
687140751Swpaul#define IRP_ASSOCIATED_IRP              0x00000008
688140751Swpaul#define IRP_BUFFERED_IO                 0x00000010
689140751Swpaul#define IRP_DEALLOCATE_BUFFER           0x00000020
690140751Swpaul#define IRP_INPUT_OPERATION             0x00000040
691140751Swpaul#define IRP_SYNCHRONOUS_PAGING_IO       0x00000040
692140751Swpaul#define IRP_CREATE_OPERATION            0x00000080
693140751Swpaul#define IRP_READ_OPERATION              0x00000100
694140751Swpaul#define IRP_WRITE_OPERATION             0x00000200
695140751Swpaul#define IRP_CLOSE_OPERATION             0x00000400
696140751Swpaul#define IRP_DEFER_IO_COMPLETION         0x00000800
697140751Swpaul#define IRP_OB_QUERY_NAME               0x00001000
698140751Swpaul#define IRP_HOLD_DEVICE_QUEUE           0x00002000
699140751Swpaul#define IRP_RETRY_IO_COMPLETION         0x00004000
700140751Swpaul#define IRP_CLASS_CACHE_OPERATION       0x00008000
701140751Swpaul#define IRP_SET_USER_EVENT              IRP_CLOSE_OPERATION
702140751Swpaul
703140751Swpaul/* IRP I/O control flags */
704140751Swpaul
705140751Swpaul#define IRP_QUOTA_CHARGED               0x01
706140751Swpaul#define IRP_ALLOCATED_MUST_SUCCEED      0x02
707140751Swpaul#define IRP_ALLOCATED_FIXED_SIZE        0x04
708140751Swpaul#define IRP_LOOKASIDE_ALLOCATION        0x08
709140751Swpaul
710140751Swpaulstruct io_status_block {
711140751Swpaul	union {
712140751Swpaul		uint32_t		isb_status;
713140751Swpaul		void			*isb_ptr;
714140751Swpaul	} u;
715140751Swpaul	register_t		isb_info;
716140751Swpaul};
717140751Swpaul
718140751Swpaultypedef struct io_status_block io_status_block;
719140751Swpaul
720140751Swpaulstruct kapc {
721140751Swpaul	uint16_t		apc_type;
722140751Swpaul	uint16_t		apc_size;
723140751Swpaul	uint32_t		apc_spare0;
724140751Swpaul	void			*apc_thread;
725140751Swpaul	list_entry		apc_list;
726140751Swpaul	void			*apc_kernfunc;
727140751Swpaul	void			*apc_rundownfunc;
728140751Swpaul	void			*apc_normalfunc;
729140751Swpaul	void			*apc_normctx;
730140751Swpaul	void			*apc_sysarg1;
731140751Swpaul	void			*apc_sysarg2;
732140751Swpaul	uint8_t			apc_stateidx;
733140751Swpaul	uint8_t			apc_cpumode;
734140751Swpaul	uint8_t			apc_inserted;
735140751Swpaul};
736140751Swpaul
737140751Swpaultypedef struct kapc kapc;
738140751Swpaul
739140751Swpaulstruct io_stack_location {
740140751Swpaul	uint8_t			isl_major;
741140751Swpaul	uint8_t			isl_minor;
742140751Swpaul	uint8_t			isl_flags;
743140751Swpaul	uint8_t			isl_ctl;
744140751Swpaul
745140751Swpaul	/*
746140751Swpaul	 * There's a big-ass union here in the actual Windows
747140751Swpaul	 * definition of the stucture, but it contains stuff
748140751Swpaul	 * that doesn't really apply to BSD, and defining it
749140751Swpaul	 * all properly would require duplicating over a dozen
750140751Swpaul	 * other structures that we'll never use. Since the
751140751Swpaul	 * io_stack_location structure is opaque to drivers
752140751Swpaul	 * anyway, I'm not going to bother with the extra crap.
753140751Swpaul	 */
754140751Swpaul
755140751Swpaul	union {
756140751Swpaul		struct {
757140751Swpaul			void			*isl_arg1;
758140751Swpaul			void			*isl_arg2;
759140751Swpaul			void			*isl_arg3;
760140751Swpaul			void			*isl_arg4;
761140751Swpaul		} isl_others;
762140751Swpaul	} isl_parameters;
763140751Swpaul
764140751Swpaul	void			*isl_devobj;
765140751Swpaul	void			*isl_fileobj;
766140751Swpaul	void			*isl_completionfunc;
767140751Swpaul	void			*isl_completionctx;
768140751Swpaul};
769140751Swpaul
770140751Swpaultypedef struct io_stack_location io_stack_location;
771140751Swpaul
772140751Swpaul/* Stack location control flags */
773140751Swpaul
774140751Swpaul#define SL_PENDING_RETURNED		0x01
775140751Swpaul#define SL_INVOKE_ON_CANCEL		0x20
776140751Swpaul#define SL_INVOKE_ON_SUCCESS		0x40
777140751Swpaul#define SL_INVOKE_ON_ERROR		0x80
778140751Swpaul
779125551Swpaulstruct irp {
780140751Swpaul	uint16_t		irp_type;
781140751Swpaul	uint16_t		irp_size;
782140751Swpaul	mdl			*irp_mdl;
783140751Swpaul	uint32_t		irp_flags;
784140751Swpaul	union {
785140751Swpaul		struct irp		*irp_master;
786140751Swpaul		uint32_t		irp_irpcnt;
787140751Swpaul		void			*irp_sysbuf;
788140751Swpaul	} irp_assoc;
789140751Swpaul	list_entry		irp_thlist;
790140751Swpaul	io_status_block		irp_iostat;
791140751Swpaul	uint8_t			irp_reqmode;
792140751Swpaul	uint8_t			irp_pendingreturned;
793140751Swpaul	uint8_t			irp_stackcnt;
794140751Swpaul	uint8_t			irp_currentstackloc;
795140751Swpaul	uint8_t			irp_cancel;
796140751Swpaul	uint8_t			irp_cancelirql;
797140751Swpaul	uint8_t			irp_apcenv;
798140751Swpaul	uint8_t			irp_allocflags;
799140751Swpaul	io_status_block		*irp_usriostat;
800140751Swpaul	nt_kevent		irp_userevent;
801140751Swpaul	union {
802140751Swpaul		struct {
803140751Swpaul			void			*irp_apcfunc;
804140751Swpaul			void			*irp_apcctx;
805140751Swpaul		} irp_asyncparms;
806140751Swpaul		uint64_t			irp_allocsz;
807140751Swpaul	} irp_overlay;
808140751Swpaul	void			*irp_cancelfunc;
809140751Swpaul	void			*irp_userbuf;
810140751Swpaul
811140751Swpaul	/* Windows kernel info */
812140751Swpaul
813140751Swpaul	union {
814140751Swpaul		struct {
815140751Swpaul			union {
816140751Swpaul				kdevice_qentry			irp_dqe;
817140751Swpaul				struct {
818140751Swpaul					void 			*irp_drvctx[4];
819140751Swpaul				} s1;
820140751Swpaul			} u1;
821140751Swpaul			void			*irp_thread;
822140751Swpaul			char			*irp_auxbuf;
823140751Swpaul			struct {
824140751Swpaul				list_entry			irp_list;
825140751Swpaul				union {
826140751Swpaul					io_stack_location	*irp_csl;
827140751Swpaul					uint32_t		irp_pkttype;
828140751Swpaul				} u2;
829140751Swpaul			} s2;
830140751Swpaul			void			*irp_fileobj;
831140751Swpaul		} irp_overlay;
832140751Swpaul		kapc			irp_apc;
833140751Swpaul		void			*irp_compkey;
834140751Swpaul	} irp_tail;
835125551Swpaul};
836125551Swpaul
837140751Swpaul#define irp_csl			s2.u2.irp_csl
838140751Swpaul#define irp_pkttype		s2.u2.irp_pkttype
839140751Swpaul
840125551Swpaultypedef struct irp irp;
841125551Swpaul
842140751Swpaul#define IoGetCurrentIrpStackLocation(irp)				\
843140751Swpaul	(irp)->irp_tail.irp_overlay.irp_csl
844140751Swpaul
845140751Swpaul#define IoGetNextIrpStackLocation(irp)					\
846140751Swpaul	((irp)->irp_tail.irp_overlay.irp_csl - 1)
847140751Swpaul
848140751Swpaul#define IoSetCompletionRoutine(irp, func, ctx, ok, err, cancel)		\
849140751Swpaul	do {								\
850140751Swpaul		io_stack_location		*s;			\
851140751Swpaul		s = IoGetNextIrpStackLocation((irp));			\
852140751Swpaul		s->isl_completionfunc = (func);				\
853140751Swpaul		s->isl_completionctx = (ctx);				\
854140751Swpaul		s->isl_ctl = 0;						\
855140751Swpaul		if (ok) irp->ctl = SL_INVOKE_ON_SUCCESS;		\
856140751Swpaul		if (err) irp->ctl |= SL_INVOKE_ON_ERROR;		\
857140751Swpaul		if (cancel) irp->ctl |= SL_INVOKE_ON_CANCEL;		\
858140751Swpaul	} while(0)
859140751Swpaul
860140751Swpaul#define IoMarkIrpPending(irp)						\
861140751Swpaul	IoGetCurrentIrpStackLocation(irp)->isl_ctl |= SL_PENDING_RETURNED
862140751Swpaul
863140751Swpaul#define IoSizeOfIrp(s)							\
864140751Swpaul	((uint16_t) (sizeof(itp) + ((s) * (sizeof(io_stack_location)))))
865140751Swpaul
866140751Swpaul#define IoCopyCurrentIrpStackLocationToNext(irp)			\
867140751Swpaul	do {								\
868140751Swpaul		io_stack_location *src, *dst;				\
869140751Swpaul		src = IoGetCurrentIrpStackLocation(irp);		\
870140751Swpaul		dst = IoGetNextIrpStackLocation(irp);			\
871140751Swpaul		bcopy((char *)src, (char *)dst,				\
872140751Swpaul		    offsetof(io_stack_location, isl_completionfunc));	\
873140751Swpaul	} while(0)
874140751Swpaul
875140751Swpaul#define IoSkipCurrentIrpStackLocation(irp)				\
876140751Swpaul	do {								\
877140751Swpaul		(irp)->irp_currentstackloc++;				\
878140751Swpaul		(irp)->irp_tail.irp_overlay.irp_csl++;			\
879140751Swpaul	} while(0)
880140751Swpaul
881125551Swpaultypedef uint32_t (*driver_dispatch)(device_object *, irp *);
882125551Swpaul
883140751Swpaul/*
884140751Swpaul * The driver_object is allocated once for each driver that's loaded
885140751Swpaul * into the system. A new one is allocated for each driver and
886140751Swpaul * populated a bit via the driver's DriverEntry function.
887140751Swpaul * In general, a Windows DriverEntry() function will provide a pointer
888140751Swpaul * to its AddDevice() method and set up the dispatch table.
889140751Swpaul * For NDIS drivers, this is all done behind the scenes in the
890140751Swpaul * NdisInitializeWrapper() and/or NdisMRegisterMiniport() routines.
891140751Swpaul */
892140751Swpaul
893140751Swpaulstruct driver_object {
894140751Swpaul	uint16_t		dro_type;
895140751Swpaul	uint16_t		dro_size;
896140751Swpaul	device_object		*dro_devobj;
897140751Swpaul	uint32_t		dro_flags;
898140751Swpaul	void			*dro_driverstart;
899140751Swpaul	uint32_t		dro_driversize;
900140751Swpaul	void			*dro_driversection;
901140751Swpaul	driver_extension	dro_driverext;
902140751Swpaul	unicode_string		dro_drivername;
903140751Swpaul	unicode_string		*dro_hwdb;
904140751Swpaul	void			*dro_pfastiodispatch;
905140751Swpaul	void			*dro_driverinitfunc;
906140751Swpaul	void			*dro_driverstartiofunc;
907140751Swpaul	void			*dro_driverunloadfunc;
908140751Swpaul	void			*dro_dispatch[IRP_MJ_MAXIMUM_FUNCTION + 1];
909140751Swpaul};
910140751Swpaul
911140751Swpaultypedef struct driver_object driver_object;
912140751Swpaul
913125551Swpaul#define DEVPROP_DEVICE_DESCRIPTION	0x00000000
914125551Swpaul#define DEVPROP_HARDWARE_ID		0x00000001
915125551Swpaul#define DEVPROP_COMPATIBLE_IDS		0x00000002
916125551Swpaul#define DEVPROP_BOOTCONF		0x00000003
917125551Swpaul#define DEVPROP_BOOTCONF_TRANSLATED	0x00000004
918125551Swpaul#define DEVPROP_CLASS_NAME		0x00000005
919125551Swpaul#define DEVPROP_CLASS_GUID		0x00000006
920125551Swpaul#define DEVPROP_DRIVER_KEYNAME		0x00000007
921125551Swpaul#define DEVPROP_MANUFACTURER		0x00000008
922125551Swpaul#define DEVPROP_FRIENDLYNAME		0x00000009
923125551Swpaul#define DEVPROP_LOCATION_INFO		0x0000000A
924125551Swpaul#define DEVPROP_PHYSDEV_NAME		0x0000000B
925125551Swpaul#define DEVPROP_BUSTYPE_GUID		0x0000000C
926125551Swpaul#define DEVPROP_LEGACY_BUSTYPE		0x0000000D
927125551Swpaul#define DEVPROP_BUS_NUMBER		0x0000000E
928125551Swpaul#define DEVPROP_ENUMERATOR_NAME		0x0000000F
929125551Swpaul#define DEVPROP_ADDRESS			0x00000010
930125551Swpaul#define DEVPROP_UINUMBER		0x00000011
931125551Swpaul#define DEVPROP_INSTALL_STATE		0x00000012
932125551Swpaul#define DEVPROP_REMOVAL_POLICY		0x00000013
933125551Swpaul
934125551Swpaul#define STATUS_SUCCESS			0x00000000
935125551Swpaul#define STATUS_USER_APC			0x000000C0
936125551Swpaul#define STATUS_KERNEL_APC		0x00000100
937125551Swpaul#define STATUS_ALERTED			0x00000101
938125551Swpaul#define STATUS_TIMEOUT			0x00000102
939125551Swpaul#define STATUS_INVALID_PARAMETER	0xC000000D
940125551Swpaul#define STATUS_INVALID_DEVICE_REQUEST	0xC0000010
941125551Swpaul#define STATUS_BUFFER_TOO_SMALL		0xC0000023
942125551Swpaul#define STATUS_MUTANT_NOT_OWNED		0xC0000046
943125551Swpaul#define STATUS_INVALID_PARAMETER_2	0xC00000F0
944125551Swpaul
945125551Swpaul#define STATUS_WAIT_0			0x00000000
946125551Swpaul
947127284Swpaul/*
948127284Swpaul * FreeBSD's kernel stack is 2 pages in size by default. The
949127284Swpaul * Windows stack is larger, so we need to give our threads more
950127284Swpaul * stack pages. 4 should be enough, we use 8 just to extra safe.
951127284Swpaul */
952127284Swpaul#define NDIS_KSTACK_PAGES	8
953127284Swpaul
954123474Swpaulextern image_patch_table ntoskrnl_functbl[];
955123474Swpaul
956123474Swpaul__BEGIN_DECLS
957123474Swpaulextern int ntoskrnl_libinit(void);
958123474Swpaulextern int ntoskrnl_libfini(void);
959140751Swpaul__stdcall extern void KeInitializeDpc(kdpc *, void *, void *);
960140751Swpaul__stdcall extern uint8_t KeInsertQueueDpc(kdpc *, void *, void *);
961140751Swpaul__stdcall extern uint8_t KeRemoveQueueDpc(kdpc *);
962140751Swpaul__stdcall extern void KeInitializeTimer(ktimer *);
963140751Swpaul__stdcall extern void KeInitializeTimerEx(ktimer *, uint32_t);
964140751Swpaul__stdcall extern uint8_t KeSetTimer(ktimer *, int64_t, kdpc *);
965140751Swpaul__stdcall extern uint8_t KeSetTimerEx(ktimer *, int64_t,
966127248Swpaul	uint32_t, kdpc *);
967140751Swpaul__stdcall extern uint8_t KeCancelTimer(ktimer *);
968140751Swpaul__stdcall extern uint8_t KeReadStateTimer(ktimer *);
969140751Swpaul__stdcall extern uint32_t KeWaitForSingleObject(nt_dispatch_header *, uint32_t,
970127248Swpaul	uint32_t, uint8_t, int64_t *);
971140751Swpaul__stdcall extern void KeInitializeEvent(nt_kevent *, uint32_t, uint8_t);
972140751Swpaul__stdcall extern void KeClearEvent(nt_kevent *);
973140751Swpaul__stdcall extern uint32_t KeReadStateEvent(nt_kevent *);
974140751Swpaul__stdcall extern uint32_t KeSetEvent(nt_kevent *, uint32_t, uint8_t);
975140751Swpaul__stdcall extern uint32_t KeResetEvent(nt_kevent *);
976140751Swpaul__fastcall extern void KefAcquireSpinLockAtDpcLevel(REGARGS1(kspin_lock *));
977140751Swpaul__fastcall extern void KefReleaseSpinLockFromDpcLevel(REGARGS1(kspin_lock *));
978140751Swpaul__stdcall extern void KeInitializeSpinLock(kspin_lock *);
979140751Swpaul__fastcall extern uint32_t IofCallDriver(REGARGS2(device_object *, irp *));
980140751Swpaul__fastcall extern void IofCompleteRequest(REGARGS2(irp *, uint8_t));
981128229Swpaul
982140751Swpaul#define IoCallDriver(a, b)		FASTCALL2(IofCallDriver, a, b)
983140751Swpaul#define IoCompleteRequest(a, b)		FASTCALL2(IofCompleteRequest, a, b)
984140751Swpaul
985128229Swpaul/*
986128229Swpaul * On the Windows x86 arch, KeAcquireSpinLock() and KeReleaseSpinLock()
987128229Swpaul * routines live in the HAL. We try to imitate this behavior.
988128229Swpaul */
989128229Swpaul#ifdef __i386__
990140751Swpaul#define KeAcquireSpinLock(a, b)	*(b) = FASTCALL1(KfAcquireSpinLock, a)
991140751Swpaul#define KeReleaseSpinLock(a, b)	FASTCALL2(KfReleaseSpinLock, a, b)
992140751Swpaul#define KeRaiseIrql(a)		FASTCALL1(KfRaiseIrql, a)
993140751Swpaul#define KeLowerIrql(a)		FASTCALL1(KfLowerIrql, a)
994128229Swpaul#endif /* __i386__ */
995123474Swpaul__END_DECLS
996123474Swpaul
997123474Swpaul#endif /* _NTOSKRNL_VAR_H_ */
998