[PATCH 037/141] staging: unisys: move parser.[ch] functionality into visorchipset

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Erik Arfvidson <erik.arfvidson@xxxxxxxxxx>

This patch moves includes files and functions from parser.[ch] into
visorchipset.

Signed-off-by: Erik Arfvidson <erik.arfvidson@xxxxxxxxxx>
Signed-off-by: Benjamin Romer <benjamin.romer@xxxxxxxxxx>
---
 drivers/staging/unisys/visorbus/visorbus_main.c    |   2 +-
 drivers/staging/unisys/visorchipset/Makefile       |   2 +-
 drivers/staging/unisys/visorchipset/parser.c       | 430 ---------------------
 drivers/staging/unisys/visorchipset/parser.h       |  45 ---
 drivers/staging/unisys/visorchipset/visorchipset.h |  24 +-
 .../unisys/visorchipset/visorchipset_main.c        | 411 +++++++++++++++++++-
 6 files changed, 432 insertions(+), 482 deletions(-)
 delete mode 100644 drivers/staging/unisys/visorchipset/parser.c
 delete mode 100644 drivers/staging/unisys/visorchipset/parser.h

diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c
index 13a270d..d7ca116 100644
--- a/drivers/staging/unisys/visorbus/visorbus_main.c
+++ b/drivers/staging/unisys/visorbus/visorbus_main.c
@@ -2040,7 +2040,7 @@ visorbus_init(void)
 
 	POSTCODE_LINUX_3(DRIVER_ENTRY_PC, rc, POSTCODE_SEVERITY_INFO);
 	bus_device_info_init(&clientbus_driverinfo,
-			     "clientbus", MYDRVNAME,
+			     "clientbus", "visorbus",
 			     VERSION, NULL);
 
 	/* process module options */
diff --git a/drivers/staging/unisys/visorchipset/Makefile b/drivers/staging/unisys/visorchipset/Makefile
index 6886cb7..e9168d8 100644
--- a/drivers/staging/unisys/visorchipset/Makefile
+++ b/drivers/staging/unisys/visorchipset/Makefile
@@ -4,7 +4,7 @@
 
 obj-$(CONFIG_UNISYS_VISORCHIPSET)	+= visorchipset.o
 
-visorchipset-y := visorchipset_main.o parser.o
+visorchipset-y := visorchipset_main.o
 
 ccflags-y += -Idrivers/staging/unisys/include
 ccflags-y += -Idrivers/staging/unisys/uislib
