]> Git Repo - linux.git/blob - drivers/staging/unisys/channels/channel.c
selinux: Remove security_ops extern
[linux.git] / drivers / staging / unisys / channels / channel.c
1 /* Copyright (C) 2010 - 2013 UNISYS CORPORATION
2  * All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or (at
7  * your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12  * NON INFRINGEMENT.  See the GNU General Public License for more
13  * details.
14  */
15
16 #include <linux/kernel.h>
17 #ifdef CONFIG_MODVERSIONS
18 #include <config/modversions.h>
19 #endif
20 #include <linux/module.h>
21 #include <linux/init.h>         /* for module_init and module_exit */
22 #include <linux/slab.h>         /* for memcpy */
23 #include <linux/types.h>
24
25 /* Implementation of exported functions for Supervisor channels */
26 #include "channel.h"
27
28 /*
29  * Routine Description:
30  * Tries to insert the prebuilt signal pointed to by pSignal into the nth
31  * Queue of the Channel pointed to by pChannel
32  *
33  * Parameters:
34  * pChannel: (IN) points to the IO Channel
35  * Queue: (IN) nth Queue of the IO Channel
36  * pSignal: (IN) pointer to the signal
37  *
38  * Assumptions:
39  * - pChannel, Queue and pSignal are valid.
40  * - If insertion fails due to a full queue, the caller will determine the
41  * retry policy (e.g. wait & try again, report an error, etc.).
42  *
43  * Return value:
44  * 1 if the insertion succeeds, 0 if the queue was full.
45  */
46 unsigned char
47 visor_signal_insert(CHANNEL_HEADER __iomem *pChannel, U32 Queue, void *pSignal)
48 {
49         void __iomem *psignal;
50         unsigned int head, tail, nof;
51
52         SIGNAL_QUEUE_HEADER __iomem *pqhdr =
53             (SIGNAL_QUEUE_HEADER __iomem *)
54                 ((char __iomem *) pChannel + readq(&pChannel->oChannelSpace))
55                 + Queue;
56
57         /* capture current head and tail */
58         head = readl(&pqhdr->Head);
59         tail = readl(&pqhdr->Tail);
60
61         /* queue is full if (head + 1) % n equals tail */
62         if (((head + 1) % readl(&pqhdr->MaxSignalSlots)) == tail) {
63                 nof = readq(&pqhdr->NumOverflows) + 1;
64                 writeq(nof, &pqhdr->NumOverflows);
65                 return 0;
66         }
67
68         /* increment the head index */
69         head = (head + 1) % readl(&pqhdr->MaxSignalSlots);
70
71         /* copy signal to the head location from the area pointed to
72          * by pSignal
73          */
74         psignal = (char __iomem *)pqhdr + readq(&pqhdr->oSignalBase) +
75                 (head * readl(&pqhdr->SignalSize));
76         MEMCPY_TOIO(psignal, pSignal, readl(&pqhdr->SignalSize));
77
78         VolatileBarrier();
79         writel(head, &pqhdr->Head);
80
81         writeq(readq(&pqhdr->NumSignalsSent) + 1, &pqhdr->NumSignalsSent);
82         return 1;
83 }
84 EXPORT_SYMBOL_GPL(visor_signal_insert);
85
86 /*
87  * Routine Description:
88  * Removes one signal from Channel pChannel's nth Queue at the
89  * time of the call and copies it into the memory pointed to by
90  * pSignal.
91  *
92  * Parameters:
93  * pChannel: (IN) points to the IO Channel
94  * Queue: (IN) nth Queue of the IO Channel
95  * pSignal: (IN) pointer to where the signals are to be copied
96  *
97  * Assumptions:
98  * - pChannel and Queue are valid.
99  * - pSignal points to a memory area large enough to hold queue's SignalSize
100  *
101  * Return value:
102  * 1 if the removal succeeds, 0 if the queue was empty.
103  */
104 unsigned char
105 visor_signal_remove(CHANNEL_HEADER __iomem *pChannel, U32 Queue, void *pSignal)
106 {
107         void __iomem *psource;
108         unsigned int head, tail;
109         SIGNAL_QUEUE_HEADER __iomem *pqhdr =
110             (SIGNAL_QUEUE_HEADER __iomem *) ((char __iomem *) pChannel +
111                                     readq(&pChannel->oChannelSpace)) + Queue;
112
113         /* capture current head and tail */
114         head = readl(&pqhdr->Head);
115         tail = readl(&pqhdr->Tail);
116
117         /* queue is empty if the head index equals the tail index */
118         if (head == tail) {
119                 writeq(readq(&pqhdr->NumEmptyCnt) + 1, &pqhdr->NumEmptyCnt);
120                 return 0;
121         }
122
123         /* advance past the 'empty' front slot */
124         tail = (tail + 1) % readl(&pqhdr->MaxSignalSlots);
125
126         /* copy signal from tail location to the area pointed to by pSignal */
127         psource = (char __iomem *) pqhdr + readq(&pqhdr->oSignalBase) +
128                 (tail * readl(&pqhdr->SignalSize));
129         MEMCPY_FROMIO(pSignal, psource, readl(&pqhdr->SignalSize));
130
131         VolatileBarrier();
132         writel(tail, &pqhdr->Tail);
133
134         writeq(readq(&pqhdr->NumSignalsReceived) + 1,
135                &pqhdr->NumSignalsReceived);
136         return 1;
137 }
138 EXPORT_SYMBOL_GPL(visor_signal_remove);
139
140 /*
141  * Routine Description:
142  * Removes all signals present in Channel pChannel's nth Queue at the
143  * time of the call and copies them into the memory pointed to by
144  * pSignal.  Returns the # of signals copied as the value of the routine.
145  *
146  * Parameters:
147  * pChannel: (IN) points to the IO Channel
148  * Queue: (IN) nth Queue of the IO Channel
149  * pSignal: (IN) pointer to where the signals are to be copied
150  *
151  * Assumptions:
152  * - pChannel and Queue are valid.
153  * - pSignal points to a memory area large enough to hold Queue's MaxSignals
154  * # of signals, each of which is Queue's SignalSize.
155  *
156  * Return value:
157  * # of signals copied.
158  */
159 unsigned int
160 SignalRemoveAll(pCHANNEL_HEADER pChannel, U32 Queue, void *pSignal)
161 {
162         void *psource;
163         unsigned int head, tail, signalCount = 0;
164         pSIGNAL_QUEUE_HEADER pqhdr =
165             (pSIGNAL_QUEUE_HEADER) ((char *) pChannel +
166                                     pChannel->oChannelSpace) + Queue;
167
168         /* capture current head and tail */
169         head = pqhdr->Head;
170         tail = pqhdr->Tail;
171
172         /* queue is empty if the head index equals the tail index */
173         if (head == tail)
174                 return 0;
175
176         while (head != tail) {
177                 /* advance past the 'empty' front slot */
178                 tail = (tail + 1) % pqhdr->MaxSignalSlots;
179
180                 /* copy signal from tail location to the area pointed
181                  * to by pSignal
182                  */
183                 psource =
184                     (char *) pqhdr + pqhdr->oSignalBase +
185                     (tail * pqhdr->SignalSize);
186                 MEMCPY((char *) pSignal + (pqhdr->SignalSize * signalCount),
187                        psource, pqhdr->SignalSize);
188
189                 VolatileBarrier();
190                 pqhdr->Tail = tail;
191
192                 signalCount++;
193                 pqhdr->NumSignalsReceived++;
194         }
195
196         return signalCount;
197 }
198
199 /*
200  * Routine Description:
201  * Determine whether a signal queue is empty.
202  *
203  * Parameters:
204  * pChannel: (IN) points to the IO Channel
205  * Queue: (IN) nth Queue of the IO Channel
206  *
207  * Return value:
208  * 1 if the signal queue is empty, 0 otherwise.
209  */
210 unsigned char
211 visor_signalqueue_empty(CHANNEL_HEADER __iomem *pChannel, U32 Queue)
212 {
213         SIGNAL_QUEUE_HEADER __iomem *pqhdr =
214             (SIGNAL_QUEUE_HEADER __iomem *) ((char __iomem *) pChannel +
215                                     readq(&pChannel->oChannelSpace)) + Queue;
216         return readl(&pqhdr->Head) == readl(&pqhdr->Tail);
217 }
218 EXPORT_SYMBOL_GPL(visor_signalqueue_empty);
219
This page took 0.04485 seconds and 4 git commands to generate.