staging: unisys: get rid of UltraLogEvent macro
[linux-2.6/btrfs-unstable.git] / drivers / staging / unisys / common-spar / include / channels / channel.h
blobd5102785c77b0c9475423bbf80ad824894dcbfda
1 /* Copyright (C) 2010 - 2013 UNISYS CORPORATION
2 * All rights reserved.
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.
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.
16 #ifndef __CHANNEL_H__
17 #define __CHANNEL_H__
19 #include <linux/types.h>
20 #include <linux/io.h>
21 #include <linux/uuid.h>
24 * Whenever this file is changed a corresponding change must be made in
25 * the Console/ServicePart/visordiag_early/supervisor_channel.h file
26 * which is needed for Linux kernel compiles. These two files must be
27 * in sync.
30 /* define the following to prevent include nesting in kernel header
31 * files of similar abbreviated content
33 #define __SUPERVISOR_CHANNEL_H__
35 #define SIGNATURE_16(A, B) ((A) | (B<<8))
36 #define SIGNATURE_32(A, B, C, D) \
37 (SIGNATURE_16(A, B) | (SIGNATURE_16(C, D) << 16))
38 #define SIGNATURE_64(A, B, C, D, E, F, G, H) \
39 (SIGNATURE_32(A, B, C, D) | ((u64)(SIGNATURE_32(E, F, G, H)) << 32))
41 #ifndef lengthof
42 #define lengthof(TYPE, MEMBER) (sizeof(((TYPE *)0)->MEMBER))
43 #endif
44 #ifndef COVERQ
45 #define COVERQ(v, d) (((v)+(d)-1) / (d))
46 #endif
47 #ifndef COVER
48 #define COVER(v, d) ((d)*COVERQ(v, d))
49 #endif
51 #define ULTRA_CHANNEL_PROTOCOL_SIGNATURE SIGNATURE_32('E', 'C', 'N', 'L')
53 typedef enum {
54 CHANNELSRV_UNINITIALIZED = 0, /* channel is in an undefined state */
55 CHANNELSRV_READY = 1 /* channel has been initialized by server */
56 } CHANNEL_SERVERSTATE;
58 typedef enum {
59 CHANNELCLI_DETACHED = 0,
60 CHANNELCLI_DISABLED = 1, /* client can see channel but is NOT
61 * allowed to use it unless given TBD
62 * explicit request (should actually be
63 * < DETACHED) */
64 CHANNELCLI_ATTACHING = 2, /* legacy EFI client request
65 * for EFI server to attach */
66 CHANNELCLI_ATTACHED = 3, /* idle, but client may want
67 * to use channel any time */
68 CHANNELCLI_BUSY = 4, /* client either wants to use or is
69 * using channel */
70 CHANNELCLI_OWNED = 5 /* "no worries" state - client can
71 * access channel anytime */
72 } CHANNEL_CLIENTSTATE;
73 static inline const u8 *
74 ULTRA_CHANNELCLI_STRING(u32 v)
76 switch (v) {
77 case CHANNELCLI_DETACHED:
78 return (const u8 *) ("DETACHED");
79 case CHANNELCLI_DISABLED:
80 return (const u8 *) ("DISABLED");
81 case CHANNELCLI_ATTACHING:
82 return (const u8 *) ("ATTACHING");
83 case CHANNELCLI_ATTACHED:
84 return (const u8 *) ("ATTACHED");
85 case CHANNELCLI_BUSY:
86 return (const u8 *) ("BUSY");
87 case CHANNELCLI_OWNED:
88 return (const u8 *) ("OWNED");
89 default:
90 break;
92 return (const u8 *) ("?");
95 #define ULTRA_CHANNELSRV_IS_READY(x) ((x) == CHANNELSRV_READY)
96 #define ULTRA_CHANNEL_SERVER_READY(pChannel) \
97 (ULTRA_CHANNELSRV_IS_READY(readl(&(pChannel)->SrvState)))
99 #define ULTRA_VALID_CHANNELCLI_TRANSITION(o, n) \
100 (((((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_DISABLED)) || \
101 (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_DISABLED)) || \
102 (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_DISABLED)) || \
103 (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_DETACHED)) || \
104 (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_DETACHED)) || \
105 (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_ATTACHING)) || \
106 (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_ATTACHED)) || \
107 (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_ATTACHED)) || \
108 (((o) == CHANNELCLI_BUSY) && ((n) == CHANNELCLI_ATTACHED)) || \
109 (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_BUSY)) || \
110 (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_OWNED)) || \
111 (((o) == CHANNELCLI_DISABLED) && ((n) == CHANNELCLI_OWNED)) || \
112 (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_OWNED)) || \
113 (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_OWNED)) || \
114 (((o) == CHANNELCLI_BUSY) && ((n) == CHANNELCLI_OWNED)) || (0)) \
115 ? (1) : (0))
117 #define ULTRA_CHANNEL_CLIENT_CHK_TRANSITION(old, new, chanId, logCtx, \
118 file, line) \
119 do { \
120 if (!ULTRA_VALID_CHANNELCLI_TRANSITION(old, new)) \
121 pr_info("%s Channel StateTransition INVALID! (%s) %s(%d)-->%s(%d) @%s:%d\n", \
122 chanId, "CliState<x>", \
123 ULTRA_CHANNELCLI_STRING(old), \
124 old, \
125 ULTRA_CHANNELCLI_STRING(new), \
126 new, \
127 PathName_Last_N_Nodes((u8 *)file, 4), \
128 line); \
129 } while (0)
131 #define ULTRA_CHANNEL_CLIENT_TRANSITION(pChan, chanId, \
132 newstate, logCtx) \
133 do { \
134 ULTRA_CHANNEL_CLIENT_CHK_TRANSITION( \
135 readl(&(((CHANNEL_HEADER __iomem *) \
136 (pChan))->CliStateOS)), \
137 newstate, \
138 chanId, logCtx, __FILE__, __LINE__); \
139 pr_info("%s Channel StateTransition (%s) %s(%d)-->%s(%d) @%s:%d\n", \
140 chanId, "CliStateOS", \
141 ULTRA_CHANNELCLI_STRING( \
142 readl(&((CHANNEL_HEADER __iomem *) \
143 (pChan))->CliStateOS)), \
144 readl(&((CHANNEL_HEADER __iomem *) \
145 (pChan))->CliStateOS), \
146 ULTRA_CHANNELCLI_STRING(newstate), \
147 newstate, \
148 PathName_Last_N_Nodes(__FILE__, 4), __LINE__); \
149 writel(newstate, &((CHANNEL_HEADER __iomem *) \
150 (pChan))->CliStateOS); \
151 mb(); /* required for channel synch */ \
152 } while (0)
154 #define ULTRA_CHANNEL_CLIENT_ACQUIRE_OS(pChan, chanId, logCtx) \
155 ULTRA_channel_client_acquire_os(pChan, chanId, logCtx, \
156 (char *)__FILE__, __LINE__, \
157 (char *)__func__)
158 #define ULTRA_CHANNEL_CLIENT_RELEASE_OS(pChan, chanId, logCtx) \
159 ULTRA_channel_client_release_os(pChan, chanId, logCtx, \
160 (char *)__FILE__, __LINE__, (char *)__func__)
162 /* Values for ULTRA_CHANNEL_PROTOCOL.CliErrorBoot: */
163 /* throttling invalid boot channel statetransition error due to client
164 * disabled */
165 #define ULTRA_CLIERRORBOOT_THROTTLEMSG_DISABLED 0x01
167 /* throttling invalid boot channel statetransition error due to client
168 * not attached */
169 #define ULTRA_CLIERRORBOOT_THROTTLEMSG_NOTATTACHED 0x02
171 /* throttling invalid boot channel statetransition error due to busy channel */
172 #define ULTRA_CLIERRORBOOT_THROTTLEMSG_BUSY 0x04
174 /* Values for ULTRA_CHANNEL_PROTOCOL.CliErrorOS: */
175 /* throttling invalid guest OS channel statetransition error due to
176 * client disabled */
177 #define ULTRA_CLIERROROS_THROTTLEMSG_DISABLED 0x01
179 /* throttling invalid guest OS channel statetransition error due to
180 * client not attached */
181 #define ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED 0x02
183 /* throttling invalid guest OS channel statetransition error due to
184 * busy channel */
185 #define ULTRA_CLIERROROS_THROTTLEMSG_BUSY 0x04
187 /* Values for ULTRA_CHANNEL_PROTOCOL.Features: This define exists so
188 * that windows guest can look at the FeatureFlags in the io channel,
189 * and configure the windows driver to use interrupts or not based on
190 * this setting. This flag is set in uislib after the
191 * ULTRA_VHBA_init_channel is called. All feature bits for all
192 * channels should be defined here. The io channel feature bits are
193 * defined right here */
194 #define ULTRA_IO_DRIVER_ENABLES_INTS (0x1ULL << 1)
195 #define ULTRA_IO_CHANNEL_IS_POLLING (0x1ULL << 3)
196 #define ULTRA_IO_IOVM_IS_OK_WITH_DRIVER_DISABLING_INTS (0x1ULL << 4)
197 #define ULTRA_IO_DRIVER_DISABLES_INTS (0x1ULL << 5)
198 #define ULTRA_IO_DRIVER_SUPPORTS_ENHANCED_RCVBUF_CHECKING (0x1ULL << 6)
200 #pragma pack(push, 1) /* both GCC and VC now allow this pragma */
201 /* Common Channel Header */
202 typedef struct _CHANNEL_HEADER {
203 u64 Signature; /* Signature */
204 u32 LegacyState; /* DEPRECATED - being replaced by */
205 /* / SrvState, CliStateBoot, and CliStateOS below */
206 u32 HeaderSize; /* sizeof(CHANNEL_HEADER) */
207 u64 Size; /* Total size of this channel in bytes */
208 u64 Features; /* Flags to modify behavior */
209 uuid_le Type; /* Channel type: data, bus, control, etc. */
210 u64 PartitionHandle; /* ID of guest partition */
211 u64 Handle; /* Device number of this channel in client */
212 u64 oChannelSpace; /* Offset in bytes to channel specific area */
213 u32 VersionId; /* CHANNEL_HEADER Version ID */
214 u32 PartitionIndex; /* Index of guest partition */
215 uuid_le ZoneGuid; /* Guid of Channel's zone */
216 u32 oClientString; /* offset from channel header to
217 * nul-terminated ClientString (0 if
218 * ClientString not present) */
219 u32 CliStateBoot; /* CHANNEL_CLIENTSTATE of pre-boot
220 * EFI client of this channel */
221 u32 CmdStateCli; /* CHANNEL_COMMANDSTATE (overloaded in
222 * Windows drivers, see ServerStateUp,
223 * ServerStateDown, etc) */
224 u32 CliStateOS; /* CHANNEL_CLIENTSTATE of Guest OS
225 * client of this channel */
226 u32 ChannelCharacteristics; /* CHANNEL_CHARACTERISTIC_<xxx> */
227 u32 CmdStateSrv; /* CHANNEL_COMMANDSTATE (overloaded in
228 * Windows drivers, see ServerStateUp,
229 * ServerStateDown, etc) */
230 u32 SrvState; /* CHANNEL_SERVERSTATE */
231 u8 CliErrorBoot; /* bits to indicate err states for
232 * boot clients, so err messages can
233 * be throttled */
234 u8 CliErrorOS; /* bits to indicate err states for OS
235 * clients, so err messages can be
236 * throttled */
237 u8 Filler[1]; /* Pad out to 128 byte cacheline */
238 /* Please add all new single-byte values below here */
239 u8 RecoverChannel;
240 } CHANNEL_HEADER, *pCHANNEL_HEADER, ULTRA_CHANNEL_PROTOCOL;
242 #define ULTRA_CHANNEL_ENABLE_INTS (0x1ULL << 0)
244 /* Subheader for the Signal Type variation of the Common Channel */
245 typedef struct _SIGNAL_QUEUE_HEADER {
246 /* 1st cache line */
247 u32 VersionId; /* SIGNAL_QUEUE_HEADER Version ID */
248 u32 Type; /* Queue type: storage, network */
249 u64 Size; /* Total size of this queue in bytes */
250 u64 oSignalBase; /* Offset to signal queue area */
251 u64 FeatureFlags; /* Flags to modify behavior */
252 u64 NumSignalsSent; /* Total # of signals placed in this queue */
253 u64 NumOverflows; /* Total # of inserts failed due to
254 * full queue */
255 u32 SignalSize; /* Total size of a signal for this queue */
256 u32 MaxSignalSlots; /* Max # of slots in queue, 1 slot is
257 * always empty */
258 u32 MaxSignals; /* Max # of signals in queue
259 * (MaxSignalSlots-1) */
260 u32 Head; /* Queue head signal # */
261 /* 2nd cache line */
262 u64 NumSignalsReceived; /* Total # of signals removed from this queue */
263 u32 Tail; /* Queue tail signal # (on separate
264 * cache line) */
265 u32 Reserved1; /* Reserved field */
266 u64 Reserved2; /* Resrved field */
267 u64 ClientQueue;
268 u64 NumInterruptsReceived; /* Total # of Interrupts received. This
269 * is incremented by the ISR in the
270 * guest windows driver */
271 u64 NumEmptyCnt; /* Number of times that visor_signal_remove
272 * is called and returned Empty
273 * Status. */
274 u32 ErrorFlags; /* Error bits set during SignalReinit
275 * to denote trouble with client's
276 * fields */
277 u8 Filler[12]; /* Pad out to 64 byte cacheline */
278 } SIGNAL_QUEUE_HEADER, *pSIGNAL_QUEUE_HEADER;
280 #pragma pack(pop)
282 #define SignalInit(chan, QHDRFLD, QDATAFLD, QDATATYPE, ver, typ) \
283 do { \
284 memset(&chan->QHDRFLD, 0, sizeof(chan->QHDRFLD)); \
285 chan->QHDRFLD.VersionId = ver; \
286 chan->QHDRFLD.Type = typ; \
287 chan->QHDRFLD.Size = sizeof(chan->QDATAFLD); \
288 chan->QHDRFLD.SignalSize = sizeof(QDATATYPE); \
289 chan->QHDRFLD.oSignalBase = (u64)(chan->QDATAFLD)- \
290 (u64)(&chan->QHDRFLD); \
291 chan->QHDRFLD.MaxSignalSlots = \
292 sizeof(chan->QDATAFLD)/sizeof(QDATATYPE); \
293 chan->QHDRFLD.MaxSignals = chan->QHDRFLD.MaxSignalSlots-1; \
294 } while (0)
296 /* Generic function useful for validating any type of channel when it is
297 * received by the client that will be accessing the channel.
298 * Note that <logCtx> is only needed for callers in the EFI environment, and
299 * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages.
301 static inline int
302 ULTRA_check_channel_client(void __iomem *pChannel,
303 uuid_le expectedTypeGuid,
304 char *channelName,
305 u64 expectedMinBytes,
306 u32 expectedVersionId,
307 u64 expectedSignature,
308 char *fileName, int lineNumber, void *logCtx)
310 if (uuid_le_cmp(expectedTypeGuid, NULL_UUID_LE) != 0) {
311 uuid_le guid;
313 memcpy_fromio(&guid,
314 &((CHANNEL_HEADER __iomem *)(pChannel))->Type,
315 sizeof(guid));
316 /* caller wants us to verify type GUID */
317 if (uuid_le_cmp(guid, expectedTypeGuid) != 0) {
318 pr_err("Channel mismatch on channel=%s(%pUL) field=type expected=%pUL actual=%pUL\n",
319 channelName, &expectedTypeGuid,
320 &expectedTypeGuid, &guid);
321 return 0;
324 if (expectedMinBytes > 0) { /* caller wants us to verify
325 * channel size */
326 unsigned long long bytes = readq(&((CHANNEL_HEADER __iomem *)
327 (pChannel))->Size);
328 if (bytes < expectedMinBytes) {
329 pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8Lx actual=0x%-8.8Lx\n",
330 channelName, &expectedTypeGuid,
331 (unsigned long long)expectedMinBytes, bytes);
332 return 0;
335 if (expectedVersionId > 0) { /* caller wants us to verify
336 * channel version */
337 unsigned long ver = readl(&((CHANNEL_HEADER __iomem *)
338 (pChannel))->VersionId);
339 if (ver != expectedVersionId) {
340 pr_err("Channel mismatch on channel=%s(%pUL) field=version expected=0x%-8.8lx actual=0x%-8.8lx\n",
341 channelName, &expectedTypeGuid,
342 (unsigned long)expectedVersionId, ver);
343 return 0;
346 if (expectedSignature > 0) { /* caller wants us to verify
347 * channel signature */
348 unsigned long long sig = readq(&((CHANNEL_HEADER __iomem *)
349 (pChannel))->Signature);
350 if (sig != expectedSignature) {
351 pr_err("Channel mismatch on channel=%s(%pUL) field=signature expected=0x%-8.8llx actual=0x%-8.8llx\n",
352 channelName, &expectedTypeGuid,
353 expectedSignature, sig);
354 return 0;
357 return 1;
360 /* Generic function useful for validating any type of channel when it is about
361 * to be initialized by the server of the channel.
362 * Note that <logCtx> is only needed for callers in the EFI environment, and
363 * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages.
365 static inline int
366 ULTRA_check_channel_server(uuid_le typeGuid,
367 char *channelName,
368 u64 expectedMinBytes,
369 u64 actualBytes,
370 char *fileName, int lineNumber, void *logCtx)
372 if (expectedMinBytes > 0) /* caller wants us to verify
373 * channel size */
374 if (actualBytes < expectedMinBytes) {
375 pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8llx actual=0x%-8.8llx\n",
376 channelName, &typeGuid, expectedMinBytes,
377 actualBytes);
378 return 0;
380 return 1;
383 /* Given a file pathname <s> (with '/' or '\' separating directory nodes),
384 * returns a pointer to the beginning of a node within that pathname such
385 * that the number of nodes from that pointer to the end of the string is
386 * NOT more than <n>. Note that if the pathname has less than <n> nodes
387 * in it, the return pointer will be to the beginning of the string.
389 static inline u8 *
390 PathName_Last_N_Nodes(u8 *s, unsigned int n)
392 u8 *p = s;
393 unsigned int node_count = 0;
395 while (*p != '\0') {
396 if ((*p == '/') || (*p == '\\'))
397 node_count++;
398 p++;
400 if (node_count <= n)
401 return s;
402 while (n > 0) {
403 p--;
404 if (p == s)
405 break; /* should never happen, unless someone
406 * is changing the string while we are
407 * looking at it!! */
408 if ((*p == '/') || (*p == '\\'))
409 n--;
411 return p + 1;
414 static inline int
415 ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId,
416 void *logCtx, char *file, int line, char *func)
418 CHANNEL_HEADER __iomem *pChan = pChannel;
420 if (readl(&pChan->CliStateOS) == CHANNELCLI_DISABLED) {
421 if ((readb(&pChan->CliErrorOS)
422 & ULTRA_CLIERROROS_THROTTLEMSG_DISABLED) == 0) {
423 /* we are NOT throttling this message */
424 writeb(readb(&pChan->CliErrorOS) |
425 ULTRA_CLIERROROS_THROTTLEMSG_DISABLED,
426 &pChan->CliErrorOS);
427 /* throttle until acquire successful */
429 pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client DISABLED @%s:%d\n",
430 chanId, PathName_Last_N_Nodes((u8 *) file, 4),
431 line);
433 return 0;
435 if ((readl(&pChan->CliStateOS) != CHANNELCLI_OWNED)
436 && (readl(&pChan->CliStateBoot) == CHANNELCLI_DISABLED)) {
437 /* Our competitor is DISABLED, so we can transition to OWNED */
438 pr_info("%s Channel StateTransition (%s) %s(%d)-->%s(%d) @%s:%d\n",
439 chanId, "CliStateOS",
440 ULTRA_CHANNELCLI_STRING(readl(&pChan->CliStateOS)),
441 readl(&pChan->CliStateOS),
442 ULTRA_CHANNELCLI_STRING(CHANNELCLI_OWNED),
443 CHANNELCLI_OWNED,
444 PathName_Last_N_Nodes((u8 *) file, 4), line);
445 writel(CHANNELCLI_OWNED, &pChan->CliStateOS);
446 mb(); /* required for channel synch */
448 if (readl(&pChan->CliStateOS) == CHANNELCLI_OWNED) {
449 if (readb(&pChan->CliErrorOS) != 0) {
450 /* we are in an error msg throttling state;
451 * come out of it */
452 pr_info("%s Channel OS client acquire now successful @%s:%d\n",
453 chanId, PathName_Last_N_Nodes((u8 *) file, 4),
454 line);
455 writeb(0, &pChan->CliErrorOS);
457 return 1;
460 /* We have to do it the "hard way". We transition to BUSY,
461 * and can use the channel iff our competitor has not also
462 * transitioned to BUSY. */
463 if (readl(&pChan->CliStateOS) != CHANNELCLI_ATTACHED) {
464 if ((readb(&pChan->CliErrorOS)
465 & ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED) == 0) {
466 /* we are NOT throttling this message */
467 writeb(readb(&pChan->CliErrorOS) |
468 ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED,
469 &pChan->CliErrorOS);
470 /* throttle until acquire successful */
471 pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client NOT ATTACHED (state=%s(%d)) @%s:%d\n",
472 chanId, ULTRA_CHANNELCLI_STRING(
473 readl(&pChan->CliStateOS)),
474 readl(&pChan->CliStateOS),
475 PathName_Last_N_Nodes((u8 *) file, 4),
476 line);
478 return 0;
480 writel(CHANNELCLI_BUSY, &pChan->CliStateOS);
481 mb(); /* required for channel synch */
482 if (readl(&pChan->CliStateBoot) == CHANNELCLI_BUSY) {
483 if ((readb(&pChan->CliErrorOS)
484 & ULTRA_CLIERROROS_THROTTLEMSG_BUSY) == 0) {
485 /* we are NOT throttling this message */
486 writeb(readb(&pChan->CliErrorOS) |
487 ULTRA_CLIERROROS_THROTTLEMSG_BUSY,
488 &pChan->CliErrorOS);
489 /* throttle until acquire successful */
490 pr_info("%s Channel StateTransition failed - host OS acquire failed because boot BUSY @%s:%d\n",
491 chanId, PathName_Last_N_Nodes((u8 *) file, 4),
492 line);
494 /* reset busy */
495 writel(CHANNELCLI_ATTACHED, &pChan->CliStateOS);
496 mb(); /* required for channel synch */
497 return 0;
499 if (readb(&pChan->CliErrorOS) != 0) {
500 /* we are in an error msg throttling state; come out of it */
501 pr_info("%s Channel OS client acquire now successful @%s:%d\n",
502 chanId, PathName_Last_N_Nodes((u8 *) file, 4),
503 line);
504 writeb(0, &pChan->CliErrorOS);
506 return 1;
509 static inline void
510 ULTRA_channel_client_release_os(void __iomem *pChannel, u8 *chanId,
511 void *logCtx, char *file, int line, char *func)
513 CHANNEL_HEADER __iomem *pChan = pChannel;
515 if (readb(&pChan->CliErrorOS) != 0) {
516 /* we are in an error msg throttling state; come out of it */
517 pr_info("%s Channel OS client error state cleared @%s:%d\n",
518 chanId, PathName_Last_N_Nodes((u8 *) file, 4),
519 line);
520 writeb(0, &pChan->CliErrorOS);
522 if (readl(&pChan->CliStateOS) == CHANNELCLI_OWNED)
523 return;
524 if (readl(&pChan->CliStateOS) != CHANNELCLI_BUSY) {
525 pr_info("%s Channel StateTransition INVALID! - release failed because OS client NOT BUSY (state=%s(%d)) @%s:%d\n",
526 chanId, ULTRA_CHANNELCLI_STRING(
527 readl(&pChan->CliStateOS)),
528 readl(&pChan->CliStateOS),
529 PathName_Last_N_Nodes((u8 *) file, 4), line);
530 /* return; */
532 writel(CHANNELCLI_ATTACHED, &pChan->CliStateOS); /* release busy */
536 * Routine Description:
537 * Tries to insert the prebuilt signal pointed to by pSignal into the nth
538 * Queue of the Channel pointed to by pChannel
540 * Parameters:
541 * pChannel: (IN) points to the IO Channel
542 * Queue: (IN) nth Queue of the IO Channel
543 * pSignal: (IN) pointer to the signal
545 * Assumptions:
546 * - pChannel, Queue and pSignal are valid.
547 * - If insertion fails due to a full queue, the caller will determine the
548 * retry policy (e.g. wait & try again, report an error, etc.).
550 * Return value: 1 if the insertion succeeds, 0 if the queue was
551 * full.
554 unsigned char visor_signal_insert(CHANNEL_HEADER __iomem *pChannel, u32 Queue,
555 void *pSignal);
558 * Routine Description:
559 * Removes one signal from Channel pChannel's nth Queue at the
560 * time of the call and copies it into the memory pointed to by
561 * pSignal.
563 * Parameters:
564 * pChannel: (IN) points to the IO Channel
565 * Queue: (IN) nth Queue of the IO Channel
566 * pSignal: (IN) pointer to where the signals are to be copied
568 * Assumptions:
569 * - pChannel and Queue are valid.
570 * - pSignal points to a memory area large enough to hold queue's SignalSize
572 * Return value: 1 if the removal succeeds, 0 if the queue was
573 * empty.
576 unsigned char visor_signal_remove(CHANNEL_HEADER __iomem *pChannel, u32 Queue,
577 void *pSignal);
580 * Routine Description:
581 * Removes all signals present in Channel pChannel's nth Queue at the
582 * time of the call and copies them into the memory pointed to by
583 * pSignal. Returns the # of signals copied as the value of the routine.
585 * Parameters:
586 * pChannel: (IN) points to the IO Channel
587 * Queue: (IN) nth Queue of the IO Channel
588 * pSignal: (IN) pointer to where the signals are to be copied
590 * Assumptions:
591 * - pChannel and Queue are valid.
592 * - pSignal points to a memory area large enough to hold Queue's MaxSignals
593 * # of signals, each of which is Queue's SignalSize.
595 * Return value:
596 * # of signals copied.
598 unsigned int SignalRemoveAll(pCHANNEL_HEADER pChannel, u32 Queue,
599 void *pSignal);
602 * Routine Description:
603 * Determine whether a signal queue is empty.
605 * Parameters:
606 * pChannel: (IN) points to the IO Channel
607 * Queue: (IN) nth Queue of the IO Channel
609 * Return value:
610 * 1 if the signal queue is empty, 0 otherwise.
612 unsigned char visor_signalqueue_empty(CHANNEL_HEADER __iomem *pChannel,
613 u32 Queue);
615 #endif