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