1*07d7fe7bSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2719f82d3SEliot Blennerhassett /****************************************************************************** 3719f82d3SEliot Blennerhassett 4719f82d3SEliot Blennerhassett AudioScience HPI driver 551e6f47dSEliot Blennerhassett Copyright (C) 1997-2014 AudioScience Inc. <support@audioscience.com> 6719f82d3SEliot Blennerhassett 7719f82d3SEliot Blennerhassett 8719f82d3SEliot Blennerhassett Hardware Programming Interface (HPI) Utility functions. 9719f82d3SEliot Blennerhassett 10719f82d3SEliot Blennerhassett (C) Copyright AudioScience Inc. 2007 11719f82d3SEliot Blennerhassett *******************************************************************************/ 12719f82d3SEliot Blennerhassett 13719f82d3SEliot Blennerhassett #include "hpi_internal.h" 14719f82d3SEliot Blennerhassett #include "hpimsginit.h" 15f9d94b57STakashi Iwai #include <linux/nospec.h> 16719f82d3SEliot Blennerhassett 17719f82d3SEliot Blennerhassett /* The actual message size for each object type */ 18719f82d3SEliot Blennerhassett static u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT; 19719f82d3SEliot Blennerhassett /* The actual response size for each object type */ 20719f82d3SEliot Blennerhassett static u16 res_size[HPI_OBJ_MAXINDEX + 1] = HPI_RESPONSE_SIZE_BY_OBJECT; 21719f82d3SEliot Blennerhassett /* Flag to enable alternate message type for SSX2 bypass. */ 22719f82d3SEliot Blennerhassett static u16 gwSSX2_bypass; 23719f82d3SEliot Blennerhassett 24719f82d3SEliot Blennerhassett /** \internal 25719f82d3SEliot Blennerhassett * initialize the HPI message structure 26719f82d3SEliot Blennerhassett */ 27719f82d3SEliot Blennerhassett static void hpi_init_message(struct hpi_message *phm, u16 object, 28719f82d3SEliot Blennerhassett u16 function) 29719f82d3SEliot Blennerhassett { 3051e6f47dSEliot Blennerhassett u16 size; 3151e6f47dSEliot Blennerhassett 32f9d94b57STakashi Iwai if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { 33f9d94b57STakashi Iwai object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1); 3451e6f47dSEliot Blennerhassett size = msg_size[object]; 35f9d94b57STakashi Iwai } else { 3651e6f47dSEliot Blennerhassett size = sizeof(*phm); 37f9d94b57STakashi Iwai } 3851e6f47dSEliot Blennerhassett 3951e6f47dSEliot Blennerhassett memset(phm, 0, size); 4051e6f47dSEliot Blennerhassett phm->size = size; 41719f82d3SEliot Blennerhassett 42719f82d3SEliot Blennerhassett if (gwSSX2_bypass) 43719f82d3SEliot Blennerhassett phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE; 44719f82d3SEliot Blennerhassett else 4582b5774fSEliot Blennerhassett phm->type = HPI_TYPE_REQUEST; 46719f82d3SEliot Blennerhassett phm->object = object; 47719f82d3SEliot Blennerhassett phm->function = function; 48719f82d3SEliot Blennerhassett phm->version = 0; 493285ea10SEliot Blennerhassett phm->adapter_index = HPI_ADAPTER_INDEX_INVALID; 500a1602c0SEliot Blennerhassett /* Expect actual adapter index to be set by caller */ 51719f82d3SEliot Blennerhassett } 52719f82d3SEliot Blennerhassett 53719f82d3SEliot Blennerhassett /** \internal 54719f82d3SEliot Blennerhassett * initialize the HPI response structure 55719f82d3SEliot Blennerhassett */ 56719f82d3SEliot Blennerhassett void hpi_init_response(struct hpi_response *phr, u16 object, u16 function, 57719f82d3SEliot Blennerhassett u16 error) 58719f82d3SEliot Blennerhassett { 5951e6f47dSEliot Blennerhassett u16 size; 6051e6f47dSEliot Blennerhassett 61f9d94b57STakashi Iwai if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { 62f9d94b57STakashi Iwai object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1); 6351e6f47dSEliot Blennerhassett size = res_size[object]; 64f9d94b57STakashi Iwai } else { 6551e6f47dSEliot Blennerhassett size = sizeof(*phr); 66f9d94b57STakashi Iwai } 6751e6f47dSEliot Blennerhassett 6851e6f47dSEliot Blennerhassett memset(phr, 0, sizeof(*phr)); 6951e6f47dSEliot Blennerhassett phr->size = size; 7051e6f47dSEliot Blennerhassett phr->type = HPI_TYPE_RESPONSE; 71719f82d3SEliot Blennerhassett phr->object = object; 72719f82d3SEliot Blennerhassett phr->function = function; 73719f82d3SEliot Blennerhassett phr->error = error; 74719f82d3SEliot Blennerhassett phr->specific_error = 0; 75719f82d3SEliot Blennerhassett phr->version = 0; 76719f82d3SEliot Blennerhassett } 77719f82d3SEliot Blennerhassett 78719f82d3SEliot Blennerhassett void hpi_init_message_response(struct hpi_message *phm, 79719f82d3SEliot Blennerhassett struct hpi_response *phr, u16 object, u16 function) 80719f82d3SEliot Blennerhassett { 81719f82d3SEliot Blennerhassett hpi_init_message(phm, object, function); 82719f82d3SEliot Blennerhassett /* default error return if the response is 83719f82d3SEliot Blennerhassett not filled in by the callee */ 84719f82d3SEliot Blennerhassett hpi_init_response(phr, object, function, 85719f82d3SEliot Blennerhassett HPI_ERROR_PROCESSING_MESSAGE); 86719f82d3SEliot Blennerhassett } 87719f82d3SEliot Blennerhassett 88719f82d3SEliot Blennerhassett static void hpi_init_messageV1(struct hpi_message_header *phm, u16 size, 89719f82d3SEliot Blennerhassett u16 object, u16 function) 90719f82d3SEliot Blennerhassett { 9151e6f47dSEliot Blennerhassett memset(phm, 0, size); 92719f82d3SEliot Blennerhassett if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { 93719f82d3SEliot Blennerhassett phm->size = size; 9482b5774fSEliot Blennerhassett phm->type = HPI_TYPE_REQUEST; 95719f82d3SEliot Blennerhassett phm->object = object; 96719f82d3SEliot Blennerhassett phm->function = function; 97719f82d3SEliot Blennerhassett phm->version = 1; 98719f82d3SEliot Blennerhassett /* Expect adapter index to be set by caller */ 99719f82d3SEliot Blennerhassett } 100719f82d3SEliot Blennerhassett } 101719f82d3SEliot Blennerhassett 102719f82d3SEliot Blennerhassett void hpi_init_responseV1(struct hpi_response_header *phr, u16 size, 103719f82d3SEliot Blennerhassett u16 object, u16 function) 104719f82d3SEliot Blennerhassett { 10551e6f47dSEliot Blennerhassett (void)object; 10651e6f47dSEliot Blennerhassett (void)function; 10751e6f47dSEliot Blennerhassett memset(phr, 0, size); 108719f82d3SEliot Blennerhassett phr->size = size; 109719f82d3SEliot Blennerhassett phr->version = 1; 110719f82d3SEliot Blennerhassett phr->type = HPI_TYPE_RESPONSE; 111719f82d3SEliot Blennerhassett phr->error = HPI_ERROR_PROCESSING_MESSAGE; 112719f82d3SEliot Blennerhassett } 113719f82d3SEliot Blennerhassett 114719f82d3SEliot Blennerhassett void hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size, 115719f82d3SEliot Blennerhassett struct hpi_response_header *phr, u16 res_size, u16 object, 116719f82d3SEliot Blennerhassett u16 function) 117719f82d3SEliot Blennerhassett { 118719f82d3SEliot Blennerhassett hpi_init_messageV1(phm, msg_size, object, function); 119719f82d3SEliot Blennerhassett hpi_init_responseV1(phr, res_size, object, function); 120719f82d3SEliot Blennerhassett } 121