3 * Copyright � 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>
27 #include "commontypes.h"
29 #include <linux/version.h>
31 #include "diagnostics/appos_subsystems.h"
33 #include "vbuschannel.h"
35 #include <linux/proc_fs.h>
36 #include <linux/uaccess.h> /* for copy_from_user */
37 #include <linux/ctype.h> /* for toupper */
38 #include <linux/list.h>
41 #include "visorchipset.h"
44 #include "guestlinuxdebug.h"
46 #define SET_PROC_OWNER(x, y)
48 #define UISLIB_TEST_PROC
49 #define POLLJIFFIES_NORMAL 1
50 /* Choose whether or not you want to wakeup the request-polling thread
51 * after an IO termination:
52 * this is shorter than using __FILE__ (full path name) in
53 * debug/info/error messages
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 static struct proc_dir_entry
*uislib_proc_dir
;
93 static struct proc_dir_entry
*uislib_proc_vbus_dir
;
94 static struct proc_dir_entry
*vnic_proc_entry
; /* Used to be "datachan" */
95 static struct proc_dir_entry
*ctrlchan_proc_entry
;
96 static struct proc_dir_entry
*pmem_proc_entry
;
97 static struct proc_dir_entry
*info_proc_entry
;
98 static struct proc_dir_entry
*switch_proc_entry
;
99 static struct proc_dir_entry
*extport_proc_entry
;
100 static struct proc_dir_entry
*platformnumber_proc_entry
;
101 static struct proc_dir_entry
*bus_proc_entry
;
102 static struct proc_dir_entry
*dev_proc_entry
;
103 static struct proc_dir_entry
*chipset_proc_entry
;
104 static struct proc_dir_entry
*cycles_before_wait_proc_entry
;
105 static struct proc_dir_entry
*reset_counts_proc_entry
;
106 static struct proc_dir_entry
*smart_wakeup_proc_entry
;
107 static struct proc_dir_entry
*disable_proc_entry
;
109 #define DIR_PROC_ENTRY "uislib"
110 #define DIR_VBUS_PROC_ENTRY "vbus"
111 #define VNIC_PROC_ENTRY_FN "vnic" /* Used to be "datachan" */
112 #define CTRLCHAN_PROC_ENTRY_FN "ctrlchan"
113 #define PMEM_PROC_ENTRY_FN "phys_to_virt"
114 #define INFO_PROC_ENTRY_FN "info"
115 #define SWITCH_PROC_ENTRY_FN "switch"
116 #define SWITCH_COUNT_PROC_ENTRY_FN "switch_count"
117 #define EXTPORT_PROC_ENTRY_FN "extport"
118 #define PLATFORMNUMBER_PROC_ENTRY_FN "platform"
119 #define BUS_PROC_ENTRY_FN "bus"
120 #define DEV_PROC_ENTRY_FN "device"
121 #define CHIPSET_PROC_ENTRY_FN "chipset"
122 #define CYCLES_BEFORE_WAIT_PROC_ENTRY_FN "cycles_before_wait"
123 #define RESET_COUNTS_PROC_ENTRY_FN "reset_counts"
124 #define SMART_WAKEUP_PROC_ENTRY_FN "smart_wakeup"
125 #define CALLHOME_PROC_ENTRY_FN "callhome"
126 #define CALLHOME_THROTTLED_PROC_ENTRY_FN "callhome_throttled"
127 #define DISABLE_PROC_ENTRY_FN "switch_state"
128 #ifdef UISLIB_TEST_PROC
129 static struct proc_dir_entry
*test_proc_entry
;
130 #define TEST_PROC_ENTRY_FN "test"
132 static unsigned long long cycles_before_wait
, wait_cycles
;
134 /*****************************************************/
135 /* local functions */
136 /*****************************************************/
138 static int proc_info_vbus_show(struct seq_file
*m
, void *v
);
140 proc_info_vbus_open(struct inode
*inode
, struct file
*filp
)
142 /* proc_info_vbus_show will grab this from seq_file.private: */
143 struct bus_info
*bus
= PDE_DATA(inode
);
144 return single_open(filp
, proc_info_vbus_show
, bus
);
147 static const struct file_operations proc_info_vbus_fops
= {
148 .open
= proc_info_vbus_open
,
151 .release
= single_release
,
154 static ssize_t
uislib_proc_read_writeonly(struct file
*file
,
156 size_t count
, loff_t
*ppos
);
158 static ssize_t
vnic_proc_write(struct file
*file
, const char __user
*buffer
,
159 size_t count
, loff_t
*ppos
);
161 static const struct file_operations proc_vnic_fops
= {
162 .read
= uislib_proc_read_writeonly
,
163 .write
= vnic_proc_write
,
166 static ssize_t
chipset_proc_write(struct file
*file
, const char __user
*buffer
,
167 size_t count
, loff_t
*ppos
);
169 static const struct file_operations proc_chipset_fops
= {
170 .read
= uislib_proc_read_writeonly
,
171 .write
= chipset_proc_write
,
174 static ssize_t
info_proc_read(struct file
*file
, char __user
*buf
,
175 size_t len
, loff_t
*offset
);
176 static const struct file_operations proc_info_fops
= {
177 .read
= info_proc_read
,
180 static ssize_t
platformnumber_proc_read(struct file
*file
, char __user
*buf
,
181 size_t len
, loff_t
*offset
);
182 static const struct file_operations proc_platformnumber_fops
= {
183 .read
= platformnumber_proc_read
,
186 static ssize_t
cycles_before_wait_proc_write(struct file
*file
,
187 const char __user
*buffer
,
188 size_t count
, loff_t
*ppos
);
189 static const struct file_operations proc_cycles_before_wait_fops
= {
190 .read
= uislib_proc_read_writeonly
,
191 .write
= cycles_before_wait_proc_write
,
194 static ssize_t
reset_counts_proc_write(struct file
*file
,
195 const char __user
*buffer
,
196 size_t count
, loff_t
*ppos
);
197 static const struct file_operations proc_reset_counts_fops
= {
198 .read
= uislib_proc_read_writeonly
,
199 .write
= reset_counts_proc_write
,
202 static ssize_t
smart_wakeup_proc_write(struct file
*file
,
203 const char __user
*buffer
,
204 size_t count
, loff_t
*ppos
);
205 static const struct file_operations proc_smart_wakeup_fops
= {
206 .read
= uislib_proc_read_writeonly
,
207 .write
= smart_wakeup_proc_write
,
210 static ssize_t
test_proc_write(struct file
*file
,
211 const char __user
*buffer
,
212 size_t count
, loff_t
*ppos
);
213 static const struct file_operations proc_test_fops
= {
214 .read
= uislib_proc_read_writeonly
,
215 .write
= test_proc_write
,
218 static ssize_t
bus_proc_write(struct file
*file
,
219 const char __user
*buffer
,
220 size_t count
, loff_t
*ppos
);
221 static const struct file_operations proc_bus_fops
= {
222 .read
= uislib_proc_read_writeonly
,
223 .write
= bus_proc_write
,
226 static ssize_t
dev_proc_write(struct file
*file
,
227 const char __user
*buffer
,
228 size_t count
, loff_t
*ppos
);
229 static const struct file_operations proc_dev_fops
= {
230 .read
= uislib_proc_read_writeonly
,
231 .write
= dev_proc_write
,
235 init_msg_header(CONTROLVM_MESSAGE
*msg
, U32 id
, uint rsp
, uint svr
)
237 memset(msg
, 0, sizeof(CONTROLVM_MESSAGE
));
239 msg
->hdr
.Flags
.responseExpected
= rsp
;
240 msg
->hdr
.Flags
.server
= svr
;
244 create_bus_proc_entries(struct bus_info
*bus
)
246 bus
->proc_dir
= proc_mkdir(bus
->name
, uislib_proc_vbus_dir
);
247 if (!bus
->proc_dir
) {
248 LOGERR("failed to create /proc/uislib/vbus/%s directory",
252 bus
->proc_info
= proc_create_data("info", 0, bus
->proc_dir
,
253 &proc_info_vbus_fops
, bus
);
254 if (!bus
->proc_info
) {
255 LOGERR("failed to create /proc/uislib/vbus/%s/info", bus
->name
);
256 remove_proc_entry(bus
->name
, uislib_proc_vbus_dir
);
257 bus
->proc_dir
= NULL
;
260 SET_PROC_OWNER(bus
->proc_info
, THIS_MODULE
);
264 static __iomem
void *
265 init_vbus_channel(U64 channelAddr
, U32 channelBytes
, int isServer
)
268 void __iomem
*pChan
= uislib_ioremap_cache(channelAddr
, channelBytes
);
270 LOGERR("CONTROLVM_BUS_CREATE error: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed",
271 (unsigned long long) channelAddr
,
272 (unsigned long long) channelBytes
);
277 memset_io(pChan
, 0, channelBytes
);
278 if (!ULTRA_VBUS_CHANNEL_OK_SERVER(channelBytes
, NULL
)) {
279 ERRDRV("%s channel cannot be used", __func__
);
280 uislib_iounmap(pChan
);
284 ULTRA_VBUS_init_channel(pChan
, channelBytes
);
286 if (!ULTRA_VBUS_CHANNEL_OK_CLIENT(pChan
, NULL
)) {
287 ERRDRV("%s channel cannot be used", __func__
);
288 uislib_iounmap(pChan
);
299 create_bus(CONTROLVM_MESSAGE
*msg
, char *buf
)
301 U32 busNo
, deviceCount
;
302 struct bus_info
*tmp
, *bus
;
305 if (MaxBusCount
== BusListCount
) {
306 LOGERR("CONTROLVM_BUS_CREATE Failed: max buses:%d already created\n",
308 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC
, MaxBusCount
,
309 POSTCODE_SEVERITY_ERR
);
310 return CONTROLVM_RESP_ERROR_MAX_BUSES
;
313 busNo
= msg
->cmd
.createBus
.busNo
;
314 deviceCount
= msg
->cmd
.createBus
.deviceCount
;
316 POSTCODE_LINUX_4(BUS_CREATE_ENTRY_PC
, busNo
, deviceCount
,
317 POSTCODE_SEVERITY_INFO
);
320 sizeof(struct bus_info
) +
321 (deviceCount
* sizeof(struct device_info
*));
322 bus
= kzalloc(size
, GFP_ATOMIC
);
324 LOGERR("CONTROLVM_BUS_CREATE Failed: kmalloc for bus failed.\n");
325 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC
, busNo
,
326 POSTCODE_SEVERITY_ERR
);
327 return CONTROLVM_RESP_ERROR_KMALLOC_FAILED
;
330 /* Currently by default, the bus Number is the GuestHandle.
331 * Configure Bus message can override this.
333 if (msg
->hdr
.Flags
.testMessage
) {
334 /* This implies we're the IOVM so set guest handle to 0... */
335 bus
->guestHandle
= 0;
339 bus
->busNo
= bus
->guestHandle
= busNo
;
340 sprintf(bus
->name
, "%d", (int) bus
->busNo
);
341 bus
->deviceCount
= deviceCount
;
343 (struct device_info
**) ((char *) bus
+ sizeof(struct bus_info
));
344 bus
->busInstGuid
= msg
->cmd
.createBus
.busInstGuid
;
345 bus
->busChannelBytes
= 0;
346 bus
->pBusChannel
= NULL
;
348 /* add bus to our bus list - but check for duplicates first */
349 read_lock(&BusListLock
);
350 for (tmp
= BusListHead
; tmp
; tmp
= tmp
->next
) {
351 if (tmp
->busNo
== bus
->busNo
)
354 read_unlock(&BusListLock
);
356 /* found a bus already in the list with same busNo -
359 LOGERR("CONTROLVM_BUS_CREATE Failed: bus %d already exists.\n",
361 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC
, bus
->busNo
,
362 POSTCODE_SEVERITY_ERR
);
364 return CONTROLVM_RESP_ERROR_ALREADY_DONE
;
366 if ((msg
->cmd
.createBus
.channelAddr
!= 0)
367 && (msg
->cmd
.createBus
.channelBytes
!= 0)) {
368 bus
->busChannelBytes
= msg
->cmd
.createBus
.channelBytes
;
370 init_vbus_channel(msg
->cmd
.createBus
.channelAddr
,
371 msg
->cmd
.createBus
.channelBytes
,
372 msg
->hdr
.Flags
.server
);
374 /* the msg is bound for virtpci; send guest_msgs struct to callback */
375 if (!msg
->hdr
.Flags
.server
) {
376 struct guest_msgs cmd
;
377 cmd
.msgtype
= GUEST_ADD_VBUS
;
378 cmd
.add_vbus
.busNo
= busNo
;
379 cmd
.add_vbus
.chanptr
= bus
->pBusChannel
;
380 cmd
.add_vbus
.deviceCount
= deviceCount
;
381 cmd
.add_vbus
.busTypeGuid
= msg
->cmd
.createBus
.busDataTypeGuid
;
382 cmd
.add_vbus
.busInstGuid
= msg
->cmd
.createBus
.busInstGuid
;
383 if (!VirtControlChanFunc
) {
385 LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci callback not registered.");
386 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC
, bus
->busNo
,
387 POSTCODE_SEVERITY_ERR
);
388 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE
;
390 if (!VirtControlChanFunc(&cmd
)) {
392 LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci GUEST_ADD_VBUS returned error.");
393 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC
, bus
->busNo
,
394 POSTCODE_SEVERITY_ERR
);
396 CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR
;
399 create_bus_proc_entries(bus
);
401 /* add bus at the head of our list */
402 write_lock(&BusListLock
);
406 bus
->next
= BusListHead
;
410 write_unlock(&BusListLock
);
412 POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC
, bus
->busNo
,
413 POSTCODE_SEVERITY_INFO
);
414 return CONTROLVM_RESP_SUCCESS
;
418 destroy_bus(CONTROLVM_MESSAGE
*msg
, char *buf
)
421 struct bus_info
*bus
, *prev
= NULL
;
424 busNo
= msg
->cmd
.destroyBus
.busNo
;
426 /* find and delete the bus */
427 read_lock(&BusListLock
);
428 for (bus
= BusListHead
; bus
; prev
= bus
, bus
= bus
->next
) {
429 if (bus
->busNo
== busNo
) {
430 /* found the bus - ensure that all device
433 for (i
= 0; i
< bus
->deviceCount
; i
++) {
434 if (bus
->device
[i
] != NULL
) {
435 LOGERR("CONTROLVM_BUS_DESTROY Failed: device %i attached to bus %d.",
437 read_unlock(&BusListLock
);
438 return CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED
;
441 read_unlock(&BusListLock
);
442 /* the msg is bound for virtpci; send
443 * guest_msgs struct to callback
445 if (!msg
->hdr
.Flags
.server
) {
446 struct guest_msgs cmd
;
447 cmd
.msgtype
= GUEST_DEL_VBUS
;
448 cmd
.del_vbus
.busNo
= busNo
;
449 if (!VirtControlChanFunc
) {
450 LOGERR("CONTROLVM_BUS_DESTROY Failed: virtpci callback not registered.");
451 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE
;
453 if (!VirtControlChanFunc(&cmd
)) {
454 LOGERR("CONTROLVM_BUS_DESTROY Failed: virtpci GUEST_DEL_VBUS returned error.");
455 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR
;
458 /* remove the bus from the list */
459 write_lock(&BusListLock
);
460 if (prev
) /* not at head */
461 prev
->next
= bus
->next
;
463 BusListHead
= bus
->next
;
465 write_unlock(&BusListLock
);
471 LOGERR("CONTROLVM_BUS_DESTROY Failed: failed to find bus %d.\n",
473 read_unlock(&BusListLock
);
474 return CONTROLVM_RESP_ERROR_ALREADY_DONE
;
476 if (bus
->proc_info
) {
477 remove_proc_entry("info", bus
->proc_dir
);
478 bus
->proc_info
= NULL
;
481 remove_proc_entry(bus
->name
, uislib_proc_vbus_dir
);
482 bus
->proc_dir
= NULL
;
484 if (bus
->pBusChannel
) {
485 uislib_iounmap(bus
->pBusChannel
);
486 bus
->pBusChannel
= NULL
;
490 return CONTROLVM_RESP_SUCCESS
;
494 create_device(CONTROLVM_MESSAGE
*msg
, char *buf
)
496 struct device_info
*dev
;
497 struct bus_info
*bus
;
499 int result
= CONTROLVM_RESP_SUCCESS
;
500 U64 minSize
= MIN_IO_CHANNEL_SIZE
;
501 ReqHandlerInfo_t
*pReqHandler
;
503 busNo
= msg
->cmd
.createDevice
.busNo
;
504 devNo
= msg
->cmd
.createDevice
.devNo
;
506 POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC
, devNo
, busNo
,
507 POSTCODE_SEVERITY_INFO
);
509 dev
= kzalloc(sizeof(struct device_info
), GFP_ATOMIC
);
511 LOGERR("CONTROLVM_DEVICE_CREATE Failed: kmalloc for dev failed.\n");
512 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC
, devNo
, busNo
,
513 POSTCODE_SEVERITY_ERR
);
514 return CONTROLVM_RESP_ERROR_KMALLOC_FAILED
;
517 dev
->channelTypeGuid
= msg
->cmd
.createDevice
.dataTypeGuid
;
518 dev
->intr
= msg
->cmd
.createDevice
.intr
;
519 dev
->channelAddr
= msg
->cmd
.createDevice
.channelAddr
;
522 sema_init(&dev
->interrupt_callback_lock
, 1); /* unlocked */
523 sprintf(dev
->devid
, "vbus%u:dev%u", (unsigned) busNo
, (unsigned) devNo
);
524 /* map the channel memory for the device. */
525 if (msg
->hdr
.Flags
.testMessage
)
526 dev
->chanptr
= (void __iomem
*)__va(dev
->channelAddr
);
528 pReqHandler
= ReqHandlerFind(dev
->channelTypeGuid
);
530 /* generic service handler registered for this
533 minSize
= pReqHandler
->min_channel_bytes
;
534 if (minSize
> msg
->cmd
.createDevice
.channelBytes
) {
535 LOGERR("CONTROLVM_DEVICE_CREATE Failed: channel size is too small, channel size:0x%lx, required size:0x%lx",
536 (ulong
) msg
->cmd
.createDevice
.channelBytes
,
538 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC
, devNo
, busNo
,
539 POSTCODE_SEVERITY_ERR
);
540 result
= CONTROLVM_RESP_ERROR_CHANNEL_SIZE_TOO_SMALL
;
544 uislib_ioremap_cache(dev
->channelAddr
,
545 msg
->cmd
.createDevice
.channelBytes
);
547 LOGERR("CONTROLVM_DEVICE_CREATE Failed: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed",
549 msg
->cmd
.createDevice
.channelBytes
);
550 result
= CONTROLVM_RESP_ERROR_IOREMAP_FAILED
;
551 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC
, devNo
, busNo
,
552 POSTCODE_SEVERITY_ERR
);
556 dev
->devInstGuid
= msg
->cmd
.createDevice
.devInstGuid
;
557 dev
->channelBytes
= msg
->cmd
.createDevice
.channelBytes
;
559 read_lock(&BusListLock
);
560 for (bus
= BusListHead
; bus
; bus
= bus
->next
) {
561 if (bus
->busNo
== busNo
) {
562 /* make sure the device number is valid */
563 if (devNo
>= bus
->deviceCount
) {
564 LOGERR("CONTROLVM_DEVICE_CREATE Failed: device (%d) >= deviceCount (%d).",
565 devNo
, bus
->deviceCount
);
566 result
= CONTROLVM_RESP_ERROR_MAX_DEVICES
;
567 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC
,
569 POSTCODE_SEVERITY_ERR
);
570 read_unlock(&BusListLock
);
573 /* make sure this device is not already set */
574 if (bus
->device
[devNo
]) {
575 LOGERR("CONTROLVM_DEVICE_CREATE Failed: device %d is already exists.",
577 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC
,
579 POSTCODE_SEVERITY_ERR
);
580 result
= CONTROLVM_RESP_ERROR_ALREADY_DONE
;
581 read_unlock(&BusListLock
);
584 read_unlock(&BusListLock
);
585 /* the msg is bound for virtpci; send
586 * guest_msgs struct to callback
588 if (!msg
->hdr
.Flags
.server
) {
589 struct guest_msgs cmd
;
591 (&dev
->channelTypeGuid
,
592 &UltraVhbaChannelProtocolGuid
,
594 WAIT_FOR_VALID_GUID(((CHANNEL_HEADER
598 if (!ULTRA_VHBA_CHANNEL_OK_CLIENT
599 (dev
->chanptr
, NULL
)) {
600 LOGERR("CONTROLVM_DEVICE_CREATE Failed:[CLIENT]VHBA dev %d chan invalid.",
603 (DEVICE_CREATE_FAILURE_PC
,
605 POSTCODE_SEVERITY_ERR
);
606 result
= CONTROLVM_RESP_ERROR_CHANNEL_INVALID
;
609 cmd
.msgtype
= GUEST_ADD_VHBA
;
610 cmd
.add_vhba
.chanptr
= dev
->chanptr
;
611 cmd
.add_vhba
.busNo
= busNo
;
612 cmd
.add_vhba
.deviceNo
= devNo
;
613 cmd
.add_vhba
.devInstGuid
=
615 cmd
.add_vhba
.intr
= dev
->intr
;
618 (&dev
->channelTypeGuid
,
619 &UltraVnicChannelProtocolGuid
,
621 WAIT_FOR_VALID_GUID(((CHANNEL_HEADER
625 if (!ULTRA_VNIC_CHANNEL_OK_CLIENT
626 (dev
->chanptr
, NULL
)) {
627 LOGERR("CONTROLVM_DEVICE_CREATE Failed: VNIC[CLIENT] dev %d chan invalid.",
630 (DEVICE_CREATE_FAILURE_PC
,
632 POSTCODE_SEVERITY_ERR
);
633 result
= CONTROLVM_RESP_ERROR_CHANNEL_INVALID
;
636 cmd
.msgtype
= GUEST_ADD_VNIC
;
637 cmd
.add_vnic
.chanptr
= dev
->chanptr
;
638 cmd
.add_vnic
.busNo
= busNo
;
639 cmd
.add_vnic
.deviceNo
= devNo
;
640 cmd
.add_vnic
.devInstGuid
=
642 cmd
.add_vhba
.intr
= dev
->intr
;
644 LOGERR("CONTROLVM_DEVICE_CREATE Failed: unknown channelTypeGuid.\n");
646 (DEVICE_CREATE_FAILURE_PC
, devNo
,
647 busNo
, POSTCODE_SEVERITY_ERR
);
648 result
= CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN
;
652 if (!VirtControlChanFunc
) {
653 LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci callback not registered.");
655 (DEVICE_CREATE_FAILURE_PC
, devNo
,
656 busNo
, POSTCODE_SEVERITY_ERR
);
657 result
= CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE
;
661 if (!VirtControlChanFunc(&cmd
)) {
662 LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci GUEST_ADD_[VHBA||VNIC] returned error.");
664 (DEVICE_CREATE_FAILURE_PC
, devNo
,
665 busNo
, POSTCODE_SEVERITY_ERR
);
666 result
= CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR
;
670 bus
->device
[devNo
] = dev
;
671 POSTCODE_LINUX_4(DEVICE_CREATE_SUCCESS_PC
, devNo
, busNo
,
672 POSTCODE_SEVERITY_INFO
);
673 return CONTROLVM_RESP_SUCCESS
;
676 read_unlock(&BusListLock
);
678 LOGERR("CONTROLVM_DEVICE_CREATE Failed: failed to find bus %d.", busNo
);
679 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC
, devNo
, busNo
,
680 POSTCODE_SEVERITY_ERR
);
681 result
= CONTROLVM_RESP_ERROR_BUS_INVALID
;
684 if (!msg
->hdr
.Flags
.testMessage
) {
685 uislib_iounmap(dev
->chanptr
);
694 pause_device(CONTROLVM_MESSAGE
*msg
)
697 struct bus_info
*bus
;
698 struct device_info
*dev
;
699 struct guest_msgs cmd
;
701 busNo
= msg
->cmd
.deviceChangeState
.busNo
;
702 devNo
= msg
->cmd
.deviceChangeState
.devNo
;
704 read_lock(&BusListLock
);
705 for (bus
= BusListHead
; bus
; bus
= bus
->next
) {
706 if (bus
->busNo
== busNo
) {
707 /* make sure the device number is valid */
708 if (devNo
>= bus
->deviceCount
) {
709 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device(%d) >= deviceCount(%d).",
710 devNo
, bus
->deviceCount
);
711 read_unlock(&BusListLock
);
712 return CONTROLVM_RESP_ERROR_DEVICE_INVALID
;
714 /* make sure this device exists */
715 dev
= bus
->device
[devNo
];
717 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device %d does not exist.",
719 read_unlock(&BusListLock
);
720 return CONTROLVM_RESP_ERROR_ALREADY_DONE
;
722 read_unlock(&BusListLock
);
723 /* the msg is bound for virtpci; send
724 * guest_msgs struct to callback
727 (&dev
->channelTypeGuid
,
728 &UltraVhbaChannelProtocolGuid
, sizeof(GUID
))) {
729 cmd
.msgtype
= GUEST_PAUSE_VHBA
;
730 cmd
.pause_vhba
.chanptr
= dev
->chanptr
;
733 (&dev
->channelTypeGuid
,
734 &UltraVnicChannelProtocolGuid
,
736 cmd
.msgtype
= GUEST_PAUSE_VNIC
;
737 cmd
.pause_vnic
.chanptr
= dev
->chanptr
;
739 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: unknown channelTypeGuid.\n");
741 CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN
;
744 if (!VirtControlChanFunc
) {
745 LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: virtpci callback not registered.");
747 CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE
;
750 if (!VirtControlChanFunc(&cmd
)) {
751 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: virtpci GUEST_PAUSE_[VHBA||VNIC] returned error.");
752 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR
;
759 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: bus %d does not exist",
761 read_unlock(&BusListLock
);
762 return CONTROLVM_RESP_ERROR_BUS_INVALID
;
765 return CONTROLVM_RESP_SUCCESS
;
769 resume_device(CONTROLVM_MESSAGE
*msg
)
772 struct bus_info
*bus
;
773 struct device_info
*dev
;
774 struct guest_msgs cmd
;
776 busNo
= msg
->cmd
.deviceChangeState
.busNo
;
777 devNo
= msg
->cmd
.deviceChangeState
.devNo
;
779 read_lock(&BusListLock
);
780 for (bus
= BusListHead
; bus
; bus
= bus
->next
) {
781 if (bus
->busNo
== busNo
) {
782 /* make sure the device number is valid */
783 if (devNo
>= bus
->deviceCount
) {
784 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device(%d) >= deviceCount(%d).",
785 devNo
, bus
->deviceCount
);
786 read_unlock(&BusListLock
);
787 return CONTROLVM_RESP_ERROR_DEVICE_INVALID
;
789 /* make sure this device exists */
790 dev
= bus
->device
[devNo
];
792 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device %d does not exist.",
794 read_unlock(&BusListLock
);
795 return CONTROLVM_RESP_ERROR_ALREADY_DONE
;
797 read_unlock(&BusListLock
);
798 /* the msg is bound for virtpci; send
799 * guest_msgs struct to callback
801 if (!memcmp(&dev
->channelTypeGuid
,
802 &UltraVhbaChannelProtocolGuid
,
804 cmd
.msgtype
= GUEST_RESUME_VHBA
;
805 cmd
.resume_vhba
.chanptr
= dev
->chanptr
;
807 if (!memcmp(&dev
->channelTypeGuid
,
808 &UltraVnicChannelProtocolGuid
,
810 cmd
.msgtype
= GUEST_RESUME_VNIC
;
811 cmd
.resume_vnic
.chanptr
= dev
->chanptr
;
813 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: unknown channelTypeGuid.\n");
815 CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN
;
818 if (!VirtControlChanFunc
) {
819 LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: virtpci callback not registered.");
821 CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE
;
824 if (!VirtControlChanFunc(&cmd
)) {
825 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: virtpci GUEST_RESUME_[VHBA||VNIC] returned error.");
826 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR
;
833 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: bus %d does not exist",
835 read_unlock(&BusListLock
);
836 return CONTROLVM_RESP_ERROR_BUS_INVALID
;
839 return CONTROLVM_RESP_SUCCESS
;
843 destroy_device(CONTROLVM_MESSAGE
*msg
, char *buf
)
846 struct bus_info
*bus
;
847 struct device_info
*dev
;
848 struct guest_msgs cmd
;
850 busNo
= msg
->cmd
.destroyDevice
.busNo
;
851 devNo
= msg
->cmd
.destroyDevice
.devNo
;
853 read_lock(&BusListLock
);
854 LOGINF("destroy_device called for busNo=%u, devNo=%u", busNo
, devNo
);
855 for (bus
= BusListHead
; bus
; bus
= bus
->next
) {
856 if (bus
->busNo
== busNo
) {
857 /* make sure the device number is valid */
858 if (devNo
>= bus
->deviceCount
) {
859 LOGERR("CONTROLVM_DEVICE_DESTORY Failed: device(%d) >= deviceCount(%d).",
860 devNo
, bus
->deviceCount
);
861 read_unlock(&BusListLock
);
862 return CONTROLVM_RESP_ERROR_DEVICE_INVALID
;
864 /* make sure this device exists */
865 dev
= bus
->device
[devNo
];
867 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: device %d does not exist.",
869 read_unlock(&BusListLock
);
870 return CONTROLVM_RESP_ERROR_ALREADY_DONE
;
872 read_unlock(&BusListLock
);
873 /* the msg is bound for virtpci; send
874 * guest_msgs struct to callback
877 (&dev
->channelTypeGuid
,
878 &UltraVhbaChannelProtocolGuid
, sizeof(GUID
))) {
879 cmd
.msgtype
= GUEST_DEL_VHBA
;
880 cmd
.del_vhba
.chanptr
= dev
->chanptr
;
883 (&dev
->channelTypeGuid
,
884 &UltraVnicChannelProtocolGuid
,
886 cmd
.msgtype
= GUEST_DEL_VNIC
;
887 cmd
.del_vnic
.chanptr
= dev
->chanptr
;
889 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: unknown channelTypeGuid.\n");
891 CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN
;
894 if (!VirtControlChanFunc
) {
895 LOGERR("CONTROLVM_DEVICE_DESTORY Failed: virtpci callback not registered.");
897 CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE
;
900 if (!VirtControlChanFunc(&cmd
)) {
901 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: virtpci GUEST_DEL_[VHBA||VNIC] returned error.");
902 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR
;
904 /* you must disable channel interrupts BEFORE you unmap the channel,
905 * because if you unmap first, there may still be some activity going
906 * on which accesses the channel and you will get a "unable to handle
907 * kernel paging request"
910 LOGINF("calling uislib_disable_channel_interrupts");
911 uislib_disable_channel_interrupts(busNo
, devNo
);
913 /* unmap the channel memory for the device. */
914 if (!msg
->hdr
.Flags
.testMessage
) {
915 LOGINF("destroy_device, doing iounmap");
916 uislib_iounmap(dev
->chanptr
);
919 bus
->device
[devNo
] = NULL
;
925 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: bus %d does not exist",
927 read_unlock(&BusListLock
);
928 return CONTROLVM_RESP_ERROR_BUS_INVALID
;
931 return CONTROLVM_RESP_SUCCESS
;
935 init_chipset(CONTROLVM_MESSAGE
*msg
, char *buf
)
937 POSTCODE_LINUX_2(CHIPSET_INIT_ENTRY_PC
, POSTCODE_SEVERITY_INFO
);
939 MaxBusCount
= msg
->cmd
.initChipset
.busCount
;
940 PlatformNumber
= msg
->cmd
.initChipset
.platformNumber
;
941 PhysicalDataChan
= 0;
943 /* We need to make sure we have our functions registered
944 * before processing messages. If we are a test vehicle the
945 * testMessage for init_chipset will be set. We can ignore the
946 * waits for the callbacks, since this will be manually entered
947 * from a user. If no testMessage is set, we will wait for the
950 if (!msg
->hdr
.Flags
.testMessage
)
951 WAIT_ON_CALLBACK(VirtControlChanFunc
);
954 POSTCODE_LINUX_2(CHIPSET_INIT_EXIT_PC
, POSTCODE_SEVERITY_INFO
);
956 return CONTROLVM_RESP_SUCCESS
;
960 stop_chipset(CONTROLVM_MESSAGE
*msg
, char *buf
)
962 /* Check that all buses and switches have been torn down and
966 /* Buses still exist. */
967 LOGERR("CONTROLVM_CHIPSET_STOP: BusListHead is not NULL");
968 return CONTROLVM_RESP_ERROR_CHIPSET_STOP_FAILED_BUS
;
971 /* BusListHead is NULL, but BusListCount != 0 */
972 LOGERR("CONTROLVM_CHIPSET_STOP: BusListCount != 0");
973 return CONTROLVM_RESP_ERROR_CHIPSET_STOP_FAILED_BUS
;
976 /* Buses are shut down. */
977 return visorchipset_chipset_notready();
981 delete_bus_glue(U32 busNo
)
983 CONTROLVM_MESSAGE msg
;
985 init_msg_header(&msg
, CONTROLVM_BUS_DESTROY
, 0, 0);
986 msg
.cmd
.destroyBus
.busNo
= busNo
;
987 if (destroy_bus(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
) {
988 LOGERR("destroy_bus failed. busNo=0x%x\n", busNo
);
995 delete_device_glue(U32 busNo
, U32 devNo
)
997 CONTROLVM_MESSAGE msg
;
999 init_msg_header(&msg
, CONTROLVM_DEVICE_DESTROY
, 0, 0);
1000 msg
.cmd
.destroyDevice
.busNo
= busNo
;
1001 msg
.cmd
.destroyDevice
.devNo
= devNo
;
1002 if (destroy_device(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
) {
1003 LOGERR("destroy_device failed. busNo=0x%x devNo=0x%x\n", busNo
,
1011 uislib_client_inject_add_bus(U32 busNo
, GUID instGuid
,
1012 U64 channelAddr
, ulong nChannelBytes
)
1014 CONTROLVM_MESSAGE msg
;
1016 LOGINF("enter busNo=0x%x\n", busNo
);
1017 /* step 0: init the chipset */
1018 POSTCODE_LINUX_3(CHIPSET_INIT_ENTRY_PC
, busNo
, POSTCODE_SEVERITY_INFO
);
1020 if (!chipset_inited
) {
1021 /* step: initialize the chipset */
1022 init_msg_header(&msg
, CONTROLVM_CHIPSET_INIT
, 0, 0);
1023 /* this change is needed so that console will come up
1024 * OK even when the bus 0 create comes in late. If the
1025 * bus 0 create is the first create, then the add_vnic
1026 * will work fine, but if the bus 0 create arrives
1027 * after number 4, then the add_vnic will fail, and the
1028 * ultraboot will fail.
1030 msg
.cmd
.initChipset
.busCount
= 23;
1031 msg
.cmd
.initChipset
.switchCount
= 0;
1032 if (init_chipset(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
) {
1033 LOGERR("init_chipset failed.\n");
1036 LOGINF("chipset initialized\n");
1037 POSTCODE_LINUX_3(CHIPSET_INIT_EXIT_PC
, busNo
,
1038 POSTCODE_SEVERITY_INFO
);
1041 /* step 1: create a bus */
1042 POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC
, busNo
, POSTCODE_SEVERITY_WARNING
);
1043 init_msg_header(&msg
, CONTROLVM_BUS_CREATE
, 0, 0);
1044 msg
.cmd
.createBus
.busNo
= busNo
;
1045 msg
.cmd
.createBus
.deviceCount
= 23; /* devNo+1; */
1046 msg
.cmd
.createBus
.channelAddr
= channelAddr
;
1047 msg
.cmd
.createBus
.channelBytes
= nChannelBytes
;
1048 if (create_bus(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
) {
1049 LOGERR("create_bus failed.\n");
1050 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC
, busNo
,
1051 POSTCODE_SEVERITY_ERR
);
1054 POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC
, busNo
, POSTCODE_SEVERITY_INFO
);
1058 EXPORT_SYMBOL_GPL(uislib_client_inject_add_bus
);
1062 uislib_client_inject_del_bus(U32 busNo
)
1064 return delete_bus_glue(busNo
);
1066 EXPORT_SYMBOL_GPL(uislib_client_inject_del_bus
);
1069 uislib_client_inject_pause_vhba(U32 busNo
, U32 devNo
)
1071 CONTROLVM_MESSAGE msg
;
1074 init_msg_header(&msg
, CONTROLVM_DEVICE_CHANGESTATE
, 0, 0);
1075 msg
.cmd
.deviceChangeState
.busNo
= busNo
;
1076 msg
.cmd
.deviceChangeState
.devNo
= devNo
;
1077 msg
.cmd
.deviceChangeState
.state
= SegmentStateStandby
;
1078 rc
= pause_device(&msg
);
1079 if (rc
!= CONTROLVM_RESP_SUCCESS
) {
1080 LOGERR("VHBA pause_device failed. busNo=0x%x devNo=0x%x\n",
1086 EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vhba
);
1089 uislib_client_inject_resume_vhba(U32 busNo
, U32 devNo
)
1091 CONTROLVM_MESSAGE msg
;
1094 init_msg_header(&msg
, CONTROLVM_DEVICE_CHANGESTATE
, 0, 0);
1095 msg
.cmd
.deviceChangeState
.busNo
= busNo
;
1096 msg
.cmd
.deviceChangeState
.devNo
= devNo
;
1097 msg
.cmd
.deviceChangeState
.state
= SegmentStateRunning
;
1098 rc
= resume_device(&msg
);
1099 if (rc
!= CONTROLVM_RESP_SUCCESS
) {
1100 LOGERR("VHBA resume_device failed. busNo=0x%x devNo=0x%x\n",
1107 EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vhba
);
1110 uislib_client_inject_add_vhba(U32 busNo
, U32 devNo
,
1111 U64 phys_chan_addr
, U32 chan_bytes
,
1112 int is_test_addr
, GUID instGuid
,
1113 struct InterruptInfo
*intr
)
1115 CONTROLVM_MESSAGE msg
;
1117 LOGINF(" enter busNo=0x%x devNo=0x%x\n", busNo
, devNo
);
1118 /* chipset init'ed with bus bus has been previously created -
1119 * Verify it still exists step 2: create the VHBA device on the
1122 POSTCODE_LINUX_4(VHBA_CREATE_ENTRY_PC
, devNo
, busNo
,
1123 POSTCODE_SEVERITY_INFO
);
1125 init_msg_header(&msg
, CONTROLVM_DEVICE_CREATE
, 0, 0);
1127 /* signify that the physical channel address does NOT
1128 * need to be ioremap()ed
1130 msg
.hdr
.Flags
.testMessage
= 1;
1131 msg
.cmd
.createDevice
.busNo
= busNo
;
1132 msg
.cmd
.createDevice
.devNo
= devNo
;
1133 msg
.cmd
.createDevice
.devInstGuid
= instGuid
;
1135 msg
.cmd
.createDevice
.intr
= *intr
;
1137 memset(&msg
.cmd
.createDevice
.intr
, 0,
1138 sizeof(struct InterruptInfo
));
1139 msg
.cmd
.createDevice
.channelAddr
= phys_chan_addr
;
1140 if (chan_bytes
< MIN_IO_CHANNEL_SIZE
) {
1141 LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n",
1142 chan_bytes
, (unsigned int) MIN_IO_CHANNEL_SIZE
);
1143 POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC
, chan_bytes
,
1144 MIN_IO_CHANNEL_SIZE
, POSTCODE_SEVERITY_ERR
);
1147 msg
.cmd
.createDevice
.channelBytes
= chan_bytes
;
1148 msg
.cmd
.createDevice
.dataTypeGuid
= UltraVhbaChannelProtocolGuid
;
1149 if (create_device(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
) {
1150 LOGERR("VHBA create_device failed.\n");
1151 POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC
, devNo
, busNo
,
1152 POSTCODE_SEVERITY_ERR
);
1155 POSTCODE_LINUX_4(VHBA_CREATE_SUCCESS_PC
, devNo
, busNo
,
1156 POSTCODE_SEVERITY_INFO
);
1159 EXPORT_SYMBOL_GPL(uislib_client_inject_add_vhba
);
1162 uislib_client_inject_del_vhba(U32 busNo
, U32 devNo
)
1164 return delete_device_glue(busNo
, devNo
);
1166 EXPORT_SYMBOL_GPL(uislib_client_inject_del_vhba
);
1169 uislib_client_inject_add_vnic(U32 busNo
, U32 devNo
,
1170 U64 phys_chan_addr
, U32 chan_bytes
,
1171 int is_test_addr
, GUID instGuid
,
1172 struct InterruptInfo
*intr
)
1174 CONTROLVM_MESSAGE msg
;
1176 LOGINF(" enter busNo=0x%x devNo=0x%x\n", busNo
, devNo
);
1177 /* chipset init'ed with bus bus has been previously created -
1178 * Verify it still exists step 2: create the VNIC device on the
1181 POSTCODE_LINUX_4(VNIC_CREATE_ENTRY_PC
, devNo
, busNo
,
1182 POSTCODE_SEVERITY_INFO
);
1184 init_msg_header(&msg
, CONTROLVM_DEVICE_CREATE
, 0, 0);
1186 /* signify that the physical channel address does NOT
1187 * need to be ioremap()ed
1189 msg
.hdr
.Flags
.testMessage
= 1;
1190 msg
.cmd
.createDevice
.busNo
= busNo
;
1191 msg
.cmd
.createDevice
.devNo
= devNo
;
1192 msg
.cmd
.createDevice
.devInstGuid
= instGuid
;
1194 msg
.cmd
.createDevice
.intr
= *intr
;
1196 memset(&msg
.cmd
.createDevice
.intr
, 0,
1197 sizeof(struct InterruptInfo
));
1198 msg
.cmd
.createDevice
.channelAddr
= phys_chan_addr
;
1199 if (chan_bytes
< MIN_IO_CHANNEL_SIZE
) {
1200 LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n",
1201 chan_bytes
, (unsigned int) MIN_IO_CHANNEL_SIZE
);
1202 POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC
, chan_bytes
,
1203 MIN_IO_CHANNEL_SIZE
, POSTCODE_SEVERITY_ERR
);
1206 msg
.cmd
.createDevice
.channelBytes
= chan_bytes
;
1207 msg
.cmd
.createDevice
.dataTypeGuid
= UltraVnicChannelProtocolGuid
;
1208 if (create_device(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
) {
1209 LOGERR("VNIC create_device failed.\n");
1210 POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC
, devNo
, busNo
,
1211 POSTCODE_SEVERITY_ERR
);
1215 POSTCODE_LINUX_4(VNIC_CREATE_SUCCESS_PC
, devNo
, busNo
,
1216 POSTCODE_SEVERITY_INFO
);
1219 EXPORT_SYMBOL_GPL(uislib_client_inject_add_vnic
);
1222 uislib_client_inject_pause_vnic(U32 busNo
, U32 devNo
)
1224 CONTROLVM_MESSAGE msg
;
1227 init_msg_header(&msg
, CONTROLVM_DEVICE_CHANGESTATE
, 0, 0);
1228 msg
.cmd
.deviceChangeState
.busNo
= busNo
;
1229 msg
.cmd
.deviceChangeState
.devNo
= devNo
;
1230 msg
.cmd
.deviceChangeState
.state
= SegmentStateStandby
;
1231 rc
= pause_device(&msg
);
1232 if (rc
!= CONTROLVM_RESP_SUCCESS
) {
1233 LOGERR("VNIC pause_device failed. busNo=0x%x devNo=0x%x\n",
1239 EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vnic
);
1242 uislib_client_inject_resume_vnic(U32 busNo
, U32 devNo
)
1244 CONTROLVM_MESSAGE msg
;
1247 init_msg_header(&msg
, CONTROLVM_DEVICE_CHANGESTATE
, 0, 0);
1248 msg
.cmd
.deviceChangeState
.busNo
= busNo
;
1249 msg
.cmd
.deviceChangeState
.devNo
= devNo
;
1250 msg
.cmd
.deviceChangeState
.state
= SegmentStateRunning
;
1251 rc
= resume_device(&msg
);
1252 if (rc
!= CONTROLVM_RESP_SUCCESS
) {
1253 LOGERR("VNIC resume_device failed. busNo=0x%x devNo=0x%x\n",
1260 EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vnic
);
1263 uislib_client_inject_del_vnic(U32 busNo
, U32 devNo
)
1265 return delete_device_glue(busNo
, devNo
);
1267 EXPORT_SYMBOL_GPL(uislib_client_inject_del_vnic
);
1270 uislib_client_add_vnic(U32 busNo
)
1272 BOOL busCreated
= FALSE
;
1273 int devNo
= 0; /* Default to 0, since only one device
1274 * will be created for this bus... */
1275 GUID dummyGuid
= GUID0
;
1276 CONTROLVM_MESSAGE msg
;
1278 init_msg_header(&msg
, CONTROLVM_BUS_CREATE
, 0, 0);
1279 msg
.hdr
.Flags
.testMessage
= 1;
1280 msg
.cmd
.createBus
.busNo
= busNo
;
1281 msg
.cmd
.createBus
.deviceCount
= 4;
1282 msg
.cmd
.createBus
.channelAddr
= 0;
1283 msg
.cmd
.createBus
.channelBytes
= 0;
1284 if (create_bus(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
) {
1285 LOGERR("client create_bus failed");
1290 init_msg_header(&msg
, CONTROLVM_DEVICE_CREATE
, 0, 0);
1291 msg
.hdr
.Flags
.testMessage
= 1;
1292 msg
.cmd
.createDevice
.busNo
= busNo
;
1293 msg
.cmd
.createDevice
.devNo
= devNo
;
1294 msg
.cmd
.createDevice
.devInstGuid
= dummyGuid
;
1295 memset(&msg
.cmd
.createDevice
.intr
, 0, sizeof(struct InterruptInfo
));
1296 msg
.cmd
.createDevice
.channelAddr
= PhysicalDataChan
;
1297 msg
.cmd
.createDevice
.channelBytes
= MIN_IO_CHANNEL_SIZE
;
1298 msg
.cmd
.createDevice
.dataTypeGuid
= UltraVnicChannelProtocolGuid
;
1299 if (create_device(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
) {
1300 LOGERR("client create_device failed");
1308 init_msg_header(&msg
, CONTROLVM_BUS_DESTROY
, 0, 0);
1309 msg
.hdr
.Flags
.testMessage
= 1;
1310 msg
.cmd
.destroyBus
.busNo
= busNo
;
1311 if (destroy_bus(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
)
1312 LOGERR("client destroy_bus failed.\n");
1316 } /* end uislib_client_add_vnic */
1317 EXPORT_SYMBOL_GPL(uislib_client_add_vnic
);
1320 uislib_client_delete_vnic(U32 busNo
)
1322 int devNo
= 0; /* Default to 0, since only one device
1323 * will be created for this bus... */
1324 CONTROLVM_MESSAGE msg
;
1326 init_msg_header(&msg
, CONTROLVM_DEVICE_DESTROY
, 0, 0);
1327 msg
.hdr
.Flags
.testMessage
= 1;
1328 msg
.cmd
.destroyDevice
.busNo
= busNo
;
1329 msg
.cmd
.destroyDevice
.devNo
= devNo
;
1330 if (destroy_device(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
) {
1331 /* Don't error exit - try to see if bus can be destroyed... */
1332 LOGERR("client destroy_device failed.\n");
1335 init_msg_header(&msg
, CONTROLVM_BUS_DESTROY
, 0, 0);
1336 msg
.hdr
.Flags
.testMessage
= 1;
1337 msg
.cmd
.destroyBus
.busNo
= busNo
;
1338 if (destroy_bus(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
)
1339 LOGERR("client destroy_bus failed.\n");
1343 EXPORT_SYMBOL_GPL(uislib_client_delete_vnic
);
1344 /* end client_delete_vnic */
1347 uislib_cache_alloc(struct kmem_cache
*cur_pool
, char *fn
, int ln
)
1349 /* __GFP_NORETRY means "ok to fail", meaning kmalloc() can
1350 * return NULL. If you do NOT specify __GFP_NORETRY, Linux
1351 * will go to extreme measures to get memory for you (like,
1352 * invoke oom killer), which will probably cripple the system.
1354 void *p
= kmem_cache_alloc(cur_pool
, GFP_ATOMIC
| __GFP_NORETRY
);
1356 LOGERR("uislib_malloc failed to alloc uiscmdrsp @%s:%d",
1362 EXPORT_SYMBOL_GPL(uislib_cache_alloc
);
1365 uislib_cache_free(struct kmem_cache
*cur_pool
, void *p
, char *fn
, int ln
)
1368 LOGERR("uislib_free NULL pointer @%s:%d", fn
, ln
);
1371 kmem_cache_free(cur_pool
, p
);
1373 EXPORT_SYMBOL_GPL(uislib_cache_free
);
1375 /*****************************************************/
1376 /* proc filesystem callback functions */
1377 /*****************************************************/
1380 vnic_proc_write(struct file
*file
, const char __user
*buffer
,
1381 size_t count
, loff_t
*ppos
)
1383 int action
= 0xffff, busNo
= 0, i
, result
= 0;
1387 if (count
>= ARRAY_SIZE(buf
))
1390 if (copy_from_user(buf
, buffer
, count
)) {
1391 LOGERR("echo > /proc/uislib/vnic copy_from_user ****FAILED.\n");
1395 i
= sscanf(buf
, "%d%c", &action
, &direction
);
1397 LOGERR("unable to parse vnic proc parameters.\n");
1401 if ((direction
!= '-') && (direction
!= '+')) {
1402 LOGERR("unable to determine whether to add or delete vnic\n");
1406 /* if (i < 1), i.e., if we didn't even read the action field,
1407 * then action will default to 0xffff and the code below will
1408 * fall through the switch and print usage.
1412 /* call client method... */
1413 busNo
= 0; /* All client drivers use bus value of 0... */
1414 if (direction
== '+')
1415 result
= uislib_client_add_vnic(busNo
);
1417 result
= uislib_client_delete_vnic(busNo
);
1419 LOGERR("echo 0%c > /proc/uislib/vnic failed (client end)",
1429 LOGERR("USAGE: echo <action><direction (up/down)> > /proc/uislib/vnic");
1431 LOGERR("Client Syntax");
1432 LOGERR("-------------");
1433 LOGERR("0+ ==> add vnic");
1434 LOGERR("0- ==> delete vnic");
1437 } /* end vnic_proc_write */
1440 chipset_proc_write(struct file
*file
, const char __user
*buffer
,
1441 size_t count
, loff_t
*ppos
)
1443 int i
, action
= 0xffff;
1445 CONTROLVM_MESSAGE msg
;
1447 if (count
>= ARRAY_SIZE(buf
))
1450 memset(&msg
, 0, sizeof(CONTROLVM_MESSAGE
));
1452 if (copy_from_user(buf
, buffer
, count
)) {
1453 LOGERR("copy_from_user ****FAILED.\n");
1457 if (chipset_inited
) {
1458 LOGINF("Chipset already initialized\n");
1461 i
= sscanf(buf
, "%x", &action
);
1463 /* if (i < 1), i.e., if we didn't even read the action field,
1464 * then action will default to 0xffff and the code below will
1465 * fall through the switch and print usage.
1470 /* step: initialize the chipset */
1471 init_msg_header(&msg
, CONTROLVM_CHIPSET_INIT
, 0, 0);
1472 msg
.hdr
.Flags
.testMessage
= 0;
1473 msg
.cmd
.initChipset
.busCount
= 23;
1474 msg
.cmd
.initChipset
.switchCount
= 23;
1476 if (init_chipset(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
) {
1477 LOGERR("init_chipset failed.\n");
1483 init_msg_header(&msg
, CONTROLVM_CHIPSET_INIT
, 0, 0);
1484 msg
.hdr
.Flags
.testMessage
= 1;
1485 msg
.cmd
.initChipset
.busCount
= 23;
1486 msg
.cmd
.initChipset
.switchCount
= 23;
1488 if (init_chipset(&msg
, NULL
) != CONTROLVM_RESP_SUCCESS
) {
1489 LOGERR("init_chipset failed.\n");
1498 LOGERR("usage: 1 ==> init_chipset client\n");
1499 LOGERR("usage: 2 ==> init_chipset test\n");
1503 #define PLINE(...) uisutil_add_proc_line_ex(&tot, buff, \
1504 buff_len, __VA_ARGS__)
1507 info_proc_read_helper(char **buff
, int *buff_len
)
1510 struct bus_info
*bus
;
1512 if (PLINE("\nBuses:\n") < 0)
1515 read_lock(&BusListLock
);
1516 for (bus
= BusListHead
; bus
; bus
= bus
->next
) {
1518 if (PLINE(" bus=0x%p, busNo=%d, deviceCount=%d\n",
1519 bus
, bus
->busNo
, bus
->deviceCount
) < 0)
1520 goto err_done_unlock
;
1523 if (PLINE(" Devices:\n") < 0)
1524 goto err_done_unlock
;
1526 for (i
= 0; i
< bus
->deviceCount
; i
++) {
1527 if (bus
->device
[i
]) {
1528 if (PLINE(" busNo %d, device[%i]: 0x%p, chanptr=0x%p, swtch=0x%p\n",
1529 bus
->busNo
, i
, bus
->device
[i
],
1530 bus
->device
[i
]->chanptr
,
1531 bus
->device
[i
]->swtch
) < 0)
1532 goto err_done_unlock
;
1534 if (PLINE(" first_busy_cnt=%llu, moved_to_tail_cnt=%llu, last_on_list_cnt=%llu\n",
1535 bus
->device
[i
]->first_busy_cnt
,
1536 bus
->device
[i
]->moved_to_tail_cnt
,
1537 bus
->device
[i
]->last_on_list_cnt
) < 0)
1538 goto err_done_unlock
;
1542 read_unlock(&BusListLock
);
1544 if (PLINE("UisUtils_Registered_Services: %d\n",
1545 atomic_read(&UisUtils_Registered_Services
)) < 0)
1547 if (PLINE("cycles_before_wait %llu wait_cycles:%llu\n",
1548 cycles_before_wait
, wait_cycles
) < 0)
1550 if (PLINE("tot_wakeup_cnt %llu:tot_wait_cnt %llu:tot_schedule_cnt %llu\n",
1551 tot_wakeup_cnt
, tot_wait_cnt
, tot_schedule_cnt
) < 0)
1553 if (PLINE("en_smart_wakeup %d\n", en_smart_wakeup
) < 0)
1555 if (PLINE("tot_moved_to_tail_cnt %llu\n", tot_moved_to_tail_cnt
) < 0)
1561 read_unlock(&BusListLock
);
1567 info_proc_read(struct file
*file
, char __user
*buf
, size_t len
, loff_t
*offset
)
1571 int remaining_bytes
= PROC_READ_BUFFER_SIZE
;
1574 if (ProcReadBuffer
== NULL
) {
1575 DBGINF("ProcReadBuffer == NULL; allocating buffer.\n.");
1576 ProcReadBuffer
= vmalloc(PROC_READ_BUFFER_SIZE
);
1578 if (ProcReadBuffer
== NULL
) {
1579 LOGERR("failed to allocate buffer to provide proc data.\n");
1584 temp
= ProcReadBuffer
;
1586 if ((*offset
== 0) || (!ProcReadBufferValid
)) {
1587 DBGINF("calling info_proc_read_helper.\n");
1588 /* if the read fails, then -1 will be returned */
1589 totalBytes
= info_proc_read_helper(&temp
, &remaining_bytes
);
1590 ProcReadBufferValid
= 1;
1592 totalBytes
= strlen(ProcReadBuffer
);
1594 return simple_read_from_buffer(buf
, len
, offset
,
1595 ProcReadBuffer
, totalBytes
);
1599 platformnumber_proc_read(struct file
*file
, char __user
*buf
,
1600 size_t len
, loff_t
*offset
)
1604 loff_t pos
= *offset
;
1609 if (pos
> 0 || !len
)
1612 vbuf
= kzalloc(len
, GFP_KERNEL
);
1616 length
= sprintf(vbuf
, "%d\n", PlatformNumber
);
1618 if (copy_to_user(buf
, vbuf
, length
)) {
1628 #ifdef UISLIB_TEST_PROC
1630 /* proc/uislib/vbus/<x>/info */
1632 proc_info_vbus_show(struct seq_file
*m
, void *v
)
1634 struct bus_info
*bus
= m
->private;
1635 int i
, devInfoCount
, x
;
1640 seq_printf(m
, "Client device / client driver info for %s partition (vbus #%d):\n",
1641 bus
->partitionName
, bus
->busNo
);
1642 if ((bus
->busChannelBytes
== 0) || (bus
->pBusChannel
== NULL
))
1645 (bus
->busChannelBytes
-
1646 sizeof(ULTRA_VBUS_CHANNEL_PROTOCOL
)) /
1647 sizeof(ULTRA_VBUS_DEVICEINFO
);
1648 x
= VBUSCHANNEL_devInfoToStringBuffer(&bus
->pBusChannel
->ChpInfo
, buf
,
1649 sizeof(buf
) - 1, -1);
1651 seq_printf(m
, "%s", buf
);
1652 x
= VBUSCHANNEL_devInfoToStringBuffer(&bus
->pBusChannel
->BusInfo
,
1653 buf
, sizeof(buf
) - 1, -1);
1655 seq_printf(m
, "%s", buf
);
1656 for (i
= 0; i
< devInfoCount
; i
++) {
1657 x
= VBUSCHANNEL_devInfoToStringBuffer(&bus
->pBusChannel
->
1659 sizeof(buf
) - 1, i
);
1662 seq_printf(m
, "%s", buf
);
1669 bus_proc_write(struct file
*file
, const char __user
*buffer
,
1670 size_t count
, loff_t
*ppos
)
1672 int server_flag
= 0;
1673 int i
, action
= 0xffff, result
;
1675 CONTROLVM_MESSAGE msg
;
1676 U32 busNo
, deviceCount
;
1678 if (count
>= ARRAY_SIZE(buf
))
1681 memset(&msg
, 0, sizeof(CONTROLVM_MESSAGE
));
1683 if (copy_from_user(buf
, buffer
, count
)) {
1684 LOGERR("echo > /proc/uislib/bus: copy_from_user ****FAILED.");
1688 i
= sscanf(buf
, "%x-%d-%d", &action
, &busNo
, &deviceCount
);
1690 /* if (i < 1), i.e., if we didn't even read the action field,
1691 * then action will default to 0xffff and the code below will
1692 * fall through the switch and print usage.
1699 init_msg_header(&msg
, CONTROLVM_BUS_DESTROY
, 0, server_flag
);
1700 msg
.cmd
.destroyBus
.busNo
= busNo
;
1702 result
= destroy_bus(&msg
, NULL
);
1704 if (result
!= CONTROLVM_RESP_SUCCESS
) {
1705 LOGERR("echo 0-%d > /proc/uislib/bus {CONTROLVM_BUS_DESTROY Failed} Result(%d)",
1714 init_msg_header(&msg
, CONTROLVM_BUS_CREATE
, 0, server_flag
);
1715 msg
.cmd
.createBus
.busNo
= busNo
;
1716 msg
.cmd
.createBus
.deviceCount
= deviceCount
;
1718 result
= create_bus(&msg
, NULL
);
1720 if (result
!= CONTROLVM_RESP_SUCCESS
) {
1721 LOGERR("echo 1-%d-%d > /proc/uislib/bus {CONTROLVM_BUS_CREATE Failed} Result(%d)",
1722 busNo
, deviceCount
, result
);
1731 LOGERR("USAGE: echo <action>-<busNo>... > /proc/uislib/bus");
1733 LOGERR("Destruct Syntax ControlVM Message Id");
1734 LOGERR("--------------- ---------------------");
1735 LOGERR("0-<busNo> ==> CONTROLVM_BUS_DESTROY");
1737 LOGERR("Construct Syntax ControlVM Message Id");
1738 LOGERR("----------------------- -------------------- ");
1739 LOGERR("1-<busNo>-<deviceCount> ==> CONTROLVM_BUS_CREATE");
1745 uislib_proc_read_writeonly(struct file
*file
, char __user
*buffer
,
1746 size_t count
, loff_t
*ppos
)
1752 dev_proc_write(struct file
*file
, const char __user
*buffer
,
1753 size_t count
, loff_t
*ppos
)
1755 int server_flag
= 0;
1756 CONTROLVM_MESSAGE msg
;
1759 unsigned int chanptr
;
1760 int type
, i
, action
= 0xffff, result
;
1762 if (count
>= ARRAY_SIZE(buf
))
1765 if (copy_from_user(buf
, buffer
, count
)) {
1766 LOGERR("echo > /proc/uislib/device: copy_from_user ****FAILED.");
1770 i
= sscanf(buf
, "%x-%d-%d-%x-%d",
1771 &action
, &busNo
, &devNo
, &chanptr
, &type
);
1778 /* destroy a device */
1779 init_msg_header(&msg
, CONTROLVM_DEVICE_DESTROY
, 0, server_flag
);
1780 msg
.cmd
.destroyDevice
.busNo
= busNo
;
1781 msg
.cmd
.destroyDevice
.devNo
= devNo
;
1783 result
= destroy_device(&msg
, NULL
);
1785 if (result
!= CONTROLVM_RESP_SUCCESS
) {
1786 LOGERR("echo 0-%d-%d > /proc/uislib/device {CONTROLVM_DEVICE_DESTROY Failed} Result(%d)",
1787 busNo
, devNo
, result
);
1797 /* create a device */
1798 init_msg_header(&msg
, CONTROLVM_DEVICE_CREATE
, 0, server_flag
);
1799 msg
.cmd
.createDevice
.busNo
= busNo
;
1800 msg
.cmd
.createDevice
.devNo
= devNo
;
1801 msg
.cmd
.createDevice
.channelAddr
= __pa(chanptr
);
1802 msg
.cmd
.createDevice
.channelBytes
= MIN_IO_CHANNEL_SIZE
;
1805 msg
.cmd
.createDevice
.dataTypeGuid
=
1806 UltraVhbaChannelProtocolGuid
;
1808 msg
.cmd
.createDevice
.dataTypeGuid
=
1809 UltraVnicChannelProtocolGuid
;
1811 LOGERR("echo 1-%d-%d-%x-<type> > /proc/uislib/devce failed: invalid device type %d.",
1812 busNo
, devNo
, chanptr
, type
);
1816 result
= create_device(&msg
, NULL
);
1818 if (result
!= CONTROLVM_RESP_SUCCESS
) {
1820 LOGERR("echo 1-%d-%d-%x-0 > /proc/uislib/device {CONTROLVM_DEVICE_CREATE[vHBA] Failed} Result(%d)",
1821 busNo
, devNo
, chanptr
, result
);
1823 LOGERR("echo 1-%d-%d-%x-1 > /proc/uislib/device {CONTROLVM_DEVICE_CREATE[vNIC] Failed} Result(%d)",
1824 busNo
, devNo
, chanptr
, result
);
1832 LOGERR("USAGE: echo <action>-<busNo>-<devNo>... > /proc/uislib/device");
1834 LOGERR("Destruct Syntax ControlVM Message Id");
1835 LOGERR("----------------- ------------------------");
1836 LOGERR("0-<busNo>-<devNo> ==> CONTROLVM_DEVICE_DESTROY");
1838 LOGERR("Construct Syntax ControlVM Message Id");
1840 ("---------------------------------- ----------------------- ");
1842 ("1-<busNo>-<devNo>-<chanptr>-<type> ==> CONTROLVM_DEVICE_CREATE");
1843 LOGERR(" <type = 0>: vHBA");
1844 LOGERR(" <type = 1>: vNIC");
1851 cycles_before_wait_proc_write(struct file
*file
, const char __user
*buffer
,
1852 size_t count
, loff_t
*ppos
)
1856 #define CYCLES_BEFORE_WAIT_USE_ERROR { \
1857 LOGERR("Incorrect Call Home Input.\n"); \
1858 pr_info("Please pass Call Home Event Parameters in the form:\n"); \
1859 pr_info("EventID Category Type[parameter1][parameter2][parameter3][parameter4][parameter5][parameter6]\n"); \
1862 if (count
>= ARRAY_SIZE(buf
))
1866 CYCLES_BEFORE_WAIT_USE_ERROR
;
1868 if (copy_from_user(buf
, buffer
, count
)) {
1869 LOGERR("copy_from_user failed.\n");
1872 buf
[count
- 1] = '\0'; /* Replace the LF at the end of the
1873 * input with a NULL */
1874 /* Pull out the cycles_before_wait must be decimal integer */
1875 if (sscanf(buf
, "%lld", &cycles_before_wait
) != 1)
1876 CYCLES_BEFORE_WAIT_USE_ERROR
;
1882 reset_counts_proc_write(struct file
*file
, const char __user
*buffer
,
1883 size_t count
, loff_t
*ppos
)
1886 unsigned long long new_value
;
1887 struct bus_info
*bus
;
1890 #define RESET_COUNTS_USE_ERROR { \
1891 LOGERR("Incorrect reset_counts Input.\n"); \
1892 pr_info("Please pass the new value for the counters:\n"); \
1893 pr_info("e.g. echo 0 > reset_counts\n"); \
1897 if (count
>= ARRAY_SIZE(buf
))
1901 RESET_COUNTS_USE_ERROR
;
1903 if (copy_from_user(buf
, buffer
, count
)) {
1904 LOGERR("copy_from_user failed.\n");
1907 buf
[count
- 1] = '\0'; /* Replace the LF at the end of the
1908 * input with a NULL */
1909 /* Pull out the reset_counts must be decimal integer */
1910 if (sscanf(buf
, "%llu", &new_value
) != 1)
1911 RESET_COUNTS_USE_ERROR
;
1912 read_lock(&BusListLock
);
1913 for (bus
= BusListHead
; bus
; bus
= bus
->next
) {
1915 for (i
= 0; i
< bus
->deviceCount
; i
++) {
1916 if (bus
->device
[i
]) {
1917 bus
->device
[i
]->first_busy_cnt
= new_value
;
1918 bus
->device
[i
]->moved_to_tail_cnt
= new_value
;
1919 bus
->device
[i
]->last_on_list_cnt
= new_value
;
1923 read_unlock(&BusListLock
);
1924 tot_moved_to_tail_cnt
= new_value
;
1925 tot_wait_cnt
= new_value
;
1926 tot_wakeup_cnt
= new_value
;
1927 tot_schedule_cnt
= new_value
;
1932 smart_wakeup_proc_write(struct file
*file
, const char __user
*buffer
,
1933 size_t count
, loff_t
*ppos
)
1938 #define SMART_WAKEUP_USE_ERROR { \
1939 LOGERR("Incorrect smart_wakeup Input 0 disables smart_wakeup, and 1 enables smart_wakeup.\n"); \
1940 pr_info("echo 0 > smart_wakeup\n"); \
1941 pr_info("echo 1 > smart_wakeup\n"); \
1945 if (count
>= ARRAY_SIZE(buf
))
1949 SMART_WAKEUP_USE_ERROR
;
1951 if (copy_from_user(buf
, buffer
, count
)) {
1952 LOGERR("copy_from_user failed.\n");
1955 buf
[count
- 1] = '\0'; /* Replace the LF at the end of the
1956 * input with a NULL */
1957 /* Pull out the smart_wakeup must be decimal integer */
1958 if (sscanf(buf
, "%d", &new_value
) != 1)
1959 SMART_WAKEUP_USE_ERROR
;
1960 en_smart_wakeup
= new_value
;
1965 test_proc_write(struct file
*file
, const char __user
*buffer
,
1966 size_t count
, loff_t
*ppos
)
1968 int i
, action
= 0xffff;
1970 CONTROLVM_MESSAGE msg
;
1973 if (count
>= ARRAY_SIZE(buf
))
1976 memset(&msg
, 0, sizeof(CONTROLVM_MESSAGE
));
1978 if (copy_from_user(buf
, buffer
, count
)) {
1979 LOGERR("copy_from_user ****FAILED.\n");
1983 i
= sscanf(buf
, "%x", &action
);
1985 /* if (i < 1), i.e., if we didn't even read the action field,
1986 * then action will default to 0xffff and the code below will
1987 * fall through the switch and print usage. */
1990 msg
.hdr
.Id
= CONTROLVM_CHIPSET_STOP
;
1991 msg
.hdr
.Flags
.responseExpected
= 1;
1992 stop_chipset(&msg
, NULL
);
1996 LOGERR("about to issue QUERY vrtc_offset=%LX", vrtc_offset
);
1997 vrtc_offset
= Issue_VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET();
1998 LOGERR("result is vrtc_offset=%LX", vrtc_offset
);
2002 LOGERR("about to increase physical time by 0x%LX seconds",
2004 vrtc_offset
= Issue_VMCALL_UPDATE_PHYSICAL_TIME(vrtc_offset
);
2008 LOGERR("about to decrease physical time by 0x%LX seconds",
2010 vrtc_offset
= Issue_VMCALL_UPDATE_PHYSICAL_TIME(vrtc_offset
);
2013 LOGERR("usage: 6 for CHIPSET_STOP\n");
2014 LOGERR(" 7 for VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET()\n");
2015 LOGERR(" 8 for VMCALL_UPDATE_PHYSICAL_TIME(60)\n");
2016 LOGERR(" 9 for VMCALL_UPDATE_PHYSICAL_TIME(-60)\n");
2023 #endif /* UISLIB_TEST_PROC */
2024 static struct device_info
*
2025 find_dev(U32 busNo
, U32 devNo
)
2027 struct bus_info
*bus
;
2028 struct device_info
*dev
= NULL
;
2030 read_lock(&BusListLock
);
2031 for (bus
= BusListHead
; bus
; bus
= bus
->next
) {
2032 if (bus
->busNo
== busNo
) {
2033 /* make sure the device number is valid */
2034 if (devNo
>= bus
->deviceCount
) {
2035 LOGERR("%s bad busNo, devNo=%d,%d",
2037 (int) (busNo
), (int) (devNo
));
2040 dev
= bus
->device
[devNo
];
2042 LOGERR("%s bad busNo, devNo=%d,%d",
2044 (int) (busNo
), (int) (devNo
));
2049 read_unlock(&BusListLock
);
2053 /* This thread calls the "interrupt" function for each device that has
2054 * enabled such using uislib_enable_channel_interrupts(). The "interrupt"
2055 * function typically reads and processes the devices's channel input
2056 * queue. This thread repeatedly does this, until the thread is told to stop
2057 * (via uisthread_stop()). Sleeping rules:
2058 * - If we have called the "interrupt" function for all devices, and all of
2059 * them have reported "nothing processed" (returned 0), then we will go to
2060 * sleep for a maximum of POLLJIFFIES_NORMAL jiffies.
2061 * - If anyone calls uislib_force_channel_interrupt(), the above jiffy
2062 * sleep will be interrupted, and we will resume calling the "interrupt"
2063 * function for all devices.
2064 * - The list of devices is dynamically re-ordered in order to
2065 * attempt to preserve fairness. Whenever we spin thru the list of
2066 * devices and call the dev->interrupt() function, if we find
2067 * devices which report that there is still more work to do, the
2068 * the first such device we find is moved to the end of the device
2069 * list. This ensures that extremely busy devices don't starve out
2074 Process_Incoming(void *v
)
2076 unsigned long long cur_cycles
, old_cycles
, idle_cycles
, delta_cycles
;
2077 struct list_head
*new_tail
= NULL
;
2079 UIS_DAEMONIZE("dev_incoming");
2080 for (i
= 0; i
< 16; i
++) {
2081 old_cycles
= get_cycles();
2082 wait_event_timeout(Wakeup_Polling_Device_Channels
,
2083 0, POLLJIFFIES_NORMAL
);
2084 cur_cycles
= get_cycles();
2085 if (wait_cycles
== 0) {
2086 wait_cycles
= (cur_cycles
- old_cycles
);
2088 if (wait_cycles
< (cur_cycles
- old_cycles
))
2089 wait_cycles
= (cur_cycles
- old_cycles
);
2092 LOGINF("wait_cycles=%llu", wait_cycles
);
2093 cycles_before_wait
= wait_cycles
;
2095 Go_Polling_Device_Channels
= 0;
2097 struct list_head
*lelt
, *tmp
;
2098 struct device_info
*dev
= NULL
;
2100 /* poll each channel for input */
2101 LOCKSEM_UNINTERRUPTIBLE(&Lock_Polling_Device_Channels
);
2103 list_for_each_safe(lelt
, tmp
, &List_Polling_Device_Channels
) {
2105 dev
= list_entry(lelt
, struct device_info
,
2106 list_polling_device_channels
);
2107 LOCKSEM_UNINTERRUPTIBLE(&dev
->interrupt_callback_lock
);
2109 rc
= dev
->interrupt(dev
->interrupt_context
);
2112 UNLOCKSEM(&dev
->interrupt_callback_lock
);
2114 /* dev->interrupt returned, but there
2115 * is still more work to do.
2116 * Reschedule work to occur as soon as
2119 if (new_tail
== NULL
) {
2120 dev
->first_busy_cnt
++;
2124 &List_Polling_Device_Channels
))) {
2126 dev
->moved_to_tail_cnt
++;
2128 dev
->last_on_list_cnt
++;
2132 if (Incoming_ThreadInfo
.should_stop
)
2135 if (new_tail
!= NULL
) {
2136 tot_moved_to_tail_cnt
++;
2137 list_move_tail(new_tail
, &List_Polling_Device_Channels
);
2139 UNLOCKSEM(&Lock_Polling_Device_Channels
);
2140 cur_cycles
= get_cycles();
2141 delta_cycles
= cur_cycles
- old_cycles
;
2142 old_cycles
= cur_cycles
;
2144 /* At this point, we have scanned thru all of the
2145 * channels, and at least one of the following is true:
2146 * - there is no input waiting on any of the channels
2147 * - we have received a signal to stop this thread
2149 if (Incoming_ThreadInfo
.should_stop
)
2151 if (en_smart_wakeup
== 0xFF) {
2152 LOGINF("en_smart_wakeup set to 0xff, to force exiting process_incoming");
2155 /* wait for POLLJIFFIES_NORMAL jiffies, or until
2156 * someone wakes up Wakeup_Polling_Device_Channels,
2157 * whichever comes first only do a wait when we have
2158 * been idle for cycles_before_wait cycles.
2160 if (idle_cycles
> cycles_before_wait
) {
2161 Go_Polling_Device_Channels
= 0;
2163 wait_event_timeout(Wakeup_Polling_Device_Channels
,
2164 Go_Polling_Device_Channels
,
2165 POLLJIFFIES_NORMAL
);
2166 Go_Polling_Device_Channels
= 1;
2170 idle_cycles
= idle_cycles
+ delta_cycles
;
2173 DBGINF("exiting.\n");
2174 complete_and_exit(&Incoming_ThreadInfo
.has_stopped
, 0);
2178 Initialize_incoming_thread(void)
2180 if (Incoming_Thread_Started
)
2182 if (!uisthread_start(&Incoming_ThreadInfo
,
2183 &Process_Incoming
, NULL
, "dev_incoming")) {
2184 LOGERR("uisthread_start Initialize_incoming_thread ****FAILED");
2187 Incoming_Thread_Started
= TRUE
;
2191 /* Add a new device/channel to the list being processed by
2192 * Process_Incoming().
2193 * <interrupt> - indicates the function to call periodically.
2194 * <interrupt_context> - indicates the data to pass to the <interrupt>
2198 uislib_enable_channel_interrupts(U32 busNo
, U32 devNo
,
2199 int (*interrupt
)(void *),
2200 void *interrupt_context
)
2202 struct device_info
*dev
;
2203 dev
= find_dev(busNo
, devNo
);
2205 LOGERR("%s busNo=%d, devNo=%d", __func__
, (int) (busNo
),
2209 LOCKSEM_UNINTERRUPTIBLE(&Lock_Polling_Device_Channels
);
2210 Initialize_incoming_thread();
2211 dev
->interrupt
= interrupt
;
2212 dev
->interrupt_context
= interrupt_context
;
2213 dev
->polling
= TRUE
;
2214 list_add_tail(&(dev
->list_polling_device_channels
),
2215 &List_Polling_Device_Channels
);
2216 UNLOCKSEM(&Lock_Polling_Device_Channels
);
2218 EXPORT_SYMBOL_GPL(uislib_enable_channel_interrupts
);
2220 /* Remove a device/channel from the list being processed by
2221 * Process_Incoming().
2224 uislib_disable_channel_interrupts(U32 busNo
, U32 devNo
)
2226 struct device_info
*dev
;
2227 dev
= find_dev(busNo
, devNo
);
2229 LOGERR("%s busNo=%d, devNo=%d", __func__
, (int) (busNo
),
2233 LOCKSEM_UNINTERRUPTIBLE(&Lock_Polling_Device_Channels
);
2234 list_del(&dev
->list_polling_device_channels
);
2235 dev
->polling
= FALSE
;
2236 dev
->interrupt
= NULL
;
2237 UNLOCKSEM(&Lock_Polling_Device_Channels
);
2239 EXPORT_SYMBOL_GPL(uislib_disable_channel_interrupts
);
2242 do_wakeup_polling_device_channels(struct work_struct
*dummy
)
2244 if (!Go_Polling_Device_Channels
) {
2245 Go_Polling_Device_Channels
= 1;
2246 wake_up(&Wakeup_Polling_Device_Channels
);
2250 static DECLARE_WORK(Work_wakeup_polling_device_channels
,
2251 do_wakeup_polling_device_channels
);
2253 /* Call this function when you want to send a hint to Process_Incoming() that
2254 * your device might have more requests.
2257 uislib_force_channel_interrupt(U32 busNo
, U32 devNo
)
2259 if (en_smart_wakeup
== 0)
2261 if (Go_Polling_Device_Channels
)
2263 /* The point of using schedule_work() instead of just doing
2264 * the work inline is to force a slight delay before waking up
2265 * the Process_Incoming() thread.
2268 schedule_work(&Work_wakeup_polling_device_channels
);
2270 EXPORT_SYMBOL_GPL(uislib_force_channel_interrupt
);
2272 /*****************************************************/
2273 /* Module Init & Exit functions */
2274 /*****************************************************/
2277 uislib_mod_init(void)
2280 LOGINF("MONITORAPIS");
2282 LOGINF("sizeof(struct uiscmdrsp):%lu bytes\n",
2283 (ulong
) sizeof(struct uiscmdrsp
));
2284 LOGINF("sizeof(struct phys_info):%lu\n",
2285 (ulong
) sizeof(struct phys_info
));
2286 LOGINF("sizeof(uiscmdrsp_scsi):%lu\n",
2287 (ulong
) sizeof(struct uiscmdrsp_scsi
));
2288 LOGINF("sizeof(uiscmdrsp_net):%lu\n",
2289 (ulong
) sizeof(struct uiscmdrsp_net
));
2290 LOGINF("sizeof(CONTROLVM_MESSAGE):%lu bytes\n",
2291 (ulong
) sizeof(CONTROLVM_MESSAGE
));
2292 LOGINF("sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL):%lu bytes\n",
2293 (ulong
) sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL
));
2294 LOGINF("sizeof(CHANNEL_HEADER):%lu bytes\n",
2295 (ulong
) sizeof(CHANNEL_HEADER
));
2296 LOGINF("sizeof(ULTRA_IO_CHANNEL_PROTOCOL):%lu bytes\n",
2297 (ulong
) sizeof(ULTRA_IO_CHANNEL_PROTOCOL
));
2298 LOGINF("SIZEOF_CMDRSP:%lu bytes\n", SIZEOF_CMDRSP
);
2299 LOGINF("SIZEOF_PROTOCOL:%lu bytes\n", SIZEOF_PROTOCOL
);
2301 /* initialize global pointers to NULL */
2303 BusListCount
= MaxBusCount
= 0;
2304 rwlock_init(&BusListLock
);
2305 VirtControlChanFunc
= NULL
;
2307 /* Issue VMCALL_GET_CONTROLVM_ADDR to get CtrlChanPhysAddr and
2308 * then map this physical address to a virtual address. */
2309 POSTCODE_LINUX_2(DRIVER_ENTRY_PC
, POSTCODE_SEVERITY_INFO
);
2311 /* create the proc entries for the channels */
2312 uislib_proc_dir
= proc_mkdir(DIR_PROC_ENTRY
, NULL
);
2313 /* (e.g., for /proc/uislib/vbus/<x>/info) */
2314 uislib_proc_vbus_dir
= proc_mkdir(DIR_VBUS_PROC_ENTRY
, uislib_proc_dir
);
2316 vnic_proc_entry
= proc_create(VNIC_PROC_ENTRY_FN
, 0, uislib_proc_dir
,
2318 SET_PROC_OWNER(vnic_proc_entry
, THIS_MODULE
);
2320 /* for testing purposes only, create the proc entries for
2321 * enqueuing Control Channel messages */
2322 chipset_proc_entry
=
2323 proc_create(CHIPSET_PROC_ENTRY_FN
, 0, uislib_proc_dir
,
2324 &proc_chipset_fops
);
2325 SET_PROC_OWNER(chipset_proc_entry
, THIS_MODULE
);
2327 info_proc_entry
= proc_create(INFO_PROC_ENTRY_FN
, 0, uislib_proc_dir
,
2329 SET_PROC_OWNER(info_proc_entry
, THIS_MODULE
);
2331 platformnumber_proc_entry
=
2332 proc_create(PLATFORMNUMBER_PROC_ENTRY_FN
, 0, uislib_proc_dir
,
2333 &proc_platformnumber_fops
);
2334 SET_PROC_OWNER(platformnumberinfo_proc_entry
, THIS_MODULE
);
2336 cycles_before_wait_proc_entry
=
2337 proc_create(CYCLES_BEFORE_WAIT_PROC_ENTRY_FN
, 0, uislib_proc_dir
,
2338 &proc_cycles_before_wait_fops
);
2339 SET_PROC_OWNER(cycles_before_wait_proc_entry
, THIS_MODULE
);
2341 reset_counts_proc_entry
=
2342 proc_create(RESET_COUNTS_PROC_ENTRY_FN
, 0, uislib_proc_dir
,
2343 &proc_reset_counts_fops
);
2344 SET_PROC_OWNER(reset_counts_proc_entry
, THIS_MODULE
);
2346 smart_wakeup_proc_entry
=
2347 proc_create(SMART_WAKEUP_PROC_ENTRY_FN
, 0, uislib_proc_dir
,
2348 &proc_smart_wakeup_fops
);
2349 SET_PROC_OWNER(smart_wakeup_proc_entry
, THIS_MODULE
);
2351 #ifdef UISLIB_TEST_PROC
2352 test_proc_entry
= proc_create(TEST_PROC_ENTRY_FN
, 0, uislib_proc_dir
,
2354 SET_PROC_OWNER(test_proc_entry
, THIS_MODULE
);
2356 bus_proc_entry
= proc_create(BUS_PROC_ENTRY_FN
, 0, uislib_proc_dir
,
2358 SET_PROC_OWNER(bus_proc_entry
, THIS_MODULE
);
2360 dev_proc_entry
= proc_create(DEV_PROC_ENTRY_FN
, 0, uislib_proc_dir
,
2362 SET_PROC_OWNER(dev_proc_entry
, THIS_MODULE
);
2363 #endif /* UISLIB_TEST_PROC */
2364 POSTCODE_LINUX_3(DRIVER_EXIT_PC
, 0, POSTCODE_SEVERITY_INFO
);
2369 uislib_mod_exit(void)
2371 if (disable_proc_entry
)
2372 remove_proc_entry(DISABLE_PROC_ENTRY_FN
, uislib_proc_dir
);
2373 if (cycles_before_wait_proc_entry
)
2374 remove_proc_entry(CYCLES_BEFORE_WAIT_PROC_ENTRY_FN
,
2376 if (reset_counts_proc_entry
)
2377 remove_proc_entry(RESET_COUNTS_PROC_ENTRY_FN
, uislib_proc_dir
);
2378 if (smart_wakeup_proc_entry
)
2379 remove_proc_entry(SMART_WAKEUP_PROC_ENTRY_FN
, uislib_proc_dir
);
2380 if (ctrlchan_proc_entry
)
2381 remove_proc_entry(CTRLCHAN_PROC_ENTRY_FN
, uislib_proc_dir
);
2382 if (pmem_proc_entry
)
2383 remove_proc_entry(PMEM_PROC_ENTRY_FN
, uislib_proc_dir
);
2384 if (info_proc_entry
)
2385 remove_proc_entry(INFO_PROC_ENTRY_FN
, uislib_proc_dir
);
2386 if (switch_proc_entry
)
2387 remove_proc_entry(SWITCH_PROC_ENTRY_FN
, uislib_proc_dir
);
2388 if (extport_proc_entry
)
2389 remove_proc_entry(EXTPORT_PROC_ENTRY_FN
, uislib_proc_dir
);
2390 if (platformnumber_proc_entry
)
2391 remove_proc_entry(PLATFORMNUMBER_PROC_ENTRY_FN
,
2394 remove_proc_entry(BUS_PROC_ENTRY_FN
, uislib_proc_dir
);
2396 remove_proc_entry(DEV_PROC_ENTRY_FN
, uislib_proc_dir
);
2397 if (vnic_proc_entry
)
2398 remove_proc_entry(VNIC_PROC_ENTRY_FN
, uislib_proc_dir
);
2399 if (chipset_proc_entry
)
2400 remove_proc_entry(CHIPSET_PROC_ENTRY_FN
, uislib_proc_dir
);
2401 if (uislib_proc_vbus_dir
)
2402 remove_proc_entry(DIR_VBUS_PROC_ENTRY
, uislib_proc_dir
);
2403 if (uislib_proc_dir
)
2404 remove_proc_entry(DIR_PROC_ENTRY
, NULL
);
2406 if (ProcReadBuffer
) {
2407 vfree(ProcReadBuffer
);
2408 ProcReadBuffer
= NULL
;
2411 DBGINF("goodbye.\n");
2415 module_init(uislib_mod_init
);
2416 module_exit(uislib_mod_exit
);
2418 MODULE_LICENSE("GPL");
2419 MODULE_AUTHOR("Usha Srinivasan");
2420 MODULE_ALIAS("uislib");
2421 /* this is extracted during depmod and kept in modules.dep */