]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/staging/unisys/visorchipset/visorchipset_main.c
staging: unisys: remove unused macros
[mirror_ubuntu-jammy-kernel.git] / drivers / staging / unisys / visorchipset / visorchipset_main.c
CommitLineData
12e364b9
KC
1/* visorchipset_main.c
2 *
f6d0c1e6 3 * Copyright (C) 2010 - 2013 UNISYS CORPORATION
12e364b9
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#include "globals.h"
19#include "controlvm.h"
20#include "visorchipset.h"
21#include "procobjecttree.h"
22#include "visorchannel.h"
23#include "periodic_work.h"
24#include "testing.h"
25#include "file.h"
26#include "parser.h"
27#include "uniklog.h"
28#include "uisutils.h"
12e364b9
KC
29#include "controlvmcompletionstatus.h"
30#include "guestlinuxdebug.h"
12e364b9
KC
31
32#include <linux/nls.h>
33#include <linux/netdevice.h>
34#include <linux/platform_device.h>
90addb02 35#include <linux/uuid.h>
12e364b9
KC
36
37#define CURRENT_FILE_PC VISOR_CHIPSET_PC_visorchipset_main_c
38#define TEST_VNIC_PHYSITF "eth0" /* physical network itf for
39 * vnic loopback test */
40#define TEST_VNIC_SWITCHNO 1
41#define TEST_VNIC_BUSNO 9
42
43#define MAX_NAME_SIZE 128
44#define MAX_IP_SIZE 50
45#define MAXOUTSTANDINGCHANNELCOMMAND 256
46#define POLLJIFFIES_CONTROLVMCHANNEL_FAST 1
47#define POLLJIFFIES_CONTROLVMCHANNEL_SLOW 100
48
49/* When the controlvm channel is idle for at least MIN_IDLE_SECONDS,
50* we switch to slow polling mode. As soon as we get a controlvm
51* message, we switch back to fast polling mode.
52*/
53#define MIN_IDLE_SECONDS 10
bd5b9b32
KC
54static ulong Poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_FAST;
55static ulong Most_recent_message_jiffies; /* when we got our last
56 * controlvm message */
12e364b9
KC
57static inline char *
58NONULLSTR(char *s)
59{
60 if (s)
61 return s;
62 else
63 return "";
64}
65
66static int serverregistered;
67static int clientregistered;
68
69#define MAX_CHIPSET_EVENTS 2
70static U8 chipset_events[MAX_CHIPSET_EVENTS] = { 0, 0 };
71
72static struct delayed_work Periodic_controlvm_work;
73static struct workqueue_struct *Periodic_controlvm_workqueue;
bd5b9b32 74static DEFINE_SEMAPHORE(NotifierLock);
12e364b9
KC
75
76typedef struct {
77 CONTROLVM_MESSAGE message;
78 unsigned int crc;
79} MESSAGE_ENVELOPE;
80
81static CONTROLVM_MESSAGE_HEADER g_DiagMsgHdr;
82static CONTROLVM_MESSAGE_HEADER g_ChipSetMsgHdr;
83static CONTROLVM_MESSAGE_HEADER g_DelDumpMsgHdr;
90addb02 84static const uuid_le UltraDiagPoolChannelProtocolGuid =
12e364b9
KC
85 ULTRA_DIAG_POOL_CHANNEL_PROTOCOL_GUID;
86/* 0xffffff is an invalid Bus/Device number */
87static ulong g_diagpoolBusNo = 0xffffff;
88static ulong g_diagpoolDevNo = 0xffffff;
89static CONTROLVM_MESSAGE_PACKET g_DeviceChangeStatePacket;
90
91/* Only VNIC and VHBA channels are sent to visorclientbus (aka
92 * "visorhackbus")
93 */
94#define FOR_VISORHACKBUS(channel_type_guid) \
90addb02
BR
95 (((uuid_le_cmp(channel_type_guid, UltraVnicChannelProtocolGuid) == 0)\
96 || (uuid_le_cmp(channel_type_guid, UltraVhbaChannelProtocolGuid) == 0)))
12e364b9
KC
97#define FOR_VISORBUS(channel_type_guid) (!(FOR_VISORHACKBUS(channel_type_guid)))
98
99#define is_diagpool_channel(channel_type_guid) \
90addb02 100 (uuid_le_cmp(channel_type_guid, UltraDiagPoolChannelProtocolGuid) == 0)
12e364b9
KC
101
102typedef enum {
103 PARTPROP_invalid,
104 PARTPROP_name,
105 PARTPROP_description,
106 PARTPROP_handle,
107 PARTPROP_busNumber,
108 /* add new properties above, but don't forget to change
109 * InitPartitionProperties() and show_partition_property() also...
110 */
111 PARTPROP_last
112} PARTITION_property;
113static const char *PartitionTypeNames[] = { "partition", NULL };
114
115static char *PartitionPropertyNames[PARTPROP_last + 1];
116static void
117InitPartitionProperties(void)
118{
119 char **p = PartitionPropertyNames;
120 p[PARTPROP_invalid] = "";
121 p[PARTPROP_name] = "name";
122 p[PARTPROP_description] = "description";
123 p[PARTPROP_handle] = "handle";
124 p[PARTPROP_busNumber] = "busNumber";
125 p[PARTPROP_last] = NULL;
126}
127
128typedef enum {
129 CTLVMPROP_invalid,
130 CTLVMPROP_physAddr,
131 CTLVMPROP_controlChannelAddr,
132 CTLVMPROP_controlChannelBytes,
133 CTLVMPROP_sparBootPart,
134 CTLVMPROP_sparStoragePart,
135 CTLVMPROP_livedumpLength,
136 CTLVMPROP_livedumpCrc32,
137 /* add new properties above, but don't forget to change
138 * InitControlVmProperties() show_controlvm_property() also...
139 */
140 CTLVMPROP_last
141} CONTROLVM_property;
142
143static const char *ControlVmTypeNames[] = { "controlvm", NULL };
144
145static char *ControlVmPropertyNames[CTLVMPROP_last + 1];
146static void
147InitControlVmProperties(void)
148{
149 char **p = ControlVmPropertyNames;
150 p[CTLVMPROP_invalid] = "";
151 p[CTLVMPROP_physAddr] = "physAddr";
152 p[CTLVMPROP_controlChannelAddr] = "controlChannelAddr";
153 p[CTLVMPROP_controlChannelBytes] = "controlChannelBytes";
154 p[CTLVMPROP_sparBootPart] = "spar_boot_part";
155 p[CTLVMPROP_sparStoragePart] = "spar_storage_part";
156 p[CTLVMPROP_livedumpLength] = "livedumpLength";
157 p[CTLVMPROP_livedumpCrc32] = "livedumpCrc32";
158 p[CTLVMPROP_last] = NULL;
159}
160
161static MYPROCOBJECT *ControlVmObject;
162static MYPROCTYPE *PartitionType;
163static MYPROCTYPE *ControlVmType;
164
165#define VISORCHIPSET_DIAG_PROC_ENTRY_FN "diagdump"
166static struct proc_dir_entry *diag_proc_dir;
167
168#define VISORCHIPSET_CHIPSET_PROC_ENTRY_FN "chipsetready"
169static struct proc_dir_entry *chipset_proc_dir;
170
171#define VISORCHIPSET_PARAHOTPLUG_PROC_ENTRY_FN "parahotplug"
172static struct proc_dir_entry *parahotplug_proc_dir;
173
174static LIST_HEAD(BusInfoList);
175static LIST_HEAD(DevInfoList);
176
177static struct proc_dir_entry *ProcDir;
178static VISORCHANNEL *ControlVm_channel;
179
180static ssize_t visorchipset_proc_read_writeonly(struct file *file,
181 char __user *buf,
182 size_t len, loff_t *offset);
183static ssize_t proc_read_installer(struct file *file, char __user *buf,
184 size_t len, loff_t *offset);
185static ssize_t proc_write_installer(struct file *file,
186 const char __user *buffer,
187 size_t count, loff_t *ppos);
188static ssize_t proc_read_toolaction(struct file *file, char __user *buf,
189 size_t len, loff_t *offset);
190static ssize_t proc_write_toolaction(struct file *file,
191 const char __user *buffer,
192 size_t count, loff_t *ppos);
193static ssize_t proc_read_bootToTool(struct file *file, char __user *buf,
194 size_t len, loff_t *offset);
195static ssize_t proc_write_bootToTool(struct file *file,
196 const char __user *buffer,
197 size_t count, loff_t *ppos);
198static const struct file_operations proc_installer_fops = {
199 .read = proc_read_installer,
200 .write = proc_write_installer,
201};
202
203static const struct file_operations proc_toolaction_fops = {
204 .read = proc_read_toolaction,
205 .write = proc_write_toolaction,
206};
207
208static const struct file_operations proc_bootToTool_fops = {
209 .read = proc_read_bootToTool,
210 .write = proc_write_bootToTool,
211};
212
213typedef struct {
bd5b9b32 214 U8 __iomem *ptr; /* pointer to base address of payload pool */
12e364b9
KC
215 U64 offset; /* offset from beginning of controlvm
216 * channel to beginning of payload * pool */
217 U32 bytes; /* number of bytes in payload pool */
218} CONTROLVM_PAYLOAD_INFO;
219
220/* Manages the request payload in the controlvm channel */
221static CONTROLVM_PAYLOAD_INFO ControlVm_payload_info;
222
223static pCHANNEL_HEADER Test_Vnic_channel;
224
225typedef struct {
226 CONTROLVM_MESSAGE_HEADER Dumpcapture_header;
227 CONTROLVM_MESSAGE_HEADER Gettextdump_header;
228 CONTROLVM_MESSAGE_HEADER Dumpcomplete_header;
229 BOOL Gettextdump_outstanding;
230 u32 crc32;
231 ulong length;
232 atomic_t buffers_in_use;
233 ulong destination;
234} LIVEDUMP_INFO;
235/* Manages the info for a CONTROLVM_DUMP_CAPTURESTATE /
236 * CONTROLVM_DUMP_GETTEXTDUMP / CONTROLVM_DUMP_COMPLETE conversation.
237 */
238static LIVEDUMP_INFO LiveDump_info;
239
240/* The following globals are used to handle the scenario where we are unable to
241 * offload the payload from a controlvm message due to memory requirements. In
242 * this scenario, we simply stash the controlvm message, then attempt to
243 * process it again the next time controlvm_periodic_work() runs.
244 */
245static CONTROLVM_MESSAGE ControlVm_Pending_Msg;
246static BOOL ControlVm_Pending_Msg_Valid = FALSE;
247
248/* Pool of struct putfile_buffer_entry, for keeping track of pending (incoming)
249 * TRANSMIT_FILE PutFile payloads.
250 */
251static struct kmem_cache *Putfile_buffer_list_pool;
252static const char Putfile_buffer_list_pool_name[] =
253 "controlvm_putfile_buffer_list_pool";
254
255/* This identifies a data buffer that has been received via a controlvm messages
256 * in a remote --> local CONTROLVM_TRANSMIT_FILE conversation.
257 */
258struct putfile_buffer_entry {
259 struct list_head next; /* putfile_buffer_entry list */
260 PARSER_CONTEXT *parser_ctx; /* points to buffer containing input data */
261};
262
263/* List of struct putfile_request *, via next_putfile_request member.
264 * Each entry in this list identifies an outstanding TRANSMIT_FILE
265 * conversation.
266 */
267static LIST_HEAD(Putfile_request_list);
268
269/* This describes a buffer and its current state of transfer (e.g., how many
270 * bytes have already been supplied as putfile data, and how many bytes are
271 * remaining) for a putfile_request.
272 */
273struct putfile_active_buffer {
274 /* a payload from a controlvm message, containing a file data buffer */
275 PARSER_CONTEXT *parser_ctx;
276 /* points within data area of parser_ctx to next byte of data */
277 u8 *pnext;
278 /* # bytes left from <pnext> to the end of this data buffer */
279 size_t bytes_remaining;
280};
281
282#define PUTFILE_REQUEST_SIG 0x0906101302281211
283/* This identifies a single remote --> local CONTROLVM_TRANSMIT_FILE
284 * conversation. Structs of this type are dynamically linked into
285 * <Putfile_request_list>.
286 */
287struct putfile_request {
288 u64 sig; /* PUTFILE_REQUEST_SIG */
289
290 /* header from original TransmitFile request */
291 CONTROLVM_MESSAGE_HEADER controlvm_header;
292 u64 file_request_number; /* from original TransmitFile request */
293
294 /* link to next struct putfile_request */
295 struct list_head next_putfile_request;
296
297 /* most-recent sequence number supplied via a controlvm message */
298 u64 data_sequence_number;
299
300 /* head of putfile_buffer_entry list, which describes the data to be
301 * supplied as putfile data;
302 * - this list is added to when controlvm messages come in that supply
303 * file data
304 * - this list is removed from via the hotplug program that is actually
305 * consuming these buffers to write as file data */
306 struct list_head input_buffer_list;
307 spinlock_t req_list_lock; /* lock for input_buffer_list */
308
309 /* waiters for input_buffer_list to go non-empty */
310 wait_queue_head_t input_buffer_wq;
311
312 /* data not yet read within current putfile_buffer_entry */
313 struct putfile_active_buffer active_buf;
314
315 /* <0 = failed, 0 = in-progress, >0 = successful; */
316 /* note that this must be set with req_list_lock, and if you set <0, */
317 /* it is your responsibility to also free up all of the other objects */
318 /* in this struct (like input_buffer_list, active_buf.parser_ctx) */
319 /* before releasing the lock */
320 int completion_status;
321};
322
bd5b9b32 323static atomic_t Visorchipset_cache_buffers_in_use = ATOMIC_INIT(0);
12e364b9
KC
324
325struct parahotplug_request {
326 struct list_head list;
327 int id;
328 unsigned long expiration;
329 CONTROLVM_MESSAGE msg;
330};
331
332static LIST_HEAD(Parahotplug_request_list);
333static DEFINE_SPINLOCK(Parahotplug_request_list_lock); /* lock for above */
334static void parahotplug_process_list(void);
335
336/* Manages the info for a CONTROLVM_DUMP_CAPTURESTATE /
337 * CONTROLVM_REPORTEVENT.
338 */
339static VISORCHIPSET_BUSDEV_NOTIFIERS BusDev_Server_Notifiers;
340static VISORCHIPSET_BUSDEV_NOTIFIERS BusDev_Client_Notifiers;
341
342static void bus_create_response(ulong busNo, int response);
343static void bus_destroy_response(ulong busNo, int response);
344static void device_create_response(ulong busNo, ulong devNo, int response);
345static void device_destroy_response(ulong busNo, ulong devNo, int response);
346static void device_resume_response(ulong busNo, ulong devNo, int response);
347
348static VISORCHIPSET_BUSDEV_RESPONDERS BusDev_Responders = {
349 .bus_create = bus_create_response,
350 .bus_destroy = bus_destroy_response,
351 .device_create = device_create_response,
352 .device_destroy = device_destroy_response,
927c7927 353 .device_pause = visorchipset_device_pause_response,
12e364b9
KC
354 .device_resume = device_resume_response,
355};
356
357/* info for /dev/visorchipset */
358static dev_t MajorDev = -1; /**< indicates major num for device */
359
360/* /sys/devices/platform/visorchipset */
361static struct platform_device Visorchipset_platform_device = {
362 .name = "visorchipset",
363 .id = -1,
364};
365
366/* Function prototypes */
367static void controlvm_respond(CONTROLVM_MESSAGE_HEADER *msgHdr, int response);
368static void controlvm_respond_chipset_init(CONTROLVM_MESSAGE_HEADER *msgHdr,
369 int response,
370 ULTRA_CHIPSET_FEATURE features);
371static void controlvm_respond_physdev_changestate(CONTROLVM_MESSAGE_HEADER *
372 msgHdr, int response,
373 ULTRA_SEGMENT_STATE state);
374
375static void
376show_partition_property(struct seq_file *f, void *ctx, int property)
377{
378 VISORCHIPSET_BUS_INFO *info = (VISORCHIPSET_BUS_INFO *) (ctx);
379
380 switch (property) {
381 case PARTPROP_name:
382 seq_printf(f, "%s\n", NONULLSTR(info->name));
383 break;
384 case PARTPROP_description:
385 seq_printf(f, "%s\n", NONULLSTR(info->description));
386 break;
387 case PARTPROP_handle:
388 seq_printf(f, "0x%-16.16Lx\n", info->partitionHandle);
389 break;
390 case PARTPROP_busNumber:
391 seq_printf(f, "%d\n", info->busNo);
392 break;
393 default:
394 seq_printf(f, "(%d??)\n", property);
395 break;
396 }
397}
398
399static void
400show_controlvm_property(struct seq_file *f, void *ctx, int property)
401{
402 /* Note: ctx is not needed since we only have 1 controlvm channel */
403 switch (property) {
404 case CTLVMPROP_physAddr:
405 if (ControlVm_channel == NULL)
406 seq_puts(f, "0x0\n");
407 else
408 seq_printf(f, "0x%-16.16Lx\n",
409 visorchannel_get_physaddr
410 (ControlVm_channel));
411 break;
412 case CTLVMPROP_controlChannelAddr:
413 if (ControlVm_channel == NULL)
414 seq_puts(f, "0x0\n");
415 else {
416 GUEST_PHYSICAL_ADDRESS addr = 0;
417 visorchannel_read(ControlVm_channel,
418 offsetof
419 (ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
420 gpControlChannel), &addr,
421 sizeof(addr));
422 seq_printf(f, "0x%-16.16Lx\n", (u64) (addr));
423 }
424 break;
425 case CTLVMPROP_controlChannelBytes:
426 if (ControlVm_channel == NULL)
427 seq_puts(f, "0x0\n");
428 else {
429 U32 bytes = 0;
430 visorchannel_read(ControlVm_channel,
431 offsetof
432 (ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
433 ControlChannelBytes), &bytes,
434 sizeof(bytes));
435 seq_printf(f, "%lu\n", (ulong) (bytes));
436 }
437 break;
438 case CTLVMPROP_sparBootPart:
439 seq_puts(f, "0:0:0:0/1\n");
440 break;
441 case CTLVMPROP_sparStoragePart:
442 seq_puts(f, "0:0:0:0/2\n");
443 break;
444 case CTLVMPROP_livedumpLength:
445 seq_printf(f, "%lu\n", LiveDump_info.length);
446 break;
447 case CTLVMPROP_livedumpCrc32:
448 seq_printf(f, "%lu\n", (ulong) LiveDump_info.crc32);
449 break;
450 default:
451 seq_printf(f, "(%d??)\n", property);
452 break;
453 }
454}
455
456static void
457proc_Init(void)
458{
459 if (ProcDir == NULL) {
460 ProcDir = proc_mkdir(MYDRVNAME, NULL);
461 if (ProcDir == NULL) {
462 LOGERR("failed to create /proc directory %s",
463 MYDRVNAME);
464 POSTCODE_LINUX_2(CHIPSET_INIT_FAILURE_PC,
465 POSTCODE_SEVERITY_ERR);
466 }
467 }
468}
469
470static void
471proc_DeInit(void)
472{
473 if (ProcDir != NULL)
474 remove_proc_entry(MYDRVNAME, NULL);
475 ProcDir = NULL;
476}
477
478#if 0
479static void
480testUnicode(void)
481{
482 wchar_t unicodeString[] = { 'a', 'b', 'c', 0 };
483 char s[sizeof(unicodeString) * NLS_MAX_CHARSET_SIZE];
484 wchar_t unicode2[99];
485
486 /* NOTE: Either due to a bug, or feature I don't understand, the
487 * kernel utf8_mbstowcs() and utf_wcstombs() do NOT copy the
488 * trailed NUL byte!! REALLY!!!!! Arrrrgggghhhhh
489 */
490
491 LOGINF("sizeof(wchar_t) = %d", sizeof(wchar_t));
492 LOGINF("utf8_wcstombs=%d",
493 chrs = utf8_wcstombs(s, unicodeString, sizeof(s)));
494 if (chrs >= 0)
495 s[chrs] = '\0'; /* GRRRRRRRR */
496 LOGINF("s='%s'", s);
497 LOGINF("utf8_mbstowcs=%d", chrs = utf8_mbstowcs(unicode2, s, 100));
498 if (chrs >= 0)
499 unicode2[chrs] = 0; /* GRRRRRRRR */
500 if (memcmp(unicodeString, unicode2, sizeof(unicodeString)) == 0)
501 LOGINF("strings match... good");
502 else
503 LOGINF("strings did not match!!");
504}
505#endif
506
507static void
508busInfo_clear(void *v)
509{
510 VISORCHIPSET_BUS_INFO *p = (VISORCHIPSET_BUS_INFO *) (v);
511
512 if (p->procObject) {
927c7927 513 visor_proc_DestroyObject(p->procObject);
12e364b9
KC
514 p->procObject = NULL;
515 }
516 kfree(p->name);
517 p->name = NULL;
518
519 kfree(p->description);
520 p->description = NULL;
521
522 p->state.created = 0;
523 memset(p, 0, sizeof(VISORCHIPSET_BUS_INFO));
524}
525
526static void
527devInfo_clear(void *v)
528{
529 VISORCHIPSET_DEVICE_INFO *p = (VISORCHIPSET_DEVICE_INFO *) (v);
530 p->state.created = 0;
531 memset(p, 0, sizeof(VISORCHIPSET_DEVICE_INFO));
532}
533
534static U8
535check_chipset_events(void)
536{
537 int i;
538 U8 send_msg = 1;
539 /* Check events to determine if response should be sent */
540 for (i = 0; i < MAX_CHIPSET_EVENTS; i++)
541 send_msg &= chipset_events[i];
542 return send_msg;
543}
544
545static void
546clear_chipset_events(void)
547{
548 int i;
549 /* Clear chipset_events */
550 for (i = 0; i < MAX_CHIPSET_EVENTS; i++)
551 chipset_events[i] = 0;
552}
553
554void
555visorchipset_register_busdev_server(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers,
556 VISORCHIPSET_BUSDEV_RESPONDERS *responders,
557 ULTRA_VBUS_DEVICEINFO *driverInfo)
558{
559 LOCKSEM_UNINTERRUPTIBLE(&NotifierLock);
560 if (notifiers == NULL) {
561 memset(&BusDev_Server_Notifiers, 0,
562 sizeof(BusDev_Server_Notifiers));
563 serverregistered = 0; /* clear flag */
564 } else {
565 BusDev_Server_Notifiers = *notifiers;
566 serverregistered = 1; /* set flag */
567 }
568 if (responders)
569 *responders = BusDev_Responders;
570 if (driverInfo)
571 BusDeviceInfo_Init(driverInfo, "chipset", "visorchipset",
572 VERSION, NULL, __DATE__, __TIME__);
573
574 UNLOCKSEM(&NotifierLock);
575}
576EXPORT_SYMBOL_GPL(visorchipset_register_busdev_server);
577
578void
579visorchipset_register_busdev_client(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers,
580 VISORCHIPSET_BUSDEV_RESPONDERS *responders,
581 ULTRA_VBUS_DEVICEINFO *driverInfo)
582{
583 LOCKSEM_UNINTERRUPTIBLE(&NotifierLock);
584 if (notifiers == NULL) {
585 memset(&BusDev_Client_Notifiers, 0,
586 sizeof(BusDev_Client_Notifiers));
587 clientregistered = 0; /* clear flag */
588 } else {
589 BusDev_Client_Notifiers = *notifiers;
590 clientregistered = 1; /* set flag */
591 }
592 if (responders)
593 *responders = BusDev_Responders;
594 if (driverInfo)
595 BusDeviceInfo_Init(driverInfo, "chipset(bolts)", "visorchipset",
596 VERSION, NULL, __DATE__, __TIME__);
597 UNLOCKSEM(&NotifierLock);
598}
599EXPORT_SYMBOL_GPL(visorchipset_register_busdev_client);
600
601static void
602cleanup_controlvm_structures(void)
603{
e6b1ea77
DC
604 VISORCHIPSET_BUS_INFO *bi, *tmp_bi;
605 VISORCHIPSET_DEVICE_INFO *di, *tmp_di;
12e364b9 606
e6b1ea77 607 list_for_each_entry_safe(bi, tmp_bi, &BusInfoList, entry) {
12e364b9
KC
608 busInfo_clear(bi);
609 list_del(&bi->entry);
610 kfree(bi);
611 }
612
e6b1ea77 613 list_for_each_entry_safe(di, tmp_di, &DevInfoList, entry) {
12e364b9
KC
614 devInfo_clear(di);
615 list_del(&di->entry);
616 kfree(di);
617 }
618}
619
620static void
621chipset_init(CONTROLVM_MESSAGE *inmsg)
622{
623 static int chipset_inited;
624 ULTRA_CHIPSET_FEATURE features = 0;
625 int rc = CONTROLVM_RESP_SUCCESS;
626
627 POSTCODE_LINUX_2(CHIPSET_INIT_ENTRY_PC, POSTCODE_SEVERITY_INFO);
628 if (chipset_inited) {
629 LOGERR("CONTROLVM_CHIPSET_INIT Failed: Already Done.");
22ad57ba
KC
630 rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE;
631 goto Away;
12e364b9
KC
632 }
633 chipset_inited = 1;
634 POSTCODE_LINUX_2(CHIPSET_INIT_EXIT_PC, POSTCODE_SEVERITY_INFO);
635
636 /* Set features to indicate we support parahotplug (if Command
637 * also supports it). */
638 features =
639 inmsg->cmd.initChipset.
640 features & ULTRA_CHIPSET_FEATURE_PARA_HOTPLUG;
641
642 /* Set the "reply" bit so Command knows this is a
643 * features-aware driver. */
644 features |= ULTRA_CHIPSET_FEATURE_REPLY;
645
646Away:
647 if (rc < 0)
648 cleanup_controlvm_structures();
649 if (inmsg->hdr.Flags.responseExpected)
650 controlvm_respond_chipset_init(&inmsg->hdr, rc, features);
651}
652
653static void
654controlvm_init_response(CONTROLVM_MESSAGE *msg,
655 CONTROLVM_MESSAGE_HEADER *msgHdr, int response)
656{
657 memset(msg, 0, sizeof(CONTROLVM_MESSAGE));
658 memcpy(&msg->hdr, msgHdr, sizeof(CONTROLVM_MESSAGE_HEADER));
659 msg->hdr.PayloadBytes = 0;
660 msg->hdr.PayloadVmOffset = 0;
661 msg->hdr.PayloadMaxBytes = 0;
662 if (response < 0) {
663 msg->hdr.Flags.failed = 1;
664 msg->hdr.CompletionStatus = (U32) (-response);
665 }
666}
667
668static void
669controlvm_respond(CONTROLVM_MESSAGE_HEADER *msgHdr, int response)
670{
671 CONTROLVM_MESSAGE outmsg;
672 if (!ControlVm_channel)
673 return;
674 controlvm_init_response(&outmsg, msgHdr, response);
675 /* For DiagPool channel DEVICE_CHANGESTATE, we need to send
676 * back the deviceChangeState structure in the packet. */
677 if (msgHdr->Id == CONTROLVM_DEVICE_CHANGESTATE
678 && g_DeviceChangeStatePacket.deviceChangeState.busNo ==
679 g_diagpoolBusNo
680 && g_DeviceChangeStatePacket.deviceChangeState.devNo ==
681 g_diagpoolDevNo)
682 outmsg.cmd = g_DeviceChangeStatePacket;
683 if (outmsg.hdr.Flags.testMessage == 1) {
684 LOGINF("%s controlvm_msg=0x%x response=%d for test message",
685 __func__, outmsg.hdr.Id, response);
686 return;
687 }
688 if (!visorchannel_signalinsert(ControlVm_channel,
689 CONTROLVM_QUEUE_REQUEST, &outmsg)) {
690 LOGERR("signalinsert failed!");
691 return;
692 }
693}
694
695static void
696controlvm_respond_chipset_init(CONTROLVM_MESSAGE_HEADER *msgHdr, int response,
697 ULTRA_CHIPSET_FEATURE features)
698{
699 CONTROLVM_MESSAGE outmsg;
700 if (!ControlVm_channel)
701 return;
702 controlvm_init_response(&outmsg, msgHdr, response);
703 outmsg.cmd.initChipset.features = features;
704 if (!visorchannel_signalinsert(ControlVm_channel,
705 CONTROLVM_QUEUE_REQUEST, &outmsg)) {
706 LOGERR("signalinsert failed!");
707 return;
708 }
709}
710
711static void
712controlvm_respond_physdev_changestate(CONTROLVM_MESSAGE_HEADER *msgHdr,
713 int response, ULTRA_SEGMENT_STATE state)
714{
715 CONTROLVM_MESSAGE outmsg;
716 if (!ControlVm_channel)
717 return;
718 controlvm_init_response(&outmsg, msgHdr, response);
719 outmsg.cmd.deviceChangeState.state = state;
720 outmsg.cmd.deviceChangeState.flags.physicalDevice = 1;
721 if (!visorchannel_signalinsert(ControlVm_channel,
722 CONTROLVM_QUEUE_REQUEST, &outmsg)) {
723 LOGERR("signalinsert failed!");
724 return;
725 }
726}
727
728void
729visorchipset_save_message(CONTROLVM_MESSAGE *msg, CRASH_OBJ_TYPE type)
730{
731 U32 localSavedCrashMsgOffset;
732 U16 localSavedCrashMsgCount;
733
734 /* get saved message count */
735 if (visorchannel_read(ControlVm_channel,
736 offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
737 SavedCrashMsgCount),
738 &localSavedCrashMsgCount, sizeof(U16)) < 0) {
739 LOGERR("failed to get Saved Message Count");
740 POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC,
741 POSTCODE_SEVERITY_ERR);
742 return;
743 }
744
745 if (localSavedCrashMsgCount != CONTROLVM_CRASHMSG_MAX) {
746 LOGERR("Saved Message Count incorrect %d",
747 localSavedCrashMsgCount);
748 POSTCODE_LINUX_3(CRASH_DEV_COUNT_FAILURE_PC,
749 localSavedCrashMsgCount,
750 POSTCODE_SEVERITY_ERR);
751 return;
752 }
753
754 /* get saved crash message offset */
755 if (visorchannel_read(ControlVm_channel,
756 offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
757 SavedCrashMsgOffset),
758 &localSavedCrashMsgOffset, sizeof(U32)) < 0) {
759 LOGERR("failed to get Saved Message Offset");
760 POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC,
761 POSTCODE_SEVERITY_ERR);
762 return;
763 }
764
765 if (type == CRASH_bus) {
766 if (visorchannel_write(ControlVm_channel,
767 localSavedCrashMsgOffset,
768 msg, sizeof(CONTROLVM_MESSAGE)) < 0) {
769 LOGERR("SAVE_MSG_BUS_FAILURE: Failed to write CrashCreateBusMsg!");
770 POSTCODE_LINUX_2(SAVE_MSG_BUS_FAILURE_PC,
771 POSTCODE_SEVERITY_ERR);
772 return;
773 }
774 } else {
775 if (visorchannel_write(ControlVm_channel,
776 localSavedCrashMsgOffset +
777 sizeof(CONTROLVM_MESSAGE), msg,
778 sizeof(CONTROLVM_MESSAGE)) < 0) {
779 LOGERR("SAVE_MSG_DEV_FAILURE: Failed to write CrashCreateDevMsg!");
780 POSTCODE_LINUX_2(SAVE_MSG_DEV_FAILURE_PC,
781 POSTCODE_SEVERITY_ERR);
782 return;
783 }
784 }
785}
786EXPORT_SYMBOL_GPL(visorchipset_save_message);
787
788static void
789bus_responder(CONTROLVM_ID cmdId, ulong busNo, int response)
790{
791 VISORCHIPSET_BUS_INFO *p = NULL;
792 BOOL need_clear = FALSE;
793
794 p = findbus(&BusInfoList, busNo);
795 if (!p) {
796 LOGERR("internal error busNo=%lu", busNo);
797 return;
798 }
799 if (response < 0) {
800 if ((cmdId == CONTROLVM_BUS_CREATE) &&
801 (response != (-CONTROLVM_RESP_ERROR_ALREADY_DONE)))
802 /* undo the row we just created... */
803 delbusdevices(&DevInfoList, busNo);
804 } else {
805 if (cmdId == CONTROLVM_BUS_CREATE)
806 p->state.created = 1;
807 if (cmdId == CONTROLVM_BUS_DESTROY)
808 need_clear = TRUE;
809 }
810
811 if (p->pendingMsgHdr.Id == CONTROLVM_INVALID) {
812 LOGERR("bus_responder no pending msg");
813 return; /* no controlvm response needed */
814 }
815 if (p->pendingMsgHdr.Id != (U32) cmdId) {
816 LOGERR("expected=%d, found=%d", cmdId, p->pendingMsgHdr.Id);
817 return;
818 }
819 controlvm_respond(&p->pendingMsgHdr, response);
820 p->pendingMsgHdr.Id = CONTROLVM_INVALID;
821 if (need_clear) {
822 busInfo_clear(p);
823 delbusdevices(&DevInfoList, busNo);
824 }
825}
826
827static void
828device_changestate_responder(CONTROLVM_ID cmdId,
829 ulong busNo, ulong devNo, int response,
830 ULTRA_SEGMENT_STATE responseState)
831{
832 VISORCHIPSET_DEVICE_INFO *p = NULL;
833 CONTROLVM_MESSAGE outmsg;
834
835 if (!ControlVm_channel)
836 return;
837
838 p = finddevice(&DevInfoList, busNo, devNo);
839 if (!p) {
840 LOGERR("internal error; busNo=%lu, devNo=%lu", busNo, devNo);
841 return;
842 }
843 if (p->pendingMsgHdr.Id == CONTROLVM_INVALID) {
844 LOGERR("device_responder no pending msg");
845 return; /* no controlvm response needed */
846 }
847 if (p->pendingMsgHdr.Id != cmdId) {
848 LOGERR("expected=%d, found=%d", cmdId, p->pendingMsgHdr.Id);
849 return;
850 }
851
852 controlvm_init_response(&outmsg, &p->pendingMsgHdr, response);
853
854 outmsg.cmd.deviceChangeState.busNo = busNo;
855 outmsg.cmd.deviceChangeState.devNo = devNo;
856 outmsg.cmd.deviceChangeState.state = responseState;
857
858 if (!visorchannel_signalinsert(ControlVm_channel,
859 CONTROLVM_QUEUE_REQUEST, &outmsg)) {
860 LOGERR("signalinsert failed!");
861 return;
862 }
863
864 p->pendingMsgHdr.Id = CONTROLVM_INVALID;
865}
866
867static void
868device_responder(CONTROLVM_ID cmdId, ulong busNo, ulong devNo, int response)
869{
870 VISORCHIPSET_DEVICE_INFO *p = NULL;
871 BOOL need_clear = FALSE;
872
873 p = finddevice(&DevInfoList, busNo, devNo);
874 if (!p) {
875 LOGERR("internal error; busNo=%lu, devNo=%lu", busNo, devNo);
876 return;
877 }
878 if (response >= 0) {
879 if (cmdId == CONTROLVM_DEVICE_CREATE)
880 p->state.created = 1;
881 if (cmdId == CONTROLVM_DEVICE_DESTROY)
882 need_clear = TRUE;
883 }
884
885 if (p->pendingMsgHdr.Id == CONTROLVM_INVALID) {
886 LOGERR("device_responder no pending msg");
887 return; /* no controlvm response needed */
888 }
889 if (p->pendingMsgHdr.Id != (U32) cmdId) {
890 LOGERR("expected=%d, found=%d", cmdId, p->pendingMsgHdr.Id);
891 return;
892 }
893 controlvm_respond(&p->pendingMsgHdr, response);
894 p->pendingMsgHdr.Id = CONTROLVM_INVALID;
895 if (need_clear)
896 devInfo_clear(p);
897}
898
899static void
900bus_epilog(U32 busNo,
901 U32 cmd, CONTROLVM_MESSAGE_HEADER *msgHdr,
902 int response, BOOL needResponse)
903{
904 BOOL notified = FALSE;
905
906 VISORCHIPSET_BUS_INFO *pBusInfo = findbus(&BusInfoList, busNo);
907
908 if (!pBusInfo) {
909 LOGERR("HUH? bad busNo=%d", busNo);
910 return;
911 }
912 if (needResponse) {
913 memcpy(&pBusInfo->pendingMsgHdr, msgHdr,
914 sizeof(CONTROLVM_MESSAGE_HEADER));
915 } else
916 pBusInfo->pendingMsgHdr.Id = CONTROLVM_INVALID;
917
918 LOCKSEM_UNINTERRUPTIBLE(&NotifierLock);
919 if (response == CONTROLVM_RESP_SUCCESS) {
920 switch (cmd) {
921 case CONTROLVM_BUS_CREATE:
922 /* We can't tell from the bus_create
923 * information which of our 2 bus flavors the
924 * devices on this bus will ultimately end up.
925 * FORTUNATELY, it turns out it is harmless to
926 * send the bus_create to both of them. We can
927 * narrow things down a little bit, though,
928 * because we know: - BusDev_Server can handle
929 * either server or client devices
930 * - BusDev_Client can handle ONLY client
931 * devices */
932 if (BusDev_Server_Notifiers.bus_create) {
933 (*BusDev_Server_Notifiers.bus_create) (busNo);
934 notified = TRUE;
935 }
936 if ((!pBusInfo->flags.server) /*client */ &&
937 BusDev_Client_Notifiers.bus_create) {
938 (*BusDev_Client_Notifiers.bus_create) (busNo);
939 notified = TRUE;
940 }
941 break;
942 case CONTROLVM_BUS_DESTROY:
943 if (BusDev_Server_Notifiers.bus_destroy) {
944 (*BusDev_Server_Notifiers.bus_destroy) (busNo);
945 notified = TRUE;
946 }
947 if ((!pBusInfo->flags.server) /*client */ &&
948 BusDev_Client_Notifiers.bus_destroy) {
949 (*BusDev_Client_Notifiers.bus_destroy) (busNo);
950 notified = TRUE;
951 }
952 break;
953 }
954 }
955 if (notified)
956 /* The callback function just called above is responsible
957 * for calling the appropriate VISORCHIPSET_BUSDEV_RESPONDERS
958 * function, which will call bus_responder()
959 */
960 ;
961 else
962 bus_responder(cmd, busNo, response);
963 UNLOCKSEM(&NotifierLock);
964}
965
966static void
967device_epilog(U32 busNo, U32 devNo, ULTRA_SEGMENT_STATE state, U32 cmd,
968 CONTROLVM_MESSAGE_HEADER *msgHdr, int response,
969 BOOL needResponse, BOOL for_visorbus)
970{
971 VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers = NULL;
972 BOOL notified = FALSE;
973
974 VISORCHIPSET_DEVICE_INFO *pDevInfo =
975 finddevice(&DevInfoList, busNo, devNo);
976 char *envp[] = {
977 "SPARSP_DIAGPOOL_PAUSED_STATE = 1",
978 NULL
979 };
980
981 if (!pDevInfo) {
982 LOGERR("HUH? bad busNo=%d, devNo=%d", busNo, devNo);
983 return;
984 }
985 if (for_visorbus)
986 notifiers = &BusDev_Server_Notifiers;
987 else
988 notifiers = &BusDev_Client_Notifiers;
989 if (needResponse) {
990 memcpy(&pDevInfo->pendingMsgHdr, msgHdr,
991 sizeof(CONTROLVM_MESSAGE_HEADER));
992 } else
993 pDevInfo->pendingMsgHdr.Id = CONTROLVM_INVALID;
994
995 LOCKSEM_UNINTERRUPTIBLE(&NotifierLock);
996 if (response >= 0) {
997 switch (cmd) {
998 case CONTROLVM_DEVICE_CREATE:
999 if (notifiers->device_create) {
1000 (*notifiers->device_create) (busNo, devNo);
1001 notified = TRUE;
1002 }
1003 break;
1004 case CONTROLVM_DEVICE_CHANGESTATE:
1005 /* ServerReady / ServerRunning / SegmentStateRunning */
1006 if (state.Alive == SegmentStateRunning.Alive &&
1007 state.Operating == SegmentStateRunning.Operating) {
1008 if (notifiers->device_resume) {
1009 (*notifiers->device_resume) (busNo,
1010 devNo);
1011 notified = TRUE;
1012 }
1013 }
1014 /* ServerNotReady / ServerLost / SegmentStateStandby */
1015 else if (state.Alive == SegmentStateStandby.Alive &&
1016 state.Operating ==
1017 SegmentStateStandby.Operating) {
1018 /* technically this is standby case
1019 * where server is lost
1020 */
1021 if (notifiers->device_pause) {
1022 (*notifiers->device_pause) (busNo,
1023 devNo);
1024 notified = TRUE;
1025 }
1026 } else if (state.Alive == SegmentStatePaused.Alive &&
1027 state.Operating ==
1028 SegmentStatePaused.Operating) {
1029 /* this is lite pause where channel is
1030 * still valid just 'pause' of it
1031 */
1032 if (busNo == g_diagpoolBusNo
1033 && devNo == g_diagpoolDevNo) {
1034 LOGINF("DEVICE_CHANGESTATE(DiagpoolChannel busNo=%d devNo=%d is pausing...)",
1035 busNo, devNo);
1036 /* this will trigger the
1037 * diag_shutdown.sh script in
1038 * the visorchipset hotplug */
1039 kobject_uevent_env
1040 (&Visorchipset_platform_device.dev.
1041 kobj, KOBJ_ONLINE, envp);
1042 }
1043 }
1044 break;
1045 case CONTROLVM_DEVICE_DESTROY:
1046 if (notifiers->device_destroy) {
1047 (*notifiers->device_destroy) (busNo, devNo);
1048 notified = TRUE;
1049 }
1050 break;
1051 }
1052 }
1053 if (notified)
1054 /* The callback function just called above is responsible
1055 * for calling the appropriate VISORCHIPSET_BUSDEV_RESPONDERS
1056 * function, which will call device_responder()
1057 */
1058 ;
1059 else
1060 device_responder(cmd, busNo, devNo, response);
1061 UNLOCKSEM(&NotifierLock);
1062}
1063
1064static void
1065bus_create(CONTROLVM_MESSAGE *inmsg)
1066{
1067 CONTROLVM_MESSAGE_PACKET *cmd = &inmsg->cmd;
1068 ulong busNo = cmd->createBus.busNo;
1069 int rc = CONTROLVM_RESP_SUCCESS;
1070 VISORCHIPSET_BUS_INFO *pBusInfo = NULL;
1071
1072
1073 pBusInfo = findbus(&BusInfoList, busNo);
1074 if (pBusInfo && (pBusInfo->state.created == 1)) {
1075 LOGERR("CONTROLVM_BUS_CREATE Failed: bus %lu already exists",
1076 busNo);
1077 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, busNo,
1078 POSTCODE_SEVERITY_ERR);
22ad57ba
KC
1079 rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE;
1080 goto Away;
12e364b9 1081 }
97a84f12 1082 pBusInfo = kzalloc(sizeof(VISORCHIPSET_BUS_INFO), GFP_KERNEL);
12e364b9 1083 if (pBusInfo == NULL) {
97a84f12 1084 LOGERR("CONTROLVM_BUS_CREATE Failed: bus %lu kzalloc failed",
12e364b9
KC
1085 busNo);
1086 POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, busNo,
1087 POSTCODE_SEVERITY_ERR);
22ad57ba
KC
1088 rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
1089 goto Away;
12e364b9
KC
1090 }
1091
12e364b9
KC
1092 INIT_LIST_HEAD(&pBusInfo->entry);
1093 pBusInfo->busNo = busNo;
1094 pBusInfo->devNo = cmd->createBus.deviceCount;
1095
1096 POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, busNo, POSTCODE_SEVERITY_INFO);
1097
1098 if (inmsg->hdr.Flags.testMessage == 1)
1099 pBusInfo->chanInfo.addrType = ADDRTYPE_localTest;
1100 else
1101 pBusInfo->chanInfo.addrType = ADDRTYPE_localPhysical;
1102
1103 pBusInfo->flags.server = inmsg->hdr.Flags.server;
1104 pBusInfo->chanInfo.channelAddr = cmd->createBus.channelAddr;
1105 pBusInfo->chanInfo.nChannelBytes = cmd->createBus.channelBytes;
1106 pBusInfo->chanInfo.channelTypeGuid = cmd->createBus.busDataTypeGuid;
1107 pBusInfo->chanInfo.channelInstGuid = cmd->createBus.busInstGuid;
1108
1109 list_add(&pBusInfo->entry, &BusInfoList);
1110
1111 POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, busNo, POSTCODE_SEVERITY_INFO);
1112
1113Away:
1114 bus_epilog(busNo, CONTROLVM_BUS_CREATE, &inmsg->hdr,
1115 rc, inmsg->hdr.Flags.responseExpected == 1);
1116}
1117
1118static void
1119bus_destroy(CONTROLVM_MESSAGE *inmsg)
1120{
1121 CONTROLVM_MESSAGE_PACKET *cmd = &inmsg->cmd;
1122 ulong busNo = cmd->destroyBus.busNo;
1123 VISORCHIPSET_BUS_INFO *pBusInfo;
1124 int rc = CONTROLVM_RESP_SUCCESS;
1125
1126 pBusInfo = findbus(&BusInfoList, busNo);
1127 if (!pBusInfo) {
1128 LOGERR("CONTROLVM_BUS_DESTROY Failed: bus %lu invalid", busNo);
22ad57ba
KC
1129 rc = -CONTROLVM_RESP_ERROR_BUS_INVALID;
1130 goto Away;
12e364b9
KC
1131 }
1132 if (pBusInfo->state.created == 0) {
1133 LOGERR("CONTROLVM_BUS_DESTROY Failed: bus %lu already destroyed",
1134 busNo);
22ad57ba
KC
1135 rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE;
1136 goto Away;
12e364b9
KC
1137 }
1138
1139Away:
1140 bus_epilog(busNo, CONTROLVM_BUS_DESTROY, &inmsg->hdr,
1141 rc, inmsg->hdr.Flags.responseExpected == 1);
1142}
1143
1144static void
1145bus_configure(CONTROLVM_MESSAGE *inmsg, PARSER_CONTEXT *parser_ctx)
1146{
1147 CONTROLVM_MESSAGE_PACKET *cmd = &inmsg->cmd;
1148 ulong busNo = cmd->configureBus.busNo;
1149 VISORCHIPSET_BUS_INFO *pBusInfo = NULL;
1150 int rc = CONTROLVM_RESP_SUCCESS;
1151 char s[99];
1152
1153 busNo = cmd->configureBus.busNo;
1154 POSTCODE_LINUX_3(BUS_CONFIGURE_ENTRY_PC, busNo, POSTCODE_SEVERITY_INFO);
1155
1156 pBusInfo = findbus(&BusInfoList, busNo);
1157 if (!pBusInfo) {
1158 LOGERR("CONTROLVM_BUS_CONFIGURE Failed: bus %lu invalid",
1159 busNo);
1160 POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, busNo,
1161 POSTCODE_SEVERITY_ERR);
22ad57ba
KC
1162 rc = -CONTROLVM_RESP_ERROR_BUS_INVALID;
1163 goto Away;
12e364b9
KC
1164 }
1165 if (pBusInfo->state.created == 0) {
1166 LOGERR("CONTROLVM_BUS_CONFIGURE Failed: Invalid bus %lu - not created yet",
1167 busNo);
1168 POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, busNo,
1169 POSTCODE_SEVERITY_ERR);
22ad57ba
KC
1170 rc = -CONTROLVM_RESP_ERROR_BUS_INVALID;
1171 goto Away;
12e364b9
KC
1172 }
1173 /* TBD - add this check to other commands also... */
1174 if (pBusInfo->pendingMsgHdr.Id != CONTROLVM_INVALID) {
1175 LOGERR("CONTROLVM_BUS_CONFIGURE Failed: bus %lu MsgId=%u outstanding",
1176 busNo, (uint) pBusInfo->pendingMsgHdr.Id);
1177 POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, busNo,
1178 POSTCODE_SEVERITY_ERR);
22ad57ba
KC
1179 rc = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT;
1180 goto Away;
12e364b9
KC
1181 }
1182
1183 pBusInfo->partitionHandle = cmd->configureBus.guestHandle;
1184 pBusInfo->partitionGuid = parser_id_get(parser_ctx);
1185 parser_param_start(parser_ctx, PARSERSTRING_NAME);
1186 pBusInfo->name = parser_string_get(parser_ctx);
1187
90addb02 1188 visorchannel_uuid_id(&pBusInfo->partitionGuid, s);
12e364b9 1189 pBusInfo->procObject =
927c7927 1190 visor_proc_CreateObject(PartitionType, s, (void *) (pBusInfo));
12e364b9
KC
1191 if (pBusInfo->procObject == NULL) {
1192 LOGERR("CONTROLVM_BUS_CONFIGURE Failed: busNo=%lu failed to create /proc entry",
1193 busNo);
1194 POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, busNo,
1195 POSTCODE_SEVERITY_ERR);
22ad57ba
KC
1196 rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
1197 goto Away;
12e364b9
KC
1198 }
1199 POSTCODE_LINUX_3(BUS_CONFIGURE_EXIT_PC, busNo, POSTCODE_SEVERITY_INFO);
1200Away:
1201 bus_epilog(busNo, CONTROLVM_BUS_CONFIGURE, &inmsg->hdr,
1202 rc, inmsg->hdr.Flags.responseExpected == 1);
1203}
1204
1205static void
1206my_device_create(CONTROLVM_MESSAGE *inmsg)
1207{
1208 CONTROLVM_MESSAGE_PACKET *cmd = &inmsg->cmd;
1209 ulong busNo = cmd->createDevice.busNo;
1210 ulong devNo = cmd->createDevice.devNo;
1211 VISORCHIPSET_DEVICE_INFO *pDevInfo = NULL;
1212 VISORCHIPSET_BUS_INFO *pBusInfo = NULL;
1213 int rc = CONTROLVM_RESP_SUCCESS;
1214
1215 pDevInfo = finddevice(&DevInfoList, busNo, devNo);
1216 if (pDevInfo && (pDevInfo->state.created == 1)) {
1217 LOGERR("CONTROLVM_DEVICE_CREATE Failed: busNo=%lu, devNo=%lu already exists",
1218 busNo, devNo);
1219 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo,
1220 POSTCODE_SEVERITY_ERR);
22ad57ba
KC
1221 rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE;
1222 goto Away;
12e364b9
KC
1223 }
1224 pBusInfo = findbus(&BusInfoList, busNo);
1225 if (!pBusInfo) {
1226 LOGERR("CONTROLVM_DEVICE_CREATE Failed: Invalid bus %lu - out of range",
1227 busNo);
1228 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo,
1229 POSTCODE_SEVERITY_ERR);
22ad57ba
KC
1230 rc = -CONTROLVM_RESP_ERROR_BUS_INVALID;
1231 goto Away;
12e364b9
KC
1232 }
1233 if (pBusInfo->state.created == 0) {
1234 LOGERR("CONTROLVM_DEVICE_CREATE Failed: Invalid bus %lu - not created yet",
1235 busNo);
1236 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo,
1237 POSTCODE_SEVERITY_ERR);
22ad57ba
KC
1238 rc = -CONTROLVM_RESP_ERROR_BUS_INVALID;
1239 goto Away;
12e364b9 1240 }
97a84f12 1241 pDevInfo = kzalloc(sizeof(VISORCHIPSET_DEVICE_INFO), GFP_KERNEL);
12e364b9
KC
1242 if (pDevInfo == NULL) {
1243 LOGERR("CONTROLVM_DEVICE_CREATE Failed: busNo=%lu, devNo=%lu kmaloc failed",
1244 busNo, devNo);
1245 POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo,
1246 POSTCODE_SEVERITY_ERR);
22ad57ba
KC
1247 rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
1248 goto Away;
12e364b9 1249 }
97a84f12 1250
12e364b9
KC
1251 INIT_LIST_HEAD(&pDevInfo->entry);
1252 pDevInfo->busNo = busNo;
1253 pDevInfo->devNo = devNo;
1254 pDevInfo->devInstGuid = cmd->createDevice.devInstGuid;
1255 POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, devNo, busNo,
1256 POSTCODE_SEVERITY_INFO);
1257
1258 if (inmsg->hdr.Flags.testMessage == 1)
1259 pDevInfo->chanInfo.addrType = ADDRTYPE_localTest;
1260 else
1261 pDevInfo->chanInfo.addrType = ADDRTYPE_localPhysical;
1262 pDevInfo->chanInfo.channelAddr = cmd->createDevice.channelAddr;
1263 pDevInfo->chanInfo.nChannelBytes = cmd->createDevice.channelBytes;
1264 pDevInfo->chanInfo.channelTypeGuid = cmd->createDevice.dataTypeGuid;
1265 pDevInfo->chanInfo.intr = cmd->createDevice.intr;
1266 list_add(&pDevInfo->entry, &DevInfoList);
1267 POSTCODE_LINUX_4(DEVICE_CREATE_EXIT_PC, devNo, busNo,
1268 POSTCODE_SEVERITY_INFO);
1269Away:
1270 /* get the bus and devNo for DiagPool channel */
1271 if (is_diagpool_channel(pDevInfo->chanInfo.channelTypeGuid)) {
1272 g_diagpoolBusNo = busNo;
1273 g_diagpoolDevNo = devNo;
1274 LOGINF("CONTROLVM_DEVICE_CREATE for DiagPool channel: busNo=%lu, devNo=%lu",
1275 g_diagpoolBusNo, g_diagpoolDevNo);
1276 }
1277 device_epilog(busNo, devNo, SegmentStateRunning,
1278 CONTROLVM_DEVICE_CREATE, &inmsg->hdr, rc,
1279 inmsg->hdr.Flags.responseExpected == 1,
1280 FOR_VISORBUS(pDevInfo->chanInfo.channelTypeGuid));
1281}
1282
1283static void
1284my_device_changestate(CONTROLVM_MESSAGE *inmsg)
1285{
1286 CONTROLVM_MESSAGE_PACKET *cmd = &inmsg->cmd;
1287 ulong busNo = cmd->deviceChangeState.busNo;
1288 ulong devNo = cmd->deviceChangeState.devNo;
1289 ULTRA_SEGMENT_STATE state = cmd->deviceChangeState.state;
1290 VISORCHIPSET_DEVICE_INFO *pDevInfo = NULL;
1291 int rc = CONTROLVM_RESP_SUCCESS;
1292
1293 pDevInfo = finddevice(&DevInfoList, busNo, devNo);
1294 if (!pDevInfo) {
1295 LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: busNo=%lu, devNo=%lu invalid (doesn't exist)",
1296 busNo, devNo);
1297 POSTCODE_LINUX_4(DEVICE_CHANGESTATE_FAILURE_PC, devNo, busNo,
1298 POSTCODE_SEVERITY_ERR);
22ad57ba
KC
1299 rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID;
1300 goto Away;
12e364b9
KC
1301 }
1302 if (pDevInfo->state.created == 0) {
1303 LOGERR("CONTROLVM_DEVICE_CHANGESTATE Failed: busNo=%lu, devNo=%lu invalid (not created)",
1304 busNo, devNo);
1305 POSTCODE_LINUX_4(DEVICE_CHANGESTATE_FAILURE_PC, devNo, busNo,
1306 POSTCODE_SEVERITY_ERR);
22ad57ba 1307 rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID;
12e364b9
KC
1308 }
1309Away:
1310 if ((rc >= CONTROLVM_RESP_SUCCESS) && pDevInfo)
1311 device_epilog(busNo, devNo, state, CONTROLVM_DEVICE_CHANGESTATE,
1312 &inmsg->hdr, rc,
1313 inmsg->hdr.Flags.responseExpected == 1,
1314 FOR_VISORBUS(pDevInfo->chanInfo.channelTypeGuid));
1315}
1316
1317static void
1318my_device_destroy(CONTROLVM_MESSAGE *inmsg)
1319{
1320 CONTROLVM_MESSAGE_PACKET *cmd = &inmsg->cmd;
1321 ulong busNo = cmd->destroyDevice.busNo;
1322 ulong devNo = cmd->destroyDevice.devNo;
1323 VISORCHIPSET_DEVICE_INFO *pDevInfo = NULL;
1324 int rc = CONTROLVM_RESP_SUCCESS;
1325
1326 pDevInfo = finddevice(&DevInfoList, busNo, devNo);
1327 if (!pDevInfo) {
1328 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: busNo=%lu, devNo=%lu invalid",
1329 busNo, devNo);
22ad57ba
KC
1330 rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID;
1331 goto Away;
12e364b9
KC
1332 }
1333 if (pDevInfo->state.created == 0) {
1334 LOGERR("CONTROLVM_DEVICE_DESTROY Failed: busNo=%lu, devNo=%lu already destroyed",
1335 busNo, devNo);
22ad57ba 1336 rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE;
12e364b9
KC
1337 }
1338
1339Away:
1340 if ((rc >= CONTROLVM_RESP_SUCCESS) && pDevInfo)
1341 device_epilog(busNo, devNo, SegmentStateRunning,
1342 CONTROLVM_DEVICE_DESTROY, &inmsg->hdr, rc,
1343 inmsg->hdr.Flags.responseExpected == 1,
1344 FOR_VISORBUS(pDevInfo->chanInfo.channelTypeGuid));
1345}
1346
1347/* When provided with the physical address of the controlvm channel
1348 * (phys_addr), the offset to the payload area we need to manage
1349 * (offset), and the size of this payload area (bytes), fills in the
1350 * CONTROLVM_PAYLOAD_INFO struct. Returns TRUE for success or FALSE
1351 * for failure.
1352 */
1353static int
1354initialize_controlvm_payload_info(HOSTADDRESS phys_addr, U64 offset, U32 bytes,
1355 CONTROLVM_PAYLOAD_INFO *info)
1356{
bd5b9b32 1357 U8 __iomem *payload = NULL;
12e364b9
KC
1358 int rc = CONTROLVM_RESP_SUCCESS;
1359
1360 if (info == NULL) {
1361 LOGERR("HUH ? CONTROLVM_PAYLOAD_INIT Failed : Programmer check at %s:%d",
1362 __FILE__, __LINE__);
22ad57ba
KC
1363 rc = -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID;
1364 goto Away;
12e364b9
KC
1365 }
1366 memset(info, 0, sizeof(CONTROLVM_PAYLOAD_INFO));
1367 if ((offset == 0) || (bytes == 0)) {
1368 LOGERR("CONTROLVM_PAYLOAD_INIT Failed: RequestPayloadOffset=%llu RequestPayloadBytes=%llu!",
1369 (u64) offset, (u64) bytes);
22ad57ba
KC
1370 rc = -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID;
1371 goto Away;
12e364b9
KC
1372 }
1373 payload = ioremap_cache(phys_addr + offset, bytes);
1374 if (payload == NULL) {
1375 LOGERR("CONTROLVM_PAYLOAD_INIT Failed: ioremap_cache %llu for %llu bytes failed",
1376 (u64) offset, (u64) bytes);
22ad57ba
KC
1377 rc = -CONTROLVM_RESP_ERROR_IOREMAP_FAILED;
1378 goto Away;
12e364b9
KC
1379 }
1380
1381 info->offset = offset;
1382 info->bytes = bytes;
1383 info->ptr = payload;
1384 LOGINF("offset=%llu, bytes=%lu, ptr=%p",
1385 (u64) (info->offset), (ulong) (info->bytes), info->ptr);
1386
1387Away:
1388 if (rc < 0) {
1389 if (payload != NULL) {
1390 iounmap(payload);
1391 payload = NULL;
1392 }
1393 }
1394 return rc;
1395}
1396
1397static void
1398destroy_controlvm_payload_info(CONTROLVM_PAYLOAD_INFO *info)
1399{
1400 if (info->ptr != NULL) {
1401 iounmap(info->ptr);
1402 info->ptr = NULL;
1403 }
1404 memset(info, 0, sizeof(CONTROLVM_PAYLOAD_INFO));
1405}
1406
1407static void
1408initialize_controlvm_payload(void)
1409{
1410 HOSTADDRESS phys_addr = visorchannel_get_physaddr(ControlVm_channel);
1411 U64 payloadOffset = 0;
1412 U32 payloadBytes = 0;
1413 if (visorchannel_read(ControlVm_channel,
1414 offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
1415 RequestPayloadOffset),
1416 &payloadOffset, sizeof(payloadOffset)) < 0) {
1417 LOGERR("CONTROLVM_PAYLOAD_INIT Failed to read controlvm channel!");
1418 POSTCODE_LINUX_2(CONTROLVM_INIT_FAILURE_PC,
1419 POSTCODE_SEVERITY_ERR);
1420 return;
1421 }
1422 if (visorchannel_read(ControlVm_channel,
1423 offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
1424 RequestPayloadBytes),
1425 &payloadBytes, sizeof(payloadBytes)) < 0) {
1426 LOGERR("CONTROLVM_PAYLOAD_INIT Failed to read controlvm channel!");
1427 POSTCODE_LINUX_2(CONTROLVM_INIT_FAILURE_PC,
1428 POSTCODE_SEVERITY_ERR);
1429 return;
1430 }
1431 initialize_controlvm_payload_info(phys_addr,
1432 payloadOffset, payloadBytes,
1433 &ControlVm_payload_info);
1434}
1435
1436/* Send ACTION=online for DEVPATH=/sys/devices/platform/visorchipset.
1437 * Returns CONTROLVM_RESP_xxx code.
1438 */
1439int
1440visorchipset_chipset_ready(void)
1441{
1442 kobject_uevent(&Visorchipset_platform_device.dev.kobj, KOBJ_ONLINE);
1443 return CONTROLVM_RESP_SUCCESS;
1444}
1445EXPORT_SYMBOL_GPL(visorchipset_chipset_ready);
1446
1447int
1448visorchipset_chipset_selftest(void)
1449{
1450 char env_selftest[20];
1451 char *envp[] = { env_selftest, NULL };
1452 sprintf(env_selftest, "SPARSP_SELFTEST=%d", 1);
1453 kobject_uevent_env(&Visorchipset_platform_device.dev.kobj, KOBJ_CHANGE,
1454 envp);
1455 return CONTROLVM_RESP_SUCCESS;
1456}
1457EXPORT_SYMBOL_GPL(visorchipset_chipset_selftest);
1458
1459/* Send ACTION=offline for DEVPATH=/sys/devices/platform/visorchipset.
1460 * Returns CONTROLVM_RESP_xxx code.
1461 */
1462int
1463visorchipset_chipset_notready(void)
1464{
1465 kobject_uevent(&Visorchipset_platform_device.dev.kobj, KOBJ_OFFLINE);
1466 return CONTROLVM_RESP_SUCCESS;
1467}
1468EXPORT_SYMBOL_GPL(visorchipset_chipset_notready);
1469
1470static void
1471chipset_ready(CONTROLVM_MESSAGE_HEADER *msgHdr)
1472{
1473 int rc = visorchipset_chipset_ready();
1474 if (rc != CONTROLVM_RESP_SUCCESS)
1475 rc = -rc;
1476 if (msgHdr->Flags.responseExpected && !visorchipset_holdchipsetready)
1477 controlvm_respond(msgHdr, rc);
1478 if (msgHdr->Flags.responseExpected && visorchipset_holdchipsetready) {
1479 /* Send CHIPSET_READY response when all modules have been loaded
1480 * and disks mounted for the partition
1481 */
1482 g_ChipSetMsgHdr = *msgHdr;
1483 LOGINF("Holding CHIPSET_READY response");
1484 }
1485}
1486
1487static void
1488chipset_selftest(CONTROLVM_MESSAGE_HEADER *msgHdr)
1489{
1490 int rc = visorchipset_chipset_selftest();
1491 if (rc != CONTROLVM_RESP_SUCCESS)
1492 rc = -rc;
1493 if (msgHdr->Flags.responseExpected)
1494 controlvm_respond(msgHdr, rc);
1495}
1496
1497static void
1498chipset_notready(CONTROLVM_MESSAGE_HEADER *msgHdr)
1499{
1500 int rc = visorchipset_chipset_notready();
1501 if (rc != CONTROLVM_RESP_SUCCESS)
1502 rc = -rc;
1503 if (msgHdr->Flags.responseExpected)
1504 controlvm_respond(msgHdr, rc);
1505}
1506
1507/* This is your "one-stop" shop for grabbing the next message from the
1508 * CONTROLVM_QUEUE_EVENT queue in the controlvm channel.
1509 */
1510static BOOL
1511read_controlvm_event(CONTROLVM_MESSAGE *msg)
1512{
1513 if (visorchannel_signalremove(ControlVm_channel,
1514 CONTROLVM_QUEUE_EVENT, msg)) {
1515 /* got a message */
1516 if (msg->hdr.Flags.testMessage == 1) {
1517 LOGERR("ignoring bad CONTROLVM_QUEUE_EVENT msg with controlvm_msg_id=0x%x because Flags.testMessage is nonsensical (=1)", msg->hdr.Id);
1518 return FALSE;
1519 } else
1520 return TRUE;
1521 }
1522 return FALSE;
1523}
1524
1525/*
1526 * The general parahotplug flow works as follows. The visorchipset
1527 * driver receives a DEVICE_CHANGESTATE message from Command
1528 * specifying a physical device to enable or disable. The CONTROLVM
1529 * message handler calls parahotplug_process_message, which then adds
1530 * the message to a global list and kicks off a udev event which
1531 * causes a user level script to enable or disable the specified
1532 * device. The udev script then writes to
1533 * /proc/visorchipset/parahotplug, which causes parahotplug_proc_write
1534 * to get called, at which point the appropriate CONTROLVM message is
1535 * retrieved from the list and responded to.
1536 */
1537
1538#define PARAHOTPLUG_TIMEOUT_MS 2000
1539
1540/*
1541 * Generate unique int to match an outstanding CONTROLVM message with a
1542 * udev script /proc response
1543 */
1544static int
1545parahotplug_next_id(void)
1546{
1547 static atomic_t id = ATOMIC_INIT(0);
1548 return atomic_inc_return(&id);
1549}
1550
1551/*
1552 * Returns the time (in jiffies) when a CONTROLVM message on the list
1553 * should expire -- PARAHOTPLUG_TIMEOUT_MS in the future
1554 */
1555static unsigned long
1556parahotplug_next_expiration(void)
1557{
1558 return jiffies + PARAHOTPLUG_TIMEOUT_MS * HZ / 1000;
1559}
1560
1561/*
1562 * Create a parahotplug_request, which is basically a wrapper for a
1563 * CONTROLVM_MESSAGE that we can stick on a list
1564 */
1565static struct parahotplug_request *
1566parahotplug_request_create(CONTROLVM_MESSAGE *msg)
1567{
1568 struct parahotplug_request *req =
1569 kmalloc(sizeof(struct parahotplug_request),
1570 GFP_KERNEL|__GFP_NORETRY);
1571 if (req == NULL)
1572 return NULL;
1573
1574 req->id = parahotplug_next_id();
1575 req->expiration = parahotplug_next_expiration();
1576 req->msg = *msg;
1577
1578 return req;
1579}
1580
1581/*
1582 * Free a parahotplug_request.
1583 */
1584static void
1585parahotplug_request_destroy(struct parahotplug_request *req)
1586{
1587 kfree(req);
1588}
1589
1590/*
1591 * Cause uevent to run the user level script to do the disable/enable
1592 * specified in (the CONTROLVM message in) the specified
1593 * parahotplug_request
1594 */
1595static void
1596parahotplug_request_kickoff(struct parahotplug_request *req)
1597{
1598 CONTROLVM_MESSAGE_PACKET *cmd = &req->msg.cmd;
1599 char env_cmd[40], env_id[40], env_state[40], env_bus[40], env_dev[40],
1600 env_func[40];
1601 char *envp[] = {
1602 env_cmd, env_id, env_state, env_bus, env_dev, env_func, NULL
1603 };
1604
1605 sprintf(env_cmd, "SPAR_PARAHOTPLUG=1");
1606 sprintf(env_id, "SPAR_PARAHOTPLUG_ID=%d", req->id);
1607 sprintf(env_state, "SPAR_PARAHOTPLUG_STATE=%d",
1608 cmd->deviceChangeState.state.Active);
1609 sprintf(env_bus, "SPAR_PARAHOTPLUG_BUS=%d",
1610 cmd->deviceChangeState.busNo);
1611 sprintf(env_dev, "SPAR_PARAHOTPLUG_DEVICE=%d",
1612 cmd->deviceChangeState.devNo >> 3);
1613 sprintf(env_func, "SPAR_PARAHOTPLUG_FUNCTION=%d",
1614 cmd->deviceChangeState.devNo & 0x7);
1615
1616 LOGINF("parahotplug_request_kickoff: state=%d, bdf=%d/%d/%d, id=%u\n",
1617 cmd->deviceChangeState.state.Active,
1618 cmd->deviceChangeState.busNo, cmd->deviceChangeState.devNo >> 3,
1619 cmd->deviceChangeState.devNo & 7, req->id);
1620
1621 kobject_uevent_env(&Visorchipset_platform_device.dev.kobj, KOBJ_CHANGE,
1622 envp);
1623}
1624
1625/*
1626 * Remove any request from the list that's been on there too long and
1627 * respond with an error.
1628 */
1629static void
1630parahotplug_process_list(void)
1631{
1632 struct list_head *pos = NULL;
1633 struct list_head *tmp = NULL;
1634
1635 spin_lock(&Parahotplug_request_list_lock);
1636
1637 list_for_each_safe(pos, tmp, &Parahotplug_request_list) {
1638 struct parahotplug_request *req =
1639 list_entry(pos, struct parahotplug_request, list);
1640 if (time_after_eq(jiffies, req->expiration)) {
1641 list_del(pos);
1642 if (req->msg.hdr.Flags.responseExpected)
1643 controlvm_respond_physdev_changestate(
1644 &req->msg.hdr,
1645 CONTROLVM_RESP_ERROR_DEVICE_UDEV_TIMEOUT,
1646 req->msg.cmd.deviceChangeState.state);
1647 parahotplug_request_destroy(req);
1648 }
1649 }
1650
1651 spin_unlock(&Parahotplug_request_list_lock);
1652}
1653
1654/*
1655 * Called from the /proc handler, which means the user script has
1656 * finished the enable/disable. Find the matching identifier, and
1657 * respond to the CONTROLVM message with success.
1658 */
1659static int
1660parahotplug_request_complete(int id, U16 active)
1661{
1662 struct list_head *pos = NULL;
1663 struct list_head *tmp = NULL;
1664
1665 spin_lock(&Parahotplug_request_list_lock);
1666
1667 /* Look for a request matching "id". */
1668 list_for_each_safe(pos, tmp, &Parahotplug_request_list) {
1669 struct parahotplug_request *req =
1670 list_entry(pos, struct parahotplug_request, list);
1671 if (req->id == id) {
1672 /* Found a match. Remove it from the list and
1673 * respond.
1674 */
1675 list_del(pos);
1676 spin_unlock(&Parahotplug_request_list_lock);
1677 req->msg.cmd.deviceChangeState.state.Active = active;
1678 if (req->msg.hdr.Flags.responseExpected)
1679 controlvm_respond_physdev_changestate(
1680 &req->msg.hdr, CONTROLVM_RESP_SUCCESS,
1681 req->msg.cmd.deviceChangeState.state);
1682 parahotplug_request_destroy(req);
1683 return 0;
1684 }
1685 }
1686
1687 spin_unlock(&Parahotplug_request_list_lock);
1688 return -1;
1689}
1690
1691/*
1692 * Enables or disables a PCI device by kicking off a udev script
1693 */
bd5b9b32 1694static void
12e364b9
KC
1695parahotplug_process_message(CONTROLVM_MESSAGE *inmsg)
1696{
1697 struct parahotplug_request *req;
1698
1699 req = parahotplug_request_create(inmsg);
1700
1701 if (req == NULL) {
1702 LOGERR("parahotplug_process_message: couldn't allocate request");
1703 return;
1704 }
1705
1706 if (inmsg->cmd.deviceChangeState.state.Active) {
1707 /* For enable messages, just respond with success
1708 * right away. This is a bit of a hack, but there are
1709 * issues with the early enable messages we get (with
1710 * either the udev script not detecting that the device
1711 * is up, or not getting called at all). Fortunately
1712 * the messages that get lost don't matter anyway, as
1713 * devices are automatically enabled at
1714 * initialization.
1715 */
1716 parahotplug_request_kickoff(req);
1717 controlvm_respond_physdev_changestate(&inmsg->hdr,
1718 CONTROLVM_RESP_SUCCESS,
1719 inmsg->cmd.
1720 deviceChangeState.state);
1721 parahotplug_request_destroy(req);
1722 } else {
1723 /* For disable messages, add the request to the
1724 * request list before kicking off the udev script. It
1725 * won't get responded to until the script has
1726 * indicated it's done.
1727 */
1728 spin_lock(&Parahotplug_request_list_lock);
1729 list_add_tail(&(req->list), &Parahotplug_request_list);
1730 spin_unlock(&Parahotplug_request_list_lock);
1731
1732 parahotplug_request_kickoff(req);
1733 }
1734}
1735
1736/*
1737 * Gets called when the udev script writes to
1738 * /proc/visorchipset/parahotplug. Expects input in the form of "<id>
1739 * <active>" where <id> is the identifier passed to the script that
1740 * matches a request on the request list, and <active> is 0 or 1
1741 * indicating whether the device is now enabled or not.
1742 */
1743static ssize_t
1744parahotplug_proc_write(struct file *file, const char __user *buffer,
1745 size_t count, loff_t *ppos)
1746{
1747 char buf[64];
1748 uint id;
1749 ushort active;
1750
1751 if (count > sizeof(buf) - 1) {
1752 LOGERR("parahotplug_proc_write: count (%d) exceeds size of buffer (%d)",
1753 (int) count, (int) sizeof(buf));
1754 return -EINVAL;
1755 }
1756 if (copy_from_user(buf, buffer, count)) {
1757 LOGERR("parahotplug_proc_write: copy_from_user failed");
1758 return -EFAULT;
1759 }
1760 buf[count] = '\0';
1761
1762 if (sscanf(buf, "%u %hu", &id, &active) != 2) {
1763 id = 0;
1764 active = 0;
1765 }
1766
1767 if (active != 1 && active != 0) {
1768 LOGERR("parahotplug_proc_write: invalid active field");
1769 return -EINVAL;
1770 }
1771
1772 parahotplug_request_complete((int) id, (U16) active);
1773
1774 return count;
1775}
1776
1777static const struct file_operations parahotplug_proc_fops = {
1778 .owner = THIS_MODULE,
1779 .read = visorchipset_proc_read_writeonly,
1780 .write = parahotplug_proc_write,
1781};
1782
1783/* Process a controlvm message.
1784 * Return result:
1785 * FALSE - this function will return FALSE only in the case where the
1786 * controlvm message was NOT processed, but processing must be
1787 * retried before reading the next controlvm message; a
1788 * scenario where this can occur is when we need to throttle
1789 * the allocation of memory in which to copy out controlvm
1790 * payload data
1791 * TRUE - processing of the controlvm message completed,
1792 * either successfully or with an error.
1793 */
1794static BOOL
1795handle_command(CONTROLVM_MESSAGE inmsg, HOSTADDRESS channel_addr)
1796{
1797 CONTROLVM_MESSAGE_PACKET *cmd = &inmsg.cmd;
1798 U64 parametersAddr = 0;
1799 U32 parametersBytes = 0;
1800 PARSER_CONTEXT *parser_ctx = NULL;
1801 BOOL isLocalAddr = FALSE;
1802 CONTROLVM_MESSAGE ackmsg;
1803
1804 /* create parsing context if necessary */
1805 isLocalAddr = (inmsg.hdr.Flags.testMessage == 1);
1806 if (channel_addr == 0) {
1807 LOGERR("HUH? channel_addr is 0!");
1808 return TRUE;
1809 }
1810 parametersAddr = channel_addr + inmsg.hdr.PayloadVmOffset;
1811 parametersBytes = inmsg.hdr.PayloadBytes;
1812
1813 /* Parameter and channel addresses within test messages actually lie
1814 * within our OS-controlled memory. We need to know that, because it
1815 * makes a difference in how we compute the virtual address.
1816 */
1817 if (parametersAddr != 0 && parametersBytes != 0) {
1818 BOOL retry = FALSE;
1819 parser_ctx =
1820 parser_init_byteStream(parametersAddr, parametersBytes,
1821 isLocalAddr, &retry);
1822 if (!parser_ctx) {
1823 if (retry) {
1824 LOGWRN("throttling to copy payload");
1825 return FALSE;
1826 }
1827 LOGWRN("parsing failed");
1828 LOGWRN("inmsg.hdr.Id=0x%lx", (ulong) inmsg.hdr.Id);
1829 LOGWRN("parametersAddr=0x%llx", (u64) parametersAddr);
1830 LOGWRN("parametersBytes=%lu", (ulong) parametersBytes);
1831 LOGWRN("isLocalAddr=%d", isLocalAddr);
1832 }
1833 }
1834
1835 if (!isLocalAddr) {
1836 controlvm_init_response(&ackmsg, &inmsg.hdr,
1837 CONTROLVM_RESP_SUCCESS);
1838 if ((ControlVm_channel)
1839 &&
1840 (!visorchannel_signalinsert
1841 (ControlVm_channel, CONTROLVM_QUEUE_ACK, &ackmsg)))
1842 LOGWRN("failed to send ACK failed");
1843 }
1844 switch (inmsg.hdr.Id) {
1845 case CONTROLVM_CHIPSET_INIT:
1846 LOGINF("CHIPSET_INIT(#busses=%lu,#switches=%lu)",
1847 (ulong) inmsg.cmd.initChipset.busCount,
1848 (ulong) inmsg.cmd.initChipset.switchCount);
1849 chipset_init(&inmsg);
1850 break;
1851 case CONTROLVM_BUS_CREATE:
1852 LOGINF("BUS_CREATE(%lu,#devs=%lu)",
1853 (ulong) cmd->createBus.busNo,
1854 (ulong) cmd->createBus.deviceCount);
1855 bus_create(&inmsg);
1856 break;
1857 case CONTROLVM_BUS_DESTROY:
1858 LOGINF("BUS_DESTROY(%lu)", (ulong) cmd->destroyBus.busNo);
1859 bus_destroy(&inmsg);
1860 break;
1861 case CONTROLVM_BUS_CONFIGURE:
1862 LOGINF("BUS_CONFIGURE(%lu)", (ulong) cmd->configureBus.busNo);
1863 bus_configure(&inmsg, parser_ctx);
1864 break;
1865 case CONTROLVM_DEVICE_CREATE:
1866 LOGINF("DEVICE_CREATE(%lu,%lu)",
1867 (ulong) cmd->createDevice.busNo,
1868 (ulong) cmd->createDevice.devNo);
1869 my_device_create(&inmsg);
1870 break;
1871 case CONTROLVM_DEVICE_CHANGESTATE:
1872 if (cmd->deviceChangeState.flags.physicalDevice) {
1873 LOGINF("DEVICE_CHANGESTATE for physical device (%lu,%lu, active=%lu)",
1874 (ulong) cmd->deviceChangeState.busNo,
1875 (ulong) cmd->deviceChangeState.devNo,
1876 (ulong) cmd->deviceChangeState.state.Active);
1877 parahotplug_process_message(&inmsg);
1878 } else {
1879 LOGINF("DEVICE_CHANGESTATE for virtual device (%lu,%lu, state.Alive=0x%lx)",
1880 (ulong) cmd->deviceChangeState.busNo,
1881 (ulong) cmd->deviceChangeState.devNo,
1882 (ulong) cmd->deviceChangeState.state.Alive);
1883 /* save the hdr and cmd structures for later use */
1884 /* when sending back the response to Command */
1885 my_device_changestate(&inmsg);
1886 g_DiagMsgHdr = inmsg.hdr;
1887 g_DeviceChangeStatePacket = inmsg.cmd;
1888 break;
1889 }
1890 break;
1891 case CONTROLVM_DEVICE_DESTROY:
1892 LOGINF("DEVICE_DESTROY(%lu,%lu)",
1893 (ulong) cmd->destroyDevice.busNo,
1894 (ulong) cmd->destroyDevice.devNo);
1895 my_device_destroy(&inmsg);
1896 break;
1897 case CONTROLVM_DEVICE_CONFIGURE:
1898 LOGINF("DEVICE_CONFIGURE(%lu,%lu)",
1899 (ulong) cmd->configureDevice.busNo,
1900 (ulong) cmd->configureDevice.devNo);
1901 /* no op for now, just send a respond that we passed */
1902 if (inmsg.hdr.Flags.responseExpected)
1903 controlvm_respond(&inmsg.hdr, CONTROLVM_RESP_SUCCESS);
1904 break;
1905 case CONTROLVM_CHIPSET_READY:
1906 LOGINF("CHIPSET_READY");
1907 chipset_ready(&inmsg.hdr);
1908 break;
1909 case CONTROLVM_CHIPSET_SELFTEST:
1910 LOGINF("CHIPSET_SELFTEST");
1911 chipset_selftest(&inmsg.hdr);
1912 break;
1913 case CONTROLVM_CHIPSET_STOP:
1914 LOGINF("CHIPSET_STOP");
1915 chipset_notready(&inmsg.hdr);
1916 break;
1917 default:
1918 LOGERR("unrecognized controlvm cmd=%d", (int) inmsg.hdr.Id);
1919 if (inmsg.hdr.Flags.responseExpected)
1920 controlvm_respond(&inmsg.hdr,
1921 -CONTROLVM_RESP_ERROR_MESSAGE_ID_UNKNOWN);
1922 break;
1923 }
1924
1925 if (parser_ctx != NULL) {
1926 parser_done(parser_ctx);
1927 parser_ctx = NULL;
1928 }
1929 return TRUE;
1930}
1931
1932static void
1933controlvm_periodic_work(struct work_struct *work)
1934{
1935 VISORCHIPSET_CHANNEL_INFO chanInfo;
1936 CONTROLVM_MESSAGE inmsg;
1937 char s[99];
1938 BOOL gotACommand = FALSE;
1939 BOOL handle_command_failed = FALSE;
1940 static U64 Poll_Count;
1941
1942 /* make sure visorbus server is registered for controlvm callbacks */
1943 if (visorchipset_serverregwait && !serverregistered)
097f4c19 1944 goto Away;
12e364b9
KC
1945 /* make sure visorclientbus server is regsitered for controlvm
1946 * callbacks
1947 */
1948 if (visorchipset_clientregwait && !clientregistered)
097f4c19 1949 goto Away;
12e364b9
KC
1950
1951 memset(&chanInfo, 0, sizeof(VISORCHIPSET_CHANNEL_INFO));
1952 if (!ControlVm_channel) {
1953 HOSTADDRESS addr = controlvm_get_channel_address();
1954 if (addr != 0) {
1955 ControlVm_channel =
1956 visorchannel_create_with_lock
1957 (addr,
1958 sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL),
1959 UltraControlvmChannelProtocolGuid);
1960 if (ControlVm_channel == NULL)
1961 LOGERR("failed to create controlvm channel");
1962 else if (ULTRA_CONTROLVM_CHANNEL_OK_CLIENT
1963 (visorchannel_get_header(ControlVm_channel),
1964 NULL)) {
1965 LOGINF("Channel %s (ControlVm) discovered",
1966 visorchannel_id(ControlVm_channel, s));
1967 initialize_controlvm_payload();
1968 } else {
1969 LOGERR("controlvm channel is invalid");
1970 visorchannel_destroy(ControlVm_channel);
1971 ControlVm_channel = NULL;
1972 }
1973 }
1974 }
1975
1976 Poll_Count++;
1977 if ((ControlVm_channel != NULL) || (Poll_Count >= 250))
1978 ; /* keep going */
1979 else
097f4c19 1980 goto Away;
12e364b9
KC
1981
1982 /* Check events to determine if response to CHIPSET_READY
1983 * should be sent
1984 */
1985 if (visorchipset_holdchipsetready
1986 && (g_ChipSetMsgHdr.Id != CONTROLVM_INVALID)) {
1987 if (check_chipset_events() == 1) {
1988 LOGINF("Sending CHIPSET_READY response");
1989 controlvm_respond(&g_ChipSetMsgHdr, 0);
1990 clear_chipset_events();
1991 memset(&g_ChipSetMsgHdr, 0,
1992 sizeof(CONTROLVM_MESSAGE_HEADER));
1993 }
1994 }
1995
1996 if (ControlVm_channel) {
1997 while (visorchannel_signalremove(ControlVm_channel,
1998 CONTROLVM_QUEUE_RESPONSE,
1999 &inmsg)) {
2000 if (inmsg.hdr.PayloadMaxBytes != 0) {
2001 LOGERR("Payload of size %lu returned @%lu with unexpected message id %d.",
2002 (ulong) inmsg.hdr.PayloadMaxBytes,
2003 (ulong) inmsg.hdr.PayloadVmOffset,
2004 inmsg.hdr.Id);
2005 }
2006 }
2007 if (!gotACommand) {
2008 if (ControlVm_Pending_Msg_Valid) {
2009 /* we throttled processing of a prior
2010 * msg, so try to process it again
2011 * rather than reading a new one
2012 */
2013 inmsg = ControlVm_Pending_Msg;
2014 ControlVm_Pending_Msg_Valid = FALSE;
2015 gotACommand = TRUE;
2016 } else
2017 gotACommand = read_controlvm_event(&inmsg);
2018 }
2019 }
2020
2021 handle_command_failed = FALSE;
2022 while (gotACommand && (!handle_command_failed)) {
2023 Most_recent_message_jiffies = jiffies;
2024 if (ControlVm_channel) {
2025 if (handle_command(inmsg,
2026 visorchannel_get_physaddr
2027 (ControlVm_channel)))
2028 gotACommand = read_controlvm_event(&inmsg);
2029 else {
2030 /* this is a scenario where throttling
2031 * is required, but probably NOT an
2032 * error...; we stash the current
2033 * controlvm msg so we will attempt to
2034 * reprocess it on our next loop
2035 */
2036 handle_command_failed = TRUE;
2037 ControlVm_Pending_Msg = inmsg;
2038 ControlVm_Pending_Msg_Valid = TRUE;
2039 }
2040
2041 } else {
2042 handle_command(inmsg, 0);
2043 gotACommand = FALSE;
2044 }
2045 }
2046
2047 /* parahotplug_worker */
2048 parahotplug_process_list();
2049
12e364b9
KC
2050Away:
2051
2052 if (time_after(jiffies,
2053 Most_recent_message_jiffies + (HZ * MIN_IDLE_SECONDS))) {
2054 /* it's been longer than MIN_IDLE_SECONDS since we
2055 * processed our last controlvm message; slow down the
2056 * polling
2057 */
2058 if (Poll_jiffies != POLLJIFFIES_CONTROLVMCHANNEL_SLOW) {
2059 LOGINF("switched to slow controlvm polling");
2060 Poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_SLOW;
2061 }
2062 } else {
2063 if (Poll_jiffies != POLLJIFFIES_CONTROLVMCHANNEL_FAST) {
2064 Poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_FAST;
2065 LOGINF("switched to fast controlvm polling");
2066 }
2067 }
2068
4b4b535e
DY
2069 queue_delayed_work(Periodic_controlvm_workqueue,
2070 &Periodic_controlvm_work, Poll_jiffies);
12e364b9
KC
2071}
2072
2073static void
2074setup_crash_devices_work_queue(struct work_struct *work)
2075{
2076
2077 CONTROLVM_MESSAGE localCrashCreateBusMsg;
2078 CONTROLVM_MESSAGE localCrashCreateDevMsg;
2079 CONTROLVM_MESSAGE msg;
2080 HOSTADDRESS host_addr;
2081 U32 localSavedCrashMsgOffset;
2082 U16 localSavedCrashMsgCount;
2083
2084 /* make sure visorbus server is registered for controlvm callbacks */
2085 if (visorchipset_serverregwait && !serverregistered)
097f4c19 2086 goto Away;
12e364b9
KC
2087
2088 /* make sure visorclientbus server is regsitered for controlvm
2089 * callbacks
2090 */
2091 if (visorchipset_clientregwait && !clientregistered)
097f4c19 2092 goto Away;
12e364b9
KC
2093
2094 POSTCODE_LINUX_2(CRASH_DEV_ENTRY_PC, POSTCODE_SEVERITY_INFO);
2095
2096 /* send init chipset msg */
2097 msg.hdr.Id = CONTROLVM_CHIPSET_INIT;
2098 msg.cmd.initChipset.busCount = 23;
2099 msg.cmd.initChipset.switchCount = 0;
2100
2101 chipset_init(&msg);
2102
2103 host_addr = controlvm_get_channel_address();
2104 if (!host_addr) {
2105 LOGERR("Huh? Host address is NULL");
2106 POSTCODE_LINUX_2(CRASH_DEV_HADDR_NULL, POSTCODE_SEVERITY_ERR);
2107 return;
2108 }
2109
2110 ControlVm_channel =
2111 visorchannel_create_with_lock
2112 (host_addr,
2113 sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL),
2114 UltraControlvmChannelProtocolGuid);
2115
2116 if (ControlVm_channel == NULL) {
2117 LOGERR("failed to create controlvm channel");
2118 POSTCODE_LINUX_2(CRASH_DEV_CONTROLVM_NULL,
2119 POSTCODE_SEVERITY_ERR);
2120 return;
2121 }
2122
2123 /* get saved message count */
2124 if (visorchannel_read(ControlVm_channel,
2125 offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
2126 SavedCrashMsgCount),
2127 &localSavedCrashMsgCount, sizeof(U16)) < 0) {
2128 LOGERR("failed to get Saved Message Count");
2129 POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC,
2130 POSTCODE_SEVERITY_ERR);
2131 return;
2132 }
2133
2134 if (localSavedCrashMsgCount != CONTROLVM_CRASHMSG_MAX) {
2135 LOGERR("Saved Message Count incorrect %d",
2136 localSavedCrashMsgCount);
2137 POSTCODE_LINUX_3(CRASH_DEV_COUNT_FAILURE_PC,
2138 localSavedCrashMsgCount,
2139 POSTCODE_SEVERITY_ERR);
2140 return;
2141 }
2142
2143 /* get saved crash message offset */
2144 if (visorchannel_read(ControlVm_channel,
2145 offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
2146 SavedCrashMsgOffset),
2147 &localSavedCrashMsgOffset, sizeof(U32)) < 0) {
2148 LOGERR("failed to get Saved Message Offset");
2149 POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC,
2150 POSTCODE_SEVERITY_ERR);
2151 return;
2152 }
2153
2154 /* read create device message for storage bus offset */
2155 if (visorchannel_read(ControlVm_channel,
2156 localSavedCrashMsgOffset,
2157 &localCrashCreateBusMsg,
2158 sizeof(CONTROLVM_MESSAGE)) < 0) {
2159 LOGERR("CRASH_DEV_RD_BUS_FAIULRE: Failed to read CrashCreateBusMsg!");
2160 POSTCODE_LINUX_2(CRASH_DEV_RD_BUS_FAIULRE_PC,
2161 POSTCODE_SEVERITY_ERR);
2162 return;
2163 }
2164
2165 /* read create device message for storage device */
2166 if (visorchannel_read(ControlVm_channel,
2167 localSavedCrashMsgOffset +
2168 sizeof(CONTROLVM_MESSAGE),
2169 &localCrashCreateDevMsg,
2170 sizeof(CONTROLVM_MESSAGE)) < 0) {
2171 LOGERR("CRASH_DEV_RD_DEV_FAIULRE: Failed to read CrashCreateDevMsg!");
2172 POSTCODE_LINUX_2(CRASH_DEV_RD_DEV_FAIULRE_PC,
2173 POSTCODE_SEVERITY_ERR);
2174 return;
2175 }
2176
2177 /* reuse IOVM create bus message */
2178 if (localCrashCreateBusMsg.cmd.createBus.channelAddr != 0)
2179 bus_create(&localCrashCreateBusMsg);
2180 else {
2181 LOGERR("CrashCreateBusMsg is null, no dump will be taken");
2182 POSTCODE_LINUX_2(CRASH_DEV_BUS_NULL_FAILURE_PC,
2183 POSTCODE_SEVERITY_ERR);
2184 return;
2185 }
2186
2187 /* reuse create device message for storage device */
2188 if (localCrashCreateDevMsg.cmd.createDevice.channelAddr != 0)
2189 my_device_create(&localCrashCreateDevMsg);
2190 else {
2191 LOGERR("CrashCreateDevMsg is null, no dump will be taken");
2192 POSTCODE_LINUX_2(CRASH_DEV_DEV_NULL_FAILURE_PC,
2193 POSTCODE_SEVERITY_ERR);
2194 return;
2195 }
2196 LOGINF("Bus and device ready for dumping");
2197 POSTCODE_LINUX_2(CRASH_DEV_EXIT_PC, POSTCODE_SEVERITY_INFO);
2198 return;
2199
2200Away:
2201
2202 Poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_SLOW;
2203
4b4b535e
DY
2204 queue_delayed_work(Periodic_controlvm_workqueue,
2205 &Periodic_controlvm_work, Poll_jiffies);
12e364b9
KC
2206}
2207
2208static void
2209bus_create_response(ulong busNo, int response)
2210{
2211 bus_responder(CONTROLVM_BUS_CREATE, busNo, response);
2212}
2213
2214static void
2215bus_destroy_response(ulong busNo, int response)
2216{
2217 bus_responder(CONTROLVM_BUS_DESTROY, busNo, response);
2218}
2219
2220static void
2221device_create_response(ulong busNo, ulong devNo, int response)
2222{
2223 device_responder(CONTROLVM_DEVICE_CREATE, busNo, devNo, response);
2224}
2225
2226static void
2227device_destroy_response(ulong busNo, ulong devNo, int response)
2228{
2229 device_responder(CONTROLVM_DEVICE_DESTROY, busNo, devNo, response);
2230}
2231
2232void
927c7927 2233visorchipset_device_pause_response(ulong busNo, ulong devNo, int response)
12e364b9
KC
2234{
2235
2236 device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE,
2237 busNo, devNo, response,
2238 SegmentStateStandby);
2239}
927c7927 2240EXPORT_SYMBOL_GPL(visorchipset_device_pause_response);
12e364b9
KC
2241
2242static void
2243device_resume_response(ulong busNo, ulong devNo, int response)
2244{
2245 device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE,
2246 busNo, devNo, response,
2247 SegmentStateRunning);
2248}
2249
2250BOOL
2251visorchipset_get_bus_info(ulong busNo, VISORCHIPSET_BUS_INFO *busInfo)
2252{
2253 void *p = findbus(&BusInfoList, busNo);
2254 if (!p) {
2255 LOGERR("(%lu) failed", busNo);
2256 return FALSE;
2257 }
2258 memcpy(busInfo, p, sizeof(VISORCHIPSET_BUS_INFO));
2259 return TRUE;
2260}
2261EXPORT_SYMBOL_GPL(visorchipset_get_bus_info);
2262
2263BOOL
2264visorchipset_set_bus_context(ulong busNo, void *context)
2265{
2266 VISORCHIPSET_BUS_INFO *p = findbus(&BusInfoList, busNo);
2267 if (!p) {
2268 LOGERR("(%lu) failed", busNo);
2269 return FALSE;
2270 }
2271 p->bus_driver_context = context;
2272 return TRUE;
2273}
2274EXPORT_SYMBOL_GPL(visorchipset_set_bus_context);
2275
2276BOOL
2277visorchipset_get_device_info(ulong busNo, ulong devNo,
2278 VISORCHIPSET_DEVICE_INFO *devInfo)
2279{
2280 void *p = finddevice(&DevInfoList, busNo, devNo);
2281 if (!p) {
2282 LOGERR("(%lu,%lu) failed", busNo, devNo);
2283 return FALSE;
2284 }
2285 memcpy(devInfo, p, sizeof(VISORCHIPSET_DEVICE_INFO));
2286 return TRUE;
2287}
2288EXPORT_SYMBOL_GPL(visorchipset_get_device_info);
2289
2290BOOL
2291visorchipset_set_device_context(ulong busNo, ulong devNo, void *context)
2292{
2293 VISORCHIPSET_DEVICE_INFO *p = finddevice(&DevInfoList, busNo, devNo);
2294 if (!p) {
2295 LOGERR("(%lu,%lu) failed", busNo, devNo);
2296 return FALSE;
2297 }
2298 p->bus_driver_context = context;
2299 return TRUE;
2300}
2301EXPORT_SYMBOL_GPL(visorchipset_set_device_context);
2302
2303/* Generic wrapper function for allocating memory from a kmem_cache pool.
2304 */
2305void *
2306visorchipset_cache_alloc(struct kmem_cache *pool, BOOL ok_to_block,
2307 char *fn, int ln)
2308{
2309 gfp_t gfp;
2310 void *p;
2311
2312 if (ok_to_block)
2313 gfp = GFP_KERNEL;
2314 else
2315 gfp = GFP_ATOMIC;
2316 /* __GFP_NORETRY means "ok to fail", meaning
2317 * kmem_cache_alloc() can return NULL, implying the caller CAN
2318 * cope with failure. If you do NOT specify __GFP_NORETRY,
2319 * Linux will go to extreme measures to get memory for you
2320 * (like, invoke oom killer), which will probably cripple the
2321 * system.
2322 */
2323 gfp |= __GFP_NORETRY;
2324 p = kmem_cache_alloc(pool, gfp);
2325 if (!p) {
2326 LOGERR("kmem_cache_alloc failed early @%s:%d\n", fn, ln);
2327 return NULL;
2328 }
2329 atomic_inc(&Visorchipset_cache_buffers_in_use);
2330 return p;
2331}
2332
2333/* Generic wrapper function for freeing memory from a kmem_cache pool.
2334 */
2335void
2336visorchipset_cache_free(struct kmem_cache *pool, void *p, char *fn, int ln)
2337{
2338 if (!p) {
2339 LOGERR("NULL pointer @%s:%d\n", fn, ln);
2340 return;
2341 }
2342 atomic_dec(&Visorchipset_cache_buffers_in_use);
2343 kmem_cache_free(pool, p);
2344}
2345
2346#define gettoken(bufp) strsep(bufp, " -\t\n")
2347
2348static ssize_t
2349chipset_proc_write(struct file *file, const char __user *buffer,
2350 size_t count, loff_t *ppos)
2351{
2352 char buf[512];
2353 char *token, *p;
2354
2355 if (count > sizeof(buf) - 1) {
2356 LOGERR("chipset_proc_write: count (%d) exceeds size of buffer (%d)",
2357 (int) count, (int) sizeof(buffer));
2358 return -EINVAL;
2359 }
2360 if (copy_from_user(buf, buffer, count)) {
2361 LOGERR("chipset_proc_write: copy_from_user failed");
2362 return -EFAULT;
2363 }
2364 buf[count] = '\0';
2365
2366 p = buf;
2367 token = gettoken(&p);
2368
2369 if (strcmp(token, "CALLHOMEDISK_MOUNTED") == 0) {
2370 token = gettoken(&p);
2371 /* The Call Home Disk has been mounted */
2372 if (strcmp(token, "0") == 0)
2373 chipset_events[0] = 1;
2374 } else if (strcmp(token, "MODULES_LOADED") == 0) {
2375 token = gettoken(&p);
2376 /* All modules for the partition have been loaded */
2377 if (strcmp(token, "0") == 0)
2378 chipset_events[1] = 1;
2379 } else if (token == NULL) {
2380 /* No event specified */
2381 LOGERR("No event was specified to send CHIPSET_READY response");
2382 return -1;
2383 } else {
2384 /* Unsupported event specified */
2385 LOGERR("%s is an invalid event for sending CHIPSET_READY response", token);
2386 return -1;
2387 }
2388
2389 return count;
2390}
2391
2392static ssize_t
2393visorchipset_proc_read_writeonly(struct file *file, char __user *buf,
2394 size_t len, loff_t *offset)
2395{
2396 return 0;
2397}
2398
2399/**
2400 * Reads the InstallationError, InstallationTextId,
2401 * InstallationRemainingSteps fields of ControlVMChannel.
2402 */
2403static ssize_t
2404proc_read_installer(struct file *file, char __user *buf,
2405 size_t len, loff_t *offset)
2406{
2407 int length = 0;
2408 U16 remainingSteps;
2409 U32 error, textId;
2410 char *vbuf;
2411 loff_t pos = *offset;
2412
b0e27960
SL
2413 if (!ControlVm_channel)
2414 return -ENODEV;
2415
12e364b9
KC
2416 if (pos < 0)
2417 return -EINVAL;
2418
2419 if (pos > 0 || !len)
2420 return 0;
2421
2422 vbuf = kzalloc(len, GFP_KERNEL);
2423 if (!vbuf)
2424 return -ENOMEM;
2425
2426 visorchannel_read(ControlVm_channel,
2427 offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
2428 InstallationRemainingSteps), &remainingSteps,
2429 sizeof(U16));
2430 visorchannel_read(ControlVm_channel,
2431 offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
2432 InstallationError), &error, sizeof(U32));
2433 visorchannel_read(ControlVm_channel,
2434 offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
2435 InstallationTextId), &textId, sizeof(U32));
2436
2437 length = sprintf(vbuf, "%u %u %u\n", remainingSteps, error, textId);
2438 if (copy_to_user(buf, vbuf, length)) {
2439 kfree(vbuf);
2440 return -EFAULT;
2441 }
2442
2443 kfree(vbuf);
2444 *offset += length;
2445 return length;
2446}
2447
2448/**
2449 * Writes to the InstallationError, InstallationTextId,
2450 * InstallationRemainingSteps fields of
2451 * ControlVMChannel.
2452 * Input: RemainingSteps Error TextId
2453 * Limit 32 characters input
2454 */
2455#define UINT16_MAX (65535U)
2456#define UINT32_MAX (4294967295U)
2457static ssize_t
2458proc_write_installer(struct file *file,
2459 const char __user *buffer, size_t count, loff_t *ppos)
2460{
2461 char buf[32];
2462 U16 remainingSteps;
2463 U32 error, textId;
2464
b0e27960
SL
2465 if (!ControlVm_channel)
2466 return -ENODEV;
2467
12e364b9
KC
2468 /* Check to make sure there is no buffer overflow */
2469 if (count > (sizeof(buf) - 1))
2470 return -EINVAL;
2471
2472 if (copy_from_user(buf, buffer, count)) {
2473 WARN(1, "Error copying from user space\n");
2474 return -EFAULT;
2475 }
2476
2477 if (sscanf(buf, "%hu %i %i", &remainingSteps, &error, &textId) != 3) {
2478 remainingSteps = UINT16_MAX;
2479 error = UINT32_MAX;
2480 textId = UINT32_MAX;
2481 }
2482
2483 if (remainingSteps != UINT16_MAX) {
2484 if (visorchannel_write
2485 (ControlVm_channel,
2486 offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
2487 InstallationRemainingSteps), &remainingSteps,
2488 sizeof(U16)) < 0)
2489 WARN(1, "Installation Status Write Failed - Write function error - RemainingSteps = %d\n",
2490 remainingSteps);
2491 }
2492
2493 if (error != UINT32_MAX) {
2494 if (visorchannel_write
2495 (ControlVm_channel,
2496 offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
2497 InstallationError), &error, sizeof(U32)) < 0)
2498 WARN(1, "Installation Status Write Failed - Write function error - Error = %d\n",
2499 error);
2500 }
2501
2502 if (textId != UINT32_MAX) {
2503 if (visorchannel_write
2504 (ControlVm_channel,
2505 offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
2506 InstallationTextId), &textId, sizeof(U32)) < 0)
2507 WARN(1, "Installation Status Write Failed - Write function error - TextId = %d\n",
2508 textId);
2509 }
2510
2511 /* So this function isn't called multiple times, must return
2512 * size of buffer
2513 */
2514 return count;
2515}
2516
2517/**
2518 * Reads the ToolAction field of ControlVMChannel.
2519 */
2520static ssize_t
2521proc_read_toolaction(struct file *file, char __user *buf,
2522 size_t len, loff_t *offset)
2523{
2524 int length = 0;
2525 U8 toolAction;
2526 char *vbuf;
2527 loff_t pos = *offset;
2528
b0e27960
SL
2529 if (!ControlVm_channel)
2530 return -ENODEV;
2531
12e364b9
KC
2532 if (pos < 0)
2533 return -EINVAL;
2534
2535 if (pos > 0 || !len)
2536 return 0;
2537
2538 vbuf = kzalloc(len, GFP_KERNEL);
2539 if (!vbuf)
2540 return -ENOMEM;
2541
2542 visorchannel_read(ControlVm_channel,
2543 offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
2544 ToolAction), &toolAction, sizeof(U8));
2545
2546 length = sprintf(vbuf, "%u\n", toolAction);
2547 if (copy_to_user(buf, vbuf, length)) {
2548 kfree(vbuf);
2549 return -EFAULT;
2550 }
2551
2552 kfree(vbuf);
2553 *offset += length;
2554 return length;
2555}
2556
2557/**
2558 * Writes to the ToolAction field of ControlVMChannel.
2559 * Input: ToolAction
2560 * Limit 3 characters input
2561 */
2562#define UINT8_MAX (255U)
2563static ssize_t
2564proc_write_toolaction(struct file *file,
2565 const char __user *buffer, size_t count, loff_t *ppos)
2566{
2567 char buf[3];
2568 U8 toolAction;
2569
b0e27960
SL
2570 if (!ControlVm_channel)
2571 return -ENODEV;
2572
12e364b9
KC
2573 /* Check to make sure there is no buffer overflow */
2574 if (count > (sizeof(buf) - 1))
2575 return -EINVAL;
2576
2577 if (copy_from_user(buf, buffer, count)) {
2578 WARN(1, "Error copying from user space\n");
2579 return -EFAULT;
2580 }
2581
2582 if (sscanf(buf, "%hhd", &toolAction) != 1)
2583 toolAction = UINT8_MAX;
2584
2585 if (toolAction != UINT8_MAX) {
2586 if (visorchannel_write
2587 (ControlVm_channel,
2588 offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, ToolAction),
2589 &toolAction, sizeof(U8)) < 0)
2590 WARN(1, "Installation ToolAction Write Failed - ToolAction = %d\n",
2591 toolAction);
2592 }
2593
2594 /* So this function isn't called multiple times, must return
2595 * size of buffer
2596 */
2597 return count;
2598}
2599
2600/**
2601 * Reads the EfiSparIndication.BootToTool field of ControlVMChannel.
2602 */
2603static ssize_t
2604proc_read_bootToTool(struct file *file, char __user *buf,
2605 size_t len, loff_t *offset)
2606{
2607 int length = 0;
2608 ULTRA_EFI_SPAR_INDICATION efiSparIndication;
2609 char *vbuf;
2610 loff_t pos = *offset;
2611
b0e27960
SL
2612 if (!ControlVm_channel)
2613 return -ENODEV;
2614
12e364b9
KC
2615 if (pos < 0)
2616 return -EINVAL;
2617
2618 if (pos > 0 || !len)
2619 return 0;
2620
2621 vbuf = kzalloc(len, GFP_KERNEL);
2622 if (!vbuf)
2623 return -ENOMEM;
2624
2625 visorchannel_read(ControlVm_channel,
2626 offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
2627 EfiSparIndication), &efiSparIndication,
2628 sizeof(ULTRA_EFI_SPAR_INDICATION));
2629
2630 length = sprintf(vbuf, "%d\n", (int) efiSparIndication.BootToTool);
2631 if (copy_to_user(buf, vbuf, length)) {
2632 kfree(vbuf);
2633 return -EFAULT;
2634 }
2635
2636 kfree(vbuf);
2637 *offset += length;
2638 return length;
2639}
2640
2641/**
2642 * Writes to the EfiSparIndication.BootToTool field of ControlVMChannel.
2643 * Input: 1 or 0 (1 being on, 0 being off)
2644 */
2645static ssize_t
2646proc_write_bootToTool(struct file *file,
2647 const char __user *buffer, size_t count, loff_t *ppos)
2648{
2649 char buf[3];
2650 int inputVal;
2651 ULTRA_EFI_SPAR_INDICATION efiSparIndication;
2652
b0e27960
SL
2653 if (!ControlVm_channel)
2654 return -ENODEV;
2655
12e364b9
KC
2656 /* Check to make sure there is no buffer overflow */
2657 if (count > (sizeof(buf) - 1))
2658 return -EINVAL;
2659
2660 if (copy_from_user(buf, buffer, count)) {
2661 WARN(1, "Error copying from user space\n");
2662 return -EFAULT;
2663 }
2664
2665 if (sscanf(buf, "%i", &inputVal) != 1)
2666 inputVal = 0;
2667
2668 efiSparIndication.BootToTool = (inputVal == 1 ? 1 : 0);
2669
2670 if (visorchannel_write
2671 (ControlVm_channel,
2672 offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, EfiSparIndication),
2673 &efiSparIndication, sizeof(ULTRA_EFI_SPAR_INDICATION)) < 0)
2674 printk
2675 ("Installation BootToTool Write Failed - BootToTool = %d\n",
2676 (int) efiSparIndication.BootToTool);
2677
2678 /* So this function isn't called multiple times, must return
2679 * size of buffer
2680 */
2681 return count;
2682}
2683
2684static const struct file_operations chipset_proc_fops = {
2685 .owner = THIS_MODULE,
2686 .read = visorchipset_proc_read_writeonly,
2687 .write = chipset_proc_write,
2688};
2689
2690static int __init
2691visorchipset_init(void)
2692{
2693 int rc = 0, x = 0;
2694 struct proc_dir_entry *installer_file;
2695 struct proc_dir_entry *toolaction_file;
2696 struct proc_dir_entry *bootToTool_file;
2697
fcd0157e
KC
2698 if (!unisys_spar_platform)
2699 return -ENODEV;
2700
12e364b9
KC
2701 LOGINF("chipset driver version %s loaded", VERSION);
2702 /* process module options */
2703 POSTCODE_LINUX_2(DRIVER_ENTRY_PC, POSTCODE_SEVERITY_INFO);
2704
2705 LOGINF("option - testvnic=%d", visorchipset_testvnic);
2706 LOGINF("option - testvnicclient=%d", visorchipset_testvnicclient);
2707 LOGINF("option - testmsg=%d", visorchipset_testmsg);
2708 LOGINF("option - testteardown=%d", visorchipset_testteardown);
2709 LOGINF("option - major=%d", visorchipset_major);
2710 LOGINF("option - serverregwait=%d", visorchipset_serverregwait);
2711 LOGINF("option - clientregwait=%d", visorchipset_clientregwait);
2712 LOGINF("option - holdchipsetready=%d", visorchipset_holdchipsetready);
2713
2714 memset(&BusDev_Server_Notifiers, 0, sizeof(BusDev_Server_Notifiers));
2715 memset(&BusDev_Client_Notifiers, 0, sizeof(BusDev_Client_Notifiers));
2716 memset(&ControlVm_payload_info, 0, sizeof(ControlVm_payload_info));
2717 memset(&LiveDump_info, 0, sizeof(LiveDump_info));
2718 atomic_set(&LiveDump_info.buffers_in_use, 0);
2719
9f8d0e8b
KC
2720 if (visorchipset_testvnic) {
2721 ERRDRV("testvnic option no longer supported: (status = %d)\n",
2722 x);
2723 POSTCODE_LINUX_3(CHIPSET_INIT_FAILURE_PC, x, DIAG_SEVERITY_ERR);
2724 rc = x;
2725 goto Away;
2726 }
12e364b9
KC
2727
2728 controlvm_init();
2729 MajorDev = MKDEV(visorchipset_major, 0);
9f8d0e8b 2730 rc = visorchipset_file_init(MajorDev, &ControlVm_channel);
4cb005a9
KC
2731 if (rc < 0) {
2732 ERRDRV("visorchipset_file_init(MajorDev, &ControlVm_channel): error (status=%d)\n", rc);
2733 POSTCODE_LINUX_2(CHIPSET_INIT_FAILURE_PC, DIAG_SEVERITY_ERR);
2734 goto Away;
2735 }
9f8d0e8b 2736
12e364b9
KC
2737 proc_Init();
2738 memset(PartitionPropertyNames, 0, sizeof(PartitionPropertyNames));
2739 memset(ControlVmPropertyNames, 0, sizeof(ControlVmPropertyNames));
2740 InitPartitionProperties();
2741 InitControlVmProperties();
2742
927c7927
KC
2743 PartitionType = visor_proc_CreateType(ProcDir, PartitionTypeNames,
2744 (const char **)
2745 PartitionPropertyNames,
2746 &show_partition_property);
12e364b9 2747 ControlVmType =
927c7927
KC
2748 visor_proc_CreateType(ProcDir, ControlVmTypeNames,
2749 (const char **) ControlVmPropertyNames,
2750 &show_controlvm_property);
12e364b9 2751
927c7927 2752 ControlVmObject = visor_proc_CreateObject(ControlVmType, NULL, NULL);
12e364b9
KC
2753
2754 /* Setup Installation fields */
2755 installer_file = proc_create("installer", 0644, ProcDir,
2756 &proc_installer_fops);
2757 /* Setup the ToolAction field */
2758 toolaction_file = proc_create("toolaction", 0644, ProcDir,
2759 &proc_toolaction_fops);
2760 /* Setup the BootToTool field */
2761 bootToTool_file = proc_create("boottotool", 0644, ProcDir,
2762 &proc_bootToTool_fops);
2763
2764 memset(&g_DiagMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
2765
2766 chipset_proc_dir = proc_create(VISORCHIPSET_CHIPSET_PROC_ENTRY_FN,
2767 0644, ProcDir, &chipset_proc_fops);
2768 memset(&g_ChipSetMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
2769
2770 parahotplug_proc_dir =
2771 proc_create(VISORCHIPSET_PARAHOTPLUG_PROC_ENTRY_FN, 0200,
2772 ProcDir, &parahotplug_proc_fops);
2773 memset(&g_DelDumpMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
2774
12e364b9
KC
2775 Putfile_buffer_list_pool =
2776 kmem_cache_create(Putfile_buffer_list_pool_name,
2777 sizeof(struct putfile_buffer_entry),
2778 0, SLAB_HWCACHE_ALIGN, NULL);
2779 if (!Putfile_buffer_list_pool) {
4cb005a9
KC
2780 ERRDRV("failed to alloc Putfile_buffer_list_pool: (status=-1)\n");
2781 POSTCODE_LINUX_2(CHIPSET_INIT_FAILURE_PC, DIAG_SEVERITY_ERR);
2782 rc = -1;
2783 goto Away;
12e364b9
KC
2784 }
2785 if (visorchipset_disable_controlvm) {
2786 LOGINF("visorchipset_init:controlvm disabled");
2787 } else {
2788 /* if booting in a crash kernel */
2789 if (visorchipset_crash_kernel)
2790 INIT_DELAYED_WORK(&Periodic_controlvm_work,
2791 setup_crash_devices_work_queue);
2792 else
2793 INIT_DELAYED_WORK(&Periodic_controlvm_work,
2794 controlvm_periodic_work);
2795 Periodic_controlvm_workqueue =
2796 create_singlethread_workqueue("visorchipset_controlvm");
2797
4cb005a9
KC
2798 if (Periodic_controlvm_workqueue == NULL) {
2799 ERRDRV("cannot create controlvm workqueue: (status=%d)\n",
2800 -ENOMEM);
2801 POSTCODE_LINUX_2(CREATE_WORKQUEUE_FAILED_PC,
2802 DIAG_SEVERITY_ERR);
2803 rc = -ENOMEM;
2804 goto Away;
2805 }
12e364b9
KC
2806 Most_recent_message_jiffies = jiffies;
2807 Poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_FAST;
9f8d0e8b
KC
2808 rc = queue_delayed_work(Periodic_controlvm_workqueue,
2809 &Periodic_controlvm_work, Poll_jiffies);
4cb005a9
KC
2810 if (rc < 0) {
2811 ERRDRV("queue_delayed_work(Periodic_controlvm_workqueue, &Periodic_controlvm_work, Poll_jiffies): error (status=%d)\n", rc);
2812 POSTCODE_LINUX_2(QUEUE_DELAYED_WORK_PC,
2813 DIAG_SEVERITY_ERR);
2814 goto Away;
2815 }
9f8d0e8b 2816
12e364b9
KC
2817 }
2818
2819 Visorchipset_platform_device.dev.devt = MajorDev;
4cb005a9
KC
2820 if (platform_device_register(&Visorchipset_platform_device) < 0) {
2821 ERRDRV("platform_device_register(visorchipset) failed: (status=-1)\n");
2822 POSTCODE_LINUX_2(DEVICE_REGISTER_FAILURE_PC, DIAG_SEVERITY_ERR);
2823 rc = -1;
2824 goto Away;
2825 }
12e364b9
KC
2826 LOGINF("visorchipset device created");
2827 POSTCODE_LINUX_2(CHIPSET_INIT_SUCCESS_PC, POSTCODE_SEVERITY_INFO);
22ad57ba 2828 rc = 0;
12e364b9 2829Away:
12e364b9
KC
2830 if (rc) {
2831 LOGERR("visorchipset_init failed");
2832 POSTCODE_LINUX_3(CHIPSET_INIT_FAILURE_PC, rc,
2833 POSTCODE_SEVERITY_ERR);
2834 }
2835 return rc;
2836}
2837
2838static void
2839visorchipset_exit(void)
2840{
2841 char s[99];
2842 POSTCODE_LINUX_2(DRIVER_EXIT_PC, POSTCODE_SEVERITY_INFO);
2843
2844 if (visorchipset_disable_controlvm) {
2845 ;
2846 } else {
2847 cancel_delayed_work(&Periodic_controlvm_work);
2848 flush_workqueue(Periodic_controlvm_workqueue);
2849 destroy_workqueue(Periodic_controlvm_workqueue);
2850 Periodic_controlvm_workqueue = NULL;
2851 destroy_controlvm_payload_info(&ControlVm_payload_info);
2852 }
2853 Test_Vnic_channel = NULL;
2854 if (Putfile_buffer_list_pool) {
2855 kmem_cache_destroy(Putfile_buffer_list_pool);
2856 Putfile_buffer_list_pool = NULL;
2857 }
12e364b9 2858 if (ControlVmObject) {
927c7927 2859 visor_proc_DestroyObject(ControlVmObject);
12e364b9
KC
2860 ControlVmObject = NULL;
2861 }
2862 cleanup_controlvm_structures();
2863
2864 if (ControlVmType) {
927c7927 2865 visor_proc_DestroyType(ControlVmType);
12e364b9
KC
2866 ControlVmType = NULL;
2867 }
2868 if (PartitionType) {
927c7927 2869 visor_proc_DestroyType(PartitionType);
12e364b9
KC
2870 PartitionType = NULL;
2871 }
2872 if (diag_proc_dir) {
2873 remove_proc_entry(VISORCHIPSET_DIAG_PROC_ENTRY_FN, ProcDir);
2874 diag_proc_dir = NULL;
2875 }
2876 memset(&g_DiagMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
2877
2878 if (chipset_proc_dir) {
2879 remove_proc_entry(VISORCHIPSET_CHIPSET_PROC_ENTRY_FN, ProcDir);
2880 chipset_proc_dir = NULL;
2881 }
2882 memset(&g_ChipSetMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
2883
2884 if (parahotplug_proc_dir) {
2885 remove_proc_entry(VISORCHIPSET_PARAHOTPLUG_PROC_ENTRY_FN,
2886 ProcDir);
2887 parahotplug_proc_dir = NULL;
2888 }
2889
2890 memset(&g_DelDumpMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
2891
2892 proc_DeInit();
2893 if (ControlVm_channel != NULL) {
2894 LOGINF("Channel %s (ControlVm) disconnected",
2895 visorchannel_id(ControlVm_channel, s));
2896 visorchannel_destroy(ControlVm_channel);
2897 ControlVm_channel = NULL;
2898 }
2899 controlvm_deinit();
2900 visorchipset_file_cleanup();
2901 POSTCODE_LINUX_2(DRIVER_EXIT_PC, POSTCODE_SEVERITY_INFO);
2902 LOGINF("chipset driver unloaded");
2903}
2904
2905module_param_named(testvnic, visorchipset_testvnic, int, S_IRUGO);
2906MODULE_PARM_DESC(visorchipset_testvnic, "1 to test vnic, using dummy VNIC connected via a loopback to a physical ethernet");
2907int visorchipset_testvnic = 0;
2908
2909module_param_named(testvnicclient, visorchipset_testvnicclient, int, S_IRUGO);
2910MODULE_PARM_DESC(visorchipset_testvnicclient, "1 to test vnic, using real VNIC channel attached to a separate IOVM guest");
2911int visorchipset_testvnicclient = 0;
2912
2913module_param_named(testmsg, visorchipset_testmsg, int, S_IRUGO);
2914MODULE_PARM_DESC(visorchipset_testmsg,
2915 "1 to manufacture the chipset, bus, and switch messages");
2916int visorchipset_testmsg = 0;
2917
2918module_param_named(major, visorchipset_major, int, S_IRUGO);
2919MODULE_PARM_DESC(visorchipset_major, "major device number to use for the device node");
2920int visorchipset_major = 0;
2921
2922module_param_named(serverregwait, visorchipset_serverregwait, int, S_IRUGO);
2923MODULE_PARM_DESC(visorchipset_serverreqwait,
2924 "1 to have the module wait for the visor bus to register");
2925int visorchipset_serverregwait = 0; /* default is off */
2926module_param_named(clientregwait, visorchipset_clientregwait, int, S_IRUGO);
2927MODULE_PARM_DESC(visorchipset_clientregwait, "1 to have the module wait for the visorclientbus to register");
2928int visorchipset_clientregwait = 1; /* default is on */
2929module_param_named(testteardown, visorchipset_testteardown, int, S_IRUGO);
2930MODULE_PARM_DESC(visorchipset_testteardown,
2931 "1 to test teardown of the chipset, bus, and switch");
2932int visorchipset_testteardown = 0; /* default is off */
2933module_param_named(disable_controlvm, visorchipset_disable_controlvm, int,
2934 S_IRUGO);
2935MODULE_PARM_DESC(visorchipset_disable_controlvm,
2936 "1 to disable polling of controlVm channel");
2937int visorchipset_disable_controlvm = 0; /* default is off */
2938module_param_named(crash_kernel, visorchipset_crash_kernel, int, S_IRUGO);
2939MODULE_PARM_DESC(visorchipset_crash_kernel,
2940 "1 means we are running in crash kernel");
2941int visorchipset_crash_kernel = 0; /* default is running in non-crash kernel */
2942module_param_named(holdchipsetready, visorchipset_holdchipsetready,
2943 int, S_IRUGO);
2944MODULE_PARM_DESC(visorchipset_holdchipsetready,
2945 "1 to hold response to CHIPSET_READY");
2946int visorchipset_holdchipsetready = 0; /* default is to send CHIPSET_READY
2947 * response immediately */
2948module_init(visorchipset_init);
2949module_exit(visorchipset_exit);
2950
2951MODULE_AUTHOR("Unisys");
2952MODULE_LICENSE("GPL");
2953MODULE_DESCRIPTION("Supervisor chipset driver for service partition: ver "
2954 VERSION);
2955MODULE_VERSION(VERSION);