diff --git a/sys/compat/ndis/hal_var.h b/sys/compat/ndis/hal_var.h index 63868956e22..c2a534e9f21 100644 --- a/sys/compat/ndis/hal_var.h +++ b/sys/compat/ndis/hal_var.h @@ -46,6 +46,8 @@ extern image_patch_table hal_functbl[]; __BEGIN_DECLS +extern int hal_libinit(void); +extern int hal_libfini(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)); diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c index f93bf4e36fb..589742badc6 100644 --- a/sys/compat/ndis/kern_ndis.c +++ b/sys/compat/ndis/kern_ndis.c @@ -85,6 +85,17 @@ __stdcall static void ndis_getdone_func(ndis_handle, ndis_status); __stdcall static void ndis_resetdone_func(ndis_handle, ndis_status, uint8_t); __stdcall static void ndis_sendrsrcavail_func(ndis_handle); +static image_patch_table kernndis_functbl[] = { + IMPORT_FUNC(ndis_status_func), + IMPORT_FUNC(ndis_statusdone_func), + IMPORT_FUNC(ndis_setdone_func), + IMPORT_FUNC(ndis_getdone_func), + IMPORT_FUNC(ndis_resetdone_func), + IMPORT_FUNC(ndis_sendrsrcavail_func), + + { NULL, NULL, NULL } +}; + struct nd_head ndis_devhead; struct ndis_req { @@ -108,12 +119,12 @@ static int ndis_enlarge_thrqueue(int); static int ndis_shrink_thrqueue(int); static void ndis_runq(void *); -static uma_zone_t ndis_packet_zone, ndis_buffer_zone; +static uma_zone_t ndis_buffer_zone; struct mtx ndis_thr_mtx; struct mtx ndis_req_mtx; static STAILQ_HEAD(ndisqhead, ndis_req) ndis_ttodo; -struct ndisqhead ndis_itodo; -struct ndisqhead ndis_free; +static struct ndisqhead ndis_itodo; +static struct ndisqhead ndis_free; static int ndis_jobs = 32; static struct ndisproc ndis_tproc; @@ -130,21 +141,27 @@ static int ndis_modevent(module_t mod, int cmd, void *arg) { int error = 0; + image_patch_table *patch; switch (cmd) { case MOD_LOAD: /* Initialize subsystems */ windrv_libinit(); + hal_libinit(); ndis_libinit(); ntoskrnl_libinit(); + patch = kernndis_functbl; + while (patch->ipt_func != NULL) { + windrv_wrap((funcptr)patch->ipt_func, + (funcptr *)&patch->ipt_wrap); + patch++; + } + /* Initialize TX buffer UMA zone. */ - ndis_packet_zone = uma_zcreate("NDIS packet", - sizeof(ndis_packet), NULL, NULL, NULL, - NULL, UMA_ALIGN_PTR, 0); ndis_buffer_zone = uma_zcreate("NDIS buffer", - sizeof(ndis_buffer), NULL, NULL, NULL, - NULL, UMA_ALIGN_PTR, 0); + sizeof(struct mdl) + (sizeof(vm_offset_t *) * 16), + NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); ndis_create_kthreads(); @@ -156,11 +173,18 @@ ndis_modevent(module_t mod, int cmd, void *arg) ndis_destroy_kthreads(); if (TAILQ_FIRST(&ndis_devhead) == NULL) { /* Shut down subsystems */ + hal_libfini(); ndis_libfini(); ntoskrnl_libfini(); + windrv_libfini(); + + patch = kernndis_functbl; + while (patch->ipt_func != NULL) { + windrv_unwrap(patch->ipt_wrap); + patch++; + } /* Remove zones */ - uma_zdestroy(ndis_packet_zone); uma_zdestroy(ndis_buffer_zone); } break; @@ -169,12 +193,18 @@ ndis_modevent(module_t mod, int cmd, void *arg) ndis_destroy_kthreads(); /* Shut down subsystems */ + hal_libfini(); ndis_libfini(); ntoskrnl_libfini(); windrv_libfini(); + patch = kernndis_functbl; + while (patch->ipt_func != NULL) { + windrv_unwrap(patch->ipt_wrap); + patch++; + } + /* Remove zones */ - uma_zdestroy(ndis_packet_zone); uma_zdestroy(ndis_buffer_zone); break; default: @@ -803,7 +833,7 @@ ndis_return(arg) returnfunc = sc->ndis_chars->nmc_return_packet_func; irql = KeRaiseIrql(DISPATCH_LEVEL); - returnfunc(adapter, p); + MSCALL2(returnfunc, adapter, p); KeLowerIrql(irql); return; @@ -859,7 +889,7 @@ ndis_free_packet(p) return; ndis_free_bufs(p->np_private.npp_head); - uma_zfree(ndis_packet_zone, p); + NdisFreePacket(p); return; } @@ -1057,21 +1087,11 @@ ndis_mtop(m0, p) ndis_buffer *buf = NULL, *prev = NULL; ndis_packet_private *priv; - if (p == NULL || m0 == NULL) + if (p == NULL || *p == NULL || m0 == NULL) return(EINVAL); - /* If caller didn't supply a packet, make one. */ - if (*p == NULL) { - *p = uma_zalloc(ndis_packet_zone, M_NOWAIT|M_ZERO); - - if (*p == NULL) - return(ENOMEM); - } - priv = &(*p)->np_private; priv->npp_totlen = m0->m_pkthdr.len; - priv->npp_packetooboffset = offsetof(ndis_packet, np_oob); - priv->npp_ndispktflags = NDIS_PACKET_ALLOCATED_BY_NDIS; for (m = m0; m != NULL; m = m->m_next) { if (m->m_len == 0) @@ -1153,7 +1173,7 @@ ndis_set_info(arg, oid, buf, buflen) return(ENXIO); KeAcquireSpinLock(&sc->ndis_block->nmb_lock, &irql); - rval = setfunc(adapter, oid, buf, *buflen, + rval = MSCALL6(setfunc, adapter, oid, buf, *buflen, &byteswritten, &bytesneeded); KeReleaseSpinLock(&sc->ndis_block->nmb_lock, irql); @@ -1210,7 +1230,7 @@ ndis_send_packets(arg, packets, cnt) sendfunc = sc->ndis_chars->nmc_sendmulti_func; senddonefunc = sc->ndis_block->nmb_senddone_func; irql = KeRaiseIrql(DISPATCH_LEVEL); - sendfunc(adapter, packets, cnt); + MSCALL3(sendfunc, adapter, packets, cnt); KeLowerIrql(irql); for (i = 0; i < cnt; i++) { @@ -1223,7 +1243,7 @@ ndis_send_packets(arg, packets, cnt) */ if (p == NULL || p->np_oob.npo_status == NDIS_STATUS_PENDING) continue; - senddonefunc(sc->ndis_block, p, p->np_oob.npo_status); + MSCALL3(senddonefunc, sc->ndis_block, p, p->np_oob.npo_status); } return(0); @@ -1249,13 +1269,14 @@ ndis_send_packet(arg, packet) senddonefunc = sc->ndis_block->nmb_senddone_func; irql = KeRaiseIrql(DISPATCH_LEVEL); - status = sendfunc(adapter, packet, packet->np_private.npp_flags); + status = MSCALL3(sendfunc, adapter, packet, + packet->np_private.npp_flags); KeLowerIrql(irql); if (status == NDIS_STATUS_PENDING) return(0); - senddonefunc(sc->ndis_block, packet, status); + MSCALL3(senddonefunc, sc->ndis_block, packet, status); return(0); } @@ -1338,7 +1359,7 @@ ndis_reset_nic(arg) return(EIO); irql = KeRaiseIrql(DISPATCH_LEVEL); - rval = resetfunc(&addressing_reset, adapter); + rval = MSCALL2(resetfunc, &addressing_reset, adapter); KeLowerIrql(irql); if (rval == NDIS_STATUS_PENDING) { @@ -1378,7 +1399,7 @@ ndis_halt_nic(arg) haltfunc = sc->ndis_chars->nmc_halt_func; NDIS_UNLOCK(sc); - haltfunc(adapter); + MSCALL1(haltfunc, adapter); NDIS_LOCK(sc); sc->ndis_block->nmb_miniportadapterctx = NULL; @@ -1404,9 +1425,9 @@ ndis_shutdown_nic(arg) return(EIO); if (sc->ndis_chars->nmc_rsvd0 == NULL) - shutdownfunc(adapter); + MSCALL1(shutdownfunc, adapter); else - shutdownfunc(sc->ndis_chars->nmc_rsvd0); + MSCALL1(shutdownfunc, sc->ndis_chars->nmc_rsvd0); ndis_shrink_thrqueue(8); TAILQ_REMOVE(&ndis_devhead, sc->ndis_block, link); @@ -1434,12 +1455,10 @@ ndis_init_nic(arg) initfunc = sc->ndis_chars->nmc_init_func; NDIS_UNLOCK(sc); - TAILQ_INIT(&block->nmb_timerlist); - for (i = 0; i < NdisMediumMax; i++) mediumarray[i] = i; - status = initfunc(&openstatus, &chosenmedium, + status = MSCALL6(initfunc, &openstatus, &chosenmedium, mediumarray, NdisMediumMax, block, block); /* @@ -1470,7 +1489,7 @@ ndis_enable_intr(arg) intrenbfunc = sc->ndis_chars->nmc_enable_interrupts_func; if (adapter == NULL || intrenbfunc == NULL) return; - intrenbfunc(adapter); + MSCALL1(intrenbfunc, adapter); return; } @@ -1488,7 +1507,7 @@ ndis_disable_intr(arg) intrdisfunc = sc->ndis_chars->nmc_disable_interrupts_func; if (adapter == NULL || intrdisfunc == NULL) return; - intrdisfunc(adapter); + MSCALL1(intrdisfunc, adapter); return; } @@ -1513,7 +1532,7 @@ ndis_isr(arg, ourintr, callhandler) if (adapter == NULL || isrfunc == NULL) return(ENXIO); - isrfunc(&accepted, &queue, adapter); + MSCALL3(isrfunc, &accepted, &queue, adapter); *ourintr = accepted; *callhandler = queue; @@ -1539,7 +1558,7 @@ ndis_intrhand(arg) if (adapter == NULL || intrfunc == NULL) return(EINVAL); - intrfunc(adapter); + MSCALL1(intrfunc, adapter); return(0); } @@ -1569,7 +1588,7 @@ ndis_get_info(arg, oid, buf, buflen) return(ENXIO); KeAcquireSpinLock(&sc->ndis_block->nmb_lock, &irql); - rval = queryfunc(adapter, oid, buf, *buflen, + rval = MSCALL6(queryfunc, adapter, oid, buf, *buflen, &byteswritten, &bytesneeded); KeReleaseSpinLock(&sc->ndis_block->nmb_lock, irql); @@ -1633,20 +1652,19 @@ NdisAddDevice(drv, pdo) * characteristics info in the if_ndis softc so the * UNIX wrapper driver can get to them later. */ - sc = device_get_softc(pdo->do_devext); sc->ndis_block = block; sc->ndis_chars = IoGetDriverObjectExtension(drv, (void *)1); - + /* Finish up BSD-specific setup. */ block->nmb_signature = (void *)0xcafebabe; - block->nmb_setdone_func = ndis_setdone_func; - block->nmb_querydone_func = ndis_getdone_func; - block->nmb_status_func = ndis_status_func; - block->nmb_statusdone_func = ndis_statusdone_func; - block->nmb_resetdone_func = ndis_resetdone_func; - block->nmb_sendrsrc_func = ndis_sendrsrcavail_func; + block->nmb_status_func = kernndis_functbl[0].ipt_wrap; + block->nmb_statusdone_func = kernndis_functbl[1].ipt_wrap; + block->nmb_setdone_func = kernndis_functbl[2].ipt_wrap; + block->nmb_querydone_func = kernndis_functbl[3].ipt_wrap; + block->nmb_resetdone_func = kernndis_functbl[4].ipt_wrap; + block->nmb_sendrsrc_func = kernndis_functbl[5].ipt_wrap; ndis_enlarge_thrqueue(8); diff --git a/sys/compat/ndis/kern_windrv.c b/sys/compat/ndis/kern_windrv.c index f298b995c35..a2279ca7028 100644 --- a/sys/compat/ndis/kern_windrv.c +++ b/sys/compat/ndis/kern_windrv.c @@ -182,9 +182,9 @@ windrv_unload(mod, img, len) e = drv->dro_driverext->dre_usrext.nle_flink; while (e != &drv->dro_driverext->dre_usrext) { c = e->nle_flink; - REMOVE_LIST_HEAD((&drv->dro_driverext->dre_usrext)); + REMOVE_LIST_ENTRY(e); ExFreePool(c); - e = e->nle_flink; + e = c; } /* Free the driver extension */ @@ -294,7 +294,7 @@ windrv_load(mod, img, len) /* Now call the DriverEntry() function. */ - status = entry(dobj, &dobj->dro_drivername); + status = MSCALL2(entry, dobj, &dobj->dro_drivername); if (status != STATUS_SUCCESS) { free(dobj->dro_drivername.us_buf, M_DEVBUF); @@ -414,3 +414,57 @@ windrv_bus_attach(drv, name) return(0); } + +#ifdef __amd64__ + +extern void x86_64_wrap(void); +extern void x86_64_wrap_call(void); +extern void x86_64_wrap_end(void); + +#endif /* __amd64__ */ + +int +windrv_wrap(func, wrap) + funcptr func; + funcptr *wrap; +{ +#ifdef __amd64__ + funcptr p; + vm_offset_t *calladdr; + vm_offset_t wrapstart, wrapend, wrapcall; + + wrapstart = (vm_offset_t)&x86_64_wrap; + wrapend = (vm_offset_t)&x86_64_wrap_end; + wrapcall = (vm_offset_t)&x86_64_wrap_call; + + /* Allocate a new wrapper instance. */ + + p = malloc((wrapend - wrapstart), M_DEVBUF, M_NOWAIT); + if (p == NULL) + return(ENOMEM); + + /* Copy over the code. */ + + bcopy((char *)wrapstart, p, (wrapend - wrapstart)); + + /* Insert the function address into the new wrapper instance. */ + + calladdr = (uint64_t *)((char *)p + (wrapcall - wrapstart) + 2); + *calladdr = (vm_offset_t)func; + + *wrap = p; +#else /* __amd64__ */ + *wrap = func; +#endif /* __amd64__ */ + return(0); +} + +int +windrv_unwrap(func) + funcptr func; +{ +#ifdef __amd64__ + free(func, M_DEVBUF); +#endif /* __amd64__ */ + return(0); +} diff --git a/sys/compat/ndis/ndis_var.h b/sys/compat/ndis/ndis_var.h index b4eaf5a1797..7b33a3e3142 100644 --- a/sys/compat/ndis/ndis_var.h +++ b/sys/compat/ndis/ndis_var.h @@ -733,15 +733,24 @@ typedef enum ndis_media_state ndis_media_state; #define NDIS_DMA_32BITS 0x01 #define NDIS_DMA_64BITS 0x02 +/* struct ndis_physaddr { +#ifdef __i386__ uint64_t np_quad; +#endif +#ifdef __amd64__ + uint32_t np_low; + uint32_t np_high; +#define np_quad np_low +#endif #ifdef notdef uint32_t np_low; uint32_t np_high; #endif }; +*/ -typedef struct ndis_physaddr ndis_physaddr; +typedef struct physaddr ndis_physaddr; struct ndis_ansi_string { uint16_t nas_len; @@ -1136,6 +1145,7 @@ struct ndis_packet { } np_macrsvd; } u; uint32_t *np_rsvd[2]; + uint8_t nm_protocolreserved[1]; /* * This next part is probably wrong, but we need some place @@ -1155,6 +1165,8 @@ struct ndis_packet { typedef struct ndis_packet ndis_packet; +#define PROTOCOL_RESERVED_SIZE_IN_PACKET (4 * sizeof(void *)) + /* mbuf ext type for NDIS */ #define EXT_NDIS 0x999 @@ -1453,7 +1465,6 @@ struct ndis_miniport_block { ndis_resource_list *nmb_rlist; ndis_status nmb_getstat; ndis_status nmb_setstat; - struct nte_head nmb_timerlist; vm_offset_t nmb_img; TAILQ_ENTRY(ndis_miniport_block) link; }; @@ -1531,7 +1542,18 @@ extern int ndis_thsuspend(struct proc *, int); extern void ndis_thresume(struct proc *); extern int ndis_strcasecmp(const char *, const char *); extern int ndis_strncasecmp(const char *, const char *, size_t); + __stdcall extern uint32_t NdisAddDevice(driver_object *, device_object *); +__stdcall extern void NdisAllocatePacketPool(ndis_status *, + ndis_handle *, uint32_t, uint32_t); +__stdcall extern void NdisAllocatePacketPoolEx(ndis_status *, + ndis_handle *, uint32_t, uint32_t, uint32_t); +__stdcall extern uint32_t NdisPacketPoolUsage(ndis_handle); +__stdcall extern void NdisFreePacketPool(ndis_handle); +__stdcall extern void NdisAllocatePacket(ndis_status *, + ndis_packet **, ndis_handle); +__stdcall extern void NdisFreePacket(ndis_packet *); + __END_DECLS #endif /* _NDIS_VAR_H_ */ diff --git a/sys/compat/ndis/ntoskrnl_var.h b/sys/compat/ndis/ntoskrnl_var.h index f1c0766cbc7..4c0112a5a71 100644 --- a/sys/compat/ndis/ntoskrnl_var.h +++ b/sys/compat/ndis/ntoskrnl_var.h @@ -1068,6 +1068,7 @@ typedef struct driver_object driver_object; #define NDIS_KSTACK_PAGES 8 extern image_patch_table ntoskrnl_functbl[]; +typedef void (*funcptr)(void); __BEGIN_DECLS extern int windrv_libinit(void); @@ -1079,6 +1080,8 @@ extern int windrv_create_pdo(driver_object *, device_t); extern void windrv_destroy_pdo(driver_object *, device_t); extern device_object *windrv_find_pdo(driver_object *, device_t); extern int windrv_bus_attach(driver_object *, char *); +extern int windrv_wrap(funcptr, funcptr *); +extern int windrv_unwrap(funcptr); extern int ntoskrnl_libinit(void); extern int ntoskrnl_libfini(void); @@ -1100,6 +1103,8 @@ __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 uint8_t KeAcquireSpinLockRaiseToDpc(kspin_lock *); +__stdcall extern void KeReleaseSpinLock(kspin_lock *, uint8_t); __stdcall extern void KeInitializeSpinLock(kspin_lock *); __stdcall extern void *ExAllocatePoolWithTag(uint32_t, size_t, uint32_t); __stdcall extern void ExFreePool(void *); @@ -1115,6 +1120,8 @@ __fastcall extern void IofCompleteRequest(REGARGS2(irp *, uint8_t)); __stdcall extern void IoDetachDevice(device_object *); __stdcall extern device_object *IoAttachDeviceToDeviceStack(device_object *, device_object *); +__stdcall mdl *IoAllocateMdl(void *, uint32_t, uint8_t, uint8_t, irp *); +__stdcall void IoFreeMdl(mdl *); #define IoCallDriver(a, b) FASTCALL2(IofCallDriver, a, b) #define IoCompleteRequest(a, b) FASTCALL2(IofCompleteRequest, a, b) @@ -1129,6 +1136,18 @@ __stdcall extern device_object *IoAttachDeviceToDeviceStack(device_object *, #define KeRaiseIrql(a) FASTCALL1(KfRaiseIrql, a) #define KeLowerIrql(a) FASTCALL1(KfLowerIrql, a) #endif /* __i386__ */ + +#ifdef __amd64__ +#define KeAcquireSpinLock(a, b) *(b) = KeAcquireSpinLockRaiseToDpc(a) + +/* + * These may need to be redefined later; + * not sure where they live on amd64 yet. + */ +#define KeRaiseIrql(a) KfRaiseIrql(a) +#define KeLowerIrql(a) KfLowerIrql(a) +#endif /* __amd64__ */ + __END_DECLS #endif /* _NTOSKRNL_VAR_H_ */ diff --git a/sys/compat/ndis/pe_var.h b/sys/compat/ndis/pe_var.h index fa635d4afeb..47055a8d5f9 100644 --- a/sys/compat/ndis/pe_var.h +++ b/sys/compat/ndis/pe_var.h @@ -39,11 +39,11 @@ * Image Format */ -#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */ -#define IMAGE_OS2_SIGNATURE 0x454E /* NE */ -#define IMAGE_OS2_SIGNATURE_LE 0x454C /* LE */ -#define IMAGE_VXD_SIGNATURE 0x454C /* LE */ -#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */ +#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */ +#define IMAGE_OS2_SIGNATURE 0x454E /* NE */ +#define IMAGE_OS2_SIGNATURE_LE 0x454C /* LE */ +#define IMAGE_VXD_SIGNATURE 0x454C /* LE */ +#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */ /* * All PE files have one of these, just so if you attempt to @@ -174,11 +174,13 @@ struct image_optional_header { uint32_t ioh_bsssize; uint32_t ioh_entryaddr; uint32_t ioh_codebaseaddr; +#ifndef __amd64__ uint32_t ioh_databaseaddr; +#endif /* NT-specific fields */ - uint32_t ioh_imagebase; + uintptr_t ioh_imagebase; uint32_t ioh_sectalign; uint32_t ioh_filealign; uint16_t ioh_osver_major; @@ -193,10 +195,10 @@ struct image_optional_header { uint32_t ioh_csum; uint16_t ioh_subsys; uint16_t ioh_dll_characteristics; - uint32_t ioh_stackreservesize; - uint32_t ioh_stackcommitsize; - uint32_t ioh_heapreservesize; - uint32_t ioh_heapcommitsize; + uintptr_t ioh_stackreservesize; + uintptr_t ioh_stackcommitsize; + uintptr_t ioh_heapreservesize; + uintptr_t ioh_heapcommitsize; uint16_t ioh_loaderflags; uint32_t ioh_rva_size_cnt; image_data_directory ioh_datadir[IMAGE_DIRECTORY_ENTRIES_MAX]; @@ -404,6 +406,7 @@ typedef struct message_resource_entry message_resource_entry; struct image_patch_table { char *ipt_name; void (*ipt_func)(void); + void (*ipt_wrap)(void); }; typedef struct image_patch_table image_patch_table; @@ -476,9 +479,78 @@ fastcall3(fcall3 f, uint32_t a, uint32_t b, uint32_t c) #define FASTCALL3(f, a, b, c) (f)((a), (b), (c)) #endif /* __i386__ */ + +/* + * AMD64 support. Microsoft uses a different calling convention + * than everyone else on the amd64 platform. Sadly, gcc has no + * built-in support for it (yet). + * + * The three major differences we're concerned with are: + * + * - The first 4 register-sized arguments are passed in the + * %rcx, %rdx, %r8 and %r9 registers, and the rest are pushed + * onto the stack. (The ELF ABI uses 6 registers, not 4). + * + * - The caller must reserve space on the stack for the 4 + * register arguments in case the callee has to spill them. + * + * - The stack myst be 16-byte aligned by the time the callee + * executes. A call instruction implicitly pushes an 8 byte + * return address onto the stack. We have to make sure that + * the amount of space we consume, plus the return address, + * is a multiple of 16 bytes in size. This means that in + * some cases, we may need to chew up an extra 8 bytes on + * the stack that will be unused. + * + * On the bright side, Microsoft seems to be using just the one + * calling convention for all functions on amd64, unlike x86 where + * they use a mix of _stdcall, _fastcall and _cdecl. + */ + +#ifdef __amd64__ + +extern uint64_t x86_64_call1(void *, uint64_t); +extern uint64_t x86_64_call2(void *, uint64_t, uint64_t); +extern uint64_t x86_64_call3(void *, uint64_t, uint64_t, uint64_t); +extern uint64_t x86_64_call4(void *, uint64_t, uint64_t, uint64_t, uint64_t); +extern uint64_t x86_64_call5(void *, uint64_t, uint64_t, uint64_t, uint64_t, + uint64_t); +extern uint64_t x86_64_call6(void *, uint64_t, uint64_t, uint64_t, uint64_t, + uint64_t, uint64_t); + + +#define MSCALL1(fn, a) \ + x86_64_call1((fn), (uint64_t)(a)) +#define MSCALL2(fn, a, b) \ + x86_64_call2((fn), (uint64_t)(a), (uint64_t)(b)) +#define MSCALL3(fn, a, b, c) \ + x86_64_call3((fn), (uint64_t)(a), (uint64_t)(b), \ + (uint64_t)(c)) +#define MSCALL4(fn, a, b, c, d) \ + x86_64_call4((fn), (uint64_t)(a), (uint64_t)(b), \ + (uint64_t)(c), (uint64_t)(d)) +#define MSCALL5(fn, a, b, c, d, e) \ + x86_64_call5((fn), (uint64_t)(a), (uint64_t)(b), \ + (uint64_t)(c), (uint64_t)(d), (uint64_t)(e)) +#define MSCALL6(fn, a, b, c, d, e, f) \ + x86_64_call6((fn), (uint64_t)(a), (uint64_t)(b), \ + (uint64_t)(c), (uint64_t)(d), (uint64_t)(e), (uint64_t)(f)) + +#else /* __amd64__ */ + +#define MSCALL1(fn, a) (fn)((a)) +#define MSCALL2(fn, a, b) (fn)((a), (b)) +#define MSCALL3(fn, a, b, c) (fn)((a), (b), (c)) +#define MSCALL4(fn, a, b, c, d) (fn)((a), (b), (c), (d)) +#define MSCALL5(fn, a, b, c, d, e) (fn)((a), (b), (c), (d), (e)) +#define MSCALL6(fn, a, b, c, d, e, f) (fn)((a), (b), (c), (d), (e), (f)) + +#endif /* __amd64__ */ + + #define FUNC void(*)(void) -#define IMPORT_FUNC(x) { #x, (FUNC)x } -#define IMPORT_FUNC_MAP(x, y) { #x, (FUNC)y } +#define IMPORT_FUNC(x) { #x, (FUNC)x, NULL } +#define IMPORT_FUNC_MAP(x, y) { #x, (FUNC)y, NULL } __BEGIN_DECLS extern int pe_get_dos_header(vm_offset_t, image_dos_header *); @@ -489,7 +561,7 @@ extern int pe_get_section_header(vm_offset_t, image_section_header *); extern int pe_numsections(vm_offset_t); extern vm_offset_t pe_imagebase(vm_offset_t); extern vm_offset_t pe_directory_offset(vm_offset_t, uint32_t); -extern vm_offset_t pe_translate_addr (vm_offset_t, uint32_t); +extern vm_offset_t pe_translate_addr (vm_offset_t, vm_offset_t); extern int pe_get_section(vm_offset_t, image_section_header *, const char *); extern int pe_relocate(vm_offset_t); extern int pe_get_import_descriptor(vm_offset_t, image_import_descriptor *, char *); diff --git a/sys/compat/ndis/resource_var.h b/sys/compat/ndis/resource_var.h index 9386052ccab..28f2d62920e 100644 --- a/sys/compat/ndis/resource_var.h +++ b/sys/compat/ndis/resource_var.h @@ -1,12 +1,48 @@ - -/* +/*- + * Copyright (c) 2005 + * Bill Paul . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Bill Paul. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * * $FreeBSD$ */ +#ifndef _RESOURCE_VAR_H_ +#define _RESOURCE_VAR_H_ + typedef int cm_resource_type; struct physaddr { - uint64_t np_quad; + uint64_t np_quad; +#ifdef notdef + uint32_t np_low; + uint32_t np_high; +#endif }; typedef struct physaddr physaddr; @@ -129,7 +165,7 @@ struct cm_partial_resource_desc { uint32_t cprd_rsvd1; uint32_t cprd_rsvd2; } cprd_devspec; - } u; + } u __attribute__((packed)); }; typedef struct cm_partial_resource_desc cm_partial_resource_desc; @@ -159,3 +195,5 @@ struct cm_resource_list { typedef struct cm_resource_list cm_resource_list; typedef cm_partial_resource_list ndis_resource_list; + +#endif /* _RESOURCE_VAR_H_ */ diff --git a/sys/compat/ndis/subr_hal.c b/sys/compat/ndis/subr_hal.c index b72613cebe5..0ec036acb59 100644 --- a/sys/compat/ndis/subr_hal.c +++ b/sys/compat/ndis/subr_hal.c @@ -82,6 +82,35 @@ __stdcall static void dummy (void); extern struct mtx_pool *ndis_mtxpool; +int +hal_libinit() +{ + image_patch_table *patch; + + patch = hal_functbl; + while (patch->ipt_func != NULL) { + windrv_wrap((funcptr)patch->ipt_func, + (funcptr *)&patch->ipt_wrap); + patch++; + } + + return(0); +} + +int +hal_libfini() +{ + image_patch_table *patch; + + patch = hal_functbl; + while (patch->ipt_func != NULL) { + windrv_unwrap(patch->ipt_wrap); + patch++; + } + + return(0); +} + __stdcall static void KeStallExecutionProcessor(usecs) uint32_t usecs; @@ -375,9 +404,9 @@ image_patch_table hal_functbl[] = { * in this table. */ - { NULL, (FUNC)dummy }, + { NULL, (FUNC)dummy, NULL }, /* End of list. */ - { NULL, NULL }, + { NULL, NULL, NULL } }; diff --git a/sys/compat/ndis/subr_ndis.c b/sys/compat/ndis/subr_ndis.c index f5b59727aa6..da56c187c63 100644 --- a/sys/compat/ndis/subr_ndis.c +++ b/sys/compat/ndis/subr_ndis.c @@ -188,15 +188,6 @@ __stdcall static uint32_t NdisGetCacheFillSize(void); __stdcall static uint32_t NdisMGetDmaAlignment(ndis_handle); __stdcall static ndis_status NdisMInitializeScatterGatherDma(ndis_handle, uint8_t, uint32_t); -__stdcall static void NdisAllocatePacketPool(ndis_status *, - ndis_handle *, uint32_t, uint32_t); -__stdcall static void NdisAllocatePacketPoolEx(ndis_status *, - ndis_handle *, uint32_t, uint32_t, uint32_t); -__stdcall static uint32_t NdisPacketPoolUsage(ndis_handle); -__stdcall static void NdisFreePacketPool(ndis_handle); -__stdcall static void NdisAllocatePacket(ndis_status *, - ndis_packet **, ndis_handle); -__stdcall static void NdisFreePacket(ndis_packet *); __stdcall static void NdisUnchainBufferAtFront(ndis_packet *, ndis_buffer **); __stdcall static void NdisUnchainBufferAtBack(ndis_packet *, ndis_buffer **); __stdcall static void NdisAllocateBufferPool(ndis_status *, @@ -306,13 +297,31 @@ __stdcall static void dummy(void); int ndis_libinit() { + image_patch_table *patch; + strcpy(ndis_filepath, "/compat/ndis"); + + patch = ndis_functbl; + while (patch->ipt_func != NULL) { + windrv_wrap((funcptr)patch->ipt_func, + (funcptr *)&patch->ipt_wrap); + patch++; + } + return(0); } int ndis_libfini() { + image_patch_table *patch; + + patch = ndis_functbl; + while (patch->ipt_func != NULL) { + windrv_unwrap(patch->ipt_wrap); + patch++; + } + return(0); } @@ -460,6 +469,7 @@ NdisAllocateMemoryWithTag(vaddr, len, tag) { void *mem; + mem = ExAllocatePoolWithTag(NonPagedPool, len, tag); if (mem == NULL) return(NDIS_STATUS_RESOURCES); @@ -528,6 +538,7 @@ NdisOpenConfiguration(status, cfg, wrapctx) ndis_handle *cfg; ndis_handle wrapctx; { + *cfg = wrapctx; *status = NDIS_STATUS_SUCCESS; @@ -676,7 +687,6 @@ NdisReadConfiguration(status, parm, cfg, key, type) } ndis_unicode_to_ascii(key->us_buf, key->us_len, &keystr); - *parm = &block->nmb_replyparm; bzero((char *)&block->nmb_replyparm, sizeof(ndis_config_parm)); unicode = (uint16_t *)&block->nmb_dummybuf; @@ -960,11 +970,14 @@ NdisWriteErrorLogEntry(ndis_handle adapter, ndis_error_code code, uint16_t flags; char msgbuf[ERRMSGLEN]; device_t dev; + driver_object *drv; block = (ndis_miniport_block *)adapter; dev = block->nmb_physdeviceobj->do_devext; + drv = block->nmb_physdeviceobj->do_drvobj; - error = pe_get_message(block->nmb_img, code, &str, &i, &flags); + error = pe_get_message((vm_offset_t)drv->dro_driverstart, + code, &str, &i, &flags); if (error == 0 && flags & MESSAGE_RESOURCE_UNICODE) { ustr = msgbuf; ndis_unicode_to_ascii((uint16_t *)str, @@ -1194,6 +1207,7 @@ NdisMQueryAdapterResources(status, adapter, list, buflen) bcopy((char *)block->nmb_rlist, (char *)list, rsclen); *status = NDIS_STATUS_SUCCESS; + return; } @@ -1381,11 +1395,11 @@ NdisMAllocateSharedMemory(adapter, len, cached, vaddr, paddr) * At least one device/driver combination (Linksys Instant * Wireless PCI Card V2.7, Broadcom 802.11b) seems to have * problems with performing DMA operations with physical - * that lie above the 1GB mark. I don't know if this is a - * hardware limitation or if the addresses are being truncated - * within the driver, but this seems to be the only way to - * make these cards work reliably in systems with more than - * 1GB of physical memory. + * addresses that lie above the 1GB mark. I don't know if this + * is a hardware limitation or if the addresses are being + * truncated within the driver, but this seems to be the only + * way to make these cards work reliably in systems with more + * than 1GB of physical memory. */ error = bus_dma_tag_create(sc->ndis_parent_tag, 64, @@ -1452,7 +1466,7 @@ ndis_asyncmem_complete(arg) donefunc = sc->ndis_chars->nmc_allocate_complete_func; NdisMAllocateSharedMemory(w->na_adapter, w->na_len, w->na_cached, &vaddr, &paddr); - donefunc(w->na_adapter, vaddr, &paddr, w->na_len, w->na_ctx); + MSCALL5(donefunc, w->na_adapter, vaddr, &paddr, w->na_len, w->na_ctx); free(arg, M_DEVBUF); @@ -1626,7 +1640,7 @@ NdisMInitializeScatterGatherDma(adapter, is64, maxphysmap) return(NDIS_STATUS_SUCCESS); } -__stdcall static void +__stdcall void NdisAllocatePacketPool(status, pool, descnum, protrsvdlen) ndis_status *status; ndis_handle *pool; @@ -1636,7 +1650,7 @@ NdisAllocatePacketPool(status, pool, descnum, protrsvdlen) ndis_packet *cur; int i; - *pool = malloc(sizeof(ndis_packet) * + *pool = malloc((sizeof(ndis_packet) + protrsvdlen) * ((descnum + NDIS_POOL_EXTRA) + 1), M_DEVBUF, M_NOWAIT|M_ZERO); @@ -1657,7 +1671,7 @@ NdisAllocatePacketPool(status, pool, descnum, protrsvdlen) return; } -__stdcall static void +__stdcall void NdisAllocatePacketPoolEx(status, pool, descnum, oflowdescnum, protrsvdlen) ndis_status *status; ndis_handle *pool; @@ -1669,7 +1683,7 @@ NdisAllocatePacketPoolEx(status, pool, descnum, oflowdescnum, protrsvdlen) descnum + oflowdescnum, protrsvdlen)); } -__stdcall static uint32_t +__stdcall uint32_t NdisPacketPoolUsage(pool) ndis_handle pool; { @@ -1680,7 +1694,7 @@ NdisPacketPoolUsage(pool) return(head->np_private.npp_count); } -__stdcall static void +__stdcall void NdisFreePacketPool(pool) ndis_handle pool; { @@ -1702,7 +1716,7 @@ NdisFreePacketPool(pool) return; } -__stdcall static void +__stdcall void NdisAllocatePacket(status, packet, pool) ndis_status *status; ndis_packet **packet; @@ -1747,7 +1761,8 @@ NdisAllocatePacket(status, packet, pool) /* * We must initialize the packet flags correctly in order * for the NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO() and - * NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO() to work correctly. + * NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO() macros to work + * correctly. */ pkt->np_private.npp_ndispktflags = NDIS_PACKET_ALLOCATED_BY_NDIS; @@ -1755,10 +1770,11 @@ NdisAllocatePacket(status, packet, pool) head->np_private.npp_count++; *status = NDIS_STATUS_SUCCESS; + return; } -__stdcall static void +__stdcall void NdisFreePacket(packet) ndis_packet *packet; { @@ -1842,12 +1858,16 @@ NdisUnchainBufferAtBack(packet, buf) } /* - * The NDIS "buffer" manipulation functions are somewhat misnamed. - * They don't really allocate buffers: they allocate buffer mappings. - * The idea is you reserve a chunk of DMA-able memory using - * NdisMAllocateSharedMemory() and then use NdisAllocateBuffer() - * to obtain the virtual address of the DMA-able region. - * NdisAllocateBufferPool() is analagous to bus_dma_tag_create(). + * The NDIS "buffer" is really an MDL (memory descriptor list) + * which is used to describe a buffer in a way that allows it + * to mapped into different contexts. We have to be careful how + * we handle them: in some versions of Windows, the NdisFreeBuffer() + * routine is an actual function in the NDIS API, but in others + * it's just a macro wrapper around IoFreeMdl(). There's really + * no way to use the 'descnum' parameter to count how many + * "buffers" are allocated since in order to use IoFreeMdl() to + * dispose of a buffer, we have to use IoAllocateMdl() to allocate + * them, and IoAllocateMdl() just grabs them out of the heap. */ __stdcall static void @@ -1856,27 +1876,13 @@ NdisAllocateBufferPool(status, pool, descnum) ndis_handle *pool; uint32_t descnum; { - ndis_buffer *cur; - int i; - - *pool = malloc(sizeof(ndis_buffer) * - ((descnum + NDIS_POOL_EXTRA) + 1), - M_DEVBUF, M_NOWAIT|M_ZERO); - - if (*pool == NULL) { - *status = NDIS_STATUS_RESOURCES; - return; - } - - cur = (ndis_buffer *)*pool; - cur->mdl_flags = 0x1; /* mark the head of the list */ - MmGetMdlByteCount(cur) = 0; /* init usage count */ - MmGetMdlByteOffset(cur) = 0; /* init deletetion flag */ - for (i = 0; i < (descnum + NDIS_POOL_EXTRA); i++) { - cur->mdl_next = cur + 1; - cur++; - } + /* + * The only thing we can really do here is verify that descnum + * is a reasonable value, but I really don't know what to check + * it against. + */ + *pool = NonPagedPool; *status = NDIS_STATUS_SUCCESS; return; } @@ -1885,26 +1891,9 @@ __stdcall static void NdisFreeBufferPool(pool) ndis_handle pool; { - ndis_buffer *head; - - head = pool; - - /* Mark this pool as 'going away.' */ - - MmGetMdlByteOffset(head) = 1; - - /* If there are no buffers loaned out, destroy the pool. */ - if (MmGetMdlByteCount(head) == 0) - free(pool, M_DEVBUF); - else - printf("NDIS: buggy driver deleting active buffer pool!\n"); - return; } -/* - * This maps to a bus_dmamap_create() and bus_dmamap_load(). - */ __stdcall static void NdisAllocateBuffer(status, buffer, pool, vaddr, len) ndis_status *status; @@ -1913,45 +1902,17 @@ NdisAllocateBuffer(status, buffer, pool, vaddr, len) void *vaddr; uint32_t len; { - ndis_buffer *head, *buf; - - head = (ndis_buffer *)pool; - if (head->mdl_flags != 0x1) { - *status = NDIS_STATUS_FAILURE; - return; - } - - /* - * If this pool is marked as 'going away' don't allocate any - * more buffers out of it. - */ - - if (MmGetMdlByteOffset(head)) { - *status = NDIS_STATUS_FAILURE; - return; - } - - buf = head->mdl_next; + ndis_buffer *buf; + buf = IoAllocateMdl(vaddr, len, FALSE, FALSE, NULL); if (buf == NULL) { *status = NDIS_STATUS_RESOURCES; return; } - head->mdl_next = buf->mdl_next; - - /* Save pointer to the pool. */ - buf->mdl_process = head; - - MmInitializeMdl(buf, vaddr, len); - *buffer = buf; - - /* Increment count of busy buffers. */ - - MmGetMdlByteCount(head)++; - *status = NDIS_STATUS_SUCCESS; + return; } @@ -1959,31 +1920,7 @@ __stdcall static void NdisFreeBuffer(buf) ndis_buffer *buf; { - ndis_buffer *head; - - if (buf == NULL || buf->mdl_process == NULL) - return; - - head = buf->mdl_process; - - if (head->mdl_flags != 0x1) - return; - - buf->mdl_next = head->mdl_next; - head->mdl_next = buf; - - /* Decrement count of busy buffers. */ - - MmGetMdlByteCount(head)--; - - /* - * If the pool has been marked for deletion and there are - * no more buffers outstanding, nuke the pool. - */ - - if (MmGetMdlByteOffset(head) && MmGetMdlByteCount(head) == 0) - free(head, M_DEVBUF); - + IoFreeMdl(buf); return; } @@ -2194,6 +2131,8 @@ NdisMRegisterInterrupt(intr, adapter, ivec, ilevel, reqisr, shared, imode) intr->ni_shared = shared; block->nmb_interrupt = intr; + KeInitializeSpinLock(&intr->ni_dpccountlock); + return(NDIS_STATUS_SUCCESS); } @@ -2423,18 +2362,17 @@ NdisMSynchronizeWithInterrupt(intr, syncfunc, syncctx) void *syncfunc; void *syncctx; { - struct ndis_softc *sc; __stdcall uint8_t (*sync)(void *); uint8_t rval; + uint8_t irql; if (syncfunc == NULL || syncctx == NULL) return(0); - sc = device_get_softc(intr->ni_block->nmb_physdeviceobj->do_devext); sync = syncfunc; - mtx_lock(&sc->ndis_intrmtx); - rval = sync(syncctx); - mtx_unlock(&sc->ndis_intrmtx); + KeAcquireSpinLock(&intr->ni_dpccountlock, &irql); + rval = MSCALL1(sync, syncctx); + KeReleaseSpinLock(&intr->ni_dpccountlock, irql); return(rval); } @@ -2901,7 +2839,7 @@ NdisMIndicateStatusComplete(adapter) block = (ndis_miniport_block *)adapter; statusdonefunc = block->nmb_statusdone_func; - statusdonefunc(adapter); + MSCALL1(statusdonefunc, adapter); return; } @@ -2918,7 +2856,7 @@ NdisMIndicateStatus(adapter, status, sbuf, slen) block = (ndis_miniport_block *)adapter; statusfunc = block->nmb_status_func; - statusfunc(adapter, status, sbuf, slen); + MSCALL4(statusfunc, adapter, status, sbuf, slen); return; } @@ -2931,7 +2869,7 @@ ndis_workfunc(ctx) work = ctx; workfunc = work->nwi_func; - workfunc(work, work->nwi_ctx); + MSCALL2(workfunc, work, work->nwi_ctx); return; } @@ -3230,9 +3168,9 @@ image_patch_table ndis_functbl[] = { * in this table. */ - { NULL, (FUNC)dummy }, + { NULL, (FUNC)dummy, NULL }, /* End of list. */ - { NULL, NULL }, + { NULL, NULL, NULL } }; diff --git a/sys/compat/ndis/subr_ntoskrnl.c b/sys/compat/ndis/subr_ntoskrnl.c index f793f2a6f19..555870581e4 100644 --- a/sys/compat/ndis/subr_ntoskrnl.c +++ b/sys/compat/ndis/subr_ntoskrnl.c @@ -143,8 +143,6 @@ __fastcall static uint32_t InterlockedDecrement(REGARGS1(volatile uint32_t *addend)); __fastcall static void ExInterlockedAddLargeStatistic(REGARGS2(uint64_t *addend, uint32_t)); -__stdcall static mdl *IoAllocateMdl(void *, uint32_t, uint8_t, uint8_t, irp *); -__stdcall static void IoFreeMdl(mdl *); __stdcall static uint32_t MmSizeOfMdl(void *, size_t); __stdcall static void MmBuildMdlForNonPagedPool(mdl *); __stdcall static void *MmMapLockedPages(mdl *, uint8_t); @@ -178,6 +176,7 @@ __stdcall static ndis_status ObReferenceObjectByHandle(ndis_handle, uint32_t, void *, uint8_t, void **, void **); __fastcall static void ObfDereferenceObject(REGARGS1(void *object)); __stdcall static uint32_t ZwClose(ndis_handle); +static void *ntoskrnl_memset(void *, int, size_t); static uint32_t DbgPrint(char *, ...); __stdcall static void DbgBreakPoint(void); __stdcall static void dummy(void); @@ -190,20 +189,51 @@ static struct nt_objref_head ntoskrnl_reflist; int ntoskrnl_libinit() { + image_patch_table *patch; + mtx_init(&ntoskrnl_dispatchlock, "ntoskrnl dispatch lock", MTX_NDIS_LOCK, MTX_DEF); KeInitializeSpinLock(&ntoskrnl_global); TAILQ_INIT(&ntoskrnl_reflist); + + patch = ntoskrnl_functbl; + while (patch->ipt_func != NULL) { + windrv_wrap((funcptr)patch->ipt_func, + (funcptr *)&patch->ipt_wrap); + patch++; + } + return(0); } int ntoskrnl_libfini() { + image_patch_table *patch; mtx_destroy(&ntoskrnl_dispatchlock); + + patch = ntoskrnl_functbl; + while (patch->ipt_func != NULL) { + windrv_unwrap(patch->ipt_wrap); + patch++; + } + return(0); } +/* + * We need to be able to reference this externally from the wrapper; + * GCC only generates a local implementation of memset. + */ +static void * +ntoskrnl_memset(buf, ch, size) + void *buf; + int ch; + size_t size; +{ + return(memset(buf, ch, size)); +} + __stdcall static uint8_t RtlEqualUnicodeString(str1, str2, caseinsensitive) ndis_unicode_string *str1; @@ -680,7 +710,7 @@ IofCompleteRequest(REGARGS2(irp *ip, uint8_t prioboost)) masterirp = ip->irp_assoc.irp_master; masterirpcnt = FASTCALL1(InterlockedDecrement, - masterirp->irp_assoc.irp_irpcnt); + &masterirp->irp_assoc.irp_irpcnt); while ((m = ip->irp_mdl) != NULL) { ip->irp_mdl = m->mdl_next; @@ -1323,7 +1353,7 @@ ExDeletePagedLookasideList(lookaside) freefunc = lookaside->nll_l.gl_freefunc; while((buf = ntoskrnl_popsl(&lookaside->nll_l.gl_listhead)) != NULL) - freefunc(buf); + MSCALL1(freefunc, buf); return; } @@ -1373,7 +1403,7 @@ ExDeleteNPagedLookasideList(lookaside) freefunc = lookaside->nll_l.gl_freefunc; while((buf = ntoskrnl_popsl(&lookaside->nll_l.gl_listhead)) != NULL) - freefunc(buf); + MSCALL1(freefunc, buf); return; } @@ -1435,6 +1465,22 @@ ExInterlockedPopEntrySList(REGARGS2(slist_header *head, kspin_lock *lock)) return(first); } +/* + * The KeInitializeSpinLock(), KefAcquireSpinLockAtDpcLevel() + * and KefReleaseSpinLockFromDpcLevel() appear to be analagous + * to splnet()/splx() in their use. We can't create a new mutex + * lock here because there is no complimentary KeFreeSpinLock() + * function. Instead, we grab a mutex from the mutex pool. + */ +__stdcall void +KeInitializeSpinLock(lock) + kspin_lock *lock; +{ + *lock = 0; + + return; +} + __fastcall void KefAcquireSpinLockAtDpcLevel(REGARGS1(kspin_lock *lock)) { @@ -1452,6 +1498,27 @@ KefReleaseSpinLockFromDpcLevel(REGARGS1(kspin_lock *lock)) return; } +__stdcall uint8_t +KeAcquireSpinLockRaiseToDpc(lock) + kspin_lock *lock; +{ + uint8_t oldirql; + + oldirql = FASTCALL1(KfAcquireSpinLock, lock); + return(oldirql); +} + +#ifndef __i386__ +__stdcall void +KeReleaseSpinLock(lock, irql) + kspin_lock *lock; + uint8_t irql; +{ + FASTCALL2(KfReleaseSpinLock, lock, irql); + return; +} +#endif + __fastcall static uint32_t InterlockedIncrement(REGARGS1(volatile uint32_t *addend)) { @@ -1478,7 +1545,7 @@ ExInterlockedAddLargeStatistic(REGARGS2(uint64_t *addend, uint32_t inc)) return; }; -__stdcall static mdl * +__stdcall mdl * IoAllocateMdl(vaddr, len, secondarybuf, chargequota, iopkt) void *vaddr; uint32_t len; @@ -1510,10 +1577,10 @@ IoAllocateMdl(vaddr, len, secondarybuf, chargequota, iopkt) } } - return (NULL); + return (m); } -__stdcall static void +__stdcall void IoFreeMdl(m) mdl *m; { @@ -1599,22 +1666,6 @@ MmUnmapLockedPages(vaddr, buf) return; } -/* - * The KeInitializeSpinLock(), KefAcquireSpinLockAtDpcLevel() - * and KefReleaseSpinLockFromDpcLevel() appear to be analagous - * to splnet()/splx() in their use. We can't create a new mutex - * lock here because there is no complimentary KeFreeSpinLock() - * function. Instead, we grab a mutex from the mutex pool. - */ -__stdcall void -KeInitializeSpinLock(lock) - kspin_lock *lock; -{ - *lock = 0; - - return; -} - __stdcall static size_t RtlCompareMemory(s1, s2, len) const void *s1; @@ -1987,7 +2038,7 @@ ntoskrnl_thrfunc(arg) tctx = thrctx->tc_thrctx; free(thrctx, M_TEMP); - rval = tfunc(tctx); + rval = MSCALL1(tfunc, tctx); PsTerminateSystemThread(rval); return; /* notreached */ @@ -2167,7 +2218,8 @@ ntoskrnl_run_dpc(arg) dpc = arg; dpcfunc = dpc->k_deferedfunc; irql = KeRaiseIrql(DISPATCH_LEVEL); - dpcfunc(dpc, dpc->k_deferredctx, dpc->k_sysarg1, dpc->k_sysarg2); + MSCALL4(dpcfunc, dpc, dpc->k_deferredctx, + dpc->k_sysarg1, dpc->k_sysarg2); KeLowerIrql(irql); return; @@ -2322,6 +2374,7 @@ image_patch_table ntoskrnl_functbl[] = { IMPORT_FUNC(RtlUnicodeStringToAnsiString), IMPORT_FUNC(RtlAnsiStringToUnicodeString), IMPORT_FUNC(RtlInitAnsiString), + IMPORT_FUNC_MAP(RtlInitString, RtlInitAnsiString), IMPORT_FUNC(RtlInitUnicodeString), IMPORT_FUNC(RtlFreeAnsiString), IMPORT_FUNC(RtlFreeUnicodeString), @@ -2338,8 +2391,8 @@ image_patch_table ntoskrnl_functbl[] = { IMPORT_FUNC(strcpy), IMPORT_FUNC(strlen), IMPORT_FUNC(memcpy), - IMPORT_FUNC_MAP(memmove, memset), - IMPORT_FUNC(memset), + IMPORT_FUNC_MAP(memmove, ntoskrnl_memset), + IMPORT_FUNC(ntoskrnl_memset), IMPORT_FUNC(IoAllocateDriverObjectExtension), IMPORT_FUNC(IoGetDriverObjectExtension), IMPORT_FUNC(IofCallDriver), @@ -2389,6 +2442,8 @@ image_patch_table ntoskrnl_functbl[] = { IMPORT_FUNC(ExInterlockedPushEntrySList), IMPORT_FUNC(KefAcquireSpinLockAtDpcLevel), IMPORT_FUNC(KefReleaseSpinLockFromDpcLevel), + IMPORT_FUNC(KeAcquireSpinLockRaiseToDpc), + IMPORT_FUNC(KeReleaseSpinLock), IMPORT_FUNC(InterlockedIncrement), IMPORT_FUNC(InterlockedDecrement), IMPORT_FUNC(ExInterlockedAddLargeStatistic), @@ -2432,9 +2487,9 @@ image_patch_table ntoskrnl_functbl[] = { * in this table. */ - { NULL, (FUNC)dummy }, + { NULL, (FUNC)dummy, NULL }, /* End of list. */ - { NULL, NULL }, + { NULL, NULL, NULL } }; diff --git a/sys/compat/ndis/subr_pe.c b/sys/compat/ndis/subr_pe.c index 5f37eade203..6ac815df36d 100644 --- a/sys/compat/ndis/subr_pe.c +++ b/sys/compat/ndis/subr_pe.c @@ -263,7 +263,7 @@ pe_directory_offset(imgbase, diridx) vm_offset_t pe_translate_addr(imgbase, rva) vm_offset_t imgbase; - uint32_t rva; + vm_offset_t rva; { image_optional_header opt_hdr; image_section_header *sect_hdr; @@ -366,7 +366,10 @@ pe_relocate(imgbase) image_section_header sect; image_base_reloc *relhdr; uint16_t rel, *sloc; - uint32_t base, delta, *lloc; + vm_offset_t base; + vm_size_t delta; + uint32_t *lloc; + uint64_t *qloc; int i, count; vm_offset_t txt; @@ -403,6 +406,13 @@ pe_relocate(imgbase) relhdr->ibr_vaddr + IMR_RELOFFSET(rel)); *sloc += (delta & 0xFFFF); break; + case IMAGE_REL_BASED_DIR64: + qloc = (uint64_t *)pe_translate_addr(imgbase, + relhdr->ibr_vaddr + IMR_RELOFFSET(rel)); + *qloc = pe_translate_addr(imgbase, + (*qloc - base)); + break; + default: printf ("[%d]reloc type: %d\n",i, IMR_RELTYPE(rel)); @@ -561,11 +571,19 @@ pe_functbl_match(functbl, name) while (p->ipt_name != NULL) { if (!strcmp(p->ipt_name, name)) - return((vm_offset_t)p->ipt_func); + return((vm_offset_t)p->ipt_wrap); p++; } printf ("no match for %s\n", name); - return((vm_offset_t)p->ipt_func); + + /* + * Return the wrapper pointer for this routine. + * For x86, this is the same as the funcptr. + * For amd64, this points to a wrapper routine + * that does calling convention translation and + * then invokes the underlying routine. + */ + return((vm_offset_t)p->ipt_wrap); } /* diff --git a/sys/compat/ndis/winx64_wrap.S b/sys/compat/ndis/winx64_wrap.S new file mode 100644 index 00000000000..a9428e1b5dd --- /dev/null +++ b/sys/compat/ndis/winx64_wrap.S @@ -0,0 +1,191 @@ +/*- + * Copyright (c) 2005 + * Bill Paul . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Bill Paul. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The x86_64 callback routines were written and graciously submitted + * by Ville-Pertti Keinonen . + * + * $FreeBSD$ + */ + +#include + +/* + * Wrapper for handling up to 16 arguments. We can't really + * know how many arguments the caller will pass us. I'm taking an + * educated guess that we'll never get over 16. Handling too + * few arguments is bad. Handling too many is inefficient, but + * not fatal. If someone can think of a way to handle an arbitrary + * number of arguments with more elegant code, freel free to let + * me know. + * + * Standard amd64 calling conventions specify the following registers + * to be used for passing the first 6 arguments: + * + * %rdi, %rsi, %rdx, %rcx, %r8, %r9 + * + * Further arguments are passed on the stack (the 7th argument is + * located immediately after the return address). + * + * Windows x86_64 calling conventions only pass the first 4 + * arguments in registers: + * + * %rcx, %rdx, %r8, %r9 + * + * Even when arguments are passed in registers, the stack must have + * space reserved for those arguments. Thus the 5th argument (the + * first non-register argument) is placed 32 bytes after the return + * address. Additionally, %rdi and %rsi must be preserved. (These + * two registers are not scratch registers in the standard convention.) + * + * Note that in this template, we load a contrived 64 bit address into + * %r11 to represent our jump address. This is to guarantee that the + * assembler leaves enough room to patch in an absolute 64-bit address + * later. The idea behind this code is that we want to avoid having to + * manually create all the wrapper functions at compile time with + * a bunch of macros. This is doable, but a) messy and b) requires + * us to maintain two separate tables (one for the UNIX function + * pointers and another with the wrappers). This means I'd have to + * update two different tables each time I added a function. + * + * To avoid this, we create the wrappers at runtime instead. The + * image patch tables now contain two pointers: one two the normal + * routine, and a blank one for the wrapper. To construct a wrapper, + * we allocate some memory and copy the template function into it, + * then patch the function pointer for the routine we want to wrap + * into the newly created wrapper. The subr_pe module can then + * simply patch the wrapper routine into the jump table into the + * windows image. As a bonus, the wrapper pointer not only serves + * as the wrapper entry point address, it's also a data pointer + * that we can pass to free() later when we unload the module. + */ + + .globl x86_64_wrap_call + .globl x86_64_wrap_end + +ENTRY(x86_64_wrap) +x86_64_wrap: + subq $96,%rsp + mov %rsi,96-8(%rsp) + mov %rdi,96-16(%rsp) + mov %rcx,%rdi + mov %rdx,%rsi + mov %r8,%rdx + mov %r9,%rcx + mov 96+40(%rsp),%r8 + mov 96+48(%rsp),%r9 + mov 96+56(%rsp),%rax + mov %rax,(%rsp) + mov 96+64(%rsp),%rax + mov %rax,8(%rsp) + mov 96+72(%rsp),%rax + mov %rax,16(%rsp) + mov 96+80(%rsp),%rax + mov %rax,24(%rsp) + mov 96+88(%rsp),%rax + mov %rax,32(%rsp) + mov 96+96(%rsp),%rax + mov %rax,40(%rsp) + mov 96+104(%rsp),%rax + mov %rax,48(%rsp) + mov 96+112(%rsp),%rax + mov %rax,56(%rsp) + mov 96+120(%rsp),%rax + mov %rax,64(%rsp) + mov 96+128(%rsp),%rax + mov %rax,72(%rsp) + xor %rax,%rax +x86_64_wrap_call: + mov $0xFF00FF00FF00FF00,%r11 + callq *%r11 + mov 96-16(%rsp),%rdi + mov 96-8(%rsp),%rsi + addq $96,%rsp + ret +x86_64_wrap_end: + +/* + * Functions for invoking x86_64 callbacks. In each case, the first + * argument is a pointer to the function. + */ + +ENTRY(x86_64_call1) + subq $8,%rsp + mov %rsi,%rcx + call *%rdi + addq $8,%rsp + ret + +ENTRY(x86_64_call2) + subq $24,%rsp + mov %rsi,%rcx + /* %rdx is already correct */ + call *%rdi + addq $24,%rsp + ret + +ENTRY(x86_64_call3) + subq $24,%rsp + mov %rcx,%r8 + mov %rsi,%rcx + call *%rdi + addq $24,%rsp + ret + +ENTRY(x86_64_call4) + subq $40,%rsp + mov %r8,%r9 + mov %rcx,%r8 + mov %rsi,%rcx + call *%rdi + addq $40,%rsp + ret + +ENTRY(x86_64_call5) + subq $40,%rsp + mov %r9,32(%rsp) + mov %r8,%r9 + mov %rcx,%r8 + mov %rsi,%rcx + call *%rdi + addq $40,%rsp + ret + +ENTRY(x86_64_call6) + subq $56,%rsp + mov 56+8(%rsp),%rax + mov %r9,32(%rsp) + mov %rax,40(%rsp) + mov %r8,%r9 + mov %rcx,%r8 + mov %rsi,%rcx + call *%rdi + addq $56,%rsp + ret diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 685cab1cbbb..0d683988c7c 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -125,6 +125,10 @@ dev/fb/fb.c optional fb dev/fb/fb.c optional vga dev/fb/splash.c optional splash dev/fb/vga.c optional vga +dev/if_ndis/if_ndis.c optional ndis +dev/if_ndis/if_ndis_pccard.c optional ndis pccard +dev/if_ndis/if_ndis_pci.c optional ndis cardbus +dev/if_ndis/if_ndis_pci.c optional ndis pci dev/io/iodev.c optional io dev/fdc/fdc.c optional fdc dev/fdc/fdc_acpi.c optional fdc @@ -196,3 +200,13 @@ compat/linux/linux_stats.c optional compat_linux32 compat/linux/linux_sysctl.c optional compat_linux32 compat/linux/linux_uid16.c optional compat_linux32 compat/linux/linux_util.c optional compat_linux32 +# +# Windows NDIS driver support +# +compat/ndis/kern_ndis.c optional ndisapi pci +compat/ndis/kern_windrv.c optional ndisapi pci +compat/ndis/subr_hal.c optional ndisapi pci +compat/ndis/subr_ndis.c optional ndisapi pci +compat/ndis/subr_ntoskrnl.c optional ndisapi pci +compat/ndis/subr_pe.c optional ndisapi pci +compat/ndis/winx64_wrap.S optional ndisapi pci diff --git a/sys/conf/options.amd64 b/sys/conf/options.amd64 index 8da2f8949a5..7839541ce24 100644 --- a/sys/conf/options.amd64 +++ b/sys/conf/options.amd64 @@ -17,7 +17,7 @@ COMPAT_IA32 opt_compat.h COMPAT_LINUX32 opt_compat.h #COMPAT_SVR4 opt_dontuse.h #DEBUG_SVR4 opt_svr4.h -#NDISAPI opt_dontuse.h +NDISAPI opt_dontuse.h CLK_CALIBRATION_LOOP opt_clock.h CLK_USE_I8254_CALIBRATION opt_clock.h diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c index 9f94daff46d..836a844c74b 100644 --- a/sys/dev/if_ndis/if_ndis.c +++ b/sys/dev/if_ndis/if_ndis.c @@ -101,6 +101,13 @@ static __stdcall void ndis_linksts (ndis_handle, ndis_status, void *, uint32_t); static __stdcall void ndis_linksts_done (ndis_handle); +/* We need to wrap these functions for amd64. */ + +static funcptr ndis_txeof_wrap; +static funcptr ndis_rxeof_wrap; +static funcptr ndis_linksts_wrap; +static funcptr ndis_linksts_done_wrap; + static void ndis_intr (void *); static void ndis_intrtask (void *); static void ndis_tick (void *); @@ -151,14 +158,27 @@ ndisdrv_modevent(mod, cmd, arg) if (ndisdrv_loaded > 1) break; windrv_load(mod, (vm_offset_t)drv_data, 0); + windrv_wrap((funcptr)ndis_rxeof, &ndis_rxeof_wrap); + windrv_wrap((funcptr)ndis_txeof, &ndis_txeof_wrap); + windrv_wrap((funcptr)ndis_linksts, &ndis_linksts_wrap); + windrv_wrap((funcptr)ndis_linksts_done, + &ndis_linksts_done_wrap); break; case MOD_UNLOAD: ndisdrv_loaded--; if (ndisdrv_loaded > 0) break; windrv_unload(mod, (vm_offset_t)drv_data, 0); + windrv_unwrap(ndis_rxeof_wrap); + windrv_unwrap(ndis_txeof_wrap); + windrv_unwrap(ndis_linksts_wrap); + windrv_unwrap(ndis_linksts_done_wrap); break; case MOD_SHUTDOWN: + windrv_unwrap(ndis_rxeof_wrap); + windrv_unwrap(ndis_txeof_wrap); + windrv_unwrap(ndis_linksts_wrap); + windrv_unwrap(ndis_linksts_done_wrap); break; default: error = EINVAL; @@ -418,8 +438,6 @@ ndis_attach(dev) mtx_init(&sc->ndis_mtx, "ndis softc lock", MTX_NETWORK_LOCK, MTX_DEF); - mtx_init(&sc->ndis_intrmtx, - "ndis irq lock", MTX_NETWORK_LOCK, MTX_DEF); /* * Hook interrupt early, since calling the driver's @@ -476,8 +494,8 @@ ndis_attach(dev) ndis_convert_res(sc); /* Install our RX and TX interrupt handlers. */ - sc->ndis_block->nmb_senddone_func = ndis_txeof; - sc->ndis_block->nmb_pktind_func = ndis_rxeof; + sc->ndis_block->nmb_senddone_func = ndis_txeof_wrap; + sc->ndis_block->nmb_pktind_func = ndis_rxeof_wrap; /* Call driver's init routine. */ if (ndis_init_nic(sc)) { @@ -511,6 +529,18 @@ ndis_attach(dev) sc->ndis_txarray = malloc(sizeof(ndis_packet *) * sc->ndis_maxpkts, M_DEVBUF, M_NOWAIT|M_ZERO); + /* Allocate a pool of ndis_packets for TX encapsulation. */ + + NdisAllocatePacketPool(&i, &sc->ndis_txpool, + sc->ndis_maxpkts, PROTOCOL_RESERVED_SIZE_IN_PACKET); + + if (i != NDIS_STATUS_SUCCESS) { + sc->ndis_txpool = NULL; + device_printf(dev, "failed to allocate TX packet pool"); + error = ENOMEM; + goto fail; + } + sc->ndis_txpending = sc->ndis_maxpkts; sc->ndis_oidcnt = 0; @@ -748,8 +778,8 @@ nonettypes: } /* Override the status handler so we can detect link changes. */ - sc->ndis_block->nmb_status_func = ndis_linksts; - sc->ndis_block->nmb_statusdone_func = ndis_linksts_done; + sc->ndis_block->nmb_status_func = ndis_linksts_wrap; + sc->ndis_block->nmb_statusdone_func = ndis_linksts_done_wrap; fail: if (error) ndis_detach(dev); @@ -778,8 +808,6 @@ ndis_detach(dev) sc = device_get_softc(dev); KASSERT(mtx_initialized(&sc->ndis_mtx), ("ndis mutex not initialized")); - KASSERT(mtx_initialized(&sc->ndis_intrmtx), - ("ndis interrupt mutex not initialized")); NDIS_LOCK(sc); ifp = &sc->arpcom.ac_if; ifp->if_flags &= ~IFF_UP; @@ -822,6 +850,9 @@ ndis_detach(dev) if (!sc->ndis_80211) ifmedia_removeall(&sc->ifmedia); + if (sc->ndis_txpool != NULL) + NdisFreePacketPool(sc->ndis_txpool); + ndis_unload_driver(sc); /* Destroy the PDO for this device. */ @@ -839,7 +870,6 @@ ndis_detach(dev) #endif mtx_destroy(&sc->ndis_mtx); - mtx_destroy(&sc->ndis_intrmtx); return(0); } @@ -1083,9 +1113,8 @@ ndis_intrtask(arg) irql = KeRaiseIrql(DISPATCH_LEVEL); ndis_intrhand(sc); KeLowerIrql(irql); - mtx_lock(&sc->ndis_intrmtx); + ndis_enable_intr(sc); - mtx_unlock(&sc->ndis_intrmtx); return; } @@ -1098,21 +1127,24 @@ ndis_intr(arg) struct ifnet *ifp; int is_our_intr = 0; int call_isr = 0; + uint8_t irql; + ndis_miniport_interrupt *intr; sc = arg; ifp = &sc->arpcom.ac_if; + intr = sc->ndis_block->nmb_interrupt; if (sc->ndis_block->nmb_miniportadapterctx == NULL) return; - mtx_lock(&sc->ndis_intrmtx); + KeAcquireSpinLock(&intr->ni_dpccountlock, &irql); if (sc->ndis_block->nmb_interrupt->ni_isrreq == TRUE) ndis_isr(sc, &is_our_intr, &call_isr); else { ndis_disable_intr(sc); call_isr = 1; } - mtx_unlock(&sc->ndis_intrmtx); + KeReleaseSpinLock(&intr->ni_dpccountlock, irql); if ((is_our_intr || call_isr)) ndis_sched(ndis_intrtask, ifp->if_softc, NDIS_SWI); @@ -1258,7 +1290,7 @@ ndis_start(ifp) struct mbuf *m = NULL; ndis_packet **p0 = NULL, *p = NULL; ndis_tcpip_csum *csum; - int pcnt = 0; + int pcnt = 0, status; sc = ifp->if_softc; @@ -1280,7 +1312,11 @@ ndis_start(ifp) if (m == NULL) break; - sc->ndis_txarray[sc->ndis_txidx] = NULL; + NdisAllocatePacket(&status, + &sc->ndis_txarray[sc->ndis_txidx], sc->ndis_txpool); + + if (status != NDIS_STATUS_SUCCESS) + break; if (ndis_mtop(m, &sc->ndis_txarray[sc->ndis_txidx])) { #if __FreeBSD_version >= 502114 diff --git a/sys/dev/if_ndis/if_ndisvar.h b/sys/dev/if_ndis/if_ndisvar.h index 6736024a672..0936aaf7fc2 100644 --- a/sys/dev/if_ndis/if_ndisvar.h +++ b/sys/dev/if_ndis/if_ndisvar.h @@ -94,7 +94,6 @@ struct ndis_softc { struct resource_list ndis_rl; int ndis_rescnt; struct mtx ndis_mtx; - struct mtx ndis_intrmtx; device_t ndis_dev; int ndis_unit; ndis_miniport_block *ndis_block; @@ -107,6 +106,7 @@ struct ndis_softc { int ndis_txidx; int ndis_txpending; ndis_packet **ndis_txarray; + ndis_handle ndis_txpool; int ndis_sc; ndis_cfg *ndis_regvals; struct nch ndis_cfglist_head; @@ -130,7 +130,6 @@ struct ndis_softc { bus_dmamap_t *ndis_mmaps; bus_dmamap_t *ndis_tmaps; int ndis_mmapcnt; - device_object *ndis_pdo; }; #define NDIS_LOCK(_sc) mtx_lock(&(_sc)->ndis_mtx) diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 8b6a2ba95d4..a383bbe4df9 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -413,7 +413,7 @@ _io= io _ips= ips #_lnc= lnc _mly= mly -#_ndis= ndis +_ndis= ndis _safe= safe _scsi_low= scsi_low _smbfs= smbfs diff --git a/sys/modules/ndis/Makefile b/sys/modules/ndis/Makefile index 0090a45e03a..4c622dd2dcc 100644 --- a/sys/modules/ndis/Makefile +++ b/sys/modules/ndis/Makefile @@ -7,4 +7,8 @@ SRCS= subr_pe.c subr_ndis.c subr_hal.c subr_ntoskrnl.c kern_ndis.c SRCS+= kern_windrv.c SRCS+= opt_bdg.h device_if.h bus_if.h pci_if.h vnode_if.h +.if ${MACHINE_ARCH} == "amd64" +SRCS+= winx64_wrap.S +.endif + .include diff --git a/usr.sbin/ndiscvt/inf.c b/usr.sbin/ndiscvt/inf.c index de6c34227e9..e6389fc74df 100644 --- a/usr.sbin/ndiscvt/inf.c +++ b/usr.sbin/ndiscvt/inf.c @@ -61,7 +61,7 @@ static void dump_deviceids_pci (void); static void dump_deviceids_pcmcia (void); static void dump_pci_id (const char *); static void dump_pcmcia_id (const char *); -static void dump_regvals (void); +/*static*/ void dump_regvals (void); static void dump_paramreg (const struct section *, const struct reg *, int); @@ -246,7 +246,8 @@ dump_deviceids_pci() if (manf->vals[1] != NULL && (strcasecmp(manf->vals[1], "NT.5.1") == 0 || strcasecmp(manf->vals[1], "NTx86") == 0 || - strcasecmp(manf->vals[1], "NTx86.5.1") == 0)) { + strcasecmp(manf->vals[1], "NTx86.5.1") == 0 || + strcasecmp(manf->vals[1], "NTamd64") == 0)) { /* Handle Windows XP INF files. */ snprintf(xpsec, sizeof(xpsec), "%s.%s", manf->vals[0], manf->vals[1]); @@ -325,7 +326,8 @@ dump_deviceids_pcmcia() if (manf->vals[1] != NULL && (strcasecmp(manf->vals[1], "NT.5.1") == 0 || strcasecmp(manf->vals[1], "NTx86") == 0 || - strcasecmp(manf->vals[1], "NTx86.5.1") == 0)) { + strcasecmp(manf->vals[1], "NTx86.5.1") == 0 || + strcasecmp(manf->vals[1], "NTamd64") == 0)) { /* Handle Windows XP INF files. */ snprintf(xpsec, sizeof(xpsec), "%s.%s", manf->vals[0], manf->vals[1]); @@ -557,7 +559,7 @@ dump_paramreg(const struct section *s, const struct reg *r, int devidx) return; } -static void +/*static*/ void dump_regvals(void) { struct assign *manf, *dev; @@ -578,7 +580,8 @@ dump_regvals(void) if (manf->vals[1] != NULL && (strcasecmp(manf->vals[1], "NT.5.1") == 0 || strcasecmp(manf->vals[1], "NTx86") == 0 || - strcasecmp(manf->vals[1], "NTx86.5.1") == 0)) { + strcasecmp(manf->vals[1], "NTx86.5.1") == 0 || + strcasecmp(manf->vals[1], "NTamd64") == 0)) { is_winxp++; /* Handle Windows XP INF files. */ snprintf(sname, sizeof(sname), "%s.%s", @@ -600,9 +603,15 @@ retry: * Look for section names with .NT, unless * this is a WinXP .INF file. */ + if (is_winxp) { sprintf(sname, "%s.NTx86", assign->vals[0]); dev = find_assign(sname, "AddReg"); + if (dev == NULL) { + sprintf(sname, "%s.NT", + assign->vals[0]); + dev = find_assign(sname, "AddReg"); + } if (dev == NULL) dev = find_assign(assign->vals[0], "AddReg");