staging: unisys: uislib: uislib.c: sparse warning of context imbalance
[firefly-linux-kernel-4.4.55.git] / drivers / staging / unisys / uislib / uislib.c
1 /* uislib.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 /* @ALL_INSPECTED */
19 #define EXPORT_SYMTAB
20 #include <linux/kernel.h>
21 #include <linux/highmem.h>
22 #ifdef CONFIG_MODVERSIONS
23 #include <config/modversions.h>
24 #endif
25 #include <linux/module.h>
26 #include <linux/debugfs.h>
27
28 #include <linux/types.h>
29 #include <linux/uuid.h>
30
31 #include <linux/version.h>
32 #include "uniklog.h"
33 #include "diagnostics/appos_subsystems.h"
34 #include "uisutils.h"
35 #include "vbuschannel.h"
36
37 #include <linux/proc_fs.h>
38 #include <linux/uaccess.h>      /* for copy_from_user */
39 #include <linux/ctype.h>        /* for toupper */
40 #include <linux/list.h>
41
42 #include "sparstop.h"
43 #include "visorchipset.h"
44 #include "chanstub.h"
45 #include "version.h"
46 #include "guestlinuxdebug.h"
47
48 #define SET_PROC_OWNER(x, y)
49
50 #define POLLJIFFIES_NORMAL 1
51 /* Choose whether or not you want to wakeup the request-polling thread
52  * after an IO termination:
53  * this is shorter than using __FILE__ (full path name) in
54  * debug/info/error messages
55  */
56 #define CURRENT_FILE_PC UISLIB_PC_uislib_c
57 #define __MYFILE__ "uislib.c"
58
59 /* global function pointers that act as callback functions into virtpcimod */
60 int (*VirtControlChanFunc)(struct guest_msgs *);
61
62 static int ProcReadBufferValid;
63 static char *ProcReadBuffer;    /* Note this MUST be global,
64                                          * because the contents must */
65 static unsigned int chipset_inited;
66
67 #define WAIT_ON_CALLBACK(handle)        \
68         do {                    \
69                 if (handle)             \
70                         break;          \
71                 UIS_THREAD_WAIT;        \
72         } while (1)
73
74 static struct bus_info *BusListHead;
75 static rwlock_t BusListLock;
76 static int BusListCount;        /* number of buses in the list */
77 static int MaxBusCount;         /* maximum number of buses expected */
78 static u64 PhysicalDataChan;
79 static int PlatformNumber;
80
81 static struct uisthread_info Incoming_ThreadInfo;
82 static BOOL Incoming_Thread_Started = FALSE;
83 static LIST_HEAD(List_Polling_Device_Channels);
84 static unsigned long long tot_moved_to_tail_cnt;
85 static unsigned long long tot_wait_cnt;
86 static unsigned long long tot_wakeup_cnt;
87 static unsigned long long tot_schedule_cnt;
88 static int en_smart_wakeup = 1;
89 static DEFINE_SEMAPHORE(Lock_Polling_Device_Channels);  /* unlocked */
90 static DECLARE_WAIT_QUEUE_HEAD(Wakeup_Polling_Device_Channels);
91 static int Go_Polling_Device_Channels;
92
93 #define CALLHOME_PROC_ENTRY_FN "callhome"
94 #define CALLHOME_THROTTLED_PROC_ENTRY_FN "callhome_throttled"
95
96 #define DIR_DEBUGFS_ENTRY "uislib"
97 static struct dentry *dir_debugfs;
98
99 #define PLATFORMNUMBER_DEBUGFS_ENTRY_FN "platform"
100 static struct dentry *platformnumber_debugfs_read;
101
102 #define CYCLES_BEFORE_WAIT_DEBUGFS_ENTRY_FN "cycles_before_wait"
103 static struct dentry *cycles_before_wait_debugfs_read;
104
105 #define SMART_WAKEUP_DEBUGFS_ENTRY_FN "smart_wakeup"
106 static struct dentry *smart_wakeup_debugfs_entry;
107
108 #define INFO_DEBUGFS_ENTRY_FN "info"
109 static struct dentry *info_debugfs_entry;
110
111 static unsigned long long cycles_before_wait, wait_cycles;
112
113 /*****************************************************/
114 /* local functions                                   */
115 /*****************************************************/
116
117 static ssize_t info_debugfs_read(struct file *file, char __user *buf,
118                               size_t len, loff_t *offset);
119 static const struct file_operations debugfs_info_fops = {
120         .read = info_debugfs_read,
121 };
122
123 static void
124 init_msg_header(CONTROLVM_MESSAGE *msg, u32 id, uint rsp, uint svr)
125 {
126         memset(msg, 0, sizeof(CONTROLVM_MESSAGE));
127         msg->hdr.Id = id;
128         msg->hdr.Flags.responseExpected = rsp;
129         msg->hdr.Flags.server = svr;
130 }
131
132 static __iomem void *
133 init_vbus_channel(u64 channelAddr, u32 channelBytes)
134 {
135         void __iomem *rc = NULL;
136         void __iomem *pChan = uislib_ioremap_cache(channelAddr, channelBytes);
137
138         if (!pChan) {
139                 LOGERR("CONTROLVM_BUS_CREATE error: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed",
140                      (unsigned long long) channelAddr,
141                      (unsigned long long) channelBytes);
142                 rc = NULL;
143                 goto Away;
144         }
145         if (!ULTRA_VBUS_CHANNEL_OK_CLIENT(pChan, NULL)) {
146                 ERRDRV("%s channel cannot be used", __func__);
147                 uislib_iounmap(pChan);
148                 rc = NULL;
149                 goto Away;
150         }
151         rc = pChan;
152 Away:
153         return rc;
154 }
155
156 static int
157 create_bus(CONTROLVM_MESSAGE *msg, char *buf)
158 {
159         u32 busNo, deviceCount;
160         struct bus_info *tmp, *bus;
161         size_t size;
162
163         if (MaxBusCount == BusListCount) {
164                 LOGERR("CONTROLVM_BUS_CREATE Failed: max buses:%d already created\n",
165                      MaxBusCount);
166                 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, MaxBusCount,
167                                  POSTCODE_SEVERITY_ERR);
168                 return CONTROLVM_RESP_ERROR_MAX_BUSES;
169         }
170
171         busNo = msg->cmd.createBus.busNo;
172         deviceCount = msg->cmd.createBus.deviceCount;
173
174         POSTCODE_LINUX_4(BUS_CREATE_ENTRY_PC, busNo, deviceCount,
175                          POSTCODE_SEVERITY_INFO);
176
177         size =
178             sizeof(struct bus_info) +
179             (deviceCount * sizeof(struct device_info *));
180         bus = kzalloc(size, GFP_ATOMIC);
181         if (!bus) {
182                 LOGERR("CONTROLVM_BUS_CREATE Failed: kmalloc for bus failed.\n");
183                 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, busNo,
184                                  POSTCODE_SEVERITY_ERR);
185                 return CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
186         }
187
188         /* Currently by default, the bus Number is the GuestHandle.
189          * Configure Bus message can override this.
190          */
191         if (msg->hdr.Flags.testMessage) {
192                 /* This implies we're the IOVM so set guest handle to 0... */
193                 bus->guestHandle = 0;
194                 bus->busNo = busNo;
195                 bus->localVnic = 1;
196         } else
197                 bus->busNo = bus->guestHandle = busNo;
198         sprintf(bus->name, "%d", (int) bus->busNo);
199         bus->deviceCount = deviceCount;
200         bus->device =
201             (struct device_info **) ((char *) bus + sizeof(struct bus_info));
202         bus->busInstGuid = msg->cmd.createBus.busInstGuid;
203         bus->busChannelBytes = 0;
204         bus->pBusChannel = NULL;
205
206         /* add bus to our bus list - but check for duplicates first */
207         read_lock(&BusListLock);
208         for (tmp = BusListHead; tmp; tmp = tmp->next) {
209                 if (tmp->busNo == bus->busNo)
210                         break;
211         }
212         read_unlock(&BusListLock);
213         if (tmp) {
214                 /* found a bus already in the list with same busNo -
215                  * reject add
216                  */
217                 LOGERR("CONTROLVM_BUS_CREATE Failed: bus %d already exists.\n",
218                        bus->busNo);
219                 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->busNo,
220                                  POSTCODE_SEVERITY_ERR);
221                 kfree(bus);
222                 return CONTROLVM_RESP_ERROR_ALREADY_DONE;
223         }
224         if ((msg->cmd.createBus.channelAddr != 0)
225             && (msg->cmd.createBus.channelBytes != 0)) {
226                 bus->busChannelBytes = msg->cmd.createBus.channelBytes;
227                 bus->pBusChannel =
228                     init_vbus_channel(msg->cmd.createBus.channelAddr,
229                                       msg->cmd.createBus.channelBytes);
230         }
231         /* the msg is bound for virtpci; send guest_msgs struct to callback */
232         if (!msg->hdr.Flags.server) {
233                 struct guest_msgs cmd;
234
235                 cmd.msgtype = GUEST_ADD_VBUS;
236                 cmd.add_vbus.busNo = busNo;
237                 cmd.add_vbus.chanptr = bus->pBusChannel;
238                 cmd.add_vbus.deviceCount = deviceCount;
239                 cmd.add_vbus.busTypeGuid = msg->cmd.createBus.busDataTypeGuid;
240                 cmd.add_vbus.busInstGuid = msg->cmd.createBus.busInstGuid;
241                 if (!VirtControlChanFunc) {
242                         LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci callback not registered.");
243                         POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->busNo,
244                                          POSTCODE_SEVERITY_ERR);
245                         kfree(bus);
246                         return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
247                 }
248                 if (!VirtControlChanFunc(&cmd)) {
249                         LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci GUEST_ADD_VBUS returned error.");
250                         POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->busNo,
251                                          POSTCODE_SEVERITY_ERR);
252                         kfree(bus);
253                         return
254                             CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
255                 }
256         }
257
258         /* add bus at the head of our list */
259         write_lock(&BusListLock);
260         if (!BusListHead)
261                 BusListHead = bus;
262         else {
263                 bus->next = BusListHead;
264                 BusListHead = bus;
265         }
266         BusListCount++;
267         write_unlock(&BusListLock);
268
269         POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus->busNo,
270                          POSTCODE_SEVERITY_INFO);
271         return CONTROLVM_RESP_SUCCESS;
272 }
273
274 static int
275 destroy_bus(CONTROLVM_MESSAGE *msg, char *buf)
276 {
277         int i;
278         struct bus_info *bus, *prev = NULL;
279         struct guest_msgs cmd;
280         u32 busNo;
281
282         busNo = msg->cmd.destroyBus.busNo;
283
284         read_lock(&BusListLock);
285
286         bus = BusListHead;
287         while (bus) {
288                 if (bus->busNo == busNo)
289                         break;
290                 prev = bus;
291                 bus = bus->next;
292         }
293
294         if (!bus) {
295                 LOGERR("CONTROLVM_BUS_DESTROY Failed: failed to find bus %d.\n",
296                        busNo);
297                 read_unlock(&BusListLock);
298                 return CONTROLVM_RESP_ERROR_ALREADY_DONE;
299         }
300
301         /* verify that this bus has no devices. */
302         for (i = 0; i < bus->deviceCount; i++) {
303                 if (bus->device[i] != NULL) {
304                         LOGERR("CONTROLVM_BUS_DESTROY Failed: device %i attached to bus %d.",
305                              i, busNo);
306                         read_unlock(&BusListLock);
307                         return CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED;
308                 }
309         }
310         read_unlock(&BusListLock);
311
312         if (msg->hdr.Flags.server)
313                 goto remove;
314
315         /* client messages require us to call the virtpci callback associated
316            with this bus. */
317         cmd.msgtype = GUEST_DEL_VBUS;
318         cmd.del_vbus.busNo = busNo;
319         if (!VirtControlChanFunc) {
320                 LOGERR("CONTROLVM_BUS_DESTROY Failed: virtpci callback not registered.");
321                 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
322         }
323         if (!VirtControlChanFunc(&cmd)) {
324                 LOGERR("CONTROLVM_BUS_DESTROY Failed: virtpci GUEST_DEL_VBUS returned error.");
325                 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
326         }
327
328         /* finally, remove the bus from the list */
329 remove:
330         write_lock(&BusListLock);
331         if (prev)       /* not at head */
332                 prev->next = bus->next;
333         else
334                 BusListHead = bus->next;
335         BusListCount--;
336         write_unlock(&BusListLock);
337
338         if (bus->pBusChannel) {
339                 uislib_iounmap(bus->pBusChannel);
340                 bus->pBusChannel = NULL;
341         }
342
343         kfree(bus);
344         return CONTROLVM_RESP_SUCCESS;
345 }
346
347 static int
348 create_device(CONTROLVM_MESSAGE *msg, char *buf)
349 {
350         struct device_info *dev;
351         struct bus_info *bus;
352         u32 busNo, devNo;
353         int result = CONTROLVM_RESP_SUCCESS;
354         u64 minSize = MIN_IO_CHANNEL_SIZE;
355         ReqHandlerInfo_t *pReqHandler;
356
357         busNo = msg->cmd.createDevice.busNo;
358         devNo = msg->cmd.createDevice.devNo;
359
360         POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, devNo, busNo,
361                          POSTCODE_SEVERITY_INFO);
362
363         dev = kzalloc(sizeof(struct device_info), GFP_ATOMIC);
364         if (!dev) {
365                 LOGERR("CONTROLVM_DEVICE_CREATE Failed: kmalloc for dev failed.\n");
366                 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo,
367                                  POSTCODE_SEVERITY_ERR);
368                 return CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
369         }
370
371         dev->channelTypeGuid = msg->cmd.createDevice.dataTypeGuid;
372         dev->intr = msg->cmd.createDevice.intr;
373         dev->channelAddr = msg->cmd.createDevice.channelAddr;
374         dev->busNo = busNo;
375         dev->devNo = devNo;
376         sema_init(&dev->interrupt_callback_lock, 1);    /* unlocked */
377         sprintf(dev->devid, "vbus%u:dev%u", (unsigned) busNo, (unsigned) devNo);
378         /* map the channel memory for the device. */
379         if (msg->hdr.Flags.testMessage)
380                 dev->chanptr = (void __iomem *)__va(dev->channelAddr);
381         else {
382                 pReqHandler = ReqHandlerFind(dev->channelTypeGuid);
383                 if (pReqHandler)
384                         /* generic service handler registered for this
385                          * channel
386                          */
387                         minSize = pReqHandler->min_channel_bytes;
388                 if (minSize > msg->cmd.createDevice.channelBytes) {
389                         LOGERR("CONTROLVM_DEVICE_CREATE Failed: channel size is too small, channel size:0x%lx, required size:0x%lx",
390                              (ulong) msg->cmd.createDevice.channelBytes,
391                              (ulong) minSize);
392                         POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo,
393                                          POSTCODE_SEVERITY_ERR);
394                         result = CONTROLVM_RESP_ERROR_CHANNEL_SIZE_TOO_SMALL;
395                         goto Away;
396                 }
397                 dev->chanptr =
398                     uislib_ioremap_cache(dev->channelAddr,
399                                          msg->cmd.createDevice.channelBytes);
400                 if (!dev->chanptr) {
401                         LOGERR("CONTROLVM_DEVICE_CREATE Failed: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed",
402                              dev->channelAddr,
403                              msg->cmd.createDevice.channelBytes);
404                         result = CONTROLVM_RESP_ERROR_IOREMAP_FAILED;
405                         POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo,
406                                          POSTCODE_SEVERITY_ERR);
407                         goto Away;
408                 }
409         }
410         dev->devInstGuid = msg->cmd.createDevice.devInstGuid;
411         dev->channelBytes = msg->cmd.createDevice.channelBytes;
412
413         read_lock(&BusListLock);
414         for (bus = BusListHead; bus; bus = bus->next) {
415                 if (bus->busNo == busNo) {
416                         /* make sure the device number is valid */
417                         if (devNo >= bus->deviceCount) {
418                                 LOGERR("CONTROLVM_DEVICE_CREATE Failed: device (%d) >= deviceCount (%d).",
419                                      devNo, bus->deviceCount);
420                                 result = CONTROLVM_RESP_ERROR_MAX_DEVICES;
421                                 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC,
422                                                  devNo, busNo,
423                                                  POSTCODE_SEVERITY_ERR);
424                                 read_unlock(&BusListLock);
425                                 goto Away;
426                         }
427                         /* make sure this device is not already set */
428                         if (bus->device[devNo]) {
429                                 LOGERR("CONTROLVM_DEVICE_CREATE Failed: device %d is already exists.",
430                                      devNo);
431                                 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC,
432                                                  devNo, busNo,
433                                                  POSTCODE_SEVERITY_ERR);
434                                 result = CONTROLVM_RESP_ERROR_ALREADY_DONE;
435                                 read_unlock(&BusListLock);
436                                 goto Away;
437                         }
438                         read_unlock(&BusListLock);
439                         /* the msg is bound for virtpci; send
440                          * guest_msgs struct to callback
441                          */
442                         if (!msg->hdr.Flags.server) {
443                                 struct guest_msgs cmd;
444
445                                 if (!uuid_le_cmp(dev->channelTypeGuid,
446                                      UltraVhbaChannelProtocolGuid)) {
447                                         wait_for_valid_guid(&((CHANNEL_HEADER
448                                                               __iomem *) (dev->
449                                                                   chanptr))->
450                                                             Type);
451                                         if (!ULTRA_VHBA_CHANNEL_OK_CLIENT
452                                             (dev->chanptr, NULL)) {
453                                                 LOGERR("CONTROLVM_DEVICE_CREATE Failed:[CLIENT]VHBA dev %d chan invalid.",
454                                                      devNo);
455                                                 POSTCODE_LINUX_4
456                                                     (DEVICE_CREATE_FAILURE_PC,
457                                                      devNo, busNo,
458                                                      POSTCODE_SEVERITY_ERR);
459                                                 result = CONTROLVM_RESP_ERROR_CHANNEL_INVALID;
460                                                 goto Away;
461                                         }
462                                         cmd.msgtype = GUEST_ADD_VHBA;
463                                         cmd.add_vhba.chanptr = dev->chanptr;
464                                         cmd.add_vhba.busNo = busNo;
465                                         cmd.add_vhba.deviceNo = devNo;
466                                         cmd.add_vhba.devInstGuid =
467                                             dev->devInstGuid;
468                                         cmd.add_vhba.intr = dev->intr;
469                                 } else
470                                     if (!uuid_le_cmp(dev->channelTypeGuid,
471                                          UltraVnicChannelProtocolGuid)) {
472                                         wait_for_valid_guid(&((CHANNEL_HEADER
473                                                               __iomem *) (dev->
474                                                                   chanptr))->
475                                                             Type);
476                                         if (!ULTRA_VNIC_CHANNEL_OK_CLIENT
477                                             (dev->chanptr, NULL)) {
478                                                 LOGERR("CONTROLVM_DEVICE_CREATE Failed: VNIC[CLIENT] dev %d chan invalid.",
479                                                      devNo);
480                                                 POSTCODE_LINUX_4
481                                                     (DEVICE_CREATE_FAILURE_PC,
482                                                      devNo, busNo,
483                                                      POSTCODE_SEVERITY_ERR);
484                                                 result = CONTROLVM_RESP_ERROR_CHANNEL_INVALID;
485                                                 goto Away;
486                                         }
487                                         cmd.msgtype = GUEST_ADD_VNIC;
488                                         cmd.add_vnic.chanptr = dev->chanptr;
489                                         cmd.add_vnic.busNo = busNo;
490                                         cmd.add_vnic.deviceNo = devNo;
491                                         cmd.add_vnic.devInstGuid =
492                                             dev->devInstGuid;
493                                         cmd.add_vhba.intr = dev->intr;
494                                 } else {
495                                         LOGERR("CONTROLVM_DEVICE_CREATE Failed: unknown channelTypeGuid.\n");
496                                         POSTCODE_LINUX_4
497                                             (DEVICE_CREATE_FAILURE_PC, devNo,
498                                              busNo, POSTCODE_SEVERITY_ERR);
499                                         result = CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN;
500                                         goto Away;
501                                 }
502
503                                 if (!VirtControlChanFunc) {
504                                         LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci callback not registered.");
505                                         POSTCODE_LINUX_4
506                                             (DEVICE_CREATE_FAILURE_PC, devNo,
507                                              busNo, POSTCODE_SEVERITY_ERR);
508                                         result = CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
509                                         goto Away;
510                                 }
511
512                                 if (!VirtControlChanFunc(&cmd)) {
513                                         LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci GUEST_ADD_[VHBA||VNIC] returned error.");
514                                         POSTCODE_LINUX_4
515                                             (DEVICE_CREATE_FAILURE_PC, devNo,
516                                              busNo, POSTCODE_SEVERITY_ERR);
517                                         result = CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
518                                         goto Away;
519                                 }
520                         }
521                         bus->device[devNo] = dev;
522                         POSTCODE_LINUX_4(DEVICE_CREATE_SUCCESS_PC, devNo, busNo,
523                                          POSTCODE_SEVERITY_INFO);
524                         return CONTROLVM_RESP_SUCCESS;
525                 }
526         }
527         read_unlock(&BusListLock);
528
529         LOGERR("CONTROLVM_DEVICE_CREATE Failed: failed to find bus %d.", busNo);
530         POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo,
531                          POSTCODE_SEVERITY_ERR);
532         result = CONTROLVM_RESP_ERROR_BUS_INVALID;
533
534 Away:
535         if (!msg->hdr.Flags.testMessage) {
536                 uislib_iounmap(dev->chanptr);
537                 dev->chanptr = NULL;
538         }
539
540         kfree(dev);
541         return result;
542 }
543
544 static int
545 pause_device(CONTROLVM_MESSAGE *msg)
546 {
547         u32 busNo, devNo;
548         struct bus_info *bus;
549         struct device_info *dev;
550         struct guest_msgs cmd;
551         int retval = CONTROLVM_RESP_SUCCESS;
552
553         busNo = msg->cmd.deviceChangeState.busNo;
554         devNo = msg->cmd.deviceChangeState.devNo;
555
556         read_lock(&BusListLock);
557         for (bus = BusListHead; bus; bus = bus->next) {
558                 if (bus->busNo == busNo) {
559                         /* make sure the device number is valid */
560                         if (devNo >= bus->deviceCount) {
561                                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device(%d) >= deviceCount(%d).",
562                                      devNo, bus->deviceCount);
563                                 retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID;
564                         } else {
565                                 /* make sure this device exists */
566                                 dev = bus->device[devNo];
567                                 if (!dev) {
568                                         LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device %d does not exist.",
569                                              devNo);
570                                         retval =
571                                           CONTROLVM_RESP_ERROR_ALREADY_DONE;
572                                 }
573                         }
574                         break;
575                 }
576         }
577         if (!bus) {
578                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: bus %d does not exist",
579                      busNo);
580                 retval = CONTROLVM_RESP_ERROR_BUS_INVALID;
581         }
582         read_unlock(&BusListLock);
583         if (retval == CONTROLVM_RESP_SUCCESS) {
584                 /* the msg is bound for virtpci; send
585                  * guest_msgs struct to callback
586                  */
587                 if (!uuid_le_cmp(dev->channelTypeGuid,
588                                 UltraVhbaChannelProtocolGuid)) {
589                         cmd.msgtype = GUEST_PAUSE_VHBA;
590                         cmd.pause_vhba.chanptr = dev->chanptr;
591                 } else if (!uuid_le_cmp(dev->channelTypeGuid,
592                                         UltraVnicChannelProtocolGuid)) {
593                         cmd.msgtype = GUEST_PAUSE_VNIC;
594                         cmd.pause_vnic.chanptr = dev->chanptr;
595                 } else {
596                         LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: unknown channelTypeGuid.\n");
597                         return CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN;
598                 }
599                 if (!VirtControlChanFunc) {
600                         LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: virtpci callback not registered.");
601                         return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
602                 }
603                 if (!VirtControlChanFunc(&cmd)) {
604                         LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: virtpci GUEST_PAUSE_[VHBA||VNIC] returned error.");
605                         return
606                           CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
607                 }
608         }
609         return retval;
610 }
611
612 static int
613 resume_device(CONTROLVM_MESSAGE *msg)
614 {
615         u32 busNo, devNo;
616         struct bus_info *bus;
617         struct device_info *dev;
618         struct guest_msgs cmd;
619         int retval = CONTROLVM_RESP_SUCCESS;
620
621         busNo = msg->cmd.deviceChangeState.busNo;
622         devNo = msg->cmd.deviceChangeState.devNo;
623
624         read_lock(&BusListLock);
625         for (bus = BusListHead; bus; bus = bus->next) {
626                 if (bus->busNo == busNo) {
627                         /* make sure the device number is valid */
628                         if (devNo >= bus->deviceCount) {
629                                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device(%d) >= deviceCount(%d).",
630                                      devNo, bus->deviceCount);
631                                 retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID;
632                         } else {
633                                 /* make sure this device exists */
634                                 dev = bus->device[devNo];
635                                 if (!dev) {
636                                         LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device %d does not exist.",
637                                              devNo);
638                                         retval =
639                                           CONTROLVM_RESP_ERROR_ALREADY_DONE;
640                                 }
641                         }
642                         break;
643                 }
644         }
645
646         if (!bus) {
647                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: bus %d does not exist",
648                      busNo);
649                 retval = CONTROLVM_RESP_ERROR_BUS_INVALID;
650         }
651         read_unlock(&BusListLock);
652         /* the msg is bound for virtpci; send
653          * guest_msgs struct to callback
654          */
655         if (retval == CONTROLVM_RESP_SUCCESS) {
656                 if (!uuid_le_cmp(dev->channelTypeGuid,
657                                  UltraVhbaChannelProtocolGuid)) {
658                         cmd.msgtype = GUEST_RESUME_VHBA;
659                         cmd.resume_vhba.chanptr = dev->chanptr;
660                 } else if (!uuid_le_cmp(dev->channelTypeGuid,
661                                         UltraVnicChannelProtocolGuid)) {
662                         cmd.msgtype = GUEST_RESUME_VNIC;
663                         cmd.resume_vnic.chanptr = dev->chanptr;
664                 } else {
665                         LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: unknown channelTypeGuid.\n");
666                         return CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN;
667                 }
668                 if (!VirtControlChanFunc) {
669                         LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: virtpci callback not registered.");
670                         return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
671                 }
672                 if (!VirtControlChanFunc(&cmd)) {
673                         LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: virtpci GUEST_RESUME_[VHBA||VNIC] returned error.");
674                         return
675                           CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
676                 }
677         }
678         return retval;
679 }
680
681 static int
682 destroy_device(CONTROLVM_MESSAGE *msg, char *buf)
683 {
684         u32 busNo, devNo;
685         struct bus_info *bus;
686         struct device_info *dev;
687         struct guest_msgs cmd;
688
689         busNo = msg->cmd.destroyDevice.busNo;
690         devNo = msg->cmd.destroyDevice.devNo;
691
692         read_lock(&BusListLock);
693         LOGINF("destroy_device called for busNo=%u, devNo=%u", busNo, devNo);
694         for (bus = BusListHead; bus; bus = bus->next) {
695                 if (bus->busNo == busNo) {
696                         /* make sure the device number is valid */
697                         if (devNo >= bus->deviceCount) {
698                                 LOGERR("CONTROLVM_DEVICE_DESTORY Failed: device(%d) >= deviceCount(%d).",
699                                      devNo, bus->deviceCount);
700                                 read_unlock(&BusListLock);
701                                 return CONTROLVM_RESP_ERROR_DEVICE_INVALID;
702                         }
703                         /* make sure this device exists */
704                         dev = bus->device[devNo];
705                         if (!dev) {
706                                 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: device %d does not exist.",
707                                      devNo);
708                                 read_unlock(&BusListLock);
709                                 return CONTROLVM_RESP_ERROR_ALREADY_DONE;
710                         }
711                         read_unlock(&BusListLock);
712                         /* the msg is bound for virtpci; send
713                          * guest_msgs struct to callback
714                          */
715                         if (!uuid_le_cmp(dev->channelTypeGuid,
716                                         UltraVhbaChannelProtocolGuid)) {
717                                 cmd.msgtype = GUEST_DEL_VHBA;
718                                 cmd.del_vhba.chanptr = dev->chanptr;
719                         } else
720                             if (!uuid_le_cmp(dev->channelTypeGuid,
721                                             UltraVnicChannelProtocolGuid)) {
722                                 cmd.msgtype = GUEST_DEL_VNIC;
723                                 cmd.del_vnic.chanptr = dev->chanptr;
724                         } else {
725                                 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: unknown channelTypeGuid.\n");
726                                 return
727                                     CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN;
728                         }
729
730                         if (!VirtControlChanFunc) {
731                                 LOGERR("CONTROLVM_DEVICE_DESTORY Failed: virtpci callback not registered.");
732                                 return
733                                     CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
734                         }
735
736                         if (!VirtControlChanFunc(&cmd)) {
737                                 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: virtpci GUEST_DEL_[VHBA||VNIC] returned error.");
738                                 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
739                         }
740 /* you must disable channel interrupts BEFORE you unmap the channel,
741  * because if you unmap first, there may still be some activity going
742  * on which accesses the channel and you will get a "unable to handle
743  * kernel paging request"
744  */
745                         if (dev->polling) {
746                                 LOGINF("calling uislib_disable_channel_interrupts");
747                                 uislib_disable_channel_interrupts(busNo, devNo);
748                         }
749                         /* unmap the channel memory for the device. */
750                         if (!msg->hdr.Flags.testMessage) {
751                                 LOGINF("destroy_device, doing iounmap");
752                                 uislib_iounmap(dev->chanptr);
753                         }
754                         kfree(dev);
755                         bus->device[devNo] = NULL;
756                         break;
757                 }
758         }
759
760         if (!bus) {
761                 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: bus %d does not exist",
762                        busNo);
763                 read_unlock(&BusListLock);
764                 return CONTROLVM_RESP_ERROR_BUS_INVALID;
765         }
766
767         return CONTROLVM_RESP_SUCCESS;
768 }
769
770 static int
771 init_chipset(CONTROLVM_MESSAGE *msg, char *buf)
772 {
773         POSTCODE_LINUX_2(CHIPSET_INIT_ENTRY_PC, POSTCODE_SEVERITY_INFO);
774
775         MaxBusCount = msg->cmd.initChipset.busCount;
776         PlatformNumber = msg->cmd.initChipset.platformNumber;
777         PhysicalDataChan = 0;
778
779         /* We need to make sure we have our functions registered
780         * before processing messages.  If we are a test vehicle the
781         * testMessage for init_chipset will be set.  We can ignore the
782         * waits for the callbacks, since this will be manually entered
783         * from a user.  If no testMessage is set, we will wait for the
784         * functions.
785         */
786         if (!msg->hdr.Flags.testMessage)
787                 WAIT_ON_CALLBACK(VirtControlChanFunc);
788
789         chipset_inited = 1;
790         POSTCODE_LINUX_2(CHIPSET_INIT_EXIT_PC, POSTCODE_SEVERITY_INFO);
791
792         return CONTROLVM_RESP_SUCCESS;
793 }
794
795 static int
796 delete_bus_glue(u32 busNo)
797 {
798         CONTROLVM_MESSAGE msg;
799
800         init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0);
801         msg.cmd.destroyBus.busNo = busNo;
802         if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
803                 LOGERR("destroy_bus failed. busNo=0x%x\n", busNo);
804                 return 0;
805         }
806         return 1;
807 }
808
809 static int
810 delete_device_glue(u32 busNo, u32 devNo)
811 {
812         CONTROLVM_MESSAGE msg;
813
814         init_msg_header(&msg, CONTROLVM_DEVICE_DESTROY, 0, 0);
815         msg.cmd.destroyDevice.busNo = busNo;
816         msg.cmd.destroyDevice.devNo = devNo;
817         if (destroy_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
818                 LOGERR("destroy_device failed. busNo=0x%x devNo=0x%x\n", busNo,
819                        devNo);
820                 return 0;
821         }
822         return 1;
823 }
824
825 int
826 uislib_client_inject_add_bus(u32 busNo, uuid_le instGuid,
827                              u64 channelAddr, ulong nChannelBytes)
828 {
829         CONTROLVM_MESSAGE msg;
830
831         LOGINF("enter busNo=0x%x\n", busNo);
832         /* step 0: init the chipset */
833         POSTCODE_LINUX_3(CHIPSET_INIT_ENTRY_PC, busNo, POSTCODE_SEVERITY_INFO);
834
835         if (!chipset_inited) {
836                 /* step: initialize the chipset */
837                 init_msg_header(&msg, CONTROLVM_CHIPSET_INIT, 0, 0);
838                 /* this change is needed so that console will come up
839                 * OK even when the bus 0 create comes in late.  If the
840                 * bus 0 create is the first create, then the add_vnic
841                 * will work fine, but if the bus 0 create arrives
842                 * after number 4, then the add_vnic will fail, and the
843                 * ultraboot will fail.
844                 */
845                 msg.cmd.initChipset.busCount = 23;
846                 msg.cmd.initChipset.switchCount = 0;
847                 if (init_chipset(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
848                         LOGERR("init_chipset failed.\n");
849                         return 0;
850                 }
851                 LOGINF("chipset initialized\n");
852                 POSTCODE_LINUX_3(CHIPSET_INIT_EXIT_PC, busNo,
853                                  POSTCODE_SEVERITY_INFO);
854         }
855
856         /* step 1: create a bus */
857         POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, busNo, POSTCODE_SEVERITY_WARNING);
858         init_msg_header(&msg, CONTROLVM_BUS_CREATE, 0, 0);
859         msg.cmd.createBus.busNo = busNo;
860         msg.cmd.createBus.deviceCount = 23;     /* devNo+1; */
861         msg.cmd.createBus.channelAddr = channelAddr;
862         msg.cmd.createBus.channelBytes = nChannelBytes;
863         if (create_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
864                 LOGERR("create_bus failed.\n");
865                 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, busNo,
866                                  POSTCODE_SEVERITY_ERR);
867                 return 0;
868         }
869         POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, busNo, POSTCODE_SEVERITY_INFO);
870
871         return 1;
872 }
873 EXPORT_SYMBOL_GPL(uislib_client_inject_add_bus);
874
875
876 int
877 uislib_client_inject_del_bus(u32 busNo)
878 {
879         return delete_bus_glue(busNo);
880 }
881 EXPORT_SYMBOL_GPL(uislib_client_inject_del_bus);
882
883 int
884 uislib_client_inject_pause_vhba(u32 busNo, u32 devNo)
885 {
886         CONTROLVM_MESSAGE msg;
887         int rc;
888
889         init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0);
890         msg.cmd.deviceChangeState.busNo = busNo;
891         msg.cmd.deviceChangeState.devNo = devNo;
892         msg.cmd.deviceChangeState.state = SegmentStateStandby;
893         rc = pause_device(&msg);
894         if (rc != CONTROLVM_RESP_SUCCESS) {
895                 LOGERR("VHBA pause_device failed. busNo=0x%x devNo=0x%x\n",
896                        busNo, devNo);
897                 return rc;
898         }
899         return 0;
900 }
901 EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vhba);
902
903 int
904 uislib_client_inject_resume_vhba(u32 busNo, u32 devNo)
905 {
906         CONTROLVM_MESSAGE msg;
907         int rc;
908
909         init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0);
910         msg.cmd.deviceChangeState.busNo = busNo;
911         msg.cmd.deviceChangeState.devNo = devNo;
912         msg.cmd.deviceChangeState.state = SegmentStateRunning;
913         rc = resume_device(&msg);
914         if (rc != CONTROLVM_RESP_SUCCESS) {
915                 LOGERR("VHBA resume_device failed. busNo=0x%x devNo=0x%x\n",
916                        busNo, devNo);
917                 return rc;
918         }
919         return 0;
920
921 }
922 EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vhba);
923
924 int
925 uislib_client_inject_add_vhba(u32 busNo, u32 devNo,
926                               u64 phys_chan_addr, u32 chan_bytes,
927                               int is_test_addr, uuid_le instGuid,
928                               struct InterruptInfo *intr)
929 {
930         CONTROLVM_MESSAGE msg;
931
932         LOGINF(" enter busNo=0x%x devNo=0x%x\n", busNo, devNo);
933         /* chipset init'ed with bus bus has been previously created -
934         * Verify it still exists step 2: create the VHBA device on the
935         * bus
936         */
937         POSTCODE_LINUX_4(VHBA_CREATE_ENTRY_PC, devNo, busNo,
938                          POSTCODE_SEVERITY_INFO);
939
940         init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, 0);
941         if (is_test_addr)
942                 /* signify that the physical channel address does NOT
943                  * need to be ioremap()ed
944                  */
945                 msg.hdr.Flags.testMessage = 1;
946         msg.cmd.createDevice.busNo = busNo;
947         msg.cmd.createDevice.devNo = devNo;
948         msg.cmd.createDevice.devInstGuid = instGuid;
949         if (intr)
950                 msg.cmd.createDevice.intr = *intr;
951         else
952                 memset(&msg.cmd.createDevice.intr, 0,
953                        sizeof(struct InterruptInfo));
954         msg.cmd.createDevice.channelAddr = phys_chan_addr;
955         if (chan_bytes < MIN_IO_CHANNEL_SIZE) {
956                 LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n",
957                      chan_bytes, (unsigned int) MIN_IO_CHANNEL_SIZE);
958                 POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC, chan_bytes,
959                                  MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR);
960                 return 0;
961         }
962         msg.cmd.createDevice.channelBytes = chan_bytes;
963         msg.cmd.createDevice.dataTypeGuid = UltraVhbaChannelProtocolGuid;
964         if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
965                 LOGERR("VHBA create_device failed.\n");
966                 POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC, devNo, busNo,
967                                  POSTCODE_SEVERITY_ERR);
968                 return 0;
969         }
970         POSTCODE_LINUX_4(VHBA_CREATE_SUCCESS_PC, devNo, busNo,
971                          POSTCODE_SEVERITY_INFO);
972         return 1;
973 }
974 EXPORT_SYMBOL_GPL(uislib_client_inject_add_vhba);
975
976 int
977 uislib_client_inject_del_vhba(u32 busNo, u32 devNo)
978 {
979         return delete_device_glue(busNo, devNo);
980 }
981 EXPORT_SYMBOL_GPL(uislib_client_inject_del_vhba);
982
983 int
984 uislib_client_inject_add_vnic(u32 busNo, u32 devNo,
985                               u64 phys_chan_addr, u32 chan_bytes,
986                               int is_test_addr, uuid_le instGuid,
987                               struct InterruptInfo *intr)
988 {
989         CONTROLVM_MESSAGE msg;
990
991         LOGINF(" enter busNo=0x%x devNo=0x%x\n", busNo, devNo);
992         /* chipset init'ed with bus bus has been previously created -
993         * Verify it still exists step 2: create the VNIC device on the
994         * bus
995         */
996         POSTCODE_LINUX_4(VNIC_CREATE_ENTRY_PC, devNo, busNo,
997                          POSTCODE_SEVERITY_INFO);
998
999         init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, 0);
1000         if (is_test_addr)
1001                 /* signify that the physical channel address does NOT
1002                  * need to be ioremap()ed
1003                  */
1004                 msg.hdr.Flags.testMessage = 1;
1005         msg.cmd.createDevice.busNo = busNo;
1006         msg.cmd.createDevice.devNo = devNo;
1007         msg.cmd.createDevice.devInstGuid = instGuid;
1008         if (intr)
1009                 msg.cmd.createDevice.intr = *intr;
1010         else
1011                 memset(&msg.cmd.createDevice.intr, 0,
1012                        sizeof(struct InterruptInfo));
1013         msg.cmd.createDevice.channelAddr = phys_chan_addr;
1014         if (chan_bytes < MIN_IO_CHANNEL_SIZE) {
1015                 LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n",
1016                      chan_bytes, (unsigned int) MIN_IO_CHANNEL_SIZE);
1017                 POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC, chan_bytes,
1018                                  MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR);
1019                 return 0;
1020         }
1021         msg.cmd.createDevice.channelBytes = chan_bytes;
1022         msg.cmd.createDevice.dataTypeGuid = UltraVnicChannelProtocolGuid;
1023         if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1024                 LOGERR("VNIC create_device failed.\n");
1025                 POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC, devNo, busNo,
1026                                  POSTCODE_SEVERITY_ERR);
1027                 return 0;
1028         }
1029
1030         POSTCODE_LINUX_4(VNIC_CREATE_SUCCESS_PC, devNo, busNo,
1031                          POSTCODE_SEVERITY_INFO);
1032         return 1;
1033 }
1034 EXPORT_SYMBOL_GPL(uislib_client_inject_add_vnic);
1035
1036 int
1037 uislib_client_inject_pause_vnic(u32 busNo, u32 devNo)
1038 {
1039         CONTROLVM_MESSAGE msg;
1040         int rc;
1041
1042         init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0);
1043         msg.cmd.deviceChangeState.busNo = busNo;
1044         msg.cmd.deviceChangeState.devNo = devNo;
1045         msg.cmd.deviceChangeState.state = SegmentStateStandby;
1046         rc = pause_device(&msg);
1047         if (rc != CONTROLVM_RESP_SUCCESS) {
1048                 LOGERR("VNIC pause_device failed. busNo=0x%x devNo=0x%x\n",
1049                        busNo, devNo);
1050                 return -1;
1051         }
1052         return 0;
1053 }
1054 EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vnic);
1055
1056 int
1057 uislib_client_inject_resume_vnic(u32 busNo, u32 devNo)
1058 {
1059         CONTROLVM_MESSAGE msg;
1060         int rc;
1061
1062         init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0);
1063         msg.cmd.deviceChangeState.busNo = busNo;
1064         msg.cmd.deviceChangeState.devNo = devNo;
1065         msg.cmd.deviceChangeState.state = SegmentStateRunning;
1066         rc = resume_device(&msg);
1067         if (rc != CONTROLVM_RESP_SUCCESS) {
1068                 LOGERR("VNIC resume_device failed. busNo=0x%x devNo=0x%x\n",
1069                        busNo, devNo);
1070                 return -1;
1071         }
1072         return 0;
1073
1074 }
1075 EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vnic);
1076
1077 int
1078 uislib_client_inject_del_vnic(u32 busNo, u32 devNo)
1079 {
1080         return delete_device_glue(busNo, devNo);
1081 }
1082 EXPORT_SYMBOL_GPL(uislib_client_inject_del_vnic);
1083
1084 static int
1085 uislib_client_add_vnic(u32 busNo)
1086 {
1087         BOOL busCreated = FALSE;
1088         int devNo = 0;          /* Default to 0, since only one device
1089                                  * will be created for this bus... */
1090         CONTROLVM_MESSAGE msg;
1091
1092         init_msg_header(&msg, CONTROLVM_BUS_CREATE, 0, 0);
1093         msg.hdr.Flags.testMessage = 1;
1094         msg.cmd.createBus.busNo = busNo;
1095         msg.cmd.createBus.deviceCount = 4;
1096         msg.cmd.createBus.channelAddr = 0;
1097         msg.cmd.createBus.channelBytes = 0;
1098         if (create_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1099                 LOGERR("client create_bus failed");
1100                 return 0;
1101         }
1102         busCreated = TRUE;
1103
1104         init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, 0);
1105         msg.hdr.Flags.testMessage = 1;
1106         msg.cmd.createDevice.busNo = busNo;
1107         msg.cmd.createDevice.devNo = devNo;
1108         msg.cmd.createDevice.devInstGuid = NULL_UUID_LE;
1109         memset(&msg.cmd.createDevice.intr, 0, sizeof(struct InterruptInfo));
1110         msg.cmd.createDevice.channelAddr = PhysicalDataChan;
1111         msg.cmd.createDevice.channelBytes = MIN_IO_CHANNEL_SIZE;
1112         msg.cmd.createDevice.dataTypeGuid = UltraVnicChannelProtocolGuid;
1113         if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1114                 LOGERR("client create_device failed");
1115                 goto AwayCleanup;
1116         }
1117
1118         return 1;
1119
1120 AwayCleanup:
1121         if (busCreated) {
1122                 init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0);
1123                 msg.hdr.Flags.testMessage = 1;
1124                 msg.cmd.destroyBus.busNo = busNo;
1125                 if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS)
1126                         LOGERR("client destroy_bus failed.\n");
1127         }
1128
1129         return 0;
1130 }                               /* end uislib_client_add_vnic */
1131 EXPORT_SYMBOL_GPL(uislib_client_add_vnic);
1132
1133 static int
1134 uislib_client_delete_vnic(u32 busNo)
1135 {
1136         int devNo = 0;          /* Default to 0, since only one device
1137                                  * will be created for this bus... */
1138         CONTROLVM_MESSAGE msg;
1139
1140         init_msg_header(&msg, CONTROLVM_DEVICE_DESTROY, 0, 0);
1141         msg.hdr.Flags.testMessage = 1;
1142         msg.cmd.destroyDevice.busNo = busNo;
1143         msg.cmd.destroyDevice.devNo = devNo;
1144         if (destroy_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1145                 /* Don't error exit - try to see if bus can be destroyed... */
1146                 LOGERR("client destroy_device failed.\n");
1147         }
1148
1149         init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0);
1150         msg.hdr.Flags.testMessage = 1;
1151         msg.cmd.destroyBus.busNo = busNo;
1152         if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS)
1153                 LOGERR("client destroy_bus failed.\n");
1154
1155         return 1;
1156 }
1157 EXPORT_SYMBOL_GPL(uislib_client_delete_vnic);
1158 /* end client_delete_vnic */
1159
1160 void *
1161 uislib_cache_alloc(struct kmem_cache *cur_pool, char *fn, int ln)
1162 {
1163         /* __GFP_NORETRY means "ok to fail", meaning kmalloc() can
1164         * return NULL.  If you do NOT specify __GFP_NORETRY, Linux
1165         * will go to extreme measures to get memory for you (like,
1166         * invoke oom killer), which will probably cripple the system.
1167         */
1168         void *p = kmem_cache_alloc(cur_pool, GFP_ATOMIC | __GFP_NORETRY);
1169
1170         if (p == NULL) {
1171                 LOGERR("uislib_malloc failed to alloc uiscmdrsp @%s:%d",
1172                        fn, ln);
1173                 return NULL;
1174         }
1175         return p;
1176 }
1177 EXPORT_SYMBOL_GPL(uislib_cache_alloc);
1178
1179 void
1180 uislib_cache_free(struct kmem_cache *cur_pool, void *p, char *fn, int ln)
1181 {
1182         if (p == NULL) {
1183                 LOGERR("uislib_free NULL pointer @%s:%d", fn, ln);
1184                 return;
1185         }
1186         kmem_cache_free(cur_pool, p);
1187 }
1188 EXPORT_SYMBOL_GPL(uislib_cache_free);
1189
1190 /*****************************************************/
1191 /* proc filesystem callback functions                */
1192 /*****************************************************/
1193
1194 #define PLINE(...) uisutil_add_proc_line_ex(&tot, buff, \
1195                                                buff_len, __VA_ARGS__)
1196
1197 static int
1198 info_debugfs_read_helper(char **buff, int *buff_len)
1199 {
1200         int i, tot = 0;
1201         struct bus_info *bus;
1202
1203         if (PLINE("\nBuses:\n") < 0)
1204                 goto err_done;
1205
1206         read_lock(&BusListLock);
1207         for (bus = BusListHead; bus; bus = bus->next) {
1208
1209                 if (PLINE("    bus=0x%p, busNo=%d, deviceCount=%d\n",
1210                           bus, bus->busNo, bus->deviceCount) < 0)
1211                         goto err_done_unlock;
1212
1213
1214                 if (PLINE("        Devices:\n") < 0)
1215                         goto err_done_unlock;
1216
1217                 for (i = 0; i < bus->deviceCount; i++) {
1218                         if (bus->device[i]) {
1219                                 if (PLINE("            busNo %d, device[%i]: 0x%p, chanptr=0x%p, swtch=0x%p\n",
1220                                           bus->busNo, i, bus->device[i],
1221                                           bus->device[i]->chanptr,
1222                                           bus->device[i]->swtch) < 0)
1223                                         goto err_done_unlock;
1224
1225                                 if (PLINE("            first_busy_cnt=%llu, moved_to_tail_cnt=%llu, last_on_list_cnt=%llu\n",
1226                                           bus->device[i]->first_busy_cnt,
1227                                           bus->device[i]->moved_to_tail_cnt,
1228                                           bus->device[i]->last_on_list_cnt) < 0)
1229                                         goto err_done_unlock;
1230                         }
1231                 }
1232         }
1233         read_unlock(&BusListLock);
1234
1235         if (PLINE("UisUtils_Registered_Services: %d\n",
1236                   atomic_read(&UisUtils_Registered_Services)) < 0)
1237                 goto err_done;
1238         if (PLINE("cycles_before_wait %llu wait_cycles:%llu\n",
1239                   cycles_before_wait, wait_cycles) < 0)
1240                         goto err_done;
1241         if (PLINE("tot_wakeup_cnt %llu:tot_wait_cnt %llu:tot_schedule_cnt %llu\n",
1242                   tot_wakeup_cnt, tot_wait_cnt, tot_schedule_cnt) < 0)
1243                         goto err_done;
1244         if (PLINE("en_smart_wakeup %d\n", en_smart_wakeup) < 0)
1245                         goto err_done;
1246         if (PLINE("tot_moved_to_tail_cnt %llu\n", tot_moved_to_tail_cnt) < 0)
1247                         goto err_done;
1248
1249         return tot;
1250
1251 err_done_unlock:
1252         read_unlock(&BusListLock);
1253 err_done:
1254         return -1;
1255 }
1256
1257 static ssize_t
1258 info_debugfs_read(struct file *file, char __user *buf,
1259                 size_t len, loff_t *offset)
1260 {
1261         char *temp;
1262         int totalBytes = 0;
1263         int remaining_bytes = PROC_READ_BUFFER_SIZE;
1264
1265 /* *start = buf; */
1266         if (ProcReadBuffer == NULL) {
1267                 DBGINF("ProcReadBuffer == NULL; allocating buffer.\n.");
1268                 ProcReadBuffer = vmalloc(PROC_READ_BUFFER_SIZE);
1269
1270                 if (ProcReadBuffer == NULL) {
1271                         LOGERR("failed to allocate buffer to provide proc data.\n");
1272                         return -ENOMEM;
1273                 }
1274         }
1275
1276         temp = ProcReadBuffer;
1277
1278         if ((*offset == 0) || (!ProcReadBufferValid)) {
1279                 DBGINF("calling info_debugfs_read_helper.\n");
1280                 /* if the read fails, then -1 will be returned */
1281                 totalBytes = info_debugfs_read_helper(&temp, &remaining_bytes);
1282                 ProcReadBufferValid = 1;
1283         } else
1284                 totalBytes = strlen(ProcReadBuffer);
1285
1286         return simple_read_from_buffer(buf, len, offset,
1287                                        ProcReadBuffer, totalBytes);
1288 }
1289
1290 static struct device_info *
1291 find_dev(u32 busNo, u32 devNo)
1292 {
1293         struct bus_info *bus;
1294         struct device_info *dev = NULL;
1295
1296         read_lock(&BusListLock);
1297         for (bus = BusListHead; bus; bus = bus->next) {
1298                 if (bus->busNo == busNo) {
1299                         /* make sure the device number is valid */
1300                         if (devNo >= bus->deviceCount) {
1301                                 LOGERR("%s bad busNo, devNo=%d,%d",
1302                                        __func__,
1303                                        (int) (busNo), (int) (devNo));
1304                                 goto Away;
1305                         }
1306                         dev = bus->device[devNo];
1307                         if (!dev)
1308                                 LOGERR("%s bad busNo, devNo=%d,%d",
1309                                        __func__,
1310                                        (int) (busNo), (int) (devNo));
1311                         goto Away;
1312                 }
1313         }
1314 Away:
1315         read_unlock(&BusListLock);
1316         return dev;
1317 }
1318
1319 /*  This thread calls the "interrupt" function for each device that has
1320  *  enabled such using uislib_enable_channel_interrupts().  The "interrupt"
1321  *  function typically reads and processes the devices's channel input
1322  *  queue.  This thread repeatedly does this, until the thread is told to stop
1323  *  (via uisthread_stop()).  Sleeping rules:
1324  *  - If we have called the "interrupt" function for all devices, and all of
1325  *    them have reported "nothing processed" (returned 0), then we will go to
1326  *    sleep for a maximum of POLLJIFFIES_NORMAL jiffies.
1327  *  - If anyone calls uislib_force_channel_interrupt(), the above jiffy
1328  *    sleep will be interrupted, and we will resume calling the "interrupt"
1329  *    function for all devices.
1330  *  - The list of devices is dynamically re-ordered in order to
1331  *    attempt to preserve fairness.  Whenever we spin thru the list of
1332  *    devices and call the dev->interrupt() function, if we find
1333  *    devices which report that there is still more work to do, the
1334  *    the first such device we find is moved to the end of the device
1335  *    list.  This ensures that extremely busy devices don't starve out
1336  *    less-busy ones.
1337  *
1338  */
1339 static int
1340 Process_Incoming(void *v)
1341 {
1342         unsigned long long cur_cycles, old_cycles, idle_cycles, delta_cycles;
1343         struct list_head *new_tail = NULL;
1344         int i;
1345
1346         UIS_DAEMONIZE("dev_incoming");
1347         for (i = 0; i < 16; i++) {
1348                 old_cycles = get_cycles();
1349                 wait_event_timeout(Wakeup_Polling_Device_Channels,
1350                                    0, POLLJIFFIES_NORMAL);
1351                 cur_cycles = get_cycles();
1352                 if (wait_cycles == 0) {
1353                         wait_cycles = (cur_cycles - old_cycles);
1354                 } else {
1355                         if (wait_cycles < (cur_cycles - old_cycles))
1356                                 wait_cycles = (cur_cycles - old_cycles);
1357                 }
1358         }
1359         LOGINF("wait_cycles=%llu", wait_cycles);
1360         cycles_before_wait = wait_cycles;
1361         idle_cycles = 0;
1362         Go_Polling_Device_Channels = 0;
1363         while (1) {
1364                 struct list_head *lelt, *tmp;
1365                 struct device_info *dev = NULL;
1366
1367                 /* poll each channel for input */
1368                 down(&Lock_Polling_Device_Channels);
1369                 new_tail = NULL;
1370                 list_for_each_safe(lelt, tmp, &List_Polling_Device_Channels) {
1371                         int rc = 0;
1372
1373                         dev = list_entry(lelt, struct device_info,
1374                                          list_polling_device_channels);
1375                         down(&dev->interrupt_callback_lock);
1376                         if (dev->interrupt)
1377                                 rc = dev->interrupt(dev->interrupt_context);
1378                         else
1379                                 continue;
1380                         up(&dev->interrupt_callback_lock);
1381                         if (rc) {
1382                                 /* dev->interrupt returned, but there
1383                                 * is still more work to do.
1384                                 * Reschedule work to occur as soon as
1385                                 * possible. */
1386                                 idle_cycles = 0;
1387                                 if (new_tail == NULL) {
1388                                         dev->first_busy_cnt++;
1389                                         if (!
1390                                             (list_is_last
1391                                              (lelt,
1392                                               &List_Polling_Device_Channels))) {
1393                                                 new_tail = lelt;
1394                                                 dev->moved_to_tail_cnt++;
1395                                         } else
1396                                                 dev->last_on_list_cnt++;
1397                                 }
1398
1399                         }
1400                         if (Incoming_ThreadInfo.should_stop)
1401                                 break;
1402                 }
1403                 if (new_tail != NULL) {
1404                         tot_moved_to_tail_cnt++;
1405                         list_move_tail(new_tail, &List_Polling_Device_Channels);
1406                 }
1407                 up(&Lock_Polling_Device_Channels);
1408                 cur_cycles = get_cycles();
1409                 delta_cycles = cur_cycles - old_cycles;
1410                 old_cycles = cur_cycles;
1411
1412                 /* At this point, we have scanned thru all of the
1413                 * channels, and at least one of the following is true:
1414                 * - there is no input waiting on any of the channels
1415                 * - we have received a signal to stop this thread
1416                 */
1417                 if (Incoming_ThreadInfo.should_stop)
1418                         break;
1419                 if (en_smart_wakeup == 0xFF) {
1420                         LOGINF("en_smart_wakeup set to 0xff, to force exiting process_incoming");
1421                         break;
1422                 }
1423                 /* wait for POLLJIFFIES_NORMAL jiffies, or until
1424                 * someone wakes up Wakeup_Polling_Device_Channels,
1425                 * whichever comes first only do a wait when we have
1426                 * been idle for cycles_before_wait cycles.
1427                 */
1428                 if (idle_cycles > cycles_before_wait) {
1429                         Go_Polling_Device_Channels = 0;
1430                         tot_wait_cnt++;
1431                         wait_event_timeout(Wakeup_Polling_Device_Channels,
1432                                            Go_Polling_Device_Channels,
1433                                            POLLJIFFIES_NORMAL);
1434                         Go_Polling_Device_Channels = 1;
1435                 } else {
1436                         tot_schedule_cnt++;
1437                         schedule();
1438                         idle_cycles = idle_cycles + delta_cycles;
1439                 }
1440         }
1441         DBGINF("exiting.\n");
1442         complete_and_exit(&Incoming_ThreadInfo.has_stopped, 0);
1443 }
1444
1445 static BOOL
1446 Initialize_incoming_thread(void)
1447 {
1448         if (Incoming_Thread_Started)
1449                 return TRUE;
1450         if (!uisthread_start(&Incoming_ThreadInfo,
1451                              &Process_Incoming, NULL, "dev_incoming")) {
1452                 LOGERR("uisthread_start Initialize_incoming_thread ****FAILED");
1453                 return FALSE;
1454         }
1455         Incoming_Thread_Started = TRUE;
1456         return TRUE;
1457 }
1458
1459 /*  Add a new device/channel to the list being processed by
1460  *  Process_Incoming().
1461  *  <interrupt> - indicates the function to call periodically.
1462  *  <interrupt_context> - indicates the data to pass to the <interrupt>
1463  *                        function.
1464  */
1465 void
1466 uislib_enable_channel_interrupts(u32 busNo, u32 devNo,
1467                                  int (*interrupt)(void *),
1468                                  void *interrupt_context)
1469 {
1470         struct device_info *dev;
1471
1472         dev = find_dev(busNo, devNo);
1473         if (!dev) {
1474                 LOGERR("%s busNo=%d, devNo=%d", __func__, (int) (busNo),
1475                        (int) (devNo));
1476                 return;
1477         }
1478         down(&Lock_Polling_Device_Channels);
1479         Initialize_incoming_thread();
1480         dev->interrupt = interrupt;
1481         dev->interrupt_context = interrupt_context;
1482         dev->polling = TRUE;
1483         list_add_tail(&(dev->list_polling_device_channels),
1484                       &List_Polling_Device_Channels);
1485         up(&Lock_Polling_Device_Channels);
1486 }
1487 EXPORT_SYMBOL_GPL(uislib_enable_channel_interrupts);
1488
1489 /*  Remove a device/channel from the list being processed by
1490  *  Process_Incoming().
1491  */
1492 void
1493 uislib_disable_channel_interrupts(u32 busNo, u32 devNo)
1494 {
1495         struct device_info *dev;
1496
1497         dev = find_dev(busNo, devNo);
1498         if (!dev) {
1499                 LOGERR("%s busNo=%d, devNo=%d", __func__, (int) (busNo),
1500                        (int) (devNo));
1501                 return;
1502         }
1503         down(&Lock_Polling_Device_Channels);
1504         list_del(&dev->list_polling_device_channels);
1505         dev->polling = FALSE;
1506         dev->interrupt = NULL;
1507         up(&Lock_Polling_Device_Channels);
1508 }
1509 EXPORT_SYMBOL_GPL(uislib_disable_channel_interrupts);
1510
1511 static void
1512 do_wakeup_polling_device_channels(struct work_struct *dummy)
1513 {
1514         if (!Go_Polling_Device_Channels) {
1515                 Go_Polling_Device_Channels = 1;
1516                 wake_up(&Wakeup_Polling_Device_Channels);
1517         }
1518 }
1519
1520 static DECLARE_WORK(Work_wakeup_polling_device_channels,
1521                     do_wakeup_polling_device_channels);
1522
1523 /*  Call this function when you want to send a hint to Process_Incoming() that
1524  *  your device might have more requests.
1525  */
1526 void
1527 uislib_force_channel_interrupt(u32 busNo, u32 devNo)
1528 {
1529         if (en_smart_wakeup == 0)
1530                 return;
1531         if (Go_Polling_Device_Channels)
1532                 return;
1533         /* The point of using schedule_work() instead of just doing
1534          * the work inline is to force a slight delay before waking up
1535          * the Process_Incoming() thread.
1536          */
1537         tot_wakeup_cnt++;
1538         schedule_work(&Work_wakeup_polling_device_channels);
1539 }
1540 EXPORT_SYMBOL_GPL(uislib_force_channel_interrupt);
1541
1542 /*****************************************************/
1543 /* Module Init & Exit functions                      */
1544 /*****************************************************/
1545
1546 static int __init
1547 uislib_mod_init(void)
1548 {
1549
1550         if (!unisys_spar_platform)
1551                 return -ENODEV;
1552
1553         LOGINF("MONITORAPIS");
1554
1555         LOGINF("sizeof(struct uiscmdrsp):%lu bytes\n",
1556                (ulong) sizeof(struct uiscmdrsp));
1557         LOGINF("sizeof(struct phys_info):%lu\n",
1558                (ulong) sizeof(struct phys_info));
1559         LOGINF("sizeof(uiscmdrsp_scsi):%lu\n",
1560                (ulong) sizeof(struct uiscmdrsp_scsi));
1561         LOGINF("sizeof(uiscmdrsp_net):%lu\n",
1562                (ulong) sizeof(struct uiscmdrsp_net));
1563         LOGINF("sizeof(CONTROLVM_MESSAGE):%lu bytes\n",
1564                (ulong) sizeof(CONTROLVM_MESSAGE));
1565         LOGINF("sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL):%lu bytes\n",
1566                (ulong) sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL));
1567         LOGINF("sizeof(CHANNEL_HEADER):%lu bytes\n",
1568                (ulong) sizeof(CHANNEL_HEADER));
1569         LOGINF("sizeof(ULTRA_IO_CHANNEL_PROTOCOL):%lu bytes\n",
1570                (ulong) sizeof(ULTRA_IO_CHANNEL_PROTOCOL));
1571         LOGINF("SIZEOF_CMDRSP:%lu bytes\n", SIZEOF_CMDRSP);
1572         LOGINF("SIZEOF_PROTOCOL:%lu bytes\n", SIZEOF_PROTOCOL);
1573
1574         /* initialize global pointers to NULL */
1575         BusListHead = NULL;
1576         BusListCount = MaxBusCount = 0;
1577         rwlock_init(&BusListLock);
1578         VirtControlChanFunc = NULL;
1579
1580         /* Issue VMCALL_GET_CONTROLVM_ADDR to get CtrlChanPhysAddr and
1581          * then map this physical address to a virtual address. */
1582         POSTCODE_LINUX_2(DRIVER_ENTRY_PC, POSTCODE_SEVERITY_INFO);
1583
1584         dir_debugfs = debugfs_create_dir(DIR_DEBUGFS_ENTRY, NULL);
1585         if (dir_debugfs) {
1586                 info_debugfs_entry = debugfs_create_file(
1587                         INFO_DEBUGFS_ENTRY_FN, 0444, dir_debugfs, NULL,
1588                         &debugfs_info_fops);
1589
1590                 platformnumber_debugfs_read = debugfs_create_u32(
1591                         PLATFORMNUMBER_DEBUGFS_ENTRY_FN, 0444, dir_debugfs,
1592                         &PlatformNumber);
1593
1594                 cycles_before_wait_debugfs_read = debugfs_create_u64(
1595                         CYCLES_BEFORE_WAIT_DEBUGFS_ENTRY_FN, 0666, dir_debugfs,
1596                         &cycles_before_wait);
1597
1598                 smart_wakeup_debugfs_entry = debugfs_create_bool(
1599                         SMART_WAKEUP_DEBUGFS_ENTRY_FN, 0666, dir_debugfs,
1600                         &en_smart_wakeup);
1601         }
1602
1603         POSTCODE_LINUX_3(DRIVER_EXIT_PC, 0, POSTCODE_SEVERITY_INFO);
1604         return 0;
1605 }
1606
1607 static void __exit
1608 uislib_mod_exit(void)
1609 {
1610         if (ProcReadBuffer) {
1611                 vfree(ProcReadBuffer);
1612                 ProcReadBuffer = NULL;
1613         }
1614
1615         debugfs_remove(info_debugfs_entry);
1616         debugfs_remove(smart_wakeup_debugfs_entry);
1617         debugfs_remove(cycles_before_wait_debugfs_read);
1618         debugfs_remove(platformnumber_debugfs_read);
1619         debugfs_remove(dir_debugfs);
1620
1621         DBGINF("goodbye.\n");
1622 }
1623
1624 module_init(uislib_mod_init);
1625 module_exit(uislib_mod_exit);
1626
1627 MODULE_LICENSE("GPL");
1628 MODULE_AUTHOR("Usha Srinivasan");
1629 MODULE_ALIAS("uislib");
1630   /* this is extracted during depmod and kept in modules.dep */