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