summaryrefslogtreecommitdiffstats
path: root/sound/pci/asihpi/hpimsginit.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/asihpi/hpimsginit.c')
-rw-r--r--sound/pci/asihpi/hpimsginit.c120
1 files changed, 120 insertions, 0 deletions
diff --git a/sound/pci/asihpi/hpimsginit.c b/sound/pci/asihpi/hpimsginit.c
new file mode 100644
index 0000000000..a3fdcbf499
--- /dev/null
+++ b/sound/pci/asihpi/hpimsginit.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/******************************************************************************
+
+ AudioScience HPI driver
+ Copyright (C) 1997-2014 AudioScience Inc. <support@audioscience.com>
+
+
+ Hardware Programming Interface (HPI) Utility functions.
+
+ (C) Copyright AudioScience Inc. 2007
+*******************************************************************************/
+
+#include "hpi_internal.h"
+#include "hpimsginit.h"
+#include <linux/nospec.h>
+
+/* The actual message size for each object type */
+static u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT;
+/* The actual response size for each object type */
+static u16 res_size[HPI_OBJ_MAXINDEX + 1] = HPI_RESPONSE_SIZE_BY_OBJECT;
+/* Flag to enable alternate message type for SSX2 bypass. */
+static u16 gwSSX2_bypass;
+
+/** \internal
+ * initialize the HPI message structure
+ */
+static void hpi_init_message(struct hpi_message *phm, u16 object,
+ u16 function)
+{
+ u16 size;
+
+ if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
+ object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1);
+ size = msg_size[object];
+ } else {
+ size = sizeof(*phm);
+ }
+
+ memset(phm, 0, size);
+ phm->size = size;
+
+ if (gwSSX2_bypass)
+ phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE;
+ else
+ phm->type = HPI_TYPE_REQUEST;
+ phm->object = object;
+ phm->function = function;
+ phm->version = 0;
+ phm->adapter_index = HPI_ADAPTER_INDEX_INVALID;
+ /* Expect actual adapter index to be set by caller */
+}
+
+/** \internal
+ * initialize the HPI response structure
+ */
+void hpi_init_response(struct hpi_response *phr, u16 object, u16 function,
+ u16 error)
+{
+ u16 size;
+
+ if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
+ object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1);
+ size = res_size[object];
+ } else {
+ size = sizeof(*phr);
+ }
+
+ memset(phr, 0, sizeof(*phr));
+ phr->size = size;
+ phr->type = HPI_TYPE_RESPONSE;
+ phr->object = object;
+ phr->function = function;
+ phr->error = error;
+ phr->specific_error = 0;
+ phr->version = 0;
+}
+
+void hpi_init_message_response(struct hpi_message *phm,
+ struct hpi_response *phr, u16 object, u16 function)
+{
+ hpi_init_message(phm, object, function);
+ /* default error return if the response is
+ not filled in by the callee */
+ hpi_init_response(phr, object, function,
+ HPI_ERROR_PROCESSING_MESSAGE);
+}
+
+static void hpi_init_messageV1(struct hpi_message_header *phm, u16 size,
+ u16 object, u16 function)
+{
+ memset(phm, 0, size);
+ if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
+ phm->size = size;
+ phm->type = HPI_TYPE_REQUEST;
+ phm->object = object;
+ phm->function = function;
+ phm->version = 1;
+ /* Expect adapter index to be set by caller */
+ }
+}
+
+void hpi_init_responseV1(struct hpi_response_header *phr, u16 size,
+ u16 object, u16 function)
+{
+ (void)object;
+ (void)function;
+ memset(phr, 0, size);
+ phr->size = size;
+ phr->version = 1;
+ phr->type = HPI_TYPE_RESPONSE;
+ phr->error = HPI_ERROR_PROCESSING_MESSAGE;
+}
+
+void hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size,
+ struct hpi_response_header *phr, u16 res_size, u16 object,
+ u16 function)
+{
+ hpi_init_messageV1(phm, msg_size, object, function);
+ hpi_init_responseV1(phr, res_size, object, function);
+}