subr_ndis.c revision 123695
1/* 2 * Copyright (c) 2003 3 * Bill Paul <wpaul@windriver.com>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Bill Paul. 16 * 4. Neither the name of the author nor the names of any co-contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> 34__FBSDID("$FreeBSD: head/sys/compat/ndis/subr_ndis.c 123695 2003-12-21 00:00:08Z wpaul $"); 35 36/* 37 * This file implements a translation layer between the BSD networking 38 * infrasturcture and Windows(R) NDIS network driver modules. A Windows 39 * NDIS driver calls into several functions in the NDIS.SYS Windows 40 * kernel module and exports a table of functions designed to be called 41 * by the NDIS subsystem. Using the PE loader, we can patch our own 42 * versions of the NDIS routines into a given Windows driver module and 43 * convince the driver that it is in fact running on Windows. 44 * 45 * We provide a table of all our implemented NDIS routines which is patched 46 * into the driver object code. All our exported routines must use the 47 * _stdcall calling convention, since that's what the Windows object code 48 * expects. 49 */ 50 51 52#include <sys/param.h> 53#include <sys/types.h> 54#include <sys/errno.h> 55 56#include <sys/callout.h> 57#include <sys/kernel.h> 58#include <sys/systm.h> 59#include <sys/malloc.h> 60#include <sys/lock.h> 61#include <sys/mutex.h> 62#include <sys/socket.h> 63#include <sys/sysctl.h> 64#include <sys/timespec.h> 65 66#include <net/if.h> 67#include <net/if_arp.h> 68#include <net/ethernet.h> 69#include <net/if_dl.h> 70#include <net/if_media.h> 71 72#include <machine/bus_memio.h> 73#include <machine/bus_pio.h> 74#include <machine/bus.h> 75#include <machine/resource.h> 76 77#include <sys/bus.h> 78#include <sys/rman.h> 79 80#include <machine/stdarg.h> 81 82#include <net80211/ieee80211_var.h> 83#include <net80211/ieee80211_ioctl.h> 84 85#include <dev/pci/pcireg.h> 86#include <dev/pci/pcivar.h> 87 88#include <compat/ndis/pe_var.h> 89#include <compat/ndis/resource_var.h> 90#include <compat/ndis/ntoskrnl_var.h> 91#include <compat/ndis/ndis_var.h> 92#include <compat/ndis/cfg_var.h> 93#include <dev/if_ndis/if_ndisvar.h> 94 95#define __stdcall __attribute__((__stdcall__)) 96#define FUNC void(*)(void) 97 98static struct mtx ndis_interlock; 99static int ndis_inits = 0; 100 101__stdcall static void ndis_initwrap(ndis_handle, 102 ndis_driver_object *, void *, void *); 103__stdcall static ndis_status ndis_register_miniport(ndis_handle, 104 ndis_miniport_characteristics *, int); 105__stdcall static ndis_status ndis_malloc_withtag(void **, uint32_t, uint32_t); 106__stdcall static ndis_status ndis_malloc(void **, 107 uint32_t, uint32_t, ndis_physaddr); 108__stdcall static void ndis_free(void *, uint32_t, uint32_t); 109__stdcall static ndis_status ndis_setattr_ex(ndis_handle, ndis_handle, 110 uint32_t, uint32_t, ndis_interface_type); 111__stdcall static void ndis_open_cfg(ndis_status *, ndis_handle *, ndis_handle); 112__stdcall static void ndis_open_cfgbyidx(ndis_status *, ndis_handle, 113 uint32_t, ndis_unicode_string *, ndis_handle *); 114__stdcall static void ndis_open_cfgbyname(ndis_status *, ndis_handle, 115 ndis_unicode_string *, ndis_handle *); 116static ndis_status ndis_encode_parm(ndis_miniport_block *, 117 struct sysctl_oid *, ndis_parm_type, ndis_config_parm **); 118static ndis_status ndis_decode_parm(ndis_miniport_block *, 119 ndis_config_parm *, char *); 120__stdcall static void ndis_read_cfg(ndis_status *, ndis_config_parm **, 121 ndis_handle, ndis_unicode_string *, ndis_parm_type); 122__stdcall static void ndis_write_cfg(ndis_status *, ndis_handle, 123 ndis_unicode_string *, ndis_config_parm *); 124__stdcall static void ndis_close_cfg(ndis_handle); 125__stdcall static void ndis_create_lock(ndis_spin_lock *); 126__stdcall static void ndis_destroy_lock(ndis_spin_lock *); 127__stdcall static void ndis_lock(ndis_spin_lock *); 128__stdcall static void ndis_unlock(ndis_spin_lock *); 129__stdcall static uint32_t ndis_read_pci(ndis_handle, uint32_t, 130 uint32_t, void *, uint32_t); 131__stdcall static uint32_t ndis_write_pci(ndis_handle, uint32_t, 132 uint32_t, void *, uint32_t); 133static void ndis_syslog(ndis_handle, ndis_error_code, uint32_t, ...); 134static void ndis_map_cb(void *, bus_dma_segment_t *, int, int); 135__stdcall static void ndis_vtophys_load(ndis_handle, ndis_buffer *, 136 uint32_t, uint8_t, ndis_paddr_unit *, uint32_t *); 137__stdcall static void ndis_vtophys_unload(ndis_handle, ndis_buffer *, uint32_t); 138__stdcall static void ndis_create_timer(ndis_miniport_timer *, ndis_handle *, 139 ndis_timer_function, void *); 140static void ndis_timercall(void *); 141__stdcall static void ndis_set_timer(ndis_miniport_timer *, uint32_t); 142static void ndis_tick(void *); 143__stdcall static void ndis_set_periodic_timer(ndis_miniport_timer *, uint32_t); 144__stdcall static void ndis_cancel_timer(ndis_miniport_timer *, uint8_t *); 145__stdcall static void ndis_query_resources(ndis_status *, ndis_handle, 146 ndis_resource_list *, uint32_t *); 147__stdcall static ndis_status ndis_register_ioport(void **, 148 ndis_handle, uint32_t, uint32_t); 149__stdcall static void ndis_deregister_ioport(ndis_handle, 150 uint32_t, uint32_t, void *); 151__stdcall static void ndis_read_netaddr(ndis_status *, void **, 152 uint32_t *, ndis_handle); 153__stdcall static ndis_status ndis_alloc_mapreg(ndis_handle, 154 uint32_t, uint8_t, uint32_t, uint32_t); 155__stdcall static void ndis_free_mapreg(ndis_handle); 156static void ndis_mapshared_cb(void *, bus_dma_segment_t *, int, int); 157__stdcall static void ndis_alloc_sharedmem(ndis_handle, uint32_t, 158 uint8_t, void **, ndis_physaddr *); 159__stdcall static void ndis_alloc_sharedmem_async(ndis_handle, 160 uint32_t, uint8_t, void *); 161__stdcall static void ndis_free_sharedmem(ndis_handle, uint32_t, 162 uint8_t, void *, ndis_physaddr); 163__stdcall static ndis_status ndis_map_iospace(void **, ndis_handle, 164 ndis_physaddr, uint32_t); 165__stdcall static void ndis_unmap_iospace(ndis_handle, void *, uint32_t); 166__stdcall static uint32_t ndis_cachefill(void); 167__stdcall static uint32_t ndis_dma_align(ndis_handle); 168__stdcall static ndis_status ndis_init_sc_dma(ndis_handle, 169 uint8_t, uint32_t); 170__stdcall static void ndis_alloc_packetpool(ndis_status *, 171 ndis_handle *, uint32_t, uint32_t); 172__stdcall static void ndis_ex_alloc_packetpool(ndis_status *, 173 ndis_handle *, uint32_t, uint32_t, uint32_t); 174__stdcall static uint32_t ndis_packetpool_use(ndis_handle); 175__stdcall static void ndis_free_packetpool(ndis_handle); 176__stdcall static void ndis_alloc_packet(ndis_status *, 177 ndis_packet **, ndis_handle); 178__stdcall static void ndis_release_packet(ndis_packet *); 179__stdcall static void ndis_unchain_headbuf(ndis_packet *, ndis_buffer **); 180__stdcall static void ndis_alloc_bufpool(ndis_status *, 181 ndis_handle *, uint32_t); 182__stdcall static void ndis_free_bufpool(ndis_handle); 183__stdcall static void ndis_alloc_buf(ndis_status *, ndis_buffer **, 184 ndis_handle, void *, uint32_t); 185__stdcall static void ndis_release_buf(ndis_buffer *); 186__stdcall static void ndis_query_buf(ndis_buffer *, void **, uint32_t *); 187__stdcall static void ndis_query_buf_safe(ndis_buffer *, void **, 188 uint32_t *, uint32_t); 189__stdcall static void ndis_adjust_buflen(ndis_buffer *, int); 190__stdcall static uint32_t ndis_interlock_inc(uint32_t *); 191__stdcall static uint32_t ndis_interlock_dec(uint32_t *); 192__stdcall static void ndis_init_event(ndis_event *); 193__stdcall static void ndis_set_event(ndis_event *); 194__stdcall static void ndis_reset_event(ndis_event *); 195__stdcall static uint8_t ndis_wait_event(ndis_event *, uint32_t); 196__stdcall static ndis_status ndis_unicode2ansi(ndis_ansi_string *, 197 ndis_unicode_string *); 198__stdcall static ndis_status ndis_ansi2unicode(ndis_unicode_string *, 199 ndis_ansi_string *); 200__stdcall static ndis_status ndis_assign_pcirsrc(ndis_handle, 201 uint32_t, ndis_resource_list **); 202__stdcall static ndis_status ndis_register_intr(ndis_miniport_interrupt *, 203 ndis_handle, uint32_t, uint32_t, uint8_t, 204 uint8_t, ndis_interrupt_mode); 205__stdcall static void ndis_deregister_intr(ndis_miniport_interrupt *); 206__stdcall static void ndis_register_shutdown(ndis_handle, void *, 207 ndis_shutdown_handler); 208__stdcall static void ndis_deregister_shutdown(ndis_handle); 209__stdcall static uint32_t ndis_numpages(ndis_buffer *); 210__stdcall static void ndis_buf_physpages(ndis_buffer *, uint32_t *); 211__stdcall static void ndis_query_bufoffset(ndis_buffer *, 212 uint32_t *, uint32_t *); 213__stdcall static void ndis_sleep(uint32_t); 214__stdcall static uint32_t ndis_read_pccard_amem(ndis_handle, 215 uint32_t, void *, uint32_t); 216__stdcall static uint32_t ndis_write_pccard_amem(ndis_handle, 217 uint32_t, void *, uint32_t); 218__stdcall static ndis_list_entry *ndis_insert_head(ndis_list_entry *, 219 ndis_list_entry *, ndis_spin_lock *); 220__stdcall static ndis_list_entry *ndis_remove_head(ndis_list_entry *, 221 ndis_spin_lock *); 222__stdcall static ndis_list_entry *ndis_insert_tail(ndis_list_entry *, 223 ndis_list_entry *, ndis_spin_lock *); 224__stdcall static uint8_t ndis_sync_with_intr(ndis_miniport_interrupt *, 225 void *, void *); 226__stdcall static void ndis_time(uint64_t *); 227__stdcall static void ndis_init_string(ndis_unicode_string **, char *); 228__stdcall static void ndis_init_ansi_string(ndis_ansi_string *, char *); 229__stdcall static void ndis_free_string(ndis_unicode_string *); 230__stdcall static ndis_status ndis_remove_miniport(ndis_handle *); 231__stdcall static void ndis_termwrap(ndis_handle, void *); 232__stdcall static void ndis_get_devprop(ndis_handle, void *, void *, 233 void *, cm_resource_list *, cm_resource_list *); 234__stdcall static void dummy(void); 235 236 237int 238ndis_libinit() 239{ 240 if (ndis_inits) { 241 ndis_inits++; 242 return(0); 243 } 244 245 mtx_init(&ndis_interlock, "ndislock", MTX_NETWORK_LOCK, 246 MTX_DEF | MTX_RECURSE | MTX_DUPOK); 247 248 ndis_inits++; 249 return(0); 250} 251 252int 253ndis_libfini() 254{ 255 if (ndis_inits != 1) { 256 ndis_inits--; 257 return(0); 258 } 259 260 mtx_destroy(&ndis_interlock); 261 ndis_inits--; 262 263 return(0); 264} 265 266/* 267 * NDIS deals with strings in unicode format, so we have 268 * do deal with them that way too. For now, we only handle 269 * conversion between unicode and ASCII since that's all 270 * that device drivers care about. 271 */ 272 273int 274ndis_ascii_to_unicode(ascii, unicode) 275 char *ascii; 276 uint16_t **unicode; 277{ 278 uint16_t *ustr; 279 int i; 280 281 if (*unicode == NULL) 282 *unicode = malloc(strlen(ascii) * 2, M_DEVBUF, M_WAITOK); 283 284 if (*unicode == NULL) 285 return(ENOMEM); 286 ustr = *unicode; 287 for (i = 0; i < strlen(ascii); i++) { 288 *ustr = (uint16_t)ascii[i]; 289 ustr++; 290 } 291 292 return(0); 293} 294 295int 296ndis_unicode_to_ascii(unicode, ulen, ascii) 297 uint16_t *unicode; 298 int ulen; 299 char **ascii; 300{ 301 uint8_t *astr; 302 int i; 303 304 if (*ascii == NULL) 305 *ascii = malloc(ulen, M_DEVBUF, M_WAITOK); 306 307 if (*ascii == NULL) 308 return(ENOMEM); 309 astr = *ascii; 310 for (i = 0; i < ulen; i++) { 311 *astr = (uint8_t)unicode[i]; 312 astr++; 313 } 314 315 return(0); 316} 317 318__stdcall static void 319ndis_initwrap(wrapper, drv_obj, path, unused) 320 ndis_handle wrapper; 321 ndis_driver_object *drv_obj; 322 void *path; 323 void *unused; 324{ 325 ndis_driver_object **drv; 326 327 drv = wrapper; 328 *drv = drv_obj; 329 330 return; 331} 332 333__stdcall static void 334ndis_termwrap(handle, syspec) 335 ndis_handle handle; 336 void *syspec; 337{ 338 return; 339} 340 341__stdcall static ndis_status 342ndis_register_miniport(handle, characteristics, len) 343 ndis_handle handle; 344 ndis_miniport_characteristics *characteristics; 345 int len; 346{ 347 ndis_driver_object *drv; 348 349 drv = handle; 350 bcopy((char *)characteristics, (char *)&drv->ndo_chars, 351 sizeof(ndis_miniport_characteristics)); 352 return(NDIS_STATUS_SUCCESS); 353} 354 355__stdcall static ndis_status 356ndis_malloc_withtag(vaddr, len, tag) 357 void **vaddr; 358 uint32_t len; 359 uint32_t tag; 360{ 361 void *mem; 362 363 mem = malloc(len, M_DEVBUF, M_NOWAIT); 364 if (mem == NULL) 365 return(NDIS_STATUS_RESOURCES); 366 *vaddr = mem; 367 368 return(NDIS_STATUS_SUCCESS); 369} 370 371__stdcall static ndis_status 372ndis_malloc(vaddr, len, flags, highaddr) 373 void **vaddr; 374 uint32_t len; 375 uint32_t flags; 376 ndis_physaddr highaddr; 377{ 378 void *mem; 379 380 mem = malloc(len, M_DEVBUF, M_NOWAIT); 381 if (mem == NULL) 382 return(NDIS_STATUS_RESOURCES); 383 *vaddr = mem; 384 385 return(NDIS_STATUS_SUCCESS); 386} 387 388__stdcall static void 389ndis_free(vaddr, len, flags) 390 void *vaddr; 391 uint32_t len; 392 uint32_t flags; 393{ 394 if (len == 0) 395 return; 396 free(vaddr, M_DEVBUF); 397 return; 398} 399 400__stdcall static ndis_status 401ndis_setattr_ex(adapter_handle, adapter_ctx, hangsecs, 402 flags, iftype) 403 ndis_handle adapter_handle; 404 ndis_handle adapter_ctx; 405 uint32_t hangsecs; 406 uint32_t flags; 407 ndis_interface_type iftype; 408{ 409 ndis_miniport_block *block; 410 411 /* 412 * Save the adapter context, we need it for calling 413 * the driver's internal functions. 414 */ 415 block = (ndis_miniport_block *)adapter_handle; 416 block->nmb_miniportadapterctx = adapter_ctx; 417 block->nmb_checkforhangsecs = hangsecs; 418 419 return(NDIS_STATUS_SUCCESS); 420} 421 422__stdcall static void 423ndis_open_cfg(status, cfg, wrapctx) 424 ndis_status *status; 425 ndis_handle *cfg; 426 ndis_handle wrapctx; 427{ 428 *cfg = wrapctx; 429 *status = NDIS_STATUS_SUCCESS; 430 return; 431} 432 433__stdcall static void 434ndis_open_cfgbyname(status, cfg, subkey, subhandle) 435 ndis_status *status; 436 ndis_handle cfg; 437 ndis_unicode_string *subkey; 438 ndis_handle *subhandle; 439{ 440 *subhandle = cfg; 441 *status = NDIS_STATUS_SUCCESS; 442 return; 443} 444 445__stdcall static void 446ndis_open_cfgbyidx(status, cfg, idx, subkey, subhandle) 447 ndis_status *status; 448 ndis_handle cfg; 449 uint32_t idx; 450 ndis_unicode_string *subkey; 451 ndis_handle *subhandle; 452{ 453 *status = NDIS_STATUS_FAILURE; 454 return; 455} 456 457static ndis_status 458ndis_encode_parm(block, oid, type, parm) 459 ndis_miniport_block *block; 460 struct sysctl_oid *oid; 461 ndis_parm_type type; 462 ndis_config_parm **parm; 463{ 464 uint16_t *unicode; 465 ndis_unicode_string *ustr; 466 467 unicode = (uint16_t *)&block->nmb_dummybuf; 468 469 switch(type) { 470 case ndis_parm_string: 471 ndis_ascii_to_unicode((char *)oid->oid_arg1, &unicode); 472 (*parm)->ncp_type = ndis_parm_string; 473 ustr = &(*parm)->ncp_parmdata.ncp_stringdata; 474 ustr->nus_len = strlen((char *)oid->oid_arg1) * 2; 475 ustr->nus_buf = unicode; 476 break; 477 case ndis_parm_int: 478 (*parm)->ncp_type = ndis_parm_int; 479 (*parm)->ncp_parmdata.ncp_intdata = 480 strtol((char *)oid->oid_arg1, NULL, 10); 481 break; 482 case ndis_parm_hexint: 483 (*parm)->ncp_type = ndis_parm_hexint; 484 (*parm)->ncp_parmdata.ncp_intdata = 485 strtoul((char *)oid->oid_arg1, NULL, 16); 486 break; 487 default: 488 return(NDIS_STATUS_FAILURE); 489 break; 490 } 491 492 return(NDIS_STATUS_SUCCESS); 493} 494 495__stdcall static void 496ndis_read_cfg(status, parm, cfg, key, type) 497 ndis_status *status; 498 ndis_config_parm **parm; 499 ndis_handle cfg; 500 ndis_unicode_string *key; 501 ndis_parm_type type; 502{ 503 char *keystr = NULL; 504 uint16_t *unicode; 505 ndis_miniport_block *block; 506 struct ndis_softc *sc; 507 struct sysctl_oid *oidp; 508 struct sysctl_ctx_entry *e; 509 510 block = (ndis_miniport_block *)cfg; 511 sc = (struct ndis_softc *)block->nmb_ifp; 512 513 ndis_unicode_to_ascii(key->nus_buf, key->nus_len, &keystr); 514 515 *parm = &block->nmb_replyparm; 516 bzero((char *)&block->nmb_replyparm, sizeof(ndis_config_parm)); 517 unicode = (uint16_t *)&block->nmb_dummybuf; 518 519 /* 520 * See if registry key is already in a list of known keys 521 * included with the driver. 522 */ 523 TAILQ_FOREACH(e, &sc->ndis_ctx, link) { 524 oidp = e->entry; 525 if (strcmp(oidp->oid_name, keystr) == 0) { 526 if (strcmp((char *)oidp->oid_arg1, "UNSET") == 0) { 527 free(keystr, M_DEVBUF); 528 *status = NDIS_STATUS_FAILURE; 529 return; 530 } 531 *status = ndis_encode_parm(block, oidp, type, parm); 532 free(keystr, M_DEVBUF); 533 return; 534 } 535 } 536 537 /* 538 * If the key didn't match, add it to the list of dynamically 539 * created ones. Sometimes, drivers refer to registry keys 540 * that aren't documented in their .INF files. These keys 541 * are supposed to be created by some sort of utility or 542 * control panel snap-in that comes with the driver software. 543 * Sometimes it's useful to be able to manipulate these. 544 * If the driver requests the key in the form of a string, 545 * make its default value an empty string, otherwise default 546 * it to "0". 547 */ 548 549 if (type == ndis_parm_int || type == ndis_parm_hexint) 550 ndis_add_sysctl(sc, keystr, "(dynamic integer key)", 551 "UNSET", CTLFLAG_RW); 552 else 553 ndis_add_sysctl(sc, keystr, "(dynamic string key)", 554 "UNSET", CTLFLAG_RW); 555 556 free(keystr, M_DEVBUF); 557 *status = NDIS_STATUS_FAILURE; 558 return; 559} 560 561static ndis_status 562ndis_decode_parm(block, parm, val) 563 ndis_miniport_block *block; 564 ndis_config_parm *parm; 565 char *val; 566{ 567 uint16_t *unicode; 568 ndis_unicode_string *ustr; 569 570 unicode = (uint16_t *)&block->nmb_dummybuf; 571 572 switch(parm->ncp_type) { 573 case ndis_parm_string: 574 ustr = &parm->ncp_parmdata.ncp_stringdata; 575 ndis_unicode_to_ascii(ustr->nus_buf, ustr->nus_len, &val); 576 break; 577 case ndis_parm_int: 578 sprintf(val, "%ul", parm->ncp_parmdata.ncp_intdata); 579 break; 580 case ndis_parm_hexint: 581 sprintf(val, "%xu", parm->ncp_parmdata.ncp_intdata); 582 break; 583 default: 584 return(NDIS_STATUS_FAILURE); 585 break; 586 } 587 return(NDIS_STATUS_SUCCESS); 588} 589 590__stdcall static void 591ndis_write_cfg(status, cfg, key, parm) 592 ndis_status *status; 593 ndis_handle cfg; 594 ndis_unicode_string *key; 595 ndis_config_parm *parm; 596{ 597 char *keystr = NULL; 598 ndis_miniport_block *block; 599 struct ndis_softc *sc; 600 struct sysctl_oid *oidp; 601 struct sysctl_ctx_entry *e; 602 char val[256]; 603 604 block = (ndis_miniport_block *)cfg; 605 sc = (struct ndis_softc *)block->nmb_ifp; 606 607 ndis_unicode_to_ascii(key->nus_buf, key->nus_len, &keystr); 608 609 /* Decode the parameter into a string. */ 610 *status = ndis_decode_parm(block, parm, val); 611 if (*status != NDIS_STATUS_SUCCESS) { 612 free(keystr, M_DEVBUF); 613 return; 614 } 615 616 /* See if the key already exists. */ 617 618 TAILQ_FOREACH(e, &sc->ndis_ctx, link) { 619 oidp = e->entry; 620 if (strcmp(oidp->oid_name, keystr) == 0) { 621 /* Found it, set the value. */ 622 strcpy((char *)oidp->oid_arg1, val); 623 free(keystr, M_DEVBUF); 624 return; 625 } 626 } 627 628 /* Not found, add a new key with the specified value. */ 629 ndis_add_sysctl(sc, keystr, "(dynamically set key)", 630 val, CTLFLAG_RW); 631 632 free(keystr, M_DEVBUF); 633 *status = NDIS_STATUS_SUCCESS; 634 return; 635} 636 637__stdcall static void 638ndis_close_cfg(cfg) 639 ndis_handle cfg; 640{ 641 return; 642} 643 644__stdcall static void 645ndis_create_lock(lock) 646 ndis_spin_lock *lock; 647{ 648 struct mtx *mtx; 649 650 mtx = malloc(sizeof(struct mtx), M_DEVBUF, M_NOWAIT|M_ZERO); 651 if (mtx == NULL) 652 return; 653 mtx_init(mtx, "ndislock", "ndis spin lock", 654 MTX_DEF | MTX_RECURSE | MTX_DUPOK); 655 lock->nsl_spinlock = (ndis_kspin_lock)mtx; 656 657 return; 658} 659 660__stdcall static void 661ndis_destroy_lock(lock) 662 ndis_spin_lock *lock; 663{ 664 struct mtx *ndis_mtx; 665 666 ndis_mtx = (struct mtx *)lock->nsl_spinlock; 667 mtx_destroy(ndis_mtx); 668 free(ndis_mtx, M_DEVBUF); 669 670 return; 671} 672 673__stdcall static void 674ndis_lock(lock) 675 ndis_spin_lock *lock; 676{ 677 if (lock == NULL) 678 return; 679 mtx_lock((struct mtx *)lock->nsl_spinlock); 680 681 return; 682} 683 684__stdcall static void 685ndis_unlock(lock) 686 ndis_spin_lock *lock; 687{ 688 if (lock == NULL) 689 return; 690 mtx_unlock((struct mtx *)lock->nsl_spinlock); 691 692 return; 693} 694 695__stdcall static uint32_t 696ndis_read_pci(adapter, slot, offset, buf, len) 697 ndis_handle adapter; 698 uint32_t slot; 699 uint32_t offset; 700 void *buf; 701 uint32_t len; 702{ 703 ndis_miniport_block *block; 704 int i; 705 char *dest; 706 707 block = (ndis_miniport_block *)adapter; 708 dest = buf; 709 if (block == NULL || block->nmb_dev == NULL) 710 return(0); 711 712 for (i = 0; i < len; i++) 713 dest[i] = pci_read_config(block->nmb_dev, i + offset, 1); 714 715 return(len); 716} 717 718__stdcall static uint32_t 719ndis_write_pci(adapter, slot, offset, buf, len) 720 ndis_handle adapter; 721 uint32_t slot; 722 uint32_t offset; 723 void *buf; 724 uint32_t len; 725{ 726 ndis_miniport_block *block; 727 int i; 728 char *dest; 729 730 block = (ndis_miniport_block *)adapter; 731 dest = buf; 732 733 if (block == NULL || block->nmb_dev == NULL) 734 return(0); 735 736 for (i = 0; i < len; i++) 737 pci_write_config(block->nmb_dev, i + offset, dest[i], 1); 738 739 return(len); 740} 741 742/* 743 * The errorlog routine uses a variable argument list, so we 744 * have to declare it this way. 745 */ 746static void 747ndis_syslog(ndis_handle adapter, ndis_error_code code, 748 uint32_t numerrors, ...) 749{ 750 ndis_miniport_block *block; 751 va_list ap; 752 int i; 753 754 block = (ndis_miniport_block *)adapter; 755 756 printf ("NDIS ERROR: %x\n", code); 757 printf ("NDIS NUMERRORS: %x\n", numerrors); 758 759 va_start(ap, numerrors); 760 for (i = 0; i < numerrors; i++) 761 printf ("argptr: %p\n", va_arg(ap, void *)); 762 va_end(ap); 763 764 return; 765} 766 767static void 768ndis_map_cb(arg, segs, nseg, error) 769 void *arg; 770 bus_dma_segment_t *segs; 771 int nseg; 772 int error; 773{ 774 struct ndis_map_arg *ctx; 775 int i; 776 777 if (error) 778 return; 779 780 ctx = arg; 781 782 for (i = 0; i < nseg; i++) { 783 ctx->nma_fraglist[i].npu_physaddr.np_quad = segs[i].ds_addr; 784 ctx->nma_fraglist[i].npu_len = segs[i].ds_len; 785 } 786 787 ctx->nma_cnt = nseg; 788 789 return; 790} 791 792__stdcall static void 793ndis_vtophys_load(adapter, buf, mapreg, writedev, addrarray, arraysize) 794 ndis_handle adapter; 795 ndis_buffer *buf; 796 uint32_t mapreg; 797 uint8_t writedev; 798 ndis_paddr_unit *addrarray; 799 uint32_t *arraysize; 800{ 801 ndis_miniport_block *block; 802 struct ndis_softc *sc; 803 struct ndis_map_arg nma; 804 bus_dmamap_t map; 805 int error; 806 807 if (adapter == NULL) 808 return; 809 810 block = (ndis_miniport_block *)adapter; 811 sc = (struct ndis_softc *)(block->nmb_ifp); 812 813 if (mapreg > sc->ndis_mmapcnt) 814 return; 815 816 map = sc->ndis_mmaps[mapreg]; 817 nma.nma_fraglist = addrarray; 818 819 error = bus_dmamap_load(sc->ndis_mtag, map, 820 buf->nb_mappedsystemva, buf->nb_bytecount, ndis_map_cb, 821 (void *)&nma, BUS_DMA_NOWAIT); 822 823 if (error) 824 return; 825 826 bus_dmamap_sync(sc->ndis_mtag, map, 827 writedev ? BUS_DMASYNC_PREWRITE : BUS_DMASYNC_PREREAD); 828 829 *arraysize = nma.nma_cnt; 830 831 return; 832} 833 834__stdcall static void 835ndis_vtophys_unload(adapter, buf, mapreg) 836 ndis_handle adapter; 837 ndis_buffer *buf; 838 uint32_t mapreg; 839{ 840 ndis_miniport_block *block; 841 struct ndis_softc *sc; 842 bus_dmamap_t map; 843 844 if (adapter == NULL) 845 return; 846 847 block = (ndis_miniport_block *)adapter; 848 sc = (struct ndis_softc *)(block->nmb_ifp); 849 850 if (mapreg > sc->ndis_mmapcnt) 851 return; 852 853 map = sc->ndis_mmaps[mapreg]; 854 855 bus_dmamap_sync(sc->ndis_mtag, map, 856 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 857 858 bus_dmamap_unload(sc->ndis_mtag, map); 859 860 return; 861} 862 863__stdcall static void 864ndis_create_timer(timer, handle, func, ctx) 865 ndis_miniport_timer *timer; 866 ndis_handle *handle; 867 ndis_timer_function func; 868 void *ctx; 869{ 870 struct callout_handle *ch; 871 872 ch = (struct callout_handle *)&timer->nmt_dpc; 873 callout_handle_init(ch); 874 timer->nmt_timerfunc = func; 875 timer->nmt_timerctx = ctx; 876 877 return; 878} 879 880/* 881 * The driver's timer callout is __stdcall function, so we need this 882 * intermediate step. 883 */ 884 885static void 886ndis_timercall(arg) 887 void *arg; 888{ 889 ndis_miniport_timer *timer; 890 __stdcall ndis_timer_function timerfunc; 891 892 timer = arg; 893 894 timerfunc = timer->nmt_timerfunc; 895 timerfunc(NULL, timer->nmt_timerctx, NULL, NULL); 896 897 return; 898} 899 900/* 901 * Windows specifies timeouts in milliseconds. We specify timeouts 902 * in hz. Trying to compute a tenth of a second based on hz is tricky. 903 * so we approximate. Note that we abuse the dpc portion of the 904 * miniport timer structure to hold the UNIX callout handle. 905 */ 906__stdcall static void 907ndis_set_timer(timer, msecs) 908 ndis_miniport_timer *timer; 909 uint32_t msecs; 910{ 911 struct callout_handle *ch; 912 struct timeval tv; 913 914 tv.tv_sec = 0; 915 tv.tv_usec = msecs * 1000; 916 917 ch = (struct callout_handle *)&timer->nmt_dpc; 918 timer->nmt_dpc.nk_sysarg2 = ndis_timercall; 919 *ch = timeout((timeout_t *)timer->nmt_dpc.nk_sysarg2, (void *)timer, 920 tvtohz(&tv)); 921 922 return; 923} 924 925static void 926ndis_tick(arg) 927 void *arg; 928{ 929 ndis_miniport_timer *timer; 930 struct callout_handle *ch; 931 __stdcall ndis_timer_function timerfunc; 932 struct timeval tv; 933 934 timer = arg; 935 936 timerfunc = timer->nmt_timerfunc; 937 timerfunc(NULL, timer->nmt_timerctx, NULL, NULL); 938 939 /* Automatically reload timer. */ 940 941 tv.tv_sec = 0; 942 tv.tv_usec = timer->nmt_ktimer.nk_period * 1000; 943 ch = (struct callout_handle *)&timer->nmt_dpc; 944 timer->nmt_dpc.nk_sysarg2 = ndis_tick; 945 *ch = timeout((timeout_t *)timer->nmt_dpc.nk_sysarg2, timer, 946 tvtohz(&tv)); 947 948 return; 949} 950 951__stdcall static void 952ndis_set_periodic_timer(timer, msecs) 953 ndis_miniport_timer *timer; 954 uint32_t msecs; 955{ 956 struct callout_handle *ch; 957 struct timeval tv; 958 959 tv.tv_sec = 0; 960 tv.tv_usec = msecs * 1000; 961 962 timer->nmt_ktimer.nk_period = msecs; 963 ch = (struct callout_handle *)&timer->nmt_dpc; 964 timer->nmt_dpc.nk_sysarg2 = ndis_tick; 965 *ch = timeout((timeout_t *)timer->nmt_dpc.nk_sysarg2, timer, 966 tvtohz(&tv)); 967 968 return; 969} 970 971__stdcall static void 972ndis_cancel_timer(timer, cancelled) 973 ndis_miniport_timer *timer; 974 uint8_t *cancelled; 975{ 976 struct callout_handle *ch; 977 978 ch = (struct callout_handle *)&timer->nmt_dpc; 979 untimeout((timeout_t *)timer->nmt_dpc.nk_sysarg2, timer, *ch); 980 981 return; 982} 983 984__stdcall static void 985ndis_query_resources(status, adapter, list, buflen) 986 ndis_status *status; 987 ndis_handle adapter; 988 ndis_resource_list *list; 989 uint32_t *buflen; 990{ 991 ndis_miniport_block *block; 992 struct ndis_softc *sc; 993 994 block = (ndis_miniport_block *)adapter; 995 sc = (struct ndis_softc *)block->nmb_ifp; 996 997 *buflen = sizeof(ndis_resource_list) + 998 (sizeof(cm_partial_resource_desc) * (sc->ndis_rescnt - 1)); 999 1000 bcopy((char *)block->nmb_rlist, (char *)list, *buflen); 1001 *status = NDIS_STATUS_SUCCESS; 1002 return; 1003} 1004 1005__stdcall static ndis_status 1006ndis_register_ioport(offset, adapter, port, numports) 1007 void **offset; 1008 ndis_handle adapter; 1009 uint32_t port; 1010 uint32_t numports; 1011{ 1012 struct ndis_miniport_block *block; 1013 struct ndis_softc *sc; 1014 1015 if (adapter == NULL) 1016 return(NDIS_STATUS_FAILURE); 1017 1018 block = (ndis_miniport_block *)adapter; 1019 sc = (struct ndis_softc *)(block->nmb_ifp); 1020 1021 if (sc->ndis_res_io == NULL) 1022 return(NDIS_STATUS_FAILURE); 1023 1024 if (rman_get_size(sc->ndis_res_io) != numports) 1025 return(NDIS_STATUS_INVALID_LENGTH); 1026 1027 *offset = (void *)rman_get_start(sc->ndis_res_io); 1028 1029 return(NDIS_STATUS_SUCCESS); 1030} 1031 1032__stdcall static void 1033ndis_deregister_ioport(adapter, port, numports, offset) 1034 ndis_handle adapter; 1035 uint32_t port; 1036 uint32_t numports; 1037 void *offset; 1038{ 1039 return; 1040} 1041 1042__stdcall static void 1043ndis_read_netaddr(status, addr, addrlen, adapter) 1044 ndis_status *status; 1045 void **addr; 1046 uint32_t *addrlen; 1047 ndis_handle adapter; 1048{ 1049 struct ndis_softc *sc; 1050 ndis_miniport_block *block; 1051 uint8_t empty[] = { 0, 0, 0, 0, 0, 0 }; 1052 1053 block = (ndis_miniport_block *)adapter; 1054 sc = (struct ndis_softc *)block->nmb_ifp; 1055 1056 if (bcmp(sc->arpcom.ac_enaddr, empty, ETHER_ADDR_LEN) == 0) 1057 *status = NDIS_STATUS_FAILURE; 1058 else { 1059 *addr = sc->arpcom.ac_enaddr; 1060 *addrlen = ETHER_ADDR_LEN; 1061 *status = NDIS_STATUS_SUCCESS; 1062 } 1063 1064 return; 1065} 1066 1067__stdcall static ndis_status 1068ndis_alloc_mapreg(adapter, dmachannel, dmasize, physmapneeded, maxmap) 1069 ndis_handle adapter; 1070 uint32_t dmachannel; 1071 uint8_t dmasize; 1072 uint32_t physmapneeded; 1073 uint32_t maxmap; 1074{ 1075 struct ndis_softc *sc; 1076 ndis_miniport_block *block; 1077 int error, i, nseg = NDIS_MAXSEG; 1078 1079 block = (ndis_miniport_block *)adapter; 1080 sc = (struct ndis_softc *)block->nmb_ifp; 1081 1082 sc->ndis_mmaps = malloc(sizeof(bus_dmamap_t) * physmapneeded, 1083 M_DEVBUF, M_NOWAIT|M_ZERO); 1084 1085 if (sc->ndis_mmaps == NULL) 1086 return(NDIS_STATUS_RESOURCES); 1087 1088 error = bus_dma_tag_create(sc->ndis_parent_tag, ETHER_ALIGN, 0, 1089 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, 1090 NULL, maxmap * nseg, nseg, maxmap, BUS_DMA_ALLOCNOW, 1091 NULL, NULL, &sc->ndis_mtag); 1092 1093 if (error) { 1094 free(sc->ndis_mmaps, M_DEVBUF); 1095 return(NDIS_STATUS_RESOURCES); 1096 } 1097 1098 for (i = 0; i < physmapneeded; i++) 1099 bus_dmamap_create(sc->ndis_mtag, 0, &sc->ndis_mmaps[i]); 1100 1101 sc->ndis_mmapcnt = physmapneeded; 1102 1103 return(NDIS_STATUS_SUCCESS); 1104} 1105 1106__stdcall static void 1107ndis_free_mapreg(adapter) 1108 ndis_handle adapter; 1109{ 1110 struct ndis_softc *sc; 1111 ndis_miniport_block *block; 1112 int i; 1113 1114 block = (ndis_miniport_block *)adapter; 1115 sc = (struct ndis_softc *)block->nmb_ifp; 1116 1117 for (i = 0; i < sc->ndis_mmapcnt; i++) 1118 bus_dmamap_destroy(sc->ndis_mtag, sc->ndis_mmaps[i]); 1119 1120 free(sc->ndis_mmaps, M_DEVBUF); 1121 1122 bus_dma_tag_destroy(sc->ndis_mtag); 1123 1124 return; 1125} 1126 1127static void 1128ndis_mapshared_cb(arg, segs, nseg, error) 1129 void *arg; 1130 bus_dma_segment_t *segs; 1131 int nseg; 1132 int error; 1133{ 1134 ndis_physaddr *p; 1135 1136 if (error || nseg > 1) 1137 return; 1138 1139 p = arg; 1140 1141 p->np_quad = segs[0].ds_addr; 1142 1143 return; 1144} 1145 1146/* 1147 * This maps to bus_dmamem_alloc(). 1148 */ 1149__stdcall static void 1150ndis_alloc_sharedmem(adapter, len, cached, vaddr, paddr) 1151 ndis_handle adapter; 1152 uint32_t len; 1153 uint8_t cached; 1154 void **vaddr; 1155 ndis_physaddr *paddr; 1156{ 1157 ndis_miniport_block *block; 1158 struct ndis_softc *sc; 1159 struct ndis_shmem *sh; 1160 int error; 1161 1162 if (adapter == NULL) 1163 return; 1164 1165 block = (ndis_miniport_block *)adapter; 1166 sc = (struct ndis_softc *)(block->nmb_ifp); 1167 1168 sh = malloc(sizeof(struct ndis_shmem), M_DEVBUF, M_NOWAIT|M_ZERO); 1169 if (sh == NULL) 1170 return; 1171 1172 error = bus_dma_tag_create(sc->ndis_parent_tag, 64, 1173 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, 1174 NULL, len, 1, len, BUS_DMA_ALLOCNOW, NULL, NULL, 1175 &sh->ndis_stag); 1176 1177 if (error) { 1178 free(sh, M_DEVBUF); 1179 return; 1180 } 1181 1182 error = bus_dmamem_alloc(sh->ndis_stag, vaddr, 1183 BUS_DMA_NOWAIT | BUS_DMA_ZERO, &sh->ndis_smap); 1184 1185 if (error) { 1186 bus_dma_tag_destroy(sh->ndis_stag); 1187 free(sh, M_DEVBUF); 1188 return; 1189 } 1190 1191 error = bus_dmamap_load(sh->ndis_stag, sh->ndis_smap, *vaddr, 1192 len, ndis_mapshared_cb, (void *)paddr, BUS_DMA_NOWAIT); 1193 1194 if (error) { 1195 bus_dmamem_free(sh->ndis_stag, *vaddr, sh->ndis_smap); 1196 bus_dma_tag_destroy(sh->ndis_stag); 1197 free(sh, M_DEVBUF); 1198 return; 1199 } 1200 1201 sh->ndis_saddr = *vaddr; 1202 sh->ndis_next = sc->ndis_shlist; 1203 sc->ndis_shlist = sh; 1204 1205 return; 1206} 1207 1208__stdcall static void 1209ndis_alloc_sharedmem_async(adapter, len, cached, ctx) 1210 ndis_handle adapter; 1211 uint32_t len; 1212 uint8_t cached; 1213 void *ctx; 1214{ 1215 ndis_miniport_block *block; 1216 struct ndis_softc *sc; 1217 void *vaddr; 1218 ndis_physaddr paddr; 1219 __stdcall ndis_allocdone_handler donefunc; 1220 1221 if (adapter == NULL) 1222 return; 1223 1224 block = (ndis_miniport_block *)adapter; 1225 sc = (struct ndis_softc *)(block->nmb_ifp); 1226 donefunc = sc->ndis_chars.nmc_allocate_complete_func; 1227 1228 ndis_alloc_sharedmem(adapter, len, cached, &vaddr, &paddr); 1229 donefunc(adapter, vaddr, &paddr, len, ctx); 1230 1231 return; 1232} 1233 1234__stdcall static void 1235ndis_free_sharedmem(adapter, len, cached, vaddr, paddr) 1236 ndis_handle adapter; 1237 uint32_t len; 1238 uint8_t cached; 1239 void *vaddr; 1240 ndis_physaddr paddr; 1241{ 1242 ndis_miniport_block *block; 1243 struct ndis_softc *sc; 1244 struct ndis_shmem *sh, *prev; 1245 1246 if (vaddr == NULL || adapter == NULL) 1247 return; 1248 1249 block = (ndis_miniport_block *)adapter; 1250 sc = (struct ndis_softc *)(block->nmb_ifp); 1251 sh = prev = sc->ndis_shlist; 1252 1253 while (sh) { 1254 if (sh->ndis_saddr == vaddr) 1255 break; 1256 prev = sh; 1257 sh = sh->ndis_next; 1258 } 1259 1260 bus_dmamap_unload(sh->ndis_stag, sh->ndis_smap); 1261 bus_dmamem_free(sh->ndis_stag, vaddr, sh->ndis_smap); 1262 bus_dma_tag_destroy(sh->ndis_stag); 1263 1264 if (sh == sc->ndis_shlist) 1265 sc->ndis_shlist = sh->ndis_next; 1266 else 1267 prev->ndis_next = sh->ndis_next; 1268 1269 free(sh, M_DEVBUF); 1270 1271 return; 1272} 1273 1274__stdcall static ndis_status 1275ndis_map_iospace(vaddr, adapter, paddr, len) 1276 void **vaddr; 1277 ndis_handle adapter; 1278 ndis_physaddr paddr; 1279 uint32_t len; 1280{ 1281 ndis_miniport_block *block; 1282 struct ndis_softc *sc; 1283 1284 if (adapter == NULL) 1285 return(NDIS_STATUS_FAILURE); 1286 1287 block = (ndis_miniport_block *)adapter; 1288 sc = (struct ndis_softc *)(block->nmb_ifp); 1289 1290 if (sc->ndis_res_mem == NULL) 1291 return(NDIS_STATUS_FAILURE); 1292 1293 *vaddr = (void *)rman_get_virtual(sc->ndis_res_mem); 1294 1295 return(NDIS_STATUS_SUCCESS); 1296} 1297 1298__stdcall static void 1299ndis_unmap_iospace(adapter, vaddr, len) 1300 ndis_handle adapter; 1301 void *vaddr; 1302 uint32_t len; 1303{ 1304 return; 1305} 1306 1307__stdcall static uint32_t 1308ndis_cachefill(void) 1309{ 1310 return(128); 1311} 1312 1313__stdcall static uint32_t 1314ndis_dma_align(handle) 1315 ndis_handle handle; 1316{ 1317 return(128); 1318} 1319 1320/* 1321 * NDIS has two methods for dealing with NICs that support DMA. 1322 * One is to just pass packets to the driver and let it call 1323 * NdisMStartBufferPhysicalMapping() to map each buffer in the packet 1324 * all by itself, and the other is to let the NDIS library handle the 1325 * buffer mapping internally, and hand the driver an already populated 1326 * scatter/gather fragment list. If the driver calls 1327 * NdisMInitializeScatterGatherDma(), it wants to use the latter 1328 * method. 1329 */ 1330 1331__stdcall static ndis_status 1332ndis_init_sc_dma(adapter, is64, maxphysmap) 1333 ndis_handle adapter; 1334 uint8_t is64; 1335 uint32_t maxphysmap; 1336{ 1337 struct ndis_softc *sc; 1338 ndis_miniport_block *block; 1339 int error; 1340 1341 if (adapter == NULL) 1342 return(NDIS_STATUS_FAILURE); 1343 block = (ndis_miniport_block *)adapter; 1344 sc = (struct ndis_softc *)block->nmb_ifp; 1345 1346 /* Don't do this twice. */ 1347 if (sc->ndis_sc == 1) 1348 return(NDIS_STATUS_SUCCESS); 1349 1350 error = bus_dma_tag_create(sc->ndis_parent_tag, ETHER_ALIGN, 0, 1351 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, 1352 MCLBYTES * NDIS_MAXSEG, NDIS_MAXSEG, MCLBYTES, BUS_DMA_ALLOCNOW, 1353 NULL, NULL, &sc->ndis_ttag); 1354 1355 sc->ndis_sc = 1; 1356 1357 return(NDIS_STATUS_SUCCESS); 1358} 1359 1360__stdcall static void 1361ndis_alloc_packetpool(status, pool, descnum, protrsvdlen) 1362 ndis_status *status; 1363 ndis_handle *pool; 1364 uint32_t descnum; 1365 uint32_t protrsvdlen; 1366{ 1367 ndis_packet *cur; 1368 int i; 1369 1370 *pool = malloc(sizeof(ndis_packet) * (descnum + 1), 1371 M_DEVBUF, M_NOWAIT|M_ZERO); 1372 1373 if (pool == NULL) { 1374 *status = NDIS_STATUS_RESOURCES; 1375 return; 1376 } 1377 1378 cur = (ndis_packet *)*pool; 1379 cur->np_private.npp_flags = 0x1; /* mark the head of the list */ 1380 for (i = 0; i < descnum; i++) { 1381 cur->np_private.npp_head = (ndis_handle)(cur + 1); 1382 cur++; 1383 } 1384 1385 *status = NDIS_STATUS_SUCCESS; 1386 return; 1387} 1388 1389__stdcall static void 1390ndis_ex_alloc_packetpool(status, pool, descnum, oflowdescnum, protrsvdlen) 1391 ndis_status *status; 1392 ndis_handle *pool; 1393 uint32_t descnum; 1394 uint32_t oflowdescnum; 1395 uint32_t protrsvdlen; 1396{ 1397 return(ndis_alloc_packetpool(status, pool, 1398 descnum + oflowdescnum, protrsvdlen)); 1399} 1400 1401__stdcall static uint32_t 1402ndis_packetpool_use(pool) 1403 ndis_handle pool; 1404{ 1405 ndis_packet *head; 1406 1407 head = (ndis_packet *)pool; 1408 1409 return(head->np_private.npp_count); 1410} 1411 1412__stdcall static void 1413ndis_free_packetpool(pool) 1414 ndis_handle pool; 1415{ 1416 free(pool, M_DEVBUF); 1417 return; 1418} 1419 1420__stdcall static void 1421ndis_alloc_packet(status, packet, pool) 1422 ndis_status *status; 1423 ndis_packet **packet; 1424 ndis_handle pool; 1425{ 1426 ndis_packet *head, *pkt; 1427 1428 head = (ndis_packet *)pool; 1429 1430 if (head->np_private.npp_flags != 0x1) { 1431 *status = NDIS_STATUS_FAILURE; 1432 return; 1433 } 1434 1435 pkt = (ndis_packet *)head->np_private.npp_head; 1436 1437 if (pkt == NULL) { 1438 *status = NDIS_STATUS_RESOURCES; 1439 return; 1440 } 1441 1442 head->np_private.npp_head = pkt->np_private.npp_head; 1443 1444 pkt->np_private.npp_head = pkt->np_private.npp_tail = NULL; 1445 /* Save pointer to the pool. */ 1446 pkt->np_private.npp_pool = head; 1447 1448 /* Set the oob offset pointer. Lots of things expect this. */ 1449 pkt->np_private.npp_packetooboffset = 1450 offsetof(ndis_packet, np_oob); 1451 1452 *packet = pkt; 1453 1454 head->np_private.npp_count++; 1455 *status = NDIS_STATUS_SUCCESS; 1456 return; 1457} 1458 1459__stdcall static void 1460ndis_release_packet(packet) 1461 ndis_packet *packet; 1462{ 1463 ndis_packet *head; 1464 1465 if (packet == NULL || packet->np_private.npp_pool == NULL) 1466 return; 1467 1468 head = packet->np_private.npp_pool; 1469 if (head->np_private.npp_flags != 0x1) 1470 return; 1471 1472 packet->np_private.npp_head = head->np_private.npp_head; 1473 head->np_private.npp_head = (ndis_buffer *)packet; 1474 head->np_private.npp_count--; 1475 1476 return; 1477} 1478 1479__stdcall static void 1480ndis_unchain_headbuf(packet, buf) 1481 ndis_packet *packet; 1482 ndis_buffer **buf; 1483{ 1484 ndis_packet_private *priv; 1485 1486 if (packet == NULL || buf == NULL) 1487 return; 1488 1489 priv = &packet->np_private; 1490 1491 priv->npp_validcounts = FALSE; 1492 1493 if (priv->npp_head == priv->npp_tail) { 1494 *buf = priv->npp_head; 1495 priv->npp_head = priv->npp_tail = NULL; 1496 } else { 1497 *buf = priv->npp_head; 1498 priv->npp_head = (*buf)->nb_next; 1499 } 1500 1501 return; 1502} 1503 1504/* 1505 * The NDIS "buffer" manipulation functions are somewhat misnamed. 1506 * They don't really allocate buffers: they allocate buffer mappings. 1507 * The idea is you reserve a chunk of DMA-able memory using 1508 * NdisMAllocateSharedMemory() and then use NdisAllocateBuffer() 1509 * to obtain the virtual address of the DMA-able region. 1510 * ndis_alloc_bufpool() is analagous to bus_dma_tag_create(). 1511 */ 1512 1513__stdcall static void 1514ndis_alloc_bufpool(status, pool, descnum) 1515 ndis_status *status; 1516 ndis_handle *pool; 1517 uint32_t descnum; 1518{ 1519 ndis_buffer *cur; 1520 int i; 1521 1522 *pool = malloc(sizeof(ndis_buffer) * (descnum + 1), 1523 M_DEVBUF, M_NOWAIT|M_ZERO); 1524 1525 if (pool == NULL) { 1526 *status = NDIS_STATUS_RESOURCES; 1527 return; 1528 } 1529 1530 cur = (ndis_buffer *)*pool; 1531 cur->nb_flags = 0x1; /* mark the head of the list */ 1532 for (i = 0; i < descnum; i++) { 1533 cur->nb_next = cur + 1; 1534 cur++; 1535 } 1536 1537 *status = NDIS_STATUS_SUCCESS; 1538 return; 1539} 1540 1541__stdcall static void 1542ndis_free_bufpool(pool) 1543 ndis_handle pool; 1544{ 1545 free(pool, M_DEVBUF); 1546 return; 1547} 1548 1549/* 1550 * This maps to a bus_dmamap_create() and bus_dmamap_load(). 1551 */ 1552__stdcall static void 1553ndis_alloc_buf(status, buffer, pool, vaddr, len) 1554 ndis_status *status; 1555 ndis_buffer **buffer; 1556 ndis_handle pool; 1557 void *vaddr; 1558 uint32_t len; 1559{ 1560 ndis_buffer *head, *buf; 1561 1562 head = (ndis_buffer *)pool; 1563 if (head->nb_flags != 0x1) { 1564 *status = NDIS_STATUS_FAILURE; 1565 return; 1566 } 1567 1568 buf = head->nb_next; 1569 1570 if (buf == NULL) { 1571 *status = NDIS_STATUS_RESOURCES; 1572 return; 1573 } 1574 1575 head->nb_next = buf->nb_next; 1576 1577 /* Save pointer to the pool. */ 1578 buf->nb_process = head; 1579 1580 buf->nb_mappedsystemva = vaddr; 1581 buf->nb_size = len; 1582 buf->nb_next = NULL; 1583 1584 *buffer = buf; 1585 1586 *status = NDIS_STATUS_SUCCESS; 1587 return; 1588} 1589 1590__stdcall static void 1591ndis_release_buf(buf) 1592 ndis_buffer *buf; 1593{ 1594 ndis_buffer *head; 1595 1596 if (buf == NULL || buf->nb_process == NULL) 1597 return; 1598 1599 head = buf->nb_process; 1600 1601 if (head->nb_flags != 0x1) 1602 return; 1603 1604 buf->nb_next = head->nb_next; 1605 head->nb_next = buf; 1606 1607 return; 1608} 1609 1610/* Get the virtual address and length of a buffer */ 1611 1612__stdcall static void 1613ndis_query_buf(buf, vaddr, len) 1614 ndis_buffer *buf; 1615 void **vaddr; 1616 uint32_t *len; 1617{ 1618 *vaddr = buf->nb_mappedsystemva; 1619 *len = buf->nb_bytecount; 1620 1621 return; 1622} 1623 1624/* Same as above -- we don't care about the priority. */ 1625 1626__stdcall static void 1627ndis_query_buf_safe(buf, vaddr, len, prio) 1628 ndis_buffer *buf; 1629 void **vaddr; 1630 uint32_t *len; 1631 uint32_t prio; 1632{ 1633 *vaddr = buf->nb_mappedsystemva; 1634 *len = buf->nb_bytecount; 1635 1636 return; 1637} 1638 1639__stdcall static void 1640ndis_adjust_buflen(buf, len) 1641 ndis_buffer *buf; 1642 int len; 1643{ 1644 if (len > buf->nb_size) 1645 return; 1646 buf->nb_bytecount = len; 1647 1648 return; 1649} 1650 1651__stdcall static uint32_t 1652ndis_interlock_inc(addend) 1653 uint32_t *addend; 1654{ 1655 mtx_lock(&ndis_interlock); 1656 *addend++; 1657 mtx_unlock(&ndis_interlock); 1658 return(*addend); 1659} 1660 1661__stdcall static uint32_t 1662ndis_interlock_dec(addend) 1663 uint32_t *addend; 1664{ 1665 mtx_lock(&ndis_interlock); 1666 *addend--; 1667 mtx_unlock(&ndis_interlock); 1668 return(*addend); 1669} 1670 1671__stdcall static void 1672ndis_init_event(event) 1673 ndis_event *event; 1674{ 1675 event->ne_event.nk_header.dh_sigstate = FALSE; 1676 return; 1677} 1678 1679__stdcall static void 1680ndis_set_event(event) 1681 ndis_event *event; 1682{ 1683 event->ne_event.nk_header.dh_sigstate = TRUE; 1684 wakeup(event); 1685 return; 1686} 1687 1688__stdcall static void 1689ndis_reset_event(event) 1690 ndis_event *event; 1691{ 1692 event->ne_event.nk_header.dh_sigstate = FALSE; 1693 wakeup(event); 1694 return; 1695} 1696 1697__stdcall static uint8_t 1698ndis_wait_event(event, msecs) 1699 ndis_event *event; 1700 uint32_t msecs; 1701{ 1702 int error; 1703 struct timeval tv; 1704 1705 if (event->ne_event.nk_header.dh_sigstate == TRUE) 1706 return(TRUE); 1707 1708 tv.tv_sec = 0; 1709 tv.tv_usec = msecs * 1000; 1710 1711 error = tsleep(event, PPAUSE|PCATCH, "ndis", tvtohz(&tv)); 1712 1713 return(event->ne_event.nk_header.dh_sigstate); 1714} 1715 1716__stdcall static ndis_status 1717ndis_unicode2ansi(dstr, sstr) 1718 ndis_ansi_string *dstr; 1719 ndis_unicode_string *sstr; 1720{ 1721 if (dstr == NULL || sstr == NULL) 1722 return(NDIS_STATUS_FAILURE); 1723 if (ndis_unicode_to_ascii(sstr->nus_buf, 1724 sstr->nus_len, &dstr->nas_buf)) 1725 return(NDIS_STATUS_FAILURE); 1726 dstr->nas_len = dstr->nas_maxlen = strlen(dstr->nas_buf); 1727 return (NDIS_STATUS_SUCCESS); 1728} 1729 1730__stdcall static ndis_status 1731ndis_ansi2unicode(dstr, sstr) 1732 ndis_unicode_string *dstr; 1733 ndis_ansi_string *sstr; 1734{ 1735 char *str; 1736 if (dstr == NULL || sstr == NULL) 1737 return(NDIS_STATUS_FAILURE); 1738 str = malloc(sstr->nas_len + 1, M_DEVBUF, M_NOWAIT); 1739 if (str == NULL) 1740 return(NDIS_STATUS_FAILURE); 1741 strncpy(str, sstr->nas_buf, sstr->nas_len); 1742 *(str + sstr->nas_len) = '\0'; 1743 if (ndis_ascii_to_unicode(str, &dstr->nus_buf)) { 1744 free(str, M_DEVBUF); 1745 return(NDIS_STATUS_FAILURE); 1746 } 1747 dstr->nus_len = dstr->nus_maxlen = sstr->nas_len * 2; 1748 free(str, M_DEVBUF); 1749 return (NDIS_STATUS_SUCCESS); 1750} 1751 1752__stdcall static ndis_status 1753ndis_assign_pcirsrc(adapter, slot, list) 1754 ndis_handle adapter; 1755 uint32_t slot; 1756 ndis_resource_list **list; 1757{ 1758 ndis_miniport_block *block; 1759 1760 if (adapter == NULL || list == NULL) 1761 return (NDIS_STATUS_FAILURE); 1762 1763 block = (ndis_miniport_block *)adapter; 1764 *list = block->nmb_rlist; 1765 1766 printf ("assign PCI resources...\n"); 1767 return (NDIS_STATUS_SUCCESS); 1768} 1769 1770__stdcall static ndis_status 1771ndis_register_intr(intr, adapter, ivec, ilevel, reqisr, shared, imode) 1772 ndis_miniport_interrupt *intr; 1773 ndis_handle adapter; 1774 uint32_t ivec; 1775 uint32_t ilevel; 1776 uint8_t reqisr; 1777 uint8_t shared; 1778 ndis_interrupt_mode imode; 1779{ 1780 1781 return(NDIS_STATUS_SUCCESS); 1782} 1783 1784__stdcall static void 1785ndis_deregister_intr(intr) 1786 ndis_miniport_interrupt *intr; 1787{ 1788 return; 1789} 1790 1791__stdcall static void 1792ndis_register_shutdown(adapter, shutdownctx, shutdownfunc) 1793 ndis_handle adapter; 1794 void *shutdownctx; 1795 ndis_shutdown_handler shutdownfunc; 1796{ 1797 ndis_miniport_block *block; 1798 ndis_miniport_characteristics *chars; 1799 struct ndis_softc *sc; 1800 1801 if (adapter == NULL) 1802 return; 1803 1804 block = (ndis_miniport_block *)adapter; 1805 sc = (struct ndis_softc *)block->nmb_ifp; 1806 chars = &sc->ndis_chars; 1807 1808 chars->nmc_shutdown_handler = shutdownfunc; 1809 chars->nmc_rsvd0 = shutdownctx; 1810 1811 return; 1812} 1813 1814__stdcall static void 1815ndis_deregister_shutdown(adapter) 1816 ndis_handle adapter; 1817{ 1818 ndis_miniport_block *block; 1819 ndis_miniport_characteristics *chars; 1820 struct ndis_softc *sc; 1821 1822 if (adapter == NULL) 1823 return; 1824 1825 block = (ndis_miniport_block *)adapter; 1826 sc = (struct ndis_softc *)block->nmb_ifp; 1827 chars = &sc->ndis_chars; 1828 1829 chars->nmc_shutdown_handler = NULL; 1830 chars->nmc_rsvd0 = NULL; 1831 1832 return; 1833} 1834 1835__stdcall static uint32_t 1836ndis_numpages(buf) 1837 ndis_buffer *buf; 1838{ 1839 if (buf->nb_bytecount == 0) 1840 return(1); 1841 return(SPAN_PAGES(buf->nb_mappedsystemva, buf->nb_bytecount)); 1842} 1843 1844__stdcall static void 1845ndis_buf_physpages(buf, pages) 1846 ndis_buffer *buf; 1847 uint32_t *pages; 1848{ 1849 *pages = ndis_numpages(buf); 1850 return; 1851} 1852 1853__stdcall static void 1854ndis_query_bufoffset(buf, off, len) 1855 ndis_buffer *buf; 1856 uint32_t *off; 1857 uint32_t *len; 1858{ 1859 *off = (uint32_t)buf->nb_mappedsystemva & (PAGE_SIZE - 1); 1860 *len = buf->nb_bytecount; 1861 1862 return; 1863} 1864 1865__stdcall static void 1866ndis_sleep(usecs) 1867 uint32_t usecs; 1868{ 1869 struct timeval tv; 1870 uint32_t dummy; 1871 1872 tv.tv_sec = 0; 1873 tv.tv_usec = usecs; 1874 1875 tsleep(&dummy, PPAUSE|PCATCH, "ndis", tvtohz(&tv)); 1876 return; 1877} 1878 1879__stdcall static uint32_t 1880ndis_read_pccard_amem(handle, offset, buf, len) 1881 ndis_handle handle; 1882 uint32_t offset; 1883 void *buf; 1884 uint32_t len; 1885{ 1886 struct ndis_softc *sc; 1887 ndis_miniport_block *block; 1888 bus_space_handle_t bh; 1889 bus_space_tag_t bt; 1890 char *dest; 1891 int i; 1892 1893 if (handle == NULL) 1894 return(0); 1895 1896 block = (ndis_miniport_block *)handle; 1897 sc = (struct ndis_softc *)block->nmb_ifp; 1898 dest = buf; 1899 1900 bh = rman_get_bushandle(sc->ndis_res_am); 1901 bt = rman_get_bustag(sc->ndis_res_am); 1902 1903 for (i = 0; i < len; i++) 1904 dest[i] = bus_space_read_1(bt, bh, (offset * 2) + (i * 2)); 1905 1906 return(i); 1907} 1908 1909__stdcall static uint32_t 1910ndis_write_pccard_amem(handle, offset, buf, len) 1911 ndis_handle handle; 1912 uint32_t offset; 1913 void *buf; 1914 uint32_t len; 1915{ 1916 struct ndis_softc *sc; 1917 ndis_miniport_block *block; 1918 bus_space_handle_t bh; 1919 bus_space_tag_t bt; 1920 char *src; 1921 int i; 1922 1923 if (handle == NULL) 1924 return(0); 1925 1926 block = (ndis_miniport_block *)handle; 1927 sc = (struct ndis_softc *)block->nmb_ifp; 1928 src = buf; 1929 1930 bh = rman_get_bushandle(sc->ndis_res_am); 1931 bt = rman_get_bustag(sc->ndis_res_am); 1932 1933 for (i = 0; i < len; i++) 1934 bus_space_write_1(bt, bh, (offset * 2) + (i * 2), src[i]); 1935 1936 return(i); 1937} 1938 1939__stdcall static ndis_list_entry * 1940ndis_insert_head(head, entry, lock) 1941 ndis_list_entry *head; 1942 ndis_list_entry *entry; 1943 ndis_spin_lock *lock; 1944{ 1945 ndis_list_entry *flink; 1946 1947 mtx_lock_spin((struct mtx *)lock->nsl_spinlock); 1948 flink = head->nle_flink; 1949 entry->nle_flink = flink; 1950 entry->nle_blink = head; 1951 flink->nle_blink = entry; 1952 head->nle_flink = entry; 1953 mtx_unlock_spin((struct mtx *)lock->nsl_spinlock); 1954 1955 return(flink); 1956} 1957 1958__stdcall static ndis_list_entry * 1959ndis_remove_head(head, lock) 1960 ndis_list_entry *head; 1961 ndis_spin_lock *lock; 1962{ 1963 ndis_list_entry *flink; 1964 ndis_list_entry *entry; 1965 1966 mtx_lock_spin((struct mtx *)lock->nsl_spinlock); 1967 entry = head->nle_flink; 1968 flink = entry->nle_flink; 1969 head->nle_flink = flink; 1970 flink->nle_blink = head; 1971 mtx_unlock_spin((struct mtx *)lock->nsl_spinlock); 1972 1973 return(entry); 1974} 1975 1976__stdcall static ndis_list_entry * 1977ndis_insert_tail(head, entry, lock) 1978 ndis_list_entry *head; 1979 ndis_list_entry *entry; 1980 ndis_spin_lock *lock; 1981{ 1982 ndis_list_entry *blink; 1983 1984 mtx_lock_spin((struct mtx *)lock->nsl_spinlock); 1985 blink = head->nle_blink; 1986 entry->nle_flink = head; 1987 entry->nle_blink = blink; 1988 blink->nle_flink = entry; 1989 head->nle_blink = entry; 1990 mtx_unlock_spin((struct mtx *)lock->nsl_spinlock); 1991 1992 return(blink); 1993} 1994 1995__stdcall static uint8_t 1996ndis_sync_with_intr(intr, syncfunc, syncctx) 1997 ndis_miniport_interrupt *intr; 1998 void *syncfunc; 1999 void *syncctx; 2000{ 2001 __stdcall uint8_t (*sync)(void *); 2002 2003 if (syncfunc == NULL || syncctx == NULL) 2004 return(0); 2005 2006 sync = syncfunc; 2007 return(sync(syncctx)); 2008} 2009 2010/* 2011 * Return the number of 100 nanosecond intervals since 2012 * January 1, 1601. (?!?!) 2013 */ 2014__stdcall static void 2015ndis_time(tval) 2016 uint64_t *tval; 2017{ 2018 struct timespec ts; 2019 nanotime(&ts); 2020 *tval = (ts.tv_nsec / 100) + (ts.tv_nsec * 10000000); 2021 *tval += 11644473600; 2022 return; 2023} 2024 2025__stdcall static void 2026ndis_init_string(dst, src) 2027 ndis_unicode_string **dst; 2028 char *src; 2029{ 2030 ndis_unicode_string *u; 2031 2032 u = malloc(sizeof(ndis_unicode_string), M_DEVBUF, M_NOWAIT); 2033 if (u == NULL) 2034 return; 2035 u->nus_buf = NULL; 2036 if (ndis_ascii_to_unicode(src, &u->nus_buf)) { 2037 free(u, M_DEVBUF); 2038 return; 2039 } 2040 u->nus_len = u->nus_maxlen = strlen(src) * 2; 2041 return; 2042} 2043 2044__stdcall static void 2045ndis_free_string(str) 2046 ndis_unicode_string *str; 2047{ 2048 if (str == NULL) 2049 return; 2050 if (str->nus_buf != NULL) 2051 free(str->nus_buf, M_DEVBUF); 2052 free(str, M_DEVBUF); 2053 return; 2054} 2055 2056__stdcall static ndis_status 2057ndis_remove_miniport(adapter) 2058 ndis_handle *adapter; 2059{ 2060 return(NDIS_STATUS_SUCCESS); 2061} 2062 2063__stdcall static void 2064ndis_init_ansi_string(dst, src) 2065 ndis_ansi_string *dst; 2066 char *src; 2067{ 2068 ndis_ansi_string *a; 2069 2070 a = dst; 2071 if (a == NULL) 2072 return; 2073 if (src == NULL) { 2074 a->nas_len = a->nas_maxlen = 0; 2075 a->nas_buf = NULL; 2076 } else { 2077 a->nas_buf = src; 2078 a->nas_len = a->nas_maxlen = strlen(src); 2079 } 2080 2081 return; 2082} 2083 2084__stdcall static void ndis_get_devprop(adapter, phydevobj, 2085 funcdevobj, nextdevobj, resources, transresources) 2086 ndis_handle adapter; 2087 void *phydevobj; 2088 void *funcdevobj; 2089 void *nextdevobj; 2090 cm_resource_list *resources; 2091 cm_resource_list *transresources; 2092{ 2093 return; 2094} 2095 2096__stdcall static void 2097dummy() 2098{ 2099 printf ("NDIS dummy called...\n"); 2100 return; 2101} 2102 2103image_patch_table ndis_functbl[] = { 2104 { "NdisGetBufferPhysicalArraySize", (FUNC)ndis_buf_physpages }, 2105 { "NdisMGetDeviceProperty", (FUNC)ndis_get_devprop }, 2106 { "NdisInitAnsiString", (FUNC)ndis_init_ansi_string }, 2107 { "NdisWriteConfiguration", (FUNC)ndis_write_cfg }, 2108 { "NdisAnsiStringToUnicodeString", (FUNC)ndis_ansi2unicode }, 2109 { "NdisTerminateWrapper", (FUNC)ndis_termwrap }, 2110 { "NdisOpenConfigurationKeyByName", (FUNC)ndis_open_cfgbyname }, 2111 { "NdisOpenConfigurationKeyByIndex", (FUNC)ndis_open_cfgbyidx }, 2112 { "NdisMRemoveMiniport", (FUNC)ndis_remove_miniport }, 2113 { "NdisInitializeString", (FUNC)ndis_init_string }, 2114 { "NdisFreeString", (FUNC)ndis_free_string }, 2115 { "NdisGetCurrentSystemTime", (FUNC)ndis_time }, 2116 { "NdisMSynchronizeWithInterrupt", (FUNC)ndis_sync_with_intr }, 2117 { "NdisMAllocateSharedMemoryAsync", (FUNC)ndis_alloc_sharedmem_async }, 2118 { "NdisInterlockedInsertHeadList", (FUNC)ndis_insert_head }, 2119 { "NdisInterlockedInsertTailList", (FUNC)ndis_insert_tail }, 2120 { "NdisInterlockedRemoveHeadList", (FUNC)ndis_remove_head }, 2121 { "NdisInitializeWrapper", (FUNC)ndis_initwrap }, 2122 { "NdisMRegisterMiniport", (FUNC)ndis_register_miniport }, 2123 { "NdisAllocateMemoryWithTag", (FUNC)ndis_malloc_withtag }, 2124 { "NdisAllocateMemory", (FUNC)ndis_malloc }, 2125 { "NdisMSetAttributesEx", (FUNC)ndis_setattr_ex }, 2126 { "NdisCloseConfiguration", (FUNC)ndis_close_cfg }, 2127 { "NdisReadConfiguration", (FUNC)ndis_read_cfg }, 2128 { "NdisOpenConfiguration", (FUNC)ndis_open_cfg }, 2129 { "NdisReleaseSpinLock", (FUNC)ndis_unlock }, 2130 { "NdisDprAcquireSpinLock", (FUNC)ndis_lock }, 2131 { "NdisDprReleaseSpinLock", (FUNC)ndis_unlock }, 2132 { "NdisAcquireSpinLock", (FUNC)ndis_lock }, 2133 { "NdisAllocateSpinLock", (FUNC)ndis_create_lock }, 2134 { "NdisFreeSpinLock", (FUNC)ndis_destroy_lock }, 2135 { "NdisFreeMemory", (FUNC)ndis_free }, 2136 { "NdisReadPciSlotInformation", (FUNC)ndis_read_pci }, 2137 { "NdisWritePciSlotInformation",(FUNC)ndis_write_pci }, 2138 { "NdisWriteErrorLogEntry", (FUNC)ndis_syslog }, 2139 { "NdisMStartBufferPhysicalMapping", (FUNC)ndis_vtophys_load }, 2140 { "NdisMCompleteBufferPhysicalMapping", (FUNC)ndis_vtophys_unload }, 2141 { "NdisMInitializeTimer", (FUNC)ndis_create_timer }, 2142 { "NdisSetTimer", (FUNC)ndis_set_timer }, 2143 { "NdisMCancelTimer", (FUNC)ndis_cancel_timer }, 2144 { "NdisMSetPeriodicTimer", (FUNC)ndis_set_periodic_timer }, 2145 { "NdisMQueryAdapterResources", (FUNC)ndis_query_resources }, 2146 { "NdisMRegisterIoPortRange", (FUNC)ndis_register_ioport }, 2147 { "NdisMDeregisterIoPortRange", (FUNC)ndis_deregister_ioport }, 2148 { "NdisReadNetworkAddress", (FUNC)ndis_read_netaddr }, 2149 { "NdisMAllocateMapRegisters", (FUNC)ndis_alloc_mapreg }, 2150 { "NdisMFreeMapRegisters", (FUNC)ndis_free_mapreg }, 2151 { "NdisMAllocateSharedMemory", (FUNC)ndis_alloc_sharedmem }, 2152 { "NdisMMapIoSpace", (FUNC)ndis_map_iospace }, 2153 { "NdisMUnmapIoSpace", (FUNC)ndis_unmap_iospace }, 2154 { "NdisGetCacheFillSize", (FUNC)ndis_cachefill }, 2155 { "NdisMGetDmaAlignment", (FUNC)ndis_dma_align }, 2156 { "NdisMInitializeScatterGatherDma", (FUNC)ndis_init_sc_dma }, 2157 { "NdisAllocatePacketPool", (FUNC)ndis_alloc_packetpool }, 2158 { "NdisAllocatePacketPoolEx", (FUNC)ndis_ex_alloc_packetpool }, 2159 { "NdisAllocatePacket", (FUNC)ndis_alloc_packet }, 2160 { "NdisFreePacket", (FUNC)ndis_release_packet }, 2161 { "NdisFreePacketPool", (FUNC)ndis_free_packetpool }, 2162 { "NdisAllocateBufferPool", (FUNC)ndis_alloc_bufpool }, 2163 { "NdisAllocateBuffer", (FUNC)ndis_alloc_buf }, 2164 { "NdisQueryBuffer", (FUNC)ndis_query_buf }, 2165 { "NdisQueryBufferSafe", (FUNC)ndis_query_buf_safe }, 2166 { "NdisFreeBuffer", (FUNC)ndis_release_buf }, 2167 { "NdisFreeBufferPool", (FUNC)ndis_free_bufpool }, 2168 { "NdisInterlockedIncrement", (FUNC)ndis_interlock_inc }, 2169 { "NdisInterlockedDecrement", (FUNC)ndis_interlock_dec }, 2170 { "NdisInitializeEvent", (FUNC)ndis_init_event }, 2171 { "NdisSetEvent", (FUNC)ndis_set_event }, 2172 { "NdisResetEvent", (FUNC)ndis_reset_event }, 2173 { "NdisWaitEvent", (FUNC)ndis_wait_event }, 2174 { "NdisUnicodeStringToAnsiString", (FUNC)ndis_unicode2ansi }, 2175 { "NdisMPciAssignResources", (FUNC)ndis_assign_pcirsrc }, 2176 { "NdisMFreeSharedMemory", (FUNC)ndis_free_sharedmem }, 2177 { "NdisMRegisterInterrupt", (FUNC)ndis_register_intr }, 2178 { "NdisMDeregisterInterrupt", (FUNC)ndis_deregister_intr }, 2179 { "NdisMRegisterAdapterShutdownHandler", (FUNC)ndis_register_shutdown }, 2180 { "NdisMDeregisterAdapterShutdownHandler", (FUNC)ndis_deregister_shutdown }, 2181 { "NDIS_BUFFER_TO_SPAN_PAGES", (FUNC)ndis_numpages }, 2182 { "NdisQueryBufferOffset", (FUNC)ndis_query_bufoffset }, 2183 { "NdisAdjustBufferLength", (FUNC)ndis_adjust_buflen }, 2184 { "NdisPacketPoolUsage", (FUNC)ndis_packetpool_use }, 2185 { "NdisMSleep", (FUNC)ndis_sleep }, 2186 { "NdisUnchainBufferAtFront", (FUNC)ndis_unchain_headbuf }, 2187 { "NdisReadPcmciaAttributeMemory", (FUNC)ndis_read_pccard_amem }, 2188 { "NdisWritePcmciaAttributeMemory", (FUNC)ndis_write_pccard_amem }, 2189 2190 /* 2191 * This last entry is a catch-all for any function we haven't 2192 * implemented yet. The PE import list patching routine will 2193 * use it for any function that doesn't have an explicit match 2194 * in this table. 2195 */ 2196 2197 { NULL, (FUNC)dummy }, 2198 2199 /* End of list. */ 2200 2201 { NULL, NULL }, 2202}; 2203 2204