Begin the first phase of trying to add IRP support (and ultimately

USB device support):

- Convert all of my locally chosen function names to their actual
  Windows equivalents, where applicable. This is a big no-op change
  since it doesn't affect functionality, but it helps avoid a bit
  of confusion (it's now a lot easier to see which functions are
  emulated Windows API routines and which are just locally defined).

- Turn ndis_buffer into an mdl, like it should have been. The structure
  is the same, but now it belongs to the subr_ntoskrnl module.

- Implement a bunch of MDL handling macros from Windows and use them where
  applicable.

- Correct the implementation of IoFreeMdl().

- Properly implement IoAllocateMdl() and MmBuildMdlForNonPagedPool().

- Add the definitions for struct irp and struct driver_object.

- Add IMPORT_FUNC() and IMPORT_FUNC_MAP() macros to make formatting
  the module function tables a little cleaner. (Should also help
  with AMD64 support later on.)

- Fix if_ndis.c to use KeRaiseIrql() and KeLowerIrql() instead of
  the previous calls to hal_raise_irql() and hal_lower_irql() which
  have been renamed.

The function renaming generated a lot of churn here, but there should
be very little operational effect.
This commit is contained in:
wpaul 2005-01-24 18:18:12 +00:00
parent 9797bcb293
commit 361515a412
9 changed files with 1345 additions and 825 deletions

View File

@ -46,11 +46,11 @@
extern image_patch_table hal_functbl[];
__BEGIN_DECLS
__fastcall extern uint8_t hal_lock(REGARGS1(kspin_lock *lock));
__fastcall void hal_unlock(REGARGS2(kspin_lock *lock, uint8_t newirql));
__fastcall extern uint8_t hal_raise_irql(REGARGS1(uint8_t irql));
__fastcall extern void hal_lower_irql(REGARGS1(uint8_t oldirql));
__stdcall extern uint8_t hal_irql(void);
__fastcall extern uint8_t KfAcquireSpinLock(REGARGS1(kspin_lock *lock));
__fastcall void KfReleaseSpinLock(REGARGS2(kspin_lock *lock, uint8_t newirql));
__fastcall extern uint8_t KfRaiseIrql(REGARGS1(uint8_t irql));
__fastcall extern void KfLowerIrql(REGARGS1(uint8_t oldirql));
__stdcall extern uint8_t KeGetCurrentIrql(void);
__END_DECLS
#endif /* _HAL_VAR_H_ */

View File

