Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / staging / unisys / visorchannel / visorchannel_funcs.c
1 /* visorchannel_funcs.c
2  *
3  * Copyright (C) 2010 - 2013 UNISYS CORPORATION
4  * All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or (at
9  * your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
14  * NON INFRINGEMENT.  See the GNU General Public License for more
15  * details.
16  */
17
18 /*
19  *  This provides Supervisor channel communication primitives, which are
20  *  independent of the mechanism used to access the channel data.  All channel
21  *  data is accessed using the memregion abstraction.  (memregion has both
22  *  a CM2 implementation and a direct memory implementation.)
23  */
24
25 #include "globals.h"
26 #include "visorchannel.h"
27 #include <linux/uuid.h>
28
29 #define MYDRVNAME "visorchannel"
30
31 struct visorchannel {
32         struct memregion *memregion;    /* from visor_memregion_create() */
33         struct channel_header chan_hdr;
34         uuid_le guid;
35         ulong size;
36         BOOL needs_lock;        /* channel creator knows if more than one
37                                  * thread will be inserting or removing */
38         spinlock_t insert_lock; /* protect head writes in chan_hdr */
39         spinlock_t remove_lock; /* protect tail writes in chan_hdr */
40
41         struct {
42                 struct signal_queue_header req_queue;
43                 struct signal_queue_header rsp_queue;
44                 struct signal_queue_header event_queue;
45                 struct signal_queue_header ack_queue;
46         } safe_uis_queue;
47 };
48
49 /* Creates the struct visorchannel abstraction for a data area in memory,
50  * but does NOT modify this data area.
51  */
52 static struct visorchannel *
53 visorchannel_create_guts(HOSTADDRESS physaddr, ulong channel_bytes,
54                          struct visorchannel *parent, ulong off, uuid_le guid,
55                          BOOL needs_lock)
56 {
57         struct visorchannel *p = NULL;
58         void *rc = NULL;
59
60         p = kmalloc(sizeof(*p), GFP_KERNEL|__GFP_NORETRY);
61         if (!p) {
62                 rc = NULL;
63                 goto cleanup;
64         }
65         p->memregion = NULL;
66         p->needs_lock = needs_lock;
67         spin_lock_init(&p->insert_lock);
68         spin_lock_init(&p->remove_lock);
69
70         /* prepare chan_hdr (abstraction to read/write channel memory) */
71         if (!parent)
72                 p->memregion =
73                     visor_memregion_create(physaddr,
74                                            sizeof(struct channel_header));
75         else
76                 p->memregion =
77                     visor_memregion_create_overlapped(parent->memregion,
78                                 off, sizeof(struct channel_header));
79         if (!p->memregion) {
80                 rc = NULL;
81                 goto cleanup;
82         }
83         if (visor_memregion_read(p->memregion, 0, &p->chan_hdr,
84                                  sizeof(struct channel_header)) < 0) {
85                 rc = NULL;
86                 goto cleanup;
87         }
88         if (channel_bytes == 0)
89                 /* we had better be a CLIENT of this channel */
90                 channel_bytes = (ulong)p->chan_hdr.size;
91         if (uuid_le_cmp(guid, NULL_UUID_LE) == 0)
92                 /* we had better be a CLIENT of this channel */
93                 guid = p->chan_hdr.chtype;
94         if (visor_memregion_resize(p->memregion, channel_bytes) < 0) {
95                 rc = NULL;
96                 goto cleanup;
97         }
98         p->size = channel_bytes;
99         p->guid = guid;
100
101         rc = p;
102 cleanup:
103
104         if (!rc) {
105                 if (!p) {
106                         visorchannel_destroy(p);
107                         p = NULL;
108                 }
109         }
110         return rc;
111 }
112
113 struct visorchannel *
114 visorchannel_create(HOSTADDRESS physaddr, ulong channel_bytes, uuid_le guid)
115 {
116         return visorchannel_create_guts(physaddr, channel_bytes, NULL, 0, guid,
117                                         FALSE);
118 }
119 EXPORT_SYMBOL_GPL(visorchannel_create);
120
121 struct visorchannel *
122 visorchannel_create_with_lock(HOSTADDRESS physaddr, ulong channel_bytes,
123                               uuid_le guid)
124 {
125         return visorchannel_create_guts(physaddr, channel_bytes, NULL, 0, guid,
126                                         TRUE);
127 }
128 EXPORT_SYMBOL_GPL(visorchannel_create_with_lock);
129
130 struct visorchannel *
131 visorchannel_create_overlapped(ulong channel_bytes,
132                                struct visorchannel *parent, ulong off,
133                                uuid_le guid)
134 {
135         return visorchannel_create_guts(0, channel_bytes, parent, off, guid,
136                                         FALSE);
137 }
138 EXPORT_SYMBOL_GPL(visorchannel_create_overlapped);
139
140 struct visorchannel *
141 visorchannel_create_overlapped_with_lock(ulong channel_bytes,
142                                          struct visorchannel *parent, ulong off,
143                                          uuid_le guid)
144 {
145         return visorchannel_create_guts(0, channel_bytes, parent, off, guid,
146                                         TRUE);
147 }
148 EXPORT_SYMBOL_GPL(visorchannel_create_overlapped_with_lock);
149
150 void
151 visorchannel_destroy(struct visorchannel *channel)
152 {
153         if (!channel)
154                 return;
155         if (channel->memregion) {
156                 visor_memregion_destroy(channel->memregion);
157                 channel->memregion = NULL;
158         }
159         kfree(channel);
160 }
161 EXPORT_SYMBOL_GPL(visorchannel_destroy);
162
163 HOSTADDRESS
164 visorchannel_get_physaddr(struct visorchannel *channel)
165 {
166         return visor_memregion_get_physaddr(channel->memregion);
167 }
168 EXPORT_SYMBOL_GPL(visorchannel_get_physaddr);
169
170 ulong
171 visorchannel_get_nbytes(struct visorchannel *channel)
172 {
173         return channel->size;
174 }
175 EXPORT_SYMBOL_GPL(visorchannel_get_nbytes);
176
177 char *
178 visorchannel_uuid_id(uuid_le *guid, char *s)
179 {
180         sprintf(s, "%pUL", guid);
181         return s;
182 }
183 EXPORT_SYMBOL_GPL(visorchannel_uuid_id);
184
185 char *
186 visorchannel_id(struct visorchannel *channel, char *s)
187 {
188         return visorchannel_uuid_id(&channel->guid, s);
189 }
190 EXPORT_SYMBOL_GPL(visorchannel_id);
191
192 char *
193 visorchannel_zoneid(struct visorchannel *channel, char *s)
194 {
195         return visorchannel_uuid_id(&channel->chan_hdr.zone_uuid, s);
196 }
197 EXPORT_SYMBOL_GPL(visorchannel_zoneid);
198
199 HOSTADDRESS
200 visorchannel_get_clientpartition(struct visorchannel *channel)
201 {
202         return channel->chan_hdr.partition_handle;
203 }
204 EXPORT_SYMBOL_GPL(visorchannel_get_clientpartition);
205
206 uuid_le
207 visorchannel_get_uuid(struct visorchannel *channel)
208 {
209         return channel->guid;
210 }
211 EXPORT_SYMBOL_GPL(visorchannel_get_uuid);
212
213 struct memregion *
214 visorchannel_get_memregion(struct visorchannel *channel)
215 {
216         return channel->memregion;
217 }
218 EXPORT_SYMBOL_GPL(visorchannel_get_memregion);
219
220 int
221 visorchannel_read(struct visorchannel *channel, ulong offset,
222                   void *local, ulong nbytes)
223 {
224         int rc = visor_memregion_read(channel->memregion, offset,
225                                       local, nbytes);
226         if ((rc >= 0) && (offset == 0) &&
227             (nbytes >= sizeof(struct channel_header))) {
228                 memcpy(&channel->chan_hdr, local,
229                        sizeof(struct channel_header));
230         }
231         return rc;
232 }
233 EXPORT_SYMBOL_GPL(visorchannel_read);
234
235 int
236 visorchannel_write(struct visorchannel *channel, ulong offset,
237                    void *local, ulong nbytes)
238 {
239         if (offset == 0 && nbytes >= sizeof(struct channel_header))
240                 memcpy(&channel->chan_hdr, local,
241                        sizeof(struct channel_header));
242         return visor_memregion_write(channel->memregion, offset, local, nbytes);
243 }
244 EXPORT_SYMBOL_GPL(visorchannel_write);
245
246 int
247 visorchannel_clear(struct visorchannel *channel, ulong offset, u8 ch,
248                    ulong nbytes)
249 {
250         int rc = -1;
251         int bufsize = 65536;
252         int written = 0;
253         u8 *buf = vmalloc(bufsize);
254
255         if (!buf)
256                 goto cleanup;
257
258         memset(buf, ch, bufsize);
259         while (nbytes > 0) {
260                 ulong thisbytes = bufsize;
261                 int x = -1;
262
263                 if (nbytes < thisbytes)
264                         thisbytes = nbytes;
265                 x = visor_memregion_write(channel->memregion, offset + written,
266                                           buf, thisbytes);
267                 if (x < 0) {
268                         rc = x;
269                         goto cleanup;
270                 }
271                 written += thisbytes;
272                 nbytes -= thisbytes;
273         }
274         rc = 0;
275
276 cleanup:
277         if (buf) {
278                 vfree(buf);
279                 buf = NULL;
280         }
281         return rc;
282 }
283 EXPORT_SYMBOL_GPL(visorchannel_clear);
284
285 void __iomem  *
286 visorchannel_get_header(struct visorchannel *channel)
287 {
288         return (void __iomem *)&channel->chan_hdr;
289 }
290 EXPORT_SYMBOL_GPL(visorchannel_get_header);
291
292 /** Return offset of a specific SIGNAL_QUEUE_HEADER from the beginning of a
293  *  channel header
294  */
295 #define SIG_QUEUE_OFFSET(chan_hdr, q) \
296         ((chan_hdr)->ch_space_offset + \
297          ((q) * sizeof(struct signal_queue_header)))
298
299 /** Return offset of a specific queue entry (data) from the beginning of a
300  *  channel header
301  */
302 #define SIG_DATA_OFFSET(chan_hdr, q, sig_hdr, slot) \
303         (SIG_QUEUE_OFFSET(chan_hdr, q) + (sig_hdr)->sig_base_offset + \
304             ((slot) * (sig_hdr)->signal_size))
305
306 /** Write the contents of a specific field within a SIGNAL_QUEUE_HEADER back
307  *  into host memory
308  */
309 #define SIG_WRITE_FIELD(channel, queue, sig_hdr, FIELD)                 \
310         (visor_memregion_write(channel->memregion,                      \
311                                SIG_QUEUE_OFFSET(&channel->chan_hdr, queue)+ \
312                                offsetof(struct signal_queue_header, FIELD),\
313                                &((sig_hdr)->FIELD),                     \
314                                sizeof((sig_hdr)->FIELD)) >= 0)
315
316 static BOOL
317 sig_read_header(struct visorchannel *channel, u32 queue,
318                 struct signal_queue_header *sig_hdr)
319 {
320         BOOL rc = FALSE;
321
322         if (channel->chan_hdr.ch_space_offset < sizeof(struct channel_header))
323                 goto cleanup;
324
325         /* Read the appropriate SIGNAL_QUEUE_HEADER into local memory. */
326
327         if (visor_memregion_read(channel->memregion,
328                                  SIG_QUEUE_OFFSET(&channel->chan_hdr, queue),
329                                  sig_hdr,
330                                  sizeof(struct signal_queue_header)) < 0) {
331                 goto cleanup;
332         }
333         rc = TRUE;
334 cleanup:
335         return rc;
336 }
337
338 static BOOL
339 sig_do_data(struct visorchannel *channel, u32 queue,
340             struct signal_queue_header *sig_hdr, u32 slot, void *data,
341             BOOL is_write)
342 {
343         BOOL rc = FALSE;
344         int signal_data_offset = SIG_DATA_OFFSET(&channel->chan_hdr, queue,
345                                                  sig_hdr, slot);
346         if (is_write) {
347                 if (visor_memregion_write(channel->memregion,
348                                           signal_data_offset,
349                                           data, sig_hdr->signal_size) < 0) {
350                         goto cleanup;
351                 }
352         } else {
353                 if (visor_memregion_read(channel->memregion, signal_data_offset,
354                                          data, sig_hdr->signal_size) < 0) {
355                         goto cleanup;
356                 }
357         }
358         rc = TRUE;
359 cleanup:
360         return rc;
361 }
362
363 static inline BOOL
364 sig_read_data(struct visorchannel *channel, u32 queue,
365               struct signal_queue_header *sig_hdr, u32 slot, void *data)
366 {
367         return sig_do_data(channel, queue, sig_hdr, slot, data, FALSE);
368 }
369
370 static inline BOOL
371 sig_write_data(struct visorchannel *channel, u32 queue,
372                struct signal_queue_header *sig_hdr, u32 slot, void *data)
373 {
374         return sig_do_data(channel, queue, sig_hdr, slot, data, TRUE);
375 }
376
377 static inline unsigned char
378 safe_sig_queue_validate(struct signal_queue_header *psafe_sqh,
379                         struct signal_queue_header *punsafe_sqh,
380                         u32 *phead, u32 *ptail)
381 {
382         if ((*phead >= psafe_sqh->max_slots) ||
383             (*ptail >= psafe_sqh->max_slots)) {
384                 /* Choose 0 or max, maybe based on current tail value */
385                 *phead = 0;
386                 *ptail = 0;
387
388                 /* Sync with client as necessary */
389                 punsafe_sqh->head = *phead;
390                 punsafe_sqh->tail = *ptail;
391
392                 return 0;
393         }
394         return 1;
395 }                               /* end safe_sig_queue_validate */
396
397 static BOOL
398 signalremove_inner(struct visorchannel *channel, u32 queue, void *msg)
399 {
400         struct signal_queue_header sig_hdr;
401
402         if (!sig_read_header(channel, queue, &sig_hdr))
403                 return FALSE;
404         if (sig_hdr.head == sig_hdr.tail)
405                 return FALSE;   /* no signals to remove */
406
407         sig_hdr.tail = (sig_hdr.tail + 1) % sig_hdr.max_slots;
408         if (!sig_read_data(channel, queue, &sig_hdr, sig_hdr.tail, msg)) {
409                 return FALSE;
410         }
411         sig_hdr.num_received++;
412
413         /* For each data field in SIGNAL_QUEUE_HEADER that was modified,
414          * update host memory.
415          */
416         mb(); /* required for channel synch */
417         if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail))
418                 return FALSE;
419         if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received))
420                 return FALSE;
421         return TRUE;
422 }
423
424 BOOL
425 visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg)
426 {
427         BOOL rc;
428
429         if (channel->needs_lock) {
430                 spin_lock(&channel->remove_lock);
431                 rc = signalremove_inner(channel, queue, msg);
432                 spin_unlock(&channel->remove_lock);
433         } else {
434                 rc = signalremove_inner(channel, queue, msg);
435         }
436
437         return rc;
438 }
439 EXPORT_SYMBOL_GPL(visorchannel_signalremove);
440
441 static BOOL
442 signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg)
443 {
444         struct signal_queue_header sig_hdr;
445
446         if (!sig_read_header(channel, queue, &sig_hdr))
447                 return FALSE;
448
449         sig_hdr.head = ((sig_hdr.head + 1) % sig_hdr.max_slots);
450         if (sig_hdr.head == sig_hdr.tail) {
451                 sig_hdr.num_overflows++;
452                 visor_memregion_write(channel->memregion,
453                                       SIG_QUEUE_OFFSET(&channel->chan_hdr,
454                                                        queue) +
455                                       offsetof(struct signal_queue_header,
456                                                num_overflows),
457                                       &(sig_hdr.num_overflows),
458                                       sizeof(sig_hdr.num_overflows));
459                 return FALSE;
460         }
461
462         if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg))
463                 return FALSE;
464
465         sig_hdr.num_sent++;
466
467         /* For each data field in SIGNAL_QUEUE_HEADER that was modified,
468          * update host memory.
469          */
470         mb(); /* required for channel synch */
471         if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, head))
472                 return FALSE;
473         if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent)) {
474                 return FALSE;
475         }
476
477         return TRUE;
478 }
479
480 BOOL
481 visorchannel_signalinsert(struct visorchannel *channel, u32 queue, void *msg)
482 {
483         BOOL rc;
484
485         if (channel->needs_lock) {
486                 spin_lock(&channel->insert_lock);
487                 rc = signalinsert_inner(channel, queue, msg);
488                 spin_unlock(&channel->insert_lock);
489         } else {
490                 rc = signalinsert_inner(channel, queue, msg);
491         }
492
493         return rc;
494 }
495 EXPORT_SYMBOL_GPL(visorchannel_signalinsert);
496
497 int
498 visorchannel_signalqueue_slots_avail(struct visorchannel *channel, u32 queue)
499 {
500         struct signal_queue_header sig_hdr;
501         u32 slots_avail, slots_used;
502         u32 head, tail;
503
504         if (!sig_read_header(channel, queue, &sig_hdr))
505                 return 0;
506         head = sig_hdr.head;
507         tail = sig_hdr.tail;
508         if (head < tail)
509                 head = head + sig_hdr.max_slots;
510         slots_used = (head - tail);
511         slots_avail = sig_hdr.max_signals - slots_used;
512         return (int)slots_avail;
513 }
514 EXPORT_SYMBOL_GPL(visorchannel_signalqueue_slots_avail);
515
516 int
517 visorchannel_signalqueue_max_slots(struct visorchannel *channel, u32 queue)
518 {
519         struct signal_queue_header sig_hdr;
520
521         if (!sig_read_header(channel, queue, &sig_hdr))
522                 return 0;
523         return (int)sig_hdr.max_signals;
524 }
525 EXPORT_SYMBOL_GPL(visorchannel_signalqueue_max_slots);
526
527 static void
528 sigqueue_debug(struct signal_queue_header *q, int which, struct seq_file *seq)
529 {
530         seq_printf(seq, "Signal Queue #%d\n", which);
531         seq_printf(seq, "   VersionId          = %lu\n", (ulong)q->version);
532         seq_printf(seq, "   Type               = %lu\n", (ulong)q->chtype);
533         seq_printf(seq, "   oSignalBase        = %llu\n",
534                    (long long)q->sig_base_offset);
535         seq_printf(seq, "   SignalSize         = %lu\n", (ulong)q->signal_size);
536         seq_printf(seq, "   MaxSignalSlots     = %lu\n",
537                    (ulong)q->max_slots);
538         seq_printf(seq, "   MaxSignals         = %lu\n", (ulong)q->max_signals);
539         seq_printf(seq, "   FeatureFlags       = %-16.16Lx\n",
540                    (long long)q->features);
541         seq_printf(seq, "   NumSignalsSent     = %llu\n",
542                    (long long)q->num_sent);
543         seq_printf(seq, "   NumSignalsReceived = %llu\n",
544                    (long long)q->num_received);
545         seq_printf(seq, "   NumOverflows       = %llu\n",
546                    (long long)q->num_overflows);
547         seq_printf(seq, "   Head               = %lu\n", (ulong)q->head);
548         seq_printf(seq, "   Tail               = %lu\n", (ulong)q->tail);
549 }
550
551 void
552 visorchannel_debug(struct visorchannel *channel, int num_queues,
553                    struct seq_file *seq, u32 off)
554 {
555         HOSTADDRESS addr = 0;
556         ulong nbytes = 0, nbytes_region = 0;
557         struct memregion *memregion = NULL;
558         struct channel_header hdr;
559         struct channel_header *phdr = &hdr;
560         int i = 0;
561         int errcode = 0;
562
563         if (!channel)
564                 return;
565         memregion = channel->memregion;
566         if (!memregion)
567                 return;
568
569         addr = visor_memregion_get_physaddr(memregion);
570         nbytes_region = visor_memregion_get_nbytes(memregion);
571         errcode = visorchannel_read(channel, off,
572                                     phdr, sizeof(struct channel_header));
573         if (errcode < 0) {
574                 seq_printf(seq,
575                            "Read of channel header failed with errcode=%d)\n",
576                            errcode);
577                 if (off == 0) {
578                         phdr = &channel->chan_hdr;
579                         seq_puts(seq, "(following data may be stale)\n");
580                 } else {
581                         return;
582                 }
583         }
584         nbytes = (ulong)(phdr->size);
585         seq_printf(seq, "--- Begin channel @0x%-16.16Lx for 0x%lx bytes (region=0x%lx bytes) ---\n",
586                    addr + off, nbytes, nbytes_region);
587         seq_printf(seq, "Type            = %pUL\n", &phdr->chtype);
588         seq_printf(seq, "ZoneGuid        = %pUL\n", &phdr->zone_uuid);
589         seq_printf(seq, "Signature       = 0x%-16.16Lx\n",
590                    (long long)phdr->signature);
591         seq_printf(seq, "LegacyState     = %lu\n", (ulong)phdr->legacy_state);
592         seq_printf(seq, "SrvState        = %lu\n", (ulong)phdr->srv_state);
593         seq_printf(seq, "CliStateBoot    = %lu\n", (ulong)phdr->cli_state_boot);
594         seq_printf(seq, "CliStateOS      = %lu\n", (ulong)phdr->cli_state_os);
595         seq_printf(seq, "HeaderSize      = %lu\n", (ulong)phdr->header_size);
596         seq_printf(seq, "Size            = %llu\n", (long long)phdr->size);
597         seq_printf(seq, "Features        = 0x%-16.16llx\n",
598                    (long long)phdr->features);
599         seq_printf(seq, "PartitionHandle = 0x%-16.16llx\n",
600                    (long long)phdr->partition_handle);
601         seq_printf(seq, "Handle          = 0x%-16.16llx\n",
602                    (long long)phdr->handle);
603         seq_printf(seq, "VersionId       = %lu\n", (ulong)phdr->version_id);
604         seq_printf(seq, "oChannelSpace   = %llu\n",
605                    (long long)phdr->ch_space_offset);
606         if ((phdr->ch_space_offset == 0) || (errcode < 0))
607                 ;
608         else
609                 for (i = 0; i < num_queues; i++) {
610                         struct signal_queue_header q;
611
612                         errcode = visorchannel_read(channel,
613                                                     off +
614                                                     phdr->ch_space_offset +
615                                                     (i * sizeof(q)),
616                                                     &q, sizeof(q));
617                         if (errcode < 0) {
618                                 seq_printf(seq,
619                                            "failed to read signal queue #%d from channel @0x%-16.16Lx errcode=%d\n",
620                                            i, addr, errcode);
621                                 continue;
622                         }
623                         sigqueue_debug(&q, i, seq);
624                 }
625         seq_printf(seq, "--- End   channel @0x%-16.16Lx for 0x%lx bytes ---\n",
626                    addr + off, nbytes);
627 }
628 EXPORT_SYMBOL_GPL(visorchannel_debug);
629
630 void
631 visorchannel_dump_section(struct visorchannel *chan, char *s,
632                           int off, int len, struct seq_file *seq)
633 {
634         char *buf, *tbuf, *fmtbuf;
635         int fmtbufsize = 0;
636         int i;
637         int errcode = 0;
638
639         fmtbufsize = 100 * COVQ(len, 16);
640         buf = kmalloc(len, GFP_KERNEL|__GFP_NORETRY);
641         if (!buf)
642                 return;
643         fmtbuf = kmalloc(fmtbufsize, GFP_KERNEL|__GFP_NORETRY);
644         if (!fmtbuf)
645                 goto fmt_failed;
646
647         errcode = visorchannel_read(chan, off, buf, len);
648         if (errcode < 0)
649                 goto read_failed;
650         seq_printf(seq, "channel %s:\n", s);
651         tbuf = buf;
652         while (len > 0) {
653                 i = (len < 16) ? len : 16;
654                 hex_dump_to_buffer(tbuf, i, 16, 1, fmtbuf, fmtbufsize, TRUE);
655                 seq_printf(seq, "%s\n", fmtbuf);
656                 tbuf += 16;
657                 len -= 16;
658         }
659
660 read_failed:
661         kfree(fmtbuf);
662 fmt_failed:
663         kfree(buf);
664 }
665 EXPORT_SYMBOL_GPL(visorchannel_dump_section);