3 * Copyright (C) 2010 - 2013 UNISYS CORPORATION
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
20 #include <linux/kernel.h>
21 #include <linux/highmem.h>
22 #ifdef CONFIG_MODVERSIONS
23 #include <config/modversions.h>
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>
33 #include "diagnostics/appos_subsystems.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>
43 #include "visorchipset.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) \
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
,
124 init_msg_header(CONTROLVM_MESSAGE
*msg
, u32 id
, uint rsp
, uint svr
)
126 memset(msg
, 0, sizeof(CONTROLVM_MESSAGE
));
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
);
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
);
145 if (!ULTRA_VBUS_CHANNEL_OK_CLIENT(pChan
, NULL
)) {
146 ERRDRV("%s channel cannot be used", __func__
);
147 uislib_iounmap(pChan
);
157 create_bus(CONTROLVM_MESSAGE
*msg
, char *buf
)
159 u32 busNo
, deviceCount
;
160 struct bus_info
*tmp
, *bus
;
163 if (MaxBusCount
== BusListCount
) {
164 LOGERR("CONTROLVM_BUS_CREATE Failed: max buses:%d already created\n",
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
);
178 sizeof(struct bus_info
) +
179 (deviceCount
* sizeof(struct device_info
*));
180 bus
= kzalloc(size
, GFP_ATOMIC
);
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;
197 bus
->busNo
= bus
->guestHandle
= busNo
;
198 sprintf(bus
->name
, "%d", (int) bus
->busNo
);
199 bus
->deviceCount
= deviceCount
;
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
)
212 read_unlock(&BusListLock
);
214 /* found a bus already in the list with same busNo -
217 LOGERR("CONTROLVM_BUS_CREATE Failed: bus %d already exists.\n",
219 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC
, bus
->busNo
,
220 POSTCODE_SEVERITY_ERR
);
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
;
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
);
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
);
254 CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR
;
258 /* add bus at the head of our list */
259 write_lock(&BusListLock
);
263 bus
->next
= BusListHead
;
267 write_unlock(&BusListLock
);
269 POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC
, bus
->busNo
,
270 POSTCODE_SEVERITY_INFO
);
271 return CONTROLVM_RESP_SUCCESS
;
275 destroy_bus(CONTROLVM_MESSAGE
*msg
, char *buf
)
278 struct bus_info
*bus
, *prev
= NULL
;
279 struct guest_msgs cmd
;
282 busNo
= msg
->cmd
.destroyBus
.busNo
;
284 read_lock(&BusListLock
);
288 if (bus
->busNo
== busNo
)
295 LOGERR("CONTROLVM_BUS_DESTROY Failed: failed to find bus %d.\n",
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.",
306 read_unlock(&BusListLock
);
307 return CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED
;
310 read_unlock(&BusListLock
);
312 if (msg
->hdr
.Flags
.server
)
315 /* client messages require us to call the virtpci callback associated
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 */
330 write_lock(&BusListLock
);
331 if (prev
) /* not at head */
332 prev
->next
= bus
->next
;
334 BusListHead
= bus
->next
;
336 write_unlock(&BusListLock
);
338 if (bus
->pBusChannel
) {
339 uislib_iounmap(bus
->pBusChannel
);
340 bus
->pBusChannel
= NULL
;
344 return CONTROLVM_RESP_SUCCESS
;
348 create_device(CONTROLVM_MESSAGE
*msg
, char *buf
)
350 struct device_info
*dev
;
351 struct bus_info
*bus
;
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
);
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
;
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
);
382 pReqHandler
= ReqHandlerFind(dev
->channelTypeGuid
);
384 /* generic service handler registered for this
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
,
392 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC
, devNo
, busNo
,
393 POSTCODE_SEVERITY_ERR
);
394 result
= CONTROLVM_RESP_ERROR_CHANNEL_SIZE_TOO_SMALL
;
398 uislib_ioremap_cache(dev
->channelAddr
,
399 msg
->cmd
.createDevice
.channelBytes
);
401 LOGERR("CONTROLVM_DEVICE_CREATE Failed: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed",
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
);
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
,
423 POSTCODE_SEVERITY_ERR
);
424 read_unlock(&BusListLock
);
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.",
431 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC
,
433 POSTCODE_SEVERITY_ERR
);
434 result
= CONTROLVM_RESP_ERROR_ALREADY_DONE
;
435 read_unlock(&BusListLock
);
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
451 if (!ULTRA_VHBA_CHANNEL_OK_CLIENT
452 (dev
->chanptr
, NULL
)) {
453 LOGERR("CONTROLVM_DEVICE_CREATE Failed:[CLIENT]VHBA dev %d chan invalid.",
456 (DEVICE_CREATE_FAILURE_PC
,
458 POSTCODE_SEVERITY_ERR
);
459 result
= CONTROLVM_RESP_ERROR_CHANNEL_INVALID
;
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
=
468 cmd
.add_vhba
.intr
= dev
->intr
;
470 if (!uuid_le_cmp(dev
->channelTypeGuid
,
471 UltraVnicChannelProtocolGuid
)) {
472 wait_for_valid_guid(&((CHANNEL_HEADER
476 if (!ULTRA_VNIC_CHANNEL_OK_CLIENT
477 (dev
->chanptr
, NULL
)) {
478 LOGERR("CONTROLVM_DEVICE_CREATE Failed: VNIC[CLIENT] dev %d chan invalid.",
481 (DEVICE_CREATE_FAILURE_PC
,
483 POSTCODE_SEVERITY_ERR
);
484 result
= CONTROLVM_RESP_ERROR_CHANNEL_INVALID
;
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
=
493 cmd
.add_vhba
.intr
= dev
->intr
;
495 LOGERR("CONTROLVM_DEVICE_CREATE Failed: unknown channelTypeGuid.\n");
497 (DEVICE_CREATE_FAILURE_PC
, devNo
,
498 busNo
, POSTCODE_SEVERITY_ERR
);
499 result
= CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN
;
503 if (!VirtControlChanFunc
) {
504 LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci callback not registered.");
506 (DEVICE_CREATE_FAILURE_PC
, devNo
,
507 busNo
, POSTCODE_SEVERITY_ERR
);
508 result
= CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE
;
512 if (!VirtControlChanFunc(&cmd
)) {
513 LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci GUEST_ADD_[VHBA||VNIC] returned error.");
515 (DEVICE_CREATE_FAILURE_PC
, devNo
,
516 busNo
, POSTCODE_SEVERITY_ERR
);
517 result
= CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR
;
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
;
535 if (!msg
->hdr
.Flags
.testMessage
) {
536 uislib_iounmap(dev
->chanptr
);
545 pause_device(CONTROLVM_MESSAGE
*msg
)
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
];
568 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device %d does not exist.",
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
;
582 if (!uuid_le_cmp(dev
->channelTypeGuid
,
583 UltraVnicChannelProtocolGuid
)) {
584 cmd
.msgtype
= GUEST_PAUSE_VNIC
;
585 cmd
.pause_vnic
.chanptr
= dev
->chanptr
;
587 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: unknown channelTypeGuid.\n");
589 CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN
;
592 if (!VirtControlChanFunc
) {
593 LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: virtpci callback not registered.");
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
;
607 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: bus %d does not exist",
609 read_unlock(&BusListLock
);
610 return CONTROLVM_RESP_ERROR_BUS_INVALID
;
613 return CONTROLVM_RESP_SUCCESS
;
617 resume_device(CONTROLVM_MESSAGE
*msg
)
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
];
640 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device %d does not exist.",
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
;
654 if (!uuid_le_cmp(dev
->channelTypeGuid
,
655 UltraVnicChannelProtocolGuid
)) {
656 cmd
.msgtype
= GUEST_RESUME_VNIC
;
657 cmd
.resume_vnic
.chanptr
= dev
->chanptr
;
659 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: unknown channelTypeGuid.\n");
661 CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN
;
664 if (!VirtControlChanFunc
) {
665 LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: virtpci callback not registered.");
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
;
679 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: bus %d does not exist",
681 read_unlock(&BusListLock
);
682 return CONTROLVM_RESP_ERROR_BUS_INVALID
;
685 return CONTROLVM_RESP_SUCCESS
;
689 destroy_device(CONTROLVM_MESSAGE
*msg
, char *buf
)
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
];
713 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: device %d does not exist.",
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
;
727 if (!uuid_le_cmp(dev
->channelTypeGuid
,
728 UltraVnicChannelProtocolGuid
)) {
729 cmd
.msgtype
= GUEST_DEL_VNIC
;
730 cmd
.del_vnic
.chanptr
= dev
->chanptr
;
732 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: unknown channelTypeGuid.\n");
734 CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN
;
737 if (!VirtControlChanFunc
) {
738 LOGERR("CONTROLVM_DEVICE_DESTORY Failed: virtpci callback not registered.");
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"
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
);
762 bus
->device
[devNo
] = NULL
;
768 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: bus %d does not exist",
770 read_unlock(&BusListLock
);
771 return CONTROLVM_RESP_ERROR_BUS_INVALID
;
774 return CONTROLVM_RESP_SUCCESS
;
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
793 if (!msg
->hdr
.Flags
.testMessage
)
794 WAIT_ON_CALLBACK(VirtControlChanFunc
);
797 POSTCODE_LINUX_2(CHIPSET_INIT_EXIT_PC
, POSTCODE_SEVERITY_INFO
);
799 return CONTROLVM_RESP_SUCCESS
;
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
);
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
,
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");
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
);
876 POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC
, busNo
, POSTCODE_SEVERITY_INFO
);
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
;
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",
908 EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vhba
);
911 uislib_client_inject_resume_vhba(u32 busNo
, u32 devNo
)
913 CONTROLVM_MESSAGE msg
;
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",
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
944 POSTCODE_LINUX_4(VHBA_CREATE_ENTRY_PC
, devNo
, busNo
,
945 POSTCODE_SEVERITY_INFO
);
947 init_msg_header(&msg
, CONTROLVM_DEVICE_CREATE
, 0, 0);
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
;
957 msg
.cmd
.createDevice
.intr
= *intr
;
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
);
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
);
977 POSTCODE_LINUX_4(VHBA_CREATE_SUCCESS_PC
, devNo
, busNo
,
978 POSTCODE_SEVERITY_INFO
);
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
1003 POSTCODE_LINUX_4(VNIC_CREATE_ENTRY_PC
, devNo
, busNo
,
1004 POSTCODE_SEVERITY_INFO
);
1006 init_msg_header(&msg
, CONTROLVM_DEVICE_CREATE
, 0, 0);
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
;
1016 msg
.cmd
.createDevice
.intr
= *intr
;
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
);
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
);
1037 POSTCODE_LINUX_4(VNIC_CREATE_SUCCESS_PC
, devNo
, busNo
,
1038 POSTCODE_SEVERITY_INFO
);
1041 EXPORT_SYMBOL_GPL(uislib_client_inject_add_vnic
);
1044 uislib_client_inject_pause_vnic(u32 busNo
, u32 devNo
)
1046 CONTROLVM_MESSAGE msg
;
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",
1061 EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vnic
);
1064 uislib_client_inject_resume_vnic(u32 busNo
, u32 devNo
)
1066 CONTROLVM_MESSAGE msg
;
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",
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
);
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");
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");
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");
1137 } /* end uislib_client_add_vnic */
1138 EXPORT_SYMBOL_GPL(uislib_client_add_vnic
);
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");
1164 EXPORT_SYMBOL_GPL(uislib_client_delete_vnic
);
1165 /* end client_delete_vnic */
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
);
1178 LOGERR("uislib_malloc failed to alloc uiscmdrsp @%s:%d",
1184 EXPORT_SYMBOL_GPL(uislib_cache_alloc
);
1187 uislib_cache_free(struct kmem_cache
*cur_pool
, void *p
, char *fn
, int ln
)
1190 LOGERR("uislib_free NULL pointer @%s:%d", fn
, ln
);
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__)
1205 info_debugfs_read_helper(char **buff
, int *buff_len
)
1208 struct bus_info
*bus
;
1210 if (PLINE("\nBuses:\n") < 0)
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)
1245 if (PLINE("cycles_before_wait %llu wait_cycles:%llu\n",
1246 cycles_before_wait
, wait_cycles
) < 0)
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)
1251 if (PLINE("en_smart_wakeup %d\n", en_smart_wakeup
) < 0)
1253 if (PLINE("tot_moved_to_tail_cnt %llu\n", tot_moved_to_tail_cnt
) < 0)
1259 read_unlock(&BusListLock
);
1265 info_debugfs_read(struct file
*file
, char __user
*buf
,
1266 size_t len
, loff_t
*offset
)
1270 int remaining_bytes
= PROC_READ_BUFFER_SIZE
;
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");
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;
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",
1310 (int) (busNo
), (int) (devNo
));
1313 dev
= bus
->device
[devNo
];
1315 LOGERR("%s bad busNo, devNo=%d,%d",
1317 (int) (busNo
), (int) (devNo
));
1322 read_unlock(&BusListLock
);
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
1347 Process_Incoming(void *v
)
1349 unsigned long long cur_cycles
, old_cycles
, idle_cycles
, delta_cycles
;
1350 struct list_head
*new_tail
= NULL
;
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
);
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
;
1369 Go_Polling_Device_Channels
= 0;
1371 struct list_head
*lelt
, *tmp
;
1372 struct device_info
*dev
= NULL
;
1374 /* poll each channel for input */
1375 down(&Lock_Polling_Device_Channels
);
1377 list_for_each_safe(lelt
, tmp
, &List_Polling_Device_Channels
) {
1380 dev
= list_entry(lelt
, struct device_info
,
1381 list_polling_device_channels
);
1382 down(&dev
->interrupt_callback_lock
);
1384 rc
= dev
->interrupt(dev
->interrupt_context
);
1387 up(&dev
->interrupt_callback_lock
);
1389 /* dev->interrupt returned, but there
1390 * is still more work to do.
1391 * Reschedule work to occur as soon as
1394 if (new_tail
== NULL
) {
1395 dev
->first_busy_cnt
++;
1399 &List_Polling_Device_Channels
))) {
1401 dev
->moved_to_tail_cnt
++;
1403 dev
->last_on_list_cnt
++;
1407 if (Incoming_ThreadInfo
.should_stop
)
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
)
1426 if (en_smart_wakeup
== 0xFF) {
1427 LOGINF("en_smart_wakeup set to 0xff, to force exiting process_incoming");
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;
1438 wait_event_timeout(Wakeup_Polling_Device_Channels
,
1439 Go_Polling_Device_Channels
,
1440 POLLJIFFIES_NORMAL
);
1441 Go_Polling_Device_Channels
= 1;
1445 idle_cycles
= idle_cycles
+ delta_cycles
;
1448 DBGINF("exiting.\n");
1449 complete_and_exit(&Incoming_ThreadInfo
.has_stopped
, 0);
1453 Initialize_incoming_thread(void)
1455 if (Incoming_Thread_Started
)
1457 if (!uisthread_start(&Incoming_ThreadInfo
,
1458 &Process_Incoming
, NULL
, "dev_incoming")) {
1459 LOGERR("uisthread_start Initialize_incoming_thread ****FAILED");
1462 Incoming_Thread_Started
= 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>
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
);
1481 LOGERR("%s busNo=%d, devNo=%d", __func__
, (int) (busNo
),
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().
1500 uislib_disable_channel_interrupts(u32 busNo
, u32 devNo
)
1502 struct device_info
*dev
;
1504 dev
= find_dev(busNo
, devNo
);
1506 LOGERR("%s busNo=%d, devNo=%d", __func__
, (int) (busNo
),
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
);
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.
1534 uislib_force_channel_interrupt(u32 busNo
, u32 devNo
)
1536 if (en_smart_wakeup
== 0)
1538 if (Go_Polling_Device_Channels
)
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.
1545 schedule_work(&Work_wakeup_polling_device_channels
);
1547 EXPORT_SYMBOL_GPL(uislib_force_channel_interrupt
);
1549 /*****************************************************/
1550 /* Module Init & Exit functions */
1551 /*****************************************************/
1554 uislib_mod_init(void)
1557 if (!unisys_spar_platform
)
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 */
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
);
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
,
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
,
1610 POSTCODE_LINUX_3(DRIVER_EXIT_PC
, 0, POSTCODE_SEVERITY_INFO
);
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");
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 */