Commit e423812a authored by Ken Cox's avatar Ken Cox Committed by Greg Kroah-Hartman

staging: visorchannel module

The visorchannel module is a support library that abstracts reading
and writing a channel in memory.
Signed-off-by: default avatarKen Cox <jkc@redhat.com>
Cc: Ben Romer <sparmaintainer@unisys.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 9d9baadd
...@@ -10,5 +10,6 @@ menuconfig UNISYSSPAR ...@@ -10,5 +10,6 @@ menuconfig UNISYSSPAR
if UNISYSSPAR if UNISYSSPAR
source "drivers/staging/unisys/visorutil/Kconfig" source "drivers/staging/unisys/visorutil/Kconfig"
source "drivers/staging/unisys/visorchannel/Kconfig"
endif # UNISYSSPAR endif # UNISYSSPAR
...@@ -2,4 +2,5 @@ ...@@ -2,4 +2,5 @@
# Makefile for Unisys SPAR drivers # Makefile for Unisys SPAR drivers
# #
obj-$(CONFIG_UNISYS_VISORUTIL) += visorutil/ obj-$(CONFIG_UNISYS_VISORUTIL) += visorutil/
obj-$(CONFIG_UNISYS_VISORCHANNEL) += visorchannel/
This diff is collapsed.
/* Copyright © 2010 - 2013 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.
*/
/* version.h */
/* Common version/release info needed by all components goes here.
* (This file must compile cleanly in all environments.)
* Ultimately, this will be combined with defines generated dynamically as
* part of the sysgen, and some of the defines below may in fact end up
* being replaced with dynamically generated ones.
*/
#ifndef __VERSION_H__
#define __VERSION_H__
#define SPARVER1 "1"
#define SPARVER2 "0"
#define SPARVER3 "0"
#define SPARVER4 "0"
#define VERSION SPARVER1 "." SPARVER2 "." SPARVER3 "." SPARVER4
#define VERSIONDATE __DATE__
/* Here are various version forms needed in Windows environments.
*/
#define VISOR_PRODUCTVERSION SPARVERCOMMA
#define VISOR_PRODUCTVERSION_STR SPARVER1 "." SPARVER2 "." SPARVER3 "." \
SPARVER4
#define VISOR_OBJECTVERSION_STR SPARVER1 "," SPARVER2 "," SPARVER3 "," \
SPARVER4
#define COPYRIGHT "Unisys Corporation"
#define COPYRIGHTDATE "2010 - 2013"
#endif
/* Copyright © 2010 - 2013 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 _COMMONTYPES_H_
#define _COMMONTYPES_H_
/* define the following to prevent include nesting in kernel header files of
* similar abreviated content */
#define _SUPERVISOR_COMMONTYPES_H_
#ifdef __KERNEL__
#include <linux/types.h>
#include <linux/version.h>
#else
#include <stdint.h>
#include <syslog.h>
#endif
#define U8 uint8_t
#define U16 uint16_t
#define U32 uint32_t
#define U64 uint64_t
#define S8 int8_t
#define S16 int16_t
#define S32 int32_t
#define S64 int64_t
#ifdef __KERNEL__
#ifdef CONFIG_X86_32
#define UINTN U32
#else
#define UINTN U64
#endif
#else
#include <stdint.h>
#if __WORDSIZE == 32
#define UINTN U32
#elif __WORDSIZE == 64
#define UINTN U64
#else
#error Unsupported __WORDSIZE
#endif
#endif
typedef struct {
U32 data1;
U16 data2;
U16 data3;
U8 data4[8];
} __attribute__ ((__packed__)) GUID;
#ifndef GUID0
#define GUID0 {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0} }
#endif
typedef U64 GUEST_PHYSICAL_ADDRESS;
#define MEMSET(ptr, val, len) memset(ptr, val, len)
#define MEMCMP(m1, m2, len) memcmp(m1, m2, len)
#define STRLEN(s) ((UINTN)strlen((const char *)s))
#define STRCPY(d, s) (strcpy((char *)d, (const char *)s))
#define INLINE inline
#define OFFSETOF offsetof
#ifdef __KERNEL__
#define MEMORYBARRIER mb()
#define MEMCPY(dest, src, len) memcpy(dest, src, len)
#define CHANNEL_GUID_MISMATCH(chType, chName, field, expected, actual, fil, \
lin, logCtx) \
do { \
char s1[50], s2[50], s3[50]; \
pr_err("Channel mismatch on channel=%s(%s) field=%s expected=%s actual=%s @%s:%d\n", \
chName, GUID_format2(&chType, s1), field, \
GUID_format2(&expected, s2), GUID_format2(&actual, s3), \
fil, lin); \
} while (0)
#define CHANNEL_U32_MISMATCH(chType, chName, field, expected, actual, fil, \
lin, logCtx) \
do { \
char s1[50]; \
pr_err("Channel mismatch on channel=%s(%s) field=%s expected=0x%-8.8lx actual=0x%-8.8lx @%s:%d\n", \
chName, GUID_format2(&chType, s1), field, \
(unsigned long)expected, (unsigned long)actual, \
fil, lin); \
} while (0)
#define CHANNEL_U64_MISMATCH(chType, chName, field, expected, actual, fil, \
lin, logCtx) \
do { \
char s1[50]; \
pr_err("Channel mismatch on channel=%s(%s) field=%s expected=0x%-8.8Lx actual=0x%-8.8Lx @%s:%d\n", \
chName, GUID_format2(&chType, s1), field, \
(unsigned long long)expected, \
(unsigned long long)actual, \
fil, lin); \
} while (0)
#define UltraLogEvent(logCtx, EventId, Severity, SubsystemMask, pFunctionName, \
LineNumber, Str, args...) \
pr_info(Str, ## args)
#else
#define MEMCPY(dest, src, len) memcpy(dest, src, len)
#define MEMORYBARRIER mb()
#define CHANNEL_GUID_MISMATCH(chType, chName, field, expected, actual, fil, \
lin, logCtx) \
do { \
char s1[50], s2[50], s3[50]; \
syslog(LOG_USER | LOG_ERR, \
"Channel mismatch on channel=%s(%s) field=%s expected=%s actual=%s @%s:%d", \
chName, GUID_format2(&chType, s1), field, \
GUID_format2(&expected, s2), GUID_format2(&actual, s3), \
fil, lin); \
} while (0)
#define CHANNEL_U32_MISMATCH(chType, chName, field, expected, actual, fil, \
lin, logCtx) \
do { \
char s1[50]; \
syslog(LOG_USER | LOG_ERR, \
"Channel mismatch on channel=%s(%s) field=%s expected=0x%-8.8lx actual=0x%-8.8lx @%s:%d", \
chName, GUID_format2(&chType, s1), field, \
(unsigned long)expected, (unsigned long)actual, \
fil, lin); \
} while (0)
#define CHANNEL_U64_MISMATCH(chType, chName, field, expected, actual, fil, \
lin, logCtx) \
do { \
char s1[50]; \
syslog(LOG_USER | LOG_ERR, \
"Channel mismatch on channel=%s(%s) field=%s expected=0x%-8.8Lx actual=0x%-8.8Lx @%s:%d", \
chName, GUID_format2(&chType, s1), field, \
(unsigned long long)expected, \
(unsigned long long)actual, \
fil, lin); \
} while (0)
#define UltraLogEvent(logCtx, EventId, Severity, SubsystemMask, pFunctionName, \
LineNumber, Str, args...) \
syslog(LOG_USER | LOG_INFO, Str, ## args)
#endif
#define VolatileBarrier() MEMORYBARRIER
#endif
#include "guidutils.h"
/* Copyright © 2010 - 2013 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.
*/
/* guidutils.h
*
* These are GUID manipulation inlines that can be used from either
* kernel-mode or user-mode.
*
*/
#ifndef __GUIDUTILS_H__
#define __GUIDUTILS_H__
#ifdef __KERNEL__
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/ctype.h>
#define GUID_STRTOUL kstrtoul
#else
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define GUID_STRTOUL strtoul
#endif
static inline char *
GUID_format1(const GUID *guid, char *s)
{
sprintf(s, "{%-8.8lx-%-4.4x-%-4.4x-%-2.2x%-2.2x%-2.2x%-2.2x%-2.2x%-2.2x%-2.2x%-2.2x}",
(ulong) guid->data1,
guid->data2,
guid->data3,
guid->data4[0],
guid->data4[1],
guid->data4[2],
guid->data4[3],
guid->data4[4], guid->data4[5], guid->data4[6], guid->data4[7]);
return s;
}
/** Format a GUID in Microsoft's 'what in the world were they thinking'
* format.
*/
static inline char *
GUID_format2(const GUID *guid, char *s)
{
sprintf(s, "{%-8.8lx-%-4.4x-%-4.4x-%-2.2x%-2.2x-%-2.2x%-2.2x%-2.2x%-2.2x%-2.2x%-2.2x}",
(ulong) guid->data1,
guid->data2,
guid->data3,
guid->data4[0],
guid->data4[1],
guid->data4[2],
guid->data4[3],
guid->data4[4], guid->data4[5], guid->data4[6], guid->data4[7]);
return s;
}
/**
* Like GUID_format2 but without the curly braces and the
* hex digits in upper case
*/
static inline char *
GUID_format3(const GUID *guid, char *s)
{
sprintf(s, "%-8.8lX-%-4.4X-%-4.4X-%-2.2X%-2.2X-%-2.2X%-2.2X%-2.2X%-2.2X%-2.2X%-2.2X",
(ulong) guid->data1,
guid->data2,
guid->data3,
guid->data4[0],
guid->data4[1],
guid->data4[2],
guid->data4[3],
guid->data4[4], guid->data4[5], guid->data4[6], guid->data4[7]);
return s;
}
/** Parse a guid string in any of these forms:
* {11111111-2222-3333-4455-66778899aabb}
* {11111111-2222-3333-445566778899aabb}
* 11111111-2222-3333-4455-66778899aabb
* 11111111-2222-3333-445566778899aabb
*/
static inline GUID
GUID_scan(U8 *p)
{
GUID guid = GUID0;
U8 x[33];
int count = 0;
int c, i = 0;
U8 cdata1[9];
U8 cdata2[5];
U8 cdata3[5];
U8 cdata4[3];
int dashcount = 0;
int brace = 0;
unsigned long uldata;
if (!p)
return guid;
if (*p == '{') {
p++;
brace = 1;
}
while (count < 32) {
if (*p == '}')
return guid;
if (*p == '\0')
return guid;
c = toupper(*p);
p++;
if (c == '-') {
switch (dashcount) {
case 0:
if (i != 8)
return guid;
break;
case 1:
if (i != 4)
return guid;
break;
case 2:
if (i != 4)
return guid;
break;
case 3:
if (i != 4)
return guid;
break;
default:
return guid;
}
dashcount++;
i = 0;
continue;
}
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'))
i++;
else
return guid;
x[count++] = c;
}
x[count] = '\0';
if (brace) {
if (*p == '}')
p++;
else
return guid;
}
if (dashcount == 3 || dashcount == 4)
;
else
return guid;
memset(cdata1, 0, sizeof(cdata1));
memset(cdata2, 0, sizeof(cdata2));
memset(cdata3, 0, sizeof(cdata3));
memset(cdata4, 0, sizeof(cdata4));
memcpy(cdata1, x + 0, 8);
memcpy(cdata2, x + 8, 4);
memcpy(cdata3, x + 12, 4);
if (GUID_STRTOUL((char *) cdata1, 16, &uldata) == 0)
guid.data1 = (U32)uldata;
if (GUID_STRTOUL((char *) cdata2, 16, &uldata) == 0)
guid.data2 = (U16)uldata;
if (GUID_STRTOUL((char *) cdata3, 16, &uldata) == 0)
guid.data3 = (U16)uldata;
for (i = 0; i < 8; i++) {
memcpy(cdata4, x + 16 + (i * 2), 2);
if (GUID_STRTOUL((char *) cdata4, 16, &uldata) == 0)
guid.data4[i] = (U8) uldata;
}
return guid;
}
static inline char *
GUID_sanitize(char *inputGuidStr, char *outputGuidStr)
{
GUID g;
GUID guid0 = GUID0;
*outputGuidStr = '\0';
g = GUID_scan((U8 *) inputGuidStr);
if (memcmp(&g, &guid0, sizeof(GUID)) == 0)
return outputGuidStr; /* bad GUID format */
return GUID_format1(&g, outputGuidStr);
}
#endif
#
# Unisys visorchannel configuration
#
config UNISYS_VISORCHANNEL
tristate "Unisys visorchannel driver"
depends on UNISYSSPAR && UNISYS_VISORUTIL
---help---
If you say Y here, you will enable the Unisys visorchannel driver.
#
# Makefile for Unisys visorchannel
#
obj-$(CONFIG_UNISYS_VISORCHANNEL) += visorchannel.o
visorchannel-y := visorchannel_main.o visorchannel_funcs.o
ccflags-y += -Idrivers/staging/unisys/include
ccflags-y += -Idrivers/staging/unisys/common-spar/include
ccflags-y += -Idrivers/staging/unisys/common-spar/include/channels
ccflags-y += -Idrivers/staging/unisys/visorutil
ccflags-y += -DCONFIG_SPAR_GUEST -DGUESTDRIVERBUILD -DNOAUTOVERSION
/* globals.h
*
* Copyright © 2010 - 2013 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 __VISORCHANNEL_GLOBALS_H__
#define __VISORCHANNEL_GLOBALS_H__
#include "uniklog.h"
#include "timskmod.h"
#include "memregion.h"
#include "version.h"
#define MYDRVNAME "visorchannel"
#endif
/* visorchannel.h
*
* Copyright 2010 - 2013 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 __VISORCHANNEL_H__
#define __VISORCHANNEL_H__
#include "commontypes.h"
#include "memregion.h"
#include "channel.h"
#ifndef HOSTADDRESS
#define HOSTADDRESS U64
#endif
#ifndef BOOL
#define BOOL int
#endif
/* VISORCHANNEL is an opaque structure to users.
* Fields are declared only in the implementation .c files.
*/
typedef struct VISORCHANNEL_Tag VISORCHANNEL;
/* Note that for visorchannel_create() and visorchannel_create_overlapped(),
* <channelBytes> and <guid> arguments may be 0 if we are a channel CLIENT.
* In this case, the values can simply be read from the channel header.
*/
VISORCHANNEL *visorchannel_create(HOSTADDRESS physaddr,
ulong channelBytes, GUID guid);
VISORCHANNEL *visorchannel_create_overlapped(ulong channelBytes,
VISORCHANNEL *parent, ulong off,
GUID guid);
VISORCHANNEL *visorchannel_create_with_lock(HOSTADDRESS physaddr,
ulong channelBytes, GUID guid);
VISORCHANNEL *visorchannel_create_overlapped_with_lock(ulong channelBytes,
VISORCHANNEL *parent,
ulong off, GUID guid);
void visorchannel_destroy(VISORCHANNEL *channel);
int visorchannel_read(VISORCHANNEL *channel, ulong offset,
void *local, ulong nbytes);
int visorchannel_write(VISORCHANNEL *channel, ulong offset,
void *local, ulong nbytes);
int visorchannel_clear(VISORCHANNEL *channel, ulong offset,
U8 ch, ulong nbytes);
BOOL visorchannel_signalremove(VISORCHANNEL *channel, U32 queue, void *msg);
BOOL visorchannel_signalinsert(VISORCHANNEL *channel, U32 queue, void *msg);
int visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, U32 queue);
int visorchannel_signalqueue_max_slots(VISORCHANNEL *channel, U32 queue);
HOSTADDRESS visorchannel_get_physaddr(VISORCHANNEL *channel);
ulong visorchannel_get_nbytes(VISORCHANNEL *channel);
char *visorchannel_id(VISORCHANNEL *channel, char *s);
char *visorchannel_zoneid(VISORCHANNEL *channel, char *s);
U64 visorchannel_get_clientpartition(VISORCHANNEL *channel);
GUID visorchannel_get_GUID(VISORCHANNEL *channel);
MEMREGION *visorchannel_get_memregion(VISORCHANNEL *channel);
char *visorchannel_GUID_id(GUID *guid, char *s);
void visorchannel_debug(VISORCHANNEL *channel, int nQueues,
struct seq_file *seq, U32 off);
void visorchannel_dump_section(VISORCHANNEL *chan, char *s,
int off, int len, struct seq_file *seq);
void *visorchannel_get_header(VISORCHANNEL *channel);
#define VISORCHANNEL_CHANGE_SERVER_STATE(chan, chanId, newstate) \
do { \
U8 *p = (U8 *)visorchannel_get_header(chan); \
if (p) { \
ULTRA_CHANNEL_SERVER_TRANSITION(p, chanId, SrvState, \
newstate, logCtx); \
visorchannel_write \
(chan, \
offsetof(ULTRA_CHANNEL_PROTOCOL, SrvState), \
p + \
offsetof(ULTRA_CHANNEL_PROTOCOL, SrvState), \
sizeof(U32)); \
} \
} while (0)
#define VISORCHANNEL_CHANGE_CLIENT_STATE(chan, chanId, newstate) \
do { \
U8 *p = (U8 *)visorchannel_get_header(chan); \
if (p) { \
ULTRA_CHANNEL_CLIENT_TRANSITION(p, chanId, CliStateOS, \
newstate, logCtx); \
visorchannel_write \
(chan, \
offsetof(ULTRA_CHANNEL_PROTOCOL, CliStateOS), \
p + \
offsetof(ULTRA_CHANNEL_PROTOCOL, CliStateOS), \
sizeof(U32)); \
} \
} while (0)
#endif
This diff is collapsed.
/* visorchannel_main.c
*
* Copyright 2010 - 2013 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.
*/
/*
* This is a module "wrapper" around visorchannel_funcs.
*/
#include "globals.h"
#include "channel.h"
#include "visorchannel.h"
#include "guidutils.h"
#define MYDRVNAME "visorchannel"
static int __init
visorchannel_init(void)
{
INFODRV("driver version %s loaded", VERSION);
return 0;
}
static void
visorchannel_exit(void)
{
INFODRV("driver unloaded");
}
module_init(visorchannel_init);
module_exit(visorchannel_exit);
MODULE_AUTHOR("Unisys");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Supervisor channel driver for service partition: ver "
VERSION);
MODULE_VERSION(VERSION);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment