1 /* Copyright (C) 2010 - 2013 UNISYS CORPORATION
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
19 #include <linux/types.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
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))
42 #define lengthof(TYPE, MEMBER) (sizeof(((TYPE *)0)->MEMBER))
45 #define COVERQ(v, d) (((v) + (d) - 1) / (d))
48 #define COVER(v, d) ((d) * COVERQ(v, d))
51 #define ULTRA_CHANNEL_PROTOCOL_SIGNATURE SIGNATURE_32('E', 'C', 'N', 'L')
53 enum channel_serverstate {
54 CHANNELSRV_UNINITIALIZED = 0, /* channel is in an undefined state */
55 CHANNELSRV_READY = 1 /* channel has been initialized by server */
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
65 CHANNELCLI_ATTACHING = 2, /* legacy EFI client request
66 * for EFI server to attach
68 CHANNELCLI_ATTACHED = 3, /* idle, but client may want
69 * to use channel any time
71 CHANNELCLI_BUSY = 4, /* client either wants to use or is
74 CHANNELCLI_OWNED = 5 /* "no worries" state - client can */
75 /* access channel anytime */
78 static inline const u8 *
79 ULTRA_CHANNELCLI_STRING(u32 state)
82 case CHANNELCLI_DETACHED:
83 return (const u8 *)("DETACHED");
84 case CHANNELCLI_DISABLED:
85 return (const u8 *)("DISABLED");
86 case CHANNELCLI_ATTACHING:
87 return (const u8 *)("ATTACHING");
88 case CHANNELCLI_ATTACHED:
89 return (const u8 *)("ATTACHED");
91 return (const u8 *)("BUSY");
92 case CHANNELCLI_OWNED:
93 return (const u8 *)("OWNED");
97 return (const u8 *)("?");
100 #define SPAR_CHANNEL_SERVER_READY(ch) \
101 (readl(&(ch)->srv_state) == CHANNELSRV_READY)
103 #define ULTRA_VALID_CHANNELCLI_TRANSITION(o, n) \
104 (((((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_DISABLED)) || \
105 (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_DISABLED)) || \
106 (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_DISABLED)) || \
107 (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_DETACHED)) || \
108 (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_DETACHED)) || \
109 (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_ATTACHING)) || \
110 (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_ATTACHED)) || \
111 (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_ATTACHED)) || \
112 (((o) == CHANNELCLI_BUSY) && ((n) == CHANNELCLI_ATTACHED)) || \
113 (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_BUSY)) || \
114 (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_OWNED)) || \
115 (((o) == CHANNELCLI_DISABLED) && ((n) == CHANNELCLI_OWNED)) || \
116 (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_OWNED)) || \
117 (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_OWNED)) || \
118 (((o) == CHANNELCLI_BUSY) && ((n) == CHANNELCLI_OWNED)) || (0)) \
121 /* Values for ULTRA_CHANNEL_PROTOCOL.CliErrorBoot: */
122 /* throttling invalid boot channel statetransition error due to client
125 #define ULTRA_CLIERRORBOOT_THROTTLEMSG_DISABLED 0x01
127 /* throttling invalid boot channel statetransition error due to client
130 #define ULTRA_CLIERRORBOOT_THROTTLEMSG_NOTATTACHED 0x02
132 /* throttling invalid boot channel statetransition error due to busy channel */
133 #define ULTRA_CLIERRORBOOT_THROTTLEMSG_BUSY 0x04
135 /* Values for ULTRA_CHANNEL_PROTOCOL.CliErrorOS: */
136 /* throttling invalid guest OS channel statetransition error due to
139 #define ULTRA_CLIERROROS_THROTTLEMSG_DISABLED 0x01
141 /* throttling invalid guest OS channel statetransition error due to
142 * client not attached
144 #define ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED 0x02
146 /* throttling invalid guest OS channel statetransition error due to
149 #define ULTRA_CLIERROROS_THROTTLEMSG_BUSY 0x04
151 /* Values for ULTRA_CHANNEL_PROTOCOL.Features: This define exists so
152 * that windows guest can look at the FeatureFlags in the io channel,
153 * and configure the windows driver to use interrupts or not based on
154 * this setting. This flag is set in uislib after the
155 * ULTRA_VHBA_init_channel is called. All feature bits for all
156 * channels should be defined here. The io channel feature bits are
159 #define ULTRA_IO_DRIVER_ENABLES_INTS (0x1ULL << 1)
160 #define ULTRA_IO_CHANNEL_IS_POLLING (0x1ULL << 3)
161 #define ULTRA_IO_IOVM_IS_OK_WITH_DRIVER_DISABLING_INTS (0x1ULL << 4)
162 #define ULTRA_IO_DRIVER_DISABLES_INTS (0x1ULL << 5)
163 #define ULTRA_IO_DRIVER_SUPPORTS_ENHANCED_RCVBUF_CHECKING (0x1ULL << 6)
165 /* Common Channel Header */
166 struct channel_header {
167 u64 signature; /* Signature */
168 u32 legacy_state; /* DEPRECATED - being replaced by */
169 /* SrvState, CliStateBoot, and CliStateOS below */
170 u32 header_size; /* sizeof(struct channel_header) */
171 u64 size; /* Total size of this channel in bytes */
172 u64 features; /* Flags to modify behavior */
173 uuid_le chtype; /* Channel type: data, bus, control, etc. */
174 u64 partition_handle; /* ID of guest partition */
175 u64 handle; /* Device number of this channel in client */
176 u64 ch_space_offset; /* Offset in bytes to channel specific area */
177 u32 version_id; /* struct channel_header Version ID */
178 u32 partition_index; /* Index of guest partition */
179 uuid_le zone_uuid; /* Guid of Channel's zone */
180 u32 cli_str_offset; /* offset from channel header to
181 * nul-terminated ClientString (0 if
182 * ClientString not present)
184 u32 cli_state_boot; /* CHANNEL_CLIENTSTATE of pre-boot
185 * EFI client of this channel
187 u32 cmd_state_cli; /* CHANNEL_COMMANDSTATE (overloaded in
188 * Windows drivers, see ServerStateUp,
189 * ServerStateDown, etc)
191 u32 cli_state_os; /* CHANNEL_CLIENTSTATE of Guest OS
192 * client of this channel
194 u32 ch_characteristic; /* CHANNEL_CHARACTERISTIC_<xxx> */
195 u32 cmd_state_srv; /* CHANNEL_COMMANDSTATE (overloaded in
196 * Windows drivers, see ServerStateUp,
197 * ServerStateDown, etc)
199 u32 srv_state; /* CHANNEL_SERVERSTATE */
200 u8 cli_error_boot; /* bits to indicate err states for
201 * boot clients, so err messages can
204 u8 cli_error_os; /* bits to indicate err states for OS
205 * clients, so err messages can be
208 u8 filler[1]; /* Pad out to 128 byte cacheline */
209 /* Please add all new single-byte values below here */
213 #define ULTRA_CHANNEL_ENABLE_INTS (0x1ULL << 0)
215 /* Subheader for the Signal Type variation of the Common Channel */
216 struct signal_queue_header {
218 u32 version; /* SIGNAL_QUEUE_HEADER Version ID */
219 u32 chtype; /* Queue type: storage, network */
220 u64 size; /* Total size of this queue in bytes */
221 u64 sig_base_offset; /* Offset to signal queue area */
222 u64 features; /* Flags to modify behavior */
223 u64 num_sent; /* Total # of signals placed in this queue */
224 u64 num_overflows; /* Total # of inserts failed due to
227 u32 signal_size; /* Total size of a signal for this queue */
228 u32 max_slots; /* Max # of slots in queue, 1 slot is
231 u32 max_signals; /* Max # of signals in queue
234 u32 head; /* Queue head signal # */
236 u64 num_received; /* Total # of signals removed from this queue */
237 u32 tail; /* Queue tail signal */
238 u32 reserved1; /* Reserved field */
239 u64 reserved2; /* Reserved field */
241 u64 num_irq_received; /* Total # of Interrupts received. This
242 * is incremented by the ISR in the
243 * guest windows driver
245 u64 num_empty; /* Number of times that visor_signal_remove
246 * is called and returned Empty Status.
248 u32 errorflags; /* Error bits set during SignalReinit
249 * to denote trouble with client's
252 u8 filler[12]; /* Pad out to 64 byte cacheline */
255 #define spar_signal_init(chan, QHDRFLD, QDATAFLD, QDATATYPE, ver, typ) \
257 memset(&chan->QHDRFLD, 0, sizeof(chan->QHDRFLD)); \
258 chan->QHDRFLD.version = ver; \
259 chan->QHDRFLD.chtype = typ; \
260 chan->QHDRFLD.size = sizeof(chan->QDATAFLD); \
261 chan->QHDRFLD.signal_size = sizeof(QDATATYPE); \
262 chan->QHDRFLD.sig_base_offset = (u64)(chan->QDATAFLD) - \
263 (u64)(&chan->QHDRFLD); \
264 chan->QHDRFLD.max_slots = \
265 sizeof(chan->QDATAFLD) / sizeof(QDATATYPE); \
266 chan->QHDRFLD.max_signals = chan->QHDRFLD.max_slots - 1;\
269 /* Generic function useful for validating any type of channel when it is
270 * received by the client that will be accessing the channel.
271 * Note that <logCtx> is only needed for callers in the EFI environment, and
272 * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages.
275 spar_check_channel_client(void __iomem *ch,
276 uuid_le expected_uuid,
278 u64 expected_min_bytes,
279 u32 expected_version,
280 u64 expected_signature)
282 if (uuid_le_cmp(expected_uuid, NULL_UUID_LE) != 0) {
286 &((struct channel_header __iomem *)(ch))->chtype,
288 /* caller wants us to verify type GUID */
289 if (uuid_le_cmp(guid, expected_uuid) != 0) {
290 pr_err("Channel mismatch on channel=%s(%pUL) field=type expected=%pUL actual=%pUL\n",
291 chname, &expected_uuid,
292 &expected_uuid, &guid);
296 if (expected_min_bytes > 0) { /* verify channel size */
297 unsigned long long bytes =
298 readq(&((struct channel_header __iomem *)
300 if (bytes < expected_min_bytes) {
301 pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8Lx actual=0x%-8.8Lx\n",
302 chname, &expected_uuid,
303 (unsigned long long)expected_min_bytes, bytes);
307 if (expected_version > 0) { /* verify channel version */
308 unsigned long ver = readl(&((struct channel_header __iomem *)
310 if (ver != expected_version) {
311 pr_err("Channel mismatch on channel=%s(%pUL) field=version expected=0x%-8.8lx actual=0x%-8.8lx\n",
312 chname, &expected_uuid,
313 (unsigned long)expected_version, ver);
317 if (expected_signature > 0) { /* verify channel signature */
318 unsigned long long sig =
319 readq(&((struct channel_header __iomem *)
321 if (sig != expected_signature) {
322 pr_err("Channel mismatch on channel=%s(%pUL) field=signature expected=0x%-8.8llx actual=0x%-8.8llx\n",
323 chname, &expected_uuid,
324 expected_signature, sig);
331 /* Generic function useful for validating any type of channel when it is about
332 * to be initialized by the server of the channel.
333 * Note that <logCtx> is only needed for callers in the EFI environment, and
334 * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages.
336 static inline int spar_check_channel_server(uuid_le typeuuid, char *name,
337 u64 expected_min_bytes,
340 if (expected_min_bytes > 0) /* verify channel size */
341 if (actual_bytes < expected_min_bytes) {
342 pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8llx actual=0x%-8.8llx\n",
343 name, &typeuuid, expected_min_bytes,
350 /* Given a file pathname <s> (with '/' or '\' separating directory nodes),
351 * returns a pointer to the beginning of a node within that pathname such
352 * that the number of nodes from that pointer to the end of the string is
353 * NOT more than <n>. Note that if the pathname has less than <n> nodes
354 * in it, the return pointer will be to the beginning of the string.
357 pathname_last_n_nodes(u8 *s, unsigned int n)
360 unsigned int node_count = 0;
363 if ((*p == '/') || (*p == '\\'))
372 break; /* should never happen, unless someone
373 * is changing the string while we are
376 if ((*p == '/') || (*p == '\\'))
383 spar_channel_client_acquire_os(void __iomem *ch, u8 *id)
385 struct channel_header __iomem *hdr = ch;
387 if (readl(&hdr->cli_state_os) == CHANNELCLI_DISABLED) {
388 if ((readb(&hdr->cli_error_os)
389 & ULTRA_CLIERROROS_THROTTLEMSG_DISABLED) == 0) {
390 /* we are NOT throttling this message */
391 writeb(readb(&hdr->cli_error_os) |
392 ULTRA_CLIERROROS_THROTTLEMSG_DISABLED,
394 /* throttle until acquire successful */
396 pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client DISABLED\n",
401 if ((readl(&hdr->cli_state_os) != CHANNELCLI_OWNED) &&
402 (readl(&hdr->cli_state_boot) == CHANNELCLI_DISABLED)) {
403 /* Our competitor is DISABLED, so we can transition to OWNED */
404 pr_info("%s Channel StateTransition (%s) %s(%d)-->%s(%d)\n",
406 ULTRA_CHANNELCLI_STRING(readl(&hdr->cli_state_os)),
407 readl(&hdr->cli_state_os),
408 ULTRA_CHANNELCLI_STRING(CHANNELCLI_OWNED),
410 writel(CHANNELCLI_OWNED, &hdr->cli_state_os);
411 mb(); /* required for channel synch */
413 if (readl(&hdr->cli_state_os) == CHANNELCLI_OWNED) {
414 if (readb(&hdr->cli_error_os)) {
415 /* we are in an error msg throttling state;
418 pr_info("%s Channel OS client acquire now successful\n",
420 writeb(0, &hdr->cli_error_os);
425 /* We have to do it the "hard way". We transition to BUSY,
426 * and can use the channel iff our competitor has not also
427 * transitioned to BUSY.
429 if (readl(&hdr->cli_state_os) != CHANNELCLI_ATTACHED) {
430 if ((readb(&hdr->cli_error_os)
431 & ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED) == 0) {
432 /* we are NOT throttling this message */
433 writeb(readb(&hdr->cli_error_os) |
434 ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED,
436 /* throttle until acquire successful */
437 pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client NOT ATTACHED (state=%s(%d))\n",
438 id, ULTRA_CHANNELCLI_STRING(
439 readl(&hdr->cli_state_os)),
440 readl(&hdr->cli_state_os));
444 writel(CHANNELCLI_BUSY, &hdr->cli_state_os);
445 mb(); /* required for channel synch */
446 if (readl(&hdr->cli_state_boot) == CHANNELCLI_BUSY) {
447 if ((readb(&hdr->cli_error_os)
448 & ULTRA_CLIERROROS_THROTTLEMSG_BUSY) == 0) {
449 /* we are NOT throttling this message */
450 writeb(readb(&hdr->cli_error_os) |
451 ULTRA_CLIERROROS_THROTTLEMSG_BUSY,
453 /* throttle until acquire successful */
454 pr_info("%s Channel StateTransition failed - host OS acquire failed because boot BUSY\n",
458 writel(CHANNELCLI_ATTACHED, &hdr->cli_state_os);
459 mb(); /* required for channel synch */
462 if (readb(&hdr->cli_error_os)) {
463 /* we are in an error msg throttling state; come out of it */
464 pr_info("%s Channel OS client acquire now successful\n", id);
465 writeb(0, &hdr->cli_error_os);
471 spar_channel_client_release_os(void __iomem *ch, u8 *id)
473 struct channel_header __iomem *hdr = ch;
475 if (readb(&hdr->cli_error_os)) {
476 /* we are in an error msg throttling state; come out of it */
477 pr_info("%s Channel OS client error state cleared\n", id);
478 writeb(0, &hdr->cli_error_os);
480 if (readl(&hdr->cli_state_os) == CHANNELCLI_OWNED)
482 if (readl(&hdr->cli_state_os) != CHANNELCLI_BUSY) {
483 pr_info("%s Channel StateTransition INVALID! - release failed because OS client NOT BUSY (state=%s(%d))\n",
484 id, ULTRA_CHANNELCLI_STRING(
485 readl(&hdr->cli_state_os)),
486 readl(&hdr->cli_state_os));
489 writel(CHANNELCLI_ATTACHED, &hdr->cli_state_os); /* release busy */
493 * Routine Description:
494 * Tries to insert the prebuilt signal pointed to by pSignal into the nth
495 * Queue of the Channel pointed to by pChannel
498 * pChannel: (IN) points to the IO Channel
499 * Queue: (IN) nth Queue of the IO Channel
500 * pSignal: (IN) pointer to the signal
503 * - pChannel, Queue and pSignal are valid.
504 * - If insertion fails due to a full queue, the caller will determine the
505 * retry policy (e.g. wait & try again, report an error, etc.).
507 * Return value: 1 if the insertion succeeds, 0 if the queue was
511 unsigned char spar_signal_insert(struct channel_header __iomem *ch, u32 queue,
515 * Routine Description:
516 * Removes one signal from Channel pChannel's nth Queue at the
517 * time of the call and copies it into the memory pointed to by
521 * pChannel: (IN) points to the IO Channel
522 * Queue: (IN) nth Queue of the IO Channel
523 * pSignal: (IN) pointer to where the signals are to be copied
526 * - pChannel and Queue are valid.
527 * - pSignal points to a memory area large enough to hold queue's SignalSize
529 * Return value: 1 if the removal succeeds, 0 if the queue was
533 unsigned char spar_signal_remove(struct channel_header __iomem *ch, u32 queue,
537 * Routine Description:
538 * Removes all signals present in Channel pChannel's nth Queue at the
539 * time of the call and copies them into the memory pointed to by
540 * pSignal. Returns the # of signals copied as the value of the routine.
543 * pChannel: (IN) points to the IO Channel
544 * Queue: (IN) nth Queue of the IO Channel
545 * pSignal: (IN) pointer to where the signals are to be copied
548 * - pChannel and Queue are valid.
549 * - pSignal points to a memory area large enough to hold Queue's MaxSignals
550 * # of signals, each of which is Queue's SignalSize.
553 * # of signals copied.
555 unsigned int spar_signal_remove_all(struct channel_header *ch, u32 queue,
559 * Routine Description:
560 * Determine whether a signal queue is empty.
563 * pChannel: (IN) points to the IO Channel
564 * Queue: (IN) nth Queue of the IO Channel
567 * 1 if the signal queue is empty, 0 otherwise.
569 unsigned char spar_signalqueue_empty(struct channel_header __iomem *ch,