diff options
Diffstat (limited to 'drivers/staging/unisys')
-rw-r--r-- | drivers/staging/unisys/Documentation/overview.txt | 14 | ||||
-rw-r--r-- | drivers/staging/unisys/include/channel.h | 361 | ||||
-rw-r--r-- | drivers/staging/unisys/include/iochannel.h | 554 | ||||
-rw-r--r-- | drivers/staging/unisys/include/visorbus.h | 44 | ||||
-rw-r--r-- | drivers/staging/unisys/visorbus/controlvmchannel.h | 715 | ||||
-rw-r--r-- | drivers/staging/unisys/visorbus/vbuschannel.h | 96 | ||||
-rw-r--r-- | drivers/staging/unisys/visorbus/visorbus_main.c | 469 | ||||
-rw-r--r-- | drivers/staging/unisys/visorbus/visorbus_private.h | 38 | ||||
-rw-r--r-- | drivers/staging/unisys/visorbus/visorchannel.c | 219 | ||||
-rw-r--r-- | drivers/staging/unisys/visorbus/visorchipset.c | 607 | ||||
-rw-r--r-- | drivers/staging/unisys/visorbus/vmcallinterface.h | 54 | ||||
-rw-r--r-- | drivers/staging/unisys/visorhba/visorhba_main.c | 438 | ||||
-rw-r--r-- | drivers/staging/unisys/visorinput/ultrainputreport.h | 68 | ||||
-rw-r--r-- | drivers/staging/unisys/visorinput/visorinput.c | 138 | ||||
-rw-r--r-- | drivers/staging/unisys/visornic/visornic_main.c | 736 |
15 files changed, 2201 insertions, 2350 deletions
diff --git a/drivers/staging/unisys/Documentation/overview.txt b/drivers/staging/unisys/Documentation/overview.txt index e0466bfada2f..9ab30af265a5 100644 --- a/drivers/staging/unisys/Documentation/overview.txt +++ b/drivers/staging/unisys/Documentation/overview.txt @@ -221,7 +221,7 @@ The following files exist under /sys/devices/visorbus<x>/vbus<x>:dev<y>: The visorhba driver registers with visorbus as the function driver to handle virtual scsi disk devices, specified using the -VISOR_VHBA_CHANNEL_UUID type in the visorbus_register_visor_driver() +VISOR_VHBA_CHANNEL_GUID type in the visorbus_register_visor_driver() call. visorhba uses scsi_add_host() to expose a Linux block device (e.g., /sys/block/) in the guest environment for each s-Par virtual device. @@ -240,7 +240,7 @@ When compiled as a module, visorhba can be autoloaded by visorbus in standard udev/systemd environments, as it includes the modules.alias definition: - "visorbus:"+VISOR_VHBA_CHANNEL_UUID_STR + "visorbus:"+VISOR_VHBA_CHANNEL_GUID_STR i.e.: @@ -252,7 +252,7 @@ i.e.: The visornic driver registers with visorbus as the function driver to handle virtual network devices, specified using the -VISOR_VNIC_CHANNEL_UUID type in the visorbus_register_visor_driver() +VISOR_VNIC_CHANNEL_GUID type in the visorbus_register_visor_driver() call. visornic uses register_netdev() to expose a Linux device of class net (e.g., /sys/class/net/) in the guest environment for each s-Par virtual device. @@ -270,7 +270,7 @@ When compiled as a module, visornic can be autoloaded by visorbus in standard udev/systemd environments, as it includes the modules.alias definition: - "visorbus:"+VISOR_VNIC_CHANNEL_UUID_STR + "visorbus:"+VISOR_VNIC_CHANNEL_GUID_STR i.e.: @@ -282,7 +282,7 @@ i.e.: The visorinput driver registers with visorbus as the function driver to handle human input devices, specified using the -VISOR_KEYBOARD_CHANNEL_UUID and VISOR_MOUSE_CHANNEL_UUID +VISOR_KEYBOARD_CHANNEL_GUID and VISOR_MOUSE_CHANNEL_GUID types in the visorbus_register_visor_driver() call. visorinput uses input_register_device() to expose devices of class input (e.g., /sys/class/input/) for virtual keyboard and virtual mouse devices. @@ -307,8 +307,8 @@ When compiled as a module, visorinput can be autoloaded by visorbus in standard udev/systemd environments, as it includes the modules.alias definition: - "visorbus:"+VISOR_MOUSE_CHANNEL_UUID_STR - "visorbus:"+VISOR_KEYBOARD_CHANNEL_UUID_STR + "visorbus:"+VISOR_MOUSE_CHANNEL_GUID_STR + "visorbus:"+VISOR_KEYBOARD_CHANNEL_GUID_STR i.e.: diff --git a/drivers/staging/unisys/include/channel.h b/drivers/staging/unisys/include/channel.h index 692efcb38245..2babe93631f3 100644 --- a/drivers/staging/unisys/include/channel.h +++ b/drivers/staging/unisys/include/channel.h @@ -1,4 +1,5 @@ -/* Copyright (C) 2010 - 2013 UNISYS CORPORATION +/* + * Copyright (C) 2010 - 2013 UNISYS CORPORATION * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -20,87 +21,48 @@ #include <linux/io.h> #include <linux/uuid.h> -#define __SUPERVISOR_CHANNEL_H__ - #define SIGNATURE_16(A, B) ((A) | ((B) << 8)) #define SIGNATURE_32(A, B, C, D) \ (SIGNATURE_16(A, B) | (SIGNATURE_16(C, D) << 16)) -#define SIGNATURE_64(A, B, C, D, E, F, G, H) \ - (SIGNATURE_32(A, B, C, D) | ((u64)(SIGNATURE_32(E, F, G, H)) << 32)) - -#ifndef COVER -#define COVER(v, d) ((d) * DIV_ROUND_UP(v, d)) -#endif - #define VISOR_CHANNEL_SIGNATURE SIGNATURE_32('E', 'C', 'N', 'L') +/* + * enum channel_serverstate + * @CHANNELSRV_UNINITIALIZED: Channel is in an undefined state. + * @CHANNELSRV_READY: Channel has been initialized by server. + */ enum channel_serverstate { - CHANNELSRV_UNINITIALIZED = 0, /* channel is in an undefined state */ - CHANNELSRV_READY = 1 /* channel has been initialized by server */ + CHANNELSRV_UNINITIALIZED = 0, + CHANNELSRV_READY = 1 }; +/* + * enum channel_clientstate + * @CHANNELCLI_DETACHED: + * @CHANNELCLI_DISABLED: Client can see channel but is NOT allowed to use it + * unless given TBD* explicit request + * (should actually be < DETACHED). + * @CHANNELCLI_ATTACHING: Legacy EFI client request for EFI server to attach. + * @CHANNELCLI_ATTACHED: Idle, but client may want to use channel any time. + * @CHANNELCLI_BUSY: Client either wants to use or is using channel. + * @CHANNELCLI_OWNED: "No worries" state - client can access channel + * anytime. + */ enum channel_clientstate { CHANNELCLI_DETACHED = 0, - CHANNELCLI_DISABLED = 1, /* client can see channel but is NOT - * allowed to use it unless given TBD - * explicit request (should actually be - * < DETACHED) - */ - CHANNELCLI_ATTACHING = 2, /* legacy EFI client request - * for EFI server to attach - */ - CHANNELCLI_ATTACHED = 3, /* idle, but client may want - * to use channel any time - */ - CHANNELCLI_BUSY = 4, /* client either wants to use or is - * using channel - */ - CHANNELCLI_OWNED = 5 /* "no worries" state - client can */ - /* access channel anytime */ + CHANNELCLI_DISABLED = 1, + CHANNELCLI_ATTACHING = 2, + CHANNELCLI_ATTACHED = 3, + CHANNELCLI_BUSY = 4, + CHANNELCLI_OWNED = 5 }; -#define VISOR_CHANNEL_SERVER_READY(ch) \ - (readl(&(ch)->srv_state) == CHANNELSRV_READY) - -#define VISOR_VALID_CHANNELCLI_TRANSITION(o, n) \ - (((((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_DISABLED)) || \ - (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_DISABLED)) || \ - (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_DISABLED)) || \ - (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_DETACHED)) || \ - (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_DETACHED)) || \ - (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_ATTACHING)) || \ - (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_ATTACHED)) || \ - (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_ATTACHED)) || \ - (((o) == CHANNELCLI_BUSY) && ((n) == CHANNELCLI_ATTACHED)) || \ - (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_BUSY)) || \ - (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_OWNED)) || \ - (((o) == CHANNELCLI_DISABLED) && ((n) == CHANNELCLI_OWNED)) || \ - (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_OWNED)) || \ - (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_OWNED)) || \ - (((o) == CHANNELCLI_BUSY) && ((n) == CHANNELCLI_OWNED)) || (0)) \ - ? (1) : (0)) - -/* Values for VISORA_CHANNEL_PROTOCOL.CliErrorBoot: */ -/* throttling invalid boot channel statetransition error due to client - * disabled - */ -#define VISOR_CLIERRORBOOT_THROTTLEMSG_DISABLED 0x01 - -/* throttling invalid boot channel statetransition error due to client - * not attached - */ -#define VISOR_CLIERRORBOOT_THROTTLEMSG_NOTATTACHED 0x02 - -/* throttling invalid boot channel statetransition error due to busy channel */ -#define VISOR_CLIERRORBOOT_THROTTLEMSG_BUSY 0x04 - -/* Values for VISOR_CHANNEL_PROTOCOL.Features: This define exists so - * that windows guest can look at the FeatureFlags in the io channel, - * and configure the windows driver to use interrupts or not based on - * this setting. This flag is set in uislib after the - * VISOR_VHBA_init_channel is called. All feature bits for all - * channels should be defined here. The io channel feature bits are - * defined right here +/* + * Values for VISOR_CHANNEL_PROTOCOL.Features: This define exists so that + * a guest can look at the FeatureFlags in the io channel, and configure the + * driver to use interrupts or not based on this setting. All feature bits for + * all channels should be defined here. The io channel feature bits are defined + * below. */ #define VISOR_DRIVER_ENABLES_INTS (0x1ULL << 1) #define VISOR_CHANNEL_IS_POLLING (0x1ULL << 3) @@ -108,171 +70,124 @@ enum channel_clientstate { #define VISOR_DRIVER_DISABLES_INTS (0x1ULL << 5) #define VISOR_DRIVER_ENHANCED_RCVBUF_CHECKING (0x1ULL << 6) -/* Common Channel Header */ +/* + * struct channel_header - Common Channel Header + * @signature: Signature. + * @legacy_state: DEPRECATED - being replaced by. + * @header_size: sizeof(struct channel_header). + * @size: Total size of this channel in bytes. + * @features: Flags to modify behavior. + * @chtype: Channel type: data, bus, control, etc.. + * @partition_handle: ID of guest partition. + * @handle: Device number of this channel in client. + * @ch_space_offset: Offset in bytes to channel specific area. + * @version_id: Struct channel_header Version ID. + * @partition_index: Index of guest partition. + * @zone_uuid: Guid of Channel's zone. + * @cli_str_offset: Offset from channel header to null-terminated + * ClientString (0 if ClientString not present). + * @cli_state_boot: CHANNEL_CLIENTSTATE of pre-boot EFI client of this + * channel. + * @cmd_state_cli: CHANNEL_COMMANDSTATE (overloaded in Windows drivers, see + * ServerStateUp, ServerStateDown, etc). + * @cli_state_os: CHANNEL_CLIENTSTATE of Guest OS client of this channel. + * @ch_characteristic: CHANNEL_CHARACTERISTIC_<xxx>. + * @cmd_state_srv: CHANNEL_COMMANDSTATE (overloaded in Windows drivers, see + * ServerStateUp, ServerStateDown, etc). + * @srv_state: CHANNEL_SERVERSTATE. + * @cli_error_boot: Bits to indicate err states for boot clients, so err + * messages can be throttled. + * @cli_error_os: Bits to indicate err states for OS clients, so err + * messages can be throttled. + * @filler: Pad out to 128 byte cacheline. + * @recover_channel: Please add all new single-byte values below here. + */ struct channel_header { - u64 signature; /* Signature */ - u32 legacy_state; /* DEPRECATED - being replaced by */ - /* SrvState, CliStateBoot, and CliStateOS below */ - u32 header_size; /* sizeof(struct channel_header) */ - u64 size; /* Total size of this channel in bytes */ - u64 features; /* Flags to modify behavior */ - uuid_le chtype; /* Channel type: data, bus, control, etc. */ - u64 partition_handle; /* ID of guest partition */ - u64 handle; /* Device number of this channel in client */ - u64 ch_space_offset; /* Offset in bytes to channel specific area */ - u32 version_id; /* struct channel_header Version ID */ - u32 partition_index; /* Index of guest partition */ - uuid_le zone_uuid; /* Guid of Channel's zone */ - u32 cli_str_offset; /* offset from channel header to - * nul-terminated ClientString (0 if - * ClientString not present) - */ - u32 cli_state_boot; /* CHANNEL_CLIENTSTATE of pre-boot - * EFI client of this channel - */ - u32 cmd_state_cli; /* CHANNEL_COMMANDSTATE (overloaded in - * Windows drivers, see ServerStateUp, - * ServerStateDown, etc) - */ - u32 cli_state_os; /* CHANNEL_CLIENTSTATE of Guest OS - * client of this channel - */ - u32 ch_characteristic; /* CHANNEL_CHARACTERISTIC_<xxx> */ - u32 cmd_state_srv; /* CHANNEL_COMMANDSTATE (overloaded in - * Windows drivers, see ServerStateUp, - * ServerStateDown, etc) - */ - u32 srv_state; /* CHANNEL_SERVERSTATE */ - u8 cli_error_boot; /* bits to indicate err states for - * boot clients, so err messages can - * be throttled - */ - u8 cli_error_os; /* bits to indicate err states for OS - * clients, so err messages can be - * throttled - */ - u8 filler[1]; /* Pad out to 128 byte cacheline */ - /* Please add all new single-byte values below here */ + u64 signature; + u32 legacy_state; + /* SrvState, CliStateBoot, and CliStateOS below */ + u32 header_size; + u64 size; + u64 features; + guid_t chtype; + u64 partition_handle; + u64 handle; + u64 ch_space_offset; + u32 version_id; + u32 partition_index; + guid_t zone_guid; + u32 cli_str_offset; + u32 cli_state_boot; + u32 cmd_state_cli; + u32 cli_state_os; + u32 ch_characteristic; + u32 cmd_state_srv; + u32 srv_state; + u8 cli_error_boot; + u8 cli_error_os; + u8 filler[1]; u8 recover_channel; } __packed; #define VISOR_CHANNEL_ENABLE_INTS (0x1ULL << 0) -/* Subheader for the Signal Type variation of the Common Channel */ +/* + * struct signal_queue_header - Subheader for the Signal Type variation of the + * Common Channel. + * @version: SIGNAL_QUEUE_HEADER Version ID. + * @chtype: Queue type: storage, network. + * @size: Total size of this queue in bytes. + * @sig_base_offset: Offset to signal queue area. + * @features: Flags to modify behavior. + * @num_sent: Total # of signals placed in this queue. + * @num_overflows: Total # of inserts failed due to full queue. + * @signal_size: Total size of a signal for this queue. + * @max_slots: Max # of slots in queue, 1 slot is always empty. + * @max_signals: Max # of signals in queue (MaxSignalSlots-1). + * @head: Queue head signal #. + * @num_received: Total # of signals removed from this queue. + * @tail: Queue tail signal. + * @reserved1: Reserved field. + * @reserved2: Reserved field. + * @client_queue: + * @num_irq_received: Total # of Interrupts received. This is incremented by the + * ISR in the guest windows driver. + * @num_empty: Number of times that visor_signal_remove is called and + * returned Empty Status. + * @errorflags: Error bits set during SignalReinit to denote trouble with + * client's fields. + * @filler: Pad out to 64 byte cacheline. + */ struct signal_queue_header { /* 1st cache line */ - u32 version; /* SIGNAL_QUEUE_HEADER Version ID */ - u32 chtype; /* Queue type: storage, network */ - u64 size; /* Total size of this queue in bytes */ - u64 sig_base_offset; /* Offset to signal queue area */ - u64 features; /* Flags to modify behavior */ - u64 num_sent; /* Total # of signals placed in this queue */ - u64 num_overflows; /* Total # of inserts failed due to - * full queue - */ - u32 signal_size; /* Total size of a signal for this queue */ - u32 max_slots; /* Max # of slots in queue, 1 slot is - * always empty - */ - u32 max_signals; /* Max # of signals in queue - * (MaxSignalSlots-1) - */ - u32 head; /* Queue head signal # */ + u32 version; + u32 chtype; + u64 size; + u64 sig_base_offset; + u64 features; + u64 num_sent; + u64 num_overflows; + u32 signal_size; + u32 max_slots; + u32 max_signals; + u32 head; /* 2nd cache line */ - u64 num_received; /* Total # of signals removed from this queue */ - u32 tail; /* Queue tail signal */ - u32 reserved1; /* Reserved field */ - u64 reserved2; /* Reserved field */ + u64 num_received; + u32 tail; + u32 reserved1; + u64 reserved2; u64 client_queue; - u64 num_irq_received; /* Total # of Interrupts received. This - * is incremented by the ISR in the - * guest windows driver - */ - u64 num_empty; /* Number of times that visor_signal_remove - * is called and returned Empty Status. - */ - u32 errorflags; /* Error bits set during SignalReinit - * to denote trouble with client's - * fields - */ - u8 filler[12]; /* Pad out to 64 byte cacheline */ + u64 num_irq_received; + u64 num_empty; + u32 errorflags; + u8 filler[12]; } __packed; -/* Generic function useful for validating any type of channel when it is - * received by the client that will be accessing the channel. - * Note that <logCtx> is only needed for callers in the EFI environment, and - * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages. - */ -static inline int -visor_check_channel(struct channel_header *ch, - uuid_le expected_uuid, - char *chname, - u64 expected_min_bytes, - u32 expected_version, - u64 expected_signature) -{ - if (uuid_le_cmp(expected_uuid, NULL_UUID_LE) != 0) { - /* caller wants us to verify type GUID */ - if (uuid_le_cmp(ch->chtype, expected_uuid) != 0) { - pr_err("Channel mismatch on channel=%s(%pUL) field=type expected=%pUL actual=%pUL\n", - chname, &expected_uuid, - &expected_uuid, &ch->chtype); - return 0; - } - } - if (expected_min_bytes > 0) { /* verify channel size */ - if (ch->size < expected_min_bytes) { - pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8Lx actual=0x%-8.8Lx\n", - chname, &expected_uuid, - (unsigned long long)expected_min_bytes, - ch->size); - return 0; - } - } - if (expected_version > 0) { /* verify channel version */ - if (ch->version_id != expected_version) { - pr_err("Channel mismatch on channel=%s(%pUL) field=version expected=0x%-8.8lx actual=0x%-8.8x\n", - chname, &expected_uuid, - (unsigned long)expected_version, - ch->version_id); - return 0; - } - } - if (expected_signature > 0) { /* verify channel signature */ - if (ch->signature != expected_signature) { - pr_err("Channel mismatch on channel=%s(%pUL) field=signature expected=0x%-8.8Lx actual=0x%-8.8Lx\n", - chname, &expected_uuid, - expected_signature, ch->signature); - return 0; - } - } - return 1; -} - -/* - * CHANNEL Guids - */ - +/* CHANNEL Guids */ /* {414815ed-c58c-11da-95a9-00e08161165f} */ -#define VISOR_VHBA_CHANNEL_UUID \ - UUID_LE(0x414815ed, 0xc58c, 0x11da, \ - 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) -static const uuid_le visor_vhba_channel_uuid = VISOR_VHBA_CHANNEL_UUID; -#define VISOR_VHBA_CHANNEL_UUID_STR \ +#define VISOR_VHBA_CHANNEL_GUID \ + GUID_INIT(0x414815ed, 0xc58c, 0x11da, \ + 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) +#define VISOR_VHBA_CHANNEL_GUID_STR \ "414815ed-c58c-11da-95a9-00e08161165f" - -/* {8cd5994d-c58e-11da-95a9-00e08161165f} */ -#define VISOR_VNIC_CHANNEL_UUID \ - UUID_LE(0x8cd5994d, 0xc58e, 0x11da, \ - 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) -static const uuid_le visor_vnic_channel_uuid = VISOR_VNIC_CHANNEL_UUID; -#define VISOR_VNIC_CHANNEL_UUID_STR \ - "8cd5994d-c58e-11da-95a9-00e08161165f" - -/* {72120008-4AAB-11DC-8530-444553544200} */ -#define VISOR_SIOVM_UUID \ - UUID_LE(0x72120008, 0x4AAB, 0x11DC, \ - 0x85, 0x30, 0x44, 0x45, 0x53, 0x54, 0x42, 0x00) -static const uuid_le visor_siovm_uuid = VISOR_SIOVM_UUID; - #endif diff --git a/drivers/staging/unisys/include/iochannel.h b/drivers/staging/unisys/include/iochannel.h index c7cb3fbde7b2..a70760f48566 100644 --- a/drivers/staging/unisys/include/iochannel.h +++ b/drivers/staging/unisys/include/iochannel.h @@ -1,5 +1,19 @@ -/* Copyright (C) 2010 - 2016 UNISYS CORPORATION */ -/* All rights reserved. */ +/* + * Copyright (C) 2010 - 2016 UNISYS CORPORATION + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + */ + #ifndef __IOCHANNEL_H__ #define __IOCHANNEL_H__ @@ -7,9 +21,7 @@ * Everything needed for IOPart-GuestPart communication is define in * this file. Note: Everything is OS-independent because this file is * used by Windows, Linux and possible EFI drivers. - */ - -/* + * * Communication flow between the IOPart and GuestPart uses the channel headers * channel state. The following states are currently being used: * UNINIT(All Zeroes), CHANNEL_ATTACHING, CHANNEL_ATTACHED, CHANNEL_OPENED @@ -30,14 +42,10 @@ */ #include <linux/uuid.h> +#include <linux/skbuff.h> -#include <linux/dma-direction.h> #include "channel.h" -#define VISOR_VHBA_CHANNEL_SIGNATURE VISOR_CHANNEL_SIGNATURE -#define VISOR_VNIC_CHANNEL_SIGNATURE VISOR_CHANNEL_SIGNATURE -#define VISOR_VSWITCH_CHANNEL_SIGNATURE VISOR_CHANNEL_SIGNATURE - /* * Must increment these whenever you insert or delete fields within this channel * struct. Also increment whenever you change the meaning of fields within this @@ -47,82 +55,73 @@ */ #define VISOR_VHBA_CHANNEL_VERSIONID 2 #define VISOR_VNIC_CHANNEL_VERSIONID 2 -#define VISOR_VSWITCH_CHANNEL_VERSIONID 1 - -#define VISOR_VHBA_CHANNEL_OK_CLIENT(ch) \ - (visor_check_channel(ch, visor_vhba_channel_uuid, \ - "vhba", MIN_IO_CHANNEL_SIZE, \ - VISOR_VHBA_CHANNEL_VERSIONID, \ - VISOR_VHBA_CHANNEL_SIGNATURE)) - -#define VISOR_VNIC_CHANNEL_OK_CLIENT(ch) \ - (visor_check_channel(ch, visor_vnic_channel_uuid, \ - "vnic", MIN_IO_CHANNEL_SIZE, \ - VISOR_VNIC_CHANNEL_VERSIONID, \ - VISOR_VNIC_CHANNEL_SIGNATURE)) /* * Everything necessary to handle SCSI & NIC traffic between Guest Partition and * IO Partition is defined below. */ -/* Defines and enums. */ -#define MINNUM(a, b) (((a) < (b)) ? (a) : (b)) -#define MAXNUM(a, b) (((a) > (b)) ? (a) : (b)) - -/* Define the two queues per data channel between iopart and ioguestparts. */ -/* Used by ioguestpart to 'insert' signals to iopart. */ +/* + * Define the two queues per data channel between iopart and ioguestparts. + * IOCHAN_TO_IOPART -- used by guest to 'insert' signals to iopart. + * IOCHAN_FROM_IOPART -- used by guest to 'remove' signals from IO part. + */ #define IOCHAN_TO_IOPART 0 -/* Used by ioguestpart to 'remove' signals from iopart, same previous queue. */ #define IOCHAN_FROM_IOPART 1 /* Size of cdb - i.e., SCSI cmnd */ #define MAX_CMND_SIZE 16 -#define MAX_SENSE_SIZE 64 +/* Unisys-specific DMA direction values */ +enum uis_dma_data_direction { + UIS_DMA_BIDIRECTIONAL = 0, + UIS_DMA_TO_DEVICE = 1, + UIS_DMA_FROM_DEVICE = 2, + UIS_DMA_NONE = 3 +}; +#define MAX_SENSE_SIZE 64 #define MAX_PHYS_INFO 64 -/* Various types of network packets that can be sent in cmdrsp. */ +/* + * enum net_types - Various types of network packets that can be sent in cmdrsp. + * @NET_RCV_POST: Submit buffer to hold receiving incoming packet. + * @NET_RCV: visornic -> uisnic. Incoming packet received. + * @NET_XMIT: uisnic -> visornic. For outgoing packet. + * @NET_XMIT_DONE: visornic -> uisnic. Outgoing packet xmitted. + * @NET_RCV_ENBDIS: uisnic -> visornic. Enable/Disable packet reception. + * @NET_RCV_ENBDIS_ACK: visornic -> uisnic. Acknowledge enable/disable packet. + * @NET_RCV_PROMISC: uisnic -> visornic. Enable/Disable promiscuous mode. + * @NET_CONNECT_STATUS: visornic -> uisnic. Indicate the loss or restoration of + * a network connection. + * @NET_MACADDR: uisnic -> visornic. Indicates the client has requested + * to update it's MAC address. + * @NET_MACADDR_ACK: MAC address acknowledge. + */ enum net_types { - NET_RCV_POST = 0, /* - * Submit buffer to hold receiving - * incoming packet - */ - /* visornic -> uisnic */ - NET_RCV, /* incoming packet received */ - /* uisnic -> visornic */ - NET_XMIT, /* for outgoing net packets */ - /* visornic -> uisnic */ - NET_XMIT_DONE, /* outgoing packet xmitted */ - /* uisnic -> visornic */ - NET_RCV_ENBDIS, /* enable/disable packet reception */ - /* visornic -> uisnic */ - NET_RCV_ENBDIS_ACK, /* acknowledge enable/disable packet */ - /* reception */ - /* uisnic -> visornic */ - NET_RCV_PROMISC, /* enable/disable promiscuous mode */ - /* visornic -> uisnic */ - NET_CONNECT_STATUS, /* - * indicate the loss or restoration of a network - * connection - */ - /* uisnic -> visornic */ - NET_MACADDR, /* - * Indicates the client has requested to update - * it's MAC address - */ - NET_MACADDR_ACK, /* MAC address acknowledge */ - + NET_RCV_POST = 0, + NET_RCV, + NET_XMIT, + NET_XMIT_DONE, + NET_RCV_ENBDIS, + NET_RCV_ENBDIS_ACK, + /* Reception */ + NET_RCV_PROMISC, + NET_CONNECT_STATUS, + NET_MACADDR, + NET_MACADDR_ACK, }; -#define ETH_MIN_DATA_SIZE 46 /* minimum eth data size */ +/* Minimum eth data size */ +#define ETH_MIN_DATA_SIZE 46 #define ETH_MIN_PACKET_SIZE (ETH_HLEN + ETH_MIN_DATA_SIZE) -#define VISOR_ETH_MAX_MTU 16384 /* maximum data size */ +/* Maximum data size */ +#define VISOR_ETH_MAX_MTU 16384 #ifndef MAX_MACADDR_LEN -#define MAX_MACADDR_LEN 6 /* number of bytes in MAC address */ +/* Number of bytes in MAC address */ +#define MAX_MACADDR_LEN 6 #endif /* Various types of scsi task mgmt commands. */ @@ -154,12 +153,16 @@ struct guest_phys_info { u64 length; } __packed; -#define GPI_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(struct guest_phys_info)) - +/* + * struct uisscsi_dest + * @channel: Bus number. + * @id: Target number. + * @lun: Logical unit number. + */ struct uisscsi_dest { - u32 channel; /* channel == bus number */ - u32 id; /* id == target number */ - u32 lun; /* lun == logical unit number */ + u32 channel; + u32 id; + u32 lun; } __packed; struct vhba_wwnn { @@ -168,61 +171,77 @@ struct vhba_wwnn { } __packed; /* - * WARNING: Values stired in this structure must contain maximum counts (not + * struct vhba_config_max + * @max_channel: Maximum channel for devices attached to this bus. + * @max_id: Maximum SCSI ID for devices attached to bus. + * @max_lun: Maximum SCSI LUN for devices attached to bus. + * @cmd_per_lun: Maximum number of outstanding commands per LUN. + * @max_io_size: Maximum io size for devices attached to this bus. Max io size + * is often determined by the resource of the hba. + * e.g Max scatter gather list length * page size / sector size. + * + * WARNING: Values stored in this structure must contain maximum counts (not * maximum values). + * + * 20 bytes */ -struct vhba_config_max {/* 20 bytes */ - u32 max_channel;/* maximum channel for devices attached to this bus */ - u32 max_id; /* maximum SCSI ID for devices attached to bus */ - u32 max_lun; /* maximum SCSI LUN for devices attached to bus */ - u32 cmd_per_lun;/* maximum number of outstanding commands per LUN */ - u32 max_io_size;/* maximum io size for devices attached to this bus */ - /* max io size is often determined by the resource of the hba. e.g */ - /* max scatter gather list length * page size / sector size */ +struct vhba_config_max { + u32 max_channel; + u32 max_id; + u32 max_lun; + u32 cmd_per_lun; + u32 max_io_size; } __packed; +/* + * struct uiscmdrsp_scsi + * + * @handle: The handle to the cmd that was received. Send it back as + * is in the rsp packet. + * @cmnd: The cdb for the command. + * @bufflen: Length of data to be transferred out or in. + * @guest_phys_entries: Number of entries in scatter-gather list. + * @struct gpi_list: Physical address information for each fragment. + * @data_dir: Direction of the data, if any. + * @struct vdest: Identifies the virtual hba, id, channel, lun to which + * cmd was sent. + * @linuxstat: Original Linux status used by Linux vdisk. + * @scsistat: The scsi status. + * @addlstat: Non-scsi status. + * @sensebuf: Sense info in case cmd failed. sensebuf holds the + * sense_data struct. See sense_data struct for more + * details. + * @*vdisk: Pointer to the vdisk to clean up when IO completes. + * @no_disk_result: Used to return no disk inquiry result when + * no_disk_result is set to 1 + * scsi.scsistat is SAM_STAT_GOOD + * scsi.addlstat is 0 + * scsi.linuxstat is SAM_STAT_GOOD + * That is, there is NO error. + */ struct uiscmdrsp_scsi { - u64 handle; /* the handle to the cmd that was received */ - /* send it back as is in the rsp packet. */ - u8 cmnd[MAX_CMND_SIZE]; /* the cdb for the command */ - u32 bufflen; /* length of data to be transferred out or in */ - u16 guest_phys_entries; /* Number of entries in scatter-gather list */ - struct guest_phys_info gpi_list[MAX_PHYS_INFO]; /* physical address - * information for each - * fragment - */ - enum dma_data_direction data_dir; /* direction of the data, if any */ - struct uisscsi_dest vdest; /* identifies the virtual hba, id, */ - /* channel, lun to which cmd was sent */ - + u64 handle; + u8 cmnd[MAX_CMND_SIZE]; + u32 bufflen; + u16 guest_phys_entries; + struct guest_phys_info gpi_list[MAX_PHYS_INFO]; + u32 data_dir; + struct uisscsi_dest vdest; /* Needed to queue the rsp back to cmd originator. */ - int linuxstat; /* original Linux status used by Linux vdisk */ - u8 scsistat; /* the scsi status */ - u8 addlstat; /* non-scsi status */ + int linuxstat; + u8 scsistat; + u8 addlstat; #define ADDL_SEL_TIMEOUT 4 - /* The following fields are need to determine the result of command. */ - u8 sensebuf[MAX_SENSE_SIZE]; /* sense info in case cmd failed; */ - /* sensebuf holds the sense_data struct; */ - /* See sense_data struct for more details. */ - void *vdisk; /* Pointer to the vdisk to clean up when IO completes. */ + u8 sensebuf[MAX_SENSE_SIZE]; + void *vdisk; int no_disk_result; - /* - * Used to return no disk inquiry result - * when no_disk_result is set to 1, - * scsi.scsistat is SAM_STAT_GOOD - * scsi.addlstat is 0 - * scsi.linuxstat is SAM_STAT_GOOD - * That is, there is NO error. - */ } __packed; /* * Defines to support sending correct inquiry result when no disk is * configured. - */ - -/* + * * From SCSI SPC2 - * * If the target is not capable of supporting a device on this logical unit, the @@ -234,22 +253,35 @@ struct uiscmdrsp_scsi { * connected to this logical unit. */ -#define DEV_NOT_CAPABLE 0x7f /* - * peripheral qualifier of 0x3 - * peripheral type of 0x1f - * specifies no device but target present - */ - -#define DEV_DISK_CAPABLE_NOT_PRESENT 0x20 /* peripheral qualifier of 0x1 - * peripheral type of 0 - disk - * Specifies device capable, but - * not present - */ +/* + * Peripheral qualifier of 0x3 + * Peripheral type of 0x1f + * Specifies no device but target present + */ +#define DEV_NOT_CAPABLE 0x7f +/* + * Peripheral qualifier of 0x1 + * Peripheral type of 0 - disk + * Specifies device capable, but not present + */ +#define DEV_DISK_CAPABLE_NOT_PRESENT 0x20 +/* HiSup = 1; shows support for report luns must be returned for lun 0. */ +#define DEV_HISUPPORT 0x10 -#define DEV_HISUPPORT 0x10 /* - * HiSup = 1; shows support for report luns - * must be returned for lun 0. - */ +/* + * Peripheral qualifier of 0x3 + * Peripheral type of 0x1f + * Specifies no device but target present + */ +#define DEV_NOT_CAPABLE 0x7f +/* + * Peripheral qualifier of 0x1 + * Peripheral type of 0 - disk + * Specifies device capable, but not present + */ +#define DEV_DISK_CAPABLE_NOT_PRESENT 0x20 +/* HiSup = 1; shows support for report luns must be returned for lun 0. */ +#define DEV_HISUPPORT 0x10 /* * NOTE: Linux code assumes inquiry contains 36 bytes. Without checking length @@ -258,11 +290,12 @@ struct uiscmdrsp_scsi { * inquiry result. */ #define NO_DISK_INQUIRY_RESULT_LEN 36 - -#define MIN_INQUIRY_RESULT_LEN 5 /* 5 bytes minimum for inquiry result */ +/* 5 bytes minimum for inquiry result */ +#define MIN_INQUIRY_RESULT_LEN 5 /* SCSI device version for no disk inquiry result */ -#define SCSI_SPC2_VER 4 /* indicates SCSI SPC2 (SPC3 is 5) */ +/* indicates SCSI SPC2 (SPC3 is 5) */ +#define SCSI_SPC2_VER 4 /* Struct and Defines to support sense information. */ @@ -297,35 +330,48 @@ struct sense_data { u8 sense_key_specific[3]; } __packed; +/* + * struct net_pkt_xmt + * @len: Full length of data in the packet. + * @num_frags: Number of fragments in frags containing data. + * @struct phys_info frags: Physical page information. + * @ethhdr: The ethernet header. + * @struct lincsum: These are needed for csum at uisnic end. + * @valid: 1 = struct is valid - else ignore. + * @hrawoffv: 1 = hwrafoff is valid. + * @nhrawoffv: 1 = nhwrafoff is valid. + * @protocol: Specifies packet protocol. + * @csum: Value used to set skb->csum at IOPart. + * @hrawoff: Value used to set skb->h.raw at IOPart. hrawoff points to + * the start of the TRANSPORT LAYER HEADER. + * @nhrawoff: Value used to set skb->nh.raw at IOPart. nhrawoff points to + * the start of the NETWORK LAYER HEADER. + * + * NOTE: + * The full packet is described in frags but the ethernet header is + * separately kept in ethhdr so that uisnic doesn't have "MAP" the + * guest memory to get to the header. uisnic needs ethhdr to + * determine how to route the packet. + */ struct net_pkt_xmt { - int len; /* full length of data in the packet */ - int num_frags; /* number of fragments in frags containing data */ - struct phys_info frags[MAX_PHYS_INFO]; /* physical page information */ - char ethhdr[ETH_HLEN]; /* the ethernet header */ + int len; + int num_frags; + struct phys_info frags[MAX_PHYS_INFO]; + char ethhdr[ETH_HLEN]; struct { - /* These are needed for csum at uisnic end */ - u8 valid; /* 1 = struct is valid - else ignore */ - u8 hrawoffv; /* 1 = hwrafoff is valid */ - u8 nhrawoffv; /* 1 = nhwrafoff is valid */ - __be16 protocol; /* specifies packet protocol */ - __wsum csum; /* value used to set skb->csum at IOPart */ - u32 hrawoff; /* value used to set skb->h.raw at IOPart */ - /* hrawoff points to the start of the TRANSPORT LAYER HEADER */ - u32 nhrawoff; /* value used to set skb->nh.raw at IOPart */ - /* nhrawoff points to the start of the NETWORK LAYER HEADER */ + u8 valid; + u8 hrawoffv; + u8 nhrawoffv; + __be16 protocol; + __wsum csum; + u32 hrawoff; + u32 nhrawoff; } lincsum; - - /* - * NOTE: - * The full packet is described in frags but the ethernet header is - * separately kept in ethhdr so that uisnic doesn't have "MAP" the - * guest memory to get to the header. uisnic needs ethhdr to - * determine how to route the packet. - */ } __packed; struct net_pkt_xmtdone { - u32 xmt_done_result; /* result of NET_XMIT */ + /* Result of NET_XMIT */ + u32 xmt_done_result; } __packed; /* @@ -341,14 +387,12 @@ struct net_pkt_xmtdone { ((VISOR_ETH_MAX_MTU + ETH_HLEN + RCVPOST_BUF_SIZE - 1) \ / RCVPOST_BUF_SIZE) -/* - * rcv buf size must be large enough to include ethernet data len + ethernet +/* rcv buf size must be large enough to include ethernet data len + ethernet * header len - we are choosing 2K because it is guaranteed to be describable. */ struct net_pkt_rcvpost { /* Physical page information for the single fragment 2K rcv buf */ struct phys_info frag; - /* * Ensures that receive posts are returned to the adapter which we sent * them from originally. @@ -358,172 +402,157 @@ struct net_pkt_rcvpost { } __packed; /* + * struct net_pkt_rcv + * @rcv_done_len: Length of the received data. + * @numrcvbufs: Contains the incoming data. Guest side MUST chain these + * together. + * @*rcvbuf: List of chained rcvbufa. Each entry is a receive buffer + * provided by NET_RCV_POST. NOTE: First rcvbuf in the + * chain will also be provided in net.buf. + * @unique_num: + * @rcvs_dropped_delta: + * * The number of rcvbuf that can be chained is based on max mtu and size of each * rcvbuf. */ struct net_pkt_rcv { - u32 rcv_done_len; /* length of received data */ - - /* - * numrcvbufs: contain the incoming data; guest side MUST chain these - * together. - */ + u32 rcv_done_len; u8 numrcvbufs; - - void *rcvbuf[MAX_NET_RCV_CHAIN]; /* list of chained rcvbufs */ - - /* Each entry is a receive buffer provided by NET_RCV_POST. */ - /* NOTE: first rcvbuf in the chain will also be provided in net.buf. */ + void *rcvbuf[MAX_NET_RCV_CHAIN]; u64 unique_num; u32 rcvs_dropped_delta; } __packed; struct net_pkt_enbdis { void *context; - u16 enable; /* 1 = enable, 0 = disable */ + /* 1 = enable, 0 = disable */ + u16 enable; } __packed; struct net_pkt_macaddr { void *context; - u8 macaddr[MAX_MACADDR_LEN]; /* 6 bytes */ + /* 6 bytes */ + u8 macaddr[MAX_MACADDR_LEN]; } __packed; -/* cmd rsp packet used for VNIC network traffic */ +/* + * struct uiscmdrsp_net - cmd rsp packet used for VNIC network traffic. + * @enum type: + * @*buf: + * @union: + * @struct xmt: Used for NET_XMIT. + * @struct xmtdone: Used for NET_XMIT_DONE. + * @struct rcvpost: Used for NET_RCV_POST. + * @struct rcv: Used for NET_RCV. + * @struct enbdis: Used for NET_RCV_ENBDIS, NET_RCV_ENBDIS_ACK, + * NET_RCV_PROMSIC, and NET_CONNECT_STATUS. + * @struct macaddr: + */ struct uiscmdrsp_net { enum net_types type; void *buf; union { - struct net_pkt_xmt xmt; /* used for NET_XMIT */ - struct net_pkt_xmtdone xmtdone; /* used for NET_XMIT_DONE */ - struct net_pkt_rcvpost rcvpost; /* used for NET_RCV_POST */ - struct net_pkt_rcv rcv; /* used for NET_RCV */ - struct net_pkt_enbdis enbdis; /* used for NET_RCV_ENBDIS, */ - /* NET_RCV_ENBDIS_ACK, */ - /* NET_RCV_PROMSIC, */ - /* and NET_CONNECT_STATUS */ + struct net_pkt_xmt xmt; + struct net_pkt_xmtdone xmtdone; + struct net_pkt_rcvpost rcvpost; + struct net_pkt_rcv rcv; + struct net_pkt_enbdis enbdis; struct net_pkt_macaddr macaddr; }; } __packed; +/* + * struct uiscmdrsp_scsitaskmgmt + * @enum tasktype: The type of task. + * @struct vdest: The vdisk for which this task mgmt is generated. + * @handle: This is a handle that the guest has saved off for its + * own use. The handle value is preserved by iopart and + * returned as in task mgmt rsp. + * @notify_handle: For Linux guests, this is a pointer to wait_queue_head + * that a thread is waiting on to see if the taskmgmt + * command has completed. When the rsp is received by + * guest, the thread receiving the response uses this to + * notify the thread waiting for taskmgmt command + * completion. It's value is preserved by iopart and + * returned as in the task mgmt rsp. + * @notifyresult_handle: This is a handle to the location in the guest where + * the result of the taskmgmt command (result field) is + * saved to when the response is handled. It's value is + * preserved by iopart and returned as is in the task mgmt + * rsp. + * @result: Result of taskmgmt command - set by IOPart. + */ struct uiscmdrsp_scsitaskmgmt { - /* The type of task. */ enum task_mgmt_types tasktype; - - /* The vdisk for which this task mgmt is generated. */ struct uisscsi_dest vdest; - - /* - * This is a handle that the guest has saved off for its own use. - * The handle value is preserved by iopart and returned as in task - * mgmt rsp. - */ u64 handle; - - /* - * For Linux guests, this is a pointer to wait_queue_head that a - * thread is waiting on to see if the taskmgmt command has completed. - * When the rsp is received by guest, the thread receiving the - * response uses this to notify the thread waiting for taskmgmt - * command completion. It's value is preserved by iopart and returned - * as in the task mgmt rsp. - */ u64 notify_handle; - - /* - * This is a handle to the location in the guest where the result of - * the taskmgmt command (result field) is saved to when the response - * is handled. It's value is preserved by iopart and returned as in - * the task mgmt rsp. - */ u64 notifyresult_handle; - - /* Result of taskmgmt command - set by IOPart - values are: */ char result; #define TASK_MGMT_FAILED 0 } __packed; -/* Used by uissd to send disk add/remove notifications to Guest. */ -/* Note that the vHba pointer is not used by the Client/Guest side. */ -struct uiscmdrsp_disknotify { - u8 add; /* 0-remove, 1-add */ - void *v_hba; /* channel info to route msg */ - u32 channel, id, lun; /* SCSI Path of Disk to added or removed */ -} __packed; - /* - * The following is used by virthba/vSCSI to send the Acquire/Release commands - * to the IOVM. + * struct uiscmdrsp_disknotify - Used by uissd to send disk add/remove + * notifications to Guest. + * @add: 0-remove, 1-add. + * @*v_hba: Channel info to route msg. + * @channel: SCSI Path of Disk to added or removed. + * @id: SCSI Path of Disk to added or removed. + * @lun: SCSI Path of Disk to added or removed. + * + * Note that the vHba pointer is not used by the Client/Guest side. */ -struct uiscmdrsp_vdiskmgmt { - /* The type of task */ - enum vdisk_mgmt_types vdisktype; - - /* The vdisk for which this task mgmt is generated */ - struct uisscsi_dest vdest; - - /* - * This is a handle that the guest has saved off for its own use. It's - * value is preserved by iopart and returned as in the task mgmt rsp. - */ - u64 handle; - - /* - * For Linux guests, this is a pointer to wait_queue_head that a - * thread is waiting on to see if the tskmgmt command has completed. - * When the rsp is received by guest, the thread receiving the - * response uses this to notify the thread waiting for taskmgmt - * command completion. It's value is preserved by iopart and returned - * as in the task mgmt rsp. - */ - u64 notify_handle; - - /* - * Handle to the location in guest where the result of the - * taskmgmt command (result field) is saved to when the response - * is handled. It's value is preserved by iopart and returned as in - * the task mgmt rsp. - */ - u64 notifyresult_handle; - - /* Result of taskmgmt command - set by IOPart - values are: */ - char result; +struct uiscmdrsp_disknotify { + u8 add; + void *v_hba; + u32 channel, id, lun; } __packed; /* Keeping cmd and rsp info in one structure for now cmd rsp packet for SCSI */ struct uiscmdrsp { char cmdtype; - -/* Describes what type of information is in the struct */ + /* Describes what type of information is in the struct */ #define CMD_SCSI_TYPE 1 #define CMD_NET_TYPE 2 #define CMD_SCSITASKMGMT_TYPE 3 #define CMD_NOTIFYGUEST_TYPE 4 -#define CMD_VDISKMGMT_TYPE 5 union { struct uiscmdrsp_scsi scsi; struct uiscmdrsp_net net; struct uiscmdrsp_scsitaskmgmt scsitaskmgmt; struct uiscmdrsp_disknotify disknotify; - struct uiscmdrsp_vdiskmgmt vdiskmgmt; }; /* Send the response when the cmd is done (scsi and scsittaskmgmt). */ void *private_data; - struct uiscmdrsp *next; /* General Purpose Queue Link */ - struct uiscmdrsp *activeQ_next; /* Pointer to the nextactive commands */ - struct uiscmdrsp *activeQ_prev; /* Pointer to the prevactive commands */ + /* General Purpose Queue Link */ + struct uiscmdrsp *next; + /* Pointer to the nextactive commands */ + struct uiscmdrsp *activeQ_next; + /* Pointer to the prevactive commands */ + struct uiscmdrsp *activeQ_prev; } __packed; +/* total = 28 bytes */ struct iochannel_vhba { - struct vhba_wwnn wwnn; /* 8 bytes */ - struct vhba_config_max max; /* 20 bytes */ -} __packed; /* total = 28 bytes */ + /* 8 bytes */ + struct vhba_wwnn wwnn; + /* 20 bytes */ + struct vhba_config_max max; +} __packed; + struct iochannel_vnic { - u8 macaddr[6]; /* 6 bytes */ - u32 num_rcv_bufs; /* 4 bytes */ - u32 mtu; /* 4 bytes */ - uuid_le zone_uuid; /* 16 bytes */ + /* 6 bytes */ + u8 macaddr[6]; + /* 4 bytes */ + u32 num_rcv_bufs; + /* 4 bytes */ + u32 mtu; + /* 16 bytes */ + guid_t zone_guid; } __packed; + /* * This is just the header of the IO channel. It is assumed that directly after * this header there is a large region of memory which contains the command and @@ -544,10 +573,11 @@ struct visor_io_channel { } __packed; /* INLINE functions for initializing and accessing I/O data channels. */ -#define SIZEOF_CMDRSP (COVER(sizeof(struct uiscmdrsp), 64)) +#define SIZEOF_CMDRSP (64 * DIV_ROUND_UP(sizeof(struct uiscmdrsp), 64)) /* Use 4K page sizes when passing page info between Guest and IOPartition. */ #define PI_PAGE_SIZE 0x1000 #define PI_PAGE_MASK 0x0FFF -#endif /* __IOCHANNEL_H__ */ +/* __IOCHANNEL_H__ */ +#endif diff --git a/drivers/staging/unisys/include/visorbus.h b/drivers/staging/unisys/include/visorbus.h index de0635542fbd..e4ee38c3dbe4 100644 --- a/drivers/staging/unisys/include/visorbus.h +++ b/drivers/staging/unisys/include/visorbus.h @@ -1,5 +1,4 @@ -/* visorbus.h - * +/* * Copyright (C) 2010 - 2013 UNISYS CORPORATION * All rights reserved. * @@ -23,7 +22,6 @@ * * There should be nothing in this file that is private to the visorbus * bus implementation itself. - * */ #ifndef __VISORBUS_H__ @@ -31,20 +29,16 @@ #include <linux/device.h> #include <linux/module.h> -#include <linux/poll.h> -#include <linux/kernel.h> -#include <linux/uuid.h> -#include <linux/seq_file.h> #include <linux/slab.h> #include "channel.h" -struct visor_driver; struct visor_device; extern struct bus_type visorbus_type; typedef void (*visorbus_state_complete_func) (struct visor_device *dev, int status); + struct visorchipset_state { u32 created:1; u32 attached:1; @@ -54,11 +48,12 @@ struct visorchipset_state { /* Remaining bits in this 32-bit word are unused. */ }; -/** This struct describes a specific Supervisor channel, by providing its - * GUID, name, and sizes. +/* + * This struct describes a specific Supervisor channel, by providing its + * GUID, name, and sizes. */ struct visor_channeltype_descriptor { - const uuid_le guid; + const guid_t guid; const char *name; }; @@ -109,8 +104,7 @@ struct visor_driver { struct device_driver driver; }; -#define to_visor_driver(x) ((x) ? \ - (container_of(x, struct visor_driver, driver)) : (NULL)) +#define to_visor_driver(x) (container_of(x, struct visor_driver, driver)) /** * struct visor_device - A device type for things "plugged" into the visorbus @@ -125,8 +119,8 @@ struct visor_driver { * activity. * @being_removed: Indicates that the device is being removed from * the bus. Private bus driver use only. - * @visordriver_callback_lock: Used by the bus driver to lock when handling - * channel events. + * @visordriver_callback_lock: Used by the bus driver to lock when adding and + * removing devices. * @pausing: Indicates that a change towards a paused state. * is in progress. Only modified by the bus driver. * @resuming: Indicates that a change towards a running state @@ -141,37 +135,42 @@ struct visor_driver { * hypervisor requests. * @vbus_hdr_info: A pointer to header info. Private use by bus * driver. - * @partition_uuid: Indicates client partion id. This should be the + * @partition_guid: Indicates client partion id. This should be the * same across all visor_devices in the current * guest. Private use by bus driver only. */ struct visor_device { struct visorchannel *visorchannel; - uuid_le channel_type_guid; + guid_t channel_type_guid; /* These fields are for private use by the bus driver only. */ struct device device; struct list_head list_all; struct timer_list timer; bool timer_active; bool being_removed; - struct mutex visordriver_callback_lock; + struct mutex visordriver_callback_lock; /* synchronize probe/remove */ bool pausing; bool resuming; u32 chipset_bus_no; u32 chipset_dev_no; struct visorchipset_state state; - uuid_le inst; + guid_t inst; u8 *name; struct controlvm_message_header *pending_msg_hdr; void *vbus_hdr_info; - uuid_le partition_uuid; + guid_t partition_guid; struct dentry *debugfs_dir; struct dentry *debugfs_client_bus_info; }; #define to_visor_device(x) container_of(x, struct visor_device, device) +int visor_check_channel(struct channel_header *ch, struct device *dev, + const guid_t *expected_uuid, char *chname, + u64 expected_min_bytes, u32 expected_version, + u64 expected_signature); + int visorbus_register_visor_driver(struct visor_driver *drv); void visorbus_unregister_visor_driver(struct visor_driver *drv); int visorbus_read_channel(struct visor_device *dev, @@ -183,7 +182,8 @@ int visorbus_write_channel(struct visor_device *dev, int visorbus_enable_channel_interrupts(struct visor_device *dev); void visorbus_disable_channel_interrupts(struct visor_device *dev); -/* Levels of severity for diagnostic events, in order from lowest severity to +/* + * Levels of severity for diagnostic events, in order from lowest severity to * highest (i.e. fatal errors are the most severe, and should always be logged, * but info events rarely need to be logged except during debugging). The * values DIAG_SEVERITY_ENUM_BEGIN and DIAG_SEVERITY_ENUM_END are not valid @@ -207,7 +207,7 @@ int visorchannel_signalremove(struct visorchannel *channel, u32 queue, int visorchannel_signalinsert(struct visorchannel *channel, u32 queue, void *msg); bool visorchannel_signalempty(struct visorchannel *channel, u32 queue); -uuid_le visorchannel_get_uuid(struct visorchannel *channel); +const guid_t *visorchannel_get_guid(struct visorchannel *channel); #define BUS_ROOT_DEVICE UINT_MAX struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no, diff --git a/drivers/staging/unisys/visorbus/controlvmchannel.h b/drivers/staging/unisys/visorbus/controlvmchannel.h index ed045eff0e33..32ff5c1bb6ba 100644 --- a/drivers/staging/unisys/visorbus/controlvmchannel.h +++ b/drivers/staging/unisys/visorbus/controlvmchannel.h @@ -1,4 +1,5 @@ -/* Copyright (C) 2010 - 2015 UNISYS CORPORATION +/* + * Copyright (C) 2010 - 2015 UNISYS CORPORATION * All rights reserved. * * This program is free software; you can redistribute it and/or modify it @@ -19,60 +20,55 @@ #include "channel.h" /* {2B3C2D10-7EF5-4ad8-B966-3448B7386B3D} */ -#define VISOR_CONTROLVM_CHANNEL_UUID \ - UUID_LE(0x2b3c2d10, 0x7ef5, 0x4ad8, \ - 0xb9, 0x66, 0x34, 0x48, 0xb7, 0x38, 0x6b, 0x3d) +#define VISOR_CONTROLVM_CHANNEL_GUID \ + GUID_INIT(0x2b3c2d10, 0x7ef5, 0x4ad8, \ + 0xb9, 0x66, 0x34, 0x48, 0xb7, 0x38, 0x6b, 0x3d) -#define VISOR_CONTROLVM_CHANNEL_SIGNATURE VISOR_CHANNEL_SIGNATURE #define CONTROLVM_MESSAGE_MAX 64 -/* Must increment this whenever you insert or delete fields within - * this channel struct. Also increment whenever you change the meaning - * of fields within this channel struct so as to break pre-existing - * software. Note that you can usually add fields to the END of the - * channel struct withOUT needing to increment this. +/* + * Must increment this whenever you insert or delete fields within this channel + * struct. Also increment whenever you change the meaning of fields within this + * channel struct so as to break pre-existing software. Note that you can + * usually add fields to the END of the channel struct withOUT needing to + * increment this. */ #define VISOR_CONTROLVM_CHANNEL_VERSIONID 1 -#define VISOR_CONTROLVM_CHANNEL_OK_CLIENT(ch) \ - (visor_check_channel(ch, \ - VISOR_CONTROLVM_CHANNEL_UUID, \ - "controlvm", \ - sizeof(struct visor_controlvm_channel), \ - VISOR_CONTROLVM_CHANNEL_VERSIONID, \ - VISOR_CONTROLVM_CHANNEL_SIGNATURE)) - /* Defines for various channel queues */ -#define CONTROLVM_QUEUE_REQUEST 0 -#define CONTROLVM_QUEUE_RESPONSE 1 -#define CONTROLVM_QUEUE_EVENT 2 -#define CONTROLVM_QUEUE_ACK 3 +#define CONTROLVM_QUEUE_REQUEST 0 +#define CONTROLVM_QUEUE_RESPONSE 1 +#define CONTROLVM_QUEUE_EVENT 2 +#define CONTROLVM_QUEUE_ACK 3 /* Max num of messages stored during IOVM creation to be reused after crash */ #define CONTROLVM_CRASHMSG_MAX 2 +/* + * struct visor_segment_state + * @enabled: May enter other states. + * @active: Assigned to active partition. + * @alive: Configure message sent to service/server. + * @revoked: Similar to partition state ShuttingDown. + * @allocated: Memory (device/port number) has been selected by Command. + * @known: Has been introduced to the service/guest partition. + * @ready: Service/Guest partition has responded to introduction. + * @operating: Resource is configured and operating. + * @reserved: Natural alignment. + * + * Note: Don't use high bit unless we need to switch to ushort which is + * non-compliant. + */ struct visor_segment_state { - /* Bit 0: May enter other states */ u16 enabled:1; - /* Bit 1: Assigned to active partition */ u16 active:1; - /* Bit 2: Configure message sent to service/server */ u16 alive:1; - /* Bit 3: similar to partition state ShuttingDown */ u16 revoked:1; - /* Bit 4: memory (device/port number) has been selected by Command */ u16 allocated:1; - /* Bit 5: has been introduced to the service/guest partition */ u16 known:1; - /* Bit 6: service/Guest partition has responded to introduction */ u16 ready:1; - /* Bit 7: resource is configured and operating */ u16 operating:1; - /* Natural alignment*/ u16 reserved:8; -/* Note: don't use high bit unless we need to switch to ushort - * which is non-compliant - */ } __packed; static const struct visor_segment_state segment_state_running = { @@ -87,74 +83,101 @@ static const struct visor_segment_state segment_state_standby = { 1, 1, 0, 0, 1, 1, 1, 0 }; -/* Ids for commands that may appear in either queue of a ControlVm channel. +/* + * enum controlvm_id + * @CONTROLVM_INVALID: + * @CONTROLVM_BUS_CREATE: CP --> SP, GP. + * @CONTROLVM_BUS_DESTROY: CP --> SP, GP. + * @CONTROLVM_BUS_CONFIGURE: CP --> SP. + * @CONTROLVM_BUS_CHANGESTATE: CP --> SP, GP. + * @CONTROLVM_BUS_CHANGESTATE_EVENT: SP, GP --> CP. + * @CONTROLVM_DEVICE_CREATE: CP --> SP, GP. + * @CONTROLVM_DEVICE_DESTROY: CP --> SP, GP. + * @CONTROLVM_DEVICE_CONFIGURE: CP --> SP. + * @CONTROLVM_DEVICE_CHANGESTATE: CP --> SP, GP. + * @CONTROLVM_DEVICE_CHANGESTATE_EVENT: SP, GP --> CP. + * @CONTROLVM_DEVICE_RECONFIGURE: CP --> Boot. + * @CONTROLVM_CHIPSET_INIT: CP --> SP, GP. + * @CONTROLVM_CHIPSET_STOP: CP --> SP, GP. + * @CONTROLVM_CHIPSET_READY: CP --> SP. + * @CONTROLVM_CHIPSET_SELFTEST: CP --> SP. * - * Commands that are initiated by the command partition (CP), by an IO or - * console service partition (SP), or by a guest partition (GP)are: - * - issued on the RequestQueue queue (q #0) in the ControlVm channel - * - responded to on the ResponseQueue queue (q #1) in the ControlVm channel + * Ids for commands that may appear in either queue of a ControlVm channel. * - * Events that are initiated by an IO or console service partition (SP) or - * by a guest partition (GP) are: - * - issued on the EventQueue queue (q #2) in the ControlVm channel - * - responded to on the EventAckQueue queue (q #3) in the ControlVm channel + * Commands that are initiated by the command partition (CP), by an IO or + * console service partition (SP), or by a guest partition (GP) are: + * - issued on the RequestQueue queue (q #0) in the ControlVm channel + * - responded to on the ResponseQueue queue (q #1) in the ControlVm channel + * + * Events that are initiated by an IO or console service partition (SP) or + * by a guest partition (GP) are: + * - issued on the EventQueue queue (q #2) in the ControlVm channel + * - responded to on the EventAckQueue queue (q #3) in the ControlVm channel */ enum controlvm_id { CONTROLVM_INVALID = 0, - /* SWITCH commands required Parameter: SwitchNumber */ - /* BUS commands required Parameter: BusNumber */ - CONTROLVM_BUS_CREATE = 0x101, /* CP --> SP, GP */ - CONTROLVM_BUS_DESTROY = 0x102, /* CP --> SP, GP */ - CONTROLVM_BUS_CONFIGURE = 0x104, /* CP --> SP */ - CONTROLVM_BUS_CHANGESTATE = 0x105, /* CP --> SP, GP */ - CONTROLVM_BUS_CHANGESTATE_EVENT = 0x106, /* SP, GP --> CP */ -/* DEVICE commands required Parameter: BusNumber, DeviceNumber */ - - CONTROLVM_DEVICE_CREATE = 0x201, /* CP --> SP, GP */ - CONTROLVM_DEVICE_DESTROY = 0x202, /* CP --> SP, GP */ - CONTROLVM_DEVICE_CONFIGURE = 0x203, /* CP --> SP */ - CONTROLVM_DEVICE_CHANGESTATE = 0x204, /* CP --> SP, GP */ - CONTROLVM_DEVICE_CHANGESTATE_EVENT = 0x205, /* SP, GP --> CP */ - CONTROLVM_DEVICE_RECONFIGURE = 0x206, /* CP --> Boot */ -/* CHIPSET commands */ - CONTROLVM_CHIPSET_INIT = 0x301, /* CP --> SP, GP */ - CONTROLVM_CHIPSET_STOP = 0x302, /* CP --> SP, GP */ - CONTROLVM_CHIPSET_READY = 0x304, /* CP --> SP */ - CONTROLVM_CHIPSET_SELFTEST = 0x305, /* CP --> SP */ - + /* + * SWITCH commands required Parameter: SwitchNumber. + * BUS commands required Parameter: BusNumber + */ + CONTROLVM_BUS_CREATE = 0x101, + CONTROLVM_BUS_DESTROY = 0x102, + CONTROLVM_BUS_CONFIGURE = 0x104, + CONTROLVM_BUS_CHANGESTATE = 0x105, + CONTROLVM_BUS_CHANGESTATE_EVENT = 0x106, + /* DEVICE commands required Parameter: BusNumber, DeviceNumber */ + CONTROLVM_DEVICE_CREATE = 0x201, + CONTROLVM_DEVICE_DESTROY = 0x202, + CONTROLVM_DEVICE_CONFIGURE = 0x203, + CONTROLVM_DEVICE_CHANGESTATE = 0x204, + CONTROLVM_DEVICE_CHANGESTATE_EVENT = 0x205, + CONTROLVM_DEVICE_RECONFIGURE = 0x206, + /* CHIPSET commands */ + CONTROLVM_CHIPSET_INIT = 0x301, + CONTROLVM_CHIPSET_STOP = 0x302, + CONTROLVM_CHIPSET_READY = 0x304, + CONTROLVM_CHIPSET_SELFTEST = 0x305, }; +/* + * struct irq_info + * @reserved1: Natural alignment purposes + * @recv_irq_handle: Specifies interrupt handle. It is used to retrieve the + * corresponding interrupt pin from Monitor; and the interrupt + * pin is used to connect to the corresponding interrupt. + * Used by IOPart-GP only. + * @recv_irq_vector: Specifies interrupt vector. It, interrupt pin, and shared + * are used to connect to the corresponding interrupt. + * Used by IOPart-GP only. + * @recv_irq_shared: Specifies if the recvInterrupt is shared. It, interrupt + * pin and vector are used to connect to 0 = not shared; + * 1 = shared the corresponding interrupt. + * Used by IOPart-GP only. + * @reserved: Natural alignment purposes + */ struct irq_info { u64 reserved1; - - /* specifies interrupt handle. It is used to retrieve the - * corresponding interrupt pin from Monitor; and the - * interrupt pin is used to connect to the corresponding - * interrupt. Used by IOPart-GP only. - */ u64 recv_irq_handle; - - /* specifies interrupt vector. It, interrupt pin, and shared are - * used to connect to the corresponding interrupt. Used by - * IOPart-GP only. - */ u32 recv_irq_vector; - - /* specifies if the recvInterrupt is shared. It, interrupt pin - * and vector are used to connect to 0 = not shared; 1 = shared. - * the corresponding interrupt. Used by IOPart-GP only. - */ u8 recv_irq_shared; - u8 reserved[3]; /* Natural alignment purposes */ + u8 reserved[3]; } __packed; +/* + * struct efi_visor_indication + * @boot_to_fw_ui: Stop in UEFI UI + * @clear_nvram: Clear NVRAM + * @clear_cmos: Clear CMOS + * @boot_to_tool: Run install tool + * @reserved: Natural alignment + */ struct efi_visor_indication { - u64 boot_to_fw_ui:1; /* Bit 0: Stop in uefi ui */ - u64 clear_nvram:1; /* Bit 1: Clear NVRAM */ - u64 clear_cmos:1; /* Bit 2: Clear CMOS */ - u64 boot_to_tool:1; /* Bit 3: Run install tool */ - /* remaining bits are available */ - u64 reserved:60; /* Natural alignment */ + u64 boot_to_fw_ui:1; + u64 clear_nvram:1; + u64 clear_cmos:1; + u64 boot_to_tool:1; + /* Remaining bits are available */ + u64 reserved:60; } __packed; enum visor_chipset_feature { @@ -162,182 +185,248 @@ enum visor_chipset_feature { VISOR_CHIPSET_FEATURE_PARA_HOTPLUG = 0x00000002, }; -/* This is the common structure that is at the beginning of every - * ControlVm message (both commands and responses) in any ControlVm - * queue. Commands are easily distinguished from responses by - * looking at the flags.response field. +/* + * struct controlvm_message_header + * @id: See CONTROLVM_ID. + * @message_size: Includes size of this struct + size of message. + * @segment_index: Index of segment containing Vm message/information. + * @completion_status: Error status code or result of message completion. + * @struct flags: + * @failed: =1 in a response to signify failure. + * @response_expected: =1 in all messages that expect a response. + * @server: =1 in all bus & device-related messages where the + * message receiver is to act as the bus or device + * server. + * @test_message: =1 for testing use only (Control and Command + * ignore this). + * @partial_completion: =1 if there are forthcoming responses/acks + * associated with this message. + * @preserve: =1 this is to let us know to preserve channel + * contents. + * @writer_in_diag: =1 the DiagWriter is active in the Diagnostic + * Partition. + * @reserve: Natural alignment. + * @reserved: Natural alignment. + * @message_handle: Identifies the particular message instance. + * @payload_vm_offset: Offset of payload area from start of this instance. + * @payload_max_bytes: Maximum bytes allocated in payload area of ControlVm + * segment. + * @payload_bytes: Actual number of bytes of payload area to copy between + * IO/Command. If non-zero, there is a payload to copy. + * + * This is the common structure that is at the beginning of every + * ControlVm message (both commands and responses) in any ControlVm + * queue. Commands are easily distinguished from responses by + * looking at the flags.response field. */ struct controlvm_message_header { - u32 id; /* See CONTROLVM_ID. */ - /* For requests, indicates the message type. */ - /* For responses, indicates the type of message we are responding to. */ - - /* Includes size of this struct + size of message */ + u32 id; + /* + * For requests, indicates the message type. For responses, indicates + * the type of message we are responding to. + */ u32 message_size; - /* Index of segment containing Vm message/information */ u32 segment_index; - /* Error status code or result of message completion */ u32 completion_status; struct { - /* =1 in a response to signify failure */ u32 failed:1; - /* =1 in all messages that expect a response */ u32 response_expected:1; - /* =1 in all bus & device-related messages where the message - * receiver is to act as the bus or device server - */ u32 server:1; - /* =1 for testing use only (Control and Command ignore this */ u32 test_message:1; - /* =1 if there are forthcoming responses/acks associated - * with this message - */ u32 partial_completion:1; - /* =1 this is to let us know to preserve channel contents */ u32 preserve:1; - /* =1 the DiagWriter is active in the Diagnostic Partition */ u32 writer_in_diag:1; - /* Natural alignment */ u32 reserve:25; } __packed flags; - /* Natural alignment */ u32 reserved; - /* Identifies the particular message instance */ u64 message_handle; - /* request instances with the corresponding response instance. */ - /* Offset of payload area from start of this instance */ u64 payload_vm_offset; - /* Maximum bytes allocated in payload area of ControlVm segment */ u32 payload_max_bytes; - /* Actual number of bytes of payload area to copy between IO/Command */ u32 payload_bytes; - /* if non-zero, there is a payload to copy. */ } __packed; +/* + * struct controlvm_packet_device_create - For CONTROLVM_DEVICE_CREATE + * @bus_no: Bus # (0..n-1) from the msg receiver's end. + * @dev_no: Bus-relative (0..n-1) device number. + * @channel_addr: Guest physical address of the channel, which can be + * dereferenced by the receiver of this ControlVm command. + * @channel_bytes: Specifies size of the channel in bytes. + * @data_type_uuid: Specifies format of data in channel. + * @dev_inst_uuid: Instance guid for the device. + * @irq_info intr: Specifies interrupt information. + */ struct controlvm_packet_device_create { - u32 bus_no; /* bus # (0..n-1) from the msg receiver's end */ - u32 dev_no; /* bus-relative (0..n-1) device number */ - /* Guest physical address of the channel, which can be dereferenced by - * the receiver of this ControlVm command - */ + u32 bus_no; + u32 dev_no; u64 channel_addr; - u64 channel_bytes; /* specifies size of the channel in bytes */ - uuid_le data_type_uuid; /* specifies format of data in channel */ - uuid_le dev_inst_uuid; /* instance guid for the device */ - struct irq_info intr; /* specifies interrupt information */ -} __packed; /* for CONTROLVM_DEVICE_CREATE */ + u64 channel_bytes; + guid_t data_type_guid; + guid_t dev_inst_guid; + struct irq_info intr; +} __packed; +/* + * struct controlvm_packet_device_configure - For CONTROLVM_DEVICE_CONFIGURE + * @bus_no: Bus number (0..n-1) from the msg receiver's perspective. + * @dev_no: Bus-relative (0..n-1) device number. + */ struct controlvm_packet_device_configure { - /* bus # (0..n-1) from the msg receiver's perspective */ u32 bus_no; - /* Control uses header SegmentIndex field to access bus number... */ - u32 dev_no; /* bus-relative (0..n-1) device number */ -} __packed; /* for CONTROLVM_DEVICE_CONFIGURE */ + u32 dev_no; +} __packed; +/* Total 128 bytes */ struct controlvm_message_device_create { struct controlvm_message_header header; struct controlvm_packet_device_create packet; -} __packed; /* total 128 bytes */ +} __packed; +/* Total 56 bytes */ struct controlvm_message_device_configure { struct controlvm_message_header header; struct controlvm_packet_device_configure packet; -} __packed; /* total 56 bytes */ +} __packed; -/* This is the format for a message in any ControlVm queue. */ +/* + * struct controlvm_message_packet - This is the format for a message in any + * ControlVm queue. + * @struct create_bus: For CONTROLVM_BUS_CREATE. + * @bus_no: Bus # (0..n-1) from the msg receiver's perspective. + * @dev_count: Indicates the max number of devices on this bus. + * @channel_addr: Guest physical address of the channel, which can be + * dereferenced by the receiver of this ControlVM + * command. + * @channel_bytes: Size of the channel. + * @bus_data_type_uuid: Indicates format of data in bus channel. + * @bus_inst_uuid: Instance uuid for the bus. + * + * @struct destroy_bus: For CONTROLVM_BUS_DESTROY. + * @bus_no: Bus # (0..n-1) from the msg receiver's perspective. + * @reserved: Natural alignment purposes. + * + * @struct configure_bus: For CONTROLVM_BUS_CONFIGURE. + * @bus_no: Bus # (0..n-1) from the receiver's perspective. + * @reserved1: For alignment purposes. + * @guest_handle: This is used to convert guest physical address to + * physical address. + * @recv_bus_irq_handle: Specifies interrupt info. It is used by SP to + * register to receive interrupts from the CP. This + * interrupt is used for bus level notifications. + * The corresponding sendBusInterruptHandle is kept + * in CP. + * + * @struct create_device: For CONTROLVM_DEVICE_CREATE. + * + * @struct destroy_device: For CONTROLVM_DEVICE_DESTROY. + * @bus_no: Bus # (0..n-1) from the msg receiver's perspective. + * @dev_no: Bus-relative (0..n-1) device number. + * + * @struct configure_device: For CONTROLVM_DEVICE_CONFIGURE. + * + * @struct reconfigure_device: For CONTROLVM_DEVICE_RECONFIGURE. + * @bus_no: Bus # (0..n-1) from the msg receiver's perspective. + * @dev_no: Bus-relative (0..n-1) device number. + * + * @struct bus_change_state: For CONTROLVM_BUS_CHANGESTATE. + * @bus_no: + * @struct state: + * @reserved: Natural alignment purposes. + * + * @struct device_change_state: For CONTROLVM_DEVICE_CHANGESTATE. + * @bus_no: + * @dev_no: + * @struct state: + * @struct flags: + * @phys_device: =1 if message is for a physical device. + * @reserved: Natural alignment. + * @reserved1: Natural alignment. + * @reserved: Natural alignment purposes. + * + * @struct device_change_state_event: For CONTROLVM_DEVICE_CHANGESTATE_EVENT. + * @bus_no: + * @dev_no: + * @struct state: + * @reserved: Natural alignment purposes. + * + * @struct init_chipset: For CONTROLVM_CHIPSET_INIT. + * @bus_count: Indicates the max number of busses. + * @switch_count: Indicates the max number of switches. + * @enum features: + * @platform_number: + * + * @struct chipset_selftest: For CONTROLVM_CHIPSET_SELFTEST. + * @options: Reserved. + * @test: Bit 0 set to run embedded selftest. + * + * @addr: A physical address of something, that can be dereferenced by the + * receiver of this ControlVm command. + * + * @handle: A handle of something (depends on command id). + */ struct controlvm_message_packet { union { struct { - /* bus # (0..n-1) from the msg receiver's perspective */ u32 bus_no; - /* indicates the max number of devices on this bus */ u32 dev_count; - /* Guest physical address of the channel, which can be - * dereferenced by the receiver of this ControlVm command - */ u64 channel_addr; - u64 channel_bytes; /* size of the channel */ - /* indicates format of data in bus channel*/ - uuid_le bus_data_type_uuid; - uuid_le bus_inst_uuid; /* instance uuid for the bus */ - } __packed create_bus; /* for CONTROLVM_BUS_CREATE */ + u64 channel_bytes; + guid_t bus_data_type_guid; + guid_t bus_inst_guid; + } __packed create_bus; struct { - /* bus # (0..n-1) from the msg receiver's perspective */ u32 bus_no; - u32 reserved; /* Natural alignment purposes */ - } __packed destroy_bus; /* for CONTROLVM_BUS_DESTROY */ + u32 reserved; + } __packed destroy_bus; struct { - /* bus # (0..n-1) from the receiver's perspective */ u32 bus_no; - u32 reserved1; /* for alignment purposes */ - /* This is used to convert guest physical address to physical address */ + u32 reserved1; u64 guest_handle; u64 recv_bus_irq_handle; - /* specifies interrupt info. It is used by SP - * to register to receive interrupts from the - * CP. This interrupt is used for bus level - * notifications. The corresponding - * sendBusInterruptHandle is kept in CP. - */ - } __packed configure_bus; /* for CONTROLVM_BUS_CONFIGURE */ - /* for CONTROLVM_DEVICE_CREATE */ + } __packed configure_bus; struct controlvm_packet_device_create create_device; struct { - /* bus # (0..n-1) from the msg receiver's perspective */ u32 bus_no; - u32 dev_no; /* bus-relative (0..n-1) device # */ - } __packed destroy_device; /* for CONTROLVM_DEVICE_DESTROY */ - /* for CONTROLVM_DEVICE_CONFIGURE */ + u32 dev_no; + } __packed destroy_device; struct controlvm_packet_device_configure configure_device; struct { - /* bus # (0..n-1) from the msg receiver's perspective */ u32 bus_no; - u32 dev_no; /* bus-relative (0..n-1) device # */ + u32 dev_no; } __packed reconfigure_device; - /* for CONTROLVM_DEVICE_RECONFIGURE */ struct { u32 bus_no; struct visor_segment_state state; - u8 reserved[2]; /* Natural alignment purposes */ - } __packed bus_change_state; /* for CONTROLVM_BUS_CHANGESTATE */ + u8 reserved[2]; + } __packed bus_change_state; struct { u32 bus_no; u32 dev_no; struct visor_segment_state state; struct { - /* =1 if message is for a physical device */ u32 phys_device:1; - u32 reserved:31; /* Natural alignment */ - u32 reserved1; /* Natural alignment */ + u32 reserved:31; + u32 reserved1; } __packed flags; - u8 reserved[2]; /* Natural alignment purposes */ + u8 reserved[2]; } __packed device_change_state; - /* for CONTROLVM_DEVICE_CHANGESTATE */ struct { u32 bus_no; u32 dev_no; struct visor_segment_state state; - u8 reserved[6]; /* Natural alignment purposes */ + u8 reserved[6]; } __packed device_change_state_event; - /* for CONTROLVM_DEVICE_CHANGESTATE_EVENT */ struct { - /* indicates the max number of busses */ u32 bus_count; - /* indicates the max number of switches */ u32 switch_count; enum visor_chipset_feature features; - u32 platform_number; /* Platform Number */ - } __packed init_chipset; /* for CONTROLVM_CHIPSET_INIT */ + u32 platform_number; + } __packed init_chipset; struct { - u32 options; /* reserved */ - u32 test; /* bit 0 set to run embedded selftest */ + u32 options; + u32 test; } __packed chipset_selftest; - /* for CONTROLVM_CHIPSET_SELFTEST */ - /* a physical address of something, that can be dereferenced - * by the receiver of this ControlVm command - */ u64 addr; - /* a handle of something (depends on command id) */ u64 handle; }; } __packed; @@ -348,93 +437,139 @@ struct controlvm_message { struct controlvm_message_packet cmd; } __packed; +/* + * struct visor_controlvm_channel + * @struct header: + * @gp_controlvm: Guest phys addr of this channel. + * @gp_partition_tables: Guest phys addr of partition tables. + * @gp_diag_guest: Guest phys addr of diagnostic channel. + * @gp_boot_romdisk: Guest phys addr of (read* only) Boot + * ROM disk. + * @gp_boot_ramdisk: Guest phys addr of writable Boot RAM + * disk. + * @gp_acpi_table: Guest phys addr of acpi table. + * @gp_control_channel: Guest phys addr of control channel. + * @gp_diag_romdisk: Guest phys addr of diagnostic ROM disk. + * @gp_nvram: Guest phys addr of NVRAM channel. + * @request_payload_offset: Offset to request payload area. + * @event_payload_offset: Offset to event payload area. + * @request_payload_bytes: Bytes available in request payload area. + * @event_payload_bytes: Bytes available in event payload area. + * @control_channel_bytes: + * @nvram_channel_bytes: Bytes in PartitionNvram segment. + * @message_bytes: sizeof(CONTROLVM_MESSAGE). + * @message_count: CONTROLVM_MESSAGE_MAX. + * @gp_smbios_table: Guest phys addr of SMBIOS tables. + * @gp_physical_smbios_table: Guest phys addr of SMBIOS table. + * @gp_reserved: VISOR_MAX_GUESTS_PER_SERVICE. + * @virtual_guest_firmware_image_base: Guest physical address of EFI firmware + * image base. + * @virtual_guest_firmware_entry_point: Guest physical address of EFI firmware + * entry point. + * @virtual_guest_firmware_image_size: Guest EFI firmware image size. + * @virtual_guest_firmware_boot_base: GPA = 1MB where EFI firmware image is + * copied to. + * @virtual_guest_image_base: + * @virtual_guest_image_size: + * @prototype_control_channel_offset: + * @virtual_guest_partition_handle: + * @restore_action: Restore Action field to restore the + * guest partition. + * @dump_action: For Windows guests it shows if the + * visordisk is in dump mode. + * @nvram_fail_count: + * @saved_crash_message_count: = CONTROLVM_CRASHMSG_MAX. + * @saved_crash_message_offset: Offset to request payload area needed + * for crash dump. + * @installation_error: Type of error encountered during + * installation. + * @installation_text_id: Id of string to display. + * @installation_remaining_steps: Number of remaining installation steps + * (for progress bars). + * @tool_action: VISOR_TOOL_ACTIONS Installation Action + * field. + * @reserved: Alignment. + * @struct efi_visor_ind: + * @sp_reserved: + * @reserved2: Force signals to begin on 128-byte + * cache line. + * @struct request_queue: Guest partition uses this queue to send + * requests to Control. + * @struct response_queue: Control uses this queue to respond to + * service or guest partition request. + * @struct event_queue: Control uses this queue to send events + * to guest partition. + * @struct event_ack_queue: Service or guest partition uses this + * queue to ack Control events. + * @struct request_msg: Request fixed-size message pool - + * does not include payload. + * @struct response_msg: Response fixed-size message pool - + * does not include payload. + * @struct event_msg: Event fixed-size message pool - + * does not include payload. + * @struct event_ack_msg: Ack fixed-size message pool - + * does not include payload. + * @struct saved_crash_msg: Message stored during IOVM creation to + * be reused after crash. + */ struct visor_controlvm_channel { struct channel_header header; - u64 gp_controlvm; /* guest phys addr of this channel */ - u64 gp_partition_tables;/* guest phys addr of partition tables */ - u64 gp_diag_guest; /* guest phys addr of diagnostic channel */ - u64 gp_boot_romdisk;/* guest phys addr of (read* only) Boot ROM disk */ - u64 gp_boot_ramdisk;/* guest phys addr of writable Boot RAM disk */ - u64 gp_acpi_table; /* guest phys addr of acpi table */ - u64 gp_control_channel;/* guest phys addr of control channel */ - u64 gp_diag_romdisk;/* guest phys addr of diagnostic ROM disk */ - u64 gp_nvram; /* guest phys addr of NVRAM channel */ - u64 request_payload_offset; /* Offset to request payload area */ - u64 event_payload_offset; /* Offset to event payload area */ - /* Bytes available in request payload area */ + u64 gp_controlvm; + u64 gp_partition_tables; + u64 gp_diag_guest; + u64 gp_boot_romdisk; + u64 gp_boot_ramdisk; + u64 gp_acpi_table; + u64 gp_control_channel; + u64 gp_diag_romdisk; + u64 gp_nvram; + u64 request_payload_offset; + u64 event_payload_offset; u32 request_payload_bytes; - u32 event_payload_bytes;/* Bytes available in event payload area */ + u32 event_payload_bytes; u32 control_channel_bytes; - u32 nvram_channel_bytes; /* Bytes in PartitionNvram segment */ - u32 message_bytes; /* sizeof(CONTROLVM_MESSAGE) */ - u32 message_count; /* CONTROLVM_MESSAGE_MAX */ - u64 gp_smbios_table; /* guest phys addr of SMBIOS tables */ - u64 gp_physical_smbios_table; /* guest phys addr of SMBIOS table */ - /* VISOR_MAX_GUESTS_PER_SERVICE */ + u32 nvram_channel_bytes; + u32 message_bytes; + u32 message_count; + u64 gp_smbios_table; + u64 gp_physical_smbios_table; char gp_reserved[2688]; - - /* guest physical address of EFI firmware image base */ u64 virtual_guest_firmware_image_base; - - /* guest physical address of EFI firmware entry point */ u64 virtual_guest_firmware_entry_point; - - /* guest EFI firmware image size */ u64 virtual_guest_firmware_image_size; - - /* GPA = 1MB where EFI firmware image is copied to */ u64 virtual_guest_firmware_boot_base; u64 virtual_guest_image_base; u64 virtual_guest_image_size; u64 prototype_control_channel_offset; u64 virtual_guest_partition_handle; - /* Restore Action field to restore the guest partition */ u16 restore_action; - /* For Windows guests it shows if the visordisk is in dump mode */ u16 dump_action; u16 nvram_fail_count; - u16 saved_crash_message_count; /* = CONTROLVM_CRASHMSG_MAX */ - /* Offset to request payload area needed for crash dump */ + u16 saved_crash_message_count; u32 saved_crash_message_offset; - /* Type of error encountered during installation */ u32 installation_error; - u32 installation_text_id; /* Id of string to display */ - /* Number of remaining installation steps (for progress bars) */ + u32 installation_text_id; u16 installation_remaining_steps; - /* VISOR_TOOL_ACTIONS Installation Action field */ u8 tool_action; - u8 reserved; /* alignment */ + u8 reserved; struct efi_visor_indication efi_visor_ind; u32 sp_reserved; - /* Force signals to begin on 128-byte cache line */ u8 reserved2[28]; - /* guest partition uses this queue to send requests to Control */ struct signal_queue_header request_queue; - /* Control uses this queue to respond to service or guest - * partition requests - */ struct signal_queue_header response_queue; - /* Control uses this queue to send events to guest partition */ struct signal_queue_header event_queue; - /* Service or guest partition uses this queue to ack Control events */ struct signal_queue_header event_ack_queue; - /* Request fixed-size message pool - does not include payload */ - struct controlvm_message request_msg[CONTROLVM_MESSAGE_MAX]; - - /* Response fixed-size message pool - does not include payload */ - struct controlvm_message response_msg[CONTROLVM_MESSAGE_MAX]; - - /* Event fixed-size message pool - does not include payload */ - struct controlvm_message event_msg[CONTROLVM_MESSAGE_MAX]; - - /* Ack fixed-size message pool - does not include payload */ - struct controlvm_message event_ack_msg[CONTROLVM_MESSAGE_MAX]; - - /* Message stored during IOVM creation to be reused after crash */ - struct controlvm_message saved_crash_msg[CONTROLVM_CRASHMSG_MAX]; + struct controlvm_message request_msg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message response_msg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message event_msg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message event_ack_msg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message saved_crash_msg[CONTROLVM_CRASHMSG_MAX]; } __packed; -/* The following header will be located at the beginning of PayloadVmOffset for +/* + * struct visor_controlvm_parameters_header + * + * The following header will be located at the beginning of PayloadVmOffset for * various ControlVm commands. The receiver of a ControlVm command with a * PayloadVmOffset will dereference this address and then use connection_offset, * initiator_offset, and target_offset to get the location of UTF-8 formatted @@ -455,9 +590,10 @@ struct visor_controlvm_parameters_header { u32 client_length; u32 name_offset; u32 name_length; - uuid_le id; + guid_t id; u32 revision; - u32 reserved; /* Natural alignment */ + /* Natural alignment */ + u32 reserved; } __packed; /* General Errors------------------------------------------------------[0-99] */ @@ -467,72 +603,57 @@ struct visor_controlvm_parameters_header { #define CONTROLVM_RESP_KMALLOC_FAILED 3 #define CONTROLVM_RESP_ID_UNKNOWN 4 #define CONTROLVM_RESP_ID_INVALID_FOR_CLIENT 5 - /* CONTROLVM_INIT_CHIPSET-------------------------------------------[100-199] */ #define CONTROLVM_RESP_CLIENT_SWITCHCOUNT_NONZERO 100 #define CONTROLVM_RESP_EXPECTED_CHIPSET_INIT 101 - /* Maximum Limit----------------------------------------------------[200-299] */ -#define CONTROLVM_RESP_ERROR_MAX_BUSES 201 /* BUS_CREATE */ -#define CONTROLVM_RESP_ERROR_MAX_DEVICES 202 /* DEVICE_CREATE */ +/* BUS_CREATE */ +#define CONTROLVM_RESP_ERROR_MAX_BUSES 201 +/* DEVICE_CREATE */ +#define CONTROLVM_RESP_ERROR_MAX_DEVICES 202 /* Payload and Parameter Related------------------------------------[400-499] */ -#define CONTROLVM_RESP_PAYLOAD_INVALID 400 /* SWITCH_ATTACHEXTPORT, - * DEVICE_CONFIGURE - */ -#define CONTROLVM_RESP_INITIATOR_PARAMETER_INVALID 401 /* Multiple */ -#define CONTROLVM_RESP_TARGET_PARAMETER_INVALID 402 /* DEVICE_CONFIGURE */ -#define CONTROLVM_RESP_CLIENT_PARAMETER_INVALID 403 /* DEVICE_CONFIGURE */ -/* Specified[Packet Structure] Value-------------------------------[500-599] */ -#define CONTROLVM_RESP_BUS_INVALID 500 /* SWITCH_ATTACHINTPORT, - * BUS_CONFIGURE, - * DEVICE_CREATE, - * DEVICE_CONFIG - * DEVICE_DESTROY - */ -#define CONTROLVM_RESP_DEVICE_INVALID 501 /* SWITCH_ATTACHINTPORT*/ - /* DEVICE_CREATE, - * DEVICE_CONFIGURE, - * DEVICE_DESTROY - */ -#define CONTROLVM_RESP_CHANNEL_INVALID 502 /* DEVICE_CREATE, - * DEVICE_CONFIGURE - */ -/* Partition Driver Callback Interface----------------------[600-699] */ -#define CONTROLVM_RESP_VIRTPCI_DRIVER_FAILURE 604 /* BUS_CREATE, - * BUS_DESTROY, - * DEVICE_CREATE, - * DEVICE_DESTROY - */ -/* Unable to invoke VIRTPCI callback */ -#define CONTROLVM_RESP_VIRTPCI_DRIVER_CALLBACK_ERROR 605 /* BUS_CREATE, - * BUS_DESTROY, - * DEVICE_CREATE, - * DEVICE_DESTROY - */ -/* VIRTPCI Callback returned error */ +/* SWITCH_ATTACHEXTPORT, DEVICE_CONFIGURE */ +#define CONTROLVM_RESP_PAYLOAD_INVALID 400 +/* Multiple */ +#define CONTROLVM_RESP_INITIATOR_PARAMETER_INVALID 401 +/* DEVICE_CONFIGURE */ +#define CONTROLVM_RESP_TARGET_PARAMETER_INVALID 402 +/* DEVICE_CONFIGURE */ +#define CONTROLVM_RESP_CLIENT_PARAMETER_INVALID 403 +/* Specified[Packet Structure] Value--------------------------------[500-599] */ +/* SWITCH_ATTACHINTPORT */ +/* BUS_CONFIGURE, DEVICE_CREATE, DEVICE_CONFIG, DEVICE_DESTROY */ +#define CONTROLVM_RESP_BUS_INVALID 500 +/* SWITCH_ATTACHINTPORT*/ +/* DEVICE_CREATE, DEVICE_CONFIGURE, DEVICE_DESTROY */ +#define CONTROLVM_RESP_DEVICE_INVALID 501 +/* DEVICE_CREATE, DEVICE_CONFIGURE */ +#define CONTROLVM_RESP_CHANNEL_INVALID 502 +/* Partition Driver Callback Interface------------------------------[600-699] */ +/* BUS_CREATE, BUS_DESTROY, DEVICE_CREATE, DEVICE_DESTROY */ +#define CONTROLVM_RESP_VIRTPCI_DRIVER_FAILURE 604 +/* Unable to invoke VIRTPCI callback. VIRTPCI Callback returned error. */ +/* BUS_CREATE, BUS_DESTROY, DEVICE_CREATE, DEVICE_DESTROY */ +#define CONTROLVM_RESP_VIRTPCI_DRIVER_CALLBACK_ERROR 605 +/* Generic device callback returned error. */ +/* SWITCH_ATTACHEXTPORT, SWITCH_DETACHEXTPORT, DEVICE_CONFIGURE */ #define CONTROLVM_RESP_GENERIC_DRIVER_CALLBACK_ERROR 606 - /* SWITCH_ATTACHEXTPORT, - * SWITCH_DETACHEXTPORT - * DEVICE_CONFIGURE - */ - -/* generic device callback returned error */ /* Bus Related------------------------------------------------------[700-799] */ -#define CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED 700 /* BUS_DESTROY */ +/* BUS_DESTROY */ +#define CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED 700 /* Channel Related--------------------------------------------------[800-899] */ -#define CONTROLVM_RESP_CHANNEL_TYPE_UNKNOWN 800 /* GET_CHANNELINFO, - * DEVICE_DESTROY - */ -#define CONTROLVM_RESP_CHANNEL_SIZE_TOO_SMALL 801 /* DEVICE_CREATE */ +/* GET_CHANNELINFO, DEVICE_DESTROY */ +#define CONTROLVM_RESP_CHANNEL_TYPE_UNKNOWN 800 +/* DEVICE_CREATE */ +#define CONTROLVM_RESP_CHANNEL_SIZE_TOO_SMALL 801 /* Chipset Shutdown Related---------------------------------------[1000-1099] */ #define CONTROLVM_RESP_CHIPSET_SHUTDOWN_FAILED 1000 #define CONTROLVM_RESP_CHIPSET_SHUTDOWN_ALREADY_ACTIVE 1001 - /* Chipset Stop Related-------------------------------------------[1100-1199] */ #define CONTROLVM_RESP_CHIPSET_STOP_FAILED_BUS 1100 #define CONTROLVM_RESP_CHIPSET_STOP_FAILED_SWITCH 1101 - /* Device Related-------------------------------------------------[1400-1499] */ #define CONTROLVM_RESP_DEVICE_UDEV_TIMEOUT 1400 -#endif /* __CONTROLVMCHANNEL_H__ */ +/* __CONTROLVMCHANNEL_H__ */ +#endif diff --git a/drivers/staging/unisys/visorbus/vbuschannel.h b/drivers/staging/unisys/visorbus/vbuschannel.h index 01d7d517dba7..27e04de14818 100644 --- a/drivers/staging/unisys/visorbus/vbuschannel.h +++ b/drivers/staging/unisys/visorbus/vbuschannel.h @@ -1,4 +1,5 @@ -/* Copyright (C) 2010 - 2015 UNISYS CORPORATION +/* + * Copyright (C) 2010 - 2015 UNISYS CORPORATION * All rights reserved. * * This program is free software; you can redistribute it and/or modify it @@ -15,26 +16,26 @@ #ifndef __VBUSCHANNEL_H__ #define __VBUSCHANNEL_H__ -/* The vbus channel is the channel area provided via the BUS_CREATE controlvm - * message for each virtual bus. This channel area is provided to both server - * and client ends of the bus. The channel header area is initialized by - * the server, and the remaining information is filled in by the client. - * We currently use this for the client to provide various information about - * the client devices and client drivers for the server end to see. +/* + * The vbus channel is the channel area provided via the BUS_CREATE controlvm + * message for each virtual bus. This channel area is provided to both server + * and client ends of the bus. The channel header area is initialized by + * the server, and the remaining information is filled in by the client. + * We currently use this for the client to provide various information about + * the client devices and client drivers for the server end to see. */ + #include <linux/uuid.h> #include <linux/ctype.h> #include "channel.h" /* {193b331b-c58f-11da-95a9-00e08161165f} */ -#define VISOR_VBUS_CHANNEL_UUID \ - UUID_LE(0x193b331b, 0xc58f, 0x11da, \ - 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) -static const uuid_le visor_vbus_channel_uuid = VISOR_VBUS_CHANNEL_UUID; +#define VISOR_VBUS_CHANNEL_GUID \ + GUID_INIT(0x193b331b, 0xc58f, 0x11da, \ + 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) -#define VISOR_VBUS_CHANNEL_SIGNATURE VISOR_CHANNEL_SIGNATURE - -/* Must increment this whenever you insert or delete fields within this channel +/* + * Must increment this whenever you insert or delete fields within this channel * struct. Also increment whenever you change the meaning of fields within this * channel struct so as to break pre-existing software. Note that you can * usually add fields to the END of the channel struct withOUT needing to @@ -43,42 +44,63 @@ static const uuid_le visor_vbus_channel_uuid = VISOR_VBUS_CHANNEL_UUID; #define VISOR_VBUS_CHANNEL_VERSIONID 1 /* + * struct visor_vbus_deviceinfo + * @devtype: Short string identifying the device type. + * @drvname: Driver .sys file name. + * @infostrs: Kernel vversion. + * @reserved: Pad size to 256 bytes. + * * An array of this struct is present in the channel area for each vbus. - * (See vbuschannel.h.) - * It is filled in by the client side to provide info about the device - * and driver from the client's perspective. + * (See vbuschannel.h.). It is filled in by the client side to provide info + * about the device and driver from the client's perspective. */ struct visor_vbus_deviceinfo { - u8 devtype[16]; /* short string identifying the device type */ - u8 drvname[16]; /* driver .sys file name */ - u8 infostrs[96]; /* kernel version */ - u8 reserved[128]; /* pad size to 256 bytes */ + u8 devtype[16]; + u8 drvname[16]; + u8 infostrs[96]; + u8 reserved[128]; } __packed; +/* + * struct visor_vbus_headerinfo + * @struct_bytes: Size of this struct in bytes. + * @device_info_struct_bytes: Size of VISOR_VBUS_DEVICEINFO. + * @dev_info_count: Num of items in DevInfo member. This is the + * allocated size. + * @chp_info_offset: Byte offset from beginning of this struct to the + * ChpInfo struct. + * @bus_info_offset: Byte offset from beginning of this struct to the + * BusInfo struct. + * @dev_info_offset: Byte offset from beginning of this struct to the + * DevInfo array. + * @reserved: Natural Alignment + */ struct visor_vbus_headerinfo { - u32 struct_bytes; /* size of this struct in bytes */ - u32 device_info_struct_bytes; /* sizeof(VISOR_VBUS_DEVICEINFO) */ - u32 dev_info_count; /* num of items in DevInfo member */ - /* (this is the allocated size) */ - u32 chp_info_offset; /* byte offset from beginning of this struct */ - /* to the ChpInfo struct (below) */ - u32 bus_info_offset; /* byte offset from beginning of this struct */ - /* to the BusInfo struct (below) */ - u32 dev_info_offset; /* byte offset from beginning of this struct */ - /* to the DevInfo array (below) */ + u32 struct_bytes; + u32 device_info_struct_bytes; + u32 dev_info_count; + u32 chp_info_offset; + u32 bus_info_offset; + u32 dev_info_offset; u8 reserved[104]; } __packed; +/* + * struct visor_vbus_channel + * @channel_header: Initialized by server. + * @hdr_info: Initialized by server. + * @chp_info: Describes client chipset device and driver. + * @bus_info: Describes client bus device and driver. + * @dev_info: Describes client device and driver for each device on the + * bus. + */ struct visor_vbus_channel { - struct channel_header channel_header; /* initialized by server */ - struct visor_vbus_headerinfo hdr_info; /* initialized by server */ - /* the remainder of this channel is filled in by the client */ + struct channel_header channel_header; + struct visor_vbus_headerinfo hdr_info; + /* The remainder of this channel is filled in by the client */ struct visor_vbus_deviceinfo chp_info; - /* describes client chipset device and driver */ struct visor_vbus_deviceinfo bus_info; - /* describes client bus device and driver */ struct visor_vbus_deviceinfo dev_info[0]; - /* describes client device and driver for each device on the bus */ } __packed; #endif diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index 1c785dd19ddd..2bc7ff7bb96a 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -1,5 +1,4 @@ -/* visorbus_main.c - * +/* * Copyright � 2010 - 2015 UNISYS CORPORATION * All rights reserved. * @@ -20,15 +19,14 @@ #include "visorbus.h" #include "visorbus_private.h" -#define MYDRVNAME "visorbus" +static const guid_t visor_vbus_channel_guid = VISOR_VBUS_CHANNEL_GUID; -/* Display string that is guaranteed to be no longer the 99 characters*/ +/* Display string that is guaranteed to be no longer the 99 characters */ #define LINESIZE 99 - -#define CURRENT_FILE_PC VISOR_BUS_PC_visorbus_main_c #define POLLJIFFIES_NORMALCHANNEL 10 -static bool initialized; /* stores whether bus_registration was successful */ +/* stores whether bus_registration was successful */ +static bool initialized; static struct dentry *visorbus_debugfs_dir; /* @@ -40,11 +38,11 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { struct visor_device *vdev; - uuid_le guid; + const guid_t *guid; vdev = to_visor_device(dev); - guid = visorchannel_get_uuid(vdev->visorchannel); - return sprintf(buf, "visorbus:%pUl\n", &guid); + guid = visorchannel_get_guid(vdev->visorchannel); + return sprintf(buf, "visorbus:%pUl\n", guid); } static DEVICE_ATTR_RO(modalias); @@ -53,15 +51,7 @@ static struct attribute *visorbus_dev_attrs[] = { NULL, }; -/* sysfs example for bridge-only sysfs files using device_type's */ -static const struct attribute_group visorbus_dev_group = { - .attrs = visorbus_dev_attrs, -}; - -static const struct attribute_group *visorbus_dev_groups[] = { - &visorbus_dev_group, - NULL, -}; +ATTRIBUTE_GROUPS(visorbus_dev); /* filled in with info about parent chipset driver when we register with it */ static struct visor_vbus_deviceinfo chipset_driverinfo; @@ -73,16 +63,70 @@ static LIST_HEAD(list_all_bus_instances); /* list of visor_device structs, linked via .list_all */ static LIST_HEAD(list_all_device_instances); -static int -visorbus_uevent(struct device *xdev, struct kobj_uevent_env *env) +/* + * Generic function useful for validating any type of channel when it is + * received by the client that will be accessing the channel. + * Note that <logCtx> is only needed for callers in the EFI environment, and + * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages. + */ +int visor_check_channel(struct channel_header *ch, + struct device *dev, + const guid_t *expected_guid, + char *chname, + u64 expected_min_bytes, + u32 expected_version, + u64 expected_signature) +{ + if (!guid_is_null(expected_guid)) { + /* caller wants us to verify type GUID */ + if (!guid_equal(&ch->chtype, expected_guid)) { + dev_err(dev, "Channel mismatch on channel=%s(%pUL) field=type expected=%pUL actual=%pUL\n", + chname, expected_guid, expected_guid, + &ch->chtype); + return 0; + } + } + /* verify channel size */ + if (expected_min_bytes > 0) { + if (ch->size < expected_min_bytes) { + dev_err(dev, "Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8Lx actual=0x%-8.8Lx\n", + chname, expected_guid, + (unsigned long long)expected_min_bytes, + ch->size); + return 0; + } + } + /* verify channel version */ + if (expected_version > 0) { + if (ch->version_id != expected_version) { + dev_err(dev, "Channel mismatch on channel=%s(%pUL) field=version expected=0x%-8.8lx actual=0x%-8.8x\n", + chname, expected_guid, + (unsigned long)expected_version, + ch->version_id); + return 0; + } + } + /* verify channel signature */ + if (expected_signature > 0) { + if (ch->signature != expected_signature) { + dev_err(dev, "Channel mismatch on channel=%s(%pUL) field=signature expected=0x%-8.8Lx actual=0x%-8.8Lx\n", + chname, expected_guid, expected_signature, + ch->signature); + return 0; + } + } + return 1; +} + +static int visorbus_uevent(struct device *xdev, struct kobj_uevent_env *env) { struct visor_device *dev; - uuid_le guid; + const guid_t *guid; dev = to_visor_device(xdev); - guid = visorchannel_get_uuid(dev->visorchannel); + guid = visorchannel_get_guid(dev->visorchannel); - return add_uevent_var(env, "MODALIAS=visorbus:%pUl", &guid); + return add_uevent_var(env, "MODALIAS=visorbus:%pUl", guid); } /* @@ -94,27 +138,21 @@ visorbus_uevent(struct device *xdev, struct kobj_uevent_env *env) * * Return: 1 iff the provided driver can control the specified device */ -static int -visorbus_match(struct device *xdev, struct device_driver *xdrv) +static int visorbus_match(struct device *xdev, struct device_driver *xdrv) { - uuid_le channel_type; + const guid_t *channel_type; int i; struct visor_device *dev; struct visor_driver *drv; dev = to_visor_device(xdev); + channel_type = visorchannel_get_guid(dev->visorchannel); drv = to_visor_driver(xdrv); - channel_type = visorchannel_get_uuid(dev->visorchannel); - if (!drv->channel_types) return 0; - for (i = 0; - (uuid_le_cmp(drv->channel_types[i].guid, NULL_UUID_LE) != 0) || - (drv->channel_types[i].name); - i++) - if (uuid_le_cmp(drv->channel_types[i].guid, - channel_type) == 0) + for (i = 0; !guid_is_null(&drv->channel_types[i].guid); i++) + if (guid_equal(&drv->channel_types[i].guid, channel_type)) return i + 1; return 0; @@ -122,7 +160,7 @@ visorbus_match(struct device *xdev, struct device_driver *xdrv) /* * This describes the TYPE of bus. - * (Don't confuse this with an INSTANCE of the bus.) + * (Don't confuse this with an INSTANCE of the bus.) */ struct bus_type visorbus_type = { .name = "visorbus", @@ -137,8 +175,7 @@ struct bus_type visorbus_type = { * involved with destroying the dev are complete * @xdev: struct device for the bus being released */ -static void -visorbus_release_busdevice(struct device *xdev) +static void visorbus_release_busdevice(struct device *xdev) { struct visor_device *dev = dev_get_drvdata(xdev); @@ -152,15 +189,11 @@ visorbus_release_busdevice(struct device *xdev) * each child device instance * @xdev: struct device for the visor device being released */ -static void -visorbus_release_device(struct device *xdev) +static void visorbus_release_device(struct device *xdev) { struct visor_device *dev = to_visor_device(xdev); - if (dev->visorchannel) { - visorchannel_destroy(dev->visorchannel); - dev->visorchannel = NULL; - } + visorchannel_destroy(dev->visorchannel); kfree(dev); } @@ -229,7 +262,7 @@ static ssize_t typename_show(struct device *dev, struct device_attribute *attr, struct device_driver *xdrv = dev->driver; struct visor_driver *drv = NULL; - if (!xbus || !xdrv) + if (!xdrv) return 0; i = xbus->match(dev, xdrv); if (!i) @@ -240,24 +273,16 @@ static ssize_t typename_show(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR_RO(typename); static struct attribute *channel_attrs[] = { - &dev_attr_physaddr.attr, - &dev_attr_nbytes.attr, - &dev_attr_clientpartition.attr, - &dev_attr_typeguid.attr, - &dev_attr_zoneguid.attr, - &dev_attr_typename.attr, - NULL + &dev_attr_physaddr.attr, + &dev_attr_nbytes.attr, + &dev_attr_clientpartition.attr, + &dev_attr_typeguid.attr, + &dev_attr_zoneguid.attr, + &dev_attr_typename.attr, + NULL }; -static struct attribute_group channel_attr_grp = { - .name = "channel", - .attrs = channel_attrs, -}; - -static const struct attribute_group *visorbus_channel_groups[] = { - &channel_attr_grp, - NULL -}; +ATTRIBUTE_GROUPS(channel); /* end implementation of specific channel attributes */ @@ -270,7 +295,8 @@ static const struct attribute_group *visorbus_channel_groups[] = { static ssize_t partition_handle_show(struct device *dev, struct device_attribute *attr, - char *buf) { + char *buf) +{ struct visor_device *vdev = to_visor_device(dev); u64 handle = visorchannel_get_clientpartition(vdev->visorchannel); @@ -280,16 +306,18 @@ static DEVICE_ATTR_RO(partition_handle); static ssize_t partition_guid_show(struct device *dev, struct device_attribute *attr, - char *buf) { + char *buf) +{ struct visor_device *vdev = to_visor_device(dev); - return sprintf(buf, "{%pUb}\n", &vdev->partition_uuid); + return sprintf(buf, "{%pUb}\n", &vdev->partition_guid); } static DEVICE_ATTR_RO(partition_guid); static ssize_t partition_name_show(struct device *dev, struct device_attribute *attr, - char *buf) { + char *buf) +{ struct visor_device *vdev = to_visor_device(dev); return sprintf(buf, "%s\n", vdev->name); @@ -298,7 +326,8 @@ static DEVICE_ATTR_RO(partition_name); static ssize_t channel_addr_show(struct device *dev, struct device_attribute *attr, - char *buf) { + char *buf) +{ struct visor_device *vdev = to_visor_device(dev); u64 addr = visorchannel_get_physaddr(vdev->visorchannel); @@ -308,7 +337,8 @@ static DEVICE_ATTR_RO(channel_addr); static ssize_t channel_bytes_show(struct device *dev, struct device_attribute *attr, - char *buf) { + char *buf) +{ struct visor_device *vdev = to_visor_device(dev); u64 nbytes = visorchannel_get_nbytes(vdev->visorchannel); @@ -318,7 +348,8 @@ static DEVICE_ATTR_RO(channel_bytes); static ssize_t channel_id_show(struct device *dev, struct device_attribute *attr, - char *buf) { + char *buf) +{ struct visor_device *vdev = to_visor_device(dev); int len = 0; @@ -330,24 +361,17 @@ static ssize_t channel_id_show(struct device *dev, } static DEVICE_ATTR_RO(channel_id); -static struct attribute *dev_attrs[] = { - &dev_attr_partition_handle.attr, - &dev_attr_partition_guid.attr, - &dev_attr_partition_name.attr, - &dev_attr_channel_addr.attr, - &dev_attr_channel_bytes.attr, - &dev_attr_channel_id.attr, - NULL -}; - -static struct attribute_group dev_attr_grp = { - .attrs = dev_attrs, +static struct attribute *visorbus_attrs[] = { + &dev_attr_partition_handle.attr, + &dev_attr_partition_guid.attr, + &dev_attr_partition_name.attr, + &dev_attr_channel_addr.attr, + &dev_attr_channel_bytes.attr, + &dev_attr_channel_id.attr, + NULL }; -static const struct attribute_group *visorbus_groups[] = { - &dev_attr_grp, - NULL -}; +ATTRIBUTE_GROUPS(visorbus); /* * BUS debugfs entries @@ -355,6 +379,7 @@ static const struct attribute_group *visorbus_groups[] = { * define & implement display of debugfs attributes under * /sys/kernel/debug/visorbus/visorbus<n>. */ + /* * vbuschannel_print_devinfo() - format a struct visor_vbus_deviceinfo * and write it to a seq_file @@ -365,12 +390,12 @@ static const struct attribute_group *visorbus_groups[] = { * * Reads @devInfo, and writes it in human-readable notation to @seq. */ -static void -vbuschannel_print_devinfo(struct visor_vbus_deviceinfo *devinfo, - struct seq_file *seq, int devix) +static void vbuschannel_print_devinfo(struct visor_vbus_deviceinfo *devinfo, + struct seq_file *seq, int devix) { + /* uninitialized vbus device entry */ if (!isprint(devinfo->devtype[0])) - return; /* uninitialized vbus device entry */ + return; if (devix >= 0) seq_printf(seq, "[%d]", devix); @@ -392,12 +417,11 @@ vbuschannel_print_devinfo(struct visor_vbus_deviceinfo *devinfo, static int client_bus_info_debugfs_show(struct seq_file *seq, void *v) { - struct visor_device *vdev = seq->private; - struct visorchannel *channel = vdev->visorchannel; - - int i; + int i = 0; unsigned long off; struct visor_vbus_deviceinfo dev_info; + struct visor_device *vdev = seq->private; + struct visorchannel *channel = vdev->visorchannel; if (!channel) return 0; @@ -406,6 +430,7 @@ static int client_bus_info_debugfs_show(struct seq_file *seq, void *v) "Client device / client driver info for %s partition (vbus #%u):\n", ((vdev->name) ? (char *)(vdev->name) : ""), vdev->chipset_bus_no); + if (visorchannel_read(channel, offsetof(struct visor_vbus_channel, chp_info), &dev_info, sizeof(dev_info)) >= 0) @@ -414,8 +439,8 @@ static int client_bus_info_debugfs_show(struct seq_file *seq, void *v) offsetof(struct visor_vbus_channel, bus_info), &dev_info, sizeof(dev_info)) >= 0) vbuschannel_print_devinfo(&dev_info, seq, -1); + off = offsetof(struct visor_vbus_channel, dev_info); - i = 0; while (off + sizeof(dev_info) <= visorchannel_get_nbytes(channel)) { if (visorchannel_read(channel, off, &dev_info, sizeof(dev_info)) >= 0) @@ -441,8 +466,7 @@ static const struct file_operations client_bus_info_debugfs_fops = { .release = single_release, }; -static void -dev_periodic_work(unsigned long __opaque) +static void dev_periodic_work(unsigned long __opaque) { struct visor_device *dev = (struct visor_device *)__opaque; struct visor_driver *drv = to_visor_driver(dev->device.driver); @@ -451,8 +475,7 @@ dev_periodic_work(unsigned long __opaque) mod_timer(&dev->timer, jiffies + POLLJIFFIES_NORMALCHANNEL); } -static int -dev_start_periodic_work(struct visor_device *dev) +static int dev_start_periodic_work(struct visor_device *dev) { if (dev->being_removed || dev->timer_active) return -EINVAL; @@ -464,8 +487,7 @@ dev_start_periodic_work(struct visor_device *dev) return 0; } -static void -dev_stop_periodic_work(struct visor_device *dev) +static void dev_stop_periodic_work(struct visor_device *dev) { if (!dev->timer_active) return; @@ -484,40 +506,39 @@ dev_stop_periodic_work(struct visor_device *dev) * * Return: 0 iff successful */ -static int -visordriver_remove_device(struct device *xdev) +static int visordriver_remove_device(struct device *xdev) { struct visor_device *dev; struct visor_driver *drv; dev = to_visor_device(xdev); drv = to_visor_driver(xdev->driver); + mutex_lock(&dev->visordriver_callback_lock); dev->being_removed = true; - if (drv->remove) - drv->remove(dev); + drv->remove(dev); mutex_unlock(&dev->visordriver_callback_lock); - dev_stop_periodic_work(dev); + dev_stop_periodic_work(dev); put_device(&dev->device); + return 0; } -/** +/* * visorbus_unregister_visor_driver() - unregisters the provided driver * @drv: the driver to unregister * * A visor function driver calls this function to unregister the driver, * i.e., within its module_exit function. */ -void -visorbus_unregister_visor_driver(struct visor_driver *drv) +void visorbus_unregister_visor_driver(struct visor_driver *drv) { driver_unregister(&drv->driver); } EXPORT_SYMBOL_GPL(visorbus_unregister_visor_driver); -/** +/* * visorbus_read_channel() - reads from the designated channel into * the provided buffer * @dev: the device whose channel is read from @@ -530,15 +551,14 @@ EXPORT_SYMBOL_GPL(visorbus_unregister_visor_driver); * * Return: integer indicating success (zero) or failure (non-zero) */ -int -visorbus_read_channel(struct visor_device *dev, unsigned long offset, - void *dest, unsigned long nbytes) +int visorbus_read_channel(struct visor_device *dev, unsigned long offset, + void *dest, unsigned long nbytes) { return visorchannel_read(dev->visorchannel, offset, dest, nbytes); } EXPORT_SYMBOL_GPL(visorbus_read_channel); -/** +/* * visorbus_write_channel() - writes the provided buffer into the designated * channel * @dev: the device whose channel is written to @@ -551,15 +571,14 @@ EXPORT_SYMBOL_GPL(visorbus_read_channel); * * Return: integer indicating success (zero) or failure (non-zero) */ -int -visorbus_write_channel(struct visor_device *dev, unsigned long offset, - void *src, unsigned long nbytes) +int visorbus_write_channel(struct visor_device *dev, unsigned long offset, + void *src, unsigned long nbytes) { return visorchannel_write(dev->visorchannel, offset, src, nbytes); } EXPORT_SYMBOL_GPL(visorbus_write_channel); -/** +/* * visorbus_enable_channel_interrupts() - enables interrupts on the * designated device * @dev: the device on which to enable interrupts @@ -567,8 +586,7 @@ EXPORT_SYMBOL_GPL(visorbus_write_channel); * Currently we don't yet have a real interrupt, so for now we just call the * interrupt function periodically via a timer. */ -int -visorbus_enable_channel_interrupts(struct visor_device *dev) +int visorbus_enable_channel_interrupts(struct visor_device *dev) { struct visor_driver *drv = to_visor_driver(dev->device.driver); @@ -581,13 +599,12 @@ visorbus_enable_channel_interrupts(struct visor_device *dev) } EXPORT_SYMBOL_GPL(visorbus_enable_channel_interrupts); -/** +/* * visorbus_disable_channel_interrupts() - disables interrupts on the * designated device * @dev: the device on which to disable interrupts */ -void -visorbus_disable_channel_interrupts(struct visor_device *dev) +void visorbus_disable_channel_interrupts(struct visor_device *dev) { dev_stop_periodic_work(dev); } @@ -616,8 +633,7 @@ EXPORT_SYMBOL_GPL(visorbus_disable_channel_interrupts); * Return: 0 if successful, otherwise the negative value returned by * device_add() indicating the reason for failure */ -static int -create_visor_device(struct visor_device *dev) +int create_visor_device(struct visor_device *dev) { int err; u32 chipset_bus_no = dev->chipset_bus_no; @@ -625,7 +641,7 @@ create_visor_device(struct visor_device *dev) mutex_init(&dev->visordriver_callback_lock); dev->device.bus = &visorbus_type; - dev->device.groups = visorbus_channel_groups; + dev->device.groups = channel_groups; device_initialize(&dev->device); dev->device.release = visorbus_release_device; /* keep a reference just for us (now 2) */ @@ -664,7 +680,10 @@ create_visor_device(struct visor_device *dev) goto err_put; list_add_tail(&dev->list_all, &list_all_device_instances); - return 0; /* success: reference kept via unmatched get_device() */ + dev->state.created = 1; + visorbus_response(dev, err, CONTROLVM_DEVICE_CREATE); + /* success: reference kept via unmatched get_device() */ + return 0; err_put: put_device(&dev->device); @@ -672,26 +691,27 @@ err_put: return err; } -static void -remove_visor_device(struct visor_device *dev) +void remove_visor_device(struct visor_device *dev) { list_del(&dev->list_all); put_device(&dev->device); device_unregister(&dev->device); + visorbus_response(dev, 0, CONTROLVM_DEVICE_DESTROY); } -static int -get_vbus_header_info(struct visorchannel *chan, - struct visor_vbus_headerinfo *hdr_info) +static int get_vbus_header_info(struct visorchannel *chan, + struct device *dev, + struct visor_vbus_headerinfo *hdr_info) { int err; if (!visor_check_channel(visorchannel_get_header(chan), - visor_vbus_channel_uuid, + dev, + &visor_vbus_channel_guid, "vbus", sizeof(struct visor_vbus_channel), VISOR_VBUS_CHANNEL_VERSIONID, - VISOR_VBUS_CHANNEL_SIGNATURE)) + VISOR_CHANNEL_SIGNATURE)) return -EINVAL; err = visorchannel_read(chan, sizeof(struct channel_header), hdr_info, @@ -722,10 +742,9 @@ get_vbus_header_info(struct visorchannel *chan, * Returns no value since this is debug information and not needed for * device functionality. */ -static void -write_vbus_chp_info(struct visorchannel *chan, - struct visor_vbus_headerinfo *hdr_info, - struct visor_vbus_deviceinfo *info) +static void write_vbus_chp_info(struct visorchannel *chan, + struct visor_vbus_headerinfo *hdr_info, + struct visor_vbus_deviceinfo *info) { int off = sizeof(struct channel_header) + hdr_info->chp_info_offset; @@ -748,10 +767,9 @@ write_vbus_chp_info(struct visorchannel *chan, * Returns no value since this is debug information and not needed for * device functionality. */ -static void -write_vbus_bus_info(struct visorchannel *chan, - struct visor_vbus_headerinfo *hdr_info, - struct visor_vbus_deviceinfo *info) +static void write_vbus_bus_info(struct visorchannel *chan, + struct visor_vbus_headerinfo *hdr_info, + struct visor_vbus_deviceinfo *info) { int off = sizeof(struct channel_header) + hdr_info->bus_info_offset; @@ -775,10 +793,10 @@ write_vbus_bus_info(struct visorchannel *chan, * Returns no value since this is debug information and not needed for * device functionality. */ -static void -write_vbus_dev_info(struct visorchannel *chan, - struct visor_vbus_headerinfo *hdr_info, - struct visor_vbus_deviceinfo *info, unsigned int devix) +static void write_vbus_dev_info(struct visorchannel *chan, + struct visor_vbus_headerinfo *hdr_info, + struct visor_vbus_deviceinfo *info, + unsigned int devix) { int off = (sizeof(struct channel_header) + hdr_info->dev_info_offset) + @@ -807,14 +825,13 @@ static void bus_device_info_init( } /* - * fix_vbus_dev_info() - for a child device just created on a client bus, fill - * in information about the driver that is controlling - * this device into the appropriate slot within the - * vbus channel of the bus instance + * publish_vbus_dev_info() - for a child device just created on a client bus, + * fill in information about the driver that is + * controlling this device into the appropriate slot + * within the vbus channel of the bus instance * @visordev: struct visor_device for the desired device */ -static void -fix_vbus_dev_info(struct visor_device *visordev) +static void publish_vbus_dev_info(struct visor_device *visordev) { int i; struct visor_device *bdev; @@ -853,7 +870,6 @@ fix_vbus_dev_info(struct visor_device *visordev) bus_device_info_init(&dev_info, chan_type_name, visordrv->name); write_vbus_dev_info(bdev->visorchannel, hdr_info, &dev_info, dev_no); - write_vbus_chp_info(bdev->visorchannel, hdr_info, &chipset_driverinfo); write_vbus_bus_info(bdev->visorchannel, hdr_info, &clientbus_driverinfo); @@ -874,18 +890,14 @@ fix_vbus_dev_info(struct visor_device *visordev) * was successful with this device, otherwise a negative errno * value indicating failure reason */ -static int -visordriver_probe_device(struct device *xdev) +static int visordriver_probe_device(struct device *xdev) { int res; struct visor_driver *drv; struct visor_device *dev; - drv = to_visor_driver(xdev->driver); dev = to_visor_device(xdev); - - if (!drv->probe) - return -ENODEV; + drv = to_visor_driver(xdev->driver); mutex_lock(&dev->visordriver_callback_lock); dev->being_removed = false; @@ -894,14 +906,14 @@ visordriver_probe_device(struct device *xdev) if (res >= 0) { /* success: reference kept via unmatched get_device() */ get_device(&dev->device); - fix_vbus_dev_info(dev); + publish_vbus_dev_info(dev); } mutex_unlock(&dev->visordriver_callback_lock); return res; } -/** +/* * visorbus_register_visor_driver() - registers the provided visor driver * for handling one or more visor device * types (channel_types) @@ -952,8 +964,21 @@ visordriver_probe_device(struct device *xdev) */ int visorbus_register_visor_driver(struct visor_driver *drv) { + /* can't register on a nonexistent bus */ if (!initialized) - return -ENODEV; /* can't register on a nonexistent bus */ + return -ENODEV; + + if (!drv->probe) + return -EINVAL; + + if (!drv->remove) + return -EINVAL; + + if (!drv->pause) + return -EINVAL; + + if (!drv->resume) + return -EINVAL; drv->driver.name = drv->name; drv->driver.bus = &visorbus_type; @@ -985,8 +1010,7 @@ EXPORT_SYMBOL_GPL(visorbus_register_visor_driver); * Return: 0 for success, otherwise negative errno value indicating reason for * failure */ -static int -visorbus_create_instance(struct visor_device *dev) +int visorbus_create_instance(struct visor_device *dev) { int id = dev->chipset_bus_no; int err; @@ -1009,7 +1033,7 @@ visorbus_create_instance(struct visor_device *dev) &client_bus_info_debugfs_fops); dev_set_drvdata(&dev->device, dev); - err = get_vbus_header_info(dev->visorchannel, hdr_info); + err = get_vbus_header_info(dev->visorchannel, &dev->device, hdr_info); if (err < 0) goto err_debugfs_dir; @@ -1019,18 +1043,21 @@ visorbus_create_instance(struct visor_device *dev) list_add_tail(&dev->list_all, &list_all_bus_instances); + dev->state.created = 1; dev->vbus_hdr_info = (void *)hdr_info; write_vbus_chp_info(dev->visorchannel, hdr_info, &chipset_driverinfo); write_vbus_bus_info(dev->visorchannel, hdr_info, &clientbus_driverinfo); + visorbus_response(dev, err, CONTROLVM_BUS_CREATE); + return 0; err_debugfs_dir: debugfs_remove_recursive(dev->debugfs_dir); kfree(hdr_info); - dev_err(&dev->device, "visorbus_create_instance failed: %d\n", err); + dev_err(&dev->device, "%s failed: %d\n", __func__, err); return err; } @@ -1038,8 +1065,7 @@ err_debugfs_dir: * visorbus_remove_instance() - remove a device instance for the visorbus itself * @dev: struct visor_device indentifying the bus to remove */ -static void -visorbus_remove_instance(struct visor_device *dev) +void visorbus_remove_instance(struct visor_device *dev) { /* * Note that this will result in the release method for @@ -1049,20 +1075,17 @@ visorbus_remove_instance(struct visor_device *dev) * successfully been able to trace thru the code to see where/how * release() gets called. But I know it does. */ - if (dev->visorchannel) { - visorchannel_destroy(dev->visorchannel); - dev->visorchannel = NULL; - } + visorchannel_destroy(dev->visorchannel); kfree(dev->vbus_hdr_info); list_del(&dev->list_all); device_unregister(&dev->device); + visorbus_response(dev, 0, CONTROLVM_BUS_DESTROY); } /* * remove_all_visor_devices() - remove all child visorbus device instances */ -static void -remove_all_visor_devices(void) +static void remove_all_visor_devices(void) { struct list_head *listentry, *listtmp; @@ -1074,50 +1097,6 @@ remove_all_visor_devices(void) } } -int -visorchipset_bus_create(struct visor_device *dev) -{ - int err; - - err = visorbus_create_instance(dev); - - if (err < 0) - return err; - - visorbus_create_response(dev, err); - - return 0; -} - -void -visorchipset_bus_destroy(struct visor_device *dev) -{ - visorbus_remove_instance(dev); - visorbus_destroy_response(dev, 0); -} - -int -visorchipset_device_create(struct visor_device *dev_info) -{ - int err; - - err = create_visor_device(dev_info); - if (err < 0) - return err; - - visorbus_device_create_response(dev_info, err); - - return 0; -} - -void -visorchipset_device_destroy(struct visor_device *dev_info) -{ - remove_visor_device(dev_info); - - visorbus_device_destroy_response(dev_info, 0); -} - /* * pause_state_change_complete() - the callback function to be called by a * visorbus function driver when a @@ -1127,15 +1106,14 @@ visorchipset_device_destroy(struct visor_device *dev_info) * @status: 0 iff the pause state change completed successfully, otherwise * a negative errno value indicating the reason for failure */ -static void -pause_state_change_complete(struct visor_device *dev, int status) +static void pause_state_change_complete(struct visor_device *dev, int status) { if (!dev->pausing) return; dev->pausing = false; - - visorbus_device_pause_response(dev, status); + visorbus_device_changestate_response(dev, status, + segment_state_standby); } /* @@ -1147,8 +1125,7 @@ pause_state_change_complete(struct visor_device *dev, int status) * @status: 0 iff the resume state change completed successfully, otherwise * a negative errno value indicating the reason for failure */ -static void -resume_state_change_complete(struct visor_device *dev, int status) +static void resume_state_change_complete(struct visor_device *dev, int status) { if (!dev->resuming) return; @@ -1160,7 +1137,8 @@ resume_state_change_complete(struct visor_device *dev, int status) * which will presumably want to send some sort of response to * the initiator. */ - visorbus_device_resume_response(dev, status); + visorbus_device_changestate_response(dev, status, + segment_state_running); } /* @@ -1174,34 +1152,28 @@ resume_state_change_complete(struct visor_device *dev, int status) * via a callback function; see pause_state_change_complete() and * resume_state_change_complete(). */ -static int -visorchipset_initiate_device_pause_resume(struct visor_device *dev, - bool is_pause) +static int visorchipset_initiate_device_pause_resume(struct visor_device *dev, + bool is_pause) { int err; struct visor_driver *drv = NULL; - drv = to_visor_driver(dev->device.driver); - if (!drv) - return -ENODEV; - + /* If no driver associated with the device nothing to pause/resume */ + if (!dev->device.driver) + return 0; if (dev->pausing || dev->resuming) return -EBUSY; + drv = to_visor_driver(dev->device.driver); if (is_pause) { - if (!drv->pause) - return -EINVAL; - dev->pausing = true; err = drv->pause(dev, pause_state_change_complete); } else { - /* The vbus_dev_info structure in the channel was been - * cleared, make sure it is valid. + /* + * The vbus_dev_info structure in the channel was been cleared, + * make sure it is valid. */ - fix_vbus_dev_info(dev); - if (!drv->resume) - return -EINVAL; - + publish_vbus_dev_info(dev); dev->resuming = true; err = drv->resume(dev, resume_state_change_complete); } @@ -1209,7 +1181,7 @@ visorchipset_initiate_device_pause_resume(struct visor_device *dev, return err; } -/** +/* * visorchipset_device_pause() - start a pause operation for a visor device * @dev_info: struct visor_device identifying the device being paused * @@ -1217,13 +1189,11 @@ visorchipset_initiate_device_pause_resume(struct visor_device *dev, * that device. Success/failure result is returned asynchronously * via a callback function; see pause_state_change_complete(). */ -int -visorchipset_device_pause(struct visor_device *dev_info) +int visorchipset_device_pause(struct visor_device *dev_info) { int err; err = visorchipset_initiate_device_pause_resume(dev_info, true); - if (err < 0) { dev_info->pausing = false; return err; @@ -1232,7 +1202,7 @@ visorchipset_device_pause(struct visor_device *dev_info) return 0; } -/** +/* * visorchipset_device_resume() - start a resume operation for a visor device * @dev_info: struct visor_device identifying the device being resumed * @@ -1240,13 +1210,11 @@ visorchipset_device_pause(struct visor_device *dev_info) * that device. Success/failure result is returned asynchronously * via a callback function; see resume_state_change_complete(). */ -int -visorchipset_device_resume(struct visor_device *dev_info) +int visorchipset_device_resume(struct visor_device *dev_info) { int err; err = visorchipset_initiate_device_pause_resume(dev_info, false); - if (err < 0) { dev_info->resuming = false; return err; @@ -1255,8 +1223,7 @@ visorchipset_device_resume(struct visor_device *dev_info) return 0; } -int -visorbus_init(void) +int visorbus_init(void) { int err; @@ -1271,14 +1238,12 @@ visorbus_init(void) return err; initialized = true; - bus_device_info_init(&chipset_driverinfo, "chipset", "visorchipset"); return 0; } -void -visorbus_exit(void) +void visorbus_exit(void) { struct list_head *listentry, *listtmp; diff --git a/drivers/staging/unisys/visorbus/visorbus_private.h b/drivers/staging/unisys/visorbus/visorbus_private.h index 98a5af19189d..e878d65ab668 100644 --- a/drivers/staging/unisys/visorbus/visorbus_private.h +++ b/drivers/staging/unisys/visorbus/visorbus_private.h @@ -1,5 +1,4 @@ -/* visorbus_private.h - * +/* * Copyright (C) 2010 - 2015 UNISYS CORPORATION * All rights reserved. * @@ -22,36 +21,27 @@ #include "controlvmchannel.h" #include "vbuschannel.h" +#include "visorbus.h" -/* TARGET_HOSTNAME specified as -DTARGET_HOSTNAME=\"thename\" on the - * command line - */ - -int visorchipset_bus_create(struct visor_device *bus_info); -void visorchipset_bus_destroy(struct visor_device *bus_info); -int visorchipset_device_create(struct visor_device *dev_info); -void visorchipset_device_destroy(struct visor_device *dev_info); +int visorbus_create_instance(struct visor_device *dev); +void visorbus_remove_instance(struct visor_device *bus_info); +int create_visor_device(struct visor_device *dev_info); +void remove_visor_device(struct visor_device *dev_info); int visorchipset_device_pause(struct visor_device *dev_info); int visorchipset_device_resume(struct visor_device *dev_info); -void visorbus_create_response(struct visor_device *p, int response); -void visorbus_destroy_response(struct visor_device *p, int response); -void visorbus_device_create_response(struct visor_device *p, int response); -void visorbus_device_destroy_response(struct visor_device *p, int response); -void visorbus_device_resume_response(struct visor_device *p, int response); -void visorbus_device_pause_response(struct visor_device *p, int response); +void visorbus_response(struct visor_device *p, int response, int controlvm_id); +void visorbus_device_changestate_response(struct visor_device *p, int response, + struct visor_segment_state state); int visorbus_init(void); void visorbus_exit(void); /* visorchannel access functions */ - -struct visorchannel *visorchannel_create(u64 physaddr, - unsigned long channel_bytes, - gfp_t gfp, uuid_le guid); -struct visorchannel *visorchannel_create_with_lock(u64 physaddr, - unsigned long channel_bytes, - gfp_t gfp, uuid_le guid); +struct visorchannel *visorchannel_create(u64 physaddr, gfp_t gfp, + const guid_t *guid); +struct visorchannel *visorchannel_create_with_lock(u64 physaddr, gfp_t gfp, + const guid_t *guid); void visorchannel_destroy(struct visorchannel *channel); int visorchannel_read(struct visorchannel *channel, ulong offset, void *dest, ulong nbytes); @@ -64,6 +54,6 @@ char *visorchannel_zoneid(struct visorchannel *channel, char *s); u64 visorchannel_get_clientpartition(struct visorchannel *channel); int visorchannel_set_clientpartition(struct visorchannel *channel, u64 partition_handle); -char *visorchannel_uuid_id(uuid_le *guid, char *s); +char *visorchannel_guid_id(const guid_t *guid, char *s); void *visorchannel_get_header(struct visorchannel *channel); #endif diff --git a/drivers/staging/unisys/visorbus/visorchannel.c b/drivers/staging/unisys/visorbus/visorchannel.c index 6885c2cb7135..2a000fee3119 100644 --- a/drivers/staging/unisys/visorbus/visorchannel.c +++ b/drivers/staging/unisys/visorbus/visorchannel.c @@ -1,5 +1,4 @@ -/* visorchannel_funcs.c - * +/* * Copyright (C) 2010 - 2015 UNISYS CORPORATION * All rights reserved. * @@ -26,13 +25,13 @@ #include "visorbus_private.h" #include "controlvmchannel.h" -#define MYDRVNAME "visorchannel" +#define VISOR_DRV_NAME "visorchannel" #define VISOR_CONSOLEVIDEO_CHANNEL_GUID \ - UUID_LE(0x3cd6e705, 0xd6a2, 0x4aa5, \ - 0xad, 0x5c, 0x7b, 0x8, 0x88, 0x9d, 0xff, 0xe2) + GUID_INIT(0x3cd6e705, 0xd6a2, 0x4aa5, \ + 0xad, 0x5c, 0x7b, 0x8, 0x88, 0x9d, 0xff, 0xe2) -static const uuid_le visor_video_guid = VISOR_CONSOLEVIDEO_CHANNEL_GUID; +static const guid_t visor_video_guid = VISOR_CONSOLEVIDEO_CHANNEL_GUID; struct visorchannel { u64 physaddr; @@ -40,18 +39,21 @@ struct visorchannel { void *mapped; bool requested; struct channel_header chan_hdr; - uuid_le guid; - bool needs_lock; /* channel creator knows if more than one */ - /* thread will be inserting or removing */ - spinlock_t insert_lock; /* protect head writes in chan_hdr */ - spinlock_t remove_lock; /* protect tail writes in chan_hdr */ - - uuid_le type; - uuid_le inst; + guid_t guid; + /* + * channel creator knows if more than one + * thread will be inserting or removing + */ + bool needs_lock; + /* protect head writes in chan_hdr */ + spinlock_t insert_lock; + /* protect tail writes in chan_hdr */ + spinlock_t remove_lock; + guid_t type; + guid_t inst; }; -void -visorchannel_destroy(struct visorchannel *channel) +void visorchannel_destroy(struct visorchannel *channel) { if (!channel) return; @@ -63,67 +65,58 @@ visorchannel_destroy(struct visorchannel *channel) kfree(channel); } -u64 -visorchannel_get_physaddr(struct visorchannel *channel) +u64 visorchannel_get_physaddr(struct visorchannel *channel) { return channel->physaddr; } -ulong -visorchannel_get_nbytes(struct visorchannel *channel) +ulong visorchannel_get_nbytes(struct visorchannel *channel) { return channel->nbytes; } -char * -visorchannel_uuid_id(uuid_le *guid, char *s) +char *visorchannel_guid_id(const guid_t *guid, char *s) { sprintf(s, "%pUL", guid); return s; } -char * -visorchannel_id(struct visorchannel *channel, char *s) +char *visorchannel_id(struct visorchannel *channel, char *s) { - return visorchannel_uuid_id(&channel->guid, s); + return visorchannel_guid_id(&channel->guid, s); } -char * -visorchannel_zoneid(struct visorchannel *channel, char *s) +char *visorchannel_zoneid(struct visorchannel *channel, char *s) { - return visorchannel_uuid_id(&channel->chan_hdr.zone_uuid, s); + return visorchannel_guid_id(&channel->chan_hdr.zone_guid, s); } -u64 -visorchannel_get_clientpartition(struct visorchannel *channel) +u64 visorchannel_get_clientpartition(struct visorchannel *channel) { return channel->chan_hdr.partition_handle; } -int -visorchannel_set_clientpartition(struct visorchannel *channel, - u64 partition_handle) +int visorchannel_set_clientpartition(struct visorchannel *channel, + u64 partition_handle) { channel->chan_hdr.partition_handle = partition_handle; return 0; } /** - * visorchannel_get_uuid() - queries the UUID of the designated channel + * visorchannel_get_guid() - queries the GUID of the designated channel * @channel: the channel to query * - * Return: the UUID of the provided channel + * Return: the GUID of the provided channel */ -uuid_le -visorchannel_get_uuid(struct visorchannel *channel) +const guid_t *visorchannel_get_guid(struct visorchannel *channel) { - return channel->guid; + return &channel->guid; } -EXPORT_SYMBOL_GPL(visorchannel_get_uuid); +EXPORT_SYMBOL_GPL(visorchannel_get_guid); -int -visorchannel_read(struct visorchannel *channel, ulong offset, - void *dest, ulong nbytes) +int visorchannel_read(struct visorchannel *channel, ulong offset, void *dest, + ulong nbytes) { if (offset + nbytes > channel->nbytes) return -EIO; @@ -133,9 +126,8 @@ visorchannel_read(struct visorchannel *channel, ulong offset, return 0; } -int -visorchannel_write(struct visorchannel *channel, ulong offset, - void *dest, ulong nbytes) +int visorchannel_write(struct visorchannel *channel, ulong offset, void *dest, + ulong nbytes) { size_t chdr_size = sizeof(struct channel_header); size_t copy_size; @@ -154,8 +146,7 @@ visorchannel_write(struct visorchannel *channel, ulong offset, return 0; } -void * -visorchannel_get_header(struct visorchannel *channel) +void *visorchannel_get_header(struct visorchannel *channel) { return &channel->chan_hdr; } @@ -164,17 +155,22 @@ visorchannel_get_header(struct visorchannel *channel) * Return offset of a specific SIGNAL_QUEUE_HEADER from the beginning of a * channel header */ -#define SIG_QUEUE_OFFSET(chan_hdr, q) \ - ((chan_hdr)->ch_space_offset + \ - ((q) * sizeof(struct signal_queue_header))) +static int sig_queue_offset(struct channel_header *chan_hdr, int q) +{ + return ((chan_hdr)->ch_space_offset + + ((q) * sizeof(struct signal_queue_header))); +} /* * Return offset of a specific queue entry (data) from the beginning of a * channel header */ -#define SIG_DATA_OFFSET(chan_hdr, q, sig_hdr, slot) \ - (SIG_QUEUE_OFFSET(chan_hdr, q) + (sig_hdr)->sig_base_offset + \ - ((slot) * (sig_hdr)->signal_size)) +static int sig_data_offset(struct channel_header *chan_hdr, int q, + struct signal_queue_header *sig_hdr, int slot) +{ + return (sig_queue_offset(chan_hdr, q) + sig_hdr->sig_base_offset + + (slot * sig_hdr->signal_size)); +} /* * Write the contents of a specific field within a SIGNAL_QUEUE_HEADER back @@ -182,48 +178,47 @@ visorchannel_get_header(struct visorchannel *channel) */ #define SIG_WRITE_FIELD(channel, queue, sig_hdr, FIELD) \ visorchannel_write(channel, \ - SIG_QUEUE_OFFSET(&channel->chan_hdr, queue) + \ + sig_queue_offset(&channel->chan_hdr, queue) + \ offsetof(struct signal_queue_header, FIELD), \ &((sig_hdr)->FIELD), \ sizeof((sig_hdr)->FIELD)) -static int -sig_read_header(struct visorchannel *channel, u32 queue, - struct signal_queue_header *sig_hdr) +static int sig_read_header(struct visorchannel *channel, u32 queue, + struct signal_queue_header *sig_hdr) { if (channel->chan_hdr.ch_space_offset < sizeof(struct channel_header)) return -EINVAL; /* Read the appropriate SIGNAL_QUEUE_HEADER into local memory. */ return visorchannel_read(channel, - SIG_QUEUE_OFFSET(&channel->chan_hdr, queue), + sig_queue_offset(&channel->chan_hdr, queue), sig_hdr, sizeof(struct signal_queue_header)); } -static int -sig_read_data(struct visorchannel *channel, u32 queue, - struct signal_queue_header *sig_hdr, u32 slot, void *data) +static int sig_read_data(struct visorchannel *channel, u32 queue, + struct signal_queue_header *sig_hdr, u32 slot, + void *data) { - int signal_data_offset = SIG_DATA_OFFSET(&channel->chan_hdr, queue, + int signal_data_offset = sig_data_offset(&channel->chan_hdr, queue, sig_hdr, slot); return visorchannel_read(channel, signal_data_offset, data, sig_hdr->signal_size); } -static int -sig_write_data(struct visorchannel *channel, u32 queue, - struct signal_queue_header *sig_hdr, u32 slot, void *data) +static int sig_write_data(struct visorchannel *channel, u32 queue, + struct signal_queue_header *sig_hdr, u32 slot, + void *data) { - int signal_data_offset = SIG_DATA_OFFSET(&channel->chan_hdr, queue, + int signal_data_offset = sig_data_offset(&channel->chan_hdr, queue, sig_hdr, slot); return visorchannel_write(channel, signal_data_offset, data, sig_hdr->signal_size); } -static int -signalremove_inner(struct visorchannel *channel, u32 queue, void *msg) +static int signalremove_inner(struct visorchannel *channel, u32 queue, + void *msg) { struct signal_queue_header sig_hdr; int error; @@ -246,9 +241,9 @@ signalremove_inner(struct visorchannel *channel, u32 queue, void *msg) /* * For each data field in SIGNAL_QUEUE_HEADER that was modified, - * update host memory. + * update host memory. Required for channel sync. */ - mb(); /* required for channel synch */ + mb(); error = SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail); if (error) @@ -269,8 +264,8 @@ signalremove_inner(struct visorchannel *channel, u32 queue, void *msg) * * Return: integer error code indicating the status of the removal */ -int -visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg) +int visorchannel_signalremove(struct visorchannel *channel, u32 queue, + void *msg) { int rc; unsigned long flags; @@ -287,8 +282,7 @@ visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg) } EXPORT_SYMBOL_GPL(visorchannel_signalremove); -static bool -queue_empty(struct visorchannel *channel, u32 queue) +static bool queue_empty(struct visorchannel *channel, u32 queue) { struct signal_queue_header sig_hdr; @@ -307,8 +301,7 @@ queue_empty(struct visorchannel *channel, u32 queue) * Return: boolean indicating whether any messages in the designated * channel/queue are present */ -bool -visorchannel_signalempty(struct visorchannel *channel, u32 queue) +bool visorchannel_signalempty(struct visorchannel *channel, u32 queue) { bool rc; unsigned long flags; @@ -324,8 +317,8 @@ visorchannel_signalempty(struct visorchannel *channel, u32 queue) } EXPORT_SYMBOL_GPL(visorchannel_signalempty); -static int -signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg) +static int signalinsert_inner(struct visorchannel *channel, u32 queue, + void *msg) { struct signal_queue_header sig_hdr; int err; @@ -351,9 +344,9 @@ signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg) /* * For each data field in SIGNAL_QUEUE_HEADER that was modified, - * update host memory. + * update host memory. Required for channel sync. */ - mb(); /* required for channel synch */ + mb(); err = SIG_WRITE_FIELD(channel, queue, &sig_hdr, head); if (err) @@ -370,17 +363,8 @@ signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg) * for a data area in memory, but does NOT modify * this data area * @physaddr: physical address of start of channel - * @channel_bytes: size of the channel in bytes; this may 0 if the channel has - * already been initialized in memory (which is true for all - * channels provided to guest environments by the s-Par - * back-end), in which case the actual channel size will be - * read from the channel header in memory * @gfp: gfp_t to use when allocating memory for the data struct - * @guid: uuid that identifies channel type; this may 0 if the channel - * has already been initialized in memory (which is true for all - * channels provided to guest environments by the s-Par - * back-end), in which case the actual channel guid will be - * read from the channel header in memory + * @guid: GUID that identifies channel type; * @needs_lock: must specify true if you have multiple threads of execution * that will be calling visorchannel methods of this * visorchannel at the same time @@ -388,9 +372,9 @@ signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg) * Return: pointer to visorchannel that was created if successful, * otherwise NULL */ -static struct visorchannel * -visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes, - gfp_t gfp, uuid_le guid, bool needs_lock) +static struct visorchannel *visorchannel_create_guts(u64 physaddr, gfp_t gfp, + const guid_t *guid, + bool needs_lock) { struct visorchannel *channel; int err; @@ -414,8 +398,8 @@ visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes, * this. Remember that we haven't requested it so we don't try to * release later on. */ - channel->requested = request_mem_region(physaddr, size, MYDRVNAME); - if (!channel->requested && uuid_le_cmp(guid, visor_video_guid)) + channel->requested = request_mem_region(physaddr, size, VISOR_DRV_NAME); + if (!channel->requested && !guid_equal(guid, &visor_video_guid)) /* we only care about errors if this is not the video channel */ goto err_destroy_channel; @@ -428,36 +412,29 @@ visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes, channel->physaddr = physaddr; channel->nbytes = size; - err = visorchannel_read(channel, 0, &channel->chan_hdr, - sizeof(struct channel_header)); + err = visorchannel_read(channel, 0, &channel->chan_hdr, size); if (err) goto err_destroy_channel; - - /* we had better be a CLIENT of this channel */ - if (channel_bytes == 0) - channel_bytes = (ulong)channel->chan_hdr.size; - if (uuid_le_cmp(guid, NULL_UUID_LE) == 0) - guid = channel->chan_hdr.chtype; + size = (ulong)channel->chan_hdr.size; memunmap(channel->mapped); if (channel->requested) release_mem_region(channel->physaddr, channel->nbytes); channel->mapped = NULL; - channel->requested = request_mem_region(channel->physaddr, - channel_bytes, MYDRVNAME); - if (!channel->requested && uuid_le_cmp(guid, visor_video_guid)) + channel->requested = request_mem_region(channel->physaddr, size, + VISOR_DRV_NAME); + if (!channel->requested && !guid_equal(guid, &visor_video_guid)) /* we only care about errors if this is not the video channel */ goto err_destroy_channel; - channel->mapped = memremap(channel->physaddr, channel_bytes, - MEMREMAP_WB); + channel->mapped = memremap(channel->physaddr, size, MEMREMAP_WB); if (!channel->mapped) { - release_mem_region(channel->physaddr, channel_bytes); + release_mem_region(channel->physaddr, size); goto err_destroy_channel; } - channel->nbytes = channel_bytes; - channel->guid = guid; + channel->nbytes = size; + guid_copy(&channel->guid, guid); return channel; err_destroy_channel: @@ -465,20 +442,16 @@ err_destroy_channel: return NULL; } -struct visorchannel * -visorchannel_create(u64 physaddr, unsigned long channel_bytes, - gfp_t gfp, uuid_le guid) +struct visorchannel *visorchannel_create(u64 physaddr, gfp_t gfp, + const guid_t *guid) { - return visorchannel_create_guts(physaddr, channel_bytes, gfp, guid, - false); + return visorchannel_create_guts(physaddr, gfp, guid, false); } -struct visorchannel * -visorchannel_create_with_lock(u64 physaddr, unsigned long channel_bytes, - gfp_t gfp, uuid_le guid) +struct visorchannel *visorchannel_create_with_lock(u64 physaddr, gfp_t gfp, + const guid_t *guid) { - return visorchannel_create_guts(physaddr, channel_bytes, gfp, guid, - true); + return visorchannel_create_guts(physaddr, gfp, guid, true); } /** @@ -490,8 +463,8 @@ visorchannel_create_with_lock(u64 physaddr, unsigned long channel_bytes, * * Return: integer error code indicating the status of the insertion */ -int -visorchannel_signalinsert(struct visorchannel *channel, u32 queue, void *msg) +int visorchannel_signalinsert(struct visorchannel *channel, u32 queue, + void *msg) { int rc; unsigned long flags; diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c index 22150564b4fb..74cce4f1a7bd 100644 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ b/drivers/staging/unisys/visorbus/visorchipset.c @@ -1,5 +1,4 @@ -/* visorchipset_main.c - * +/* * Copyright (C) 2010 - 2015 UNISYS CORPORATION * All rights reserved. * @@ -15,19 +14,18 @@ */ #include <linux/acpi.h> -#include <linux/ctype.h> -#include <linux/fs.h> -#include <linux/mm.h> -#include <linux/nls.h> -#include <linux/netdevice.h> -#include <linux/uuid.h> #include <linux/crash_dump.h> #include "visorbus.h" #include "visorbus_private.h" -#include "vmcallinterface.h" -#define CURRENT_FILE_PC VISOR_BUS_PC_visorchipset_c +/* {72120008-4AAB-11DC-8530-444553544200} */ +#define VISOR_SIOVM_GUID GUID_INIT(0x72120008, 0x4AAB, 0x11DC, 0x85, 0x30, \ + 0x44, 0x45, 0x53, 0x54, 0x42, 0x00) + +static const guid_t visor_vhba_channel_guid = VISOR_VHBA_CHANNEL_GUID; +static const guid_t visor_siovm_guid = VISOR_SIOVM_GUID; +static const guid_t visor_controlvm_channel_guid = VISOR_CONTROLVM_CHANNEL_GUID; #define POLLJIFFIES_CONTROLVMCHANNEL_FAST 1 #define POLLJIFFIES_CONTROLVMCHANNEL_SLOW 100 @@ -42,9 +40,9 @@ #define UNISYS_VISOR_ID_EDX 0x34367261 /* - * When the controlvm channel is idle for at least MIN_IDLE_SECONDS, - * we switch to slow polling mode. As soon as we get a controlvm - * message, we switch back to fast polling mode. + * When the controlvm channel is idle for at least MIN_IDLE_SECONDS, we switch + * to slow polling mode. As soon as we get a controlvm message, we switch back + * to fast polling mode. */ #define MIN_IDLE_SECONDS 10 @@ -54,15 +52,39 @@ struct parser_context { u8 *curr; unsigned long bytes_remaining; bool byte_stream; - char data[0]; + struct visor_controlvm_parameters_header data; }; -struct vmcall_controlvm_addr { - struct vmcall_io_controlvm_addr_params params; - int err; - u64 physaddr; +/* VMCALL_CONTROLVM_ADDR: Used by all guests, not just IO. */ +#define VMCALL_CONTROLVM_ADDR 0x0501 + +enum vmcall_result { + VMCALL_RESULT_SUCCESS = 0, + VMCALL_RESULT_INVALID_PARAM = 1, + VMCALL_RESULT_DATA_UNAVAILABLE = 2, + VMCALL_RESULT_FAILURE_UNAVAILABLE = 3, + VMCALL_RESULT_DEVICE_ERROR = 4, + VMCALL_RESULT_DEVICE_NOT_READY = 5 }; +/* + * struct vmcall_io_controlvm_addr_params - Structure for IO VMCALLS. Has + * parameters to VMCALL_CONTROLVM_ADDR + * interface. + * @address: The Guest-relative physical address of the ControlVm channel. + * This VMCall fills this in with the appropriate address. + * Contents provided by this VMCALL (OUT). + * @channel_bytes: The size of the ControlVm channel in bytes This VMCall fills + * this in with the appropriate address. Contents provided by + * this VMCALL (OUT). + * @unused: Unused Bytes in the 64-Bit Aligned Struct. + */ +struct vmcall_io_controlvm_addr_params { + u64 address; + u32 channel_bytes; + u8 unused[4]; +} __packed; + struct visorchipset_device { struct acpi_device *acpi_device; unsigned long poll_jiffies; @@ -80,7 +102,7 @@ struct visorchipset_device { */ struct controlvm_message controlvm_pending_msg; bool controlvm_pending_msg_valid; - struct vmcall_controlvm_addr controlvm_addr; + struct vmcall_io_controlvm_addr_params controlvm_params; }; static struct visorchipset_device *chipset_dev; @@ -124,7 +146,6 @@ static ssize_t toolaction_store(struct device *dev, offsetof(struct visor_controlvm_channel, tool_action), &tool_action, sizeof(u8)); - if (err) return err; return count; @@ -143,7 +164,6 @@ static ssize_t boottotool_show(struct device *dev, efi_visor_ind), &efi_visor_indication, sizeof(struct efi_visor_indication)); - if (err) return err; return sprintf(buf, "%u\n", efi_visor_indication.boot_to_tool); @@ -165,7 +185,6 @@ static ssize_t boottotool_store(struct device *dev, efi_visor_ind), &(efi_visor_indication), sizeof(struct efi_visor_indication)); - if (err) return err; return count; @@ -184,7 +203,7 @@ static ssize_t error_show(struct device *dev, struct device_attribute *attr, &error, sizeof(u32)); if (err) return err; - return sprintf(buf, "%i\n", error); + return sprintf(buf, "%u\n", error); } static ssize_t error_store(struct device *dev, struct device_attribute *attr, @@ -219,7 +238,7 @@ static ssize_t textid_show(struct device *dev, struct device_attribute *attr, if (err) return err; - return sprintf(buf, "%i\n", text_id); + return sprintf(buf, "%u\n", text_id); } static ssize_t textid_store(struct device *dev, struct device_attribute *attr, @@ -277,67 +296,6 @@ static ssize_t remaining_steps_store(struct device *dev, } static DEVICE_ATTR_RW(remaining_steps); -static uuid_le -parser_id_get(struct parser_context *ctx) -{ - struct visor_controlvm_parameters_header *phdr = NULL; - - phdr = (struct visor_controlvm_parameters_header *)(ctx->data); - return phdr->id; -} - -static void parser_done(struct parser_context *ctx) -{ - chipset_dev->controlvm_payload_bytes_buffered -= ctx->param_bytes; - kfree(ctx); -} - -static void * -parser_string_get(struct parser_context *ctx) -{ - u8 *pscan; - unsigned long nscan; - int value_length = -1; - void *value = NULL; - int i; - - pscan = ctx->curr; - nscan = ctx->bytes_remaining; - if (nscan == 0) - return NULL; - if (!pscan) - return NULL; - for (i = 0, value_length = -1; i < nscan; i++) - if (pscan[i] == '\0') { - value_length = i; - break; - } - if (value_length < 0) /* '\0' was not included in the length */ - value_length = nscan; - value = kmalloc(value_length + 1, GFP_KERNEL); - if (!value) - return NULL; - if (value_length > 0) - memcpy(value, pscan, value_length); - ((u8 *)(value))[value_length] = '\0'; - return value; -} - -static void * -parser_name_get(struct parser_context *ctx) -{ - struct visor_controlvm_parameters_header *phdr = NULL; - - phdr = (struct visor_controlvm_parameters_header *)(ctx->data); - - if (phdr->name_offset + phdr->name_length > ctx->param_bytes) - return NULL; - - ctx->curr = ctx->data + phdr->name_offset; - ctx->bytes_remaining = phdr->name_length; - return parser_string_get(ctx); -} - struct visor_busdev { u32 bus_no; u32 dev_no; @@ -347,11 +305,9 @@ static int match_visorbus_dev_by_id(struct device *dev, void *data) { struct visor_device *vdev = to_visor_device(dev); struct visor_busdev *id = data; - u32 bus_no = id->bus_no; - u32 dev_no = id->dev_no; - if ((vdev->chipset_bus_no == bus_no) && - (vdev->chipset_dev_no == dev_no)) + if ((vdev->chipset_bus_no == id->bus_no) && + (vdev->chipset_dev_no == id->dev_no)) return 1; return 0; @@ -364,9 +320,9 @@ struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no, struct device *dev_start = NULL; struct visor_device *vdev = NULL; struct visor_busdev id = { - .bus_no = bus_no, - .dev_no = dev_no - }; + .bus_no = bus_no, + .dev_no = dev_no + }; if (from) dev_start = &from->device; @@ -377,9 +333,9 @@ struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no, return vdev; } -static void -controlvm_init_response(struct controlvm_message *msg, - struct controlvm_message_header *msg_hdr, int response) +static void controlvm_init_response(struct controlvm_message *msg, + struct controlvm_message_header *msg_hdr, + int response) { memset(msg, 0, sizeof(struct controlvm_message)); memcpy(&msg->hdr, msg_hdr, sizeof(struct controlvm_message_header)); @@ -392,10 +348,10 @@ controlvm_init_response(struct controlvm_message *msg, } } -static int -controlvm_respond_chipset_init(struct controlvm_message_header *msg_hdr, - int response, - enum visor_chipset_feature features) +static int controlvm_respond_chipset_init( + struct controlvm_message_header *msg_hdr, + int response, + enum visor_chipset_feature features) { struct controlvm_message outmsg; @@ -405,8 +361,7 @@ controlvm_respond_chipset_init(struct controlvm_message_header *msg_hdr, CONTROLVM_QUEUE_REQUEST, &outmsg); } -static int -chipset_init(struct controlvm_message *inmsg) +static int chipset_init(struct controlvm_message *inmsg) { static int chipset_inited; enum visor_chipset_feature features = 0; @@ -421,15 +376,15 @@ chipset_init(struct controlvm_message *inmsg) chipset_inited = 1; /* - * Set features to indicate we support parahotplug (if Command - * also supports it). + * Set features to indicate we support parahotplug (if Command also + * supports it). */ features = inmsg->cmd.init_chipset.features & VISOR_CHIPSET_FEATURE_PARA_HOTPLUG; /* - * Set the "reply" bit so Command knows this is a - * features-aware driver. + * Set the "reply" bit so Command knows this is a features-aware + * driver. */ features |= VISOR_CHIPSET_FEATURE_REPLY; @@ -440,9 +395,9 @@ out_respond: return res; } -static int -controlvm_respond(struct controlvm_message_header *msg_hdr, int response, - struct visor_segment_state *state) +static int controlvm_respond(struct controlvm_message_header *msg_hdr, + int response, + struct visor_segment_state *state) { struct controlvm_message outmsg; @@ -464,8 +419,8 @@ enum crash_obj_type { CRASH_BUS, }; -static int -save_crash_message(struct controlvm_message *msg, enum crash_obj_type cr_type) +static int save_crash_message(struct controlvm_message *msg, + enum crash_obj_type cr_type) { u32 local_crash_msg_offset; u16 local_crash_msg_count; @@ -529,10 +484,9 @@ save_crash_message(struct controlvm_message *msg, enum crash_obj_type cr_type) return 0; } -static int -controlvm_responder(enum controlvm_id cmd_id, - struct controlvm_message_header *pending_msg_hdr, - int response) +static int controlvm_responder(enum controlvm_id cmd_id, + struct controlvm_message_header *pending_msg_hdr, + int response) { if (!pending_msg_hdr) return -EIO; @@ -543,14 +497,12 @@ controlvm_responder(enum controlvm_id cmd_id, return controlvm_respond(pending_msg_hdr, response, NULL); } -static int -device_changestate_responder(enum controlvm_id cmd_id, - struct visor_device *p, int response, - struct visor_segment_state response_state) +static int device_changestate_responder( + enum controlvm_id cmd_id, + struct visor_device *p, int response, + struct visor_segment_state response_state) { struct controlvm_message outmsg; - u32 bus_no = p->chipset_bus_no; - u32 dev_no = p->chipset_dev_no; if (!p->pending_msg_hdr) return -EIO; @@ -559,16 +511,15 @@ device_changestate_responder(enum controlvm_id cmd_id, controlvm_init_response(&outmsg, p->pending_msg_hdr, response); - outmsg.cmd.device_change_state.bus_no = bus_no; - outmsg.cmd.device_change_state.dev_no = dev_no; + outmsg.cmd.device_change_state.bus_no = p->chipset_bus_no; + outmsg.cmd.device_change_state.dev_no = p->chipset_dev_no; outmsg.cmd.device_change_state.state = response_state; return visorchannel_signalinsert(chipset_dev->controlvm_channel, CONTROLVM_QUEUE_REQUEST, &outmsg); } -static int -visorbus_create(struct controlvm_message *inmsg) +static int visorbus_create(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; struct controlvm_message_header *pmsg_hdr = NULL; @@ -580,7 +531,7 @@ visorbus_create(struct controlvm_message *inmsg) bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); if (bus_info && (bus_info->state.created == 1)) { dev_err(&chipset_dev->acpi_device->dev, - "failed visorbus_create: already exists\n"); + "failed %s: already exists\n", __func__); err = -EEXIST; goto err_respond; } @@ -595,7 +546,7 @@ visorbus_create(struct controlvm_message *inmsg) bus_info->chipset_bus_no = bus_no; bus_info->chipset_dev_no = BUS_ROOT_DEVICE; - if (uuid_le_cmp(cmd->create_bus.bus_inst_uuid, visor_siovm_uuid) == 0) { + if (guid_equal(&cmd->create_bus.bus_inst_guid, &visor_siovm_guid)) { err = save_crash_message(inmsg, CRASH_BUS); if (err) goto err_free_bus_info; @@ -615,19 +566,17 @@ visorbus_create(struct controlvm_message *inmsg) } visorchannel = visorchannel_create(cmd->create_bus.channel_addr, - cmd->create_bus.channel_bytes, GFP_KERNEL, - cmd->create_bus.bus_data_type_uuid); - + &cmd->create_bus.bus_data_type_guid); if (!visorchannel) { err = -ENOMEM; goto err_free_pending_msg; } + bus_info->visorchannel = visorchannel; - /* Response will be handled by visorchipset_bus_create */ - err = visorchipset_bus_create(bus_info); - /* If visorchipset_bus_create didn't respond, need to respond here */ + /* Response will be handled by visorbus_create_instance on success */ + err = visorbus_create_instance(bus_info); if (err) goto err_destroy_channel; @@ -648,8 +597,7 @@ err_respond: return err; } -static int -visorbus_destroy(struct controlvm_message *inmsg) +static int visorbus_destroy(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; struct controlvm_message_header *pmsg_hdr = NULL; @@ -683,8 +631,8 @@ visorbus_destroy(struct controlvm_message *inmsg) bus_info->pending_msg_hdr = pmsg_hdr; } - /* Response will be handled by visorchipset_bus_destroy */ - visorchipset_bus_destroy(bus_info); + /* Response will be handled by visorbus_remove_instance */ + visorbus_remove_instance(bus_info); return 0; err_respond: @@ -693,9 +641,60 @@ err_respond: return err; } -static int -visorbus_configure(struct controlvm_message *inmsg, - struct parser_context *parser_ctx) +static const guid_t *parser_id_get(struct parser_context *ctx) +{ + return &ctx->data.id; +} + +static void *parser_string_get(struct parser_context *ctx) +{ + u8 *pscan; + unsigned long nscan; + int value_length; + void *value; + int i; + + pscan = ctx->curr; + if (!pscan) + return NULL; + nscan = ctx->bytes_remaining; + if (nscan == 0) + return NULL; + + for (i = 0, value_length = -1; i < nscan; i++) + if (pscan[i] == '\0') { + value_length = i; + break; + } + /* '\0' was not included in the length */ + if (value_length < 0) + value_length = nscan; + + value = kmalloc(value_length + 1, GFP_KERNEL); + if (!value) + return NULL; + if (value_length > 0) + memcpy(value, pscan, value_length); + ((u8 *)(value))[value_length] = '\0'; + return value; +} + +static void *parser_name_get(struct parser_context *ctx) +{ + struct visor_controlvm_parameters_header *phdr = NULL; + + phdr = &ctx->data; + + if (phdr->name_offset + phdr->name_length > ctx->param_bytes) + return NULL; + + ctx->curr = (char *)&phdr + phdr->name_offset; + ctx->bytes_remaining = phdr->name_length; + return parser_string_get(ctx); +} + +static int visorbus_configure(struct controlvm_message *inmsg, + struct parser_context *parser_ctx) { struct controlvm_message_packet *cmd = &inmsg->cmd; u32 bus_no; @@ -707,10 +706,12 @@ visorbus_configure(struct controlvm_message *inmsg, if (!bus_info) { err = -EINVAL; goto err_respond; - } else if (bus_info->state.created == 0) { + } + if (bus_info->state.created == 0) { err = -EINVAL; goto err_respond; - } else if (bus_info->pending_msg_hdr) { + } + if (bus_info->pending_msg_hdr) { err = -EIO; goto err_respond; } @@ -722,7 +723,9 @@ visorbus_configure(struct controlvm_message *inmsg, goto err_respond; if (parser_ctx) { - bus_info->partition_uuid = parser_id_get(parser_ctx); + const guid_t *partition_guid = parser_id_get(parser_ctx); + + guid_copy(&bus_info->partition_guid, partition_guid); bus_info->name = parser_name_get(parser_ctx); } @@ -732,14 +735,13 @@ visorbus_configure(struct controlvm_message *inmsg, err_respond: dev_err(&chipset_dev->acpi_device->dev, - "visorbus_configure exited with err: %d\n", err); + "%s exited with err: %d\n", __func__, err); if (inmsg->hdr.flags.response_expected == 1) controlvm_responder(inmsg->hdr.id, &inmsg->hdr, err); return err; } -static int -visorbus_device_create(struct controlvm_message *inmsg) +static int visorbus_device_create(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; struct controlvm_message_header *pmsg_hdr = NULL; @@ -757,7 +759,6 @@ visorbus_device_create(struct controlvm_message *inmsg) err = -ENODEV; goto err_respond; } - if (bus_info->state.created == 0) { dev_err(&chipset_dev->acpi_device->dev, "bus not created, id: %d\n", bus_no); @@ -781,17 +782,13 @@ visorbus_device_create(struct controlvm_message *inmsg) dev_info->chipset_bus_no = bus_no; dev_info->chipset_dev_no = dev_no; - dev_info->inst = cmd->create_device.dev_inst_uuid; - - /* not sure where the best place to set the 'parent' */ + guid_copy(&dev_info->inst, &cmd->create_device.dev_inst_guid); dev_info->device.parent = &bus_info->device; visorchannel = visorchannel_create_with_lock(cmd->create_device.channel_addr, - cmd->create_device.channel_bytes, GFP_KERNEL, - cmd->create_device.data_type_uuid); - + &cmd->create_device.data_type_guid); if (!visorchannel) { dev_err(&chipset_dev->acpi_device->dev, "failed to create visorchannel: %d/%d\n", @@ -800,9 +797,8 @@ visorbus_device_create(struct controlvm_message *inmsg) goto err_free_dev_info; } dev_info->visorchannel = visorchannel; - dev_info->channel_type_guid = cmd->create_device.data_type_uuid; - if (uuid_le_cmp(cmd->create_device.data_type_uuid, - visor_vhba_channel_uuid) == 0) { + guid_copy(&dev_info->channel_type_guid, &cmd->create_device.data_type_guid); + if (guid_equal(&cmd->create_device.data_type_guid, &visor_vhba_channel_guid)) { err = save_crash_message(inmsg, CRASH_DEV); if (err) goto err_destroy_visorchannel; @@ -819,8 +815,8 @@ visorbus_device_create(struct controlvm_message *inmsg) sizeof(struct controlvm_message_header)); dev_info->pending_msg_hdr = pmsg_hdr; } - /* visorchipset_device_create will send response */ - err = visorchipset_device_create(dev_info); + /* create_visor_device will send response */ + err = create_visor_device(dev_info); if (err) goto err_destroy_visorchannel; @@ -838,8 +834,7 @@ err_respond: return err; } -static int -visorbus_device_changestate(struct controlvm_message *inmsg) +static int visorbus_device_changestate(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; struct controlvm_message_header *pmsg_hdr = NULL; @@ -899,8 +894,7 @@ err_respond: return err; } -static int -visorbus_device_destroy(struct controlvm_message *inmsg) +static int visorbus_device_destroy(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; struct controlvm_message_header *pmsg_hdr = NULL; @@ -918,7 +912,6 @@ visorbus_device_destroy(struct controlvm_message *inmsg) err = -EINVAL; goto err_respond; } - if (dev_info->pending_msg_hdr) { /* only non-NULL if dev is still waiting on a response */ err = -EIO; @@ -936,7 +929,8 @@ visorbus_device_destroy(struct controlvm_message *inmsg) dev_info->pending_msg_hdr = pmsg_hdr; } - visorchipset_device_destroy(dev_info); + kfree(dev_info->name); + remove_visor_device(dev_info); return 0; err_respond: @@ -954,8 +948,7 @@ err_respond: * disable the specified device. The udev script then writes to * /sys/devices/platform/visorchipset/parahotplug, which causes the * parahotplug store functions to get called, at which point the - * appropriate CONTROLVM message is retrieved from the list and responded - * to. + * appropriate CONTROLVM message is retrieved from the list and responded to. */ #define PARAHOTPLUG_TIMEOUT_MS 2000 @@ -967,8 +960,7 @@ err_respond: * * Return: a unique integer value */ -static int -parahotplug_next_id(void) +static int parahotplug_next_id(void) { static atomic_t id = ATOMIC_INIT(0); @@ -982,8 +974,7 @@ parahotplug_next_id(void) * * Return: expected expiration time (in jiffies) */ -static unsigned long -parahotplug_next_expiration(void) +static unsigned long parahotplug_next_expiration(void) { return jiffies + msecs_to_jiffies(PARAHOTPLUG_TIMEOUT_MS); } @@ -996,8 +987,8 @@ parahotplug_next_expiration(void) * * Return: the request containing the provided message */ -static struct parahotplug_request * -parahotplug_request_create(struct controlvm_message *msg) +static struct parahotplug_request *parahotplug_request_create( + struct controlvm_message *msg) { struct parahotplug_request *req; @@ -1016,14 +1007,14 @@ parahotplug_request_create(struct controlvm_message *msg) * parahotplug_request_destroy() - free a parahotplug_request * @req: the request to deallocate */ -static void -parahotplug_request_destroy(struct parahotplug_request *req) +static void parahotplug_request_destroy(struct parahotplug_request *req) { kfree(req); } static LIST_HEAD(parahotplug_request_list); -static DEFINE_SPINLOCK(parahotplug_request_list_lock); /* lock for above */ +/* lock for above */ +static DEFINE_SPINLOCK(parahotplug_request_list_lock); /* * parahotplug_request_complete() - mark request as complete @@ -1036,8 +1027,7 @@ static DEFINE_SPINLOCK(parahotplug_request_list_lock); /* lock for above */ * * Return: 0 on success or -EINVAL on failure */ -static int -parahotplug_request_complete(int id, u16 active) +static int parahotplug_request_complete(int id, u16 active) { struct list_head *pos; struct list_head *tmp; @@ -1146,7 +1136,7 @@ static struct attribute *visorchipset_parahotplug_attrs[] = { NULL }; -static struct attribute_group visorchipset_parahotplug_group = { +static const struct attribute_group visorchipset_parahotplug_group = { .name = "parahotplug", .attrs = visorchipset_parahotplug_attrs }; @@ -1164,8 +1154,7 @@ static const struct attribute_group *visorchipset_dev_groups[] = { * Cause uevent to run the user level script to do the disable/enable specified * in the parahotplug_request. */ -static int -parahotplug_request_kickoff(struct parahotplug_request *req) +static int parahotplug_request_kickoff(struct parahotplug_request *req) { struct controlvm_message_packet *cmd = &req->msg.cmd; char env_cmd[40], env_id[40], env_state[40], env_bus[40], env_dev[40], @@ -1194,14 +1183,12 @@ parahotplug_request_kickoff(struct parahotplug_request *req) * off a udev script * @inmsg: the message indicating whether to enable or disable */ -static int -parahotplug_process_message(struct controlvm_message *inmsg) +static int parahotplug_process_message(struct controlvm_message *inmsg) { struct parahotplug_request *req; int err; req = parahotplug_request_create(inmsg); - if (!req) return -ENOMEM; @@ -1220,10 +1207,9 @@ parahotplug_process_message(struct controlvm_message *inmsg) } /* - * For disable messages, add the request to the - * request list before kicking off the udev script. It - * won't get responded to until the script has - * indicated it's done. + * For disable messages, add the request to the request list before + * kicking off the udev script. It won't get responded to until the + * script has indicated it's done. */ spin_lock(¶hotplug_request_list_lock); list_add_tail(&req->list, ¶hotplug_request_list); @@ -1247,8 +1233,7 @@ err_respond: * * Return: 0 on success, negative on failure */ -static int -chipset_ready_uevent(struct controlvm_message_header *msg_hdr) +static int chipset_ready_uevent(struct controlvm_message_header *msg_hdr) { int res; @@ -1268,8 +1253,7 @@ chipset_ready_uevent(struct controlvm_message_header *msg_hdr) * * Return: 0 on success, negative on failure */ -static int -chipset_selftest_uevent(struct controlvm_message_header *msg_hdr) +static int chipset_selftest_uevent(struct controlvm_message_header *msg_hdr) { char env_selftest[20]; char *envp[] = { env_selftest, NULL }; @@ -1292,13 +1276,11 @@ chipset_selftest_uevent(struct controlvm_message_header *msg_hdr) * * Return: 0 on success, negative on failure */ -static int -chipset_notready_uevent(struct controlvm_message_header *msg_hdr) +static int chipset_notready_uevent(struct controlvm_message_header *msg_hdr) { - int res; - - res = kobject_uevent(&chipset_dev->acpi_device->dev.kobj, + int res = kobject_uevent(&chipset_dev->acpi_device->dev.kobj, KOBJ_OFFLINE); + if (msg_hdr->flags.response_expected) controlvm_respond(msg_hdr, res, NULL); @@ -1321,13 +1303,12 @@ static int unisys_vmcall(unsigned long tuple, unsigned long param) __asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) : "a"(tuple), "b"(reg_ebx), "c"(reg_ecx)); - if (result) goto error; return 0; - -error: /* Need to convert from VMCALL error codes to Linux */ +/* Need to convert from VMCALL error codes to Linux */ +error: switch (result) { case VMCALL_RESULT_INVALID_PARAM: return -EINVAL; @@ -1337,35 +1318,27 @@ error: /* Need to convert from VMCALL error codes to Linux */ return -EFAULT; } } -static unsigned int -issue_vmcall_io_controlvm_addr(u64 *control_addr, u32 *control_bytes) -{ - chipset_dev->controlvm_addr.physaddr = virt_to_phys( - &chipset_dev->controlvm_addr.params); - chipset_dev->controlvm_addr.err = unisys_vmcall(VMCALL_CONTROLVM_ADDR, - chipset_dev->controlvm_addr.physaddr); - if (chipset_dev->controlvm_addr.err) - return chipset_dev->controlvm_addr.err; - - *control_addr = chipset_dev->controlvm_addr.params.address; - *control_bytes = chipset_dev->controlvm_addr.params.channel_bytes; - - return 0; -} -static u64 controlvm_get_channel_address(void) +static int controlvm_channel_create(struct visorchipset_device *dev) { - u64 addr = 0; - u32 size = 0; - - if (issue_vmcall_io_controlvm_addr(&addr, &size)) - return 0; + struct visorchannel *chan; + u64 addr; + int err; - return addr; + err = unisys_vmcall(VMCALL_CONTROLVM_ADDR, + virt_to_phys(&dev->controlvm_params)); + if (err) + return err; + addr = dev->controlvm_params.address; + chan = visorchannel_create_with_lock(addr, GFP_KERNEL, + &visor_controlvm_channel_guid); + if (!chan) + return -ENOMEM; + dev->controlvm_channel = chan; + return 0; } -static void -setup_crash_devices_work_queue(struct work_struct *work) +static void setup_crash_devices_work_queue(struct work_struct *work) { struct controlvm_message local_crash_bus_msg; struct controlvm_message local_crash_dev_msg; @@ -1444,87 +1417,44 @@ setup_crash_devices_work_queue(struct work_struct *work) visorbus_device_create(&local_crash_dev_msg); } -void -visorbus_create_response(struct visor_device *bus_info, int response) +void visorbus_response(struct visor_device *bus_info, int response, + int controlvm_id) { - if (response >= 0) - bus_info->state.created = 1; - - controlvm_responder(CONTROLVM_BUS_CREATE, bus_info->pending_msg_hdr, - response); + controlvm_responder(controlvm_id, bus_info->pending_msg_hdr, response); kfree(bus_info->pending_msg_hdr); bus_info->pending_msg_hdr = NULL; } -void -visorbus_destroy_response(struct visor_device *bus_info, int response) -{ - controlvm_responder(CONTROLVM_BUS_DESTROY, bus_info->pending_msg_hdr, - response); - - kfree(bus_info->pending_msg_hdr); - bus_info->pending_msg_hdr = NULL; -} - -void -visorbus_device_create_response(struct visor_device *dev_info, int response) -{ - if (response >= 0) - dev_info->state.created = 1; - - controlvm_responder(CONTROLVM_DEVICE_CREATE, dev_info->pending_msg_hdr, - response); - - kfree(dev_info->pending_msg_hdr); - dev_info->pending_msg_hdr = NULL; -} - -void -visorbus_device_destroy_response(struct visor_device *dev_info, int response) -{ - controlvm_responder(CONTROLVM_DEVICE_DESTROY, dev_info->pending_msg_hdr, - response); - - kfree(dev_info->pending_msg_hdr); - dev_info->pending_msg_hdr = NULL; -} - -void -visorbus_device_pause_response(struct visor_device *dev_info, int response) +void visorbus_device_changestate_response(struct visor_device *dev_info, + int response, + struct visor_segment_state state) { device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE, - dev_info, response, - segment_state_standby); + dev_info, response, state); kfree(dev_info->pending_msg_hdr); dev_info->pending_msg_hdr = NULL; } -void -visorbus_device_resume_response(struct visor_device *dev_info, int response) +static void parser_done(struct parser_context *ctx) { - device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE, - dev_info, response, - segment_state_running); - - kfree(dev_info->pending_msg_hdr); - dev_info->pending_msg_hdr = NULL; + chipset_dev->controlvm_payload_bytes_buffered -= ctx->param_bytes; + kfree(ctx); } -static struct parser_context * -parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry) +static struct parser_context *parser_init_stream(u64 addr, u32 bytes, + bool *retry) { - int allocbytes = sizeof(struct parser_context) + bytes; + int allocbytes; struct parser_context *ctx; + void *mapping; *retry = false; - /* - * alloc an 0 extra byte to ensure payload is - * '\0'-terminated - */ - allocbytes++; + /* alloc an extra byte to ensure payload is \0 terminated */ + allocbytes = bytes + 1 + (sizeof(struct parser_context) - + sizeof(struct visor_controlvm_parameters_header)); if ((chipset_dev->controlvm_payload_bytes_buffered + bytes) > MAX_CONTROLVM_PAYLOAD_BYTES) { *retry = true; @@ -1538,32 +1468,18 @@ parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry) ctx->allocbytes = allocbytes; ctx->param_bytes = bytes; - ctx->curr = NULL; - ctx->bytes_remaining = 0; - ctx->byte_stream = false; - if (local) { - void *p; - - if (addr > virt_to_phys(high_memory - 1)) - goto err_finish_ctx; - p = __va((unsigned long)(addr)); - memcpy(ctx->data, p, bytes); - } else { - void *mapping = memremap(addr, bytes, MEMREMAP_WB); - - if (!mapping) - goto err_finish_ctx; - memcpy(ctx->data, mapping, bytes); - memunmap(mapping); - } - + mapping = memremap(addr, bytes, MEMREMAP_WB); + if (!mapping) + goto err_finish_ctx; + memcpy(&ctx->data, mapping, bytes); + memunmap(mapping); ctx->byte_stream = true; chipset_dev->controlvm_payload_bytes_buffered += ctx->param_bytes; return ctx; err_finish_ctx: - parser_done(ctx); + kfree(ctx); return NULL; } @@ -1580,19 +1496,16 @@ err_finish_ctx: * which to copy out controlvm payload data. * < 0 - error: ControlVM message was processed but an error occurred. */ -static int -handle_command(struct controlvm_message inmsg, u64 channel_addr) +static int handle_command(struct controlvm_message inmsg, u64 channel_addr) { struct controlvm_message_packet *cmd = &inmsg.cmd; u64 parm_addr; u32 parm_bytes; struct parser_context *parser_ctx = NULL; - bool local_addr; struct controlvm_message ackmsg; int err = 0; /* create parsing context if necessary */ - local_addr = (inmsg.hdr.flags.test_message == 1); parm_addr = channel_addr + inmsg.hdr.payload_vm_offset; parm_bytes = inmsg.hdr.payload_bytes; @@ -1601,25 +1514,19 @@ handle_command(struct controlvm_message inmsg, u64 channel_addr) * within our OS-controlled memory. We need to know that, because it * makes a difference in how we compute the virtual address. */ - if (parm_addr && parm_bytes) { + if (parm_bytes) { bool retry = false; - parser_ctx = - parser_init_byte_stream(parm_addr, parm_bytes, - local_addr, &retry); + parser_ctx = parser_init_stream(parm_addr, parm_bytes, &retry); if (!parser_ctx && retry) return -EAGAIN; } + controlvm_init_response(&ackmsg, &inmsg.hdr, CONTROLVM_RESP_SUCCESS); + err = visorchannel_signalinsert(chipset_dev->controlvm_channel, + CONTROLVM_QUEUE_ACK, &ackmsg); + if (err) + return err; - if (!local_addr) { - controlvm_init_response(&ackmsg, &inmsg.hdr, - CONTROLVM_RESP_SUCCESS); - err = visorchannel_signalinsert(chipset_dev->controlvm_channel, - CONTROLVM_QUEUE_ACK, - &ackmsg); - if (err) - return err; - } switch (inmsg.hdr.id) { case CONTROLVM_CHIPSET_INIT: err = chipset_init(&inmsg); @@ -1641,8 +1548,8 @@ handle_command(struct controlvm_message inmsg, u64 channel_addr) err = parahotplug_process_message(&inmsg); } else { /* - * save the hdr and cmd structures for later use - * when sending back the response to Command + * save the hdr and cmd structures for later use when + * sending back the response to Command */ err = visorbus_device_changestate(&inmsg); break; @@ -1689,12 +1596,9 @@ handle_command(struct controlvm_message inmsg, u64 channel_addr) * * Return: 0 if valid message was retrieved or -error */ -static int -read_controlvm_event(struct controlvm_message *msg) +static int read_controlvm_event(struct controlvm_message *msg) { - int err; - - err = visorchannel_signalremove(chipset_dev->controlvm_channel, + int err = visorchannel_signalremove(chipset_dev->controlvm_channel, CONTROLVM_QUEUE_EVENT, msg); if (err) return err; @@ -1710,8 +1614,7 @@ read_controlvm_event(struct controlvm_message *msg) * parahotplug_process_list() - remove any request from the list that's been on * there too long and respond with an error */ -static void -parahotplug_process_list(void) +static void parahotplug_process_list(void) { struct list_head *pos; struct list_head *tmp; @@ -1737,8 +1640,7 @@ parahotplug_process_list(void) spin_unlock(¶hotplug_request_list_lock); } -static void -controlvm_periodic_work(struct work_struct *work) +static void controlvm_periodic_work(struct work_struct *work) { struct controlvm_message inmsg; int count = 0; @@ -1756,9 +1658,8 @@ controlvm_periodic_work(struct work_struct *work) if (chipset_dev->controlvm_pending_msg_valid) { /* - * we throttled processing of a prior - * msg, so try to process it again - * rather than reading a new one + * we throttled processing of a prior msg, so try to process + * it again rather than reading a new one */ inmsg = chipset_dev->controlvm_pending_msg; chipset_dev->controlvm_pending_msg_valid = false; @@ -1793,9 +1694,8 @@ schedule_out: if (time_after(jiffies, chipset_dev->most_recent_message_jiffies + (HZ * MIN_IDLE_SECONDS))) { /* - * it's been longer than MIN_IDLE_SECONDS since we - * processed our last controlvm message; slow down the - * polling + * it's been longer than MIN_IDLE_SECONDS since we processed + * our last controlvm message; slow down the polling */ if (chipset_dev->poll_jiffies != POLLJIFFIES_CONTROLVMCHANNEL_SLOW) @@ -1812,41 +1712,36 @@ schedule_out: chipset_dev->poll_jiffies); } -static int -visorchipset_init(struct acpi_device *acpi_device) +static int visorchipset_init(struct acpi_device *acpi_device) { int err = -ENODEV; - u64 addr; - uuid_le uuid = VISOR_CONTROLVM_CHANNEL_UUID; struct visorchannel *controlvm_channel; chipset_dev = kzalloc(sizeof(*chipset_dev), GFP_KERNEL); if (!chipset_dev) goto error; - addr = controlvm_get_channel_address(); - if (!addr) - goto error; + err = controlvm_channel_create(chipset_dev); + if (err) + goto error_free_chipset_dev; acpi_device->driver_data = chipset_dev; - chipset_dev->acpi_device = acpi_device; chipset_dev->poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_FAST; - controlvm_channel = visorchannel_create_with_lock(addr, - 0, GFP_KERNEL, uuid); - - if (!controlvm_channel) - goto error_free_chipset_dev; - - chipset_dev->controlvm_channel = controlvm_channel; err = sysfs_create_groups(&chipset_dev->acpi_device->dev.kobj, visorchipset_dev_groups); if (err < 0) goto error_destroy_channel; - if (!VISOR_CONTROLVM_CHANNEL_OK_CLIENT( - visorchannel_get_header(controlvm_channel))) + controlvm_channel = chipset_dev->controlvm_channel; + if (!visor_check_channel(visorchannel_get_header(controlvm_channel), + &chipset_dev->acpi_device->dev, + &visor_controlvm_channel_guid, + "controlvm", + sizeof(struct visor_controlvm_channel), + VISOR_CONTROLVM_CHANNEL_VERSIONID, + VISOR_CHANNEL_SIGNATURE)) goto error_delete_groups; /* if booting in a crash kernel */ @@ -1886,8 +1781,7 @@ error: return err; } -static int -visorchipset_exit(struct acpi_device *acpi_device) +static int visorchipset_exit(struct acpi_device *acpi_device) { visorbus_exit(); cancel_delayed_work_sync(&chipset_dev->periodic_controlvm_work); @@ -1928,9 +1822,8 @@ static __init int visorutil_spar_detect(void) return (ebx == UNISYS_VISOR_ID_EBX) && (ecx == UNISYS_VISOR_ID_ECX) && (edx == UNISYS_VISOR_ID_EDX); - } else { - return 0; } + return 0; } static int init_unisys(void) diff --git a/drivers/staging/unisys/visorbus/vmcallinterface.h b/drivers/staging/unisys/visorbus/vmcallinterface.h deleted file mode 100644 index cc70e1b16bda..000000000000 --- a/drivers/staging/unisys/visorbus/vmcallinterface.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (C) 2010 - 2015 UNISYS CORPORATION - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -#ifndef __VMCALLINTERFACE_H__ -#define __VMCALLINTERFACE_H__ - -enum vmcall_monitor_interface_method_tuple { /* VMCALL identification tuples */ - /* Note: when a new VMCALL is added: - * - the 1st 2 hex digits correspond to one of the - * VMCALL_MONITOR_INTERFACE types and - * - the next 2 hex digits are the nth relative instance of within a - * type - * E.G. for VMCALL_VIRTPART_RECYCLE_PART, - * - the 0x02 identifies it as a VMCALL_VIRTPART type and - * - the 0x01 identifies it as the 1st instance of a VMCALL_VIRTPART - * type of VMCALL - */ - /* used by all Guests, not just IO */ - VMCALL_CONTROLVM_ADDR = 0x0501, -}; - -enum vmcall_result { - VMCALL_RESULT_SUCCESS = 0, - VMCALL_RESULT_INVALID_PARAM = 1, - VMCALL_RESULT_DATA_UNAVAILABLE = 2, - VMCALL_RESULT_FAILURE_UNAVAILABLE = 3, - VMCALL_RESULT_DEVICE_ERROR = 4, - VMCALL_RESULT_DEVICE_NOT_READY = 5 -}; - -/* Structures for IO VMCALLs */ -/* Parameters to VMCALL_CONTROLVM_ADDR interface */ -struct vmcall_io_controlvm_addr_params { - /* The Guest-relative physical address of the ControlVm channel. */ - /* This VMCall fills this in with the appropriate address. */ - u64 address; /* contents provided by this VMCALL (OUT) */ - /* the size of the ControlVm channel in bytes This VMCall fills this */ - /* in with the appropriate address. */ - u32 channel_bytes; /* contents provided by this VMCALL (OUT) */ - u8 unused[4]; /* Unused Bytes in the 64-Bit Aligned Struct */ -} __packed; - -#endif /* __VMCALLINTERFACE_H__ */ diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c index a6e7a6bbc428..8567e447891e 100644 --- a/drivers/staging/unisys/visorhba/visorhba_main.c +++ b/drivers/staging/unisys/visorhba/visorhba_main.c @@ -1,4 +1,5 @@ -/* Copyright (c) 2012 - 2015 UNISYS CORPORATION +/* + * Copyright (c) 2012 - 2015 UNISYS CORPORATION * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -14,7 +15,6 @@ */ #include <linux/debugfs.h> -#include <linux/skbuff.h> #include <linux/kthread.h> #include <linux/idr.h> #include <linux/seq_file.h> @@ -39,16 +39,17 @@ static struct visor_channeltype_descriptor visorhba_channel_types[] = { /* Note that the only channel type we expect to be reported by the * bus driver is the VISOR_VHBA channel. */ - { VISOR_VHBA_CHANNEL_UUID, "sparvhba" }, - { NULL_UUID_LE, NULL } + { VISOR_VHBA_CHANNEL_GUID, "sparvhba" }, + {} }; MODULE_DEVICE_TABLE(visorbus, visorhba_channel_types); -MODULE_ALIAS("visorbus:" VISOR_VHBA_CHANNEL_UUID_STR); +MODULE_ALIAS("visorbus:" VISOR_VHBA_CHANNEL_GUID_STR); struct visordisk_info { u32 valid; - u32 channel, id, lun; /* Disk Path */ + /* Disk Path */ + u32 channel, id, lun; atomic_t ios_threshold; atomic_t error_count; struct visordisk_info *next; @@ -56,8 +57,10 @@ struct visordisk_info { struct scsipending { struct uiscmdrsp cmdrsp; - void *sent; /* The Data being tracked */ - char cmdtype; /* Type of pointer that is being stored */ + /* The Data being tracked */ + void *sent; + /* Type of pointer that is being stored */ + char cmdtype; }; /* Each scsi_host has a host_data area that contains this struct. */ @@ -71,7 +74,8 @@ struct visorhba_devdata { struct scsipending pending[MAX_PENDING_REQUESTS]; /* Start search for next pending free slot here */ unsigned int nextinsert; - spinlock_t privlock; /* lock to protect data in devdata */ + /* lock to protect data in devdata */ + spinlock_t privlock; bool serverdown; bool serverchangingstate; unsigned long long acquire_failed_cnt; @@ -108,18 +112,18 @@ struct visorhba_devices_open { (iter->lun == match->lun)) /* - * visor_thread_start - starts a thread for the device - * @threadfn: Function the thread starts - * @thrcontext: Context to pass to the thread, i.e. devdata - * @name: string describing name of thread + * visor_thread_start - Starts a thread for the device + * @threadfn: Function the thread starts + * @thrcontext: Context to pass to the thread, i.e. devdata + * @name: String describing name of thread * - * Starts a thread for the device. + * Starts a thread for the device. * - * Return the task_struct * denoting the thread on success, - * or NULL on failure + * Return: The task_struct * denoting the thread on success, + * or NULL on failure */ -static struct task_struct *visor_thread_start -(int (*threadfn)(void *), void *thrcontext, char *name) +static struct task_struct *visor_thread_start(int (*threadfn)(void *), + void *thrcontext, char *name) { struct task_struct *task; @@ -132,27 +136,27 @@ static struct task_struct *visor_thread_start } /* - * visor_thread_stop - stops the thread if it is running + * visor_thread_stop - Stops the thread if it is running + * @task: Description of process to stop */ static void visor_thread_stop(struct task_struct *task) { - if (!task) - return; /* no thread running */ kthread_stop(task); } /* - * add_scsipending_entry - save off io command that is pending in - * Service Partition - * @devdata: Pointer to devdata - * @cmdtype: Specifies the type of command pending - * @new: The command to be saved + * add_scsipending_entry - Save off io command that is pending in + * Service Partition + * @devdata: Pointer to devdata + * @cmdtype: Specifies the type of command pending + * @new: The command to be saved * - * Saves off the io command that is being handled by the Service - * Partition so that it can be handled when it completes. If new is - * NULL it is assumed the entry refers only to the cmdrsp. - * Returns insert_location where entry was added, - * -EBUSY if it can't + * Saves off the io command that is being handled by the Service + * Partition so that it can be handled when it completes. If new is + * NULL it is assumed the entry refers only to the cmdrsp. + * + * Return: Insert_location where entry was added on success, + * -EBUSY if it can't */ static int add_scsipending_entry(struct visorhba_devdata *devdata, char cmdtype, void *new) @@ -176,7 +180,8 @@ static int add_scsipending_entry(struct visorhba_devdata *devdata, entry->cmdtype = cmdtype; if (new) entry->sent = new; - else /* wants to send cmdrsp */ + /* wants to send cmdrsp */ + else entry->sent = &entry->cmdrsp; devdata->nextinsert = (insert_location + 1) % MAX_PENDING_REQUESTS; spin_unlock_irqrestore(&devdata->privlock, flags); @@ -185,15 +190,15 @@ static int add_scsipending_entry(struct visorhba_devdata *devdata, } /* - * del_scsipending_ent - removes an entry from the pending array - * @devdata: Device holding the pending array - * @del: Entry to remove + * del_scsipending_ent - Removes an entry from the pending array + * @devdata: Device holding the pending array + * @del: Entry to remove * - * Removes the entry pointed at by del and returns it. - * Returns the scsipending entry pointed at + * Removes the entry pointed at by del and returns it. + * + * Return: The scsipending entry pointed to on success, NULL on failure */ -static void *del_scsipending_ent(struct visorhba_devdata *devdata, - int del) +static void *del_scsipending_ent(struct visorhba_devdata *devdata, int del) { unsigned long flags; void *sent; @@ -203,7 +208,6 @@ static void *del_scsipending_ent(struct visorhba_devdata *devdata, spin_lock_irqsave(&devdata->privlock, flags); sent = devdata->pending[del].sent; - devdata->pending[del].cmdtype = 0; devdata->pending[del].sent = NULL; spin_unlock_irqrestore(&devdata->privlock, flags); @@ -212,13 +216,14 @@ static void *del_scsipending_ent(struct visorhba_devdata *devdata, } /* - * get_scsipending_cmdrsp - return the cmdrsp stored in a pending entry - * @ddata: Device holding the pending array - * @ent: Entry that stores the cmdrsp + * get_scsipending_cmdrsp - Return the cmdrsp stored in a pending entry + * @ddata: Device holding the pending array + * @ent: Entry that stores the cmdrsp * - * Each scsipending entry has a cmdrsp in it. The cmdrsp is only valid - * if the "sent" field is not NULL - * Returns a pointer to the cmdrsp. + * Each scsipending entry has a cmdrsp in it. The cmdrsp is only valid + * if the "sent" field is not NULL. + * + * Return: A pointer to the cmdrsp, NULL on failure */ static struct uiscmdrsp *get_scsipending_cmdrsp(struct visorhba_devdata *ddata, int ent) @@ -230,13 +235,15 @@ static struct uiscmdrsp *get_scsipending_cmdrsp(struct visorhba_devdata *ddata, } /* - * simple_idr_get - associate a provided pointer with an int value - * 1 <= value <= INT_MAX, and return this int value; - * the pointer value can be obtained later by passing - * this int value to idr_find() - * @idrtable: the data object maintaining the pointer<-->int mappings - * @p: the pointer value to be remembered - * @lock: a spinlock used when exclusive access to idrtable is needed + * simple_idr_get - Associate a provided pointer with an int value + * 1 <= value <= INT_MAX, and return this int value; + * the pointer value can be obtained later by passing + * this int value to idr_find() + * @idrtable: The data object maintaining the pointer<-->int mappings + * @p: The pointer value to be remembered + * @lock: A spinlock used when exclusive access to idrtable is needed + * + * Return: The id number mapped to pointer 'p', 0 on failure */ static unsigned int simple_idr_get(struct idr *idrtable, void *p, spinlock_t *lock) @@ -249,16 +256,23 @@ static unsigned int simple_idr_get(struct idr *idrtable, void *p, id = idr_alloc(idrtable, p, 1, INT_MAX, GFP_NOWAIT); spin_unlock_irqrestore(lock, flags); idr_preload_end(); + /* failure */ if (id < 0) - return 0; /* failure */ - return (unsigned int)(id); /* idr_alloc() guarantees > 0 */ + return 0; + /* idr_alloc() guarantees > 0 */ + return (unsigned int)(id); } /* - * setup_scsitaskmgmt_handles - stash the necessary handles so that the - * completion processing logic for a taskmgmt - * cmd will be able to find who to wake up - * and where to stash the result + * setup_scsitaskmgmt_handles - Stash the necessary handles so that the + * completion processing logic for a taskmgmt + * cmd will be able to find who to wake up + * and where to stash the result + * @idrtable: The data object maintaining the pointer<-->int mappings + * @lock: A spinlock used when exclusive access to idrtable is needed + * @cmdrsp: Response from the IOVM + * @event: The event handle to associate with an id + * @result: The location to place the result of the event handle into */ static void setup_scsitaskmgmt_handles(struct idr *idrtable, spinlock_t *lock, struct uiscmdrsp *cmdrsp, @@ -273,8 +287,10 @@ static void setup_scsitaskmgmt_handles(struct idr *idrtable, spinlock_t *lock, } /* - * cleanup_scsitaskmgmt_handles - forget handles created by - * setup_scsitaskmgmt_handles() + * cleanup_scsitaskmgmt_handles - Forget handles created by + * setup_scsitaskmgmt_handles() + * @idrtable: The data object maintaining the pointer<-->int mappings + * @cmdrsp: Response from the IOVM */ static void cleanup_scsitaskmgmt_handles(struct idr *idrtable, struct uiscmdrsp *cmdrsp) @@ -286,14 +302,15 @@ static void cleanup_scsitaskmgmt_handles(struct idr *idrtable, } /* - * forward_taskmgmt_command - send taskmegmt command to the Service - * Partition - * @tasktype: Type of taskmgmt command - * @scsidev: Scsidev that issued command + * forward_taskmgmt_command - Send taskmegmt command to the Service + * Partition + * @tasktype: Type of taskmgmt command + * @scsidev: Scsidev that issued command * - * Create a cmdrsp packet and send it to the Serivce Partition - * that will service this request. - * Returns whether the command was queued successfully or not. + * Create a cmdrsp packet and send it to the Serivce Partition + * that will service this request. + * + * Return: Int representing whether command was queued successfully or not */ static int forward_taskmgmt_command(enum task_mgmt_types tasktype, struct scsi_cmnd *scsicmd) @@ -365,11 +382,10 @@ err_del_scsipending_ent: } /* - * visorhba_abort_handler - Send TASK_MGMT_ABORT_TASK - * @scsicmd: The scsicmd that needs aborted - * - * Returns SUCCESS if inserted, failure otherwise + * visorhba_abort_handler - Send TASK_MGMT_ABORT_TASK + * @scsicmd: The scsicmd that needs aborted * + * Return: SUCCESS if inserted, FAILED otherwise */ static int visorhba_abort_handler(struct scsi_cmnd *scsicmd) { @@ -390,10 +406,10 @@ static int visorhba_abort_handler(struct scsi_cmnd *scsicmd) } /* - * visorhba_device_reset_handler - Send TASK_MGMT_LUN_RESET - * @scsicmd: The scsicmd that needs aborted + * visorhba_device_reset_handler - Send TASK_MGMT_LUN_RESET + * @scsicmd: The scsicmd that needs aborted * - * Returns SUCCESS if inserted, failure otherwise + * Return: SUCCESS if inserted, FAILED otherwise */ static int visorhba_device_reset_handler(struct scsi_cmnd *scsicmd) { @@ -414,11 +430,11 @@ static int visorhba_device_reset_handler(struct scsi_cmnd *scsicmd) } /* - * visorhba_bus_reset_handler - Send TASK_MGMT_TARGET_RESET for each - * target on the bus - * @scsicmd: The scsicmd that needs aborted + * visorhba_bus_reset_handler - Send TASK_MGMT_TARGET_RESET for each + * target on the bus + * @scsicmd: The scsicmd that needs aborted * - * Returns SUCCESS + * Return: SUCCESS if inserted, FAILED otherwise */ static int visorhba_bus_reset_handler(struct scsi_cmnd *scsicmd) { @@ -438,24 +454,22 @@ static int visorhba_bus_reset_handler(struct scsi_cmnd *scsicmd) } /* - * visorhba_host_reset_handler - Not supported - * @scsicmd: The scsicmd that needs aborted + * visorhba_host_reset_handler - Not supported + * @scsicmd: The scsicmd that needs to be aborted * - * Not supported, return SUCCESS - * Returns SUCCESS + * Return: Not supported, return SUCCESS */ -static int -visorhba_host_reset_handler(struct scsi_cmnd *scsicmd) +static int visorhba_host_reset_handler(struct scsi_cmnd *scsicmd) { /* issue TASK_MGMT_TARGET_RESET for each target on each bus for host */ return SUCCESS; } /* - * visorhba_get_info - * @shp: Scsi host that is requesting information + * visorhba_get_info - Get information about SCSI device + * @shp: Scsi host that is requesting information * - * Returns string with info + * Return: String with visorhba information */ static const char *visorhba_get_info(struct Scsi_Host *shp) { @@ -464,19 +478,42 @@ static const char *visorhba_get_info(struct Scsi_Host *shp) } /* - * visorhba_queue_command_lck -- queues command to the Service Partition - * @scsicmd: Command to be queued - * @vsiorhba_cmnd_done: Done command to call when scsicmd is returned + * dma_data_dir_linux_to_spar - convert dma_data_direction value to + * Unisys-specific equivalent + * @d: dma direction value to convert + * + * Returns the Unisys-specific dma direction value corresponding to @d + */ +static u32 dma_data_dir_linux_to_spar(enum dma_data_direction d) +{ + switch (d) { + case DMA_BIDIRECTIONAL: + return UIS_DMA_BIDIRECTIONAL; + case DMA_TO_DEVICE: + return UIS_DMA_TO_DEVICE; + case DMA_FROM_DEVICE: + return UIS_DMA_FROM_DEVICE; + case DMA_NONE: + return UIS_DMA_NONE; + default: + return UIS_DMA_NONE; + } +} + +/* + * visorhba_queue_command_lck - Queues command to the Service Partition + * @scsicmd: Command to be queued + * @vsiorhba_cmnd_done: Done command to call when scsicmd is returned * - * Queues to scsicmd to the ServicePartition after converting it to a - * uiscmdrsp structure. + * Queues to scsicmd to the ServicePartition after converting it to a + * uiscmdrsp structure. * - * Returns success if queued to the Service Partition, otherwise - * failure. + * Return: 0 if successfully queued to the Service Partition, otherwise + * error code */ -static int -visorhba_queue_command_lck(struct scsi_cmnd *scsicmd, - void (*visorhba_cmnd_done)(struct scsi_cmnd *)) +static int visorhba_queue_command_lck(struct scsi_cmnd *scsicmd, + void (*visorhba_cmnd_done) + (struct scsi_cmnd *)) { struct uiscmdrsp *cmdrsp; struct scsi_device *scsidev = scsicmd->device; @@ -494,12 +531,10 @@ visorhba_queue_command_lck(struct scsi_cmnd *scsicmd, insert_location = add_scsipending_entry(devdata, CMD_SCSI_TYPE, (void *)scsicmd); - if (insert_location < 0) return SCSI_MLQUEUE_DEVICE_BUSY; cmdrsp = get_scsipending_cmdrsp(devdata, insert_location); - cmdrsp->cmdtype = CMD_SCSI_TYPE; /* save the pending insertion location. Deletion from pending * will return the scsicmd pointer for completion @@ -513,9 +548,9 @@ visorhba_queue_command_lck(struct scsi_cmnd *scsicmd, cmdrsp->scsi.vdest.id = scsidev->id; cmdrsp->scsi.vdest.lun = scsidev->lun; /* save datadir */ - cmdrsp->scsi.data_dir = scsicmd->sc_data_direction; + cmdrsp->scsi.data_dir = + dma_data_dir_linux_to_spar(scsicmd->sc_data_direction); memcpy(cmdrsp->scsi.cmnd, cdb, MAX_CMND_SIZE); - cmdrsp->scsi.bufflen = scsi_bufflen(scsicmd); /* keep track of the max buffer length so far. */ @@ -555,13 +590,13 @@ static DEF_SCSI_QCMD(visorhba_queue_command) #endif /* - * visorhba_slave_alloc - called when new disk is discovered - * @scsidev: New disk + * visorhba_slave_alloc - Called when new disk is discovered + * @scsidev: New disk * - * Create a new visordisk_info structure and add it to our - * list of vdisks. + * Create a new visordisk_info structure and add it to our + * list of vdisks. * - * Returns success when created, otherwise error. + * Return: 0 on success, -ENOMEM on failure. */ static int visorhba_slave_alloc(struct scsi_device *scsidev) { @@ -573,12 +608,14 @@ static int visorhba_slave_alloc(struct scsi_device *scsidev) struct visorhba_devdata *devdata; struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host; + /* even though we errored, treat as success */ devdata = (struct visorhba_devdata *)scsihost->hostdata; if (!devdata) - return 0; /* even though we errored, treat as success */ + return 0; + /* already allocated return success */ for_each_vdisk_match(vdisk, devdata, scsidev) - return 0; /* already allocated return success */ + return 0; tmpvdisk = kzalloc(sizeof(*tmpvdisk), GFP_ATOMIC); if (!tmpvdisk) @@ -592,11 +629,8 @@ static int visorhba_slave_alloc(struct scsi_device *scsidev) } /* - * visorhba_slave_destroy - disk is going away - * @scsidev: scsi device going away - * - * Disk is going away, clean up resources. - * Returns void. + * visorhba_slave_destroy - Disk is going away, clean up resources. + * @scsidev: Scsi device to destroy */ static void visorhba_slave_destroy(struct scsi_device *scsidev) { @@ -635,10 +669,13 @@ static struct scsi_host_template visorhba_driver_template = { }; /* - * info_debugfs_show - debugfs interface to dump visorhba states + * info_debugfs_show - Debugfs interface to dump visorhba states + * @seq: The sequence file to write information to + * @v: Unused, but needed for use with seq file single_open invocation + * + * Presents a file in the debugfs tree named: /visorhba/vbus<x>:dev<y>/info. * - * This presents a file in the debugfs tree named: - * /visorhba/vbus<x>:dev<y>/info + * Return: SUCCESS */ static int info_debugfs_show(struct seq_file *seq, void *v) { @@ -679,12 +716,13 @@ static const struct file_operations info_debugfs_fops = { }; /* - * complete_taskmgmt_command - complete task management - * @cmdrsp: Response from the IOVM + * complete_taskmgmt_command - Complete task management + * @idrtable: The data object maintaining the pointer<-->int mappings + * @cmdrsp: Response from the IOVM + * @result: The result of the task management command * - * Service Partition returned the result of the task management - * command. Wake up anyone waiting for it. - * Returns void + * Service Partition returned the result of the task management + * command. Wake up anyone waiting for it. */ static void complete_taskmgmt_command(struct idr *idrtable, struct uiscmdrsp *cmdrsp, int result) @@ -693,7 +731,6 @@ static void complete_taskmgmt_command(struct idr *idrtable, idr_find(idrtable, cmdrsp->scsitaskmgmt.notify_handle); int *scsi_result_ptr = idr_find(idrtable, cmdrsp->scsitaskmgmt.notifyresult_handle); - if (unlikely(!(wq && scsi_result_ptr))) { pr_err("visorhba: no completion context; cmd will time out\n"); return; @@ -708,13 +745,12 @@ static void complete_taskmgmt_command(struct idr *idrtable, } /* - * visorhba_serverdown_complete - Called when we are done cleaning up - * from serverdown - * @work: work structure for this serverdown request + * visorhba_serverdown_complete - Called when we are done cleaning up + * from serverdown + * @devdata: Visorhba instance on which to complete serverdown * - * Called when we are done cleanning up from serverdown, stop processing - * queue, fail pending IOs. - * Returns void when finished cleaning up + * Called when we are done cleanning up from serverdown, stop processing + * queue, fail pending IOs. */ static void visorhba_serverdown_complete(struct visorhba_devdata *devdata) { @@ -758,12 +794,13 @@ static void visorhba_serverdown_complete(struct visorhba_devdata *devdata) } /* - * visorhba_serverdown - Got notified that the IOVM is down - * @devdata: visorhba that is being serviced by downed IOVM. + * visorhba_serverdown - Got notified that the IOVM is down + * @devdata: Visorhba that is being serviced by downed IOVM + * + * Something happened to the IOVM, return immediately and + * schedule cleanup work. * - * Something happened to the IOVM, return immediately and - * schedule work cleanup work. - * Return SUCCESS or EINVAL + * Return: 0 on success, -EINVAL on failure */ static int visorhba_serverdown(struct visorhba_devdata *devdata) { @@ -777,15 +814,14 @@ static int visorhba_serverdown(struct visorhba_devdata *devdata) } /* - * do_scsi_linuxstat - scsi command returned linuxstat - * @cmdrsp: response from IOVM - * @scsicmd: Command issued. + * do_scsi_linuxstat - Scsi command returned linuxstat + * @cmdrsp: Response from IOVM + * @scsicmd: Command issued * - * Don't log errors for disk-not-present inquiries - * Returns void + * Don't log errors for disk-not-present inquiries. */ -static void -do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) +static void do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, + struct scsi_cmnd *scsicmd) { struct visorhba_devdata *devdata; struct visordisk_info *vdisk; @@ -809,10 +845,10 @@ do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) } } -static int set_no_disk_inquiry_result(unsigned char *buf, - size_t len, bool is_lun0) +static int set_no_disk_inquiry_result(unsigned char *buf, size_t len, + bool is_lun0) { - if (!buf || len < NO_DISK_INQUIRY_RESULT_LEN) + if (len < NO_DISK_INQUIRY_RESULT_LEN) return -EINVAL; memset(buf, 0, NO_DISK_INQUIRY_RESULT_LEN); buf[2] = SCSI_SPC2_VER; @@ -828,15 +864,14 @@ static int set_no_disk_inquiry_result(unsigned char *buf, } /* - * do_scsi_nolinuxstat - scsi command didn't have linuxstat - * @cmdrsp: response from IOVM - * @scsicmd: Command issued. + * do_scsi_nolinuxstat - Scsi command didn't have linuxstat + * @cmdrsp: Response from IOVM + * @scsicmd: Command issued * - * Handle response when no linuxstat was returned - * Returns void + * Handle response when no linuxstat was returned. */ -static void -do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) +static void do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, + struct scsi_cmnd *scsicmd) { struct scsi_device *scsidev; unsigned char *buf; @@ -895,16 +930,15 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) } /* - * complete_scsi_command - complete a scsi command - * @uiscmdrsp: Response from Service Partition - * @scsicmd: The scsi command + * complete_scsi_command - Complete a scsi command + * @uiscmdrsp: Response from Service Partition + * @scsicmd: The scsi command * - * Response returned by the Service Partition, finish it and send - * completion to the scsi midlayer. - * Returns void. + * Response was returned by the Service Partition. Finish it and send + * completion to the scsi midlayer. */ -static void -complete_scsi_command(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) +static void complete_scsi_command(struct uiscmdrsp *cmdrsp, + struct scsi_cmnd *scsicmd) { /* take what we need out of cmdrsp and complete the scsicmd */ scsicmd->result = cmdrsp->scsi.linuxstat; @@ -917,24 +951,23 @@ complete_scsi_command(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) } /* - * drain_queue - pull responses out of iochannel - * @cmdrsp: Response from the IOSP - * @devdata: device that owns this iochannel + * drain_queue - Pull responses out of iochannel + * @cmdrsp: Response from the IOSP + * @devdata: Device that owns this iochannel * - * Pulls responses out of the iochannel and process the responses. - * Restuns void + * Pulls responses out of the iochannel and process the responses. */ -static void -drain_queue(struct uiscmdrsp *cmdrsp, struct visorhba_devdata *devdata) +static void drain_queue(struct uiscmdrsp *cmdrsp, + struct visorhba_devdata *devdata) { struct scsi_cmnd *scsicmd; while (1) { + /* queue empty */ if (visorchannel_signalremove(devdata->dev->visorchannel, IOCHAN_FROM_IOPART, cmdrsp)) - break; /* queue empty */ - + break; if (cmdrsp->cmdtype == CMD_SCSI_TYPE) { /* scsicmd location is returned by the * deletion @@ -959,12 +992,14 @@ drain_queue(struct uiscmdrsp *cmdrsp, struct visorhba_devdata *devdata) } /* - * process_incoming_rsps - Process responses from IOSP - * @v: void pointer to visorhba_devdata + * process_incoming_rsps - Process responses from IOSP + * @v: Void pointer to visorhba_devdata * - * Main function for the thread that processes the responses - * from the IO Service Partition. When the queue is empty, wait - * to check to see if it is full again. + * Main function for the thread that processes the responses + * from the IO Service Partition. When the queue is empty, wait + * to check to see if it is full again. + * + * Return: 0 on success, -ENOMEM on failure */ static int process_incoming_rsps(void *v) { @@ -991,14 +1026,15 @@ static int process_incoming_rsps(void *v) } /* - * visorhba_pause - function to handle visorbus pause messages - * @dev: device that is pausing. - * @complete_func: function to call when finished + * visorhba_pause - Function to handle visorbus pause messages + * @dev: Device that is pausing + * @complete_func: Function to call when finished + * + * Something has happened to the IO Service Partition that is + * handling this device. Quiet this device and reset commands + * so that the Service Partition can be corrected. * - * Something has happened to the IO Service Partition that is - * handling this device. Quiet this device and reset commands - * so that the Service Partition can be corrected. - * Returns SUCCESS + * Return: SUCCESS */ static int visorhba_pause(struct visor_device *dev, visorbus_state_complete_func complete_func) @@ -1011,13 +1047,14 @@ static int visorhba_pause(struct visor_device *dev, } /* - * visorhba_resume - function called when the IO Service Partition is back - * @dev: device that is pausing. - * @complete_func: function to call when finished + * visorhba_resume - Function called when the IO Service Partition is back + * @dev: Device that is pausing + * @complete_func: Function to call when finished * - * Yay! The IO Service Partition is back, the channel has been wiped - * so lets re-establish connection and start processing responses. - * Returns 0 on success, error on failure. + * Yay! The IO Service Partition is back, the channel has been wiped + * so lets re-establish connection and start processing responses. + * + * Return: 0 on success, -EINVAL on failure */ static int visorhba_resume(struct visor_device *dev, visorbus_state_complete_func complete_func) @@ -1033,7 +1070,6 @@ static int visorhba_resume(struct visor_device *dev, devdata->thread = visor_thread_start(process_incoming_rsps, devdata, "vhba_incming"); - devdata->serverdown = false; devdata->serverchangingstate = false; @@ -1041,11 +1077,12 @@ static int visorhba_resume(struct visor_device *dev, } /* - * visorhba_probe - device has been discovered, do acquire - * @dev: visor_device that was discovered + * visorhba_probe - Device has been discovered; do acquire + * @dev: visor_device that was discovered * - * A new HBA was discovered, do the initial connections of it. - * Return 0 on success, otherwise error. + * A new HBA was discovered; do the initial connections of it. + * + * Return: 0 on success, otherwise error code */ static int visorhba_probe(struct visor_device *dev) { @@ -1139,11 +1176,10 @@ err_scsi_host_put: } /* - * visorhba_remove - remove a visorhba device - * @dev: Device to remove + * visorhba_remove - Remove a visorhba device + * @dev: Device to remove * - * Removes the visorhba device. - * Returns void. + * Removes the visorhba device. */ static void visorhba_remove(struct visor_device *dev) { @@ -1181,10 +1217,12 @@ static struct visor_driver visorhba_driver = { }; /* - * visorhba_init - driver init routine + * visorhba_init - Driver init routine + * + * Initialize the visorhba driver and register it with visorbus + * to handle s-Par virtual host bus adapter. * - * Initialize the visorhba driver and register it with visorbus - * to handle s-Par virtual host bus adapter. + * Return: 0 on success, error code otherwise */ static int visorhba_init(void) { @@ -1207,9 +1245,9 @@ cleanup_debugfs: } /* - * visorhba_exit - driver exit routine + * visorhba_exit - Driver exit routine * - * Unregister driver from the bus and free up memory. + * Unregister driver from the bus and free up memory. */ static void visorhba_exit(void) { diff --git a/drivers/staging/unisys/visorinput/ultrainputreport.h b/drivers/staging/unisys/visorinput/ultrainputreport.h index a4baea53c518..53975a09535f 100644 --- a/drivers/staging/unisys/visorinput/ultrainputreport.h +++ b/drivers/staging/unisys/visorinput/ultrainputreport.h @@ -1,4 +1,5 @@ -/* Copyright (C) 2010 - 2015 UNISYS CORPORATION +/* + * Copyright (C) 2010 - 2015 UNISYS CORPORATION * All rights reserved. * * This program is free software; you can redistribute it and/or modify it @@ -20,44 +21,35 @@ /* These defines identify mouse and keyboard activity which is specified by the * firmware to the host using the cmsimpleinput protocol. @ingroup coretypes */ -#define INPUTACTION_XY_MOTION 1 /* only motion; arg1=x, arg2=y */ -#define INPUTACTION_MOUSE_BUTTON_DOWN 2 /* arg1: 1=left,2=center,3=right */ -#define INPUTACTION_MOUSE_BUTTON_UP 3 /* arg1: 1=left,2=center,3=right */ -#define INPUTACTION_MOUSE_BUTTON_CLICK 4 /* arg1: 1=left,2=center,3=right */ -#define INPUTACTION_MOUSE_BUTTON_DCLICK 5 /* arg1: 1=left,2=center, - * 3=right - */ -#define INPUTACTION_WHEEL_ROTATE_AWAY 6 /* arg1: wheel rotation away from - * user - */ -#define INPUTACTION_WHEEL_ROTATE_TOWARD 7 /* arg1: wheel rotation toward - * user - */ -#define INPUTACTION_KEY_DOWN 64 /* arg1: scancode, as follows: - * If arg1 <= 0xff, it's a 1-byte - * scancode and arg1 is that scancode. - * If arg1 > 0xff, it's a 2-byte - * scanecode, with the 1st byte in the - * low 8 bits, and the 2nd byte in the - * high 8 bits. E.g., the right ALT key - * would appear as x'38e0'. - */ -#define INPUTACTION_KEY_UP 65 /* arg1: scancode (in same format as - * inputaction_keyDown) - */ + /* only motion; arg1=x, arg2=y */ +#define INPUTACTION_XY_MOTION 1 +/* arg1: 1=left,2=center,3=right */ +#define INPUTACTION_MOUSE_BUTTON_DOWN 2 +/* arg1: 1=left,2=center,3=right */ +#define INPUTACTION_MOUSE_BUTTON_UP 3 +/* arg1: 1=left,2=center,3=right */ +#define INPUTACTION_MOUSE_BUTTON_CLICK 4 +/* arg1: 1=left,2=center 3=right */ +#define INPUTACTION_MOUSE_BUTTON_DCLICK 5 +/* arg1: wheel rotation away from user */ +#define INPUTACTION_WHEEL_ROTATE_AWAY 6 +/* arg1: wheel rotation toward user */ +#define INPUTACTION_WHEEL_ROTATE_TOWARD 7 +/* arg1: scancode, as follows: If arg1 <= 0xff, it's a 1-byte scancode and arg1 + * is that scancode. If arg1 > 0xff, it's a 2-byte scanecode, with the 1st + * byte in the low 8 bits, and the 2nd byte in the high 8 bits. + * E.g., the right ALT key would appear as x'38e0'. + */ +#define INPUTACTION_KEY_DOWN 64 +/* arg1: scancode (in same format as inputaction_keyDown) */ +#define INPUTACTION_KEY_UP 65 +/* arg1: scancode (in same format as inputaction_keyDown); MUST refer to one of + * the locking keys, like capslock, numlock, or scrolllock. + * arg2: 1 iff locking key should be in the LOCKED position (e.g., light is ON) + */ #define INPUTACTION_SET_LOCKING_KEY_STATE 66 - /* arg1: scancode (in same format - * as inputaction_keyDown); - * MUST refer to one of the - * locking keys, like capslock, - * numlock, or scrolllock - * arg2: 1 iff locking key should be - * in the LOCKED position - * (e.g., light is ON) - */ -#define INPUTACTION_KEY_DOWN_UP 67 /* arg1: scancode (in same format - * as inputaction_keyDown) - */ +/* arg1: scancode (in same format as inputaction_keyDown */ +#define INPUTACTION_KEY_DOWN_UP 67 struct visor_inputactivity { u16 action; diff --git a/drivers/staging/unisys/visorinput/visorinput.c b/drivers/staging/unisys/visorinput/visorinput.c index 45bc340d4e9d..9d8cbc52de8b 100644 --- a/drivers/staging/unisys/visorinput/visorinput.c +++ b/drivers/staging/unisys/visorinput/visorinput.c @@ -1,5 +1,4 @@ -/* visorinput.c - * +/* * Copyright (C) 2011 - 2015 UNISYS CORPORATION * All rights reserved. * @@ -21,11 +20,8 @@ * standard way the Linux expects for input drivers. */ -#include <linux/buffer_head.h> #include <linux/fb.h> -#include <linux/fs.h> #include <linux/input.h> -#include <linux/uaccess.h> #include <linux/kernel.h> #include <linux/uuid.h> @@ -33,16 +29,16 @@ #include "ultrainputreport.h" /* Keyboard channel {c73416d0-b0b8-44af-b304-9d2ae99f1b3d} */ -#define VISOR_KEYBOARD_CHANNEL_UUID \ - UUID_LE(0xc73416d0, 0xb0b8, 0x44af, \ - 0xb3, 0x4, 0x9d, 0x2a, 0xe9, 0x9f, 0x1b, 0x3d) -#define VISOR_KEYBOARD_CHANNEL_UUID_STR "c73416d0-b0b8-44af-b304-9d2ae99f1b3d" +#define VISOR_KEYBOARD_CHANNEL_GUID \ + GUID_INIT(0xc73416d0, 0xb0b8, 0x44af, \ + 0xb3, 0x4, 0x9d, 0x2a, 0xe9, 0x9f, 0x1b, 0x3d) +#define VISOR_KEYBOARD_CHANNEL_GUID_STR "c73416d0-b0b8-44af-b304-9d2ae99f1b3d" /* Mouse channel {addf07d4-94a9-46e2-81c3-61abcdbdbd87} */ -#define VISOR_MOUSE_CHANNEL_UUID \ - UUID_LE(0xaddf07d4, 0x94a9, 0x46e2, \ - 0x81, 0xc3, 0x61, 0xab, 0xcd, 0xbd, 0xbd, 0x87) -#define VISOR_MOUSE_CHANNEL_UUID_STR "addf07d4-94a9-46e2-81c3-61abcdbdbd87" +#define VISOR_MOUSE_CHANNEL_GUID \ + GUID_INIT(0xaddf07d4, 0x94a9, 0x46e2, \ + 0x81, 0xc3, 0x61, 0xab, 0xcd, 0xbd, 0xbd, 0x87) +#define VISOR_MOUSE_CHANNEL_GUID_STR "addf07d4-94a9-46e2-81c3-61abcdbdbd87" #define PIXELS_ACROSS_DEFAULT 800 #define PIXELS_DOWN_DEFAULT 600 @@ -60,17 +56,19 @@ enum visorinput_device_type { */ struct visorinput_devdata { struct visor_device *dev; - struct mutex lock_visor_dev; /* lock for dev */ + /* lock for dev */ + struct mutex lock_visor_dev; struct input_dev *visorinput_dev; bool paused; bool interrupts_enabled; - unsigned int keycode_table_bytes; /* size of following array */ + /* size of following array */ + unsigned int keycode_table_bytes; /* for keyboard devices: visorkbd_keycode[] + visorkbd_ext_keycode[] */ unsigned char keycode_table[0]; }; -static const uuid_le visor_keyboard_channel_uuid = VISOR_KEYBOARD_CHANNEL_UUID; -static const uuid_le visor_mouse_channel_uuid = VISOR_MOUSE_CHANNEL_UUID; +static const guid_t visor_keyboard_channel_guid = VISOR_KEYBOARD_CHANNEL_GUID; +static const guid_t visor_mouse_channel_guid = VISOR_MOUSE_CHANNEL_GUID; /* * Borrowed from drivers/input/keyboard/atakbd.c @@ -162,9 +160,8 @@ static const unsigned char visorkbd_keycode[KEYCODE_TABLE_BYTES] = { [81] = KEY_KP3, [82] = KEY_KP0, [83] = KEY_KPDOT, - [86] = KEY_102ND, /* enables UK backslash+pipe key, - * and FR lessthan+greaterthan key - */ + /* enables UK backslash+pipe key and FR lessthan+greaterthan key */ + [86] = KEY_102ND, [87] = KEY_F11, [88] = KEY_F12, [90] = KEY_KPLEFTPAREN, @@ -260,7 +257,6 @@ static void visorinput_close(struct input_dev *visorinput_dev) * interrupts should be disabled so when we resume we will * not re-enable them. */ - mutex_lock(&devdata->lock_visor_dev); devdata->interrupts_enabled = false; if (devdata->paused) @@ -276,15 +272,13 @@ out_unlock: * we can use to deliver keyboard inputs to Linux. We of course do this when * we see keyboard inputs coming in on a keyboard channel. */ -static struct input_dev * -setup_client_keyboard(void *devdata, /* opaque on purpose */ - unsigned char *keycode_table) +static struct input_dev *setup_client_keyboard(void *devdata, + unsigned char *keycode_table) { int i; - struct input_dev *visorinput_dev; + struct input_dev *visorinput_dev = input_allocate_device(); - visorinput_dev = input_allocate_device(); if (!visorinput_dev) return NULL; @@ -302,7 +296,8 @@ setup_client_keyboard(void *devdata, /* opaque on purpose */ BIT_MASK(LED_SCROLLL) | BIT_MASK(LED_NUML); visorinput_dev->keycode = keycode_table; - visorinput_dev->keycodesize = 1; /* sizeof(unsigned char) */ + /* sizeof(unsigned char) */ + visorinput_dev->keycodesize = 1; visorinput_dev->keycodemax = KEYCODE_TABLE_BYTES; for (i = 1; i < visorinput_dev->keycodemax; i++) @@ -313,19 +308,18 @@ setup_client_keyboard(void *devdata, /* opaque on purpose */ visorinput_dev->open = visorinput_open; visorinput_dev->close = visorinput_close; - input_set_drvdata(visorinput_dev, devdata); /* pre input_register! */ + /* pre input_register! */ + input_set_drvdata(visorinput_dev, devdata); return visorinput_dev; } -static struct input_dev * -setup_client_mouse(void *devdata /* opaque on purpose */) +static struct input_dev *setup_client_mouse(void *devdata) { - struct input_dev *visorinput_dev = NULL; int xres, yres; struct fb_info *fb0; + struct input_dev *visorinput_dev = input_allocate_device(); - visorinput_dev = input_allocate_device(); if (!visorinput_dev) return NULL; @@ -354,14 +348,16 @@ setup_client_mouse(void *devdata /* opaque on purpose */) visorinput_dev->open = visorinput_open; visorinput_dev->close = visorinput_close; - input_set_drvdata(visorinput_dev, devdata); /* pre input_register! */ + /* pre input_register! */ + input_set_drvdata(visorinput_dev, devdata); input_set_capability(visorinput_dev, EV_REL, REL_WHEEL); return visorinput_dev; } -static struct visorinput_devdata * -devdata_create(struct visor_device *dev, enum visorinput_device_type devtype) +static struct visorinput_devdata *devdata_create( + struct visor_device *dev, + enum visorinput_device_type devtype) { struct visorinput_devdata *devdata = NULL; unsigned int extra_bytes = 0; @@ -446,16 +442,15 @@ err_kfree_devdata: return NULL; } -static int -visorinput_probe(struct visor_device *dev) +static int visorinput_probe(struct visor_device *dev) { - uuid_le guid; + const guid_t *guid; enum visorinput_device_type devtype; - guid = visorchannel_get_uuid(dev->visorchannel); - if (uuid_le_cmp(guid, visor_mouse_channel_uuid) == 0) + guid = visorchannel_get_guid(dev->visorchannel); + if (guid_equal(guid, &visor_mouse_channel_guid)) devtype = visorinput_mouse; - else if (uuid_le_cmp(guid, visor_keyboard_channel_uuid) == 0) + else if (guid_equal(guid, &visor_keyboard_channel_guid)) devtype = visorinput_keyboard; else return -ENODEV; @@ -465,15 +460,13 @@ visorinput_probe(struct visor_device *dev) return 0; } -static void -unregister_client_input(struct input_dev *visorinput_dev) +static void unregister_client_input(struct input_dev *visorinput_dev) { if (visorinput_dev) input_unregister_device(visorinput_dev); } -static void -visorinput_remove(struct visor_device *dev) +static void visorinput_remove(struct visor_device *dev) { struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device); @@ -499,9 +492,8 @@ visorinput_remove(struct visor_device *dev) * Make it so the current locking state of the locking key indicated by * <keycode> is as indicated by <desired_state> (1=locked, 0=unlocked). */ -static void -handle_locking_key(struct input_dev *visorinput_dev, - int keycode, int desired_state) +static void handle_locking_key(struct input_dev *visorinput_dev, int keycode, + int desired_state) { int led; @@ -533,17 +525,15 @@ handle_locking_key(struct input_dev *visorinput_dev, * with 0xE0 in the low byte and the extended scancode value in the next * higher byte. */ -static int -scancode_to_keycode(int scancode) +static int scancode_to_keycode(int scancode) { if (scancode > 0xff) return visorkbd_ext_keycode[(scancode >> 8) & 0xff]; - return visorkbd_keycode[scancode]; + return visorkbd_keycode[scancode]; } -static int -calc_button(int x) +static int calc_button(int x) { switch (x) { case 1: @@ -562,15 +552,13 @@ calc_button(int x) * client guest partition. It is called periodically so we can obtain inputs * from the channel, and deliver them to the guest OS. */ -static void -visorinput_channel_interrupt(struct visor_device *dev) +static void visorinput_channel_interrupt(struct visor_device *dev) { struct visor_inputreport r; int scancode, keycode; struct input_dev *visorinput_dev; int xmotion, ymotion, button; int i; - struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device); if (!devdata) @@ -626,7 +614,6 @@ visorinput_channel_interrupt(struct visor_device *dev) if (button < 0) break; input_report_key(visorinput_dev, button, 1); - input_sync(visorinput_dev); input_report_key(visorinput_dev, button, 0); input_sync(visorinput_dev); @@ -657,9 +644,8 @@ visorinput_channel_interrupt(struct visor_device *dev) } } -static int -visorinput_pause(struct visor_device *dev, - visorbus_state_complete_func complete_func) +static int visorinput_pause(struct visor_device *dev, + visorbus_state_complete_func complete_func) { int rc; struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device); @@ -681,7 +667,6 @@ visorinput_pause(struct visor_device *dev, * due to above, at this time no thread of execution will be * in visorinput_channel_interrupt() */ - devdata->paused = true; complete_func(dev, 0); rc = 0; @@ -691,9 +676,8 @@ out: return rc; } -static int -visorinput_resume(struct visor_device *dev, - visorbus_state_complete_func complete_func) +static int visorinput_resume(struct visor_device *dev, + visorbus_state_complete_func complete_func) { int rc; struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device); @@ -727,9 +711,9 @@ out: /* GUIDS for all channel types supported by this driver. */ static struct visor_channeltype_descriptor visorinput_channel_types[] = { - { VISOR_KEYBOARD_CHANNEL_UUID, "keyboard"}, - { VISOR_MOUSE_CHANNEL_UUID, "mouse"}, - { NULL_UUID_LE, NULL } + { VISOR_KEYBOARD_CHANNEL_GUID, "keyboard"}, + { VISOR_MOUSE_CHANNEL_GUID, "mouse"}, + {} }; static struct visor_driver visorinput_driver = { @@ -743,20 +727,8 @@ static struct visor_driver visorinput_driver = { .resume = visorinput_resume, }; -static int -visorinput_init(void) -{ - return visorbus_register_visor_driver(&visorinput_driver); -} - -static void -visorinput_cleanup(void) -{ - visorbus_unregister_visor_driver(&visorinput_driver); -} - -module_init(visorinput_init); -module_exit(visorinput_cleanup); +module_driver(visorinput_driver, visorbus_register_visor_driver, + visorbus_unregister_visor_driver); MODULE_DEVICE_TABLE(visorbus, visorinput_channel_types); @@ -764,5 +736,5 @@ MODULE_AUTHOR("Unisys"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("s-Par human input driver for virtual keyboard/mouse"); -MODULE_ALIAS("visorbus:" VISOR_MOUSE_CHANNEL_UUID_STR); -MODULE_ALIAS("visorbus:" VISOR_KEYBOARD_CHANNEL_UUID_STR); +MODULE_ALIAS("visorbus:" VISOR_MOUSE_CHANNEL_GUID_STR); +MODULE_ALIAS("visorbus:" VISOR_KEYBOARD_CHANNEL_GUID_STR); diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c index 2891622eef18..dc390eae2960 100644 --- a/drivers/staging/unisys/visornic/visornic_main.c +++ b/drivers/staging/unisys/visornic/visornic_main.c @@ -37,22 +37,28 @@ #define NAPI_WEIGHT 64 /* GUIDS for director channel type supported by this driver. */ +/* {8cd5994d-c58e-11da-95a9-00e08161165f} */ +#define VISOR_VNIC_CHANNEL_GUID \ + GUID_INIT(0x8cd5994d, 0xc58e, 0x11da, \ + 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) +#define VISOR_VNIC_CHANNEL_GUID_STR \ + "8cd5994d-c58e-11da-95a9-00e08161165f" + static struct visor_channeltype_descriptor visornic_channel_types[] = { /* Note that the only channel type we expect to be reported by the * bus driver is the VISOR_VNIC channel. */ - { VISOR_VNIC_CHANNEL_UUID, "ultravnic" }, - { NULL_UUID_LE, NULL } + { VISOR_VNIC_CHANNEL_GUID, "ultravnic" }, + {} }; MODULE_DEVICE_TABLE(visorbus, visornic_channel_types); -/* - * FIXME XXX: This next line of code must be fixed and removed before +/* FIXME XXX: This next line of code must be fixed and removed before * acceptance into the 'normal' part of the kernel. It is only here as a place * holder to get module autoloading functionality working for visorbus. Code * must be added to scripts/mode/file2alias.c, etc., to get this working * properly. */ -MODULE_ALIAS("visorbus:" VISOR_VNIC_CHANNEL_UUID_STR); +MODULE_ALIAS("visorbus:" VISOR_VNIC_CHANNEL_GUID_STR); struct chanstat { unsigned long got_rcv; @@ -68,10 +74,67 @@ struct chanstat { unsigned long extra_rcvbufs_sent; }; +/* struct visornic_devdata + * @enabled: 0 disabled 1 enabled to receive. + * @enab_dis_acked: NET_RCV_ENABLE/DISABLE acked by IOPART. + * @struct *dev: + * @struct *netdev: + * @struct net_stats: + * @interrupt_rcvd: + * @rsp_queue: + * @struct **rcvbuf: + * @incarnation_id: incarnation_id lets IOPART know about + * re-birth. + * @old_flags: flags as they were prior to + * set_multicast_list. + * @usage: count of users. + * @num_rcv_bufs: number of rcv buffers the vnic will post. + * @num_rcv_bufs_could_not_alloc: + * @num_rcvbuf_in_iovm: + * @alloc_failed_in_if_needed_cnt: + * @alloc_failed_in_repost_rtn_cnt: + * @max_outstanding_net_xmits: absolute max number of outstanding xmits + * - should never hit this. + * @upper_threshold_net_xmits: high water mark for calling + * netif_stop_queue(). + * @lower_threshold_net_xmits: high water mark for calling + * netif_wake_queue(). + * @struct xmitbufhead: xmitbufhead - head of the xmit buffer list + * sent to the IOPART end. + * @server_down_complete_func: + * @struct timeout_reset: + * @struct *cmdrsp_rcv: cmdrsp_rcv is used for posting/unposting rcv + * buffers. + * @struct *xmit_cmdrsp: xmit_cmdrsp - issues NET_XMIT - only one + * active xmit at a time. + * @server_down: IOPART is down. + * @server_change_state: Processing SERVER_CHANGESTATE msg. + * @going_away: device is being torn down. + * @struct *eth_debugfs_dir: + * @interrupts_rcvd: + * @interrupts_notme: + * @interrupts_disabled: + * @busy_cnt: + * @priv_lock: spinlock to access devdata structures. + * @flow_control_upper_hits: + * @flow_control_lower_hits: + * @n_rcv0: # rcvs of 0 buffers. + * @n_rcv1: # rcvs of 1 buffers. + * @n_rcv2: # rcvs of 2 buffers. + * @n_rcvx: # rcvs of >2 buffers. + * @found_repost_rcvbuf_cnt: # repost_rcvbuf_cnt. + * @repost_found_skb_cnt: # of found the skb. + * @n_repost_deficit: # of lost rcv buffers. + * @bad_rcv_buf: # of unknown rcv skb not freed. + * @n_rcv_packets_not_accepted: # bogs rcv packets. + * @queuefullmsg_logged: + * @struct chstat: + * @struct irq_poll_timer: + * @struct napi: + * @struct cmdrsp: + */ struct visornic_devdata { - /* 0 disabled 1 enabled to receive */ unsigned short enabled; - /* NET_RCV_ENABLE/DISABLE acked by IOPART */ unsigned short enab_dis_acked; struct visor_device *dev; @@ -80,59 +143,50 @@ struct visornic_devdata { atomic_t interrupt_rcvd; wait_queue_head_t rsp_queue; struct sk_buff **rcvbuf; - /* incarnation_id lets IOPART know about re-birth */ u64 incarnation_id; - /* flags as they were prior to set_multicast_list */ unsigned short old_flags; - atomic_t usage; /* count of users */ + atomic_t usage; - /* number of rcv buffers the vnic will post */ int num_rcv_bufs; int num_rcv_bufs_could_not_alloc; atomic_t num_rcvbuf_in_iovm; unsigned long alloc_failed_in_if_needed_cnt; unsigned long alloc_failed_in_repost_rtn_cnt; - /* absolute max number of outstanding xmits - should never hit this */ unsigned long max_outstanding_net_xmits; - /* high water mark for calling netif_stop_queue() */ unsigned long upper_threshold_net_xmits; - /* high water mark for calling netif_wake_queue() */ unsigned long lower_threshold_net_xmits; - /* xmitbufhead - head of the xmit buffer list sent to the IOPART end */ struct sk_buff_head xmitbufhead; visorbus_state_complete_func server_down_complete_func; struct work_struct timeout_reset; - /* cmdrsp_rcv is used for posting/unposting rcv buffers */ struct uiscmdrsp *cmdrsp_rcv; - /* xmit_cmdrsp - issues NET_XMIT - only one active xmit at a time */ struct uiscmdrsp *xmit_cmdrsp; - - bool server_down; /* IOPART is down */ - bool server_change_state; /* Processing SERVER_CHANGESTATE msg */ - bool going_away; /* device is being torn down */ + bool server_down; + bool server_change_state; + bool going_away; struct dentry *eth_debugfs_dir; u64 interrupts_rcvd; u64 interrupts_notme; u64 interrupts_disabled; u64 busy_cnt; - spinlock_t priv_lock; /* spinlock to access devdata structures */ + /* spinlock to access devdata structures. */ + spinlock_t priv_lock; /* flow control counter */ u64 flow_control_upper_hits; u64 flow_control_lower_hits; /* debug counters */ - unsigned long n_rcv0; /* # rcvs of 0 buffers */ - unsigned long n_rcv1; /* # rcvs of 1 buffers */ - unsigned long n_rcv2; /* # rcvs of 2 buffers */ - unsigned long n_rcvx; /* # rcvs of >2 buffers */ - unsigned long found_repost_rcvbuf_cnt; /* # repost_rcvbuf_cnt */ - unsigned long repost_found_skb_cnt; /* # of found the skb */ - unsigned long n_repost_deficit; /* # of lost rcv buffers */ - unsigned long bad_rcv_buf; /* # of unknown rcv skb not freed */ - unsigned long n_rcv_packets_not_accepted;/* # bogs rcv packets */ + unsigned long n_rcv0; + unsigned long n_rcv1; + unsigned long n_rcv2; + unsigned long n_rcvx; + unsigned long found_repost_rcvbuf_cnt; + unsigned long repost_found_skb_cnt; + unsigned long n_repost_deficit; + unsigned long bad_rcv_buf; + unsigned long n_rcv_packets_not_accepted; int queuefullmsg_logged; struct chanstat chstat; @@ -142,12 +196,11 @@ struct visornic_devdata { }; /* Returns next non-zero index on success or 0 on failure (i.e. out of room). */ -static u16 -add_physinfo_entries(u64 inp_pfn, u16 inp_off, u32 inp_len, u16 index, - u16 max_pi_arr_entries, struct phys_info pi_arr[]) +static u16 add_physinfo_entries(u64 inp_pfn, u16 inp_off, u16 inp_len, + u16 index, u16 max_pi_arr_entries, + struct phys_info pi_arr[]) { - u32 len; - u16 i, firstlen; + u16 i, len, firstlen; firstlen = PI_PAGE_SIZE - inp_off; if (inp_len <= firstlen) { @@ -171,29 +224,27 @@ add_physinfo_entries(u64 inp_pfn, u16 inp_off, u32 inp_len, u16 index, pi_arr[index].pi_len = firstlen; } else { pi_arr[index + i].pi_off = 0; - pi_arr[index + i].pi_len = - (u16)MINNUM(len, (u32)PI_PAGE_SIZE); + pi_arr[index + i].pi_len = min_t(u16, len, + PI_PAGE_SIZE); } } return index + i; } -/* - * visor_copy_fragsinfo_from_skb( - * @skb_in: skbuff that we are pulling the frags from - * @firstfraglen: length of first fragment in skb - * @frags_max: max len of frags array - * @frags: frags array filled in on output +/* visor_copy_fragsinfo_from_skb - copy fragment list in the SKB to a phys_info + * array that the IOPART understands + * @skb: Skbuff that we are pulling the frags from. + * @firstfraglen: Length of first fragment in skb. + * @frags_max: Max len of frags array. + * @frags: Frags array filled in on output. * - * Copy the fragment list in the SKB to a phys_info - * array that the IOPART understands. - * Return value indicates number of entries filled in frags - * Negative values indicate an error. + * Return: Positive integer indicating number of entries filled in frags on + * success, negative integer on error. */ -static int -visor_copy_fragsinfo_from_skb(struct sk_buff *skb, unsigned int firstfraglen, - unsigned int frags_max, - struct phys_info frags[]) +static int visor_copy_fragsinfo_from_skb(struct sk_buff *skb, + unsigned int firstfraglen, + unsigned int frags_max, + struct phys_info frags[]) { unsigned int count = 0, frag, size, offset = 0, numfrags; unsigned int total_count; @@ -239,11 +290,10 @@ visor_copy_fragsinfo_from_skb(struct sk_buff *skb, unsigned int firstfraglen, for (frag = 0; frag < numfrags; frag++) { count = add_physinfo_entries(page_to_pfn( - skb_frag_page(&skb_shinfo(skb)->frags[frag])), - skb_shinfo(skb)->frags[frag]. - page_offset, - skb_shinfo(skb)->frags[frag]. - size, count, frags_max, frags); + skb_frag_page(&skb_shinfo(skb)->frags[frag])), + skb_shinfo(skb)->frags[frag].page_offset, + skb_shinfo(skb)->frags[frag].size, count, + frags_max, frags); /* add_physinfo_entries only returns * zero if the frags array is out of room * That should never happen because we @@ -287,21 +337,15 @@ static const struct file_operations debugfs_enable_ints_fops = { .write = enable_ints_write, }; -/* - * visornic_serverdown_complete - IOPART went down, pause device - * @work: Work queue it was scheduled on +/* visornic_serverdown_complete - pause device following IOPART going down + * @devdata: Device managed by IOPART. * - * The IO partition has gone down and we need to do some cleanup - * for when it comes back. Treat the IO partition as the link - * being down. - * Returns void. + * The IO partition has gone down, and we need to do some cleanup for when it + * comes back. Treat the IO partition as the link being down. */ -static void -visornic_serverdown_complete(struct visornic_devdata *devdata) +static void visornic_serverdown_complete(struct visornic_devdata *devdata) { - struct net_device *netdev; - - netdev = devdata->netdev; + struct net_device *netdev = devdata->netdev; /* Stop polling for interrupts */ del_timer_sync(&devdata->irq_poll_timer); @@ -322,17 +366,17 @@ visornic_serverdown_complete(struct visornic_devdata *devdata) devdata->server_down_complete_func = NULL; } -/* - * visornic_serverdown - Command has notified us that IOPART is down - * @devdata: device that is being managed by IOPART +/* visornic_serverdown - Command has notified us that IOPART is down + * @devdata: Device managed by IOPART. + * @complete_func: Function to call when finished. + * + * Schedule the work needed to handle the server down request. Make sure we + * haven't already handled the server change state event. * - * Schedule the work needed to handle the server down request. Make - * sure we haven't already handled the server change state event. - * Returns 0 if we scheduled the work, -EINVAL on error. + * Return: 0 if we scheduled the work, negative integer on error. */ -static int -visornic_serverdown(struct visornic_devdata *devdata, - visorbus_state_complete_func complete_func) +static int visornic_serverdown(struct visornic_devdata *devdata, + visorbus_state_complete_func complete_func) { unsigned long flags; int err; @@ -369,16 +413,15 @@ err_unlock: return err; } -/* - * alloc_rcv_buf - alloc rcv buffer to be given to the IO Partition. - * @netdev: network adapter the rcv bufs are attached too. +/* alloc_rcv_buf - alloc rcv buffer to be given to the IO Partition + * @netdev: Network adapter the rcv bufs are attached too. * - * Create an sk_buff (rcv_buf) that will be passed to the IO Partition - * so that it can write rcv data into our memory space. - * Return pointer to sk_buff + * Create an sk_buff (rcv_buf) that will be passed to the IO Partition + * so that it can write rcv data into our memory space. + * + * Return: Pointer to sk_buff. */ -static struct sk_buff * -alloc_rcv_buf(struct net_device *netdev) +static struct sk_buff *alloc_rcv_buf(struct net_device *netdev) { struct sk_buff *skb; @@ -400,18 +443,15 @@ alloc_rcv_buf(struct net_device *netdev) return skb; } -/* - * post_skb - post a skb to the IO Partition. - * @cmdrsp: cmdrsp packet to be send to the IO Partition - * @devdata: visornic_devdata to post the skb too - * @skb: skb to give to the IO partition +/* post_skb - post a skb to the IO Partition + * @cmdrsp: Cmdrsp packet to be send to the IO Partition. + * @devdata: visornic_devdata to post the skb to. + * @skb: Skb to give to the IO partition. * - * Send the skb to the IO Partition. - * Returns 0 or error + * Return: 0 on success, negative integer on error. */ -static int -post_skb(struct uiscmdrsp *cmdrsp, - struct visornic_devdata *devdata, struct sk_buff *skb) +static int post_skb(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata, + struct sk_buff *skb) { int err; @@ -437,23 +477,20 @@ post_skb(struct uiscmdrsp *cmdrsp, atomic_inc(&devdata->num_rcvbuf_in_iovm); devdata->chstat.sent_post++; - return 0; } -/* - * send_enbdis - send NET_RCV_ENBDIS to IO Partition - * @netdev: netdevice we are enable/disable, used as context - * return value - * @state: enable = 1/disable = 0 - * @devdata: visornic device we are enabling/disabling +/* send_enbdis - Send NET_RCV_ENBDIS to IO Partition + * @netdev: Netdevice we are enabling/disabling, used as context return value. + * @state: Enable = 1/disable = 0. + * @devdata: Visornic device we are enabling/disabling. + * + * Send the enable/disable message to the IO Partition. * - * Send the enable/disable message to the IO Partition. - * Returns 0 or error + * Return: 0 on success, negative integer on error. */ -static int -send_enbdis(struct net_device *netdev, int state, - struct visornic_devdata *devdata) +static int send_enbdis(struct net_device *netdev, int state, + struct visornic_devdata *devdata) { int err; @@ -470,19 +507,17 @@ send_enbdis(struct net_device *netdev, int state, return 0; } -/* - * visornic_disable_with_timeout - Disable network adapter - * @netdev: netdevice to disable - * @timeout: timeout to wait for disable +/* visornic_disable_with_timeout - disable network adapter + * @netdev: netdevice to disable. + * @timeout: Timeout to wait for disable. * - * Disable the network adapter and inform the IO Partition that we - * are disabled, reclaim memory from rcv bufs. - * Returns 0 on success, negative for failure of IO Partition - * responding. + * Disable the network adapter and inform the IO Partition that we are disabled. + * Reclaim memory from rcv bufs. * + * Return: 0 on success, negative integer on failure of IO Partition responding. */ -static int -visornic_disable_with_timeout(struct net_device *netdev, const int timeout) +static int visornic_disable_with_timeout(struct net_device *netdev, + const int timeout) { struct visornic_devdata *devdata = netdev_priv(netdev); int i; @@ -493,7 +528,8 @@ visornic_disable_with_timeout(struct net_device *netdev, const int timeout) /* send a msg telling the other end we are stopping incoming pkts */ spin_lock_irqsave(&devdata->priv_lock, flags); devdata->enabled = 0; - devdata->enab_dis_acked = 0; /* must wait for ack */ + /* must wait for ack */ + devdata->enab_dis_acked = 0; spin_unlock_irqrestore(&devdata->priv_lock, flags); /* send disable and wait for ack -- don't hold lock when sending @@ -560,16 +596,16 @@ visornic_disable_with_timeout(struct net_device *netdev, const int timeout) return 0; } -/* - * init_rcv_bufs -- initialize receive bufs and send them to the IO Part - * @netdev: struct netdevice - * @devdata: visornic_devdata +/* init_rcv_bufs - initialize receive buffs and send them to the IO Partition + * @netdev: struct netdevice. + * @devdata: visornic_devdata. + * + * Allocate rcv buffers and post them to the IO Partition. * - * Allocate rcv buffers and post them to the IO Partition. - * Return 0 for success, and negative for failure. + * Return: 0 on success, negative integer on failure. */ -static int -init_rcv_bufs(struct net_device *netdev, struct visornic_devdata *devdata) +static int init_rcv_bufs(struct net_device *netdev, + struct visornic_devdata *devdata) { int i, j, count, err; @@ -578,10 +614,12 @@ init_rcv_bufs(struct net_device *netdev, struct visornic_devdata *devdata) */ for (i = 0; i < devdata->num_rcv_bufs; i++) { devdata->rcvbuf[i] = alloc_rcv_buf(netdev); + /* if we failed to allocate one let us stop */ if (!devdata->rcvbuf[i]) - break; /* if we failed to allocate one let us stop */ + break; } - if (i == 0) /* couldn't even allocate one -- bail out */ + /* couldn't even allocate one -- bail out */ + if (i == 0) return -ENOMEM; count = i; @@ -624,17 +662,17 @@ init_rcv_bufs(struct net_device *netdev, struct visornic_devdata *devdata) return 0; } -/* - * visornic_enable_with_timeout - send enable to IO Part - * @netdev: struct net_device - * @timeout: Time to wait for the ACK from the enable +/* visornic_enable_with_timeout - send enable to IO Partition + * @netdev: struct net_device. + * @timeout: Time to wait for the ACK from the enable. * - * Sends enable to IOVM, inits, and posts receive buffers to IOVM - * timeout is defined in msecs (timeout of 0 specifies infinite wait) - * Return 0 for success, negative for failure. + * Sends enable to IOVM and inits, and posts receive buffers to IOVM. Timeout is + * defined in msecs (timeout of 0 specifies infinite wait). + * + * Return: 0 on success, negative integer on failure. */ -static int -visornic_enable_with_timeout(struct net_device *netdev, const int timeout) +static int visornic_enable_with_timeout(struct net_device *netdev, + const int timeout) { int err = 0; struct visornic_devdata *devdata = netdev_priv(netdev); @@ -695,20 +733,17 @@ visornic_enable_with_timeout(struct net_device *netdev, const int timeout) } netif_start_queue(netdev); - return 0; } -/* - * visornic_timeout_reset - handle xmit timeout resets - * @work work item that scheduled the work +/* visornic_timeout_reset - handle xmit timeout resets + * @work: Work item that scheduled the work. * - * Transmit Timeouts are typically handled by resetting the - * device for our virtual NIC we will send a Disable and Enable - * to the IOVM. If it doesn't respond we will trigger a serverdown. + * Transmit timeouts are typically handled by resetting the device for our + * virtual NIC; we will send a disable and enable to the IOVM. If it doesn't + * respond, we will trigger a serverdown. */ -static void -visornic_timeout_reset(struct work_struct *work) +static void visornic_timeout_reset(struct work_struct *work) { struct visornic_devdata *devdata; struct net_device *netdev; @@ -742,41 +777,36 @@ call_serverdown: rtnl_unlock(); } -/* - * visornic_open - Enable the visornic device and mark the queue started - * @netdev: netdevice to start +/* visornic_open - enable the visornic device and mark the queue started + * @netdev: netdevice to start. * - * Enable the device and start the transmit queue. - * Return 0 for success + * Enable the device and start the transmit queue. + * + * Return: 0 on success. */ -static int -visornic_open(struct net_device *netdev) +static int visornic_open(struct net_device *netdev) { visornic_enable_with_timeout(netdev, VISORNIC_INFINITE_RSP_WAIT); - return 0; } -/* - * visornic_close - Disables the visornic device and stops the queues - * @netdev: netdevice to start +/* visornic_close - disables the visornic device and stops the queues + * @netdev: netdevice to stop. * - * Disable the device and stop the transmit queue. - * Return 0 for success + * Disable the device and stop the transmit queue. + * + * Return 0 on success. */ -static int -visornic_close(struct net_device *netdev) +static int visornic_close(struct net_device *netdev) { visornic_disable_with_timeout(netdev, VISORNIC_INFINITE_RSP_WAIT); - return 0; } -/* - * devdata_xmits_outstanding - compute outstanding xmits - * @devdata: visornic_devdata for device +/* devdata_xmits_outstanding - compute outstanding xmits + * @devdata: visornic_devdata for device * - * Return value is the number of outstanding xmits. + * Return: Long integer representing the number of outstanding xmits. */ static unsigned long devdata_xmits_outstanding(struct visornic_devdata *devdata) { @@ -787,14 +817,13 @@ static unsigned long devdata_xmits_outstanding(struct visornic_devdata *devdata) + devdata->chstat.sent_xmit + 1); } -/* - * vnic_hit_high_watermark - * @devdata: indicates visornic device we are checking - * @high_watermark: max num of unacked xmits we will tolerate, - * before we will start throttling +/* vnic_hit_high_watermark + * @devdata: Indicates visornic device we are checking. + * @high_watermark: Max num of unacked xmits we will tolerate before we will + * start throttling. * - * Returns true iff the number of unacked xmits sent to - * the IO partition is >= high_watermark. + * Return: True iff the number of unacked xmits sent to the IO Partition is >= + * high_watermark. False otherwise. */ static bool vnic_hit_high_watermark(struct visornic_devdata *devdata, ulong high_watermark) @@ -802,15 +831,13 @@ static bool vnic_hit_high_watermark(struct visornic_devdata *devdata, return (devdata_xmits_outstanding(devdata) >= high_watermark); } -/* - * vnic_hit_low_watermark - * @devdata: indicates visornic device we are checking - * @low_watermark: we will wait until the num of unacked xmits - * drops to this value or lower before we start - * transmitting again +/* vnic_hit_low_watermark + * @devdata: Indicates visornic device we are checking. + * @low_watermark: We will wait until the num of unacked xmits drops to this + * value or lower before we start transmitting again. * - * Returns true iff the number of unacked xmits sent to - * the IO partition is <= low_watermark. + * Return: True iff the number of unacked xmits sent to the IO Partition is <= + * low_watermark. */ static bool vnic_hit_low_watermark(struct visornic_devdata *devdata, ulong low_watermark) @@ -818,20 +845,18 @@ static bool vnic_hit_low_watermark(struct visornic_devdata *devdata, return (devdata_xmits_outstanding(devdata) <= low_watermark); } -/* - * visornic_xmit - send a packet to the IO Partition - * @skb: Packet to be sent - * @netdev: net device the packet is being sent from +/* visornic_xmit - send a packet to the IO Partition + * @skb: Packet to be sent. + * @netdev: Net device the packet is being sent from. + * + * Convert the skb to a cmdrsp so the IO Partition can understand it, and send + * the XMIT command to the IO Partition for processing. This function is + * protected from concurrent calls by a spinlock xmit_lock in the net_device + * struct. As soon as the function returns, it can be called again. * - * Convert the skb to a cmdrsp so the IO Partition can understand it. - * Send the XMIT command to the IO Partition for processing. This - * function is protected from concurrent calls by a spinlock xmit_lock - * in the net_device struct, but as soon as the function returns it - * can be called again. - * Returns NETDEV_TX_OK. + * Return: NETDEV_TX_OK. */ -static int -visornic_xmit(struct sk_buff *skb, struct net_device *netdev) +static int visornic_xmit(struct sk_buff *skb, struct net_device *netdev) { struct visornic_devdata *devdata; int len, firstfraglen, padlen; @@ -938,6 +963,7 @@ visornic_xmit(struct sk_buff *skb, struct net_device *netdev) * - everything else will be pass in frags & DMA'ed */ memcpy(cmdrsp->net.xmt.ethhdr, skb->data, ETH_HLEN); + /* copy frags info - from skb->data we need to only provide access * beyond eth header */ @@ -991,46 +1017,39 @@ visornic_xmit(struct sk_buff *skb, struct net_device *netdev) return NETDEV_TX_OK; } -/* - * visornic_get_stats - returns net_stats of the visornic device - * @netdev: netdevice +/* visornic_get_stats - returns net_stats of the visornic device + * @netdev: netdevice. * - * Returns the net_device_stats for the device + * Return: Pointer to the net_device_stats struct for the device. */ -static struct net_device_stats * -visornic_get_stats(struct net_device *netdev) +static struct net_device_stats *visornic_get_stats(struct net_device *netdev) { struct visornic_devdata *devdata = netdev_priv(netdev); return &devdata->net_stats; } -/* - * visornic_change_mtu - changes mtu of device. - * @netdev: netdevice - * @new_mtu: value of new mtu +/* visornic_change_mtu - changes mtu of device + * @netdev: netdevice. + * @new_mtu: Value of new mtu. + * + * The device's MTU cannot be changed by system; it must be changed via a + * CONTROLVM message. All vnics and pnics in a switch have to have the same MTU + * for everything to work. Currently not supported. * - * MTU cannot be changed by system, must be changed via - * CONTROLVM message. All vnics and pnics in a switch have - * to have the same MTU for everything to work. - * Currently not supported. - * Returns EINVAL + * Return: -EINVAL. */ -static int -visornic_change_mtu(struct net_device *netdev, int new_mtu) +static int visornic_change_mtu(struct net_device *netdev, int new_mtu) { return -EINVAL; } -/* - * visornic_set_multi - changes mtu of device. - * @netdev: netdevice +/* visornic_set_multi - set visornic device flags + * @netdev: netdevice. * - * Only flag we support currently is IFF_PROMISC - * Returns void + * The only flag we currently support is IFF_PROMISC. */ -static void -visornic_set_multi(struct net_device *netdev) +static void visornic_set_multi(struct net_device *netdev) { struct uiscmdrsp *cmdrsp; struct visornic_devdata *devdata = netdev_priv(netdev); @@ -1062,16 +1081,13 @@ out_save_flags: devdata->old_flags = netdev->flags; } -/* - * visornic_xmit_timeout - request to timeout the xmit - * @netdev +/* visornic_xmit_timeout - request to timeout the xmit + * @netdev: netdevice. * - * Queue the work and return. Make sure we have not already - * been informed the IO Partition is gone, if it is gone - * we will already timeout the xmits. + * Queue the work and return. Make sure we have not already been informed that + * the IO Partition is gone; if so, we will have already timed-out the xmits. */ -static void -visornic_xmit_timeout(struct net_device *netdev) +static void visornic_xmit_timeout(struct net_device *netdev) { struct visornic_devdata *devdata = netdev_priv(netdev); unsigned long flags; @@ -1097,20 +1113,20 @@ visornic_xmit_timeout(struct net_device *netdev) spin_unlock_irqrestore(&devdata->priv_lock, flags); } -/* - * repost_return - repost rcv bufs that have come back - * @cmdrsp: io channel command struct to post - * @devdata: visornic devdata for the device - * @skb: skb - * @netdev: netdevice +/* repost_return - repost rcv bufs that have come back + * @cmdrsp: IO channel command struct to post. + * @devdata: Visornic devdata for the device. + * @skb: Socket buffer. + * @netdev: netdevice. + * + * Repost rcv buffers that have been returned to us when we are finished + * with them. * - * Repost rcv buffers that have been returned to us when - * we are finished with them. - * Returns 0 for success, -1 for error. + * Return: 0 for success, negative integer on error. */ -static int -repost_return(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata, - struct sk_buff *skb, struct net_device *netdev) +static int repost_return(struct uiscmdrsp *cmdrsp, + struct visornic_devdata *devdata, + struct sk_buff *skb, struct net_device *netdev) { struct net_pkt_rcv copy; int i = 0, cc, numreposted; @@ -1174,16 +1190,15 @@ repost_return(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata, return status; } -/* - * visornic_rx - Handle receive packets coming back from IO Part - * @cmdrsp: Receive packet returned from IO Part +/* visornic_rx - handle receive packets coming back from IO Partition + * @cmdrsp: Receive packet returned from IO Partition. * - * Got a receive packet back from the IO Part, handle it and send - * it up the stack. - * Returns 1 iff an skb was received, otherwise 0 + * Got a receive packet back from the IO Partition; handle it and send it up + * the stack. + + * Return: 1 iff an skb was received, otherwise 0. */ -static int -visornic_rx(struct uiscmdrsp *cmdrsp) +static int visornic_rx(struct uiscmdrsp *cmdrsp) { struct visornic_devdata *devdata; struct sk_buff *skb, *prev, *curr; @@ -1236,7 +1251,8 @@ visornic_rx(struct uiscmdrsp *cmdrsp) * firstfrag & set data_len to show rest see if we have to chain * frag_list. */ - if (skb->len > RCVPOST_BUF_SIZE) { /* do PRECAUTIONARY check */ + /* do PRECAUTIONARY check */ + if (skb->len > RCVPOST_BUF_SIZE) { if (cmdrsp->net.rcv.numrcvbufs < 2) { if (repost_return(cmdrsp, devdata, skb, netdev) < 0) dev_err(&devdata->netdev->dev, @@ -1244,23 +1260,24 @@ visornic_rx(struct uiscmdrsp *cmdrsp) return 0; } /* length rcvd is greater than firstfrag in this skb rcv buf */ - skb->tail += RCVPOST_BUF_SIZE; /* amount in skb->data */ - skb->data_len = skb->len - RCVPOST_BUF_SIZE; /* amount that - * will be in - * frag_list - */ + /* amount in skb->data */ + skb->tail += RCVPOST_BUF_SIZE; + /* amount that will be in frag_list */ + skb->data_len = skb->len - RCVPOST_BUF_SIZE; } else { /* data fits in this skb - no chaining - do * PRECAUTIONARY check */ - if (cmdrsp->net.rcv.numrcvbufs != 1) { /* should be 1 */ + /* should be 1 */ + if (cmdrsp->net.rcv.numrcvbufs != 1) { if (repost_return(cmdrsp, devdata, skb, netdev) < 0) dev_err(&devdata->netdev->dev, "repost_return failed"); return 0; } skb->tail += skb->len; - skb->data_len = 0; /* nothing rcvd in frag_list */ + /* nothing rcvd in frag_list */ + skb->data_len = 0; } off = skb_tail_pointer(skb) - skb->data; @@ -1286,7 +1303,8 @@ visornic_rx(struct uiscmdrsp *cmdrsp) cc < cmdrsp->net.rcv.numrcvbufs; cc++) { curr = (struct sk_buff *)cmdrsp->net.rcv.rcvbuf[cc]; curr->next = NULL; - if (!prev) /* start of list- set head */ + /* start of list- set head */ + if (!prev) skb_shinfo(skb)->frag_list = curr; else prev->next = curr; @@ -1314,18 +1332,18 @@ visornic_rx(struct uiscmdrsp *cmdrsp) * sets up skb->pkt_type & it also PULLS out the eth header */ skb->protocol = eth_type_trans(skb, netdev); - eth = eth_hdr(skb); - skb->csum = 0; skb->ip_summed = CHECKSUM_NONE; do { + /* accept all packets */ if (netdev->flags & IFF_PROMISC) - break; /* accept all packets */ + break; if (skb->pkt_type == PACKET_BROADCAST) { + /* accept all broadcast packets */ if (netdev->flags & IFF_BROADCAST) - break; /* accept all broadcast packets */ + break; } else if (skb->pkt_type == PACKET_MULTICAST) { if ((netdev->flags & IFF_MULTICAST) && (netdev_mc_count(netdev))) { @@ -1367,8 +1385,7 @@ visornic_rx(struct uiscmdrsp *cmdrsp) */ skb = NULL; - /* - * whether the packet got dropped or handled, the skb is freed by + /* whether the packet got dropped or handled, the skb is freed by * kernel code, so we shouldn't free it. but we should repost a * new rcv buffer. */ @@ -1376,29 +1393,25 @@ visornic_rx(struct uiscmdrsp *cmdrsp) return 1; } -/* - * devdata_initialize - Initialize devdata structure - * @devdata: visornic_devdata structure to initialize - * #dev: visorbus_deviced it belongs to +/* devdata_initialize - initialize devdata structure + * @devdata: visornic_devdata structure to initialize. + * @dev: visorbus_device it belongs to. * - * Setup initial values for the visornic based on channel and default - * values. - * Returns a pointer to the devdata structure + * Setup initial values for the visornic, based on channel and default values. + * + * Return: A pointer to the devdata structure. */ -static struct visornic_devdata * -devdata_initialize(struct visornic_devdata *devdata, struct visor_device *dev) +static struct visornic_devdata *devdata_initialize( + struct visornic_devdata *devdata, + struct visor_device *dev) { devdata->dev = dev; devdata->incarnation_id = get_jiffies_64(); return devdata; } -/* - * devdata_release - Frees up references in devdata - * @devdata: struct to clean up - * - * Frees up references in devdata. - * Returns void +/* devdata_release - free up references in devdata + * @devdata: Struct to clean up. */ static void devdata_release(struct visornic_devdata *devdata) { @@ -1570,15 +1583,10 @@ static const struct file_operations debugfs_info_fops = { .read = info_debugfs_read, }; -/* - * send_rcv_posts_if_needed - * @devdata: visornic device - * - * Send receive buffers to the IO Partition. - * Returns void +/* send_rcv_posts_if_needed - send receive buffers to the IO Partition. + * @devdata: Visornic device. */ -static int -send_rcv_posts_if_needed(struct visornic_devdata *devdata) +static void send_rcv_posts_if_needed(struct visornic_devdata *devdata) { int i; struct net_device *netdev; @@ -1588,7 +1596,7 @@ send_rcv_posts_if_needed(struct visornic_devdata *devdata) /* don't do this until vnic is marked ready */ if (!(devdata->enabled && devdata->enab_dis_acked)) - return 0; + return; netdev = devdata->netdev; rcv_bufs_allocated = 0; @@ -1617,16 +1625,14 @@ send_rcv_posts_if_needed(struct visornic_devdata *devdata) } } devdata->num_rcv_bufs_could_not_alloc -= rcv_bufs_allocated; - return 0; } -/* - * drain_resp_queue - drains and ignores all messages from the resp queue - * @cmdrsp: io channel command response message - * @devdata: visornic device to drain +/* drain_resp_queue - drains and ignores all messages from the resp queue + * @cmdrsp: IO channel command response message. + * @devdata: Visornic device to drain. */ -static void -drain_resp_queue(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata) +static void drain_resp_queue(struct uiscmdrsp *cmdrsp, + struct visornic_devdata *devdata) { while (!visorchannel_signalremove(devdata->dev->visorchannel, IOCHAN_FROM_IOPART, @@ -1634,30 +1640,31 @@ drain_resp_queue(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata) ; } -/* - * service_resp_queue - drains the response queue - * @cmdrsp: io channel command response message - * @devdata: visornic device to drain +/* service_resp_queue - drain the response queue + * @cmdrsp: IO channel command response message. + * @devdata: Visornic device to drain. + * @rx_work_done: + * @budget: * - * Drain the response queue of any responses from the IO partition. - * Process the responses as we get them. - * Returns when response queue is empty or when the thread stops. + * Drain the response queue of any responses from the IO Partition. Process the + * responses as we get them. */ -static void -service_resp_queue(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata, - int *rx_work_done, int budget) +static void service_resp_queue(struct uiscmdrsp *cmdrsp, + struct visornic_devdata *devdata, + int *rx_work_done, int budget) { unsigned long flags; struct net_device *netdev; while (*rx_work_done < budget) { - /* TODO: CLIENT ACQUIRE -- Don't really need this at the - * moment - */ + /* TODO: CLIENT ACQUIRE -- Don't really need this at the + * moment + */ + /* queue empty */ if (visorchannel_signalremove(devdata->dev->visorchannel, IOCHAN_FROM_IOPART, cmdrsp)) - break; /* queue empty */ + break; switch (cmdrsp->net.type) { case NET_RCV: @@ -1740,12 +1747,8 @@ static int visornic_poll(struct napi_struct *napi, int budget) struct visornic_devdata, napi); int rx_count = 0; - int err; - - err = send_rcv_posts_if_needed(devdata); - if (err) - return err; + send_rcv_posts_if_needed(devdata); service_resp_queue(devdata->cmdrsp, devdata, &rx_count, budget); /* If there aren't any more packets to receive stop the poll */ @@ -1755,16 +1758,13 @@ static int visornic_poll(struct napi_struct *napi, int budget) return rx_count; } -/* - * poll_for_irq - Checks the status of the response queue. - * @v: void pointer to the visronic devdata +/* poll_for_irq - checks the status of the response queue + * @v: Void pointer to the visronic devdata struct. * - * Main function of the vnic_incoming thread. Periodically check the - * response queue and drain it if needed. - * Returns when thread has stopped. + * Main function of the vnic_incoming thread. Periodically check the response + * queue and drain it if needed. */ -static void -poll_for_irq(unsigned long v) +static void poll_for_irq(unsigned long v) { struct visornic_devdata *devdata = (struct visornic_devdata *)v; @@ -1778,13 +1778,13 @@ poll_for_irq(unsigned long v) mod_timer(&devdata->irq_poll_timer, msecs_to_jiffies(2)); } -/* - * visornic_probe - probe function for visornic devices - * @dev: The visor device discovered +/* visornic_probe - probe function for visornic devices + * @dev: The visor device discovered. + * + * Called when visorbus discovers a visornic device on its bus. It creates a new + * visornic ethernet adapter. * - * Called when visorbus discovers a visornic device on its - * bus. It creates a new visornic ethernet adapter. - * Returns 0 or negative for error. + * Return: 0 on success, or negative integer on error. */ static int visornic_probe(struct visor_device *dev) { @@ -1831,7 +1831,8 @@ static int visornic_probe(struct visor_device *dev) dev_set_drvdata(&dev->device, devdata); init_waitqueue_head(&devdata->rsp_queue); spin_lock_init(&devdata->priv_lock); - devdata->enabled = 0; /* not yet */ + /* not yet */ + devdata->enabled = 0; atomic_set(&devdata->usage, 1); /* Setup rcv bufs */ @@ -1852,9 +1853,10 @@ static int visornic_probe(struct visor_device *dev) goto cleanup_netdev; } - /* set the net_xmit outstanding threshold */ - /* always leave two slots open but you should have 3 at a minimum */ - /* note that max_outstanding_net_xmits must be > 0 */ + /* set the net_xmit outstanding threshold + * always leave two slots open but you should have 3 at a minimum + * note that max_outstanding_net_xmits must be > 0 + */ devdata->max_outstanding_net_xmits = max_t(unsigned long, 3, ((devdata->num_rcv_bufs / 3) - 2)); devdata->upper_threshold_net_xmits = @@ -1972,28 +1974,25 @@ cleanup_netdev: return err; } -/* - * host_side_disappeared - IO part is gone. - * @devdata: device object +/* host_side_disappeared - IO Partition is gone + * @devdata: Device object. * - * IO partition servicing this device is gone, do cleanup - * Returns void. + * IO partition servicing this device is gone; do cleanup. */ static void host_side_disappeared(struct visornic_devdata *devdata) { unsigned long flags; spin_lock_irqsave(&devdata->priv_lock, flags); - devdata->dev = NULL; /* indicate device destroyed */ + /* indicate device destroyed */ + devdata->dev = NULL; spin_unlock_irqrestore(&devdata->priv_lock, flags); } -/* - * visornic_remove - Called when visornic dev goes away - * @dev: visornic device that is being removed +/* visornic_remove - called when visornic dev goes away + * @dev: Visornic device that is being removed. * - * Called when DEVICE_DESTROY gets called to remove device. - * Returns void + * Called when DEVICE_DESTROY gets called to remove device. */ static void visornic_remove(struct visor_device *dev) { @@ -2023,8 +2022,8 @@ static void visornic_remove(struct visor_device *dev) cancel_work_sync(&devdata->timeout_reset); debugfs_remove_recursive(devdata->eth_debugfs_dir); - - unregister_netdev(netdev); /* this will call visornic_close() */ + /* this will call visornic_close() */ + unregister_netdev(netdev); del_timer_sync(&devdata->irq_poll_timer); netif_napi_del(&devdata->napi); @@ -2035,18 +2034,17 @@ static void visornic_remove(struct visor_device *dev) free_netdev(netdev); } -/* - * visornic_pause - Called when IO Part disappears - * @dev: visornic device that is being serviced - * @complete_func: call when finished. +/* visornic_pause - called when IO Part disappears + * @dev: Visornic device that is being serviced. + * @complete_func: Call when finished. + * + * Called when the IO Partition has gone down. Need to free up resources and + * wait for IO partition to come back. Mark link as down and don't attempt any + * DMA. When we have freed memory, call the complete_func so that Command knows + * we are done. If we don't call complete_func, the IO Partition will never + * come back. * - * Called when the IO Partition has gone down. Need to free - * up resources and wait for IO partition to come back. Mark - * link as down and don't attempt any DMA. When we have freed - * memory call the complete_func so that Command knows we are - * done. If we don't call complete_func, IO part will never - * come back. - * Returns 0 for success. + * Return: 0 on success. */ static int visornic_pause(struct visor_device *dev, visorbus_state_complete_func complete_func) @@ -2057,15 +2055,14 @@ static int visornic_pause(struct visor_device *dev, return 0; } -/* - * visornic_resume - Called when IO part has recovered - * @dev: visornic device that is being serviced - * @compelte_func: call when finished +/* visornic_resume - called when IO Partition has recovered + * @dev: Visornic device that is being serviced. + * @compelte_func: Call when finished. + * + * Called when the IO partition has recovered. Re-establish connection to the IO + * Partition and set the link up. Okay to do DMA again. * - * Called when the IO partition has recovered. Reestablish - * connection to the IO part and set the link up. Okay to do - * DMA again. - * Returns 0 for success. + * Returns 0 for success, negative integer on error. */ static int visornic_resume(struct visor_device *dev, visorbus_state_complete_func complete_func) @@ -2127,12 +2124,12 @@ static struct visor_driver visornic_driver = { .channel_interrupt = NULL, }; -/* - * visornic_init - Init function +/* visornic_init - init function * - * Init function for the visornic driver. Do initial driver setup - * and wait for devices. - * Returns 0 for success, negative for error. + * Init function for the visornic driver. Do initial driver setup and wait + * for devices. + * + * Return: 0 on success, negative integer on error. */ static int visornic_init(void) { @@ -2160,19 +2157,16 @@ static int visornic_init(void) cleanup_debugfs: debugfs_remove_recursive(visornic_debugfs_dir); - return err; } -/* - * visornic_cleanup - driver exit routine +/* visornic_cleanup - driver exit routine * - * Unregister driver from the bus and free up memory. + * Unregister driver from the bus and free up memory. */ static void visornic_cleanup(void) { visorbus_unregister_visor_driver(&visornic_driver); - debugfs_remove_recursive(visornic_debugfs_dir); } |