staging: unisys: refactor SPAR_CONTROLVM_CHANNEL_PROTOCOL
[deliverable/linux.git] / drivers / staging / unisys / uislib / uislib.c
CommitLineData
bac8a4d5
KC
1/* uislib.c
2 *
f6d0c1e6 3 * Copyright (C) 2010 - 2013 UNISYS CORPORATION
bac8a4d5
KC
4 * All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or (at
9 * your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
14 * NON INFRINGEMENT. See the GNU General Public License for more
15 * details.
16 */
17
18/* @ALL_INSPECTED */
19#define EXPORT_SYMTAB
20#include <linux/kernel.h>
21#include <linux/highmem.h>
22#ifdef CONFIG_MODVERSIONS
23#include <config/modversions.h>
24#endif
25#include <linux/module.h>
28fa597f 26#include <linux/debugfs.h>
bac8a4d5 27
1d2def98
BR
28#include <linux/types.h>
29#include <linux/uuid.h>
bac8a4d5
KC
30
31#include <linux/version.h>
32#include "uniklog.h"
33#include "diagnostics/appos_subsystems.h"
34#include "uisutils.h"
35#include "vbuschannel.h"
36
37#include <linux/proc_fs.h>
38#include <linux/uaccess.h> /* for copy_from_user */
39#include <linux/ctype.h> /* for toupper */
40#include <linux/list.h>
41
42#include "sparstop.h"
43#include "visorchipset.h"
44#include "chanstub.h"
45#include "version.h"
46#include "guestlinuxdebug.h"
47
48#define SET_PROC_OWNER(x, y)
49
bac8a4d5
KC
50#define POLLJIFFIES_NORMAL 1
51/* Choose whether or not you want to wakeup the request-polling thread
52 * after an IO termination:
53 * this is shorter than using __FILE__ (full path name) in
54 * debug/info/error messages
55 */
56#define CURRENT_FILE_PC UISLIB_PC_uislib_c
57#define __MYFILE__ "uislib.c"
58
59/* global function pointers that act as callback functions into virtpcimod */
2df7cc62 60int (*virt_control_chan_func)(struct guest_msgs *);
bac8a4d5
KC
61
62static int ProcReadBufferValid;
63static char *ProcReadBuffer; /* Note this MUST be global,
64 * because the contents must */
65static unsigned int chipset_inited;
a8d7f21d 66
bac8a4d5
KC
67#define WAIT_ON_CALLBACK(handle) \
68 do { \
69 if (handle) \
70 break; \
71 UIS_THREAD_WAIT; \
72 } while (1)
73
74static struct bus_info *BusListHead;
75static rwlock_t BusListLock;
76static int BusListCount; /* number of buses in the list */
77static int MaxBusCount; /* maximum number of buses expected */
5fc0229a 78static u64 PhysicalDataChan;
bac8a4d5
KC
79static int PlatformNumber;
80
bac8a4d5
KC
81static struct uisthread_info Incoming_ThreadInfo;
82static BOOL Incoming_Thread_Started = FALSE;
a8d7f21d
KC
83static LIST_HEAD(List_Polling_Device_Channels);
84static unsigned long long tot_moved_to_tail_cnt;
85static unsigned long long tot_wait_cnt;
86static unsigned long long tot_wakeup_cnt;
87static unsigned long long tot_schedule_cnt;
88static int en_smart_wakeup = 1;
bac8a4d5 89static DEFINE_SEMAPHORE(Lock_Polling_Device_Channels); /* unlocked */
a8d7f21d 90static DECLARE_WAIT_QUEUE_HEAD(Wakeup_Polling_Device_Channels);
bac8a4d5
KC
91static int Go_Polling_Device_Channels;
92
bac8a4d5
KC
93#define CALLHOME_PROC_ENTRY_FN "callhome"
94#define CALLHOME_THROTTLED_PROC_ENTRY_FN "callhome_throttled"
b27a00de 95
28fa597f
BR
96#define DIR_DEBUGFS_ENTRY "uislib"
97static struct dentry *dir_debugfs;
98
99#define PLATFORMNUMBER_DEBUGFS_ENTRY_FN "platform"
100static struct dentry *platformnumber_debugfs_read;
101
b913a2ef
BR
102#define CYCLES_BEFORE_WAIT_DEBUGFS_ENTRY_FN "cycles_before_wait"
103static struct dentry *cycles_before_wait_debugfs_read;
104
81d2d7de
BR
105#define SMART_WAKEUP_DEBUGFS_ENTRY_FN "smart_wakeup"
106static struct dentry *smart_wakeup_debugfs_entry;
107
7ec96720
BR
108#define INFO_DEBUGFS_ENTRY_FN "info"
109static struct dentry *info_debugfs_entry;
110
a8d7f21d 111static unsigned long long cycles_before_wait, wait_cycles;
bac8a4d5
KC
112
113/*****************************************************/
114/* local functions */
115/*****************************************************/
116
7ec96720 117static ssize_t info_debugfs_read(struct file *file, char __user *buf,
bac8a4d5 118 size_t len, loff_t *offset);
7ec96720
BR
119static const struct file_operations debugfs_info_fops = {
120 .read = info_debugfs_read,
bac8a4d5
KC
121};
122
bac8a4d5 123static void
3ab47701 124init_msg_header(struct controlvm_message *msg, u32 id, uint rsp, uint svr)
bac8a4d5 125{
3ab47701 126 memset(msg, 0, sizeof(struct controlvm_message));
98d7b594
BR
127 msg->hdr.id = id;
128 msg->hdr.flags.response_expected = rsp;
129 msg->hdr.flags.server = svr;
bac8a4d5
KC
130}
131
a8d7f21d 132static __iomem void *
5fc0229a 133init_vbus_channel(u64 channelAddr, u32 channelBytes)
bac8a4d5 134{
3db5540d 135 void __iomem *rc = NULL;
a8d7f21d 136 void __iomem *pChan = uislib_ioremap_cache(channelAddr, channelBytes);
ddc9f84b 137
bac8a4d5
KC
138 if (!pChan) {
139 LOGERR("CONTROLVM_BUS_CREATE error: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed",
140 (unsigned long long) channelAddr,
141 (unsigned long long) channelBytes);
d9355f89
KC
142 rc = NULL;
143 goto Away;
bac8a4d5 144 }
93a84565 145 if (!SPAR_VBUS_CHANNEL_OK_CLIENT(pChan, NULL)) {
548950a2
KC
146 ERRDRV("%s channel cannot be used", __func__);
147 uislib_iounmap(pChan);
148 rc = NULL;
149 goto Away;
bac8a4d5 150 }
d9355f89 151 rc = pChan;
bac8a4d5
KC
152Away:
153 return rc;
154}
155
156static int
3ab47701 157create_bus(struct controlvm_message *msg, char *buf)
bac8a4d5 158{
b3c55b13 159 u32 busNo, deviceCount;
bac8a4d5
KC
160 struct bus_info *tmp, *bus;
161 size_t size;
162
163 if (MaxBusCount == BusListCount) {
164 LOGERR("CONTROLVM_BUS_CREATE Failed: max buses:%d already created\n",
165 MaxBusCount);
166 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, MaxBusCount,
167 POSTCODE_SEVERITY_ERR);
168 return CONTROLVM_RESP_ERROR_MAX_BUSES;
169 }
170
2ea5117b
BR
171 busNo = msg->cmd.create_bus.bus_no;
172 deviceCount = msg->cmd.create_bus.dev_count;
bac8a4d5
KC
173
174 POSTCODE_LINUX_4(BUS_CREATE_ENTRY_PC, busNo, deviceCount,
175 POSTCODE_SEVERITY_INFO);
176
177 size =
178 sizeof(struct bus_info) +
179 (deviceCount * sizeof(struct device_info *));
60140462 180 bus = kzalloc(size, GFP_ATOMIC);
bac8a4d5
KC
181 if (!bus) {
182 LOGERR("CONTROLVM_BUS_CREATE Failed: kmalloc for bus failed.\n");
183 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, busNo,
184 POSTCODE_SEVERITY_ERR);
185 return CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
186 }
187
bac8a4d5
KC
188 /* Currently by default, the bus Number is the GuestHandle.
189 * Configure Bus message can override this.
190 */
98d7b594 191 if (msg->hdr.flags.test_message) {
bac8a4d5 192 /* This implies we're the IOVM so set guest handle to 0... */
43ecb9fe
BR
193 bus->guest_handle = 0;
194 bus->bus_no = busNo;
195 bus->local_vnic = 1;
bac8a4d5 196 } else
43ecb9fe
BR
197 bus->bus_no = bus->guest_handle = busNo;
198 sprintf(bus->name, "%d", (int) bus->bus_no);
199 bus->device_count = deviceCount;
bac8a4d5
KC
200 bus->device =
201 (struct device_info **) ((char *) bus + sizeof(struct bus_info));
2ea5117b 202 bus->bus_inst_uuid = msg->cmd.create_bus.bus_inst_uuid;
43ecb9fe
BR
203 bus->bus_channel_bytes = 0;
204 bus->bus_channel = NULL;
bac8a4d5
KC
205
206 /* add bus to our bus list - but check for duplicates first */
207 read_lock(&BusListLock);
208 for (tmp = BusListHead; tmp; tmp = tmp->next) {
43ecb9fe 209 if (tmp->bus_no == bus->bus_no)
bac8a4d5
KC
210 break;
211 }
212 read_unlock(&BusListLock);
213 if (tmp) {
214 /* found a bus already in the list with same busNo -
215 * reject add
216 */
217 LOGERR("CONTROLVM_BUS_CREATE Failed: bus %d already exists.\n",
43ecb9fe
BR
218 bus->bus_no);
219 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->bus_no,
bac8a4d5 220 POSTCODE_SEVERITY_ERR);
60140462 221 kfree(bus);
bac8a4d5
KC
222 return CONTROLVM_RESP_ERROR_ALREADY_DONE;
223 }
2ea5117b
BR
224 if ((msg->cmd.create_bus.channel_addr != 0)
225 && (msg->cmd.create_bus.channel_bytes != 0)) {
226 bus->bus_channel_bytes = msg->cmd.create_bus.channel_bytes;
43ecb9fe 227 bus->bus_channel =
2ea5117b
BR
228 init_vbus_channel(msg->cmd.create_bus.channel_addr,
229 msg->cmd.create_bus.channel_bytes);
bac8a4d5
KC
230 }
231 /* the msg is bound for virtpci; send guest_msgs struct to callback */
98d7b594 232 if (!msg->hdr.flags.server) {
bac8a4d5 233 struct guest_msgs cmd;
ddc9f84b 234
bac8a4d5 235 cmd.msgtype = GUEST_ADD_VBUS;
34e6230b 236 cmd.add_vbus.bus_no = busNo;
43ecb9fe 237 cmd.add_vbus.chanptr = bus->bus_channel;
34e6230b 238 cmd.add_vbus.dev_count = deviceCount;
2ea5117b
BR
239 cmd.add_vbus.bus_uuid = msg->cmd.create_bus.bus_data_type_uuid;
240 cmd.add_vbus.instance_uuid = msg->cmd.create_bus.bus_inst_uuid;
2df7cc62 241 if (!virt_control_chan_func) {
bac8a4d5 242 LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci callback not registered.");
43ecb9fe 243 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->bus_no,
bac8a4d5 244 POSTCODE_SEVERITY_ERR);
d21bb450 245 kfree(bus);
bac8a4d5
KC
246 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
247 }
2df7cc62 248 if (!virt_control_chan_func(&cmd)) {
bac8a4d5 249 LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci GUEST_ADD_VBUS returned error.");
43ecb9fe 250 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->bus_no,
bac8a4d5 251 POSTCODE_SEVERITY_ERR);
d21bb450 252 kfree(bus);
bac8a4d5
KC
253 return
254 CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
255 }
256 }
bac8a4d5
KC
257
258 /* add bus at the head of our list */
259 write_lock(&BusListLock);
260 if (!BusListHead)
261 BusListHead = bus;
262 else {
263 bus->next = BusListHead;
264 BusListHead = bus;
265 }
266 BusListCount++;
267 write_unlock(&BusListLock);
268
43ecb9fe 269 POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus->bus_no,
bac8a4d5
KC
270 POSTCODE_SEVERITY_INFO);
271 return CONTROLVM_RESP_SUCCESS;
272}
273
274static int
3ab47701 275destroy_bus(struct controlvm_message *msg, char *buf)
bac8a4d5
KC
276{
277 int i;
278 struct bus_info *bus, *prev = NULL;
81e4c97e 279 struct guest_msgs cmd;
b3c55b13 280 u32 busNo;
bac8a4d5 281
2ea5117b 282 busNo = msg->cmd.destroy_bus.bus_no;
bac8a4d5 283
bac8a4d5 284 read_lock(&BusListLock);
81e4c97e
BR
285
286 bus = BusListHead;
287 while (bus) {
43ecb9fe 288 if (bus->bus_no == busNo)
bac8a4d5 289 break;
81e4c97e
BR
290 prev = bus;
291 bus = bus->next;
bac8a4d5
KC
292 }
293
294 if (!bus) {
295 LOGERR("CONTROLVM_BUS_DESTROY Failed: failed to find bus %d.\n",
296 busNo);
297 read_unlock(&BusListLock);
298 return CONTROLVM_RESP_ERROR_ALREADY_DONE;
299 }
81e4c97e
BR
300
301 /* verify that this bus has no devices. */
43ecb9fe 302 for (i = 0; i < bus->device_count; i++) {
81e4c97e
BR
303 if (bus->device[i] != NULL) {
304 LOGERR("CONTROLVM_BUS_DESTROY Failed: device %i attached to bus %d.",
305 i, busNo);
306 read_unlock(&BusListLock);
307 return CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED;
308 }
309 }
310 read_unlock(&BusListLock);
311
98d7b594 312 if (msg->hdr.flags.server)
81e4c97e
BR
313 goto remove;
314
315 /* client messages require us to call the virtpci callback associated
316 with this bus. */
317 cmd.msgtype = GUEST_DEL_VBUS;
a990356d 318 cmd.del_vbus.bus_no = busNo;
2df7cc62 319 if (!virt_control_chan_func) {
81e4c97e
BR
320 LOGERR("CONTROLVM_BUS_DESTROY Failed: virtpci callback not registered.");
321 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
322 }
2df7cc62 323 if (!virt_control_chan_func(&cmd)) {
81e4c97e
BR
324 LOGERR("CONTROLVM_BUS_DESTROY Failed: virtpci GUEST_DEL_VBUS returned error.");
325 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
326 }
327
328 /* finally, remove the bus from the list */
329remove:
330 write_lock(&BusListLock);
331 if (prev) /* not at head */
332 prev->next = bus->next;
333 else
334 BusListHead = bus->next;
335 BusListCount--;
336 write_unlock(&BusListLock);
337
43ecb9fe
BR
338 if (bus->bus_channel) {
339 uislib_iounmap(bus->bus_channel);
340 bus->bus_channel = NULL;
bac8a4d5
KC
341 }
342
60140462 343 kfree(bus);
bac8a4d5
KC
344 return CONTROLVM_RESP_SUCCESS;
345}
346
347static int
3ab47701 348create_device(struct controlvm_message *msg, char *buf)
bac8a4d5
KC
349{
350 struct device_info *dev;
351 struct bus_info *bus;
b3c55b13 352 u32 busNo, devNo;
bac8a4d5 353 int result = CONTROLVM_RESP_SUCCESS;
5fc0229a 354 u64 minSize = MIN_IO_CHANNEL_SIZE;
38ab19b6 355 struct req_handler_info *pReqHandler;
bac8a4d5 356
f91b9262
BR
357 busNo = msg->cmd.create_device.bus_no;
358 devNo = msg->cmd.create_device.dev_no;
bac8a4d5
KC
359
360 POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, devNo, busNo,
361 POSTCODE_SEVERITY_INFO);
362
60140462 363 dev = kzalloc(sizeof(struct device_info), GFP_ATOMIC);
bac8a4d5
KC
364 if (!dev) {
365 LOGERR("CONTROLVM_DEVICE_CREATE Failed: kmalloc for dev failed.\n");
366 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo,
367 POSTCODE_SEVERITY_ERR);
368 return CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
369 }
370
f91b9262 371 dev->channel_uuid = msg->cmd.create_device.data_type_uuid;
2ea5117b 372 dev->intr = msg->cmd.create_device.intr;
f91b9262 373 dev->channel_addr = msg->cmd.create_device.channel_addr;
f796e84c
BR
374 dev->bus_no = busNo;
375 dev->dev_no = devNo;
bac8a4d5
KC
376 sema_init(&dev->interrupt_callback_lock, 1); /* unlocked */
377 sprintf(dev->devid, "vbus%u:dev%u", (unsigned) busNo, (unsigned) devNo);
378 /* map the channel memory for the device. */
98d7b594 379 if (msg->hdr.flags.test_message)
f796e84c 380 dev->chanptr = (void __iomem *)__va(dev->channel_addr);
bac8a4d5 381 else {
ea2cfd65 382 pReqHandler = req_handler_find(dev->channel_uuid);
bac8a4d5
KC
383 if (pReqHandler)
384 /* generic service handler registered for this
385 * channel
386 */
387 minSize = pReqHandler->min_channel_bytes;
f91b9262 388 if (minSize > msg->cmd.create_device.channel_bytes) {
bac8a4d5 389 LOGERR("CONTROLVM_DEVICE_CREATE Failed: channel size is too small, channel size:0x%lx, required size:0x%lx",
f91b9262 390 (ulong) msg->cmd.create_device.channel_bytes,
bac8a4d5
KC
391 (ulong) minSize);
392 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo,
393 POSTCODE_SEVERITY_ERR);
394 result = CONTROLVM_RESP_ERROR_CHANNEL_SIZE_TOO_SMALL;
395 goto Away;
396 }
397 dev->chanptr =
f796e84c 398 uislib_ioremap_cache(dev->channel_addr,
f91b9262 399 msg->cmd.create_device.channel_bytes);
bac8a4d5
KC
400 if (!dev->chanptr) {
401 LOGERR("CONTROLVM_DEVICE_CREATE Failed: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed",
f796e84c 402 dev->channel_addr,
f91b9262 403 msg->cmd.create_device.channel_bytes);
bac8a4d5
KC
404 result = CONTROLVM_RESP_ERROR_IOREMAP_FAILED;
405 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo,
406 POSTCODE_SEVERITY_ERR);
407 goto Away;
408 }
409 }
f91b9262
BR
410 dev->instance_uuid = msg->cmd.create_device.dev_inst_uuid;
411 dev->channel_bytes = msg->cmd.create_device.channel_bytes;
bac8a4d5
KC
412
413 read_lock(&BusListLock);
414 for (bus = BusListHead; bus; bus = bus->next) {
43ecb9fe 415 if (bus->bus_no == busNo) {
bac8a4d5 416 /* make sure the device number is valid */
43ecb9fe 417 if (devNo >= bus->device_count) {
bac8a4d5 418 LOGERR("CONTROLVM_DEVICE_CREATE Failed: device (%d) >= deviceCount (%d).",
43ecb9fe 419 devNo, bus->device_count);
bac8a4d5
KC
420 result = CONTROLVM_RESP_ERROR_MAX_DEVICES;
421 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC,
422 devNo, busNo,
423 POSTCODE_SEVERITY_ERR);
424 read_unlock(&BusListLock);
425 goto Away;
426 }
427 /* make sure this device is not already set */
428 if (bus->device[devNo]) {
429 LOGERR("CONTROLVM_DEVICE_CREATE Failed: device %d is already exists.",
430 devNo);
431 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC,
432 devNo, busNo,
433 POSTCODE_SEVERITY_ERR);
434 result = CONTROLVM_RESP_ERROR_ALREADY_DONE;
435 read_unlock(&BusListLock);
436 goto Away;
437 }
438 read_unlock(&BusListLock);
439 /* the msg is bound for virtpci; send
440 * guest_msgs struct to callback
441 */
98d7b594 442 if (!msg->hdr.flags.server) {
bac8a4d5 443 struct guest_msgs cmd;
ddc9f84b 444
f796e84c 445 if (!uuid_le_cmp(dev->channel_uuid,
9eee5d1f 446 spar_vhba_channel_protocol_uuid)) {
9fd1b95a
BR
447 wait_for_valid_guid(&((
448 struct channel_header
449 __iomem *) (dev->
bac8a4d5 450 chanptr))->
a8a31f61 451 chtype);
93a84565 452 if (!SPAR_VHBA_CHANNEL_OK_CLIENT
bac8a4d5
KC
453 (dev->chanptr, NULL)) {
454 LOGERR("CONTROLVM_DEVICE_CREATE Failed:[CLIENT]VHBA dev %d chan invalid.",
455 devNo);
456 POSTCODE_LINUX_4
457 (DEVICE_CREATE_FAILURE_PC,
458 devNo, busNo,
459 POSTCODE_SEVERITY_ERR);
460 result = CONTROLVM_RESP_ERROR_CHANNEL_INVALID;
461 goto Away;
462 }
463 cmd.msgtype = GUEST_ADD_VHBA;
464 cmd.add_vhba.chanptr = dev->chanptr;
8bd352ef
BR
465 cmd.add_vhba.bus_no = busNo;
466 cmd.add_vhba.device_no = devNo;
467 cmd.add_vhba.instance_uuid =
f796e84c 468 dev->instance_uuid;
bac8a4d5
KC
469 cmd.add_vhba.intr = dev->intr;
470 } else
f796e84c 471 if (!uuid_le_cmp(dev->channel_uuid,
9eee5d1f 472 spar_vnic_channel_protocol_uuid)) {
9fd1b95a
BR
473 wait_for_valid_guid(&((
474 struct channel_header
475 __iomem *) (dev->
bac8a4d5 476 chanptr))->
a8a31f61 477 chtype);
93a84565 478 if (!SPAR_VNIC_CHANNEL_OK_CLIENT
bac8a4d5
KC
479 (dev->chanptr, NULL)) {
480 LOGERR("CONTROLVM_DEVICE_CREATE Failed: VNIC[CLIENT] dev %d chan invalid.",
481 devNo);
482 POSTCODE_LINUX_4
483 (DEVICE_CREATE_FAILURE_PC,
484 devNo, busNo,
485 POSTCODE_SEVERITY_ERR);
486 result = CONTROLVM_RESP_ERROR_CHANNEL_INVALID;
487 goto Away;
488 }
489 cmd.msgtype = GUEST_ADD_VNIC;
490 cmd.add_vnic.chanptr = dev->chanptr;
8bd352ef
BR
491 cmd.add_vnic.bus_no = busNo;
492 cmd.add_vnic.device_no = devNo;
493 cmd.add_vnic.instance_uuid =
f796e84c 494 dev->instance_uuid;
bac8a4d5
KC
495 cmd.add_vhba.intr = dev->intr;
496 } else {
497 LOGERR("CONTROLVM_DEVICE_CREATE Failed: unknown channelTypeGuid.\n");
498 POSTCODE_LINUX_4
499 (DEVICE_CREATE_FAILURE_PC, devNo,
500 busNo, POSTCODE_SEVERITY_ERR);
501 result = CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN;
502 goto Away;
503 }
504
2df7cc62 505 if (!virt_control_chan_func) {
bac8a4d5
KC
506 LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci callback not registered.");
507 POSTCODE_LINUX_4
508 (DEVICE_CREATE_FAILURE_PC, devNo,
509 busNo, POSTCODE_SEVERITY_ERR);
510 result = CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
511 goto Away;
512 }
513
2df7cc62 514 if (!virt_control_chan_func(&cmd)) {
bac8a4d5
KC
515 LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci GUEST_ADD_[VHBA||VNIC] returned error.");
516 POSTCODE_LINUX_4
517 (DEVICE_CREATE_FAILURE_PC, devNo,
518 busNo, POSTCODE_SEVERITY_ERR);
519 result = CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
520 goto Away;
521 }
522 }
523 bus->device[devNo] = dev;
524 POSTCODE_LINUX_4(DEVICE_CREATE_SUCCESS_PC, devNo, busNo,
525 POSTCODE_SEVERITY_INFO);
526 return CONTROLVM_RESP_SUCCESS;
527 }
528 }
529 read_unlock(&BusListLock);
530
531 LOGERR("CONTROLVM_DEVICE_CREATE Failed: failed to find bus %d.", busNo);
532 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo,
533 POSTCODE_SEVERITY_ERR);
534 result = CONTROLVM_RESP_ERROR_BUS_INVALID;
535
536Away:
98d7b594 537 if (!msg->hdr.flags.test_message) {
bac8a4d5
KC
538 uislib_iounmap(dev->chanptr);
539 dev->chanptr = NULL;
540 }
541
60140462 542 kfree(dev);
bac8a4d5
KC
543 return result;
544}
545
546static int
3ab47701 547pause_device(struct controlvm_message *msg)
bac8a4d5 548{
b3c55b13 549 u32 busNo, devNo;
bac8a4d5
KC
550 struct bus_info *bus;
551 struct device_info *dev;
552 struct guest_msgs cmd;
b5114432 553 int retval = CONTROLVM_RESP_SUCCESS;
bac8a4d5 554
2ea5117b
BR
555 busNo = msg->cmd.device_change_state.bus_no;
556 devNo = msg->cmd.device_change_state.dev_no;
bac8a4d5
KC
557
558 read_lock(&BusListLock);
559 for (bus = BusListHead; bus; bus = bus->next) {
43ecb9fe 560 if (bus->bus_no == busNo) {
bac8a4d5 561 /* make sure the device number is valid */
43ecb9fe 562 if (devNo >= bus->device_count) {
bac8a4d5 563 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device(%d) >= deviceCount(%d).",
43ecb9fe 564 devNo, bus->device_count);
b5114432 565 retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID;
bac8a4d5 566 } else {
b5114432
SM
567 /* make sure this device exists */
568 dev = bus->device[devNo];
569 if (!dev) {
570 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device %d does not exist.",
571 devNo);
572 retval =
573 CONTROLVM_RESP_ERROR_ALREADY_DONE;
574 }
bac8a4d5
KC
575 }
576 break;
577 }
578 }
bac8a4d5
KC
579 if (!bus) {
580 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: bus %d does not exist",
581 busNo);
b5114432 582 retval = CONTROLVM_RESP_ERROR_BUS_INVALID;
bac8a4d5 583 }
b5114432
SM
584 read_unlock(&BusListLock);
585 if (retval == CONTROLVM_RESP_SUCCESS) {
586 /* the msg is bound for virtpci; send
587 * guest_msgs struct to callback
588 */
f796e84c 589 if (!uuid_le_cmp(dev->channel_uuid,
9eee5d1f 590 spar_vhba_channel_protocol_uuid)) {
b5114432
SM
591 cmd.msgtype = GUEST_PAUSE_VHBA;
592 cmd.pause_vhba.chanptr = dev->chanptr;
f796e84c 593 } else if (!uuid_le_cmp(dev->channel_uuid,
9eee5d1f 594 spar_vnic_channel_protocol_uuid)) {
b5114432
SM
595 cmd.msgtype = GUEST_PAUSE_VNIC;
596 cmd.pause_vnic.chanptr = dev->chanptr;
597 } else {
598 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: unknown channelTypeGuid.\n");
599 return CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN;
600 }
2df7cc62 601 if (!virt_control_chan_func) {
b5114432
SM
602 LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: virtpci callback not registered.");
603 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
604 }
2df7cc62 605 if (!virt_control_chan_func(&cmd)) {
b5114432
SM
606 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: virtpci GUEST_PAUSE_[VHBA||VNIC] returned error.");
607 return
608 CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
609 }
610 }
611 return retval;
bac8a4d5
KC
612}
613
614static int
3ab47701 615resume_device(struct controlvm_message *msg)
bac8a4d5 616{
b3c55b13 617 u32 busNo, devNo;
bac8a4d5
KC
618 struct bus_info *bus;
619 struct device_info *dev;
620 struct guest_msgs cmd;
4f01952d 621 int retval = CONTROLVM_RESP_SUCCESS;
bac8a4d5 622
2ea5117b
BR
623 busNo = msg->cmd.device_change_state.bus_no;
624 devNo = msg->cmd.device_change_state.dev_no;
bac8a4d5
KC
625
626 read_lock(&BusListLock);
627 for (bus = BusListHead; bus; bus = bus->next) {
43ecb9fe 628 if (bus->bus_no == busNo) {
bac8a4d5 629 /* make sure the device number is valid */
43ecb9fe 630 if (devNo >= bus->device_count) {
bac8a4d5 631 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device(%d) >= deviceCount(%d).",
43ecb9fe 632 devNo, bus->device_count);
4f01952d 633 retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID;
bac8a4d5 634 } else {
4f01952d
SM
635 /* make sure this device exists */
636 dev = bus->device[devNo];
637 if (!dev) {
638 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device %d does not exist.",
639 devNo);
640 retval =
641 CONTROLVM_RESP_ERROR_ALREADY_DONE;
642 }
bac8a4d5
KC
643 }
644 break;
645 }
646 }
647
648 if (!bus) {
649 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: bus %d does not exist",
650 busNo);
4f01952d 651 retval = CONTROLVM_RESP_ERROR_BUS_INVALID;
bac8a4d5 652 }
4f01952d
SM
653 read_unlock(&BusListLock);
654 /* the msg is bound for virtpci; send
655 * guest_msgs struct to callback
656 */
657 if (retval == CONTROLVM_RESP_SUCCESS) {
f796e84c 658 if (!uuid_le_cmp(dev->channel_uuid,
9eee5d1f 659 spar_vhba_channel_protocol_uuid)) {
4f01952d
SM
660 cmd.msgtype = GUEST_RESUME_VHBA;
661 cmd.resume_vhba.chanptr = dev->chanptr;
f796e84c 662 } else if (!uuid_le_cmp(dev->channel_uuid,
9eee5d1f 663 spar_vnic_channel_protocol_uuid)) {
4f01952d
SM
664 cmd.msgtype = GUEST_RESUME_VNIC;
665 cmd.resume_vnic.chanptr = dev->chanptr;
666 } else {
667 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: unknown channelTypeGuid.\n");
668 return CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN;
669 }
2df7cc62 670 if (!virt_control_chan_func) {
4f01952d
SM
671 LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: virtpci callback not registered.");
672 return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
673 }
2df7cc62 674 if (!virt_control_chan_func(&cmd)) {
4f01952d
SM
675 LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: virtpci GUEST_RESUME_[VHBA||VNIC] returned error.");
676 return
677 CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
678 }
679 }
680 return retval;
bac8a4d5
KC
681}
682
683static int
3ab47701 684destroy_device(struct controlvm_message *msg, char *buf)
bac8a4d5 685{
b3c55b13 686 u32 busNo, devNo;
bac8a4d5
KC
687 struct bus_info *bus;
688 struct device_info *dev;
689 struct guest_msgs cmd;
3aa2ec58 690 int retval = CONTROLVM_RESP_SUCCESS;
bac8a4d5 691
2ea5117b
BR
692 busNo = msg->cmd.destroy_device.bus_no;
693 devNo = msg->cmd.destroy_device.bus_no;
bac8a4d5
KC
694
695 read_lock(&BusListLock);
696 LOGINF("destroy_device called for busNo=%u, devNo=%u", busNo, devNo);
697 for (bus = BusListHead; bus; bus = bus->next) {
43ecb9fe 698 if (bus->bus_no == busNo) {
bac8a4d5 699 /* make sure the device number is valid */
43ecb9fe 700 if (devNo >= bus->device_count) {
bac8a4d5 701 LOGERR("CONTROLVM_DEVICE_DESTORY Failed: device(%d) >= deviceCount(%d).",
43ecb9fe 702 devNo, bus->device_count);
3aa2ec58 703 retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID;
bac8a4d5 704 } else {
3aa2ec58
SM
705 /* make sure this device exists */
706 dev = bus->device[devNo];
707 if (!dev) {
708 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: device %d does not exist.",
709 devNo);
710 retval =
711 CONTROLVM_RESP_ERROR_ALREADY_DONE;
712 }
bac8a4d5 713 }
bac8a4d5
KC
714 break;
715 }
716 }
717
718 if (!bus) {
719 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: bus %d does not exist",
720 busNo);
3aa2ec58 721 retval = CONTROLVM_RESP_ERROR_BUS_INVALID;
bac8a4d5 722 }
3aa2ec58
SM
723 read_unlock(&BusListLock);
724 if (retval == CONTROLVM_RESP_SUCCESS) {
725 /* the msg is bound for virtpci; send
726 * guest_msgs struct to callback
727 */
f796e84c 728 if (!uuid_le_cmp(dev->channel_uuid,
9eee5d1f 729 spar_vhba_channel_protocol_uuid)) {
3aa2ec58
SM
730 cmd.msgtype = GUEST_DEL_VHBA;
731 cmd.del_vhba.chanptr = dev->chanptr;
f796e84c 732 } else if (!uuid_le_cmp(dev->channel_uuid,
9eee5d1f 733 spar_vnic_channel_protocol_uuid)) {
3aa2ec58
SM
734 cmd.msgtype = GUEST_DEL_VNIC;
735 cmd.del_vnic.chanptr = dev->chanptr;
736 } else {
737 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: unknown channelTypeGuid.\n");
738 return
739 CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN;
740 }
2df7cc62 741 if (!virt_control_chan_func) {
3aa2ec58
SM
742 LOGERR("CONTROLVM_DEVICE_DESTORY Failed: virtpci callback not registered.");
743 return
744 CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
745 }
2df7cc62 746 if (!virt_control_chan_func(&cmd)) {
3aa2ec58
SM
747 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: virtpci GUEST_DEL_[VHBA||VNIC] returned error.");
748 return
749 CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
750 }
751/* you must disable channel interrupts BEFORE you unmap the channel,
752 * because if you unmap first, there may still be some activity going
753 * on which accesses the channel and you will get a "unable to handle
754 * kernel paging request"
755 */
756 if (dev->polling) {
757 LOGINF("calling uislib_disable_channel_interrupts");
758 uislib_disable_channel_interrupts(busNo, devNo);
759 }
760 /* unmap the channel memory for the device. */
98d7b594 761 if (!msg->hdr.flags.test_message) {
3aa2ec58
SM
762 LOGINF("destroy_device, doing iounmap");
763 uislib_iounmap(dev->chanptr);
764 }
765 kfree(dev);
766 bus->device[devNo] = NULL;
767 }
768 return retval;
bac8a4d5
KC
769}
770
bac8a4d5 771static int
3ab47701 772init_chipset(struct controlvm_message *msg, char *buf)
bac8a4d5
KC
773{
774 POSTCODE_LINUX_2(CHIPSET_INIT_ENTRY_PC, POSTCODE_SEVERITY_INFO);
775
2ea5117b
BR
776 MaxBusCount = msg->cmd.init_chipset.bus_count;
777 PlatformNumber = msg->cmd.init_chipset.platform_number;
bac8a4d5
KC
778 PhysicalDataChan = 0;
779
780 /* We need to make sure we have our functions registered
781 * before processing messages. If we are a test vehicle the
98d7b594 782 * test_message for init_chipset will be set. We can ignore the
bac8a4d5 783 * waits for the callbacks, since this will be manually entered
98d7b594 784 * from a user. If no test_message is set, we will wait for the
bac8a4d5
KC
785 * functions.
786 */
98d7b594 787 if (!msg->hdr.flags.test_message)
2df7cc62 788 WAIT_ON_CALLBACK(virt_control_chan_func);
bac8a4d5
KC
789
790 chipset_inited = 1;
791 POSTCODE_LINUX_2(CHIPSET_INIT_EXIT_PC, POSTCODE_SEVERITY_INFO);
792
793 return CONTROLVM_RESP_SUCCESS;
794}
795
bac8a4d5 796static int
b3c55b13 797delete_bus_glue(u32 busNo)
bac8a4d5 798{
3ab47701 799 struct controlvm_message msg;
bac8a4d5
KC
800
801 init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0);
2ea5117b 802 msg.cmd.destroy_bus.bus_no = busNo;
bac8a4d5
KC
803 if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
804 LOGERR("destroy_bus failed. busNo=0x%x\n", busNo);
805 return 0;
806 }
807 return 1;
808}
809
810static int
b3c55b13 811delete_device_glue(u32 busNo, u32 devNo)
bac8a4d5 812{
3ab47701 813 struct controlvm_message msg;
bac8a4d5
KC
814
815 init_msg_header(&msg, CONTROLVM_DEVICE_DESTROY, 0, 0);
2ea5117b
BR
816 msg.cmd.destroy_device.bus_no = busNo;
817 msg.cmd.destroy_device.dev_no = devNo;
bac8a4d5
KC
818 if (destroy_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
819 LOGERR("destroy_device failed. busNo=0x%x devNo=0x%x\n", busNo,
820 devNo);
821 return 0;
822 }
823 return 1;
824}
825
826int
e1242538
BR
827uislib_client_inject_add_bus(u32 bus_no, uuid_le inst_uuid,
828 u64 channel_addr, ulong n_channel_bytes)
bac8a4d5 829{
3ab47701 830 struct controlvm_message msg;
bac8a4d5 831
e1242538 832 LOGINF("enter busNo=0x%x\n", bus_no);
bac8a4d5 833 /* step 0: init the chipset */
e1242538 834 POSTCODE_LINUX_3(CHIPSET_INIT_ENTRY_PC, bus_no, POSTCODE_SEVERITY_INFO);
bac8a4d5
KC
835
836 if (!chipset_inited) {
837 /* step: initialize the chipset */
838 init_msg_header(&msg, CONTROLVM_CHIPSET_INIT, 0, 0);
839 /* this change is needed so that console will come up
840 * OK even when the bus 0 create comes in late. If the
841 * bus 0 create is the first create, then the add_vnic
842 * will work fine, but if the bus 0 create arrives
843 * after number 4, then the add_vnic will fail, and the
844 * ultraboot will fail.
845 */
2ea5117b
BR
846 msg.cmd.init_chipset.bus_count = 23;
847 msg.cmd.init_chipset.switch_count = 0;
bac8a4d5
KC
848 if (init_chipset(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
849 LOGERR("init_chipset failed.\n");
850 return 0;
851 }
852 LOGINF("chipset initialized\n");
e1242538 853 POSTCODE_LINUX_3(CHIPSET_INIT_EXIT_PC, bus_no,
bac8a4d5
KC
854 POSTCODE_SEVERITY_INFO);
855 }
856
857 /* step 1: create a bus */
e1242538
BR
858 POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, bus_no,
859 POSTCODE_SEVERITY_WARNING);
bac8a4d5 860 init_msg_header(&msg, CONTROLVM_BUS_CREATE, 0, 0);
2ea5117b
BR
861 msg.cmd.create_bus.bus_no = bus_no;
862 msg.cmd.create_bus.dev_count = 23; /* devNo+1; */
863 msg.cmd.create_bus.channel_addr = channel_addr;
864 msg.cmd.create_bus.channel_bytes = n_channel_bytes;
bac8a4d5
KC
865 if (create_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
866 LOGERR("create_bus failed.\n");
e1242538 867 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no,
bac8a4d5
KC
868 POSTCODE_SEVERITY_ERR);
869 return 0;
870 }
e1242538 871 POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus_no, POSTCODE_SEVERITY_INFO);
bac8a4d5
KC
872
873 return 1;
874}
875EXPORT_SYMBOL_GPL(uislib_client_inject_add_bus);
876
877
878int
ac15ba59 879uislib_client_inject_del_bus(u32 bus_no)
bac8a4d5 880{
ac15ba59 881 return delete_bus_glue(bus_no);
bac8a4d5
KC
882}
883EXPORT_SYMBOL_GPL(uislib_client_inject_del_bus);
884
885int
062d312d 886uislib_client_inject_pause_vhba(u32 bus_no, u32 dev_no)
bac8a4d5 887{
3ab47701 888 struct controlvm_message msg;
bac8a4d5
KC
889 int rc;
890
891 init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0);
2ea5117b
BR
892 msg.cmd.device_change_state.bus_no = bus_no;
893 msg.cmd.device_change_state.dev_no = dev_no;
894 msg.cmd.device_change_state.state = segment_state_standby;
bac8a4d5
KC
895 rc = pause_device(&msg);
896 if (rc != CONTROLVM_RESP_SUCCESS) {
897 LOGERR("VHBA pause_device failed. busNo=0x%x devNo=0x%x\n",
062d312d 898 bus_no, dev_no);
bac8a4d5
KC
899 return rc;
900 }
901 return 0;
902}
903EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vhba);
904
905int
ae47a51b 906uislib_client_inject_resume_vhba(u32 bus_no, u32 dev_no)
bac8a4d5 907{
3ab47701 908 struct controlvm_message msg;
bac8a4d5
KC
909 int rc;
910
911 init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0);
2ea5117b
BR
912 msg.cmd.device_change_state.bus_no = bus_no;
913 msg.cmd.device_change_state.dev_no = dev_no;
914 msg.cmd.device_change_state.state = segment_state_running;
bac8a4d5
KC
915 rc = resume_device(&msg);
916 if (rc != CONTROLVM_RESP_SUCCESS) {
917 LOGERR("VHBA resume_device failed. busNo=0x%x devNo=0x%x\n",
ae47a51b 918 bus_no, dev_no);
bac8a4d5
KC
919 return rc;
920 }
921 return 0;
922
923}
924EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vhba);
925
926int
3d3b7154 927uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no,
5fc0229a 928 u64 phys_chan_addr, u32 chan_bytes,
3d3b7154 929 int is_test_addr, uuid_le inst_uuid,
4eddbf13 930 struct irq_info *intr)
bac8a4d5 931{
3ab47701 932 struct controlvm_message msg;
bac8a4d5 933
3d3b7154 934 LOGINF(" enter busNo=0x%x devNo=0x%x\n", bus_no, dev_no);
bac8a4d5
KC
935 /* chipset init'ed with bus bus has been previously created -
936 * Verify it still exists step 2: create the VHBA device on the
937 * bus
938 */
3d3b7154 939 POSTCODE_LINUX_4(VHBA_CREATE_ENTRY_PC, dev_no, bus_no,
bac8a4d5
KC
940 POSTCODE_SEVERITY_INFO);
941
942 init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, 0);
943 if (is_test_addr)
944 /* signify that the physical channel address does NOT
945 * need to be ioremap()ed
946 */
98d7b594 947 msg.hdr.flags.test_message = 1;
f91b9262
BR
948 msg.cmd.create_device.bus_no = bus_no;
949 msg.cmd.create_device.dev_no = dev_no;
950 msg.cmd.create_device.dev_inst_uuid = inst_uuid;
bac8a4d5 951 if (intr)
2ea5117b 952 msg.cmd.create_device.intr = *intr;
bac8a4d5 953 else
2ea5117b 954 memset(&msg.cmd.create_device.intr, 0,
4eddbf13 955 sizeof(struct irq_info));
f91b9262 956 msg.cmd.create_device.channel_addr = phys_chan_addr;
bac8a4d5
KC
957 if (chan_bytes < MIN_IO_CHANNEL_SIZE) {
958 LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n",
959 chan_bytes, (unsigned int) MIN_IO_CHANNEL_SIZE);
960 POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC, chan_bytes,
961 MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR);
962 return 0;
963 }
f91b9262
BR
964 msg.cmd.create_device.channel_bytes = chan_bytes;
965 msg.cmd.create_device.data_type_uuid = spar_vhba_channel_protocol_uuid;
bac8a4d5
KC
966 if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
967 LOGERR("VHBA create_device failed.\n");
3d3b7154 968 POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC, dev_no, bus_no,
bac8a4d5
KC
969 POSTCODE_SEVERITY_ERR);
970 return 0;
971 }
3d3b7154 972 POSTCODE_LINUX_4(VHBA_CREATE_SUCCESS_PC, dev_no, bus_no,
bac8a4d5
KC
973 POSTCODE_SEVERITY_INFO);
974 return 1;
975}
976EXPORT_SYMBOL_GPL(uislib_client_inject_add_vhba);
977
978int
6bc962ac 979uislib_client_inject_del_vhba(u32 bus_no, u32 dev_no)
bac8a4d5 980{
6bc962ac 981 return delete_device_glue(bus_no, dev_no);
bac8a4d5
KC
982}
983EXPORT_SYMBOL_GPL(uislib_client_inject_del_vhba);
984
985int
94a887da 986uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no,
5fc0229a 987 u64 phys_chan_addr, u32 chan_bytes,
94a887da 988 int is_test_addr, uuid_le inst_uuid,
4eddbf13 989 struct irq_info *intr)
bac8a4d5 990{
3ab47701 991 struct controlvm_message msg;
bac8a4d5 992
94a887da 993 LOGINF(" enter busNo=0x%x devNo=0x%x\n", bus_no, dev_no);
bac8a4d5
KC
994 /* chipset init'ed with bus bus has been previously created -
995 * Verify it still exists step 2: create the VNIC device on the
996 * bus
997 */
94a887da 998 POSTCODE_LINUX_4(VNIC_CREATE_ENTRY_PC, dev_no, bus_no,
bac8a4d5
KC
999 POSTCODE_SEVERITY_INFO);
1000
1001 init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, 0);
1002 if (is_test_addr)
1003 /* signify that the physical channel address does NOT
1004 * need to be ioremap()ed
1005 */
98d7b594 1006 msg.hdr.flags.test_message = 1;
f91b9262
BR
1007 msg.cmd.create_device.bus_no = bus_no;
1008 msg.cmd.create_device.dev_no = dev_no;
1009 msg.cmd.create_device.dev_inst_uuid = inst_uuid;
bac8a4d5 1010 if (intr)
2ea5117b 1011 msg.cmd.create_device.intr = *intr;
bac8a4d5 1012 else
2ea5117b 1013 memset(&msg.cmd.create_device.intr, 0,
4eddbf13 1014 sizeof(struct irq_info));
f91b9262 1015 msg.cmd.create_device.channel_addr = phys_chan_addr;
bac8a4d5
KC
1016 if (chan_bytes < MIN_IO_CHANNEL_SIZE) {
1017 LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n",
1018 chan_bytes, (unsigned int) MIN_IO_CHANNEL_SIZE);
1019 POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC, chan_bytes,
1020 MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR);
1021 return 0;
1022 }
f91b9262
BR
1023 msg.cmd.create_device.channel_bytes = chan_bytes;
1024 msg.cmd.create_device.data_type_uuid = spar_vnic_channel_protocol_uuid;
bac8a4d5
KC
1025 if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1026 LOGERR("VNIC create_device failed.\n");
94a887da 1027 POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC, dev_no, bus_no,
bac8a4d5
KC
1028 POSTCODE_SEVERITY_ERR);
1029 return 0;
1030 }
1031
94a887da 1032 POSTCODE_LINUX_4(VNIC_CREATE_SUCCESS_PC, dev_no, bus_no,
bac8a4d5
KC
1033 POSTCODE_SEVERITY_INFO);
1034 return 1;
1035}
1036EXPORT_SYMBOL_GPL(uislib_client_inject_add_vnic);
1037
1038int
68a4b12c 1039uislib_client_inject_pause_vnic(u32 bus_no, u32 dev_no)
bac8a4d5 1040{
3ab47701 1041 struct controlvm_message msg;
bac8a4d5
KC
1042 int rc;
1043
1044 init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0);
2ea5117b
BR
1045 msg.cmd.device_change_state.bus_no = bus_no;
1046 msg.cmd.device_change_state.dev_no = dev_no;
1047 msg.cmd.device_change_state.state = segment_state_standby;
bac8a4d5
KC
1048 rc = pause_device(&msg);
1049 if (rc != CONTROLVM_RESP_SUCCESS) {
1050 LOGERR("VNIC pause_device failed. busNo=0x%x devNo=0x%x\n",
68a4b12c 1051 bus_no, dev_no);
bac8a4d5
KC
1052 return -1;
1053 }
1054 return 0;
1055}
1056EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vnic);
1057
1058int
3fe7cec4 1059uislib_client_inject_resume_vnic(u32 bus_no, u32 dev_no)
bac8a4d5 1060{
3ab47701 1061 struct controlvm_message msg;
bac8a4d5
KC
1062 int rc;
1063
1064 init_msg_header(&msg, CONTROLVM_DEVICE_CHANGESTATE, 0, 0);
2ea5117b
BR
1065 msg.cmd.device_change_state.bus_no = bus_no;
1066 msg.cmd.device_change_state.dev_no = dev_no;
1067 msg.cmd.device_change_state.state = segment_state_running;
bac8a4d5
KC
1068 rc = resume_device(&msg);
1069 if (rc != CONTROLVM_RESP_SUCCESS) {
1070 LOGERR("VNIC resume_device failed. busNo=0x%x devNo=0x%x\n",
3fe7cec4 1071 bus_no, dev_no);
bac8a4d5
KC
1072 return -1;
1073 }
1074 return 0;
1075
1076}
1077EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vnic);
1078
1079int
bdb628d0 1080uislib_client_inject_del_vnic(u32 bus_no, u32 dev_no)
bac8a4d5 1081{
bdb628d0 1082 return delete_device_glue(bus_no, dev_no);
bac8a4d5
KC
1083}
1084EXPORT_SYMBOL_GPL(uislib_client_inject_del_vnic);
1085
a8d7f21d 1086static int
b3c55b13 1087uislib_client_add_vnic(u32 busNo)
bac8a4d5
KC
1088{
1089 BOOL busCreated = FALSE;
1090 int devNo = 0; /* Default to 0, since only one device
1091 * will be created for this bus... */
3ab47701 1092 struct controlvm_message msg;
bac8a4d5
KC
1093
1094 init_msg_header(&msg, CONTROLVM_BUS_CREATE, 0, 0);
98d7b594 1095 msg.hdr.flags.test_message = 1;
2ea5117b
BR
1096 msg.cmd.create_bus.bus_no = busNo;
1097 msg.cmd.create_bus.dev_count = 4;
1098 msg.cmd.create_bus.channel_addr = 0;
1099 msg.cmd.create_bus.channel_bytes = 0;
bac8a4d5
KC
1100 if (create_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1101 LOGERR("client create_bus failed");
1102 return 0;
1103 }
1104 busCreated = TRUE;
1105
1106 init_msg_header(&msg, CONTROLVM_DEVICE_CREATE, 0, 0);
98d7b594 1107 msg.hdr.flags.test_message = 1;
f91b9262
BR
1108 msg.cmd.create_device.bus_no = busNo;
1109 msg.cmd.create_device.dev_no = devNo;
1110 msg.cmd.create_device.dev_inst_uuid = NULL_UUID_LE;
2ea5117b 1111 memset(&msg.cmd.create_device.intr, 0, sizeof(struct irq_info));
f91b9262
BR
1112 msg.cmd.create_device.channel_addr = PhysicalDataChan;
1113 msg.cmd.create_device.channel_bytes = MIN_IO_CHANNEL_SIZE;
1114 msg.cmd.create_device.data_type_uuid = spar_vnic_channel_protocol_uuid;
bac8a4d5
KC
1115 if (create_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1116 LOGERR("client create_device failed");
1117 goto AwayCleanup;
1118 }
1119
1120 return 1;
1121
1122AwayCleanup:
1123 if (busCreated) {
1124 init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0);
98d7b594 1125 msg.hdr.flags.test_message = 1;
2ea5117b 1126 msg.cmd.destroy_bus.bus_no = busNo;
bac8a4d5
KC
1127 if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS)
1128 LOGERR("client destroy_bus failed.\n");
1129 }
1130
1131 return 0;
1132} /* end uislib_client_add_vnic */
1133EXPORT_SYMBOL_GPL(uislib_client_add_vnic);
1134
a8d7f21d 1135static int
b3c55b13 1136uislib_client_delete_vnic(u32 busNo)
bac8a4d5
KC
1137{
1138 int devNo = 0; /* Default to 0, since only one device
1139 * will be created for this bus... */
3ab47701 1140 struct controlvm_message msg;
bac8a4d5
KC
1141
1142 init_msg_header(&msg, CONTROLVM_DEVICE_DESTROY, 0, 0);
98d7b594 1143 msg.hdr.flags.test_message = 1;
2ea5117b
BR
1144 msg.cmd.destroy_device.bus_no = busNo;
1145 msg.cmd.destroy_device.dev_no = devNo;
bac8a4d5
KC
1146 if (destroy_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
1147 /* Don't error exit - try to see if bus can be destroyed... */
1148 LOGERR("client destroy_device failed.\n");
1149 }
1150
1151 init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0);
98d7b594 1152 msg.hdr.flags.test_message = 1;
2ea5117b 1153 msg.cmd.destroy_bus.bus_no = busNo;
bac8a4d5
KC
1154 if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS)
1155 LOGERR("client destroy_bus failed.\n");
1156
1157 return 1;
1158}
1159EXPORT_SYMBOL_GPL(uislib_client_delete_vnic);
60140462 1160/* end client_delete_vnic */
bac8a4d5
KC
1161
1162void *
1163uislib_cache_alloc(struct kmem_cache *cur_pool, char *fn, int ln)
1164{
1165 /* __GFP_NORETRY means "ok to fail", meaning kmalloc() can
1166 * return NULL. If you do NOT specify __GFP_NORETRY, Linux
1167 * will go to extreme measures to get memory for you (like,
1168 * invoke oom killer), which will probably cripple the system.
1169 */
1170 void *p = kmem_cache_alloc(cur_pool, GFP_ATOMIC | __GFP_NORETRY);
ddc9f84b 1171
bac8a4d5
KC
1172 if (p == NULL) {
1173 LOGERR("uislib_malloc failed to alloc uiscmdrsp @%s:%d",
1174 fn, ln);
1175 return NULL;
1176 }
1177 return p;
1178}
1179EXPORT_SYMBOL_GPL(uislib_cache_alloc);
1180
1181void
1182uislib_cache_free(struct kmem_cache *cur_pool, void *p, char *fn, int ln)
1183{
1184 if (p == NULL) {
1185 LOGERR("uislib_free NULL pointer @%s:%d", fn, ln);
1186 return;
1187 }
1188 kmem_cache_free(cur_pool, p);
1189}
1190EXPORT_SYMBOL_GPL(uislib_cache_free);
1191
1192/*****************************************************/
1193/* proc filesystem callback functions */
1194/*****************************************************/
1195
27dd5548
KC
1196#define PLINE(...) uisutil_add_proc_line_ex(&tot, buff, \
1197 buff_len, __VA_ARGS__)
bac8a4d5
KC
1198
1199static int
7ec96720 1200info_debugfs_read_helper(char **buff, int *buff_len)
bac8a4d5
KC
1201{
1202 int i, tot = 0;
1203 struct bus_info *bus;
1204
27dd5548
KC
1205 if (PLINE("\nBuses:\n") < 0)
1206 goto err_done;
bac8a4d5
KC
1207
1208 read_lock(&BusListLock);
1209 for (bus = BusListHead; bus; bus = bus->next) {
1210
27dd5548 1211 if (PLINE(" bus=0x%p, busNo=%d, deviceCount=%d\n",
43ecb9fe 1212 bus, bus->bus_no, bus->device_count) < 0)
27dd5548 1213 goto err_done_unlock;
bac8a4d5 1214
27dd5548
KC
1215
1216 if (PLINE(" Devices:\n") < 0)
1217 goto err_done_unlock;
bac8a4d5 1218
43ecb9fe 1219 for (i = 0; i < bus->device_count; i++) {
bac8a4d5 1220 if (bus->device[i]) {
27dd5548 1221 if (PLINE(" busNo %d, device[%i]: 0x%p, chanptr=0x%p, swtch=0x%p\n",
43ecb9fe 1222 bus->bus_no, i, bus->device[i],
27dd5548
KC
1223 bus->device[i]->chanptr,
1224 bus->device[i]->swtch) < 0)
1225 goto err_done_unlock;
1226
1227 if (PLINE(" first_busy_cnt=%llu, moved_to_tail_cnt=%llu, last_on_list_cnt=%llu\n",
1228 bus->device[i]->first_busy_cnt,
1229 bus->device[i]->moved_to_tail_cnt,
1230 bus->device[i]->last_on_list_cnt) < 0)
1231 goto err_done_unlock;
bac8a4d5
KC
1232 }
1233 }
1234 }
1235 read_unlock(&BusListLock);
1236
27dd5548 1237 if (PLINE("UisUtils_Registered_Services: %d\n",
e9b9262a 1238 atomic_read(&uisutils_registered_services)) < 0)
27dd5548
KC
1239 goto err_done;
1240 if (PLINE("cycles_before_wait %llu wait_cycles:%llu\n",
1241 cycles_before_wait, wait_cycles) < 0)
1242 goto err_done;
1243 if (PLINE("tot_wakeup_cnt %llu:tot_wait_cnt %llu:tot_schedule_cnt %llu\n",
1244 tot_wakeup_cnt, tot_wait_cnt, tot_schedule_cnt) < 0)
1245 goto err_done;
1246 if (PLINE("en_smart_wakeup %d\n", en_smart_wakeup) < 0)
1247 goto err_done;
1248 if (PLINE("tot_moved_to_tail_cnt %llu\n", tot_moved_to_tail_cnt) < 0)
1249 goto err_done;
bac8a4d5
KC
1250
1251 return tot;
bac8a4d5 1252
27dd5548
KC
1253err_done_unlock:
1254 read_unlock(&BusListLock);
1255err_done:
bac8a4d5
KC
1256 return -1;
1257}
1258
1259static ssize_t
7ec96720
BR
1260info_debugfs_read(struct file *file, char __user *buf,
1261 size_t len, loff_t *offset)
bac8a4d5
KC
1262{
1263 char *temp;
1264 int totalBytes = 0;
1265 int remaining_bytes = PROC_READ_BUFFER_SIZE;
1266
1267/* *start = buf; */
1268 if (ProcReadBuffer == NULL) {
1269 DBGINF("ProcReadBuffer == NULL; allocating buffer.\n.");
60140462 1270 ProcReadBuffer = vmalloc(PROC_READ_BUFFER_SIZE);
bac8a4d5
KC
1271
1272 if (ProcReadBuffer == NULL) {
1273 LOGERR("failed to allocate buffer to provide proc data.\n");
1274 return -ENOMEM;
1275 }
1276 }
1277
1278 temp = ProcReadBuffer;
1279
1280 if ((*offset == 0) || (!ProcReadBufferValid)) {
7ec96720 1281 DBGINF("calling info_debugfs_read_helper.\n");
bac8a4d5 1282 /* if the read fails, then -1 will be returned */
7ec96720 1283 totalBytes = info_debugfs_read_helper(&temp, &remaining_bytes);
bac8a4d5
KC
1284 ProcReadBufferValid = 1;
1285 } else
1286 totalBytes = strlen(ProcReadBuffer);
1287
1288 return simple_read_from_buffer(buf, len, offset,
1289 ProcReadBuffer, totalBytes);
1290}
1291
bac8a4d5 1292static struct device_info *
b3c55b13 1293find_dev(u32 busNo, u32 devNo)
bac8a4d5
KC
1294{
1295 struct bus_info *bus;
1296 struct device_info *dev = NULL;
1297
1298 read_lock(&BusListLock);
1299 for (bus = BusListHead; bus; bus = bus->next) {
43ecb9fe 1300 if (bus->bus_no == busNo) {
bac8a4d5 1301 /* make sure the device number is valid */
43ecb9fe 1302 if (devNo >= bus->device_count) {
bac8a4d5
KC
1303 LOGERR("%s bad busNo, devNo=%d,%d",
1304 __func__,
1305 (int) (busNo), (int) (devNo));
1306 goto Away;
1307 }
1308 dev = bus->device[devNo];
1309 if (!dev)
1310 LOGERR("%s bad busNo, devNo=%d,%d",
1311 __func__,
1312 (int) (busNo), (int) (devNo));
1313 goto Away;
1314 }
1315 }
1316Away:
1317 read_unlock(&BusListLock);
1318 return dev;
1319}
1320
1321/* This thread calls the "interrupt" function for each device that has
1322 * enabled such using uislib_enable_channel_interrupts(). The "interrupt"
1323 * function typically reads and processes the devices's channel input
1324 * queue. This thread repeatedly does this, until the thread is told to stop
1325 * (via uisthread_stop()). Sleeping rules:
1326 * - If we have called the "interrupt" function for all devices, and all of
1327 * them have reported "nothing processed" (returned 0), then we will go to
1328 * sleep for a maximum of POLLJIFFIES_NORMAL jiffies.
1329 * - If anyone calls uislib_force_channel_interrupt(), the above jiffy
1330 * sleep will be interrupted, and we will resume calling the "interrupt"
1331 * function for all devices.
1332 * - The list of devices is dynamically re-ordered in order to
1333 * attempt to preserve fairness. Whenever we spin thru the list of
1334 * devices and call the dev->interrupt() function, if we find
1335 * devices which report that there is still more work to do, the
1336 * the first such device we find is moved to the end of the device
1337 * list. This ensures that extremely busy devices don't starve out
1338 * less-busy ones.
1339 *
1340 */
1341static int
1342Process_Incoming(void *v)
1343{
1344 unsigned long long cur_cycles, old_cycles, idle_cycles, delta_cycles;
1345 struct list_head *new_tail = NULL;
1346 int i;
ddc9f84b 1347
bac8a4d5
KC
1348 UIS_DAEMONIZE("dev_incoming");
1349 for (i = 0; i < 16; i++) {
1350 old_cycles = get_cycles();
1351 wait_event_timeout(Wakeup_Polling_Device_Channels,
1352 0, POLLJIFFIES_NORMAL);
1353 cur_cycles = get_cycles();
1354 if (wait_cycles == 0) {
1355 wait_cycles = (cur_cycles - old_cycles);
1356 } else {
1357 if (wait_cycles < (cur_cycles - old_cycles))
1358 wait_cycles = (cur_cycles - old_cycles);
1359 }
1360 }
1361 LOGINF("wait_cycles=%llu", wait_cycles);
1362 cycles_before_wait = wait_cycles;
1363 idle_cycles = 0;
1364 Go_Polling_Device_Channels = 0;
1365 while (1) {
1366 struct list_head *lelt, *tmp;
1367 struct device_info *dev = NULL;
1368
1369 /* poll each channel for input */
f2170625 1370 down(&Lock_Polling_Device_Channels);
bac8a4d5
KC
1371 new_tail = NULL;
1372 list_for_each_safe(lelt, tmp, &List_Polling_Device_Channels) {
1373 int rc = 0;
ddc9f84b 1374
bac8a4d5
KC
1375 dev = list_entry(lelt, struct device_info,
1376 list_polling_device_channels);
f2170625 1377 down(&dev->interrupt_callback_lock);
bac8a4d5
KC
1378 if (dev->interrupt)
1379 rc = dev->interrupt(dev->interrupt_context);
1380 else
1381 continue;
f2170625 1382 up(&dev->interrupt_callback_lock);
bac8a4d5
KC
1383 if (rc) {
1384 /* dev->interrupt returned, but there
1385 * is still more work to do.
1386 * Reschedule work to occur as soon as
1387 * possible. */
1388 idle_cycles = 0;
1389 if (new_tail == NULL) {
1390 dev->first_busy_cnt++;
1391 if (!
1392 (list_is_last
1393 (lelt,
1394 &List_Polling_Device_Channels))) {
1395 new_tail = lelt;
1396 dev->moved_to_tail_cnt++;
1397 } else
1398 dev->last_on_list_cnt++;
1399 }
1400
1401 }
1402 if (Incoming_ThreadInfo.should_stop)
1403 break;
1404 }
1405 if (new_tail != NULL) {
1406 tot_moved_to_tail_cnt++;
1407 list_move_tail(new_tail, &List_Polling_Device_Channels);
1408 }
f2170625 1409 up(&Lock_Polling_Device_Channels);
bac8a4d5
KC
1410 cur_cycles = get_cycles();
1411 delta_cycles = cur_cycles - old_cycles;
1412 old_cycles = cur_cycles;
1413
1414 /* At this point, we have scanned thru all of the
1415 * channels, and at least one of the following is true:
1416 * - there is no input waiting on any of the channels
1417 * - we have received a signal to stop this thread
1418 */
1419 if (Incoming_ThreadInfo.should_stop)
1420 break;
1421 if (en_smart_wakeup == 0xFF) {
1422 LOGINF("en_smart_wakeup set to 0xff, to force exiting process_incoming");
1423 break;
1424 }
1425 /* wait for POLLJIFFIES_NORMAL jiffies, or until
1426 * someone wakes up Wakeup_Polling_Device_Channels,
1427 * whichever comes first only do a wait when we have
1428 * been idle for cycles_before_wait cycles.
1429 */
1430 if (idle_cycles > cycles_before_wait) {
1431 Go_Polling_Device_Channels = 0;
1432 tot_wait_cnt++;
1433 wait_event_timeout(Wakeup_Polling_Device_Channels,
1434 Go_Polling_Device_Channels,
1435 POLLJIFFIES_NORMAL);
1436 Go_Polling_Device_Channels = 1;
1437 } else {
1438 tot_schedule_cnt++;
1439 schedule();
1440 idle_cycles = idle_cycles + delta_cycles;
1441 }
1442 }
1443 DBGINF("exiting.\n");
1444 complete_and_exit(&Incoming_ThreadInfo.has_stopped, 0);
1445}
1446
1447static BOOL
1448Initialize_incoming_thread(void)
1449{
1450 if (Incoming_Thread_Started)
1451 return TRUE;
1452 if (!uisthread_start(&Incoming_ThreadInfo,
1453 &Process_Incoming, NULL, "dev_incoming")) {
1454 LOGERR("uisthread_start Initialize_incoming_thread ****FAILED");
1455 return FALSE;
1456 }
1457 Incoming_Thread_Started = TRUE;
1458 return TRUE;
1459}
1460
1461/* Add a new device/channel to the list being processed by
1462 * Process_Incoming().
1463 * <interrupt> - indicates the function to call periodically.
1464 * <interrupt_context> - indicates the data to pass to the <interrupt>
1465 * function.
1466 */
1467void
93d1304f 1468uislib_enable_channel_interrupts(u32 bus_no, u32 dev_no,
bac8a4d5
KC
1469 int (*interrupt)(void *),
1470 void *interrupt_context)
1471{
1472 struct device_info *dev;
ddc9f84b 1473
93d1304f 1474 dev = find_dev(bus_no, dev_no);
bac8a4d5 1475 if (!dev) {
93d1304f
BR
1476 LOGERR("%s busNo=%d, devNo=%d", __func__, (int) (bus_no),
1477 (int) (dev_no));
bac8a4d5
KC
1478 return;
1479 }
f2170625 1480 down(&Lock_Polling_Device_Channels);
bac8a4d5
KC
1481 Initialize_incoming_thread();
1482 dev->interrupt = interrupt;
1483 dev->interrupt_context = interrupt_context;
1484 dev->polling = TRUE;
1485 list_add_tail(&(dev->list_polling_device_channels),
1486 &List_Polling_Device_Channels);
f2170625 1487 up(&Lock_Polling_Device_Channels);
bac8a4d5
KC
1488}
1489EXPORT_SYMBOL_GPL(uislib_enable_channel_interrupts);
1490
1491/* Remove a device/channel from the list being processed by
1492 * Process_Incoming().
1493 */
1494void
d0dd33f3 1495uislib_disable_channel_interrupts(u32 bus_no, u32 dev_no)
bac8a4d5
KC
1496{
1497 struct device_info *dev;
ddc9f84b 1498
d0dd33f3 1499 dev = find_dev(bus_no, dev_no);
bac8a4d5 1500 if (!dev) {
d0dd33f3
BR
1501 LOGERR("%s busNo=%d, devNo=%d", __func__, (int) (bus_no),
1502 (int) (dev_no));
bac8a4d5
KC
1503 return;
1504 }
f2170625 1505 down(&Lock_Polling_Device_Channels);
bac8a4d5
KC
1506 list_del(&dev->list_polling_device_channels);
1507 dev->polling = FALSE;
1508 dev->interrupt = NULL;
f2170625 1509 up(&Lock_Polling_Device_Channels);
bac8a4d5
KC
1510}
1511EXPORT_SYMBOL_GPL(uislib_disable_channel_interrupts);
1512
1513static void
1514do_wakeup_polling_device_channels(struct work_struct *dummy)
1515{
1516 if (!Go_Polling_Device_Channels) {
1517 Go_Polling_Device_Channels = 1;
1518 wake_up(&Wakeup_Polling_Device_Channels);
1519 }
1520}
1521
a8d7f21d
KC
1522static DECLARE_WORK(Work_wakeup_polling_device_channels,
1523 do_wakeup_polling_device_channels);
bac8a4d5
KC
1524
1525/* Call this function when you want to send a hint to Process_Incoming() that
1526 * your device might have more requests.
1527 */
1528void
f7b33ff4 1529uislib_force_channel_interrupt(u32 bus_no, u32 dev_no)
bac8a4d5
KC
1530{
1531 if (en_smart_wakeup == 0)
1532 return;
1533 if (Go_Polling_Device_Channels)
1534 return;
1535 /* The point of using schedule_work() instead of just doing
1536 * the work inline is to force a slight delay before waking up
1537 * the Process_Incoming() thread.
1538 */
1539 tot_wakeup_cnt++;
1540 schedule_work(&Work_wakeup_polling_device_channels);
1541}
1542EXPORT_SYMBOL_GPL(uislib_force_channel_interrupt);
1543
1544/*****************************************************/
1545/* Module Init & Exit functions */
1546/*****************************************************/
1547
1548static int __init
1549uislib_mod_init(void)
1550{
1551
fcd0157e
KC
1552 if (!unisys_spar_platform)
1553 return -ENODEV;
1554
bac8a4d5
KC
1555 LOGINF("MONITORAPIS");
1556
1557 LOGINF("sizeof(struct uiscmdrsp):%lu bytes\n",
1558 (ulong) sizeof(struct uiscmdrsp));
1559 LOGINF("sizeof(struct phys_info):%lu\n",
1560 (ulong) sizeof(struct phys_info));
1561 LOGINF("sizeof(uiscmdrsp_scsi):%lu\n",
1562 (ulong) sizeof(struct uiscmdrsp_scsi));
1563 LOGINF("sizeof(uiscmdrsp_net):%lu\n",
1564 (ulong) sizeof(struct uiscmdrsp_net));
1565 LOGINF("sizeof(CONTROLVM_MESSAGE):%lu bytes\n",
3ab47701 1566 (ulong) sizeof(struct controlvm_message));
d19642f6
BR
1567 LOGINF("sizeof(struct spar_controlvm_channel_protocol):%lu bytes\n",
1568 (ulong) sizeof(struct spar_controlvm_channel_protocol));
bac8a4d5 1569 LOGINF("sizeof(CHANNEL_HEADER):%lu bytes\n",
9fd1b95a 1570 (ulong) sizeof(struct channel_header));
bac8a4d5
KC
1571 LOGINF("sizeof(ULTRA_IO_CHANNEL_PROTOCOL):%lu bytes\n",
1572 (ulong) sizeof(ULTRA_IO_CHANNEL_PROTOCOL));
1573 LOGINF("SIZEOF_CMDRSP:%lu bytes\n", SIZEOF_CMDRSP);
1574 LOGINF("SIZEOF_PROTOCOL:%lu bytes\n", SIZEOF_PROTOCOL);
1575
1576 /* initialize global pointers to NULL */
1577 BusListHead = NULL;
1578 BusListCount = MaxBusCount = 0;
1579 rwlock_init(&BusListLock);
2df7cc62 1580 virt_control_chan_func = NULL;
bac8a4d5
KC
1581
1582 /* Issue VMCALL_GET_CONTROLVM_ADDR to get CtrlChanPhysAddr and
1583 * then map this physical address to a virtual address. */
1584 POSTCODE_LINUX_2(DRIVER_ENTRY_PC, POSTCODE_SEVERITY_INFO);
1585
28fa597f 1586 dir_debugfs = debugfs_create_dir(DIR_DEBUGFS_ENTRY, NULL);
28fa597f 1587 if (dir_debugfs) {
7ec96720
BR
1588 info_debugfs_entry = debugfs_create_file(
1589 INFO_DEBUGFS_ENTRY_FN, 0444, dir_debugfs, NULL,
1590 &debugfs_info_fops);
1591
28fa597f
BR
1592 platformnumber_debugfs_read = debugfs_create_u32(
1593 PLATFORMNUMBER_DEBUGFS_ENTRY_FN, 0444, dir_debugfs,
1594 &PlatformNumber);
bac8a4d5 1595
b913a2ef
BR
1596 cycles_before_wait_debugfs_read = debugfs_create_u64(
1597 CYCLES_BEFORE_WAIT_DEBUGFS_ENTRY_FN, 0666, dir_debugfs,
1598 &cycles_before_wait);
bac8a4d5 1599
81d2d7de
BR
1600 smart_wakeup_debugfs_entry = debugfs_create_bool(
1601 SMART_WAKEUP_DEBUGFS_ENTRY_FN, 0666, dir_debugfs,
1602 &en_smart_wakeup);
1603 }
bac8a4d5 1604
bac8a4d5
KC
1605 POSTCODE_LINUX_3(DRIVER_EXIT_PC, 0, POSTCODE_SEVERITY_INFO);
1606 return 0;
1607}
1608
1609static void __exit
1610uislib_mod_exit(void)
1611{
bac8a4d5 1612 if (ProcReadBuffer) {
60140462 1613 vfree(ProcReadBuffer);
bac8a4d5
KC
1614 ProcReadBuffer = NULL;
1615 }
1616
7ec96720 1617 debugfs_remove(info_debugfs_entry);
81d2d7de 1618 debugfs_remove(smart_wakeup_debugfs_entry);
b913a2ef 1619 debugfs_remove(cycles_before_wait_debugfs_read);
28fa597f
BR
1620 debugfs_remove(platformnumber_debugfs_read);
1621 debugfs_remove(dir_debugfs);
1622
bac8a4d5 1623 DBGINF("goodbye.\n");
bac8a4d5
KC
1624}
1625
1626module_init(uislib_mod_init);
1627module_exit(uislib_mod_exit);
1628
bac8a4d5
KC
1629MODULE_LICENSE("GPL");
1630MODULE_AUTHOR("Usha Srinivasan");
1631MODULE_ALIAS("uislib");
1632 /* this is extracted during depmod and kept in modules.dep */
This page took 0.600743 seconds and 5 git commands to generate.