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 "commontypes.h"
30 #include <linux/version.h>
32 #include "diagnostics/appos_subsystems.h"
34 #include "vbuschannel.h"
36 #include <linux/proc_fs.h>
37 #include <linux/uaccess.h> /* for copy_from_user */
38 #include <linux/ctype.h> /* for toupper */
39 #include <linux/list.h>
42 #include "visorchipset.h"
45 #include "guestlinuxdebug.h"
47 #define SET_PROC_OWNER(x, y)
49 #define POLLJIFFIES_NORMAL 1
50 /* Choose whether or not you want to wakeup the request-polling thread
51 * after an IO termination:
52 * this is shorter than using __FILE__ (full path name) in
53 * debug/info/error messages
55 #define CURRENT_FILE_PC UISLIB_PC_uislib_c
56 #define __MYFILE__ "uislib.c"
58 /* global function pointers that act as callback functions into virtpcimod */
59 int (*VirtControlChanFunc
)(struct guest_msgs
*);
61 static int ProcReadBufferValid
;
62 static char *ProcReadBuffer
; /* Note this MUST be global,
63 * because the contents must */
64 static unsigned int chipset_inited
;
66 #define WAIT_ON_CALLBACK(handle) \
73 static struct bus_info
*BusListHead
;
74 static rwlock_t BusListLock
;
75 static int BusListCount
; /* number of buses in the list */
76 static int MaxBusCount
; /* maximum number of buses expected */
77 static U64 PhysicalDataChan
;
78 static int PlatformNumber
;
80 static struct uisthread_info Incoming_ThreadInfo
;
81 static BOOL Incoming_Thread_Started
= FALSE
;
82 static LIST_HEAD(List_Polling_Device_Channels
);
83 static unsigned long long tot_moved_to_tail_cnt
;
84 static unsigned long long tot_wait_cnt
;
85 static unsigned long long tot_wakeup_cnt
;
86 static unsigned long long tot_schedule_cnt
;
87 static int en_smart_wakeup
= 1;
88 static DEFINE_SEMAPHORE(Lock_Polling_Device_Channels
); /* unlocked */
89 static DECLARE_WAIT_QUEUE_HEAD(Wakeup_Polling_Device_Channels
);
90 static int Go_Polling_Device_Channels
;
92 #define CALLHOME_PROC_ENTRY_FN "callhome"
93 #define CALLHOME_THROTTLED_PROC_ENTRY_FN "callhome_throttled"
95 #define DIR_DEBUGFS_ENTRY "uislib"
96 static struct dentry
*dir_debugfs
;
98 #define PLATFORMNUMBER_DEBUGFS_ENTRY_FN "platform"
99 static struct dentry
*platformnumber_debugfs_read
;
101 #define CYCLES_BEFORE_WAIT_DEBUGFS_ENTRY_FN "cycles_before_wait"
102 static struct dentry
*cycles_before_wait_debugfs_read
;
104 #define SMART_WAKEUP_DEBUGFS_ENTRY_FN "smart_wakeup"
105 static struct dentry
*smart_wakeup_debugfs_entry
;
107 #define INFO_DEBUGFS_ENTRY_FN "info"
108 static struct dentry
*info_debugfs_entry
;
110 static unsigned long long cycles_before_wait
, wait_cycles
;
112 /*****************************************************/
113 /* local functions */
114 /*****************************************************/
116 static ssize_t
info_debugfs_read(struct file
*file
, char __user
*buf
,
117 size_t len
, loff_t
*offset
);
118 static const struct file_operations debugfs_info_fops
= {
119 .read
= info_debugfs_read
,
123 init_msg_header(CONTROLVM_MESSAGE
*msg
, u32 id
, uint rsp
, uint svr
)
125 memset(msg
, 0, sizeof(CONTROLVM_MESSAGE
));
127 msg
->hdr
.Flags
.responseExpected
= rsp
;
128 msg
->hdr
.Flags
.server
= svr
;
131 static __iomem
void *
132 init_vbus_channel(U64 channelAddr
, u32 channelBytes
)
134 void __iomem
*rc
= NULL
;
135 void __iomem
*pChan
= uislib_ioremap_cache(channelAddr
, channelBytes
);
137 LOGERR("CONTROLVM_BUS_CREATE error: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed",
138 (unsigned long long) channelAddr
,
139 (unsigned long long) channelBytes
);
143 if (!ULTRA_VBUS_CHANNEL_OK_CLIENT(pChan
, NULL
)) {
144 ERRDRV("%s channel cannot be used", __func__
);
145 uislib_iounmap(pChan
);
155 create_bus(CONTROLVM_MESSAGE
*msg
, char *buf
)
157 u32 busNo
, deviceCount
;
158 struct bus_info
*tmp
, *bus
;
161 if (MaxBusCount
== BusListCount
) {
162 LOGERR("CONTROLVM_BUS_CREATE Failed: max buses:%d already created\n",
164 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC
, MaxBusCount
,
165 POSTCODE_SEVERITY_ERR
);
166 return CONTROLVM_RESP_ERROR_MAX_BUSES
;
169 busNo
= msg
->cmd
.createBus
.busNo
;
170 deviceCount
= msg
->cmd
.createBus
.deviceCount
;
172 POSTCODE_LINUX_4(BUS_CREATE_ENTRY_PC
, busNo
, deviceCount
,
173 POSTCODE_SEVERITY_INFO
);
176 sizeof(struct bus_info
) +
177 (deviceCount
* sizeof(struct device_info
*));
178 bus
= kzalloc(size
, GFP_ATOMIC
);
180 LOGERR("CONTROLVM_BUS_CREATE Failed: kmalloc for bus failed.\n");
181 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC
, busNo
,
182 POSTCODE_SEVERITY_ERR
);
183 return CONTROLVM_RESP_ERROR_KMALLOC_FAILED
;
186 /* Currently by default, the bus Number is the GuestHandle.
187 * Configure Bus message can override this.
189 if (msg
->hdr
.Flags
.testMessage
) {
190 /* This implies we're the IOVM so set guest handle to 0... */
191 bus
->guestHandle
= 0;
195 bus
->busNo
= bus
->guestHandle
= busNo
;
196 sprintf(bus
->name
, "%d", (int) bus
->busNo
);
197 bus
->deviceCount
= deviceCount
;
199 (struct device_info
**) ((char *) bus
+ sizeof(struct bus_info
));
200 bus
->busInstGuid
= msg
->cmd
.createBus
.busInstGuid
;
201 bus
->busChannelBytes
= 0;
202 bus
->pBusChannel
= NULL
;
204 /* add bus to our bus list - but check for duplicates first */
205 read_lock(&BusListLock
);
206 for (tmp
= BusListHead
; tmp
; tmp
= tmp
->next
) {
207 if (tmp
->busNo
== bus
->busNo
)
210 read_unlock(&BusListLock
);
212 /* found a bus already in the list with same busNo -
215 LOGERR("CONTROLVM_BUS_CREATE Failed: bus %d already exists.\n",
217 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC
, bus
->busNo
,
218 POSTCODE_SEVERITY_ERR
);
220 return CONTROLVM_RESP_ERROR_ALREADY_DONE
;
222 if ((msg
->cmd
.createBus
.channelAddr
!= 0)
223 && (msg
->cmd
.createBus
.channelBytes
!= 0)) {
224 bus
->busChannelBytes
= msg
->cmd
.createBus
.channelBytes
;
226 init_vbus_channel(msg
->cmd
.createBus
.channelAddr
,
227 msg
->cmd
.createBus
.channelBytes
);
229 /* the msg is bound for virtpci; send guest_msgs struct to callback */
230 if (!msg
->hdr
.Flags
.server
) {
231 struct guest_msgs cmd
;
232 cmd
.msgtype
= GUEST_ADD_VBUS
;
233 cmd
.add_vbus
.busNo
= busNo
;
234 cmd
.add_vbus
.chanptr
= bus
->pBusChannel
;
235 cmd
.add_vbus
.deviceCount
= deviceCount
;
236 cmd
.add_vbus
.busTypeGuid
= msg
->cmd
.createBus
.busDataTypeGuid
;
237 cmd
.add_vbus
.busInstGuid
= msg
->cmd
.createBus
.busInstGuid
;
238 if (!VirtControlChanFunc
) {
239 LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci callback not registered.");
240 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC
, bus
->busNo
,
241 POSTCODE_SEVERITY_ERR
);
243 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE
;
245 if (!VirtControlChanFunc(&cmd
)) {
246 LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci GUEST_ADD_VBUS returned error.");
247 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC
, bus
->busNo
,
248 POSTCODE_SEVERITY_ERR
);
251 CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR
;
255 /* add bus at the head of our list */
256 write_lock(&BusListLock
);
260 bus
->next
= BusListHead
;
264 write_unlock(&BusListLock
);
266 POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC
, bus
->busNo
,
267 POSTCODE_SEVERITY_INFO
);
268 return CONTROLVM_RESP_SUCCESS
;
272 destroy_bus(CONTROLVM_MESSAGE
*msg
, char *buf
)
275 struct bus_info
*bus
, *prev
= NULL
;
278 busNo
= msg
->cmd
.destroyBus
.busNo
;
280 /* find and delete the bus */
281 read_lock(&BusListLock
);
282 for (bus
= BusListHead
; bus
; prev
= bus
, bus
= bus
->next
) {
283 if (bus
->busNo
== busNo
) {
284 /* found the bus - ensure that all device
287 for (i
= 0; i
< bus
->deviceCount
; i
++) {
288 if (bus
->device
[i
] != NULL
) {
289 LOGERR("CONTROLVM_BUS_DESTROY Failed: device %i attached to bus %d.",
291 read_unlock(&BusListLock
);
292 return CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED
;
295 read_unlock(&BusListLock
);
296 /* the msg is bound for virtpci; send
297 * guest_msgs struct to callback
299 if (!msg
->hdr
.Flags
.server
) {
300 struct guest_msgs cmd
;
301 cmd
.msgtype
= GUEST_DEL_VBUS
;
302 cmd
.del_vbus
.busNo
= busNo
;
303 if (!VirtControlChanFunc
) {
304 LOGERR("CONTROLVM_BUS_DESTROY Failed: virtpci callback not registered.");
305 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE
;
307 if (!VirtControlChanFunc(&cmd
)) {
308 LOGERR("CONTROLVM_BUS_DESTROY Failed: virtpci GUEST_DEL_VBUS returned error.");
309 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR
;
312 /* remove the bus from the list */
313 write_lock(&BusListLock
);
314 if (prev
) /* not at head */
315 prev
->next
= bus
->next
;
317 BusListHead
= bus
->next
;
319 write_unlock(&BusListLock
);
325 LOGERR("CONTROLVM_BUS_DESTROY Failed: failed to find bus %d.\n",
327 read_unlock(&BusListLock
);
328 return CONTROLVM_RESP_ERROR_ALREADY_DONE
;
330 if (bus
->pBusChannel
) {
331 uislib_iounmap(bus
->pBusChannel
);
332 bus
->pBusChannel
= NULL
;
336 return CONTROLVM_RESP_SUCCESS
;
340 create_device(CONTROLVM_MESSAGE
*msg
, char *buf
)
342 struct device_info
*dev
;
343 struct bus_info
*bus
;
345 int result
= CONTROLVM_RESP_SUCCESS
;
346 U64 minSize
= MIN_IO_CHANNEL_SIZE
;
347 ReqHandlerInfo_t
*pReqHandler
;
349 busNo
= msg
->cmd
.createDevice
.busNo
;
350 devNo
= msg
->cmd
.createDevice
.devNo
;
352 POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC
, devNo
, busNo
,
353 POSTCODE_SEVERITY_INFO
);
355 dev
= kzalloc(sizeof(struct device_info
), GFP_ATOMIC
);
357 LOGERR("CONTROLVM_DEVICE_CREATE Failed: kmalloc for dev failed.\n");
358 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC
, devNo
, busNo
,
359 POSTCODE_SEVERITY_ERR
);
360 return CONTROLVM_RESP_ERROR_KMALLOC_FAILED
;
363 dev
->channelTypeGuid
= msg
->cmd
.createDevice
.dataTypeGuid
;
364 dev
->intr
= msg
->cmd
.createDevice
.intr
;
365 dev
->channelAddr
= msg
->cmd
.createDevice
.channelAddr
;
368 sema_init(&dev
->interrupt_callback_lock
, 1); /* unlocked */
369 sprintf(dev
->devid
, "vbus%u:dev%u", (unsigned) busNo
, (unsigned) devNo
);
370 /* map the channel memory for the device. */
371 if (msg
->hdr
.Flags
.testMessage
)
372 dev
->chanptr
= (void __iomem
*)__va(dev
->channelAddr
);
374 pReqHandler
= ReqHandlerFind(dev
->channelTypeGuid
);
376 /* generic service handler registered for this
379 minSize
= pReqHandler
->min_channel_bytes
;
380 if (minSize
> msg
->cmd
.createDevice
.channelBytes
) {
381 LOGERR("CONTROLVM_DEVICE_CREATE Failed: channel size is too small, channel size:0x%lx, required size:0x%lx",
382 (ulong
) msg
->cmd
.createDevice
.channelBytes
,
384 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC
, devNo
, busNo
,
385 POSTCODE_SEVERITY_ERR
);
386 result
= CONTROLVM_RESP_ERROR_CHANNEL_SIZE_TOO_SMALL
;
390 uislib_ioremap_cache(dev
->channelAddr
,
391 msg
->cmd
.createDevice
.channelBytes
);
393 LOGERR("CONTROLVM_DEVICE_CREATE Failed: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed",
395 msg
->cmd
.createDevice
.channelBytes
);
396 result
= CONTROLVM_RESP_ERROR_IOREMAP_FAILED
;
397 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC
, devNo
, busNo
,
398 POSTCODE_SEVERITY_ERR
);
402 dev
->devInstGuid
= msg
->cmd
.createDevice
.devInstGuid
;
403 dev
->channelBytes
= msg
->cmd
.createDevice
.channelBytes
;
405 read_lock(&BusListLock
);
406 for (bus
= BusListHead
; bus
; bus
= bus
->next
) {
407 if (bus
->busNo
== busNo
) {
408 /* make sure the device number is valid */
409 if (devNo
>= bus
->deviceCount
) {
410 LOGERR("CONTROLVM_DEVICE_CREATE Failed: device (%d) >= deviceCount (%d).",
411 devNo
, bus
->deviceCount
);
412 result
= CONTROLVM_RESP_ERROR_MAX_DEVICES
;
413 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC
,
415 POSTCODE_SEVERITY_ERR
);
416 read_unlock(&BusListLock
);
419 /* make sure this device is not already set */
420 if (bus
->device
[devNo
]) {
421 LOGERR("CONTROLVM_DEVICE_CREATE Failed: device %d is already exists.",
423 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC
,
425 POSTCODE_SEVERITY_ERR
);
426 result
= CONTROLVM_RESP_ERROR_ALREADY_DONE
;
427 read_unlock(&BusListLock
);
430 read_unlock(&BusListLock
);
431 /* the msg is bound for virtpci; send
432 * guest_msgs struct to callback
434 if (!msg
->hdr
.Flags
.server
) {
435 struct guest_msgs cmd
;
436 if (!uuid_le_cmp(dev
->channelTypeGuid
,
437 UltraVhbaChannelProtocolGuid
)) {
438 wait_for_valid_guid(&((CHANNEL_HEADER
442 if (!ULTRA_VHBA_CHANNEL_OK_CLIENT
443 (dev
->chanptr
, NULL
)) {
444 LOGERR("CONTROLVM_DEVICE_CREATE Failed:[CLIENT]VHBA dev %d chan invalid.",
447 (DEVICE_CREATE_FAILURE_PC
,
449 POSTCODE_SEVERITY_ERR
);
450 result
= CONTROLVM_RESP_ERROR_CHANNEL_INVALID
;
453 cmd
.msgtype
= GUEST_ADD_VHBA
;
454 cmd
.add_vhba
.chanptr
= dev
->chanptr
;
455 cmd
.add_vhba
.busNo
= busNo
;
456 cmd
.add_vhba
.deviceNo
= devNo
;
457 cmd
.add_vhba
.devInstGuid
=
459 cmd
.add_vhba
.intr
= dev
->intr
;
461 if (!uuid_le_cmp(dev
->channelTypeGuid
,
462 UltraVnicChannelProtocolGuid
)) {
463 wait_for_valid_guid(&((CHANNEL_HEADER
467 if (!ULTRA_VNIC_CHANNEL_OK_CLIENT
468 (dev
->chanptr
, NULL
)) {
469 LOGERR("CONTROLVM_DEVICE_CREATE Failed: VNIC[CLIENT] dev %d chan invalid.",
472 (DEVICE_CREATE_FAILURE_PC
,
474 POSTCODE_SEVERITY_ERR
);
475 result
= CONTROLVM_RESP_ERROR_CHANNEL_INVALID
;
478 cmd
.msgtype
= GUEST_ADD_VNIC
;
479 cmd
.add_vnic
.chanptr
= dev
->chanptr
;
480 cmd
.add_vnic
.busNo
= busNo
;
481 cmd
.add_vnic
.deviceNo
= devNo
;
482 cmd
.add_vnic
.devInstGuid
=
484 cmd
.add_vhba
.intr
= dev
->intr
;
486 LOGERR("CONTROLVM_DEVICE_CREATE Failed: unknown channelTypeGuid.\n");
488 (DEVICE_CREATE_FAILURE_PC
, devNo
,
489 busNo
, POSTCODE_SEVERITY_ERR
);
490 result
= CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN
;
494 if (!VirtControlChanFunc
) {
495 LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci callback not registered.");
497 (DEVICE_CREATE_FAILURE_PC
, devNo
,
498 busNo
, POSTCODE_SEVERITY_ERR
);
499 result
= CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE
;
503 if (!VirtControlChanFunc(&cmd
)) {
504 LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci GUEST_ADD_[VHBA||VNIC] returned error.");
506 (DEVICE_CREATE_FAILURE_PC
, devNo
,
507 busNo
, POSTCODE_SEVERITY_ERR
);
508 result
= CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR
;
512 bus
->device
[devNo
] = dev
;
513 POSTCODE_LINUX_4(DEVICE_CREATE_SUCCESS_PC
, devNo
, busNo
,
514 POSTCODE_SEVERITY_INFO
);
515 return CONTROLVM_RESP_SUCCESS
;
518 read_unlock(&BusListLock
);
520 LOGERR("CONTROLVM_DEVICE_CREATE Failed: failed to find bus %d.", busNo
);
521 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC
, devNo
, busNo
,
522 POSTCODE_SEVERITY_ERR
);
523 result
= CONTROLVM_RESP_ERROR_BUS_INVALID
;
526 if (!msg
->hdr
.Flags
.testMessage
) {
527 uislib_iounmap(dev
->chanptr
);
536 pause_device(CONTROLVM_MESSAGE
*msg
)
539 struct bus_info
*bus
;
540 struct device_info
*dev
;
541 struct guest_msgs cmd
;
543 busNo
= msg
->cmd
.deviceChangeState
.busNo
;
544 devNo
= msg
->cmd
.deviceChangeState
.devNo
;
546 read_lock(&BusListLock
);
547 for (bus
= BusListHead
; bus
; bus
= bus
->next
) {
548 if (bus
->busNo
== busNo
) {
549 /* make sure the device number is valid */
550 if (devNo
>= bus
->deviceCount
) {
551 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device(%d) >= deviceCount(%d).",
552 devNo
, bus
->deviceCount
);
553 read_unlock(&BusListLock
);
554 return CONTROLVM_RESP_ERROR_DEVICE_INVALID
;
556 /* make sure this device exists */
557 dev
= bus
->device
[devNo
];
559 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device %d does not exist.",
561 read_unlock(&BusListLock
);
562 return CONTROLVM_RESP_ERROR_ALREADY_DONE
;
564 read_unlock(&BusListLock
);
565 /* the msg is bound for virtpci; send
566 * guest_msgs struct to callback
568 if (!uuid_le_cmp(dev
->channelTypeGuid
,
569 UltraVhbaChannelProtocolGuid
)) {
570 cmd
.msgtype
= GUEST_PAUSE_VHBA
;
571 cmd
.pause_vhba
.chanptr
= dev
->chanptr
;
573 if (!uuid_le_cmp(dev
->channelTypeGuid
,
574 UltraVnicChannelProtocolGuid
)) {
575 cmd
.msgtype
= GUEST_PAUSE_VNIC
;
576 cmd
.pause_vnic
.chanptr
= dev
->chanptr
;
578 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: unknown channelTypeGuid.\n");
580 CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN
;
583 if (!VirtControlChanFunc
) {
584 LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: virtpci callback not registered.");
586 CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE
;
589 if (!VirtControlChanFunc(&cmd
)) {
590 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: virtpci GUEST_PAUSE_[VHBA||VNIC] returned error.");
591 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR
;
598 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: bus %d does not exist",
600 read_unlock(&BusListLock
);
601 return CONTROLVM_RESP_ERROR_BUS_INVALID
;
604 return CONTROLVM_RESP_SUCCESS
;
608 resume_device(CONTROLVM_MESSAGE
*msg
)
611 struct bus_info
*bus
;
612 struct device_info
*dev
;
613 struct guest_msgs cmd
;
615 busNo
= msg
->cmd
.deviceChangeState
.busNo
;
616 devNo
= msg
->cmd
.deviceChangeState
.devNo
;
618 read_lock(&BusListLock
);
619 for (bus
= BusListHead
; bus
; bus
= bus
->next
) {
620 if (bus
->busNo
== busNo
) {
621 /* make sure the device number is valid */
622 if (devNo
>= bus
->deviceCount
) {
623 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device(%d) >= deviceCount(%d).",
624 devNo
, bus
->deviceCount
);
625 read_unlock(&BusListLock
);
626 return CONTROLVM_RESP_ERROR_DEVICE_INVALID
;
628 /* make sure this device exists */
629 dev
= bus
->device
[devNo
];
631 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device %d does not exist.",
633 read_unlock(&BusListLock
);
634 return CONTROLVM_RESP_ERROR_ALREADY_DONE
;
636 read_unlock(&BusListLock
);
637 /* the msg is bound for virtpci; send
638 * guest_msgs struct to callback
640 if (!uuid_le_cmp(dev
->channelTypeGuid
,
641 UltraVhbaChannelProtocolGuid
)) {
642 cmd
.msgtype
= GUEST_RESUME_VHBA
;
643 cmd
.resume_vhba
.chanptr
= dev
->chanptr
;
645 if (!uuid_le_cmp(dev
->channelTypeGuid
,
646 UltraVnicChannelProtocolGuid
)) {
647 cmd
.msgtype
= GUEST_RESUME_VNIC
;
648 cmd
.resume_vnic
.chanptr
= dev
->chanptr
;
650 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: unknown channelTypeGuid.\n");
652 CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN
;
655 if (!VirtControlChanFunc
) {
656 LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: virtpci callback not registered.");
658 CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE
;
661 if (!VirtControlChanFunc(&cmd
)) {
662 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: virtpci GUEST_RESUME_[VHBA||VNIC] returned error.");
663 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR
;
670 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: bus %d does not exist",
672 read_unlock(&BusListLock
);
673 return CONTROLVM_RESP_ERROR_BUS_INVALID
;
676 return CONTROLVM_RESP_SUCCESS
;
680 destroy_device(CONTROLVM_MESSAGE
*msg
, char *buf
)
683 struct bus_info
*bus
;
684 struct device_info
*dev
;
685 struct guest_msgs cmd
;
687 busNo
= msg
->cmd
.destroyDevice
.busNo
;
688 devNo
= msg
->cmd
.destroyDevice
.devNo
;
690 read_lock(&BusListLock
);
691 LOGINF("destroy_device called for busNo=%u, devNo=%u", busNo
, devNo
);
692 for (bus
= BusListHead
; bus
; bus
= bus
->next
) {
693 if (bus
->busNo
== busNo
) {
694 /* make sure the device number is valid */
695 if (devNo
>= bus
->deviceCount
) {
696 LOGERR("CONTROLVM_DEVICE_DESTORY Failed: device(%d) >= deviceCount(%d).",
697 devNo
, bus
->deviceCount
);
698 read_unlock(&BusListLock
);
699 return CONTROLVM_RESP_ERROR_DEVICE_INVALID
;
701 /* make sure this device exists */
702 dev
= bus
->device
[devNo
];
704 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: device %d does not exist.",
706 read_unlock(&BusListLock
);
707 return CONTROLVM_RESP_ERROR_ALREADY_DONE
;
709 read_unlock(&BusListLock
);
710 /* the msg is bound for virtpci; send
711 * guest_msgs struct to callback
713 if (!uuid_le_cmp(dev
->channelTypeGuid
,
714 UltraVhbaChannelProtocolGuid
)) {
715 cmd
.msgtype
= GUEST_DEL_VHBA
;
716 cmd
.del_vhba
.chanptr
= dev
->chanptr
;
718 if (!uuid_le_cmp(dev
->channelTypeGuid
,
719 UltraVnicChannelProtocolGuid
)) {
720 cmd
.msgtype
= GUEST_DEL_VNIC
;
721 cmd
.del_vnic
.chanptr
= dev
->chanptr
;
723 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: unknown channelTypeGuid.\n");
725 CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN
;
728 if (!VirtControlChanFunc
) {
729 LOGERR("CONTROLVM_DEVICE_DESTORY Failed: virtpci callback not registered.");
731 CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE
;
734 if (!VirtControlChanFunc(&cmd
)) {
735 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: virtpci GUEST_DEL_[VHBA||VNIC] returned error.");
736 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR
;
738 /* you must disable channel interrupts BEFORE you unmap the channel,
739 * because if you unmap first, there may still be some activity going
740 * on which accesses the channel and you will get a "unable to handle
741 * kernel paging request"
744 LOGINF("calling uislib_disable_channel_interrupts");
745 uislib_disable_channel_interrupts(busNo
, devNo
);
747 /* unmap the channel memory for the device. */
748 if (!msg
->hdr
.Flags
.testMessage
) {
749 LOGINF("destroy_device, doing iounmap");
750 uislib_iounmap(dev
->chanptr
);
753 bus
->device
[devNo
] = NULL
;
759 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: bus %d does not exist",
761 read_unlock(&BusListLock
);
762 return CONTROLVM_RESP_ERROR_BUS_INVALID
;
765 return CONTROLVM_RESP_SUCCESS
;
769 init_chipset(CONTROLVM_MESSAGE
*msg
, char *buf
)
771 POSTCODE_LINUX_2(CHIPSET_INIT_ENTRY_PC
, POSTCODE_SEVERITY_INFO
);
773 MaxBusCount
= msg
->cmd
.initChipset
.busCount
;
774 PlatformNumber
= msg
->cmd
.initChipset
.platformNumber
;
775 PhysicalDataChan
= 0;
777 /* We need to make sure we have our functions registered
778 * before processing messages. If we are a test vehicle the
779 * testMessage for init_chipset will be set. We can ignore the
780 * waits for the callbacks, since this will be manually entered
781 * from a user. If no testMessage is set, we will wait for the
784 if (!msg
->hdr
.Flags
.testMessage
)
785 WAIT_ON_CALLBACK(VirtControlChanFunc
);
788 POSTCODE_LINUX_2(CHIPSET_INIT_EXIT_PC
, POSTCODE_SEVERITY_INFO
);
790 return CONTROLVM_RESP_SUCCESS
;
794 delete_bus_glue(u32 busNo
)
796 CONTROLVM_MESSAGE msg
;
798 init_msg_header(&msg
, CONTROLVM_BUS_DESTROY
, 0, 0);
799 msg
.cmd
.destroyBus
.busNo
= busNo
;
800 if (destroy_bus(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
) {
801 LOGERR("destroy_bus failed. busNo=0x%x\n", busNo
);
808 delete_device_glue(u32 busNo
, u32 devNo
)
810 CONTROLVM_MESSAGE msg
;
812 init_msg_header(&msg
, CONTROLVM_DEVICE_DESTROY
, 0, 0);
813 msg
.cmd
.destroyDevice
.busNo
= busNo
;
814 msg
.cmd
.destroyDevice
.devNo
= devNo
;
815 if (destroy_device(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
) {
816 LOGERR("destroy_device failed. busNo=0x%x devNo=0x%x\n", busNo
,
824 uislib_client_inject_add_bus(u32 busNo
, uuid_le instGuid
,
825 U64 channelAddr
, ulong nChannelBytes
)
827 CONTROLVM_MESSAGE msg
;
829 LOGINF("enter busNo=0x%x\n", busNo
);
830 /* step 0: init the chipset */
831 POSTCODE_LINUX_3(CHIPSET_INIT_ENTRY_PC
, busNo
, POSTCODE_SEVERITY_INFO
);
833 if (!chipset_inited
) {
834 /* step: initialize the chipset */
835 init_msg_header(&msg
, CONTROLVM_CHIPSET_INIT
, 0, 0);
836 /* this change is needed so that console will come up
837 * OK even when the bus 0 create comes in late. If the
838 * bus 0 create is the first create, then the add_vnic
839 * will work fine, but if the bus 0 create arrives
840 * after number 4, then the add_vnic will fail, and the
841 * ultraboot will fail.
843 msg
.cmd
.initChipset
.busCount
= 23;
844 msg
.cmd
.initChipset
.switchCount
= 0;
845 if (init_chipset(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
) {
846 LOGERR("init_chipset failed.\n");
849 LOGINF("chipset initialized\n");
850 POSTCODE_LINUX_3(CHIPSET_INIT_EXIT_PC
, busNo
,
851 POSTCODE_SEVERITY_INFO
);
854 /* step 1: create a bus */
855 POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC
, busNo
, POSTCODE_SEVERITY_WARNING
);
856 init_msg_header(&msg
, CONTROLVM_BUS_CREATE
, 0, 0);
857 msg
.cmd
.createBus
.busNo
= busNo
;
858 msg
.cmd
.createBus
.deviceCount
= 23; /* devNo+1; */
859 msg
.cmd
.createBus
.channelAddr
= channelAddr
;
860 msg
.cmd
.createBus
.channelBytes
= nChannelBytes
;
861 if (create_bus(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
) {
862 LOGERR("create_bus failed.\n");
863 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC
, busNo
,
864 POSTCODE_SEVERITY_ERR
);
867 POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC
, busNo
, POSTCODE_SEVERITY_INFO
);
871 EXPORT_SYMBOL_GPL(uislib_client_inject_add_bus
);
875 uislib_client_inject_del_bus(u32 busNo
)
877 return delete_bus_glue(busNo
);
879 EXPORT_SYMBOL_GPL(uislib_client_inject_del_bus
);
882 uislib_client_inject_pause_vhba(u32 busNo
, u32 devNo
)
884 CONTROLVM_MESSAGE msg
;
887 init_msg_header(&msg
, CONTROLVM_DEVICE_CHANGESTATE
, 0, 0);
888 msg
.cmd
.deviceChangeState
.busNo
= busNo
;
889 msg
.cmd
.deviceChangeState
.devNo
= devNo
;
890 msg
.cmd
.deviceChangeState
.state
= SegmentStateStandby
;
891 rc
= pause_device(&msg
);
892 if (rc
!= CONTROLVM_RESP_SUCCESS
) {
893 LOGERR("VHBA pause_device failed. busNo=0x%x devNo=0x%x\n",
899 EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vhba
);
902 uislib_client_inject_resume_vhba(u32 busNo
, u32 devNo
)
904 CONTROLVM_MESSAGE msg
;
907 init_msg_header(&msg
, CONTROLVM_DEVICE_CHANGESTATE
, 0, 0);
908 msg
.cmd
.deviceChangeState
.busNo
= busNo
;
909 msg
.cmd
.deviceChangeState
.devNo
= devNo
;
910 msg
.cmd
.deviceChangeState
.state
= SegmentStateRunning
;
911 rc
= resume_device(&msg
);
912 if (rc
!= CONTROLVM_RESP_SUCCESS
) {
913 LOGERR("VHBA resume_device failed. busNo=0x%x devNo=0x%x\n",
920 EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vhba
);
923 uislib_client_inject_add_vhba(u32 busNo
, u32 devNo
,
924 U64 phys_chan_addr
, u32 chan_bytes
,
925 int is_test_addr
, uuid_le instGuid
,
926 struct InterruptInfo
*intr
)
928 CONTROLVM_MESSAGE msg
;
930 LOGINF(" enter busNo=0x%x devNo=0x%x\n", busNo
, devNo
);
931 /* chipset init'ed with bus bus has been previously created -
932 * Verify it still exists step 2: create the VHBA device on the
935 POSTCODE_LINUX_4(VHBA_CREATE_ENTRY_PC
, devNo
, busNo
,
936 POSTCODE_SEVERITY_INFO
);
938 init_msg_header(&msg
, CONTROLVM_DEVICE_CREATE
, 0, 0);
940 /* signify that the physical channel address does NOT
941 * need to be ioremap()ed
943 msg
.hdr
.Flags
.testMessage
= 1;
944 msg
.cmd
.createDevice
.busNo
= busNo
;
945 msg
.cmd
.createDevice
.devNo
= devNo
;
946 msg
.cmd
.createDevice
.devInstGuid
= instGuid
;
948 msg
.cmd
.createDevice
.intr
= *intr
;
950 memset(&msg
.cmd
.createDevice
.intr
, 0,
951 sizeof(struct InterruptInfo
));
952 msg
.cmd
.createDevice
.channelAddr
= phys_chan_addr
;
953 if (chan_bytes
< MIN_IO_CHANNEL_SIZE
) {
954 LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n",
955 chan_bytes
, (unsigned int) MIN_IO_CHANNEL_SIZE
);
956 POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC
, chan_bytes
,
957 MIN_IO_CHANNEL_SIZE
, POSTCODE_SEVERITY_ERR
);
960 msg
.cmd
.createDevice
.channelBytes
= chan_bytes
;
961 msg
.cmd
.createDevice
.dataTypeGuid
= UltraVhbaChannelProtocolGuid
;
962 if (create_device(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
) {
963 LOGERR("VHBA create_device failed.\n");
964 POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC
, devNo
, busNo
,
965 POSTCODE_SEVERITY_ERR
);
968 POSTCODE_LINUX_4(VHBA_CREATE_SUCCESS_PC
, devNo
, busNo
,
969 POSTCODE_SEVERITY_INFO
);
972 EXPORT_SYMBOL_GPL(uislib_client_inject_add_vhba
);
975 uislib_client_inject_del_vhba(u32 busNo
, u32 devNo
)
977 return delete_device_glue(busNo
, devNo
);
979 EXPORT_SYMBOL_GPL(uislib_client_inject_del_vhba
);
982 uislib_client_inject_add_vnic(u32 busNo
, u32 devNo
,
983 U64 phys_chan_addr
, u32 chan_bytes
,
984 int is_test_addr
, uuid_le instGuid
,
985 struct InterruptInfo
*intr
)
987 CONTROLVM_MESSAGE msg
;
989 LOGINF(" enter busNo=0x%x devNo=0x%x\n", busNo
, devNo
);
990 /* chipset init'ed with bus bus has been previously created -
991 * Verify it still exists step 2: create the VNIC device on the
994 POSTCODE_LINUX_4(VNIC_CREATE_ENTRY_PC
, devNo
, busNo
,
995 POSTCODE_SEVERITY_INFO
);
997 init_msg_header(&msg
, CONTROLVM_DEVICE_CREATE
, 0, 0);
999 /* signify that the physical channel address does NOT
1000 * need to be ioremap()ed
1002 msg
.hdr
.Flags
.testMessage
= 1;
1003 msg
.cmd
.createDevice
.busNo
= busNo
;
1004 msg
.cmd
.createDevice
.devNo
= devNo
;
1005 msg
.cmd
.createDevice
.devInstGuid
= instGuid
;
1007 msg
.cmd
.createDevice
.intr
= *intr
;
1009 memset(&msg
.cmd
.createDevice
.intr
, 0,
1010 sizeof(struct InterruptInfo
));
1011 msg
.cmd
.createDevice
.channelAddr
= phys_chan_addr
;
1012 if (chan_bytes
< MIN_IO_CHANNEL_SIZE
) {
1013 LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n",
1014 chan_bytes
, (unsigned int) MIN_IO_CHANNEL_SIZE
);
1015 POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC
, chan_bytes
,
1016 MIN_IO_CHANNEL_SIZE
, POSTCODE_SEVERITY_ERR
);
1019 msg
.cmd
.createDevice
.channelBytes
= chan_bytes
;
1020 msg
.cmd
.createDevice
.dataTypeGuid
= UltraVnicChannelProtocolGuid
;
1021 if (create_device(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
) {
1022 LOGERR("VNIC create_device failed.\n");
1023 POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC
, devNo
, busNo
,
1024 POSTCODE_SEVERITY_ERR
);
1028 POSTCODE_LINUX_4(VNIC_CREATE_SUCCESS_PC
, devNo
, busNo
,
1029 POSTCODE_SEVERITY_INFO
);
1032 EXPORT_SYMBOL_GPL(uislib_client_inject_add_vnic
);
1035 uislib_client_inject_pause_vnic(u32 busNo
, u32 devNo
)
1037 CONTROLVM_MESSAGE msg
;
1040 init_msg_header(&msg
, CONTROLVM_DEVICE_CHANGESTATE
, 0, 0);
1041 msg
.cmd
.deviceChangeState
.busNo
= busNo
;
1042 msg
.cmd
.deviceChangeState
.devNo
= devNo
;
1043 msg
.cmd
.deviceChangeState
.state
= SegmentStateStandby
;
1044 rc
= pause_device(&msg
);
1045 if (rc
!= CONTROLVM_RESP_SUCCESS
) {
1046 LOGERR("VNIC pause_device failed. busNo=0x%x devNo=0x%x\n",
1052 EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vnic
);
1055 uislib_client_inject_resume_vnic(u32 busNo
, u32 devNo
)
1057 CONTROLVM_MESSAGE msg
;
1060 init_msg_header(&msg
, CONTROLVM_DEVICE_CHANGESTATE
, 0, 0);
1061 msg
.cmd
.deviceChangeState
.busNo
= busNo
;
1062 msg
.cmd
.deviceChangeState
.devNo
= devNo
;
1063 msg
.cmd
.deviceChangeState
.state
= SegmentStateRunning
;
1064 rc
= resume_device(&msg
);
1065 if (rc
!= CONTROLVM_RESP_SUCCESS
) {
1066 LOGERR("VNIC resume_device failed. busNo=0x%x devNo=0x%x\n",
1073 EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vnic
);
1076 uislib_client_inject_del_vnic(u32 busNo
, u32 devNo
)
1078 return delete_device_glue(busNo
, devNo
);
1080 EXPORT_SYMBOL_GPL(uislib_client_inject_del_vnic
);
1083 uislib_client_add_vnic(u32 busNo
)
1085 BOOL busCreated
= FALSE
;
1086 int devNo
= 0; /* Default to 0, since only one device
1087 * will be created for this bus... */
1088 CONTROLVM_MESSAGE msg
;
1090 init_msg_header(&msg
, CONTROLVM_BUS_CREATE
, 0, 0);
1091 msg
.hdr
.Flags
.testMessage
= 1;
1092 msg
.cmd
.createBus
.busNo
= busNo
;
1093 msg
.cmd
.createBus
.deviceCount
= 4;
1094 msg
.cmd
.createBus
.channelAddr
= 0;
1095 msg
.cmd
.createBus
.channelBytes
= 0;
1096 if (create_bus(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
) {
1097 LOGERR("client create_bus failed");
1102 init_msg_header(&msg
, CONTROLVM_DEVICE_CREATE
, 0, 0);
1103 msg
.hdr
.Flags
.testMessage
= 1;
1104 msg
.cmd
.createDevice
.busNo
= busNo
;
1105 msg
.cmd
.createDevice
.devNo
= devNo
;
1106 msg
.cmd
.createDevice
.devInstGuid
= NULL_UUID_LE
;
1107 memset(&msg
.cmd
.createDevice
.intr
, 0, sizeof(struct InterruptInfo
));
1108 msg
.cmd
.createDevice
.channelAddr
= PhysicalDataChan
;
1109 msg
.cmd
.createDevice
.channelBytes
= MIN_IO_CHANNEL_SIZE
;
1110 msg
.cmd
.createDevice
.dataTypeGuid
= UltraVnicChannelProtocolGuid
;
1111 if (create_device(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
) {
1112 LOGERR("client create_device failed");
1120 init_msg_header(&msg
, CONTROLVM_BUS_DESTROY
, 0, 0);
1121 msg
.hdr
.Flags
.testMessage
= 1;
1122 msg
.cmd
.destroyBus
.busNo
= busNo
;
1123 if (destroy_bus(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
)
1124 LOGERR("client destroy_bus failed.\n");
1128 } /* end uislib_client_add_vnic */
1129 EXPORT_SYMBOL_GPL(uislib_client_add_vnic
);
1132 uislib_client_delete_vnic(u32 busNo
)
1134 int devNo
= 0; /* Default to 0, since only one device
1135 * will be created for this bus... */
1136 CONTROLVM_MESSAGE msg
;
1138 init_msg_header(&msg
, CONTROLVM_DEVICE_DESTROY
, 0, 0);
1139 msg
.hdr
.Flags
.testMessage
= 1;
1140 msg
.cmd
.destroyDevice
.busNo
= busNo
;
1141 msg
.cmd
.destroyDevice
.devNo
= devNo
;
1142 if (destroy_device(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
) {
1143 /* Don't error exit - try to see if bus can be destroyed... */
1144 LOGERR("client destroy_device failed.\n");
1147 init_msg_header(&msg
, CONTROLVM_BUS_DESTROY
, 0, 0);
1148 msg
.hdr
.Flags
.testMessage
= 1;
1149 msg
.cmd
.destroyBus
.busNo
= busNo
;
1150 if (destroy_bus(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
)
1151 LOGERR("client destroy_bus failed.\n");
1155 EXPORT_SYMBOL_GPL(uislib_client_delete_vnic
);
1156 /* end client_delete_vnic */
1159 uislib_cache_alloc(struct kmem_cache
*cur_pool
, char *fn
, int ln
)
1161 /* __GFP_NORETRY means "ok to fail", meaning kmalloc() can
1162 * return NULL. If you do NOT specify __GFP_NORETRY, Linux
1163 * will go to extreme measures to get memory for you (like,
1164 * invoke oom killer), which will probably cripple the system.
1166 void *p
= kmem_cache_alloc(cur_pool
, GFP_ATOMIC
| __GFP_NORETRY
);
1168 LOGERR("uislib_malloc failed to alloc uiscmdrsp @%s:%d",
1174 EXPORT_SYMBOL_GPL(uislib_cache_alloc
);
1177 uislib_cache_free(struct kmem_cache
*cur_pool
, void *p
, char *fn
, int ln
)
1180 LOGERR("uislib_free NULL pointer @%s:%d", fn
, ln
);
1183 kmem_cache_free(cur_pool
, p
);
1185 EXPORT_SYMBOL_GPL(uislib_cache_free
);
1187 /*****************************************************/
1188 /* proc filesystem callback functions */
1189 /*****************************************************/
1191 #define PLINE(...) uisutil_add_proc_line_ex(&tot, buff, \
1192 buff_len, __VA_ARGS__)
1195 info_debugfs_read_helper(char **buff
, int *buff_len
)
1198 struct bus_info
*bus
;
1200 if (PLINE("\nBuses:\n") < 0)
1203 read_lock(&BusListLock
);
1204 for (bus
= BusListHead
; bus
; bus
= bus
->next
) {
1206 if (PLINE(" bus=0x%p, busNo=%d, deviceCount=%d\n",
1207 bus
, bus
->busNo
, bus
->deviceCount
) < 0)
1208 goto err_done_unlock
;
1211 if (PLINE(" Devices:\n") < 0)
1212 goto err_done_unlock
;
1214 for (i
= 0; i
< bus
->deviceCount
; i
++) {
1215 if (bus
->device
[i
]) {
1216 if (PLINE(" busNo %d, device[%i]: 0x%p, chanptr=0x%p, swtch=0x%p\n",
1217 bus
->busNo
, i
, bus
->device
[i
],
1218 bus
->device
[i
]->chanptr
,
1219 bus
->device
[i
]->swtch
) < 0)
1220 goto err_done_unlock
;
1222 if (PLINE(" first_busy_cnt=%llu, moved_to_tail_cnt=%llu, last_on_list_cnt=%llu\n",
1223 bus
->device
[i
]->first_busy_cnt
,
1224 bus
->device
[i
]->moved_to_tail_cnt
,
1225 bus
->device
[i
]->last_on_list_cnt
) < 0)
1226 goto err_done_unlock
;
1230 read_unlock(&BusListLock
);
1232 if (PLINE("UisUtils_Registered_Services: %d\n",
1233 atomic_read(&UisUtils_Registered_Services
)) < 0)
1235 if (PLINE("cycles_before_wait %llu wait_cycles:%llu\n",
1236 cycles_before_wait
, wait_cycles
) < 0)
1238 if (PLINE("tot_wakeup_cnt %llu:tot_wait_cnt %llu:tot_schedule_cnt %llu\n",
1239 tot_wakeup_cnt
, tot_wait_cnt
, tot_schedule_cnt
) < 0)
1241 if (PLINE("en_smart_wakeup %d\n", en_smart_wakeup
) < 0)
1243 if (PLINE("tot_moved_to_tail_cnt %llu\n", tot_moved_to_tail_cnt
) < 0)
1249 read_unlock(&BusListLock
);
1255 info_debugfs_read(struct file
*file
, char __user
*buf
,
1256 size_t len
, loff_t
*offset
)
1260 int remaining_bytes
= PROC_READ_BUFFER_SIZE
;
1263 if (ProcReadBuffer
== NULL
) {
1264 DBGINF("ProcReadBuffer == NULL; allocating buffer.\n.");
1265 ProcReadBuffer
= vmalloc(PROC_READ_BUFFER_SIZE
);
1267 if (ProcReadBuffer
== NULL
) {
1268 LOGERR("failed to allocate buffer to provide proc data.\n");
1273 temp
= ProcReadBuffer
;
1275 if ((*offset
== 0) || (!ProcReadBufferValid
)) {
1276 DBGINF("calling info_debugfs_read_helper.\n");
1277 /* if the read fails, then -1 will be returned */
1278 totalBytes
= info_debugfs_read_helper(&temp
, &remaining_bytes
);
1279 ProcReadBufferValid
= 1;
1281 totalBytes
= strlen(ProcReadBuffer
);
1283 return simple_read_from_buffer(buf
, len
, offset
,
1284 ProcReadBuffer
, totalBytes
);
1287 static struct device_info
*
1288 find_dev(u32 busNo
, u32 devNo
)
1290 struct bus_info
*bus
;
1291 struct device_info
*dev
= NULL
;
1293 read_lock(&BusListLock
);
1294 for (bus
= BusListHead
; bus
; bus
= bus
->next
) {
1295 if (bus
->busNo
== busNo
) {
1296 /* make sure the device number is valid */
1297 if (devNo
>= bus
->deviceCount
) {
1298 LOGERR("%s bad busNo, devNo=%d,%d",
1300 (int) (busNo
), (int) (devNo
));
1303 dev
= bus
->device
[devNo
];
1305 LOGERR("%s bad busNo, devNo=%d,%d",
1307 (int) (busNo
), (int) (devNo
));
1312 read_unlock(&BusListLock
);
1316 /* This thread calls the "interrupt" function for each device that has
1317 * enabled such using uislib_enable_channel_interrupts(). The "interrupt"
1318 * function typically reads and processes the devices's channel input
1319 * queue. This thread repeatedly does this, until the thread is told to stop
1320 * (via uisthread_stop()). Sleeping rules:
1321 * - If we have called the "interrupt" function for all devices, and all of
1322 * them have reported "nothing processed" (returned 0), then we will go to
1323 * sleep for a maximum of POLLJIFFIES_NORMAL jiffies.
1324 * - If anyone calls uislib_force_channel_interrupt(), the above jiffy
1325 * sleep will be interrupted, and we will resume calling the "interrupt"
1326 * function for all devices.
1327 * - The list of devices is dynamically re-ordered in order to
1328 * attempt to preserve fairness. Whenever we spin thru the list of
1329 * devices and call the dev->interrupt() function, if we find
1330 * devices which report that there is still more work to do, the
1331 * the first such device we find is moved to the end of the device
1332 * list. This ensures that extremely busy devices don't starve out
1337 Process_Incoming(void *v
)
1339 unsigned long long cur_cycles
, old_cycles
, idle_cycles
, delta_cycles
;
1340 struct list_head
*new_tail
= NULL
;
1342 UIS_DAEMONIZE("dev_incoming");
1343 for (i
= 0; i
< 16; i
++) {
1344 old_cycles
= get_cycles();
1345 wait_event_timeout(Wakeup_Polling_Device_Channels
,
1346 0, POLLJIFFIES_NORMAL
);
1347 cur_cycles
= get_cycles();
1348 if (wait_cycles
== 0) {
1349 wait_cycles
= (cur_cycles
- old_cycles
);
1351 if (wait_cycles
< (cur_cycles
- old_cycles
))
1352 wait_cycles
= (cur_cycles
- old_cycles
);
1355 LOGINF("wait_cycles=%llu", wait_cycles
);
1356 cycles_before_wait
= wait_cycles
;
1358 Go_Polling_Device_Channels
= 0;
1360 struct list_head
*lelt
, *tmp
;
1361 struct device_info
*dev
= NULL
;
1363 /* poll each channel for input */
1364 LOCKSEM_UNINTERRUPTIBLE(&Lock_Polling_Device_Channels
);
1366 list_for_each_safe(lelt
, tmp
, &List_Polling_Device_Channels
) {
1368 dev
= list_entry(lelt
, struct device_info
,
1369 list_polling_device_channels
);
1370 LOCKSEM_UNINTERRUPTIBLE(&dev
->interrupt_callback_lock
);
1372 rc
= dev
->interrupt(dev
->interrupt_context
);
1375 UNLOCKSEM(&dev
->interrupt_callback_lock
);
1377 /* dev->interrupt returned, but there
1378 * is still more work to do.
1379 * Reschedule work to occur as soon as
1382 if (new_tail
== NULL
) {
1383 dev
->first_busy_cnt
++;
1387 &List_Polling_Device_Channels
))) {
1389 dev
->moved_to_tail_cnt
++;
1391 dev
->last_on_list_cnt
++;
1395 if (Incoming_ThreadInfo
.should_stop
)
1398 if (new_tail
!= NULL
) {
1399 tot_moved_to_tail_cnt
++;
1400 list_move_tail(new_tail
, &List_Polling_Device_Channels
);
1402 UNLOCKSEM(&Lock_Polling_Device_Channels
);
1403 cur_cycles
= get_cycles();
1404 delta_cycles
= cur_cycles
- old_cycles
;
1405 old_cycles
= cur_cycles
;
1407 /* At this point, we have scanned thru all of the
1408 * channels, and at least one of the following is true:
1409 * - there is no input waiting on any of the channels
1410 * - we have received a signal to stop this thread
1412 if (Incoming_ThreadInfo
.should_stop
)
1414 if (en_smart_wakeup
== 0xFF) {
1415 LOGINF("en_smart_wakeup set to 0xff, to force exiting process_incoming");
1418 /* wait for POLLJIFFIES_NORMAL jiffies, or until
1419 * someone wakes up Wakeup_Polling_Device_Channels,
1420 * whichever comes first only do a wait when we have
1421 * been idle for cycles_before_wait cycles.
1423 if (idle_cycles
> cycles_before_wait
) {
1424 Go_Polling_Device_Channels
= 0;
1426 wait_event_timeout(Wakeup_Polling_Device_Channels
,
1427 Go_Polling_Device_Channels
,
1428 POLLJIFFIES_NORMAL
);
1429 Go_Polling_Device_Channels
= 1;
1433 idle_cycles
= idle_cycles
+ delta_cycles
;
1436 DBGINF("exiting.\n");
1437 complete_and_exit(&Incoming_ThreadInfo
.has_stopped
, 0);
1441 Initialize_incoming_thread(void)
1443 if (Incoming_Thread_Started
)
1445 if (!uisthread_start(&Incoming_ThreadInfo
,
1446 &Process_Incoming
, NULL
, "dev_incoming")) {
1447 LOGERR("uisthread_start Initialize_incoming_thread ****FAILED");
1450 Incoming_Thread_Started
= TRUE
;
1454 /* Add a new device/channel to the list being processed by
1455 * Process_Incoming().
1456 * <interrupt> - indicates the function to call periodically.
1457 * <interrupt_context> - indicates the data to pass to the <interrupt>
1461 uislib_enable_channel_interrupts(u32 busNo
, u32 devNo
,
1462 int (*interrupt
)(void *),
1463 void *interrupt_context
)
1465 struct device_info
*dev
;
1466 dev
= find_dev(busNo
, devNo
);
1468 LOGERR("%s busNo=%d, devNo=%d", __func__
, (int) (busNo
),
1472 LOCKSEM_UNINTERRUPTIBLE(&Lock_Polling_Device_Channels
);
1473 Initialize_incoming_thread();
1474 dev
->interrupt
= interrupt
;
1475 dev
->interrupt_context
= interrupt_context
;
1476 dev
->polling
= TRUE
;
1477 list_add_tail(&(dev
->list_polling_device_channels
),
1478 &List_Polling_Device_Channels
);
1479 UNLOCKSEM(&Lock_Polling_Device_Channels
);
1481 EXPORT_SYMBOL_GPL(uislib_enable_channel_interrupts
);
1483 /* Remove a device/channel from the list being processed by
1484 * Process_Incoming().
1487 uislib_disable_channel_interrupts(u32 busNo
, u32 devNo
)
1489 struct device_info
*dev
;
1490 dev
= find_dev(busNo
, devNo
);
1492 LOGERR("%s busNo=%d, devNo=%d", __func__
, (int) (busNo
),
1496 LOCKSEM_UNINTERRUPTIBLE(&Lock_Polling_Device_Channels
);
1497 list_del(&dev
->list_polling_device_channels
);
1498 dev
->polling
= FALSE
;
1499 dev
->interrupt
= NULL
;
1500 UNLOCKSEM(&Lock_Polling_Device_Channels
);
1502 EXPORT_SYMBOL_GPL(uislib_disable_channel_interrupts
);
1505 do_wakeup_polling_device_channels(struct work_struct
*dummy
)
1507 if (!Go_Polling_Device_Channels
) {
1508 Go_Polling_Device_Channels
= 1;
1509 wake_up(&Wakeup_Polling_Device_Channels
);
1513 static DECLARE_WORK(Work_wakeup_polling_device_channels
,
1514 do_wakeup_polling_device_channels
);
1516 /* Call this function when you want to send a hint to Process_Incoming() that
1517 * your device might have more requests.
1520 uislib_force_channel_interrupt(u32 busNo
, u32 devNo
)
1522 if (en_smart_wakeup
== 0)
1524 if (Go_Polling_Device_Channels
)
1526 /* The point of using schedule_work() instead of just doing
1527 * the work inline is to force a slight delay before waking up
1528 * the Process_Incoming() thread.
1531 schedule_work(&Work_wakeup_polling_device_channels
);
1533 EXPORT_SYMBOL_GPL(uislib_force_channel_interrupt
);
1535 /*****************************************************/
1536 /* Module Init & Exit functions */
1537 /*****************************************************/
1540 uislib_mod_init(void)
1543 if (!unisys_spar_platform
)
1546 LOGINF("MONITORAPIS");
1548 LOGINF("sizeof(struct uiscmdrsp):%lu bytes\n",
1549 (ulong
) sizeof(struct uiscmdrsp
));
1550 LOGINF("sizeof(struct phys_info):%lu\n",
1551 (ulong
) sizeof(struct phys_info
));
1552 LOGINF("sizeof(uiscmdrsp_scsi):%lu\n",
1553 (ulong
) sizeof(struct uiscmdrsp_scsi
));
1554 LOGINF("sizeof(uiscmdrsp_net):%lu\n",
1555 (ulong
) sizeof(struct uiscmdrsp_net
));
1556 LOGINF("sizeof(CONTROLVM_MESSAGE):%lu bytes\n",
1557 (ulong
) sizeof(CONTROLVM_MESSAGE
));
1558 LOGINF("sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL):%lu bytes\n",
1559 (ulong
) sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL
));
1560 LOGINF("sizeof(CHANNEL_HEADER):%lu bytes\n",
1561 (ulong
) sizeof(CHANNEL_HEADER
));
1562 LOGINF("sizeof(ULTRA_IO_CHANNEL_PROTOCOL):%lu bytes\n",
1563 (ulong
) sizeof(ULTRA_IO_CHANNEL_PROTOCOL
));
1564 LOGINF("SIZEOF_CMDRSP:%lu bytes\n", SIZEOF_CMDRSP
);
1565 LOGINF("SIZEOF_PROTOCOL:%lu bytes\n", SIZEOF_PROTOCOL
);
1567 /* initialize global pointers to NULL */
1569 BusListCount
= MaxBusCount
= 0;
1570 rwlock_init(&BusListLock
);
1571 VirtControlChanFunc
= NULL
;
1573 /* Issue VMCALL_GET_CONTROLVM_ADDR to get CtrlChanPhysAddr and
1574 * then map this physical address to a virtual address. */
1575 POSTCODE_LINUX_2(DRIVER_ENTRY_PC
, POSTCODE_SEVERITY_INFO
);
1577 dir_debugfs
= debugfs_create_dir(DIR_DEBUGFS_ENTRY
, NULL
);
1579 info_debugfs_entry
= debugfs_create_file(
1580 INFO_DEBUGFS_ENTRY_FN
, 0444, dir_debugfs
, NULL
,
1581 &debugfs_info_fops
);
1583 platformnumber_debugfs_read
= debugfs_create_u32(
1584 PLATFORMNUMBER_DEBUGFS_ENTRY_FN
, 0444, dir_debugfs
,
1587 cycles_before_wait_debugfs_read
= debugfs_create_u64(
1588 CYCLES_BEFORE_WAIT_DEBUGFS_ENTRY_FN
, 0666, dir_debugfs
,
1589 &cycles_before_wait
);
1591 smart_wakeup_debugfs_entry
= debugfs_create_bool(
1592 SMART_WAKEUP_DEBUGFS_ENTRY_FN
, 0666, dir_debugfs
,
1596 POSTCODE_LINUX_3(DRIVER_EXIT_PC
, 0, POSTCODE_SEVERITY_INFO
);
1601 uislib_mod_exit(void)
1603 if (ProcReadBuffer
) {
1604 vfree(ProcReadBuffer
);
1605 ProcReadBuffer
= NULL
;
1608 debugfs_remove(info_debugfs_entry
);
1609 debugfs_remove(smart_wakeup_debugfs_entry
);
1610 debugfs_remove(cycles_before_wait_debugfs_read
);
1611 debugfs_remove(platformnumber_debugfs_read
);
1612 debugfs_remove(dir_debugfs
);
1614 DBGINF("goodbye.\n");
1618 module_init(uislib_mod_init
);
1619 module_exit(uislib_mod_exit
);
1621 MODULE_LICENSE("GPL");
1622 MODULE_AUTHOR("Usha Srinivasan");
1623 MODULE_ALIAS("uislib");
1624 /* this is extracted during depmod and kept in modules.dep */