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

📄 ndis.c

📁 万能网卡驱动程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
{	return buf->data; }STDCALL unsigned long NdisBufferLength(struct ndis_buffer *buf){	return buf->len;}STDCALL void NdisAllocatePacketPool(unsigned int *status,                                    unsigned int *poolhandle,				    unsigned int size,				    unsigned int rsvlen){	DBGTRACE("%s: size=%d\n", __FUNCTION__, size);	*poolhandle = 0xa000fff4;	*status = NDIS_STATUS_SUCCESS;}STDCALL void NdisAllocatePacketPoolEx(unsigned int *status,                                      unsigned int *poolhandle,				      unsigned int size,				      unsigned int overflowsize,				      unsigned int rsvlen){	NdisAllocatePacketPool(status, poolhandle, size, rsvlen);}STDCALL void NdisFreePacketPool(void *poolhandle){	DBGTRACE("%s: %08x\n", __FUNCTION__, (int)poolhandle);}STDCALL void NdisAllocatePacket(unsigned int *status, struct ndis_packet **packet_out, void *poolhandle){	struct ndis_packet *packet = (struct ndis_packet*) kmalloc(sizeof(struct ndis_packet), GFP_ATOMIC);	if(!packet)	{		printk(KERN_ERR "%s failed\n", __FUNCTION__);		*packet_out = NULL;		*status = NDIS_STATUS_FAILURE;		return;	}	memset(packet, 0, sizeof(struct ndis_packet));	packet->oob_offset = (int)(&packet->timesent1) - (int)packet;	*packet_out = packet;	*status = NDIS_STATUS_SUCCESS;	}STDCALL void NdisFreePacket(void *packet){	if(packet)	{		memset(packet, 0, sizeof(struct ndis_packet));		kfree(packet);	}}/* * Bottom half of the timer function. */void ndis_timer_handler_bh(void *data){	struct ndis_timer *timer = (struct ndis_timer*) data;	STDCALL void (*func)(void *res1, void *data, void *res3, void *res4) = timer->func;	func(0, timer->ctx, 0, 0);	if(timer->repeat)	{		timer->timer.expires = jiffies + timer->repeat;		add_timer(&timer->timer);	}}/* * Top half of the timer function. */void ndis_timer_handler(unsigned long data){	struct ndis_timer *timer = (struct ndis_timer*) data;	schedule_work(&timer->bh);}STDCALL void NdisMInitializeTimer(struct ndis_timer **timer_handle,                                  struct ndis_handle *handle,				  void *func,				  void *ctx){	struct ndis_timer *timer;	DBGTRACE("%s: %08x %08x, %08x, %08x\n", __FUNCTION__ , (int)timer_handle, (int)handle, (int)func, (int)ctx);	timer = kmalloc(sizeof(struct ndis_timer), GFP_KERNEL);	if(!timer)		timer_handle = NULL;	init_timer(&timer->timer);	timer->timer.data = (unsigned long) timer;	timer->timer.function = &ndis_timer_handler;	timer->func = func;	timer->ctx = ctx;	INIT_WORK(&timer->bh, &ndis_timer_handler_bh, timer);	*timer_handle = timer;	DBGTRACE("Allocated timer at %08x\n", (int)timer);}/* * Start a one shot timer. */STDCALL void NdisSetTimer(struct ndis_timer **timer_handle, unsigned int ms){	struct ndis_timer *ndis_timer = *timer_handle;	ndis_timer->timer.expires = jiffies + (ms * HZ) / 1000;	ndis_timer->repeat = 0;	add_timer(&ndis_timer->timer);}/* * Start a repeated timer. */STDCALL void NdisMSetPeriodicTimer(struct ndis_timer **timer_handle,                                   unsigned int ms){	struct ndis_timer *ndis_timer = *timer_handle;	ndis_timer->timer.expires = jiffies + (ms * HZ) / 1000;	ndis_timer->repeat = (ms * HZ) / 1000;	add_timer(&ndis_timer->timer);}/* * Cancel a pending timer */STDCALL void NdisMCancelTimer(struct ndis_timer **timer_handle, char *canceled){	DBGTRACE("%s\n", __FUNCTION__);	(*timer_handle)->repeat = 0;	*canceled = del_timer_sync(&(*timer_handle)->timer);}/* * The driver asks ndis what mac it should use. If this * function returns failiure it will use it's default mac. */STDCALL void NdisReadNetworkAddress(unsigned int *status,                                    char * adr,				    unsigned int *len,				    void *conf_handle){	*len = 0;	*status = NDIS_STATUS_FAILURE;}STDCALL void NdisMRegisterAdapterShutdownHandler(struct ndis_handle *handle,                                                 void *ctx,						 void *func){	DBGTRACE("%s sp:%08x\n", __FUNCTION__ , getSp());}STDCALL void NdisMDeregisterAdapterShutdownHandler(struct ndis_handle *handle){	DBGTRACE("%s sp:%08x\n", __FUNCTION__ , getSp());}/* *  bottom half of the irq handler * */void ndis_irq_bh(void *data){	struct ndis_handle *handle = (struct ndis_handle *) data;	handle->driver->miniport_char.handle_interrupt(handle->adapter_ctx);}/* *  Top half of the irq handler * */irqreturn_t ndis_irq_th(int irq, void *data, struct pt_regs *pt_regs){	int handeled = 0;	int more_work = 0;	struct ndis_irq *irqhandle = (struct ndis_irq *) data;	struct ndis_handle *handle = irqhandle->handle; 	spin_lock(&irqhandle->spinlock);	handle->driver->miniport_char.isr(&handeled, &more_work, handle->adapter_ctx);	spin_unlock(&irqhandle->spinlock);	if(more_work)		schedule_work(&handle->irq_bh);		if(handeled)		return IRQ_HANDLED;	return IRQ_NONE;}/* * Register an irq * */STDCALL unsigned int NdisMRegisterInterrupt(struct ndis_irq **ndis_irq_ptr,                                            struct ndis_handle *handle,					    unsigned int vector,					    unsigned int level,					    char req_isr,					    char shared,					    unsigned int mode){	struct ndis_irq *ndis_irq; 	DBGTRACE("%s. %08x, vector:%d, level:%d, req_isr:%d, shared:%d, mode:%d sp:%08x\n", __FUNCTION__, (int)ndis_irq_ptr, vector, level, req_isr, shared, mode, (int)getSp());	*ndis_irq_ptr = (struct ndis_irq*) kmalloc(sizeof(struct ndis_irq), GFP_KERNEL);		if(!*ndis_irq_ptr)		return NDIS_STATUS_FAILURE;	ndis_irq = *ndis_irq_ptr;	handle->irq = vector;	spin_lock_init(&ndis_irq->spinlock);	ndis_irq->irq = vector;	ndis_irq->handle = handle;	spin_lock(&ndis_irq->spinlock);	spin_unlock(&ndis_irq->spinlock);	if(request_irq(vector, ndis_irq_th, SA_SHIRQ, "ndiswrapper", ndis_irq))	{		kfree(ndis_irq);		return NDIS_STATUS_FAILURE;	}	INIT_WORK(&handle->irq_bh, &ndis_irq_bh, handle);	return NDIS_STATUS_SUCCESS;}/* * Deregister an irq * */STDCALL void NdisMDeregisterInterrupt(struct ndis_irq **ndis_irq_ptr){	struct ndis_irq *ndis_irq = *ndis_irq_ptr;	DBGTRACE("%s: %08x %d %08x\n", __FUNCTION__, (int)ndis_irq, ndis_irq->irq, (int)ndis_irq->handle);	if(ndis_irq)	{		free_irq(ndis_irq->irq, ndis_irq);		kfree(ndis_irq);	}}/* * Run func synchorinized with the isr. * */typedef unsigned int (*sync_func_t)(void *ctx);STDCALL char NdisMSynchronizeWithInterrupt(struct ndis_irq **ndis_irq_ptr,                                           STDCALL sync_func_t func,					   void *ctx){	unsigned int ret;	unsigned long flags;	struct ndis_irq *ndis_irq = *ndis_irq_ptr;	DBGTRACE("%s: %08x %08x %08x %08x\n", __FUNCTION__, (int) ndis_irq, (int) ndis_irq_ptr, (int) func, (int) ctx);	spin_lock_irqsave(&ndis_irq->spinlock, flags);	ret = func(ctx);	spin_unlock_irqrestore(&ndis_irq->spinlock, flags);	DBGTRACE("%s: Past func\n", __FUNCTION__);	return ret;}/* * This function is not called in a format way. * It's called using a macro that referenced the opaque miniport-handler * */STDCALL void NdisIndicateStatus(struct ndis_handle *handle, unsigned int status, void *buf, unsigned int len){	DBGTRACE("%s %08x\n", __FUNCTION__, status);}/* * * * Called via function pointer. */STDCALL void NdisIndicateStatusComplete(struct ndis_handle *handle){	DBGTRACE("%s\n", __FUNCTION__);}/* * * * Called via function pointer. */STDCALL void NdisMIndicateReceivePacket(struct ndis_handle *handle, struct ndis_packet **packets, unsigned int nr_packets){	struct ndis_buffer *buffer;	struct ndis_packet *packet;	struct sk_buff *skb;	int i;	for(i = 0; i < nr_packets; i++)	{		packet = packets[i];		buffer = packet->buffer_head;		skb = dev_alloc_skb(buffer->len);		if(skb)		{			skb->dev = handle->net_dev;					eth_copy_and_sum(skb, buffer->data, buffer->len, 0);			skb_put(skb, buffer->len);			skb->protocol = eth_type_trans (skb, handle->net_dev);			handle->stats.rx_bytes += buffer->len;			netif_rx(skb);		}		handle->driver->miniport_char.return_packet(handle->adapter_ctx,  packet);	}}/* * * * Called via function pointer. */STDCALL void NdisMSendComplete(struct ndis_handle *handle, struct ndis_packet *packet, unsigned int status){	handle->stats.tx_bytes += packet->len;	ndis_sendpacket_done(handle, packet);}STDCALL unsigned long NDIS_BUFFER_TO_SPAN_PAGES(void *buffer){	DBGTRACE("%s\n", __FUNCTION__ );	return 1;}/* * Sleeps for the given number of microseconds */STDCALL void NdisMSleep(unsigned long us_to_sleep){	DBGTRACE("%s called to sleep for %lu us\n", __FUNCTION__, us_to_sleep);	if (us_to_sleep > 0)	{		schedule_timeout((us_to_sleep * HZ)/1000000);		DBGTRACE("%s woke up\n", __FUNCTION__);	} }STDCALL void NdisGetCurrentSystemTime(u64 *time){#define TICKSPERSEC             10000000#define SECSPERDAY              86400 /* 1601 to 1970 is 369 years plus 89 leap days */#define SECS_1601_TO_1970       ((369 * 365 + 89) * (u64)SECSPERDAY)#define TICKS_1601_TO_1970      (SECS_1601_TO_1970 * TICKSPERSEC)	struct timeval now;	u64 t; 	do_gettimeofday(&now);	t = (u64) now.tv_sec * TICKSPERSEC;	t += now.tv_usec * 10 + TICKS_1601_TO_1970;/*	DBGTRACE("%s: %llu\n", __FUNCTION__, t);*/	*time = t;}STDCALL unsigned int NdisMRegisterIoPortRange(void **virt, struct ndis_handle *handle, unsigned int start, unsigned int len){	DBGTRACE("%s %08x %08x\n", __FUNCTION__, start, len);	*virt = (void*) start;	return NDIS_STATUS_SUCCESS;}STDCALL void NdisMDeregisterIoPortRange(struct ndis_handle *handle, unsigned int start, unsigned int len, void* virt){	DBGTRACE("%s %08x %08x\n", __FUNCTION__, start, len);}spinlock_t atomic_lock = SPIN_LOCK_UNLOCKED;STDCALL long NdisInterlockedDecrement(long *val){	unsigned long flags;	long x;	spin_lock_irqsave(&atomic_lock, flags);	*val--;	x = *val;	spin_unlock_irqrestore(&atomic_lock, flags);	return x;}STDCALL long NdisInterlockedIncrement(long *val){	unsigned long flags;	long x;	spin_lock_irqsave(&atomic_lock, flags);	*val++;	x = *val;	spin_unlock_irqrestore(&atomic_lock, flags);	return x;}/* * Arguments: * ndis_handle MiniportAdapterHandle: Handle input to MiniportInitialize * int Dma64BitAddress: Boolean if NIC can handle 64 bit addresses * unsigned long MaximumPhysicalMapping: Number of bytes the NIC can transfer on a single DMA operation */STDCALL int NdisMInitializeScatterGatherDma(struct ndis_handle *handle,                                            int is64bit,                                            unsigned long maxtransfer){	DBGTRACE("NdisMInitializeScatterGatherDma: 64bit=%d, maxtransfer=%ld\n", is64bit, maxtransfer);	handle->use_scatter_gather = 1;	return NDIS_STATUS_SUCCESS;}STDCALL unsigned int NdisMGetDmaAlignment(struct ndis_handle *handle){	DBGTRACE("%s\n", __FUNCTION__);	return PAGE_SIZE;}STDCALL void NdisQueryBufferOffset(struct ndis_buffer *buffer, unsigned int *offset, unsigned int *length){	*offset = 0;	*length = buffer->len;}STDCALL int NdisSystemProcessorCount(void){	return NR_CPUS;}DECLARE_WAIT_QUEUE_HEAD(event_wq);STDCALL void NdisInitializeEvent(struct ndis_event *event){	DBGTRACE("%s %08x\n", __FUNCTION__, (int)event);	event->state = 0;}                                                                                                                                                                                                                                    STDCALL int NdisWaitEvent(struct ndis_event *event, int timeout){	DBGTRACE("%s %08x %08x\n", __FUNCTION__, (int)event, timeout);	wait_event(event_wq, event->state == 1);	DBGTRACE("%s %08x Woke up\n", __FUNCTION__, (int)event);	return 1;}STDCALL void NdisSetEvent(struct ndis_event *event){	event->state = 1;	wake_up(&event_wq);}STDCALL void NdisResetEvent(struct ndis_event *event){	DBGTRACE("%s %08x\n", __FUNCTION__, (int)event);	event->state = 0;}LIST_HEAD(worklist);spinlock_t worklist_lock = SPIN_LOCK_UNLOCKED;static void worker(void *context){	unsigned long flags;	struct ndis_workentry *workentry;	struct ndis_work *ndis_work;	DBGTRACE("%s\n", __FUNCTION__);	while(1)	{		spin_lock_irqsave(&worklist_lock, flags);		if(!list_empty(&worklist))		{			workentry = (struct ndis_workentry*) worklist.next;			list_del(&workentry->list);		}		else			workentry = 0;		spin_unlock_irqrestore(&worklist_lock, flags);		if(!workentry)		{			DBGTRACE("%s No more work\n", __FUNCTION__);			break;		}				ndis_work = workentry->work;		kfree(workentry);		DBGTRACE("%s Calling work at %08x (rva %08x)with parameter %08x\n", __FUNCTION__, (int)ndis_work->func, (int)ndis_work->func - image_offset, (int)ndis_work->ctx);		ndis_work->func(ndis_work, ndis_work->ctx);	}		}struct work_struct work;void init_ndis_work(void){	INIT_WORK(&work, &worker, NULL); }STDCALL void NdisScheduleWorkItem(struct ndis_work *ndis_work){	unsigned long flags;	struct ndis_workentry *workentry;	DBGTRACE("%s\n", __FUNCTION__);	workentry = kmalloc(sizeof(*workentry), GFP_ATOMIC);	if(!workentry)	{		BUG();	}	workentry->work = ndis_work;		spin_lock_irqsave(&worklist_lock, flags);	list_add_tail(&workentry->list, &worklist);	spin_unlock_irqrestore(&worklist_lock, flags);		schedule_work(&work);}                                                                                                                                                                                                                                     /* Unimplemented...*/STDCALL void NdisInitAnsiString(void *src, void *dst) {UNIMPL();}STDCALL void NdisOpenConfigurationKeyByName(unsigned int *status, void *handle, void *key, void *subkeyhandle){UNIMPL();}STDCALL void NdisWriteConfiguration(unsigned int *status, void *handle, void *keyword, void *val){UNIMPL();}STDCALL unsigned int NdisAnsiStringToUnicodeString(void *dst, void *src){UNIMPL();return 0;}STDCALL void NdisMGetDeviceProperty(void *handle, void **p1, void **p2, void **p3, void**p4, void**p5){UNIMPL();}STDCALL unsigned long NdisWritePcmciaAttributeMemory(void *handle, unsigned int offset, void *buffer, unsigned int length){UNIMPL();return 0;}STDCALL unsigned long NdisReadPcmciaAttributeMemory(void *handle, unsigned int offset, void *buffer, unsigned int length){UNIMPL();return 0;}STDCALL void NdisUnicodeStringToAnsiString(void){UNIMPL();}STDCALL void NdisInitializeString(void){UNIMPL();}STDCALL void NdisUnchainBufferAtBack(void){UNIMPL();}STDCALL void NdisGetFirstBufferFromPacketSafe(void){UNIMPL();}STDCALL void NdisUnchainBufferAtFront(void){UNIMPL();}STDCALL void NdisMSetAttributes(void){UNIMPL();}STDCALL void EthFilterDprIndicateReceiveComplete(void){UNIMPL();}STDCALL void EthFilterDprIndicateReceive(void){UNIMPL();}STDCALL void NdisMStartBufferPhysicalMapping(void){UNIMPL();}STDCALL void NdisMCompleteBufferPhysicalMapping(void){UNIMPL();}STDCALL void NdisMPciAssignResources(void){UNIMPL();}

⌨️ 快捷键说明

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