libnvdimm, pmem: direct map legacy pmem by default
[cascardo/linux.git] / drivers / staging / unisys / visorbus / visorchannel.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.
21  */
22
23 #include <linux/uuid.h>
24 #include <linux/io.h>
25
26 #include "version.h"
27 #include "visorbus.h"
28 #include "controlvmchannel.h"
29
30 #define MYDRVNAME "visorchannel"
31
32 #define SPAR_CONSOLEVIDEO_CHANNEL_PROTOCOL_GUID \
33         UUID_LE(0x3cd6e705, 0xd6a2, 0x4aa5,           \
34                 0xad, 0x5c, 0x7b, 0x8, 0x88, 0x9d, 0xff, 0xe2)
35 static const uuid_le spar_video_guid = SPAR_CONSOLEVIDEO_CHANNEL_PROTOCOL_GUID;
36
37 struct visorchannel {
38         u64 physaddr;
39         ulong nbytes;
40         void *mapped;
41         bool requested;
42         struct channel_header chan_hdr;
43         uuid_le guid;
44         ulong size;
45         bool needs_lock;        /* channel creator knows if more than one
46                                  * thread will be inserting or removing */
47         spinlock_t insert_lock; /* protect head writes in chan_hdr */
48         spinlock_t remove_lock; /* protect tail writes in chan_hdr */
49
50         struct {
51                 struct signal_queue_header req_queue;
52                 struct signal_queue_header rsp_queue;
53                 struct signal_queue_header event_queue;
54                 struct signal_queue_header ack_queue;
55         } safe_uis_queue;
56         uuid_le type;
57         uuid_le inst;
58 };
59
60 /* Creates the struct visorchannel abstraction for a data area in memory,
61  * but does NOT modify this data area.
62  */
63 static struct visorchannel *
64 visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes,
65                          gfp_t gfp, unsigned long off,
66                          uuid_le guid, bool needs_lock)
67 {
68         struct visorchannel *channel;
69         int err;
70         size_t size = sizeof(struct channel_header);
71
72         if (physaddr == 0)
73                 return NULL;
74
75         channel = kzalloc(sizeof(*channel), gfp);
76         if (!channel)
77                 goto cleanup;
78
79         channel->needs_lock = needs_lock;
80         spin_lock_init(&channel->insert_lock);
81         spin_lock_init(&channel->remove_lock);
82
83         /* Video driver constains the efi framebuffer so it will get a
84          * conflict resource when requesting its full mem region. Since
85          * we are only using the efi framebuffer for video we can ignore
86          * this. Remember that we haven't requested it so we don't try to
87          * release later on.
88          */
89         channel->requested = request_mem_region(physaddr, size, MYDRVNAME);
90         if (!channel->requested) {
91                 if (uuid_le_cmp(guid, spar_video_guid)) {
92                         /* Not the video channel we care about this */
93                         goto cleanup;
94                 }
95         }
96
97         channel->mapped = memremap(physaddr, size, MEMREMAP_WB);
98         if (!channel->mapped) {
99                 release_mem_region(physaddr, size);
100                 goto cleanup;
101         }
102
103         channel->physaddr = physaddr;
104         channel->nbytes = size;
105
106         err = visorchannel_read(channel, 0, &channel->chan_hdr,
107                                 sizeof(struct channel_header));
108         if (err)
109                 goto cleanup;
110
111         /* we had better be a CLIENT of this channel */
112         if (channel_bytes == 0)
113                 channel_bytes = (ulong)channel->chan_hdr.size;
114         if (uuid_le_cmp(guid, NULL_UUID_LE) == 0)
115                 guid = channel->chan_hdr.chtype;
116
117         memunmap(channel->mapped);
118         if (channel->requested)
119                 release_mem_region(channel->physaddr, channel->nbytes);
120         channel->mapped = NULL;
121         channel->requested = request_mem_region(channel->physaddr,
122                                                 channel_bytes, MYDRVNAME);
123         if (!channel->requested) {
124                 if (uuid_le_cmp(guid, spar_video_guid)) {
125                         /* Different we care about this */
126                         goto cleanup;
127                 }
128         }
129
130         channel->mapped = memremap(channel->physaddr, channel_bytes,
131                         MEMREMAP_WB);
132         if (!channel->mapped) {
133                 release_mem_region(channel->physaddr, channel_bytes);
134                 goto cleanup;
135         }
136
137         channel->nbytes = channel_bytes;
138
139         channel->size = channel_bytes;
140         channel->guid = guid;
141         return channel;
142
143 cleanup:
144         visorchannel_destroy(channel);
145         return NULL;
146 }
147
148 struct visorchannel *
149 visorchannel_create(u64 physaddr, unsigned long channel_bytes,
150                     gfp_t gfp, uuid_le guid)
151 {
152         return visorchannel_create_guts(physaddr, channel_bytes, gfp, 0, guid,
153                                         false);
154 }
155 EXPORT_SYMBOL_GPL(visorchannel_create);
156
157 struct visorchannel *
158 visorchannel_create_with_lock(u64 physaddr, unsigned long channel_bytes,
159                               gfp_t gfp, uuid_le guid)
160 {
161         return visorchannel_create_guts(physaddr, channel_bytes, gfp, 0, guid,
162                                         true);
163 }
164 EXPORT_SYMBOL_GPL(visorchannel_create_with_lock);
165
166 void
167 visorchannel_destroy(struct visorchannel *channel)
168 {
169         if (!channel)
170                 return;
171         if (channel->mapped) {
172                 memunmap(channel->mapped);
173                 if (channel->requested)
174                         release_mem_region(channel->physaddr, channel->nbytes);
175         }
176         kfree(channel);
177 }
178 EXPORT_SYMBOL_GPL(visorchannel_destroy);
179
180 u64
181 visorchannel_get_physaddr(struct visorchannel *channel)
182 {
183         return channel->physaddr;
184 }
185 EXPORT_SYMBOL_GPL(visorchannel_get_physaddr);
186
187 ulong
188 visorchannel_get_nbytes(struct visorchannel *channel)
189 {
190         return channel->size;
191 }
192 EXPORT_SYMBOL_GPL(visorchannel_get_nbytes);
193
194 char *
195 visorchannel_uuid_id(uuid_le *guid, char *s)
196 {
197         sprintf(s, "%pUL", guid);
198         return s;
199 }
200 EXPORT_SYMBOL_GPL(visorchannel_uuid_id);
201
202 char *
203 visorchannel_id(struct visorchannel *channel, char *s)
204 {
205         return visorchannel_uuid_id(&channel->guid, s);
206 }
207 EXPORT_SYMBOL_GPL(visorchannel_id);
208
209 char *
210 visorchannel_zoneid(struct visorchannel *channel, char *s)
211 {
212         return visorchannel_uuid_id(&channel->chan_hdr.zone_uuid, s);
213 }
214 EXPORT_SYMBOL_GPL(visorchannel_zoneid);
215
216 u64
217 visorchannel_get_clientpartition(struct visorchannel *channel)
218 {
219         return channel->chan_hdr.partition_handle;
220 }
221 EXPORT_SYMBOL_GPL(visorchannel_get_clientpartition);
222
223 int
224 visorchannel_set_clientpartition(struct visorchannel *channel,
225                                  u64 partition_handle)
226 {
227         channel->chan_hdr.partition_handle = partition_handle;
228         return 0;
229 }
230 EXPORT_SYMBOL_GPL(visorchannel_set_clientpartition);
231
232 uuid_le
233 visorchannel_get_uuid(struct visorchannel *channel)
234 {
235         return channel->guid;
236 }
237 EXPORT_SYMBOL_GPL(visorchannel_get_uuid);
238
239 int
240 visorchannel_read(struct visorchannel *channel, ulong offset,
241                   void *local, ulong nbytes)
242 {
243         if (offset + nbytes > channel->nbytes)
244                 return -EIO;
245
246         memcpy(local, channel->mapped + offset, nbytes);
247
248         return 0;
249 }
250 EXPORT_SYMBOL_GPL(visorchannel_read);
251
252 int
253 visorchannel_write(struct visorchannel *channel, ulong offset,
254                    void *local, ulong nbytes)
255 {
256         size_t chdr_size = sizeof(struct channel_header);
257         size_t copy_size;
258
259         if (offset + nbytes > channel->nbytes)
260                 return -EIO;
261
262         if (offset < chdr_size) {
263                 copy_size = min(chdr_size - offset, nbytes);
264                 memcpy(&channel->chan_hdr + offset, 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
422         if (channel->needs_lock) {
423                 spin_lock(&channel->remove_lock);
424                 rc = signalremove_inner(channel, queue, msg);
425                 spin_unlock(&channel->remove_lock);
426         } else {
427                 rc = signalremove_inner(channel, queue, msg);
428         }
429
430         return rc;
431 }
432 EXPORT_SYMBOL_GPL(visorchannel_signalremove);
433
434 static bool
435 signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg)
436 {
437         struct signal_queue_header sig_hdr;
438
439         if (!sig_read_header(channel, queue, &sig_hdr))
440                 return false;
441
442         sig_hdr.head = ((sig_hdr.head + 1) % sig_hdr.max_slots);
443         if (sig_hdr.head == sig_hdr.tail) {
444                 sig_hdr.num_overflows++;
445                 visorchannel_write(channel,
446                                    SIG_QUEUE_OFFSET(&channel->chan_hdr, queue) +
447                                    offsetof(struct signal_queue_header,
448                                             num_overflows),
449                                    &(sig_hdr.num_overflows),
450                                    sizeof(sig_hdr.num_overflows));
451                 return false;
452         }
453
454         if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg))
455                 return false;
456
457         sig_hdr.num_sent++;
458
459         /* For each data field in SIGNAL_QUEUE_HEADER that was modified,
460          * update host memory.
461          */
462         mb(); /* required for channel synch */
463         if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, head))
464                 return false;
465         if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent))
466                 return false;
467
468         return true;
469 }
470
471 bool
472 visorchannel_signalinsert(struct visorchannel *channel, u32 queue, void *msg)
473 {
474         bool rc;
475
476         if (channel->needs_lock) {
477                 spin_lock(&channel->insert_lock);
478                 rc = signalinsert_inner(channel, queue, msg);
479                 spin_unlock(&channel->insert_lock);
480         } else {
481                 rc = signalinsert_inner(channel, queue, msg);
482         }
483
484         return rc;
485 }
486 EXPORT_SYMBOL_GPL(visorchannel_signalinsert);
487
488 int
489 visorchannel_signalqueue_slots_avail(struct visorchannel *channel, u32 queue)
490 {
491         struct signal_queue_header sig_hdr;
492         u32 slots_avail, slots_used;
493         u32 head, tail;
494
495         if (!sig_read_header(channel, queue, &sig_hdr))
496                 return 0;
497         head = sig_hdr.head;
498         tail = sig_hdr.tail;
499         if (head < tail)
500                 head = head + sig_hdr.max_slots;
501         slots_used = (head - tail);
502         slots_avail = sig_hdr.max_signals - slots_used;
503         return (int)slots_avail;
504 }
505 EXPORT_SYMBOL_GPL(visorchannel_signalqueue_slots_avail);
506
507 int
508 visorchannel_signalqueue_max_slots(struct visorchannel *channel, u32 queue)
509 {
510         struct signal_queue_header sig_hdr;
511
512         if (!sig_read_header(channel, queue, &sig_hdr))
513                 return 0;
514         return (int)sig_hdr.max_signals;
515 }
516 EXPORT_SYMBOL_GPL(visorchannel_signalqueue_max_slots);
517
518 static void
519 sigqueue_debug(struct signal_queue_header *q, int which, struct seq_file *seq)
520 {
521         seq_printf(seq, "Signal Queue #%d\n", which);
522         seq_printf(seq, "   VersionId          = %lu\n", (ulong)q->version);
523         seq_printf(seq, "   Type               = %lu\n", (ulong)q->chtype);
524         seq_printf(seq, "   oSignalBase        = %llu\n",
525                    (long long)q->sig_base_offset);
526         seq_printf(seq, "   SignalSize         = %lu\n", (ulong)q->signal_size);
527         seq_printf(seq, "   MaxSignalSlots     = %lu\n",
528                    (ulong)q->max_slots);
529         seq_printf(seq, "   MaxSignals         = %lu\n", (ulong)q->max_signals);
530         seq_printf(seq, "   FeatureFlags       = %-16.16Lx\n",
531                    (long long)q->features);
532         seq_printf(seq, "   NumSignalsSent     = %llu\n",
533                    (long long)q->num_sent);
534         seq_printf(seq, "   NumSignalsReceived = %llu\n",
535                    (long long)q->num_received);
536         seq_printf(seq, "   NumOverflows       = %llu\n",
537                    (long long)q->num_overflows);
538         seq_printf(seq, "   Head               = %lu\n", (ulong)q->head);
539         seq_printf(seq, "   Tail               = %lu\n", (ulong)q->tail);
540 }
541
542 void
543 visorchannel_debug(struct visorchannel *channel, int num_queues,
544                    struct seq_file *seq, u32 off)
545 {
546         u64 addr = 0;
547         ulong nbytes = 0, nbytes_region = 0;
548         struct channel_header hdr;
549         struct channel_header *phdr = &hdr;
550         int i = 0;
551         int errcode = 0;
552
553         if (!channel)
554                 return;
555
556         addr = visorchannel_get_physaddr(channel);
557         nbytes_region = visorchannel_get_nbytes(channel);
558         errcode = visorchannel_read(channel, off,
559                                     phdr, sizeof(struct channel_header));
560         if (errcode < 0) {
561                 seq_printf(seq,
562                            "Read of channel header failed with errcode=%d)\n",
563                            errcode);
564                 if (off == 0) {
565                         phdr = &channel->chan_hdr;
566                         seq_puts(seq, "(following data may be stale)\n");
567                 } else {
568                         return;
569                 }
570         }
571         nbytes = (ulong)(phdr->size);
572         seq_printf(seq, "--- Begin channel @0x%-16.16Lx for 0x%lx bytes (region=0x%lx bytes) ---\n",
573                    addr + off, nbytes, nbytes_region);
574         seq_printf(seq, "Type            = %pUL\n", &phdr->chtype);
575         seq_printf(seq, "ZoneGuid        = %pUL\n", &phdr->zone_uuid);
576         seq_printf(seq, "Signature       = 0x%-16.16Lx\n",
577                    (long long)phdr->signature);
578         seq_printf(seq, "LegacyState     = %lu\n", (ulong)phdr->legacy_state);
579         seq_printf(seq, "SrvState        = %lu\n", (ulong)phdr->srv_state);
580         seq_printf(seq, "CliStateBoot    = %lu\n", (ulong)phdr->cli_state_boot);
581         seq_printf(seq, "CliStateOS      = %lu\n", (ulong)phdr->cli_state_os);
582         seq_printf(seq, "HeaderSize      = %lu\n", (ulong)phdr->header_size);
583         seq_printf(seq, "Size            = %llu\n", (long long)phdr->size);
584         seq_printf(seq, "Features        = 0x%-16.16llx\n",
585                    (long long)phdr->features);
586         seq_printf(seq, "PartitionHandle = 0x%-16.16llx\n",
587                    (long long)phdr->partition_handle);
588         seq_printf(seq, "Handle          = 0x%-16.16llx\n",
589                    (long long)phdr->handle);
590         seq_printf(seq, "VersionId       = %lu\n", (ulong)phdr->version_id);
591         seq_printf(seq, "oChannelSpace   = %llu\n",
592                    (long long)phdr->ch_space_offset);
593         if ((phdr->ch_space_offset == 0) || (errcode < 0))
594                 ;
595         else
596                 for (i = 0; i < num_queues; i++) {
597                         struct signal_queue_header q;
598
599                         errcode = visorchannel_read(channel,
600                                                     off +
601                                                     phdr->ch_space_offset +
602                                                     (i * sizeof(q)),
603                                                     &q, sizeof(q));
604                         if (errcode < 0) {
605                                 seq_printf(seq,
606                                            "failed to read signal queue #%d from channel @0x%-16.16Lx errcode=%d\n",
607                                            i, addr, errcode);
608                                 continue;
609                         }
610                         sigqueue_debug(&q, i, seq);
611                 }
612         seq_printf(seq, "--- End   channel @0x%-16.16Lx for 0x%lx bytes ---\n",
613                    addr + off, nbytes);
614 }
615 EXPORT_SYMBOL_GPL(visorchannel_debug);