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: releng/11.0/sys/compat/ndis/ntoskrnl_var.h 298828 2016-04-30 00:35:46Z pfg $ 33123474Swpaul */ 34123474Swpaul 35123474Swpaul#ifndef _NTOSKRNL_VAR_H_ 36189488Sweongyo#define _NTOSKRNL_VAR_H_ 37123474Swpaul 38189488Sweongyo#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 { 85189488Sweongyo 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 99189488Sweongyo#define MDL_MAPPED_TO_SYSTEM_VA 0x0001 100189488Sweongyo#define MDL_PAGES_LOCKED 0x0002 101189488Sweongyo#define MDL_SOURCE_IS_NONPAGED_POOL 0x0004 102189488Sweongyo#define MDL_ALLOCATED_FIXED_SIZE 0x0008 103189488Sweongyo#define MDL_PARTIAL 0x0010 104189488Sweongyo#define MDL_PARTIAL_HAS_BEEN_MAPPED 0x0020 105189488Sweongyo#define MDL_IO_PAGE_READ 0x0040 106189488Sweongyo#define MDL_WRITE_OPERATION 0x0080 107189488Sweongyo#define MDL_PARENT_MAPPED_SYSTEM_VA 0x0100 108189488Sweongyo#define MDL_FREE_EXTRA_PTES 0x0200 109189488Sweongyo#define MDL_IO_SPACE 0x0800 110189488Sweongyo#define MDL_NETWORK_HEADER 0x1000 111189488Sweongyo#define MDL_MAPPING_CAN_FAIL 0x2000 112189488Sweongyo#define MDL_ALLOCATED_MUST_SUCCEED 0x4000 113189488Sweongyo#define MDL_ZONE_ALLOCED 0x8000 /* BSD private */ 114140751Swpaul 115189488Sweongyo#define MDL_ZONE_PAGES 16 116189488Sweongyo#define MDL_ZONE_SIZE (sizeof(mdl) + (sizeof(vm_offset_t) * MDL_ZONE_PAGES)) 117142530Swpaul 118123512Swpaul/* Note: assumes x86 page size of 4K. */ 119140751Swpaul 120183003Sthompsa#ifndef PAGE_SHIFT 121140751Swpaul#if PAGE_SIZE == 4096 122189488Sweongyo#define PAGE_SHIFT 12 123140751Swpaul#elif PAGE_SIZE == 8192 124189488Sweongyo#define PAGE_SHIFT 13 125140751Swpaul#else 126140751Swpaul#error PAGE_SHIFT undefined! 127140751Swpaul#endif 128183003Sthompsa#endif 129140751Swpaul 130189488Sweongyo#define SPAN_PAGES(ptr, len) \ 131140751Swpaul ((uint32_t)((((uintptr_t)(ptr) & (PAGE_SIZE - 1)) + \ 132123512Swpaul (len) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)) 133140751Swpaul 134189488Sweongyo#define PAGE_ALIGN(ptr) \ 135123757Swpaul ((void *)((uintptr_t)(ptr) & ~(PAGE_SIZE - 1))) 136140751Swpaul 137189488Sweongyo#define BYTE_OFFSET(ptr) \ 138123757Swpaul ((uint32_t)((uintptr_t)(ptr) & (PAGE_SIZE - 1))) 139140751Swpaul 140189488Sweongyo#define MDL_PAGES(m) (vm_offset_t *)(m + 1) 141140751Swpaul 142189488Sweongyo#define MmInitializeMdl(b, baseva, len) \ 143140751Swpaul (b)->mdl_next = NULL; \ 144140751Swpaul (b)->mdl_size = (uint16_t)(sizeof(mdl) + \ 145144175Swpaul (sizeof(vm_offset_t) * SPAN_PAGES((baseva), (len)))); \ 146140751Swpaul (b)->mdl_flags = 0; \ 147140751Swpaul (b)->mdl_startva = (void *)PAGE_ALIGN((baseva)); \ 148140751Swpaul (b)->mdl_byteoffset = BYTE_OFFSET((baseva)); \ 149140751Swpaul (b)->mdl_bytecount = (uint32_t)(len); 150123512Swpaul 151189488Sweongyo#define MmGetMdlByteOffset(mdl) ((mdl)->mdl_byteoffset) 152189488Sweongyo#define MmGetMdlByteCount(mdl) ((mdl)->mdl_bytecount) 153189488Sweongyo#define MmGetMdlVirtualAddress(mdl) \ 154140751Swpaul ((void *)((char *)((mdl)->mdl_startva) + (mdl)->mdl_byteoffset)) 155189488Sweongyo#define MmGetMdlStartVa(mdl) ((mdl)->mdl_startva) 156189488Sweongyo#define MmGetMdlPfnArray(mdl) MDL_PAGES(mdl) 157140751Swpaul 158189488Sweongyo#define WDM_MAJOR 1 159189488Sweongyo#define WDM_MINOR_WIN98 0x00 160189488Sweongyo#define WDM_MINOR_WINME 0x05 161189488Sweongyo#define WDM_MINOR_WIN2000 0x10 162189488Sweongyo#define WDM_MINOR_WINXP 0x20 163189488Sweongyo#define WDM_MINOR_WIN2003 0x30 164124729Swpaul 165215419Sbschmidtenum nt_caching_type { 166215419Sbschmidt MmNonCached = 0, 167215419Sbschmidt MmCached = 1, 168215419Sbschmidt MmWriteCombined = 2, 169215419Sbschmidt MmHardwareCoherentCached = 3, 170215419Sbschmidt MmNonCachedUnordered = 4, 171215419Sbschmidt MmUSWCCached = 5, 172215419Sbschmidt MmMaximumCacheType = 6 173215419Sbschmidt}; 174215419Sbschmidt 175124582Sobrien/*- 176124582Sobrien * The ndis_kspin_lock type is called KSPIN_LOCK in MS-Windows. 177124582Sobrien * According to the Windows DDK header files, KSPIN_LOCK is defined like this: 178124582Sobrien * typedef ULONG_PTR KSPIN_LOCK; 179124582Sobrien * 180124582Sobrien * From basetsd.h (SDK, Feb. 2003): 181189488Sweongyo * typedef [public] unsigned __int3264 ULONG_PTR, *PULONG_PTR; 182189488Sweongyo * typedef unsigned __int64 ULONG_PTR, *PULONG_PTR; 183189488Sweongyo * typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR; 184189488Sweongyo * 185124582Sobrien * The keyword __int3264 specifies an integral type that has the following 186124582Sobrien * properties: 187124582Sobrien * + It is 32-bit on 32-bit platforms 188124582Sobrien * + It is 64-bit on 64-bit platforms 189124582Sobrien * + It is 32-bit on the wire for backward compatibility. 190124582Sobrien * It gets truncated on the sending side and extended appropriately 191124582Sobrien * (signed or unsigned) on the receiving side. 192124582Sobrien * 193124582Sobrien * Thus register_t seems the proper mapping onto FreeBSD for spin locks. 194124582Sobrien */ 195123474Swpaul 196124582Sobrientypedef register_t kspin_lock; 197124582Sobrien 198123474Swpaulstruct slist_entry { 199123474Swpaul struct slist_entry *sl_next; 200123474Swpaul}; 201123474Swpaul 202123474Swpaultypedef struct slist_entry slist_entry; 203123474Swpaul 204123474Swpaulunion slist_header { 205123474Swpaul uint64_t slh_align; 206123474Swpaul struct { 207123474Swpaul struct slist_entry *slh_next; 208123474Swpaul uint16_t slh_depth; 209123474Swpaul uint16_t slh_seq; 210123474Swpaul } slh_list; 211123474Swpaul}; 212123474Swpaul 213123474Swpaultypedef union slist_header slist_header; 214123474Swpaul 215123507Swpaulstruct list_entry { 216189488Sweongyo struct list_entry *nle_flink; 217189488Sweongyo struct list_entry *nle_blink; 218123507Swpaul}; 219123507Swpaul 220123507Swpaultypedef struct list_entry list_entry; 221123507Swpaul 222189488Sweongyo#define InitializeListHead(l) \ 223141524Swpaul (l)->nle_flink = (l)->nle_blink = (l) 224125551Swpaul 225189488Sweongyo#define IsListEmpty(h) \ 226151207Swpaul ((h)->nle_flink == (h)) 227151207Swpaul 228189488Sweongyo#define RemoveEntryList(e) \ 229125551Swpaul do { \ 230125551Swpaul list_entry *b; \ 231125551Swpaul list_entry *f; \ 232125551Swpaul \ 233151207Swpaul f = (e)->nle_flink; \ 234151207Swpaul b = (e)->nle_blink; \ 235125551Swpaul b->nle_flink = f; \ 236125551Swpaul f->nle_blink = b; \ 237125551Swpaul } while (0) 238125551Swpaul 239151207Swpaul/* These two have to be inlined since they return things. */ 240125551Swpaul 241151207Swpaulstatic __inline__ list_entry * 242151207SwpaulRemoveHeadList(list_entry *l) 243151207Swpaul{ 244151207Swpaul list_entry *f; 245151207Swpaul list_entry *e; 246125551Swpaul 247151207Swpaul e = l->nle_flink; 248151207Swpaul f = e->nle_flink; 249151207Swpaul l->nle_flink = f; 250151207Swpaul f->nle_blink = l; 251151207Swpaul 252151207Swpaul return (e); 253151207Swpaul} 254151207Swpaul 255151207Swpaulstatic __inline__ list_entry * 256151207SwpaulRemoveTailList(list_entry *l) 257151207Swpaul{ 258151207Swpaul list_entry *b; 259151207Swpaul list_entry *e; 260151207Swpaul 261151207Swpaul e = l->nle_blink; 262151207Swpaul b = e->nle_blink; 263151207Swpaul l->nle_blink = b; 264151207Swpaul b->nle_flink = l; 265151207Swpaul 266151207Swpaul return (e); 267151207Swpaul} 268151207Swpaul 269189488Sweongyo#define InsertTailList(l, e) \ 270125551Swpaul do { \ 271125551Swpaul list_entry *b; \ 272125551Swpaul \ 273125551Swpaul b = l->nle_blink; \ 274125860Swpaul e->nle_flink = l; \ 275125551Swpaul e->nle_blink = b; \ 276141524Swpaul b->nle_flink = (e); \ 277141524Swpaul l->nle_blink = (e); \ 278125551Swpaul } while (0) 279125551Swpaul 280189488Sweongyo#define InsertHeadList(l, e) \ 281125551Swpaul do { \ 282125551Swpaul list_entry *f; \ 283125551Swpaul \ 284125551Swpaul f = l->nle_flink; \ 285125551Swpaul e->nle_flink = f; \ 286125551Swpaul e->nle_blink = l; \ 287125551Swpaul f->nle_blink = e; \ 288125551Swpaul l->nle_flink = e; \ 289125551Swpaul } while (0) 290125551Swpaul 291189488Sweongyo#define CONTAINING_RECORD(addr, type, field) \ 292145895Swpaul ((type *)((vm_offset_t)(addr) - (vm_offset_t)(&((type *)0)->field))) 293145895Swpaul 294125551Swpaulstruct nt_dispatch_header { 295125551Swpaul uint8_t dh_type; 296125551Swpaul uint8_t dh_abs; 297125551Swpaul uint8_t dh_size; 298125551Swpaul uint8_t dh_inserted; 299151207Swpaul int32_t dh_sigstate; 300125551Swpaul list_entry dh_waitlisthead; 301125551Swpaul}; 302125551Swpaul 303125551Swpaultypedef struct nt_dispatch_header nt_dispatch_header; 304125551Swpaul 305151207Swpaul/* Dispatcher object types */ 306151207Swpaul 307189488Sweongyo#define DISP_TYPE_NOTIFICATION_EVENT 0 /* KEVENT */ 308189488Sweongyo#define DISP_TYPE_SYNCHRONIZATION_EVENT 1 /* KEVENT */ 309189488Sweongyo#define DISP_TYPE_MUTANT 2 /* KMUTANT/KMUTEX */ 310189488Sweongyo#define DISP_TYPE_PROCESS 3 /* KPROCESS */ 311189488Sweongyo#define DISP_TYPE_QUEUE 4 /* KQUEUE */ 312189488Sweongyo#define DISP_TYPE_SEMAPHORE 5 /* KSEMAPHORE */ 313189488Sweongyo#define DISP_TYPE_THREAD 6 /* KTHREAD */ 314189488Sweongyo#define DISP_TYPE_NOTIFICATION_TIMER 8 /* KTIMER */ 315189488Sweongyo#define DISP_TYPE_SYNCHRONIZATION_TIMER 9 /* KTIMER */ 316151207Swpaul 317189488Sweongyo#define OTYPE_EVENT 0 318189488Sweongyo#define OTYPE_MUTEX 1 319189488Sweongyo#define OTYPE_THREAD 2 320189488Sweongyo#define OTYPE_TIMER 3 321125551Swpaul 322125551Swpaul/* Windows dispatcher levels. */ 323125551Swpaul 324189488Sweongyo#define PASSIVE_LEVEL 0 325189488Sweongyo#define LOW_LEVEL 0 326189488Sweongyo#define APC_LEVEL 1 327189488Sweongyo#define DISPATCH_LEVEL 2 328189488Sweongyo#define DEVICE_LEVEL (DISPATCH_LEVEL + 1) 329189488Sweongyo#define PROFILE_LEVEL 27 330189488Sweongyo#define CLOCK1_LEVEL 28 331189488Sweongyo#define CLOCK2_LEVEL 28 332189488Sweongyo#define IPI_LEVEL 29 333189488Sweongyo#define POWER_LEVEL 30 334189488Sweongyo#define HIGH_LEVEL 31 335125551Swpaul 336189488Sweongyo#define SYNC_LEVEL_UP DISPATCH_LEVEL 337189488Sweongyo#define SYNC_LEVEL_MP (IPI_LEVEL - 1) 338125551Swpaul 339189488Sweongyo#define AT_PASSIVE_LEVEL(td) \ 340295435Skib ((td)->td_proc->p_flag & P_KPROC == FALSE) 341128229Swpaul 342189488Sweongyo#define AT_DISPATCH_LEVEL(td) \ 343128449Swpaul ((td)->td_base_pri == PI_REALTIME) 344128229Swpaul 345189488Sweongyo#define AT_DIRQL_LEVEL(td) \ 346128295Swpaul ((td)->td_priority <= PI_NET) 347128229Swpaul 348189488Sweongyo#define AT_HIGH_LEVEL(td) \ 349128229Swpaul ((td)->td_critnest != 0) 350128229Swpaul 351125551Swpaulstruct nt_objref { 352125551Swpaul nt_dispatch_header no_dh; 353125551Swpaul void *no_obj; 354125551Swpaul TAILQ_ENTRY(nt_objref) link; 355125551Swpaul}; 356125551Swpaul 357125551SwpaulTAILQ_HEAD(nt_objref_head, nt_objref); 358125551Swpaul 359125551Swpaultypedef struct nt_objref nt_objref; 360125551Swpaul 361189488Sweongyo#define EVENT_TYPE_NOTIFY 0 362189488Sweongyo#define EVENT_TYPE_SYNC 1 363125551Swpaul 364126620Swpaul/* 365126620Swpaul * We need to use the timeout()/untimeout() API for ktimers 366126620Swpaul * since timers can be initialized, but not destroyed (so 367126620Swpaul * malloc()ing our own callout structures would mean a leak, 368126620Swpaul * since there'd be no way to free() them). This means we 369126620Swpaul * need to use struct callout_handle, which is really just a 370126620Swpaul * pointer. To make it easier to deal with, we use a union 371126620Swpaul * to overlay the callout_handle over the k_timerlistentry. 372126620Swpaul * The latter is a list_entry, which is two pointers, so 373126620Swpaul * there's enough space available to hide a callout_handle 374126620Swpaul * there. 375126620Swpaul */ 376126620Swpaul 377125551Swpaulstruct ktimer { 378125551Swpaul nt_dispatch_header k_header; 379125551Swpaul uint64_t k_duetime; 380126620Swpaul union { 381126620Swpaul list_entry k_timerlistentry; 382151207Swpaul struct callout *k_callout; 383126620Swpaul } u; 384125551Swpaul void *k_dpc; 385125551Swpaul uint32_t k_period; 386125551Swpaul}; 387125551Swpaul 388189488Sweongyo#define k_timerlistentry u.k_timerlistentry 389189488Sweongyo#define k_callout u.k_callout 390126620Swpaul 391126620Swpaultypedef struct ktimer ktimer; 392126620Swpaul 393125551Swpaulstruct nt_kevent { 394125551Swpaul nt_dispatch_header k_header; 395125551Swpaul}; 396125551Swpaul 397125551Swpaultypedef struct nt_kevent nt_kevent; 398125551Swpaul 399125551Swpaul/* Kernel defered procedure call (i.e. timer callback) */ 400125551Swpaul 401125551Swpaulstruct kdpc; 402144888Swpaultypedef void (*kdpc_func)(struct kdpc *, void *, void *, void *); 403125551Swpaul 404125551Swpaulstruct kdpc { 405125551Swpaul uint16_t k_type; 406145895Swpaul uint8_t k_num; /* CPU number */ 407145895Swpaul uint8_t k_importance; /* priority */ 408125551Swpaul list_entry k_dpclistentry; 409140827Swpaul void *k_deferedfunc; 410125551Swpaul void *k_deferredctx; 411125551Swpaul void *k_sysarg1; 412125551Swpaul void *k_sysarg2; 413145895Swpaul void *k_lock; 414125551Swpaul}; 415125551Swpaul 416189488Sweongyo#define KDPC_IMPORTANCE_LOW 0 417189488Sweongyo#define KDPC_IMPORTANCE_MEDIUM 1 418189488Sweongyo#define KDPC_IMPORTANCE_HIGH 2 419145895Swpaul 420189488Sweongyo#define KDPC_CPU_DEFAULT 255 421145895Swpaul 422126620Swpaultypedef struct kdpc kdpc; 423126620Swpaul 424125551Swpaul/* 425125551Swpaul * Note: the acquisition count is BSD-specific. The Microsoft 426125551Swpaul * documentation says that mutexes can be acquired recursively 427125551Swpaul * by a given thread, but that you must release the mutex as 428125551Swpaul * many times as you acquired it before it will be set to the 429125551Swpaul * signalled state (i.e. before any other threads waiting on 430125551Swpaul * the object will be woken up). However the Windows KMUTANT 431125551Swpaul * structure has no field for keeping track of the number of 432125551Swpaul * acquisitions, so we need to add one ourselves. As long as 433125551Swpaul * driver code treats the mutex as opaque, we should be ok. 434125551Swpaul */ 435125551Swpaulstruct kmutant { 436125551Swpaul nt_dispatch_header km_header; 437151207Swpaul list_entry km_listentry; 438125551Swpaul void *km_ownerthread; 439125551Swpaul uint8_t km_abandoned; 440125551Swpaul uint8_t km_apcdisable; 441125551Swpaul}; 442125551Swpaul 443125551Swpaultypedef struct kmutant kmutant; 444125551Swpaul 445189488Sweongyo#define LOOKASIDE_DEPTH 256 446125860Swpaul 447123474Swpaulstruct general_lookaside { 448123474Swpaul slist_header gl_listhead; 449123474Swpaul uint16_t gl_depth; 450123474Swpaul uint16_t gl_maxdepth; 451123474Swpaul uint32_t gl_totallocs; 452123474Swpaul union { 453123474Swpaul uint32_t gl_allocmisses; 454123474Swpaul uint32_t gl_allochits; 455123474Swpaul } u_a; 456123474Swpaul uint32_t gl_totalfrees; 457123474Swpaul union { 458123474Swpaul uint32_t gl_freemisses; 459123474Swpaul uint32_t gl_freehits; 460123474Swpaul } u_m; 461123474Swpaul uint32_t gl_type; 462123474Swpaul uint32_t gl_tag; 463123474Swpaul uint32_t gl_size; 464123474Swpaul void *gl_allocfunc; 465123474Swpaul void *gl_freefunc; 466123507Swpaul list_entry gl_listent; 467123474Swpaul uint32_t gl_lasttotallocs; 468123474Swpaul union { 469123474Swpaul uint32_t gl_lastallocmisses; 470123474Swpaul uint32_t gl_lastallochits; 471123474Swpaul } u_l; 472123474Swpaul uint32_t gl_rsvd[2]; 473123474Swpaul}; 474123474Swpaul 475123474Swpaultypedef struct general_lookaside general_lookaside; 476123474Swpaul 477123474Swpaulstruct npaged_lookaside_list { 478123474Swpaul general_lookaside nll_l; 479144240Swpaul#ifdef __i386__ 480123474Swpaul kspin_lock nll_obsoletelock; 481144240Swpaul#endif 482123474Swpaul}; 483123474Swpaul 484123474Swpaultypedef struct npaged_lookaside_list npaged_lookaside_list; 485123474Swpaultypedef struct npaged_lookaside_list paged_lookaside_list; 486123474Swpaul 487123474Swpaultypedef void * (*lookaside_alloc_func)(uint32_t, size_t, uint32_t); 488123474Swpaultypedef void (*lookaside_free_func)(void *); 489123474Swpaul 490125551Swpaulstruct irp; 491123474Swpaul 492125551Swpaulstruct kdevice_qentry { 493125551Swpaul list_entry kqe_devlistent; 494125551Swpaul uint32_t kqe_sortkey; 495125551Swpaul uint8_t kqe_inserted; 496125551Swpaul}; 497125551Swpaul 498125551Swpaultypedef struct kdevice_qentry kdevice_qentry; 499125551Swpaul 500125551Swpaulstruct kdevice_queue { 501125551Swpaul uint16_t kq_type; 502125551Swpaul uint16_t kq_size; 503125551Swpaul list_entry kq_devlisthead; 504125551Swpaul kspin_lock kq_lock; 505125551Swpaul uint8_t kq_busy; 506125551Swpaul}; 507125551Swpaul 508125551Swpaultypedef struct kdevice_queue kdevice_queue; 509125551Swpaul 510125551Swpaulstruct wait_ctx_block { 511125551Swpaul kdevice_qentry wcb_waitqueue; 512125551Swpaul void *wcb_devfunc; 513125551Swpaul void *wcb_devctx; 514125551Swpaul uint32_t wcb_mapregcnt; 515125551Swpaul void *wcb_devobj; 516125551Swpaul void *wcb_curirp; 517125551Swpaul void *wcb_bufchaindpc; 518125551Swpaul}; 519125551Swpaul 520125551Swpaultypedef struct wait_ctx_block wait_ctx_block; 521125551Swpaul 522125551Swpaulstruct wait_block { 523125551Swpaul list_entry wb_waitlist; 524125551Swpaul void *wb_kthread; 525125551Swpaul nt_dispatch_header *wb_object; 526125551Swpaul struct wait_block *wb_next; 527151207Swpaul#ifdef notdef 528125551Swpaul uint16_t wb_waitkey; 529125551Swpaul uint16_t wb_waittype; 530151207Swpaul#endif 531151207Swpaul uint8_t wb_waitkey; 532151207Swpaul uint8_t wb_waittype; 533151207Swpaul uint8_t wb_awakened; 534151207Swpaul uint8_t wb_oldpri; 535125551Swpaul}; 536125551Swpaul 537125551Swpaultypedef struct wait_block wait_block; 538125551Swpaul 539189488Sweongyo#define wb_ext wb_kthread 540151207Swpaul 541189488Sweongyo#define THREAD_WAIT_OBJECTS 3 542189488Sweongyo#define MAX_WAIT_OBJECTS 64 543125551Swpaul 544189488Sweongyo#define WAITTYPE_ALL 0 545189488Sweongyo#define WAITTYPE_ANY 1 546125551Swpaul 547189488Sweongyo#define WAITKEY_VALID 0x8000 548151207Swpaul 549186507Sweongyo/* kthread priority */ 550186507Sweongyo#define LOW_PRIORITY 0 551186507Sweongyo#define LOW_REALTIME_PRIORITY 16 552186507Sweongyo#define HIGH_PRIORITY 31 553186507Sweongyo 554125551Swpaulstruct thread_context { 555125551Swpaul void *tc_thrctx; 556125551Swpaul void *tc_thrfunc; 557125551Swpaul}; 558125551Swpaul 559125551Swpaultypedef struct thread_context thread_context; 560125551Swpaul 561140751Swpaul/* Forward declaration */ 562140751Swpaulstruct driver_object; 563140751Swpaulstruct devobj_extension; 564140751Swpaul 565140751Swpaulstruct driver_extension { 566140751Swpaul struct driver_object *dre_driverobj; 567140751Swpaul void *dre_adddevicefunc; 568140751Swpaul uint32_t dre_reinitcnt; 569140751Swpaul unicode_string dre_srvname; 570141524Swpaul 571141524Swpaul /* 572141524Swpaul * Drivers are allowed to add one or more custom extensions 573141524Swpaul * to the driver object, but there's no special pointer 574141524Swpaul * for them. Hang them off here for now. 575141524Swpaul */ 576141524Swpaul 577141524Swpaul list_entry dre_usrext; 578140751Swpaul}; 579140751Swpaul 580140751Swpaultypedef struct driver_extension driver_extension; 581140751Swpaul 582141524Swpaulstruct custom_extension { 583141524Swpaul list_entry ce_list; 584141524Swpaul void *ce_clid; 585141524Swpaul}; 586141524Swpaul 587141524Swpaultypedef struct custom_extension custom_extension; 588141524Swpaul 589140751Swpaul/* 590151207Swpaul * The KINTERRUPT structure in Windows is opaque to drivers. 591151207Swpaul * We define our own custom version with things we need. 592151207Swpaul */ 593151207Swpaul 594151207Swpaulstruct kinterrupt { 595151451Swpaul list_entry ki_list; 596151207Swpaul device_t ki_dev; 597151451Swpaul int ki_rid; 598151207Swpaul void *ki_cookie; 599151207Swpaul struct resource *ki_irq; 600151207Swpaul kspin_lock ki_lock_priv; 601151207Swpaul kspin_lock *ki_lock; 602151207Swpaul void *ki_svcfunc; 603151207Swpaul void *ki_svcctx; 604151207Swpaul}; 605151207Swpaul 606151207Swpaultypedef struct kinterrupt kinterrupt; 607151207Swpaul 608215708Sbschmidtstruct ksystem_time { 609215708Sbschmidt uint32_t low_part; 610215708Sbschmidt int32_t high1_time; 611215708Sbschmidt int32_t high2_time; 612215708Sbschmidt}; 613215708Sbschmidt 614215708Sbschmidtenum nt_product_type { 615215708Sbschmidt NT_PRODUCT_WIN_NT = 1, 616215708Sbschmidt NT_PRODUCT_LAN_MAN_NT, 617215708Sbschmidt NT_PRODUCT_SERVER 618215708Sbschmidt}; 619215708Sbschmidt 620215708Sbschmidtenum alt_arch_type { 621215708Sbschmidt STANDARD_DESIGN, 622215708Sbschmidt NEC98x86, 623215708Sbschmidt END_ALTERNATIVES 624215708Sbschmidt}; 625215708Sbschmidt 626215708Sbschmidtstruct kuser_shared_data { 627215708Sbschmidt uint32_t tick_count; 628215708Sbschmidt uint32_t tick_count_multiplier; 629215708Sbschmidt volatile struct ksystem_time interrupt_time; 630215708Sbschmidt volatile struct ksystem_time system_time; 631215708Sbschmidt volatile struct ksystem_time time_zone_bias; 632215708Sbschmidt uint16_t image_number_low; 633215708Sbschmidt uint16_t image_number_high; 634215708Sbschmidt int16_t nt_system_root[260]; 635215708Sbschmidt uint32_t max_stack_trace_depth; 636215708Sbschmidt uint32_t crypto_exponent; 637215708Sbschmidt uint32_t time_zone_id; 638215708Sbschmidt uint32_t large_page_min; 639215708Sbschmidt uint32_t reserved2[7]; 640215708Sbschmidt enum nt_product_type nt_product_type; 641215708Sbschmidt uint8_t product_type_is_valid; 642215708Sbschmidt uint32_t nt_major_version; 643215708Sbschmidt uint32_t nt_minor_version; 644215708Sbschmidt uint8_t processor_features[64]; 645215708Sbschmidt uint32_t reserved1; 646215708Sbschmidt uint32_t reserved3; 647215708Sbschmidt volatile uint32_t time_slip; 648215708Sbschmidt enum alt_arch_type alt_arch_type; 649215708Sbschmidt int64_t system_expiration_date; 650215708Sbschmidt uint32_t suite_mask; 651215708Sbschmidt uint8_t kdbg_enabled; 652215708Sbschmidt volatile uint32_t active_console; 653215708Sbschmidt volatile uint32_t dismount_count; 654215708Sbschmidt uint32_t com_plus_package; 655215708Sbschmidt uint32_t last_system_rit_event_tick_count; 656215708Sbschmidt uint32_t num_phys_pages; 657215708Sbschmidt uint8_t safe_boot_mode; 658215708Sbschmidt uint32_t trace_log; 659215708Sbschmidt uint64_t fill0; 660215708Sbschmidt uint64_t sys_call[4]; 661215708Sbschmidt union { 662215708Sbschmidt volatile struct ksystem_time tick_count; 663215708Sbschmidt volatile uint64_t tick_count_quad; 664215708Sbschmidt } tick; 665215708Sbschmidt}; 666215708Sbschmidt 667151207Swpaul/* 668140751Swpaul * In Windows, there are Physical Device Objects (PDOs) and 669140751Swpaul * Functional Device Objects (FDOs). Physical Device Objects are 670140751Swpaul * created and maintained by bus drivers. For example, the PCI 671140751Swpaul * bus driver might detect two PCI ethernet cards on a given 672140751Swpaul * bus. The PCI bus driver will then allocate two device_objects 673298828Spfg * for its own internal bookeeping purposes. This is analogous 674140751Swpaul * to the device_t that the FreeBSD PCI code allocates and passes 675140751Swpaul * into each PCI driver's probe and attach routines. 676140751Swpaul * 677140751Swpaul * When an ethernet driver claims one of the ethernet cards 678140751Swpaul * on the bus, it will create its own device_object. This is 679298828Spfg * the Functional Device Object. This object is analogous to the 680140751Swpaul * device-specific softc structure. 681140751Swpaul */ 682140751Swpaul 683125551Swpaulstruct device_object { 684125551Swpaul uint16_t do_type; 685125551Swpaul uint16_t do_size; 686125551Swpaul uint32_t do_refcnt; 687141524Swpaul struct driver_object *do_drvobj; 688125551Swpaul struct device_object *do_nextdev; 689125551Swpaul struct device_object *do_attacheddev; 690125551Swpaul struct irp *do_currirp; 691125551Swpaul void *do_iotimer; 692125551Swpaul uint32_t do_flags; 693125551Swpaul uint32_t do_characteristics; 694125551Swpaul void *do_vpb; 695125551Swpaul void *do_devext; 696141524Swpaul uint32_t do_devtype; 697125551Swpaul uint8_t do_stacksize; 698125551Swpaul union { 699125551Swpaul list_entry do_listent; 700125551Swpaul wait_ctx_block do_wcb; 701125551Swpaul } queue; 702125551Swpaul uint32_t do_alignreq; 703125551Swpaul kdevice_queue do_devqueue; 704125551Swpaul struct kdpc do_dpc; 705125551Swpaul uint32_t do_activethreads; 706125551Swpaul void *do_securitydesc; 707125551Swpaul struct nt_kevent do_devlock; 708125551Swpaul uint16_t do_sectorsz; 709125551Swpaul uint16_t do_spare1; 710140751Swpaul struct devobj_extension *do_devobj_ext; 711125551Swpaul void *do_rsvd; 712125551Swpaul}; 713125551Swpaul 714125551Swpaultypedef struct device_object device_object; 715125551Swpaul 716140751Swpaulstruct devobj_extension { 717140751Swpaul uint16_t dve_type; 718140751Swpaul uint16_t dve_size; 719140751Swpaul device_object *dve_devobj; 720140751Swpaul}; 721140751Swpaul 722140751Swpaultypedef struct devobj_extension devobj_extension; 723140751Swpaul 724142311Swpaul/* Device object flags */ 725142311Swpaul 726189488Sweongyo#define DO_VERIFY_VOLUME 0x00000002 727189488Sweongyo#define DO_BUFFERED_IO 0x00000004 728189488Sweongyo#define DO_EXCLUSIVE 0x00000008 729189488Sweongyo#define DO_DIRECT_IO 0x00000010 730189488Sweongyo#define DO_MAP_IO_BUFFER 0x00000020 731189488Sweongyo#define DO_DEVICE_HAS_NAME 0x00000040 732189488Sweongyo#define DO_DEVICE_INITIALIZING 0x00000080 733189488Sweongyo#define DO_SYSTEM_BOOT_PARTITION 0x00000100 734189488Sweongyo#define DO_LONG_TERM_REQUESTS 0x00000200 735189488Sweongyo#define DO_NEVER_LAST_DEVICE 0x00000400 736189488Sweongyo#define DO_SHUTDOWN_REGISTERED 0x00000800 737189488Sweongyo#define DO_BUS_ENUMERATED_DEVICE 0x00001000 738189488Sweongyo#define DO_POWER_PAGABLE 0x00002000 739189488Sweongyo#define DO_POWER_INRUSH 0x00004000 740189488Sweongyo#define DO_LOW_PRIORITY_FILESYSTEM 0x00010000 741142311Swpaul 742142311Swpaul/* Priority boosts */ 743142311Swpaul 744189488Sweongyo#define IO_NO_INCREMENT 0 745189488Sweongyo#define IO_CD_ROM_INCREMENT 1 746189488Sweongyo#define IO_DISK_INCREMENT 1 747189488Sweongyo#define IO_KEYBOARD_INCREMENT 6 748189488Sweongyo#define IO_MAILSLOT_INCREMENT 2 749189488Sweongyo#define IO_MOUSE_INCREMENT 6 750189488Sweongyo#define IO_NAMED_PIPE_INCREMENT 2 751189488Sweongyo#define IO_NETWORK_INCREMENT 2 752189488Sweongyo#define IO_PARALLEL_INCREMENT 1 753189488Sweongyo#define IO_SERIAL_INCREMENT 2 754189488Sweongyo#define IO_SOUND_INCREMENT 8 755189488Sweongyo#define IO_VIDEO_INCREMENT 1 756140751Swpaul 757140751Swpaul/* IRP major codes */ 758140751Swpaul 759189488Sweongyo#define IRP_MJ_CREATE 0x00 760189488Sweongyo#define IRP_MJ_CREATE_NAMED_PIPE 0x01 761189488Sweongyo#define IRP_MJ_CLOSE 0x02 762189488Sweongyo#define IRP_MJ_READ 0x03 763189488Sweongyo#define IRP_MJ_WRITE 0x04 764189488Sweongyo#define IRP_MJ_QUERY_INFORMATION 0x05 765189488Sweongyo#define IRP_MJ_SET_INFORMATION 0x06 766189488Sweongyo#define IRP_MJ_QUERY_EA 0x07 767189488Sweongyo#define IRP_MJ_SET_EA 0x08 768189488Sweongyo#define IRP_MJ_FLUSH_BUFFERS 0x09 769189488Sweongyo#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a 770189488Sweongyo#define IRP_MJ_SET_VOLUME_INFORMATION 0x0b 771189488Sweongyo#define IRP_MJ_DIRECTORY_CONTROL 0x0c 772189488Sweongyo#define IRP_MJ_FILE_SYSTEM_CONTROL 0x0d 773189488Sweongyo#define IRP_MJ_DEVICE_CONTROL 0x0e 774189488Sweongyo#define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f 775189488Sweongyo#define IRP_MJ_SHUTDOWN 0x10 776189488Sweongyo#define IRP_MJ_LOCK_CONTROL 0x11 777189488Sweongyo#define IRP_MJ_CLEANUP 0x12 778189488Sweongyo#define IRP_MJ_CREATE_MAILSLOT 0x13 779189488Sweongyo#define IRP_MJ_QUERY_SECURITY 0x14 780189488Sweongyo#define IRP_MJ_SET_SECURITY 0x15 781189488Sweongyo#define IRP_MJ_POWER 0x16 782189488Sweongyo#define IRP_MJ_SYSTEM_CONTROL 0x17 783189488Sweongyo#define IRP_MJ_DEVICE_CHANGE 0x18 784189488Sweongyo#define IRP_MJ_QUERY_QUOTA 0x19 785189488Sweongyo#define IRP_MJ_SET_QUOTA 0x1a 786189488Sweongyo#define IRP_MJ_PNP 0x1b 787189488Sweongyo#define IRP_MJ_PNP_POWER IRP_MJ_PNP // Obsolete.... 788189488Sweongyo#define IRP_MJ_MAXIMUM_FUNCTION 0x1b 789189488Sweongyo#define IRP_MJ_SCSI IRP_MJ_INTERNAL_DEVICE_CONTROL 790140751Swpaul 791140751Swpaul/* IRP minor codes */ 792140751Swpaul 793189488Sweongyo#define IRP_MN_QUERY_DIRECTORY 0x01 794189488Sweongyo#define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x02 795189488Sweongyo#define IRP_MN_USER_FS_REQUEST 0x00 796140751Swpaul 797189488Sweongyo#define IRP_MN_MOUNT_VOLUME 0x01 798189488Sweongyo#define IRP_MN_VERIFY_VOLUME 0x02 799189488Sweongyo#define IRP_MN_LOAD_FILE_SYSTEM 0x03 800189488Sweongyo#define IRP_MN_TRACK_LINK 0x04 801189488Sweongyo#define IRP_MN_KERNEL_CALL 0x04 802140751Swpaul 803189488Sweongyo#define IRP_MN_LOCK 0x01 804189488Sweongyo#define IRP_MN_UNLOCK_SINGLE 0x02 805189488Sweongyo#define IRP_MN_UNLOCK_ALL 0x03 806189488Sweongyo#define IRP_MN_UNLOCK_ALL_BY_KEY 0x04 807140751Swpaul 808189488Sweongyo#define IRP_MN_NORMAL 0x00 809189488Sweongyo#define IRP_MN_DPC 0x01 810189488Sweongyo#define IRP_MN_MDL 0x02 811189488Sweongyo#define IRP_MN_COMPLETE 0x04 812189488Sweongyo#define IRP_MN_COMPRESSED 0x08 813140751Swpaul 814189488Sweongyo#define IRP_MN_MDL_DPC (IRP_MN_MDL | IRP_MN_DPC) 815189488Sweongyo#define IRP_MN_COMPLETE_MDL (IRP_MN_COMPLETE | IRP_MN_MDL) 816189488Sweongyo#define IRP_MN_COMPLETE_MDL_DPC (IRP_MN_COMPLETE_MDL | IRP_MN_DPC) 817140751Swpaul 818189488Sweongyo#define IRP_MN_SCSI_CLASS 0x01 819140751Swpaul 820189488Sweongyo#define IRP_MN_START_DEVICE 0x00 821189488Sweongyo#define IRP_MN_QUERY_REMOVE_DEVICE 0x01 822189488Sweongyo#define IRP_MN_REMOVE_DEVICE 0x02 823189488Sweongyo#define IRP_MN_CANCEL_REMOVE_DEVICE 0x03 824189488Sweongyo#define IRP_MN_STOP_DEVICE 0x04 825189488Sweongyo#define IRP_MN_QUERY_STOP_DEVICE 0x05 826189488Sweongyo#define IRP_MN_CANCEL_STOP_DEVICE 0x06 827140751Swpaul 828189488Sweongyo#define IRP_MN_QUERY_DEVICE_RELATIONS 0x07 829189488Sweongyo#define IRP_MN_QUERY_INTERFACE 0x08 830189488Sweongyo#define IRP_MN_QUERY_CAPABILITIES 0x09 831189488Sweongyo#define IRP_MN_QUERY_RESOURCES 0x0A 832189488Sweongyo#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS 0x0B 833189488Sweongyo#define IRP_MN_QUERY_DEVICE_TEXT 0x0C 834189488Sweongyo#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS 0x0D 835140751Swpaul 836189488Sweongyo#define IRP_MN_READ_CONFIG 0x0F 837189488Sweongyo#define IRP_MN_WRITE_CONFIG 0x10 838189488Sweongyo#define IRP_MN_EJECT 0x11 839189488Sweongyo#define IRP_MN_SET_LOCK 0x12 840189488Sweongyo#define IRP_MN_QUERY_ID 0x13 841189488Sweongyo#define IRP_MN_QUERY_PNP_DEVICE_STATE 0x14 842189488Sweongyo#define IRP_MN_QUERY_BUS_INFORMATION 0x15 843189488Sweongyo#define IRP_MN_DEVICE_USAGE_NOTIFICATION 0x16 844189488Sweongyo#define IRP_MN_SURPRISE_REMOVAL 0x17 845189488Sweongyo#define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18 846140751Swpaul 847189488Sweongyo#define IRP_MN_WAIT_WAKE 0x00 848189488Sweongyo#define IRP_MN_POWER_SEQUENCE 0x01 849189488Sweongyo#define IRP_MN_SET_POWER 0x02 850189488Sweongyo#define IRP_MN_QUERY_POWER 0x03 851140751Swpaul 852189488Sweongyo#define IRP_MN_QUERY_ALL_DATA 0x00 853189488Sweongyo#define IRP_MN_QUERY_SINGLE_INSTANCE 0x01 854189488Sweongyo#define IRP_MN_CHANGE_SINGLE_INSTANCE 0x02 855189488Sweongyo#define IRP_MN_CHANGE_SINGLE_ITEM 0x03 856189488Sweongyo#define IRP_MN_ENABLE_EVENTS 0x04 857189488Sweongyo#define IRP_MN_DISABLE_EVENTS 0x05 858189488Sweongyo#define IRP_MN_ENABLE_COLLECTION 0x06 859189488Sweongyo#define IRP_MN_DISABLE_COLLECTION 0x07 860189488Sweongyo#define IRP_MN_REGINFO 0x08 861189488Sweongyo#define IRP_MN_EXECUTE_METHOD 0x09 862189488Sweongyo#define IRP_MN_REGINFO_EX 0x0b 863140751Swpaul 864140751Swpaul/* IRP flags */ 865140751Swpaul 866189488Sweongyo#define IRP_NOCACHE 0x00000001 867189488Sweongyo#define IRP_PAGING_IO 0x00000002 868189488Sweongyo#define IRP_MOUNT_COMPLETION 0x00000002 869189488Sweongyo#define IRP_SYNCHRONOUS_API 0x00000004 870189488Sweongyo#define IRP_ASSOCIATED_IRP 0x00000008 871189488Sweongyo#define IRP_BUFFERED_IO 0x00000010 872189488Sweongyo#define IRP_DEALLOCATE_BUFFER 0x00000020 873189488Sweongyo#define IRP_INPUT_OPERATION 0x00000040 874189488Sweongyo#define IRP_SYNCHRONOUS_PAGING_IO 0x00000040 875189488Sweongyo#define IRP_CREATE_OPERATION 0x00000080 876189488Sweongyo#define IRP_READ_OPERATION 0x00000100 877189488Sweongyo#define IRP_WRITE_OPERATION 0x00000200 878189488Sweongyo#define IRP_CLOSE_OPERATION 0x00000400 879189488Sweongyo#define IRP_DEFER_IO_COMPLETION 0x00000800 880189488Sweongyo#define IRP_OB_QUERY_NAME 0x00001000 881189488Sweongyo#define IRP_HOLD_DEVICE_QUEUE 0x00002000 882189488Sweongyo#define IRP_RETRY_IO_COMPLETION 0x00004000 883189488Sweongyo#define IRP_CLASS_CACHE_OPERATION 0x00008000 884189488Sweongyo#define IRP_SET_USER_EVENT IRP_CLOSE_OPERATION 885140751Swpaul 886140751Swpaul/* IRP I/O control flags */ 887140751Swpaul 888189488Sweongyo#define IRP_QUOTA_CHARGED 0x01 889189488Sweongyo#define IRP_ALLOCATED_MUST_SUCCEED 0x02 890189488Sweongyo#define IRP_ALLOCATED_FIXED_SIZE 0x04 891189488Sweongyo#define IRP_LOOKASIDE_ALLOCATION 0x08 892140751Swpaul 893142311Swpaul/* I/O method types */ 894142311Swpaul 895189488Sweongyo#define METHOD_BUFFERED 0 896189488Sweongyo#define METHOD_IN_DIRECT 1 897189488Sweongyo#define METHOD_OUT_DIRECT 2 898189488Sweongyo#define METHOD_NEITHER 3 899142311Swpaul 900142497Swpaul/* File access types */ 901142497Swpaul 902189488Sweongyo#define FILE_ANY_ACCESS 0x0000 903189488Sweongyo#define FILE_SPECIAL_ACCESS FILE_ANY_ACCESS 904189488Sweongyo#define FILE_READ_ACCESS 0x0001 905189488Sweongyo#define FILE_WRITE_ACCESS 0x0002 906142497Swpaul 907142497Swpaul/* Recover I/O access method from IOCTL code. */ 908142497Swpaul 909189488Sweongyo#define IO_METHOD(x) ((x) & 0xFFFFFFFC) 910142311Swpaul 911142497Swpaul/* Recover function code from IOCTL code */ 912142497Swpaul 913189488Sweongyo#define IO_FUNC(x) (((x) & 0x7FFC) >> 2) 914142497Swpaul 915142497Swpaul/* Macro to construct an IOCTL code. */ 916142497Swpaul 917189488Sweongyo#define IOCTL_CODE(dev, func, iomethod, acc) \ 918142497Swpaul ((dev) << 16) | (acc << 14) | (func << 2) | (iomethod)) 919142497Swpaul 920142497Swpaul 921140751Swpaulstruct io_status_block { 922140751Swpaul union { 923140751Swpaul uint32_t isb_status; 924140751Swpaul void *isb_ptr; 925140751Swpaul } u; 926140751Swpaul register_t isb_info; 927140751Swpaul}; 928189488Sweongyo#define isb_status u.isb_status 929189488Sweongyo#define isb_ptr u.isb_ptr 930140751Swpaul 931140751Swpaultypedef struct io_status_block io_status_block; 932140751Swpaul 933140751Swpaulstruct kapc { 934140751Swpaul uint16_t apc_type; 935140751Swpaul uint16_t apc_size; 936140751Swpaul uint32_t apc_spare0; 937140751Swpaul void *apc_thread; 938140751Swpaul list_entry apc_list; 939140751Swpaul void *apc_kernfunc; 940140751Swpaul void *apc_rundownfunc; 941140751Swpaul void *apc_normalfunc; 942140751Swpaul void *apc_normctx; 943140751Swpaul void *apc_sysarg1; 944140751Swpaul void *apc_sysarg2; 945140751Swpaul uint8_t apc_stateidx; 946140751Swpaul uint8_t apc_cpumode; 947140751Swpaul uint8_t apc_inserted; 948140751Swpaul}; 949140751Swpaul 950140751Swpaultypedef struct kapc kapc; 951140751Swpaul 952144888Swpaultypedef uint32_t (*completion_func)(device_object *, 953141524Swpaul struct irp *, void *); 954144888Swpaultypedef uint32_t (*cancel_func)(device_object *, 955142311Swpaul struct irp *); 956141524Swpaul 957140751Swpaulstruct io_stack_location { 958140751Swpaul uint8_t isl_major; 959140751Swpaul uint8_t isl_minor; 960140751Swpaul uint8_t isl_flags; 961140751Swpaul uint8_t isl_ctl; 962140751Swpaul 963140751Swpaul /* 964140751Swpaul * There's a big-ass union here in the actual Windows 965298828Spfg * definition of the structure, but it contains stuff 966140751Swpaul * that doesn't really apply to BSD, and defining it 967140751Swpaul * all properly would require duplicating over a dozen 968140751Swpaul * other structures that we'll never use. Since the 969140751Swpaul * io_stack_location structure is opaque to drivers 970140751Swpaul * anyway, I'm not going to bother with the extra crap. 971140751Swpaul */ 972140751Swpaul 973140751Swpaul union { 974140751Swpaul struct { 975142311Swpaul uint32_t isl_len; 976142311Swpaul uint32_t *isl_key; 977142311Swpaul uint64_t isl_byteoff; 978142311Swpaul } isl_read; 979142311Swpaul struct { 980142311Swpaul uint32_t isl_len; 981142311Swpaul uint32_t *isl_key; 982142311Swpaul uint64_t isl_byteoff; 983142311Swpaul } isl_write; 984142311Swpaul struct { 985142311Swpaul uint32_t isl_obuflen; 986142311Swpaul uint32_t isl_ibuflen; 987142311Swpaul uint32_t isl_iocode; 988142311Swpaul void *isl_type3ibuf; 989142311Swpaul } isl_ioctl; 990142311Swpaul struct { 991140751Swpaul void *isl_arg1; 992140751Swpaul void *isl_arg2; 993140751Swpaul void *isl_arg3; 994140751Swpaul void *isl_arg4; 995140751Swpaul } isl_others; 996142311Swpaul } isl_parameters __attribute__((packed)); 997140751Swpaul 998140751Swpaul void *isl_devobj; 999140751Swpaul void *isl_fileobj; 1000141524Swpaul completion_func isl_completionfunc; 1001140751Swpaul void *isl_completionctx; 1002140751Swpaul}; 1003140751Swpaul 1004140751Swpaultypedef struct io_stack_location io_stack_location; 1005140751Swpaul 1006140751Swpaul/* Stack location control flags */ 1007140751Swpaul 1008189488Sweongyo#define SL_PENDING_RETURNED 0x01 1009189488Sweongyo#define SL_INVOKE_ON_CANCEL 0x20 1010189488Sweongyo#define SL_INVOKE_ON_SUCCESS 0x40 1011189488Sweongyo#define SL_INVOKE_ON_ERROR 0x80 1012140751Swpaul 1013125551Swpaulstruct irp { 1014140751Swpaul uint16_t irp_type; 1015140751Swpaul uint16_t irp_size; 1016140751Swpaul mdl *irp_mdl; 1017140751Swpaul uint32_t irp_flags; 1018140751Swpaul union { 1019140751Swpaul struct irp *irp_master; 1020140751Swpaul uint32_t irp_irpcnt; 1021140751Swpaul void *irp_sysbuf; 1022140751Swpaul } irp_assoc; 1023140751Swpaul list_entry irp_thlist; 1024140751Swpaul io_status_block irp_iostat; 1025140751Swpaul uint8_t irp_reqmode; 1026140751Swpaul uint8_t irp_pendingreturned; 1027140751Swpaul uint8_t irp_stackcnt; 1028140751Swpaul uint8_t irp_currentstackloc; 1029140751Swpaul uint8_t irp_cancel; 1030140751Swpaul uint8_t irp_cancelirql; 1031140751Swpaul uint8_t irp_apcenv; 1032140751Swpaul uint8_t irp_allocflags; 1033140751Swpaul io_status_block *irp_usriostat; 1034141524Swpaul nt_kevent *irp_usrevent; 1035140751Swpaul union { 1036140751Swpaul struct { 1037140751Swpaul void *irp_apcfunc; 1038140751Swpaul void *irp_apcctx; 1039140751Swpaul } irp_asyncparms; 1040140751Swpaul uint64_t irp_allocsz; 1041140751Swpaul } irp_overlay; 1042142311Swpaul cancel_func irp_cancelfunc; 1043140751Swpaul void *irp_userbuf; 1044140751Swpaul 1045140751Swpaul /* Windows kernel info */ 1046140751Swpaul 1047140751Swpaul union { 1048140751Swpaul struct { 1049140751Swpaul union { 1050140751Swpaul kdevice_qentry irp_dqe; 1051140751Swpaul struct { 1052189488Sweongyo void *irp_drvctx[4]; 1053140751Swpaul } s1; 1054140751Swpaul } u1; 1055140751Swpaul void *irp_thread; 1056140751Swpaul char *irp_auxbuf; 1057140751Swpaul struct { 1058140751Swpaul list_entry irp_list; 1059140751Swpaul union { 1060140751Swpaul io_stack_location *irp_csl; 1061140751Swpaul uint32_t irp_pkttype; 1062140751Swpaul } u2; 1063140751Swpaul } s2; 1064140751Swpaul void *irp_fileobj; 1065140751Swpaul } irp_overlay; 1066186507Sweongyo union { 1067186507Sweongyo kapc irp_apc; 1068186507Sweongyo struct { 1069189488Sweongyo void *irp_ep; 1070186507Sweongyo void *irp_dev; 1071186507Sweongyo } irp_usb; 1072186507Sweongyo } irp_misc; 1073140751Swpaul void *irp_compkey; 1074140751Swpaul } irp_tail; 1075125551Swpaul}; 1076125551Swpaul 1077189488Sweongyo#define irp_csl s2.u2.irp_csl 1078189488Sweongyo#define irp_pkttype s2.u2.irp_pkttype 1079140751Swpaul 1080186507Sweongyo#define IRP_NDIS_DEV(irp) (irp)->irp_tail.irp_misc.irp_usb.irp_dev 1081189488Sweongyo#define IRP_NDISUSB_EP(irp) (irp)->irp_tail.irp_misc.irp_usb.irp_ep 1082186507Sweongyo 1083125551Swpaultypedef struct irp irp; 1084125551Swpaul 1085189488Sweongyo#define InterlockedExchangePointer(dst, val) \ 1086144888Swpaul (void *)InterlockedExchange((uint32_t *)(dst), (uintptr_t)(val)) 1087142311Swpaul 1088189488Sweongyo#define IoSizeOfIrp(ssize) \ 1089141524Swpaul ((uint16_t) (sizeof(irp) + ((ssize) * (sizeof(io_stack_location))))) 1090141524Swpaul 1091189488Sweongyo#define IoSetCancelRoutine(irp, func) \ 1092142311Swpaul (cancel_func)InterlockedExchangePointer( \ 1093142311Swpaul (void *)&(ip)->irp_cancelfunc, (void *)(func)) 1094141524Swpaul 1095186507Sweongyo#define IoSetCancelValue(irp, val) \ 1096186507Sweongyo (u_long)InterlockedExchangePointer( \ 1097186507Sweongyo (void *)&(ip)->irp_cancel, (void *)(val)) 1098186507Sweongyo 1099189488Sweongyo#define IoGetCurrentIrpStackLocation(irp) \ 1100140751Swpaul (irp)->irp_tail.irp_overlay.irp_csl 1101140751Swpaul 1102189488Sweongyo#define IoGetNextIrpStackLocation(irp) \ 1103140751Swpaul ((irp)->irp_tail.irp_overlay.irp_csl - 1) 1104140751Swpaul 1105189488Sweongyo#define IoSetNextIrpStackLocation(irp) \ 1106141524Swpaul do { \ 1107141524Swpaul irp->irp_currentstackloc--; \ 1108141524Swpaul irp->irp_tail.irp_overlay.irp_csl--; \ 1109141524Swpaul } while(0) 1110141524Swpaul 1111189488Sweongyo#define IoSetCompletionRoutine(irp, func, ctx, ok, err, cancel) \ 1112140751Swpaul do { \ 1113140751Swpaul io_stack_location *s; \ 1114140751Swpaul s = IoGetNextIrpStackLocation((irp)); \ 1115140751Swpaul s->isl_completionfunc = (func); \ 1116140751Swpaul s->isl_completionctx = (ctx); \ 1117140751Swpaul s->isl_ctl = 0; \ 1118141524Swpaul if (ok) s->isl_ctl = SL_INVOKE_ON_SUCCESS; \ 1119141524Swpaul if (err) s->isl_ctl |= SL_INVOKE_ON_ERROR; \ 1120141524Swpaul if (cancel) s->isl_ctl |= SL_INVOKE_ON_CANCEL; \ 1121140751Swpaul } while(0) 1122140751Swpaul 1123189488Sweongyo#define IoMarkIrpPending(irp) \ 1124140751Swpaul IoGetCurrentIrpStackLocation(irp)->isl_ctl |= SL_PENDING_RETURNED 1125186507Sweongyo#define IoUnmarkIrpPending(irp) \ 1126186507Sweongyo IoGetCurrentIrpStackLocation(irp)->isl_ctl &= ~SL_PENDING_RETURNED 1127140751Swpaul 1128189488Sweongyo#define IoCopyCurrentIrpStackLocationToNext(irp) \ 1129140751Swpaul do { \ 1130140751Swpaul io_stack_location *src, *dst; \ 1131140751Swpaul src = IoGetCurrentIrpStackLocation(irp); \ 1132140751Swpaul dst = IoGetNextIrpStackLocation(irp); \ 1133140751Swpaul bcopy((char *)src, (char *)dst, \ 1134140751Swpaul offsetof(io_stack_location, isl_completionfunc)); \ 1135140751Swpaul } while(0) 1136140751Swpaul 1137189488Sweongyo#define IoSkipCurrentIrpStackLocation(irp) \ 1138140751Swpaul do { \ 1139140751Swpaul (irp)->irp_currentstackloc++; \ 1140140751Swpaul (irp)->irp_tail.irp_overlay.irp_csl++; \ 1141140751Swpaul } while(0) 1142140751Swpaul 1143189488Sweongyo#define IoInitializeDpcRequest(dobj, dpcfunc) \ 1144144175Swpaul KeInitializeDpc(&(dobj)->do_dpc, dpcfunc, dobj) 1145144175Swpaul 1146189488Sweongyo#define IoRequestDpc(dobj, irp, ctx) \ 1147144175Swpaul KeInsertQueueDpc(&(dobj)->do_dpc, irp, ctx) 1148144175Swpaul 1149144888Swpaultypedef uint32_t (*driver_dispatch)(device_object *, irp *); 1150125551Swpaul 1151140751Swpaul/* 1152140751Swpaul * The driver_object is allocated once for each driver that's loaded 1153140751Swpaul * into the system. A new one is allocated for each driver and 1154140751Swpaul * populated a bit via the driver's DriverEntry function. 1155140751Swpaul * In general, a Windows DriverEntry() function will provide a pointer 1156140751Swpaul * to its AddDevice() method and set up the dispatch table. 1157140751Swpaul * For NDIS drivers, this is all done behind the scenes in the 1158140751Swpaul * NdisInitializeWrapper() and/or NdisMRegisterMiniport() routines. 1159140751Swpaul */ 1160140751Swpaul 1161140751Swpaulstruct driver_object { 1162140751Swpaul uint16_t dro_type; 1163140751Swpaul uint16_t dro_size; 1164140751Swpaul device_object *dro_devobj; 1165140751Swpaul uint32_t dro_flags; 1166140751Swpaul void *dro_driverstart; 1167140751Swpaul uint32_t dro_driversize; 1168140751Swpaul void *dro_driversection; 1169141524Swpaul driver_extension *dro_driverext; 1170140751Swpaul unicode_string dro_drivername; 1171140751Swpaul unicode_string *dro_hwdb; 1172140751Swpaul void *dro_pfastiodispatch; 1173140751Swpaul void *dro_driverinitfunc; 1174140751Swpaul void *dro_driverstartiofunc; 1175140751Swpaul void *dro_driverunloadfunc; 1176141524Swpaul driver_dispatch dro_dispatch[IRP_MJ_MAXIMUM_FUNCTION + 1]; 1177140751Swpaul}; 1178140751Swpaul 1179140751Swpaultypedef struct driver_object driver_object; 1180140751Swpaul 1181189488Sweongyo#define DEVPROP_DEVICE_DESCRIPTION 0x00000000 1182189488Sweongyo#define DEVPROP_HARDWARE_ID 0x00000001 1183189488Sweongyo#define DEVPROP_COMPATIBLE_IDS 0x00000002 1184189488Sweongyo#define DEVPROP_BOOTCONF 0x00000003 1185189488Sweongyo#define DEVPROP_BOOTCONF_TRANSLATED 0x00000004 1186189488Sweongyo#define DEVPROP_CLASS_NAME 0x00000005 1187189488Sweongyo#define DEVPROP_CLASS_GUID 0x00000006 1188189488Sweongyo#define DEVPROP_DRIVER_KEYNAME 0x00000007 1189189488Sweongyo#define DEVPROP_MANUFACTURER 0x00000008 1190189488Sweongyo#define DEVPROP_FRIENDLYNAME 0x00000009 1191189488Sweongyo#define DEVPROP_LOCATION_INFO 0x0000000A 1192189488Sweongyo#define DEVPROP_PHYSDEV_NAME 0x0000000B 1193189488Sweongyo#define DEVPROP_BUSTYPE_GUID 0x0000000C 1194189488Sweongyo#define DEVPROP_LEGACY_BUSTYPE 0x0000000D 1195189488Sweongyo#define DEVPROP_BUS_NUMBER 0x0000000E 1196189488Sweongyo#define DEVPROP_ENUMERATOR_NAME 0x0000000F 1197189488Sweongyo#define DEVPROP_ADDRESS 0x00000010 1198189488Sweongyo#define DEVPROP_UINUMBER 0x00000011 1199189488Sweongyo#define DEVPROP_INSTALL_STATE 0x00000012 1200189488Sweongyo#define DEVPROP_REMOVAL_POLICY 0x00000013 1201125551Swpaul 1202141524Swpaul/* Various supported device types (used with IoCreateDevice()) */ 1203141524Swpaul 1204189488Sweongyo#define FILE_DEVICE_BEEP 0x00000001 1205189488Sweongyo#define FILE_DEVICE_CD_ROM 0x00000002 1206189488Sweongyo#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 1207189488Sweongyo#define FILE_DEVICE_CONTROLLER 0x00000004 1208189488Sweongyo#define FILE_DEVICE_DATALINK 0x00000005 1209189488Sweongyo#define FILE_DEVICE_DFS 0x00000006 1210189488Sweongyo#define FILE_DEVICE_DISK 0x00000007 1211189488Sweongyo#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 1212189488Sweongyo#define FILE_DEVICE_FILE_SYSTEM 0x00000009 1213189488Sweongyo#define FILE_DEVICE_INPORT_PORT 0x0000000A 1214189488Sweongyo#define FILE_DEVICE_KEYBOARD 0x0000000B 1215189488Sweongyo#define FILE_DEVICE_MAILSLOT 0x0000000C 1216189488Sweongyo#define FILE_DEVICE_MIDI_IN 0x0000000D 1217189488Sweongyo#define FILE_DEVICE_MIDI_OUT 0x0000000E 1218189488Sweongyo#define FILE_DEVICE_MOUSE 0x0000000F 1219189488Sweongyo#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010 1220189488Sweongyo#define FILE_DEVICE_NAMED_PIPE 0x00000011 1221189488Sweongyo#define FILE_DEVICE_NETWORK 0x00000012 1222189488Sweongyo#define FILE_DEVICE_NETWORK_BROWSER 0x00000013 1223189488Sweongyo#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014 1224189488Sweongyo#define FILE_DEVICE_NULL 0x00000015 1225189488Sweongyo#define FILE_DEVICE_PARALLEL_PORT 0x00000016 1226189488Sweongyo#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017 1227189488Sweongyo#define FILE_DEVICE_PRINTER 0x00000018 1228189488Sweongyo#define FILE_DEVICE_SCANNER 0x00000019 1229189488Sweongyo#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001A 1230189488Sweongyo#define FILE_DEVICE_SERIAL_PORT 0x0000001B 1231189488Sweongyo#define FILE_DEVICE_SCREEN 0x0000001C 1232189488Sweongyo#define FILE_DEVICE_SOUND 0x0000001D 1233189488Sweongyo#define FILE_DEVICE_STREAMS 0x0000001E 1234189488Sweongyo#define FILE_DEVICE_TAPE 0x0000001F 1235189488Sweongyo#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020 1236189488Sweongyo#define FILE_DEVICE_TRANSPORT 0x00000021 1237189488Sweongyo#define FILE_DEVICE_UNKNOWN 0x00000022 1238189488Sweongyo#define FILE_DEVICE_VIDEO 0x00000023 1239189488Sweongyo#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 1240189488Sweongyo#define FILE_DEVICE_WAVE_IN 0x00000025 1241189488Sweongyo#define FILE_DEVICE_WAVE_OUT 0x00000026 1242189488Sweongyo#define FILE_DEVICE_8042_PORT 0x00000027 1243189488Sweongyo#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 1244189488Sweongyo#define FILE_DEVICE_BATTERY 0x00000029 1245189488Sweongyo#define FILE_DEVICE_BUS_EXTENDER 0x0000002A 1246189488Sweongyo#define FILE_DEVICE_MODEM 0x0000002B 1247189488Sweongyo#define FILE_DEVICE_VDM 0x0000002C 1248189488Sweongyo#define FILE_DEVICE_MASS_STORAGE 0x0000002D 1249189488Sweongyo#define FILE_DEVICE_SMB 0x0000002E 1250189488Sweongyo#define FILE_DEVICE_KS 0x0000002F 1251189488Sweongyo#define FILE_DEVICE_CHANGER 0x00000030 1252189488Sweongyo#define FILE_DEVICE_SMARTCARD 0x00000031 1253189488Sweongyo#define FILE_DEVICE_ACPI 0x00000032 1254189488Sweongyo#define FILE_DEVICE_DVD 0x00000033 1255189488Sweongyo#define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034 1256189488Sweongyo#define FILE_DEVICE_DFS_FILE_SYSTEM 0x00000035 1257189488Sweongyo#define FILE_DEVICE_DFS_VOLUME 0x00000036 1258189488Sweongyo#define FILE_DEVICE_SERENUM 0x00000037 1259189488Sweongyo#define FILE_DEVICE_TERMSRV 0x00000038 1260189488Sweongyo#define FILE_DEVICE_KSEC 0x00000039 1261189488Sweongyo#define FILE_DEVICE_FIPS 0x0000003A 1262141524Swpaul 1263141524Swpaul/* Device characteristics */ 1264141524Swpaul 1265189488Sweongyo#define FILE_REMOVABLE_MEDIA 0x00000001 1266189488Sweongyo#define FILE_READ_ONLY_DEVICE 0x00000002 1267189488Sweongyo#define FILE_FLOPPY_DISKETTE 0x00000004 1268189488Sweongyo#define FILE_WRITE_ONCE_MEDIA 0x00000008 1269189488Sweongyo#define FILE_REMOTE_DEVICE 0x00000010 1270189488Sweongyo#define FILE_DEVICE_IS_MOUNTED 0x00000020 1271189488Sweongyo#define FILE_VIRTUAL_VOLUME 0x00000040 1272189488Sweongyo#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080 1273189488Sweongyo#define FILE_DEVICE_SECURE_OPEN 0x00000100 1274141524Swpaul 1275141524Swpaul/* Status codes */ 1276141524Swpaul 1277189488Sweongyo#define STATUS_SUCCESS 0x00000000 1278189488Sweongyo#define STATUS_USER_APC 0x000000C0 1279189488Sweongyo#define STATUS_KERNEL_APC 0x00000100 1280189488Sweongyo#define STATUS_ALERTED 0x00000101 1281189488Sweongyo#define STATUS_TIMEOUT 0x00000102 1282189488Sweongyo#define STATUS_PENDING 0x00000103 1283186507Sweongyo#define STATUS_FAILURE 0xC0000001 1284186507Sweongyo#define STATUS_NOT_IMPLEMENTED 0xC0000002 1285215779Sbschmidt#define STATUS_ACCESS_VIOLATION 0xC0000005 1286189488Sweongyo#define STATUS_INVALID_PARAMETER 0xC000000D 1287189488Sweongyo#define STATUS_INVALID_DEVICE_REQUEST 0xC0000010 1288189488Sweongyo#define STATUS_MORE_PROCESSING_REQUIRED 0xC0000016 1289186507Sweongyo#define STATUS_NO_MEMORY 0xC0000017 1290189488Sweongyo#define STATUS_BUFFER_TOO_SMALL 0xC0000023 1291189488Sweongyo#define STATUS_MUTANT_NOT_OWNED 0xC0000046 1292186507Sweongyo#define STATUS_NOT_SUPPORTED 0xC00000BB 1293189488Sweongyo#define STATUS_INVALID_PARAMETER_2 0xC00000F0 1294189488Sweongyo#define STATUS_INSUFFICIENT_RESOURCES 0xC000009A 1295186507Sweongyo#define STATUS_DEVICE_NOT_CONNECTED 0xC000009D 1296186507Sweongyo#define STATUS_CANCELLED 0xC0000120 1297189488Sweongyo#define STATUS_NOT_FOUND 0xC0000225 1298186507Sweongyo#define STATUS_DEVICE_REMOVED 0xC00002B6 1299125551Swpaul 1300189488Sweongyo#define STATUS_WAIT_0 0x00000000 1301125551Swpaul 1302141524Swpaul/* Memory pool types, for ExAllocatePoolWithTag() */ 1303141524Swpaul 1304189488Sweongyo#define NonPagedPool 0x00000000 1305189488Sweongyo#define PagedPool 0x00000001 1306189488Sweongyo#define NonPagedPoolMustSucceed 0x00000002 1307189488Sweongyo#define DontUseThisType 0x00000003 1308189488Sweongyo#define NonPagedPoolCacheAligned 0x00000004 1309189488Sweongyo#define PagedPoolCacheAligned 0x00000005 1310189488Sweongyo#define NonPagedPoolCacheAlignedMustS 0x00000006 1311189488Sweongyo#define MaxPoolType 0x00000007 1312141524Swpaul 1313127284Swpaul/* 1314145895Swpaul * IO_WORKITEM is an opaque structures that must be allocated 1315145895Swpaul * via IoAllocateWorkItem() and released via IoFreeWorkItem(). 1316145895Swpaul * Consequently, we can define it any way we want. 1317145895Swpaul */ 1318145895Swpaultypedef void (*io_workitem_func)(device_object *, void *); 1319145895Swpaul 1320145895Swpaulstruct io_workitem { 1321145895Swpaul io_workitem_func iw_func; 1322145895Swpaul void *iw_ctx; 1323145895Swpaul list_entry iw_listentry; 1324145895Swpaul device_object *iw_dobj; 1325146364Swpaul int iw_idx; 1326145895Swpaul}; 1327145895Swpaul 1328145895Swpaultypedef struct io_workitem io_workitem; 1329145895Swpaul 1330189488Sweongyo#define WORKQUEUE_CRITICAL 0 1331189488Sweongyo#define WORKQUEUE_DELAYED 1 1332189488Sweongyo#define WORKQUEUE_HYPERCRITICAL 2 1333145895Swpaul 1334189488Sweongyo#define WORKITEM_THREADS 4 1335189488Sweongyo#define WORKITEM_LEGACY_THREAD 3 1336189488Sweongyo#define WORKIDX_INC(x) (x) = (x + 1) % WORKITEM_LEGACY_THREAD 1337146364Swpaul 1338145895Swpaul/* 1339145895Swpaul * Older, deprecated work item API, needed to support NdisQueueWorkItem(). 1340145895Swpaul */ 1341145895Swpaul 1342145895Swpaulstruct work_queue_item; 1343145895Swpaul 1344145895Swpaultypedef void (*work_item_func)(struct work_queue_item *, void *); 1345145895Swpaul 1346145895Swpaulstruct work_queue_item { 1347145895Swpaul list_entry wqi_entry; 1348145895Swpaul work_item_func wqi_func; 1349145895Swpaul void *wqi_ctx; 1350145895Swpaul}; 1351145895Swpaul 1352145895Swpaultypedef struct work_queue_item work_queue_item; 1353145895Swpaul 1354189488Sweongyo#define ExInitializeWorkItem(w, func, ctx) \ 1355145895Swpaul do { \ 1356145895Swpaul (w)->wqi_func = (func); \ 1357145895Swpaul (w)->wqi_ctx = (ctx); \ 1358151207Swpaul InitializeListHead(&((w)->wqi_entry)); \ 1359161425Simp } while (0) 1360145895Swpaul 1361145895Swpaul/* 1362127284Swpaul * FreeBSD's kernel stack is 2 pages in size by default. The 1363127284Swpaul * Windows stack is larger, so we need to give our threads more 1364127284Swpaul * stack pages. 4 should be enough, we use 8 just to extra safe. 1365127284Swpaul */ 1366189488Sweongyo#define NDIS_KSTACK_PAGES 8 1367127284Swpaul 1368144888Swpaul/* 1369144888Swpaul * Different kinds of function wrapping we can do. 1370144888Swpaul */ 1371144888Swpaul 1372189488Sweongyo#define WINDRV_WRAP_STDCALL 1 1373189488Sweongyo#define WINDRV_WRAP_FASTCALL 2 1374189488Sweongyo#define WINDRV_WRAP_REGPARM 3 1375189488Sweongyo#define WINDRV_WRAP_CDECL 4 1376189488Sweongyo#define WINDRV_WRAP_AMD64 5 1377144888Swpaul 1378145485Swpaulstruct drvdb_ent { 1379145485Swpaul driver_object *windrv_object; 1380145485Swpaul void *windrv_devlist; 1381145485Swpaul ndis_cfg *windrv_regvals; 1382145485Swpaul interface_type windrv_bustype; 1383145485Swpaul STAILQ_ENTRY(drvdb_ent) link; 1384145485Swpaul}; 1385145485Swpaul 1386123474Swpaulextern image_patch_table ntoskrnl_functbl[]; 1387215708Sbschmidt#ifdef __amd64__ 1388215708Sbschmidtextern struct kuser_shared_data kuser_shared_data; 1389215708Sbschmidt#endif 1390141963Swpaultypedef void (*funcptr)(void); 1391146016Swpaultypedef int (*matchfuncptr)(interface_type, void *, void *); 1392123474Swpaul 1393123474Swpaul__BEGIN_DECLS 1394141524Swpaulextern int windrv_libinit(void); 1395141524Swpaulextern int windrv_libfini(void); 1396142399Swpaulextern driver_object *windrv_lookup(vm_offset_t, char *); 1397145485Swpaulextern struct drvdb_ent *windrv_match(matchfuncptr, void *); 1398145485Swpaulextern int windrv_load(module_t, vm_offset_t, int, interface_type, 1399145485Swpaul void *, ndis_cfg *); 1400141524Swpaulextern int windrv_unload(module_t, vm_offset_t, int); 1401141524Swpaulextern int windrv_create_pdo(driver_object *, device_t); 1402141524Swpaulextern void windrv_destroy_pdo(driver_object *, device_t); 1403141524Swpaulextern device_object *windrv_find_pdo(driver_object *, device_t); 1404141524Swpaulextern int windrv_bus_attach(driver_object *, char *); 1405144888Swpaulextern int windrv_wrap(funcptr, funcptr *, int, int); 1406141963Swpaulextern int windrv_unwrap(funcptr); 1407144888Swpaulextern void ctxsw_utow(void); 1408144888Swpaulextern void ctxsw_wtou(void); 1409141524Swpaul 1410123474Swpaulextern int ntoskrnl_libinit(void); 1411123474Swpaulextern int ntoskrnl_libfini(void); 1412151207Swpaul 1413151451Swpaulextern void ntoskrnl_intr(void *); 1414174150Sthompsaextern void ntoskrnl_time(uint64_t *); 1415151451Swpaul 1416151451Swpaulextern uint16_t ExQueryDepthSList(slist_header *); 1417151451Swpaulextern slist_entry 1418151451Swpaul *InterlockedPushEntrySList(slist_header *, slist_entry *); 1419151451Swpaulextern slist_entry *InterlockedPopEntrySList(slist_header *); 1420151207Swpaulextern uint32_t RtlUnicodeStringToAnsiString(ansi_string *, 1421151207Swpaul unicode_string *, uint8_t); 1422151207Swpaulextern uint32_t RtlAnsiStringToUnicodeString(unicode_string *, 1423151207Swpaul ansi_string *, uint8_t); 1424151207Swpaulextern void RtlInitAnsiString(ansi_string *, char *); 1425151207Swpaulextern void RtlInitUnicodeString(unicode_string *, 1426151207Swpaul uint16_t *); 1427151207Swpaulextern void RtlFreeUnicodeString(unicode_string *); 1428151207Swpaulextern void RtlFreeAnsiString(ansi_string *); 1429144888Swpaulextern void KeInitializeDpc(kdpc *, void *, void *); 1430144888Swpaulextern uint8_t KeInsertQueueDpc(kdpc *, void *, void *); 1431144888Swpaulextern uint8_t KeRemoveQueueDpc(kdpc *); 1432145895Swpaulextern void KeSetImportanceDpc(kdpc *, uint32_t); 1433145895Swpaulextern void KeSetTargetProcessorDpc(kdpc *, uint8_t); 1434145895Swpaulextern void KeFlushQueuedDpcs(void); 1435145895Swpaulextern uint32_t KeGetCurrentProcessorNumber(void); 1436144888Swpaulextern void KeInitializeTimer(ktimer *); 1437144888Swpaulextern void KeInitializeTimerEx(ktimer *, uint32_t); 1438189488Sweongyoextern uint8_t KeSetTimer(ktimer *, int64_t, kdpc *); 1439144888Swpaulextern uint8_t KeSetTimerEx(ktimer *, int64_t, uint32_t, kdpc *); 1440144888Swpaulextern uint8_t KeCancelTimer(ktimer *); 1441144888Swpaulextern uint8_t KeReadStateTimer(ktimer *); 1442151248Swpaulextern uint32_t KeWaitForSingleObject(void *, uint32_t, 1443127248Swpaul uint32_t, uint8_t, int64_t *); 1444144888Swpaulextern void KeInitializeEvent(nt_kevent *, uint32_t, uint8_t); 1445144888Swpaulextern void KeClearEvent(nt_kevent *); 1446144888Swpaulextern uint32_t KeReadStateEvent(nt_kevent *); 1447144888Swpaulextern uint32_t KeSetEvent(nt_kevent *, uint32_t, uint8_t); 1448144888Swpaulextern uint32_t KeResetEvent(nt_kevent *); 1449144175Swpaul#ifdef __i386__ 1450144888Swpaulextern void KefAcquireSpinLockAtDpcLevel(kspin_lock *); 1451144888Swpaulextern void KefReleaseSpinLockFromDpcLevel(kspin_lock *); 1452144888Swpaulextern uint8_t KeAcquireSpinLockRaiseToDpc(kspin_lock *); 1453144175Swpaul#else 1454144888Swpaulextern void KeAcquireSpinLockAtDpcLevel(kspin_lock *); 1455144888Swpaulextern void KeReleaseSpinLockFromDpcLevel(kspin_lock *); 1456144175Swpaul#endif 1457144888Swpaulextern void KeInitializeSpinLock(kspin_lock *); 1458151451Swpaulextern uint8_t KeAcquireInterruptSpinLock(kinterrupt *); 1459151451Swpaulextern void KeReleaseInterruptSpinLock(kinterrupt *, uint8_t); 1460151207Swpaulextern uint8_t KeSynchronizeExecution(kinterrupt *, void *, void *); 1461144888Swpaulextern uintptr_t InterlockedExchange(volatile uint32_t *, 1462144888Swpaul uintptr_t); 1463144888Swpaulextern void *ExAllocatePoolWithTag(uint32_t, size_t, uint32_t); 1464144888Swpaulextern void ExFreePool(void *); 1465151207Swpaulextern uint32_t IoConnectInterrupt(kinterrupt **, void *, void *, 1466151207Swpaul kspin_lock *, uint32_t, uint8_t, uint8_t, uint8_t, uint8_t, 1467151207Swpaul uint32_t, uint8_t); 1468186507Sweongyoextern uint8_t MmIsAddressValid(void *); 1469216242Sbschmidtextern void *MmGetSystemRoutineAddress(unicode_string *); 1470151691Swpaulextern void *MmMapIoSpace(uint64_t, uint32_t, uint32_t); 1471151691Swpaulextern void MmUnmapIoSpace(void *, size_t); 1472151207Swpaulextern void MmBuildMdlForNonPagedPool(mdl *); 1473151207Swpaulextern void IoDisconnectInterrupt(kinterrupt *); 1474144888Swpaulextern uint32_t IoAllocateDriverObjectExtension(driver_object *, 1475141524Swpaul void *, uint32_t, void **); 1476144888Swpaulextern void *IoGetDriverObjectExtension(driver_object *, void *); 1477144888Swpaulextern uint32_t IoCreateDevice(driver_object *, uint32_t, 1478141524Swpaul unicode_string *, uint32_t, uint32_t, uint8_t, device_object **); 1479144888Swpaulextern void IoDeleteDevice(device_object *); 1480144888Swpaulextern device_object *IoGetAttachedDevice(device_object *); 1481144888Swpaulextern uint32_t IofCallDriver(device_object *, irp *); 1482144888Swpaulextern void IofCompleteRequest(irp *, uint8_t); 1483144888Swpaulextern void IoAcquireCancelSpinLock(uint8_t *); 1484144888Swpaulextern void IoReleaseCancelSpinLock(uint8_t); 1485144888Swpaulextern uint8_t IoCancelIrp(irp *); 1486144888Swpaulextern void IoDetachDevice(device_object *); 1487144888Swpaulextern device_object *IoAttachDeviceToDeviceStack(device_object *, 1488141524Swpaul device_object *); 1489145895Swpaulextern mdl *IoAllocateMdl(void *, uint32_t, uint8_t, uint8_t, irp *); 1490145895Swpaulextern void IoFreeMdl(mdl *); 1491145895Swpaulextern io_workitem *IoAllocateWorkItem(device_object *); 1492145895Swpaulextern void ExQueueWorkItem(work_queue_item *, u_int32_t); 1493145895Swpaulextern void IoFreeWorkItem(io_workitem *); 1494145895Swpaulextern void IoQueueWorkItem(io_workitem *, io_workitem_func, 1495145895Swpaul uint32_t, void *); 1496128229Swpaul 1497189488Sweongyo#define IoCallDriver(a, b) IofCallDriver(a, b) 1498189488Sweongyo#define IoCompleteRequest(a, b) IofCompleteRequest(a, b) 1499140751Swpaul 1500128229Swpaul/* 1501128229Swpaul * On the Windows x86 arch, KeAcquireSpinLock() and KeReleaseSpinLock() 1502128229Swpaul * routines live in the HAL. We try to imitate this behavior. 1503128229Swpaul */ 1504128229Swpaul#ifdef __i386__ 1505215708Sbschmidt#define KI_USER_SHARED_DATA 0xffdf0000 1506189488Sweongyo#define KeAcquireSpinLock(a, b) *(b) = KfAcquireSpinLock(a) 1507189488Sweongyo#define KeReleaseSpinLock(a, b) KfReleaseSpinLock(a, b) 1508189488Sweongyo#define KeRaiseIrql(a, b) *(b) = KfRaiseIrql(a) 1509189488Sweongyo#define KeLowerIrql(a) KfLowerIrql(a) 1510189488Sweongyo#define KeAcquireSpinLockAtDpcLevel(a) KefAcquireSpinLockAtDpcLevel(a) 1511189488Sweongyo#define KeReleaseSpinLockFromDpcLevel(a) KefReleaseSpinLockFromDpcLevel(a) 1512128229Swpaul#endif /* __i386__ */ 1513141963Swpaul 1514141963Swpaul#ifdef __amd64__ 1515215708Sbschmidt#define KI_USER_SHARED_DATA 0xfffff78000000000UL 1516189488Sweongyo#define KeAcquireSpinLock(a, b) *(b) = KfAcquireSpinLock(a) 1517189488Sweongyo#define KeReleaseSpinLock(a, b) KfReleaseSpinLock(a, b) 1518141963Swpaul 1519141963Swpaul/* 1520141963Swpaul * These may need to be redefined later; 1521141963Swpaul * not sure where they live on amd64 yet. 1522141963Swpaul */ 1523189488Sweongyo#define KeRaiseIrql(a, b) *(b) = KfRaiseIrql(a) 1524189488Sweongyo#define KeLowerIrql(a) KfLowerIrql(a) 1525141963Swpaul#endif /* __amd64__ */ 1526141963Swpaul 1527123474Swpaul__END_DECLS 1528123474Swpaul 1529123474Swpaul#endif /* _NTOSKRNL_VAR_H_ */ 1530