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