diff --git a/drivers/staging/unisys/visorchipset/parser.c b/drivers/staging/unisys/visorchipset/parser.c
deleted file mode 100644
index 6ca6da8..0000000
--- a/drivers/staging/unisys/visorchipset/parser.c
+++ /dev/null
@@ -1,430 +0,0 @@
-/* parser.c
- *
- * Copyright (C) 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.
- */
-
-#include "parser.h"
-#include "memregion.h"
-#include "controlvmchannel.h"
-#include <linux/ctype.h>
-#include <linux/mm.h>
-#include <linux/uuid.h>
-
-#define MYDRVNAME "visorchipset_parser"
-#define CURRENT_FILE_PC VISOR_CHIPSET_PC_parser_c
-
-/* We will refuse to allocate more than this many bytes to copy data from
- * incoming payloads.  This serves as a throttling mechanism.
- */
-#define MAX_CONTROLVM_PAYLOAD_BYTES (1024*128)
-static unsigned long controlvm_payload_bytes_buffered;
-
-struct parser_context {
-	unsigned long allocbytes;
-	unsigned long param_bytes;
-	u8 *curr;
-	unsigned long bytes_remaining;
-	bool byte_stream;
-	char data[0];
-};
-
-static struct parser_context *
-parser_init_guts(u64 addr, u32 bytes, bool local,
-		 bool standard_payload_header, bool *retry)
-{
-	int allocbytes = sizeof(struct parser_context) + bytes;
-	struct parser_context *rc = NULL;
-	struct parser_context *ctx = NULL;
-	struct memregion *rgn = NULL;
-	struct spar_controlvm_parameters_header *phdr = NULL;
-
-	if (retry)
-		*retry = false;
-	if (!standard_payload_header)
-		/* alloc and 0 extra byte to ensure payload is
-		 * '\0'-terminated
-		 */
-		allocbytes++;
-	if ((controlvm_payload_bytes_buffered + bytes)
-	    > MAX_CONTROLVM_PAYLOAD_BYTES) {
-		if (retry)
-			*retry = true;
-		rc = NULL;
-		goto cleanup;
-	}
-	ctx = kzalloc(allocbytes, GFP_KERNEL|__GFP_NORETRY);
-	if (!ctx) {
-		if (retry)
-			*retry = true;
-		rc = NULL;
-		goto cleanup;
-	}
-
-	ctx->allocbytes = allocbytes;
-	ctx->param_bytes = bytes;
-	ctx->curr = NULL;
-	ctx->bytes_remaining = 0;
-	ctx->byte_stream = false;
-	if (local) {
-		void *p;
-
-		if (addr > virt_to_phys(high_memory - 1)) {
-			rc = NULL;
-			goto cleanup;
-		}
-		p = __va((unsigned long) (addr));
-		memcpy(ctx->data, p, bytes);
-	} else {
-		rgn = visor_memregion_create(addr, bytes);
-		if (!rgn) {
-			rc = NULL;
-			goto cleanup;
-		}
-		if (visor_memregion_read(rgn, 0, ctx->data, bytes) < 0) {
-			rc = NULL;
-			goto cleanup;
-		}
-	}
-	if (!standard_payload_header) {
-		ctx->byte_stream = true;
-		rc = ctx;
-		goto cleanup;
-	}
-	phdr = (struct spar_controlvm_parameters_header *)(ctx->data);
-	if (phdr->total_length != bytes) {
-		rc = NULL;
-		goto cleanup;
-	}
-	if (phdr->total_length < phdr->header_length) {
-		rc = NULL;
-		goto cleanup;
-	}
-	if (phdr->header_length <
-	    sizeof(struct spar_controlvm_parameters_header)) {
-		rc = NULL;
-		goto cleanup;
-	}
-
-	rc = ctx;
-cleanup:
-	if (rgn) {
-		visor_memregion_destroy(rgn);
-		rgn = NULL;
-	}
-	if (rc) {
-		controlvm_payload_bytes_buffered += ctx->param_bytes;
-	} else {
-		if (ctx) {
-			parser_done(ctx);
-			ctx = NULL;
-		}
-	}
-	return rc;
-}
-
-struct parser_context *
-parser_init(u64 addr, u32 bytes, bool local, bool *retry)
-{
-	return parser_init_guts(addr, bytes, local, true, retry);
-}
-
-/* Call this instead of parser_init() if the payload area consists of just
- * a sequence of bytes, rather than a struct spar_controlvm_parameters_header
- * structures.  Afterwards, you can call parser_simpleString_get() or
- * parser_byteStream_get() to obtain the data.
- */
-struct parser_context *
-parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry)
-{
-	return parser_init_guts(addr, bytes, local, false, retry);
-}
-
-/* Obtain '\0'-terminated copy of string in payload area.
- */
-char *
-parser_simpleString_get(struct parser_context *ctx)
-{
-	if (!ctx->byte_stream)
-		return NULL;
-	return ctx->data;	/* note this IS '\0'-terminated, because of
-				 * the num of bytes we alloc+clear in
-				 * parser_init_byteStream() */
-}
-
-/* Obtain a copy of the buffer in the payload area.
- */
-void *parser_byte_stream_get(struct parser_context *ctx, unsigned long *nbytes)
-{
-	if (!ctx->byte_stream)
-		return NULL;
-	if (nbytes)
-		*nbytes = ctx->param_bytes;
-	return (void *)ctx->data;
-}
-
-uuid_le
-parser_id_get(struct parser_context *ctx)
-{
-	struct spar_controlvm_parameters_header *phdr = NULL;
-
-	if (ctx == NULL)
-		return NULL_UUID_LE;
-	phdr = (struct spar_controlvm_parameters_header *)(ctx->data);
-	return phdr->id;
-}
-
-void
-parser_param_start(struct parser_context *ctx, PARSER_WHICH_STRING which_string)
-{
-	struct spar_controlvm_parameters_header *phdr = NULL;
-
-	if (ctx == NULL)
-		goto Away;
-	phdr = (struct spar_controlvm_parameters_header *)(ctx->data);
-	switch (which_string) {
-	case PARSERSTRING_INITIATOR:
-		ctx->curr = ctx->data + phdr->initiator_offset;
-		ctx->bytes_remaining = phdr->initiator_length;
-		break;
-	case PARSERSTRING_TARGET:
-		ctx->curr = ctx->data + phdr->target_offset;
-		ctx->bytes_remaining = phdr->target_length;
-		break;
-	case PARSERSTRING_CONNECTION:
-		ctx->curr = ctx->data + phdr->connection_offset;
-		ctx->bytes_remaining = phdr->connection_length;
-		break;
-	case PARSERSTRING_NAME:
-		ctx->curr = ctx->data + phdr->name_offset;
-		ctx->bytes_remaining = phdr->name_length;
-		break;
-	default:
-		break;
-	}
-
-Away:
-	return;
-}
-
-void
-parser_done(struct parser_context *ctx)
-{
-	if (!ctx)
-		return;
-	controlvm_payload_bytes_buffered -= ctx->param_bytes;
-	kfree(ctx);
-}
-
-/** Return length of string not counting trailing spaces. */
-static int
-string_length_no_trail(char *s, int len)
-{
-	int i = len - 1;
-
-	while (i >= 0) {
-		if (!isspace(s[i]))
-			return i + 1;
-		i--;
-	}
-	return 0;
-}
-
-/** Grab the next name and value out of the parameter buffer.
- *  The entire parameter buffer looks like this:
- *      <name>=<value>\0
- *      <name>=<value>\0
- *      ...
- *      \0
- *  If successful, the next <name> value is returned within the supplied
- *  <nam> buffer (the value is always upper-cased), and the corresponding
- *  <value> is returned within a kmalloc()ed buffer, whose pointer is
- *  provided as the return value of this function.
- *  (The total number of bytes allocated is strlen(<value>)+1.)
- *
- *  NULL is returned to indicate failure, which can occur for several reasons:
- *  - all <name>=<value> pairs have already been processed
- *  - bad parameter
- *  - parameter buffer ends prematurely (couldn't find an '=' or '\0' within
- *    the confines of the parameter buffer)
- *  - the <nam> buffer is not large enough to hold the <name> of the next
- *    parameter
- */
-void *
-parser_param_get(struct parser_context *ctx, char *nam, int namesize)
-{
-	u8 *pscan, *pnam = nam;
-	unsigned long nscan;
-	int value_length = -1, orig_value_length = -1;
-	void *value = NULL;
-	int i;
-	int closing_quote = 0;
-
-	if (!ctx)
-		return NULL;
-	pscan = ctx->curr;
-	nscan = ctx->bytes_remaining;
-	if (nscan == 0)
-		return NULL;
-	if (*pscan == '\0')
-		/*  This is the normal return point after you have processed
-		 *  all of the <name>=<value> pairs in a syntactically-valid
-		 *  parameter buffer.
-		 */
-		return NULL;
-
-	/* skip whitespace */
-	while (isspace(*pscan)) {
-		pscan++;
-		nscan--;
-		if (nscan == 0)
-			return NULL;
-	}
-
-	while (*pscan != ':') {
-		if (namesize <= 0)
-			return NULL;
-		*pnam = toupper(*pscan);
-		pnam++;
-		namesize--;
-		pscan++;
-		nscan--;
-		if (nscan == 0)
-			return NULL;
-	}
-	if (namesize <= 0)
-		return NULL;
-	*pnam = '\0';
-	nam[string_length_no_trail(nam, strlen(nam))] = '\0';
-
-	/* point to char immediately after ":" in "<name>:<value>" */
-	pscan++;
-	nscan--;
-	/* skip whitespace */
-	while (isspace(*pscan)) {
-		pscan++;
-		nscan--;
-		if (nscan == 0)
-			return NULL;
-	}
-	if (nscan == 0)
-		return NULL;
-	if (*pscan == '\'' || *pscan == '"') {
-		closing_quote = *pscan;
-		pscan++;
-		nscan--;
-		if (nscan == 0)
-			return NULL;
-	}
-
-	/* look for a separator character, terminator character, or
-	 * end of data
-	 */
-	for (i = 0, value_length = -1; i < nscan; i++) {
-		if (closing_quote) {
-			if (pscan[i] == '\0')
-				return NULL;
-			if (pscan[i] == closing_quote) {
-				value_length = i;
-				break;
-			}
-		} else
-		    if (pscan[i] == ',' || pscan[i] == ';'
-			|| pscan[i] == '\0') {
-			value_length = i;
-			break;
-		}
-	}
-	if (value_length < 0) {
-		if (closing_quote)
-			return NULL;
-		value_length = nscan;
-	}
-	orig_value_length = value_length;
-	if (closing_quote == 0)
-		value_length = string_length_no_trail(pscan, orig_value_length);
-	value = kmalloc(value_length + 1, GFP_KERNEL|__GFP_NORETRY);
-	if (value == NULL)
-		return NULL;
-	memcpy(value, pscan, value_length);
-	((u8 *) (value))[value_length] = '\0';
-
-	pscan += orig_value_length;
-	nscan -= orig_value_length;
-
-	/* skip past separator or closing quote */
-	if (nscan > 0) {
-		if (*pscan != '\0') {
-			pscan++;
-			nscan--;
-		}
-	}
-
-	if (closing_quote && (nscan > 0)) {
-		/* we still need to skip around the real separator if present */
-		/* first, skip whitespace */
-		while (isspace(*pscan)) {
-			pscan++;
-			nscan--;
-			if (nscan == 0)
-				break;
-		}
-		if (nscan > 0) {
-			if (*pscan == ',' || *pscan == ';') {
-				pscan++;
-				nscan--;
-			} else if (*pscan != '\0') {
-				kfree(value);
-				value = NULL;
-				return NULL;
-			}
-		}
-	}
-	ctx->curr = pscan;
-	ctx->bytes_remaining = nscan;
-	return value;
-}
-
-void *
-parser_string_get(struct parser_context *ctx)
-{
-	u8 *pscan;
-	unsigned long nscan;
-	int value_length = -1;
-	void *value = NULL;
-	int i;
-
-	if (!ctx)
-		return NULL;
-	pscan = ctx->curr;
-	nscan = ctx->bytes_remaining;
-	if (nscan == 0)
-		return NULL;
-	if (!pscan)
-		return NULL;
-	for (i = 0, value_length = -1; i < nscan; i++)
-		if (pscan[i] == '\0') {
-			value_length = i;
-			break;
-		}
-	if (value_length < 0)	/* '\0' was not included in the length */
-		value_length = nscan;
-	value = kmalloc(value_length + 1, GFP_KERNEL|__GFP_NORETRY);
-	if (value == NULL)
-		return NULL;
-	if (value_length > 0)
-		memcpy(value, pscan, value_length);
-	((u8 *) (value))[value_length] = '\0';
-	return value;
-}
diff --git a/drivers/staging/unisys/visorchipset/parser.h b/drivers/staging/unisys/visorchipset/parser.h
deleted file mode 100644
index 3fe17c0..0000000
--- a/drivers/staging/unisys/visorchipset/parser.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* parser.h
- *
- * Copyright (C) 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 __PARSER_H__
-#define __PARSER_H__
-
-#include <linux/uuid.h>
-
-#include "channel.h"
-
-typedef enum {
-	PARSERSTRING_INITIATOR,
-	PARSERSTRING_TARGET,
-	PARSERSTRING_CONNECTION,
-	PARSERSTRING_NAME,
-} PARSER_WHICH_STRING;
-
-struct parser_context *parser_init(u64 addr, u32 bytes, bool isLocal,
-				   bool *tryAgain);
-struct parser_context *parser_init_byte_stream(u64 addr, u32 bytes, bool local,
-				       bool *retry);
-void parser_param_start(struct parser_context *ctx,
-			PARSER_WHICH_STRING which_string);
-void *parser_param_get(struct parser_context *ctx, char *nam, int namesize);
-void *parser_string_get(struct parser_context *ctx);
-uuid_le parser_id_get(struct parser_context *ctx);
-char *parser_simpleString_get(struct parser_context *ctx);
-void *parser_byte_stream_get(struct parser_context *ctx, unsigned long *nbytes);
-void parser_done(struct parser_context *ctx);
-
-#endif
diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h
index 93763ee..264a3e9 100644
--- a/drivers/staging/unisys/visorchipset/visorchipset.h
+++ b/drivers/staging/unisys/visorchipset/visorchipset.h
@@ -22,17 +22,37 @@
 
 #include "channel.h"
 #include "controlvmchannel.h"
