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

📄 s390io.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
	}}void s390_displayhex2(char *str, void *ptr, s32 cnt, int level){	s32 cnt1, cnt2, maxcnt2;	u32 *currptr = (__u32 *)ptr;	char buffer[cnt*12];	debug_sprintf_event(cio_debug_msg_id, level, "%s\n", str);	for (cnt1 = 0; cnt1<cnt; cnt1+=16) {		sprintf(buffer, "%08lX ", (unsigned long)currptr);		maxcnt2 = cnt - cnt1;		if (maxcnt2 > 16)			maxcnt2 = 16;		for (cnt2 = 0; cnt2 < maxcnt2; cnt2 += 4)			sprintf(buffer, "%08X ", *currptr++);	}	debug_sprintf_event(cio_debug_msg_id, level, "%s\n",buffer);}static int __init cio_setup( char *parm ){	if ( !strcmp( parm, "yes") )	{		cio_show_msg = 1;	}	else if ( !strcmp( parm, "no") )	{		cio_show_msg = 0;	}	else	{		printk( KERN_ERR "cio_setup : invalid cio_msg parameter '%s'", parm);	} /* endif */	return 1;}__setup("cio_msg=", cio_setup);static int __init cio_notoper_setup(char *parm){	if (!strcmp(parm, "yes")) {		cio_notoper_msg = 1;	} else if (!strcmp(parm, "no")) {		cio_notoper_msg = 0;	} else {		printk( KERN_ERR "cio_notoper_setup: invalid cio_notoper_msg parameter '%s'", parm);	}	return 1;}	__setup("cio_notoper_msg=", cio_notoper_setup);#ifdef CONFIG_PROC_FSstatic int __init cio_proc_devinfo_setup(char *parm){	if (!strcmp(parm, "yes")) {		cio_proc_devinfo = 1;	} else if (!strcmp(parm, "no")) {		cio_proc_devinfo = 0;	} else {		printk( KERN_ERR "cio_proc_devinfo_setup: invalid parameter '%s'\n",parm);	}	return 1;}__setup("cio_proc_devinfo=", cio_proc_devinfo_setup);#endif/* * register for adapter interrupts * * With HiperSockets the zSeries architecture provides for *  means of adapter interrups, pseudo I/O interrupts that are *  not tied to an I/O subchannel, but to an adapter. However, *  it doesn't disclose the info how to enable/disable them, but *  to recognize them only. Perhaps we should consider them *  being shared interrupts, and thus build a linked list *  of adapter handlers ... to be evaluated ... */int  s390_register_adapter_interrupt( adapter_int_handler_t handler ){	int ret = 0;	char dbf_txt[15];		if (cio_debug_initialized)		debug_text_event(cio_debug_trace_id, 4, "rgaint");	spin_lock( &adapter_lock );	if ( handler == NULL )		ret = -EINVAL;	else if ( adapter_handler )		ret = -EBUSY;	else		adapter_handler = handler;  		spin_unlock( &adapter_lock ); 		if (cio_debug_initialized) {		sprintf(dbf_txt,"ret:%d",ret);		debug_text_event(cio_debug_trace_id, 4, dbf_txt);	}	return( ret);}int  s390_unregister_adapter_interrupt( adapter_int_handler_t handler ){	int ret = 0;	char dbf_txt[15];		if (cio_debug_initialized)		debug_text_event(cio_debug_trace_id, 4, "urgaint");	spin_lock( &adapter_lock ); 		if ( handler == NULL )		ret = -EINVAL;	else if ( handler != adapter_handler )		ret = -EINVAL;	else		adapter_handler = NULL;  		spin_unlock( &adapter_lock ); 		if (cio_debug_initialized) {		sprintf(dbf_txt,"ret:%d",ret);		debug_text_event(cio_debug_trace_id, 4, dbf_txt);	}	return( ret);}static inline void do_adapter_IO( __u32 intparm ){	if (cio_debug_initialized)		debug_text_event(cio_debug_trace_id, 4, "doaio");		spin_lock( &adapter_lock ); 		if ( adapter_handler )		(*adapter_handler)( intparm );	spin_unlock( &adapter_lock );	return;  	}/* * Note : internal use of irqflags SA_PROBE for NOT path grouping  * */int s390_request_irq_special( int                      irq,                              io_handler_func_t        io_handler,                              not_oper_handler_func_t  not_oper_handler,                              unsigned long            irqflags,                              const char              *devname,                              void                    *dev_id){	int		retval = 0;	unsigned long	flags;	char            dbf_txt[15];	int             retry;	if (irq >= __MAX_SUBCHANNELS)		return -EINVAL;	if ( !io_handler || !dev_id )		return -EINVAL;	if ( ioinfo[irq] == INVALID_STORAGE_AREA )		return -ENODEV;	if (cio_debug_initialized) {		sprintf(dbf_txt, "reqsp%x", irq);		debug_text_event(cio_debug_trace_id, 4, dbf_txt);	}	/*	 * The following block of code has to be executed atomically	 */	s390irq_spin_lock_irqsave( irq, flags);	if ( !ioinfo[irq]->ui.flags.ready )	{		retry = 5;				ioinfo[irq]->irq_desc.handler = io_handler;		ioinfo[irq]->irq_desc.name    = devname;		ioinfo[irq]->irq_desc.dev_id  = dev_id;		ioinfo[irq]->ui.flags.ready   = 1;						do {			retval = enable_subchannel(irq);			if (retval) {				ioinfo[irq]->ui.flags.ready = 0;				break;			}						stsch(irq,&ioinfo[irq]->schib);			if (ioinfo[irq]->schib.pmcw.ena) 				retry = 0;			else				retry--;		} while (retry);	}	else	{		/*		 *  interrupt already owned, and shared interrupts		 *   aren't supported on S/390.		 */		retval = -EBUSY;	} /* endif */	s390irq_spin_unlock_irqrestore(irq,flags);	if ( retval == 0 )	{		if ( !(irqflags & SA_PROBE))			s390_DevicePathVerification( irq, 0 );		ioinfo[irq]->ui.flags.newreq = 1;		ioinfo[irq]->nopfunc         = not_oper_handler;  		}	if (cio_debug_initialized)		debug_int_event(cio_debug_trace_id, 4, retval);	return retval;}int s390_request_irq( unsigned int   irq,                      void           (*handler)(int, void *, struct pt_regs *),                      unsigned long  irqflags,                      const char    *devname,                      void          *dev_id){	int ret;	ret = s390_request_irq_special( irq,                                   (io_handler_func_t)handler,                                   NULL,                                   irqflags,                                   devname,                                   dev_id);	if ( ret == 0 )	{		ioinfo[irq]->ui.flags.newreq = 0;	} /* endif */	return( ret);}void s390_free_irq(unsigned int irq, void *dev_id){	unsigned long flags;	int          ret;	char dbf_txt[15];	if ( irq >= __MAX_SUBCHANNELS || ioinfo[irq] == INVALID_STORAGE_AREA )		return;	if (cio_debug_initialized) {		sprintf(dbf_txt, "free%x", irq);		debug_text_event(cio_debug_trace_id, 2, dbf_txt);	}	s390irq_spin_lock_irqsave( irq, flags);#ifdef  CONFIG_KERNEL_DEBUG	if ( irq != cons_dev )		printk( KERN_DEBUG "Trying to free IRQ%d\n",irq);#endif	if (cio_debug_initialized)		debug_sprintf_event(cio_debug_msg_id, 2, "Trying to free IRQ %d\n", irq);	/*	 * disable the device and reset all IRQ info if	 *  the IRQ is actually owned by the handler ...	 */	if ( ioinfo[irq]->ui.flags.ready ) {		if ( dev_id == ioinfo[irq]->irq_desc.dev_id ) {			/* start deregister */			ioinfo[irq]->ui.flags.unready = 1;			/*			 * Try to stop IO first...			 * ... it seems disable_subchannel is sometimes			 * successfully called with IO still pending.			 */			halt_IO( irq,				 0xC8C1D3E3,				 DOIO_WAIT_FOR_INTERRUPT );				ret = disable_subchannel( irq);			if ( ret == -EBUSY ) {					/*					 * kill it !					 * ... we first try sync and eventually					 *  try terminating the current I/O by					 *  an async request, twice halt, then					 *  clear.					 */				ret = halt_IO( irq,						                0xC8C1D3E3,						                DOIO_WAIT_FOR_INTERRUPT );   					if ( ret == -EBUSY ) {							halt_IO( irq, 0xC8C1D3E3, 0);							s390irq_spin_unlock_irqrestore( irq, flags);							udelay( 200000 ); /* 200 ms */							s390irq_spin_lock_irqsave( irq, flags);						} /* endif */								ret = disable_subchannel(irq);				if (ret == -EBUSY) {   						clear_IO( irq, 0x40C3D3D9,0 );							s390irq_spin_unlock_irqrestore( irq, flags);							udelay( 1000000 ); /* 1000 ms */							s390irq_spin_lock_irqsave( irq, flags);						/* give it a very last try ... */						disable_subchannel( irq);					if ( ioinfo[irq]->ui.flags.busy ) {							printk( KERN_CRIT"free_irq(%04X) "							       "- device %04X busy, retry "							       "count exceeded\n",								irq,								ioinfo[irq]->devstat.devno);							if (cio_debug_initialized)								debug_sprintf_event(cio_debug_msg_id, 0,										    "free_irq(%04X) - device %04X busy, retry count exceeded\n",										    irq, ioinfo[irq]->devstat.devno);						} /* endif */											} /* endif */				} /* endif */					ioinfo[irq]->ui.flags.ready   = 0;			ioinfo[irq]->ui.flags.unready = 0; /* deregister ended */			ioinfo[irq]->nopfunc = NULL;			s390irq_spin_unlock_irqrestore( irq, flags);		} else {			s390irq_spin_unlock_irqrestore( irq, flags);			printk( KERN_ERR "free_irq(%04X) : error, "			        "dev_id does not match !\n", irq);			if (cio_debug_initialized)				debug_sprintf_event(cio_debug_msg_id, 0, 						    "free_irq(%04X) : error, dev_id does not match !\n", irq);		} /* endif */	} else {		s390irq_spin_unlock_irqrestore( irq, flags);		printk( KERN_ERR "free_irq(%04X) : error, "		        "no action block ... !\n", irq);		if (cio_debug_initialized)			debug_sprintf_event(cio_debug_msg_id, 0,					    "free_irq(%04X) : error, no action block ... !\n", irq);	} /* endif */}/* * Generic enable/disable code */int disable_irq(unsigned int irq){	unsigned long flags;	int           ret;	char dbf_txt[15];	SANITY_CHECK(irq);	if ( !ioinfo[irq]->ui.flags.ready )		return -ENODEV;	if (cio_debug_initialized) {		sprintf(dbf_txt, "disirq%x", irq);		debug_text_event(cio_debug_trace_id, 4, dbf_txt);	}	s390irq_spin_lock_irqsave(irq, flags);	ret = disable_subchannel(irq);	s390irq_spin_unlock_irqrestore(irq, flags);	synchronize_irq();	if (cio_debug_initialized) 		debug_int_event(cio_debug_trace_id, 4, ret);	return( ret);}int enable_irq(unsigned int irq){	unsigned long flags;	int           ret;	char dbf_txt[15];	SANITY_CHECK(irq);	if ( !ioinfo[irq]->ui.flags.ready )		return -ENODEV;	if (cio_debug_initialized) {		sprintf(dbf_txt, "enirq%x", irq);		debug_text_event(cio_debug_trace_id, 4, dbf_txt);	}	s390irq_spin_lock_irqsave(irq, flags);	ret = enable_subchannel(irq);	s390irq_spin_unlock_irqrestore(irq, flags);	if (cio_debug_initialized) 		debug_int_event(cio_debug_trace_id, 4, ret);	return(ret);}/* * Enable IRQ by modifying the subchannel */static int enable_subchannel( unsigned int irq){	int   ret = 0;	int   ccode;	int   retry = 5;	char dbf_txt[15];	SANITY_CHECK(irq);	if (cio_debug_initialized) {		sprintf(dbf_txt, "ensch%x", irq);		debug_text_event(cio_debug_trace_id, 2, dbf_txt);	}	/*	 * If a previous disable request is pending we reset it. However, this	 *  status implies that the device may (still) be not-operational.	 */	if (  ioinfo[irq]->ui.flags.d_disable )	{		ioinfo[irq]->ui.flags.d_disable = 0;		ret                             = 0;	}	else	{		ccode = stsch(irq, &(ioinfo[irq]->schib) );		if ( ccode )		{			ret = -ENODEV;		}		else		{			ioinfo[irq]->schib.pmcw.ena = 1;			if ( irq == cons_dev )			{				ioinfo[irq]->schib.pmcw.isc = 7;			}			else				{				ioinfo[irq]->schib.pmcw.isc = 3;			} /* endif */			do			{				ccode = msch( irq, &(ioinfo[irq]->schib) );				switch (ccode) {				case 0: /* ok */					ret = 0;					retry = 0;					break;				case 1: /* status pending */					ioinfo[irq]->ui.flags.s_pend = 1;					s390_process_IRQ( irq );					ioinfo[irq]->ui.flags.s_pend = 0;					ret = -EIO;    /* might be overwritten */					               /* ... on re-driving    */					               /* ... the msch()       */					retry--;					break;				case 2: /* busy */					udelay(100);	/* allow for recovery */					ret = -EBUSY;					retry--;					break;				case 3: /* not oper */					ioinfo[irq]->ui.flags.oper = 0;					retry = 0;					ret = -ENODEV;					break;				}			} while ( retry );		} /* endif */	}  /* endif */	if (cio_debug_initialized) {		sprintf(dbf_txt,"ret:%d",ret);

⌨️ 快捷键说明

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