ntoskrnl_var.h revision 151451
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 151451 2005-10-18 19:52:15Z wpaul $
33123474Swpaul */
34123474Swpaul
35123474Swpaul#ifndef _NTOSKRNL_VAR_H_
36123474Swpaul#define _NTOSKRNL_VAR_H_
37123474Swpaul
38151451Swpaul#define MTX_NTOSKRNL_SPIN_LOCK "NDIS thread lock"
39151451Swpaul
40140751Swpaul/*
41140751Swpaul * us_buf is really a wchar_t *, but it's inconvenient to include
42140751Swpaul * all the necessary header goop needed to define it, and it's a
43140751Swpaul * pointer anyway, so for now, just make it a uint16_t *.
44140751Swpaul */
45140751Swpaulstruct unicode_string {
46140751Swpaul	uint16_t		us_len;
47140751Swpaul	uint16_t		us_maxlen;
48140751Swpaul	uint16_t		*us_buf;
49140751Swpaul};
50140751Swpaul
51140751Swpaultypedef struct unicode_string unicode_string;
52140751Swpaul
53151207Swpaulstruct ansi_string {
54151207Swpaul	uint16_t		as_len;
55151207Swpaul	uint16_t		as_maxlen;
56151207Swpaul	char			*as_buf;
57151207Swpaul};
58151207Swpaul
59151207Swpaultypedef struct ansi_string ansi_string;
60151207Swpaul
61140751Swpaul/*
62140751Swpaul * Windows memory descriptor list. In Windows, it's possible for
63140751Swpaul * buffers to be passed between user and kernel contexts without
64140751Swpaul * copying. Buffers may also be allocated in either paged or
65140751Swpaul * non-paged memory regions. An MDL describes the pages of memory
66140751Swpaul * used to contain a particular buffer. Note that a single MDL
67140751Swpaul * may describe a buffer that spans multiple pages. An array of
68140751Swpaul * page addresses appears immediately after the MDL structure itself.
69140751Swpaul * MDLs are therefore implicitly variably sized, even though they
70140751Swpaul * don't look it.
71140751Swpaul *
72140751Swpaul * Note that in FreeBSD, we can take many shortcuts in the way
73140751Swpaul * we handle MDLs because:
74140751Swpaul *
75140751Swpaul * - We are only concerned with pages in kernel context. This means
76140751Swpaul *   we will only ever use the kernel's memory map, and remapping
77140751Swpaul *   of buffers is never needed.
78140751Swpaul *
79140751Swpaul * - Kernel pages can never be paged out, so we don't have to worry
80140751Swpaul *   about whether or not a page is actually mapped before going to
81140751Swpaul *   touch it.
82140751Swpaul */
83140751Swpaul
84140751Swpaulstruct mdl {
85140751Swpaul        struct mdl		*mdl_next;
86140751Swpaul	uint16_t		mdl_size;
87140751Swpaul	uint16_t		mdl_flags;
88140751Swpaul	void			*mdl_process;
89140751Swpaul	void			*mdl_mappedsystemva;
90140751Swpaul	void			*mdl_startva;
91140751Swpaul	uint32_t		mdl_bytecount;
92140751Swpaul	uint32_t		mdl_byteoffset;
93140751Swpaul};
94140751Swpaul
95140751Swpaultypedef struct mdl mdl, ndis_buffer;
96140751Swpaul
97140751Swpaul/* MDL flags */
98140751Swpaul
99140751Swpaul#define MDL_MAPPED_TO_SYSTEM_VA		0x0001
100140751Swpaul#define MDL_PAGES_LOCKED		0x0002
101140751Swpaul#define MDL_SOURCE_IS_NONPAGED_POOL	0x0004
102140751Swpaul#define MDL_ALLOCATED_FIXED_SIZE	0x0008
103140751Swpaul#define MDL_PARTIAL			0x0010
104140751Swpaul#define MDL_PARTIAL_HAS_BEEN_MAPPED	0x0020
105140751Swpaul#define MDL_IO_PAGE_READ		0x0040
106140751Swpaul#define MDL_WRITE_OPERATION		0x0080
107140751Swpaul#define MDL_PARENT_MAPPED_SYSTEM_VA	0x0100
108140751Swpaul#define MDL_FREE_EXTRA_PTES		0x0200
109140751Swpaul#define MDL_IO_SPACE			0x0800
110140751Swpaul#define MDL_NETWORK_HEADER		0x1000
111140751Swpaul#define MDL_MAPPING_CAN_FAIL		0x2000
112140751Swpaul#define MDL_ALLOCATED_MUST_SUCCEED	0x4000
113142530Swpaul#define MDL_ZONE_ALLOCED		0x8000	/* BSD private */
114140751Swpaul
115142530Swpaul#define MDL_ZONE_PAGES 16
116142530Swpaul#define MDL_ZONE_SIZE (sizeof(mdl) + (sizeof(vm_offset_t) * MDL_ZONE_PAGES))
117142530Swpaul
118123512Swpaul/* Note: assumes x86 page size of 4K. */
119140751Swpaul
120140751Swpaul#if PAGE_SIZE == 4096
121123512Swpaul#define PAGE_SHIFT	12
122140751Swpaul#elif PAGE_SIZE == 8192
123140751Swpaul#define PAGE_SHIFT	13
124140751Swpaul#else
125140751Swpaul#error PAGE_SHIFT undefined!
126140751Swpaul#endif
127140751Swpaul
128123512Swpaul#define SPAN_PAGES(ptr, len)					\
129140751Swpaul	((uint32_t)((((uintptr_t)(ptr) & (PAGE_SIZE - 1)) +	\
130123512Swpaul	(len) + (PAGE_SIZE - 1)) >> PAGE_SHIFT))
131140751Swpaul
132123757Swpaul#define PAGE_ALIGN(ptr)						\
133123757Swpaul	((void *)((uintptr_t)(ptr) & ~(PAGE_SIZE - 1)))
134140751Swpaul
135123757Swpaul#define BYTE_OFFSET(ptr)					\
136123757Swpaul	((uint32_t)((uintptr_t)(ptr) & (PAGE_SIZE - 1)))
137140751Swpaul
138140751Swpaul#define MDL_PAGES(m)	(vm_offset_t *)(m + 1)
139140751Swpaul
140140751Swpaul#define MmInitializeMdl(b, baseva, len)					\
141140751Swpaul	(b)->mdl_next = NULL;						\
142140751Swpaul	(b)->mdl_size = (uint16_t)(sizeof(mdl) +			\
143144175Swpaul		(sizeof(vm_offset_t) * SPAN_PAGES((baseva), (len))));	\
144140751Swpaul	(b)->mdl_flags = 0;						\
145140751Swpaul	(b)->mdl_startva = (void *)PAGE_ALIGN((baseva));		\
146140751Swpaul	(b)->mdl_byteoffset = BYTE_OFFSET((baseva));			\
147140751Swpaul	(b)->mdl_bytecount = (uint32_t)(len);
148123512Swpaul
149140751Swpaul#define MmGetMdlByteOffset(mdl)		((mdl)->mdl_byteoffset)
150140751Swpaul#define MmGetMdlByteCount(mdl)		((mdl)->mdl_bytecount)
151140751Swpaul#define MmGetMdlVirtualAddress(mdl)					\
152140751Swpaul	((void *)((char *)((mdl)->mdl_startva) + (mdl)->mdl_byteoffset))
153140751Swpaul#define MmGetMdlStartVa(mdl)		((mdl)->mdl_startva)
154140751Swpaul#define MmGetMdlPfnArray(mdl)		MDL_PAGES(mdl)
155140751Swpaul
156124729Swpaul#define WDM_MAJOR		1
157124729Swpaul#define WDM_MINOR_WIN98		0x00
158124729Swpaul#define WDM_MINOR_WINME		0x05
159124729Swpaul#define WDM_MINOR_WIN2000	0x10
160124729Swpaul#define WDM_MINOR_WINXP		0x20
161124729Swpaul#define WDM_MINOR_WIN2003	0x30
162124729Swpaul
163124582Sobrien/*-
164124582Sobrien * The ndis_kspin_lock type is called KSPIN_LOCK in MS-Windows.
165124582Sobrien * According to the Windows DDK header files, KSPIN_LOCK is defined like this:
166124582Sobrien *	typedef ULONG_PTR KSPIN_LOCK;
167124582Sobrien *
168124582Sobrien * From basetsd.h (SDK, Feb. 2003):
169124582Sobrien * 	typedef [public] unsigned __int3264 ULONG_PTR, *PULONG_PTR;
170124582Sobrien * 	typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
171124582Sobrien * 	typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR;
172124582Sobrien *
173124582Sobrien * The keyword __int3264 specifies an integral type that has the following
174124582Sobrien * properties:
175124582Sobrien *	+ It is 32-bit on 32-bit platforms
176124582Sobrien *	+ It is 64-bit on 64-bit platforms
177124582Sobrien *	+ It is 32-bit on the wire for backward compatibility.
178124582Sobrien *	  It gets truncated on the sending side and extended appropriately
179124582Sobrien *	  (signed or unsigned) on the receiving side.
180124582Sobrien *
181124582Sobrien * Thus register_t seems the proper mapping onto FreeBSD for spin locks.
182124582Sobrien */
183123474Swpaul
184124582Sobrientypedef register_t kspin_lock;
185124582Sobrien
186123474Swpaulstruct slist_entry {
187123474Swpaul	struct slist_entry	*sl_next;
188123474Swpaul};
189123474Swpaul
190123474Swpaultypedef struct slist_entry slist_entry;
191123474Swpaul
192123474Swpaulunion slist_header {
193123474Swpaul	uint64_t		slh_align;
194123474Swpaul	struct {
195123474Swpaul		struct slist_entry	*slh_next;
196123474Swpaul		uint16_t		slh_depth;
197123474Swpaul		uint16_t		slh_seq;
198123474Swpaul	} slh_list;
199123474Swpaul};
200123474Swpaul
201123474Swpaultypedef union slist_header slist_header;
202123474Swpaul
203123507Swpaulstruct list_entry {
204123507Swpaul        struct list_entry *nle_flink;
205123507Swpaul        struct list_entry *nle_blink;
206123507Swpaul};
207123507Swpaul
208123507Swpaultypedef struct list_entry list_entry;
209123507Swpaul
210151207Swpaul#define InitializeListHead(l)			\
211141524Swpaul	(l)->nle_flink = (l)->nle_blink = (l)
212125551Swpaul
213151207Swpaul#define IsListEmpty(h)				\
214151207Swpaul	((h)->nle_flink == (h))
215151207Swpaul
216151207Swpaul#define RemoveEntryList(e)			\
217125551Swpaul	do {					\
218125551Swpaul		list_entry		*b;	\
219125551Swpaul		list_entry		*f;	\
220125551Swpaul						\
221151207Swpaul		f = (e)->nle_flink;		\
222151207Swpaul		b = (e)->nle_blink;		\
223125551Swpaul		b->nle_flink = f;		\
224125551Swpaul		f->nle_blink = b;		\
225125551Swpaul	} while (0)
226125551Swpaul
227151207Swpaul/* These two have to be inlined since they return things. */
228125551Swpaul
229151207Swpaulstatic __inline__ list_entry *
230151207SwpaulRemoveHeadList(list_entry *l)
231151207Swpaul{
232151207Swpaul	list_entry		*f;
233151207Swpaul	list_entry		*e;
234125551Swpaul
235151207Swpaul	e = l->nle_flink;
236151207Swpaul	f = e->nle_flink;
237151207Swpaul	l->nle_flink = f;
238151207Swpaul	f->nle_blink = l;
239151207Swpaul
240151207Swpaul	return (e);
241151207Swpaul}
242151207Swpaul
243151207Swpaulstatic __inline__ list_entry *
244151207SwpaulRemoveTailList(list_entry *l)
245151207Swpaul{
246151207Swpaul	list_entry		*b;
247151207Swpaul	list_entry		*e;
248151207Swpaul
249151207Swpaul	e = l->nle_blink;
250151207Swpaul	b = e->nle_blink;
251151207Swpaul	l->nle_blink = b;
252151207Swpaul	b->nle_flink = l;
253151207Swpaul
254151207Swpaul	return (e);
255151207Swpaul}
256151207Swpaul
257151207Swpaul#define InsertTailList(l, e)			\
258125551Swpaul	do {					\
259125551Swpaul		list_entry		*b;	\
260125551Swpaul						\
261125551Swpaul		b = l->nle_blink;		\
262125860Swpaul		e->nle_flink = l;		\
263125551Swpaul		e->nle_blink = b;		\
264141524Swpaul		b->nle_flink = (e);		\
265141524Swpaul		l->nle_blink = (e);		\
266125551Swpaul	} while (0)
267125551Swpaul
268151207Swpaul#define InsertHeadList(l, e)			\
269125551Swpaul	do {					\
270125551Swpaul		list_entry		*f;	\
271125551Swpaul						\
272125551Swpaul		f = l->nle_flink;		\
273125551Swpaul		e->nle_flink = f;		\
274125551Swpaul		e->nle_blink = l;		\
275125551Swpaul		f->nle_blink = e;		\
276125551Swpaul		l->nle_flink = e;		\
277125551Swpaul	} while (0)
278125551Swpaul
279145895Swpaul#define CONTAINING_RECORD(addr, type, field)	\
280145895Swpaul	((type *)((vm_offset_t)(addr) - (vm_offset_t)(&((type *)0)->field)))
281145895Swpaul
282125551Swpaulstruct nt_dispatch_header {
283125551Swpaul	uint8_t			dh_type;
284125551Swpaul	uint8_t			dh_abs;
285125551Swpaul	uint8_t			dh_size;
286125551Swpaul	uint8_t			dh_inserted;
287151207Swpaul	int32_t			dh_sigstate;
288125551Swpaul	list_entry		dh_waitlisthead;
289125551Swpaul};
290125551Swpaul
291125551Swpaultypedef struct nt_dispatch_header nt_dispatch_header;
292125551Swpaul
293151207Swpaul/* Dispatcher object types */
294151207Swpaul
295151207Swpaul#define DISP_TYPE_NOTIFICATION_EVENT	0	/* KEVENT */
296151207Swpaul#define DISP_TYPE_SYNCHRONIZATION_EVENT	1	/* KEVENT */
297151207Swpaul#define DISP_TYPE_MUTANT		2	/* KMUTANT/KMUTEX */
298151207Swpaul#define DISP_TYPE_PROCESS		3	/* KPROCESS */
299151207Swpaul#define DISP_TYPE_QUEUE			4	/* KQUEUE */
300151207Swpaul#define DISP_TYPE_SEMAPHORE		5	/* KSEMAPHORE */
301151207Swpaul#define DISP_TYPE_THREAD		6	/* KTHREAD */
302151207Swpaul#define DISP_TYPE_NOTIFICATION_TIMER	8	/* KTIMER */
303151207Swpaul#define DISP_TYPE_SYNCHRONIZATION_TIMER	9	/* KTIMER */
304151207Swpaul
305125551Swpaul#define OTYPE_EVENT		0
306125551Swpaul#define OTYPE_MUTEX		1
307125551Swpaul#define OTYPE_THREAD		2
308125551Swpaul#define OTYPE_TIMER		3
309125551Swpaul
310125551Swpaul/* Windows dispatcher levels. */
311125551Swpaul
312125551Swpaul#define PASSIVE_LEVEL		0
313125551Swpaul#define LOW_LEVEL		0
314125551Swpaul#define APC_LEVEL		1
315125551Swpaul#define DISPATCH_LEVEL		2
316128229Swpaul#define DEVICE_LEVEL		(DISPATCH_LEVEL + 1)
317125551Swpaul#define PROFILE_LEVEL		27
318125551Swpaul#define CLOCK1_LEVEL		28
319125551Swpaul#define CLOCK2_LEVEL		28
320125551Swpaul#define IPI_LEVEL		29
321125551Swpaul#define POWER_LEVEL		30
322125551Swpaul#define HIGH_LEVEL		31
323125551Swpaul
324125551Swpaul#define SYNC_LEVEL_UP		DISPATCH_LEVEL
325125551Swpaul#define SYNC_LEVEL_MP		(IPI_LEVEL - 1)
326125551Swpaul
327128229Swpaul#define AT_PASSIVE_LEVEL(td)		\
328128229Swpaul	((td)->td_proc->p_flag & P_KTHREAD == FALSE)
329128229Swpaul
330128229Swpaul#define AT_DISPATCH_LEVEL(td)		\
331128449Swpaul	((td)->td_base_pri == PI_REALTIME)
332128229Swpaul
333128229Swpaul#define AT_DIRQL_LEVEL(td)		\
334128295Swpaul	((td)->td_priority <= PI_NET)
335128229Swpaul
336128229Swpaul#define AT_HIGH_LEVEL(td)		\
337128229Swpaul	((td)->td_critnest != 0)
338128229Swpaul
339125551Swpaulstruct nt_objref {
340125551Swpaul	nt_dispatch_header	no_dh;
341125551Swpaul	void			*no_obj;
342125551Swpaul	TAILQ_ENTRY(nt_objref)	link;
343125551Swpaul};
344125551Swpaul
345125551SwpaulTAILQ_HEAD(nt_objref_head, nt_objref);
346125551Swpaul
347125551Swpaultypedef struct nt_objref nt_objref;
348125551Swpaul
349125551Swpaul#define EVENT_TYPE_NOTIFY	0
350125551Swpaul#define EVENT_TYPE_SYNC		1
351125551Swpaul
352126620Swpaul/*
353126620Swpaul * We need to use the timeout()/untimeout() API for ktimers
354126620Swpaul * since timers can be initialized, but not destroyed (so
355126620Swpaul * malloc()ing our own callout structures would mean a leak,
356126620Swpaul * since there'd be no way to free() them). This means we
357126620Swpaul * need to use struct callout_handle, which is really just a
358126620Swpaul * pointer. To make it easier to deal with, we use a union
359126620Swpaul * to overlay the callout_handle over the k_timerlistentry.
360126620Swpaul * The latter is a list_entry, which is two pointers, so
361126620Swpaul * there's enough space available to hide a callout_handle
362126620Swpaul * there.
363126620Swpaul */
364126620Swpaul
365125551Swpaulstruct ktimer {
366125551Swpaul	nt_dispatch_header	k_header;
367125551Swpaul	uint64_t		k_duetime;
368126620Swpaul	union {
369126620Swpaul		list_entry		k_timerlistentry;
370151207Swpaul		struct callout		*k_callout;
371126620Swpaul	} u;
372125551Swpaul	void			*k_dpc;
373125551Swpaul	uint32_t		k_period;
374125551Swpaul};
375125551Swpaul
376126620Swpaul#define k_timerlistentry	u.k_timerlistentry
377151207Swpaul#define k_callout		u.k_callout
378126620Swpaul
379126620Swpaultypedef struct ktimer ktimer;
380126620Swpaul
381125551Swpaulstruct nt_kevent {
382125551Swpaul	nt_dispatch_header	k_header;
383125551Swpaul};
384125551Swpaul
385125551Swpaultypedef struct nt_kevent nt_kevent;
386125551Swpaul
387125551Swpaul/* Kernel defered procedure call (i.e. timer callback) */
388125551Swpaul
389125551Swpaulstruct kdpc;
390144888Swpaultypedef void (*kdpc_func)(struct kdpc *, void *, void *, void *);
391125551Swpaul
392125551Swpaulstruct kdpc {
393125551Swpaul	uint16_t		k_type;
394145895Swpaul	uint8_t			k_num;		/* CPU number */
395145895Swpaul	uint8_t			k_importance;	/* priority */
396125551Swpaul	list_entry		k_dpclistentry;
397140827Swpaul	void			*k_deferedfunc;
398125551Swpaul	void			*k_deferredctx;
399125551Swpaul	void			*k_sysarg1;
400125551Swpaul	void			*k_sysarg2;
401145895Swpaul	void			*k_lock;
402125551Swpaul};
403125551Swpaul
404145895Swpaul#define KDPC_IMPORTANCE_LOW	0
405145895Swpaul#define KDPC_IMPORTANCE_MEDIUM	1
406145895Swpaul#define KDPC_IMPORTANCE_HIGH	2
407145895Swpaul
408145895Swpaul#define KDPC_CPU_DEFAULT	255
409145895Swpaul
410126620Swpaultypedef struct kdpc kdpc;
411126620Swpaul
412125551Swpaul/*
413125551Swpaul * Note: the acquisition count is BSD-specific. The Microsoft
414125551Swpaul * documentation says that mutexes can be acquired recursively
415125551Swpaul * by a given thread, but that you must release the mutex as
416125551Swpaul * many times as you acquired it before it will be set to the
417125551Swpaul * signalled state (i.e. before any other threads waiting on
418125551Swpaul * the object will be woken up). However the Windows KMUTANT
419125551Swpaul * structure has no field for keeping track of the number of
420125551Swpaul * acquisitions, so we need to add one ourselves. As long as
421125551Swpaul * driver code treats the mutex as opaque, we should be ok.
422125551Swpaul */
423125551Swpaulstruct kmutant {
424125551Swpaul	nt_dispatch_header	km_header;
425151207Swpaul	list_entry		km_listentry;
426125551Swpaul	void			*km_ownerthread;
427125551Swpaul	uint8_t			km_abandoned;
428125551Swpaul	uint8_t			km_apcdisable;
429125551Swpaul};
430125551Swpaul
431125551Swpaultypedef struct kmutant kmutant;
432125551Swpaul
433125860Swpaul#define LOOKASIDE_DEPTH 256
434125860Swpaul
435123474Swpaulstruct general_lookaside {
436123474Swpaul	slist_header		gl_listhead;
437123474Swpaul	uint16_t		gl_depth;
438123474Swpaul	uint16_t		gl_maxdepth;
439123474Swpaul	uint32_t		gl_totallocs;
440123474Swpaul	union {
441123474Swpaul		uint32_t		gl_allocmisses;
442123474Swpaul		uint32_t		gl_allochits;
443123474Swpaul	} u_a;
444123474Swpaul	uint32_t		gl_totalfrees;
445123474Swpaul	union {
446123474Swpaul		uint32_t		gl_freemisses;
447123474Swpaul		uint32_t		gl_freehits;
448123474Swpaul	} u_m;
449123474Swpaul	uint32_t		gl_type;
450123474Swpaul	uint32_t		gl_tag;
451123474Swpaul	uint32_t		gl_size;
452123474Swpaul	void			*gl_allocfunc;
453123474Swpaul	void			*gl_freefunc;
454123507Swpaul	list_entry		gl_listent;
455123474Swpaul	uint32_t		gl_lasttotallocs;
456123474Swpaul	union {
457123474Swpaul		uint32_t		gl_lastallocmisses;
458123474Swpaul		uint32_t		gl_lastallochits;
459123474Swpaul	} u_l;
460123474Swpaul	uint32_t		gl_rsvd[2];
461123474Swpaul};
462123474Swpaul
463123474Swpaultypedef struct general_lookaside general_lookaside;
464123474Swpaul
465123474Swpaulstruct npaged_lookaside_list {
466123474Swpaul	general_lookaside	nll_l;
467144240Swpaul#ifdef __i386__
468123474Swpaul	kspin_lock		nll_obsoletelock;
469144240Swpaul#endif
470123474Swpaul};
471123474Swpaul
472123474Swpaultypedef struct npaged_lookaside_list npaged_lookaside_list;
473123474Swpaultypedef struct npaged_lookaside_list paged_lookaside_list;
474123474Swpaul
475123474Swpaultypedef void * (*lookaside_alloc_func)(uint32_t, size_t, uint32_t);
476123474Swpaultypedef void (*lookaside_free_func)(void *);
477123474Swpaul
478125551Swpaulstruct irp;
479123474Swpaul
480125551Swpaulstruct kdevice_qentry {
481125551Swpaul	list_entry		kqe_devlistent;
482125551Swpaul	uint32_t		kqe_sortkey;
483125551Swpaul	uint8_t			kqe_inserted;
484125551Swpaul};
485125551Swpaul
486125551Swpaultypedef struct kdevice_qentry kdevice_qentry;
487125551Swpaul
488125551Swpaulstruct kdevice_queue {
489125551Swpaul	uint16_t		kq_type;
490125551Swpaul	uint16_t		kq_size;
491125551Swpaul	list_entry		kq_devlisthead;
492125551Swpaul	kspin_lock		kq_lock;
493125551Swpaul	uint8_t			kq_busy;
494125551Swpaul};
495125551Swpaul
496125551Swpaultypedef struct kdevice_queue kdevice_queue;
497125551Swpaul
498125551Swpaulstruct wait_ctx_block {
499125551Swpaul	kdevice_qentry		wcb_waitqueue;
500125551Swpaul	void			*wcb_devfunc;
501125551Swpaul	void			*wcb_devctx;
502125551Swpaul	uint32_t		wcb_mapregcnt;
503125551Swpaul	void			*wcb_devobj;
504125551Swpaul	void			*wcb_curirp;
505125551Swpaul	void			*wcb_bufchaindpc;
506125551Swpaul};
507125551Swpaul
508125551Swpaultypedef struct wait_ctx_block wait_ctx_block;
509125551Swpaul
510125551Swpaulstruct wait_block {
511125551Swpaul	list_entry		wb_waitlist;
512125551Swpaul	void			*wb_kthread;
513125551Swpaul	nt_dispatch_header	*wb_object;
514125551Swpaul	struct wait_block	*wb_next;
515151207Swpaul#ifdef notdef
516125551Swpaul	uint16_t		wb_waitkey;
517125551Swpaul	uint16_t		wb_waittype;
518151207Swpaul#endif
519151207Swpaul	uint8_t			wb_waitkey;
520151207Swpaul	uint8_t			wb_waittype;
521151207Swpaul	uint8_t			wb_awakened;
522151207Swpaul	uint8_t			wb_oldpri;
523125551Swpaul};
524125551Swpaul
525125551Swpaultypedef struct wait_block wait_block;
526125551Swpaul
527151207Swpaul#define wb_ext wb_kthread
528151207Swpaul
529125551Swpaul#define THREAD_WAIT_OBJECTS	3
530125551Swpaul#define MAX_WAIT_OBJECTS	64
531125551Swpaul
532125551Swpaul#define WAITTYPE_ALL		0
533125551Swpaul#define WAITTYPE_ANY		1
534125551Swpaul
535151207Swpaul#define WAITKEY_VALID		0x8000
536151207Swpaul
537125551Swpaulstruct thread_context {
538125551Swpaul	void			*tc_thrctx;
539125551Swpaul	void			*tc_thrfunc;
540125551Swpaul};
541125551Swpaul
542125551Swpaultypedef struct thread_context thread_context;
543125551Swpaul
544140751Swpaul/* Forward declaration */
545140751Swpaulstruct driver_object;
546140751Swpaulstruct devobj_extension;
547140751Swpaul
548140751Swpaulstruct driver_extension {
549140751Swpaul	struct driver_object	*dre_driverobj;
550140751Swpaul	void			*dre_adddevicefunc;
551140751Swpaul	uint32_t		dre_reinitcnt;
552140751Swpaul	unicode_string		dre_srvname;
553141524Swpaul
554141524Swpaul	/*
555141524Swpaul	 * Drivers are allowed to add one or more custom extensions
556141524Swpaul	 * to the driver object, but there's no special pointer
557141524Swpaul	 * for them. Hang them off here for now.
558141524Swpaul	 */
559141524Swpaul
560141524Swpaul	list_entry		dre_usrext;
561140751Swpaul};
562140751Swpaul
563140751Swpaultypedef struct driver_extension driver_extension;
564140751Swpaul
565141524Swpaulstruct custom_extension {
566141524Swpaul	list_entry		ce_list;
567141524Swpaul	void			*ce_clid;
568141524Swpaul};
569141524Swpaul
570141524Swpaultypedef struct custom_extension custom_extension;
571141524Swpaul
572140751Swpaul/*
573151207Swpaul * The KINTERRUPT structure in Windows is opaque to drivers.
574151207Swpaul * We define our own custom version with things we need.
575151207Swpaul */
576151207Swpaul
577151207Swpaulstruct kinterrupt {
578151451Swpaul	list_entry		ki_list;
579151207Swpaul	device_t		ki_dev;
580151451Swpaul	int			ki_rid;
581151207Swpaul	void			*ki_cookie;
582151207Swpaul	struct resource		*ki_irq;
583151207Swpaul	kspin_lock		ki_lock_priv;
584151207Swpaul	kspin_lock		*ki_lock;
585151207Swpaul	void			*ki_svcfunc;
586151207Swpaul	void			*ki_svcctx;
587151207Swpaul};
588151207Swpaul
589151207Swpaultypedef struct kinterrupt kinterrupt;
590151207Swpaul
591151207Swpaul/*
592140751Swpaul * In Windows, there are Physical Device Objects (PDOs) and
593140751Swpaul * Functional Device Objects (FDOs). Physical Device Objects are
594140751Swpaul * created and maintained by bus drivers. For example, the PCI
595140751Swpaul * bus driver might detect two PCI ethernet cards on a given
596140751Swpaul * bus. The PCI bus driver will then allocate two device_objects
597140751Swpaul * for its own internal bookeeping purposes. This is analagous
598140751Swpaul * to the device_t that the FreeBSD PCI code allocates and passes
599140751Swpaul * into each PCI driver's probe and attach routines.
600140751Swpaul *
601140751Swpaul * When an ethernet driver claims one of the ethernet cards
602140751Swpaul * on the bus, it will create its own device_object. This is
603140751Swpaul * the Functional Device Object. This object is analagous to the
604140751Swpaul * device-specific softc structure.
605140751Swpaul */
606140751Swpaul
607125551Swpaulstruct device_object {
608125551Swpaul	uint16_t		do_type;
609125551Swpaul	uint16_t		do_size;
610125551Swpaul	uint32_t		do_refcnt;
611141524Swpaul	struct driver_object	*do_drvobj;
612125551Swpaul	struct device_object	*do_nextdev;
613125551Swpaul	struct device_object	*do_attacheddev;
614125551Swpaul	struct irp		*do_currirp;
615125551Swpaul	void			*do_iotimer;
616125551Swpaul	uint32_t		do_flags;
617125551Swpaul	uint32_t		do_characteristics;
618125551Swpaul	void			*do_vpb;
619125551Swpaul	void			*do_devext;
620141524Swpaul	uint32_t		do_devtype;
621125551Swpaul	uint8_t			do_stacksize;
622125551Swpaul	union {
623125551Swpaul		list_entry		do_listent;
624125551Swpaul		wait_ctx_block		do_wcb;
625125551Swpaul	} queue;
626125551Swpaul	uint32_t		do_alignreq;
627125551Swpaul	kdevice_queue		do_devqueue;
628125551Swpaul	struct kdpc		do_dpc;
629125551Swpaul	uint32_t		do_activethreads;
630125551Swpaul	void			*do_securitydesc;
631125551Swpaul	struct nt_kevent	do_devlock;
632125551Swpaul	uint16_t		do_sectorsz;
633125551Swpaul	uint16_t		do_spare1;
634140751Swpaul	struct devobj_extension	*do_devobj_ext;
635125551Swpaul	void			*do_rsvd;
636125551Swpaul};
637125551Swpaul
638125551Swpaultypedef struct device_object device_object;
639125551Swpaul
640140751Swpaulstruct devobj_extension {
641140751Swpaul	uint16_t		dve_type;
642140751Swpaul	uint16_t		dve_size;
643140751Swpaul	device_object		*dve_devobj;
644140751Swpaul};
645140751Swpaul
646140751Swpaultypedef struct devobj_extension devobj_extension;
647140751Swpaul
648142311Swpaul/* Device object flags */
649142311Swpaul
650142311Swpaul#define DO_VERIFY_VOLUME		0x00000002
651142311Swpaul#define DO_BUFFERED_IO			0x00000004
652142311Swpaul#define DO_EXCLUSIVE			0x00000008
653142311Swpaul#define DO_DIRECT_IO			0x00000010
654142311Swpaul#define DO_MAP_IO_BUFFER		0x00000020
655142311Swpaul#define DO_DEVICE_HAS_NAME		0x00000040
656142311Swpaul#define DO_DEVICE_INITIALIZING		0x00000080
657142311Swpaul#define DO_SYSTEM_BOOT_PARTITION	0x00000100
658142311Swpaul#define DO_LONG_TERM_REQUESTS		0x00000200
659142311Swpaul#define DO_NEVER_LAST_DEVICE		0x00000400
660142311Swpaul#define DO_SHUTDOWN_REGISTERED		0x00000800
661142311Swpaul#define DO_BUS_ENUMERATED_DEVICE	0x00001000
662142311Swpaul#define DO_POWER_PAGABLE		0x00002000
663142311Swpaul#define DO_POWER_INRUSH			0x00004000
664142311Swpaul#define DO_LOW_PRIORITY_FILESYSTEM	0x00010000
665142311Swpaul
666142311Swpaul/* Priority boosts */
667142311Swpaul
668140751Swpaul#define IO_NO_INCREMENT			0
669140751Swpaul#define IO_CD_ROM_INCREMENT		1
670140751Swpaul#define IO_DISK_INCREMENT		1
671140751Swpaul#define IO_KEYBOARD_INCREMENT		6
672140751Swpaul#define IO_MAILSLOT_INCREMENT		2
673140751Swpaul#define IO_MOUSE_INCREMENT		6
674140751Swpaul#define IO_NAMED_PIPE_INCREMENT		2
675140751Swpaul#define IO_NETWORK_INCREMENT		2
676140751Swpaul#define IO_PARALLEL_INCREMENT		1
677140751Swpaul#define IO_SERIAL_INCREMENT		2
678140751Swpaul#define IO_SOUND_INCREMENT		8
679140751Swpaul#define IO_VIDEO_INCREMENT		1
680140751Swpaul
681140751Swpaul/* IRP major codes */
682140751Swpaul
683140751Swpaul#define IRP_MJ_CREATE                   0x00
684140751Swpaul#define IRP_MJ_CREATE_NAMED_PIPE        0x01
685140751Swpaul#define IRP_MJ_CLOSE                    0x02
686140751Swpaul#define IRP_MJ_READ                     0x03
687140751Swpaul#define IRP_MJ_WRITE                    0x04
688140751Swpaul#define IRP_MJ_QUERY_INFORMATION        0x05
689140751Swpaul#define IRP_MJ_SET_INFORMATION          0x06
690140751Swpaul#define IRP_MJ_QUERY_EA                 0x07
691140751Swpaul#define IRP_MJ_SET_EA                   0x08
692140751Swpaul#define IRP_MJ_FLUSH_BUFFERS            0x09
693140751Swpaul#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a
694140751Swpaul#define IRP_MJ_SET_VOLUME_INFORMATION   0x0b
695140751Swpaul#define IRP_MJ_DIRECTORY_CONTROL        0x0c
696140751Swpaul#define IRP_MJ_FILE_SYSTEM_CONTROL      0x0d
697140751Swpaul#define IRP_MJ_DEVICE_CONTROL           0x0e
698140751Swpaul#define IRP_MJ_INTERNAL_DEVICE_CONTROL  0x0f
699140751Swpaul#define IRP_MJ_SHUTDOWN                 0x10
700140751Swpaul#define IRP_MJ_LOCK_CONTROL             0x11
701140751Swpaul#define IRP_MJ_CLEANUP                  0x12
702140751Swpaul#define IRP_MJ_CREATE_MAILSLOT          0x13
703140751Swpaul#define IRP_MJ_QUERY_SECURITY           0x14
704140751Swpaul#define IRP_MJ_SET_SECURITY             0x15
705140751Swpaul#define IRP_MJ_POWER                    0x16
706140751Swpaul#define IRP_MJ_SYSTEM_CONTROL           0x17
707140751Swpaul#define IRP_MJ_DEVICE_CHANGE            0x18
708140751Swpaul#define IRP_MJ_QUERY_QUOTA              0x19
709140751Swpaul#define IRP_MJ_SET_QUOTA                0x1a
710140751Swpaul#define IRP_MJ_PNP                      0x1b
711140751Swpaul#define IRP_MJ_PNP_POWER                IRP_MJ_PNP      // Obsolete....
712140751Swpaul#define IRP_MJ_MAXIMUM_FUNCTION         0x1b
713140751Swpaul#define IRP_MJ_SCSI                     IRP_MJ_INTERNAL_DEVICE_CONTROL
714140751Swpaul
715140751Swpaul/* IRP minor codes */
716140751Swpaul
717140751Swpaul#define IRP_MN_QUERY_DIRECTORY          0x01
718140751Swpaul#define IRP_MN_NOTIFY_CHANGE_DIRECTORY  0x02
719140751Swpaul#define IRP_MN_USER_FS_REQUEST          0x00
720140751Swpaul
721140751Swpaul#define IRP_MN_MOUNT_VOLUME             0x01
722140751Swpaul#define IRP_MN_VERIFY_VOLUME            0x02
723140751Swpaul#define IRP_MN_LOAD_FILE_SYSTEM         0x03
724144240Swpaul#define IRP_MN_TRACK_LINK               0x04
725140751Swpaul#define IRP_MN_KERNEL_CALL              0x04
726140751Swpaul
727140751Swpaul#define IRP_MN_LOCK                     0x01
728140751Swpaul#define IRP_MN_UNLOCK_SINGLE            0x02
729140751Swpaul#define IRP_MN_UNLOCK_ALL               0x03
730140751Swpaul#define IRP_MN_UNLOCK_ALL_BY_KEY        0x04
731140751Swpaul
732140751Swpaul#define IRP_MN_NORMAL                   0x00
733140751Swpaul#define IRP_MN_DPC                      0x01
734140751Swpaul#define IRP_MN_MDL                      0x02
735140751Swpaul#define IRP_MN_COMPLETE                 0x04
736140751Swpaul#define IRP_MN_COMPRESSED               0x08
737140751Swpaul
738140751Swpaul#define IRP_MN_MDL_DPC                  (IRP_MN_MDL | IRP_MN_DPC)
739140751Swpaul#define IRP_MN_COMPLETE_MDL             (IRP_MN_COMPLETE | IRP_MN_MDL)
740140751Swpaul#define IRP_MN_COMPLETE_MDL_DPC         (IRP_MN_COMPLETE_MDL | IRP_MN_DPC)
741140751Swpaul
742140751Swpaul#define IRP_MN_SCSI_CLASS               0x01
743140751Swpaul
744140751Swpaul#define IRP_MN_START_DEVICE                 0x00
745140751Swpaul#define IRP_MN_QUERY_REMOVE_DEVICE          0x01
746140751Swpaul#define IRP_MN_REMOVE_DEVICE                0x02
747140751Swpaul#define IRP_MN_CANCEL_REMOVE_DEVICE         0x03
748140751Swpaul#define IRP_MN_STOP_DEVICE                  0x04
749140751Swpaul#define IRP_MN_QUERY_STOP_DEVICE            0x05
750140751Swpaul#define IRP_MN_CANCEL_STOP_DEVICE           0x06
751140751Swpaul
752140751Swpaul#define IRP_MN_QUERY_DEVICE_RELATIONS       0x07
753140751Swpaul#define IRP_MN_QUERY_INTERFACE              0x08
754140751Swpaul#define IRP_MN_QUERY_CAPABILITIES           0x09
755140751Swpaul#define IRP_MN_QUERY_RESOURCES              0x0A
756140751Swpaul#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS  0x0B
757140751Swpaul#define IRP_MN_QUERY_DEVICE_TEXT            0x0C
758140751Swpaul#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS 0x0D
759140751Swpaul
760140751Swpaul#define IRP_MN_READ_CONFIG                  0x0F
761140751Swpaul#define IRP_MN_WRITE_CONFIG                 0x10
762140751Swpaul#define IRP_MN_EJECT                        0x11
763140751Swpaul#define IRP_MN_SET_LOCK                     0x12
764140751Swpaul#define IRP_MN_QUERY_ID                     0x13
765140751Swpaul#define IRP_MN_QUERY_PNP_DEVICE_STATE       0x14
766140751Swpaul#define IRP_MN_QUERY_BUS_INFORMATION        0x15
767140751Swpaul#define IRP_MN_DEVICE_USAGE_NOTIFICATION    0x16
768140751Swpaul#define IRP_MN_SURPRISE_REMOVAL             0x17
769140751Swpaul#define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18
770140751Swpaul
771140751Swpaul#define IRP_MN_WAIT_WAKE                    0x00
772140751Swpaul#define IRP_MN_POWER_SEQUENCE               0x01
773140751Swpaul#define IRP_MN_SET_POWER                    0x02
774140751Swpaul#define IRP_MN_QUERY_POWER                  0x03
775140751Swpaul
776140751Swpaul#define IRP_MN_QUERY_ALL_DATA               0x00
777140751Swpaul#define IRP_MN_QUERY_SINGLE_INSTANCE        0x01
778140751Swpaul#define IRP_MN_CHANGE_SINGLE_INSTANCE       0x02
779140751Swpaul#define IRP_MN_CHANGE_SINGLE_ITEM           0x03
780140751Swpaul#define IRP_MN_ENABLE_EVENTS                0x04
781140751Swpaul#define IRP_MN_DISABLE_EVENTS               0x05
782140751Swpaul#define IRP_MN_ENABLE_COLLECTION            0x06
783140751Swpaul#define IRP_MN_DISABLE_COLLECTION           0x07
784140751Swpaul#define IRP_MN_REGINFO                      0x08
785140751Swpaul#define IRP_MN_EXECUTE_METHOD               0x09
786140751Swpaul#define IRP_MN_REGINFO_EX                   0x0b
787140751Swpaul
788140751Swpaul/* IRP flags */
789140751Swpaul
790140751Swpaul#define IRP_NOCACHE                     0x00000001
791140751Swpaul#define IRP_PAGING_IO                   0x00000002
792140751Swpaul#define IRP_MOUNT_COMPLETION            0x00000002
793140751Swpaul#define IRP_SYNCHRONOUS_API             0x00000004
794140751Swpaul#define IRP_ASSOCIATED_IRP              0x00000008
795140751Swpaul#define IRP_BUFFERED_IO                 0x00000010
796140751Swpaul#define IRP_DEALLOCATE_BUFFER           0x00000020
797140751Swpaul#define IRP_INPUT_OPERATION             0x00000040
798140751Swpaul#define IRP_SYNCHRONOUS_PAGING_IO       0x00000040
799140751Swpaul#define IRP_CREATE_OPERATION            0x00000080
800140751Swpaul#define IRP_READ_OPERATION              0x00000100
801140751Swpaul#define IRP_WRITE_OPERATION             0x00000200
802140751Swpaul#define IRP_CLOSE_OPERATION             0x00000400
803140751Swpaul#define IRP_DEFER_IO_COMPLETION         0x00000800
804140751Swpaul#define IRP_OB_QUERY_NAME               0x00001000
805140751Swpaul#define IRP_HOLD_DEVICE_QUEUE           0x00002000
806140751Swpaul#define IRP_RETRY_IO_COMPLETION         0x00004000
807140751Swpaul#define IRP_CLASS_CACHE_OPERATION       0x00008000
808140751Swpaul#define IRP_SET_USER_EVENT              IRP_CLOSE_OPERATION
809140751Swpaul
810140751Swpaul/* IRP I/O control flags */
811140751Swpaul
812140751Swpaul#define IRP_QUOTA_CHARGED               0x01
813140751Swpaul#define IRP_ALLOCATED_MUST_SUCCEED      0x02
814140751Swpaul#define IRP_ALLOCATED_FIXED_SIZE        0x04
815140751Swpaul#define IRP_LOOKASIDE_ALLOCATION        0x08
816140751Swpaul
817142311Swpaul/* I/O method types */
818142311Swpaul
819142311Swpaul#define METHOD_BUFFERED			0
820142311Swpaul#define METHOD_IN_DIRECT		1
821142311Swpaul#define METHOD_OUT_DIRECT		2
822142311Swpaul#define METHOD_NEITHER			3
823142311Swpaul
824142497Swpaul/* File access types */
825142497Swpaul
826142497Swpaul#define FILE_ANY_ACCESS			0x0000
827142497Swpaul#define FILE_SPECIAL_ACCESS		FILE_ANY_ACCESS
828142497Swpaul#define FILE_READ_ACCESS		0x0001
829142497Swpaul#define FILE_WRITE_ACCESS		0x0002
830142497Swpaul
831142497Swpaul/* Recover I/O access method from IOCTL code. */
832142497Swpaul
833142311Swpaul#define IO_METHOD(x)			((x) & 0xFFFFFFFC)
834142311Swpaul
835142497Swpaul/* Recover function code from IOCTL code */
836142497Swpaul
837142497Swpaul#define IO_FUNC(x)			(((x) & 0x7FFC) >> 2)
838142497Swpaul
839142497Swpaul/* Macro to construct an IOCTL code. */
840142497Swpaul
841142497Swpaul#define IOCTL_CODE(dev, func, iomethod, acc)	\
842142497Swpaul	((dev) << 16) | (acc << 14) | (func << 2) | (iomethod))
843142497Swpaul
844142497Swpaul
845140751Swpaulstruct io_status_block {
846140751Swpaul	union {
847140751Swpaul		uint32_t		isb_status;
848140751Swpaul		void			*isb_ptr;
849140751Swpaul	} u;
850140751Swpaul	register_t		isb_info;
851140751Swpaul};
852141524Swpaul#define isb_status		u.isb_status
853141524Swpaul#define isb_ptr			u.isb_ptr
854140751Swpaul
855140751Swpaultypedef struct io_status_block io_status_block;
856140751Swpaul
857140751Swpaulstruct kapc {
858140751Swpaul	uint16_t		apc_type;
859140751Swpaul	uint16_t		apc_size;
860140751Swpaul	uint32_t		apc_spare0;
861140751Swpaul	void			*apc_thread;
862140751Swpaul	list_entry		apc_list;
863140751Swpaul	void			*apc_kernfunc;
864140751Swpaul	void			*apc_rundownfunc;
865140751Swpaul	void			*apc_normalfunc;
866140751Swpaul	void			*apc_normctx;
867140751Swpaul	void			*apc_sysarg1;
868140751Swpaul	void			*apc_sysarg2;
869140751Swpaul	uint8_t			apc_stateidx;
870140751Swpaul	uint8_t			apc_cpumode;
871140751Swpaul	uint8_t			apc_inserted;
872140751Swpaul};
873140751Swpaul
874140751Swpaultypedef struct kapc kapc;
875140751Swpaul
876144888Swpaultypedef uint32_t (*completion_func)(device_object *,
877141524Swpaul	struct irp *, void *);
878144888Swpaultypedef uint32_t (*cancel_func)(device_object *,
879142311Swpaul	struct irp *);
880141524Swpaul
881140751Swpaulstruct io_stack_location {
882140751Swpaul	uint8_t			isl_major;
883140751Swpaul	uint8_t			isl_minor;
884140751Swpaul	uint8_t			isl_flags;
885140751Swpaul	uint8_t			isl_ctl;
886140751Swpaul
887140751Swpaul	/*
888140751Swpaul	 * There's a big-ass union here in the actual Windows
889140751Swpaul	 * definition of the stucture, but it contains stuff
890140751Swpaul	 * that doesn't really apply to BSD, and defining it
891140751Swpaul	 * all properly would require duplicating over a dozen
892140751Swpaul	 * other structures that we'll never use. Since the
893140751Swpaul	 * io_stack_location structure is opaque to drivers
894140751Swpaul	 * anyway, I'm not going to bother with the extra crap.
895140751Swpaul	 */
896140751Swpaul
897140751Swpaul	union {
898140751Swpaul		struct {
899142311Swpaul			uint32_t		isl_len;
900142311Swpaul			uint32_t		*isl_key;
901142311Swpaul			uint64_t		isl_byteoff;
902142311Swpaul		} isl_read;
903142311Swpaul		struct {
904142311Swpaul			uint32_t		isl_len;
905142311Swpaul			uint32_t		*isl_key;
906142311Swpaul			uint64_t		isl_byteoff;
907142311Swpaul		} isl_write;
908142311Swpaul		struct {
909142311Swpaul			uint32_t		isl_obuflen;
910142311Swpaul			uint32_t		isl_ibuflen;
911142311Swpaul			uint32_t		isl_iocode;
912142311Swpaul			void			*isl_type3ibuf;
913142311Swpaul		} isl_ioctl;
914142311Swpaul		struct {
915140751Swpaul			void			*isl_arg1;
916140751Swpaul			void			*isl_arg2;
917140751Swpaul			void			*isl_arg3;
918140751Swpaul			void			*isl_arg4;
919140751Swpaul		} isl_others;
920142311Swpaul	} isl_parameters __attribute__((packed));
921140751Swpaul
922140751Swpaul	void			*isl_devobj;
923140751Swpaul	void			*isl_fileobj;
924141524Swpaul	completion_func		isl_completionfunc;
925140751Swpaul	void			*isl_completionctx;
926140751Swpaul};
927140751Swpaul
928140751Swpaultypedef struct io_stack_location io_stack_location;
929140751Swpaul
930140751Swpaul/* Stack location control flags */
931140751Swpaul
932140751Swpaul#define SL_PENDING_RETURNED		0x01
933140751Swpaul#define SL_INVOKE_ON_CANCEL		0x20
934140751Swpaul#define SL_INVOKE_ON_SUCCESS		0x40
935140751Swpaul#define SL_INVOKE_ON_ERROR		0x80
936140751Swpaul
937125551Swpaulstruct irp {
938140751Swpaul	uint16_t		irp_type;
939140751Swpaul	uint16_t		irp_size;
940140751Swpaul	mdl			*irp_mdl;
941140751Swpaul	uint32_t		irp_flags;
942140751Swpaul	union {
943140751Swpaul		struct irp		*irp_master;
944140751Swpaul		uint32_t		irp_irpcnt;
945140751Swpaul		void			*irp_sysbuf;
946140751Swpaul	} irp_assoc;
947140751Swpaul	list_entry		irp_thlist;
948140751Swpaul	io_status_block		irp_iostat;
949140751Swpaul	uint8_t			irp_reqmode;
950140751Swpaul	uint8_t			irp_pendingreturned;
951140751Swpaul	uint8_t			irp_stackcnt;
952140751Swpaul	uint8_t			irp_currentstackloc;
953140751Swpaul	uint8_t			irp_cancel;
954140751Swpaul	uint8_t			irp_cancelirql;
955140751Swpaul	uint8_t			irp_apcenv;
956140751Swpaul	uint8_t			irp_allocflags;
957140751Swpaul	io_status_block		*irp_usriostat;
958141524Swpaul	nt_kevent		*irp_usrevent;
959140751Swpaul	union {
960140751Swpaul		struct {
961140751Swpaul			void			*irp_apcfunc;
962140751Swpaul			void			*irp_apcctx;
963140751Swpaul		} irp_asyncparms;
964140751Swpaul		uint64_t			irp_allocsz;
965140751Swpaul	} irp_overlay;
966142311Swpaul	cancel_func		irp_cancelfunc;
967140751Swpaul	void			*irp_userbuf;
968140751Swpaul
969140751Swpaul	/* Windows kernel info */
970140751Swpaul
971140751Swpaul	union {
972140751Swpaul		struct {
973140751Swpaul			union {
974140751Swpaul				kdevice_qentry			irp_dqe;
975140751Swpaul				struct {
976140751Swpaul					void 			*irp_drvctx[4];
977140751Swpaul				} s1;
978140751Swpaul			} u1;
979140751Swpaul			void			*irp_thread;
980140751Swpaul			char			*irp_auxbuf;
981140751Swpaul			struct {
982140751Swpaul				list_entry			irp_list;
983140751Swpaul				union {
984140751Swpaul					io_stack_location	*irp_csl;
985140751Swpaul					uint32_t		irp_pkttype;
986140751Swpaul				} u2;
987140751Swpaul			} s2;
988140751Swpaul			void			*irp_fileobj;
989140751Swpaul		} irp_overlay;
990140751Swpaul		kapc			irp_apc;
991140751Swpaul		void			*irp_compkey;
992140751Swpaul	} irp_tail;
993125551Swpaul};
994125551Swpaul
995140751Swpaul#define irp_csl			s2.u2.irp_csl
996140751Swpaul#define irp_pkttype		s2.u2.irp_pkttype
997140751Swpaul
998125551Swpaultypedef struct irp irp;
999125551Swpaul
1000142311Swpaul#define InterlockedExchangePointer(dst, val)				\
1001144888Swpaul	(void *)InterlockedExchange((uint32_t *)(dst), (uintptr_t)(val))
1002142311Swpaul
1003141524Swpaul#define IoSizeOfIrp(ssize)						\
1004141524Swpaul	((uint16_t) (sizeof(irp) + ((ssize) * (sizeof(io_stack_location)))))
1005141524Swpaul
1006142311Swpaul#define IoSetCancelRoutine(irp, func)					\
1007142311Swpaul	(cancel_func)InterlockedExchangePointer(			\
1008142311Swpaul	(void *)&(ip)->irp_cancelfunc, (void *)(func))
1009141524Swpaul
1010140751Swpaul#define IoGetCurrentIrpStackLocation(irp)				\
1011140751Swpaul	(irp)->irp_tail.irp_overlay.irp_csl
1012140751Swpaul
1013140751Swpaul#define IoGetNextIrpStackLocation(irp)					\
1014140751Swpaul	((irp)->irp_tail.irp_overlay.irp_csl - 1)
1015140751Swpaul
1016141524Swpaul#define IoSetNextIrpStackLocation(irp)					\
1017141524Swpaul	do {								\
1018141524Swpaul		irp->irp_currentstackloc--;				\
1019141524Swpaul		irp->irp_tail.irp_overlay.irp_csl--;			\
1020141524Swpaul	} while(0)
1021141524Swpaul
1022140751Swpaul#define IoSetCompletionRoutine(irp, func, ctx, ok, err, cancel)		\
1023140751Swpaul	do {								\
1024140751Swpaul		io_stack_location		*s;			\
1025140751Swpaul		s = IoGetNextIrpStackLocation((irp));			\
1026140751Swpaul		s->isl_completionfunc = (func);				\
1027140751Swpaul		s->isl_completionctx = (ctx);				\
1028140751Swpaul		s->isl_ctl = 0;						\
1029141524Swpaul		if (ok) s->isl_ctl = SL_INVOKE_ON_SUCCESS;		\
1030141524Swpaul		if (err) s->isl_ctl |= SL_INVOKE_ON_ERROR;		\
1031141524Swpaul		if (cancel) s->isl_ctl |= SL_INVOKE_ON_CANCEL;		\
1032140751Swpaul	} while(0)
1033140751Swpaul
1034140751Swpaul#define IoMarkIrpPending(irp)						\
1035140751Swpaul	IoGetCurrentIrpStackLocation(irp)->isl_ctl |= SL_PENDING_RETURNED
1036140751Swpaul
1037140751Swpaul#define IoCopyCurrentIrpStackLocationToNext(irp)			\
1038140751Swpaul	do {								\
1039140751Swpaul		io_stack_location *src, *dst;				\
1040140751Swpaul		src = IoGetCurrentIrpStackLocation(irp);		\
1041140751Swpaul		dst = IoGetNextIrpStackLocation(irp);			\
1042140751Swpaul		bcopy((char *)src, (char *)dst,				\
1043140751Swpaul		    offsetof(io_stack_location, isl_completionfunc));	\
1044140751Swpaul	} while(0)
1045140751Swpaul
1046140751Swpaul#define IoSkipCurrentIrpStackLocation(irp)				\
1047140751Swpaul	do {								\
1048140751Swpaul		(irp)->irp_currentstackloc++;				\
1049140751Swpaul		(irp)->irp_tail.irp_overlay.irp_csl++;			\
1050140751Swpaul	} while(0)
1051140751Swpaul
1052144175Swpaul#define IoInitializeDpcRequest(dobj, dpcfunc)				\
1053144175Swpaul	KeInitializeDpc(&(dobj)->do_dpc, dpcfunc, dobj)
1054144175Swpaul
1055144175Swpaul#define IoRequestDpc(dobj, irp, ctx)					\
1056144175Swpaul	KeInsertQueueDpc(&(dobj)->do_dpc, irp, ctx)
1057144175Swpaul
1058144888Swpaultypedef uint32_t (*driver_dispatch)(device_object *, irp *);
1059125551Swpaul
1060140751Swpaul/*
1061140751Swpaul * The driver_object is allocated once for each driver that's loaded
1062140751Swpaul * into the system. A new one is allocated for each driver and
1063140751Swpaul * populated a bit via the driver's DriverEntry function.
1064140751Swpaul * In general, a Windows DriverEntry() function will provide a pointer
1065140751Swpaul * to its AddDevice() method and set up the dispatch table.
1066140751Swpaul * For NDIS drivers, this is all done behind the scenes in the
1067140751Swpaul * NdisInitializeWrapper() and/or NdisMRegisterMiniport() routines.
1068140751Swpaul */
1069140751Swpaul
1070140751Swpaulstruct driver_object {
1071140751Swpaul	uint16_t		dro_type;
1072140751Swpaul	uint16_t		dro_size;
1073140751Swpaul	device_object		*dro_devobj;
1074140751Swpaul	uint32_t		dro_flags;
1075140751Swpaul	void			*dro_driverstart;
1076140751Swpaul	uint32_t		dro_driversize;
1077140751Swpaul	void			*dro_driversection;
1078141524Swpaul	driver_extension	*dro_driverext;
1079140751Swpaul	unicode_string		dro_drivername;
1080140751Swpaul	unicode_string		*dro_hwdb;
1081140751Swpaul	void			*dro_pfastiodispatch;
1082140751Swpaul	void			*dro_driverinitfunc;
1083140751Swpaul	void			*dro_driverstartiofunc;
1084140751Swpaul	void			*dro_driverunloadfunc;
1085141524Swpaul	driver_dispatch		dro_dispatch[IRP_MJ_MAXIMUM_FUNCTION + 1];
1086140751Swpaul};
1087140751Swpaul
1088140751Swpaultypedef struct driver_object driver_object;
1089140751Swpaul
1090125551Swpaul#define DEVPROP_DEVICE_DESCRIPTION	0x00000000
1091125551Swpaul#define DEVPROP_HARDWARE_ID		0x00000001
1092125551Swpaul#define DEVPROP_COMPATIBLE_IDS		0x00000002
1093125551Swpaul#define DEVPROP_BOOTCONF		0x00000003
1094125551Swpaul#define DEVPROP_BOOTCONF_TRANSLATED	0x00000004
1095125551Swpaul#define DEVPROP_CLASS_NAME		0x00000005
1096125551Swpaul#define DEVPROP_CLASS_GUID		0x00000006
1097125551Swpaul#define DEVPROP_DRIVER_KEYNAME		0x00000007
1098125551Swpaul#define DEVPROP_MANUFACTURER		0x00000008
1099125551Swpaul#define DEVPROP_FRIENDLYNAME		0x00000009
1100125551Swpaul#define DEVPROP_LOCATION_INFO		0x0000000A
1101125551Swpaul#define DEVPROP_PHYSDEV_NAME		0x0000000B
1102125551Swpaul#define DEVPROP_BUSTYPE_GUID		0x0000000C
1103125551Swpaul#define DEVPROP_LEGACY_BUSTYPE		0x0000000D
1104125551Swpaul#define DEVPROP_BUS_NUMBER		0x0000000E
1105125551Swpaul#define DEVPROP_ENUMERATOR_NAME		0x0000000F
1106125551Swpaul#define DEVPROP_ADDRESS			0x00000010
1107125551Swpaul#define DEVPROP_UINUMBER		0x00000011
1108125551Swpaul#define DEVPROP_INSTALL_STATE		0x00000012
1109125551Swpaul#define DEVPROP_REMOVAL_POLICY		0x00000013
1110125551Swpaul
1111141524Swpaul/* Various supported device types (used with IoCreateDevice()) */
1112141524Swpaul
1113141524Swpaul#define FILE_DEVICE_BEEP		0x00000001
1114141524Swpaul#define FILE_DEVICE_CD_ROM		0x00000002
1115141524Swpaul#define FILE_DEVICE_CD_ROM_FILE_SYSTEM	0x00000003
1116141524Swpaul#define FILE_DEVICE_CONTROLLER		0x00000004
1117141524Swpaul#define FILE_DEVICE_DATALINK		0x00000005
1118141524Swpaul#define FILE_DEVICE_DFS			0x00000006
1119141524Swpaul#define FILE_DEVICE_DISK		0x00000007
1120141524Swpaul#define FILE_DEVICE_DISK_FILE_SYSTEM	0x00000008
1121141524Swpaul#define FILE_DEVICE_FILE_SYSTEM		0x00000009
1122141524Swpaul#define FILE_DEVICE_INPORT_PORT		0x0000000A
1123141524Swpaul#define FILE_DEVICE_KEYBOARD		0x0000000B
1124141524Swpaul#define FILE_DEVICE_MAILSLOT		0x0000000C
1125141524Swpaul#define FILE_DEVICE_MIDI_IN		0x0000000D
1126141524Swpaul#define FILE_DEVICE_MIDI_OUT		0x0000000E
1127141524Swpaul#define FILE_DEVICE_MOUSE		0x0000000F
1128141524Swpaul#define FILE_DEVICE_MULTI_UNC_PROVIDER	0x00000010
1129141524Swpaul#define FILE_DEVICE_NAMED_PIPE		0x00000011
1130141524Swpaul#define FILE_DEVICE_NETWORK		0x00000012
1131141524Swpaul#define FILE_DEVICE_NETWORK_BROWSER	0x00000013
1132141524Swpaul#define FILE_DEVICE_NETWORK_FILE_SYSTEM	0x00000014
1133141524Swpaul#define FILE_DEVICE_NULL		0x00000015
1134141524Swpaul#define FILE_DEVICE_PARALLEL_PORT	0x00000016
1135141524Swpaul#define FILE_DEVICE_PHYSICAL_NETCARD	0x00000017
1136141524Swpaul#define FILE_DEVICE_PRINTER		0x00000018
1137141524Swpaul#define FILE_DEVICE_SCANNER		0x00000019
1138141524Swpaul#define FILE_DEVICE_SERIAL_MOUSE_PORT	0x0000001A
1139141524Swpaul#define FILE_DEVICE_SERIAL_PORT		0x0000001B
1140141524Swpaul#define FILE_DEVICE_SCREEN		0x0000001C
1141141524Swpaul#define FILE_DEVICE_SOUND		0x0000001D
1142141524Swpaul#define FILE_DEVICE_STREAMS		0x0000001E
1143141524Swpaul#define FILE_DEVICE_TAPE		0x0000001F
1144141524Swpaul#define FILE_DEVICE_TAPE_FILE_SYSTEM	0x00000020
1145141524Swpaul#define FILE_DEVICE_TRANSPORT		0x00000021
1146141524Swpaul#define FILE_DEVICE_UNKNOWN		0x00000022
1147141524Swpaul#define FILE_DEVICE_VIDEO		0x00000023
1148141524Swpaul#define FILE_DEVICE_VIRTUAL_DISK	0x00000024
1149141524Swpaul#define FILE_DEVICE_WAVE_IN		0x00000025
1150141524Swpaul#define FILE_DEVICE_WAVE_OUT		0x00000026
1151141524Swpaul#define FILE_DEVICE_8042_PORT		0x00000027
1152141524Swpaul#define FILE_DEVICE_NETWORK_REDIRECTOR	0x00000028
1153141524Swpaul#define FILE_DEVICE_BATTERY		0x00000029
1154141524Swpaul#define FILE_DEVICE_BUS_EXTENDER	0x0000002A
1155141524Swpaul#define FILE_DEVICE_MODEM		0x0000002B
1156141524Swpaul#define FILE_DEVICE_VDM			0x0000002C
1157141524Swpaul#define FILE_DEVICE_MASS_STORAGE	0x0000002D
1158141524Swpaul#define FILE_DEVICE_SMB			0x0000002E
1159141524Swpaul#define FILE_DEVICE_KS			0x0000002F
1160141524Swpaul#define FILE_DEVICE_CHANGER		0x00000030
1161141524Swpaul#define FILE_DEVICE_SMARTCARD		0x00000031
1162141524Swpaul#define FILE_DEVICE_ACPI		0x00000032
1163141524Swpaul#define FILE_DEVICE_DVD			0x00000033
1164141524Swpaul#define FILE_DEVICE_FULLSCREEN_VIDEO	0x00000034
1165141524Swpaul#define FILE_DEVICE_DFS_FILE_SYSTEM	0x00000035
1166141524Swpaul#define FILE_DEVICE_DFS_VOLUME		0x00000036
1167141524Swpaul#define FILE_DEVICE_SERENUM		0x00000037
1168141524Swpaul#define FILE_DEVICE_TERMSRV		0x00000038
1169141524Swpaul#define FILE_DEVICE_KSEC		0x00000039
1170141524Swpaul#define FILE_DEVICE_FIPS		0x0000003A
1171141524Swpaul
1172141524Swpaul/* Device characteristics */
1173141524Swpaul
1174141524Swpaul#define FILE_REMOVABLE_MEDIA		0x00000001
1175141524Swpaul#define FILE_READ_ONLY_DEVICE		0x00000002
1176141524Swpaul#define FILE_FLOPPY_DISKETTE		0x00000004
1177141524Swpaul#define FILE_WRITE_ONCE_MEDIA		0x00000008
1178141524Swpaul#define FILE_REMOTE_DEVICE		0x00000010
1179141524Swpaul#define FILE_DEVICE_IS_MOUNTED		0x00000020
1180141524Swpaul#define FILE_VIRTUAL_VOLUME		0x00000040
1181141524Swpaul#define FILE_AUTOGENERATED_DEVICE_NAME	0x00000080
1182141524Swpaul#define FILE_DEVICE_SECURE_OPEN		0x00000100
1183141524Swpaul
1184141524Swpaul/* Status codes */
1185141524Swpaul
1186125551Swpaul#define STATUS_SUCCESS			0x00000000
1187125551Swpaul#define STATUS_USER_APC			0x000000C0
1188125551Swpaul#define STATUS_KERNEL_APC		0x00000100
1189125551Swpaul#define STATUS_ALERTED			0x00000101
1190125551Swpaul#define STATUS_TIMEOUT			0x00000102
1191142443Swpaul#define STATUS_PENDING			0x00000103
1192125551Swpaul#define STATUS_INVALID_PARAMETER	0xC000000D
1193125551Swpaul#define STATUS_INVALID_DEVICE_REQUEST	0xC0000010
1194141524Swpaul#define STATUS_MORE_PROCESSING_REQUIRED	0xC0000016
1195125551Swpaul#define STATUS_BUFFER_TOO_SMALL		0xC0000023
1196125551Swpaul#define STATUS_MUTANT_NOT_OWNED		0xC0000046
1197125551Swpaul#define STATUS_INVALID_PARAMETER_2	0xC00000F0
1198141524Swpaul#define STATUS_INSUFFICIENT_RESOURCES	0xC000009A
1199125551Swpaul
1200125551Swpaul#define STATUS_WAIT_0			0x00000000
1201125551Swpaul
1202141524Swpaul/* Memory pool types, for ExAllocatePoolWithTag() */
1203141524Swpaul
1204141524Swpaul#define NonPagedPool			0x00000000
1205141524Swpaul#define PagedPool			0x00000001
1206141524Swpaul#define NonPagedPoolMustSucceed		0x00000002
1207141524Swpaul#define DontUseThisType			0x00000003
1208141524Swpaul#define NonPagedPoolCacheAligned	0x00000004
1209141524Swpaul#define PagedPoolCacheAligned		0x00000005
1210141524Swpaul#define NonPagedPoolCacheAlignedMustS	0x00000006
1211141524Swpaul#define MaxPoolType			0x00000007
1212141524Swpaul
1213127284Swpaul/*
1214145895Swpaul * IO_WORKITEM is an opaque structures that must be allocated
1215145895Swpaul * via IoAllocateWorkItem() and released via IoFreeWorkItem().
1216145895Swpaul * Consequently, we can define it any way we want.
1217145895Swpaul */
1218145895Swpaultypedef void (*io_workitem_func)(device_object *, void *);
1219145895Swpaul
1220145895Swpaulstruct io_workitem {
1221145895Swpaul	io_workitem_func	iw_func;
1222145895Swpaul	void			*iw_ctx;
1223145895Swpaul	list_entry		iw_listentry;
1224145895Swpaul	device_object		*iw_dobj;
1225146364Swpaul	int			iw_idx;
1226145895Swpaul};
1227145895Swpaul
1228145895Swpaultypedef struct io_workitem io_workitem;
1229145895Swpaul
1230145895Swpaul#define WORKQUEUE_CRITICAL	0
1231145895Swpaul#define WORKQUEUE_DELAYED	1
1232146364Swpaul#define WORKQUEUE_HYPERCRITICAL	2
1233145895Swpaul
1234146364Swpaul#define WORKITEM_THREADS	4
1235146364Swpaul#define WORKITEM_LEGACY_THREAD	3
1236146364Swpaul#define WORKIDX_INC(x)		(x) = (x + 1) % WORKITEM_LEGACY_THREAD
1237146364Swpaul
1238145895Swpaul/*
1239145895Swpaul * Older, deprecated work item API, needed to support NdisQueueWorkItem().
1240145895Swpaul */
1241145895Swpaul
1242145895Swpaulstruct work_queue_item;
1243145895Swpaul
1244145895Swpaultypedef void (*work_item_func)(struct work_queue_item *, void *);
1245145895Swpaul
1246145895Swpaulstruct work_queue_item {
1247145895Swpaul	list_entry		wqi_entry;
1248145895Swpaul	work_item_func		wqi_func;
1249145895Swpaul	void			*wqi_ctx;
1250145895Swpaul};
1251145895Swpaul
1252145895Swpaultypedef struct work_queue_item work_queue_item;
1253145895Swpaul
1254145895Swpaul#define ExInitializeWorkItem(w, func, ctx)		\
1255145895Swpaul	do {						\
1256145895Swpaul		(w)->wqi_func = (func);			\
1257145895Swpaul		(w)->wqi_ctx = (ctx);			\
1258151207Swpaul		InitializeListHead(&((w)->wqi_entry));	\
1259145895Swpaul	} while (0);					\
1260145895Swpaul
1261145895Swpaul
1262145895Swpaul/*
1263127284Swpaul * FreeBSD's kernel stack is 2 pages in size by default. The
1264127284Swpaul * Windows stack is larger, so we need to give our threads more
1265127284Swpaul * stack pages. 4 should be enough, we use 8 just to extra safe.
1266127284Swpaul */
1267127284Swpaul#define NDIS_KSTACK_PAGES	8
1268127284Swpaul
1269144888Swpaul/*
1270144888Swpaul * Different kinds of function wrapping we can do.
1271144888Swpaul */
1272144888Swpaul
1273144888Swpaul#define WINDRV_WRAP_STDCALL	1
1274144888Swpaul#define WINDRV_WRAP_FASTCALL	2
1275144888Swpaul#define WINDRV_WRAP_REGPARM	3
1276144888Swpaul#define WINDRV_WRAP_CDECL	4
1277144888Swpaul#define WINDRV_WRAP_AMD64	5
1278144888Swpaul
1279145485Swpaulstruct drvdb_ent {
1280145485Swpaul	driver_object		*windrv_object;
1281145485Swpaul	void			*windrv_devlist;
1282145485Swpaul	ndis_cfg		*windrv_regvals;
1283145485Swpaul	interface_type		windrv_bustype;
1284145485Swpaul	STAILQ_ENTRY(drvdb_ent) link;
1285145485Swpaul};
1286145485Swpaul
1287123474Swpaulextern image_patch_table ntoskrnl_functbl[];
1288141963Swpaultypedef void (*funcptr)(void);
1289146016Swpaultypedef int (*matchfuncptr)(interface_type, void *, void *);
1290123474Swpaul
1291123474Swpaul__BEGIN_DECLS
1292141524Swpaulextern int windrv_libinit(void);
1293141524Swpaulextern int windrv_libfini(void);
1294142399Swpaulextern driver_object *windrv_lookup(vm_offset_t, char *);
1295145485Swpaulextern struct drvdb_ent *windrv_match(matchfuncptr, void *);
1296145485Swpaulextern int windrv_load(module_t, vm_offset_t, int, interface_type,
1297145485Swpaul	void *, ndis_cfg *);
1298141524Swpaulextern int windrv_unload(module_t, vm_offset_t, int);
1299141524Swpaulextern int windrv_create_pdo(driver_object *, device_t);
1300141524Swpaulextern void windrv_destroy_pdo(driver_object *, device_t);
1301141524Swpaulextern device_object *windrv_find_pdo(driver_object *, device_t);
1302141524Swpaulextern int windrv_bus_attach(driver_object *, char *);
1303144888Swpaulextern int windrv_wrap(funcptr, funcptr *, int, int);
1304141963Swpaulextern int windrv_unwrap(funcptr);
1305144888Swpaulextern void ctxsw_utow(void);
1306144888Swpaulextern void ctxsw_wtou(void);
1307141524Swpaul
1308123474Swpaulextern int ntoskrnl_libinit(void);
1309123474Swpaulextern int ntoskrnl_libfini(void);
1310151207Swpaul
1311151451Swpaulextern void ntoskrnl_intr(void *);
1312151451Swpaul
1313151451Swpaulextern uint16_t ExQueryDepthSList(slist_header *);
1314151451Swpaulextern slist_entry
1315151451Swpaul	*InterlockedPushEntrySList(slist_header *, slist_entry *);
1316151451Swpaulextern slist_entry *InterlockedPopEntrySList(slist_header *);
1317151207Swpaulextern uint32_t RtlUnicodeStringToAnsiString(ansi_string *,
1318151207Swpaul	unicode_string *, uint8_t);
1319151207Swpaulextern uint32_t RtlAnsiStringToUnicodeString(unicode_string *,
1320151207Swpaul	ansi_string *, uint8_t);
1321151207Swpaulextern void RtlInitAnsiString(ansi_string *, char *);
1322151207Swpaulextern void RtlInitUnicodeString(unicode_string *,
1323151207Swpaul	uint16_t *);
1324151207Swpaulextern void RtlFreeUnicodeString(unicode_string *);
1325151207Swpaulextern void RtlFreeAnsiString(ansi_string *);
1326144888Swpaulextern void KeInitializeDpc(kdpc *, void *, void *);
1327144888Swpaulextern uint8_t KeInsertQueueDpc(kdpc *, void *, void *);
1328144888Swpaulextern uint8_t KeRemoveQueueDpc(kdpc *);
1329145895Swpaulextern void KeSetImportanceDpc(kdpc *, uint32_t);
1330145895Swpaulextern void KeSetTargetProcessorDpc(kdpc *, uint8_t);
1331145895Swpaulextern void KeFlushQueuedDpcs(void);
1332145895Swpaulextern uint32_t KeGetCurrentProcessorNumber(void);
1333144888Swpaulextern void KeInitializeTimer(ktimer *);
1334144888Swpaulextern void KeInitializeTimerEx(ktimer *, uint32_t);
1335144888Swpaulextern uint8_t KeSetTimer(ktimer *, int64_t, kdpc *);
1336144888Swpaulextern uint8_t KeSetTimerEx(ktimer *, int64_t, uint32_t, kdpc *);
1337144888Swpaulextern uint8_t KeCancelTimer(ktimer *);
1338144888Swpaulextern uint8_t KeReadStateTimer(ktimer *);
1339151248Swpaulextern uint32_t KeWaitForSingleObject(void *, uint32_t,
1340127248Swpaul	uint32_t, uint8_t, int64_t *);
1341144888Swpaulextern void KeInitializeEvent(nt_kevent *, uint32_t, uint8_t);
1342144888Swpaulextern void KeClearEvent(nt_kevent *);
1343144888Swpaulextern uint32_t KeReadStateEvent(nt_kevent *);
1344144888Swpaulextern uint32_t KeSetEvent(nt_kevent *, uint32_t, uint8_t);
1345144888Swpaulextern uint32_t KeResetEvent(nt_kevent *);
1346144175Swpaul#ifdef __i386__
1347144888Swpaulextern void KefAcquireSpinLockAtDpcLevel(kspin_lock *);
1348144888Swpaulextern void KefReleaseSpinLockFromDpcLevel(kspin_lock *);
1349144888Swpaulextern uint8_t KeAcquireSpinLockRaiseToDpc(kspin_lock *);
1350144175Swpaul#else
1351144888Swpaulextern void KeAcquireSpinLockAtDpcLevel(kspin_lock *);
1352144888Swpaulextern void KeReleaseSpinLockFromDpcLevel(kspin_lock *);
1353144175Swpaul#endif
1354144888Swpaulextern void KeInitializeSpinLock(kspin_lock *);
1355151451Swpaulextern uint8_t KeAcquireInterruptSpinLock(kinterrupt *);
1356151451Swpaulextern void KeReleaseInterruptSpinLock(kinterrupt *, uint8_t);
1357151207Swpaulextern uint8_t KeSynchronizeExecution(kinterrupt *, void *, void *);
1358144888Swpaulextern uintptr_t InterlockedExchange(volatile uint32_t *,
1359144888Swpaul	uintptr_t);
1360144888Swpaulextern void *ExAllocatePoolWithTag(uint32_t, size_t, uint32_t);
1361144888Swpaulextern void ExFreePool(void *);
1362151207Swpaulextern uint32_t IoConnectInterrupt(kinterrupt **, void *, void *,
1363151207Swpaul	kspin_lock *, uint32_t, uint8_t, uint8_t, uint8_t, uint8_t,
1364151207Swpaul	uint32_t, uint8_t);
1365151207Swpaulextern void MmBuildMdlForNonPagedPool(mdl *);
1366151207Swpaulextern void IoDisconnectInterrupt(kinterrupt *);
1367144888Swpaulextern uint32_t IoAllocateDriverObjectExtension(driver_object *,
1368141524Swpaul	void *, uint32_t, void **);
1369144888Swpaulextern void *IoGetDriverObjectExtension(driver_object *, void *);
1370144888Swpaulextern uint32_t IoCreateDevice(driver_object *, uint32_t,
1371141524Swpaul	unicode_string *, uint32_t, uint32_t, uint8_t, device_object **);
1372144888Swpaulextern void IoDeleteDevice(device_object *);
1373144888Swpaulextern device_object *IoGetAttachedDevice(device_object *);
1374144888Swpaulextern uint32_t IofCallDriver(device_object *, irp *);
1375144888Swpaulextern void IofCompleteRequest(irp *, uint8_t);
1376144888Swpaulextern void IoAcquireCancelSpinLock(uint8_t *);
1377144888Swpaulextern void IoReleaseCancelSpinLock(uint8_t);
1378144888Swpaulextern uint8_t IoCancelIrp(irp *);
1379144888Swpaulextern void IoDetachDevice(device_object *);
1380144888Swpaulextern device_object *IoAttachDeviceToDeviceStack(device_object *,
1381141524Swpaul	device_object *);
1382145895Swpaulextern mdl *IoAllocateMdl(void *, uint32_t, uint8_t, uint8_t, irp *);
1383145895Swpaulextern void IoFreeMdl(mdl *);
1384145895Swpaulextern io_workitem *IoAllocateWorkItem(device_object *);
1385145895Swpaulextern void ExQueueWorkItem(work_queue_item *, u_int32_t);
1386145895Swpaulextern void IoFreeWorkItem(io_workitem *);
1387145895Swpaulextern void IoQueueWorkItem(io_workitem *, io_workitem_func,
1388145895Swpaul	uint32_t, void *);
1389128229Swpaul
1390144888Swpaul#define IoCallDriver(a, b)		IofCallDriver(a, b)
1391144888Swpaul#define IoCompleteRequest(a, b)		IofCompleteRequest(a, b)
1392140751Swpaul
1393128229Swpaul/*
1394128229Swpaul * On the Windows x86 arch, KeAcquireSpinLock() and KeReleaseSpinLock()
1395128229Swpaul * routines live in the HAL. We try to imitate this behavior.
1396128229Swpaul */
1397128229Swpaul#ifdef __i386__
1398144888Swpaul#define KeAcquireSpinLock(a, b)	*(b) = KfAcquireSpinLock(a)
1399144888Swpaul#define KeReleaseSpinLock(a, b)	KfReleaseSpinLock(a, b)
1400144888Swpaul#define KeRaiseIrql(a)		KfRaiseIrql(a)
1401144888Swpaul#define KeLowerIrql(a)		KfLowerIrql(a)
1402144888Swpaul#define KeAcquireSpinLockAtDpcLevel(a)	KefAcquireSpinLockAtDpcLevel(a)
1403144888Swpaul#define KeReleaseSpinLockFromDpcLevel(a)  KefReleaseSpinLockFromDpcLevel(a)
1404128229Swpaul#endif /* __i386__ */
1405141963Swpaul
1406141963Swpaul#ifdef __amd64__
1407141980Swpaul#define KeAcquireSpinLock(a, b)	*(b) = KfAcquireSpinLock(a)
1408141980Swpaul#define KeReleaseSpinLock(a, b)	KfReleaseSpinLock(a, b)
1409141963Swpaul
1410141963Swpaul/*
1411141963Swpaul * These may need to be redefined later;
1412141963Swpaul * not sure where they live on amd64 yet.
1413141963Swpaul */
1414141963Swpaul#define KeRaiseIrql(a)		KfRaiseIrql(a)
1415141963Swpaul#define KeLowerIrql(a)		KfLowerIrql(a)
1416141963Swpaul#endif /* __amd64__ */
1417141963Swpaul
1418123474Swpaul__END_DECLS
1419123474Swpaul
1420123474Swpaul#endif /* _NTOSKRNL_VAR_H_ */
1421