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