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