xref: /openbmc/linux/sound/pci/asihpi/hpimsginit.c (revision f9d94b57e30fd1575b4935045b32d738668aa74b)
1719f82d3SEliot Blennerhassett /******************************************************************************
2719f82d3SEliot Blennerhassett 
3719f82d3SEliot Blennerhassett     AudioScience HPI driver
451e6f47dSEliot Blennerhassett     Copyright (C) 1997-2014  AudioScience Inc. <support@audioscience.com>
5719f82d3SEliot Blennerhassett 
6719f82d3SEliot Blennerhassett     This program is free software; you can redistribute it and/or modify
7719f82d3SEliot Blennerhassett     it under the terms of version 2 of the GNU General Public License as
8719f82d3SEliot Blennerhassett     published by the Free Software Foundation;
9719f82d3SEliot Blennerhassett 
10719f82d3SEliot Blennerhassett     This program is distributed in the hope that it will be useful,
11719f82d3SEliot Blennerhassett     but WITHOUT ANY WARRANTY; without even the implied warranty of
12719f82d3SEliot Blennerhassett     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13719f82d3SEliot Blennerhassett     GNU General Public License for more details.
14719f82d3SEliot Blennerhassett 
15719f82d3SEliot Blennerhassett     You should have received a copy of the GNU General Public License
16719f82d3SEliot Blennerhassett     along with this program; if not, write to the Free Software
17719f82d3SEliot Blennerhassett     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18719f82d3SEliot Blennerhassett 
19719f82d3SEliot Blennerhassett  Hardware Programming Interface (HPI) Utility functions.
20719f82d3SEliot Blennerhassett 
21719f82d3SEliot Blennerhassett  (C) Copyright AudioScience Inc. 2007
22719f82d3SEliot Blennerhassett *******************************************************************************/
23719f82d3SEliot Blennerhassett 
24719f82d3SEliot Blennerhassett #include "hpi_internal.h"
25719f82d3SEliot Blennerhassett #include "hpimsginit.h"
26*f9d94b57STakashi Iwai #include <linux/nospec.h>
27719f82d3SEliot Blennerhassett 
28719f82d3SEliot Blennerhassett /* The actual message size for each object type */
29719f82d3SEliot Blennerhassett static u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT;
30719f82d3SEliot Blennerhassett /* The actual response size for each object type */
31719f82d3SEliot Blennerhassett static u16 res_size[HPI_OBJ_MAXINDEX + 1] = HPI_RESPONSE_SIZE_BY_OBJECT;
32719f82d3SEliot Blennerhassett /* Flag to enable alternate message type for SSX2 bypass. */
33719f82d3SEliot Blennerhassett static u16 gwSSX2_bypass;
34719f82d3SEliot Blennerhassett 
35719f82d3SEliot Blennerhassett /** \internal
36719f82d3SEliot Blennerhassett   * initialize the HPI message structure
37719f82d3SEliot Blennerhassett   */
38719f82d3SEliot Blennerhassett static void hpi_init_message(struct hpi_message *phm, u16 object,
39719f82d3SEliot Blennerhassett 	u16 function)
40719f82d3SEliot Blennerhassett {
4151e6f47dSEliot Blennerhassett 	u16 size;
4251e6f47dSEliot Blennerhassett 
43*f9d94b57STakashi Iwai 	if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
44*f9d94b57STakashi Iwai 		object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1);
4551e6f47dSEliot Blennerhassett 		size = msg_size[object];
46*f9d94b57STakashi Iwai 	} else {
4751e6f47dSEliot Blennerhassett 		size = sizeof(*phm);
48*f9d94b57STakashi Iwai 	}
4951e6f47dSEliot Blennerhassett 
5051e6f47dSEliot Blennerhassett 	memset(phm, 0, size);
5151e6f47dSEliot Blennerhassett 	phm->size = size;
52719f82d3SEliot Blennerhassett 
53719f82d3SEliot Blennerhassett 	if (gwSSX2_bypass)
54719f82d3SEliot Blennerhassett 		phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE;
55719f82d3SEliot Blennerhassett 	else
5682b5774fSEliot Blennerhassett 		phm->type = HPI_TYPE_REQUEST;
57719f82d3SEliot Blennerhassett 	phm->object = object;
58719f82d3SEliot Blennerhassett 	phm->function = function;
59719f82d3SEliot Blennerhassett 	phm->version = 0;
603285ea10SEliot Blennerhassett 	phm->adapter_index = HPI_ADAPTER_INDEX_INVALID;
610a1602c0SEliot Blennerhassett 	/* Expect actual adapter index to be set by caller */
62719f82d3SEliot Blennerhassett }
63719f82d3SEliot Blennerhassett 
64719f82d3SEliot Blennerhassett /** \internal
65719f82d3SEliot Blennerhassett   * initialize the HPI response structure
66719f82d3SEliot Blennerhassett   */
67719f82d3SEliot Blennerhassett void hpi_init_response(struct hpi_response *phr, u16 object, u16 function,
68719f82d3SEliot Blennerhassett 	u16 error)
69719f82d3SEliot Blennerhassett {
7051e6f47dSEliot Blennerhassett 	u16 size;
7151e6f47dSEliot Blennerhassett 
72*f9d94b57STakashi Iwai 	if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
73*f9d94b57STakashi Iwai 		object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1);
7451e6f47dSEliot Blennerhassett 		size = res_size[object];
75*f9d94b57STakashi Iwai 	} else {
7651e6f47dSEliot Blennerhassett 		size = sizeof(*phr);
77*f9d94b57STakashi Iwai 	}
7851e6f47dSEliot Blennerhassett 
7951e6f47dSEliot Blennerhassett 	memset(phr, 0, sizeof(*phr));
8051e6f47dSEliot Blennerhassett 	phr->size = size;
8151e6f47dSEliot Blennerhassett 	phr->type = HPI_TYPE_RESPONSE;
82719f82d3SEliot Blennerhassett 	phr->object = object;
83719f82d3SEliot Blennerhassett 	phr->function = function;
84719f82d3SEliot Blennerhassett 	phr->error = error;
85719f82d3SEliot Blennerhassett 	phr->specific_error = 0;
86719f82d3SEliot Blennerhassett 	phr->version = 0;
87719f82d3SEliot Blennerhassett }
88719f82d3SEliot Blennerhassett 
89719f82d3SEliot Blennerhassett void hpi_init_message_response(struct hpi_message *phm,
90719f82d3SEliot Blennerhassett 	struct hpi_response *phr, u16 object, u16 function)
91719f82d3SEliot Blennerhassett {
92719f82d3SEliot Blennerhassett 	hpi_init_message(phm, object, function);
93719f82d3SEliot Blennerhassett 	/* default error return if the response is
94719f82d3SEliot Blennerhassett 	   not filled in by the callee */
95719f82d3SEliot Blennerhassett 	hpi_init_response(phr, object, function,
96719f82d3SEliot Blennerhassett 		HPI_ERROR_PROCESSING_MESSAGE);
97719f82d3SEliot Blennerhassett }
98719f82d3SEliot Blennerhassett 
99719f82d3SEliot Blennerhassett static void hpi_init_messageV1(struct hpi_message_header *phm, u16 size,
100719f82d3SEliot Blennerhassett 	u16 object, u16 function)
101719f82d3SEliot Blennerhassett {
10251e6f47dSEliot Blennerhassett 	memset(phm, 0, size);
103719f82d3SEliot Blennerhassett 	if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
104719f82d3SEliot Blennerhassett 		phm->size = size;
10582b5774fSEliot Blennerhassett 		phm->type = HPI_TYPE_REQUEST;
106719f82d3SEliot Blennerhassett 		phm->object = object;
107719f82d3SEliot Blennerhassett 		phm->function = function;
108719f82d3SEliot Blennerhassett 		phm->version = 1;
109719f82d3SEliot Blennerhassett 		/* Expect adapter index to be set by caller */
110719f82d3SEliot Blennerhassett 	}
111719f82d3SEliot Blennerhassett }
112719f82d3SEliot Blennerhassett 
113719f82d3SEliot Blennerhassett void hpi_init_responseV1(struct hpi_response_header *phr, u16 size,
114719f82d3SEliot Blennerhassett 	u16 object, u16 function)
115719f82d3SEliot Blennerhassett {
11651e6f47dSEliot Blennerhassett 	(void)object;
11751e6f47dSEliot Blennerhassett 	(void)function;
11851e6f47dSEliot Blennerhassett 	memset(phr, 0, size);
119719f82d3SEliot Blennerhassett 	phr->size = size;
120719f82d3SEliot Blennerhassett 	phr->version = 1;
121719f82d3SEliot Blennerhassett 	phr->type = HPI_TYPE_RESPONSE;
122719f82d3SEliot Blennerhassett 	phr->error = HPI_ERROR_PROCESSING_MESSAGE;
123719f82d3SEliot Blennerhassett }
124719f82d3SEliot Blennerhassett 
125719f82d3SEliot Blennerhassett void hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size,
126719f82d3SEliot Blennerhassett 	struct hpi_response_header *phr, u16 res_size, u16 object,
127719f82d3SEliot Blennerhassett 	u16 function)
128719f82d3SEliot Blennerhassett {
129719f82d3SEliot Blennerhassett 	hpi_init_messageV1(phm, msg_size, object, function);
130719f82d3SEliot Blennerhassett 	hpi_init_responseV1(phr, res_size, object, function);
131719f82d3SEliot Blennerhassett }
132