1 // SPDX-License-Identifier: GPL-2.0-only 2 /****************************************************************************** 3 4 AudioScience HPI driver 5 Copyright (C) 1997-2014 AudioScience Inc. <support@audioscience.com> 6 7 8 Hardware Programming Interface (HPI) Utility functions. 9 10 (C) Copyright AudioScience Inc. 2007 11 *******************************************************************************/ 12 13 #include "hpi_internal.h" 14 #include "hpimsginit.h" 15 #include <linux/nospec.h> 16 17 /* The actual message size for each object type */ 18 static u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT; 19 /* The actual response size for each object type */ 20 static u16 res_size[HPI_OBJ_MAXINDEX + 1] = HPI_RESPONSE_SIZE_BY_OBJECT; 21 /* Flag to enable alternate message type for SSX2 bypass. */ 22 static u16 gwSSX2_bypass; 23 24 /** \internal 25 * initialize the HPI message structure 26 */ 27 static void hpi_init_message(struct hpi_message *phm, u16 object, 28 u16 function) 29 { 30 u16 size; 31 32 if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { 33 object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1); 34 size = msg_size[object]; 35 } else { 36 size = sizeof(*phm); 37 } 38 39 memset(phm, 0, size); 40 phm->size = size; 41 42 if (gwSSX2_bypass) 43 phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE; 44 else 45 phm->type = HPI_TYPE_REQUEST; 46 phm->object = object; 47 phm->function = function; 48 phm->version = 0; 49 phm->adapter_index = HPI_ADAPTER_INDEX_INVALID; 50 /* Expect actual adapter index to be set by caller */ 51 } 52 53 /** \internal 54 * initialize the HPI response structure 55 */ 56 void hpi_init_response(struct hpi_response *phr, u16 object, u16 function, 57 u16 error) 58 { 59 u16 size; 60 61 if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { 62 object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1); 63 size = res_size[object]; 64 } else { 65 size = sizeof(*phr); 66 } 67 68 memset(phr, 0, sizeof(*phr)); 69 phr->size = size; 70 phr->type = HPI_TYPE_RESPONSE; 71 phr->object = object; 72 phr->function = function; 73 phr->error = error; 74 phr->specific_error = 0; 75 phr->version = 0; 76 } 77 78 void hpi_init_message_response(struct hpi_message *phm, 79 struct hpi_response *phr, u16 object, u16 function) 80 { 81 hpi_init_message(phm, object, function); 82 /* default error return if the response is 83 not filled in by the callee */ 84 hpi_init_response(phr, object, function, 85 HPI_ERROR_PROCESSING_MESSAGE); 86 } 87 88 static void hpi_init_messageV1(struct hpi_message_header *phm, u16 size, 89 u16 object, u16 function) 90 { 91 memset(phm, 0, size); 92 if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { 93 phm->size = size; 94 phm->type = HPI_TYPE_REQUEST; 95 phm->object = object; 96 phm->function = function; 97 phm->version = 1; 98 /* Expect adapter index to be set by caller */ 99 } 100 } 101 102 void hpi_init_responseV1(struct hpi_response_header *phr, u16 size, 103 u16 object, u16 function) 104 { 105 (void)object; 106 (void)function; 107 memset(phr, 0, size); 108 phr->size = size; 109 phr->version = 1; 110 phr->type = HPI_TYPE_RESPONSE; 111 phr->error = HPI_ERROR_PROCESSING_MESSAGE; 112 } 113 114 void hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size, 115 struct hpi_response_header *phr, u16 res_size, u16 object, 116 u16 function) 117 { 118 hpi_init_messageV1(phm, msg_size, object, function); 119 hpi_init_responseV1(phr, res_size, object, function); 120 } 121