[go: nahoru, domu]

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