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

📄 chandev.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		case (del_force_stridx*stridx_mult)|iscomma:			if(ints[0]!=1)				goto BadArgs;			chandev_del_force(ints[1]);			break;		case (use_devno_names_stridx*stridx_mult):			use_devno_names=1;			break;		case (dont_use_devno_names_stridx*stridx_mult):			use_devno_names=0;	        case (add_model_stridx*stridx_mult)|iscomma:			if(ints[0]<3)				goto BadArgs;			if(ints[0]==3)			{				ints[0]=4;				ints[4]=-1;			}			chandev_add_model(ints[1],ints[2],ints[3],ints[4]);		break;		case (del_model_stridx*stridx_mult)|iscomma:			if(ints[0]!=2)				goto BadArgs;			chandev_del_model(ints[1],ints[2]);			break;		case del_all_models_stridx*stridx_mult:			chandev_remove_all_models();			break;		default:			goto BadArgs;		}			}	return(1); BadArgs:	chandev_print_args();	return(0);}__setup("chandev=",chandev_setup);int chandev_doprobe(chandev_force *force,chandev *read_chandev,chandev *write_chandev){	chandev_probelist *probe;	chandev_model_info *model_info;	chandev_probeinfo probeinfo;	int  retval=-1,hint=-1;	model_info=read_chandev->model_info;	if(read_chandev->model_info!=write_chandev->model_info||	   (force&&((force->chan_type&model_info->chan_type)==0)))		return(-1); /* inconsistent */	for(probe=chandev_probelist_head;	    probe!=NULL;	    probe=probe->next)	{		if(probe->chan_type&model_info->chan_type)		{			if(use_devno_names)				probeinfo.devif_num=read_chandev->devno;			else				probeinfo.devif_num=-1;			probeinfo.read_irq=read_chandev->irq;			probeinfo.write_irq=write_chandev->irq;						probeinfo.max_port_no=model_info->max_port_no;			if(force)			{				probeinfo.forced_port_no=force->port_no;				if(force->devif_num!=-1)					probeinfo.devif_num=force->devif_num;				probeinfo.do_ip_checksumming=force->do_ip_checksumming;				probeinfo.use_hw_stats=force->use_hw_stats;							}			else			{				probeinfo.forced_port_no=-1;				probeinfo.do_ip_checksumming=FALSE;				probeinfo.use_hw_stats=FALSE;				if(probe->chan_type&lcs)				{					hint=(read_chandev->devno&0xFF)>>1;					if(hint>model_info->max_port_no)					{				/* The card is possibly emulated e.g P/390 */				/* or possibly configured to use a shared */				/* port configured by osa-sf. */						hint=0;					}				}			}			probeinfo.hint_port_no=hint;			retval=probe->probefunc(&probeinfo);			if(retval==0)				break;		}	}	return(retval);}void chandev_probe(void){	chandev *read_chandev,*write_chandev,*curr_chandev;	chandev_force *curr_force;	chandev_noauto_range *curr_noauto;	chandev_collect_devices();	for(curr_force=chandev_force_head;curr_force!=NULL;		    curr_force=curr_force->next)	{		for(read_chandev=chandev_head;		    read_chandev!=NULL;		    read_chandev=read_chandev->next)			if(read_chandev->devno==curr_force->read_devno)			{				for(write_chandev=chandev_head;				    write_chandev!=NULL;				    write_chandev=write_chandev->next)					if(write_chandev->devno==					   curr_force->write_devno)					{						if(chandev_doprobe(curr_force,								read_chandev,								write_chandev)==0)						{							chandev_remove(read_chandev);							chandev_remove(write_chandev);							goto chandev_probe_skip;						}					}			}	chandev_probe_skip:	}	for(curr_chandev=chandev_head;		    curr_chandev!=NULL;		    curr_chandev=curr_chandev->next)	{		for(curr_noauto=chandev_noauto_head;curr_noauto!=NULL;		    curr_noauto=curr_noauto->next)		{			if(curr_chandev->devno>=curr_noauto->lo_devno&&			   curr_chandev->devno<=curr_noauto->hi_devno)			{				chandev_remove(curr_chandev);				break;			}		}	}	for(curr_chandev=chandev_head;curr_chandev!=NULL;	    curr_chandev=curr_chandev->next)	{		if(curr_chandev->next&&curr_chandev->model_info==		   curr_chandev->next->model_info)		{						chandev_doprobe(NULL,curr_chandev,curr_chandev->next);			curr_chandev=curr_chandev->next;		}	}	chandev_remove_all();}int chandev_do_setup(char *buff,int size){	int curr,startline=0,comment=FALSE,newline=FALSE,oldnewline=TRUE;	int rc=1;	buff[size]=0;	for(curr=0;curr<=size;curr++)	{		if(buff[curr]=='#')		{			comment=TRUE;			newline=FALSE;		}		else if(buff[curr]==10||buff[curr]==13||buff[curr]==0)		{			buff[curr]=0;			comment=FALSE;			newline=TRUE;		}		if(comment==FALSE&&curr>startline		   &&((oldnewline==TRUE&&newline==FALSE)||curr==size))		{			if((rc=chandev_setup(&buff[startline]))==0)				break;			startline=curr+1;		}	        oldnewline=newline;	}	return(rc);}void chandev_read_conf(void){#define CHANDEV_FILE "/etc/chandev.conf"	struct stat statbuf;	char        *buff;	int         curr,left,len,fd;	chandev_conf_read=TRUE;	set_fs(KERNEL_DS);	if(stat(CHANDEV_FILE,&statbuf)==0)	{		set_fs(USER_DS);		buff=vmalloc(statbuf.st_size+1);		if(buff)		{			set_fs(KERNEL_DS);			if((fd=open(CHANDEV_FILE,O_RDONLY,0))!=-1)			{				curr=0;				left=statbuf.st_size;				while((len=read(fd,&buff[curr],left))>0)				{					curr+=len;					left-=len;				}				close(fd);			}			set_fs(USER_DS);			chandev_do_setup(buff,statbuf.st_size);			vfree(buff);		}	}	set_fs(USER_DS);}void chandev_register_and_probe(chandev_probefunc probefunc,chandev_type chan_type){	chandev_probelist *new_probe;	if(!chandev_conf_read)		chandev_read_conf();	if((new_probe=chandev_alloc_listmember((list **)&		chandev_probelist_head,sizeof(chandev_probelist))))	{		new_probe->probefunc=probefunc;		new_probe->chan_type=chan_type;		chandev_probe();	}}void chandev_unregister(chandev_probefunc probefunc){	 chandev_probelist *curr_probe=NULL;			for(curr_probe=chandev_probelist_head;curr_probe!=NULL;		    curr_probe=curr_probe->next)	{		if(curr_probe->probefunc==probefunc)			chandev_free_listmember((list **)&chandev_probelist_head,						(list *)curr_probe);	}}#ifdef CONFIG_PROC_FS#define chandev_printf(exitchan,args...)     \splen=sprintf(spbuff,##args);                \spoffset+=splen;                             \if(spoffset>offset) {                        \       spbuff+=splen;                        \       currlen+=splen;                       \}                                            \if(currlen>=length)                          \       goto exitchan;static int chandev_read_proc(char *page, char **start, off_t offset,			  int length, int *eof, void *data){	char *spbuff=*start=page;	int    currlen=0,splen;	off_t  spoffset=0;	chandev_model_info *curr_model;	chandev_noauto_range *curr_noauto;	chandev_force *curr_force;	chandev_printf(chan_exit,"Channels enabled for detection\n");      	chandev_printf(chan_exit,"chan_type   cu_type       cu_model    max_port_no\n");	chandev_printf(chan_exit,"=================================================\n");	for(curr_model=chandev_models_head;curr_model!=NULL;	    curr_model=curr_model->next)	{		chandev_printf(chan_exit,"0x%02x       0x%04x         0x%02x        %d\n",		       curr_model->chan_type,(int)curr_model->cu_type,		       (int)curr_model->cu_model,(int)curr_model->max_port_no);         	}	        chandev_printf(chan_exit,"%s",chandev_keydescript);	chandev_printf(chan_exit,"No auto devno ranges\n");	chandev_printf(chan_exit,"   From        To   \n");	chandev_printf(chan_exit,"====================\n");	for(curr_noauto=chandev_noauto_head;curr_noauto!=NULL;		    curr_noauto=curr_noauto->next)	{		chandev_printf(chan_exit,"0x%4x       0x%4x\n",			       curr_noauto->lo_devno,			       curr_noauto->hi_devno);	}	chandev_printf(chan_exit,"\nForced devices\n");	chandev_printf(chan_exit,"chan_type defif_num read_devno write_devno port_no ip_cksum hw_stats\n");	chandev_printf(chan_exit,"====================================================================\n");	for(curr_force=chandev_force_head;curr_force!=NULL;		    curr_force=curr_force->next)	{	chandev_printf(chan_exit,"0x%2x   %d  0x%4x 0x%4x  %4d    %1d   %1d\n",		       curr_force->chan_type,curr_force->devif_num,		       curr_force->read_devno,curr_force->write_devno,		       curr_force->port_no,curr_force->do_ip_checksumming,		       curr_force->use_hw_stats);	}	*eof=TRUE; chan_exit:	if(currlen>length) {		/* rewind to previous printf so that we are correctly		 * aligned if we get called to print another page.                 */		currlen-=splen;	}	return(currlen);}static int chandev_write_proc(struct file *file, const char *buffer,			   unsigned long count, void *data){	int         rc;	char        *buff;	buff=vmalloc(count+1);	if(buff)	{		rc = copy_from_user(buff,buffer,count);		if (rc)			goto chandev_write_exit;		chandev_do_setup(buff,count);		rc=count;	chandev_write_exit:		vfree(buff);		return rc;	}	else		return -ENOMEM;	return(0);}static void __init chandev_create_proc(void){	struct proc_dir_entry *dir_entry=		create_proc_entry("chandev",0644,				  &proc_root);	if(dir_entry)	{		dir_entry->read_proc=&chandev_read_proc;		dir_entry->write_proc=&chandev_write_proc;	}}#endifstatic int __init chandev_init(void){	chandev_init_default_models();#if CONFIG_PROC_FS	chandev_create_proc();#endif	return(0);}__initcall(chandev_init);

⌨️ 快捷键说明

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