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

📄 ndis.c

📁 万能网卡驱动程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  Copyright (C) 2003 Pontus Fuchs * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *  GNU General Public License for more details. * */#include <linux/module.h>#include <linux/pci.h>#include <linux/spinlock.h>#include <linux/timer.h>#include <linux/interrupt.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/types.h>#include "ndis.h"extern int image_offset;int getSp(void){	volatile int i;	asm("movl %esp,(%esp,1)");	return i;}int unicodeToStr(char *dst, struct ustring *src, int dstlen){	char *buf = src->buf;	int i = 0;	while((i/2 < src->len) && (buf[0] || buf[1])) {		if(i >= dstlen)		{			printk(KERN_ERR "%s failed. Buffer to small\n", __FUNCTION__);			return -1;			}		dst[i++] = buf[0];		buf +=2;	}	dst[i] = 0;	return 0;}/* *  * * Called from the driver entry. */STDCALL void NdisInitializeWrapper(struct ndis_handle **ndis_handle,	                           void *SystemSpecific1,				   void *SystemSpecific2,				   void *SystemSpecific3){	DBGTRACE("%s handle=%08x, SS1=%08x, SS2=%08x\n", __FUNCTION__, (int)ndis_handle, (int)SystemSpecific1, (int)SystemSpecific2);	*ndis_handle = (struct ndis_handle*) SystemSpecific1;}STDCALL void NdisTerminateWrapper(struct ndis_handle *ndis_handle,	                          void *SystemSpecific1){	DBGTRACE("%s\n", __FUNCTION__ );}/* * Register a miniport with NDIS.  * * Called from driver entry */STDCALL int NdisMRegisterMiniport(struct ndis_driver *ndis_driver,	                          struct miniport_char *miniport_char,	                          unsigned int char_len){	DBGTRACE("%s driver: %08x\n", __FUNCTION__, (int)ndis_driver);	if(miniport_char->majorVersion < 4)	{		return NDIS_STATUS_BAD_VERSION;	}	if(char_len < sizeof(struct miniport_char))	{		return NDIS_STATUS_BAD_CHAR;	}	DBGTRACE("%s Version %d.%d\n", __FUNCTION__, miniport_char->majorVersion, miniport_char->minorVersion);	DBGTRACE("%s Len: %08x:%08x\n", __FUNCTION__, char_len, sizeof(struct miniport_char));	memcpy(&ndis_driver->miniport_char, miniport_char, sizeof(struct miniport_char));	return NDIS_STATUS_SUCCESS;}#define VMALLOC_THRESHOLD 65536/* * Allocate mem. * */STDCALL unsigned int NdisAllocateMemory(void **dest,	                                unsigned int length,					unsigned int flags,					unsigned int highest_addr){	if(length < VMALLOC_THRESHOLD)		*dest = (void*) kmalloc(length, GFP_ATOMIC);	else		*dest = vmalloc(length);	if(*dest)		return NDIS_STATUS_SUCCESS;	DBGTRACE("%s: Allocatemem failed size=%d\n", __FUNCTION__, length);	return NDIS_STATUS_FAILURE;}/* * Allocate mem. * * Debug version? */STDCALL unsigned int NdisAllocateMemoryWithTag(void **dest,	                                       unsigned int length,					       unsigned int tag){	return NdisAllocateMemory(dest, length, 0, 0);}/* * Free mem. */STDCALL void NdisFreeMemory(void *adr, unsigned int length, unsigned int flags){	if(length < VMALLOC_THRESHOLD)		kfree(adr);	else		vfree(adr);}/* * Log an error. * * This function should not be STDCALL because it's a variable args function.  */void NdisWriteErrorLogEntry(struct ndis_handle *handle,	                    unsigned int error,			    unsigned int length,			    unsigned int p1){	printk(KERN_ERR "%s: error: %08x, %d %08x\n", __FUNCTION__, (int)error, (int) length, (int)p1);}STDCALL void NdisOpenConfiguration(unsigned int *status,	                           void **confhandle,				   struct ndis_handle *handle){	DBGTRACE("%s: Handle: %08x\n", __FUNCTION__, (int) handle);	*confhandle = (void*) handle;	*status = NDIS_STATUS_SUCCESS;}STDCALL void NdisCloseConfiguration(void *confhandle){	DBGTRACE("%s: confhandle: %08x\n", __FUNCTION__, (int) confhandle);}struct internal_parameters{	char *name;	struct ndis_setting_val val;};struct internal_parameters internal_parameters[] = { 	{		.name = "NdisVersion",		.val = {.type = 0, .data = {.intval = 0x00050000}}	},	{		.name = "Environment",		.val = {.type = 0, .data = {.intval = 1}}	},	{		.name = "BusType",		.val = {.type = 0, .data = {.intval = 5}}	},	{		.name = "media_type",		.val = {.type = 2, .data = {.ustring = {20, 22, "A\0u\0t\0o\0s\0e\0l\0e\0c\0t\0\0"}}}	},	{		.name = 0,		.val = {.type = 0, .data = {.intval = 0}}	}};STDCALL void NdisReadConfiguration(unsigned int *status,                                   struct ndis_setting_val **dest,				   struct ndis_handle *handle, struct ustring *key,				   unsigned int type){	struct ndis_setting *setting;	char keyname[1024];	int i;	unicodeToStr(keyname, key, sizeof(keyname));	/* Search built in keys */	for(i = 0; internal_parameters[i].name; i++)	{		if(strcmp(keyname, internal_parameters[i].name) == 0)		{			DBGTRACE("%s: Builting found value for %s\n", __FUNCTION__, keyname);						*dest = &internal_parameters[i].val;			*status = NDIS_STATUS_SUCCESS;			return;		}	}	/* Search parameters from inf-file */	list_for_each_entry(setting, &handle->driver->settings, list)	{		if(strcmp(keyname, setting->name) == 0)		{			DBGTRACE("%s: From inf found value for %s: %d\n", __FUNCTION__, keyname, setting->val.data.intval);			*dest =& setting->val;			*status = NDIS_STATUS_SUCCESS;			return;		}	}		DBGTRACE(KERN_INFO "%s: Key not found type:%d. key:%s\n", __FUNCTION__, type, keyname);	*dest = (struct ndis_setting_val*)0;	*status = NDIS_STATUS_FAILURE;}/* * Called by driver from the init callback. * * The adapter_ctx should be supplied to most other callbacks so we save * it in out handle. * */ STDCALL void NdisMSetAttributesEx(struct ndis_handle *handle,                                  void* adapter_ctx,				  unsigned int hangchecktime,				  unsigned int attributes,				  unsigned int adaptortype){	DBGTRACE("%s, %08x, %08x %d %08x, %d\n", __FUNCTION__, (int)handle, (int)adapter_ctx, hangchecktime, attributes, adaptortype);	if(attributes & 8)	{		pci_set_master(handle->pci_dev);	}		handle->adapter_ctx = adapter_ctx;}/* * Read information from the PCI config area * */  STDCALL unsigned int NdisReadPciSlotInformation(struct ndis_handle *handle,                                                unsigned int slot,						unsigned int offset,						char *buf,						unsigned int len){	int i;	for(i = 0; i < len; i++)	{		pci_read_config_byte(handle->pci_dev, offset+i, &buf[i]);	}	return len;}/* * Write information to the PCI config area * */  STDCALL unsigned int NdisWritePciSlotInformation(struct ndis_handle *handle,                                                 unsigned int slot,						 unsigned int offset,						 char *buf,						 unsigned int len){	int i;	for(i = 0; i < len; i++)	{		pci_write_config_byte(handle->pci_dev, offset+i, buf[i]);	}	return len;}/* * Read information about IRQ and other resources * * - This needs to be more general, and I'm not sure it's correct.. * - IOPort resources are not handled. */STDCALL void NdisMQueryAdapterResources(unsigned int *status,                                        struct ndis_handle *handle,					struct ndis_resource_list *resource_list,					unsigned int *size){	int i;	int len = 0;	struct pci_dev *pci_dev = handle->pci_dev;	struct ndis_resource_entry *entry;	DBGTRACE("%s handle: %08x. buf: %08x, len: %d. IRQ:%d\n", __FUNCTION__, (int)handle, (int)resource_list, *size, pci_dev->irq);	resource_list->version = 1;	resource_list->revision = 0;	/* 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->param1 = pci_resource_start(pci_dev, i);				entry->param2 = 0;		entry->param3 = 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->param1 = pci_dev->irq; //Level	entry->param2 = pci_dev->irq; //Vector	entry->param3 = -1;  //affinity	resource_list->length = len;	*size = (char*) (&resource_list->list[len]) - (char*)resource_list;	*status = NDIS_STATUS_SUCCESS;#ifdef DEBUG	{		DBGTRACE("resource list v%d.%d len %d, size=%d\n", resource_list->version, resource_list->revision, resource_list->length, *size);		for(i = 0; i < len; i++)		{			DBGTRACE("Resource: %d: %08x %08x %08x, %d\n", resource_list->list[i].type, resource_list->list[i].param1, resource_list->list[i].param2, resource_list->list[i].param3, resource_list->list[i].flags); 		}		}#endif	return;}/* * Just like ioremap */STDCALL unsigned int NdisMMapIoSpace(void **virt,                                     struct ndis_handle *handle,				     unsigned int physlo,				     unsigned int physhi,				     unsigned int len){	DBGTRACE("%s: %08x, %d\n", __FUNCTION__, (int)physlo, len);	*virt = ioremap(physlo, len);	if(*virt == NULL) {		printk(KERN_ERR "IORemap failed\n");		return NDIS_STATUS_FAILURE;	}		handle->mem_start = physlo;	handle->mem_end = physlo + len -1;	DBGTRACE("ioremap successful %08x\n", (int)*virt);	return NDIS_STATUS_SUCCESS;}/* * Just like iounmap */STDCALL void NdisMUnmapIoSpace(struct ndis_handle *handle,                               void *virtaddr,			       unsigned int len){	DBGTRACE("%s: %08x, %d\n", __FUNCTION__, (int)virtaddr, len);	iounmap(virtaddr);}STDCALL void NdisAllocateSpinLock(spinlock_t **lock){	*lock = kmalloc(sizeof(spinlock_t), GFP_KERNEL);	if(*lock)		spin_lock_init(*lock);}STDCALL void NdisFreeSpinLock(spinlock_t **lock){	if(!lock)	{		DBGTRACE("%s: NULL\n", __FUNCTION__);		return;       	}	if(*lock)		kfree(*lock);	*lock = NULL;}STDCALL void NdisAcquireSpinLock(spinlock_t **lock){	spin_lock(*lock);	}STDCALL void NdisReleaseSpinLock(spinlock_t **lock){	spin_unlock(*lock);	}STDCALL void NdisDprAcquireSpinLock(spinlock_t **lock){	spin_lock(*lock);	}STDCALL void NdisDprReleaseSpinLock(spinlock_t **lock){	spin_unlock(*lock);	}STDCALL unsigned int NdisMAllocateMapRegisters(struct ndis_handle *handle,                                               unsigned int dmachan,					       unsigned char dmasize,					       unsigned int basemap,					       unsigned int size){	DBGTRACE("%s: %d %d %d %d\n", __FUNCTION__, dmachan, dmasize, basemap, size);	return NDIS_STATUS_SUCCESS;}STDCALL void NdisMFreeMapRegisters(void *handle){	DBGTRACE("%s: %08x\n", __FUNCTION__, (int)handle);}STDCALL void NdisMAllocateSharedMemory(struct ndis_handle *handle,                                       unsigned int size,				       char cached,				       void **virt,				       struct ndis_phy_address *phys){	dma_addr_t p;	void *v = pci_alloc_consistent(handle->pci_dev, size, &p);  	if(!v)	{		printk(KERN_ERR "failed to allocate shared mem\n");	}	*(char**)virt = v;	phys->low = (unsigned int)p;	phys->high = 0;}STDCALL void NdisMFreeSharedMemory(struct ndis_handle *handle,                                   unsigned int size,				   char cached,				   void *virt,				   unsigned int physlow,				   unsigned int physhigh){	pci_free_consistent(handle->pci_dev, size, virt, physlow);}STDCALL void NdisAllocateBufferPool(unsigned int *status,                                    unsigned int *poolhandle,				    unsigned int size){	*poolhandle = 0x0000fff8;	*status = NDIS_STATUS_SUCCESS;}STDCALL void NdisFreeBufferPool(void *poolhandle){	DBGTRACE("%s: %08x\n", __FUNCTION__, (int)poolhandle);}STDCALL void NdisAllocateBuffer(unsigned int *status,                                void **buffer,				void *poolhandle,				void *virt,				unsigned int len){	struct ndis_buffer *my_buffer = kmalloc(sizeof(struct ndis_buffer), GFP_ATOMIC);	if(!my_buffer)	{		printk(KERN_ERR "%s failed\n", __FUNCTION__);		*status = NDIS_STATUS_FAILURE;		return;	}	memset(my_buffer, 0, sizeof(struct ndis_buffer));	my_buffer->data = virt;	my_buffer->next = 0;	my_buffer->len = len;	*buffer = my_buffer;		*status = NDIS_STATUS_SUCCESS;}STDCALL void NdisFreeBuffer(void *buffer){	if(buffer)	{		memset(buffer, 0, sizeof(struct ndis_buffer));		kfree(buffer);	}}STDCALL void NdisAdjustBufferLength(struct ndis_buffer *buf, unsigned int len){	buf->len = len;}STDCALL void NdisQueryBuffer(struct ndis_buffer *buf, void **adr, unsigned int *len){	*adr = buf->data;	*len = buf->len;}STDCALL void NdisQueryBufferSafe(struct ndis_buffer *buf, void **addr, unsigned int *len,                                 unsigned int priority){	*addr = buf->data;	*len = buf->len;}                                STDCALL void *NdisBufferVirtualAddress(struct ndis_buffer *buf)

⌨️ 快捷键说明

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