1 /****************************************************************************** 2 3 AudioScience HPI driver 4 Copyright (C) 1997-2014 AudioScience Inc. <support@audioscience.com> 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of version 2 of the GNU General Public License as 8 published by the Free Software Foundation; 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 19 Hardware Programming Interface (HPI) Utility functions. 20 21 (C) Copyright AudioScience Inc. 2007 22 *******************************************************************************/ 23 24 #include "hpi_internal.h" 25 #include "hpimsginit.h" 26 #include <linux/nospec.h> 27 28 /* The actual message size for each object type */ 29 static u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT; 30 /* The actual response size for each object type */ 31 static u16 res_size[HPI_OBJ_MAXINDEX + 1] = HPI_RESPONSE_SIZE_BY_OBJECT; 32 /* Flag to enable alternate message type for SSX2 bypass. */ 33 static u16 gwSSX2_bypass; 34 35 /** \internal 36 * initialize the HPI message structure 37 */ 38 static void hpi_init_message(struct hpi_message *phm, u16 object, 39 u16 function) 40 { 41 u16 size; 42 43 if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { 44 object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1); 45 size = msg_size[object]; 46 } else { 47 size = sizeof(*phm); 48 } 49 50 memset(phm, 0, size); 51 phm->size = size; 52 53 if (gwSSX2_bypass) 54 phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE; 55 else 56 phm->type = HPI_TYPE_REQUEST; 57 phm->object = object; 58 phm->function = function; 59 phm->version = 0; 60 phm->adapter_index = HPI_ADAPTER_INDEX_INVALID; 61 /* Expect actual adapter index to be set by caller */ 62 } 63 64 /** \internal 65 * initialize the HPI response structure 66 */ 67 void hpi_init_response(struct hpi_response *phr, u16 object, u16 function, 68 u16 error) 69 { 70 u16 size; 71 72 if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { 73 object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1); 74 size = res_size[object]; 75 } else { 76 size = sizeof(*phr); 77 } 78 79 memset(phr, 0, sizeof(*phr)); 80 phr->size = size; 81 phr->type = HPI_TYPE_RESPONSE; 82 phr->object = object; 83 phr->function = function; 84 phr->error = error; 85 phr->specific_error = 0; 86 phr->version = 0; 87 } 88 89 void hpi_init_message_response(struct hpi_message *phm, 90 struct hpi_response *phr, u16 object, u16 function) 91 { 92 hpi_init_message(phm, object, function); 93 /* default error return if the response is 94 not filled in by the callee */ 95 hpi_init_response(phr, object, function, 96 HPI_ERROR_PROCESSING_MESSAGE); 97 } 98 99 static void hpi_init_messageV1(struct hpi_message_header *phm, u16 size, 100 u16 object, u16 function) 101 { 102 memset(phm, 0, size); 103 if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { 104 phm->size = size; 105 phm->type = HPI_TYPE_REQUEST; 106 phm->object = object; 107 phm->function = function; 108 phm->version = 1; 109 /* Expect adapter index to be set by caller */ 110 } 111 } 112 113 void hpi_init_responseV1(struct hpi_response_header *phr, u16 size, 114 u16 object, u16 function) 115 { 116 (void)object; 117 (void)function; 118 memset(phr, 0, size); 119 phr->size = size; 120 phr->version = 1; 121 phr->type = HPI_TYPE_RESPONSE; 122 phr->error = HPI_ERROR_PROCESSING_MESSAGE; 123 } 124 125 void hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size, 126 struct hpi_response_header *phr, u16 res_size, u16 object, 127 u16 function) 128 { 129 hpi_init_messageV1(phm, msg_size, object, function); 130 hpi_init_responseV1(phr, res_size, object, function); 131 } 132