1/*
2 *  drivers/s390/cio/airq.c
3 *   S/390 common I/O routines -- support for adapter interruptions
4 *
5 *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
6 *			      IBM Corporation
7 *    Author(s): Ingo Adlung (adlung@de.ibm.com)
8 *		 Cornelia Huck (cornelia.huck@de.ibm.com)
9 *		 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)
46		synchronize_sched();  /* Allow interrupts to complete. */
47
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;
66		synchronize_sched();  /* Allow interrupts to complete. */
67		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);
86