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

📄 s390io.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *  drivers/s390/s390io.c *   S/390 common I/O routines * *  S390 version *    Copyright (C) 1999, 2000 IBM Deutschland Entwicklung GmbH, *                             IBM Corporation *    Author(s): Ingo Adlung (adlung@de.ibm.com) *               Cornelia Huck (cohuck@de.ibm.com)  *    ChangeLog: 01/07/2001 Blacklist cleanup (djbarrow@de.ibm.com,barrow_dj@yahoo.com) *               01/04/2001 Holger Smolinski (smolinsk@de.ibm.com) *                          Fixed lost interrupts and do_adapter_IO *               xx/xx/xxxx nnn          multiple changes not reflected *               03/12/2001 Ingo Adlung  blacklist= - changed to cio_ignore=   *               03/14/2001 Ingo Adlung  disable interrupts before start_IO *                                        in Path Group processing  *                                       decrease retry2 on busy while  *                                        disabling sync_isc; reset isc_cnt *                                        on io error during sync_isc enablement *               05/09/2001 Cornelia Huck added exploitation of debug feature *               05/16/2001 Cornelia Huck added /proc/deviceinfo/<devno>/ *               05/22/2001 Cornelia Huck added /proc/cio_ignore *                                        un-ignore blacklisted devices by piping  *                                        to /proc/cio_ignore *               xx/xx/xxxx some bugfixes & cleanups *               08/02/2001 Cornelia Huck not already known devices can be blacklisted *                                        by piping to /proc/cio_ignore *               09/xx/2001 couple more fixes *               10/29/2001 Cornelia Huck Blacklisting reworked again *               10/29/2001 Cornelia Huck improved utilization of debug feature */#include <linux/module.h>#include <linux/config.h>#include <linux/errno.h>#include <linux/kernel_stat.h>#include <linux/signal.h>#include <linux/sched.h>#include <linux/interrupt.h>#include <linux/slab.h>#include <linux/string.h>#include <linux/smp.h>#include <linux/threads.h>#include <linux/smp_lock.h>#include <linux/init.h>#include <linux/bootmem.h>#ifdef CONFIG_PROC_FS#include <linux/proc_fs.h>#endif #include <asm/system.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/bitops.h>#include <asm/smp.h>#include <asm/pgtable.h>#include <asm/delay.h>#include <asm/processor.h>#include <asm/lowcore.h>#include <asm/idals.h>#include <asm/uaccess.h> #include <asm/cpcmd.h>#include <asm/s390io.h>#include <asm/s390dyn.h>#include <asm/s390mach.h>#include <asm/debug.h>#include <asm/queue.h>#ifndef TRUE#define TRUE  1#define FALSE 0#endif#define SANITY_CHECK(irq) do { \if (irq > highest_subchannel || irq < 0) \		return (-ENODEV); \	if (ioinfo[irq] == INVALID_STORAGE_AREA) \		return (-ENODEV); \	} while(0) #undef  CONFIG_DEBUG_IO#define CONFIG_DEBUG_CRWunsigned int           highest_subchannel;ioinfo_t              *ioinfo_head = NULL;ioinfo_t              *ioinfo_tail = NULL;ioinfo_t              *ioinfo[__MAX_SUBCHANNELS] = {	[0 ... (__MAX_SUBCHANNELS-1)] = INVALID_STORAGE_AREA};static atomic_t    sync_isc     = ATOMIC_INIT(-1);static int         sync_isc_cnt = 0;      // synchronous irq processing lockstatic spinlock_t  adapter_lock = SPIN_LOCK_UNLOCKED;                                          // adapter interrupt lockstatic psw_t      io_sync_wait;           // wait PSW for sync IO, prot. by sync_iscstatic int        cons_dev          = -1; // identify console devicestatic int        init_IRQ_complete = 0;static int        cio_show_msg      = 0;static schib_t   *p_init_schib      = NULL;static irb_t     *p_init_irb        = NULL;static __u64      irq_IPL_TOD;static adapter_int_handler_t adapter_handler   = NULL;/* for use of debug feature */debug_info_t *cio_debug_msg_id = NULL;  debug_info_t *cio_debug_trace_id = NULL;debug_info_t *cio_debug_crw_id = NULL;int cio_debug_initialized = 0;static void init_IRQ_handler( int irq, void *dev_id, struct pt_regs *regs);static void s390_process_subchannels( void);static void s390_device_recognition_all( void);static void s390_device_recognition_irq( int irq);#ifdef CONFIG_PROC_FSstatic void s390_redo_validation(void);#endifstatic int  s390_validate_subchannel( int irq, int enable);static int  s390_SenseID( int irq, senseid_t *sid, __u8 lpm);static int  s390_SetPGID( int irq, __u8 lpm, pgid_t *pgid);static int  s390_SensePGID( int irq, __u8 lpm, pgid_t *pgid);static int  s390_process_IRQ( unsigned int irq );static int  enable_subchannel( unsigned int irq);static int  disable_subchannel( unsigned int irq);#ifdef CONFIG_PROC_FSstatic int chan_proc_init( void );#endif static inline void do_adapter_IO( __u32 intparm );int  s390_DevicePathVerification( int irq, __u8 domask );int  s390_register_adapter_interrupt( adapter_int_handler_t handler );int  s390_unregister_adapter_interrupt( adapter_int_handler_t handler );extern int  do_none(unsigned int irq, int cpu, struct pt_regs * regs);extern int  enable_none(unsigned int irq);extern int  disable_none(unsigned int irq);asmlinkage void do_IRQ( struct pt_regs regs );#ifdef CONFIG_PROC_FS#define MAX_CIO_PROCFS_ENTRIES 0x300/* magic number; we want to have some room to spare */int cio_procfs_device_create(int devno);int cio_procfs_device_remove(int devno);int cio_procfs_device_purge(void);#endifint cio_notoper_msg = 1;#ifdef CONFIG_PROC_FSint cio_proc_devinfo = 0; /* switch off the /proc/deviceinfo/ stuff by default			     until problems are dealt with */#endifunsigned long s390_irq_count[NR_CPUS]; /* trace how many irqs have occured per cpu... */int cio_count_irqs = 1;       /* toggle use here... *//*  * "Blacklisting" of certain devices: * Device numbers given in the commandline as cio_ignore=... won't be known to Linux * These can be single devices or ranges of devices * * 10/23/01 reworked to get rid of lists */static unsigned long bl_dev[2048] = {0,};    static spinlock_t blacklist_lock = SPIN_LOCK_UNLOCKED;static int highest_ignored = 0;static int nr_ignored = 0;/*  * Function: blacklist_range_add * Blacklist the devices from-to */static inline void blacklist_range_add( int from, int to,int locked){      unsigned long flags;     int i;     if (to && (from>to)) {	     printk(KERN_WARNING "Invalid blacklist range %x to %x, skipping\n", from, to);	     return;     }     if(!locked)	     spin_lock_irqsave( &blacklist_lock, flags );     if (!to) 	     to = from;     for (i=from;i<=to;i++) {	     set_bit(i,&bl_dev);	     nr_ignored++;     }     if (to>=highest_ignored)	     highest_ignored = to;     if(!locked)	     spin_unlock_irqrestore( &blacklist_lock, flags );}/*  * Function: blacklist_range_remove * Removes a range from the blacklist chain */static inline void blacklist_range_remove( int from, int to ){     long flags;	int i;     spin_lock_irqsave( &blacklist_lock, flags );     	for (i=from;i<=to;i++) {		clear_bit(i,&bl_dev);		nr_ignored--;	}	if (to == highest_ignored) 		for (highest_ignored=from;(highest_ignored>0) && (!test_bit(highest_ignored,&bl_dev));highest_ignored--);     spin_unlock_irqrestore( &blacklist_lock, flags );}/* Parsing the commandline for blacklist parameters *//*  * Variable to hold the blacklisted devices given by the parameter line * cio_ignore=... */char *blacklist[256] = {NULL, };/* * Get the cio_ignore=... items from the parameter line */static void blacklist_split_parm_string (char *str){	char *tmp = str;	int count = 0;	do {		char *end;		int len;		end = strchr (tmp, ',');		if (end == NULL) {			len = strlen (tmp) + 1;		} else {			len = (long) end - (long) tmp + 1;			*end = '\0';			end++;		}		blacklist[count] = alloc_bootmem (len * sizeof (char) );		if (blacklist == NULL) {			printk (KERN_WARNING "can't store cio_ignore= parameter no %d\n", count + 1);			break;		}		memset (blacklist[count], 0, len * sizeof (char));		memcpy (blacklist[count], tmp, len * sizeof (char));		count++;		tmp = end;	} while (tmp != NULL && *tmp != '\0');}/* * The blacklist parameters as one concatenated string */static char blacklist_parm_string[1024] __initdata = {0,};/*  * function: blacklist_strtoul * Strip leading '0x' and interpret the values as Hex */static inline int blacklist_strtoul (char *str, char **stra){	char *temp = str;	int val;	if (*temp == '0') {		temp++;		                /* strip leading zero */		if (*temp == 'x')			temp++;	                /* strip leading x */	}	val = simple_strtoul (temp, &temp, 16);	/* interpret anything as hex */	*stra = temp;	return val;}/* * Function: blacklist_parse * Parse the parameters given to cio_ignore=...  * Add the blacklisted devices to the blacklist chain */static inline void blacklist_parse( char **str ){     char *temp;     int from, to;     while (*str) {	  temp = *str;	  from = 0;	  to = 0;	  	  from = blacklist_strtoul( temp, &temp );	  if (*temp == '-') {	       temp++;	       to = blacklist_strtoul( temp, &temp );	  }	  blacklist_range_add( from, to, 0 );#ifdef CONFIG_DEBUG_IO	  printk( KERN_INFO "Blacklisted range from %X to %X\n", from, to );#endif	  str++;     }}/* * Initialisation of blacklist  */void __init blacklist_init( void ){#ifdef CONFIG_DEBUG_IO          printk( KERN_DEBUG "Reading blacklist...\n");#endif     if (cio_debug_initialized)	     debug_sprintf_event(cio_debug_msg_id, 6,				 "Reading blacklist\n");     blacklist_split_parm_string( blacklist_parm_string );     blacklist_parse( blacklist );}/* * Get all the blacklist parameters from parameter line */void __init blacklist_setup (char *str, int *ints){	int len = strlen (blacklist_parm_string);	if (len != 0) {		strcat (blacklist_parm_string, ",");	}	strcat (blacklist_parm_string, str);}int __init blacklist_call_setup (char *str){        int dummy;#ifdef CONFIG_DEBUG_IO	printk( KERN_DEBUG "Reading blacklist parameters...\n" );#endif	if (cio_debug_initialized)		debug_sprintf_event(cio_debug_msg_id, 6,				    "Reading blacklist parameters\n");        blacklist_setup(str,&dummy);		blacklist_init(); /* Blacklist ranges must be ready when device recognition starts */       	return 1;}__setup ("cio_ignore=", blacklist_call_setup);/* Checking if devices are blacklisted *//* * Function: is_blacklisted * Returns 1 if the given devicenumber can be found in the blacklist, otherwise 0. */static inline int is_blacklisted( int devno ){     long flags;     int retval=0;     spin_lock_irqsave( &blacklist_lock, flags );      if (test_bit(devno,&bl_dev)) 		     retval=1;     spin_unlock_irqrestore( &blacklist_lock, flags );     return retval;}/* * Function: blacklist_free_all_ranges * set all blacklisted devices free... */void blacklist_free_all_ranges(void) {	unsigned long flags;	int i;	spin_lock_irqsave( &blacklist_lock, flags ); 	for (i=0;i<=highest_ignored;i++)		clear_bit(i,&bl_dev);	highest_ignored = 0;	nr_ignored = 0;	spin_unlock_irqrestore( &blacklist_lock, flags );}#ifdef CONFIG_PROC_FS/* * Function: blacklist_parse_proc_parameters * parse the stuff which is piped to /proc/cio_ignore */void blacklist_parse_proc_parameters(char *buf){	char *tmp;	int i;	char *end;	int len = -1;	char *param;	int from = 0;	int to = 0;	long flags;	int err = 0;	tmp = buf;	if (strstr(tmp, "free ")) {		for (i=0; i<5; i++) {			tmp++;		}		if (strstr(tmp, "all")) {			blacklist_free_all_ranges();			s390_redo_validation();		} else {			while (tmp != NULL) {				end = strchr(tmp, ',');				if (end == NULL) {					len = strlen(tmp) + 1;				} else {					len = (long)end - (long) tmp + 1;					*end = '\0';					end++;				}				param =  (char*) kmalloc(len * sizeof(char) + 1, GFP_KERNEL);				strncpy(param, (const char *) tmp, len);				tmp = end;				from = blacklist_strtoul(param, &param);				if (*param == '-') {					param++;					to = blacklist_strtoul(param, &param);				} else {					to = from;				}				blacklist_range_remove( from, to );				kfree(param);			}				s390_redo_validation();		}	} else if (strstr(tmp, "add ")) {		for (i=0;i<4;i++){			tmp++;		}		while (tmp != NULL) {			end = strchr(tmp, ',');			if (end == NULL) {				len = strlen(tmp) + 1;			} else {				len = (long)end - (long) tmp + 1;				*end = '\0';				end++;			}			param =  (char*) kmalloc(len * sizeof(char) + 1, GFP_KERNEL);			strncpy(param, (const char *) tmp, len);			tmp = end;			from = blacklist_strtoul(param, &param);			if (*param == '-') {				param++;				to = blacklist_strtoul(param, &param);			} else {				to = from;			}			spin_lock_irqsave( &blacklist_lock, flags ); 						/*			 * Don't allow for already known devices to be			 * blacklisted			 * The criterion is a bit dumb, devices which once were			 * there but are already gone are also caught...			 */						err = 0;			for (i=0; i<=highest_subchannel; i++) {				if (ioinfo[i]!=INVALID_STORAGE_AREA) {					if (   (ioinfo[i]->schib.pmcw.dev >= from)					    && (ioinfo[i]->schib.pmcw.dev <= to)  ) {						printk(KERN_WARNING "cio_ignore: Won't blacklist "						       "already known devices, skipping range "						       "%x to %x\n", from, to);						err = 1;						break;					}				}			}			if (!err) 				blacklist_range_add(from, to, 1);						spin_unlock_irqrestore( &blacklist_lock, flags );			kfree(param);		}	} else {		printk( KERN_WARNING "cio_ignore: Parse error; try using 'free all|<devno-range>,<devno-range>,...'\n");		printk( KERN_WARNING "or 'add <devno-range>,<devno-range>,...'\n");	}}#endif/* End of blacklist handling */void s390_displayhex(char *str,void *ptr,s32 cnt);void s390_displayhex2(char *str, void *ptr, s32 cnt, int level);void s390_displayhex(char *str,void *ptr,s32 cnt){	s32	cnt1,cnt2,maxcnt2;	u32	*currptr=(__u32 *)ptr;	printk("\n%s\n",str);	for(cnt1=0;cnt1<cnt;cnt1+=16)	{		printk("%08lX ",(unsigned long)currptr);		maxcnt2=cnt-cnt1;		if(maxcnt2>16)			maxcnt2=16;		for(cnt2=0;cnt2<maxcnt2;cnt2+=4)			printk("%08X ",*currptr++);		printk("\n");

⌨️ 快捷键说明

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