staging: unisys: remove U32 type
[deliverable/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.042743 seconds and 5 git commands to generate.