| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  *  drivers/s390/cio/airq.c | 
 | 3 |  *   S/390 common I/O routines -- support for adapter interruptions | 
 | 4 |  * | 
 | 5 |  *   $Revision: 1.12 $ | 
 | 6 |  * | 
 | 7 |  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, | 
 | 8 |  *			      IBM Corporation | 
 | 9 |  *    Author(s): Ingo Adlung (adlung@de.ibm.com) | 
 | 10 |  *		 Cornelia Huck (cohuck@de.ibm.com) | 
 | 11 |  *		 Arnd Bergmann (arndb@de.ibm.com) | 
 | 12 |  */ | 
 | 13 |  | 
 | 14 | #include <linux/init.h> | 
 | 15 | #include <linux/module.h> | 
 | 16 | #include <linux/slab.h> | 
 | 17 | #include <linux/rcupdate.h> | 
 | 18 |  | 
 | 19 | #include "cio_debug.h" | 
 | 20 | #include "airq.h" | 
 | 21 |  | 
 | 22 | static adapter_int_handler_t adapter_handler; | 
 | 23 |  | 
 | 24 | /* | 
 | 25 |  * register for adapter interrupts | 
 | 26 |  * | 
 | 27 |  * With HiperSockets the zSeries architecture provides for | 
 | 28 |  *  means of adapter interrups, pseudo I/O interrupts that are | 
 | 29 |  *  not tied to an I/O subchannel, but to an adapter. However, | 
 | 30 |  *  it doesn't disclose the info how to enable/disable them, but | 
 | 31 |  *  to recognize them only. Perhaps we should consider them | 
 | 32 |  *  being shared interrupts, and thus build a linked list | 
 | 33 |  *  of adapter handlers ... to be evaluated ... | 
 | 34 |  */ | 
 | 35 | int | 
 | 36 | s390_register_adapter_interrupt (adapter_int_handler_t handler) | 
 | 37 | { | 
 | 38 | 	int ret; | 
 | 39 | 	char dbf_txt[15]; | 
 | 40 |  | 
 | 41 | 	CIO_TRACE_EVENT (4, "rgaint"); | 
 | 42 |  | 
 | 43 | 	if (handler == NULL) | 
 | 44 | 		ret = -EINVAL; | 
 | 45 | 	else | 
 | 46 | 		ret = (cmpxchg(&adapter_handler, NULL, handler) ? -EBUSY : 0); | 
 | 47 | 	if (!ret) | 
| Paul E. McKenney | fbd568a3e | 2005-05-01 08:59:04 -0700 | [diff] [blame] | 48 | 		synchronize_sched();  /* Allow interrupts to complete. */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 49 |  | 
 | 50 | 	sprintf (dbf_txt, "ret:%d", ret); | 
 | 51 | 	CIO_TRACE_EVENT (4, dbf_txt); | 
 | 52 |  | 
 | 53 | 	return ret; | 
 | 54 | } | 
 | 55 |  | 
 | 56 | int | 
 | 57 | s390_unregister_adapter_interrupt (adapter_int_handler_t handler) | 
 | 58 | { | 
 | 59 | 	int ret; | 
 | 60 | 	char dbf_txt[15]; | 
 | 61 |  | 
 | 62 | 	CIO_TRACE_EVENT (4, "urgaint"); | 
 | 63 |  | 
 | 64 | 	if (handler == NULL) | 
 | 65 | 		ret = -EINVAL; | 
 | 66 | 	else { | 
 | 67 | 		adapter_handler = NULL; | 
| Paul E. McKenney | fbd568a3e | 2005-05-01 08:59:04 -0700 | [diff] [blame] | 68 | 		synchronize_sched();  /* Allow interrupts to complete. */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 69 | 		ret = 0; | 
 | 70 | 	} | 
 | 71 | 	sprintf (dbf_txt, "ret:%d", ret); | 
 | 72 | 	CIO_TRACE_EVENT (4, dbf_txt); | 
 | 73 |  | 
 | 74 | 	return ret; | 
 | 75 | } | 
 | 76 |  | 
 | 77 | void | 
 | 78 | do_adapter_IO (void) | 
 | 79 | { | 
 | 80 | 	CIO_TRACE_EVENT (6, "doaio"); | 
 | 81 |  | 
 | 82 | 	if (adapter_handler) | 
 | 83 | 		(*adapter_handler) (); | 
 | 84 | } | 
 | 85 |  | 
 | 86 | EXPORT_SYMBOL (s390_register_adapter_interrupt); | 
 | 87 | EXPORT_SYMBOL (s390_unregister_adapter_interrupt); |