c4d6cae5aaf0d1cf9d05db7e0d8c5c330379eaed
[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
620         busNo = msg->cmd.deviceChangeState.busNo;
621         devNo = msg->cmd.deviceChangeState.devNo;
622
623         read_lock(&BusListLock);
624         for (bus = BusListHead; bus; bus = bus->next) {
625                 if (bus->busNo == busNo) {
626                         /* make sure the device number is valid */
627                         if (devNo >= bus->deviceCount) {
628                                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device(%d) >= deviceCount(%d).",
629                                      devNo, bus->deviceCount);
630                                 read_unlock(&BusListLock);
631                                 return CONTROLVM_RESP_ERROR_DEVICE_INVALID;
632                         }
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                                 read_unlock(&BusListLock);
639                                 return CONTROLVM_RESP_ERROR_ALREADY_DONE;
640                         }
641                         read_unlock(&BusListLock);
642                         /* the msg is bound for virtpci; send
643                          * guest_msgs struct to callback
644                          */
645                         if (!uuid_le_cmp(dev->channelTypeGuid,
646                                         UltraVhbaChannelProtocolGuid)) {
647                                 cmd.msgtype = GUEST_RESUME_VHBA;
648                                 cmd.resume_vhba.chanptr = dev->chanptr;
649                         } else
650                             if (!uuid_le_cmp(dev->channelTypeGuid,
651                                             UltraVnicChannelProtocolGuid)) {
652                                 cmd.msgtype = GUEST_RESUME_VNIC;
653                                 cmd.resume_vnic.chanptr = dev->chanptr;
654                         } else {
655                                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: unknown channelTypeGuid.\n");
656                                 return
657                                     CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN;
658                         }
659
660                         if (!VirtControlChanFunc) {
661                                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: virtpci callback not registered.");
662                                 return
663                                     CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
664                         }
665
666                         if (!VirtControlChanFunc(&cmd)) {
667                                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: virtpci GUEST_RESUME_[VHBA||VNIC] returned error.");
668                                 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
669                         }
670                         break;
671                 }
672         }
673
674         if (!bus) {
675                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: bus %d does not exist",
676                      busNo);
677                 read_unlock(&BusListLock);
678                 return CONTROLVM_RESP_ERROR_BUS_INVALID;
679         }
680
681         return CONTROLVM_RESP_SUCCESS;
682 }
683
684 static int
685 destroy_device(CONTROLVM_MESSAGE *msg, char *buf)
686 {
687         u32 busNo, devNo;
688         struct bus_info *bus;
689         struct device_info *dev;
690         struct guest_msgs cmd;
691
692         busNo = msg->cmd.destroyDevice.busNo;
693         devNo = msg->cmd.destroyDevice.devNo;
694
695         read_lock(&BusListLock);
696         LOGINF("destroy_device called for busNo=%u, devNo=%u", busNo, devNo);
697         for (bus = BusListHead; bus; bus = bus->next) {
698                 if (bus->busNo == busNo) {
699                         /* make sure the device number is valid */
700                         if (devNo >= bus->deviceCount) {
701                                 LOGERR("CONTROLVM_DEVICE_DESTORY Failed: device(%d) >= deviceCount(%d).",
702                                      devNo, bus->deviceCount);
703                                 read_unlock(&BusListLock);
704                                 return CONTROLVM_RESP_ERROR_DEVICE_INVALID;
705                         }
706                         /* make sure this device exists */
707                         dev = bus->device[devNo];
708                         if (!dev) {
709                                 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: device %d does not exist.",
710                                      devNo);
711                                 read_unlock(&BusListLock);
712                                 return CONTROLVM_RESP_ERROR_ALREADY_DONE;
713                         }
714                         read_unlock(&BusListLock);
715                         /* the msg is bound for virtpci; send
716                          * guest_msgs struct to callback
717                          */
718                         if (!uuid_le_cmp(dev->channelTypeGuid,
719                                         UltraVhbaChannelProtocolGuid)) {
720                                 cmd.msgtype = GUEST_DEL_VHBA;
721                                 cmd.del_vhba.chanptr = dev->chanptr;
722                         } else
723                             if (!uuid_le_cmp(dev->channelTypeGuid,
724                                             UltraVnicChannelProtocolGuid)) {
725                                 cmd.msgtype = GUEST_DEL_VNIC;
726                                 cmd.del_vnic.chanptr = dev->chanptr;
727                         } else {
728                                 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: unknown channelTypeGuid.\n");
729                                 return
730                                     CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN;
731                         }
732
733                         if (!VirtControlChanFunc) {
734                                 LOGERR("CONTROLVM_DEVICE_DESTORY Failed: virtpci callback not registered.");
735                                 return
736                                     CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
737                         }
738
739                         if (!VirtControlChanFunc(&cmd)) {
740                                 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: virtpci GUEST_DEL_[VHBA||VNIC] returned error.");
741                                 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
742                         }
743 /* you must disable channel interrupts BEFORE you unmap the channel,
744  * because if you unmap first, there may still be some activity going
745  * on which accesses the channel and you will get a "unable to handle
746  * kernel paging request"
747  */
748                         if (dev->polling) {
749                                 LOGINF("calling uislib_disable_channel_interrupts");
750                                 uislib_disable_channel_interrupts(busNo, devNo);
751                         }
752                         /* unmap the channel memory for the device. */
753                         if (!msg->hdr.Flags.testMessage) {
754                                 LOGINF("destroy_device, doing iounmap");
755                                 uislib_iounmap(dev->chanptr);
756                         }
757                         kfree(dev);
758                         bus->device[devNo] = NULL;
759                         break;
760                 }
761         }
762
763         if (!bus) {
764                 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: bus %d does not exist",
765                        busNo);
766                 read_unlock(&BusListLock);
767                 return CONTROLVM_RESP_ERROR_BUS_INVALID;
768         }
769
770         return CONTROLVM_RESP_SUCCESS;
771 }
772
773 static int
774 init_chipset(CONTROLVM_MESSAGE *msg, char *buf)
775 {
776         POSTCODE_LINUX_2(CHIPSET_INIT_ENTRY_PC, POSTCODE_SEVERITY_INFO);
777
778         MaxBusCount = msg->cmd.initChipset.busCount;
779         PlatformNumber = msg->cmd.initChipset.platformNumber;
780         PhysicalDataChan = 0;
781
782         /* We need to make sure we have our functions registered
783         * before processing messages.  If we are a test vehicle the
784         * testMessage for init_chipset will be set.  We can ignore the
785         * waits for the callbacks, since this will be manually entered
786         * from a user.  If no testMessage is set, we will wait for the
787         * functions.
788         */
789         if (!msg->hdr.Flags.testMessage)
790                 WAIT_ON_CALLBACK(VirtControlChanFunc);
791
792         chipset_inited = 1;
793         POSTCODE_LINUX_2(CHIPSET_INIT_EXIT_PC, POSTCODE_SEVERITY_INFO);
794
795         return CONTROLVM_RESP_SUCCESS;
796 }
797
798 static int
799 delete_bus_glue(u32 busNo)
800 {
801         CONTROLVM_MESSAGE msg;
802
803         init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0);
804         msg.cmd.destroyBus.busNo = busNo;
805         if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
806                 LOGERR("destroy_bus failed. busNo=0x%x\n", busNo);
807                 return 0;
808         }
809         return 1;
810 }
811
812 static int
813 delete_device_glue(u32 busNo, u32 devNo)
814 {
815         CONTROLVM_MESSAGE msg;
816
817         init_msg_header(&msg, CONTROLVM_DEVICE_DESTROY, 0, 0);
818         msg.cmd.destroyDevice.busNo = busNo;
819         msg.cmd.destroyDevice.devNo = devNo;
820         if (destroy_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
821                 LOGERR("destroy_device failed. busNo=0x%x devNo=0x%x\n", busNo,
822                        devNo);
823                 return 0;
824         }
825         return 1;
826 }
827
828 int
829 uislib_client_inject_add_bus(u32 busNo, uuid_le instGuid,
830                              u64 channelAddr, ulong nChannelBytes)
831 {
832         CONTROLVM_MESSAGE msg;
833
834         LOGINF("enter busNo=0x%x\n", busNo);
835         /* step 0: init the chipset */
836         POSTCODE_LINUX_3(CHIPSET_INIT_ENTRY_PC, busNo, POSTCODE_SEVERITY_INFO);
837
838         if (!chipset_inited) {
839                 /* step: initialize the chipset */
840                 init_msg_header(&msg, CONTROLVM_CHIPSET_INIT, 0, 0);
841                 /* this change is needed so that console will come up
842                 * OK even when the bus 0 create comes in late.  If the
843                 * bus 0 create is the first create, then the add_vnic
844                 * will work fine, but if the bus 0 create arrives
845                 * after number 4, then the add_vnic will fail, and the
846                 * ultraboot will fail.
847                 */
848                 msg.cmd.initChipset.busCount = 23;
849                 msg.cmd.initChipset.switchCount = 0;
850                 if (init_chipset(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
851                         LOGERR("init_chipset failed.\n");
852                         return 0;
853                 }
854                 LOGINF("chipset initialized\n");
855                 POSTCODE_LINUX_3(CHIPSET_INIT_EXIT_PC, busNo,
856                                  POSTCODE_SEVERITY_INFO);
857         }
858
859         /* step 1: create a bus */
860         POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, busNo, POSTCODE_SEVERITY_WARNING);
861         init_msg_header(&msg, CONTROLVM_BUS_CREATE, 0, 0);
862         msg.cmd.createBus.busNo = busNo;
863         msg.cmd.createBus.deviceCount = 23;     /* devNo+1; */
864         msg.cmd.createBus.channelAddr = channelAddr;
865         msg.cmd.createBus.channelBytes = nChannelBytes;
866         if (create_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
867                 LOGERR("create_bus failed.\n");
868                 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, busNo,
869                                  POSTCODE_SEVERITY_ERR);
870                 return 0;
871         }
872         POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, busNo, POSTCODE_SEVERITY_INFO);
873
874         return 1;
875 }
876 EXPORT_SYMBOL_GPL(uislib_client_inject_add_bus);
877
878
879 int
880 uislib_client_inject_del_bus(u32 busNo)
881 {
882         return delete_bus_glue(busNo);
883 }
884 EXPORT_SYMBOL_GPL(uislib_client_inject_del_bus);
885
886 int
887 uislib_client_inject_pause_vhba(u32 busNo, u32 devNo)
888 {
889         CONTROLVM_MESSAGE msg;
890         int rc;
891
892         init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0);
893         msg.cmd.deviceChangeState.busNo = busNo;
894         msg.cmd.deviceChangeState.devNo = devNo;
895         msg.cmd.deviceChangeState.state = SegmentStateStandby;
896         rc = pause_device(&msg);
897         if (rc != CONTROLVM_RESP_SUCCESS) {
898                 LOGERR("VHBA pause_device failed. busNo=0x%x devNo=0x%x\n",
899                        busNo, devNo);
900                 return rc;
901         }
902         return 0;
903 }
904 EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vhba);
905
906 int
907 uislib_client_inject_resume_vhba(u32 busNo, u32 devNo)
908 {
909         CONTROLVM_MESSAGE msg;
910         int rc;
911
912         init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0);
913         msg.cmd.deviceChangeState.busNo = busNo;
914         msg.cmd.deviceChangeState.devNo = devNo;
915         msg.cmd.deviceChangeState.state = SegmentStateRunning;
916         rc = resume_device(&msg);
917         if (rc != CONTROLVM_RESP_SUCCESS) {
918                 LOGERR("VHBA resume_device failed. busNo=0x%x devNo=0x%x\n",
919                        busNo, devNo);
920                 return rc;
921         }
922         return 0;
923
924 }
925 EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vhba);
926
927 int
928 uislib_client_inject_add_vhba(u32 busNo, u32 devNo,
929                               u64 phys_chan_addr, u32 chan_bytes,
930                               int is_test_addr, uuid_le instGuid,
931                               struct InterruptInfo *intr)
932 {
933         CONTROLVM_MESSAGE msg;
934
935         LOGINF(" enter busNo=0x%x devNo=0x%x\n", busNo, devNo);
936         /* chipset init'ed with bus bus has been previously created -
937         * Verify it still exists step 2: create the VHBA device on the
938         * bus
939         */
940         POSTCODE_LINUX_4(VHBA_CREATE_ENTRY_PC, devNo, busNo,
941                          POSTCODE_SEVERITY_INFO);
942
943         init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, 0);
944         if (is_test_addr)
945                 /* signify that the physical channel address does NOT
946                  * need to be ioremap()ed
947                  */
948                 msg.hdr.Flags.testMessage = 1;
949         msg.cmd.createDevice.busNo = busNo;
950         msg.cmd.createDevice.devNo = devNo;
951         msg.cmd.createDevice.devInstGuid = instGuid;
952         if (intr)
953                 msg.cmd.createDevice.intr = *intr;
954         else
955                 memset(&msg.cmd.createDevice.intr, 0,
956                        sizeof(struct InterruptInfo));
957         msg.cmd.createDevice.channelAddr = phys_chan_addr;
958         if (chan_bytes < MIN_IO_CHANNEL_SIZE) {
959                 LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n",
960                      chan_bytes, (unsigned int) MIN_IO_CHANNEL_SIZE);
961                 POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC, chan_bytes,
962                                  MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR);
963                 return 0;
964         }
965         msg.cmd.createDevice.channelBytes = chan_bytes;
966         msg.cmd.createDevice.dataTypeGuid = UltraVhbaChannelProtocolGuid;
967         if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
968                 LOGERR("VHBA create_device failed.\n");
969                 POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC, devNo, busNo,
970                                  POSTCODE_SEVERITY_ERR);
971                 return 0;
972         }
973         POSTCODE_LINUX_4(VHBA_CREATE_SUCCESS_PC, devNo, busNo,
974                          POSTCODE_SEVERITY_INFO);
975         return 1;
976 }
977 EXPORT_SYMBOL_GPL(uislib_client_inject_add_vhba);
978
979 int
980 uislib_client_inject_del_vhba(u32 busNo, u32 devNo)
981 {
982         return delete_device_glue(busNo, devNo);
983 }
984 EXPORT_SYMBOL_GPL(uislib_client_inject_del_vhba);
985
986 int
987 uislib_client_inject_add_vnic(u32 busNo, u32 devNo,
988                               u64 phys_chan_addr, u32 chan_bytes,
989                               int is_test_addr, uuid_le instGuid,
990                               struct InterruptInfo *intr)
991 {
992         CONTROLVM_MESSAGE msg;
993
994         LOGINF(" enter busNo=0x%x devNo=0x%x\n", busNo, devNo);
995         /* chipset init'ed with bus bus has been previously created -
996         * Verify it still exists step 2: create the VNIC device on the
997         * bus
998         */
999         POSTCODE_LINUX_4(VNIC_CREATE_ENTRY_PC, devNo, busNo,
1000                          POSTCODE_SEVERITY_INFO);
1001
1002         init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, 0);
1003         if (is_test_addr)
1004                 /* signify that the physical channel address does NOT
1005                  * need to be ioremap()ed
1006                  */
1007                 msg.hdr.Flags.testMessage = 1;
1008         msg.cmd.createDevice.busNo = busNo;
1009         msg.cmd.createDevice.devNo = devNo;
1010         msg.cmd.createDevice.devInstGuid = instGuid;
1011         if (intr)
1012                 msg.cmd.createDevice.intr = *intr;
1013         else
1014                 memset(&msg.cmd.createDevice.intr, 0,
1015                        sizeof(struct InterruptInfo));
1016         msg.cmd.createDevice.channelAddr = phys_chan_addr;
1017         if (chan_bytes < MIN_IO_CHANNEL_SIZE) {
1018                 LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n",
1019                      chan_bytes, (unsigned int) MIN_IO_CHANNEL_SIZE);
1020                 POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC, chan_bytes,
1021                                  MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR);
1022                 return 0;
1023         }
1024         msg.cmd.createDevice.channelBytes = chan_bytes;
1025         msg.cmd.createDevice.dataTypeGuid = UltraVnicChannelProtocolGuid;
1026         if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1027                 LOGERR("VNIC create_device failed.\n");
1028                 POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC, devNo, busNo,
1029                                  POSTCODE_SEVERITY_ERR);
1030                 return 0;
1031         }
1032
1033         POSTCODE_LINUX_4(VNIC_CREATE_SUCCESS_PC, devNo, busNo,
1034                          POSTCODE_SEVERITY_INFO);
1035         return 1;
1036 }
1037 EXPORT_SYMBOL_GPL(uislib_client_inject_add_vnic);
1038
1039 int
1040 uislib_client_inject_pause_vnic(u32 busNo, u32 devNo)
1041 {
1042         CONTROLVM_MESSAGE msg;
1043         int rc;
1044
1045         init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0);
1046         msg.cmd.deviceChangeState.busNo = busNo;
1047         msg.cmd.deviceChangeState.devNo = devNo;
1048         msg.cmd.deviceChangeState.state = SegmentStateStandby;
1049         rc = pause_device(&msg);
1050         if (rc != CONTROLVM_RESP_SUCCESS) {
1051                 LOGERR("VNIC pause_device failed. busNo=0x%x devNo=0x%x\n",
1052                        busNo, devNo);
1053                 return -1;
1054         }
1055         return 0;
1056 }
1057 EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vnic);
1058
1059 int
1060 uislib_client_inject_resume_vnic(u32 busNo, u32 devNo)
1061 {
1062         CONTROLVM_MESSAGE msg;
1063         int rc;
1064
1065         init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0);
1066         msg.cmd.deviceChangeState.busNo = busNo;
1067         msg.cmd.deviceChangeState.devNo = devNo;
1068         msg.cmd.deviceChangeState.state = SegmentStateRunning;
1069         rc = resume_device(&msg);
1070         if (rc != CONTROLVM_RESP_SUCCESS) {
1071                 LOGERR("VNIC resume_device failed. busNo=0x%x devNo=0x%x\n",
1072                        busNo, devNo);
1073                 return -1;
1074         }
1075         return 0;
1076
1077 }
1078 EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vnic);
1079
1080 int
1081 uislib_client_inject_del_vnic(u32 busNo, u32 devNo)
1082 {
1083         return delete_device_glue(busNo, devNo);
1084 }
1085 EXPORT_SYMBOL_GPL(uislib_client_inject_del_vnic);
1086
1087 static int
1088 uislib_client_add_vnic(u32 busNo)
1089 {
1090         BOOL busCreated = FALSE;
1091         int devNo = 0;          /* Default to 0, since only one device
1092                                  * will be created for this bus... */
1093         CONTROLVM_MESSAGE msg;
1094
1095         init_msg_header(&msg, CONTROLVM_BUS_CREATE, 0, 0);
1096         msg.hdr.Flags.testMessage = 1;
1097         msg.cmd.createBus.busNo = busNo;
1098         msg.cmd.createBus.deviceCount = 4;
1099         msg.cmd.createBus.channelAddr = 0;
1100         msg.cmd.createBus.channelBytes = 0;
1101         if (create_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1102                 LOGERR("client create_bus failed");
1103                 return 0;
1104         }
1105         busCreated = TRUE;
1106
1107         init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, 0);
1108         msg.hdr.Flags.testMessage = 1;
1109         msg.cmd.createDevice.busNo = busNo;
1110         msg.cmd.createDevice.devNo = devNo;
1111         msg.cmd.createDevice.devInstGuid = NULL_UUID_LE;
1112         memset(&msg.cmd.createDevice.intr, 0, sizeof(struct InterruptInfo));
1113         msg.cmd.createDevice.channelAddr = PhysicalDataChan;
1114         msg.cmd.createDevice.channelBytes = MIN_IO_CHANNEL_SIZE;
1115         msg.cmd.createDevice.dataTypeGuid = UltraVnicChannelProtocolGuid;
1116         if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1117                 LOGERR("client create_device failed");
1118                 goto AwayCleanup;
1119         }
1120
1121         return 1;
1122
1123 AwayCleanup:
1124         if (busCreated) {
1125                 init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0);
1126                 msg.hdr.Flags.testMessage = 1;
1127                 msg.cmd.destroyBus.busNo = busNo;
1128                 if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS)
1129                         LOGERR("client destroy_bus failed.\n");
1130         }
1131
1132         return 0;
1133 }                               /* end uislib_client_add_vnic */
1134 EXPORT_SYMBOL_GPL(uislib_client_add_vnic);
1135
1136 static int
1137 uislib_client_delete_vnic(u32 busNo)
1138 {
1139         int devNo = 0;          /* Default to 0, since only one device
1140                                  * will be created for this bus... */
1141         CONTROLVM_MESSAGE msg;
1142
1143         init_msg_header(&msg, CONTROLVM_DEVICE_DESTROY, 0, 0);
1144         msg.hdr.Flags.testMessage = 1;
1145         msg.cmd.destroyDevice.busNo = busNo;
1146         msg.cmd.destroyDevice.devNo = devNo;
1147         if (destroy_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1148                 /* Don't error exit - try to see if bus can be destroyed... */
1149                 LOGERR("client destroy_device failed.\n");
1150         }
1151
1152         init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0);
1153         msg.hdr.Flags.testMessage = 1;
1154         msg.cmd.destroyBus.busNo = busNo;
1155         if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS)
1156                 LOGERR("client destroy_bus failed.\n");
1157
1158         return 1;
1159 }
1160 EXPORT_SYMBOL_GPL(uislib_client_delete_vnic);
1161 /* end client_delete_vnic */
1162
1163 void *
1164 uislib_cache_alloc(struct kmem_cache *cur_pool, char *fn, int ln)
1165 {
1166         /* __GFP_NORETRY means "ok to fail", meaning kmalloc() can
1167         * return NULL.  If you do NOT specify __GFP_NORETRY, Linux
1168         * will go to extreme measures to get memory for you (like,
1169         * invoke oom killer), which will probably cripple the system.
1170         */
1171         void *p = kmem_cache_alloc(cur_pool, GFP_ATOMIC | __GFP_NORETRY);
1172
1173         if (p == NULL) {
1174                 LOGERR("uislib_malloc failed to alloc uiscmdrsp @%s:%d",
1175                        fn, ln);
1176                 return NULL;
1177         }
1178         return p;
1179 }
1180 EXPORT_SYMBOL_GPL(uislib_cache_alloc);
1181
1182 void
1183 uislib_cache_free(struct kmem_cache *cur_pool, void *p, char *fn, int ln)
1184 {
1185         if (p == NULL) {
1186                 LOGERR("uislib_free NULL pointer @%s:%d", fn, ln);
1187                 return;
1188         }
1189         kmem_cache_free(cur_pool, p);
1190 }
1191 EXPORT_SYMBOL_GPL(uislib_cache_free);
1192
1193 /*****************************************************/
1194 /* proc filesystem callback functions                */
1195 /*****************************************************/
1196
1197 #define PLINE(...) uisutil_add_proc_line_ex(&tot, buff, \
1198                                                buff_len, __VA_ARGS__)
1199
1200 static int
1201 info_debugfs_read_helper(char **buff, int *buff_len)
1202 {
1203         int i, tot = 0;
1204         struct bus_info *bus;
1205
1206         if (PLINE("\nBuses:\n") < 0)
1207                 goto err_done;
1208
1209         read_lock(&BusListLock);
1210         for (bus = BusListHead; bus; bus = bus->next) {
1211
1212                 if (PLINE("    bus=0x%p, busNo=%d, deviceCount=%d\n",
1213                           bus, bus->busNo, bus->deviceCount) < 0)
1214                         goto err_done_unlock;
1215
1216
1217                 if (PLINE("        Devices:\n") < 0)
1218                         goto err_done_unlock;
1219
1220                 for (i = 0; i < bus->deviceCount; i++) {
1221                         if (bus->device[i]) {
1222                                 if (PLINE("            busNo %d, device[%i]: 0x%p, chanptr=0x%p, swtch=0x%p\n",
1223                                           bus->busNo, i, bus->device[i],
1224                                           bus->device[i]->chanptr,
1225                                           bus->device[i]->swtch) < 0)
1226                                         goto err_done_unlock;
1227
1228                                 if (PLINE("            first_busy_cnt=%llu, moved_to_tail_cnt=%llu, last_on_list_cnt=%llu\n",
1229                                           bus->device[i]->first_busy_cnt,
1230                                           bus->device[i]->moved_to_tail_cnt,
1231                                           bus->device[i]->last_on_list_cnt) < 0)
1232                                         goto err_done_unlock;
1233                         }
1234                 }
1235         }
1236         read_unlock(&BusListLock);
1237
1238         if (PLINE("UisUtils_Registered_Services: %d\n",
1239                   atomic_read(&UisUtils_Registered_Services)) < 0)
1240                 goto err_done;
1241         if (PLINE("cycles_before_wait %llu wait_cycles:%llu\n",
1242                   cycles_before_wait, wait_cycles) < 0)
1243                         goto err_done;
1244         if (PLINE("tot_wakeup_cnt %llu:tot_wait_cnt %llu:tot_schedule_cnt %llu\n",
1245                   tot_wakeup_cnt, tot_wait_cnt, tot_schedule_cnt) < 0)
1246                         goto err_done;
1247         if (PLINE("en_smart_wakeup %d\n", en_smart_wakeup) < 0)
1248                         goto err_done;
1249         if (PLINE("tot_moved_to_tail_cnt %llu\n", tot_moved_to_tail_cnt) < 0)
1250                         goto err_done;
1251
1252         return tot;
1253
1254 err_done_unlock:
1255         read_unlock(&BusListLock);
1256 err_done:
1257         return -1;
1258 }
1259
1260 static ssize_t
1261 info_debugfs_read(struct file *file, char __user *buf,
1262                 size_t len, loff_t *offset)
1263 {
1264         char *temp;
1265         int totalBytes = 0;
1266         int remaining_bytes = PROC_READ_BUFFER_SIZE;
1267
1268 /* *start = buf; */
1269         if (ProcReadBuffer == NULL) {
1270                 DBGINF("ProcReadBuffer == NULL; allocating buffer.\n.");
1271                 ProcReadBuffer = vmalloc(PROC_READ_BUFFER_SIZE);
1272
1273                 if (ProcReadBuffer == NULL) {
1274                         LOGERR("failed to allocate buffer to provide proc data.\n");
1275                         return -ENOMEM;
1276                 }
1277         }
1278
1279         temp = ProcReadBuffer;
1280
1281         if ((*offset == 0) || (!ProcReadBufferValid)) {
1282                 DBGINF("calling info_debugfs_read_helper.\n");
1283                 /* if the read fails, then -1 will be returned */
1284                 totalBytes = info_debugfs_read_helper(&temp, &remaining_bytes);
1285                 ProcReadBufferValid = 1;
1286         } else
1287                 totalBytes = strlen(ProcReadBuffer);
1288
1289         return simple_read_from_buffer(buf, len, offset,
1290                                        ProcReadBuffer, totalBytes);
1291 }
1292
1293 static struct device_info *
1294 find_dev(u32 busNo, u32 devNo)
1295 {
1296         struct bus_info *bus;
1297         struct device_info *dev = NULL;
1298
1299         read_lock(&BusListLock);
1300         for (bus = BusListHead; bus; bus = bus->next) {
1301                 if (bus->busNo == busNo) {
1302                         /* make sure the device number is valid */
1303                         if (devNo >= bus->deviceCount) {
1304                                 LOGERR("%s bad busNo, devNo=%d,%d",
1305                                        __func__,
1306                                        (int) (busNo), (int) (devNo));
1307                                 goto Away;
1308                         }
1309                         dev = bus->device[devNo];
1310                         if (!dev)
1311                                 LOGERR("%s bad busNo, devNo=%d,%d",
1312                                        __func__,
1313                                        (int) (busNo), (int) (devNo));
1314                         goto Away;
1315                 }
1316         }
1317 Away:
1318         read_unlock(&BusListLock);
1319         return dev;
1320 }
1321
1322 /*  This thread calls the "interrupt" function for each device that has
1323  *  enabled such using uislib_enable_channel_interrupts().  The "interrupt"
1324  *  function typically reads and processes the devices's channel input
1325  *  queue.  This thread repeatedly does this, until the thread is told to stop
1326  *  (via uisthread_stop()).  Sleeping rules:
1327  *  - If we have called the "interrupt" function for all devices, and all of
1328  *    them have reported "nothing processed" (returned 0), then we will go to
1329  *    sleep for a maximum of POLLJIFFIES_NORMAL jiffies.
1330  *  - If anyone calls uislib_force_channel_interrupt(), the above jiffy
1331  *    sleep will be interrupted, and we will resume calling the "interrupt"
1332  *    function for all devices.
1333  *  - The list of devices is dynamically re-ordered in order to
1334  *    attempt to preserve fairness.  Whenever we spin thru the list of
1335  *    devices and call the dev->interrupt() function, if we find
1336  *    devices which report that there is still more work to do, the
1337  *    the first such device we find is moved to the end of the device
1338  *    list.  This ensures that extremely busy devices don't starve out
1339  *    less-busy ones.
1340  *
1341  */
1342 static int
1343 Process_Incoming(void *v)
1344 {
1345         unsigned long long cur_cycles, old_cycles, idle_cycles, delta_cycles;
1346         struct list_head *new_tail = NULL;
1347         int i;
1348
1349         UIS_DAEMONIZE("dev_incoming");
1350         for (i = 0; i < 16; i++) {
1351                 old_cycles = get_cycles();
1352                 wait_event_timeout(Wakeup_Polling_Device_Channels,
1353                                    0, POLLJIFFIES_NORMAL);
1354                 cur_cycles = get_cycles();
1355                 if (wait_cycles == 0) {
1356                         wait_cycles = (cur_cycles - old_cycles);
1357                 } else {
1358                         if (wait_cycles < (cur_cycles - old_cycles))
1359                                 wait_cycles = (cur_cycles - old_cycles);
1360                 }
1361         }
1362         LOGINF("wait_cycles=%llu", wait_cycles);
1363         cycles_before_wait = wait_cycles;
1364         idle_cycles = 0;
1365         Go_Polling_Device_Channels = 0;
1366         while (1) {
1367                 struct list_head *lelt, *tmp;
1368                 struct device_info *dev = NULL;
1369
1370                 /* poll each channel for input */
1371                 down(&Lock_Polling_Device_Channels);
1372                 new_tail = NULL;
1373                 list_for_each_safe(lelt, tmp, &List_Polling_Device_Channels) {
1374                         int rc = 0;
1375
1376                         dev = list_entry(lelt, struct device_info,
1377                                          list_polling_device_channels);
1378                         down(&dev->interrupt_callback_lock);
1379                         if (dev->interrupt)
1380                                 rc = dev->interrupt(dev->interrupt_context);
1381                         else
1382                                 continue;
1383                         up(&dev->interrupt_callback_lock);
1384                         if (rc) {
1385                                 /* dev->interrupt returned, but there
1386                                 * is still more work to do.
1387                                 * Reschedule work to occur as soon as
1388                                 * possible. */
1389                                 idle_cycles = 0;
1390                                 if (new_tail == NULL) {
1391                                         dev->first_busy_cnt++;
1392                                         if (!
1393                                             (list_is_last
1394                                              (lelt,
1395                                               &List_Polling_Device_Channels))) {
1396                                                 new_tail = lelt;
1397                                                 dev->moved_to_tail_cnt++;
1398                                         } else
1399                                                 dev->last_on_list_cnt++;
1400                                 }
1401
1402                         }
1403                         if (Incoming_ThreadInfo.should_stop)
1404                                 break;
1405                 }
1406                 if (new_tail != NULL) {
1407                         tot_moved_to_tail_cnt++;
1408                         list_move_tail(new_tail, &List_Polling_Device_Channels);
1409                 }
1410                 up(&Lock_Polling_Device_Channels);
1411                 cur_cycles = get_cycles();
1412                 delta_cycles = cur_cycles - old_cycles;
1413                 old_cycles = cur_cycles;
1414
1415                 /* At this point, we have scanned thru all of the
1416                 * channels, and at least one of the following is true:
1417                 * - there is no input waiting on any of the channels
1418                 * - we have received a signal to stop this thread
1419                 */
1420                 if (Incoming_ThreadInfo.should_stop)
1421                         break;
1422                 if (en_smart_wakeup == 0xFF) {
1423                         LOGINF("en_smart_wakeup set to 0xff, to force exiting process_incoming");
1424                         break;
1425                 }
1426                 /* wait for POLLJIFFIES_NORMAL jiffies, or until
1427                 * someone wakes up Wakeup_Polling_Device_Channels,
1428                 * whichever comes first only do a wait when we have
1429                 * been idle for cycles_before_wait cycles.
1430                 */
1431                 if (idle_cycles > cycles_before_wait) {
1432                         Go_Polling_Device_Channels = 0;
1433                         tot_wait_cnt++;
1434                         wait_event_timeout(Wakeup_Polling_Device_Channels,
1435                                            Go_Polling_Device_Channels,
1436                                            POLLJIFFIES_NORMAL);
1437                         Go_Polling_Device_Channels = 1;
1438                 } else {
1439                         tot_schedule_cnt++;
1440                         schedule();
1441                         idle_cycles = idle_cycles + delta_cycles;
1442                 }
1443         }
1444         DBGINF("exiting.\n");
1445         complete_and_exit(&Incoming_ThreadInfo.has_stopped, 0);
1446 }
1447
1448 static BOOL
1449 Initialize_incoming_thread(void)
1450 {
1451         if (Incoming_Thread_Started)
1452                 return TRUE;
1453         if (!uisthread_start(&Incoming_ThreadInfo,
1454                              &Process_Incoming, NULL, "dev_incoming")) {
1455                 LOGERR("uisthread_start Initialize_incoming_thread ****FAILED");
1456                 return FALSE;
1457         }
1458         Incoming_Thread_Started = TRUE;
1459         return TRUE;
1460 }
1461
1462 /*  Add a new device/channel to the list being processed by
1463  *  Process_Incoming().
1464  *  <interrupt> - indicates the function to call periodically.
1465  *  <interrupt_context> - indicates the data to pass to the <interrupt>
1466  *                        function.
1467  */
1468 void
1469 uislib_enable_channel_interrupts(u32 busNo, u32 devNo,
1470                                  int (*interrupt)(void *),
1471                                  void *interrupt_context)
1472 {
1473         struct device_info *dev;
1474
1475         dev = find_dev(busNo, devNo);
1476         if (!dev) {
1477                 LOGERR("%s busNo=%d, devNo=%d", __func__, (int) (busNo),
1478                        (int) (devNo));
1479                 return;
1480         }
1481         down(&Lock_Polling_Device_Channels);
1482         Initialize_incoming_thread();
1483         dev->interrupt = interrupt;
1484         dev->interrupt_context = interrupt_context;
1485         dev->polling = TRUE;
1486         list_add_tail(&(dev->list_polling_device_channels),
1487                       &List_Polling_Device_Channels);
1488         up(&Lock_Polling_Device_Channels);
1489 }
1490 EXPORT_SYMBOL_GPL(uislib_enable_channel_interrupts);
1491
1492 /*  Remove a device/channel from the list being processed by
1493  *  Process_Incoming().
1494  */
1495 void
1496 uislib_disable_channel_interrupts(u32 busNo, u32 devNo)
1497 {
1498         struct device_info *dev;
1499
1500         dev = find_dev(busNo, devNo);
1501         if (!dev) {
1502                 LOGERR("%s busNo=%d, devNo=%d", __func__, (int) (busNo),
1503                        (int) (devNo));
1504                 return;
1505         }
1506         down(&Lock_Polling_Device_Channels);
1507         list_del(&dev->list_polling_device_channels);
1508         dev->polling = FALSE;
1509         dev->interrupt = NULL;
1510         up(&Lock_Polling_Device_Channels);
1511 }
1512 EXPORT_SYMBOL_GPL(uislib_disable_channel_interrupts);
1513
1514 static void
1515 do_wakeup_polling_device_channels(struct work_struct *dummy)
1516 {
1517         if (!Go_Polling_Device_Channels) {
1518                 Go_Polling_Device_Channels = 1;
1519                 wake_up(&Wakeup_Polling_Device_Channels);
1520         }
1521 }
1522
1523 static DECLARE_WORK(Work_wakeup_polling_device_channels,
1524                     do_wakeup_polling_device_channels);
1525
1526 /*  Call this function when you want to send a hint to Process_Incoming() that
1527  *  your device might have more requests.
1528  */
1529 void
1530 uislib_force_channel_interrupt(u32 busNo, u32 devNo)
1531 {
1532         if (en_smart_wakeup == 0)
1533                 return;
1534         if (Go_Polling_Device_Channels)
1535                 return;
1536         /* The point of using schedule_work() instead of just doing
1537          * the work inline is to force a slight delay before waking up
1538          * the Process_Incoming() thread.
1539          */
1540         tot_wakeup_cnt++;
1541         schedule_work(&Work_wakeup_polling_device_channels);
1542 }
1543 EXPORT_SYMBOL_GPL(uislib_force_channel_interrupt);
1544
1545 /*****************************************************/
1546 /* Module Init & Exit functions                      */
1547 /*****************************************************/
1548
1549 static int __init
1550 uislib_mod_init(void)
1551 {
1552
1553         if (!unisys_spar_platform)
1554                 return -ENODEV;
1555
1556         LOGINF("MONITORAPIS");
1557
1558         LOGINF("sizeof(struct uiscmdrsp):%lu bytes\n",
1559                (ulong) sizeof(struct uiscmdrsp));
1560         LOGINF("sizeof(struct phys_info):%lu\n",
1561                (ulong) sizeof(struct phys_info));
1562         LOGINF("sizeof(uiscmdrsp_scsi):%lu\n",
1563                (ulong) sizeof(struct uiscmdrsp_scsi));
1564         LOGINF("sizeof(uiscmdrsp_net):%lu\n",
1565                (ulong) sizeof(struct uiscmdrsp_net));
1566         LOGINF("sizeof(CONTROLVM_MESSAGE):%lu bytes\n",
1567                (ulong) sizeof(CONTROLVM_MESSAGE));
1568         LOGINF("sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL):%lu bytes\n",
1569                (ulong) sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL));
1570         LOGINF("sizeof(CHANNEL_HEADER):%lu bytes\n",
1571                (ulong) sizeof(CHANNEL_HEADER));
1572         LOGINF("sizeof(ULTRA_IO_CHANNEL_PROTOCOL):%lu bytes\n",
1573                (ulong) sizeof(ULTRA_IO_CHANNEL_PROTOCOL));
1574         LOGINF("SIZEOF_CMDRSP:%lu bytes\n", SIZEOF_CMDRSP);
1575         LOGINF("SIZEOF_PROTOCOL:%lu bytes\n", SIZEOF_PROTOCOL);
1576
1577         /* initialize global pointers to NULL */
1578         BusListHead = NULL;
1579         BusListCount = MaxBusCount = 0;
1580         rwlock_init(&BusListLock);
1581         VirtControlChanFunc = NULL;
1582
1583         /* Issue VMCALL_GET_CONTROLVM_ADDR to get CtrlChanPhysAddr and
1584          * then map this physical address to a virtual address. */
1585         POSTCODE_LINUX_2(DRIVER_ENTRY_PC, POSTCODE_SEVERITY_INFO);
1586
1587         dir_debugfs = debugfs_create_dir(DIR_DEBUGFS_ENTRY, NULL);
1588         if (dir_debugfs) {
1589                 info_debugfs_entry = debugfs_create_file(
1590                         INFO_DEBUGFS_ENTRY_FN, 0444, dir_debugfs, NULL,
1591                         &debugfs_info_fops);
1592
1593                 platformnumber_debugfs_read = debugfs_create_u32(
1594                         PLATFORMNUMBER_DEBUGFS_ENTRY_FN, 0444, dir_debugfs,
1595                         &PlatformNumber);
1596
1597                 cycles_before_wait_debugfs_read = debugfs_create_u64(
1598                         CYCLES_BEFORE_WAIT_DEBUGFS_ENTRY_FN, 0666, dir_debugfs,
1599                         &cycles_before_wait);
1600
1601                 smart_wakeup_debugfs_entry = debugfs_create_bool(
1602                         SMART_WAKEUP_DEBUGFS_ENTRY_FN, 0666, dir_debugfs,
1603                         &en_smart_wakeup);
1604         }
1605
1606         POSTCODE_LINUX_3(DRIVER_EXIT_PC, 0, POSTCODE_SEVERITY_INFO);
1607         return 0;
1608 }
1609
1610 static void __exit
1611 uislib_mod_exit(void)
1612 {
1613         if (ProcReadBuffer) {
1614                 vfree(ProcReadBuffer);
1615                 ProcReadBuffer = NULL;
1616         }
1617
1618         debugfs_remove(info_debugfs_entry);
1619         debugfs_remove(smart_wakeup_debugfs_entry);
1620         debugfs_remove(cycles_before_wait_debugfs_read);
1621         debugfs_remove(platformnumber_debugfs_read);
1622         debugfs_remove(dir_debugfs);
1623
1624         DBGINF("goodbye.\n");
1625 }
1626
1627 module_init(uislib_mod_init);
1628 module_exit(uislib_mod_exit);
1629
1630 MODULE_LICENSE("GPL");
1631 MODULE_AUTHOR("Usha Srinivasan");
1632 MODULE_ALIAS("uislib");
1633   /* this is extracted during depmod and kept in modules.dep */