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

📄 ndis.c

📁 ndis在linux下的无线网卡驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	       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_miniport_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_miniport_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)		WARNING("couldn't allocate %d bytes of %scached DMA memory",			size, cached ? "" : "un-");	*phys = dma_addr;	EXIT3(return);}wstdcall void WIN_FUNC(NdisMFreeSharedMemory,5)	(struct ndis_miniport_block *nmb, ULONG size, BOOLEAN cached,	 void *virt, NDIS_PHY_ADDRESS addr){	struct wrap_device *wd = nmb->wnd->wd;	ENTER3("");	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_char *miniport;	void *virt;	NDIS_PHY_ADDRESS phys;	KIRQL irql;	wnd = arg1;	alloc_shared_mem = arg2;	miniport = &wnd->wd->driver->ndis_driver->miniport;	NdisMAllocateSharedMemory(wnd->nmb, alloc_shared_mem->size,				  alloc_shared_mem->cached, &virt, &phys);	irql = serialize_lock_irql(wnd);	LIN2WIN5(miniport->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_miniport_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), gfp_irql());	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), gfp_irql());	if (!pool) {		*status = NDIS_STATUS_RESOURCES;		EXIT3(return);	}	nt_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;	KIRQL irql;	ENTER4("pool: %p, allocated: %d", pool, pool->num_allocated_descr);	if (!pool) {		*status = NDIS_STATUS_FAILURE;		EXIT4(return);	}	DBG_BLOCK(2) {		if (pool->num_allocated_descr > pool->max_descr)			WARNING("pool %p is full: %d(%d)", pool,				pool->num_allocated_descr, pool->max_descr);	}	irql = nt_spin_lock_irql(&pool->lock, DISPATCH_LEVEL);	if (pool->free_descr) {		typeof(descr->flags) flags;		descr = pool->free_descr;		pool->free_descr = descr->next;		nt_spin_unlock_irql(&pool->lock, irql);		flags = descr->flags;		memset(descr, 0, sizeof(*descr));		MmInitializeMdl(descr, virt, length);		if (flags & MDL_CACHE_ALLOCATED)			descr->flags |= MDL_CACHE_ALLOCATED;	} else {		nt_spin_unlock_irql(&pool->lock, irql);		descr = allocate_init_mdl(virt, length);		if (!descr) {			WARNING("couldn't allocate buffer");			*status = NDIS_STATUS_FAILURE;			EXIT4(return);		}		TRACE4("allocated 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;	KIRQL irql;	ENTER4("%p", buffer);	if (!buffer || !buffer->pool) {		ERROR("invalid buffer");		EXIT4(return);	}	pool = buffer->pool;	irql = nt_spin_lock_irql(&pool->lock, DISPATCH_LEVEL);	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;		nt_spin_unlock_irql(&pool->lock, irql);		free_mdl(buffer);	} else {		buffer->next = pool->free_descr;		pool->free_descr = buffer;		nt_spin_unlock_irql(&pool->lock, irql);	}	EXIT4(return);}wstdcall void WIN_FUNC(NdisFreeBufferPool,1)	(struct ndis_buffer_pool *pool){	ndis_buffer *cur, *next;	KIRQL irql;	TRACE3("pool: %p", pool);	if (!pool) {		WARNING("invalid pool");		EXIT3(return);	}	irql = nt_spin_lock_irql(&pool->lock, DISPATCH_LEVEL);	cur = pool->free_descr;	while (cur) {		next = cur->next;		cur->pool = NULL;		free_mdl(cur);		cur = next;	}	nt_spin_unlock_irql(&pool->lock, irql);	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,	 void **first_buffer_va, UINT *first_buffer_length,	 UINT *total_buffer_length, enum mm_page_priority priority){	NdisGetFirstBufferFromPacketSafe(packet, first_buffer,					 first_buffer_va, first_buffer_length,					 total_buffer_length,					 NormalPagePriority);}wstdcall void WIN_FUNC(NdisAllocatePacketPoolEx,5)	(NDIS_STATUS *status, struct ndis_packet_pool **pool_handle,	 UINT num_descr, UINT overflowsize, UINT proto_rsvd_length){	struct ndis_packet_pool *pool;	ENTER3("buffers: %d, length: %d", num_descr, proto_rsvd_length);	pool = kmalloc(sizeof(*pool), gfp_irql());	if (!pool) {		*status = NDIS_STATUS_RESOURCES;		EXIT3(return);	}	memset(pool, 0, sizeof(*pool));	nt_spin_lock_init(&pool->lock);	pool->max_descr = num_descr;	pool->num_allocated_descr = 0;	pool->num_used_descr = 0;	pool->free_descr = NULL;	pool->proto_rsvd_length = proto_rsvd_length;	*pool_handle = pool;	*status = NDIS_STATUS_SUCCESS;	TRACE3("pool: %p", pool);	EXIT3(return);}wstdcall void WIN_FUNC(NdisAllocatePacketPool,4)	(NDIS_STATUS *status, struct ndis_packet_pool **pool_handle,	 UINT num_descr, UINT proto_rsvd_length){	NdisAllocatePacketPoolEx(status, pool_handle, num_descr, 0,				 proto_rsvd_length);	EXIT3(return);}wstdcall void WIN_FUNC(NdisFreePacketPool,1)	(struct ndis_packet_pool *pool){	struct ndis_packet *packet, *next;	KIRQL irql;	ENTER3("pool: %p", pool);	if (!pool) {		WARNING("invalid pool");		EXIT3(return);	}	irql = nt_spin_lock_irql(&pool->lock, DISPATCH_LEVEL);	packet = pool->free_descr;	while (packet) {		next = (struct ndis_packet *)packet->reserved[0];		kfree(packet);		packet = next;	}	pool->num_allocated_descr = 0;	pool->num_used_descr = 0;	pool->free_descr = NULL;	nt_spin_unlock_irql(&pool->lock, irql);	kfree(pool);	EXIT3(return);}wstdcall UINT WIN_FUNC(NdisPacketPoolUsage,1)	(struct ndis_packet_pool *pool){	EXIT4(return pool->num_used_descr);}wstdcall void WIN_FUNC(NdisAllocatePacket,3)	(NDIS_STATUS *status, struct ndis_packet **ndis_packet,	 struct ndis_packet_pool *pool){	struct ndis_packet *packet;	int packet_length;	KIRQL irql;	ENTER4("pool: %p", pool);	if (!pool) {		*status = NDIS_STATUS_RESOURCES;		EXIT4(return);	}

⌨️ 快捷键说明

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