| 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); |