@ -786,9 +786,9 @@ ndis_return(arg)
return;
returnfunc = sc->ndis_chars.nmc_return_packet_func;
irql = ntoskrnl_raise_irql(DISPATCH_LEVEL);
irql = KeRaiseIrql(DISPATCH_LEVEL);
returnfunc(adapter, p);
ntoskrnl_lower_irql(irql);
KeLowerIrql(irql);
return;
}
@ -827,7 +827,7 @@ ndis_free_bufs(b0)
return;
while(b0 != NULL) {
next = b0->nb_next;
next = b0->mdl_next;
uma_zfree (ndis_buffer_zone, b0);
b0 = next;
}
@ -989,7 +989,7 @@ ndis_ptom(m0, p)
buf = priv->npp_head;
p->np_refcnt = 0;
for (buf = priv->npp_head; buf != NULL; buf = buf->nb_next) {
for (buf = priv->npp_head; buf != NULL; buf = buf->mdl_next) {
if (buf == priv->npp_head)
MGETHDR(m, M_DONTWAIT, MT_HEADER);
else
@ -999,8 +999,8 @@ ndis_ptom(m0, p)
*m0 = NULL;
return(ENOBUFS);
}
m->m_len = buf->nb_bytecount;
m->m_data = MDL_VA(buf);
m->m_len = MmGetMdlByteCount(buf);
m->m_data = MmGetMdlVirtualAddress(buf);
MEXTADD(m, m->m_data, m->m_len, ndis_return_packet,
p, 0, EXT_NDIS);
p->np_refcnt++;
@ -1067,11 +1067,11 @@ ndis_mtop(m0, p)
return(ENOMEM);
}
MDL_INIT(buf, m->m_data, m->m_len);
MmInitializeMdl(buf, m->m_data, m->m_len);
if (priv->npp_head == NULL)
priv->npp_head = buf;
else
prev->nb_next = buf;
prev->mdl_next = buf;
prev = buf;
}
@ -1136,10 +1136,10 @@ ndis_set_info(arg, oid, buf, buflen)
if (adapter == NULL || setfunc == NULL)
return(ENXIO);
ntoskrnl_acquire_spinlock(&sc->ndis_block.nmb_lock, &irql);
KeAcquireSpinLock(&sc->ndis_block.nmb_lock, &irql);
rval = setfunc(adapter, oid, buf, *buflen,
&byteswritten, &bytesneeded);
ntoskrnl_release_spinlock(&sc->ndis_block.nmb_lock, irql);
KeReleaseSpinLock(&sc->ndis_block.nmb_lock, irql);
if (rval == NDIS_STATUS_PENDING) {
mtx_lock(&ndis_req_mtx);
@ -1193,9 +1193,9 @@ ndis_send_packets(arg, packets, cnt)
return(ENXIO);
sendfunc = sc->ndis_chars.nmc_sendmulti_func;
senddonefunc = sc->ndis_block.nmb_senddone_func;
irql = ntoskrnl_raise_irql(DISPATCH_LEVEL);
irql = KeRaiseIrql(DISPATCH_LEVEL);
sendfunc(adapter, packets, cnt);
ntoskrnl_lower_irql(irql);
KeLowerIrql(irql);
for (i = 0; i < cnt; i++) {
p = packets[i];
@ -1232,9 +1232,9 @@ ndis_send_packet(arg, packet)
sendfunc = sc->ndis_chars.nmc_sendsingle_func;
senddonefunc = sc->ndis_block.nmb_senddone_func;
irql = ntoskrnl_raise_irql(DISPATCH_LEVEL);
irql = KeRaiseIrql(DISPATCH_LEVEL);
status = sendfunc(adapter, packet, packet->np_private.npp_flags);
ntoskrnl_lower_irql(irql);
KeLowerIrql(irql);
if (status == NDIS_STATUS_PENDING)
return(0);
@ -1321,9 +1321,9 @@ ndis_reset_nic(arg)
if (adapter == NULL || resetfunc == NULL)
return(EIO);
irql = ntoskrnl_raise_irql(DISPATCH_LEVEL);
irql = KeRaiseIrql(DISPATCH_LEVEL);
rval = resetfunc(&addressing_reset, adapter);
ntoskrnl_lower_irql(irql);
KeLowerIrql(irql);
if (rval == NDIS_STATUS_PENDING) {
mtx_lock(&ndis_req_mtx);
@ -1554,10 +1554,10 @@ ndis_get_info(arg, oid, buf, buflen)
if (adapter == NULL || queryfunc == NULL)
return(ENXIO);
ntoskrnl_acquire_spinlock(&sc->ndis_block.nmb_lock, &irql);
KeAcquireSpinLock(&sc->ndis_block.nmb_lock, &irql);
rval = queryfunc(adapter, oid, buf, *buflen,
&byteswritten, &bytesneeded);
ntoskrnl_release_spinlock(&sc->ndis_block.nmb_lock, irql);
KeReleaseSpinLock(&sc->ndis_block.nmb_lock, irql);
/* Wait for requests that block. */
@ -1711,7 +1711,7 @@ ndis_load_driver(img, arg)
ndis_enlarge_thrqueue(8);
TAILQ_INSERT_TAIL(&ndis_devhead, block, link);
ntoskrnl_init_lock(&block->nmb_lock);
KeInitializeSpinLock(&block->nmb_lock);
return(0);
}

View File

@ -953,6 +953,7 @@ struct ndis_work_item {
typedef struct ndis_work_item ndis_work_item;
#ifdef notdef
struct ndis_buffer {
struct ndis_buffer *nb_next;
uint16_t nb_size;
@ -965,6 +966,7 @@ struct ndis_buffer {
};
typedef struct ndis_buffer ndis_buffer;
#endif
struct ndis_sc_element {
ndis_physaddr nse_addr;

View File

@ -35,25 +35,109 @@
#ifndef _NTOSKRNL_VAR_H_
#define _NTOSKRNL_VAR_H_
/*
* us_buf is really a wchar_t *, but it's inconvenient to include
* all the necessary header goop needed to define it, and it's a
* pointer anyway, so for now, just make it a uint16_t *.
*/
struct unicode_string {
uint16_t us_len;
uint16_t us_maxlen;
uint16_t *us_buf;
};
typedef struct unicode_string unicode_string;
/*
* Windows memory descriptor list. In Windows, it's possible for
* buffers to be passed between user and kernel contexts without
* copying. Buffers may also be allocated in either paged or
* non-paged memory regions. An MDL describes the pages of memory
* used to contain a particular buffer. Note that a single MDL
* may describe a buffer that spans multiple pages. An array of
* page addresses appears immediately after the MDL structure itself.
* MDLs are therefore implicitly variably sized, even though they
* don't look it.
*
* Note that in FreeBSD, we can take many shortcuts in the way
* we handle MDLs because:
*
* - We are only concerned with pages in kernel context. This means
* we will only ever use the kernel's memory map, and remapping
* of buffers is never needed.
*
* - Kernel pages can never be paged out, so we don't have to worry
* about whether or not a page is actually mapped before going to
* touch it.
*/
struct mdl {
struct mdl *mdl_next;
uint16_t mdl_size;
uint16_t mdl_flags;
void *mdl_process;
void *mdl_mappedsystemva;
void *mdl_startva;
uint32_t mdl_bytecount;
uint32_t mdl_byteoffset;
};
typedef struct mdl mdl, ndis_buffer;
/* MDL flags */
#define MDL_MAPPED_TO_SYSTEM_VA 0x0001
#define MDL_PAGES_LOCKED 0x0002
#define MDL_SOURCE_IS_NONPAGED_POOL 0x0004
#define MDL_ALLOCATED_FIXED_SIZE 0x0008
#define MDL_PARTIAL 0x0010
#define MDL_PARTIAL_HAS_BEEN_MAPPED 0x0020
#define MDL_IO_PAGE_READ 0x0040
#define MDL_WRITE_OPERATION 0x0080
#define MDL_PARENT_MAPPED_SYSTEM_VA 0x0100
#define MDL_FREE_EXTRA_PTES 0x0200
#define MDL_IO_SPACE 0x0800
#define MDL_NETWORK_HEADER 0x1000
#define MDL_MAPPING_CAN_FAIL 0x2000
#define MDL_ALLOCATED_MUST_SUCCEED 0x4000
/* Note: assumes x86 page size of 4K. */
#if PAGE_SIZE == 4096
#define PAGE_SHIFT 12
#elif PAGE_SIZE == 8192
#define PAGE_SHIFT 13
#else
#error PAGE_SHIFT undefined!
#endif
#define SPAN_PAGES(ptr, len) \
((uint32_t)((((uintptr_t)(ptr) & (PAGE_SIZE -1)) + \
((uint32_t)((((uintptr_t)(ptr) & (PAGE_SIZE - 1)) + \
(len) + (PAGE_SIZE - 1)) >> PAGE_SHIFT))
#define PAGE_ALIGN(ptr) \
((void *)((uintptr_t)(ptr) & ~(PAGE_SIZE - 1)))
#define BYTE_OFFSET(ptr) \
((uint32_t)((uintptr_t)(ptr) & (PAGE_SIZE - 1)))
#define MDL_INIT(b, baseva, len) \
(b)->nb_next = NULL; \
(b)->nb_size = (uint16_t)(sizeof(struct ndis_buffer) + \
#define MDL_PAGES(m) (vm_offset_t *)(m + 1)
#define MmInitializeMdl(b, baseva, len) \
(b)->mdl_next = NULL; \
(b)->mdl_size = (uint16_t)(sizeof(mdl) + \
(sizeof(uint32_t) * SPAN_PAGES((baseva), (len)))); \
(b)->nb_flags = 0; \
(b)->nb_startva = (void *)PAGE_ALIGN((baseva)); \
(b)->nb_byteoffset = BYTE_OFFSET((baseva)); \
(b)->nb_bytecount = (uint32_t)(len);
#define MDL_VA(b) \
((void *)((char *)((b)->nb_startva) + (b)->nb_byteoffset))
(b)->mdl_flags = 0; \
(b)->mdl_startva = (void *)PAGE_ALIGN((baseva)); \
(b)->mdl_byteoffset = BYTE_OFFSET((baseva)); \
(b)->mdl_bytecount = (uint32_t)(len);
#define MmGetMdlByteOffset(mdl) ((mdl)->mdl_byteoffset)
#define MmGetMdlByteCount(mdl) ((mdl)->mdl_bytecount)
#define MmGetMdlVirtualAddress(mdl) \
((void *)((char *)((mdl)->mdl_startva) + (mdl)->mdl_byteoffset))
#define MmGetMdlStartVa(mdl) ((mdl)->mdl_startva)
#define MmGetMdlPfnArray(mdl) MDL_PAGES(mdl)
#define WDM_MAJOR 1
#define WDM_MINOR_WIN98 0x00
@ -405,6 +489,35 @@ struct thread_context {
typedef struct thread_context thread_context;
/* Forward declaration */
struct driver_object;
struct devobj_extension;
struct driver_extension {
struct driver_object *dre_driverobj;
void *dre_adddevicefunc;
uint32_t dre_reinitcnt;
unicode_string dre_srvname;
};
typedef struct driver_extension driver_extension;
/*
* In Windows, there are Physical Device Objects (PDOs) and
* Functional Device Objects (FDOs). Physical Device Objects are
* created and maintained by bus drivers. For example, the PCI
* bus driver might detect two PCI ethernet cards on a given
* bus. The PCI bus driver will then allocate two device_objects
* for its own internal bookeeping purposes. This is analagous
* to the device_t that the FreeBSD PCI code allocates and passes
* into each PCI driver's probe and attach routines.
*
* When an ethernet driver claims one of the ethernet cards
* on the bus, it will create its own device_object. This is
* the Functional Device Object. This object is analagous to the
* device-specific softc structure.
*/
struct device_object {
uint16_t do_type;
uint16_t do_size;
@ -431,20 +544,372 @@ struct device_object {
struct nt_kevent do_devlock;
uint16_t do_sectorsz;
uint16_t do_spare1;
void *do_devobj_ext;
struct devobj_extension *do_devobj_ext;
void *do_rsvd;
};
typedef struct device_object device_object;
struct irp {
uint32_t i_dummy;
struct devobj_extension {
uint16_t dve_type;
uint16_t dve_size;
device_object *dve_devobj;
};
typedef struct devobj_extension devobj_extension;
#define IO_NO_INCREMENT 0
#define IO_CD_ROM_INCREMENT 1
#define IO_DISK_INCREMENT 1
#define IO_KEYBOARD_INCREMENT 6
#define IO_MAILSLOT_INCREMENT 2
#define IO_MOUSE_INCREMENT 6
#define IO_NAMED_PIPE_INCREMENT 2
#define IO_NETWORK_INCREMENT 2
#define IO_PARALLEL_INCREMENT 1
#define IO_SERIAL_INCREMENT 2
#define IO_SOUND_INCREMENT 8
#define IO_VIDEO_INCREMENT 1
/* IRP major codes */
#define IRP_MJ_CREATE 0x00
#define IRP_MJ_CREATE_NAMED_PIPE 0x01
#define IRP_MJ_CLOSE 0x02
#define IRP_MJ_READ 0x03
#define IRP_MJ_WRITE 0x04
#define IRP_MJ_QUERY_INFORMATION 0x05
#define IRP_MJ_SET_INFORMATION 0x06
#define IRP_MJ_QUERY_EA 0x07
#define IRP_MJ_SET_EA 0x08
#define IRP_MJ_FLUSH_BUFFERS 0x09
#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a
#define IRP_MJ_SET_VOLUME_INFORMATION 0x0b
#define IRP_MJ_DIRECTORY_CONTROL 0x0c
#define IRP_MJ_FILE_SYSTEM_CONTROL 0x0d
#define IRP_MJ_DEVICE_CONTROL 0x0e
#define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f
#define IRP_MJ_SHUTDOWN 0x10
#define IRP_MJ_LOCK_CONTROL 0x11
#define IRP_MJ_CLEANUP 0x12
#define IRP_MJ_CREATE_MAILSLOT 0x13
#define IRP_MJ_QUERY_SECURITY 0x14
#define IRP_MJ_SET_SECURITY 0x15
#define IRP_MJ_POWER 0x16
#define IRP_MJ_SYSTEM_CONTROL 0x17
#define IRP_MJ_DEVICE_CHANGE 0x18
#define IRP_MJ_QUERY_QUOTA 0x19
#define IRP_MJ_SET_QUOTA 0x1a
#define IRP_MJ_PNP 0x1b
#define IRP_MJ_PNP_POWER IRP_MJ_PNP // Obsolete....
#define IRP_MJ_MAXIMUM_FUNCTION 0x1b
#define IRP_MJ_SCSI IRP_MJ_INTERNAL_DEVICE_CONTROL
/* IRP minor codes */
#define IRP_MN_QUERY_DIRECTORY 0x01
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x02
#define IRP_MN_USER_FS_REQUEST 0x00
#define IRP_MN_MOUNT_VOLUME 0x01
#define IRP_MN_VERIFY_VOLUME 0x02
#define IRP_MN_LOAD_FILE_SYSTEM 0x03
#define IRP_MN_TRACK_LINK 0x04 // To be obsoleted soon
#define IRP_MN_KERNEL_CALL 0x04
#define IRP_MN_LOCK 0x01
#define IRP_MN_UNLOCK_SINGLE 0x02
#define IRP_MN_UNLOCK_ALL 0x03
#define IRP_MN_UNLOCK_ALL_BY_KEY 0x04
#define IRP_MN_NORMAL 0x00
#define IRP_MN_DPC 0x01
#define IRP_MN_MDL 0x02
#define IRP_MN_COMPLETE 0x04
#define IRP_MN_COMPRESSED 0x08
#define IRP_MN_MDL_DPC (IRP_MN_MDL | IRP_MN_DPC)
#define IRP_MN_COMPLETE_MDL (IRP_MN_COMPLETE | IRP_MN_MDL)
#define IRP_MN_COMPLETE_MDL_DPC (IRP_MN_COMPLETE_MDL | IRP_MN_DPC)
#define IRP_MN_SCSI_CLASS 0x01
#define IRP_MN_START_DEVICE 0x00
#define IRP_MN_QUERY_REMOVE_DEVICE 0x01
#define IRP_MN_REMOVE_DEVICE 0x02
#define IRP_MN_CANCEL_REMOVE_DEVICE 0x03
#define IRP_MN_STOP_DEVICE 0x04
#define IRP_MN_QUERY_STOP_DEVICE 0x05
#define IRP_MN_CANCEL_STOP_DEVICE 0x06
#define IRP_MN_QUERY_DEVICE_RELATIONS 0x07
#define IRP_MN_QUERY_INTERFACE 0x08
#define IRP_MN_QUERY_CAPABILITIES 0x09
#define IRP_MN_QUERY_RESOURCES 0x0A
#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS 0x0B
#define IRP_MN_QUERY_DEVICE_TEXT 0x0C
#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS 0x0D
#define IRP_MN_READ_CONFIG 0x0F
#define IRP_MN_WRITE_CONFIG 0x10
#define IRP_MN_EJECT 0x11
#define IRP_MN_SET_LOCK 0x12
#define IRP_MN_QUERY_ID 0x13
#define IRP_MN_QUERY_PNP_DEVICE_STATE 0x14
#define IRP_MN_QUERY_BUS_INFORMATION 0x15
#define IRP_MN_DEVICE_USAGE_NOTIFICATION 0x16
#define IRP_MN_SURPRISE_REMOVAL 0x17
#define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18
#define IRP_MN_WAIT_WAKE 0x00
#define IRP_MN_POWER_SEQUENCE 0x01
#define IRP_MN_SET_POWER 0x02
#define IRP_MN_QUERY_POWER 0x03
#define IRP_MN_QUERY_ALL_DATA 0x00
#define IRP_MN_QUERY_SINGLE_INSTANCE 0x01
#define IRP_MN_CHANGE_SINGLE_INSTANCE 0x02
#define IRP_MN_CHANGE_SINGLE_ITEM 0x03
#define IRP_MN_ENABLE_EVENTS 0x04
#define IRP_MN_DISABLE_EVENTS 0x05
#define IRP_MN_ENABLE_COLLECTION 0x06
#define IRP_MN_DISABLE_COLLECTION 0x07
#define IRP_MN_REGINFO 0x08
#define IRP_MN_EXECUTE_METHOD 0x09
#define IRP_MN_REGINFO_EX 0x0b
/* IRP flags */
#define IRP_NOCACHE 0x00000001
#define IRP_PAGING_IO 0x00000002
#define IRP_MOUNT_COMPLETION 0x00000002
#define IRP_SYNCHRONOUS_API 0x00000004
#define IRP_ASSOCIATED_IRP 0x00000008
#define IRP_BUFFERED_IO 0x00000010
#define IRP_DEALLOCATE_BUFFER 0x00000020
#define IRP_INPUT_OPERATION 0x00000040
#define IRP_SYNCHRONOUS_PAGING_IO 0x00000040
#define IRP_CREATE_OPERATION 0x00000080
#define IRP_READ_OPERATION 0x00000100
#define IRP_WRITE_OPERATION 0x00000200
#define IRP_CLOSE_OPERATION 0x00000400
#define IRP_DEFER_IO_COMPLETION 0x00000800
#define IRP_OB_QUERY_NAME 0x00001000
#define IRP_HOLD_DEVICE_QUEUE 0x00002000
#define IRP_RETRY_IO_COMPLETION 0x00004000
#define IRP_CLASS_CACHE_OPERATION 0x00008000
#define IRP_SET_USER_EVENT IRP_CLOSE_OPERATION
/* IRP I/O control flags */
#define IRP_QUOTA_CHARGED 0x01
#define IRP_ALLOCATED_MUST_SUCCEED 0x02
#define IRP_ALLOCATED_FIXED_SIZE 0x04
#define IRP_LOOKASIDE_ALLOCATION 0x08
struct io_status_block {
union {
uint32_t isb_status;
void *isb_ptr;
} u;
register_t isb_info;
};
typedef struct io_status_block io_status_block;
struct kapc {
uint16_t apc_type;
uint16_t apc_size;
uint32_t apc_spare0;
void *apc_thread;
list_entry apc_list;
void *apc_kernfunc;
void *apc_rundownfunc;
void *apc_normalfunc;
void *apc_normctx;
void *apc_sysarg1;
void *apc_sysarg2;
uint8_t apc_stateidx;
uint8_t apc_cpumode;
uint8_t apc_inserted;
};
typedef struct kapc kapc;
struct io_stack_location {
uint8_t isl_major;
uint8_t isl_minor;
uint8_t isl_flags;
uint8_t isl_ctl;
/*
* There's a big-ass union here in the actual Windows
* definition of the stucture, but it contains stuff
* that doesn't really apply to BSD, and defining it
* all properly would require duplicating over a dozen
* other structures that we'll never use. Since the
* io_stack_location structure is opaque to drivers
* anyway, I'm not going to bother with the extra crap.
*/
union {
struct {
void *isl_arg1;
void *isl_arg2;
void *isl_arg3;
void *isl_arg4;
} isl_others;
} isl_parameters;
void *isl_devobj;
void *isl_fileobj;
void *isl_completionfunc;
void *isl_completionctx;
};
typedef struct io_stack_location io_stack_location;
/* Stack location control flags */
#define SL_PENDING_RETURNED 0x01
#define SL_INVOKE_ON_CANCEL 0x20
#define SL_INVOKE_ON_SUCCESS 0x40
#define SL_INVOKE_ON_ERROR 0x80
struct irp {
uint16_t irp_type;
uint16_t irp_size;
mdl *irp_mdl;
uint32_t irp_flags;
union {
struct irp *irp_master;
uint32_t irp_irpcnt;
void *irp_sysbuf;
} irp_assoc;
list_entry irp_thlist;
io_status_block irp_iostat;
uint8_t irp_reqmode;
uint8_t irp_pendingreturned;
uint8_t irp_stackcnt;
uint8_t irp_currentstackloc;
uint8_t irp_cancel;
uint8_t irp_cancelirql;
uint8_t irp_apcenv;
uint8_t irp_allocflags;
io_status_block *irp_usriostat;
nt_kevent irp_userevent;
union {
struct {
void *irp_apcfunc;
void *irp_apcctx;
} irp_asyncparms;
uint64_t irp_allocsz;
} irp_overlay;
void *irp_cancelfunc;
void *irp_userbuf;
/* Windows kernel info */
union {
struct {
union {
kdevice_qentry irp_dqe;
struct {
void *irp_drvctx[4];
} s1;
} u1;
void *irp_thread;
char *irp_auxbuf;
struct {
list_entry irp_list;
union {
io_stack_location *irp_csl;
uint32_t irp_pkttype;
} u2;
} s2;
void *irp_fileobj;
} irp_overlay;
kapc irp_apc;
void *irp_compkey;
} irp_tail;
};
#define irp_csl s2.u2.irp_csl
#define irp_pkttype s2.u2.irp_pkttype
typedef struct irp irp;
#define IoGetCurrentIrpStackLocation(irp) \
(irp)->irp_tail.irp_overlay.irp_csl
#define IoGetNextIrpStackLocation(irp) \
((irp)->irp_tail.irp_overlay.irp_csl - 1)
#define IoSetCompletionRoutine(irp, func, ctx, ok, err, cancel) \
do { \
io_stack_location *s; \
s = IoGetNextIrpStackLocation((irp)); \
s->isl_completionfunc = (func); \
s->isl_completionctx = (ctx); \
s->isl_ctl = 0; \
if (ok) irp->ctl = SL_INVOKE_ON_SUCCESS; \
if (err) irp->ctl |= SL_INVOKE_ON_ERROR; \
if (cancel) irp->ctl |= SL_INVOKE_ON_CANCEL; \
} while(0)
#define IoMarkIrpPending(irp) \
IoGetCurrentIrpStackLocation(irp)->isl_ctl |= SL_PENDING_RETURNED
#define IoSizeOfIrp(s) \
((uint16_t) (sizeof(itp) + ((s) * (sizeof(io_stack_location)))))
#define IoCopyCurrentIrpStackLocationToNext(irp) \
do { \
io_stack_location *src, *dst; \
src = IoGetCurrentIrpStackLocation(irp); \
dst = IoGetNextIrpStackLocation(irp); \
bcopy((char *)src, (char *)dst, \
offsetof(io_stack_location, isl_completionfunc)); \
} while(0)
#define IoSkipCurrentIrpStackLocation(irp) \
do { \
(irp)->irp_currentstackloc++; \
(irp)->irp_tail.irp_overlay.irp_csl++; \
} while(0)
typedef uint32_t (*driver_dispatch)(device_object *, irp *);
/*
* The driver_object is allocated once for each driver that's loaded
* into the system. A new one is allocated for each driver and
* populated a bit via the driver's DriverEntry function.
* In general, a Windows DriverEntry() function will provide a pointer
* to its AddDevice() method and set up the dispatch table.
* For NDIS drivers, this is all done behind the scenes in the
* NdisInitializeWrapper() and/or NdisMRegisterMiniport() routines.
*/
struct driver_object {
uint16_t dro_type;
uint16_t dro_size;
device_object *dro_devobj;
uint32_t dro_flags;
void *dro_driverstart;
uint32_t dro_driversize;
void *dro_driversection;
driver_extension dro_driverext;
unicode_string dro_drivername;
unicode_string *dro_hwdb;
void *dro_pfastiodispatch;
void *dro_driverinitfunc;
void *dro_driverstartiofunc;
void *dro_driverunloadfunc;
void *dro_dispatch[IRP_MJ_MAXIMUM_FUNCTION + 1];
};
typedef struct driver_object driver_object;
#define DEVPROP_DEVICE_DESCRIPTION 0x00000000
#define DEVPROP_HARDWARE_ID 0x00000001
#define DEVPROP_COMPATIBLE_IDS 0x00000002
@ -491,36 +956,41 @@ extern image_patch_table ntoskrnl_functbl[];
__BEGIN_DECLS
extern int ntoskrnl_libinit(void);
extern int ntoskrnl_libfini(void);
__stdcall extern void ntoskrnl_init_dpc(kdpc *, void *, void *);
__stdcall extern uint8_t ntoskrnl_queue_dpc(kdpc *, void *, void *);
__stdcall extern uint8_t ntoskrnl_dequeue_dpc(kdpc *);
__stdcall extern void ntoskrnl_init_timer(ktimer *);
__stdcall extern void ntoskrnl_init_timer_ex(ktimer *, uint32_t);
__stdcall extern uint8_t ntoskrnl_set_timer(ktimer *, int64_t, kdpc *);
__stdcall extern uint8_t ntoskrnl_set_timer_ex(ktimer *, int64_t,
__stdcall extern void KeInitializeDpc(kdpc *, void *, void *);
__stdcall extern uint8_t KeInsertQueueDpc(kdpc *, void *, void *);
__stdcall extern uint8_t KeRemoveQueueDpc(kdpc *);
__stdcall extern void KeInitializeTimer(ktimer *);
__stdcall extern void KeInitializeTimerEx(ktimer *, uint32_t);
__stdcall extern uint8_t KeSetTimer(ktimer *, int64_t, kdpc *);
__stdcall extern uint8_t KeSetTimerEx(ktimer *, int64_t,
uint32_t, kdpc *);
__stdcall extern uint8_t ntoskrnl_cancel_timer(ktimer *);
__stdcall extern uint8_t ntoskrnl_read_timer(ktimer *);
__stdcall extern uint32_t ntoskrnl_waitforobj(nt_dispatch_header *, uint32_t,
__stdcall extern uint8_t KeCancelTimer(ktimer *);
__stdcall extern uint8_t KeReadStateTimer(ktimer *);
__stdcall extern uint32_t KeWaitForSingleObject(nt_dispatch_header *, uint32_t,
uint32_t, uint8_t, int64_t *);
__stdcall extern void ntoskrnl_init_event(nt_kevent *, uint32_t, uint8_t);
__stdcall extern void ntoskrnl_clear_event(nt_kevent *);
__stdcall extern uint32_t ntoskrnl_read_event(nt_kevent *);
__stdcall extern uint32_t ntoskrnl_set_event(nt_kevent *, uint32_t, uint8_t);
__stdcall extern uint32_t ntoskrnl_reset_event(nt_kevent *);
__stdcall extern void ntoskrnl_init_lock(kspin_lock *);
__fastcall extern void ntoskrnl_lock_dpc(REGARGS1(kspin_lock *));
__fastcall extern void ntoskrnl_unlock_dpc(REGARGS1(kspin_lock *));
__stdcall extern void KeInitializeEvent(nt_kevent *, uint32_t, uint8_t);
__stdcall extern void KeClearEvent(nt_kevent *);
__stdcall extern uint32_t KeReadStateEvent(nt_kevent *);
__stdcall extern uint32_t KeSetEvent(nt_kevent *, uint32_t, uint8_t);
__stdcall extern uint32_t KeResetEvent(nt_kevent *);
__fastcall extern void KefAcquireSpinLockAtDpcLevel(REGARGS1(kspin_lock *));
__fastcall extern void KefReleaseSpinLockFromDpcLevel(REGARGS1(kspin_lock *));
__stdcall extern void KeInitializeSpinLock(kspin_lock *);
__fastcall extern uint32_t IofCallDriver(REGARGS2(device_object *, irp *));
__fastcall extern void IofCompleteRequest(REGARGS2(irp *, uint8_t));
#define IoCallDriver(a, b) FASTCALL2(IofCallDriver, a, b)
#define IoCompleteRequest(a, b) FASTCALL2(IofCompleteRequest, a, b)
/*
* On the Windows x86 arch, KeAcquireSpinLock() and KeReleaseSpinLock()
* routines live in the HAL. We try to imitate this behavior.
*/
#ifdef __i386__
#define ntoskrnl_acquire_spinlock(a, b) *(b) = FASTCALL1(hal_lock, a)
#define ntoskrnl_release_spinlock(a, b) FASTCALL2(hal_unlock, a, b)
#define ntoskrnl_raise_irql(a) FASTCALL1(hal_raise_irql, a)
#define ntoskrnl_lower_irql(a) FASTCALL1(hal_lower_irql, a)
#define KeAcquireSpinLock(a, b) *(b) = FASTCALL1(KfAcquireSpinLock, a)
#define KeReleaseSpinLock(a, b) FASTCALL2(KfReleaseSpinLock, a, b)
#define KeRaiseIrql(a) FASTCALL1(KfRaiseIrql, a)
#define KeLowerIrql(a) FASTCALL1(KfLowerIrql, a)
#endif /* __i386__ */
__END_DECLS

View File

@ -476,6 +476,10 @@ fastcall3(fcall3 f, uint32_t a, uint32_t b, uint32_t c)
#define FASTCALL3(f, a, b, c) (f)((a), (b), (c))
#endif /* __i386__ */
#define FUNC void(*)(void)
#define IMPORT_FUNC(x) { #x, (FUNC)x }
#define IMPORT_FUNC_MAP(x, y) { #x, (FUNC)y }
__BEGIN_DECLS
extern int pe_get_dos_header(vm_offset_t, image_dos_header *);
extern int pe_is_nt_image(vm_offset_t);

View File

@ -57,34 +57,32 @@ __FBSDID("$FreeBSD$");
#include <compat/ndis/ntoskrnl_var.h>
#include <compat/ndis/hal_var.h>
#define FUNC void(*)(void)
__stdcall static void hal_stall_exec_cpu(uint32_t);
__stdcall static void hal_writeport_buf_ulong(uint32_t *,
__stdcall static void KeStallExecutionProcessor(uint32_t);
__stdcall static void WRITE_PORT_BUFFER_ULONG(uint32_t *,
uint32_t *, uint32_t);
__stdcall static void hal_writeport_buf_ushort(uint16_t *,
__stdcall static void WRITE_PORT_BUFFER_USHORT(uint16_t *,
uint16_t *, uint32_t);
__stdcall static void hal_writeport_buf_uchar(uint8_t *,
__stdcall static void WRITE_PORT_BUFFER_UCHAR(uint8_t *,
uint8_t *, uint32_t);
__stdcall static void hal_writeport_ulong(uint32_t *, uint32_t);
__stdcall static void hal_writeport_ushort(uint16_t *, uint16_t);
__stdcall static void hal_writeport_uchar(uint8_t *, uint8_t);
__stdcall static uint32_t hal_readport_ulong(uint32_t *);
__stdcall static uint16_t hal_readport_ushort(uint16_t *);
__stdcall static uint8_t hal_readport_uchar(uint8_t *);
__stdcall static void hal_readport_buf_ulong(uint32_t *,
__stdcall static void WRITE_PORT_ULONG(uint32_t *, uint32_t);
__stdcall static void WRITE_PORT_USHORT(uint16_t *, uint16_t);
__stdcall static void WRITE_PORT_UCHAR(uint8_t *, uint8_t);
__stdcall static uint32_t READ_PORT_ULONG(uint32_t *);
__stdcall static uint16_t READ_PORT_USHORT(uint16_t *);
__stdcall static uint8_t READ_PORT_UCHAR(uint8_t *);
__stdcall static void READ_PORT_BUFFER_ULONG(uint32_t *,
uint32_t *, uint32_t);
__stdcall static void hal_readport_buf_ushort(uint16_t *,
__stdcall static void READ_PORT_BUFFER_USHORT(uint16_t *,
uint16_t *, uint32_t);
__stdcall static void hal_readport_buf_uchar(uint8_t *,
__stdcall static void READ_PORT_BUFFER_UCHAR(uint8_t *,
uint8_t *, uint32_t);
__stdcall static uint64_t hal_perfcount(uint64_t *);
__stdcall static uint64_t KeQueryPerformanceCounter(uint64_t *);
__stdcall static void dummy (void);
extern struct mtx_pool *ndis_mtxpool;
__stdcall static void
hal_stall_exec_cpu(usecs)
KeStallExecutionProcessor(usecs)
uint32_t usecs;
{
DELAY(usecs);
@ -92,7 +90,7 @@ hal_stall_exec_cpu(usecs)
}
__stdcall static void
hal_writeport_ulong(port, val)
WRITE_PORT_ULONG(port, val)
uint32_t *port;
uint32_t val;
{
@ -101,7 +99,7 @@ hal_writeport_ulong(port, val)
}
__stdcall static void
hal_writeport_ushort(port, val)
WRITE_PORT_USHORT(port, val)
uint16_t *port;
uint16_t val;
{
@ -110,7 +108,7 @@ hal_writeport_ushort(port, val)
}
__stdcall static void
hal_writeport_uchar(port, val)
WRITE_PORT_UCHAR(port, val)
uint8_t *port;
uint8_t val;
{
@ -119,7 +117,7 @@ hal_writeport_uchar(port, val)
}
__stdcall static void
hal_writeport_buf_ulong(port, val, cnt)
WRITE_PORT_BUFFER_ULONG(port, val, cnt)
uint32_t *port;
uint32_t *val;
uint32_t cnt;
@ -130,7 +128,7 @@ hal_writeport_buf_ulong(port, val, cnt)
}
__stdcall static void
hal_writeport_buf_ushort(port, val, cnt)
WRITE_PORT_BUFFER_USHORT(port, val, cnt)
uint16_t *port;
uint16_t *val;
uint32_t cnt;
@ -141,7 +139,7 @@ hal_writeport_buf_ushort(port, val, cnt)
}
__stdcall static void
hal_writeport_buf_uchar(port, val, cnt)
WRITE_PORT_BUFFER_UCHAR(port, val, cnt)
uint8_t *port;
uint8_t *val;
uint32_t cnt;
@ -152,28 +150,28 @@ hal_writeport_buf_uchar(port, val, cnt)
}
__stdcall static uint16_t
hal_readport_ushort(port)
READ_PORT_USHORT(port)
uint16_t *port;
{
return(bus_space_read_2(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port));
}
__stdcall static uint32_t
hal_readport_ulong(port)
READ_PORT_ULONG(port)
uint32_t *port;
{
return(bus_space_read_4(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port));
}
__stdcall static uint8_t
hal_readport_uchar(port)
READ_PORT_UCHAR(port)
uint8_t *port;
{
return(bus_space_read_1(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port));
}
__stdcall static void
hal_readport_buf_ulong(port, val, cnt)
READ_PORT_BUFFER_ULONG(port, val, cnt)
uint32_t *port;
uint32_t *val;
uint32_t cnt;
@ -184,7 +182,7 @@ hal_readport_buf_ulong(port, val, cnt)
}
__stdcall static void
hal_readport_buf_ushort(port, val, cnt)
READ_PORT_BUFFER_USHORT(port, val, cnt)
uint16_t *port;
uint16_t *val;
uint32_t cnt;
@ -195,7 +193,7 @@ hal_readport_buf_ushort(port, val, cnt)
}
__stdcall static void
hal_readport_buf_uchar(port, val, cnt)
READ_PORT_BUFFER_UCHAR(port, val, cnt)
uint8_t *port;
uint8_t *val;
uint32_t cnt;
@ -253,31 +251,31 @@ hal_readport_buf_uchar(port, val, cnt)
*/
__fastcall uint8_t
hal_lock(REGARGS1(kspin_lock *lock))
KfAcquireSpinLock(REGARGS1(kspin_lock *lock))
{
uint8_t oldirql;
/* I am so going to hell for this. */
if (hal_irql() > DISPATCH_LEVEL)
if (KeGetCurrentIrql() > DISPATCH_LEVEL)
panic("IRQL_NOT_LESS_THAN_OR_EQUAL");
oldirql = FASTCALL1(hal_raise_irql, DISPATCH_LEVEL);
FASTCALL1(ntoskrnl_lock_dpc, lock);
oldirql = FASTCALL1(KfRaiseIrql, DISPATCH_LEVEL);
FASTCALL1(KefAcquireSpinLockAtDpcLevel, lock);
return(oldirql);
}
__fastcall void
hal_unlock(REGARGS2(kspin_lock *lock, uint8_t newirql))
KfReleaseSpinLock(REGARGS2(kspin_lock *lock, uint8_t newirql))
{
FASTCALL1(ntoskrnl_unlock_dpc, lock);
FASTCALL1(hal_lower_irql, newirql);
FASTCALL1(KefReleaseSpinLockFromDpcLevel, lock);
FASTCALL1(KfLowerIrql, newirql);
return;
}
__stdcall uint8_t
hal_irql(void)
KeGetCurrentIrql(void)
{
if (AT_DISPATCH_LEVEL(curthread))
return(DISPATCH_LEVEL);
@ -285,7 +283,7 @@ hal_irql(void)
}
__stdcall static uint64_t
hal_perfcount(freq)
KeQueryPerformanceCounter(freq)
uint64_t *freq;
{
if (freq != NULL)
@ -295,14 +293,14 @@ hal_perfcount(freq)
}
__fastcall uint8_t
hal_raise_irql(REGARGS1(uint8_t irql))
KfRaiseIrql(REGARGS1(uint8_t irql))
{
uint8_t oldirql;
if (irql < hal_irql())
if (irql < KeGetCurrentIrql())
panic("IRQL_NOT_LESS_THAN");
if (hal_irql() == DISPATCH_LEVEL)
if (KeGetCurrentIrql() == DISPATCH_LEVEL)
return(DISPATCH_LEVEL);
mtx_lock_spin(&sched_lock);
@ -314,12 +312,12 @@ hal_raise_irql(REGARGS1(uint8_t irql))
}
__fastcall void
hal_lower_irql(REGARGS1(uint8_t oldirql))
KfLowerIrql(REGARGS1(uint8_t oldirql))
{
if (oldirql == DISPATCH_LEVEL)
return;
if (hal_irql() != DISPATCH_LEVEL)
if (KeGetCurrentIrql() != DISPATCH_LEVEL)
panic("IRQL_NOT_GREATER_THAN");
mtx_lock_spin(&sched_lock);
@ -337,25 +335,25 @@ static void dummy()
}
image_patch_table hal_functbl[] = {
{ "KeStallExecutionProcessor", (FUNC)hal_stall_exec_cpu },
{ "WRITE_PORT_ULONG", (FUNC)hal_writeport_ulong },
{ "WRITE_PORT_USHORT", (FUNC)hal_writeport_ushort },
{ "WRITE_PORT_UCHAR", (FUNC)hal_writeport_uchar },
{ "WRITE_PORT_BUFFER_ULONG", (FUNC)hal_writeport_buf_ulong },
{ "WRITE_PORT_BUFFER_USHORT", (FUNC)hal_writeport_buf_ushort },
{ "WRITE_PORT_BUFFER_UCHAR", (FUNC)hal_writeport_buf_uchar },
{ "READ_PORT_ULONG", (FUNC)hal_readport_ulong },
{ "READ_PORT_USHORT", (FUNC)hal_readport_ushort },
{ "READ_PORT_UCHAR", (FUNC)hal_readport_uchar },
{ "READ_PORT_BUFFER_ULONG", (FUNC)hal_readport_buf_ulong },
{ "READ_PORT_BUFFER_USHORT", (FUNC)hal_readport_buf_ushort },
{ "READ_PORT_BUFFER_UCHAR", (FUNC)hal_readport_buf_uchar },
{ "KfAcquireSpinLock", (FUNC)hal_lock },
{ "KfReleaseSpinLock", (FUNC)hal_unlock },
{ "KeGetCurrentIrql", (FUNC)hal_irql },
{ "KeQueryPerformanceCounter", (FUNC)hal_perfcount },
{ "KfLowerIrql", (FUNC)hal_lower_irql },
{ "KfRaiseIrql", (FUNC)hal_raise_irql },
IMPORT_FUNC(KeStallExecutionProcessor),
IMPORT_FUNC(WRITE_PORT_ULONG),
IMPORT_FUNC(WRITE_PORT_USHORT),
IMPORT_FUNC(WRITE_PORT_UCHAR),
IMPORT_FUNC(WRITE_PORT_BUFFER_ULONG),
IMPORT_FUNC(WRITE_PORT_BUFFER_USHORT),
IMPORT_FUNC(WRITE_PORT_BUFFER_UCHAR),
IMPORT_FUNC(READ_PORT_ULONG),
IMPORT_FUNC(READ_PORT_USHORT),
IMPORT_FUNC(READ_PORT_UCHAR),
IMPORT_FUNC(READ_PORT_BUFFER_ULONG),
IMPORT_FUNC(READ_PORT_BUFFER_USHORT),
IMPORT_FUNC(READ_PORT_BUFFER_UCHAR),
IMPORT_FUNC(KfAcquireSpinLock),
IMPORT_FUNC(KfReleaseSpinLock),
IMPORT_FUNC(KeGetCurrentIrql),
IMPORT_FUNC(KeQueryPerformanceCounter),
IMPORT_FUNC(KfLowerIrql),
IMPORT_FUNC(KfRaiseIrql),
/*
* This last entry is a catch-all for any function we haven't

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1016,9 +1016,9 @@ ndis_intrtask(arg)
sc = arg;
ifp = &sc->arpcom.ac_if;
irql = FASTCALL1(hal_raise_irql, DISPATCH_LEVEL);
irql = KeRaiseIrql(DISPATCH_LEVEL);
ndis_intrhand(sc);
FASTCALL1(hal_lower_irql, irql);
KeLowerIrql(irql);
mtx_lock(&sc->ndis_intrmtx);
ndis_enable_intr(sc);
mtx_unlock(&sc->ndis_intrmtx);