]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - drivers/staging/unisys/uislib/uisqueue.c
staging: unisys: remove U8 type
[mirror_ubuntu-zesty-kernel.git] / drivers / staging / unisys / uislib / uisqueue.c
1 /* uisqueue.c
2 *
3 * Copyright (C) 2010 - 2013 UNISYS CORPORATION
4 * All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or (at
9 * your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
14 * NON INFRINGEMENT. See the GNU General Public License for more
15 * details.
16 */
17
18 /* @ALL_INSPECTED */
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21
22 #include "uisutils.h"
23
24 #include "chanstub.h"
25
26 /* this is shorter than using __FILE__ (full path name) in
27 * debug/info/error messages */
28 #define CURRENT_FILE_PC UISLIB_PC_uisqueue_c
29 #define __MYFILE__ "uisqueue.c"
30
31 #define CHECK_CACHE_ALIGN 0
32
33 /*****************************************************/
34 /* Exported functions */
35 /*****************************************************/
36 unsigned long long
37 uisqueue_InterlockedOr(unsigned long long __iomem *Target,
38 unsigned long long Set)
39 {
40 unsigned long long i;
41 unsigned long long j;
42
43 j = readq(Target);
44 do {
45 i = j;
46 j = uislibcmpxchg64((__force unsigned long long *)Target,
47 i, i | Set, sizeof(*(Target)));
48
49 } while (i != j);
50
51 return j;
52 }
53 EXPORT_SYMBOL_GPL(uisqueue_InterlockedOr);
54
55 unsigned long long
56 uisqueue_InterlockedAnd(unsigned long long __iomem *Target,
57 unsigned long long Set)
58 {
59 unsigned long long i;
60 unsigned long long j;
61
62 j = readq(Target);
63 do {
64 i = j;
65 j = uislibcmpxchg64((__force unsigned long long *)Target,
66 i, i & Set, sizeof(*(Target)));
67
68 } while (i != j);
69
70 return j;
71 }
72 EXPORT_SYMBOL_GPL(uisqueue_InterlockedAnd);
73
74 static u8
75 do_locked_client_insert(struct uisqueue_info *queueinfo,
76 unsigned int whichqueue,
77 void *pSignal,
78 spinlock_t *lock,
79 unsigned char issueInterruptIfEmpty,
80 U64 interruptHandle, u8 *channelId)
81 {
82 unsigned long flags;
83 unsigned char queueWasEmpty;
84 unsigned int locked = 0;
85 unsigned int acquired = 0;
86 u8 rc = 0;
87
88 spin_lock_irqsave(lock, flags);
89 locked = 1;
90
91 if (!ULTRA_CHANNEL_CLIENT_ACQUIRE_OS(queueinfo->chan, channelId, NULL))
92 goto Away;
93
94 acquired = 1;
95
96 queueWasEmpty = visor_signalqueue_empty(queueinfo->chan, whichqueue);
97 if (!visor_signal_insert(queueinfo->chan, whichqueue, pSignal))
98 goto Away;
99 ULTRA_CHANNEL_CLIENT_RELEASE_OS(queueinfo->chan, channelId, NULL);
100 acquired = 0;
101 spin_unlock_irqrestore(lock, flags);
102 locked = 0;
103
104 queueinfo->packets_sent++;
105
106 rc = 1;
107 Away:
108 if (acquired) {
109 ULTRA_CHANNEL_CLIENT_RELEASE_OS(queueinfo->chan, channelId,
110 NULL);
111 acquired = 0;
112 }
113 if (locked) {
114 spin_unlock_irqrestore((spinlock_t *) lock, flags);
115 locked = 0;
116 }
117
118 return rc;
119 }
120
121 int
122 uisqueue_put_cmdrsp_with_lock_client(struct uisqueue_info *queueinfo,
123 struct uiscmdrsp *cmdrsp,
124 unsigned int whichqueue,
125 void *insertlock,
126 unsigned char issueInterruptIfEmpty,
127 U64 interruptHandle,
128 char oktowait, u8 *channelId)
129 {
130 while (!do_locked_client_insert(queueinfo, whichqueue, cmdrsp,
131 (spinlock_t *) insertlock,
132 issueInterruptIfEmpty,
133 interruptHandle, channelId)) {
134 if (oktowait != OK_TO_WAIT) {
135 LOGERR("****FAILED visor_signal_insert failed; cannot wait; insert aborted\n");
136 return 0; /* failed to queue */
137 }
138 /* try again */
139 LOGERR("****FAILED visor_signal_insert failed; waiting to try again\n");
140 set_current_state(TASK_INTERRUPTIBLE);
141 schedule_timeout(msecs_to_jiffies(10));
142 }
143 return 1;
144 }
145 EXPORT_SYMBOL_GPL(uisqueue_put_cmdrsp_with_lock_client);
146
147 /* uisqueue_get_cmdrsp gets the cmdrsp entry at the head of the queue
148 * returns NULL if queue is empty */
149 int
150 uisqueue_get_cmdrsp(struct uisqueue_info *queueinfo,
151 void *cmdrsp, unsigned int whichqueue)
152 {
153 if (!visor_signal_remove(queueinfo->chan, whichqueue, cmdrsp))
154 return 0;
155
156 queueinfo->packets_received++;
157
158 return 1; /* Success */
159 }
160 EXPORT_SYMBOL_GPL(uisqueue_get_cmdrsp);