staging: unisys: remove U32 type
[deliverable/linux.git] / drivers / staging / unisys / common-spar / include / channels / channel.h
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 #ifndef __CHANNEL_H__
17 #define __CHANNEL_H__
18
19 #include <linux/uuid.h>
20
21 /*
22 * Whenever this file is changed a corresponding change must be made in
23 * the Console/ServicePart/visordiag_early/supervisor_channel.h file
24 * which is needed for Linux kernel compiles. These two files must be
25 * in sync.
26 */
27
28 /* define the following to prevent include nesting in kernel header
29 * files of similar abbreviated content
30 */
31 #define __SUPERVISOR_CHANNEL_H__
32
33 #include "commontypes.h"
34
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))
40
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
50
51 #define ULTRA_CHANNEL_PROTOCOL_SIGNATURE SIGNATURE_32('E', 'C', 'N', 'L')
52
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;
57
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)
75 {
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;
91 }
92 return (const u8 *) ("?");
93 }
94
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)))
98
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))
116
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 UltraLogEvent(logCtx, \
122 CHANNELSTATE_DIAG_EVENTID_TRANSITERR, \
123 CHANNELSTATE_DIAG_SEVERITY, \
124 CHANNELSTATE_DIAG_SUBSYS, \
125 __func__, __LINE__, \
126 "%s Channel StateTransition INVALID! (%s) %s(%d)-->%s(%d) @%s:%d\n", \
127 chanId, "CliState<x>", \
128 ULTRA_CHANNELCLI_STRING(old), \
129 old, \
130 ULTRA_CHANNELCLI_STRING(new), \
131 new, \
132 PathName_Last_N_Nodes((u8 *)file, 4), \
133 line); \
134 } while (0)
135
136 #define ULTRA_CHANNEL_CLIENT_TRANSITION(pChan, chanId, \
137 newstate, logCtx) \
138 do { \
139 ULTRA_CHANNEL_CLIENT_CHK_TRANSITION( \
140 readl(&(((CHANNEL_HEADER __iomem *) \
141 (pChan))->CliStateOS)), \
142 newstate, \
143 chanId, logCtx, __FILE__, __LINE__); \
144 UltraLogEvent(logCtx, CHANNELSTATE_DIAG_EVENTID_TRANSITOK, \
145 CHANNELSTATE_DIAG_SEVERITY, \
146 CHANNELSTATE_DIAG_SUBSYS, \
147 __func__, __LINE__, \
148 "%s Channel StateTransition (%s) %s(%d)-->%s(%d) @%s:%d\n", \
149 chanId, "CliStateOS", \
150 ULTRA_CHANNELCLI_STRING( \
151 readl(&((CHANNEL_HEADER __iomem *) \
152 (pChan))->CliStateOS)), \
153 readl(&((CHANNEL_HEADER __iomem *) \
154 (pChan))->CliStateOS), \
155 ULTRA_CHANNELCLI_STRING(newstate), \
156 newstate, \
157 PathName_Last_N_Nodes(__FILE__, 4), __LINE__); \
158 writel(newstate, &((CHANNEL_HEADER __iomem *) \
159 (pChan))->CliStateOS); \
160 MEMORYBARRIER; \
161 } while (0)
162
163 #define ULTRA_CHANNEL_CLIENT_ACQUIRE_OS(pChan, chanId, logCtx) \
164 ULTRA_channel_client_acquire_os(pChan, chanId, logCtx, \
165 (char *)__FILE__, __LINE__, \
166 (char *)__func__)
167 #define ULTRA_CHANNEL_CLIENT_RELEASE_OS(pChan, chanId, logCtx) \
168 ULTRA_channel_client_release_os(pChan, chanId, logCtx, \
169 (char *)__FILE__, __LINE__, (char *)__func__)
170
171 /* Values for ULTRA_CHANNEL_PROTOCOL.CliErrorBoot: */
172 /* throttling invalid boot channel statetransition error due to client
173 * disabled */
174 #define ULTRA_CLIERRORBOOT_THROTTLEMSG_DISABLED 0x01
175
176 /* throttling invalid boot channel statetransition error due to client
177 * not attached */
178 #define ULTRA_CLIERRORBOOT_THROTTLEMSG_NOTATTACHED 0x02
179
180 /* throttling invalid boot channel statetransition error due to busy channel */
181 #define ULTRA_CLIERRORBOOT_THROTTLEMSG_BUSY 0x04
182
183 /* Values for ULTRA_CHANNEL_PROTOCOL.CliErrorOS: */
184 /* throttling invalid guest OS channel statetransition error due to
185 * client disabled */
186 #define ULTRA_CLIERROROS_THROTTLEMSG_DISABLED 0x01
187
188 /* throttling invalid guest OS channel statetransition error due to
189 * client not attached */
190 #define ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED 0x02
191
192 /* throttling invalid guest OS channel statetransition error due to
193 * busy channel */
194 #define ULTRA_CLIERROROS_THROTTLEMSG_BUSY 0x04
195
196 /* Values for ULTRA_CHANNEL_PROTOCOL.Features: This define exists so
197 * that windows guest can look at the FeatureFlags in the io channel,
198 * and configure the windows driver to use interrupts or not based on
199 * this setting. This flag is set in uislib after the
200 * ULTRA_VHBA_init_channel is called. All feature bits for all
201 * channels should be defined here. The io channel feature bits are
202 * defined right here */
203 #define ULTRA_IO_DRIVER_ENABLES_INTS (0x1ULL << 1)
204 #define ULTRA_IO_CHANNEL_IS_POLLING (0x1ULL << 3)
205 #define ULTRA_IO_IOVM_IS_OK_WITH_DRIVER_DISABLING_INTS (0x1ULL << 4)
206 #define ULTRA_IO_DRIVER_DISABLES_INTS (0x1ULL << 5)
207 #define ULTRA_IO_DRIVER_SUPPORTS_ENHANCED_RCVBUF_CHECKING (0x1ULL << 6)
208
209 #pragma pack(push, 1) /* both GCC and VC now allow this pragma */
210 /* Common Channel Header */
211 typedef struct _CHANNEL_HEADER {
212 U64 Signature; /* Signature */
213 u32 LegacyState; /* DEPRECATED - being replaced by */
214 /* / SrvState, CliStateBoot, and CliStateOS below */
215 u32 HeaderSize; /* sizeof(CHANNEL_HEADER) */
216 U64 Size; /* Total size of this channel in bytes */
217 U64 Features; /* Flags to modify behavior */
218 uuid_le Type; /* Channel type: data, bus, control, etc. */
219 U64 PartitionHandle; /* ID of guest partition */
220 U64 Handle; /* Device number of this channel in client */
221 U64 oChannelSpace; /* Offset in bytes to channel specific area */
222 u32 VersionId; /* CHANNEL_HEADER Version ID */
223 u32 PartitionIndex; /* Index of guest partition */
224 uuid_le ZoneGuid; /* Guid of Channel's zone */
225 u32 oClientString; /* offset from channel header to
226 * nul-terminated ClientString (0 if
227 * ClientString not present) */
228 u32 CliStateBoot; /* CHANNEL_CLIENTSTATE of pre-boot
229 * EFI client of this channel */
230 u32 CmdStateCli; /* CHANNEL_COMMANDSTATE (overloaded in
231 * Windows drivers, see ServerStateUp,
232 * ServerStateDown, etc) */
233 u32 CliStateOS; /* CHANNEL_CLIENTSTATE of Guest OS
234 * client of this channel */
235 u32 ChannelCharacteristics; /* CHANNEL_CHARACTERISTIC_<xxx> */
236 u32 CmdStateSrv; /* CHANNEL_COMMANDSTATE (overloaded in
237 * Windows drivers, see ServerStateUp,
238 * ServerStateDown, etc) */
239 u32 SrvState; /* CHANNEL_SERVERSTATE */
240 u8 CliErrorBoot; /* bits to indicate err states for
241 * boot clients, so err messages can
242 * be throttled */
243 u8 CliErrorOS; /* bits to indicate err states for OS
244 * clients, so err messages can be
245 * throttled */
246 u8 Filler[1]; /* Pad out to 128 byte cacheline */
247 /* Please add all new single-byte values below here */
248 u8 RecoverChannel;
249 } CHANNEL_HEADER, *pCHANNEL_HEADER, ULTRA_CHANNEL_PROTOCOL;
250
251 #define ULTRA_CHANNEL_ENABLE_INTS (0x1ULL << 0)
252
253 /* Subheader for the Signal Type variation of the Common Channel */
254 typedef struct _SIGNAL_QUEUE_HEADER {
255 /* 1st cache line */
256 u32 VersionId; /* SIGNAL_QUEUE_HEADER Version ID */
257 u32 Type; /* Queue type: storage, network */
258 U64 Size; /* Total size of this queue in bytes */
259 U64 oSignalBase; /* Offset to signal queue area */
260 U64 FeatureFlags; /* Flags to modify behavior */
261 U64 NumSignalsSent; /* Total # of signals placed in this queue */
262 U64 NumOverflows; /* Total # of inserts failed due to
263 * full queue */
264 u32 SignalSize; /* Total size of a signal for this queue */
265 u32 MaxSignalSlots; /* Max # of slots in queue, 1 slot is
266 * always empty */
267 u32 MaxSignals; /* Max # of signals in queue
268 * (MaxSignalSlots-1) */
269 u32 Head; /* Queue head signal # */
270 /* 2nd cache line */
271 U64 NumSignalsReceived; /* Total # of signals removed from this queue */
272 u32 Tail; /* Queue tail signal # (on separate
273 * cache line) */
274 u32 Reserved1; /* Reserved field */
275 U64 Reserved2; /* Resrved field */
276 U64 ClientQueue;
277 U64 NumInterruptsReceived; /* Total # of Interrupts received. This
278 * is incremented by the ISR in the
279 * guest windows driver */
280 U64 NumEmptyCnt; /* Number of times that visor_signal_remove
281 * is called and returned Empty
282 * Status. */
283 u32 ErrorFlags; /* Error bits set during SignalReinit
284 * to denote trouble with client's
285 * fields */
286 u8 Filler[12]; /* Pad out to 64 byte cacheline */
287 } SIGNAL_QUEUE_HEADER, *pSIGNAL_QUEUE_HEADER;
288
289 #pragma pack(pop)
290
291 #define SignalInit(chan, QHDRFLD, QDATAFLD, QDATATYPE, ver, typ) \
292 do { \
293 MEMSET(&chan->QHDRFLD, 0, sizeof(chan->QHDRFLD)); \
294 chan->QHDRFLD.VersionId = ver; \
295 chan->QHDRFLD.Type = typ; \
296 chan->QHDRFLD.Size = sizeof(chan->QDATAFLD); \
297 chan->QHDRFLD.SignalSize = sizeof(QDATATYPE); \
298 chan->QHDRFLD.oSignalBase = (UINTN)(chan->QDATAFLD)- \
299 (UINTN)(&chan->QHDRFLD); \
300 chan->QHDRFLD.MaxSignalSlots = \
301 sizeof(chan->QDATAFLD)/sizeof(QDATATYPE); \
302 chan->QHDRFLD.MaxSignals = chan->QHDRFLD.MaxSignalSlots-1; \
303 } while (0)
304
305 /* Generic function useful for validating any type of channel when it is
306 * received by the client that will be accessing the channel.
307 * Note that <logCtx> is only needed for callers in the EFI environment, and
308 * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages.
309 */
310 static inline int
311 ULTRA_check_channel_client(void __iomem *pChannel,
312 uuid_le expectedTypeGuid,
313 char *channelName,
314 U64 expectedMinBytes,
315 u32 expectedVersionId,
316 U64 expectedSignature,
317 char *fileName, int lineNumber, void *logCtx)
318 {
319 if (uuid_le_cmp(expectedTypeGuid, NULL_UUID_LE) != 0)
320 /* caller wants us to verify type GUID */
321 if (MEMCMP_IO(&(((CHANNEL_HEADER __iomem *) (pChannel))->Type),
322 &expectedTypeGuid, sizeof(uuid_le)) != 0) {
323 CHANNEL_GUID_MISMATCH(expectedTypeGuid, channelName,
324 "type", expectedTypeGuid,
325 ((CHANNEL_HEADER __iomem *)
326 (pChannel))->Type, fileName,
327 lineNumber, logCtx);
328 return 0;
329 }
330 if (expectedMinBytes > 0) /* caller wants us to verify
331 * channel size */
332 if (readq(&((CHANNEL_HEADER __iomem *)
333 (pChannel))->Size) < expectedMinBytes) {
334 CHANNEL_U64_MISMATCH(expectedTypeGuid, channelName,
335 "size", expectedMinBytes,
336 readq(&((CHANNEL_HEADER __iomem *)
337 (pChannel))->Size),
338 fileName,
339 lineNumber, logCtx);
340 return 0;
341 }
342 if (expectedVersionId > 0) /* caller wants us to verify
343 * channel version */
344 if (readl(&((CHANNEL_HEADER __iomem *) (pChannel))->VersionId)
345 != expectedVersionId) {
346 CHANNEL_U32_MISMATCH(expectedTypeGuid, channelName,
347 "version", expectedVersionId,
348 readl(&((CHANNEL_HEADER __iomem *)
349 (pChannel))->VersionId),
350 fileName, lineNumber, logCtx);
351 return 0;
352 }
353 if (expectedSignature > 0) /* caller wants us to verify
354 * channel signature */
355 if (readq(&((CHANNEL_HEADER __iomem *) (pChannel))->Signature)
356 != expectedSignature) {
357 CHANNEL_U64_MISMATCH(expectedTypeGuid, channelName,
358 "signature", expectedSignature,
359 readq(&((CHANNEL_HEADER __iomem *)
360 (pChannel))->Signature),
361 fileName,
362 lineNumber, logCtx);
363 return 0;
364 }
365 return 1;
366 }
367
368 /* Generic function useful for validating any type of channel when it is about
369 * to be initialized by the server of the channel.
370 * Note that <logCtx> is only needed for callers in the EFI environment, and
371 * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages.
372 */
373 static inline int
374 ULTRA_check_channel_server(uuid_le typeGuid,
375 char *channelName,
376 U64 expectedMinBytes,
377 U64 actualBytes,
378 char *fileName, int lineNumber, void *logCtx)
379 {
380 if (expectedMinBytes > 0) /* caller wants us to verify
381 * channel size */
382 if (actualBytes < expectedMinBytes) {
383 CHANNEL_U64_MISMATCH(typeGuid, channelName, "size",
384 expectedMinBytes, actualBytes,
385 fileName, lineNumber, logCtx);
386 return 0;
387 }
388 return 1;
389 }
390
391 /* Given a file pathname <s> (with '/' or '\' separating directory nodes),
392 * returns a pointer to the beginning of a node within that pathname such
393 * that the number of nodes from that pointer to the end of the string is
394 * NOT more than <n>. Note that if the pathname has less than <n> nodes
395 * in it, the return pointer will be to the beginning of the string.
396 */
397 static inline u8 *
398 PathName_Last_N_Nodes(u8 *s, unsigned int n)
399 {
400 u8 *p = s;
401 unsigned int node_count = 0;
402 while (*p != '\0') {
403 if ((*p == '/') || (*p == '\\'))
404 node_count++;
405 p++;
406 }
407 if (node_count <= n)
408 return s;
409 while (n > 0) {
410 p--;
411 if (p == s)
412 break; /* should never happen, unless someone
413 * is changing the string while we are
414 * looking at it!! */
415 if ((*p == '/') || (*p == '\\'))
416 n--;
417 }
418 return p + 1;
419 }
420
421 static inline int
422 ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId,
423 void *logCtx, char *file, int line, char *func)
424 {
425 CHANNEL_HEADER __iomem *pChan = pChannel;
426
427 if (readl(&pChan->CliStateOS) == CHANNELCLI_DISABLED) {
428 if ((readb(&pChan->CliErrorOS)
429 & ULTRA_CLIERROROS_THROTTLEMSG_DISABLED) == 0) {
430 /* we are NOT throttling this message */
431 writeb(readb(&pChan->CliErrorOS) |
432 ULTRA_CLIERROROS_THROTTLEMSG_DISABLED,
433 &pChan->CliErrorOS);
434 /* throttle until acquire successful */
435
436 UltraLogEvent(logCtx,
437 CHANNELSTATE_DIAG_EVENTID_TRANSITERR,
438 CHANNELSTATE_DIAG_SEVERITY,
439 CHANNELSTATE_DIAG_SUBSYS, func, line,
440 "%s Channel StateTransition INVALID! - acquire failed because OS client DISABLED @%s:%d\n",
441 chanId, PathName_Last_N_Nodes(
442 (u8 *) file, 4), line);
443 }
444 return 0;
445 }
446 if ((readl(&pChan->CliStateOS) != CHANNELCLI_OWNED)
447 && (readl(&pChan->CliStateBoot) == CHANNELCLI_DISABLED)) {
448 /* Our competitor is DISABLED, so we can transition to OWNED */
449 UltraLogEvent(logCtx, CHANNELSTATE_DIAG_EVENTID_TRANSITOK,
450 CHANNELSTATE_DIAG_SEVERITY,
451 CHANNELSTATE_DIAG_SUBSYS, func, line,
452 "%s Channel StateTransition (%s) %s(%d)-->%s(%d) @%s:%d\n",
453 chanId, "CliStateOS",
454 ULTRA_CHANNELCLI_STRING(
455 readl(&pChan->CliStateOS)),
456 readl(&pChan->CliStateOS),
457 ULTRA_CHANNELCLI_STRING(CHANNELCLI_OWNED),
458 CHANNELCLI_OWNED,
459 PathName_Last_N_Nodes((u8 *) file, 4), line);
460 writel(CHANNELCLI_OWNED, &pChan->CliStateOS);
461 MEMORYBARRIER;
462 }
463 if (readl(&pChan->CliStateOS) == CHANNELCLI_OWNED) {
464 if (readb(&pChan->CliErrorOS) != 0) {
465 /* we are in an error msg throttling state;
466 * come out of it */
467 UltraLogEvent(logCtx,
468 CHANNELSTATE_DIAG_EVENTID_TRANSITOK,
469 CHANNELSTATE_DIAG_SEVERITY,
470 CHANNELSTATE_DIAG_SUBSYS, func, line,
471 "%s Channel OS client acquire now successful @%s:%d\n",
472 chanId, PathName_Last_N_Nodes((u8 *) file,
473 4), line);
474 writeb(0, &pChan->CliErrorOS);
475 }
476 return 1;
477 }
478
479 /* We have to do it the "hard way". We transition to BUSY,
480 * and can use the channel iff our competitor has not also
481 * transitioned to BUSY. */
482 if (readl(&pChan->CliStateOS) != CHANNELCLI_ATTACHED) {
483 if ((readb(&pChan->CliErrorOS)
484 & ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED) == 0) {
485 /* we are NOT throttling this message */
486 writeb(readb(&pChan->CliErrorOS) |
487 ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED,
488 &pChan->CliErrorOS);
489 /* throttle until acquire successful */
490 UltraLogEvent(logCtx,
491 CHANNELSTATE_DIAG_EVENTID_TRANSITERR,
492 CHANNELSTATE_DIAG_SEVERITY,
493 CHANNELSTATE_DIAG_SUBSYS, func, line,
494 "%s Channel StateTransition INVALID! - acquire failed because OS client NOT ATTACHED (state=%s(%d)) @%s:%d\n",
495 chanId,
496 ULTRA_CHANNELCLI_STRING(
497 readl(&pChan->CliStateOS)),
498 readl(&pChan->CliStateOS),
499 PathName_Last_N_Nodes((u8 *) file, 4),
500 line);
501 }
502 return 0;
503 }
504 writel(CHANNELCLI_BUSY, &pChan->CliStateOS);
505 MEMORYBARRIER;
506 if (readl(&pChan->CliStateBoot) == CHANNELCLI_BUSY) {
507 if ((readb(&pChan->CliErrorOS)
508 & ULTRA_CLIERROROS_THROTTLEMSG_BUSY) == 0) {
509 /* we are NOT throttling this message */
510 writeb(readb(&pChan->CliErrorOS) |
511 ULTRA_CLIERROROS_THROTTLEMSG_BUSY,
512 &pChan->CliErrorOS);
513 /* throttle until acquire successful */
514 UltraLogEvent(logCtx,
515 CHANNELSTATE_DIAG_EVENTID_TRANSITBUSY,
516 CHANNELSTATE_DIAG_SEVERITY,
517 CHANNELSTATE_DIAG_SUBSYS, func, line,
518 "%s Channel StateTransition failed - host OS acquire failed because boot BUSY @%s:%d\n",
519 chanId, PathName_Last_N_Nodes((u8 *) file,
520 4), line);
521 }
522 /* reset busy */
523 writel(CHANNELCLI_ATTACHED, &pChan->CliStateOS);
524 MEMORYBARRIER;
525 return 0;
526 }
527 if (readb(&pChan->CliErrorOS) != 0) {
528 /* we are in an error msg throttling state; come out of it */
529 UltraLogEvent(logCtx, CHANNELSTATE_DIAG_EVENTID_TRANSITOK,
530 CHANNELSTATE_DIAG_SEVERITY,
531 CHANNELSTATE_DIAG_SUBSYS, func, line,
532 "%s Channel OS client acquire now successful @%s:%d\n",
533 chanId, PathName_Last_N_Nodes((u8 *) file, 4),
534 line);
535 writeb(0, &pChan->CliErrorOS);
536 }
537 return 1;
538 }
539
540 static inline void
541 ULTRA_channel_client_release_os(void __iomem *pChannel, u8 *chanId,
542 void *logCtx, char *file, int line, char *func)
543 {
544 CHANNEL_HEADER __iomem *pChan = pChannel;
545 if (readb(&pChan->CliErrorOS) != 0) {
546 /* we are in an error msg throttling state; come out of it */
547 UltraLogEvent(logCtx, CHANNELSTATE_DIAG_EVENTID_TRANSITOK,
548 CHANNELSTATE_DIAG_SEVERITY,
549 CHANNELSTATE_DIAG_SUBSYS, func, line,
550 "%s Channel OS client error state cleared @%s:%d\n",
551 chanId, PathName_Last_N_Nodes((u8 *) file, 4),
552 line);
553 writeb(0, &pChan->CliErrorOS);
554 }
555 if (readl(&pChan->CliStateOS) == CHANNELCLI_OWNED)
556 return;
557 if (readl(&pChan->CliStateOS) != CHANNELCLI_BUSY) {
558 UltraLogEvent(logCtx, CHANNELSTATE_DIAG_EVENTID_TRANSITERR,
559 CHANNELSTATE_DIAG_SEVERITY,
560 CHANNELSTATE_DIAG_SUBSYS, func, line,
561 "%s Channel StateTransition INVALID! - release failed because OS client NOT BUSY (state=%s(%d)) @%s:%d\n",
562 chanId,
563 ULTRA_CHANNELCLI_STRING(
564 readl(&pChan->CliStateOS)),
565 readl(&pChan->CliStateOS),
566 PathName_Last_N_Nodes((u8 *) file, 4), line);
567 /* return; */
568 }
569 writel(CHANNELCLI_ATTACHED, &pChan->CliStateOS); /* release busy */
570 }
571
572 /*
573 * Routine Description:
574 * Tries to insert the prebuilt signal pointed to by pSignal into the nth
575 * Queue of the Channel pointed to by pChannel
576 *
577 * Parameters:
578 * pChannel: (IN) points to the IO Channel
579 * Queue: (IN) nth Queue of the IO Channel
580 * pSignal: (IN) pointer to the signal
581 *
582 * Assumptions:
583 * - pChannel, Queue and pSignal are valid.
584 * - If insertion fails due to a full queue, the caller will determine the
585 * retry policy (e.g. wait & try again, report an error, etc.).
586 *
587 * Return value: 1 if the insertion succeeds, 0 if the queue was
588 * full.
589 */
590
591 unsigned char visor_signal_insert(CHANNEL_HEADER __iomem *pChannel, u32 Queue,
592 void *pSignal);
593
594 /*
595 * Routine Description:
596 * Removes one signal from Channel pChannel's nth Queue at the
597 * time of the call and copies it into the memory pointed to by
598 * pSignal.
599 *
600 * Parameters:
601 * pChannel: (IN) points to the IO Channel
602 * Queue: (IN) nth Queue of the IO Channel
603 * pSignal: (IN) pointer to where the signals are to be copied
604 *
605 * Assumptions:
606 * - pChannel and Queue are valid.
607 * - pSignal points to a memory area large enough to hold queue's SignalSize
608 *
609 * Return value: 1 if the removal succeeds, 0 if the queue was
610 * empty.
611 */
612
613 unsigned char visor_signal_remove(CHANNEL_HEADER __iomem *pChannel, u32 Queue,
614 void *pSignal);
615
616 /*
617 * Routine Description:
618 * Removes all signals present in Channel pChannel's nth Queue at the
619 * time of the call and copies them into the memory pointed to by
620 * pSignal. Returns the # of signals copied as the value of the routine.
621 *
622 * Parameters:
623 * pChannel: (IN) points to the IO Channel
624 * Queue: (IN) nth Queue of the IO Channel
625 * pSignal: (IN) pointer to where the signals are to be copied
626 *
627 * Assumptions:
628 * - pChannel and Queue are valid.
629 * - pSignal points to a memory area large enough to hold Queue's MaxSignals
630 * # of signals, each of which is Queue's SignalSize.
631 *
632 * Return value:
633 * # of signals copied.
634 */
635 unsigned int SignalRemoveAll(pCHANNEL_HEADER pChannel, u32 Queue,
636 void *pSignal);
637
638 /*
639 * Routine Description:
640 * Determine whether a signal queue is empty.
641 *
642 * Parameters:
643 * pChannel: (IN) points to the IO Channel
644 * Queue: (IN) nth Queue of the IO Channel
645 *
646 * Return value:
647 * 1 if the signal queue is empty, 0 otherwise.
648 */
649 unsigned char visor_signalqueue_empty(CHANNEL_HEADER __iomem *pChannel,
650 u32 Queue);
651
652 #endif
This page took 0.058029 seconds and 5 git commands to generate.