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

📄 airo.c

📁 pcmcia source code
💻 C
📖 第 1 页 / 共 5 页
字号:
 * will be called with fill set to zero. */static void airo_fill_inode( struct inode *i, int fill ) {	if ( fill ) {		MOD_INC_USE_COUNT;	} else {		MOD_DEC_USE_COUNT;	}}#endif#if (LINUX_VERSION_CODE < 0x20311)static struct file_operations airo_file_ops = {	NULL, // lseek	NULL, // read	NULL, // write	NULL, // readdir	NULL, // select	NULL, // ioctl	NULL, // mmap	NULL, // open	NULL, // release};static struct inode_operations airo_inode_ops = {	&airo_file_ops,	NULL, // create	NULL, // lookup};static struct proc_dir_entry airo_entry = {	0,	7,	"aironet",	S_IFDIR | S_IRUGO | S_IXUGO,	1,	0, 0,	44,	&airo_inode_ops,	0, // get_info#if ((LINUX_VERSION_CODE > 0x20155) && (LINUX_VERSION_CODE < 0x20311))	airo_fill_inode#endif};#elsestatic struct proc_dir_entry *airo_entry = 0;#endif#if (LINUX_VERSION_CODE < 0x20311)static struct proc_dir_entry wepkey_entry = {	0, 6, "WepKey",	S_IFREG | S_IWUSR, 2, 0, 0,	13,	&proc_inode_wepkey_ops, NULL};static struct proc_dir_entry statsdelta_entry = {	0, 10, "StatsDelta",	S_IFREG | S_IRUGO | S_IWUSR , 2, 0, 0,	13,	&proc_inode_statsdelta_ops, NULL};static struct proc_dir_entry stats_entry = {	0, 5, "Stats",	S_IFREG | S_IRUGO , 2, 0, 0,	13,	&proc_inode_stats_ops, NULL};static struct proc_dir_entry status_entry = {	0, 6, "Status",	S_IFREG | S_IRUGO , 2, 0, 0,	13,	&proc_inode_status_ops, NULL};static struct proc_dir_entry SSID_entry = {	0, 4, "SSID",	S_IFREG | S_IRUGO | S_IWUSR, 2, 0, 0,	13,	&proc_inode_SSID_ops, NULL};static struct proc_dir_entry APList_entry = {	0, 6, "APList",	S_IFREG | S_IRUGO | S_IWUSR, 2, 0, 0,	13,	&proc_inode_APList_ops, NULL};static struct proc_dir_entry config_entry = {	0, 6, "Config",	S_IFREG | S_IRUGO | S_IWUSR, 2, 0, 0,	13,	&proc_inode_config_ops, NULL};#endifstruct proc_data {	int release_buffer;	int readlen;	char *rbuffer;	int writelen;	int maxwritelen;	char *wbuffer;	void (*on_close) (struct inode *, struct file *);};#if (LINUX_VERSION_CODE < 0x20311)static int setup_proc_entry( struct net_device *dev,			     struct airo_info *apriv ) {	/* First setup the device directory */	memset( &apriv->proc_entry, 0, sizeof( apriv->proc_entry ) );	apriv->proc_entry.namelen = strlen( dev->name );	apriv->proc_entry.name = dev->name;	apriv->proc_entry.mode = S_IFDIR | S_IRUGO | S_IXUGO;	apriv->proc_entry.nlink = 2;	apriv->proc_entry.ops = airo_entry.ops;	PROC_REGISTER( &airo_entry, &apriv->proc_entry );		/* Setup the StatsDelta */	memcpy( &apriv->proc_statsdelta_entry, &statsdelta_entry, 		sizeof( statsdelta_entry ) );	apriv->proc_statsdelta_entry.data = dev;	PROC_REGISTER( &apriv->proc_entry, 		       &apriv->proc_statsdelta_entry );		/* Setup the Stats */	memcpy( &apriv->proc_stats_entry, &stats_entry, 		sizeof( stats_entry ) );	apriv->proc_stats_entry.data = dev;	PROC_REGISTER( &apriv->proc_entry, 		       &apriv->proc_stats_entry );		/* Setup the Status */	memcpy( &apriv->proc_status_entry, &status_entry, 		sizeof( status_entry ) );	apriv->proc_status_entry.data = dev;	PROC_REGISTER( &apriv->proc_entry, 		       &apriv->proc_status_entry );		/* Setup the Config */	memcpy( &apriv->proc_config_entry, &config_entry, 		sizeof( config_entry ) );	apriv->proc_config_entry.data = dev;	PROC_REGISTER( &apriv->proc_entry, 		       &apriv->proc_config_entry );	/* Setup the SSID */	memcpy( &apriv->proc_SSID_entry, &SSID_entry, sizeof( SSID_entry ) );	apriv->proc_SSID_entry.data = dev;	PROC_REGISTER( &apriv->proc_entry, 		       &apriv->proc_SSID_entry );		/* Setup the APList */	memcpy( &apriv->proc_APList_entry, &APList_entry, 		sizeof( APList_entry ) );	apriv->proc_APList_entry.data = dev;	PROC_REGISTER( &apriv->proc_entry, 		       &apriv->proc_APList_entry );		/* Setup the WepKey */	memcpy( &apriv->proc_wepkey_entry, &wepkey_entry, 		sizeof( wepkey_entry ) );	apriv->proc_wepkey_entry.data = dev;	PROC_REGISTER( &apriv->proc_entry, 		       &apriv->proc_wepkey_entry );		return 0;}static int takedown_proc_entry( struct net_device *dev,				struct airo_info *apriv ) {	if ( !apriv->proc_entry.namelen ) return 0;	PROC_UNREGISTER( &apriv->proc_entry, &apriv->proc_statsdelta_entry );	PROC_UNREGISTER( &apriv->proc_entry, &apriv->proc_stats_entry );	PROC_UNREGISTER( &apriv->proc_entry, &apriv->proc_status_entry );	PROC_UNREGISTER( &apriv->proc_entry, &apriv->proc_config_entry );	PROC_UNREGISTER( &apriv->proc_entry, &apriv->proc_SSID_entry );	PROC_UNREGISTER( &apriv->proc_entry, &apriv->proc_APList_entry );	PROC_UNREGISTER( &apriv->proc_entry, &apriv->proc_wepkey_entry );	PROC_UNREGISTER( &airo_entry, &apriv->proc_entry );	return 0;}#elsestatic int setup_proc_entry( struct net_device *dev,			     struct airo_info *apriv ) {	struct proc_dir_entry *entry;	/* First setup the device directory */	apriv->proc_entry = create_proc_entry(dev->name,					      S_IFDIR|S_IRUGO|S_IXUGO,					      airo_entry);	/* Setup the StatsDelta */	entry = create_proc_entry("StatsDelta",				  S_IFREG | S_IRUGO | S_IWUSR,				  apriv->proc_entry);	entry->data = dev;/*	This is what was needed right up to the last few versions        of 2.3:	entry->ops = &proc_inode_statsdelta_ops;*/	entry->proc_fops = &proc_statsdelta_ops;		/* Setup the Stats */	entry = create_proc_entry("Stats",				  S_IFREG | S_IRUGO,				  apriv->proc_entry);	entry->data = dev;	entry->proc_fops = &proc_stats_ops;		/* Setup the Status */	entry = create_proc_entry("Status",				  S_IFREG | S_IRUGO,				  apriv->proc_entry);	entry->data = dev;	entry->proc_fops = &proc_status_ops;		/* Setup the Config */	entry = create_proc_entry("Config",				  S_IFREG | S_IRUGO | S_IWUGO,				  apriv->proc_entry);	entry->data = dev;	entry->proc_fops = &proc_config_ops;	/* Setup the SSID */	entry = create_proc_entry("SSID",				  S_IFREG | S_IRUGO | S_IWUGO,				  apriv->proc_entry);	entry->data = dev;	entry->proc_fops = &proc_SSID_ops;	/* Setup the APList */	entry = create_proc_entry("APList",				  S_IFREG | S_IRUGO | S_IWUGO,				  apriv->proc_entry);	entry->data = dev;	entry->proc_fops = &proc_APList_ops;	/* Setup the WepKey */	entry = create_proc_entry("WepKey",				  S_IFREG | S_IWUSR,				  apriv->proc_entry);	entry->data = dev;	entry->proc_fops = &proc_wepkey_ops;	return 0;}static int takedown_proc_entry( struct net_device *dev,				struct airo_info *apriv ) {	if ( !apriv->proc_entry->namelen ) return 0;	remove_proc_entry("Stats",apriv->proc_entry);	remove_proc_entry("StatsDelta",apriv->proc_entry);	remove_proc_entry("Status",apriv->proc_entry);	remove_proc_entry("Config",apriv->proc_entry);	remove_proc_entry("SSID",apriv->proc_entry);	remove_proc_entry("APList",apriv->proc_entry);	remove_proc_entry("WepKey",apriv->proc_entry);	remove_proc_entry(dev->name,airo_entry);	return 0;}#endif/* *  What we want from the proc_fs is to be able to efficiently read *  and write the configuration.  To do this, we want to read the *  configuration when the file is opened and write it when the file is *  closed.  So basically we allocate a read buffer at open and fill it *  with data, and allocate a write buffer and read it at close. *//* *  The read routine is generic, it relies on the preallocated rbuffer *  to supply the data. */#if (LINUX_VERSION_CODE > 0x20155)static ssize_t proc_read( struct file *file,			  char *buffer,			  size_t len,			  loff_t *offset )#elsestatic int proc_read( struct inode *inode,		      struct file *file,		      char *buffer,		      int len ) #endif{	int i;	int pos;	struct proc_data *priv = (struct proc_data*)file->private_data;		if( !priv->rbuffer ) return -EINVAL;	#if (LINUX_VERSION_CODE > 0x20155)	pos = *offset;#else	pos = file->f_pos;#endif	for( i = 0; i+pos < priv->readlen && i < len; i++ ) {		put_user( priv->rbuffer[i+pos], buffer+i );	}#if (LINUX_VERSION_CODE > 0x20155)	*offset += i;#else	file->f_pos += i;#endif	return i;}/* *  The write routine is generic, it fills in a preallocated rbuffer *  to supply the data. */#if (LINUX_VERSION_CODE > 0x20155)static ssize_t proc_write( struct file *file,			   const char *buffer,			   size_t len,			   loff_t *offset ) #elsestatic int proc_write( struct inode *inode,		       struct file *file,		       const char *buffer,		       int len ) #endif{	int i;	int pos;	struct proc_data *priv = (struct proc_data*)file->private_data;		if ( !priv->wbuffer ) {		return -EINVAL;	}	#if (LINUX_VERSION_CODE > 0x20155)	pos = *offset;#else	pos = file->f_pos;#endif		for( i = 0; i + pos <  priv->maxwritelen &&		     i < len; i++ ) {#if (LINUX_VERSION_CODE > 0x20155)		get_user( priv->wbuffer[i+pos], buffer + i );#else		priv->wbuffer[i+pos] = get_user( buffer + i );#endif	}	if ( i+pos > priv->writelen ) priv->writelen = i+file->f_pos;#if (LINUX_VERSION_CODE > 0x20155)	*offset += i;#else	file->f_pos += i;#endif	return i;}static int proc_status_open( struct inode *inode, struct file *file ) {	struct proc_data *data;	struct proc_dir_entry *dp = inode->u.generic_ip;	struct net_device *dev = dp->data;	struct airo_info *apriv = (struct airo_info *)dev->priv;	CapabilityRid cap_rid;	StatusRid status_rid;		MOD_INC_USE_COUNT;		dp = (struct proc_dir_entry *) inode->u.generic_ip;		file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL);	memset(file->private_data, 0, sizeof(struct proc_data));	data = (struct proc_data *)file->private_data;	data->rbuffer = kmalloc( 2048, GFP_KERNEL );		readStatusRid(apriv, &status_rid);	readCapabilityRid(apriv, &cap_rid);		sprintf( data->rbuffer, "Mode: %x\n"		 "Signal Strength: %d\n"		 "Signal Quality: %d\n"		 "SSID: %-.*s\n"		 "AP: %-.16s\n"		 "Freq: %d\n"		 "BitRate: %dmbs\n"		 "Driver Version: %s\n"		 "Device: %s\nManufacturer: %s\nFirmware Version: %s\n"		 "Radio type: %x\nCountry: %x\nHardware Version: %x\n"		 "Software Version: %x\nSoftware Subversion: %x\n"		 "Boot block version: %x\n",		 (int)status_rid.mode,		 (int)status_rid.normalizedSignalStrength,		 (int)status_rid.signalQuality,		 (int)status_rid.SSIDlen,		 status_rid.SSID,		 status_rid.apName,		 (int)status_rid.channel,		 (int)status_rid.currentXmitRate/2,		 version,		 cap_rid.prodName,		 cap_rid.manName,		 cap_rid.prodVer,		 cap_rid.radioType,		 cap_rid.country,		 cap_rid.hardVer,		 (int)cap_rid.softVer,		 (int)cap_rid.softSubVer,		 (int)cap_rid.bootBlockVer );	data->readlen = strlen( data->rbuffer );	return 0;}static int proc_stats_rid_open(struct inode*, struct file*, u16);static int proc_statsdelta_open( struct inode *inode, 				 struct file *file ) {	if (file->f_mode&FMODE_WRITE) {	return proc_stats_rid_open(inode, file, RID_STATSDELTACLEAR);	}	return proc_stats_rid_open(inode, file, RID_STATSDELTA);}static int proc_stats_open( struct inode *inode, struct file *file ) {	return proc_stats_rid_open(inode, file, RID_STATS);}static int proc_stats_rid_open( struct inode *inode, 				struct file *file,				u16 rid ) {	struct proc_data *data;	struct proc_dir_entry *dp = inode->u.generic_ip;	struct net_device *dev = dp->data;	struct airo_info *apriv = (struct airo_info *)dev->priv;	StatsRid stats;	int i, j;	int *vals = stats.vals;	MOD_INC_USE_COUNT;			dp = (struct proc_dir_entry *) inode->u.generic_ip;		file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL);	memset(file->private_data, 0, sizeof(struct proc_data));	data = (struct proc_data *)file->private_data;	data->rbuffer = kmalloc( 4096, GFP_KERNEL );		readStatsRid(apriv, &stats, rid);        j = 0;	for(i=0; (int)statsLabels[i]!=-1 && 		    i*4<stats.len; i++){                if (!statsLabels[i]) continue;		if (j+strlen(statsLabels[i])+16>4096) {			printk(KERN_WARNING			       "airo: Potentially disasterous buffer overflow averted!\n");			break;		}		j+=sprintf(data->rbuffer+j, "%s: %d\n", statsLabels[i], vals[i]);        }	if (i*4>=stats.len){		printk(KERN_WARNING		       "airo: Got a short rid\n");	}	data->readlen = j;	return 0;}static int get_dec_u16( char *buffer, int *start, int limit ) {	u16 value;	int valid = 0;	for( value = 0; buffer[*start] >= '0' &&		     buffer[*start] <= '9' &&		     *start < limit; (*start)++ ) {		valid = 1;		value *= 10;		value += buffer[*start] - '0';	}	if ( !valid ) return -1;	return value;}static void checkThrottle(ConfigRid *config) {	int i;

⌨️ 快捷键说明

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