diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-13 11:35:00 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-13 11:35:00 -0800 |
commit | 72cca7baf4fba777b8ab770b902cf2e08941773f (patch) | |
tree | c5cdbcd65ac166946f54f1dd6ef3693eea29d791 /drivers/staging/unisys | |
parent | 5266e70335dac35c35b5ca9cea4251c1389d4a68 (diff) | |
parent | 3e0f9b2ca8e4839335e4d64ec0a75f4fd5111c4b (diff) |
Merge tag 'staging-4.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging/IIO updates from Greg KH:
"Here's the "big" staging/iio pull request for 4.10-rc1.
Not as big as 4.9 was, but still just over a thousand changes. We
almost broke even of lines added vs. removed, as the slicoss driver
was removed (got a "clean" driver for the same hardware through the
netdev tree), and some iio drivers were also dropped, but I think we
ended up adding a few thousand lines to the source tree in the end.
Other than that it's a lot of minor fixes all over the place, nothing
major stands out at all.
All of these have been in linux-next for a while. There will be a
merge conflict with Al's vfs tree in the lustre code, but the
resolution for that should be pretty simple, that too has been in
linux-next"
* tag 'staging-4.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (1002 commits)
staging: comedi: comedidev.h: Document usage of 'detach' handler
staging: fsl-mc: remove unnecessary info prints from bus driver
staging: fsl-mc: add sysfs ABI doc
staging/lustre/o2iblnd: Fix misspelled attemps->attempts
staging/lustre/o2iblnd: Fix misspelling intialized->intialized
staging/lustre: Convert all bare unsigned to unsigned int
staging/lustre/socklnd: Fix whitespace problem
staging/lustre/o2iblnd: Add missing space
staging/lustre/lnetselftest: Fix potential integer overflow
staging: greybus: audio_module: remove redundant OOM message
staging: dgnc: Fix lines longer than 80 characters
staging: dgnc: fix blank line after '{' warnings.
staging/android: remove Sync Framework tasks from TODO
staging/lustre/osc: Revert erroneous list_for_each_entry_safe use
staging: slicoss: remove the staging driver
staging: lustre: libcfs: remove lnet upcall code
staging: lustre: remove set but unused variables
staging: lustre: osc: set lock data for readahead lock
staging: lustre: import: don't reconnect during connect interpret
staging: lustre: clio: remove mtime check in vvp_io_fault_start()
...
Diffstat (limited to 'drivers/staging/unisys')
-rw-r--r-- | drivers/staging/unisys/include/iochannel.h | 335 | ||||
-rw-r--r-- | drivers/staging/unisys/include/visorbus.h | 2 | ||||
-rw-r--r-- | drivers/staging/unisys/visorbus/vbuschannel.h | 225 | ||||
-rw-r--r-- | drivers/staging/unisys/visorbus/visorbus_main.c | 231 | ||||
-rw-r--r-- | drivers/staging/unisys/visorbus/visorbus_private.h | 4 | ||||
-rw-r--r-- | drivers/staging/unisys/visorbus/visorchannel.c | 44 | ||||
-rw-r--r-- | drivers/staging/unisys/visorbus/visorchipset.c | 653 | ||||
-rw-r--r-- | drivers/staging/unisys/visorbus/vmcallinterface.h | 185 | ||||
-rw-r--r-- | drivers/staging/unisys/visorinput/visorinput.c | 6 | ||||
-rw-r--r-- | drivers/staging/unisys/visornic/visornic_main.c | 2 |
10 files changed, 758 insertions, 929 deletions
diff --git a/drivers/staging/unisys/include/iochannel.h b/drivers/staging/unisys/include/iochannel.h index 9081b3f8779c..54f490090a59 100644 --- a/drivers/staging/unisys/include/iochannel.h +++ b/drivers/staging/unisys/include/iochannel.h @@ -1,20 +1,20 @@ -/* Copyright (C) 2010 - 2013 UNISYS CORPORATION */ +/* Copyright (C) 2010 - 2016 UNISYS CORPORATION */ /* All rights reserved. */ #ifndef __IOCHANNEL_H__ #define __IOCHANNEL_H__ /* * Everything needed for IOPart-GuestPart communication is define in - * this file. Note: Everything is OS-independent because this file is + * 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: + * channel state. The following states are currently being used: * UNINIT(All Zeroes), CHANNEL_ATTACHING, CHANNEL_ATTACHED, CHANNEL_OPENED * - * additional states will be used later. No locking is needed to switch between + * Additional states will be used later. No locking is needed to switch between * states due to the following rules: * * 1. IOPart is only the only partition allowed to change from UNIT @@ -39,10 +39,11 @@ #define ULTRA_VSWITCH_CHANNEL_PROTOCOL_SIGNATURE \ ULTRA_CHANNEL_PROTOCOL_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 - * 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 +/* + * Must increment these 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 ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID 2 @@ -70,59 +71,62 @@ #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. */ +/* Used by ioguestpart to 'insert' signals to iopart. */ #define IOCHAN_TO_IOPART 0 -/* used by ioguestpart to 'remove' signals from iopart, same previous queue */ +/* Used by ioguestpart to 'remove' signals from iopart, same previous queue. */ #define IOCHAN_FROM_IOPART 1 -/* size of cdb - i.e., scsi cmnd */ +/* Size of cdb - i.e., SCSI cmnd */ #define MAX_CMND_SIZE 16 #define MAX_SENSE_SIZE 64 #define MAX_PHYS_INFO 64 -/* various types of network packets that can be sent in cmdrsp */ +/* Various types of network packets that can be sent in cmdrsp. */ enum net_types { - NET_RCV_POST = 0, /* submit buffer to hold receiving + NET_RCV_POST = 0, /* + * Submit buffer to hold receiving * incoming packet */ - /* virtnic -> uisnic */ + /* visornic -> uisnic */ NET_RCV, /* incoming packet received */ /* uisnic -> virtpci */ NET_XMIT, /* for outgoing net packets */ - /* virtnic -> uisnic */ + /* visornic -> uisnic */ NET_XMIT_DONE, /* outgoing packet xmitted */ /* uisnic -> virtpci */ NET_RCV_ENBDIS, /* enable/disable packet reception */ - /* virtnic -> uisnic */ + /* visornic -> uisnic */ NET_RCV_ENBDIS_ACK, /* acknowledge enable/disable packet */ /* reception */ - /* uisnic -> virtnic */ + /* uisnic -> visornic */ NET_RCV_PROMISC, /* enable/disable promiscuous mode */ - /* virtnic -> uisnic */ - NET_CONNECT_STATUS, /* indicate the loss or restoration of a network + /* visornic -> uisnic */ + NET_CONNECT_STATUS, /* + * indicate the loss or restoration of a network * connection */ - /* uisnic -> virtnic */ - NET_MACADDR, /* indicates the client has requested to update - * its MAC addr + /* uisnic -> visornic */ + NET_MACADDR, /* + * Indicates the client has requested to update + * it's MAC address */ - NET_MACADDR_ACK, /* MAC address */ + NET_MACADDR_ACK, /* MAC address acknowledge */ }; -#define ETH_MIN_DATA_SIZE 46 /* minimum eth data size */ -#define ETH_MIN_PACKET_SIZE (ETH_HLEN + ETH_MIN_DATA_SIZE) +#define ETH_MIN_DATA_SIZE 46 /* minimum eth data size */ +#define ETH_MIN_PACKET_SIZE (ETH_HLEN + ETH_MIN_DATA_SIZE) -#define VISOR_ETH_MAX_MTU 16384 /* maximum data size */ +#define VISOR_ETH_MAX_MTU 16384 /* maximum data size */ #ifndef MAX_MACADDR_LEN #define MAX_MACADDR_LEN 6 /* number of bytes in MAC address */ -#endif /* MAX_MACADDR_LEN */ +#endif -/* various types of scsi task mgmt commands */ +/* Various types of scsi task mgmt commands. */ enum task_mgmt_types { TASK_MGMT_ABORT_TASK = 1, TASK_MGMT_BUS_RESET, @@ -130,7 +134,7 @@ enum task_mgmt_types { TASK_MGMT_TARGET_RESET, }; -/* various types of vdisk mgmt commands */ +/* Various types of vdisk mgmt commands. */ enum vdisk_mgmt_types { VDISK_MGMT_ACQUIRE = 1, VDISK_MGMT_RELEASE, @@ -144,7 +148,7 @@ struct phys_info { #define MIN_NUMSIGNALS 64 -/* structs with pragma pack */ +/* Structs with pragma pack. */ struct guest_phys_info { u64 address; @@ -154,9 +158,9 @@ struct guest_phys_info { #define GPI_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(struct guest_phys_info)) struct uisscsi_dest { - u32 channel; /* channel == bus number */ - u32 id; /* id == target number */ - u32 lun; /* lun == logical unit number */ + u32 channel; /* channel == bus number */ + u32 id; /* id == target number */ + u32 lun; /* lun == logical unit number */ } __packed; struct vhba_wwnn { @@ -164,7 +168,8 @@ struct vhba_wwnn { u32 wwnn2; } __packed; -/* WARNING: Values stired in this structure must contain maximum counts (not +/* + * WARNING: Values stired in this structure must contain maximum counts (not * maximum values). */ struct vhba_config_max {/* 20 bytes */ @@ -187,23 +192,24 @@ struct uiscmdrsp_scsi { * information for each * fragment */ - enum dma_data_direction data_dir; /* direction of the data, if any */ + 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 */ - /* Needed to queue the rsp back to cmd originator */ - int linuxstat; /* original Linux status used by linux vdisk */ + /* 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 */ #define ADDL_SEL_TIMEOUT 4 - /* the following fields are need to determine the result of command */ + /* The following fields are need to determine the result of command. */ u8 sensebuf[MAX_SENSE_SIZE]; /* sense info in case cmd failed; */ - /* it holds the sense_data struct; */ - /* see that struct for details. */ - void *vdisk; /* pointer to the vdisk to clean up when IO completes. */ + /* 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. */ int no_disk_result; - /* used to return no disk inquiry 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 @@ -212,35 +218,44 @@ struct uiscmdrsp_scsi { */ } __packed; -/* Defines to support sending correct inquiry result when no disk is +/* + * Defines to support sending correct inquiry result when no disk is * configured. */ -/* From SCSI SPC2 - +/* + * From SCSI SPC2 - * * If the target is not capable of supporting a device on this logical unit, the * device server shall set this field to 7Fh (PERIPHERAL QUALIFIER set to 011b * and PERIPHERAL DEVICE TYPE set to 1Fh). * - *The device server is capable of supporting the specified peripheral device - *type on this logical unit. However, the physical device is not currently - *connected to this logical unit. + * The device server is capable of supporting the specified peripheral device + * type on this logical unit. However, the physical device is not currently + * 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_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 */ +#define DEV_DISK_CAPABLE_NOT_PRESENT 0x20 /* peripheral qualifier of 0x1 + * peripheral type of 0 - disk + * Specifies device capable, but + * not present + */ -#define DEV_HISUPPORT 0x10 /* HiSup = 1; shows support for report luns */ - /* must be returned for lun 0. */ +#define DEV_HISUPPORT 0x10 /* + * HiSup = 1; shows support for report luns + * must be returned for lun 0. + */ -/* NOTE: Linux code assumes inquiry contains 36 bytes. Without checking length - * in buf[4] some linux code accesses bytes beyond 5 to retrieve vendor, product - * & revision. Yikes! So let us always send back 36 bytes, the minimum for +/* + * NOTE: Linux code assumes inquiry contains 36 bytes. Without checking length + * in buf[4] some Linux code accesses bytes beyond 5 to retrieve vendor, product + * and revision. Yikes! So let us always send back 36 bytes, the minimum for * inquiry result. */ #define NO_DISK_INQUIRY_RESULT_LEN 36 @@ -248,11 +263,12 @@ struct uiscmdrsp_scsi { #define MIN_INQUIRY_RESULT_LEN 5 /* 5 bytes minimum for inquiry result */ /* SCSI device version for no disk inquiry result */ -#define SCSI_SPC2_VER 4 /* indicates SCSI SPC2 (SPC3 is 5) */ +#define SCSI_SPC2_VER 4 /* indicates SCSI SPC2 (SPC3 is 5) */ -/* Struct & Defines to support sense information. */ +/* Struct and Defines to support sense information. */ -/* The following struct is returned in sensebuf field in uiscmdrsp_scsi. It is +/* + * The following struct is returned in sensebuf field in uiscmdrsp_scsi. It is * initialized in exactly the manner that is recommended in Windows (hence the * odd values). * When set, these fields will have the following values: @@ -288,7 +304,7 @@ struct net_pkt_xmt { struct phys_info frags[MAX_PHYS_INFO]; /* physical page information */ char ethhdr[ETH_HLEN]; /* the ethernet header */ struct { - /* these are needed for csum at uisnic end */ + /* 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 */ @@ -300,7 +316,8 @@ struct net_pkt_xmt { /* nhrawoff points to the start of the NETWORK LAYER HEADER */ } lincsum; - /* **** NOTE **** + /* + * 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 @@ -309,14 +326,15 @@ struct net_pkt_xmt { } __packed; struct net_pkt_xmtdone { - u32 xmt_done_result; /* result of NET_XMIT */ + u32 xmt_done_result; /* result of NET_XMIT */ } __packed; -/* RCVPOST_BUF_SIZe must be at most page_size(4096) - cache_line_size (64) The +/* + * RCVPOST_BUF_SIZE must be at most page_size(4096) - cache_line_size (64) The * reason is because dev_skb_alloc which is used to generate RCV_POST skbs in - * virtnic requires that there is "overhead" in the buffer, and pads 16 bytes. I - * prefer to use 1 full cache line size for "overhead" so that transfers are - * better. IOVM requires that a buffer be represented by 1 phys_info structure + * visornic requires that there is "overhead" in the buffer, and pads 16 bytes. + * Use 1 full cache line size for "overhead" so that transfers are optimized. + * IOVM requires that a buffer be represented by 1 phys_info structure * which can only cover page_size. */ #define RCVPOST_BUF_SIZE 4032 @@ -324,26 +342,38 @@ 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 + * header len - we are choosing 2K because it is guaranteed to be describable. + */ struct net_pkt_rcvpost { - /* 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 phys_info frag; /* physical page information for the */ - /* single fragment 2K rcv buf */ - u64 unique_num; - /* unique_num ensure that receive posts are returned to */ - /* the Adapter which we sent them originally. */ + /* 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. + */ + u64 unique_num; + } __packed; +/* + * The number of rcvbuf that can be chained is based on max mtu and size of each + * rcvbuf. + */ struct net_pkt_rcv { - /* the number of receive buffers that can be chained */ - /* is based on max mtu and size of each rcv buf */ - u32 rcv_done_len; /* length of received data */ - u8 numrcvbufs; /* number of receive buffers that contain the */ - /* incoming data; guest end MUST chain these together. */ - void *rcvbuf[MAX_NET_RCV_CHAIN]; /* list of chained rcvbufs */ - /* each entry is a receive buffer provided by NET_RCV_POST. */ + u32 rcv_done_len; /* length of received data */ + + /* + * numrcvbufs: contain the incoming data; guest side MUST chain these + * together. + */ + 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. */ u64 unique_num; u32 rcvs_dropped_delta; @@ -351,12 +381,12 @@ struct net_pkt_rcv { struct net_pkt_enbdis { void *context; - u16 enable; /* 1 = enable, 0 = disable */ + u16 enable; /* 1 = enable, 0 = disable */ } __packed; struct net_pkt_macaddr { void *context; - u8 macaddr[MAX_MACADDR_LEN]; /* 6 bytes */ + u8 macaddr[MAX_MACADDR_LEN]; /* 6 bytes */ } __packed; /* cmd rsp packet used for VNIC network traffic */ @@ -377,41 +407,44 @@ struct uiscmdrsp_net { } __packed; struct uiscmdrsp_scsitaskmgmt { + /* The type of task. */ enum task_mgmt_types tasktype; - /* the type of task */ + /* The vdisk for which this task mgmt is generated. */ struct uisscsi_dest vdest; - /* the vdisk for which this task mgmt is generated */ + /* + * 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; - /* This is a handle that the guest has saved off for its own use. - * Its value is preserved by iopart & returned as is in the task - * mgmt rsp. - */ + /* + * 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; - /* 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. Its value is preserved by iopart & returned - * as is in the task mgmt rsp. - */ + /* + * 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; - /* this is a handle to location in guest where the result of the - * taskmgmt command (result field) is to saved off when the response - * is handled. Its value is preserved by iopart & returned as is in - * the task mgmt rsp. - */ + /* Result of taskmgmt command - set by IOPart - values are: */ char result; - /* result of taskmgmt command - set by IOPart - values are: */ #define TASK_MGMT_FAILED 0 } __packed; -/* Used by uissd to send disk add/remove notifications to Guest */ +/* 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 */ @@ -419,49 +452,50 @@ struct uiscmdrsp_disknotify { 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 +/* + * The following is used by virthba/vSCSI to send the Acquire/Release commands * to the IOVM. */ struct uiscmdrsp_vdiskmgmt { + /* The type of task */ enum vdisk_mgmt_types vdisktype; - /* the type of task */ + /* The vdisk for which this task mgmt is generated */ struct uisscsi_dest vdest; - /* the vdisk for which this task mgmt is generated */ + /* + * 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; - /* This is a handle that the guest has saved off for its own use. - * Its value is preserved by iopart & returned as is in the task - * mgmt rsp. - */ + /* + * 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; - /* 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. Its value is preserved by iopart & returned - * as is in the task mgmt rsp. - */ + /* + * 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; - /* this is a handle to location in guest where the result of the - * taskmgmt command (result field) is to saved off when the response - * is handled. Its value is preserved by iopart & returned as is in - * the task mgmt rsp. - */ + /* Result of taskmgmt command - set by IOPart - values are: */ char result; - - /* result of taskmgmt command - set by IOPart - values are: */ -#define VDISK_MGMT_FAILED 0 } __packed; -/* keeping cmd & rsp info in one structure for now cmd rsp packet for scsi */ +/* 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 @@ -474,11 +508,11 @@ struct uiscmdrsp { struct uiscmdrsp_disknotify disknotify; struct uiscmdrsp_vdiskmgmt vdiskmgmt; }; - void *private_data; /* send the response when the cmd is */ - /* done (scsi & scsittaskmgmt). */ + /* 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; /* Used to track active commands */ - struct uiscmdrsp *activeQ_prev; /* Used to track active commands */ + struct uiscmdrsp *activeQ_next; /* Pointer to the nextactive commands */ + struct uiscmdrsp *activeQ_prev; /* Pointer to the prevactive commands */ } __packed; struct iochannel_vhba { @@ -491,7 +525,8 @@ struct iochannel_vnic { u32 mtu; /* 4 bytes */ uuid_le zone_uuid; /* 16 bytes */ } __packed; -/* This is just the header of the IO channel. It is assumed that directly after +/* + * 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 * response queues as specified in cmd_q and rsp_q SIGNAL_QUEUE_HEADERS. */ @@ -505,31 +540,19 @@ struct spar_io_channel_protocol { } __packed; #define MAX_CLIENTSTRING_LEN 1024 - /* client_string is NULL termimated so holds max -1 bytes */ + /* client_string is NULL termimated so holds max-1 bytes */ u8 client_string[MAX_CLIENTSTRING_LEN]; } __packed; -/* INLINE functions for initializing and accessing I/O data channels */ -#define SIZEOF_PROTOCOL (COVER(sizeof(struct spar_io_channel_protocol), 64)) +/* INLINE functions for initializing and accessing I/O data channels. */ #define SIZEOF_CMDRSP (COVER(sizeof(struct uiscmdrsp), 64)) -#define MIN_IO_CHANNEL_SIZE COVER(SIZEOF_PROTOCOL + \ - 2 * MIN_NUMSIGNALS * SIZEOF_CMDRSP, 4096) - -/* - * INLINE function for expanding a guest's pfn-off-size into multiple 4K page - * pfn-off-size entires. - */ - -/* use 4K page sizes when we it comes to passing page information between */ -/* Guest and IOPartition. */ +/* Use 4K page sizes when passing page info between Guest and IOPartition. */ #define PI_PAGE_SIZE 0x1000 #define PI_PAGE_MASK 0x0FFF -/* returns next non-zero index on success or zero on failure (i.e. out of - * room) - */ -static inline u16 +/* Returns next non-zero index on success or 0 on failure (i.e. out of room). */ +static inline 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[]) { @@ -538,7 +561,7 @@ add_physinfo_entries(u64 inp_pfn, u16 inp_off, u32 inp_len, u16 index, firstlen = PI_PAGE_SIZE - inp_off; if (inp_len <= firstlen) { - /* the input entry spans only one page - add as is */ + /* The input entry spans only one page - add as is. */ if (index >= max_pi_arr_entries) return 0; pi_arr[index].pi_pfn = inp_pfn; @@ -547,7 +570,7 @@ add_physinfo_entries(u64 inp_pfn, u16 inp_off, u32 inp_len, u16 index, return index + 1; } - /* this entry spans multiple pages */ + /* This entry spans multiple pages. */ for (len = inp_len, i = 0; len; len -= pi_arr[index + i].pi_len, i++) { if (index + i >= max_pi_arr_entries) @@ -565,4 +588,4 @@ add_physinfo_entries(u64 inp_pfn, u16 inp_off, u32 inp_len, u16 index, return index + i; } -#endif /* __IOCHANNEL_H__ */ +#endif /* __IOCHANNEL_H__ */ diff --git a/drivers/staging/unisys/include/visorbus.h b/drivers/staging/unisys/include/visorbus.h index 677627c72c4c..03d56f818a86 100644 --- a/drivers/staging/unisys/include/visorbus.h +++ b/drivers/staging/unisys/include/visorbus.h @@ -166,6 +166,8 @@ struct visor_device { struct controlvm_message_header *pending_msg_hdr; void *vbus_hdr_info; uuid_le partition_uuid; + struct dentry *debugfs_dir; + struct dentry *debugfs_client_bus_info; }; #define to_visor_device(x) container_of(x, struct visor_device, device) diff --git a/drivers/staging/unisys/visorbus/vbuschannel.h b/drivers/staging/unisys/visorbus/vbuschannel.h index e97917522f6a..b0df26155d02 100644 --- a/drivers/staging/unisys/visorbus/vbuschannel.h +++ b/drivers/staging/unisys/visorbus/vbuschannel.h @@ -23,6 +23,7 @@ * 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} */ @@ -50,12 +51,6 @@ static const uuid_le spar_vbus_channel_protocol_uuid = SPAR_VBUS_CHANNEL_PROTOCOL_VERSIONID, \ SPAR_VBUS_CHANNEL_PROTOCOL_SIGNATURE) -#define SPAR_VBUS_CHANNEL_OK_SERVER(actual_bytes) \ - (spar_check_channel_server(spar_vbus_channel_protocol_uuid, \ - "vbus", \ - sizeof(struct spar_vbus_channel_protocol),\ - actual_bytes)) - #pragma pack(push, 1) /* both GCC and VC now allow this pragma */ /* @@ -72,199 +67,38 @@ struct ultra_vbus_deviceinfo { }; /** - * vbuschannel_sanitize_buffer() - remove non-printable chars from buffer - * @p: destination buffer where chars are written to - * @remain: number of bytes that can be written starting at #p - * @src: pointer to source buffer - * @srcmax: number of valid characters at #src - * - * Reads chars from the buffer at @src for @srcmax bytes, and writes to - * the buffer at @p, which is @remain bytes long, ensuring never to - * overflow the buffer at @p, using the following rules: - * - printable characters are simply copied from the buffer at @src to the - * buffer at @p - * - intervening streaks of non-printable characters in the buffer at @src - * are replaced with a single space in the buffer at @p - * Note that we pay no attention to '\0'-termination. - * - * Pass @p == NULL and @remain == 0 for this special behavior -- In this - * case, we simply return the number of bytes that WOULD HAVE been written - * to a buffer at @p, had it been infinitely big. - * - * Return: the number of bytes written to @p (or WOULD HAVE been written to - * @p, as described in the previous paragraph) - */ -static inline int -vbuschannel_sanitize_buffer(char *p, int remain, char *src, int srcmax) -{ - int chars = 0; - int nonprintable_streak = 0; - - while (srcmax > 0) { - if ((*src >= ' ') && (*src < 0x7f)) { - if (nonprintable_streak) { - if (remain > 0) { - *p = ' '; - p++; - remain--; - chars++; - } else if (!p) { - chars++; - } - nonprintable_streak = 0; - } - if (remain > 0) { - *p = *src; - p++; - remain--; - chars++; - } else if (!p) { - chars++; - } - } else { - nonprintable_streak = 1; - } - src++; - srcmax--; - } - return chars; -} - -#define VBUSCHANNEL_ADDACHAR(ch, p, remain, chars) \ - do { \ - if (remain <= 0) \ - break; \ - *p = ch; \ - p++; chars++; remain--; \ - } while (0) - -/** - * vbuschannel_itoa() - convert non-negative int to string - * @p: destination string - * @remain: max number of bytes that can be written to @p - * @num: input int to convert - * - * Converts the non-negative value at @num to an ascii decimal string - * at @p, writing at most @remain bytes. Note there is NO '\0' termination - * written to @p. - * - * Return: number of bytes written to @p - * - */ -static inline int -vbuschannel_itoa(char *p, int remain, int num) -{ - int digits = 0; - char s[32]; - int i; - - if (num == 0) { - /* '0' is a special case */ - if (remain <= 0) - return 0; - *p = '0'; - return 1; - } - /* form a backwards decimal ascii string in <s> */ - while (num > 0) { - if (digits >= (int)sizeof(s)) - return 0; - s[digits++] = (num % 10) + '0'; - num = num / 10; - } - if (remain < digits) { - /* not enough room left at <p> to hold number, so fill with - * '?' - */ - for (i = 0; i < remain; i++, p++) - *p = '?'; - return remain; - } - /* plug in the decimal ascii string representing the number, by */ - /* reversing the string we just built in <s> */ - i = digits; - while (i > 0) { - i--; - *p = s[i]; - p++; - } - return digits; -} - -/** - * vbuschannel_devinfo_to_string() - format a struct ultra_vbus_deviceinfo - * to a printable string + * vbuschannel_print_devinfo() - format a struct ultra_vbus_deviceinfo + * and write it to a seq_file * @devinfo: the struct ultra_vbus_deviceinfo to format - * @p: destination string area - * @remain: size of destination string area in bytes + * @seq: seq_file to write to * @devix: the device index to be included in the output data, or -1 if no * device index is to be included * - * Reads @devInfo, and converts its contents to a printable string at @p, - * writing at most @remain bytes. Note there is NO '\0' termination - * written to @p. - * - * Return: number of bytes written to @p + * Reads @devInfo, and writes it in human-readable notation to @seq. */ -static inline int -vbuschannel_devinfo_to_string(struct ultra_vbus_deviceinfo *devinfo, - char *p, int remain, int devix) +static inline void +vbuschannel_print_devinfo(struct ultra_vbus_deviceinfo *devinfo, + struct seq_file *seq, int devix) { - char *psrc; - int nsrc, x, i, pad; - int chars = 0; - - psrc = &devinfo->devtype[0]; - nsrc = sizeof(devinfo->devtype); - if (vbuschannel_sanitize_buffer(NULL, 0, psrc, nsrc) <= 0) - return 0; - - /* emit device index */ - if (devix >= 0) { - VBUSCHANNEL_ADDACHAR('[', p, remain, chars); - x = vbuschannel_itoa(p, remain, devix); - p += x; - remain -= x; - chars += x; - VBUSCHANNEL_ADDACHAR(']', p, remain, chars); - } else { - VBUSCHANNEL_ADDACHAR(' ', p, remain, chars); - VBUSCHANNEL_ADDACHAR(' ', p, remain, chars); - VBUSCHANNEL_ADDACHAR(' ', p, remain, chars); - } - - /* emit device type */ - x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc); - p += x; - remain -= x; - chars += x; - pad = 15 - x; /* pad device type to be exactly 15 chars */ - for (i = 0; i < pad; i++) - VBUSCHANNEL_ADDACHAR(' ', p, remain, chars); - VBUSCHANNEL_ADDACHAR(' ', p, remain, chars); - - /* emit driver name */ - psrc = &devinfo->drvname[0]; - nsrc = sizeof(devinfo->drvname); - x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc); - p += x; - remain -= x; - chars += x; - pad = 15 - x; /* pad driver name to be exactly 15 chars */ - for (i = 0; i < pad; i++) - VBUSCHANNEL_ADDACHAR(' ', p, remain, chars); - VBUSCHANNEL_ADDACHAR(' ', p, remain, chars); - - /* emit strings */ - psrc = &devinfo->infostrs[0]; - nsrc = sizeof(devinfo->infostrs); - x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc); - p += x; - remain -= x; - chars += x; - VBUSCHANNEL_ADDACHAR('\n', p, remain, chars); - - return chars; + if (!isprint(devinfo->devtype[0])) + return; /* uninitialized vbus device entry */ + + if (devix >= 0) + seq_printf(seq, "[%d]", devix); + else + /* vbus device entry is for bus or chipset */ + seq_puts(seq, " "); + + /* + * Note: because the s-Par back-end is free to scribble in this area, + * we never assume '\0'-termination. + */ + seq_printf(seq, "%-*.*s ", (int)sizeof(devinfo->devtype), + (int)sizeof(devinfo->devtype), devinfo->devtype); + seq_printf(seq, "%-*.*s ", (int)sizeof(devinfo->drvname), + (int)sizeof(devinfo->drvname), devinfo->drvname); + seq_printf(seq, "%.*s\n", (int)sizeof(devinfo->infostrs), + devinfo->infostrs); } struct spar_vbus_headerinfo { @@ -293,11 +127,6 @@ struct spar_vbus_channel_protocol { /* describes client device and driver for each device on the bus */ }; -#define VBUS_CH_SIZE_EXACT(MAXDEVICES) \ - (sizeof(ULTRA_VBUS_CHANNEL_PROTOCOL) + ((MAXDEVICES) * \ - sizeof(ULTRA_VBUS_DEVICEINFO))) -#define VBUS_CH_SIZE(MAXDEVICES) COVER(VBUS_CH_SIZE_EXACT(MAXDEVICES), 4096) - #pragma pack(pop) #endif diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index fec0a54916fe..3457ef338e1e 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -14,6 +14,7 @@ * details. */ +#include <linux/debugfs.h> #include <linux/uuid.h> #include "visorbus.h" @@ -33,6 +34,7 @@ static int visorbus_forcenomatch; #define POLLJIFFIES_NORMALCHANNEL 10 static int busreg_rc = -ENODEV; /* stores the result from bus registration */ +static struct dentry *visorbus_debugfs_dir; /* * DEVICE type attributes @@ -151,6 +153,8 @@ visorbus_release_busdevice(struct device *xdev) { struct visor_device *dev = dev_get_drvdata(xdev); + debugfs_remove(dev->debugfs_client_bus_info); + debugfs_remove_recursive(dev->debugfs_dir); kfree(dev); } @@ -186,6 +190,7 @@ static ssize_t physaddr_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "0x%llx\n", visorchannel_get_physaddr(vdev->visorchannel)); } +static DEVICE_ATTR_RO(physaddr); static ssize_t nbytes_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -197,6 +202,7 @@ static ssize_t nbytes_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "0x%lx\n", visorchannel_get_nbytes(vdev->visorchannel)); } +static DEVICE_ATTR_RO(nbytes); static ssize_t clientpartition_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -208,6 +214,7 @@ static ssize_t clientpartition_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "0x%llx\n", visorchannel_get_clientpartition(vdev->visorchannel)); } +static DEVICE_ATTR_RO(clientpartition); static ssize_t typeguid_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -220,6 +227,7 @@ static ssize_t typeguid_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "%s\n", visorchannel_id(vdev->visorchannel, typeid)); } +static DEVICE_ATTR_RO(typeguid); static ssize_t zoneguid_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -232,6 +240,7 @@ static ssize_t zoneguid_show(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, "%s\n", visorchannel_zoneid(vdev->visorchannel, zoneid)); } +static DEVICE_ATTR_RO(zoneguid); static ssize_t typename_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -250,12 +259,6 @@ static ssize_t typename_show(struct device *dev, struct device_attribute *attr, drv = to_visor_driver(xdrv); return snprintf(buf, PAGE_SIZE, "%s\n", drv->channel_types[i - 1].name); } - -static DEVICE_ATTR_RO(physaddr); -static DEVICE_ATTR_RO(nbytes); -static DEVICE_ATTR_RO(clientpartition); -static DEVICE_ATTR_RO(typeguid); -static DEVICE_ATTR_RO(zoneguid); static DEVICE_ATTR_RO(typename); static struct attribute *channel_attrs[] = { @@ -295,6 +298,7 @@ static ssize_t partition_handle_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "0x%llx\n", handle); } +static DEVICE_ATTR_RO(partition_handle); static ssize_t partition_guid_show(struct device *dev, struct device_attribute *attr, @@ -303,6 +307,7 @@ static ssize_t partition_guid_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "{%pUb}\n", &vdev->partition_uuid); } +static DEVICE_ATTR_RO(partition_guid); static ssize_t partition_name_show(struct device *dev, struct device_attribute *attr, @@ -311,6 +316,7 @@ static ssize_t partition_name_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "%s\n", vdev->name); } +static DEVICE_ATTR_RO(partition_name); static ssize_t channel_addr_show(struct device *dev, struct device_attribute *attr, @@ -320,6 +326,7 @@ static ssize_t channel_addr_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "0x%llx\n", addr); } +static DEVICE_ATTR_RO(channel_addr); static ssize_t channel_bytes_show(struct device *dev, struct device_attribute *attr, @@ -329,6 +336,7 @@ static ssize_t channel_bytes_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "0x%llx\n", nbytes); } +static DEVICE_ATTR_RO(channel_bytes); static ssize_t channel_id_show(struct device *dev, struct device_attribute *attr, @@ -343,77 +351,7 @@ static ssize_t channel_id_show(struct device *dev, } return len; } - -static ssize_t client_bus_info_show(struct device *dev, - struct device_attribute *attr, - char *buf) { - struct visor_device *vdev = to_visor_device(dev); - struct visorchannel *channel = vdev->visorchannel; - - int i, shift, remain = PAGE_SIZE; - unsigned long off; - char *pos = buf; - u8 *partition_name; - struct ultra_vbus_deviceinfo dev_info; - - partition_name = ""; - if (channel) { - if (vdev->name) - partition_name = vdev->name; - shift = snprintf(pos, remain, - "Client device / client driver info for %s partition (vbus #%u):\n", - partition_name, vdev->chipset_bus_no); - pos += shift; - remain -= shift; - shift = visorchannel_read(channel, - offsetof(struct - spar_vbus_channel_protocol, - chp_info), - &dev_info, sizeof(dev_info)); - if (shift >= 0) { - shift = vbuschannel_devinfo_to_string(&dev_info, pos, - remain, -1); - pos += shift; - remain -= shift; - } - shift = visorchannel_read(channel, - offsetof(struct - spar_vbus_channel_protocol, - bus_info), - &dev_info, sizeof(dev_info)); - if (shift >= 0) { - shift = vbuschannel_devinfo_to_string(&dev_info, pos, - remain, -1); - pos += shift; - remain -= shift; - } - off = offsetof(struct spar_vbus_channel_protocol, dev_info); - i = 0; - while (off + sizeof(dev_info) <= - visorchannel_get_nbytes(channel)) { - shift = visorchannel_read(channel, - off, &dev_info, - sizeof(dev_info)); - if (shift >= 0) { - shift = vbuschannel_devinfo_to_string - (&dev_info, pos, remain, i); - pos += shift; - remain -= shift; - } - off += sizeof(dev_info); - i++; - } - } - return PAGE_SIZE - remain; -} - -static DEVICE_ATTR_RO(partition_handle); -static DEVICE_ATTR_RO(partition_guid); -static DEVICE_ATTR_RO(partition_name); -static DEVICE_ATTR_RO(channel_addr); -static DEVICE_ATTR_RO(channel_bytes); static DEVICE_ATTR_RO(channel_id); -static DEVICE_ATTR_RO(client_bus_info); static struct attribute *dev_attrs[] = { &dev_attr_partition_handle.attr, @@ -422,7 +360,6 @@ static struct attribute *dev_attrs[] = { &dev_attr_channel_addr.attr, &dev_attr_channel_bytes.attr, &dev_attr_channel_id.attr, - &dev_attr_client_bus_info.attr, NULL }; @@ -435,6 +372,66 @@ static const struct attribute_group *visorbus_groups[] = { NULL }; +/* + * BUS debugfs entries + * + * define & implement display of debugfs attributes under + * /sys/kernel/debug/visorbus/visorbus<n>. + */ + +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; + unsigned long off; + struct ultra_vbus_deviceinfo dev_info; + + if (!channel) + return 0; + + seq_printf(seq, + "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 spar_vbus_channel_protocol, + chp_info), + &dev_info, sizeof(dev_info)) >= 0) + vbuschannel_print_devinfo(&dev_info, seq, -1); + if (visorchannel_read(channel, + offsetof(struct spar_vbus_channel_protocol, + bus_info), + &dev_info, sizeof(dev_info)) >= 0) + vbuschannel_print_devinfo(&dev_info, seq, -1); + off = offsetof(struct spar_vbus_channel_protocol, dev_info); + i = 0; + while (off + sizeof(dev_info) <= visorchannel_get_nbytes(channel)) { + if (visorchannel_read(channel, off, &dev_info, + sizeof(dev_info)) >= 0) + vbuschannel_print_devinfo(&dev_info, seq, i); + off += sizeof(dev_info); + i++; + } + + return 0; +} + +static int client_bus_info_debugfs_open(struct inode *inode, struct file *file) +{ + return single_open(file, client_bus_info_debugfs_show, + inode->i_private); +} + +static const struct file_operations client_bus_info_debugfs_fops = { + .owner = THIS_MODULE, + .open = client_bus_info_debugfs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static void dev_periodic_work(unsigned long __opaque) { @@ -610,8 +607,8 @@ create_visor_device(struct visor_device *dev) u32 chipset_bus_no = dev->chipset_bus_no; u32 chipset_dev_no = dev->chipset_dev_no; - POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, chipset_dev_no, chipset_bus_no, - POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(DEVICE_CREATE_ENTRY_PC, chipset_dev_no, chipset_bus_no, + DIAG_SEVERITY_PRINT); mutex_init(&dev->visordriver_callback_lock); dev->device.bus = &visorbus_type; @@ -651,8 +648,8 @@ create_visor_device(struct visor_device *dev) */ err = device_add(&dev->device); if (err < 0) { - POSTCODE_LINUX_3(DEVICE_ADD_PC, chipset_bus_no, - DIAG_SEVERITY_ERR); + POSTCODE_LINUX(DEVICE_ADD_PC, 0, chipset_bus_no, + DIAG_SEVERITY_ERR); goto err_put; } @@ -966,9 +963,10 @@ static int create_bus_instance(struct visor_device *dev) { int id = dev->chipset_bus_no; + int err; struct spar_vbus_headerinfo *hdr_info; - POSTCODE_LINUX_2(BUS_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(BUS_CREATE_ENTRY_PC, 0, 0, DIAG_SEVERITY_PRINT); hdr_info = kzalloc(sizeof(*hdr_info), GFP_KERNEL); if (!hdr_info) @@ -979,11 +977,26 @@ create_bus_instance(struct visor_device *dev) dev->device.groups = visorbus_groups; dev->device.release = visorbus_release_busdevice; + dev->debugfs_dir = debugfs_create_dir(dev_name(&dev->device), + visorbus_debugfs_dir); + if (!dev->debugfs_dir) { + err = -ENOMEM; + goto err_hdr_info; + } + dev->debugfs_client_bus_info = + debugfs_create_file("client_bus_info", S_IRUSR | S_IRGRP, + dev->debugfs_dir, dev, + &client_bus_info_debugfs_fops); + if (!dev->debugfs_client_bus_info) { + err = -ENOMEM; + goto err_debugfs_dir; + } + if (device_register(&dev->device) < 0) { - POSTCODE_LINUX_3(DEVICE_CREATE_FAILURE_PC, id, - POSTCODE_SEVERITY_ERR); - kfree(hdr_info); - return -ENODEV; + POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, 0, id, + DIAG_SEVERITY_ERR); + err = -ENODEV; + goto err_debugfs_created; } if (get_vbus_header_info(dev->visorchannel, hdr_info) >= 0) { @@ -998,6 +1011,16 @@ create_bus_instance(struct visor_device *dev) list_add_tail(&dev->list_all, &list_all_bus_instances); dev_set_drvdata(&dev->device, dev); return 0; + +err_debugfs_created: + debugfs_remove(dev->debugfs_client_bus_info); + +err_debugfs_dir: + debugfs_remove_recursive(dev->debugfs_dir); + +err_hdr_info: + kfree(hdr_info); + return err; } /** @@ -1069,16 +1092,16 @@ chipset_bus_create(struct visor_device *dev) int rc; u32 bus_no = dev->chipset_bus_no; - POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, bus_no, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(BUS_CREATE_ENTRY_PC, 0, bus_no, DIAG_SEVERITY_PRINT); rc = create_bus_instance(dev); - POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus_no, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(BUS_CREATE_EXIT_PC, 0, bus_no, DIAG_SEVERITY_PRINT); if (rc < 0) - POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(BUS_CREATE_FAILURE_PC, 0, bus_no, + DIAG_SEVERITY_ERR); else - POSTCODE_LINUX_3(CHIPSET_INIT_SUCCESS_PC, bus_no, - POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(CHIPSET_INIT_SUCCESS_PC, 0, bus_no, + DIAG_SEVERITY_PRINT); bus_create_response(dev, rc); } @@ -1097,18 +1120,18 @@ chipset_device_create(struct visor_device *dev_info) u32 bus_no = dev_info->chipset_bus_no; u32 dev_no = dev_info->chipset_dev_no; - POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, dev_no, bus_no, - POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(DEVICE_CREATE_ENTRY_PC, dev_no, bus_no, + DIAG_SEVERITY_PRINT); rc = create_visor_device(dev_info); device_create_response(dev_info, rc); if (rc < 0) - POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, + DIAG_SEVERITY_ERR); else - POSTCODE_LINUX_4(DEVICE_CREATE_SUCCESS_PC, dev_no, bus_no, - POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(DEVICE_CREATE_SUCCESS_PC, dev_no, bus_no, + DIAG_SEVERITY_PRINT); } void @@ -1274,12 +1297,17 @@ visorbus_init(void) { int err; - POSTCODE_LINUX_3(DRIVER_ENTRY_PC, 0, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(DRIVER_ENTRY_PC, 0, 0, DIAG_SEVERITY_PRINT); + + visorbus_debugfs_dir = debugfs_create_dir("visorbus", NULL); + if (!visorbus_debugfs_dir) + return -ENOMEM; + bus_device_info_init(&clientbus_driverinfo, "clientbus", "visorbus"); err = create_bus_type(); if (err < 0) { - POSTCODE_LINUX_2(BUS_CREATE_ENTRY_PC, DIAG_SEVERITY_ERR); + POSTCODE_LINUX(BUS_CREATE_ENTRY_PC, 0, 0, DIAG_SEVERITY_ERR); goto error; } @@ -1288,7 +1316,7 @@ visorbus_init(void) return 0; error: - POSTCODE_LINUX_3(CHIPSET_INIT_FAILURE_PC, err, POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CHIPSET_INIT_FAILURE_PC, 0, err, DIAG_SEVERITY_ERR); return err; } @@ -1306,6 +1334,7 @@ visorbus_exit(void) remove_bus_instance(dev); } remove_bus_type(); + debugfs_remove_recursive(visorbus_debugfs_dir); } module_param_named(forcematch, visorbus_forcematch, int, S_IRUGO); diff --git a/drivers/staging/unisys/visorbus/visorbus_private.h b/drivers/staging/unisys/visorbus/visorbus_private.h index 15403fb52847..49bec1763e33 100644 --- a/drivers/staging/unisys/visorbus/visorbus_private.h +++ b/drivers/staging/unisys/visorbus/visorbus_private.h @@ -70,9 +70,9 @@ struct visorchannel *visorchannel_create_with_lock(u64 physaddr, gfp_t gfp, uuid_le guid); void visorchannel_destroy(struct visorchannel *channel); int visorchannel_read(struct visorchannel *channel, ulong offset, - void *local, ulong nbytes); + void *dest, ulong nbytes); int visorchannel_write(struct visorchannel *channel, ulong offset, - void *local, ulong nbytes); + void *dest, ulong nbytes); u64 visorchannel_get_physaddr(struct visorchannel *channel); ulong visorchannel_get_nbytes(struct visorchannel *channel); char *visorchannel_id(struct visorchannel *channel, char *s); diff --git a/drivers/staging/unisys/visorbus/visorchannel.c b/drivers/staging/unisys/visorbus/visorchannel.c index 300a65dc5c6c..f51a7258bef0 100644 --- a/drivers/staging/unisys/visorbus/visorchannel.c +++ b/drivers/staging/unisys/visorbus/visorchannel.c @@ -23,6 +23,7 @@ #include <linux/io.h> #include "visorbus.h" +#include "visorbus_private.h" #include "controlvmchannel.h" #define MYDRVNAME "visorchannel" @@ -127,19 +128,19 @@ EXPORT_SYMBOL_GPL(visorchannel_get_uuid); int visorchannel_read(struct visorchannel *channel, ulong offset, - void *local, ulong nbytes) + void *dest, ulong nbytes) { if (offset + nbytes > channel->nbytes) return -EIO; - memcpy(local, channel->mapped + offset, nbytes); + memcpy(dest, channel->mapped + offset, nbytes); return 0; } int visorchannel_write(struct visorchannel *channel, ulong offset, - void *local, ulong nbytes) + void *dest, ulong nbytes) { size_t chdr_size = sizeof(struct channel_header); size_t copy_size; @@ -150,10 +151,10 @@ visorchannel_write(struct visorchannel *channel, ulong offset, if (offset < chdr_size) { copy_size = min(chdr_size - offset, nbytes); memcpy(((char *)(&channel->chan_hdr)) + offset, - local, copy_size); + dest, copy_size); } - memcpy(channel->mapped + offset, local, nbytes); + memcpy(channel->mapped + offset, dest, nbytes); return 0; } @@ -236,8 +237,9 @@ signalremove_inner(struct visorchannel *channel, u32 queue, void *msg) if (error) return error; + /* No signals to remove; have caller try again. */ if (sig_hdr.head == sig_hdr.tail) - return -EIO; /* no signals to remove */ + return -EAGAIN; sig_hdr.tail = (sig_hdr.tail + 1) % sig_hdr.max_slots; @@ -299,22 +301,30 @@ EXPORT_SYMBOL_GPL(visorchannel_signalremove); * Return: boolean indicating whether any messages in the designated * channel/queue are present */ + +static bool +queue_empty(struct visorchannel *channel, u32 queue) +{ + struct signal_queue_header sig_hdr; + + if (sig_read_header(channel, queue, &sig_hdr)) + return true; + + return (sig_hdr.head == sig_hdr.tail); +} + bool visorchannel_signalempty(struct visorchannel *channel, u32 queue) { - unsigned long flags = 0; - struct signal_queue_header sig_hdr; - bool rc = false; + bool rc; + unsigned long flags; - if (channel->needs_lock) - spin_lock_irqsave(&channel->remove_lock, flags); + if (!channel->needs_lock) + return queue_empty(channel, queue); - if (sig_read_header(channel, queue, &sig_hdr)) - rc = true; - if (sig_hdr.head == sig_hdr.tail) - rc = true; - if (channel->needs_lock) - spin_unlock_irqrestore(&channel->remove_lock, flags); + spin_lock_irqsave(&channel->remove_lock, flags); + rc = queue_empty(channel, queue); + spin_unlock_irqrestore(&channel->remove_lock, flags); return rc; } diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c index 59871495ea85..d7148c351d3f 100644 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ b/drivers/staging/unisys/visorbus/visorchipset.c @@ -29,7 +29,7 @@ #include "visorbus_private.h" #include "vmcallinterface.h" -#define CURRENT_FILE_PC VISOR_CHIPSET_PC_visorchipset_main_c +#define CURRENT_FILE_PC VISOR_BUS_PC_visorchipset_c #define POLLJIFFIES_CONTROLVMCHANNEL_FAST 1 #define POLLJIFFIES_CONTROLVMCHANNEL_SLOW 100 @@ -57,7 +57,6 @@ visorchipset_open(struct inode *inode, struct file *file) if (minor_number) return -ENODEV; - file->private_data = NULL; return 0; } @@ -499,7 +498,7 @@ controlvm_init_response(struct controlvm_message *msg, } } -static void +static int controlvm_respond_chipset_init(struct controlvm_message_header *msg_hdr, int response, enum ultra_chipset_feature features) @@ -508,34 +507,33 @@ controlvm_respond_chipset_init(struct controlvm_message_header *msg_hdr, controlvm_init_response(&outmsg, msg_hdr, response); outmsg.cmd.init_chipset.features = features; - if (visorchannel_signalinsert(controlvm_channel, - CONTROLVM_QUEUE_REQUEST, &outmsg)) { - return; - } + return visorchannel_signalinsert(controlvm_channel, + CONTROLVM_QUEUE_REQUEST, &outmsg); } -static void +static int chipset_init(struct controlvm_message *inmsg) { static int chipset_inited; enum ultra_chipset_feature features = 0; int rc = CONTROLVM_RESP_SUCCESS; + int res = 0; - POSTCODE_LINUX_2(CHIPSET_INIT_ENTRY_PC, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(CHIPSET_INIT_ENTRY_PC, 0, 0, DIAG_SEVERITY_PRINT); if (chipset_inited) { rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; + res = -EIO; goto out_respond; } chipset_inited = 1; - POSTCODE_LINUX_2(CHIPSET_INIT_EXIT_PC, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(CHIPSET_INIT_EXIT_PC, 0, 0, DIAG_SEVERITY_PRINT); /* * Set features to indicate we support parahotplug (if Command * also supports it). */ - features = - inmsg->cmd.init_chipset. - features & ULTRA_CHIPSET_FEATURE_PARA_HOTPLUG; + features = inmsg->cmd.init_chipset.features & + ULTRA_CHIPSET_FEATURE_PARA_HOTPLUG; /* * Set the "reply" bit so Command knows this is a @@ -545,25 +543,25 @@ chipset_init(struct controlvm_message *inmsg) out_respond: if (inmsg->hdr.flags.response_expected) - controlvm_respond_chipset_init(&inmsg->hdr, rc, features); + res = controlvm_respond_chipset_init(&inmsg->hdr, rc, features); + + return res; } -static void +static int controlvm_respond(struct controlvm_message_header *msg_hdr, int response) { struct controlvm_message outmsg; controlvm_init_response(&outmsg, msg_hdr, response); if (outmsg.hdr.flags.test_message == 1) - return; + return -EINVAL; - if (visorchannel_signalinsert(controlvm_channel, - CONTROLVM_QUEUE_REQUEST, &outmsg)) { - return; - } + return visorchannel_signalinsert(controlvm_channel, + CONTROLVM_QUEUE_REQUEST, &outmsg); } -static void controlvm_respond_physdev_changestate( +static int controlvm_respond_physdev_changestate( struct controlvm_message_header *msg_hdr, int response, struct spar_segment_state state) { @@ -572,10 +570,8 @@ static void controlvm_respond_physdev_changestate( controlvm_init_response(&outmsg, msg_hdr, response); outmsg.cmd.device_change_state.state = state; outmsg.cmd.device_change_state.flags.phys_device = 1; - if (visorchannel_signalinsert(controlvm_channel, - CONTROLVM_QUEUE_REQUEST, &outmsg)) { - return; - } + return visorchannel_signalinsert(controlvm_channel, + CONTROLVM_QUEUE_REQUEST, &outmsg); } enum crash_obj_type { @@ -583,74 +579,80 @@ enum crash_obj_type { CRASH_BUS, }; -static void +static int save_crash_message(struct controlvm_message *msg, enum crash_obj_type typ) { u32 local_crash_msg_offset; u16 local_crash_msg_count; + int err; - if (visorchannel_read(controlvm_channel, - offsetof(struct spar_controlvm_channel_protocol, - saved_crash_message_count), - &local_crash_msg_count, sizeof(u16)) < 0) { - POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, - POSTCODE_SEVERITY_ERR); - return; + err = visorchannel_read(controlvm_channel, + offsetof(struct spar_controlvm_channel_protocol, + saved_crash_message_count), + &local_crash_msg_count, sizeof(u16)); + if (err) { + POSTCODE_LINUX(CRASH_DEV_CTRL_RD_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); + return err; } if (local_crash_msg_count != CONTROLVM_CRASHMSG_MAX) { - POSTCODE_LINUX_3(CRASH_DEV_COUNT_FAILURE_PC, - local_crash_msg_count, - POSTCODE_SEVERITY_ERR); - return; + POSTCODE_LINUX(CRASH_DEV_COUNT_FAILURE_PC, 0, + local_crash_msg_count, + DIAG_SEVERITY_ERR); + return -EIO; } - if (visorchannel_read(controlvm_channel, - offsetof(struct spar_controlvm_channel_protocol, - saved_crash_message_offset), - &local_crash_msg_offset, sizeof(u32)) < 0) { - POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, - POSTCODE_SEVERITY_ERR); - return; + err = visorchannel_read(controlvm_channel, + offsetof(struct spar_controlvm_channel_protocol, + saved_crash_message_offset), + &local_crash_msg_offset, sizeof(u32)); + if (err) { + POSTCODE_LINUX(CRASH_DEV_CTRL_RD_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); + return err; } if (typ == CRASH_BUS) { - if (visorchannel_write(controlvm_channel, - local_crash_msg_offset, - msg, - sizeof(struct controlvm_message)) < 0) { - POSTCODE_LINUX_2(SAVE_MSG_BUS_FAILURE_PC, - POSTCODE_SEVERITY_ERR); - return; + err = visorchannel_write(controlvm_channel, + local_crash_msg_offset, + msg, + sizeof(struct controlvm_message)); + if (err) { + POSTCODE_LINUX(SAVE_MSG_BUS_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); + return err; } } else { local_crash_msg_offset += sizeof(struct controlvm_message); - if (visorchannel_write(controlvm_channel, - local_crash_msg_offset, - msg, - sizeof(struct controlvm_message)) < 0) { - POSTCODE_LINUX_2(SAVE_MSG_DEV_FAILURE_PC, - POSTCODE_SEVERITY_ERR); - return; + err = visorchannel_write(controlvm_channel, + local_crash_msg_offset, + msg, + sizeof(struct controlvm_message)); + if (err) { + POSTCODE_LINUX(SAVE_MSG_DEV_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); + return err; } } + return 0; } -static void +static int bus_responder(enum controlvm_id cmd_id, struct controlvm_message_header *pending_msg_hdr, int response) { if (!pending_msg_hdr) - return; /* no controlvm response needed */ + return -EIO; if (pending_msg_hdr->id != (u32)cmd_id) - return; + return -EINVAL; - controlvm_respond(pending_msg_hdr, response); + return controlvm_respond(pending_msg_hdr, response); } -static void +static int device_changestate_responder(enum controlvm_id cmd_id, struct visor_device *p, int response, struct spar_segment_state response_state) @@ -660,9 +662,9 @@ device_changestate_responder(enum controlvm_id cmd_id, u32 dev_no = p->chipset_dev_no; if (!p->pending_msg_hdr) - return; /* no controlvm response needed */ + return -EIO; if (p->pending_msg_hdr->id != cmd_id) - return; + return -EINVAL; controlvm_init_response(&outmsg, p->pending_msg_hdr, response); @@ -670,175 +672,74 @@ device_changestate_responder(enum controlvm_id cmd_id, outmsg.cmd.device_change_state.dev_no = dev_no; outmsg.cmd.device_change_state.state = response_state; - if (visorchannel_signalinsert(controlvm_channel, - CONTROLVM_QUEUE_REQUEST, &outmsg)) - return; + return visorchannel_signalinsert(controlvm_channel, + CONTROLVM_QUEUE_REQUEST, &outmsg); } -static void +static int device_responder(enum controlvm_id cmd_id, struct controlvm_message_header *pending_msg_hdr, int response) { if (!pending_msg_hdr) - return; /* no controlvm response needed */ + return -EIO; if (pending_msg_hdr->id != (u32)cmd_id) - return; - - controlvm_respond(pending_msg_hdr, response); -} - -static void -bus_epilog(struct visor_device *bus_info, - u32 cmd, struct controlvm_message_header *msg_hdr, - int response, bool need_response) -{ - struct controlvm_message_header *pmsg_hdr = NULL; - - if (!bus_info) { - /* - * relying on a valid passed in response code - * be lazy and re-use msg_hdr for this failure, is this ok?? - */ - pmsg_hdr = msg_hdr; - goto out_respond; - } - - if (bus_info->pending_msg_hdr) { - /* only non-NULL if dev is still waiting on a response */ - response = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT; - pmsg_hdr = bus_info->pending_msg_hdr; - goto out_respond; - } - - if (need_response) { - pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL); - if (!pmsg_hdr) { - POSTCODE_LINUX_4(MALLOC_FAILURE_PC, cmd, - bus_info->chipset_bus_no, - POSTCODE_SEVERITY_ERR); - return; - } - - memcpy(pmsg_hdr, msg_hdr, - sizeof(struct controlvm_message_header)); - bus_info->pending_msg_hdr = pmsg_hdr; - } - - if (response == CONTROLVM_RESP_SUCCESS) { - switch (cmd) { - case CONTROLVM_BUS_CREATE: - chipset_bus_create(bus_info); - break; - case CONTROLVM_BUS_DESTROY: - chipset_bus_destroy(bus_info); - break; - } - } - -out_respond: - bus_responder(cmd, pmsg_hdr, response); -} - -static void -device_epilog(struct visor_device *dev_info, - struct spar_segment_state state, u32 cmd, - struct controlvm_message_header *msg_hdr, int response, - bool need_response, bool for_visorbus) -{ - struct controlvm_message_header *pmsg_hdr = NULL; - - if (!dev_info) { - /* - * relying on a valid passed in response code - * be lazy and re-use msg_hdr for this failure, is this ok?? - */ - pmsg_hdr = msg_hdr; - goto out_respond; - } - - if (dev_info->pending_msg_hdr) { - /* only non-NULL if dev is still waiting on a response */ - response = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT; - pmsg_hdr = dev_info->pending_msg_hdr; - goto out_respond; - } - - if (need_response) { - pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL); - if (!pmsg_hdr) { - response = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; - goto out_respond; - } - - memcpy(pmsg_hdr, msg_hdr, - sizeof(struct controlvm_message_header)); - dev_info->pending_msg_hdr = pmsg_hdr; - } - - if (response >= 0) { - switch (cmd) { - case CONTROLVM_DEVICE_CREATE: - chipset_device_create(dev_info); - break; - case CONTROLVM_DEVICE_CHANGESTATE: - /* ServerReady / ServerRunning / SegmentStateRunning */ - if (state.alive == segment_state_running.alive && - state.operating == - segment_state_running.operating) { - chipset_device_resume(dev_info); - } - /* ServerNotReady / ServerLost / SegmentStateStandby */ - else if (state.alive == segment_state_standby.alive && - state.operating == - segment_state_standby.operating) { - /* - * technically this is standby case - * where server is lost - */ - chipset_device_pause(dev_info); - } - break; - case CONTROLVM_DEVICE_DESTROY: - chipset_device_destroy(dev_info); - break; - } - } + return -EINVAL; -out_respond: - device_responder(cmd, pmsg_hdr, response); + return controlvm_respond(pending_msg_hdr, response); } -static void +static int bus_create(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; + struct controlvm_message_header *pmsg_hdr = NULL; u32 bus_no = cmd->create_bus.bus_no; - int rc = CONTROLVM_RESP_SUCCESS; struct visor_device *bus_info; struct visorchannel *visorchannel; + int err; bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); if (bus_info && (bus_info->state.created == 1)) { - POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no, - POSTCODE_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; - goto out_bus_epilog; + POSTCODE_LINUX(BUS_CREATE_FAILURE_PC, 0, bus_no, + DIAG_SEVERITY_ERR); + err = -EEXIST; + goto err_respond; } + bus_info = kzalloc(sizeof(*bus_info), GFP_KERNEL); if (!bus_info) { - POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no, - POSTCODE_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; - goto out_bus_epilog; + POSTCODE_LINUX(BUS_CREATE_FAILURE_PC, 0, bus_no, + DIAG_SEVERITY_ERR); + err = -ENOMEM; + goto err_respond; } INIT_LIST_HEAD(&bus_info->list_all); bus_info->chipset_bus_no = bus_no; bus_info->chipset_dev_no = BUS_ROOT_DEVICE; - POSTCODE_LINUX_3(BUS_CREATE_ENTRY_PC, bus_no, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(BUS_CREATE_ENTRY_PC, 0, bus_no, DIAG_SEVERITY_PRINT); + + if (uuid_le_cmp(cmd->create_bus.bus_inst_uuid, spar_siovm_uuid) == 0) + save_crash_message(inmsg, CRASH_BUS); + + if (inmsg->hdr.flags.response_expected == 1) { + pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), + GFP_KERNEL); + if (!pmsg_hdr) { + POSTCODE_LINUX(MALLOC_FAILURE_PC, cmd, + bus_info->chipset_bus_no, + DIAG_SEVERITY_ERR); + err = -ENOMEM; + goto err_free_bus_info; + } + + memcpy(pmsg_hdr, &inmsg->hdr, + sizeof(struct controlvm_message_header)); + bus_info->pending_msg_hdr = pmsg_hdr; + } visorchannel = visorchannel_create(cmd->create_bus.channel_addr, cmd->create_bus.channel_bytes, @@ -846,89 +747,138 @@ bus_create(struct controlvm_message *inmsg) cmd->create_bus.bus_data_type_uuid); if (!visorchannel) { - POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no, - POSTCODE_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; - kfree(bus_info); - bus_info = NULL; - goto out_bus_epilog; + POSTCODE_LINUX(BUS_CREATE_FAILURE_PC, 0, bus_no, + DIAG_SEVERITY_ERR); + err = -ENOMEM; + goto err_free_pending_msg; } bus_info->visorchannel = visorchannel; - if (uuid_le_cmp(cmd->create_bus.bus_inst_uuid, spar_siovm_uuid) == 0) - save_crash_message(inmsg, CRASH_BUS); - POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus_no, POSTCODE_SEVERITY_INFO); + /* Response will be handled by chipset_bus_create */ + chipset_bus_create(bus_info); + + POSTCODE_LINUX(BUS_CREATE_EXIT_PC, 0, bus_no, DIAG_SEVERITY_PRINT); + return 0; + +err_free_pending_msg: + kfree(bus_info->pending_msg_hdr); + +err_free_bus_info: + kfree(bus_info); -out_bus_epilog: - bus_epilog(bus_info, CONTROLVM_BUS_CREATE, &inmsg->hdr, - rc, inmsg->hdr.flags.response_expected == 1); +err_respond: + if (inmsg->hdr.flags.response_expected == 1) + bus_responder(inmsg->hdr.id, &inmsg->hdr, err); + return err; } -static void +static int bus_destroy(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; + struct controlvm_message_header *pmsg_hdr = NULL; u32 bus_no = cmd->destroy_bus.bus_no; struct visor_device *bus_info; - int rc = CONTROLVM_RESP_SUCCESS; + int err; bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); - if (!bus_info) - rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; - else if (bus_info->state.created == 0) - rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; + if (!bus_info) { + err = -ENODEV; + goto err_respond; + } + if (bus_info->state.created == 0) { + err = -ENOENT; + goto err_respond; + } + if (bus_info->pending_msg_hdr) { + /* only non-NULL if dev is still waiting on a response */ + err = -EEXIST; + goto err_respond; + } + if (inmsg->hdr.flags.response_expected == 1) { + pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL); + if (!pmsg_hdr) { + POSTCODE_LINUX(MALLOC_FAILURE_PC, cmd, + bus_info->chipset_bus_no, + DIAG_SEVERITY_ERR); + err = -ENOMEM; + goto err_respond; + } - bus_epilog(bus_info, CONTROLVM_BUS_DESTROY, &inmsg->hdr, - rc, inmsg->hdr.flags.response_expected == 1); + memcpy(pmsg_hdr, &inmsg->hdr, + sizeof(struct controlvm_message_header)); + bus_info->pending_msg_hdr = pmsg_hdr; + } - /* bus_info is freed as part of the busdevice_release function */ + /* Response will be handled by chipset_bus_destroy */ + chipset_bus_destroy(bus_info); + return 0; + +err_respond: + if (inmsg->hdr.flags.response_expected == 1) + bus_responder(inmsg->hdr.id, &inmsg->hdr, err); + return err; } -static void +static int bus_configure(struct controlvm_message *inmsg, struct parser_context *parser_ctx) { struct controlvm_message_packet *cmd = &inmsg->cmd; u32 bus_no; struct visor_device *bus_info; - int rc = CONTROLVM_RESP_SUCCESS; + int err = 0; bus_no = cmd->configure_bus.bus_no; - POSTCODE_LINUX_3(BUS_CONFIGURE_ENTRY_PC, bus_no, - POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(BUS_CONFIGURE_ENTRY_PC, 0, bus_no, + DIAG_SEVERITY_PRINT); bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); if (!bus_info) { - POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, bus_no, - POSTCODE_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; + POSTCODE_LINUX(BUS_CONFIGURE_FAILURE_PC, 0, bus_no, + DIAG_SEVERITY_ERR); + err = -EINVAL; + goto err_respond; } else if (bus_info->state.created == 0) { - POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, bus_no, - POSTCODE_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; + POSTCODE_LINUX(BUS_CONFIGURE_FAILURE_PC, 0, bus_no, + DIAG_SEVERITY_ERR); + err = -EINVAL; + goto err_respond; } else if (bus_info->pending_msg_hdr) { - POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, bus_no, - POSTCODE_SEVERITY_ERR); - rc = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT; - } else { - visorchannel_set_clientpartition - (bus_info->visorchannel, - cmd->configure_bus.guest_handle); - bus_info->partition_uuid = parser_id_get(parser_ctx); - parser_param_start(parser_ctx, PARSERSTRING_NAME); - bus_info->name = parser_string_get(parser_ctx); - - POSTCODE_LINUX_3(BUS_CONFIGURE_EXIT_PC, bus_no, - POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(BUS_CONFIGURE_FAILURE_PC, 0, bus_no, + DIAG_SEVERITY_ERR); + err = -EIO; + goto err_respond; } - bus_epilog(bus_info, CONTROLVM_BUS_CONFIGURE, &inmsg->hdr, - rc, inmsg->hdr.flags.response_expected == 1); + + err = visorchannel_set_clientpartition + (bus_info->visorchannel, + cmd->configure_bus.guest_handle); + if (err) + goto err_respond; + + bus_info->partition_uuid = parser_id_get(parser_ctx); + parser_param_start(parser_ctx, PARSERSTRING_NAME); + bus_info->name = parser_string_get(parser_ctx); + + POSTCODE_LINUX(BUS_CONFIGURE_EXIT_PC, 0, bus_no, + DIAG_SEVERITY_PRINT); + + if (inmsg->hdr.flags.response_expected == 1) + bus_responder(inmsg->hdr.id, &inmsg->hdr, err); + return 0; + +err_respond: + if (inmsg->hdr.flags.response_expected == 1) + bus_responder(inmsg->hdr.id, &inmsg->hdr, err); + return err; } static void my_device_create(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; + struct controlvm_message_header *pmsg_hdr = NULL; u32 bus_no = cmd->create_device.bus_no; u32 dev_no = cmd->create_device.dev_no; struct visor_device *dev_info = NULL; @@ -938,31 +888,31 @@ my_device_create(struct controlvm_message *inmsg) bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); if (!bus_info) { - POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, + DIAG_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; goto out_respond; } if (bus_info->state.created == 0) { - POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, + DIAG_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_BUS_INVALID; goto out_respond; } dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL); if (dev_info && (dev_info->state.created == 1)) { - POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, + DIAG_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; goto out_respond; } dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL); if (!dev_info) { - POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, + DIAG_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; goto out_respond; } @@ -974,8 +924,8 @@ my_device_create(struct controlvm_message *inmsg) /* not sure where the best place to set the 'parent' */ dev_info->device.parent = &bus_info->device; - POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, dev_no, bus_no, - POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(DEVICE_CREATE_ENTRY_PC, dev_no, bus_no, + DIAG_SEVERITY_PRINT); visorchannel = visorchannel_create_with_lock(cmd->create_device.channel_addr, @@ -984,12 +934,10 @@ my_device_create(struct controlvm_message *inmsg) cmd->create_device.data_type_uuid); if (!visorchannel) { - POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no, + DIAG_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; - kfree(dev_info); - dev_info = NULL; - goto out_respond; + goto out_free_dev_info; } dev_info->visorchannel = visorchannel; dev_info->channel_type_guid = cmd->create_device.data_type_uuid; @@ -997,18 +945,36 @@ my_device_create(struct controlvm_message *inmsg) spar_vhba_channel_protocol_uuid) == 0) save_crash_message(inmsg, CRASH_DEV); - POSTCODE_LINUX_4(DEVICE_CREATE_EXIT_PC, dev_no, bus_no, - POSTCODE_SEVERITY_INFO); + if (inmsg->hdr.flags.response_expected == 1) { + pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL); + if (!pmsg_hdr) { + rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; + goto out_free_dev_info; + } + + memcpy(pmsg_hdr, &inmsg->hdr, + sizeof(struct controlvm_message_header)); + dev_info->pending_msg_hdr = pmsg_hdr; + } + /* Chipset_device_create will send response */ + chipset_device_create(dev_info); + POSTCODE_LINUX(DEVICE_CREATE_EXIT_PC, dev_no, bus_no, + DIAG_SEVERITY_PRINT); + return; + +out_free_dev_info: + kfree(dev_info); + out_respond: - device_epilog(dev_info, segment_state_running, - CONTROLVM_DEVICE_CREATE, &inmsg->hdr, rc, - inmsg->hdr.flags.response_expected == 1, 1); + if (inmsg->hdr.flags.response_expected == 1) + device_responder(inmsg->hdr.id, &inmsg->hdr, rc); } static void my_device_changestate(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; + struct controlvm_message_header *pmsg_hdr = NULL; u32 bus_no = cmd->device_change_state.bus_no; u32 dev_no = cmd->device_change_state.dev_no; struct spar_segment_state state = cmd->device_change_state.state; @@ -1017,39 +983,97 @@ my_device_changestate(struct controlvm_message *inmsg) dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL); if (!dev_info) { - POSTCODE_LINUX_4(DEVICE_CHANGESTATE_FAILURE_PC, dev_no, bus_no, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(DEVICE_CHANGESTATE_FAILURE_PC, dev_no, bus_no, + DIAG_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID; - } else if (dev_info->state.created == 0) { - POSTCODE_LINUX_4(DEVICE_CHANGESTATE_FAILURE_PC, dev_no, bus_no, - POSTCODE_SEVERITY_ERR); + goto err_respond; + } + if (dev_info->state.created == 0) { + POSTCODE_LINUX(DEVICE_CHANGESTATE_FAILURE_PC, dev_no, bus_no, + DIAG_SEVERITY_ERR); rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID; + goto err_respond; + } + if (dev_info->pending_msg_hdr) { + /* only non-NULL if dev is still waiting on a response */ + rc = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT; + goto err_respond; } - if ((rc >= CONTROLVM_RESP_SUCCESS) && dev_info) - device_epilog(dev_info, state, - CONTROLVM_DEVICE_CHANGESTATE, &inmsg->hdr, rc, - inmsg->hdr.flags.response_expected == 1, 1); + if (inmsg->hdr.flags.response_expected == 1) { + pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL); + if (!pmsg_hdr) { + rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; + goto err_respond; + } + + memcpy(pmsg_hdr, &inmsg->hdr, + sizeof(struct controlvm_message_header)); + dev_info->pending_msg_hdr = pmsg_hdr; + } + + if (state.alive == segment_state_running.alive && + state.operating == segment_state_running.operating) + /* Response will be sent from chipset_device_resume */ + chipset_device_resume(dev_info); + /* ServerNotReady / ServerLost / SegmentStateStandby */ + else if (state.alive == segment_state_standby.alive && + state.operating == segment_state_standby.operating) + /* + * technically this is standby case where server is lost. + * Response will be sent from chipset_device_pause. + */ + chipset_device_pause(dev_info); + + return; + +err_respond: + if (inmsg->hdr.flags.response_expected == 1) + device_responder(inmsg->hdr.id, &inmsg->hdr, rc); } static void my_device_destroy(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; + struct controlvm_message_header *pmsg_hdr = NULL; u32 bus_no = cmd->destroy_device.bus_no; u32 dev_no = cmd->destroy_device.dev_no; struct visor_device *dev_info; int rc = CONTROLVM_RESP_SUCCESS; dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL); - if (!dev_info) + if (!dev_info) { rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID; - else if (dev_info->state.created == 0) + goto err_respond; + } + if (dev_info->state.created == 0) { rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE; + goto err_respond; + } - if ((rc >= CONTROLVM_RESP_SUCCESS) && dev_info) - device_epilog(dev_info, segment_state_running, - CONTROLVM_DEVICE_DESTROY, &inmsg->hdr, rc, - inmsg->hdr.flags.response_expected == 1, 1); + if (dev_info->pending_msg_hdr) { + /* only non-NULL if dev is still waiting on a response */ + rc = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT; + goto err_respond; + } + if (inmsg->hdr.flags.response_expected == 1) { + pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL); + if (!pmsg_hdr) { + rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED; + goto err_respond; + } + + memcpy(pmsg_hdr, &inmsg->hdr, + sizeof(struct controlvm_message_header)); + dev_info->pending_msg_hdr = pmsg_hdr; + } + + chipset_device_destroy(dev_info); + return; + +err_respond: + if (inmsg->hdr.flags.response_expected == 1) + device_responder(inmsg->hdr.id, &inmsg->hdr, rc); } /** @@ -1075,7 +1099,6 @@ initialize_controlvm_payload_info(u64 phys_addr, u64 offset, u32 bytes, if (!info) return -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID; - memset(info, 0, sizeof(struct visor_controlvm_payload_info)); if ((offset == 0) || (bytes == 0)) return -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID; @@ -1083,6 +1106,7 @@ initialize_controlvm_payload_info(u64 phys_addr, u64 offset, u32 bytes, if (!payload) return -CONTROLVM_RESP_ERROR_IOREMAP_FAILED; + memset(info, 0, sizeof(struct visor_controlvm_payload_info)); info->offset = offset; info->bytes = bytes; info->ptr = payload; @@ -1111,16 +1135,16 @@ initialize_controlvm_payload(void) offsetof(struct spar_controlvm_channel_protocol, request_payload_offset), &payload_offset, sizeof(payload_offset)) < 0) { - POSTCODE_LINUX_2(CONTROLVM_INIT_FAILURE_PC, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CONTROLVM_INIT_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); return; } if (visorchannel_read(controlvm_channel, offsetof(struct spar_controlvm_channel_protocol, request_payload_bytes), &payload_bytes, sizeof(payload_bytes)) < 0) { - POSTCODE_LINUX_2(CONTROLVM_INIT_FAILURE_PC, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CONTROLVM_INIT_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); return; } initialize_controlvm_payload_info(phys_addr, @@ -1317,7 +1341,7 @@ static struct attribute *visorchipset_install_attrs[] = { NULL }; -static struct attribute_group visorchipset_install_group = { +static const struct attribute_group visorchipset_install_group = { .name = "install", .attrs = visorchipset_install_attrs }; @@ -1540,7 +1564,7 @@ setup_crash_devices_work_queue(struct work_struct *work) u32 local_crash_msg_offset; u16 local_crash_msg_count; - POSTCODE_LINUX_2(CRASH_DEV_ENTRY_PC, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(CRASH_DEV_ENTRY_PC, 0, 0, DIAG_SEVERITY_PRINT); /* send init chipset msg */ msg.hdr.id = CONTROLVM_CHIPSET_INIT; @@ -1554,15 +1578,15 @@ setup_crash_devices_work_queue(struct work_struct *work) offsetof(struct spar_controlvm_channel_protocol, saved_crash_message_count), &local_crash_msg_count, sizeof(u16)) < 0) { - POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CRASH_DEV_CTRL_RD_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); return; } if (local_crash_msg_count != CONTROLVM_CRASHMSG_MAX) { - POSTCODE_LINUX_3(CRASH_DEV_COUNT_FAILURE_PC, - local_crash_msg_count, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CRASH_DEV_COUNT_FAILURE_PC, 0, + local_crash_msg_count, + DIAG_SEVERITY_ERR); return; } @@ -1571,8 +1595,8 @@ setup_crash_devices_work_queue(struct work_struct *work) offsetof(struct spar_controlvm_channel_protocol, saved_crash_message_offset), &local_crash_msg_offset, sizeof(u32)) < 0) { - POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CRASH_DEV_CTRL_RD_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); return; } @@ -1581,8 +1605,8 @@ setup_crash_devices_work_queue(struct work_struct *work) local_crash_msg_offset, &local_crash_bus_msg, sizeof(struct controlvm_message)) < 0) { - POSTCODE_LINUX_2(CRASH_DEV_RD_BUS_FAIULRE_PC, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CRASH_DEV_RD_BUS_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); return; } @@ -1592,8 +1616,8 @@ setup_crash_devices_work_queue(struct work_struct *work) sizeof(struct controlvm_message), &local_crash_dev_msg, sizeof(struct controlvm_message)) < 0) { - POSTCODE_LINUX_2(CRASH_DEV_RD_DEV_FAIULRE_PC, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CRASH_DEV_RD_DEV_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); return; } @@ -1601,8 +1625,8 @@ setup_crash_devices_work_queue(struct work_struct *work) if (local_crash_bus_msg.cmd.create_bus.channel_addr) { bus_create(&local_crash_bus_msg); } else { - POSTCODE_LINUX_2(CRASH_DEV_BUS_NULL_FAILURE_PC, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CRASH_DEV_BUS_NULL_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); return; } @@ -1610,11 +1634,11 @@ setup_crash_devices_work_queue(struct work_struct *work) if (local_crash_dev_msg.cmd.create_device.channel_addr) { my_device_create(&local_crash_dev_msg); } else { - POSTCODE_LINUX_2(CRASH_DEV_DEV_NULL_FAILURE_PC, - POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CRASH_DEV_DEV_NULL_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); return; } - POSTCODE_LINUX_2(CRASH_DEV_EXIT_PC, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(CRASH_DEV_EXIT_PC, 0, 0, DIAG_SEVERITY_PRINT); } void @@ -2119,8 +2143,6 @@ visorchipset_init(struct acpi_device *acpi_device) if (!addr) goto error; - memset(&controlvm_payload_info, 0, sizeof(controlvm_payload_info)); - controlvm_channel = visorchannel_create_with_lock(addr, 0, GFP_KERNEL, uuid); if (!controlvm_channel) @@ -2152,11 +2174,12 @@ visorchipset_init(struct acpi_device *acpi_device) visorchipset_platform_device.dev.devt = major_dev; if (platform_device_register(&visorchipset_platform_device) < 0) { - POSTCODE_LINUX_2(DEVICE_REGISTER_FAILURE_PC, DIAG_SEVERITY_ERR); + POSTCODE_LINUX(DEVICE_REGISTER_FAILURE_PC, 0, 0, + DIAG_SEVERITY_ERR); err = -ENODEV; goto error_cancel_work; } - POSTCODE_LINUX_2(CHIPSET_INIT_SUCCESS_PC, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(CHIPSET_INIT_SUCCESS_PC, 0, 0, DIAG_SEVERITY_PRINT); err = visorbus_init(); if (err < 0) @@ -2178,14 +2201,14 @@ error_destroy_channel: visorchannel_destroy(controlvm_channel); error: - POSTCODE_LINUX_3(CHIPSET_INIT_FAILURE_PC, err, POSTCODE_SEVERITY_ERR); + POSTCODE_LINUX(CHIPSET_INIT_FAILURE_PC, 0, err, DIAG_SEVERITY_ERR); return err; } static int visorchipset_exit(struct acpi_device *acpi_device) { - POSTCODE_LINUX_2(DRIVER_EXIT_PC, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(DRIVER_EXIT_PC, 0, 0, DIAG_SEVERITY_PRINT); visorbus_exit(); @@ -2196,7 +2219,7 @@ visorchipset_exit(struct acpi_device *acpi_device) visorchipset_file_cleanup(visorchipset_platform_device.dev.devt); platform_device_unregister(&visorchipset_platform_device); - POSTCODE_LINUX_2(DRIVER_EXIT_PC, POSTCODE_SEVERITY_INFO); + POSTCODE_LINUX(DRIVER_EXIT_PC, 0, 0, DIAG_SEVERITY_PRINT); return 0; } diff --git a/drivers/staging/unisys/visorbus/vmcallinterface.h b/drivers/staging/unisys/visorbus/vmcallinterface.h index 86e695d5a441..674a88b657d3 100644 --- a/drivers/staging/unisys/visorbus/vmcallinterface.h +++ b/drivers/staging/unisys/visorbus/vmcallinterface.h @@ -92,15 +92,6 @@ enum vmcall_monitor_interface_method_tuple { /* VMCALL identification tuples */ #define ISSUE_IO_VMCALL(method, param, result) \ (result = unisys_vmcall(method, (param) & 0xFFFFFFFF, \ (param) >> 32)) -#define ISSUE_IO_EXTENDED_VMCALL(method, param1, param2, param3) \ - unisys_extended_vmcall(method, param1, param2, param3) - - /* The following uses VMCALL_POST_CODE_LOGEVENT interface but is currently - * not used much - */ -#define ISSUE_IO_VMCALL_POSTCODE_SEVERITY(postcode, severity) \ - ISSUE_IO_EXTENDED_VMCALL(VMCALL_POST_CODE_LOGEVENT, severity, \ - MDS_APPOS, postcode) /* Structures for IO VMCALLs */ @@ -117,118 +108,53 @@ struct vmcall_io_controlvm_addr_params { /******* INFO ON ISSUE_POSTCODE_LINUX() BELOW *******/ enum driver_pc { /* POSTCODE driver identifier tuples */ - /* visorchipset driver files */ - VISOR_CHIPSET_PC = 0xA0, - VISOR_CHIPSET_PC_controlvm_c = 0xA1, - VISOR_CHIPSET_PC_controlvm_cm2 = 0xA2, - VISOR_CHIPSET_PC_controlvm_direct_c = 0xA3, - VISOR_CHIPSET_PC_file_c = 0xA4, - VISOR_CHIPSET_PC_parser_c = 0xA5, - VISOR_CHIPSET_PC_testing_c = 0xA6, - VISOR_CHIPSET_PC_visorchipset_main_c = 0xA7, - VISOR_CHIPSET_PC_visorswitchbus_c = 0xA8, /* visorbus driver files */ - VISOR_BUS_PC = 0xB0, - VISOR_BUS_PC_businst_attr_c = 0xB1, - VISOR_BUS_PC_channel_attr_c = 0xB2, - VISOR_BUS_PC_devmajorminor_attr_c = 0xB3, - VISOR_BUS_PC_visorbus_main_c = 0xB4, - /* visorclientbus driver files */ - VISOR_CLIENT_BUS_PC = 0xC0, - VISOR_CLIENT_BUS_PC_visorclientbus_main_c = 0xC1, - /* virt hba driver files */ - VIRT_HBA_PC = 0xC2, - VIRT_HBA_PC_virthba_c = 0xC3, - /* virtpci driver files */ - VIRT_PCI_PC = 0xC4, - VIRT_PCI_PC_virtpci_c = 0xC5, - /* virtnic driver files */ - VIRT_NIC_PC = 0xC6, - VIRT_NIC_P_virtnic_c = 0xC7, - /* uislib driver files */ - UISLIB_PC = 0xD0, - UISLIB_PC_uislib_c = 0xD1, - UISLIB_PC_uisqueue_c = 0xD2, - /* 0xD3 RESERVED */ - UISLIB_PC_uisutils_c = 0xD4, + VISOR_BUS_PC = 0xF0, + VISOR_BUS_PC_visorbus_main_c = 0xFF, + VISOR_BUS_PC_visorchipset_c = 0xFE, }; enum event_pc { /* POSTCODE event identifier tuples */ - ATTACH_PORT_ENTRY_PC = 0x001, - ATTACH_PORT_FAILURE_PC = 0x002, - ATTACH_PORT_SUCCESS_PC = 0x003, - BUS_FAILURE_PC = 0x004, - BUS_CREATE_ENTRY_PC = 0x005, - BUS_CREATE_FAILURE_PC = 0x006, - BUS_CREATE_EXIT_PC = 0x007, - BUS_CONFIGURE_ENTRY_PC = 0x008, - BUS_CONFIGURE_FAILURE_PC = 0x009, - BUS_CONFIGURE_EXIT_PC = 0x00A, - CHIPSET_INIT_ENTRY_PC = 0x00B, - CHIPSET_INIT_SUCCESS_PC = 0x00C, - CHIPSET_INIT_FAILURE_PC = 0x00D, - CHIPSET_INIT_EXIT_PC = 0x00E, - CREATE_WORKQUEUE_PC = 0x00F, - CREATE_WORKQUEUE_FAILED_PC = 0x0A0, - CONTROLVM_INIT_FAILURE_PC = 0x0A1, - DEVICE_CREATE_ENTRY_PC = 0x0A2, - DEVICE_CREATE_FAILURE_PC = 0x0A3, - DEVICE_CREATE_SUCCESS_PC = 0x0A4, - DEVICE_CREATE_EXIT_PC = 0x0A5, - DEVICE_ADD_PC = 0x0A6, - DEVICE_REGISTER_FAILURE_PC = 0x0A7, - DEVICE_CHANGESTATE_ENTRY_PC = 0x0A8, - DEVICE_CHANGESTATE_FAILURE_PC = 0x0A9, - DEVICE_CHANGESTATE_EXIT_PC = 0x0AA, - DRIVER_ENTRY_PC = 0x0AB, - DRIVER_EXIT_PC = 0x0AC, - MALLOC_FAILURE_PC = 0x0AD, - QUEUE_DELAYED_WORK_PC = 0x0AE, - /* 0x0B7 RESERVED */ - VBUS_CHANNEL_ENTRY_PC = 0x0B8, - VBUS_CHANNEL_FAILURE_PC = 0x0B9, - VBUS_CHANNEL_EXIT_PC = 0x0BA, - VHBA_CREATE_ENTRY_PC = 0x0BB, - VHBA_CREATE_FAILURE_PC = 0x0BC, - VHBA_CREATE_EXIT_PC = 0x0BD, - VHBA_CREATE_SUCCESS_PC = 0x0BE, - VHBA_COMMAND_HANDLER_PC = 0x0BF, - VHBA_PROBE_ENTRY_PC = 0x0C0, - VHBA_PROBE_FAILURE_PC = 0x0C1, - VHBA_PROBE_EXIT_PC = 0x0C2, - VNIC_CREATE_ENTRY_PC = 0x0C3, - VNIC_CREATE_FAILURE_PC = 0x0C4, - VNIC_CREATE_SUCCESS_PC = 0x0C5, - VNIC_PROBE_ENTRY_PC = 0x0C6, - VNIC_PROBE_FAILURE_PC = 0x0C7, - VNIC_PROBE_EXIT_PC = 0x0C8, - VPCI_CREATE_ENTRY_PC = 0x0C9, - VPCI_CREATE_FAILURE_PC = 0x0CA, - VPCI_CREATE_EXIT_PC = 0x0CB, - VPCI_PROBE_ENTRY_PC = 0x0CC, - VPCI_PROBE_FAILURE_PC = 0x0CD, - VPCI_PROBE_EXIT_PC = 0x0CE, - CRASH_DEV_ENTRY_PC = 0x0CF, - CRASH_DEV_EXIT_PC = 0x0D0, - CRASH_DEV_HADDR_NULL = 0x0D1, - CRASH_DEV_CONTROLVM_NULL = 0x0D2, - CRASH_DEV_RD_BUS_FAIULRE_PC = 0x0D3, - CRASH_DEV_RD_DEV_FAIULRE_PC = 0x0D4, - CRASH_DEV_BUS_NULL_FAILURE_PC = 0x0D5, - CRASH_DEV_DEV_NULL_FAILURE_PC = 0x0D6, - CRASH_DEV_CTRL_RD_FAILURE_PC = 0x0D7, - CRASH_DEV_COUNT_FAILURE_PC = 0x0D8, - SAVE_MSG_BUS_FAILURE_PC = 0x0D9, - SAVE_MSG_DEV_FAILURE_PC = 0x0DA, - CALLHOME_INIT_FAILURE_PC = 0x0DB + BUS_CREATE_ENTRY_PC = 0x001, + BUS_CREATE_FAILURE_PC = 0x002, + BUS_CREATE_EXIT_PC = 0x003, + BUS_CONFIGURE_ENTRY_PC = 0x004, + BUS_CONFIGURE_FAILURE_PC = 0x005, + BUS_CONFIGURE_EXIT_PC = 0x006, + CHIPSET_INIT_ENTRY_PC = 0x007, + CHIPSET_INIT_SUCCESS_PC = 0x008, + CHIPSET_INIT_FAILURE_PC = 0x009, + CHIPSET_INIT_EXIT_PC = 0x00A, + CONTROLVM_INIT_FAILURE_PC = 0x00B, + DEVICE_CREATE_ENTRY_PC = 0x00C, + DEVICE_CREATE_FAILURE_PC = 0x00D, + DEVICE_CREATE_SUCCESS_PC = 0x00E, + DEVICE_CREATE_EXIT_PC = 0x00F, + DEVICE_ADD_PC = 0x010, + DEVICE_REGISTER_FAILURE_PC = 0x011, + DEVICE_CHANGESTATE_FAILURE_PC = 0x012, + DRIVER_ENTRY_PC = 0x013, + DRIVER_EXIT_PC = 0x014, + MALLOC_FAILURE_PC = 0x015, + CRASH_DEV_ENTRY_PC = 0x016, + CRASH_DEV_EXIT_PC = 0x017, + CRASH_DEV_RD_BUS_FAILURE_PC = 0x018, + CRASH_DEV_RD_DEV_FAILURE_PC = 0x019, + CRASH_DEV_BUS_NULL_FAILURE_PC = 0x01A, + CRASH_DEV_DEV_NULL_FAILURE_PC = 0x01B, + CRASH_DEV_CTRL_RD_FAILURE_PC = 0x01C, + CRASH_DEV_COUNT_FAILURE_PC = 0x01D, + SAVE_MSG_BUS_FAILURE_PC = 0x01E, + SAVE_MSG_DEV_FAILURE_PC = 0x01F, }; -#define POSTCODE_SEVERITY_ERR DIAG_SEVERITY_ERR -#define POSTCODE_SEVERITY_WARNING DIAG_SEVERITY_WARNING -/* TODO-> Info currently doesn't show, so we set info=warning */ -#define POSTCODE_SEVERITY_INFO DIAG_SEVERITY_PRINT - -/* example call of POSTCODE_LINUX_2(VISOR_CHIPSET_PC, POSTCODE_SEVERITY_ERR); +/* Write a 64-bit value to the hypervisor's log file + * POSTCODE_LINUX generates a value in the form 0xAABBBCCCDDDDEEEE where + * A is an identifier for the file logging the postcode + * B is an identifier for the event logging the postcode + * C is the line logging the postcode + * D is additional information the caller wants to log + * E is additional information the caller wants to log * Please also note that the resulting postcode is in hex, so if you are * searching for the __LINE__ number, convert it first to decimal. The line * number combined with driver and type of call, will allow you to track down @@ -236,35 +162,16 @@ enum event_pc { /* POSTCODE event identifier tuples */ * entered/exited from. */ -/* BASE FUNCTIONS */ -#define POSTCODE_LINUX_A(DRIVER_PC, EVENT_PC, pc32bit, severity) \ -do { \ - unsigned long long post_code_temp; \ - post_code_temp = (((u64)DRIVER_PC) << 56) | (((u64)EVENT_PC) << 44) | \ - ((((u64)__LINE__) & 0xFFF) << 32) | \ - (((u64)pc32bit) & 0xFFFFFFFF); \ - ISSUE_IO_VMCALL_POSTCODE_SEVERITY(post_code_temp, severity); \ -} while (0) - -#define POSTCODE_LINUX_B(DRIVER_PC, EVENT_PC, pc16bit1, pc16bit2, severity) \ +#define POSTCODE_LINUX(EVENT_PC, pc16bit1, pc16bit2, severity) \ do { \ unsigned long long post_code_temp; \ - post_code_temp = (((u64)DRIVER_PC) << 56) | (((u64)EVENT_PC) << 44) | \ + post_code_temp = (((u64)CURRENT_FILE_PC) << 56) | \ + (((u64)EVENT_PC) << 44) | \ ((((u64)__LINE__) & 0xFFF) << 32) | \ ((((u64)pc16bit1) & 0xFFFF) << 16) | \ (((u64)pc16bit2) & 0xFFFF); \ - ISSUE_IO_VMCALL_POSTCODE_SEVERITY(post_code_temp, severity); \ + unisys_extended_vmcall(VMCALL_POST_CODE_LOGEVENT, severity, \ + MDS_APPOS, post_code_temp); \ } while (0) -/* MOST COMMON */ -#define POSTCODE_LINUX_2(EVENT_PC, severity) \ - POSTCODE_LINUX_A(CURRENT_FILE_PC, EVENT_PC, 0x0000, severity) - -#define POSTCODE_LINUX_3(EVENT_PC, pc32bit, severity) \ - POSTCODE_LINUX_A(CURRENT_FILE_PC, EVENT_PC, pc32bit, severity) - -#define POSTCODE_LINUX_4(EVENT_PC, pc16bit1, pc16bit2, severity) \ - POSTCODE_LINUX_B(CURRENT_FILE_PC, EVENT_PC, pc16bit1, \ - pc16bit2, severity) - #endif /* __IOMONINTF_H__ */ diff --git a/drivers/staging/unisys/visorinput/visorinput.c b/drivers/staging/unisys/visorinput/visorinput.c index 6f94b646f7c5..949cce680b29 100644 --- a/drivers/staging/unisys/visorinput/visorinput.c +++ b/drivers/staging/unisys/visorinput/visorinput.c @@ -409,6 +409,9 @@ devdata_create(struct visor_device *dev, enum visorinput_device_type devtype) if (!devdata->visorinput_dev) goto cleanups_register; break; + default: + /* No other input devices supported */ + break; } dev_set_drvdata(&dev->device, devdata); @@ -653,6 +656,9 @@ visorinput_channel_interrupt(struct visor_device *dev) input_report_rel(visorinput_dev, REL_WHEEL, -1); input_sync(visorinput_dev); break; + default: + /* Unsupported input action */ + break; } } } diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c index f8a584bf4a77..c1f674f5268c 100644 --- a/drivers/staging/unisys/visornic/visornic_main.c +++ b/drivers/staging/unisys/visornic/visornic_main.c @@ -1371,7 +1371,7 @@ static ssize_t info_debugfs_read(struct file *file, char __user *buf, " num_rcv_bufs = %d\n", devdata->num_rcv_bufs); str_pos += scnprintf(vbuf + str_pos, len - str_pos, - " max_oustanding_next_xmits = %lu\n", + " max_outstanding_next_xmits = %lu\n", devdata->max_outstanding_net_xmits); str_pos += scnprintf(vbuf + str_pos, len - str_pos, " upper_threshold_net_xmits = %lu\n", |