📄 ndis.c
字号:
setting->config_param.data.ustring.buf) RtlFreeUnicodeString(&setting->config_param.data.ustring); switch(val->type) { case NDIS_CONFIG_PARAM_INT: snprintf(setting->value, sizeof(u32), "%u", val->data.intval); setting->value[sizeof(ULONG)] = 0; break; case NDIS_CONFIG_PARAM_HEXINT: snprintf(setting->value, sizeof(u32), "%x", val->data.intval); setting->value[sizeof(ULONG)] = 0; break; case NDIS_CONFIG_PARAM_STRING: ansi.buf = setting->value; ansi.buflen = MAX_STR_LEN; if (RtlUnicodeStringToAnsiString(&ansi, &val->data.ustring, 0) || ansi.len >= MAX_STR_LEN) { TRACEEXIT1(return NDIS_STATUS_FAILURE); } memcpy(setting->value, ansi.buf, ansi.len); DBGTRACE2("value = %s", setting->value); setting->value[ansi.len] = 0; break; default: DBGTRACE2("unknown setting type: %d", val->type); return NDIS_STATUS_FAILURE; } setting->config_param.type = NDIS_CONFIG_PARAM_NONE; return NDIS_STATUS_SUCCESS;}STDCALL void WRAP_EXPORT(NdisReadConfiguration) (NDIS_STATUS *status, struct ndis_config_param **dest, struct ndis_handle *handle, struct unicode_string *key, enum ndis_config_param_type type){ struct device_setting *setting; struct ansi_string ansi; char *keyname; int ret; TRACEENTER2("handle: %p", handle); ret = RtlUnicodeStringToAnsiString(&ansi, key, 1); DBGTRACE3("rtl func returns: %d", ret); if (ret) { *dest = NULL; *status = NDIS_STATUS_FAILURE; RtlFreeAnsiString(&ansi); TRACEEXIT2(return); } DBGTRACE3("handle: %p, string: %s", handle, ansi.buf); keyname = ansi.buf; DBGTRACE3("handle: %p, string: %s", handle, keyname); list_for_each_entry(setting, &handle->device->settings, list) { if (stricmp(keyname, setting->name) == 0) { DBGTRACE2("setting found %s=%s", keyname, setting->value); *status = ndis_encode_setting(setting, type); if (*status == NDIS_STATUS_SUCCESS) *dest = &setting->config_param; else *dest = NULL; RtlFreeAnsiString(&ansi); DBGTRACE2("status = %d", *status); TRACEEXIT2(return); } } DBGTRACE2("setting %s not found (type:%d)", keyname, type); *dest = NULL; *status = NDIS_STATUS_FAILURE; RtlFreeAnsiString(&ansi); TRACEEXIT2(return);}STDCALL void WRAP_EXPORT(NdisWriteConfiguration) (NDIS_STATUS *status, struct ndis_handle *handle, struct unicode_string *key, struct ndis_config_param *param){ struct ansi_string ansi; char *keyname; struct device_setting *setting; TRACEENTER2("%s", ""); if (RtlUnicodeStringToAnsiString(&ansi, key, 1)) { *status = NDIS_STATUS_FAILURE; TRACEEXIT2(return); } keyname = ansi.buf; DBGTRACE2("key = %s", keyname); list_for_each_entry(setting, &handle->device->settings, list) { if (strcmp(keyname, setting->name) == 0) { *status = ndis_decode_setting(setting, param); DBGTRACE2("setting changed %s=%s", keyname, setting->value); RtlFreeAnsiString(&ansi); TRACEEXIT2(return); } } if ((setting = kmalloc(sizeof(*setting), GFP_KERNEL)) == NULL) { *status = NDIS_STATUS_RESOURCES; RtlFreeAnsiString(&ansi); TRACEEXIT2(return); } memset(setting, 0, sizeof(*setting)); memcpy(setting->name, keyname, ansi.len); setting->name[ansi.len] = 0; *status = ndis_decode_setting(setting, param); if (*status == NDIS_STATUS_SUCCESS) list_add(&setting->list, &handle->device->settings); else { kfree(setting->name); kfree(setting); } RtlFreeAnsiString(&ansi); TRACEEXIT2(return);}STDCALL void WRAP_EXPORT(NdisInitializeString) (struct unicode_string *dest, UCHAR *src){ struct ansi_string ansi; TRACEENTER2("%s", ""); ansi.len = ansi.buflen = strlen(src); ansi.buf = src; if (RtlAnsiStringToUnicodeString(dest, &ansi, 1)) DBGTRACE2("%s", "failed"); TRACEEXIT2(return);}STDCALL void WRAP_EXPORT(NdisInitAnsiString) (struct ansi_string *dst, CHAR *src){ RtlInitAnsiString(dst, src); TRACEEXIT2(return);}STDCALL void WRAP_EXPORT(NdisInitString) (struct ansi_string *dst, CHAR *src){ RtlInitString(dst, src); TRACEEXIT2(return);}STDCALL void WRAP_EXPORT(NdisInitUnicodeString) (struct unicode_string *dest, const wchar_t *src){ int i; TRACEENTER2("%s", ""); if (dest == NULL) TRACEEXIT2(return); if (src == NULL) { dest->len = dest->buflen = 0; dest->buf = NULL; TRACEEXIT2(return); } for (i = 0 ; src[i] ; i++) ; dest->len = dest->buflen = i * 2; dest->buf = (wchar_t *)src; TRACEEXIT2(return);}STDCALL NDIS_STATUS WRAP_EXPORT(NdisAnsiStringToUnicodeString) (struct unicode_string *dst, struct ansi_string *src){ int dup; TRACEENTER2("%s", ""); if (dst == NULL || src == NULL) TRACEEXIT2(return NDIS_STATUS_FAILURE); if (dst->buf == NULL) dup = 1; else dup = 0; TRACEEXIT2(return RtlAnsiStringToUnicodeString(dst, src, 0));}STDCALL NDIS_STATUS WRAP_EXPORT(NdisUnicodeStringToAnsiString) (struct ansi_string *dst, struct unicode_string *src){ int dup; TRACEENTER2("%s", ""); if (dst == NULL || src == NULL) TRACEEXIT2(return NDIS_STATUS_FAILURE); if (dst->buf == NULL) dup = 1; else dup = 0; TRACEEXIT2(return RtlUnicodeStringToAnsiString(dst, src, dup));}/* * Called by driver from the init callback. * The adapter_ctx should be supplied to most other callbacks so we save * it in out handle. Some functions are called only with adapter_ctx, but * we also need handle in them, so we store handle X adapter_ctx map in * a global list. */STDCALL void WRAP_EXPORT(NdisMSetAttributesEx) (struct ndis_handle *handle, void *adapter_ctx, UINT hangcheck_interval, UINT attributes, ULONG adaptortype){ struct handle_ctx_entry *handle_ctx; TRACEENTER2("%p, %p %d %08x, %d", handle, adapter_ctx, hangcheck_interval, attributes, adaptortype); /* FIXME: is it possible to have duplicate ctx's? */ handle_ctx = kmalloc(sizeof(*handle_ctx), GFP_KERNEL); if (handle_ctx) { handle_ctx->handle = handle; handle_ctx->ctx = adapter_ctx; /* ntoskernel_lock is not meant for use here, but since this * function is called during initialization only, * no harm abusing it */ kspin_lock(&ntoskernel_lock); list_add(&handle_ctx->list, &handle_ctx_list); kspin_unlock(&ntoskernel_lock); } if (attributes & NDIS_ATTRIBUTE_BUS_MASTER) pci_set_master(handle->dev.pci); if (!(attributes & NDIS_ATTRIBUTE_DESERIALIZE)) { DBGTRACE2("serialized driver"); set_bit(ATTR_SERIALIZED, &handle->attributes); } if (attributes & NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK) set_bit(ATTR_SURPRISE_REMOVE, &handle->attributes); if (!(attributes & NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND)) set_bit(ATTR_HALT_ON_SUSPEND, &handle->attributes); if (handle->hangcheck_interval >= 0) { /* less than 3 seconds seem to be problematic */ if (hangcheck_interval > 2) handle->hangcheck_interval = 2*hangcheck_interval * HZ; else handle->hangcheck_interval = 3 * HZ; } handle->adapter_ctx = adapter_ctx; TRACEEXIT2(return);}static struct ndis_handle *ctx_to_handle(void *ctx){ struct handle_ctx_entry *handle_ctx; kspin_lock(&ntoskernel_lock); list_for_each_entry(handle_ctx, &handle_ctx_list, list) { if (handle_ctx->ctx == ctx) { kspin_unlock(&ntoskernel_lock); return handle_ctx->handle; } } kspin_unlock(&ntoskernel_lock); return NULL;}STDCALL ULONG WRAP_EXPORT(NdisReadPciSlotInformation) (struct ndis_handle *handle, ULONG slot, ULONG offset, char *buf, ULONG len){ int i; for (i = 0; i < len; i++) pci_read_config_byte(handle->dev.pci, offset+i, &buf[i]); return len;}STDCALL ULONG WRAP_EXPORT(NdisWritePciSlotInformation) (struct ndis_handle *handle, ULONG slot, ULONG offset, char *buf, ULONG len){ int i; for (i = 0; i < len; i++) pci_write_config_byte(handle->dev.pci, offset+i, buf[i]); return len;}STDCALL void WRAP_EXPORT(NdisMQueryAdapterResources) (NDIS_STATUS *status, struct ndis_handle *handle, struct ndis_resource_list *resource_list, UINT *size){ int i; int len = 0; /* FIXME: do USB drivers call this? */ struct pci_dev *pci_dev = handle->dev.pci; struct ndis_resource_entry *entry; TRACEENTER2("handle: %p. buf: %p, len: %d. IRQ:%d", handle, resource_list, *size, pci_dev->irq); resource_list->version = 1; /* Put all memory and port resources */ i = 0; while (pci_resource_start(pci_dev, i)) { entry = &resource_list->list[len++]; if (pci_resource_flags(pci_dev, i) & IORESOURCE_MEM) { entry->type = 3; entry->flags = 0; } else if (pci_resource_flags(pci_dev, i) & IORESOURCE_IO) { entry->type = 1; entry->flags = 1; } entry->share = 0; entry->u.generic.start = (ULONG_PTR)pci_resource_start(pci_dev, i); entry->u.generic.length = pci_resource_len(pci_dev, i); i++; } /* Put IRQ resource */ entry = &resource_list->list[len++]; entry->type = 2; entry->share = 0; entry->flags = 0; entry->u.interrupt.level = pci_dev->irq; entry->u.interrupt.vector = pci_dev->irq; entry->u.interrupt.affinity = -1; resource_list->length = len; *size = (char *) (&resource_list->list[len]) - (char *)resource_list; *status = NDIS_STATUS_SUCCESS; DBGTRACE2("resource list v%d.%d len %d, size=%d", resource_list->version, resource_list->revision, resource_list->length, *size); for (i = 0; i < len; i++) { DBGTRACE2("resource: %d: %Lx %d, %d", resource_list->list[i].type, resource_list->list[i].u.generic.start, resource_list->list[i].u.generic.length, resource_list->list[i].flags); } TRACEEXIT2(return);}STDCALL NDIS_STATUS WRAP_EXPORT(NdisMPciAssignResources) (struct ndis_handle *handle, ULONG slot_number, struct ndis_resource_list **resources){ UINT size; NDIS_STATUS status; size = sizeof(struct ndis_resource_list) + sizeof(struct ndis_resource_entry) * 20; handle->pci_resources = vmalloc(size); if (!handle->resources) { ERROR("couldn't allocate memory"); TRACEEXIT2(return NDIS_STATUS_SUCCESS); } NdisMQueryAdapterResources(&status, handle, handle->pci_resources, &size); *resources = handle->pci_resources; TRACEEXIT2(return NDIS_STATUS_SUCCESS);}STDCALL NDIS_STATUS WRAP_EXPORT(NdisMMapIoSpace) (void **virt, struct ndis_handle *handle, NDIS_PHY_ADDRESS phy_addr, UINT len){ TRACEENTER2("%016llx, %d", phy_addr, len); *virt = ioremap(phy_addr, len); if (*virt == NULL) { ERROR("%s", "ioremap failed"); TRACEEXIT2(return NDIS_STATUS_FAILURE); } handle->mem_start = phy_addr; handle->mem_end = phy_addr + len -1; DBGTRACE2("ioremap successful %p", *virt); TRACEEXIT2(return NDIS_STATUS_SUCCESS);}STDCALL void WRAP_EXPORT(NdisMUnmapIoSpace) (struct ndis_handle *handle, void *virtaddr, UINT len){ TRACEENTER2("%p, %d", virtaddr, len); iounmap(virtaddr);}STDCALL void WRAP_EXPORT(NdisAllocateSpinLock) (struct ndis_spinlock *lock){ TRACEENTER4("lock %p", lock); KeInitializeSpinLock(&lock->klock); TRACEEXIT4(return);}STDCALL void WRAP_EXPORT(NdisFreeSpinLock) (struct ndis_spinlock *lock){ TRACEENTER4("lock %p", lock); TRACEEXIT4(return);}STDCALL void WRAP_EXPORT(NdisAcquireSpinLock) (struct ndis_spinlock *lock){ TRACEENTER5("lock %p", lock); lock->irql = kspin_lock_irql(&lock->klock, DISPATCH_LEVEL); TRACEEXIT5(return);}STDCALL void WRAP_EXPORT(NdisReleaseSpinLock) (struct ndis_spinlock *lock){ TRACEENTER5("lock %p", lock); kspin_unlock_irql(&lock->klock, lock->irql); TRACEEXIT5(return);}STDCALL void WRAP_EXPORT(NdisDprAcquireSpinLock) (struct ndis_spinlock *lock){ TRACEENTER5("lock %p", lock); kspin_lock(&lock->klock); TRACEEXIT5(return);}STDCALL void WRAP_EXPORT(NdisDprReleaseSpinLock) (struct ndis_spinlock *lock){ TRACEENTER5("lock %p", lock); kspin_unlock(&lock->klock); TRACEEXIT5(return);}STDCALL void WRAP_EXPORT(NdisInitializeReadWriteLock) (struct ndis_rw_lock *rw_lock){ memset(rw_lock, 0, sizeof(*rw_lock)); KeInitializeSpinLock(&rw_lock->u.s.klock); return;}STDCALL NDIS_STATUS WRAP_EXPORT(NdisMAllocateMapRegisters) (struct ndis_handle *handle, UINT dmachan, NDIS_DMA_SIZE dmasize, ULONG basemap, ULONG size){ TRACEENTER2("%d %d %d %d", dmachan, dmasize, basemap, size);// if (basemap > 64)// return NDIS_STATUS_RESOURCES; if (handle->map_count > 0) { DBGTRACE2("%s: map registers already allocated: %u", handle->net_dev->name, handle->map_count); TRACEEXIT2(return NDIS_STATUS_RESOURCES); } handle->map_count = basemap; handle->map_dma_addr = kmalloc(basemap * sizeof(dma_addr_t), GFP_KERNEL); if (!handle->map_dma_addr) TRACEEXIT2(return NDIS_STATUS_RESOURCES); memset(handle->map_dma_addr, 0, basemap * sizeof(dma_addr_t)); TRACEEXIT2(return NDIS_STATUS_SUCCESS);}STDCALL void WRAP_EXPORT(NdisMFreeMapRegisters) (struct ndis_handle *handle){ TRACEENTER2("handle: %p", handle); if (handle->map_dma_addr != NULL) kfree(handle->map_dma_addr); handle->map_count = 0; TRACEEXIT2(return);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -