Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / 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/types.h>
20 #include <linux/io.h>
21 #include <linux/uuid.h>
22
23 /*
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.
28 */
29
30 /* define the following to prevent include nesting in kernel header
31  * files of similar abbreviated content
32  */
33 #define __SUPERVISOR_CHANNEL_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 enum channel_serverstate {
54         CHANNELSRV_UNINITIALIZED = 0,   /* channel is in an undefined state */
55         CHANNELSRV_READY = 1    /* channel has been initialized by server */
56 };
57
58 enum channel_clientstate {
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 };
73
74 static inline const u8 *
75 ULTRA_CHANNELCLI_STRING(u32 v)
76 {
77         switch (v) {
78         case CHANNELCLI_DETACHED:
79                 return (const u8 *)("DETACHED");
80         case CHANNELCLI_DISABLED:
81                 return (const u8 *)("DISABLED");
82         case CHANNELCLI_ATTACHING:
83                 return (const u8 *)("ATTACHING");
84         case CHANNELCLI_ATTACHED:
85                 return (const u8 *)("ATTACHED");
86         case CHANNELCLI_BUSY:
87                 return (const u8 *)("BUSY");
88         case CHANNELCLI_OWNED:
89                 return (const u8 *)("OWNED");
90         default:
91                 break;
92         }
93         return (const u8 *)("?");
94 }
95
96 #define SPAR_CHANNEL_SERVER_READY(ch) \
97         (readl(&(ch)->srv_state) == CHANNELSRV_READY)
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 SPAR_CHANNEL_CLIENT_CHK_TRANSITION(old, new, id, log,   \
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                                 id, "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)
130
131 #define SPAR_CHANNEL_CLIENT_TRANSITION(ch, id, newstate, log)           \
132         do {                                                            \
133                 SPAR_CHANNEL_CLIENT_CHK_TRANSITION(                     \
134                         readl(&(((struct channel_header __iomem *)\
135                                  (ch))->cli_state_os)),         \
136                         newstate, id, log, __FILE__, __LINE__);         \
137                         pr_info("%s Channel StateTransition (%s) %s(%d)-->%s(%d) @%s:%d\n", \
138                                 id, "CliStateOS",                       \
139                                 ULTRA_CHANNELCLI_STRING( \
140                                       readl(&((struct channel_header __iomem *)\
141                                               (ch))->cli_state_os)),    \
142                                 readl(&((struct channel_header __iomem *)\
143                                       (ch))->cli_state_os),             \
144                                 ULTRA_CHANNELCLI_STRING(newstate),      \
145                                 newstate,                               \
146                                 pathname_last_n_nodes(__FILE__, 4), __LINE__); \
147                 writel(newstate, &((struct channel_header __iomem *)\
148                                    (ch))->cli_state_os);                \
149                 mb(); /* required for channel synch */                  \
150         } while (0)
151
152 /* Values for ULTRA_CHANNEL_PROTOCOL.CliErrorBoot: */
153 /* throttling invalid boot channel statetransition error due to client
154  * disabled */
155 #define ULTRA_CLIERRORBOOT_THROTTLEMSG_DISABLED    0x01
156
157 /* throttling invalid boot channel statetransition error due to client
158  * not attached */
159 #define ULTRA_CLIERRORBOOT_THROTTLEMSG_NOTATTACHED 0x02
160
161 /* throttling invalid boot channel statetransition error due to busy channel */
162 #define ULTRA_CLIERRORBOOT_THROTTLEMSG_BUSY        0x04
163
164 /* Values for ULTRA_CHANNEL_PROTOCOL.CliErrorOS: */
165 /* throttling invalid guest OS channel statetransition error due to
166  * client disabled */
167 #define ULTRA_CLIERROROS_THROTTLEMSG_DISABLED      0x01
168
169 /* throttling invalid guest OS channel statetransition error due to
170  * client not attached */
171 #define ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED   0x02
172
173 /* throttling invalid guest OS channel statetransition error due to
174  * busy channel */
175 #define ULTRA_CLIERROROS_THROTTLEMSG_BUSY          0x04
176
177 /* Values for ULTRA_CHANNEL_PROTOCOL.Features: This define exists so
178 * that windows guest can look at the FeatureFlags in the io channel,
179 * and configure the windows driver to use interrupts or not based on
180 * this setting.  This flag is set in uislib after the
181 * ULTRA_VHBA_init_channel is called.  All feature bits for all
182 * channels should be defined here.  The io channel feature bits are
183 * defined right here */
184 #define ULTRA_IO_DRIVER_ENABLES_INTS (0x1ULL << 1)
185 #define ULTRA_IO_CHANNEL_IS_POLLING (0x1ULL << 3)
186 #define ULTRA_IO_IOVM_IS_OK_WITH_DRIVER_DISABLING_INTS (0x1ULL << 4)
187 #define ULTRA_IO_DRIVER_DISABLES_INTS (0x1ULL << 5)
188 #define ULTRA_IO_DRIVER_SUPPORTS_ENHANCED_RCVBUF_CHECKING (0x1ULL << 6)
189
190 #pragma pack(push, 1)           /* both GCC and VC now allow this pragma */
191 /* Common Channel Header */
192 struct channel_header {
193         u64 signature;          /* Signature */
194         u32 legacy_state;       /* DEPRECATED - being replaced by */
195         /* /              SrvState, CliStateBoot, and CliStateOS below */
196         u32 header_size;        /* sizeof(struct channel_header) */
197         u64 size;               /* Total size of this channel in bytes */
198         u64 features;           /* Flags to modify behavior */
199         uuid_le chtype;         /* Channel type: data, bus, control, etc. */
200         u64 partition_handle;   /* ID of guest partition */
201         u64 handle;             /* Device number of this channel in client */
202         u64 ch_space_offset;    /* Offset in bytes to channel specific area */
203         u32 version_id;         /* struct channel_header Version ID */
204         u32 partition_index;    /* Index of guest partition */
205         uuid_le zone_uuid;      /* Guid of Channel's zone */
206         u32 cli_str_offset;     /* offset from channel header to
207                                  * nul-terminated ClientString (0 if
208                                  * ClientString not present) */
209         u32 cli_state_boot;     /* CHANNEL_CLIENTSTATE of pre-boot
210                                  * EFI client of this channel */
211         u32 cmd_state_cli;      /* CHANNEL_COMMANDSTATE (overloaded in
212                                  * Windows drivers, see ServerStateUp,
213                                  * ServerStateDown, etc) */
214         u32 cli_state_os;       /* CHANNEL_CLIENTSTATE of Guest OS
215                                  * client of this channel */
216         u32 ch_characteristic;  /* CHANNEL_CHARACTERISTIC_<xxx> */
217         u32 cmd_state_srv;      /* CHANNEL_COMMANDSTATE (overloaded in
218                                  * Windows drivers, see ServerStateUp,
219                                  * ServerStateDown, etc) */
220         u32 srv_state;          /* CHANNEL_SERVERSTATE */
221         u8 cli_error_boot;      /* bits to indicate err states for
222                                  * boot clients, so err messages can
223                                  * be throttled */
224         u8 cli_error_os;        /* bits to indicate err states for OS
225                                  * clients, so err messages can be
226                                  * throttled */
227         u8 filler[1];           /* Pad out to 128 byte cacheline */
228         /* Please add all new single-byte values below here */
229         u8 recover_channel;
230 };
231
232 #define ULTRA_CHANNEL_ENABLE_INTS (0x1ULL << 0)
233
234 /* Subheader for the Signal Type variation of the Common Channel */
235 struct signal_queue_header {
236         /* 1st cache line */
237         u32 version;            /* SIGNAL_QUEUE_HEADER Version ID */
238         u32 chtype;             /* Queue type: storage, network */
239         u64 size;               /* Total size of this queue in bytes */
240         u64 sig_base_offset;    /* Offset to signal queue area */
241         u64 features;           /* Flags to modify behavior */
242         u64 num_sent;           /* Total # of signals placed in this queue */
243         u64 num_overflows;      /* Total # of inserts failed due to
244                                  * full queue */
245         u32 signal_size;        /* Total size of a signal for this queue */
246         u32 max_slots;          /* Max # of slots in queue, 1 slot is
247                                  * always empty */
248         u32 max_signals;        /* Max # of signals in queue
249                                  * (MaxSignalSlots-1) */
250         u32 head;               /* Queue head signal # */
251         /* 2nd cache line */
252         u64 num_received;       /* Total # of signals removed from this queue */
253         u32 tail;               /* Queue tail signal # (on separate
254                                  * cache line) */
255         u32 reserved1;          /* Reserved field */
256         u64 reserved2;          /* Reserved field */
257         u64 client_queue;
258         u64 num_irq_received;   /* Total # of Interrupts received.  This
259                                          * is incremented by the ISR in the
260                                          * guest windows driver */
261         u64 num_empty;          /* Number of times that visor_signal_remove
262                                  * is called and returned Empty
263                                  * Status. */
264         u32 errorflags;         /* Error bits set during SignalReinit
265                                  * to denote trouble with client's
266                                  * fields */
267         u8 filler[12];          /* Pad out to 64 byte cacheline */
268 };
269
270 #pragma pack(pop)
271
272 #define spar_signal_init(chan, QHDRFLD, QDATAFLD, QDATATYPE, ver, typ)  \
273         do {                                                            \
274                 memset(&chan->QHDRFLD, 0, sizeof(chan->QHDRFLD));       \
275                 chan->QHDRFLD.version = ver;                            \
276                 chan->QHDRFLD.chtype = typ;                             \
277                 chan->QHDRFLD.size = sizeof(chan->QDATAFLD);            \
278                 chan->QHDRFLD.signal_size = sizeof(QDATATYPE);          \
279                 chan->QHDRFLD.sig_base_offset = (u64)(chan->QDATAFLD)-  \
280                         (u64)(&chan->QHDRFLD);                          \
281                 chan->QHDRFLD.max_slots =                               \
282                         sizeof(chan->QDATAFLD)/sizeof(QDATATYPE);       \
283                 chan->QHDRFLD.max_signals = chan->QHDRFLD.max_slots-1;  \
284         } while (0)
285
286 /* Generic function useful for validating any type of channel when it is
287  * received by the client that will be accessing the channel.
288  * Note that <logCtx> is only needed for callers in the EFI environment, and
289  * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages.
290  */
291 static inline int
292 spar_check_channel_client(void __iomem *ch,
293                           uuid_le expected_uuid,
294                           char *chname,
295                           u64 expected_min_bytes,
296                           u32 expected_version,
297                           u64 expected_signature)
298 {
299         if (uuid_le_cmp(expected_uuid, NULL_UUID_LE) != 0) {
300                 uuid_le guid;
301
302                 memcpy_fromio(&guid,
303                               &((struct channel_header __iomem *)(ch))->chtype,
304                               sizeof(guid));
305                 /* caller wants us to verify type GUID */
306                 if (uuid_le_cmp(guid, expected_uuid) != 0) {
307                         pr_err("Channel mismatch on channel=%s(%pUL) field=type expected=%pUL actual=%pUL\n",
308                                chname, &expected_uuid,
309                                &expected_uuid, &guid);
310                         return 0;
311                 }
312         }
313         if (expected_min_bytes > 0) {   /* caller wants us to verify
314                                          * channel size */
315                 unsigned long long bytes =
316                                 readq(&((struct channel_header __iomem *)
317                                         (ch))->size);
318                 if (bytes < expected_min_bytes) {
319                         pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8Lx actual=0x%-8.8Lx\n",
320                                chname, &expected_uuid,
321                                (unsigned long long)expected_min_bytes, bytes);
322                         return 0;
323                 }
324         }
325         if (expected_version > 0) {     /* caller wants us to verify
326                                          * channel version */
327                 unsigned long ver = readl(&((struct channel_header __iomem *)
328                                     (ch))->version_id);
329                 if (ver != expected_version) {
330                         pr_err("Channel mismatch on channel=%s(%pUL) field=version expected=0x%-8.8lx actual=0x%-8.8lx\n",
331                                chname, &expected_uuid,
332                                (unsigned long)expected_version, ver);
333                         return 0;
334                 }
335         }
336         if (expected_signature > 0) {   /* caller wants us to verify
337                                          * channel signature */
338                 unsigned long long sig =
339                                 readq(&((struct channel_header __iomem *)
340                                         (ch))->signature);
341                 if (sig != expected_signature) {
342                         pr_err("Channel mismatch on channel=%s(%pUL) field=signature expected=0x%-8.8llx actual=0x%-8.8llx\n",
343                                chname, &expected_uuid,
344                                expected_signature, sig);
345                         return 0;
346                 }
347         }
348         return 1;
349 }
350
351 /* Generic function useful for validating any type of channel when it is about
352  * to be initialized by the server of the channel.
353  * Note that <logCtx> is only needed for callers in the EFI environment, and
354  * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages.
355  */
356 static inline int spar_check_channel_server(uuid_le typeuuid, char *name,
357                                             u64 expected_min_bytes,
358                                             u64 actual_bytes)
359 {
360         if (expected_min_bytes > 0)     /* caller wants us to verify
361                                          * channel size */
362                 if (actual_bytes < expected_min_bytes) {
363                         pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8llx actual=0x%-8.8llx\n",
364                                name, &typeuuid, expected_min_bytes,
365                                actual_bytes);
366                         return 0;
367                 }
368         return 1;
369 }
370
371 /* Given a file pathname <s> (with '/' or '\' separating directory nodes),
372  * returns a pointer to the beginning of a node within that pathname such
373  * that the number of nodes from that pointer to the end of the string is
374  * NOT more than <n>.  Note that if the pathname has less than <n> nodes
375  * in it, the return pointer will be to the beginning of the string.
376  */
377 static inline u8 *
378 pathname_last_n_nodes(u8 *s, unsigned int n)
379 {
380         u8 *p = s;
381         unsigned int node_count = 0;
382
383         while (*p != '\0') {
384                 if ((*p == '/') || (*p == '\\'))
385                         node_count++;
386                 p++;
387         }
388         if (node_count <= n)
389                 return s;
390         while (n > 0) {
391                 p--;
392                 if (p == s)
393                         break;  /* should never happen, unless someone
394                                  * is changing the string while we are
395                                  * looking at it!! */
396                 if ((*p == '/') || (*p == '\\'))
397                         n--;
398         }
399         return p + 1;
400 }
401
402 static inline int
403 spar_channel_client_acquire_os(void __iomem *ch, u8 *id)
404 {
405         struct channel_header __iomem *hdr = ch;
406
407         if (readl(&hdr->cli_state_os) == CHANNELCLI_DISABLED) {
408                 if ((readb(&hdr->cli_error_os)
409                      & ULTRA_CLIERROROS_THROTTLEMSG_DISABLED) == 0) {
410                         /* we are NOT throttling this message */
411                         writeb(readb(&hdr->cli_error_os) |
412                                ULTRA_CLIERROROS_THROTTLEMSG_DISABLED,
413                                &hdr->cli_error_os);
414                         /* throttle until acquire successful */
415
416                         pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client DISABLED\n",
417                                 id);
418                 }
419                 return 0;
420         }
421         if ((readl(&hdr->cli_state_os) != CHANNELCLI_OWNED) &&
422             (readl(&hdr->cli_state_boot) == CHANNELCLI_DISABLED)) {
423                 /* Our competitor is DISABLED, so we can transition to OWNED */
424                 pr_info("%s Channel StateTransition (%s) %s(%d)-->%s(%d)\n",
425                         id, "cli_state_os",
426                         ULTRA_CHANNELCLI_STRING(readl(&hdr->cli_state_os)),
427                         readl(&hdr->cli_state_os),
428                         ULTRA_CHANNELCLI_STRING(CHANNELCLI_OWNED),
429                         CHANNELCLI_OWNED);
430                 writel(CHANNELCLI_OWNED, &hdr->cli_state_os);
431                 mb(); /* required for channel synch */
432         }
433         if (readl(&hdr->cli_state_os) == CHANNELCLI_OWNED) {
434                 if (readb(&hdr->cli_error_os) != 0) {
435                         /* we are in an error msg throttling state;
436                          * come out of it */
437                         pr_info("%s Channel OS client acquire now successful\n",
438                                 id);
439                         writeb(0, &hdr->cli_error_os);
440                 }
441                 return 1;
442         }
443
444         /* We have to do it the "hard way".  We transition to BUSY,
445         * and can use the channel iff our competitor has not also
446         * transitioned to BUSY. */
447         if (readl(&hdr->cli_state_os) != CHANNELCLI_ATTACHED) {
448                 if ((readb(&hdr->cli_error_os)
449                      & ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED) == 0) {
450                         /* we are NOT throttling this message */
451                         writeb(readb(&hdr->cli_error_os) |
452                                ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED,
453                                &hdr->cli_error_os);
454                         /* throttle until acquire successful */
455                         pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client NOT ATTACHED (state=%s(%d))\n",
456                                 id, ULTRA_CHANNELCLI_STRING(
457                                                 readl(&hdr->cli_state_os)),
458                                 readl(&hdr->cli_state_os));
459                 }
460                 return 0;
461         }
462         writel(CHANNELCLI_BUSY, &hdr->cli_state_os);
463         mb(); /* required for channel synch */
464         if (readl(&hdr->cli_state_boot) == CHANNELCLI_BUSY) {
465                 if ((readb(&hdr->cli_error_os)
466                      & ULTRA_CLIERROROS_THROTTLEMSG_BUSY) == 0) {
467                         /* we are NOT throttling this message */
468                         writeb(readb(&hdr->cli_error_os) |
469                                ULTRA_CLIERROROS_THROTTLEMSG_BUSY,
470                                &hdr->cli_error_os);
471                         /* throttle until acquire successful */
472                         pr_info("%s Channel StateTransition failed - host OS acquire failed because boot BUSY\n",
473                                 id);
474                 }
475                 /* reset busy */
476                 writel(CHANNELCLI_ATTACHED, &hdr->cli_state_os);
477                 mb(); /* required for channel synch */
478                 return 0;
479         }
480         if (readb(&hdr->cli_error_os) != 0) {
481                 /* we are in an error msg throttling state; come out of it */
482                 pr_info("%s Channel OS client acquire now successful\n", id);
483                 writeb(0, &hdr->cli_error_os);
484         }
485         return 1;
486 }
487
488 static inline void
489 spar_channel_client_release_os(void __iomem *ch, u8 *id)
490 {
491         struct channel_header __iomem *hdr = ch;
492
493         if (readb(&hdr->cli_error_os) != 0) {
494                 /* we are in an error msg throttling state; come out of it */
495                 pr_info("%s Channel OS client error state cleared\n", id);
496                 writeb(0, &hdr->cli_error_os);
497         }
498         if (readl(&hdr->cli_state_os) == CHANNELCLI_OWNED)
499                 return;
500         if (readl(&hdr->cli_state_os) != CHANNELCLI_BUSY) {
501                 pr_info("%s Channel StateTransition INVALID! - release failed because OS client NOT BUSY (state=%s(%d))\n",
502                         id, ULTRA_CHANNELCLI_STRING(
503                                         readl(&hdr->cli_state_os)),
504                         readl(&hdr->cli_state_os));
505                 /* return; */
506         }
507         writel(CHANNELCLI_ATTACHED, &hdr->cli_state_os); /* release busy */
508 }
509
510 /*
511 * Routine Description:
512 * Tries to insert the prebuilt signal pointed to by pSignal into the nth
513 * Queue of the Channel pointed to by pChannel
514 *
515 * Parameters:
516 * pChannel: (IN) points to the IO Channel
517 * Queue: (IN) nth Queue of the IO Channel
518 * pSignal: (IN) pointer to the signal
519 *
520 * Assumptions:
521 * - pChannel, Queue and pSignal are valid.
522 * - If insertion fails due to a full queue, the caller will determine the
523 * retry policy (e.g. wait & try again, report an error, etc.).
524 *
525 * Return value: 1 if the insertion succeeds, 0 if the queue was
526 * full.
527 */
528
529 unsigned char spar_signal_insert(struct channel_header __iomem *ch, u32 queue,
530                                  void *sig);
531
532 /*
533 * Routine Description:
534 * Removes one signal from Channel pChannel's nth Queue at the
535 * time of the call and copies it into the memory pointed to by
536 * pSignal.
537 *
538 * Parameters:
539 * pChannel: (IN) points to the IO Channel
540 * Queue: (IN) nth Queue of the IO Channel
541 * pSignal: (IN) pointer to where the signals are to be copied
542 *
543 * Assumptions:
544 * - pChannel and Queue are valid.
545 * - pSignal points to a memory area large enough to hold queue's SignalSize
546 *
547 * Return value: 1 if the removal succeeds, 0 if the queue was
548 * empty.
549 */
550
551 unsigned char spar_signal_remove(struct channel_header __iomem *ch, u32 queue,
552                                  void *sig);
553
554 /*
555 * Routine Description:
556 * Removes all signals present in Channel pChannel's nth Queue at the
557 * time of the call and copies them into the memory pointed to by
558 * pSignal.  Returns the # of signals copied as the value of the routine.
559 *
560 * Parameters:
561 * pChannel: (IN) points to the IO Channel
562 * Queue: (IN) nth Queue of the IO Channel
563 * pSignal: (IN) pointer to where the signals are to be copied
564 *
565 * Assumptions:
566 * - pChannel and Queue are valid.
567 * - pSignal points to a memory area large enough to hold Queue's MaxSignals
568 * # of signals, each of which is Queue's SignalSize.
569 *
570 * Return value:
571 * # of signals copied.
572 */
573 unsigned int spar_signal_remove_all(struct channel_header *ch, u32 queue,
574                                     void *sig);
575
576 /*
577 * Routine Description:
578 * Determine whether a signal queue is empty.
579 *
580 * Parameters:
581 * pChannel: (IN) points to the IO Channel
582 * Queue: (IN) nth Queue of the IO Channel
583 *
584 * Return value:
585 * 1 if the signal queue is empty, 0 otherwise.
586 */
587 unsigned char spar_signalqueue_empty(struct channel_header __iomem *ch,
588                                      u32 queue);
589
590 #endif