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