]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/unisys/uislib/uislib.c
Merge remote-tracking branch 'asoc/topic/dt' into asoc-next
[karo-tx-linux.git] / drivers / staging / unisys / uislib / uislib.c
1 /* uislib.c
2  *
3  * Copyright � 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
27 #include "commontypes.h"
28
29 #include <linux/version.h>
30 #include "uniklog.h"
31 #include "diagnostics/appos_subsystems.h"
32 #include "uisutils.h"
33 #include "vbuschannel.h"
34
35 #include <linux/proc_fs.h>
36 #include <linux/uaccess.h>      /* for copy_from_user */
37 #include <linux/ctype.h>        /* for toupper */
38 #include <linux/list.h>
39
40 #include "sparstop.h"
41 #include "visorchipset.h"
42 #include "chanstub.h"
43 #include "version.h"
44 #include "guestlinuxdebug.h"
45
46 #define SET_PROC_OWNER(x, y)
47
48 #define UISLIB_TEST_PROC
49 #define POLLJIFFIES_NORMAL 1
50 /* Choose whether or not you want to wakeup the request-polling thread
51  * after an IO termination:
52  * this is shorter than using __FILE__ (full path name) in
53  * debug/info/error messages
54  */
55 #define CURRENT_FILE_PC UISLIB_PC_uislib_c
56 #define __MYFILE__ "uislib.c"
57
58 /* global function pointers that act as callback functions into virtpcimod */
59 int (*VirtControlChanFunc)(struct guest_msgs *);
60
61 static int ProcReadBufferValid;
62 static char *ProcReadBuffer;    /* Note this MUST be global,
63                                          * because the contents must */
64 static unsigned int chipset_inited;
65
66 #define WAIT_ON_CALLBACK(handle)        \
67         do {                    \
68                 if (handle)             \
69                         break;          \
70                 UIS_THREAD_WAIT;        \
71         } while (1)
72
73 static struct bus_info *BusListHead;
74 static rwlock_t BusListLock;
75 static int BusListCount;        /* number of buses in the list */
76 static int MaxBusCount;         /* maximum number of buses expected */
77 static U64 PhysicalDataChan;
78 static int PlatformNumber;
79
80 static struct uisthread_info Incoming_ThreadInfo;
81 static BOOL Incoming_Thread_Started = FALSE;
82 static LIST_HEAD(List_Polling_Device_Channels);
83 static unsigned long long tot_moved_to_tail_cnt;
84 static unsigned long long tot_wait_cnt;
85 static unsigned long long tot_wakeup_cnt;
86 static unsigned long long tot_schedule_cnt;
87 static int en_smart_wakeup = 1;
88 static DEFINE_SEMAPHORE(Lock_Polling_Device_Channels);  /* unlocked */
89 static DECLARE_WAIT_QUEUE_HEAD(Wakeup_Polling_Device_Channels);
90 static int Go_Polling_Device_Channels;
91
92 static struct proc_dir_entry *uislib_proc_dir;
93 static struct proc_dir_entry *uislib_proc_vbus_dir;
94 static struct proc_dir_entry *vnic_proc_entry;  /* Used to be "datachan" */
95 static struct proc_dir_entry *ctrlchan_proc_entry;
96 static struct proc_dir_entry *pmem_proc_entry;
97 static struct proc_dir_entry *info_proc_entry;
98 static struct proc_dir_entry *switch_proc_entry;
99 static struct proc_dir_entry *extport_proc_entry;
100 static struct proc_dir_entry *platformnumber_proc_entry;
101 static struct proc_dir_entry *bus_proc_entry;
102 static struct proc_dir_entry *dev_proc_entry;
103 static struct proc_dir_entry *chipset_proc_entry;
104 static struct proc_dir_entry *cycles_before_wait_proc_entry;
105 static struct proc_dir_entry *reset_counts_proc_entry;
106 static struct proc_dir_entry *smart_wakeup_proc_entry;
107 static struct proc_dir_entry *disable_proc_entry;
108
109 #define DIR_PROC_ENTRY "uislib"
110 #define DIR_VBUS_PROC_ENTRY "vbus"
111 #define VNIC_PROC_ENTRY_FN "vnic"       /* Used to be "datachan" */
112 #define CTRLCHAN_PROC_ENTRY_FN "ctrlchan"
113 #define PMEM_PROC_ENTRY_FN "phys_to_virt"
114 #define INFO_PROC_ENTRY_FN "info"
115 #define SWITCH_PROC_ENTRY_FN "switch"
116 #define SWITCH_COUNT_PROC_ENTRY_FN "switch_count"
117 #define EXTPORT_PROC_ENTRY_FN "extport"
118 #define PLATFORMNUMBER_PROC_ENTRY_FN "platform"
119 #define BUS_PROC_ENTRY_FN "bus"
120 #define DEV_PROC_ENTRY_FN "device"
121 #define CHIPSET_PROC_ENTRY_FN "chipset"
122 #define CYCLES_BEFORE_WAIT_PROC_ENTRY_FN "cycles_before_wait"
123 #define RESET_COUNTS_PROC_ENTRY_FN "reset_counts"
124 #define SMART_WAKEUP_PROC_ENTRY_FN "smart_wakeup"
125 #define CALLHOME_PROC_ENTRY_FN "callhome"
126 #define CALLHOME_THROTTLED_PROC_ENTRY_FN "callhome_throttled"
127 #define DISABLE_PROC_ENTRY_FN "switch_state"
128 #ifdef UISLIB_TEST_PROC
129 static struct proc_dir_entry *test_proc_entry;
130 #define TEST_PROC_ENTRY_FN "test"
131 #endif
132 static unsigned long long cycles_before_wait, wait_cycles;
133
134 /*****************************************************/
135 /* local functions                                   */
136 /*****************************************************/
137
138 static int proc_info_vbus_show(struct seq_file *m, void *v);
139 static int
140 proc_info_vbus_open(struct inode *inode, struct file *filp)
141 {
142         /* proc_info_vbus_show will grab this from seq_file.private: */
143         struct bus_info *bus = PDE_DATA(inode);
144         return single_open(filp, proc_info_vbus_show, bus);
145 }
146
147 static const struct file_operations proc_info_vbus_fops = {
148         .open = proc_info_vbus_open,
149         .read = seq_read,
150         .llseek = seq_lseek,
151         .release = single_release,
152 };
153
154 static ssize_t uislib_proc_read_writeonly(struct file *file,
155                                           char __user *buffer,
156                                           size_t count, loff_t *ppos);
157
158 static ssize_t vnic_proc_write(struct file *file, const char __user *buffer,
159                                size_t count, loff_t *ppos);
160
161 static const struct file_operations proc_vnic_fops = {
162         .read = uislib_proc_read_writeonly,
163         .write = vnic_proc_write,
164 };
165
166 static ssize_t chipset_proc_write(struct file *file, const char __user *buffer,
167                                   size_t count, loff_t *ppos);
168
169 static const struct file_operations proc_chipset_fops = {
170         .read = uislib_proc_read_writeonly,
171         .write = chipset_proc_write,
172 };
173
174 static ssize_t info_proc_read(struct file *file, char __user *buf,
175                               size_t len, loff_t *offset);
176 static const struct file_operations proc_info_fops = {
177         .read = info_proc_read,
178 };
179
180 static ssize_t platformnumber_proc_read(struct file *file, char __user *buf,
181                                         size_t len, loff_t *offset);
182 static const struct file_operations proc_platformnumber_fops = {
183         .read = platformnumber_proc_read,
184 };
185
186 static ssize_t cycles_before_wait_proc_write(struct file *file,
187                                              const char __user *buffer,
188                                              size_t count, loff_t *ppos);
189 static const struct file_operations proc_cycles_before_wait_fops = {
190         .read = uislib_proc_read_writeonly,
191         .write = cycles_before_wait_proc_write,
192 };
193
194 static ssize_t reset_counts_proc_write(struct file *file,
195                                        const char __user *buffer,
196                                        size_t count, loff_t *ppos);
197 static const struct file_operations proc_reset_counts_fops = {
198         .read = uislib_proc_read_writeonly,
199         .write = reset_counts_proc_write,
200 };
201
202 static ssize_t smart_wakeup_proc_write(struct file *file,
203                                        const char __user *buffer,
204                                        size_t count, loff_t *ppos);
205 static const struct file_operations proc_smart_wakeup_fops = {
206         .read = uislib_proc_read_writeonly,
207         .write = smart_wakeup_proc_write,
208 };
209
210 static ssize_t test_proc_write(struct file *file,
211                                const char __user *buffer,
212                                size_t count, loff_t *ppos);
213 static const struct file_operations proc_test_fops = {
214         .read = uislib_proc_read_writeonly,
215         .write = test_proc_write,
216 };
217
218 static ssize_t bus_proc_write(struct file *file,
219                               const char __user *buffer,
220                               size_t count, loff_t *ppos);
221 static const struct file_operations proc_bus_fops = {
222         .read = uislib_proc_read_writeonly,
223         .write = bus_proc_write,
224 };
225
226 static ssize_t dev_proc_write(struct file *file,
227                               const char __user *buffer,
228                               size_t count, loff_t *ppos);
229 static const struct file_operations proc_dev_fops = {
230         .read = uislib_proc_read_writeonly,
231         .write = dev_proc_write,
232 };
233
234 static void
235 init_msg_header(CONTROLVM_MESSAGE *msg, U32 id, uint rsp, uint svr)
236 {
237         memset(msg, 0, sizeof(CONTROLVM_MESSAGE));
238         msg->hdr.Id = id;
239         msg->hdr.Flags.responseExpected = rsp;
240         msg->hdr.Flags.server = svr;
241 }
242
243 static void
244 create_bus_proc_entries(struct bus_info *bus)
245 {
246         bus->proc_dir = proc_mkdir(bus->name, uislib_proc_vbus_dir);
247         if (!bus->proc_dir) {
248                 LOGERR("failed to create /proc/uislib/vbus/%s directory",
249                        bus->name);
250                 return;
251         }
252         bus->proc_info = proc_create_data("info", 0, bus->proc_dir,
253                                           &proc_info_vbus_fops, bus);
254         if (!bus->proc_info) {
255                 LOGERR("failed to create /proc/uislib/vbus/%s/info", bus->name);
256                 remove_proc_entry(bus->name, uislib_proc_vbus_dir);
257                 bus->proc_dir = NULL;
258                 return;
259         }
260         SET_PROC_OWNER(bus->proc_info, THIS_MODULE);
261
262 }
263
264 static __iomem void *
265 init_vbus_channel(U64 channelAddr, U32 channelBytes, int isServer)
266 {
267         void *rc = NULL;
268         void __iomem *pChan = uislib_ioremap_cache(channelAddr, channelBytes);
269         if (!pChan) {
270                 LOGERR("CONTROLVM_BUS_CREATE error: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed",
271                      (unsigned long long) channelAddr,
272                      (unsigned long long) channelBytes);
273                 rc = NULL;
274                 goto Away;
275         }
276         if (isServer) {
277                 memset_io(pChan, 0, channelBytes);
278                 if (!ULTRA_VBUS_CHANNEL_OK_SERVER(channelBytes, NULL)) {
279                         ERRDRV("%s channel cannot be used", __func__);
280                         uislib_iounmap(pChan);
281                         rc = NULL;
282                         goto Away;
283                 }
284                 ULTRA_VBUS_init_channel(pChan, channelBytes);
285         } else {
286                 if (!ULTRA_VBUS_CHANNEL_OK_CLIENT(pChan, NULL)) {
287                         ERRDRV("%s channel cannot be used", __func__);
288                         uislib_iounmap(pChan);
289                         rc = NULL;
290                         goto Away;
291                 }
292         }
293         rc = pChan;
294 Away:
295         return rc;
296 }
297
298 static int
299 create_bus(CONTROLVM_MESSAGE *msg, char *buf)
300 {
301         U32 busNo, deviceCount;
302         struct bus_info *tmp, *bus;
303         size_t size;
304
305         if (MaxBusCount == BusListCount) {
306                 LOGERR("CONTROLVM_BUS_CREATE Failed: max buses:%d already created\n",
307                      MaxBusCount);
308                 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, MaxBusCount,
309                                  POSTCODE_SEVERITY_ERR);
310                 return CONTROLVM_RESP_ERROR_MAX_BUSES;
311         }
312
313         busNo = msg->cmd.createBus.busNo;
314         deviceCount = msg->cmd.createBus.deviceCount;
315
316         POSTCODE_LINUX_4(BUS_CREATE_ENTRY_PC, busNo, deviceCount,
317                          POSTCODE_SEVERITY_INFO);
318
319         size =
320             sizeof(struct bus_info) +
321             (deviceCount * sizeof(struct device_info *));
322         bus = kzalloc(size, GFP_ATOMIC);
323         if (!bus) {
324                 LOGERR("CONTROLVM_BUS_CREATE Failed: kmalloc for bus failed.\n");
325                 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, busNo,
326                                  POSTCODE_SEVERITY_ERR);
327                 return CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
328         }
329
330         /* Currently by default, the bus Number is the GuestHandle.
331          * Configure Bus message can override this.
332          */
333         if (msg->hdr.Flags.testMessage) {
334                 /* This implies we're the IOVM so set guest handle to 0... */
335                 bus->guestHandle = 0;
336                 bus->busNo = busNo;
337                 bus->localVnic = 1;
338         } else
339                 bus->busNo = bus->guestHandle = busNo;
340         sprintf(bus->name, "%d", (int) bus->busNo);
341         bus->deviceCount = deviceCount;
342         bus->device =
343             (struct device_info **) ((char *) bus + sizeof(struct bus_info));
344         bus->busInstGuid = msg->cmd.createBus.busInstGuid;
345         bus->busChannelBytes = 0;
346         bus->pBusChannel = NULL;
347
348         /* add bus to our bus list - but check for duplicates first */
349         read_lock(&BusListLock);
350         for (tmp = BusListHead; tmp; tmp = tmp->next) {
351                 if (tmp->busNo == bus->busNo)
352                         break;
353         }
354         read_unlock(&BusListLock);
355         if (tmp) {
356                 /* found a bus already in the list with same busNo -
357                  * reject add
358                  */
359                 LOGERR("CONTROLVM_BUS_CREATE Failed: bus %d already exists.\n",
360                        bus->busNo);
361                 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->busNo,
362                                  POSTCODE_SEVERITY_ERR);
363                 kfree(bus);
364                 return CONTROLVM_RESP_ERROR_ALREADY_DONE;
365         }
366         if ((msg->cmd.createBus.channelAddr != 0)
367             && (msg->cmd.createBus.channelBytes != 0)) {
368                 bus->busChannelBytes = msg->cmd.createBus.channelBytes;
369                 bus->pBusChannel =
370                     init_vbus_channel(msg->cmd.createBus.channelAddr,
371                                       msg->cmd.createBus.channelBytes,
372                                       msg->hdr.Flags.server);
373         }
374         /* the msg is bound for virtpci; send guest_msgs struct to callback */
375         if (!msg->hdr.Flags.server) {
376                 struct guest_msgs cmd;
377                 cmd.msgtype = GUEST_ADD_VBUS;
378                 cmd.add_vbus.busNo = busNo;
379                 cmd.add_vbus.chanptr = bus->pBusChannel;
380                 cmd.add_vbus.deviceCount = deviceCount;
381                 cmd.add_vbus.busTypeGuid = msg->cmd.createBus.busDataTypeGuid;
382                 cmd.add_vbus.busInstGuid = msg->cmd.createBus.busInstGuid;
383                 if (!VirtControlChanFunc) {
384                         LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci callback not registered.");
385                         POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->busNo,
386                                          POSTCODE_SEVERITY_ERR);
387                         kfree(bus);
388                         return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
389                 }
390                 if (!VirtControlChanFunc(&cmd)) {
391                         LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci GUEST_ADD_VBUS returned error.");
392                         POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->busNo,
393                                          POSTCODE_SEVERITY_ERR);
394                         kfree(bus);
395                         return
396                             CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
397                 }
398         }
399         create_bus_proc_entries(bus);
400
401         /* add bus at the head of our list */
402         write_lock(&BusListLock);
403         if (!BusListHead)
404                 BusListHead = bus;
405         else {
406                 bus->next = BusListHead;
407                 BusListHead = bus;
408         }
409         BusListCount++;
410         write_unlock(&BusListLock);
411
412         POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus->busNo,
413                          POSTCODE_SEVERITY_INFO);
414         return CONTROLVM_RESP_SUCCESS;
415 }
416
417 static int
418 destroy_bus(CONTROLVM_MESSAGE *msg, char *buf)
419 {
420         int i;
421         struct bus_info *bus, *prev = NULL;
422         U32 busNo;
423
424         busNo = msg->cmd.destroyBus.busNo;
425
426         /* find and delete the bus */
427         read_lock(&BusListLock);
428         for (bus = BusListHead; bus; prev = bus, bus = bus->next) {
429                 if (bus->busNo == busNo) {
430                         /* found the bus - ensure that all device
431                          * slots are NULL
432                          */
433                         for (i = 0; i < bus->deviceCount; i++) {
434                                 if (bus->device[i] != NULL) {
435                                         LOGERR("CONTROLVM_BUS_DESTROY Failed: device %i attached to bus %d.",
436                                              i, busNo);
437                                         read_unlock(&BusListLock);
438                                         return CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED;
439                                 }
440                         }
441                         read_unlock(&BusListLock);
442                         /* the msg is bound for virtpci; send
443                          * guest_msgs struct to callback
444                          */
445                         if (!msg->hdr.Flags.server) {
446                                 struct guest_msgs cmd;
447                                 cmd.msgtype = GUEST_DEL_VBUS;
448                                 cmd.del_vbus.busNo = busNo;
449                                 if (!VirtControlChanFunc) {
450                                         LOGERR("CONTROLVM_BUS_DESTROY Failed: virtpci callback not registered.");
451                                         return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
452                                 }
453                                 if (!VirtControlChanFunc(&cmd)) {
454                                         LOGERR("CONTROLVM_BUS_DESTROY Failed: virtpci GUEST_DEL_VBUS returned error.");
455                                         return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
456                                 }
457                         }
458                         /* remove the bus from the list */
459                         write_lock(&BusListLock);
460                         if (prev)       /* not at head */
461                                 prev->next = bus->next;
462                         else
463                                 BusListHead = bus->next;
464                         BusListCount--;
465                         write_unlock(&BusListLock);
466                         break;
467                 }
468         }
469
470         if (!bus) {
471                 LOGERR("CONTROLVM_BUS_DESTROY Failed: failed to find bus %d.\n",
472                        busNo);
473                 read_unlock(&BusListLock);
474                 return CONTROLVM_RESP_ERROR_ALREADY_DONE;
475         }
476         if (bus->proc_info) {
477                 remove_proc_entry("info", bus->proc_dir);
478                 bus->proc_info = NULL;
479         }
480         if (bus->proc_dir) {
481                 remove_proc_entry(bus->name, uislib_proc_vbus_dir);
482                 bus->proc_dir = NULL;
483         }
484         if (bus->pBusChannel) {
485                 uislib_iounmap(bus->pBusChannel);
486                 bus->pBusChannel = NULL;
487         }
488
489         kfree(bus);
490         return CONTROLVM_RESP_SUCCESS;
491 }
492
493 static int
494 create_device(CONTROLVM_MESSAGE *msg, char *buf)
495 {
496         struct device_info *dev;
497         struct bus_info *bus;
498         U32 busNo, devNo;
499         int result = CONTROLVM_RESP_SUCCESS;
500         U64 minSize = MIN_IO_CHANNEL_SIZE;
501         ReqHandlerInfo_t *pReqHandler;
502
503         busNo = msg->cmd.createDevice.busNo;
504         devNo = msg->cmd.createDevice.devNo;
505
506         POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, devNo, busNo,
507                          POSTCODE_SEVERITY_INFO);
508
509         dev = kzalloc(sizeof(struct device_info), GFP_ATOMIC);
510         if (!dev) {
511                 LOGERR("CONTROLVM_DEVICE_CREATE Failed: kmalloc for dev failed.\n");
512                 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo,
513                                  POSTCODE_SEVERITY_ERR);
514                 return CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
515         }
516
517         dev->channelTypeGuid = msg->cmd.createDevice.dataTypeGuid;
518         dev->intr = msg->cmd.createDevice.intr;
519         dev->channelAddr = msg->cmd.createDevice.channelAddr;
520         dev->busNo = busNo;
521         dev->devNo = devNo;
522         sema_init(&dev->interrupt_callback_lock, 1);    /* unlocked */
523         sprintf(dev->devid, "vbus%u:dev%u", (unsigned) busNo, (unsigned) devNo);
524         /* map the channel memory for the device. */
525         if (msg->hdr.Flags.testMessage)
526                 dev->chanptr = (void __iomem *)__va(dev->channelAddr);
527         else {
528                 pReqHandler = ReqHandlerFind(dev->channelTypeGuid);
529                 if (pReqHandler)
530                         /* generic service handler registered for this
531                          * channel
532                          */
533                         minSize = pReqHandler->min_channel_bytes;
534                 if (minSize > msg->cmd.createDevice.channelBytes) {
535                         LOGERR("CONTROLVM_DEVICE_CREATE Failed: channel size is too small, channel size:0x%lx, required size:0x%lx",
536                              (ulong) msg->cmd.createDevice.channelBytes,
537                              (ulong) minSize);
538                         POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo,
539                                          POSTCODE_SEVERITY_ERR);
540                         result = CONTROLVM_RESP_ERROR_CHANNEL_SIZE_TOO_SMALL;
541                         goto Away;
542                 }
543                 dev->chanptr =
544                     uislib_ioremap_cache(dev->channelAddr,
545                                          msg->cmd.createDevice.channelBytes);
546                 if (!dev->chanptr) {
547                         LOGERR("CONTROLVM_DEVICE_CREATE Failed: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed",
548                              dev->channelAddr,
549                              msg->cmd.createDevice.channelBytes);
550                         result = CONTROLVM_RESP_ERROR_IOREMAP_FAILED;
551                         POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo,
552                                          POSTCODE_SEVERITY_ERR);
553                         goto Away;
554                 }
555         }
556         dev->devInstGuid = msg->cmd.createDevice.devInstGuid;
557         dev->channelBytes = msg->cmd.createDevice.channelBytes;
558
559         read_lock(&BusListLock);
560         for (bus = BusListHead; bus; bus = bus->next) {
561                 if (bus->busNo == busNo) {
562                         /* make sure the device number is valid */
563                         if (devNo >= bus->deviceCount) {
564                                 LOGERR("CONTROLVM_DEVICE_CREATE Failed: device (%d) >= deviceCount (%d).",
565                                      devNo, bus->deviceCount);
566                                 result = CONTROLVM_RESP_ERROR_MAX_DEVICES;
567                                 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC,
568                                                  devNo, busNo,
569                                                  POSTCODE_SEVERITY_ERR);
570                                 read_unlock(&BusListLock);
571                                 goto Away;
572                         }
573                         /* make sure this device is not already set */
574                         if (bus->device[devNo]) {
575                                 LOGERR("CONTROLVM_DEVICE_CREATE Failed: device %d is already exists.",
576                                      devNo);
577                                 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC,
578                                                  devNo, busNo,
579                                                  POSTCODE_SEVERITY_ERR);
580                                 result = CONTROLVM_RESP_ERROR_ALREADY_DONE;
581                                 read_unlock(&BusListLock);
582                                 goto Away;
583                         }
584                         read_unlock(&BusListLock);
585                         /* the msg is bound for virtpci; send
586                          * guest_msgs struct to callback
587                          */
588                         if (!msg->hdr.Flags.server) {
589                                 struct guest_msgs cmd;
590                                 if (!memcmp
591                                     (&dev->channelTypeGuid,
592                                      &UltraVhbaChannelProtocolGuid,
593                                      sizeof(GUID))) {
594                                         WAIT_FOR_VALID_GUID(((CHANNEL_HEADER
595                                                               __iomem *) (dev->
596                                                                   chanptr))->
597                                                             Type);
598                                         if (!ULTRA_VHBA_CHANNEL_OK_CLIENT
599                                             (dev->chanptr, NULL)) {
600                                                 LOGERR("CONTROLVM_DEVICE_CREATE Failed:[CLIENT]VHBA dev %d chan invalid.",
601                                                      devNo);
602                                                 POSTCODE_LINUX_4
603                                                     (DEVICE_CREATE_FAILURE_PC,
604                                                      devNo, busNo,
605                                                      POSTCODE_SEVERITY_ERR);
606                                                 result = CONTROLVM_RESP_ERROR_CHANNEL_INVALID;
607                                                 goto Away;
608                                         }
609                                         cmd.msgtype = GUEST_ADD_VHBA;
610                                         cmd.add_vhba.chanptr = dev->chanptr;
611                                         cmd.add_vhba.busNo = busNo;
612                                         cmd.add_vhba.deviceNo = devNo;
613                                         cmd.add_vhba.devInstGuid =
614                                             dev->devInstGuid;
615                                         cmd.add_vhba.intr = dev->intr;
616                                 } else
617                                     if (!memcmp
618                                         (&dev->channelTypeGuid,
619                                          &UltraVnicChannelProtocolGuid,
620                                          sizeof(GUID))) {
621                                         WAIT_FOR_VALID_GUID(((CHANNEL_HEADER
622                                                               __iomem *) (dev->
623                                                                   chanptr))->
624                                                             Type);
625                                         if (!ULTRA_VNIC_CHANNEL_OK_CLIENT
626                                             (dev->chanptr, NULL)) {
627                                                 LOGERR("CONTROLVM_DEVICE_CREATE Failed: VNIC[CLIENT] dev %d chan invalid.",
628                                                      devNo);
629                                                 POSTCODE_LINUX_4
630                                                     (DEVICE_CREATE_FAILURE_PC,
631                                                      devNo, busNo,
632                                                      POSTCODE_SEVERITY_ERR);
633                                                 result = CONTROLVM_RESP_ERROR_CHANNEL_INVALID;
634                                                 goto Away;
635                                         }
636                                         cmd.msgtype = GUEST_ADD_VNIC;
637                                         cmd.add_vnic.chanptr = dev->chanptr;
638                                         cmd.add_vnic.busNo = busNo;
639                                         cmd.add_vnic.deviceNo = devNo;
640                                         cmd.add_vnic.devInstGuid =
641                                             dev->devInstGuid;
642                                         cmd.add_vhba.intr = dev->intr;
643                                 } else {
644                                         LOGERR("CONTROLVM_DEVICE_CREATE Failed: unknown channelTypeGuid.\n");
645                                         POSTCODE_LINUX_4
646                                             (DEVICE_CREATE_FAILURE_PC, devNo,
647                                              busNo, POSTCODE_SEVERITY_ERR);
648                                         result = CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN;
649                                         goto Away;
650                                 }
651
652                                 if (!VirtControlChanFunc) {
653                                         LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci callback not registered.");
654                                         POSTCODE_LINUX_4
655                                             (DEVICE_CREATE_FAILURE_PC, devNo,
656                                              busNo, POSTCODE_SEVERITY_ERR);
657                                         result = CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
658                                         goto Away;
659                                 }
660
661                                 if (!VirtControlChanFunc(&cmd)) {
662                                         LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci GUEST_ADD_[VHBA||VNIC] returned error.");
663                                         POSTCODE_LINUX_4
664                                             (DEVICE_CREATE_FAILURE_PC, devNo,
665                                              busNo, POSTCODE_SEVERITY_ERR);
666                                         result = CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
667                                         goto Away;
668                                 }
669                         }
670                         bus->device[devNo] = dev;
671                         POSTCODE_LINUX_4(DEVICE_CREATE_SUCCESS_PC, devNo, busNo,
672                                          POSTCODE_SEVERITY_INFO);
673                         return CONTROLVM_RESP_SUCCESS;
674                 }
675         }
676         read_unlock(&BusListLock);
677
678         LOGERR("CONTROLVM_DEVICE_CREATE Failed: failed to find bus %d.", busNo);
679         POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo,
680                          POSTCODE_SEVERITY_ERR);
681         result = CONTROLVM_RESP_ERROR_BUS_INVALID;
682
683 Away:
684         if (!msg->hdr.Flags.testMessage) {
685                 uislib_iounmap(dev->chanptr);
686                 dev->chanptr = NULL;
687         }
688
689         kfree(dev);
690         return result;
691 }
692
693 static int
694 pause_device(CONTROLVM_MESSAGE *msg)
695 {
696         U32 busNo, devNo;
697         struct bus_info *bus;
698         struct device_info *dev;
699         struct guest_msgs cmd;
700
701         busNo = msg->cmd.deviceChangeState.busNo;
702         devNo = msg->cmd.deviceChangeState.devNo;
703
704         read_lock(&BusListLock);
705         for (bus = BusListHead; bus; bus = bus->next) {
706                 if (bus->busNo == busNo) {
707                         /* make sure the device number is valid */
708                         if (devNo >= bus->deviceCount) {
709                                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device(%d) >= deviceCount(%d).",
710                                      devNo, bus->deviceCount);
711                                 read_unlock(&BusListLock);
712                                 return CONTROLVM_RESP_ERROR_DEVICE_INVALID;
713                         }
714                         /* make sure this device exists */
715                         dev = bus->device[devNo];
716                         if (!dev) {
717                                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device %d does not exist.",
718                                      devNo);
719                                 read_unlock(&BusListLock);
720                                 return CONTROLVM_RESP_ERROR_ALREADY_DONE;
721                         }
722                         read_unlock(&BusListLock);
723                         /* the msg is bound for virtpci; send
724                          * guest_msgs struct to callback
725                          */
726                         if (!memcmp
727                             (&dev->channelTypeGuid,
728                              &UltraVhbaChannelProtocolGuid, sizeof(GUID))) {
729                                 cmd.msgtype = GUEST_PAUSE_VHBA;
730                                 cmd.pause_vhba.chanptr = dev->chanptr;
731                         } else
732                             if (!memcmp
733                                 (&dev->channelTypeGuid,
734                                  &UltraVnicChannelProtocolGuid,
735                                  sizeof(GUID))) {
736                                 cmd.msgtype = GUEST_PAUSE_VNIC;
737                                 cmd.pause_vnic.chanptr = dev->chanptr;
738                         } else {
739                                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: unknown channelTypeGuid.\n");
740                                 return
741                                     CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN;
742                         }
743
744                         if (!VirtControlChanFunc) {
745                                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: virtpci callback not registered.");
746                                 return
747                                     CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
748                         }
749
750                         if (!VirtControlChanFunc(&cmd)) {
751                                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: virtpci GUEST_PAUSE_[VHBA||VNIC] returned error.");
752                                 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
753                         }
754                         break;
755                 }
756         }
757
758         if (!bus) {
759                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: bus %d does not exist",
760                      busNo);
761                 read_unlock(&BusListLock);
762                 return CONTROLVM_RESP_ERROR_BUS_INVALID;
763         }
764
765         return CONTROLVM_RESP_SUCCESS;
766 }
767
768 static int
769 resume_device(CONTROLVM_MESSAGE *msg)
770 {
771         U32 busNo, devNo;
772         struct bus_info *bus;
773         struct device_info *dev;
774         struct guest_msgs cmd;
775
776         busNo = msg->cmd.deviceChangeState.busNo;
777         devNo = msg->cmd.deviceChangeState.devNo;
778
779         read_lock(&BusListLock);
780         for (bus = BusListHead; bus; bus = bus->next) {
781                 if (bus->busNo == busNo) {
782                         /* make sure the device number is valid */
783                         if (devNo >= bus->deviceCount) {
784                                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device(%d) >= deviceCount(%d).",
785                                      devNo, bus->deviceCount);
786                                 read_unlock(&BusListLock);
787                                 return CONTROLVM_RESP_ERROR_DEVICE_INVALID;
788                         }
789                         /* make sure this device exists */
790                         dev = bus->device[devNo];
791                         if (!dev) {
792                                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device %d does not exist.",
793                                      devNo);
794                                 read_unlock(&BusListLock);
795                                 return CONTROLVM_RESP_ERROR_ALREADY_DONE;
796                         }
797                         read_unlock(&BusListLock);
798                         /* the msg is bound for virtpci; send
799                          * guest_msgs struct to callback
800                          */
801                         if (!memcmp(&dev->channelTypeGuid,
802                                     &UltraVhbaChannelProtocolGuid,
803                                     sizeof(GUID))) {
804                                 cmd.msgtype = GUEST_RESUME_VHBA;
805                                 cmd.resume_vhba.chanptr = dev->chanptr;
806                         } else
807                             if (!memcmp(&dev->channelTypeGuid,
808                                         &UltraVnicChannelProtocolGuid,
809                                         sizeof(GUID))) {
810                                 cmd.msgtype = GUEST_RESUME_VNIC;
811                                 cmd.resume_vnic.chanptr = dev->chanptr;
812                         } else {
813                                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: unknown channelTypeGuid.\n");
814                                 return
815                                     CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN;
816                         }
817
818                         if (!VirtControlChanFunc) {
819                                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: virtpci callback not registered.");
820                                 return
821                                     CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
822                         }
823
824                         if (!VirtControlChanFunc(&cmd)) {
825                                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: virtpci GUEST_RESUME_[VHBA||VNIC] returned error.");
826                                 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
827                         }
828                         break;
829                 }
830         }
831
832         if (!bus) {
833                 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: bus %d does not exist",
834                      busNo);
835                 read_unlock(&BusListLock);
836                 return CONTROLVM_RESP_ERROR_BUS_INVALID;
837         }
838
839         return CONTROLVM_RESP_SUCCESS;
840 }
841
842 static int
843 destroy_device(CONTROLVM_MESSAGE *msg, char *buf)
844 {
845         U32 busNo, devNo;
846         struct bus_info *bus;
847         struct device_info *dev;
848         struct guest_msgs cmd;
849
850         busNo = msg->cmd.destroyDevice.busNo;
851         devNo = msg->cmd.destroyDevice.devNo;
852
853         read_lock(&BusListLock);
854         LOGINF("destroy_device called for busNo=%u, devNo=%u", busNo, devNo);
855         for (bus = BusListHead; bus; bus = bus->next) {
856                 if (bus->busNo == busNo) {
857                         /* make sure the device number is valid */
858                         if (devNo >= bus->deviceCount) {
859                                 LOGERR("CONTROLVM_DEVICE_DESTORY Failed: device(%d) >= deviceCount(%d).",
860                                      devNo, bus->deviceCount);
861                                 read_unlock(&BusListLock);
862                                 return CONTROLVM_RESP_ERROR_DEVICE_INVALID;
863                         }
864                         /* make sure this device exists */
865                         dev = bus->device[devNo];
866                         if (!dev) {
867                                 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: device %d does not exist.",
868                                      devNo);
869                                 read_unlock(&BusListLock);
870                                 return CONTROLVM_RESP_ERROR_ALREADY_DONE;
871                         }
872                         read_unlock(&BusListLock);
873                         /* the msg is bound for virtpci; send
874                          * guest_msgs struct to callback
875                          */
876                         if (!memcmp
877                             (&dev->channelTypeGuid,
878                              &UltraVhbaChannelProtocolGuid, sizeof(GUID))) {
879                                 cmd.msgtype = GUEST_DEL_VHBA;
880                                 cmd.del_vhba.chanptr = dev->chanptr;
881                         } else
882                             if (!memcmp
883                                 (&dev->channelTypeGuid,
884                                  &UltraVnicChannelProtocolGuid,
885                                  sizeof(GUID))) {
886                                 cmd.msgtype = GUEST_DEL_VNIC;
887                                 cmd.del_vnic.chanptr = dev->chanptr;
888                         } else {
889                                 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: unknown channelTypeGuid.\n");
890                                 return
891                                     CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN;
892                         }
893
894                         if (!VirtControlChanFunc) {
895                                 LOGERR("CONTROLVM_DEVICE_DESTORY Failed: virtpci callback not registered.");
896                                 return
897                                     CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
898                         }
899
900                         if (!VirtControlChanFunc(&cmd)) {
901                                 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: virtpci GUEST_DEL_[VHBA||VNIC] returned error.");
902                                 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
903                         }
904 /* you must disable channel interrupts BEFORE you unmap the channel,
905  * because if you unmap first, there may still be some activity going
906  * on which accesses the channel and you will get a "unable to handle
907  * kernel paging request"
908  */
909                         if (dev->polling) {
910                                 LOGINF("calling uislib_disable_channel_interrupts");
911                                 uislib_disable_channel_interrupts(busNo, devNo);
912                         }
913                         /* unmap the channel memory for the device. */
914                         if (!msg->hdr.Flags.testMessage) {
915                                 LOGINF("destroy_device, doing iounmap");
916                                 uislib_iounmap(dev->chanptr);
917                         }
918                         kfree(dev);
919                         bus->device[devNo] = NULL;
920                         break;
921                 }
922         }
923
924         if (!bus) {
925                 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: bus %d does not exist",
926                        busNo);
927                 read_unlock(&BusListLock);
928                 return CONTROLVM_RESP_ERROR_BUS_INVALID;
929         }
930
931         return CONTROLVM_RESP_SUCCESS;
932 }
933
934 static int
935 init_chipset(CONTROLVM_MESSAGE *msg, char *buf)
936 {
937         POSTCODE_LINUX_2(CHIPSET_INIT_ENTRY_PC, POSTCODE_SEVERITY_INFO);
938
939         MaxBusCount = msg->cmd.initChipset.busCount;
940         PlatformNumber = msg->cmd.initChipset.platformNumber;
941         PhysicalDataChan = 0;
942
943         /* We need to make sure we have our functions registered
944         * before processing messages.  If we are a test vehicle the
945         * testMessage for init_chipset will be set.  We can ignore the
946         * waits for the callbacks, since this will be manually entered
947         * from a user.  If no testMessage is set, we will wait for the
948         * functions.
949         */
950         if (!msg->hdr.Flags.testMessage)
951                 WAIT_ON_CALLBACK(VirtControlChanFunc);
952
953         chipset_inited = 1;
954         POSTCODE_LINUX_2(CHIPSET_INIT_EXIT_PC, POSTCODE_SEVERITY_INFO);
955
956         return CONTROLVM_RESP_SUCCESS;
957 }
958
959 static int
960 stop_chipset(CONTROLVM_MESSAGE *msg, char *buf)
961 {
962         /* Check that all buses and switches have been torn down and
963          * destroyed.
964          */
965         if (BusListHead) {
966                 /* Buses still exist. */
967                 LOGERR("CONTROLVM_CHIPSET_STOP: BusListHead is not NULL");
968                 return CONTROLVM_RESP_ERROR_CHIPSET_STOP_FAILED_BUS;
969         }
970         if (BusListCount) {
971                 /* BusListHead is NULL, but BusListCount != 0 */
972                 LOGERR("CONTROLVM_CHIPSET_STOP: BusListCount != 0");
973                 return CONTROLVM_RESP_ERROR_CHIPSET_STOP_FAILED_BUS;
974         }
975
976         /* Buses are shut down. */
977         return visorchipset_chipset_notready();
978 }
979
980 static int
981 delete_bus_glue(U32 busNo)
982 {
983         CONTROLVM_MESSAGE msg;
984
985         init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0);
986         msg.cmd.destroyBus.busNo = busNo;
987         if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
988                 LOGERR("destroy_bus failed. busNo=0x%x\n", busNo);
989                 return 0;
990         }
991         return 1;
992 }
993
994 static int
995 delete_device_glue(U32 busNo, U32 devNo)
996 {
997         CONTROLVM_MESSAGE msg;
998
999         init_msg_header(&msg, CONTROLVM_DEVICE_DESTROY, 0, 0);
1000         msg.cmd.destroyDevice.busNo = busNo;
1001         msg.cmd.destroyDevice.devNo = devNo;
1002         if (destroy_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1003                 LOGERR("destroy_device failed. busNo=0x%x devNo=0x%x\n", busNo,
1004                        devNo);
1005                 return 0;
1006         }
1007         return 1;
1008 }
1009
1010 int
1011 uislib_client_inject_add_bus(U32 busNo, GUID instGuid,
1012                              U64 channelAddr, ulong nChannelBytes)
1013 {
1014         CONTROLVM_MESSAGE msg;
1015
1016         LOGINF("enter busNo=0x%x\n", busNo);
1017         /* step 0: init the chipset */
1018         POSTCODE_LINUX_3(CHIPSET_INIT_ENTRY_PC, busNo, POSTCODE_SEVERITY_INFO);
1019
1020         if (!chipset_inited) {
1021                 /* step: initialize the chipset */
1022                 init_msg_header(&msg, CONTROLVM_CHIPSET_INIT, 0, 0);
1023                 /* this change is needed so that console will come up
1024                 * OK even when the bus 0 create comes in late.  If the
1025                 * bus 0 create is the first create, then the add_vnic
1026                 * will work fine, but if the bus 0 create arrives
1027                 * after number 4, then the add_vnic will fail, and the
1028                 * ultraboot will fail.
1029                 */
1030                 msg.cmd.initChipset.busCount = 23;
1031                 msg.cmd.initChipset.switchCount = 0;
1032                 if (init_chipset(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1033                         LOGERR("init_chipset failed.\n");
1034                         return 0;
1035                 }
1036                 LOGINF("chipset initialized\n");
1037                 POSTCODE_LINUX_3(CHIPSET_INIT_EXIT_PC, busNo,
1038                                  POSTCODE_SEVERITY_INFO);
1039         }
1040
1041         /* step 1: create a bus */
1042         POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, busNo, POSTCODE_SEVERITY_WARNING);
1043         init_msg_header(&msg, CONTROLVM_BUS_CREATE, 0, 0);
1044         msg.cmd.createBus.busNo = busNo;
1045         msg.cmd.createBus.deviceCount = 23;     /* devNo+1; */
1046         msg.cmd.createBus.channelAddr = channelAddr;
1047         msg.cmd.createBus.channelBytes = nChannelBytes;
1048         if (create_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1049                 LOGERR("create_bus failed.\n");
1050                 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, busNo,
1051                                  POSTCODE_SEVERITY_ERR);
1052                 return 0;
1053         }
1054         POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, busNo, POSTCODE_SEVERITY_INFO);
1055
1056         return 1;
1057 }
1058 EXPORT_SYMBOL_GPL(uislib_client_inject_add_bus);
1059
1060
1061 int
1062 uislib_client_inject_del_bus(U32 busNo)
1063 {
1064         return delete_bus_glue(busNo);
1065 }
1066 EXPORT_SYMBOL_GPL(uislib_client_inject_del_bus);
1067
1068 int
1069 uislib_client_inject_pause_vhba(U32 busNo, U32 devNo)
1070 {
1071         CONTROLVM_MESSAGE msg;
1072         int rc;
1073
1074         init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0);
1075         msg.cmd.deviceChangeState.busNo = busNo;
1076         msg.cmd.deviceChangeState.devNo = devNo;
1077         msg.cmd.deviceChangeState.state = SegmentStateStandby;
1078         rc = pause_device(&msg);
1079         if (rc != CONTROLVM_RESP_SUCCESS) {
1080                 LOGERR("VHBA pause_device failed. busNo=0x%x devNo=0x%x\n",
1081                        busNo, devNo);
1082                 return rc;
1083         }
1084         return 0;
1085 }
1086 EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vhba);
1087
1088 int
1089 uislib_client_inject_resume_vhba(U32 busNo, U32 devNo)
1090 {
1091         CONTROLVM_MESSAGE msg;
1092         int rc;
1093
1094         init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0);
1095         msg.cmd.deviceChangeState.busNo = busNo;
1096         msg.cmd.deviceChangeState.devNo = devNo;
1097         msg.cmd.deviceChangeState.state = SegmentStateRunning;
1098         rc = resume_device(&msg);
1099         if (rc != CONTROLVM_RESP_SUCCESS) {
1100                 LOGERR("VHBA resume_device failed. busNo=0x%x devNo=0x%x\n",
1101                        busNo, devNo);
1102                 return rc;
1103         }
1104         return 0;
1105
1106 }
1107 EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vhba);
1108
1109 int
1110 uislib_client_inject_add_vhba(U32 busNo, U32 devNo,
1111                               U64 phys_chan_addr, U32 chan_bytes,
1112                               int is_test_addr, GUID instGuid,
1113                               struct InterruptInfo *intr)
1114 {
1115         CONTROLVM_MESSAGE msg;
1116
1117         LOGINF(" enter busNo=0x%x devNo=0x%x\n", busNo, devNo);
1118         /* chipset init'ed with bus bus has been previously created -
1119         * Verify it still exists step 2: create the VHBA device on the
1120         * bus
1121         */
1122         POSTCODE_LINUX_4(VHBA_CREATE_ENTRY_PC, devNo, busNo,
1123                          POSTCODE_SEVERITY_INFO);
1124
1125         init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, 0);
1126         if (is_test_addr)
1127                 /* signify that the physical channel address does NOT
1128                  * need to be ioremap()ed
1129                  */
1130                 msg.hdr.Flags.testMessage = 1;
1131         msg.cmd.createDevice.busNo = busNo;
1132         msg.cmd.createDevice.devNo = devNo;
1133         msg.cmd.createDevice.devInstGuid = instGuid;
1134         if (intr)
1135                 msg.cmd.createDevice.intr = *intr;
1136         else
1137                 memset(&msg.cmd.createDevice.intr, 0,
1138                        sizeof(struct InterruptInfo));
1139         msg.cmd.createDevice.channelAddr = phys_chan_addr;
1140         if (chan_bytes < MIN_IO_CHANNEL_SIZE) {
1141                 LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n",
1142                      chan_bytes, (unsigned int) MIN_IO_CHANNEL_SIZE);
1143                 POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC, chan_bytes,
1144                                  MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR);
1145                 return 0;
1146         }
1147         msg.cmd.createDevice.channelBytes = chan_bytes;
1148         msg.cmd.createDevice.dataTypeGuid = UltraVhbaChannelProtocolGuid;
1149         if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1150                 LOGERR("VHBA create_device failed.\n");
1151                 POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC, devNo, busNo,
1152                                  POSTCODE_SEVERITY_ERR);
1153                 return 0;
1154         }
1155         POSTCODE_LINUX_4(VHBA_CREATE_SUCCESS_PC, devNo, busNo,
1156                          POSTCODE_SEVERITY_INFO);
1157         return 1;
1158 }
1159 EXPORT_SYMBOL_GPL(uislib_client_inject_add_vhba);
1160
1161 int
1162 uislib_client_inject_del_vhba(U32 busNo, U32 devNo)
1163 {
1164         return delete_device_glue(busNo, devNo);
1165 }
1166 EXPORT_SYMBOL_GPL(uislib_client_inject_del_vhba);
1167
1168 int
1169 uislib_client_inject_add_vnic(U32 busNo, U32 devNo,
1170                               U64 phys_chan_addr, U32 chan_bytes,
1171                               int is_test_addr, GUID instGuid,
1172                               struct InterruptInfo *intr)
1173 {
1174         CONTROLVM_MESSAGE msg;
1175
1176         LOGINF(" enter busNo=0x%x devNo=0x%x\n", busNo, devNo);
1177         /* chipset init'ed with bus bus has been previously created -
1178         * Verify it still exists step 2: create the VNIC device on the
1179         * bus
1180         */
1181         POSTCODE_LINUX_4(VNIC_CREATE_ENTRY_PC, devNo, busNo,
1182                          POSTCODE_SEVERITY_INFO);
1183
1184         init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, 0);
1185         if (is_test_addr)
1186                 /* signify that the physical channel address does NOT
1187                  * need to be ioremap()ed
1188                  */
1189                 msg.hdr.Flags.testMessage = 1;
1190         msg.cmd.createDevice.busNo = busNo;
1191         msg.cmd.createDevice.devNo = devNo;
1192         msg.cmd.createDevice.devInstGuid = instGuid;
1193         if (intr)
1194                 msg.cmd.createDevice.intr = *intr;
1195         else
1196                 memset(&msg.cmd.createDevice.intr, 0,
1197                        sizeof(struct InterruptInfo));
1198         msg.cmd.createDevice.channelAddr = phys_chan_addr;
1199         if (chan_bytes < MIN_IO_CHANNEL_SIZE) {
1200                 LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n",
1201                      chan_bytes, (unsigned int) MIN_IO_CHANNEL_SIZE);
1202                 POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC, chan_bytes,
1203                                  MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR);
1204                 return 0;
1205         }
1206         msg.cmd.createDevice.channelBytes = chan_bytes;
1207         msg.cmd.createDevice.dataTypeGuid = UltraVnicChannelProtocolGuid;
1208         if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1209                 LOGERR("VNIC create_device failed.\n");
1210                 POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC, devNo, busNo,
1211                                  POSTCODE_SEVERITY_ERR);
1212                 return 0;
1213         }
1214
1215         POSTCODE_LINUX_4(VNIC_CREATE_SUCCESS_PC, devNo, busNo,
1216                          POSTCODE_SEVERITY_INFO);
1217         return 1;
1218 }
1219 EXPORT_SYMBOL_GPL(uislib_client_inject_add_vnic);
1220
1221 int
1222 uislib_client_inject_pause_vnic(U32 busNo, U32 devNo)
1223 {
1224         CONTROLVM_MESSAGE msg;
1225         int rc;
1226
1227         init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0);
1228         msg.cmd.deviceChangeState.busNo = busNo;
1229         msg.cmd.deviceChangeState.devNo = devNo;
1230         msg.cmd.deviceChangeState.state = SegmentStateStandby;
1231         rc = pause_device(&msg);
1232         if (rc != CONTROLVM_RESP_SUCCESS) {
1233                 LOGERR("VNIC pause_device failed. busNo=0x%x devNo=0x%x\n",
1234                        busNo, devNo);
1235                 return -1;
1236         }
1237         return 0;
1238 }
1239 EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vnic);
1240
1241 int
1242 uislib_client_inject_resume_vnic(U32 busNo, U32 devNo)
1243 {
1244         CONTROLVM_MESSAGE msg;
1245         int rc;
1246
1247         init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0);
1248         msg.cmd.deviceChangeState.busNo = busNo;
1249         msg.cmd.deviceChangeState.devNo = devNo;
1250         msg.cmd.deviceChangeState.state = SegmentStateRunning;
1251         rc = resume_device(&msg);
1252         if (rc != CONTROLVM_RESP_SUCCESS) {
1253                 LOGERR("VNIC resume_device failed. busNo=0x%x devNo=0x%x\n",
1254                        busNo, devNo);
1255                 return -1;
1256         }
1257         return 0;
1258
1259 }
1260 EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vnic);
1261
1262 int
1263 uislib_client_inject_del_vnic(U32 busNo, U32 devNo)
1264 {
1265         return delete_device_glue(busNo, devNo);
1266 }
1267 EXPORT_SYMBOL_GPL(uislib_client_inject_del_vnic);
1268
1269 static int
1270 uislib_client_add_vnic(U32 busNo)
1271 {
1272         BOOL busCreated = FALSE;
1273         int devNo = 0;          /* Default to 0, since only one device
1274                                  * will be created for this bus... */
1275         GUID dummyGuid = GUID0;
1276         CONTROLVM_MESSAGE msg;
1277
1278         init_msg_header(&msg, CONTROLVM_BUS_CREATE, 0, 0);
1279         msg.hdr.Flags.testMessage = 1;
1280         msg.cmd.createBus.busNo = busNo;
1281         msg.cmd.createBus.deviceCount = 4;
1282         msg.cmd.createBus.channelAddr = 0;
1283         msg.cmd.createBus.channelBytes = 0;
1284         if (create_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1285                 LOGERR("client create_bus failed");
1286                 return 0;
1287         }
1288         busCreated = TRUE;
1289
1290         init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, 0);
1291         msg.hdr.Flags.testMessage = 1;
1292         msg.cmd.createDevice.busNo = busNo;
1293         msg.cmd.createDevice.devNo = devNo;
1294         msg.cmd.createDevice.devInstGuid = dummyGuid;
1295         memset(&msg.cmd.createDevice.intr, 0, sizeof(struct InterruptInfo));
1296         msg.cmd.createDevice.channelAddr = PhysicalDataChan;
1297         msg.cmd.createDevice.channelBytes = MIN_IO_CHANNEL_SIZE;
1298         msg.cmd.createDevice.dataTypeGuid = UltraVnicChannelProtocolGuid;
1299         if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1300                 LOGERR("client create_device failed");
1301                 goto AwayCleanup;
1302         }
1303
1304         return 1;
1305
1306 AwayCleanup:
1307         if (busCreated) {
1308                 init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0);
1309                 msg.hdr.Flags.testMessage = 1;
1310                 msg.cmd.destroyBus.busNo = busNo;
1311                 if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS)
1312                         LOGERR("client destroy_bus failed.\n");
1313         }
1314
1315         return 0;
1316 }                               /* end uislib_client_add_vnic */
1317 EXPORT_SYMBOL_GPL(uislib_client_add_vnic);
1318
1319 static int
1320 uislib_client_delete_vnic(U32 busNo)
1321 {
1322         int devNo = 0;          /* Default to 0, since only one device
1323                                  * will be created for this bus... */
1324         CONTROLVM_MESSAGE msg;
1325
1326         init_msg_header(&msg, CONTROLVM_DEVICE_DESTROY, 0, 0);
1327         msg.hdr.Flags.testMessage = 1;
1328         msg.cmd.destroyDevice.busNo = busNo;
1329         msg.cmd.destroyDevice.devNo = devNo;
1330         if (destroy_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1331                 /* Don't error exit - try to see if bus can be destroyed... */
1332                 LOGERR("client destroy_device failed.\n");
1333         }
1334
1335         init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0);
1336         msg.hdr.Flags.testMessage = 1;
1337         msg.cmd.destroyBus.busNo = busNo;
1338         if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS)
1339                 LOGERR("client destroy_bus failed.\n");
1340
1341         return 1;
1342 }
1343 EXPORT_SYMBOL_GPL(uislib_client_delete_vnic);
1344 /* end client_delete_vnic */
1345
1346 void *
1347 uislib_cache_alloc(struct kmem_cache *cur_pool, char *fn, int ln)
1348 {
1349         /* __GFP_NORETRY means "ok to fail", meaning kmalloc() can
1350         * return NULL.  If you do NOT specify __GFP_NORETRY, Linux
1351         * will go to extreme measures to get memory for you (like,
1352         * invoke oom killer), which will probably cripple the system.
1353         */
1354         void *p = kmem_cache_alloc(cur_pool, GFP_ATOMIC | __GFP_NORETRY);
1355         if (p == NULL) {
1356                 LOGERR("uislib_malloc failed to alloc uiscmdrsp @%s:%d",
1357                        fn, ln);
1358                 return NULL;
1359         }
1360         return p;
1361 }
1362 EXPORT_SYMBOL_GPL(uislib_cache_alloc);
1363
1364 void
1365 uislib_cache_free(struct kmem_cache *cur_pool, void *p, char *fn, int ln)
1366 {
1367         if (p == NULL) {
1368                 LOGERR("uislib_free NULL pointer @%s:%d", fn, ln);
1369                 return;
1370         }
1371         kmem_cache_free(cur_pool, p);
1372 }
1373 EXPORT_SYMBOL_GPL(uislib_cache_free);
1374
1375 /*****************************************************/
1376 /* proc filesystem callback functions                */
1377 /*****************************************************/
1378
1379 static ssize_t
1380 vnic_proc_write(struct file *file, const char __user *buffer,
1381                 size_t count, loff_t *ppos)
1382 {
1383         int action = 0xffff, busNo = 0, i, result = 0;
1384         char buf[4];
1385         char direction;
1386 /* GUID guid; */
1387         if (count >= ARRAY_SIZE(buf))
1388                 return -EINVAL;
1389
1390         if (copy_from_user(buf, buffer, count)) {
1391                 LOGERR("echo > /proc/uislib/vnic copy_from_user ****FAILED.\n");
1392                 return -EFAULT;
1393         }
1394
1395         i = sscanf(buf, "%d%c", &action, &direction);
1396         if (i != 2) {
1397                 LOGERR("unable to parse vnic proc parameters.\n");
1398                 return -EFAULT;
1399         }
1400
1401         if ((direction != '-') && (direction != '+')) {
1402                 LOGERR("unable to determine whether to add or delete vnic\n");
1403                 return -EFAULT;
1404         }
1405
1406         /* if (i < 1), i.e., if we didn't even read the action field,
1407         * then action will default to 0xffff and the code below will
1408         * fall through the switch and print usage.
1409         */
1410         switch (action) {
1411         case 0:
1412                 /* call client method... */
1413                 busNo = 0;      /* All client drivers use bus value of 0... */
1414                 if (direction == '+')
1415                         result = uislib_client_add_vnic(busNo);
1416                 else
1417                         result = uislib_client_delete_vnic(busNo);
1418                 if (!result) {
1419                         LOGERR("echo 0%c > /proc/uislib/vnic failed (client end)",
1420                              direction);
1421                         return -EFAULT;
1422                 }
1423                 return count;
1424
1425         default:
1426                 break;
1427         }
1428
1429         LOGERR("USAGE: echo <action><direction (up/down)> > /proc/uislib/vnic");
1430         LOGERR(" ");
1431         LOGERR("Client Syntax");
1432         LOGERR("-------------");
1433         LOGERR("0+    ==> add vnic");
1434         LOGERR("0-    ==> delete vnic");
1435         LOGERR(" ");
1436         return count;
1437 }                               /* end vnic_proc_write */
1438
1439 static ssize_t
1440 chipset_proc_write(struct file *file, const char __user *buffer,
1441                    size_t count, loff_t *ppos)
1442 {
1443         int i, action = 0xffff;
1444         char buf[4];
1445         CONTROLVM_MESSAGE msg;
1446
1447         if (count >= ARRAY_SIZE(buf))
1448                 return -EINVAL;
1449
1450         memset(&msg, 0, sizeof(CONTROLVM_MESSAGE));
1451
1452         if (copy_from_user(buf, buffer, count)) {
1453                 LOGERR("copy_from_user ****FAILED.\n");
1454                 return -EFAULT;
1455         }
1456
1457         if (chipset_inited) {
1458                 LOGINF("Chipset already initialized\n");
1459                 return -EFAULT;
1460         }
1461         i = sscanf(buf, "%x", &action);
1462
1463         /* if (i < 1), i.e., if we didn't even read the action field,
1464         * then action will default to 0xffff and the code below will
1465         * fall through the switch and print usage.
1466         */
1467         switch (action) {
1468         case 1:
1469                 /* GUEST */
1470                 /* step: initialize the chipset */
1471                 init_msg_header(&msg, CONTROLVM_CHIPSET_INIT, 0, 0);
1472                 msg.hdr.Flags.testMessage = 0;
1473                 msg.cmd.initChipset.busCount = 23;
1474                 msg.cmd.initChipset.switchCount = 23;
1475
1476                 if (init_chipset(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1477                         LOGERR("init_chipset failed.\n");
1478                         return 0;
1479                 }
1480                 return 1;
1481         case 2:
1482                 /* BOTH */
1483                 init_msg_header(&msg, CONTROLVM_CHIPSET_INIT, 0, 0);
1484                 msg.hdr.Flags.testMessage = 1;
1485                 msg.cmd.initChipset.busCount = 23;
1486                 msg.cmd.initChipset.switchCount = 23;
1487
1488                 if (init_chipset(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1489                         LOGERR("init_chipset failed.\n");
1490                         return 0;
1491                 }
1492                 return 1;
1493
1494         default:
1495                 break;
1496         }
1497
1498         LOGERR("usage: 1 ==> init_chipset client\n");
1499         LOGERR("usage: 2 ==> init_chipset test\n");
1500         return -EFAULT;
1501 }
1502
1503 #define PLINE(...) uisutil_add_proc_line_ex(&tot, buff, \
1504                                                buff_len, __VA_ARGS__)
1505
1506 static int
1507 info_proc_read_helper(char **buff, int *buff_len)
1508 {
1509         int i, tot = 0;
1510         struct bus_info *bus;
1511
1512         if (PLINE("\nBuses:\n") < 0)
1513                 goto err_done;
1514
1515         read_lock(&BusListLock);
1516         for (bus = BusListHead; bus; bus = bus->next) {
1517
1518                 if (PLINE("    bus=0x%p, busNo=%d, deviceCount=%d\n",
1519                           bus, bus->busNo, bus->deviceCount) < 0)
1520                         goto err_done_unlock;
1521
1522
1523                 if (PLINE("        Devices:\n") < 0)
1524                         goto err_done_unlock;
1525
1526                 for (i = 0; i < bus->deviceCount; i++) {
1527                         if (bus->device[i]) {
1528                                 if (PLINE("            busNo %d, device[%i]: 0x%p, chanptr=0x%p, swtch=0x%p\n",
1529                                           bus->busNo, i, bus->device[i],
1530                                           bus->device[i]->chanptr,
1531                                           bus->device[i]->swtch) < 0)
1532                                         goto err_done_unlock;
1533
1534                                 if (PLINE("            first_busy_cnt=%llu, moved_to_tail_cnt=%llu, last_on_list_cnt=%llu\n",
1535                                           bus->device[i]->first_busy_cnt,
1536                                           bus->device[i]->moved_to_tail_cnt,
1537                                           bus->device[i]->last_on_list_cnt) < 0)
1538                                         goto err_done_unlock;
1539                         }
1540                 }
1541         }
1542         read_unlock(&BusListLock);
1543
1544         if (PLINE("UisUtils_Registered_Services: %d\n",
1545                   atomic_read(&UisUtils_Registered_Services)) < 0)
1546                 goto err_done;
1547         if (PLINE("cycles_before_wait %llu wait_cycles:%llu\n",
1548                   cycles_before_wait, wait_cycles) < 0)
1549                         goto err_done;
1550         if (PLINE("tot_wakeup_cnt %llu:tot_wait_cnt %llu:tot_schedule_cnt %llu\n",
1551                   tot_wakeup_cnt, tot_wait_cnt, tot_schedule_cnt) < 0)
1552                         goto err_done;
1553         if (PLINE("en_smart_wakeup %d\n", en_smart_wakeup) < 0)
1554                         goto err_done;
1555         if (PLINE("tot_moved_to_tail_cnt %llu\n", tot_moved_to_tail_cnt) < 0)
1556                         goto err_done;
1557
1558         return tot;
1559
1560 err_done_unlock:
1561         read_unlock(&BusListLock);
1562 err_done:
1563         return -1;
1564 }
1565
1566 static ssize_t
1567 info_proc_read(struct file *file, char __user *buf, size_t len, loff_t *offset)
1568 {
1569         char *temp;
1570         int totalBytes = 0;
1571         int remaining_bytes = PROC_READ_BUFFER_SIZE;
1572
1573 /* *start = buf; */
1574         if (ProcReadBuffer == NULL) {
1575                 DBGINF("ProcReadBuffer == NULL; allocating buffer.\n.");
1576                 ProcReadBuffer = vmalloc(PROC_READ_BUFFER_SIZE);
1577
1578                 if (ProcReadBuffer == NULL) {
1579                         LOGERR("failed to allocate buffer to provide proc data.\n");
1580                         return -ENOMEM;
1581                 }
1582         }
1583
1584         temp = ProcReadBuffer;
1585
1586         if ((*offset == 0) || (!ProcReadBufferValid)) {
1587                 DBGINF("calling info_proc_read_helper.\n");
1588                 /* if the read fails, then -1 will be returned */
1589                 totalBytes = info_proc_read_helper(&temp, &remaining_bytes);
1590                 ProcReadBufferValid = 1;
1591         } else
1592                 totalBytes = strlen(ProcReadBuffer);
1593
1594         return simple_read_from_buffer(buf, len, offset,
1595                                        ProcReadBuffer, totalBytes);
1596 }
1597
1598 static ssize_t
1599 platformnumber_proc_read(struct file *file, char __user *buf,
1600                          size_t len, loff_t *offset)
1601 {
1602         int length = 0;
1603         char *vbuf;
1604         loff_t pos = *offset;
1605
1606         if (pos < 0)
1607                 return -EINVAL;
1608
1609         if (pos > 0 || !len)
1610                 return 0;
1611
1612         vbuf = kzalloc(len, GFP_KERNEL);
1613         if (!vbuf)
1614                 return -ENOMEM;
1615
1616         length = sprintf(vbuf, "%d\n", PlatformNumber);
1617
1618         if (copy_to_user(buf, vbuf, length)) {
1619                 kfree(vbuf);
1620                 return -EFAULT;
1621         }
1622
1623         kfree(vbuf);
1624         *offset += length;
1625         return length;
1626 }
1627
1628 #ifdef UISLIB_TEST_PROC
1629
1630 /* proc/uislib/vbus/<x>/info */
1631 static int
1632 proc_info_vbus_show(struct seq_file *m, void *v)
1633 {
1634         struct bus_info *bus = m->private;
1635         int i, devInfoCount, x;
1636         char buf[999];
1637
1638         if (bus == NULL)
1639                 return 0;
1640         seq_printf(m, "Client device / client driver info for %s partition (vbus #%d):\n",
1641                    bus->partitionName, bus->busNo);
1642         if ((bus->busChannelBytes == 0) || (bus->pBusChannel == NULL))
1643                 return 0;
1644         devInfoCount =
1645             (bus->busChannelBytes -
1646              sizeof(ULTRA_VBUS_CHANNEL_PROTOCOL)) /
1647             sizeof(ULTRA_VBUS_DEVICEINFO);
1648         x = VBUSCHANNEL_devInfoToStringBuffer(&bus->pBusChannel->ChpInfo, buf,
1649                                               sizeof(buf) - 1, -1);
1650         buf[x] = '\0';
1651         seq_printf(m, "%s", buf);
1652         x = VBUSCHANNEL_devInfoToStringBuffer(&bus->pBusChannel->BusInfo,
1653                                               buf, sizeof(buf) - 1, -1);
1654         buf[x] = '\0';
1655         seq_printf(m, "%s", buf);
1656         for (i = 0; i < devInfoCount; i++) {
1657                 x = VBUSCHANNEL_devInfoToStringBuffer(&bus->pBusChannel->
1658                                                       DevInfo[i], buf,
1659                                                       sizeof(buf) - 1, i);
1660                 if (x > 0) {
1661                         buf[x] = '\0';
1662                         seq_printf(m, "%s", buf);
1663                 }
1664         }
1665         return 0;
1666 }
1667
1668 static ssize_t
1669 bus_proc_write(struct file *file, const char __user *buffer,
1670                size_t count, loff_t *ppos)
1671 {
1672         int server_flag = 0;
1673         int i, action = 0xffff, result;
1674         char buf[16];
1675         CONTROLVM_MESSAGE msg;
1676         U32 busNo, deviceCount;
1677
1678         if (count >= ARRAY_SIZE(buf))
1679                 return -EINVAL;
1680
1681         memset(&msg, 0, sizeof(CONTROLVM_MESSAGE));
1682
1683         if (copy_from_user(buf, buffer, count)) {
1684                 LOGERR("echo > /proc/uislib/bus: copy_from_user ****FAILED.");
1685                 return -EFAULT;
1686         }
1687
1688         i = sscanf(buf, "%x-%d-%d", &action, &busNo, &deviceCount);
1689
1690         /* if (i < 1), i.e., if we didn't even read the action field,
1691         * then action will default to 0xffff and the code below will
1692         * fall through the switch and print usage.
1693         */
1694         switch (action) {
1695         case 0:
1696                 /* destroy a bus */
1697                 if (i != 2)
1698                         break;
1699                 init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, server_flag);
1700                 msg.cmd.destroyBus.busNo = busNo;
1701
1702                 result = destroy_bus(&msg, NULL);
1703
1704                 if (result != CONTROLVM_RESP_SUCCESS) {
1705                         LOGERR("echo 0-%d > /proc/uislib/bus {CONTROLVM_BUS_DESTROY Failed} Result(%d)",
1706                              busNo, result);
1707                         return -EFAULT;
1708                 }
1709                 return count;
1710         case 1:
1711                 /* create a bus */
1712                 if (i != 3)
1713                         break;
1714                 init_msg_header(&msg, CONTROLVM_BUS_CREATE, 0, server_flag);
1715                 msg.cmd.createBus.busNo = busNo;
1716                 msg.cmd.createBus.deviceCount = deviceCount;
1717
1718                 result = create_bus(&msg, NULL);
1719
1720                 if (result != CONTROLVM_RESP_SUCCESS) {
1721                         LOGERR("echo 1-%d-%d > /proc/uislib/bus {CONTROLVM_BUS_CREATE Failed} Result(%d)",
1722                              busNo, deviceCount, result);
1723                         return -EFAULT;
1724                 }
1725
1726                 return count;
1727         default:
1728                 break;
1729         }
1730
1731         LOGERR("USAGE: echo <action>-<busNo>... > /proc/uislib/bus");
1732         LOGERR(" ");
1733         LOGERR("Destruct Syntax     ControlVM Message Id");
1734         LOGERR("---------------     ---------------------");
1735         LOGERR("0-<busNo>       ==> CONTROLVM_BUS_DESTROY");
1736         LOGERR(" ");
1737         LOGERR("Construct Syntax            ControlVM Message Id");
1738         LOGERR("-----------------------     -------------------- ");
1739         LOGERR("1-<busNo>-<deviceCount> ==> CONTROLVM_BUS_CREATE");
1740
1741         return -EFAULT;
1742 }
1743
1744 static ssize_t
1745 uislib_proc_read_writeonly(struct file *file, char __user *buffer,
1746                size_t count, loff_t *ppos)
1747 {
1748         return 0;
1749 }
1750
1751 static ssize_t
1752 dev_proc_write(struct file *file, const char __user *buffer,
1753                size_t count, loff_t *ppos)
1754 {
1755         int server_flag = 0;
1756         CONTROLVM_MESSAGE msg;
1757         U32 busNo, devNo;
1758         char buf[32];
1759         unsigned int chanptr;
1760         int type, i, action = 0xffff, result;
1761
1762         if (count >= ARRAY_SIZE(buf))
1763                 return -EINVAL;
1764
1765         if (copy_from_user(buf, buffer, count)) {
1766                 LOGERR("echo > /proc/uislib/device: copy_from_user ****FAILED.");
1767                 return -EFAULT;
1768         }
1769
1770         i = sscanf(buf, "%x-%d-%d-%x-%d",
1771                    &action, &busNo, &devNo, &chanptr, &type);
1772
1773         switch (action) {
1774         case 0:
1775                 if (i != 3)
1776                         break;
1777
1778                 /* destroy a device */
1779                 init_msg_header(&msg, CONTROLVM_DEVICE_DESTROY, 0, server_flag);
1780                 msg.cmd.destroyDevice.busNo = busNo;
1781                 msg.cmd.destroyDevice.devNo = devNo;
1782
1783                 result = destroy_device(&msg, NULL);
1784
1785                 if (result != CONTROLVM_RESP_SUCCESS) {
1786                         LOGERR("echo 0-%d-%d > /proc/uislib/device {CONTROLVM_DEVICE_DESTROY Failed} Result(%d)",
1787                              busNo, devNo, result);
1788                         return -EFAULT;
1789                 }
1790
1791                 return count;
1792
1793         case 1:
1794                 if (i != 5)
1795                         break;
1796
1797                 /* create a device */
1798                 init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, server_flag);
1799                 msg.cmd.createDevice.busNo = busNo;
1800                 msg.cmd.createDevice.devNo = devNo;
1801                 msg.cmd.createDevice.channelAddr = __pa(chanptr);
1802                 msg.cmd.createDevice.channelBytes = MIN_IO_CHANNEL_SIZE;
1803
1804                 if (type == 0)
1805                         msg.cmd.createDevice.dataTypeGuid =
1806                             UltraVhbaChannelProtocolGuid;
1807                 else if (type == 1)
1808                         msg.cmd.createDevice.dataTypeGuid =
1809                             UltraVnicChannelProtocolGuid;
1810                 else {
1811                         LOGERR("echo 1-%d-%d-%x-<type> > /proc/uislib/devce failed: invalid device type %d.",
1812                              busNo, devNo, chanptr, type);
1813                         return -EFAULT;
1814                 }
1815
1816                 result = create_device(&msg, NULL);
1817
1818                 if (result != CONTROLVM_RESP_SUCCESS) {
1819                         if (type == 0)
1820                                 LOGERR("echo 1-%d-%d-%x-0 > /proc/uislib/device {CONTROLVM_DEVICE_CREATE[vHBA] Failed} Result(%d)",
1821                                      busNo, devNo, chanptr, result);
1822                         else
1823                                 LOGERR("echo 1-%d-%d-%x-1 > /proc/uislib/device {CONTROLVM_DEVICE_CREATE[vNIC] Failed} Result(%d)",
1824                                      busNo, devNo, chanptr, result);
1825                         return -EFAULT;
1826                 }
1827
1828         default:
1829                 break;
1830         }
1831
1832         LOGERR("USAGE: echo <action>-<busNo>-<devNo>... > /proc/uislib/device");
1833         LOGERR(" ");
1834         LOGERR("Destruct Syntax       ControlVM Message Id");
1835         LOGERR("-----------------     ------------------------");
1836         LOGERR("0-<busNo>-<devNo> ==> CONTROLVM_DEVICE_DESTROY");
1837         LOGERR(" ");
1838         LOGERR("Construct Syntax                       ControlVM Message Id");
1839         LOGERR
1840             ("----------------------------------     ----------------------- ");
1841         LOGERR
1842             ("1-<busNo>-<devNo>-<chanptr>-<type> ==> CONTROLVM_DEVICE_CREATE");
1843         LOGERR("      <type = 0>: vHBA");
1844         LOGERR("      <type = 1>: vNIC");
1845         LOGERR(" ");
1846
1847         return -EFAULT;
1848 }
1849
1850 static ssize_t
1851 cycles_before_wait_proc_write(struct file *file, const char __user *buffer,
1852                               size_t count, loff_t *ppos)
1853 {
1854         char buf[16];
1855
1856 #define CYCLES_BEFORE_WAIT_USE_ERROR  { \
1857         LOGERR("Incorrect Call Home Input.\n"); \
1858         pr_info("Please pass Call Home Event Parameters in the form:\n"); \
1859         pr_info("EventID Category Type[parameter1][parameter2][parameter3][parameter4][parameter5][parameter6]\n"); \
1860         return -EFAULT; \
1861 }
1862         if (count >= ARRAY_SIZE(buf))
1863                 return -EINVAL;
1864
1865         if (count == 0)
1866                 CYCLES_BEFORE_WAIT_USE_ERROR;
1867
1868         if (copy_from_user(buf, buffer, count)) {
1869                 LOGERR("copy_from_user failed.\n");
1870                 return -EFAULT;
1871         }
1872         buf[count - 1] = '\0';  /* Replace the LF at the end of the
1873                                  * input with a NULL */
1874         /* Pull out the cycles_before_wait must be decimal integer */
1875         if (sscanf(buf, "%lld", &cycles_before_wait) != 1)
1876                 CYCLES_BEFORE_WAIT_USE_ERROR;
1877
1878         return count;
1879 }
1880
1881 static ssize_t
1882 reset_counts_proc_write(struct file *file, const char __user *buffer,
1883                         size_t count, loff_t *ppos)
1884 {
1885         char buf[16];
1886         unsigned long long new_value;
1887         struct bus_info *bus;
1888         int i;
1889
1890 #define RESET_COUNTS_USE_ERROR  { \
1891         LOGERR("Incorrect reset_counts Input.\n"); \
1892         pr_info("Please pass the new value for the counters:\n"); \
1893         pr_info("e.g. echo 0 > reset_counts\n"); \
1894         return -EFAULT; \
1895         }
1896
1897         if (count >= ARRAY_SIZE(buf))
1898                 return -EINVAL;
1899
1900         if (count == 0)
1901                 RESET_COUNTS_USE_ERROR;
1902
1903         if (copy_from_user(buf, buffer, count)) {
1904                 LOGERR("copy_from_user failed.\n");
1905                 return -EFAULT;
1906         }
1907         buf[count - 1] = '\0';  /* Replace the LF at the end of the
1908                                  * input with a NULL */
1909         /* Pull out the reset_counts must be decimal integer */
1910         if (sscanf(buf, "%llu", &new_value) != 1)
1911                 RESET_COUNTS_USE_ERROR;
1912         read_lock(&BusListLock);
1913         for (bus = BusListHead; bus; bus = bus->next) {
1914
1915                 for (i = 0; i < bus->deviceCount; i++) {
1916                         if (bus->device[i]) {
1917                                 bus->device[i]->first_busy_cnt = new_value;
1918                                 bus->device[i]->moved_to_tail_cnt = new_value;
1919                                 bus->device[i]->last_on_list_cnt = new_value;
1920                         }
1921                 }
1922         }
1923         read_unlock(&BusListLock);
1924         tot_moved_to_tail_cnt = new_value;
1925         tot_wait_cnt = new_value;
1926         tot_wakeup_cnt = new_value;
1927         tot_schedule_cnt = new_value;
1928         return count;
1929 }
1930
1931 static ssize_t
1932 smart_wakeup_proc_write(struct file *file, const char __user *buffer,
1933                         size_t count, loff_t *ppos)
1934 {
1935         char buf[16];
1936         int new_value;
1937
1938 #define SMART_WAKEUP_USE_ERROR  { \
1939         LOGERR("Incorrect smart_wakeup Input 0 disables smart_wakeup, and 1 enables smart_wakeup.\n"); \
1940         pr_info("echo 0 > smart_wakeup\n"); \
1941         pr_info("echo 1 > smart_wakeup\n"); \
1942         return -EFAULT; \
1943         }
1944
1945         if (count >= ARRAY_SIZE(buf))
1946                 return -EINVAL;
1947
1948         if (count == 0)
1949                 SMART_WAKEUP_USE_ERROR;
1950
1951         if (copy_from_user(buf, buffer, count)) {
1952                 LOGERR("copy_from_user failed.\n");
1953                 return -EFAULT;
1954         }
1955         buf[count - 1] = '\0';  /* Replace the LF at the end of the
1956                                  * input with a NULL */
1957         /* Pull out the smart_wakeup must be decimal integer */
1958         if (sscanf(buf, "%d", &new_value) != 1)
1959                 SMART_WAKEUP_USE_ERROR;
1960         en_smart_wakeup = new_value;
1961         return count;
1962 }
1963
1964 static ssize_t
1965 test_proc_write(struct file *file, const char __user *buffer,
1966                 size_t count, loff_t *ppos)
1967 {
1968         int i, action = 0xffff;
1969         char buf[16];
1970         CONTROLVM_MESSAGE msg;
1971         S64 vrtc_offset;
1972
1973         if (count >= ARRAY_SIZE(buf))
1974                 return -EINVAL;
1975
1976         memset(&msg, 0, sizeof(CONTROLVM_MESSAGE));
1977
1978         if (copy_from_user(buf, buffer, count)) {
1979                 LOGERR("copy_from_user ****FAILED.\n");
1980                 return -EFAULT;
1981         }
1982
1983         i = sscanf(buf, "%x", &action);
1984
1985         /* if (i < 1), i.e., if we didn't even read the action field,
1986         * then action will default to 0xffff and the code below will
1987         * fall through the switch and print usage. */
1988         switch (action) {
1989         case 6:
1990                 msg.hdr.Id = CONTROLVM_CHIPSET_STOP;
1991                 msg.hdr.Flags.responseExpected = 1;
1992                 stop_chipset(&msg, NULL);
1993                 break;
1994         case 7:
1995                 vrtc_offset = 0;
1996                 LOGERR("about to issue QUERY vrtc_offset=%LX", vrtc_offset);
1997                 vrtc_offset = Issue_VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET();
1998                 LOGERR("result is vrtc_offset=%LX", vrtc_offset);
1999                 break;
2000         case 8:
2001                 vrtc_offset = 60;
2002                 LOGERR("about to increase physical time by 0x%LX seconds",
2003                        vrtc_offset);
2004                 vrtc_offset = Issue_VMCALL_UPDATE_PHYSICAL_TIME(vrtc_offset);
2005                 break;
2006         case 9:
2007                 vrtc_offset = -60;
2008                 LOGERR("about to decrease physical time by 0x%LX seconds",
2009                        vrtc_offset);
2010                 vrtc_offset = Issue_VMCALL_UPDATE_PHYSICAL_TIME(vrtc_offset);
2011                 break;
2012         default:
2013                 LOGERR("usage: 6 for CHIPSET_STOP\n");
2014                 LOGERR("       7 for VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET()\n");
2015                 LOGERR("       8 for VMCALL_UPDATE_PHYSICAL_TIME(60)\n");
2016                 LOGERR("       9 for VMCALL_UPDATE_PHYSICAL_TIME(-60)\n");
2017                 return -EFAULT;
2018                 break;
2019         }
2020         return count;
2021 }
2022
2023 #endif                          /* UISLIB_TEST_PROC */
2024 static struct device_info *
2025 find_dev(U32 busNo, U32 devNo)
2026 {
2027         struct bus_info *bus;
2028         struct device_info *dev = NULL;
2029
2030         read_lock(&BusListLock);
2031         for (bus = BusListHead; bus; bus = bus->next) {
2032                 if (bus->busNo == busNo) {
2033                         /* make sure the device number is valid */
2034                         if (devNo >= bus->deviceCount) {
2035                                 LOGERR("%s bad busNo, devNo=%d,%d",
2036                                        __func__,
2037                                        (int) (busNo), (int) (devNo));
2038                                 goto Away;
2039                         }
2040                         dev = bus->device[devNo];
2041                         if (!dev)
2042                                 LOGERR("%s bad busNo, devNo=%d,%d",
2043                                        __func__,
2044                                        (int) (busNo), (int) (devNo));
2045                         goto Away;
2046                 }
2047         }
2048 Away:
2049         read_unlock(&BusListLock);
2050         return dev;
2051 }
2052
2053 /*  This thread calls the "interrupt" function for each device that has
2054  *  enabled such using uislib_enable_channel_interrupts().  The "interrupt"
2055  *  function typically reads and processes the devices's channel input
2056  *  queue.  This thread repeatedly does this, until the thread is told to stop
2057  *  (via uisthread_stop()).  Sleeping rules:
2058  *  - If we have called the "interrupt" function for all devices, and all of
2059  *    them have reported "nothing processed" (returned 0), then we will go to
2060  *    sleep for a maximum of POLLJIFFIES_NORMAL jiffies.
2061  *  - If anyone calls uislib_force_channel_interrupt(), the above jiffy
2062  *    sleep will be interrupted, and we will resume calling the "interrupt"
2063  *    function for all devices.
2064  *  - The list of devices is dynamically re-ordered in order to
2065  *    attempt to preserve fairness.  Whenever we spin thru the list of
2066  *    devices and call the dev->interrupt() function, if we find
2067  *    devices which report that there is still more work to do, the
2068  *    the first such device we find is moved to the end of the device
2069  *    list.  This ensures that extremely busy devices don't starve out
2070  *    less-busy ones.
2071  *
2072  */
2073 static int
2074 Process_Incoming(void *v)
2075 {
2076         unsigned long long cur_cycles, old_cycles, idle_cycles, delta_cycles;
2077         struct list_head *new_tail = NULL;
2078         int i;
2079         UIS_DAEMONIZE("dev_incoming");
2080         for (i = 0; i < 16; i++) {
2081                 old_cycles = get_cycles();
2082                 wait_event_timeout(Wakeup_Polling_Device_Channels,
2083                                    0, POLLJIFFIES_NORMAL);
2084                 cur_cycles = get_cycles();
2085                 if (wait_cycles == 0) {
2086                         wait_cycles = (cur_cycles - old_cycles);
2087                 } else {
2088                         if (wait_cycles < (cur_cycles - old_cycles))
2089                                 wait_cycles = (cur_cycles - old_cycles);
2090                 }
2091         }
2092         LOGINF("wait_cycles=%llu", wait_cycles);
2093         cycles_before_wait = wait_cycles;
2094         idle_cycles = 0;
2095         Go_Polling_Device_Channels = 0;
2096         while (1) {
2097                 struct list_head *lelt, *tmp;
2098                 struct device_info *dev = NULL;
2099
2100                 /* poll each channel for input */
2101                 LOCKSEM_UNINTERRUPTIBLE(&Lock_Polling_Device_Channels);
2102                 new_tail = NULL;
2103                 list_for_each_safe(lelt, tmp, &List_Polling_Device_Channels) {
2104                         int rc = 0;
2105                         dev = list_entry(lelt, struct device_info,
2106                                          list_polling_device_channels);
2107                         LOCKSEM_UNINTERRUPTIBLE(&dev->interrupt_callback_lock);
2108                         if (dev->interrupt)
2109                                 rc = dev->interrupt(dev->interrupt_context);
2110                         else
2111                                 continue;
2112                         UNLOCKSEM(&dev->interrupt_callback_lock);
2113                         if (rc) {
2114                                 /* dev->interrupt returned, but there
2115                                 * is still more work to do.
2116                                 * Reschedule work to occur as soon as
2117                                 * possible. */
2118                                 idle_cycles = 0;
2119                                 if (new_tail == NULL) {
2120                                         dev->first_busy_cnt++;
2121                                         if (!
2122                                             (list_is_last
2123                                              (lelt,
2124                                               &List_Polling_Device_Channels))) {
2125                                                 new_tail = lelt;
2126                                                 dev->moved_to_tail_cnt++;
2127                                         } else
2128                                                 dev->last_on_list_cnt++;
2129                                 }
2130
2131                         }
2132                         if (Incoming_ThreadInfo.should_stop)
2133                                 break;
2134                 }
2135                 if (new_tail != NULL) {
2136                         tot_moved_to_tail_cnt++;
2137                         list_move_tail(new_tail, &List_Polling_Device_Channels);
2138                 }
2139                 UNLOCKSEM(&Lock_Polling_Device_Channels);
2140                 cur_cycles = get_cycles();
2141                 delta_cycles = cur_cycles - old_cycles;
2142                 old_cycles = cur_cycles;
2143
2144                 /* At this point, we have scanned thru all of the
2145                 * channels, and at least one of the following is true:
2146                 * - there is no input waiting on any of the channels
2147                 * - we have received a signal to stop this thread
2148                 */
2149                 if (Incoming_ThreadInfo.should_stop)
2150                         break;
2151                 if (en_smart_wakeup == 0xFF) {
2152                         LOGINF("en_smart_wakeup set to 0xff, to force exiting process_incoming");
2153                         break;
2154                 }
2155                 /* wait for POLLJIFFIES_NORMAL jiffies, or until
2156                 * someone wakes up Wakeup_Polling_Device_Channels,
2157                 * whichever comes first only do a wait when we have
2158                 * been idle for cycles_before_wait cycles.
2159                 */
2160                 if (idle_cycles > cycles_before_wait) {
2161                         Go_Polling_Device_Channels = 0;
2162                         tot_wait_cnt++;
2163                         wait_event_timeout(Wakeup_Polling_Device_Channels,
2164                                            Go_Polling_Device_Channels,
2165                                            POLLJIFFIES_NORMAL);
2166                         Go_Polling_Device_Channels = 1;
2167                 } else {
2168                         tot_schedule_cnt++;
2169                         schedule();
2170                         idle_cycles = idle_cycles + delta_cycles;
2171                 }
2172         }
2173         DBGINF("exiting.\n");
2174         complete_and_exit(&Incoming_ThreadInfo.has_stopped, 0);
2175 }
2176
2177 static BOOL
2178 Initialize_incoming_thread(void)
2179 {
2180         if (Incoming_Thread_Started)
2181                 return TRUE;
2182         if (!uisthread_start(&Incoming_ThreadInfo,
2183                              &Process_Incoming, NULL, "dev_incoming")) {
2184                 LOGERR("uisthread_start Initialize_incoming_thread ****FAILED");
2185                 return FALSE;
2186         }
2187         Incoming_Thread_Started = TRUE;
2188         return TRUE;
2189 }
2190
2191 /*  Add a new device/channel to the list being processed by
2192  *  Process_Incoming().
2193  *  <interrupt> - indicates the function to call periodically.
2194  *  <interrupt_context> - indicates the data to pass to the <interrupt>
2195  *                        function.
2196  */
2197 void
2198 uislib_enable_channel_interrupts(U32 busNo, U32 devNo,
2199                                  int (*interrupt)(void *),
2200                                  void *interrupt_context)
2201 {
2202         struct device_info *dev;
2203         dev = find_dev(busNo, devNo);
2204         if (!dev) {
2205                 LOGERR("%s busNo=%d, devNo=%d", __func__, (int) (busNo),
2206                        (int) (devNo));
2207                 return;
2208         }
2209         LOCKSEM_UNINTERRUPTIBLE(&Lock_Polling_Device_Channels);
2210         Initialize_incoming_thread();
2211         dev->interrupt = interrupt;
2212         dev->interrupt_context = interrupt_context;
2213         dev->polling = TRUE;
2214         list_add_tail(&(dev->list_polling_device_channels),
2215                       &List_Polling_Device_Channels);
2216         UNLOCKSEM(&Lock_Polling_Device_Channels);
2217 }
2218 EXPORT_SYMBOL_GPL(uislib_enable_channel_interrupts);
2219
2220 /*  Remove a device/channel from the list being processed by
2221  *  Process_Incoming().
2222  */
2223 void
2224 uislib_disable_channel_interrupts(U32 busNo, U32 devNo)
2225 {
2226         struct device_info *dev;
2227         dev = find_dev(busNo, devNo);
2228         if (!dev) {
2229                 LOGERR("%s busNo=%d, devNo=%d", __func__, (int) (busNo),
2230                        (int) (devNo));
2231                 return;
2232         }
2233         LOCKSEM_UNINTERRUPTIBLE(&Lock_Polling_Device_Channels);
2234         list_del(&dev->list_polling_device_channels);
2235         dev->polling = FALSE;
2236         dev->interrupt = NULL;
2237         UNLOCKSEM(&Lock_Polling_Device_Channels);
2238 }
2239 EXPORT_SYMBOL_GPL(uislib_disable_channel_interrupts);
2240
2241 static void
2242 do_wakeup_polling_device_channels(struct work_struct *dummy)
2243 {
2244         if (!Go_Polling_Device_Channels) {
2245                 Go_Polling_Device_Channels = 1;
2246                 wake_up(&Wakeup_Polling_Device_Channels);
2247         }
2248 }
2249
2250 static DECLARE_WORK(Work_wakeup_polling_device_channels,
2251                     do_wakeup_polling_device_channels);
2252
2253 /*  Call this function when you want to send a hint to Process_Incoming() that
2254  *  your device might have more requests.
2255  */
2256 void
2257 uislib_force_channel_interrupt(U32 busNo, U32 devNo)
2258 {
2259         if (en_smart_wakeup == 0)
2260                 return;
2261         if (Go_Polling_Device_Channels)
2262                 return;
2263         /* The point of using schedule_work() instead of just doing
2264          * the work inline is to force a slight delay before waking up
2265          * the Process_Incoming() thread.
2266          */
2267         tot_wakeup_cnt++;
2268         schedule_work(&Work_wakeup_polling_device_channels);
2269 }
2270 EXPORT_SYMBOL_GPL(uislib_force_channel_interrupt);
2271
2272 /*****************************************************/
2273 /* Module Init & Exit functions                      */
2274 /*****************************************************/
2275
2276 static int __init
2277 uislib_mod_init(void)
2278 {
2279
2280         LOGINF("MONITORAPIS");
2281
2282         LOGINF("sizeof(struct uiscmdrsp):%lu bytes\n",
2283                (ulong) sizeof(struct uiscmdrsp));
2284         LOGINF("sizeof(struct phys_info):%lu\n",
2285                (ulong) sizeof(struct phys_info));
2286         LOGINF("sizeof(uiscmdrsp_scsi):%lu\n",
2287                (ulong) sizeof(struct uiscmdrsp_scsi));
2288         LOGINF("sizeof(uiscmdrsp_net):%lu\n",
2289                (ulong) sizeof(struct uiscmdrsp_net));
2290         LOGINF("sizeof(CONTROLVM_MESSAGE):%lu bytes\n",
2291                (ulong) sizeof(CONTROLVM_MESSAGE));
2292         LOGINF("sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL):%lu bytes\n",
2293                (ulong) sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL));
2294         LOGINF("sizeof(CHANNEL_HEADER):%lu bytes\n",
2295                (ulong) sizeof(CHANNEL_HEADER));
2296         LOGINF("sizeof(ULTRA_IO_CHANNEL_PROTOCOL):%lu bytes\n",
2297                (ulong) sizeof(ULTRA_IO_CHANNEL_PROTOCOL));
2298         LOGINF("SIZEOF_CMDRSP:%lu bytes\n", SIZEOF_CMDRSP);
2299         LOGINF("SIZEOF_PROTOCOL:%lu bytes\n", SIZEOF_PROTOCOL);
2300
2301         /* initialize global pointers to NULL */
2302         BusListHead = NULL;
2303         BusListCount = MaxBusCount = 0;
2304         rwlock_init(&BusListLock);
2305         VirtControlChanFunc = NULL;
2306
2307         /* Issue VMCALL_GET_CONTROLVM_ADDR to get CtrlChanPhysAddr and
2308          * then map this physical address to a virtual address. */
2309         POSTCODE_LINUX_2(DRIVER_ENTRY_PC, POSTCODE_SEVERITY_INFO);
2310
2311         /* create the proc entries for the channels */
2312         uislib_proc_dir = proc_mkdir(DIR_PROC_ENTRY, NULL);
2313         /* (e.g., for /proc/uislib/vbus/<x>/info) */
2314         uislib_proc_vbus_dir = proc_mkdir(DIR_VBUS_PROC_ENTRY, uislib_proc_dir);
2315
2316         vnic_proc_entry = proc_create(VNIC_PROC_ENTRY_FN, 0, uislib_proc_dir,
2317                                       &proc_vnic_fops);
2318         SET_PROC_OWNER(vnic_proc_entry, THIS_MODULE);
2319
2320         /* for testing purposes only, create the proc entries for
2321          * enqueuing Control Channel messages */
2322         chipset_proc_entry =
2323             proc_create(CHIPSET_PROC_ENTRY_FN, 0, uislib_proc_dir,
2324                         &proc_chipset_fops);
2325         SET_PROC_OWNER(chipset_proc_entry, THIS_MODULE);
2326
2327         info_proc_entry = proc_create(INFO_PROC_ENTRY_FN, 0, uislib_proc_dir,
2328                                       &proc_info_fops);
2329         SET_PROC_OWNER(info_proc_entry, THIS_MODULE);
2330
2331         platformnumber_proc_entry =
2332             proc_create(PLATFORMNUMBER_PROC_ENTRY_FN, 0, uislib_proc_dir,
2333                         &proc_platformnumber_fops);
2334         SET_PROC_OWNER(platformnumberinfo_proc_entry, THIS_MODULE);
2335
2336         cycles_before_wait_proc_entry =
2337             proc_create(CYCLES_BEFORE_WAIT_PROC_ENTRY_FN, 0, uislib_proc_dir,
2338                         &proc_cycles_before_wait_fops);
2339         SET_PROC_OWNER(cycles_before_wait_proc_entry, THIS_MODULE);
2340
2341         reset_counts_proc_entry =
2342             proc_create(RESET_COUNTS_PROC_ENTRY_FN, 0, uislib_proc_dir,
2343                         &proc_reset_counts_fops);
2344         SET_PROC_OWNER(reset_counts_proc_entry, THIS_MODULE);
2345
2346         smart_wakeup_proc_entry =
2347             proc_create(SMART_WAKEUP_PROC_ENTRY_FN, 0, uislib_proc_dir,
2348                         &proc_smart_wakeup_fops);
2349         SET_PROC_OWNER(smart_wakeup_proc_entry, THIS_MODULE);
2350
2351 #ifdef UISLIB_TEST_PROC
2352         test_proc_entry = proc_create(TEST_PROC_ENTRY_FN, 0, uislib_proc_dir,
2353                                       &proc_test_fops);
2354         SET_PROC_OWNER(test_proc_entry, THIS_MODULE);
2355
2356         bus_proc_entry = proc_create(BUS_PROC_ENTRY_FN, 0, uislib_proc_dir,
2357                                      &proc_bus_fops);
2358         SET_PROC_OWNER(bus_proc_entry, THIS_MODULE);
2359
2360         dev_proc_entry = proc_create(DEV_PROC_ENTRY_FN, 0, uislib_proc_dir,
2361                                      &proc_dev_fops);
2362         SET_PROC_OWNER(dev_proc_entry, THIS_MODULE);
2363 #endif                          /* UISLIB_TEST_PROC */
2364         POSTCODE_LINUX_3(DRIVER_EXIT_PC, 0, POSTCODE_SEVERITY_INFO);
2365         return 0;
2366 }
2367
2368 static void __exit
2369 uislib_mod_exit(void)
2370 {
2371         if (disable_proc_entry)
2372                 remove_proc_entry(DISABLE_PROC_ENTRY_FN, uislib_proc_dir);
2373         if (cycles_before_wait_proc_entry)
2374                 remove_proc_entry(CYCLES_BEFORE_WAIT_PROC_ENTRY_FN,
2375                                   uislib_proc_dir);
2376         if (reset_counts_proc_entry)
2377                 remove_proc_entry(RESET_COUNTS_PROC_ENTRY_FN, uislib_proc_dir);
2378         if (smart_wakeup_proc_entry)
2379                 remove_proc_entry(SMART_WAKEUP_PROC_ENTRY_FN, uislib_proc_dir);
2380         if (ctrlchan_proc_entry)
2381                 remove_proc_entry(CTRLCHAN_PROC_ENTRY_FN, uislib_proc_dir);
2382         if (pmem_proc_entry)
2383                 remove_proc_entry(PMEM_PROC_ENTRY_FN, uislib_proc_dir);
2384         if (info_proc_entry)
2385                 remove_proc_entry(INFO_PROC_ENTRY_FN, uislib_proc_dir);
2386         if (switch_proc_entry)
2387                 remove_proc_entry(SWITCH_PROC_ENTRY_FN, uislib_proc_dir);
2388         if (extport_proc_entry)
2389                 remove_proc_entry(EXTPORT_PROC_ENTRY_FN, uislib_proc_dir);
2390         if (platformnumber_proc_entry)
2391                 remove_proc_entry(PLATFORMNUMBER_PROC_ENTRY_FN,
2392                                   uislib_proc_dir);
2393         if (bus_proc_entry)
2394                 remove_proc_entry(BUS_PROC_ENTRY_FN, uislib_proc_dir);
2395         if (dev_proc_entry)
2396                 remove_proc_entry(DEV_PROC_ENTRY_FN, uislib_proc_dir);
2397         if (vnic_proc_entry)
2398                 remove_proc_entry(VNIC_PROC_ENTRY_FN, uislib_proc_dir);
2399         if (chipset_proc_entry)
2400                 remove_proc_entry(CHIPSET_PROC_ENTRY_FN, uislib_proc_dir);
2401         if (uislib_proc_vbus_dir)
2402                 remove_proc_entry(DIR_VBUS_PROC_ENTRY, uislib_proc_dir);
2403         if (uislib_proc_dir)
2404                 remove_proc_entry(DIR_PROC_ENTRY, NULL);
2405
2406         if (ProcReadBuffer) {
2407                 vfree(ProcReadBuffer);
2408                 ProcReadBuffer = NULL;
2409         }
2410
2411         DBGINF("goodbye.\n");
2412         return;
2413 }
2414
2415 module_init(uislib_mod_init);
2416 module_exit(uislib_mod_exit);
2417
2418 MODULE_LICENSE("GPL");
2419 MODULE_AUTHOR("Usha Srinivasan");
2420 MODULE_ALIAS("uislib");
2421   /* this is extracted during depmod and kept in modules.dep */