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