ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / s390 / cio / airq.c
1 /*
2  *  drivers/s390/cio/airq.c
3  *   S/390 common I/O routines -- support for adapter interruptions
4  *
5  *   $Revision: 1.11 $
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
18 #include "cio_debug.h"
19 #include "airq.h"
20
21 static spinlock_t adapter_lock = SPIN_LOCK_UNLOCKED;
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         spin_lock (&adapter_lock);
44
45         if (handler == NULL)
46                 ret = -EINVAL;
47         else if (adapter_handler)
48                 ret = -EBUSY;
49         else {
50                 adapter_handler = handler;
51                 ret = 0;
52         }
53
54         spin_unlock (&adapter_lock);
55
56         sprintf (dbf_txt, "ret:%d", ret);
57         CIO_TRACE_EVENT (4, dbf_txt);
58
59         return (ret);
60 }
61
62 int
63 s390_unregister_adapter_interrupt (adapter_int_handler_t handler)
64 {
65         int ret;
66         char dbf_txt[15];
67
68         CIO_TRACE_EVENT (4, "urgaint");
69
70         spin_lock (&adapter_lock);
71
72         if (handler == NULL)
73                 ret = -EINVAL;
74         else if (handler != adapter_handler)
75                 ret = -EINVAL;
76         else {
77                 adapter_handler = NULL;
78                 ret = 0;
79         }
80
81         spin_unlock (&adapter_lock);
82
83         sprintf (dbf_txt, "ret:%d", ret);
84         CIO_TRACE_EVENT (4, dbf_txt);
85
86         return (ret);
87 }
88
89 void
90 do_adapter_IO (void)
91 {
92         CIO_TRACE_EVENT (4, "doaio");
93
94         spin_lock (&adapter_lock);
95
96         if (adapter_handler)
97                 (*adapter_handler) ();
98
99         spin_unlock (&adapter_lock);
100
101         return;
102 }
103
104 EXPORT_SYMBOL (s390_register_adapter_interrupt);
105 EXPORT_SYMBOL (s390_unregister_adapter_interrupt);