-#include "parser.h"
 #include "procobjecttree.h"
 #include "vbusdeviceinfo.h"
 #include "vbushelper.h"
 
-#define MYDRVNAME "visorchipset"
 #define VISORCHIPSET_MMAP_CONTROLCHANOFFSET	0x00000000
 
 /** Describes the state from the perspective of which controlvm messages have
  *  been received for a bus or device.
  */
+
+enum PARSER_WHICH_STRING {
+	PARSERSTRING_INITIATOR,
+	PARSERSTRING_TARGET,
+	PARSERSTRING_CONNECTION,
+	PARSERSTRING_NAME,
+};
+
+struct visorchannel;
+struct parser_context *parser_init(u64 addr, u32 bytes, bool isLocal,
+				   bool *tryAgain);
+struct parser_context *parser_init_byte_stream(u64 addr, u32 bytes, bool local,
+				       bool *retry);
+void parser_param_start(struct parser_context *ctx,
+			PARSER_WHICH_STRING which_string);
+void *parser_param_get(struct parser_context *ctx, char *nam, int namesize);
+void *parser_string_get(struct parser_context *ctx);
+uuid_le parser_id_get(struct parser_context *ctx);
+char *parser_simpleString_get(struct parser_context *ctx);
+void *parser_byte_stream_get(struct parser_context *ctx, unsigned long *nbytes);
+void parser_done(struct parser_context *ctx);
+
 struct visorchipset_state {
 	u32 created:1;
 	u32 attached:1;
diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c
index d5bd1a1..dc9f1dc 100644
--- a/drivers/staging/unisys/visorchipset/visorchipset_main.c
+++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c
@@ -15,16 +15,19 @@
  * details.
  */
 
+#include "memregion.h"
+#include "controlvmchannel.h"
 #include "version.h"
 #include "procobjecttree.h"
 #include "visorbus.h"
 #include "periodic_work.h"
-#include "parser.h"
 #include "uisutils.h"
 #include "controlvmcompletionstatus.h"
 #include "guestlinuxdebug.h"
 #include "visorchipset.h"
 
+
+#include <linux/ctype.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/nls.h>
@@ -45,6 +48,7 @@
 #define POLLJIFFIES_CONTROLVMCHANNEL_FAST   1
 #define POLLJIFFIES_CONTROLVMCHANNEL_SLOW 100
 
+#define MAX_CONTROLVM_PAYLOAD_BYTES (1024*128)
 /*
  * Module parameters
  */
@@ -57,6 +61,7 @@ static int visorchipset_clientregwait = 1;	/* default is on */
 static int visorchipset_testteardown;
 static int visorchipset_disable_controlvm;
 static int visorchipset_holdchipsetready;
+static unsigned long controlvm_payload_bytes_buffered;
 
 static int
 visorchipset_open(struct inode *inode, struct file *file)
@@ -89,6 +94,15 @@ static int clientregistered;
 #define MAX_CHIPSET_EVENTS 2
 static u8 chipset_events[MAX_CHIPSET_EVENTS] = { 0, 0 };
 
+struct parser_context {
+	unsigned long allocbytes;
+	unsigned long param_bytes;
+	u8 *curr;
+	unsigned long bytes_remaining;
+	bool byte_stream;
+	char data[0];
+};
+
 static struct delayed_work periodic_controlvm_work;
 static struct workqueue_struct *periodic_controlvm_workqueue;
 static DEFINE_SEMAPHORE(notifier_lock);
@@ -367,6 +381,397 @@ static void controlvm_respond_physdev_changestate(
 		struct controlvm_message_header *msg_hdr, int response,
 		struct spar_segment_state state);
 
+
+static struct parser_context *
+parser_init_guts(u64 addr, u32 bytes, bool local,
+		 bool standard_payload_header, bool *retry)
+{
+	int allocbytes = sizeof(struct parser_context) + bytes;
+	struct parser_context *rc = NULL;
+	struct parser_context *ctx = NULL;
+	struct memregion *rgn = NULL;
+	struct spar_controlvm_parameters_header *phdr = NULL;
+
+	if (retry)
+		*retry = false;
+	if (!standard_payload_header)
+		/* alloc and 0 extra byte to ensure payload is
+		 * '\0'-terminated
+		 */
+		allocbytes++;
+	if ((controlvm_payload_bytes_buffered + bytes)
+	    > MAX_CONTROLVM_PAYLOAD_BYTES) {
+		if (retry)
+			*retry = true;
+		rc = NULL;
+		goto cleanup;
+	}
+	ctx = kzalloc(allocbytes, GFP_KERNEL|__GFP_NORETRY);
+	if (!ctx) {
+		if (retry)
+			*retry = true;
+		rc = NULL;
+		goto cleanup;
+	}
+
+	ctx->allocbytes = allocbytes;
+	ctx->param_bytes = bytes;
+	ctx->curr = NULL;
+	ctx->bytes_remaining = 0;
+	ctx->byte_stream = false;
+	if (local) {
+		void *p;
+
+		if (addr > virt_to_phys(high_memory - 1)) {
+			rc = NULL;
+			goto cleanup;
+		}
+		p = __va((unsigned long) (addr));
+		memcpy(ctx->data, p, bytes);
+	} else {
+		rgn = visor_memregion_create(addr, bytes);
+		if (!rgn) {
+			rc = NULL;
+			goto cleanup;
+		}
+		if (visor_memregion_read(rgn, 0, ctx->data, bytes) < 0) {
+			rc = NULL;
+			goto cleanup;
+		}
+	}
+	if (!standard_payload_header) {
+		ctx->byte_stream = true;
+		rc = ctx;
+		goto cleanup;
+	}
+	phdr = (struct spar_controlvm_parameters_header *)(ctx->data);
+	if (phdr->total_length != bytes) {
+		rc = NULL;
+		goto cleanup;
+	}
+	if (phdr->total_length < phdr->header_length) {
+		rc = NULL;
+		goto cleanup;
+	}
+	if (phdr->header_length <
+	    sizeof(struct spar_controlvm_parameters_header)) {
+		rc = NULL;
+		goto cleanup;
+	}
+
+	rc = ctx;
+cleanup:
+	if (rgn) {
+		visor_memregion_destroy(rgn);
+		rgn = NULL;
+	}
+	if (rc) {
+		controlvm_payload_bytes_buffered += ctx->param_bytes;
+	} else {
+		if (ctx) {
+			parser_done(ctx);
+			ctx = NULL;
+		}
+	}
+	return rc;
+}
+
+struct parser_context *
+parser_init(u64 addr, u32 bytes, bool local, bool *retry)
+{
+	return parser_init_guts(addr, bytes, local, true, retry);
+}
+
+/* Call this instead of parser_init() if the payload area consists of just
+ * a sequence of bytes, rather than a struct spar_controlvm_parameters_header
+ * structures.  Afterwards, you can call parser_simpleString_get() or
+ * parser_byteStream_get() to obtain the data.
+ */
+struct parser_context *
+parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry)
+{
+	return parser_init_guts(addr, bytes, local, false, retry);
+}
+
+/* Obtain '\0'-terminated copy of string in payload area.
+ */
+char *
+parser_simpleString_get(struct parser_context *ctx)
+{
+	if (!ctx->byte_stream)
+		return NULL;
+	return ctx->data;	/* note this IS '\0'-terminated, because of
+				 * the num of bytes we alloc+clear in
+				 * parser_init_byteStream() */
+}
+
+/* Obtain a copy of the buffer in the payload area.
+ */
+void *parser_byte_stream_get(struct parser_context *ctx, unsigned long *nbytes)
+{
+	if (!ctx->byte_stream)
+		return NULL;
+	if (nbytes)
+		*nbytes = ctx->param_bytes;
+	return (void *)ctx->data;
+}
+
+uuid_le
+parser_id_get(struct parser_context *ctx)
+{
+	struct spar_controlvm_parameters_header *phdr = NULL;
+
+	if (ctx == NULL)
+		return NULL_UUID_LE;
+	phdr = (struct spar_controlvm_parameters_header *)(ctx->data);
+	return phdr->id;
+}
+
+void
+parser_param_start(struct parser_context *ctx, PARSER_WHICH_STRING which_string)
+{
+	struct spar_controlvm_parameters_header *phdr = NULL;
+
+	if (ctx == NULL)
+		goto Away;
+	phdr = (struct spar_controlvm_parameters_header *)(ctx->data);
+	switch (which_string) {
+	case PARSERSTRING_INITIATOR:
+		ctx->curr = ctx->data + phdr->initiator_offset;
+		ctx->bytes_remaining = phdr->initiator_length;
+		break;
+	case PARSERSTRING_TARGET:
+		ctx->curr = ctx->data + phdr->target_offset;
+		ctx->bytes_remaining = phdr->target_length;
+		break;
+	case PARSERSTRING_CONNECTION:
+		ctx->curr = ctx->data + phdr->connection_offset;
+		ctx->bytes_remaining = phdr->connection_length;
+		break;
+	case PARSERSTRING_NAME:
+		ctx->curr = ctx->data + phdr->name_offset;
+		ctx->bytes_remaining = phdr->name_length;
+		break;
+	default:
+		break;
+	}
+
+Away:
+	return;
+}
+
+void
+parser_done(struct parser_context *ctx)
+{
+	if (!ctx)
+		return;
+	controlvm_payload_bytes_buffered -= ctx->param_bytes;
+	kfree(ctx);
+}
+
+/** Return length of string not counting trailing spaces. */
+static int
+string_length_no_trail(char *s, int len)
+{
+	int i = len - 1;
+
+	while (i >= 0) {
+		if (!isspace(s[i]))
+			return i + 1;
+		i--;
+	}
+	return 0;
+}
+
+/** Grab the next name and value out of the parameter buffer.
+ *  The entire parameter buffer looks like this:
+ *      <name>=<value>\0
+ *      <name>=<value>\0
+ *      ...
+ *      \0
+ *  If successful, the next <name> value is returned within the supplied
+ *  <nam> buffer (the value is always upper-cased), and the corresponding
+ *  <value> is returned within a kmalloc()ed buffer, whose pointer is
+ *  provided as the return value of this function.
+ *  (The total number of bytes allocated is strlen(<value>)+1.)
+ *
+ *  NULL is returned to indicate failure, which can occur for several reasons:
+ *  - all <name>=<value> pairs have already been processed
+ *  - bad parameter
+ *  - parameter buffer ends prematurely (couldn't find an '=' or '\0' within
+ *    the confines of the parameter buffer)
+ *  - the <nam> buffer is not large enough to hold the <name> of the next
+ *    parameter
+ */
+void *
+parser_param_get(struct parser_context *ctx, char *nam, int namesize)
+{
+	u8 *pscan, *pnam = nam;
+	unsigned long nscan;
+	int value_length = -1, orig_value_length = -1;
+	void *value = NULL;
+	int i;
+	int closing_quote = 0;
+
+	if (!ctx)
+		return NULL;
+	pscan = ctx->curr;
+	nscan = ctx->bytes_remaining;
+	if (nscan == 0)
+		return NULL;
+	if (*pscan == '\0')
+		/*  This is the normal return point after you have processed
+		 *  all of the <name>=<value> pairs in a syntactically-valid
+		 *  parameter buffer.
+		 */
+		return NULL;
+
+	/* skip whitespace */
+	while (isspace(*pscan)) {
+		pscan++;
+		nscan--;
+		if (nscan == 0)
+			return NULL;
+	}
+
+	while (*pscan != ':') {
+		if (namesize <= 0)
+			return NULL;
+		*pnam = toupper(*pscan);
+		pnam++;
+		namesize--;
+		pscan++;
+		nscan--;
+		if (nscan == 0)
+			return NULL;
+	}
+	if (namesize <= 0)
+		return NULL;
+	*pnam = '\0';
+	nam[string_length_no_trail(nam, strlen(nam))] = '\0';
+
+	/* point to char immediately after ":" in "<name>:<value>" */
+	pscan++;
+	nscan--;
+	/* skip whitespace */
+	while (isspace(*pscan)) {
+		pscan++;
+		nscan--;
+		if (nscan == 0)
+			return NULL;
+	}
+	if (nscan == 0)
+		return NULL;
+	if (*pscan == '\'' || *pscan == '"') {
+		closing_quote = *pscan;
+		pscan++;
+		nscan--;
+		if (nscan == 0)
+			return NULL;
+	}
+
+	/* look for a separator character, terminator character, or
+	 * end of data
+	 */
+	for (i = 0, value_length = -1; i < nscan; i++) {
+		if (closing_quote) {
+			if (pscan[i] == '\0')
+				return NULL;
+			if (pscan[i] == closing_quote) {
+				value_length = i;
+				break;
+			}
+		} else
+		    if (pscan[i] == ',' || pscan[i] == ';'
+			|| pscan[i] == '\0') {
+			value_length = i;
+			break;
+		}
+	}
+	if (value_length < 0) {
+		if (closing_quote)
+			return NULL;
+		value_length = nscan;
+	}
+	orig_value_length = value_length;
+	if (closing_quote == 0)
+		value_length = string_length_no_trail(pscan, orig_value_length);
+	value = kmalloc(value_length + 1, GFP_KERNEL|__GFP_NORETRY);
+	if (value == NULL)
+		return NULL;
+	memcpy(value, pscan, value_length);
+	((u8 *) (value))[value_length] = '\0';
+
+	pscan += orig_value_length;
+	nscan -= orig_value_length;
+
+	/* skip past separator or closing quote */
+	if (nscan > 0) {
+		if (*pscan != '\0') {
+			pscan++;
+			nscan--;
+		}
+	}
+
+	if (closing_quote && (nscan > 0)) {
+		/* we still need to skip around the real separator if present */
+		/* first, skip whitespace */
+		while (isspace(*pscan)) {
+			pscan++;
+			nscan--;
+			if (nscan == 0)
+				break;
+		}
+		if (nscan > 0) {
+			if (*pscan == ',' || *pscan == ';') {
+				pscan++;
+				nscan--;
+			} else if (*pscan != '\0') {
+				kfree(value);
+				value = NULL;
+				return NULL;
+			}
+		}
+	}
+	ctx->curr = pscan;
+	ctx->bytes_remaining = nscan;
+	return value;
+}
+
+void *
+parser_string_get(struct parser_context *ctx)
+{
+	u8 *pscan;
+	unsigned long nscan;
+	int value_length = -1;
+	void *value = NULL;
+	int i;
+
+	if (!ctx)
+		return NULL;
+	pscan = ctx->curr;
+	nscan = ctx->bytes_remaining;
+	if (nscan == 0)
+		return NULL;
+	if (!pscan)
+		return NULL;
+	for (i = 0, value_length = -1; i < nscan; i++)
+		if (pscan[i] == '\0') {
+			value_length = i;
+			break;
+		}
+	if (value_length < 0)	/* '\0' was not included in the length */
+		value_length = nscan;
+	value = kmalloc(value_length + 1, GFP_KERNEL|__GFP_NORETRY);
+	if (value == NULL)
+		return NULL;
+	if (value_length > 0)
+		memcpy(value, pscan, value_length);
+	((u8 *) (value))[value_length] = '\0';
+	return value;
+}
+
+
 static ssize_t toolaction_show(struct device *dev,
 			       struct device_attribute *attr,
 			       char *buf)
@@ -2274,13 +2679,13 @@ visorchipset_file_init(dev_t major_dev, struct visorchannel **controlvm_channel)
 	cdev_init(&file_cdev, &visorchipset_fops);
 	file_cdev.owner = THIS_MODULE;
 	if (MAJOR(major_dev) == 0) {
-		rc = alloc_chrdev_region(&major_dev, 0, 1, MYDRVNAME);
+		rc = alloc_chrdev_region(&major_dev, 0, 1, "visorchipset");
 		/* dynamic major device number registration required */
 		if (rc < 0)
 			return rc;
 	} else {
 		/* static major device number registration required */
-		rc = register_chrdev_region(major_dev, 1, MYDRVNAME);
+		rc = register_chrdev_region(major_dev, 1, "visorchipset");
 		if (rc < 0)
 			return rc;
 	}
-- 
2.1.4

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel




[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux