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

📄 chandev.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
			       " this is nothing to worry about chan_type/chan_model/dev_type/dev_model %s\n",buff);			drinfo->oper_func=NULL;		}		chandev_add_to_list((list **)&chandev_models_head,newmodel);	}}void chandev_remove(chandev *member){	chandev_free_queuemember(&chandev_head,(queue *)member);}void chandev_remove_all(void){	chandev_free_all_queue(&chandev_head);}void chandev_remove_model(chandev_model_info *model){	chandev *curr_chandev,*next_chandev;	chandev_lock();	for_each_allow_delete(curr_chandev,next_chandev,(chandev *)chandev_head.head)		if(curr_chandev->model_info==model)			chandev_remove(curr_chandev);	if(model->drinfo.oper_func)		s390_device_unregister(&model->drinfo);	chandev_free_listmember((list **)&chandev_models_head,(list *)model);	chandev_unlock();}void chandev_remove_all_models(void){	chandev_lock();	while(chandev_models_head)		chandev_remove_model(chandev_models_head);	chandev_unlock();}void chandev_del_model(s32 cu_type,s16 cu_model,s32 dev_type,s16 dev_model){	chandev_model_info *curr_model,*next_model;		chandev_lock();	for_each_allow_delete(curr_model,next_model,chandev_models_head)		if((curr_model->cu_type==cu_type||cu_type==-1)&&		   (curr_model->cu_model==cu_model||cu_model==-1)&&		   (curr_model->dev_type==dev_type||dev_type==-1)&&		   (curr_model->dev_model==dev_model||dev_model==-1))			chandev_remove_model(curr_model);				chandev_unlock();}static void chandev_init_default_models(void){	/* Usually P390/Planter 3172 emulation assume maximum 16 to be safe. */	chandev_add_model(chandev_type_lcs,0x3088,0x1,-1,-1,15,default_msck_bits,FALSE,FALSE);		/* 3172/2216 Paralell the 2216 allows 16 ports per card the */	/* the original 3172 only allows 4 we will assume the max of 16 */	chandev_add_model(chandev_type_lcs|chandev_type_ctc,0x3088,0x8,-1,-1,15,default_msck_bits,FALSE,FALSE);	/* 3172/2216 Escon serial the 2216 allows 16 ports per card the */	/* the original 3172 only allows 4 we will assume the max of 16 */	chandev_add_model(chandev_type_lcs|chandev_type_escon,0x3088,0x1F,-1,-1,15,default_msck_bits,FALSE,FALSE);	/* Only 2 ports allowed on OSA2 cards model 0x60 */	chandev_add_model(chandev_type_lcs,0x3088,0x60,-1,-1,1,default_msck_bits,FALSE,FALSE);	/* qeth gigabit ethernet */	chandev_add_model(chandev_type_qeth,0x1731,0x1,0x1732,0x1,0,default_msck_bits,FALSE,FALSE);	chandev_add_model(chandev_type_qeth,0x1731,0x5,0x1732,0x5,0,default_msck_bits,FALSE,FALSE);	/* Osa-D we currently aren't too emotionally involved with this */	chandev_add_model(chandev_type_osad,0x3088,0x62,-1,-1,0,default_msck_bits,FALSE,FALSE);	/* claw */	chandev_add_model(chandev_type_claw,0x3088,0x61,-1,-1,0,default_msck_bits,FALSE,FALSE);	/* ficon attached ctc */	chandev_add_model(chandev_type_escon,0x3088,0x1E,-1,-1,0,default_msck_bits,FALSE,FALSE);}void chandev_del_noauto(u16 devno){	chandev_noauto_range *curr_noauto,*next_noauto;	chandev_lock();	for_each_allow_delete(curr_noauto,next_noauto,chandev_noauto_head)		if(curr_noauto->lo_devno<=devno&&curr_noauto->hi_devno>=devno)			chandev_free_listmember((list **)&chandev_noauto_head,(list *)curr_noauto); 	chandev_unlock();}void chandev_del_msck(u16 devno){	chandev_msck_range *curr_msck_range,*next_msck_range;	chandev_lock();	for_each_allow_delete(curr_msck_range,next_msck_range,chandev_msck_range_head)		if(curr_msck_range->lo_devno<=devno&&curr_msck_range->hi_devno>=devno)			chandev_free_listmember((list **)&chandev_msck_range_head,(list *)curr_msck_range); 	chandev_unlock();}void chandev_add(s390_dev_info_t  *newdevinfo,chandev_model_info *newmodelinfo){	chandev *new_chandev=NULL;	if((new_chandev=chandev_alloc(sizeof(chandev))))	{		new_chandev->model_info=newmodelinfo;		new_chandev->sch.devno=newdevinfo->devno;		new_chandev->sch.irq=newdevinfo->irq;		new_chandev->sch.cu_type=newdevinfo->sid_data.cu_type; /* control unit type */		new_chandev->sch.cu_model=newdevinfo->sid_data.cu_model; /* control unit model */		new_chandev->sch.dev_type=newdevinfo->sid_data.dev_type; /* device type */		new_chandev->sch.dev_model=newdevinfo->sid_data.dev_model; /* device model */		chandev_add_schib_info(newdevinfo->irq,&new_chandev->sch);		new_chandev->owned=(newdevinfo->status&DEVSTAT_DEVICE_OWNED ? TRUE:FALSE);		chandev_queuemember(&chandev_head,new_chandev);	}}void chandev_unregister_probe(chandev_probefunc probefunc){	chandev_probelist *curr_probe,*next_probe;	chandev_lock();	for_each_allow_delete(curr_probe,next_probe,chandev_probelist_head)		if(curr_probe->probefunc==probefunc)			chandev_free_listmember((list **)&chandev_probelist_head,						(list *)curr_probe);	chandev_unlock();}void chandev_unregister_probe_by_chan_type(chandev_type chan_type){	chandev_probelist *curr_probe,*next_probe;	chandev_lock();	for_each_allow_delete(curr_probe,next_probe,chandev_probelist_head)		if(curr_probe->chan_type==chan_type)			chandev_free_listmember((list **)&chandev_probelist_head,						(list *)curr_probe);	chandev_unlock();}void chandev_reset(void){	chandev_lock();	chandev_remove_all_models();	chandev_free_all_list((list **)&chandev_noauto_head);	chandev_free_all_list((list **)&chandev_msck_range_head);	chandev_free_all_list((list **)&chandev_force_head);	chandev_remove_parms(-1,FALSE,-1);#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)	chandev_use_devno_names=FALSE;#endif	chandev_persistent=0;	chandev_unlock();}int chandev_is_chandev(int irq,s390_dev_info_t *devinfo,chandev_force **forceinfo,chandev_model_info **ret_model){	chandev_force *curr_force;	chandev_model_info *curr_model=NULL;	int err;	int retval=FALSE;	if(forceinfo)		*forceinfo=NULL;	if(ret_model)		*ret_model=NULL;	if((err=get_dev_info_by_irq(irq,devinfo)))	{		printk("chandev_is_chandev get_dev_info_by_irq reported err=%X on irq %d\n"		       "should not happen\n",err,irq);			return FALSE;	}	chandev_lock();		for_each(curr_model,chandev_models_head)	{		if(((curr_model->cu_type==devinfo->sid_data.cu_type)||(curr_model->cu_type==-1))&&		   ((curr_model->cu_model==devinfo->sid_data.cu_model)||(curr_model->cu_model==-1))&&		   ((curr_model->dev_type==devinfo->sid_data.dev_type)||(curr_model->dev_type==-1))&&		   ((curr_model->dev_model==devinfo->sid_data.dev_model)||(curr_model->dev_model==-1)))		{			retval=TRUE;			if(ret_model)				*ret_model=curr_model;			break;		}	}	for_each(curr_force,chandev_force_head)	{		if(((curr_force->read_lo_devno==devinfo->devno)&&		   (curr_force->write_hi_devno==devinfo->devno)&&		    (curr_force->devif_num!=-2))||		   ((curr_force->read_lo_devno>=devinfo->devno)&&		    (curr_force->write_hi_devno<=devinfo->devno)&&		    (curr_force->devif_num==-2)))		{			if(forceinfo)				*forceinfo=curr_force;			break;		}	}	chandev_unlock();	return(retval);}void chandev_collect_devices(void){	int curr_irq,loopcnt=0;	s390_dev_info_t   curr_devinfo;	chandev_model_info *curr_model;     	for(curr_irq=get_irq_first();curr_irq>=0; curr_irq=get_irq_next(curr_irq))	{		/* check read chandev		 * we had to do the cu_model check also because ctc devices		 * have the same cutype & after asking some people		 * the model numbers are given out pseudo randomly so		 * we can't just take a range of them also the dev_type & models are 0		 */		loopcnt++;		if(loopcnt>0x10000)		{			printk(KERN_ERR"chandev_collect_devices detected infinite loop bug in get_irq_next\n");			break;		}		chandev_lock();		if(chandev_is_chandev(curr_irq,&curr_devinfo,NULL,&curr_model))			chandev_add(&curr_devinfo,curr_model);		chandev_unlock();	}}int chandev_add_force(chandev_type chan_type,s32 devif_num,u16 read_lo_devno,u16 write_hi_devno,u16 data_devno,s32 memory_usage_in_k,s16 port_protocol_no,u8 checksum_received_ip_pkts,u8 use_hw_stats,char *host_name,char *adapter_name,char *api_type){	chandev_force *new_chandev_force;		if(devif_num==-2&&read_lo_devno>write_hi_devno)	{		printk("chandev_add_force detected bad device range lo_devno=0x%04x  hi_devno=0x%04x\n,",		       (int)read_lo_devno,(int)write_hi_devno);		return(-1);	}	if(memory_usage_in_k<0)	{		printk("chandev_add_force memory_usage_in_k is bad\n");		return(-1);	}	if(chan_type==chandev_type_claw)	{		int host_name_len=strlen(host_name),			adapter_name_len=strlen(adapter_name),			api_type_len=strlen(api_type);		if(host_name_len>=CLAW_NAMELEN||host_name_len==0||		   adapter_name_len>=CLAW_NAMELEN||adapter_name_len==0||		   api_type_len>=CLAW_NAMELEN||api_type_len==0)			return(-1);	}	if((new_chandev_force=chandev_alloc(sizeof(chandev_force))))	{		new_chandev_force->chan_type=chan_type;		new_chandev_force->devif_num=devif_num;		new_chandev_force->read_lo_devno=read_lo_devno;		new_chandev_force->write_hi_devno=write_hi_devno;		new_chandev_force->data_devno=data_devno;		new_chandev_force->memory_usage_in_k=memory_usage_in_k;		new_chandev_force->port_protocol_no=port_protocol_no;		new_chandev_force->checksum_received_ip_pkts=checksum_received_ip_pkts;		new_chandev_force->use_hw_stats=use_hw_stats;				if(chan_type==chandev_type_claw)		{			strcpy(new_chandev_force->claw.host_name,host_name);			strcpy(new_chandev_force->claw.adapter_name,adapter_name);			strcpy(new_chandev_force->claw.api_type,api_type);		}		chandev_add_to_list((list **)&chandev_force_head,new_chandev_force);	}	return(0);}void chandev_del_force(int read_lo_devno){	chandev_force *curr_force,*next_force;		chandev_lock();	for_each_allow_delete(curr_force,next_force,chandev_force_head)	{		if(curr_force->read_lo_devno==read_lo_devno||read_lo_devno==-1)			chandev_free_listmember((list **)&chandev_force_head,						(list *)curr_force);	}	chandev_unlock();}void chandev_shutdown(chandev_activelist *curr_device){	int err=0;	chandev_lock();	/* unregister_netdev calls the dev->close so we shouldn't do this */	/* this otherwise we crash */	if(curr_device->unreg_dev)	{		curr_device->unreg_dev(curr_device->dev_ptr);		curr_device->unreg_dev=NULL;	}	if(curr_device->shutdownfunc)	{		err=curr_device->shutdownfunc(curr_device->dev_ptr);	}	if(err)		printk("chandev_shutdown unable to fully shutdown & unload %s err=%d\n"		       "probably some upper layer still requires the device to exist\n",		       curr_device->devname,err);	else	{				chandev_free_irq_by_irqinfo(curr_device->read_irqinfo);		chandev_free_irq_by_irqinfo(curr_device->write_irqinfo);		if(curr_device->data_irqinfo)			chandev_free_irq_by_irqinfo(curr_device->data_irqinfo);		chandev_free_listmember((list **)&chandev_activelist_head,				(list *)curr_device);	}	chandev_unlock();}void chandev_shutdown_all(void){	while(chandev_activelist_head)		chandev_shutdown(chandev_activelist_head);}void chandev_shutdown_by_name(char *devname){	chandev_activelist *curr_device;	chandev_lock();	for_each(curr_device,chandev_activelist_head)		if(strcmp(devname,curr_device->devname)==0)		{			chandev_shutdown(curr_device);			break;		}	chandev_unlock();}static chandev_activelist *chandev_active(u16 devno){	chandev_activelist *curr_device;	for_each(curr_device,chandev_activelist_head)		if(curr_device->read_irqinfo->sch.devno==devno||		   curr_device->write_irqinfo->sch.devno==devno||		   (curr_device->data_irqinfo&&curr_device->data_irqinfo->sch.devno==devno))		{			return(curr_device);		}	return(NULL);}void chandev_shutdown_by_devno(u16 devno){	chandev_activelist *curr_device;	chandev_lock();	curr_device=chandev_active(devno);	if(curr_device)		chandev_shutdown(curr_device);	chandev_unlock();}int chandev_pack_args(char *str){	char *newstr=str,*next;	int strcnt=1;	while(*str)	{		next=str+1;		/*remove dead spaces */		if(isspace(*str)&&isspace(*next))		{			str++;			continue;		}		if(isspace(*str))		{			*str=',';			goto pack_dn;		}		if(((*str)==';')&&(*next))		{			strcnt++;			*str=0;		}	pack_dn:		*newstr++=*str++;			}	*newstr=0;	return(strcnt);}typedef enum{ 	isnull=0,	isstr=1,	isnum=2,	iscomma=4,} chandev_strval;chandev_strval chandev_strcmp(char *teststr,char **str,long *endlong){	char *cur;	chandev_strval  retval=isnull;	int len=strlen(teststr);	if(strncmp(teststr,*str,len)==0)	{		*str+=len;		retval=isstr;		cur=*str;		*endlong=simple_strtol(cur,str,0);		if(cur!=*str)			retval|=isnum;		if(**str==',')		{			retval|=iscomma;			*str+=1;		}		else if(**str!=0)			retval=isnull;	}	return(retval);}int chandev_initdevice(chandev_probeinfo *probeinfo,void *dev_ptr,u8 port_no,char *devname,chandev_category category,chandev_unregfunc unreg_dev){	chandev_activelist *newdevice,*curr_device;	chandev_interrupt_check();	if(probeinfo->newdevice!=NULL)	{		printk("probeinfo->newdevice!=NULL in chandev_initdevice for %s",devname);		return(-EPERM);	}	chandev_lock();	for_each(curr_device,chandev_activelist_head)	{		if(strcmp(curr_device->devname,devname)==0)		{			printk("chandev_initdevice detected duplicate devicename %s\n",devname);			chandev_unlock();			return(-EPERM);		}	}	if((newdevice=chandev_allocstr(devname,offsetof(chandev_activelist,devname))))	{		newdevice->read_irqinfo=chandev_get_irqinfo_by_irq(probeinfo->read.irq);		newdevice->write_irqinfo=chandev_get_irqinfo_by_irq(probeinfo->write.irq);		if(probeinfo->data_exists)			newdevice->data_irqinfo=chandev_get_irqinfo_by_irq(probeinfo->data.irq);		chandev_unlock();		if(newdevice->read_irqinfo==NULL||newdevice->write_irqinfo==NULL||		   (probeinfo->data_exists&&newdevice->data_irqinfo==NULL))		{			printk("chandev_initdevice, it appears that chandev_request_irq was not "			       "called for devname=%s read_irq=%d write_irq=%d data_irq=%d\n",			       devname,probeinfo->read.irq,probeinfo->write.irq,probeinfo->data.irq);			kfree(newdevice);			return(-EPERM);		}

⌨️ 快捷键说明

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