ntoskrnl_var.h revision 145485
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 145485 2005-04-24 20:21:22Z 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
103142530Swpaul#define MDL_ZONE_ALLOCED		0x8000	/* BSD private */
104140751Swpaul
105142530Swpaul#define MDL_ZONE_PAGES 16
106142530Swpaul#define MDL_ZONE_SIZE (sizeof(mdl) + (sizeof(vm_offset_t) * MDL_ZONE_PAGES))
107142530Swpaul
108123512Swpaul/* Note: assumes x86 page size of 4K. */
109140751Swpaul
110140751Swpaul#if PAGE_SIZE == 4096
111123512Swpaul#define PAGE_SHIFT	12
112140751Swpaul#elif PAGE_SIZE == 8192
113140751Swpaul#define PAGE_SHIFT	13
114140751Swpaul#else
115140751Swpaul#error PAGE_SHIFT undefined!
116140751Swpaul#endif
117140751Swpaul
118123512Swpaul#define SPAN_PAGES(ptr, len)					\
119140751Swpaul	((uint32_t)((((uintptr_t)(ptr) & (PAGE_SIZE - 1)) +	\
120123512Swpaul	(len) + (PAGE_SIZE - 1)) >> PAGE_SHIFT))
121140751Swpaul
122123757Swpaul#define PAGE_ALIGN(ptr)						\
123123757Swpaul	((void *)((uintptr_t)(ptr) & ~(PAGE_SIZE - 1)))
124140751Swpaul
125123757Swpaul#define BYTE_OFFSET(ptr)					\
126123757Swpaul	((uint32_t)((uintptr_t)(ptr) & (PAGE_SIZE - 1)))
127140751Swpaul
128140751Swpaul#define MDL_PAGES(m)	(vm_offset_t *)(m + 1)
129140751Swpaul
130140751Swpaul#define MmInitializeMdl(b, baseva, len)					\
131140751Swpaul	(b)->mdl_next = NULL;						\
132140751Swpaul	(b)->mdl_size = (uint16_t)(sizeof(mdl) +			\
133144175Swpaul		(sizeof(vm_offset_t) * SPAN_PAGES((baseva), (len))));	\
134140751Swpaul	(b)->mdl_flags = 0;						\
135140751Swpaul	(b)->mdl_startva = (void *)PAGE_ALIGN((baseva));		\
136140751Swpaul	(b)->mdl_byteoffset = BYTE_OFFSET((baseva));			\
137140751Swpaul	(b)->mdl_bytecount = (uint32_t)(len);
138123512Swpaul
139140751Swpaul#define MmGetMdlByteOffset(mdl)		((mdl)->mdl_byteoffset)
140140751Swpaul#define MmGetMdlByteCount(mdl)		((mdl)->mdl_bytecount)
141140751Swpaul#define MmGetMdlVirtualAddress(mdl)					\
142140751Swpaul	((void *)((char *)((mdl)->mdl_startva) + (mdl)->mdl_byteoffset))
143140751Swpaul#define MmGetMdlStartVa(mdl)		((mdl)->mdl_startva)
144140751Swpaul#define MmGetMdlPfnArray(mdl)		MDL_PAGES(mdl)
145140751Swpaul
146124729Swpaul#define WDM_MAJOR		1
147124729Swpaul#define WDM_MINOR_WIN98		0x00
148124729Swpaul#define WDM_MINOR_WINME		0x05
149124729Swpaul#define WDM_MINOR_WIN2000	0x10
150124729Swpaul#define WDM_MINOR_WINXP		0x20
151124729Swpaul#define WDM_MINOR_WIN2003	0x30
152124729Swpaul
153124582Sobrien/*-
154124582Sobrien * The ndis_kspin_lock type is called KSPIN_LOCK in MS-Windows.
155124582Sobrien * According to the Windows DDK header files, KSPIN_LOCK is defined like this:
156124582Sobrien *	typedef ULONG_PTR KSPIN_LOCK;
157124582Sobrien *
158124582Sobrien * From basetsd.h (SDK, Feb. 2003):
159124582Sobrien * 	typedef [public] unsigned __int3264 ULONG_PTR, *PULONG_PTR;
160124582Sobrien * 	typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
161124582Sobrien * 	typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR;
162124582Sobrien *
163124582Sobrien * The keyword __int3264 specifies an integral type that has the following
164124582Sobrien * properties:
165124582Sobrien *	+ It is 32-bit on 32-bit platforms
166124582Sobrien *	+ It is 64-bit on 64-bit platforms
167124582Sobrien *	+ It is 32-bit on the wire for backward compatibility.
168124582Sobrien *	  It gets truncated on the sending side and extended appropriately
169124582Sobrien *	  (signed or unsigned) on the receiving side.
170124582Sobrien *
171124582Sobrien * Thus register_t seems the proper mapping onto FreeBSD for spin locks.
172124582Sobrien */
173123474Swpaul
174124582Sobrientypedef register_t kspin_lock;
175124582Sobrien
176123474Swpaulstruct slist_entry {
177123474Swpaul	struct slist_entry	*sl_next;
178123474Swpaul};
179123474Swpaul
180123474Swpaultypedef struct slist_entry slist_entry;
181123474Swpaul
182123474Swpaulunion slist_header {
183123474Swpaul	uint64_t		slh_align;
184123474Swpaul	struct {
185123474Swpaul		struct slist_entry	*slh_next;
186123474Swpaul		uint16_t		slh_depth;
187123474Swpaul		uint16_t		slh_seq;
188123474Swpaul	} slh_list;
189123474Swpaul};
190123474Swpaul
191123474Swpaultypedef union slist_header slist_header;
192123474Swpaul
193123507Swpaulstruct list_entry {
194123507Swpaul        struct list_entry *nle_flink;
195123507Swpaul        struct list_entry *nle_blink;
196123507Swpaul};
197123507Swpaul
198123507Swpaultypedef struct list_entry list_entry;
199123507Swpaul
200125551Swpaul#define INIT_LIST_HEAD(l)	\
201141524Swpaul	(l)->nle_flink = (l)->nle_blink = (l)
202125551Swpaul
203125551Swpaul#define REMOVE_LIST_ENTRY(e)			\
204125551Swpaul	do {					\
205125551Swpaul		list_entry		*b;	\
206125551Swpaul		list_entry		*f;	\
207125551Swpaul						\
208125551Swpaul		f = e->nle_flink;		\
209125551Swpaul		b = e->nle_blink;		\
210125551Swpaul		b->nle_flink = f;		\
211125551Swpaul		f->nle_blink = b;		\
212125551Swpaul	} while (0)
213125551Swpaul
214125551Swpaul#define REMOVE_LIST_HEAD(l)			\
215125551Swpaul	do {					\
216125551Swpaul		list_entry		*f;	\
217125551Swpaul		list_entry		*e;	\
218125551Swpaul						\
219125551Swpaul		e = l->nle_flink;		\
220125551Swpaul		f = e->nle_flink;		\
221125551Swpaul		l->nle_flink = f;		\
222125551Swpaul		f->nle_blink = l;		\
223125551Swpaul	} while (0)
224125551Swpaul
225125551Swpaul#define REMOVE_LIST_TAIL(l)			\
226125551Swpaul	do {					\
227125551Swpaul		list_entry		*b;	\
228125551Swpaul		list_entry		*e;	\
229125551Swpaul						\
230125551Swpaul		e = l->nle_blink;		\
231125551Swpaul		b = e->nle_blink;		\
232125551Swpaul		l->nle_blink = b;		\
233125551Swpaul		b->nle_flink = l;		\
234125551Swpaul	} while (0)
235125551Swpaul
236125551Swpaul#define INSERT_LIST_TAIL(l, e)			\
237125551Swpaul	do {					\
238125551Swpaul		list_entry		*b;	\
239125551Swpaul						\
240125551Swpaul		b = l->nle_blink;		\
241125860Swpaul		e->nle_flink = l;		\
242125551Swpaul		e->nle_blink = b;		\
243141524Swpaul		b->nle_flink = (e);		\
244141524Swpaul		l->nle_blink = (e);		\
245125551Swpaul	} while (0)
246125551Swpaul
247125551Swpaul#define INSERT_LIST_HEAD(l, e)			\
248125551Swpaul	do {					\
249125551Swpaul		list_entry		*f;	\
250125551Swpaul						\
251125551Swpaul		f = l->nle_flink;		\
252125551Swpaul		e->nle_flink = f;		\
253125551Swpaul		e->nle_blink = l;		\
254125551Swpaul		f->nle_blink = e;		\
255125551Swpaul		l->nle_flink = e;		\
256125551Swpaul	} while (0)
257125551Swpaul
258125551Swpaulstruct nt_dispatch_header {
259125551Swpaul	uint8_t			dh_type;
260125551Swpaul	uint8_t			dh_abs;
261125551Swpaul	uint8_t			dh_size;
262125551Swpaul	uint8_t			dh_inserted;
263125551Swpaul	uint32_t		dh_sigstate;
264125551Swpaul	list_entry		dh_waitlisthead;
265125551Swpaul};
266125551Swpaul
267125551Swpaultypedef struct nt_dispatch_header nt_dispatch_header;
268125551Swpaul
269125551Swpaul#define OTYPE_EVENT		0
270125551Swpaul#define OTYPE_MUTEX		1
271125551Swpaul#define OTYPE_THREAD		2
272125551Swpaul#define OTYPE_TIMER		3
273125551Swpaul
274125551Swpaul/* Windows dispatcher levels. */
275125551Swpaul
276125551Swpaul#define PASSIVE_LEVEL		0
277125551Swpaul#define LOW_LEVEL		0
278125551Swpaul#define APC_LEVEL		1
279125551Swpaul#define DISPATCH_LEVEL		2
280128229Swpaul#define DEVICE_LEVEL		(DISPATCH_LEVEL + 1)
281125551Swpaul#define PROFILE_LEVEL		27
282125551Swpaul#define CLOCK1_LEVEL		28
283125551Swpaul#define CLOCK2_LEVEL		28
284125551Swpaul#define IPI_LEVEL		29
285125551Swpaul#define POWER_LEVEL		30
286125551Swpaul#define HIGH_LEVEL		31
287125551Swpaul
288125551Swpaul#define SYNC_LEVEL_UP		DISPATCH_LEVEL
289125551Swpaul#define SYNC_LEVEL_MP		(IPI_LEVEL - 1)
290125551Swpaul
291128229Swpaul#define AT_PASSIVE_LEVEL(td)		\
292128229Swpaul	((td)->td_proc->p_flag & P_KTHREAD == FALSE)
293128229Swpaul
294128229Swpaul#define AT_DISPATCH_LEVEL(td)		\
295128449Swpaul	((td)->td_base_pri == PI_REALTIME)
296128229Swpaul
297128229Swpaul#define AT_DIRQL_LEVEL(td)		\
298128295Swpaul	((td)->td_priority <= PI_NET)
299128229Swpaul
300128229Swpaul#define AT_HIGH_LEVEL(td)		\
301128229Swpaul	((td)->td_critnest != 0)
302128229Swpaul
303125551Swpaulstruct nt_objref {
304125551Swpaul	nt_dispatch_header	no_dh;
305125551Swpaul	void			*no_obj;
306125551Swpaul	TAILQ_ENTRY(nt_objref)	link;
307125551Swpaul};
308125551Swpaul
309125551SwpaulTAILQ_HEAD(nt_objref_head, nt_objref);
310125551Swpaul
311125551Swpaultypedef struct nt_objref nt_objref;
312125551Swpaul
313125551Swpaul#define EVENT_TYPE_NOTIFY	0
314125551Swpaul#define EVENT_TYPE_SYNC		1
315125551Swpaul
316126620Swpaul/*
317126620Swpaul * We need to use the timeout()/untimeout() API for ktimers
318126620Swpaul * since timers can be initialized, but not destroyed (so
319126620Swpaul * malloc()ing our own callout structures would mean a leak,
320126620Swpaul * since there'd be no way to free() them). This means we
321126620Swpaul * need to use struct callout_handle, which is really just a
322126620Swpaul * pointer. To make it easier to deal with, we use a union
323126620Swpaul * to overlay the callout_handle over the k_timerlistentry.
324126620Swpaul * The latter is a list_entry, which is two pointers, so
325126620Swpaul * there's enough space available to hide a callout_handle
326126620Swpaul * there.
327126620Swpaul */
328126620Swpaul
329125551Swpaulstruct ktimer {
330125551Swpaul	nt_dispatch_header	k_header;
331125551Swpaul	uint64_t		k_duetime;
332126620Swpaul	union {
333126620Swpaul		list_entry		k_timerlistentry;
334126620Swpaul		struct callout_handle	k_handle;
335126620Swpaul	} u;
336125551Swpaul	void			*k_dpc;
337125551Swpaul	uint32_t		k_period;
338125551Swpaul};
339125551Swpaul
340126620Swpaul#define k_timerlistentry	u.k_timerlistentry
341126620Swpaul#define k_handle		u.k_handle
342126620Swpaul
343126620Swpaultypedef struct ktimer ktimer;
344126620Swpaul
345125551Swpaulstruct nt_kevent {
346125551Swpaul	nt_dispatch_header	k_header;
347125551Swpaul};
348125551Swpaul
349125551Swpaultypedef struct nt_kevent nt_kevent;
350125551Swpaul
351125551Swpaul/* Kernel defered procedure call (i.e. timer callback) */
352125551Swpaul
353125551Swpaulstruct kdpc;
354144888Swpaultypedef void (*kdpc_func)(struct kdpc *, void *, void *, void *);
355125551Swpaul
356125551Swpaulstruct kdpc {
357125551Swpaul	uint16_t		k_type;
358125551Swpaul	uint8_t			k_num;
359125551Swpaul	uint8_t			k_importance;
360125551Swpaul	list_entry		k_dpclistentry;
361140827Swpaul	void			*k_deferedfunc;
362125551Swpaul	void			*k_deferredctx;
363125551Swpaul	void			*k_sysarg1;
364125551Swpaul	void			*k_sysarg2;
365127552Swpaul	register_t		k_lock;
366125551Swpaul};
367125551Swpaul
368126620Swpaultypedef struct kdpc kdpc;
369126620Swpaul
370125551Swpaul/*
371125551Swpaul * Note: the acquisition count is BSD-specific. The Microsoft
372125551Swpaul * documentation says that mutexes can be acquired recursively
373125551Swpaul * by a given thread, but that you must release the mutex as
374125551Swpaul * many times as you acquired it before it will be set to the
375125551Swpaul * signalled state (i.e. before any other threads waiting on
376125551Swpaul * the object will be woken up). However the Windows KMUTANT
377125551Swpaul * structure has no field for keeping track of the number of
378125551Swpaul * acquisitions, so we need to add one ourselves. As long as
379125551Swpaul * driver code treats the mutex as opaque, we should be ok.
380125551Swpaul */
381125551Swpaulstruct kmutant {
382125551Swpaul	nt_dispatch_header	km_header;
383126620Swpaul	union {
384126620Swpaul		list_entry		km_listentry;
385126620Swpaul		uint32_t		km_acquirecnt;
386126620Swpaul	} u;
387125551Swpaul	void			*km_ownerthread;
388125551Swpaul	uint8_t			km_abandoned;
389125551Swpaul	uint8_t			km_apcdisable;
390125551Swpaul};
391125551Swpaul
392126620Swpaul#define km_listentry		u.km_listentry
393126620Swpaul#define km_acquirecnt		u.km_acquirecnt
394126620Swpaul
395125551Swpaultypedef struct kmutant kmutant;
396125551Swpaul
397125860Swpaul#define LOOKASIDE_DEPTH 256
398125860Swpaul
399123474Swpaulstruct general_lookaside {
400123474Swpaul	slist_header		gl_listhead;
401123474Swpaul	uint16_t		gl_depth;
402123474Swpaul	uint16_t		gl_maxdepth;
403123474Swpaul	uint32_t		gl_totallocs;
404123474Swpaul	union {
405123474Swpaul		uint32_t		gl_allocmisses;
406123474Swpaul		uint32_t		gl_allochits;
407123474Swpaul	} u_a;
408123474Swpaul	uint32_t		gl_totalfrees;
409123474Swpaul	union {
410123474Swpaul		uint32_t		gl_freemisses;
411123474Swpaul		uint32_t		gl_freehits;
412123474Swpaul	} u_m;
413123474Swpaul	uint32_t		gl_type;
414123474Swpaul	uint32_t		gl_tag;
415123474Swpaul	uint32_t		gl_size;
416123474Swpaul	void			*gl_allocfunc;
417123474Swpaul	void			*gl_freefunc;
418123507Swpaul	list_entry		gl_listent;
419123474Swpaul	uint32_t		gl_lasttotallocs;
420123474Swpaul	union {
421123474Swpaul		uint32_t		gl_lastallocmisses;
422123474Swpaul		uint32_t		gl_lastallochits;
423123474Swpaul	} u_l;
424123474Swpaul	uint32_t		gl_rsvd[2];
425123474Swpaul};
426123474Swpaul
427123474Swpaultypedef struct general_lookaside general_lookaside;
428123474Swpaul
429123474Swpaulstruct npaged_lookaside_list {
430123474Swpaul	general_lookaside	nll_l;
431144240Swpaul#ifdef __i386__
432123474Swpaul	kspin_lock		nll_obsoletelock;
433144240Swpaul#endif
434123474Swpaul};
435123474Swpaul
436123474Swpaultypedef struct npaged_lookaside_list npaged_lookaside_list;
437123474Swpaultypedef struct npaged_lookaside_list paged_lookaside_list;
438123474Swpaul
439123474Swpaultypedef void * (*lookaside_alloc_func)(uint32_t, size_t, uint32_t);
440123474Swpaultypedef void (*lookaside_free_func)(void *);
441123474Swpaul
442125551Swpaulstruct irp;
443123474Swpaul
444125551Swpaulstruct kdevice_qentry {
445125551Swpaul	list_entry		kqe_devlistent;
446125551Swpaul	uint32_t		kqe_sortkey;
447125551Swpaul	uint8_t			kqe_inserted;
448125551Swpaul};
449125551Swpaul
450125551Swpaultypedef struct kdevice_qentry kdevice_qentry;
451125551Swpaul
452125551Swpaulstruct kdevice_queue {
453125551Swpaul	uint16_t		kq_type;
454125551Swpaul	uint16_t		kq_size;
455125551Swpaul	list_entry		kq_devlisthead;
456125551Swpaul	kspin_lock		kq_lock;
457125551Swpaul	uint8_t			kq_busy;
458125551Swpaul};
459125551Swpaul
460125551Swpaultypedef struct kdevice_queue kdevice_queue;
461125551Swpaul
462125551Swpaulstruct wait_ctx_block {
463125551Swpaul	kdevice_qentry		wcb_waitqueue;
464125551Swpaul	void			*wcb_devfunc;
465125551Swpaul	void			*wcb_devctx;
466125551Swpaul	uint32_t		wcb_mapregcnt;
467125551Swpaul	void			*wcb_devobj;
468125551Swpaul	void			*wcb_curirp;
469125551Swpaul	void			*wcb_bufchaindpc;
470125551Swpaul};
471125551Swpaul
472125551Swpaultypedef struct wait_ctx_block wait_ctx_block;
473125551Swpaul
474125551Swpaulstruct wait_block {
475125551Swpaul	list_entry		wb_waitlist;
476125551Swpaul	void			*wb_kthread;
477125551Swpaul	nt_dispatch_header	*wb_object;
478125551Swpaul	struct wait_block	*wb_next;
479125551Swpaul	uint16_t		wb_waitkey;
480125551Swpaul	uint16_t		wb_waittype;
481125551Swpaul};
482125551Swpaul
483125551Swpaultypedef struct wait_block wait_block;
484125551Swpaul
485125551Swpaul#define THREAD_WAIT_OBJECTS	3
486125551Swpaul#define MAX_WAIT_OBJECTS	64
487125551Swpaul
488125551Swpaul#define WAITTYPE_ALL		0
489125551Swpaul#define WAITTYPE_ANY		1
490125551Swpaul
491125551Swpaulstruct thread_context {
492125551Swpaul	void			*tc_thrctx;
493125551Swpaul	void			*tc_thrfunc;
494125551Swpaul};
495125551Swpaul
496125551Swpaultypedef struct thread_context thread_context;
497125551Swpaul
498140751Swpaul/* Forward declaration */
499140751Swpaulstruct driver_object;
500140751Swpaulstruct devobj_extension;
501140751Swpaul
502140751Swpaulstruct driver_extension {
503140751Swpaul	struct driver_object	*dre_driverobj;
504140751Swpaul	void			*dre_adddevicefunc;
505140751Swpaul	uint32_t		dre_reinitcnt;
506140751Swpaul	unicode_string		dre_srvname;
507141524Swpaul
508141524Swpaul	/*
509141524Swpaul	 * Drivers are allowed to add one or more custom extensions
510141524Swpaul	 * to the driver object, but there's no special pointer
511141524Swpaul	 * for them. Hang them off here for now.
512141524Swpaul	 */
513141524Swpaul
514141524Swpaul	list_entry		dre_usrext;
515140751Swpaul};
516140751Swpaul
517140751Swpaultypedef struct driver_extension driver_extension;
518140751Swpaul
519141524Swpaulstruct custom_extension {
520141524Swpaul	list_entry		ce_list;
521141524Swpaul	void			*ce_clid;
522141524Swpaul};
523141524Swpaul
524141524Swpaultypedef struct custom_extension custom_extension;
525141524Swpaul
526140751Swpaul/*
527140751Swpaul * In Windows, there are Physical Device Objects (PDOs) and
528140751Swpaul * Functional Device Objects (FDOs). Physical Device Objects are
529140751Swpaul * created and maintained by bus drivers. For example, the PCI
530140751Swpaul * bus driver might detect two PCI ethernet cards on a given
531140751Swpaul * bus. The PCI bus driver will then allocate two device_objects
532140751Swpaul * for its own internal bookeeping purposes. This is analagous
533140751Swpaul * to the device_t that the FreeBSD PCI code allocates and passes
534140751Swpaul * into each PCI driver's probe and attach routines.
535140751Swpaul *
536140751Swpaul * When an ethernet driver claims one of the ethernet cards
537140751Swpaul * on the bus, it will create its own device_object. This is
538140751Swpaul * the Functional Device Object. This object is analagous to the
539140751Swpaul * device-specific softc structure.
540140751Swpaul */
541140751Swpaul
542125551Swpaulstruct device_object {
543125551Swpaul	uint16_t		do_type;
544125551Swpaul	uint16_t		do_size;
545125551Swpaul	uint32_t		do_refcnt;
546141524Swpaul	struct driver_object	*do_drvobj;
547125551Swpaul	struct device_object	*do_nextdev;
548125551Swpaul	struct device_object	*do_attacheddev;
549125551Swpaul	struct irp		*do_currirp;
550125551Swpaul	void			*do_iotimer;
551125551Swpaul	uint32_t		do_flags;
552125551Swpaul	uint32_t		do_characteristics;
553125551Swpaul	void			*do_vpb;
554125551Swpaul	void			*do_devext;
555141524Swpaul	uint32_t		do_devtype;
556125551Swpaul	uint8_t			do_stacksize;
557125551Swpaul	union {
558125551Swpaul		list_entry		do_listent;
559125551Swpaul		wait_ctx_block		do_wcb;
560125551Swpaul	} queue;
561125551Swpaul	uint32_t		do_alignreq;
562125551Swpaul	kdevice_queue		do_devqueue;
563125551Swpaul	struct kdpc		do_dpc;
564125551Swpaul	uint32_t		do_activethreads;
565125551Swpaul	void			*do_securitydesc;
566125551Swpaul	struct nt_kevent	do_devlock;
567125551Swpaul	uint16_t		do_sectorsz;
568125551Swpaul	uint16_t		do_spare1;
569140751Swpaul	struct devobj_extension	*do_devobj_ext;
570125551Swpaul	void			*do_rsvd;
571125551Swpaul};
572125551Swpaul
573125551Swpaultypedef struct device_object device_object;
574125551Swpaul
575140751Swpaulstruct devobj_extension {
576140751Swpaul	uint16_t		dve_type;
577140751Swpaul	uint16_t		dve_size;
578140751Swpaul	device_object		*dve_devobj;
579140751Swpaul};
580140751Swpaul
581140751Swpaultypedef struct devobj_extension devobj_extension;
582140751Swpaul
583142311Swpaul/* Device object flags */
584142311Swpaul
585142311Swpaul#define DO_VERIFY_VOLUME		0x00000002
586142311Swpaul#define DO_BUFFERED_IO			0x00000004
587142311Swpaul#define DO_EXCLUSIVE			0x00000008
588142311Swpaul#define DO_DIRECT_IO			0x00000010
589142311Swpaul#define DO_MAP_IO_BUFFER		0x00000020
590142311Swpaul#define DO_DEVICE_HAS_NAME		0x00000040
591142311Swpaul#define DO_DEVICE_INITIALIZING		0x00000080
592142311Swpaul#define DO_SYSTEM_BOOT_PARTITION	0x00000100
593142311Swpaul#define DO_LONG_TERM_REQUESTS		0x00000200
594142311Swpaul#define DO_NEVER_LAST_DEVICE		0x00000400
595142311Swpaul#define DO_SHUTDOWN_REGISTERED		0x00000800
596142311Swpaul#define DO_BUS_ENUMERATED_DEVICE	0x00001000
597142311Swpaul#define DO_POWER_PAGABLE		0x00002000
598142311Swpaul#define DO_POWER_INRUSH			0x00004000
599142311Swpaul#define DO_LOW_PRIORITY_FILESYSTEM	0x00010000
600142311Swpaul
601142311Swpaul/* Priority boosts */
602142311Swpaul
603140751Swpaul#define IO_NO_INCREMENT			0
604140751Swpaul#define IO_CD_ROM_INCREMENT		1
605140751Swpaul#define IO_DISK_INCREMENT		1
606140751Swpaul#define IO_KEYBOARD_INCREMENT		6
607140751Swpaul#define IO_MAILSLOT_INCREMENT		2
608140751Swpaul#define IO_MOUSE_INCREMENT		6
609140751Swpaul#define IO_NAMED_PIPE_INCREMENT		2
610140751Swpaul#define IO_NETWORK_INCREMENT		2
611140751Swpaul#define IO_PARALLEL_INCREMENT		1
612140751Swpaul#define IO_SERIAL_INCREMENT		2
613140751Swpaul#define IO_SOUND_INCREMENT		8
614140751Swpaul#define IO_VIDEO_INCREMENT		1
615140751Swpaul
616140751Swpaul/* IRP major codes */
617140751Swpaul
618140751Swpaul#define IRP_MJ_CREATE                   0x00
619140751Swpaul#define IRP_MJ_CREATE_NAMED_PIPE        0x01
620140751Swpaul#define IRP_MJ_CLOSE                    0x02
621140751Swpaul#define IRP_MJ_READ                     0x03
622140751Swpaul#define IRP_MJ_WRITE                    0x04
623140751Swpaul#define IRP_MJ_QUERY_INFORMATION        0x05
624140751Swpaul#define IRP_MJ_SET_INFORMATION          0x06
625140751Swpaul#define IRP_MJ_QUERY_EA                 0x07
626140751Swpaul#define IRP_MJ_SET_EA                   0x08
627140751Swpaul#define IRP_MJ_FLUSH_BUFFERS            0x09
628140751Swpaul#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a
629140751Swpaul#define IRP_MJ_SET_VOLUME_INFORMATION   0x0b
630140751Swpaul#define IRP_MJ_DIRECTORY_CONTROL        0x0c
631140751Swpaul#define IRP_MJ_FILE_SYSTEM_CONTROL      0x0d
632140751Swpaul#define IRP_MJ_DEVICE_CONTROL           0x0e
633140751Swpaul#define IRP_MJ_INTERNAL_DEVICE_CONTROL  0x0f
634140751Swpaul#define IRP_MJ_SHUTDOWN                 0x10
635140751Swpaul#define IRP_MJ_LOCK_CONTROL             0x11
636140751Swpaul#define IRP_MJ_CLEANUP                  0x12
637140751Swpaul#define IRP_MJ_CREATE_MAILSLOT          0x13
638140751Swpaul#define IRP_MJ_QUERY_SECURITY           0x14
639140751Swpaul#define IRP_MJ_SET_SECURITY             0x15
640140751Swpaul#define IRP_MJ_POWER                    0x16
641140751Swpaul#define IRP_MJ_SYSTEM_CONTROL           0x17
642140751Swpaul#define IRP_MJ_DEVICE_CHANGE            0x18
643140751Swpaul#define IRP_MJ_QUERY_QUOTA              0x19
644140751Swpaul#define IRP_MJ_SET_QUOTA                0x1a
645140751Swpaul#define IRP_MJ_PNP                      0x1b
646140751Swpaul#define IRP_MJ_PNP_POWER                IRP_MJ_PNP      // Obsolete....
647140751Swpaul#define IRP_MJ_MAXIMUM_FUNCTION         0x1b
648140751Swpaul#define IRP_MJ_SCSI                     IRP_MJ_INTERNAL_DEVICE_CONTROL
649140751Swpaul
650140751Swpaul/* IRP minor codes */
651140751Swpaul
652140751Swpaul#define IRP_MN_QUERY_DIRECTORY          0x01
653140751Swpaul#define IRP_MN_NOTIFY_CHANGE_DIRECTORY  0x02
654140751Swpaul#define IRP_MN_USER_FS_REQUEST          0x00
655140751Swpaul
656140751Swpaul#define IRP_MN_MOUNT_VOLUME             0x01
657140751Swpaul#define IRP_MN_VERIFY_VOLUME            0x02
658140751Swpaul#define IRP_MN_LOAD_FILE_SYSTEM         0x03
659144240Swpaul#define IRP_MN_TRACK_LINK               0x04
660140751Swpaul#define IRP_MN_KERNEL_CALL              0x04
661140751Swpaul
662140751Swpaul#define IRP_MN_LOCK                     0x01
663140751Swpaul#define IRP_MN_UNLOCK_SINGLE            0x02
664140751Swpaul#define IRP_MN_UNLOCK_ALL               0x03
665140751Swpaul#define IRP_MN_UNLOCK_ALL_BY_KEY        0x04
666140751Swpaul
667140751Swpaul#define IRP_MN_NORMAL                   0x00
668140751Swpaul#define IRP_MN_DPC                      0x01
669140751Swpaul#define IRP_MN_MDL                      0x02
670140751Swpaul#define IRP_MN_COMPLETE                 0x04
671140751Swpaul#define IRP_MN_COMPRESSED               0x08
672140751Swpaul
673140751Swpaul#define IRP_MN_MDL_DPC                  (IRP_MN_MDL | IRP_MN_DPC)
674140751Swpaul#define IRP_MN_COMPLETE_MDL             (IRP_MN_COMPLETE | IRP_MN_MDL)
675140751Swpaul#define IRP_MN_COMPLETE_MDL_DPC         (IRP_MN_COMPLETE_MDL | IRP_MN_DPC)
676140751Swpaul
677140751Swpaul#define IRP_MN_SCSI_CLASS               0x01
678140751Swpaul
679140751Swpaul#define IRP_MN_START_DEVICE                 0x00
680140751Swpaul#define IRP_MN_QUERY_REMOVE_DEVICE          0x01
681140751Swpaul#define IRP_MN_REMOVE_DEVICE                0x02
682140751Swpaul#define IRP_MN_CANCEL_REMOVE_DEVICE         0x03
683140751Swpaul#define IRP_MN_STOP_DEVICE                  0x04
684140751Swpaul#define IRP_MN_QUERY_STOP_DEVICE            0x05
685140751Swpaul#define IRP_MN_CANCEL_STOP_DEVICE           0x06
686140751Swpaul
687140751Swpaul#define IRP_MN_QUERY_DEVICE_RELATIONS       0x07
688140751Swpaul#define IRP_MN_QUERY_INTERFACE              0x08
689140751Swpaul#define IRP_MN_QUERY_CAPABILITIES           0x09
690140751Swpaul#define IRP_MN_QUERY_RESOURCES              0x0A
691140751Swpaul#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS  0x0B
692140751Swpaul#define IRP_MN_QUERY_DEVICE_TEXT            0x0C
693140751Swpaul#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS 0x0D
694140751Swpaul
695140751Swpaul#define IRP_MN_READ_CONFIG                  0x0F
696140751Swpaul#define IRP_MN_WRITE_CONFIG                 0x10
697140751Swpaul#define IRP_MN_EJECT                        0x11
698140751Swpaul#define IRP_MN_SET_LOCK                     0x12
699140751Swpaul#define IRP_MN_QUERY_ID                     0x13
700140751Swpaul#define IRP_MN_QUERY_PNP_DEVICE_STATE       0x14
701140751Swpaul#define IRP_MN_QUERY_BUS_INFORMATION        0x15
702140751Swpaul#define IRP_MN_DEVICE_USAGE_NOTIFICATION    0x16
703140751Swpaul#define IRP_MN_SURPRISE_REMOVAL             0x17
704140751Swpaul#define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18
705140751Swpaul
706140751Swpaul#define IRP_MN_WAIT_WAKE                    0x00
707140751Swpaul#define IRP_MN_POWER_SEQUENCE               0x01
708140751Swpaul#define IRP_MN_SET_POWER                    0x02
709140751Swpaul#define IRP_MN_QUERY_POWER                  0x03
710140751Swpaul
711140751Swpaul#define IRP_MN_QUERY_ALL_DATA               0x00
712140751Swpaul#define IRP_MN_QUERY_SINGLE_INSTANCE        0x01
713140751Swpaul#define IRP_MN_CHANGE_SINGLE_INSTANCE       0x02
714140751Swpaul#define IRP_MN_CHANGE_SINGLE_ITEM           0x03
715140751Swpaul#define IRP_MN_ENABLE_EVENTS                0x04
716140751Swpaul#define IRP_MN_DISABLE_EVENTS               0x05
717140751Swpaul#define IRP_MN_ENABLE_COLLECTION            0x06
718140751Swpaul#define IRP_MN_DISABLE_COLLECTION           0x07
719140751Swpaul#define IRP_MN_REGINFO                      0x08
720140751Swpaul#define IRP_MN_EXECUTE_METHOD               0x09
721140751Swpaul#define IRP_MN_REGINFO_EX                   0x0b
722140751Swpaul
723140751Swpaul/* IRP flags */
724140751Swpaul
725140751Swpaul#define IRP_NOCACHE                     0x00000001
726140751Swpaul#define IRP_PAGING_IO                   0x00000002
727140751Swpaul#define IRP_MOUNT_COMPLETION            0x00000002
728140751Swpaul#define IRP_SYNCHRONOUS_API             0x00000004
729140751Swpaul#define IRP_ASSOCIATED_IRP              0x00000008
730140751Swpaul#define IRP_BUFFERED_IO                 0x00000010
731140751Swpaul#define IRP_DEALLOCATE_BUFFER           0x00000020
732140751Swpaul#define IRP_INPUT_OPERATION             0x00000040
733140751Swpaul#define IRP_SYNCHRONOUS_PAGING_IO       0x00000040
734140751Swpaul#define IRP_CREATE_OPERATION            0x00000080
735140751Swpaul#define IRP_READ_OPERATION              0x00000100
736140751Swpaul#define IRP_WRITE_OPERATION             0x00000200
737140751Swpaul#define IRP_CLOSE_OPERATION             0x00000400
738140751Swpaul#define IRP_DEFER_IO_COMPLETION         0x00000800
739140751Swpaul#define IRP_OB_QUERY_NAME               0x00001000
740140751Swpaul#define IRP_HOLD_DEVICE_QUEUE           0x00002000
741140751Swpaul#define IRP_RETRY_IO_COMPLETION         0x00004000
742140751Swpaul#define IRP_CLASS_CACHE_OPERATION       0x00008000
743140751Swpaul#define IRP_SET_USER_EVENT              IRP_CLOSE_OPERATION
744140751Swpaul
745140751Swpaul/* IRP I/O control flags */
746140751Swpaul
747140751Swpaul#define IRP_QUOTA_CHARGED               0x01
748140751Swpaul#define IRP_ALLOCATED_MUST_SUCCEED      0x02
749140751Swpaul#define IRP_ALLOCATED_FIXED_SIZE        0x04
750140751Swpaul#define IRP_LOOKASIDE_ALLOCATION        0x08
751140751Swpaul
752142311Swpaul/* I/O method types */
753142311Swpaul
754142311Swpaul#define METHOD_BUFFERED			0
755142311Swpaul#define METHOD_IN_DIRECT		1
756142311Swpaul#define METHOD_OUT_DIRECT		2
757142311Swpaul#define METHOD_NEITHER			3
758142311Swpaul
759142497Swpaul/* File access types */
760142497Swpaul
761142497Swpaul#define FILE_ANY_ACCESS			0x0000
762142497Swpaul#define FILE_SPECIAL_ACCESS		FILE_ANY_ACCESS
763142497Swpaul#define FILE_READ_ACCESS		0x0001
764142497Swpaul#define FILE_WRITE_ACCESS		0x0002
765142497Swpaul
766142497Swpaul/* Recover I/O access method from IOCTL code. */
767142497Swpaul
768142311Swpaul#define IO_METHOD(x)			((x) & 0xFFFFFFFC)
769142311Swpaul
770142497Swpaul/* Recover function code from IOCTL code */
771142497Swpaul
772142497Swpaul#define IO_FUNC(x)			(((x) & 0x7FFC) >> 2)
773142497Swpaul
774142497Swpaul/* Macro to construct an IOCTL code. */
775142497Swpaul
776142497Swpaul#define IOCTL_CODE(dev, func, iomethod, acc)	\
777142497Swpaul	((dev) << 16) | (acc << 14) | (func << 2) | (iomethod))
778142497Swpaul
779142497Swpaul
780140751Swpaulstruct io_status_block {
781140751Swpaul	union {
782140751Swpaul		uint32_t		isb_status;
783140751Swpaul		void			*isb_ptr;
784140751Swpaul	} u;
785140751Swpaul	register_t		isb_info;
786140751Swpaul};
787141524Swpaul#define isb_status		u.isb_status
788141524Swpaul#define isb_ptr			u.isb_ptr
789140751Swpaul
790140751Swpaultypedef struct io_status_block io_status_block;
791140751Swpaul
792140751Swpaulstruct kapc {
793140751Swpaul	uint16_t		apc_type;
794140751Swpaul	uint16_t		apc_size;
795140751Swpaul	uint32_t		apc_spare0;
796140751Swpaul	void			*apc_thread;
797140751Swpaul	list_entry		apc_list;
798140751Swpaul	void			*apc_kernfunc;
799140751Swpaul	void			*apc_rundownfunc;
800140751Swpaul	void			*apc_normalfunc;
801140751Swpaul	void			*apc_normctx;
802140751Swpaul	void			*apc_sysarg1;
803140751Swpaul	void			*apc_sysarg2;
804140751Swpaul	uint8_t			apc_stateidx;
805140751Swpaul	uint8_t			apc_cpumode;
806140751Swpaul	uint8_t			apc_inserted;
807140751Swpaul};
808140751Swpaul
809140751Swpaultypedef struct kapc kapc;
810140751Swpaul
811144888Swpaultypedef uint32_t (*completion_func)(device_object *,
812141524Swpaul	struct irp *, void *);
813144888Swpaultypedef uint32_t (*cancel_func)(device_object *,
814142311Swpaul	struct irp *);
815141524Swpaul
816140751Swpaulstruct io_stack_location {
817140751Swpaul	uint8_t			isl_major;
818140751Swpaul	uint8_t			isl_minor;
819140751Swpaul	uint8_t			isl_flags;
820140751Swpaul	uint8_t			isl_ctl;
821140751Swpaul
822140751Swpaul	/*
823140751Swpaul	 * There's a big-ass union here in the actual Windows
824140751Swpaul	 * definition of the stucture, but it contains stuff
825140751Swpaul	 * that doesn't really apply to BSD, and defining it
826140751Swpaul	 * all properly would require duplicating over a dozen
827140751Swpaul	 * other structures that we'll never use. Since the
828140751Swpaul	 * io_stack_location structure is opaque to drivers
829140751Swpaul	 * anyway, I'm not going to bother with the extra crap.
830140751Swpaul	 */
831140751Swpaul
832140751Swpaul	union {
833140751Swpaul		struct {
834142311Swpaul			uint32_t		isl_len;
835142311Swpaul			uint32_t		*isl_key;
836142311Swpaul			uint64_t		isl_byteoff;
837142311Swpaul		} isl_read;
838142311Swpaul		struct {
839142311Swpaul			uint32_t		isl_len;
840142311Swpaul			uint32_t		*isl_key;
841142311Swpaul			uint64_t		isl_byteoff;
842142311Swpaul		} isl_write;
843142311Swpaul		struct {
844142311Swpaul			uint32_t		isl_obuflen;
845142311Swpaul			uint32_t		isl_ibuflen;
846142311Swpaul			uint32_t		isl_iocode;
847142311Swpaul			void			*isl_type3ibuf;
848142311Swpaul		} isl_ioctl;
849142311Swpaul		struct {
850140751Swpaul			void			*isl_arg1;
851140751Swpaul			void			*isl_arg2;
852140751Swpaul			void			*isl_arg3;
853140751Swpaul			void			*isl_arg4;
854140751Swpaul		} isl_others;
855142311Swpaul	} isl_parameters __attribute__((packed));
856140751Swpaul
857140751Swpaul	void			*isl_devobj;
858140751Swpaul	void			*isl_fileobj;
859141524Swpaul	completion_func		isl_completionfunc;
860140751Swpaul	void			*isl_completionctx;
861140751Swpaul};
862140751Swpaul
863140751Swpaultypedef struct io_stack_location io_stack_location;
864140751Swpaul
865140751Swpaul/* Stack location control flags */
866140751Swpaul
867140751Swpaul#define SL_PENDING_RETURNED		0x01
868140751Swpaul#define SL_INVOKE_ON_CANCEL		0x20
869140751Swpaul#define SL_INVOKE_ON_SUCCESS		0x40
870140751Swpaul#define SL_INVOKE_ON_ERROR		0x80
871140751Swpaul
872125551Swpaulstruct irp {
873140751Swpaul	uint16_t		irp_type;
874140751Swpaul	uint16_t		irp_size;
875140751Swpaul	mdl			*irp_mdl;
876140751Swpaul	uint32_t		irp_flags;
877140751Swpaul	union {
878140751Swpaul		struct irp		*irp_master;
879140751Swpaul		uint32_t		irp_irpcnt;
880140751Swpaul		void			*irp_sysbuf;
881140751Swpaul	} irp_assoc;
882140751Swpaul	list_entry		irp_thlist;
883140751Swpaul	io_status_block		irp_iostat;
884140751Swpaul	uint8_t			irp_reqmode;
885140751Swpaul	uint8_t			irp_pendingreturned;
886140751Swpaul	uint8_t			irp_stackcnt;
887140751Swpaul	uint8_t			irp_currentstackloc;
888140751Swpaul	uint8_t			irp_cancel;
889140751Swpaul	uint8_t			irp_cancelirql;
890140751Swpaul	uint8_t			irp_apcenv;
891140751Swpaul	uint8_t			irp_allocflags;
892140751Swpaul	io_status_block		*irp_usriostat;
893141524Swpaul	nt_kevent		*irp_usrevent;
894140751Swpaul	union {
895140751Swpaul		struct {
896140751Swpaul			void			*irp_apcfunc;
897140751Swpaul			void			*irp_apcctx;
898140751Swpaul		} irp_asyncparms;
899140751Swpaul		uint64_t			irp_allocsz;
900140751Swpaul	} irp_overlay;
901142311Swpaul	cancel_func		irp_cancelfunc;
902140751Swpaul	void			*irp_userbuf;
903140751Swpaul
904140751Swpaul	/* Windows kernel info */
905140751Swpaul
906140751Swpaul	union {
907140751Swpaul		struct {
908140751Swpaul			union {
909140751Swpaul				kdevice_qentry			irp_dqe;
910140751Swpaul				struct {
911140751Swpaul					void 			*irp_drvctx[4];
912140751Swpaul				} s1;
913140751Swpaul			} u1;
914140751Swpaul			void			*irp_thread;
915140751Swpaul			char			*irp_auxbuf;
916140751Swpaul			struct {
917140751Swpaul				list_entry			irp_list;
918140751Swpaul				union {
919140751Swpaul					io_stack_location	*irp_csl;
920140751Swpaul					uint32_t		irp_pkttype;
921140751Swpaul				} u2;
922140751Swpaul			} s2;
923140751Swpaul			void			*irp_fileobj;
924140751Swpaul		} irp_overlay;
925140751Swpaul		kapc			irp_apc;
926140751Swpaul		void			*irp_compkey;
927140751Swpaul	} irp_tail;
928125551Swpaul};
929125551Swpaul
930140751Swpaul#define irp_csl			s2.u2.irp_csl
931140751Swpaul#define irp_pkttype		s2.u2.irp_pkttype
932140751Swpaul
933125551Swpaultypedef struct irp irp;
934125551Swpaul
935142311Swpaul#define InterlockedExchangePointer(dst, val)				\
936144888Swpaul	(void *)InterlockedExchange((uint32_t *)(dst), (uintptr_t)(val))
937142311Swpaul
938141524Swpaul#define IoSizeOfIrp(ssize)						\
939141524Swpaul	((uint16_t) (sizeof(irp) + ((ssize) * (sizeof(io_stack_location)))))
940141524Swpaul
941142311Swpaul#define IoSetCancelRoutine(irp, func)					\
942142311Swpaul	(cancel_func)InterlockedExchangePointer(			\
943142311Swpaul	(void *)&(ip)->irp_cancelfunc, (void *)(func))
944141524Swpaul
945140751Swpaul#define IoGetCurrentIrpStackLocation(irp)				\
946140751Swpaul	(irp)->irp_tail.irp_overlay.irp_csl
947140751Swpaul
948140751Swpaul#define IoGetNextIrpStackLocation(irp)					\
949140751Swpaul	((irp)->irp_tail.irp_overlay.irp_csl - 1)
950140751Swpaul
951141524Swpaul#define IoSetNextIrpStackLocation(irp)					\
952141524Swpaul	do {								\
953141524Swpaul		irp->irp_currentstackloc--;				\
954141524Swpaul		irp->irp_tail.irp_overlay.irp_csl--;			\
955141524Swpaul	} while(0)
956141524Swpaul
957140751Swpaul#define IoSetCompletionRoutine(irp, func, ctx, ok, err, cancel)		\
958140751Swpaul	do {								\
959140751Swpaul		io_stack_location		*s;			\
960140751Swpaul		s = IoGetNextIrpStackLocation((irp));			\
961140751Swpaul		s->isl_completionfunc = (func);				\
962140751Swpaul		s->isl_completionctx = (ctx);				\
963140751Swpaul		s->isl_ctl = 0;						\
964141524Swpaul		if (ok) s->isl_ctl = SL_INVOKE_ON_SUCCESS;		\
965141524Swpaul		if (err) s->isl_ctl |= SL_INVOKE_ON_ERROR;		\
966141524Swpaul		if (cancel) s->isl_ctl |= SL_INVOKE_ON_CANCEL;		\
967140751Swpaul	} while(0)
968140751Swpaul
969140751Swpaul#define IoMarkIrpPending(irp)						\
970140751Swpaul	IoGetCurrentIrpStackLocation(irp)->isl_ctl |= SL_PENDING_RETURNED
971140751Swpaul
972140751Swpaul#define IoCopyCurrentIrpStackLocationToNext(irp)			\
973140751Swpaul	do {								\
974140751Swpaul		io_stack_location *src, *dst;				\
975140751Swpaul		src = IoGetCurrentIrpStackLocation(irp);		\
976140751Swpaul		dst = IoGetNextIrpStackLocation(irp);			\
977140751Swpaul		bcopy((char *)src, (char *)dst,				\
978140751Swpaul		    offsetof(io_stack_location, isl_completionfunc));	\
979140751Swpaul	} while(0)
980140751Swpaul
981140751Swpaul#define IoSkipCurrentIrpStackLocation(irp)				\
982140751Swpaul	do {								\
983140751Swpaul		(irp)->irp_currentstackloc++;				\
984140751Swpaul		(irp)->irp_tail.irp_overlay.irp_csl++;			\
985140751Swpaul	} while(0)
986140751Swpaul
987144175Swpaul#define IoInitializeDpcRequest(dobj, dpcfunc)				\
988144175Swpaul	KeInitializeDpc(&(dobj)->do_dpc, dpcfunc, dobj)
989144175Swpaul
990144175Swpaul#define IoRequestDpc(dobj, irp, ctx)					\
991144175Swpaul	KeInsertQueueDpc(&(dobj)->do_dpc, irp, ctx)
992144175Swpaul
993144888Swpaultypedef uint32_t (*driver_dispatch)(device_object *, irp *);
994125551Swpaul
995140751Swpaul/*
996140751Swpaul * The driver_object is allocated once for each driver that's loaded
997140751Swpaul * into the system. A new one is allocated for each driver and
998140751Swpaul * populated a bit via the driver's DriverEntry function.
999140751Swpaul * In general, a Windows DriverEntry() function will provide a pointer
1000140751Swpaul * to its AddDevice() method and set up the dispatch table.
1001140751Swpaul * For NDIS drivers, this is all done behind the scenes in the
1002140751Swpaul * NdisInitializeWrapper() and/or NdisMRegisterMiniport() routines.
1003140751Swpaul */
1004140751Swpaul
1005140751Swpaulstruct driver_object {
1006140751Swpaul	uint16_t		dro_type;
1007140751Swpaul	uint16_t		dro_size;
1008140751Swpaul	device_object		*dro_devobj;
1009140751Swpaul	uint32_t		dro_flags;
1010140751Swpaul	void			*dro_driverstart;
1011140751Swpaul	uint32_t		dro_driversize;
1012140751Swpaul	void			*dro_driversection;
1013141524Swpaul	driver_extension	*dro_driverext;
1014140751Swpaul	unicode_string		dro_drivername;
1015140751Swpaul	unicode_string		*dro_hwdb;
1016140751Swpaul	void			*dro_pfastiodispatch;
1017140751Swpaul	void			*dro_driverinitfunc;
1018140751Swpaul	void			*dro_driverstartiofunc;
1019140751Swpaul	void			*dro_driverunloadfunc;
1020141524Swpaul	driver_dispatch		dro_dispatch[IRP_MJ_MAXIMUM_FUNCTION + 1];
1021140751Swpaul};
1022140751Swpaul
1023140751Swpaultypedef struct driver_object driver_object;
1024140751Swpaul
1025125551Swpaul#define DEVPROP_DEVICE_DESCRIPTION	0x00000000
1026125551Swpaul#define DEVPROP_HARDWARE_ID		0x00000001
1027125551Swpaul#define DEVPROP_COMPATIBLE_IDS		0x00000002
1028125551Swpaul#define DEVPROP_BOOTCONF		0x00000003
1029125551Swpaul#define DEVPROP_BOOTCONF_TRANSLATED	0x00000004
1030125551Swpaul#define DEVPROP_CLASS_NAME		0x00000005
1031125551Swpaul#define DEVPROP_CLASS_GUID		0x00000006
1032125551Swpaul#define DEVPROP_DRIVER_KEYNAME		0x00000007
1033125551Swpaul#define DEVPROP_MANUFACTURER		0x00000008
1034125551Swpaul#define DEVPROP_FRIENDLYNAME		0x00000009
1035125551Swpaul#define DEVPROP_LOCATION_INFO		0x0000000A
1036125551Swpaul#define DEVPROP_PHYSDEV_NAME		0x0000000B
1037125551Swpaul#define DEVPROP_BUSTYPE_GUID		0x0000000C
1038125551Swpaul#define DEVPROP_LEGACY_BUSTYPE		0x0000000D
1039125551Swpaul#define DEVPROP_BUS_NUMBER		0x0000000E
1040125551Swpaul#define DEVPROP_ENUMERATOR_NAME		0x0000000F
1041125551Swpaul#define DEVPROP_ADDRESS			0x00000010
1042125551Swpaul#define DEVPROP_UINUMBER		0x00000011
1043125551Swpaul#define DEVPROP_INSTALL_STATE		0x00000012
1044125551Swpaul#define DEVPROP_REMOVAL_POLICY		0x00000013
1045125551Swpaul
1046141524Swpaul/* Various supported device types (used with IoCreateDevice()) */
1047141524Swpaul
1048141524Swpaul#define FILE_DEVICE_BEEP		0x00000001
1049141524Swpaul#define FILE_DEVICE_CD_ROM		0x00000002
1050141524Swpaul#define FILE_DEVICE_CD_ROM_FILE_SYSTEM	0x00000003
1051141524Swpaul#define FILE_DEVICE_CONTROLLER		0x00000004
1052141524Swpaul#define FILE_DEVICE_DATALINK		0x00000005
1053141524Swpaul#define FILE_DEVICE_DFS			0x00000006
1054141524Swpaul#define FILE_DEVICE_DISK		0x00000007
1055141524Swpaul#define FILE_DEVICE_DISK_FILE_SYSTEM	0x00000008
1056141524Swpaul#define FILE_DEVICE_FILE_SYSTEM		0x00000009
1057141524Swpaul#define FILE_DEVICE_INPORT_PORT		0x0000000A
1058141524Swpaul#define FILE_DEVICE_KEYBOARD		0x0000000B
1059141524Swpaul#define FILE_DEVICE_MAILSLOT		0x0000000C
1060141524Swpaul#define FILE_DEVICE_MIDI_IN		0x0000000D
1061141524Swpaul#define FILE_DEVICE_MIDI_OUT		0x0000000E
1062141524Swpaul#define FILE_DEVICE_MOUSE		0x0000000F
1063141524Swpaul#define FILE_DEVICE_MULTI_UNC_PROVIDER	0x00000010
1064141524Swpaul#define FILE_DEVICE_NAMED_PIPE		0x00000011
1065141524Swpaul#define FILE_DEVICE_NETWORK		0x00000012
1066141524Swpaul#define FILE_DEVICE_NETWORK_BROWSER	0x00000013
1067141524Swpaul#define FILE_DEVICE_NETWORK_FILE_SYSTEM	0x00000014
1068141524Swpaul#define FILE_DEVICE_NULL		0x00000015
1069141524Swpaul#define FILE_DEVICE_PARALLEL_PORT	0x00000016
1070141524Swpaul#define FILE_DEVICE_PHYSICAL_NETCARD	0x00000017
1071141524Swpaul#define FILE_DEVICE_PRINTER		0x00000018
1072141524Swpaul#define FILE_DEVICE_SCANNER		0x00000019
1073141524Swpaul#define FILE_DEVICE_SERIAL_MOUSE_PORT	0x0000001A
1074141524Swpaul#define FILE_DEVICE_SERIAL_PORT		0x0000001B
1075141524Swpaul#define FILE_DEVICE_SCREEN		0x0000001C
1076141524Swpaul#define FILE_DEVICE_SOUND		0x0000001D
1077141524Swpaul#define FILE_DEVICE_STREAMS		0x0000001E
1078141524Swpaul#define FILE_DEVICE_TAPE		0x0000001F
1079141524Swpaul#define FILE_DEVICE_TAPE_FILE_SYSTEM	0x00000020
1080141524Swpaul#define FILE_DEVICE_TRANSPORT		0x00000021
1081141524Swpaul#define FILE_DEVICE_UNKNOWN		0x00000022
1082141524Swpaul#define FILE_DEVICE_VIDEO		0x00000023
1083141524Swpaul#define FILE_DEVICE_VIRTUAL_DISK	0x00000024
1084141524Swpaul#define FILE_DEVICE_WAVE_IN		0x00000025
1085141524Swpaul#define FILE_DEVICE_WAVE_OUT		0x00000026
1086141524Swpaul#define FILE_DEVICE_8042_PORT		0x00000027
1087141524Swpaul#define FILE_DEVICE_NETWORK_REDIRECTOR	0x00000028
1088141524Swpaul#define FILE_DEVICE_BATTERY		0x00000029
1089141524Swpaul#define FILE_DEVICE_BUS_EXTENDER	0x0000002A
1090141524Swpaul#define FILE_DEVICE_MODEM		0x0000002B
1091141524Swpaul#define FILE_DEVICE_VDM			0x0000002C
1092141524Swpaul#define FILE_DEVICE_MASS_STORAGE	0x0000002D
1093141524Swpaul#define FILE_DEVICE_SMB			0x0000002E
1094141524Swpaul#define FILE_DEVICE_KS			0x0000002F
1095141524Swpaul#define FILE_DEVICE_CHANGER		0x00000030
1096141524Swpaul#define FILE_DEVICE_SMARTCARD		0x00000031
1097141524Swpaul#define FILE_DEVICE_ACPI		0x00000032
1098141524Swpaul#define FILE_DEVICE_DVD			0x00000033
1099141524Swpaul#define FILE_DEVICE_FULLSCREEN_VIDEO	0x00000034
1100141524Swpaul#define FILE_DEVICE_DFS_FILE_SYSTEM	0x00000035
1101141524Swpaul#define FILE_DEVICE_DFS_VOLUME		0x00000036
1102141524Swpaul#define FILE_DEVICE_SERENUM		0x00000037
1103141524Swpaul#define FILE_DEVICE_TERMSRV		0x00000038
1104141524Swpaul#define FILE_DEVICE_KSEC		0x00000039
1105141524Swpaul#define FILE_DEVICE_FIPS		0x0000003A
1106141524Swpaul
1107141524Swpaul/* Device characteristics */
1108141524Swpaul
1109141524Swpaul#define FILE_REMOVABLE_MEDIA		0x00000001
1110141524Swpaul#define FILE_READ_ONLY_DEVICE		0x00000002
1111141524Swpaul#define FILE_FLOPPY_DISKETTE		0x00000004
1112141524Swpaul#define FILE_WRITE_ONCE_MEDIA		0x00000008
1113141524Swpaul#define FILE_REMOTE_DEVICE		0x00000010
1114141524Swpaul#define FILE_DEVICE_IS_MOUNTED		0x00000020
1115141524Swpaul#define FILE_VIRTUAL_VOLUME		0x00000040
1116141524Swpaul#define FILE_AUTOGENERATED_DEVICE_NAME	0x00000080
1117141524Swpaul#define FILE_DEVICE_SECURE_OPEN		0x00000100
1118141524Swpaul
1119141524Swpaul/* Status codes */
1120141524Swpaul
1121125551Swpaul#define STATUS_SUCCESS			0x00000000
1122125551Swpaul#define STATUS_USER_APC			0x000000C0
1123125551Swpaul#define STATUS_KERNEL_APC		0x00000100
1124125551Swpaul#define STATUS_ALERTED			0x00000101
1125125551Swpaul#define STATUS_TIMEOUT			0x00000102
1126142443Swpaul#define STATUS_PENDING			0x00000103
1127125551Swpaul#define STATUS_INVALID_PARAMETER	0xC000000D
1128125551Swpaul#define STATUS_INVALID_DEVICE_REQUEST	0xC0000010
1129141524Swpaul#define STATUS_MORE_PROCESSING_REQUIRED	0xC0000016
1130125551Swpaul#define STATUS_BUFFER_TOO_SMALL		0xC0000023
1131125551Swpaul#define STATUS_MUTANT_NOT_OWNED		0xC0000046
1132125551Swpaul#define STATUS_INVALID_PARAMETER_2	0xC00000F0
1133141524Swpaul#define STATUS_INSUFFICIENT_RESOURCES	0xC000009A
1134125551Swpaul
1135125551Swpaul#define STATUS_WAIT_0			0x00000000
1136125551Swpaul
1137141524Swpaul/* Memory pool types, for ExAllocatePoolWithTag() */
1138141524Swpaul
1139141524Swpaul#define NonPagedPool			0x00000000
1140141524Swpaul#define PagedPool			0x00000001
1141141524Swpaul#define NonPagedPoolMustSucceed		0x00000002
1142141524Swpaul#define DontUseThisType			0x00000003
1143141524Swpaul#define NonPagedPoolCacheAligned	0x00000004
1144141524Swpaul#define PagedPoolCacheAligned		0x00000005
1145141524Swpaul#define NonPagedPoolCacheAlignedMustS	0x00000006
1146141524Swpaul#define MaxPoolType			0x00000007
1147141524Swpaul
1148127284Swpaul/*
1149127284Swpaul * FreeBSD's kernel stack is 2 pages in size by default. The
1150127284Swpaul * Windows stack is larger, so we need to give our threads more
1151127284Swpaul * stack pages. 4 should be enough, we use 8 just to extra safe.
1152127284Swpaul */
1153127284Swpaul#define NDIS_KSTACK_PAGES	8
1154127284Swpaul
1155144888Swpaul/*
1156144888Swpaul * Different kinds of function wrapping we can do.
1157144888Swpaul */
1158144888Swpaul
1159144888Swpaul#define WINDRV_WRAP_STDCALL	1
1160144888Swpaul#define WINDRV_WRAP_FASTCALL	2
1161144888Swpaul#define WINDRV_WRAP_REGPARM	3
1162144888Swpaul#define WINDRV_WRAP_CDECL	4
1163144888Swpaul#define WINDRV_WRAP_AMD64	5
1164144888Swpaul
1165145485Swpaulstruct drvdb_ent {
1166145485Swpaul	driver_object		*windrv_object;
1167145485Swpaul	void			*windrv_devlist;
1168145485Swpaul	ndis_cfg		*windrv_regvals;
1169145485Swpaul	interface_type		windrv_bustype;
1170145485Swpaul	STAILQ_ENTRY(drvdb_ent) link;
1171145485Swpaul};
1172145485Swpaul
1173123474Swpaulextern image_patch_table ntoskrnl_functbl[];
1174141963Swpaultypedef void (*funcptr)(void);
1175145485Swpaultypedef int (*matchfuncptr)(void *, void *);
1176123474Swpaul
1177123474Swpaul__BEGIN_DECLS
1178141524Swpaulextern int windrv_libinit(void);
1179141524Swpaulextern int windrv_libfini(void);
1180142399Swpaulextern driver_object *windrv_lookup(vm_offset_t, char *);
1181145485Swpaulextern struct drvdb_ent *windrv_match(matchfuncptr, void *);
1182145485Swpaulextern int windrv_load(module_t, vm_offset_t, int, interface_type,
1183145485Swpaul	void *, ndis_cfg *);
1184141524Swpaulextern int windrv_unload(module_t, vm_offset_t, int);
1185141524Swpaulextern int windrv_create_pdo(driver_object *, device_t);
1186141524Swpaulextern void windrv_destroy_pdo(driver_object *, device_t);
1187141524Swpaulextern device_object *windrv_find_pdo(driver_object *, device_t);
1188141524Swpaulextern int windrv_bus_attach(driver_object *, char *);
1189144888Swpaulextern int windrv_wrap(funcptr, funcptr *, int, int);
1190141963Swpaulextern int windrv_unwrap(funcptr);
1191144888Swpaulextern void ctxsw_utow(void);
1192144888Swpaulextern void ctxsw_wtou(void);
1193141524Swpaul
1194123474Swpaulextern int ntoskrnl_libinit(void);
1195123474Swpaulextern int ntoskrnl_libfini(void);
1196144888Swpaulextern void KeInitializeDpc(kdpc *, void *, void *);
1197144888Swpaulextern uint8_t KeInsertQueueDpc(kdpc *, void *, void *);
1198144888Swpaulextern uint8_t KeRemoveQueueDpc(kdpc *);
1199144888Swpaulextern void KeInitializeTimer(ktimer *);
1200144888Swpaulextern void KeInitializeTimerEx(ktimer *, uint32_t);
1201144888Swpaulextern uint8_t KeSetTimer(ktimer *, int64_t, kdpc *);
1202144888Swpaulextern uint8_t KeSetTimerEx(ktimer *, int64_t, uint32_t, kdpc *);
1203144888Swpaulextern uint8_t KeCancelTimer(ktimer *);
1204144888Swpaulextern uint8_t KeReadStateTimer(ktimer *);
1205144888Swpaulextern uint32_t KeWaitForSingleObject(nt_dispatch_header *, uint32_t,
1206127248Swpaul	uint32_t, uint8_t, int64_t *);
1207144888Swpaulextern void KeInitializeEvent(nt_kevent *, uint32_t, uint8_t);
1208144888Swpaulextern void KeClearEvent(nt_kevent *);
1209144888Swpaulextern uint32_t KeReadStateEvent(nt_kevent *);
1210144888Swpaulextern uint32_t KeSetEvent(nt_kevent *, uint32_t, uint8_t);
1211144888Swpaulextern uint32_t KeResetEvent(nt_kevent *);
1212144175Swpaul#ifdef __i386__
1213144888Swpaulextern void KefAcquireSpinLockAtDpcLevel(kspin_lock *);
1214144888Swpaulextern void KefReleaseSpinLockFromDpcLevel(kspin_lock *);
1215144888Swpaulextern uint8_t KeAcquireSpinLockRaiseToDpc(kspin_lock *);
1216144175Swpaul#else
1217144888Swpaulextern void KeAcquireSpinLockAtDpcLevel(kspin_lock *);
1218144888Swpaulextern void KeReleaseSpinLockFromDpcLevel(kspin_lock *);
1219144175Swpaul#endif
1220144888Swpaulextern void KeInitializeSpinLock(kspin_lock *);
1221144888Swpaulextern uintptr_t InterlockedExchange(volatile uint32_t *,
1222144888Swpaul	uintptr_t);
1223144888Swpaulextern void *ExAllocatePoolWithTag(uint32_t, size_t, uint32_t);
1224144888Swpaulextern void ExFreePool(void *);
1225144888Swpaulextern uint32_t IoAllocateDriverObjectExtension(driver_object *,
1226141524Swpaul	void *, uint32_t, void **);
1227144888Swpaulextern void *IoGetDriverObjectExtension(driver_object *, void *);
1228144888Swpaulextern uint32_t IoCreateDevice(driver_object *, uint32_t,
1229141524Swpaul	unicode_string *, uint32_t, uint32_t, uint8_t, device_object **);
1230144888Swpaulextern void IoDeleteDevice(device_object *);
1231144888Swpaulextern device_object *IoGetAttachedDevice(device_object *);
1232144888Swpaulextern uint32_t IofCallDriver(device_object *, irp *);
1233144888Swpaulextern void IofCompleteRequest(irp *, uint8_t);
1234144888Swpaulextern void IoAcquireCancelSpinLock(uint8_t *);
1235144888Swpaulextern void IoReleaseCancelSpinLock(uint8_t);
1236144888Swpaulextern uint8_t IoCancelIrp(irp *);
1237144888Swpaulextern void IoDetachDevice(device_object *);
1238144888Swpaulextern device_object *IoAttachDeviceToDeviceStack(device_object *,
1239141524Swpaul	device_object *);
1240144888Swpaulmdl *IoAllocateMdl(void *, uint32_t, uint8_t, uint8_t, irp *);
1241144888Swpaulvoid IoFreeMdl(mdl *);
1242128229Swpaul
1243144888Swpaul#define IoCallDriver(a, b)		IofCallDriver(a, b)
1244144888Swpaul#define IoCompleteRequest(a, b)		IofCompleteRequest(a, b)
1245140751Swpaul
1246128229Swpaul/*
1247128229Swpaul * On the Windows x86 arch, KeAcquireSpinLock() and KeReleaseSpinLock()
1248128229Swpaul * routines live in the HAL. We try to imitate this behavior.
1249128229Swpaul */
1250128229Swpaul#ifdef __i386__
1251144888Swpaul#define KeAcquireSpinLock(a, b)	*(b) = KfAcquireSpinLock(a)
1252144888Swpaul#define KeReleaseSpinLock(a, b)	KfReleaseSpinLock(a, b)
1253144888Swpaul#define KeRaiseIrql(a)		KfRaiseIrql(a)
1254144888Swpaul#define KeLowerIrql(a)		KfLowerIrql(a)
1255144888Swpaul#define KeAcquireSpinLockAtDpcLevel(a)	KefAcquireSpinLockAtDpcLevel(a)
1256144888Swpaul#define KeReleaseSpinLockFromDpcLevel(a)  KefReleaseSpinLockFromDpcLevel(a)
1257128229Swpaul#endif /* __i386__ */
1258141963Swpaul
1259141963Swpaul#ifdef __amd64__
1260141980Swpaul#define KeAcquireSpinLock(a, b)	*(b) = KfAcquireSpinLock(a)
1261141980Swpaul#define KeReleaseSpinLock(a, b)	KfReleaseSpinLock(a, b)
1262141963Swpaul
1263141963Swpaul/*
1264141963Swpaul * These may need to be redefined later;
1265141963Swpaul * not sure where they live on amd64 yet.
1266141963Swpaul */
1267141963Swpaul#define KeRaiseIrql(a)		KfRaiseIrql(a)
1268141963Swpaul#define KeLowerIrql(a)		KfLowerIrql(a)
1269141963Swpaul#endif /* __amd64__ */
1270141963Swpaul
1271123474Swpaul__END_DECLS
1272123474Swpaul
1273123474Swpaul#endif /* _NTOSKRNL_VAR_H_ */
1274