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