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

📄 aironet4500_proc.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *	 Aironet 4500 Pcmcia driver * *		Elmer Joandi, Januar 1999 *	Copyright GPL *	 * *	Revision 0.1 ,started  30.12.1998 * * */#include <linux/module.h>#include <linux/init.h>#include <linux/config.h>#include <linux/kernel.h>#include <linux/version.h>#include <linux/sched.h>#include <linux/ptrace.h>#include <linux/malloc.h>#include <linux/string.h>#include <linux/timer.h>#include <linux/interrupt.h>#include <linux/in.h>#include <asm/io.h>#include <asm/system.h>#include <asm/bitops.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/skbuff.h>#include <linux/if_arp.h>#include <linux/ioport.h>#ifdef CONFIG_PROC_FS#ifdef CONFIG_PROC_FS#include <linux/sysctl.h>#else#error awc driver needs CONFIG_PROC_FS#endif#include "aironet4500.h"#include "aironet4500_rid.c"#define AWC_STR_SIZE 	0x2ff0#define DEV_AWC_INFO 	1#define DEV_AWC 	1struct awc_proc_private{	struct ctl_table_header *	sysctl_header;  	struct ctl_table	*	proc_table;  	struct ctl_table		proc_table_device_root[2];  	struct ctl_table		proc_table_sys_root[2];	char 				proc_name[10];};	        static char awc_drive_info[AWC_STR_SIZE]="Zcom \n\0";static char awc_proc_buff[AWC_STR_SIZE]="\0";static int  awc_int_buff;static struct awc_proc_private awc_proc_priv[MAX_AWCS]; extern int awc_proc_unset_device(int device_number);int awc_proc_format_array(int write,char * buff, size_t * len, struct awc_rid_dir * rid_dir, struct aironet4500_RID * rid){  u8 * data = rid_dir->buff + rid->offset;  int pos = 0;  int null_past = 0;  int hex = ((rid->mask == 0xff) && (rid->value == 0x0 ));  int string = ((rid->mask == 0) && (rid->value == 0 ));  u32 val =0;  int bytes = (rid->bits / 8);  int ch =0;  int i,k;  int array_len = rid->array;  int nullX = 0;   	AWC_ENTRY_EXIT_DEBUG("awc_proc_format_array");      if (rid->bits %8 ) bytes +=1;          if (bytes > 4 && rid->array == 1){     	array_len = bytes;     	bytes = 1;     	hex = 1;     };     if (bytes < 1 || bytes > 4){     	printk(KERN_ERR " weird number of bytes %d in aironet rid \n",bytes);     	return -1;     };    	     DEBUG(0x20000,"awc proc array  bytes %d",bytes);     DEBUG(0x20000," hex %d",hex);     DEBUG(0x20000," string %d",string);     DEBUG(0x20000," array_len %d \n",array_len);     DEBUG(0x20000," offset %d \n",rid->offset);     if (!write){	for (i=0; i < array_len ; i++){			if 	(bytes <= 1 ) val = data[i*bytes];		else if (bytes <= 2 ) val = *((u16 *)&data[i*bytes]);		else if (bytes <= 4 ) val = *((u32 *)&data[i*bytes]);				if (rid->null_terminated && !val)			null_past =1;			 		if (hex && !string)			for (k=0; k <bytes; k++)				pos += sprintf(buff+pos, "%02x",(unsigned char ) data[i*bytes +k]);		else if (string)			pos += sprintf(buff+pos, "%c",val);		else	pos += sprintf(buff+pos, "%c",val);		DEBUG(0x20000, "awcproc %x %x \n",data[i], val);	};	     } else {     	for (i=0; i < array_len ; i++){     	     		DEBUG(0x20000, "awcproc %x %x \n",data[i], buff[i]);     		if (hex && ! string){     			     			val = 0;     			     			for (k=0; k < bytes; k++){     				val <<= 8;       				ch = *(buff + 2*i*bytes +k + nullX);     				if (ch >= '0' && ch <='9')     					ch -= '0';     				if (ch >= 'A' && ch <='F')     					ch -= 'A'+ 0xA;     				if (ch >= 'a' && ch <='f')     					ch -= 'a'+ 0xA;				val += ch <<4;				k++;				     				ch = *(buff + 2*i*bytes +k + nullX);     				if (val == 0 && (ch == 'X' || ch == 'x')){     					nullX=2;     					val = 0;     					k = -1;     					continue;     				};     				if (ch >= '0' && ch <='9')     					ch -= '0';     				if (ch >= 'A' && ch <='F')     					ch -= 'A'+ 0xA;     				if (ch >= 'a' && ch <='f')     					ch -= 'a'+ 0xA;     					     				val += ch;     				if (i*bytes > *len )     					val = 0;	     			}			if (rid->bits <=8 ) 	            data[i*bytes]  = val;			else if (rid->bits <=16 ) *((u16 *)&data[i*bytes]) = val;			else if (rid->bits <=32 ) *((u32 *)&data[i*bytes]) = val;     			if (!val) null_past=1;	     			     		} else {     			for (k=0; k < bytes; k++){     				data[i*bytes +k] = *(buff + i*bytes +k);     				if (i*bytes +k > *len || !data[i*bytes +k])     					null_past = 1;;     			}     	     		}     		if (null_past){     			if (rid->bits <=8 ) 	            data[i*bytes]  = 0;			else if (rid->bits <=16 ) *((u16 *)&data[i*bytes]) = 0;			else if (rid->bits <=32 ) *((u32 *)&data[i*bytes]) = 0;		}     	}     	     };     	//     *len = pos;   	AWC_ENTRY_EXIT_DEBUG("awc_proc_format_array");     return 0;	};int awc_proc_format_bits(int write,u32 * buff, size_t* lenp, struct awc_rid_dir * rid_dir, struct aironet4500_RID * rid){  u8 * data = rid_dir->buff + rid->offset;  u32 val = 0;  int not_bool = 0;   	AWC_ENTRY_EXIT_DEBUG("awc_proc_format_bits");	if ((rid->bits == 8 && rid->mask == 0xff) 	|| 	    (rid->bits == 16 && rid->mask == 0xffff) 	|| 	    (rid->bits == 32 && rid->mask == 0xffffffff)   )	    not_bool = 1;	    	if (rid->bits <=8 ) 		val = 		*data;	else if (rid->bits <=16 ) 	val = *((u16 *)data);	else if (rid->bits <=32 ) 	val = *((u32 *)data);	DEBUG(0x20000,"awc proc int enter data %x \n",val);	DEBUG(0x20000,"awc proc int enter buff %x \n",*buff);	DEBUG(0x20000,"awc proc int enter intbuff %x \n",awc_int_buff);	DEBUG(0x20000,"awc proc int enter lenp  %x \n",*lenp);	if (!write){		if (rid->mask)			val &= rid->mask;		if (!not_bool && rid->mask && 		    ((val & rid->mask) == (rid->value & rid->mask)))			*buff = 1;		else if (!not_bool) *buff = 0;		else *buff = val;	} else {		if (not_bool){			val &= ~rid->mask; 			val |= (*buff & rid->mask);		} else {			if (*buff){				val &= ~rid->mask;				if (rid->value)					val |= rid->mask & rid->value;				else 	val |= rid->mask & ~rid->value;			} else val &= ~rid->mask;		};		if (rid->bits == 8) *data = val & 0xff;		if (rid->bits == 16) *((u16*)data) = val &0xffff;		if (rid->bits == 32) *((u32*)data) = val &0xffffffff; 		}	DEBUG(0x20000,"awc proc int buff %x \n",awc_int_buff);	if (rid->bits <=8 ) 		val = 		*data;	else if (rid->bits <=16 ) 	val = *((u16 *)data);	else if (rid->bits <=32 ) 	val = *((u32 *)data);	DEBUG(0x20000,"awc proc int data %x \n",val);	// both of them are crazy//	*lenp = sizeof(int);// 	*lenp += 1; 	  	AWC_ENTRY_EXIT_DEBUG("exit");	return 0;};int awc_proc_fun(ctl_table *ctl, int write, struct file * filp,                           void *buffer, size_t *lenp){        int retv =-1;   	struct awc_private *priv = NULL;	unsigned long  flags;//	int device_number = (int ) ctl->extra1;	struct awc_rid_dir * rid_dir;	struct net_device * dev= NULL;	struct aironet4500_RID * rid = (struct aironet4500_RID * ) ctl->extra2;	   	AWC_ENTRY_EXIT_DEBUG("awc_proc_fun");	if (!write && filp)	 if (filp->f_pos){//	 	printk(KERN_CRIT "Oversize read\n");		*lenp = 0;// hack against reading til eof	  	return	0;	 } 	MOD_INC_USE_COUNT;	rid_dir = ((struct awc_rid_dir *)ctl->extra1);	dev = rid_dir->dev;		if (!dev){		printk(KERN_ERR " NO device here \n");		goto final;	}	if(ctl->procname == NULL || awc_drive_info == NULL ){		printk(KERN_WARNING " procname is NULL in sysctl_table or awc_mib_info is NULL \n at awc module\n ");		MOD_DEC_USE_COUNT;		return -1;	}	priv = (struct awc_private * ) dev->priv; 	if ((rid->selector->read_only || rid->read_only) && write){		printk(KERN_ERR "This value is read-only \n");		goto final;	};	if (!write && rid->selector->may_change) {

⌨️ 快捷键说明

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