[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/ndis/ntoskrnl_var.h

Version: -  FREEBSD  -  FREEBSD7  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  OPENSOLARIS  -  minix-3-1-1  -  TRUSTEDBSD-SEBSD  -  FREEBSD-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
SearchContext: -  none  -  excerpts  -  bigexcerpts 

  1 /*-
  2  * Copyright (c) 2003
  3  *      Bill Paul <wpaul@windriver.com>.  All rights reserved.
  4  *
  5  * Redistribution and use in source and binary forms, with or without
  6  * modification, are permitted provided that the following conditions
  7  * are met:
  8  * 1. Redistributions of source code must retain the above copyright
  9  *    notice, this list of conditions and the following disclaimer.
 10  * 2. Redistributions in binary form must reproduce the above copyright
 11  *    notice, this list of conditions and the following disclaimer in the
 12  *    documentation and/or other materials provided with the distribution.
 13  * 3. All advertising materials mentioning features or use of this software
 14  *    must display the following acknowledgement:
 15  *      This product includes software developed by Bill Paul.
 16  * 4. Neither the name of the author nor the names of any co-contributors
 17  *    may be used to endorse or promote products derived from this software
 18  *    without specific prior written permission.
 19  *
 20  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
 21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 23  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
 24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 30  * THE POSSIBILITY OF SUCH DAMAGE.
 31  *
 32  * $FreeBSD: src/sys/compat/ndis/ntoskrnl_var.h,v 1.46 2008/12/27 08:03:32 weongyo Exp $
 33  */
 34 
 35 #ifndef _NTOSKRNL_VAR_H_
 36 #define _NTOSKRNL_VAR_H_
 37 
 38 #define MTX_NTOSKRNL_SPIN_LOCK "NDIS thread lock"
 39 
 40 /*
 41  * us_buf is really a wchar_t *, but it's inconvenient to include
 42  * all the necessary header goop needed to define it, and it's a
 43  * pointer anyway, so for now, just make it a uint16_t *.
 44  */
 45 struct unicode_string {
 46         uint16_t                us_len;
 47         uint16_t                us_maxlen;
 48         uint16_t                *us_buf;
 49 };
 50 
 51 typedef struct unicode_string unicode_string;
 52 
 53 struct ansi_string {
 54         uint16_t                as_len;
 55         uint16_t                as_maxlen;
 56         char                    *as_buf;
 57 };
 58 
 59 typedef struct ansi_string ansi_string;
 60 
 61 /*
 62  * Windows memory descriptor list. In Windows, it's possible for
 63  * buffers to be passed between user and kernel contexts without
 64  * copying. Buffers may also be allocated in either paged or
 65  * non-paged memory regions. An MDL describes the pages of memory
 66  * used to contain a particular buffer. Note that a single MDL
 67  * may describe a buffer that spans multiple pages. An array of
 68  * page addresses appears immediately after the MDL structure itself.
 69  * MDLs are therefore implicitly variably sized, even though they
 70  * don't look it.
 71  *
 72  * Note that in FreeBSD, we can take many shortcuts in the way
 73  * we handle MDLs because:
 74  *
 75  * - We are only concerned with pages in kernel context. This means
 76  *   we will only ever use the kernel's memory map, and remapping
 77  *   of buffers is never needed.
 78  *
 79  * - Kernel pages can never be paged out, so we don't have to worry
 80  *   about whether or not a page is actually mapped before going to
 81  *   touch it.
 82  */
 83 
 84 struct mdl {
 85         struct mdl              *mdl_next;
 86         uint16_t                mdl_size;
 87         uint16_t                mdl_flags;
 88         void                    *mdl_process;
 89         void                    *mdl_mappedsystemva;
 90         void                    *mdl_startva;
 91         uint32_t                mdl_bytecount;
 92         uint32_t                mdl_byteoffset;
 93 };
 94 
 95 typedef struct mdl mdl, ndis_buffer;
 96 
 97 /* MDL flags */
 98 
 99 #define MDL_MAPPED_TO_SYSTEM_VA         0x0001
100 #define MDL_PAGES_LOCKED                0x0002
101 #define MDL_SOURCE_IS_NONPAGED_POOL     0x0004
102 #define MDL_ALLOCATED_FIXED_SIZE        0x0008
103 #define MDL_PARTIAL                     0x0010
104 #define MDL_PARTIAL_HAS_BEEN_MAPPED     0x0020
105 #define MDL_IO_PAGE_READ                0x0040
106 #define MDL_WRITE_OPERATION             0x0080
107 #define MDL_PARENT_MAPPED_SYSTEM_VA     0x0100
108 #define MDL_FREE_EXTRA_PTES             0x0200
109 #define MDL_IO_SPACE                    0x0800
110 #define MDL_NETWORK_HEADER              0x1000
111 #define MDL_MAPPING_CAN_FAIL            0x2000
112 #define MDL_ALLOCATED_MUST_SUCCEED      0x4000
113 #define MDL_ZONE_ALLOCED                0x8000  /* BSD private */
114 
115 #define MDL_ZONE_PAGES 16
116 #define MDL_ZONE_SIZE (sizeof(mdl) + (sizeof(vm_offset_t) * MDL_ZONE_PAGES))
117 
118 /* Note: assumes x86 page size of 4K. */
119 
120 #ifndef PAGE_SHIFT
121 #if PAGE_SIZE == 4096
122 #define PAGE_SHIFT      12
123 #elif PAGE_SIZE == 8192
124 #define PAGE_SHIFT      13
125 #else
126 #error PAGE_SHIFT undefined!
127 #endif
128 #endif
129 
130 #define SPAN_PAGES(ptr, len)                                    \
131         ((uint32_t)((((uintptr_t)(ptr) & (PAGE_SIZE - 1)) +     \
132         (len) + (PAGE_SIZE - 1)) >> PAGE_SHIFT))
133 
134 #define PAGE_ALIGN(ptr)                                         \
135         ((void *)((uintptr_t)(ptr) & ~(PAGE_SIZE - 1)))
136 
137 #define BYTE_OFFSET(ptr)                                        \
138         ((uint32_t)((uintptr_t)(ptr) & (PAGE_SIZE - 1)))
139 
140 #define MDL_PAGES(m)    (vm_offset_t *)(m + 1)
141 
142 #define MmInitializeMdl(b, baseva, len)                                 \
143         (b)->mdl_next = NULL;                                           \
144         (b)->mdl_size = (uint16_t)(sizeof(mdl) +                        \
145                 (sizeof(vm_offset_t) * SPAN_PAGES((baseva), (len))));   \
146         (b)->mdl_flags = 0;                                             \
147         (b)->mdl_startva = (void *)PAGE_ALIGN((baseva));                \
148         (b)->mdl_byteoffset = BYTE_OFFSET((baseva));                    \
149         (b)->mdl_bytecount = (uint32_t)(len);
150 
151 #define MmGetMdlByteOffset(mdl)         ((mdl)->mdl_byteoffset)
152 #define MmGetMdlByteCount(mdl)          ((mdl)->mdl_bytecount)
153 #define MmGetMdlVirtualAddress(mdl)                                     \
154         ((void *)((char *)((mdl)->mdl_startva) + (mdl)->mdl_byteoffset))
155 #define MmGetMdlStartVa(mdl)            ((mdl)->mdl_startva)
156 #define MmGetMdlPfnArray(mdl)           MDL_PAGES(mdl)
157 
158 #define WDM_MAJOR               1
159 #define WDM_MINOR_WIN98         0x00
160 #define WDM_MINOR_WINME         0x05
161 #define WDM_MINOR_WIN2000       0x10
162 #define WDM_MINOR_WINXP         0x20
163 #define WDM_MINOR_WIN2003       0x30
164 
165 /*-
166  * The ndis_kspin_lock type is called KSPIN_LOCK in MS-Windows.
167  * According to the Windows DDK header files, KSPIN_LOCK is defined like this:
168  *      typedef ULONG_PTR KSPIN_LOCK;
169  *
170  * From basetsd.h (SDK, Feb. 2003):
171  *      typedef [public] unsigned __int3264 ULONG_PTR, *PULONG_PTR;
172  *      typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
173  *      typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR;
174  * 
175  * The keyword __int3264 specifies an integral type that has the following
176  * properties:
177  *      + It is 32-bit on 32-bit platforms
178  *      + It is 64-bit on 64-bit platforms
179  *      + It is 32-bit on the wire for backward compatibility.
180  *        It gets truncated on the sending side and extended appropriately
181  *        (signed or unsigned) on the receiving side.
182  *
183  * Thus register_t seems the proper mapping onto FreeBSD for spin locks.
184  */
185 
186 typedef register_t kspin_lock;
187 
188 struct slist_entry {
189         struct slist_entry      *sl_next;
190 };
191 
192 typedef struct slist_entry slist_entry;
193 
194 union slist_header {
195         uint64_t                slh_align;
196         struct {
197                 struct slist_entry      *slh_next;
198                 uint16_t                slh_depth;
199                 uint16_t                slh_seq;
200         } slh_list;
201 };
202 
203 typedef union slist_header slist_header;
204 
205 struct list_entry {
206         struct list_entry *nle_flink;
207         struct list_entry *nle_blink;
208 };
209 
210 typedef struct list_entry list_entry;
211 
212 #define InitializeListHead(l)                   \
213         (l)->nle_flink = (l)->nle_blink = (l)
214 
215 #define IsListEmpty(h)                          \
216         ((h)->nle_flink == (h))
217 
218 #define RemoveEntryList(e)                      \
219         do {                                    \
220                 list_entry              *b;     \
221                 list_entry              *f;     \
222                                                 \
223                 f = (e)->nle_flink;             \
224                 b = (e)->nle_blink;             \
225                 b->nle_flink = f;               \
226                 f->nle_blink = b;               \
227         } while (0)
228 
229 /* These two have to be inlined since they return things. */
230 
231 static __inline__ list_entry *
232 RemoveHeadList(list_entry *l)
233 {
234         list_entry              *f;
235         list_entry              *e;
236 
237         e = l->nle_flink;
238         f = e->nle_flink;
239         l->nle_flink = f;
240         f->nle_blink = l;
241 
242         return (e);
243 }
244 
245 static __inline__ list_entry *
246 RemoveTailList(list_entry *l)
247 {
248         list_entry              *b;
249         list_entry              *e;
250 
251         e = l->nle_blink;
252         b = e->nle_blink;
253         l->nle_blink = b;
254         b->nle_flink = l;
255 
256         return (e);
257 }
258 
259 #define InsertTailList(l, e)                    \
260         do {                                    \
261                 list_entry              *b;     \
262                                                 \
263                 b = l->nle_blink;               \
264                 e->nle_flink = l;               \
265                 e->nle_blink = b;               \
266                 b->nle_flink = (e);             \
267                 l->nle_blink = (e);             \
268         } while (0)
269 
270 #define InsertHeadList(l, e)                    \
271         do {                                    \
272                 list_entry              *f;     \
273                                                 \
274                 f = l->nle_flink;               \
275                 e->nle_flink = f;               \
276                 e->nle_blink = l;               \
277                 f->nle_blink = e;               \
278                 l->nle_flink = e;               \
279         } while (0)
280 
281 #define CONTAINING_RECORD(addr, type, field)    \
282         ((type *)((vm_offset_t)(addr) - (vm_offset_t)(&((type *)0)->field)))
283 
284 struct nt_dispatch_header {
285         uint8_t                 dh_type;
286         uint8_t                 dh_abs;
287         uint8_t                 dh_size;
288         uint8_t                 dh_inserted;
289         int32_t                 dh_sigstate;
290         list_entry              dh_waitlisthead;
291 };
292 
293 typedef struct nt_dispatch_header nt_dispatch_header;
294 
295 /* Dispatcher object types */
296 
297 #define DISP_TYPE_NOTIFICATION_EVENT    0       /* KEVENT */
298 #define DISP_TYPE_SYNCHRONIZATION_EVENT 1       /* KEVENT */
299 #define DISP_TYPE_MUTANT                2       /* KMUTANT/KMUTEX */
300 #define DISP_TYPE_PROCESS               3       /* KPROCESS */
301 #define DISP_TYPE_QUEUE                 4       /* KQUEUE */
302 #define DISP_TYPE_SEMAPHORE             5       /* KSEMAPHORE */
303 #define DISP_TYPE_THREAD                6       /* KTHREAD */
304 #define DISP_TYPE_NOTIFICATION_TIMER    8       /* KTIMER */
305 #define DISP_TYPE_SYNCHRONIZATION_TIMER 9       /* KTIMER */
306 
307 #define OTYPE_EVENT             0
308 #define OTYPE_MUTEX             1
309 #define OTYPE_THREAD            2
310 #define OTYPE_TIMER             3
311 
312 /* Windows dispatcher levels. */
313 
314 #define PASSIVE_LEVEL           0
315 #define LOW_LEVEL               0
316 #define APC_LEVEL               1
317 #define DISPATCH_LEVEL          2
318 #define DEVICE_LEVEL            (DISPATCH_LEVEL + 1)
319 #define PROFILE_LEVEL           27
320 #define CLOCK1_LEVEL            28
321 #define CLOCK2_LEVEL            28
322 #define IPI_LEVEL               29
323 #define POWER_LEVEL             30
324 #define HIGH_LEVEL              31
325 
326 #define SYNC_LEVEL_UP           DISPATCH_LEVEL
327 #define SYNC_LEVEL_MP           (IPI_LEVEL - 1)
328 
329 #define AT_PASSIVE_LEVEL(td)            \
330         ((td)->td_proc->p_flag & P_KTHREAD == FALSE)
331 
332 #define AT_DISPATCH_LEVEL(td)           \
333         ((td)->td_base_pri == PI_REALTIME)
334 
335 #define AT_DIRQL_LEVEL(td)              \
336         ((td)->td_priority <= PI_NET)
337 
338 #define AT_HIGH_LEVEL(td)               \
339         ((td)->td_critnest != 0)
340 
341 struct nt_objref {
342         nt_dispatch_header      no_dh;
343         void                    *no_obj;
344         TAILQ_ENTRY(nt_objref)  link;
345 };
346 
347 TAILQ_HEAD(nt_objref_head, nt_objref);
348 
349 typedef struct nt_objref nt_objref;
350 
351 #define EVENT_TYPE_NOTIFY       0
352 #define EVENT_TYPE_SYNC         1
353 
354 /*
355  * We need to use the timeout()/untimeout() API for ktimers
356  * since timers can be initialized, but not destroyed (so
357  * malloc()ing our own callout structures would mean a leak,
358  * since there'd be no way to free() them). This means we
359  * need to use struct callout_handle, which is really just a
360  * pointer. To make it easier to deal with, we use a union
361  * to overlay the callout_handle over the k_timerlistentry.
362  * The latter is a list_entry, which is two pointers, so
363  * there's enough space available to hide a callout_handle
364  * there.
365  */
366 
367 struct ktimer {
368         nt_dispatch_header      k_header;
369         uint64_t                k_duetime;
370         union {
371                 list_entry              k_timerlistentry;
372                 struct callout          *k_callout;
373         } u;
374         void                    *k_dpc;
375         uint32_t                k_period;
376 };
377 
378 #define k_timerlistentry        u.k_timerlistentry
379 #define k_callout               u.k_callout
380 
381 typedef struct ktimer ktimer;
382 
383 struct nt_kevent {
384         nt_dispatch_header      k_header;
385 };
386 
387 typedef struct nt_kevent nt_kevent;
388 
389 /* Kernel defered procedure call (i.e. timer callback) */
390 
391 struct kdpc;
392 typedef void (*kdpc_func)(struct kdpc *, void *, void *, void *);
393 
394 struct kdpc {
395         uint16_t                k_type;
396         uint8_t                 k_num;          /* CPU number */
397         uint8_t                 k_importance;   /* priority */
398         list_entry              k_dpclistentry;
399         void                    *k_deferedfunc;
400         void                    *k_deferredctx;
401         void                    *k_sysarg1;
402         void                    *k_sysarg2;
403         void                    *k_lock;
404 };
405 
406 #define KDPC_IMPORTANCE_LOW     0
407 #define KDPC_IMPORTANCE_MEDIUM  1
408 #define KDPC_IMPORTANCE_HIGH    2
409 
410 #define KDPC_CPU_DEFAULT        255
411 
412 typedef struct kdpc kdpc;
413 
414 /*
415  * Note: the acquisition count is BSD-specific. The Microsoft
416  * documentation says that mutexes can be acquired recursively
417  * by a given thread, but that you must release the mutex as
418  * many times as you acquired it before it will be set to the
419  * signalled state (i.e. before any other threads waiting on
420  * the object will be woken up). However the Windows KMUTANT
421  * structure has no field for keeping track of the number of
422  * acquisitions, so we need to add one ourselves. As long as
423  * driver code treats the mutex as opaque, we should be ok.
424  */
425 struct kmutant {
426         nt_dispatch_header      km_header;
427         list_entry              km_listentry;
428         void                    *km_ownerthread;
429         uint8_t                 km_abandoned;
430         uint8_t                 km_apcdisable;
431 };
432 
433 typedef struct kmutant kmutant;
434 
435 #define LOOKASIDE_DEPTH 256
436 
437 struct general_lookaside {
438         slist_header            gl_listhead;
439         uint16_t                gl_depth;
440         uint16_t                gl_maxdepth;
441         uint32_t                gl_totallocs;
442         union {
443                 uint32_t                gl_allocmisses;
444                 uint32_t                gl_allochits;
445         } u_a;
446         uint32_t                gl_totalfrees;
447         union {
448                 uint32_t                gl_freemisses;
449                 uint32_t                gl_freehits;
450         } u_m;
451         uint32_t                gl_type;
452         uint32_t                gl_tag;
453         uint32_t                gl_size;
454         void                    *gl_allocfunc;
455         void                    *gl_freefunc;
456         list_entry              gl_listent;
457         uint32_t                gl_lasttotallocs;
458         union {
459                 uint32_t                gl_lastallocmisses;
460                 uint32_t                gl_lastallochits;
461         } u_l;
462         uint32_t                gl_rsvd[2];
463 };
464 
465 typedef struct general_lookaside general_lookaside;
466 
467 struct npaged_lookaside_list {
468         general_lookaside       nll_l;
469 #ifdef __i386__
470         kspin_lock              nll_obsoletelock;
471 #endif
472 };
473 
474 typedef struct npaged_lookaside_list npaged_lookaside_list;
475 typedef struct npaged_lookaside_list paged_lookaside_list;
476 
477 typedef void * (*lookaside_alloc_func)(uint32_t, size_t, uint32_t);
478 typedef void (*lookaside_free_func)(void *);
479 
480 struct irp;
481 
482 struct kdevice_qentry {
483         list_entry              kqe_devlistent;
484         uint32_t                kqe_sortkey;
485         uint8_t                 kqe_inserted;
486 };
487 
488 typedef struct kdevice_qentry kdevice_qentry;
489 
490 struct kdevice_queue {
491         uint16_t                kq_type;
492         uint16_t                kq_size;
493         list_entry              kq_devlisthead;
494         kspin_lock              kq_lock;
495         uint8_t                 kq_busy;
496 };
497 
498 typedef struct kdevice_queue kdevice_queue;
499 
500 struct wait_ctx_block {
501         kdevice_qentry          wcb_waitqueue;
502         void                    *wcb_devfunc;
503         void                    *wcb_devctx;
504         uint32_t                wcb_mapregcnt;
505         void                    *wcb_devobj;
506         void                    *wcb_curirp;
507         void                    *wcb_bufchaindpc;
508 };
509 
510 typedef struct wait_ctx_block wait_ctx_block;
511 
512 struct wait_block {
513         list_entry              wb_waitlist;
514         void                    *wb_kthread;
515         nt_dispatch_header      *wb_object;
516         struct wait_block       *wb_next;
517 #ifdef notdef
518         uint16_t                wb_waitkey;
519         uint16_t                wb_waittype;
520 #endif
521         uint8_t                 wb_waitkey;
522         uint8_t                 wb_waittype;
523         uint8_t                 wb_awakened;
524         uint8_t                 wb_oldpri;
525 };
526 
527 typedef struct wait_block wait_block;
528 
529 #define wb_ext wb_kthread
530 
531 #define THREAD_WAIT_OBJECTS     3
532 #define MAX_WAIT_OBJECTS        64
533 
534 #define WAITTYPE_ALL            0
535 #define WAITTYPE_ANY            1
536 
537 #define WAITKEY_VALID           0x8000
538 
539 /* kthread priority  */
540 #define LOW_PRIORITY            0
541 #define LOW_REALTIME_PRIORITY   16
542 #define HIGH_PRIORITY           31
543 
544 struct thread_context {
545         void                    *tc_thrctx;
546         void                    *tc_thrfunc;
547 };
548 
549 typedef struct thread_context thread_context;
550 
551 /* Forward declaration */
552 struct driver_object;
553 struct devobj_extension;
554 
555 struct driver_extension {
556         struct driver_object    *dre_driverobj;
557         void                    *dre_adddevicefunc;
558         uint32_t                dre_reinitcnt;
559         unicode_string          dre_srvname;
560 
561         /*
562          * Drivers are allowed to add one or more custom extensions
563          * to the driver object, but there's no special pointer
564          * for them. Hang them off here for now.
565          */
566 
567         list_entry              dre_usrext;
568 };
569 
570 typedef struct driver_extension driver_extension;
571 
572 struct custom_extension {
573         list_entry              ce_list;
574         void                    *ce_clid;
575 };
576 
577 typedef struct custom_extension custom_extension;
578 
579 /*
580  * The KINTERRUPT structure in Windows is opaque to drivers.
581  * We define our own custom version with things we need.
582  */
583 
584 struct kinterrupt {
585         list_entry              ki_list;
586         device_t                ki_dev;
587         int                     ki_rid;
588         void                    *ki_cookie;
589         struct resource         *ki_irq;
590         kspin_lock              ki_lock_priv;
591         kspin_lock              *ki_lock;
592         void                    *ki_svcfunc;
593         void                    *ki_svcctx;
594 };
595 
596 typedef struct kinterrupt kinterrupt;
597 
598 /*
599  * In Windows, there are Physical Device Objects (PDOs) and
600  * Functional Device Objects (FDOs). Physical Device Objects are
601  * created and maintained by bus drivers. For example, the PCI
602  * bus driver might detect two PCI ethernet cards on a given
603  * bus. The PCI bus driver will then allocate two device_objects
604  * for its own internal bookeeping purposes. This is analagous
605  * to the device_t that the FreeBSD PCI code allocates and passes
606  * into each PCI driver's probe and attach routines.
607  *
608  * When an ethernet driver claims one of the ethernet cards
609  * on the bus, it will create its own device_object. This is
610  * the Functional Device Object. This object is analagous to the
611  * device-specific softc structure.
612  */
613 
614 struct device_object {
615         uint16_t                do_type;
616         uint16_t                do_size;
617         uint32_t                do_refcnt;
618         struct driver_object    *do_drvobj;
619         struct device_object    *do_nextdev;
620         struct device_object    *do_attacheddev;
621         struct irp              *do_currirp;
622         void                    *do_iotimer;
623         uint32_t                do_flags;
624         uint32_t                do_characteristics;
625         void                    *do_vpb;
626         void                    *do_devext;
627         uint32_t                do_devtype;
628         uint8_t                 do_stacksize;
629         union {
630                 list_entry              do_listent;
631                 wait_ctx_block          do_wcb;
632         } queue;
633         uint32_t                do_alignreq;
634         kdevice_queue           do_devqueue;
635         struct kdpc             do_dpc;
636         uint32_t                do_activethreads;
637         void                    *do_securitydesc;
638         struct nt_kevent        do_devlock;
639         uint16_t                do_sectorsz;
640         uint16_t                do_spare1;
641         struct devobj_extension *do_devobj_ext;
642         void                    *do_rsvd;
643 };
644 
645 typedef struct device_object device_object;
646 
647 struct devobj_extension {
648         uint16_t                dve_type;
649         uint16_t                dve_size;
650         device_object           *dve_devobj;
651 };
652 
653 typedef struct devobj_extension devobj_extension;
654 
655 /* Device object flags */
656 
657 #define DO_VERIFY_VOLUME                0x00000002      
658 #define DO_BUFFERED_IO                  0x00000004      
659 #define DO_EXCLUSIVE                    0x00000008      
660 #define DO_DIRECT_IO                    0x00000010      
661 #define DO_MAP_IO_BUFFER                0x00000020      
662 #define DO_DEVICE_HAS_NAME              0x00000040      
663 #define DO_DEVICE_INITIALIZING          0x00000080      
664 #define DO_SYSTEM_BOOT_PARTITION        0x00000100      
665 #define DO_LONG_TERM_REQUESTS           0x00000200      
666 #define DO_NEVER_LAST_DEVICE            0x00000400      
667 #define DO_SHUTDOWN_REGISTERED          0x00000800      
668 #define DO_BUS_ENUMERATED_DEVICE        0x00001000      
669 #define DO_POWER_PAGABLE                0x00002000      
670 #define DO_POWER_INRUSH                 0x00004000      
671 #define DO_LOW_PRIORITY_FILESYSTEM      0x00010000      
672 
673 /* Priority boosts */
674 
675 #define IO_NO_INCREMENT                 0
676 #define IO_CD_ROM_INCREMENT             1
677 #define IO_DISK_INCREMENT               1
678 #define IO_KEYBOARD_INCREMENT           6
679 #define IO_MAILSLOT_INCREMENT           2
680 #define IO_MOUSE_INCREMENT              6
681 #define IO_NAMED_PIPE_INCREMENT         2
682 #define IO_NETWORK_INCREMENT            2
683 #define IO_PARALLEL_INCREMENT           1
684 #define IO_SERIAL_INCREMENT             2
685 #define IO_SOUND_INCREMENT              8
686 #define IO_VIDEO_INCREMENT              1
687 
688 /* IRP major codes */
689 
690 #define IRP_MJ_CREATE                   0x00
691 #define IRP_MJ_CREATE_NAMED_PIPE        0x01
692 #define IRP_MJ_CLOSE                    0x02
693 #define IRP_MJ_READ                     0x03
694 #define IRP_MJ_WRITE                    0x04
695 #define IRP_MJ_QUERY_INFORMATION        0x05
696 #define IRP_MJ_SET_INFORMATION          0x06
697 #define IRP_MJ_QUERY_EA                 0x07
698 #define IRP_MJ_SET_EA                   0x08
699 #define IRP_MJ_FLUSH_BUFFERS            0x09
700 #define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a
701 #define IRP_MJ_SET_VOLUME_INFORMATION   0x0b
702 #define IRP_MJ_DIRECTORY_CONTROL        0x0c
703 #define IRP_MJ_FILE_SYSTEM_CONTROL      0x0d
704 #define IRP_MJ_DEVICE_CONTROL           0x0e
705 #define IRP_MJ_INTERNAL_DEVICE_CONTROL  0x0f
706 #define IRP_MJ_SHUTDOWN                 0x10
707 #define IRP_MJ_LOCK_CONTROL             0x11
708 #define IRP_MJ_CLEANUP                  0x12
709 #define IRP_MJ_CREATE_MAILSLOT          0x13
710 #define IRP_MJ_QUERY_SECURITY           0x14
711 #define IRP_MJ_SET_SECURITY             0x15
712 #define IRP_MJ_POWER                    0x16
713 #define IRP_MJ_SYSTEM_CONTROL           0x17
714 #define IRP_MJ_DEVICE_CHANGE            0x18
715 #define IRP_MJ_QUERY_QUOTA              0x19
716 #define IRP_MJ_SET_QUOTA                0x1a
717 #define IRP_MJ_PNP                      0x1b
718 #define IRP_MJ_PNP_POWER                IRP_MJ_PNP      // Obsolete....
719 #define IRP_MJ_MAXIMUM_FUNCTION         0x1b
720 #define IRP_MJ_SCSI                     IRP_MJ_INTERNAL_DEVICE_CONTROL
721 
722 /* IRP minor codes */
723 
724 #define IRP_MN_QUERY_DIRECTORY          0x01
725 #define IRP_MN_NOTIFY_CHANGE_DIRECTORY  0x02
726 #define IRP_MN_USER_FS_REQUEST          0x00
727 
728 #define IRP_MN_MOUNT_VOLUME             0x01
729 #define IRP_MN_VERIFY_VOLUME            0x02
730 #define IRP_MN_LOAD_FILE_SYSTEM         0x03
731 #define IRP_MN_TRACK_LINK               0x04
732 #define IRP_MN_KERNEL_CALL              0x04
733 
734 #define IRP_MN_LOCK                     0x01
735 #define IRP_MN_UNLOCK_SINGLE            0x02
736 #define IRP_MN_UNLOCK_ALL               0x03
737 #define IRP_MN_UNLOCK_ALL_BY_KEY        0x04
738 
739 #define IRP_MN_NORMAL                   0x00
740 #define IRP_MN_DPC                      0x01
741 #define IRP_MN_MDL                      0x02
742 #define IRP_MN_COMPLETE                 0x04
743 #define IRP_MN_COMPRESSED               0x08
744 
745 #define IRP_MN_MDL_DPC                  (IRP_MN_MDL | IRP_MN_DPC)
746 #define IRP_MN_COMPLETE_MDL             (IRP_MN_COMPLETE | IRP_MN_MDL)
747 #define IRP_MN_COMPLETE_MDL_DPC         (IRP_MN_COMPLETE_MDL | IRP_MN_DPC)
748 
749 #define IRP_MN_SCSI_CLASS               0x01
750 
751 #define IRP_MN_START_DEVICE                 0x00
752 #define IRP_MN_QUERY_REMOVE_DEVICE          0x01
753 #define IRP_MN_REMOVE_DEVICE                0x02
754 #define IRP_MN_CANCEL_REMOVE_DEVICE         0x03
755 #define IRP_MN_STOP_DEVICE                  0x04
756 #define IRP_MN_QUERY_STOP_DEVICE            0x05
757 #define IRP_MN_CANCEL_STOP_DEVICE           0x06
758 
759 #define IRP_MN_QUERY_DEVICE_RELATIONS       0x07
760 #define IRP_MN_QUERY_INTERFACE              0x08
761 #define IRP_MN_QUERY_CAPABILITIES           0x09
762 #define IRP_MN_QUERY_RESOURCES              0x0A
763 #define IRP_MN_QUERY_RESOURCE_REQUIREMENTS  0x0B
764 #define IRP_MN_QUERY_DEVICE_TEXT            0x0C
765 #define IRP_MN_FILTER_RESOURCE_REQUIREMENTS 0x0D
766 
767 #define IRP_MN_READ_CONFIG                  0x0F
768 #define IRP_MN_WRITE_CONFIG                 0x10
769 #define IRP_MN_EJECT                        0x11
770 #define IRP_MN_SET_LOCK                     0x12
771 #define IRP_MN_QUERY_ID                     0x13
772 #define IRP_MN_QUERY_PNP_DEVICE_STATE       0x14
773 #define IRP_MN_QUERY_BUS_INFORMATION        0x15
774 #define IRP_MN_DEVICE_USAGE_NOTIFICATION    0x16
775 #define IRP_MN_SURPRISE_REMOVAL             0x17
776 #define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18
777 
778 #define IRP_MN_WAIT_WAKE                    0x00
779 #define IRP_MN_POWER_SEQUENCE               0x01
780 #define IRP_MN_SET_POWER                    0x02
781 #define IRP_MN_QUERY_POWER                  0x03
782 
783 #define IRP_MN_QUERY_ALL_DATA               0x00
784 #define IRP_MN_QUERY_SINGLE_INSTANCE        0x01
785 #define IRP_MN_CHANGE_SINGLE_INSTANCE       0x02
786 #define IRP_MN_CHANGE_SINGLE_ITEM           0x03
787 #define IRP_MN_ENABLE_EVENTS                0x04
788 #define IRP_MN_DISABLE_EVENTS               0x05
789 #define IRP_MN_ENABLE_COLLECTION            0x06
790 #define IRP_MN_DISABLE_COLLECTION           0x07
791 #define IRP_MN_REGINFO                      0x08
792 #define IRP_MN_EXECUTE_METHOD               0x09
793 #define IRP_MN_REGINFO_EX                   0x0b
794 
795 /* IRP flags */
796 
797 #define IRP_NOCACHE                     0x00000001
798 #define IRP_PAGING_IO                   0x00000002
799 #define IRP_MOUNT_COMPLETION            0x00000002
800 #define IRP_SYNCHRONOUS_API             0x00000004
801 #define IRP_ASSOCIATED_IRP              0x00000008
802 #define IRP_BUFFERED_IO                 0x00000010
803 #define IRP_DEALLOCATE_BUFFER           0x00000020
804 #define IRP_INPUT_OPERATION             0x00000040
805 #define IRP_SYNCHRONOUS_PAGING_IO       0x00000040
806 #define IRP_CREATE_OPERATION            0x00000080
807 #define IRP_READ_OPERATION              0x00000100
808 #define IRP_WRITE_OPERATION             0x00000200
809 #define IRP_CLOSE_OPERATION             0x00000400
810 #define IRP_DEFER_IO_COMPLETION         0x00000800
811 #define IRP_OB_QUERY_NAME               0x00001000
812 #define IRP_HOLD_DEVICE_QUEUE           0x00002000
813 #define IRP_RETRY_IO_COMPLETION         0x00004000
814 #define IRP_CLASS_CACHE_OPERATION       0x00008000
815 #define IRP_SET_USER_EVENT              IRP_CLOSE_OPERATION
816 
817 /* IRP I/O control flags */
818 
819 #define IRP_QUOTA_CHARGED               0x01
820 #define IRP_ALLOCATED_MUST_SUCCEED      0x02
821 #define IRP_ALLOCATED_FIXED_SIZE        0x04
822 #define IRP_LOOKASIDE_ALLOCATION        0x08
823 
824 /* I/O method types */
825 
826 #define METHOD_BUFFERED                 0
827 #define METHOD_IN_DIRECT                1
828 #define METHOD_OUT_DIRECT               2
829 #define METHOD_NEITHER                  3
830 
831 /* File access types */
832 
833 #define FILE_ANY_ACCESS                 0x0000
834 #define FILE_SPECIAL_ACCESS             FILE_ANY_ACCESS
835 #define FILE_READ_ACCESS                0x0001
836 #define FILE_WRITE_ACCESS               0x0002
837 
838 /* Recover I/O access method from IOCTL code. */
839 
840 #define IO_METHOD(x)                    ((x) & 0xFFFFFFFC)
841 
842 /* Recover function code from IOCTL code */
843 
844 #define IO_FUNC(x)                      (((x) & 0x7FFC) >> 2)
845 
846 /* Macro to construct an IOCTL code. */
847 
848 #define IOCTL_CODE(dev, func, iomethod, acc)    \
849         ((dev) << 16) | (acc << 14) | (func << 2) | (iomethod))
850 
851 
852 struct io_status_block {
853         union {
854                 uint32_t                isb_status;
855                 void                    *isb_ptr;
856         } u;
857         register_t              isb_info;
858 };
859 #define isb_status              u.isb_status
860 #define isb_ptr                 u.isb_ptr
861 
862 typedef struct io_status_block io_status_block;
863 
864 struct kapc {
865         uint16_t                apc_type;
866         uint16_t                apc_size;
867         uint32_t                apc_spare0;
868         void                    *apc_thread;
869         list_entry              apc_list;
870         void                    *apc_kernfunc;
871         void                    *apc_rundownfunc;
872         void                    *apc_normalfunc;
873         void                    *apc_normctx;
874         void                    *apc_sysarg1;
875         void                    *apc_sysarg2;
876         uint8_t                 apc_stateidx;
877         uint8_t                 apc_cpumode;
878         uint8_t                 apc_inserted;
879 };
880 
881 typedef struct kapc kapc;
882 
883 typedef uint32_t (*completion_func)(device_object *,
884         struct irp *, void *);
885 typedef uint32_t (*cancel_func)(device_object *,
886         struct irp *);
887 
888 struct io_stack_location {
889         uint8_t                 isl_major;
890         uint8_t                 isl_minor;
891         uint8_t                 isl_flags;
892         uint8_t                 isl_ctl;
893 
894         /*
895          * There's a big-ass union here in the actual Windows
896          * definition of the stucture, but it contains stuff
897          * that doesn't really apply to BSD, and defining it
898          * all properly would require duplicating over a dozen
899          * other structures that we'll never use. Since the
900          * io_stack_location structure is opaque to drivers
901          * anyway, I'm not going to bother with the extra crap.
902          */
903 
904         union {
905                 struct {
906                         uint32_t                isl_len;
907                         uint32_t                *isl_key;
908                         uint64_t                isl_byteoff;
909                 } isl_read;
910                 struct {
911                         uint32_t                isl_len;
912                         uint32_t                *isl_key;
913                         uint64_t                isl_byteoff;
914                 } isl_write;
915                 struct {
916                         uint32_t                isl_obuflen;
917                         uint32_t                isl_ibuflen;
918                         uint32_t                isl_iocode;
919                         void                    *isl_type3ibuf;
920                 } isl_ioctl;
921                 struct {
922                         void                    *isl_arg1;
923                         void                    *isl_arg2;
924                         void                    *isl_arg3;
925                         void                    *isl_arg4;
926                 } isl_others;
927         } isl_parameters __attribute__((packed));
928 
929         void                    *isl_devobj;
930         void                    *isl_fileobj;
931         completion_func         isl_completionfunc;
932         void                    *isl_completionctx;
933 };
934 
935 typedef struct io_stack_location io_stack_location;
936 
937 /* Stack location control flags */
938 
939 #define SL_PENDING_RETURNED             0x01
940 #define SL_INVOKE_ON_CANCEL             0x20
941 #define SL_INVOKE_ON_SUCCESS            0x40
942 #define SL_INVOKE_ON_ERROR              0x80
943 
944 struct irp {
945         uint16_t                irp_type;
946         uint16_t                irp_size;
947         mdl                     *irp_mdl;
948         uint32_t                irp_flags;
949         union {
950                 struct irp              *irp_master;
951                 uint32_t                irp_irpcnt;
952                 void                    *irp_sysbuf;
953         } irp_assoc;
954         list_entry              irp_thlist;
955         io_status_block         irp_iostat;
956         uint8_t                 irp_reqmode;
957         uint8_t                 irp_pendingreturned;
958         uint8_t                 irp_stackcnt;
959         uint8_t                 irp_currentstackloc;
960         uint8_t                 irp_cancel;
961         uint8_t                 irp_cancelirql;
962         uint8_t                 irp_apcenv;
963         uint8_t                 irp_allocflags;
964         io_status_block         *irp_usriostat;
965         nt_kevent               *irp_usrevent;
966         union {
967                 struct {
968                         void                    *irp_apcfunc;
969                         void                    *irp_apcctx;
970                 } irp_asyncparms;
971                 uint64_t                        irp_allocsz;
972         } irp_overlay;
973         cancel_func             irp_cancelfunc;
974         void                    *irp_userbuf;
975 
976         /* Windows kernel info */
977 
978         union {
979                 struct {
980                         union {
981                                 kdevice_qentry                  irp_dqe;
982                                 struct {
983