📄 ndis.c
字号:
{ 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 + -