⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ndis.c

📁 linux下安装无线网卡启动的程式
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	if (dmasize == NDIS_DMA_24BITS) {		if (pci_set_dma_mask(wnd->wd->pci.pdev, DMA_24BIT_MASK) ||		    pci_set_consistent_dma_mask(wnd->wd->pci.pdev,						DMA_24BIT_MASK))			WARNING("setting dma mask failed");	} else if (dmasize == NDIS_DMA_32BITS) {		/* consistent dma is in low 32-bits by default */		if (pci_set_dma_mask(wnd->wd->pci.pdev, DMA_32BIT_MASK))			WARNING("setting dma mask failed");#ifdef CONFIG_X86_64	} else if (dmasize == NDIS_DMA_64BITS) {		if (pci_set_dma_mask(wnd->wd->pci.pdev, DMA_64BIT_MASK) ||		    pci_set_consistent_dma_mask(wnd->wd->pci.pdev,						DMA_64BIT_MASK))			WARNING("setting dma mask failed");		else			wnd->net_dev->features |= NETIF_F_HIGHDMA;#endif	}	/* since memory for buffer is allocated with kmalloc, buffer	 * is physically contiguous, so entire map will fit in one	 * register */	if (basemap > 64) {		WARNING("Windows driver %s requesting too many (%u) "			"map registers", wnd->wd->driver->name, basemap);		/* As per NDIS, NDIS_STATUS_RESOURCES should be		 * returned, but with that Atheros PCI driver fails -		 * for now tolerate it *///		EXIT2(return NDIS_STATUS_RESOURCES);	}	wnd->dma_map_addr = kmalloc(basemap * sizeof(*(wnd->dma_map_addr)),				    GFP_KERNEL);	if (!wnd->dma_map_addr)		EXIT2(return NDIS_STATUS_RESOURCES);	memset(wnd->dma_map_addr, 0, basemap * sizeof(*(wnd->dma_map_addr)));	wnd->dma_map_count = basemap;	TRACE2("%u", wnd->dma_map_count);	EXIT2(return NDIS_STATUS_SUCCESS);}wstdcall void WIN_FUNC(NdisMFreeMapRegisters,1)	(struct ndis_mp_block *nmb){	struct wrap_ndis_device *wnd = nmb->wnd;	int i;	ENTER2("wnd: %p", wnd);	if (wnd->dma_map_addr) {		for (i = 0; i < wnd->dma_map_count; i++) {			if (wnd->dma_map_addr[i])				WARNING("%s: dma addr %p not freed by "					"Windows driver", wnd->net_dev->name,					(void *)wnd->dma_map_addr[i]);		}		kfree(wnd->dma_map_addr);		wnd->dma_map_addr = NULL;	} else		WARNING("map registers already freed?");	wnd->dma_map_count = 0;	EXIT2(return);}wstdcall void WIN_FUNC(NdisMStartBufferPhysicalMapping,6)	(struct ndis_mp_block *nmb, ndis_buffer *buf,	 ULONG index, BOOLEAN write_to_dev,	 struct ndis_phy_addr_unit *phy_addr_array, UINT *array_size){	struct wrap_ndis_device *wnd = nmb->wnd;	ENTER3("%p, %p, %u, %u", wnd, buf, index, wnd->dma_map_count);	if (unlikely(wnd->sg_dma_size || !write_to_dev ||		     index >= wnd->dma_map_count)) {		WARNING("invalid request: %d, %d, %d, %d", wnd->sg_dma_size,			write_to_dev, index, wnd->dma_map_count);		phy_addr_array[0].phy_addr = 0;		phy_addr_array[0].length = 0;		*array_size = 0;		return;	}	if (wnd->dma_map_addr[index]) {		TRACE2("buffer %p at %d is already mapped: %lx", buf, index,		       (unsigned long)wnd->dma_map_addr[index]);//		*array_size = 1;		return;	}	TRACE3("%p, %p, %u", buf, MmGetSystemAddressForMdl(buf),	       MmGetMdlByteCount(buf));	DBG_BLOCK(4) {		dump_bytes(__FUNCTION__, MmGetSystemAddressForMdl(buf),			   MmGetMdlByteCount(buf));	}	wnd->dma_map_addr[index] = 		PCI_DMA_MAP_SINGLE(wnd->wd->pci.pdev,				   MmGetSystemAddressForMdl(buf),				   MmGetMdlByteCount(buf), PCI_DMA_TODEVICE);	phy_addr_array[0].phy_addr = wnd->dma_map_addr[index];	phy_addr_array[0].length = MmGetMdlByteCount(buf);	TRACE4("%Lx, %d, %d", phy_addr_array[0].phy_addr,	       phy_addr_array[0].length, index);	*array_size = 1;}wstdcall void WIN_FUNC(NdisMCompleteBufferPhysicalMapping,3)	(struct ndis_mp_block *nmb, ndis_buffer *buf, ULONG index){	struct wrap_ndis_device *wnd = nmb->wnd;	ENTER3("%p, %p %u (%u)", wnd, buf, index, wnd->dma_map_count);	if (unlikely(wnd->sg_dma_size))		WARNING("buffer %p may have been unmapped already", buf);	if (index >= wnd->dma_map_count) {		ERROR("invalid map register (%u >= %u)",		      index, wnd->dma_map_count);		return;	}	TRACE4("%lx", (unsigned long)wnd->dma_map_addr[index]);	if (wnd->dma_map_addr[index]) {		PCI_DMA_UNMAP_SINGLE(wnd->wd->pci.pdev, wnd->dma_map_addr[index],				     MmGetMdlByteCount(buf), PCI_DMA_TODEVICE);		wnd->dma_map_addr[index] = 0;	} else		WARNING("map registers at %u not used", index);}wstdcall void WIN_FUNC(NdisMAllocateSharedMemory,5)	(struct ndis_mp_block *nmb, ULONG size,	 BOOLEAN cached, void **virt, NDIS_PHY_ADDRESS *phys){	dma_addr_t dma_addr;	struct wrap_device *wd = nmb->wnd->wd;	ENTER3("size: %u, cached: %d", size, cached);	*virt = PCI_DMA_ALLOC_COHERENT(wd->pci.pdev, size, &dma_addr);	if (*virt)		*phys = dma_addr;	else		WARNING("couldn't allocate %d bytes of %scached DMA memory",			size, cached ? "" : "un-");	EXIT3(return);}wstdcall void WIN_FUNC(NdisMFreeSharedMemory,5)	(struct ndis_mp_block *nmb, ULONG size, BOOLEAN cached,	 void *virt, NDIS_PHY_ADDRESS addr){	struct wrap_device *wd = nmb->wnd->wd;	ENTER3("%p, %Lx, %u", virt, addr, size);	PCI_DMA_FREE_COHERENT(wd->pci.pdev, size, virt, addr);	EXIT3(return);}wstdcall void alloc_shared_memory_async(void *arg1, void *arg2){	struct wrap_ndis_device *wnd;	struct alloc_shared_mem *alloc_shared_mem;	struct miniport *mp;	void *virt;	NDIS_PHY_ADDRESS phys;	KIRQL irql;	wnd = arg1;	alloc_shared_mem = arg2;	mp = &wnd->wd->driver->ndis_driver->mp;	NdisMAllocateSharedMemory(wnd->nmb, alloc_shared_mem->size,				  alloc_shared_mem->cached, &virt, &phys);	irql = serialize_lock_irql(wnd);	assert_irql(_irql_ == DISPATCH_LEVEL);	LIN2WIN5(mp->alloc_complete, wnd->nmb, virt,		 &phys, alloc_shared_mem->size, alloc_shared_mem->ctx);	serialize_unlock_irql(wnd, irql);	kfree(alloc_shared_mem);}WIN_FUNC_DECL(alloc_shared_memory_async,2)wstdcall NDIS_STATUS WIN_FUNC(NdisMAllocateSharedMemoryAsync,4)	(struct ndis_mp_block *nmb, ULONG size, BOOLEAN cached, void *ctx){	struct wrap_ndis_device *wnd = nmb->wnd;	struct alloc_shared_mem *alloc_shared_mem;	ENTER3("wnd: %p", wnd);	alloc_shared_mem = kmalloc(sizeof(*alloc_shared_mem), irql_gfp());	if (!alloc_shared_mem) {		WARNING("couldn't allocate memory");		return NDIS_STATUS_FAILURE;	}	alloc_shared_mem->size = size;	alloc_shared_mem->cached = cached;	alloc_shared_mem->ctx = ctx;	if (schedule_ntos_work_item(WIN_FUNC_PTR(alloc_shared_memory_async,2),				    wnd, alloc_shared_mem))		EXIT3(return NDIS_STATUS_FAILURE);	EXIT3(return NDIS_STATUS_PENDING);}/* Some drivers allocate NDIS_BUFFER (aka MDL) very often; instead of * allocating and freeing with kernel functions, we chain them into * ndis_buffer_pool. When an MDL is freed, it is added to the list of * free MDLs. When allocated, we first check if there is one in free * list and if so just return it; otherwise, we allocate a new one and * return that. This reduces memory fragmentation. Windows DDK says * that the driver itself shouldn't check what is returned in * pool_handle, presumably because buffer pools are not used in * XP. However, as long as driver follows rest of the semantics - that * it should indicate maximum number of MDLs used with num_descr and * pass the same pool_handle in other buffer functions, this should * work. Sadly, though, NdisFreeBuffer doesn't pass the pool_handle, * so we use 'process' field of MDL to store pool_handle. */wstdcall void WIN_FUNC(NdisAllocateBufferPool,3)	(NDIS_STATUS *status, struct ndis_buffer_pool **pool_handle,	 UINT num_descr){	struct ndis_buffer_pool *pool;	ENTER1("buffers: %d", num_descr);	pool = kmalloc(sizeof(*pool), irql_gfp());	if (!pool) {		*status = NDIS_STATUS_RESOURCES;		EXIT3(return);	}	spin_lock_init(&pool->lock);	pool->max_descr = num_descr;	pool->num_allocated_descr = 0;	pool->free_descr = NULL;	*pool_handle = pool;	*status = NDIS_STATUS_SUCCESS;	TRACE1("pool: %p, num_descr: %d", pool, num_descr);	EXIT1(return);}wstdcall void WIN_FUNC(NdisAllocateBuffer,5)	(NDIS_STATUS *status, ndis_buffer **buffer,	 struct ndis_buffer_pool *pool, void *virt, UINT length){	ndis_buffer *descr;	ENTER4("pool: %p, allocated: %d", pool, pool->num_allocated_descr);	/* NDIS drivers should call this at DISPATCH_LEVEL, but	 * alloc_tx_packet calls at SOFT_IRQL */	assert_irql(_irql_ <= SOFT_LEVEL);	if (!pool) {		*status = NDIS_STATUS_FAILURE;		*buffer = NULL;		EXIT4(return);	}	spin_lock_bh(&pool->lock);	if ((descr = pool->free_descr))		pool->free_descr = descr->next;	spin_unlock_bh(&pool->lock);	if (descr) {		typeof(descr->flags) flags;		flags = descr->flags;		memset(descr, 0, sizeof(*descr));		MmInitializeMdl(descr, virt, length);		if (flags & MDL_CACHE_ALLOCATED)			descr->flags |= MDL_CACHE_ALLOCATED;	} else {		if (pool->num_allocated_descr > pool->max_descr) {			TRACE2("pool %p is full: %d(%d)", pool,			       pool->num_allocated_descr, pool->max_descr);#ifndef ALLOW_POOL_OVERFLOW			*status = NDIS_STATUS_FAILURE;			*buffer = NULL;			return;#endif		}		descr = allocate_init_mdl(virt, length);		if (!descr) {			WARNING("couldn't allocate buffer");			*status = NDIS_STATUS_FAILURE;			*buffer = NULL;			EXIT4(return);		}		TRACE4("buffer %p for %p, %d", descr, virt, length);		atomic_inc_var(pool->num_allocated_descr);	}	/* TODO: make sure this mdl can map given buffer */	MmBuildMdlForNonPagedPool(descr);//	descr->flags |= MDL_ALLOCATED_FIXED_SIZE |//		MDL_MAPPED_TO_SYSTEM_VA | MDL_PAGES_LOCKED;	descr->pool = pool;	*buffer = descr;	*status = NDIS_STATUS_SUCCESS;	TRACE4("buffer: %p", descr);	EXIT4(return);}wstdcall void WIN_FUNC(NdisFreeBuffer,1)	(ndis_buffer *buffer){	struct ndis_buffer_pool *pool;	ENTER4("%p", buffer);	if (!buffer || !buffer->pool) {		ERROR("invalid buffer");		EXIT4(return);	}	pool = buffer->pool;	spin_lock_bh(&pool->lock);	if (pool->num_allocated_descr > MAX_ALLOCATED_NDIS_BUFFERS) {		/* NB NB NB: set mdl's 'pool' field to NULL before		 * calling free_mdl; otherwise free_mdl calls		 * NdisFreeBuffer causing deadlock (for spinlock) */		pool->num_allocated_descr--;		buffer->pool = NULL;		spin_unlock_bh(&pool->lock);		free_mdl(buffer);	} else {		buffer->next = pool->free_descr;		pool->free_descr = buffer;		spin_unlock_bh(&pool->lock);	}	EXIT4(return);}wstdcall void WIN_FUNC(NdisFreeBufferPool,1)	(struct ndis_buffer_pool *pool){	ndis_buffer *cur, *next;	TRACE3("pool: %p", pool);	if (!pool) {		WARNING("invalid pool");		EXIT3(return);	}	spin_lock_bh(&pool->lock);	cur = pool->free_descr;	while (cur) {		next = cur->next;		cur->pool = NULL;		free_mdl(cur);		cur = next;	}	spin_unlock_bh(&pool->lock);	kfree(pool);	pool = NULL;	EXIT3(return);}wstdcall void WIN_FUNC(NdisAdjustBufferLength,2)	(ndis_buffer *buffer, UINT length){	ENTER4("%p, %d", buffer, length);	buffer->bytecount = length;}wstdcall void WIN_FUNC(NdisQueryBuffer,3)	(ndis_buffer *buffer, void **virt, UINT *length){	ENTER4("buffer: %p", buffer);	if (virt)		*virt = MmGetSystemAddressForMdl(buffer);	*length = MmGetMdlByteCount(buffer);	TRACE4("%p, %u", virt? *virt : NULL, *length);	return;}wstdcall void WIN_FUNC(NdisQueryBufferSafe,4)	(ndis_buffer *buffer, void **virt, UINT *length,	 enum mm_page_priority priority){	ENTER4("%p, %p, %p, %d", buffer, virt, length, priority);	if (virt)		*virt = MmGetSystemAddressForMdlSafe(buffer, priority);	*length = MmGetMdlByteCount(buffer);	TRACE4("%p, %u", virt? *virt : NULL, *length);}wstdcall void *WIN_FUNC(NdisBufferVirtualAddress,1)	(ndis_buffer *buffer){	ENTER3("%p", buffer);	return MmGetSystemAddressForMdl(buffer);}wstdcall ULONG WIN_FUNC(NdisBufferLength,1)	(ndis_buffer *buffer){	ENTER3("%p", buffer);	return MmGetMdlByteCount(buffer);}wstdcall void WIN_FUNC(NdisQueryBufferOffset,3)	(ndis_buffer *buffer, UINT *offset, UINT *length){	ENTER3("%p", buffer);	*offset = MmGetMdlByteOffset(buffer);	*length = MmGetMdlByteCount(buffer);	TRACE3("%d, %d", *offset, *length);}wstdcall void WIN_FUNC(NdisUnchainBufferAtBack,2)	(struct ndis_packet *packet, ndis_buffer **buffer){	ndis_buffer *b, *btail;	ENTER3("%p", packet);	b = packet->private.buffer_head;	if (!b) {		/* no buffer in packet */		*buffer = NULL;		EXIT3(return);	}	btail = packet->private.buffer_tail;	*buffer = btail;	if (b == btail) {		/* one buffer in packet */		packet->private.buffer_head = NULL;		packet->private.buffer_tail = NULL;	} else {		while (b->next != btail)			b = b->next;		packet->private.buffer_tail = b;		b->next = NULL;	}	packet->private.valid_counts = FALSE;	EXIT3(return);}wstdcall void WIN_FUNC(NdisUnchainBufferAtFront,2)	(struct ndis_packet *packet, ndis_buffer **buffer){	ENTER3("%p", packet);	if (packet->private.buffer_head == NULL) {		/* no buffer in packet */		*buffer = NULL;		EXIT3(return);	}	*buffer = packet->private.buffer_head;	if (packet->private.buffer_head == packet->private.buffer_tail) {		/* one buffer in packet */		packet->private.buffer_head = NULL;		packet->private.buffer_tail = NULL;	} else		packet->private.buffer_head = (*buffer)->next;	packet->private.valid_counts = FALSE;	EXIT3(return);}wstdcall void WIN_FUNC(NdisGetFirstBufferFromPacketSafe,6)	(struct ndis_packet *packet, ndis_buffer **first_buffer,	 void **first_buffer_va, UINT *first_buffer_length,	 UINT *total_buffer_length, enum mm_page_priority priority){	ndis_buffer *b = packet->private.buffer_head;	ENTER3("%p(%p)", packet, b);	*first_buffer = b;	if (b) {		*first_buffer_va = MmGetSystemAddressForMdlSafe(b, priority);		*first_buffer_length = *total_buffer_length =			MmGetMdlByteCount(b);		for (b = b->next; b; b = b->next)			*total_buffer_length += MmGetMdlByteCount(b);	} else {		*first_buffer_va = NULL;		*first_buffer_length = 0;		*total_buffer_length = 0;	}	TRACE3("%p, %d, %d", *first_buffer_va, *first_buffer_length,	       *total_buffer_length);	EXIT3(return);}wstdcall void WIN_FUNC(NdisGetFirstBufferFromPacket,6)	(struct ndis_packet *packet, ndis_buffer **first_buffer,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -