107d7fe7bSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2719f82d3SEliot Blennerhassett /******************************************************************************
3719f82d3SEliot Blennerhassett
4719f82d3SEliot Blennerhassett AudioScience HPI driver
55bc91f5bSEliot Blennerhassett Copyright (C) 1997-2014 AudioScience Inc. <support@audioscience.com>
6719f82d3SEliot Blennerhassett
7719f82d3SEliot Blennerhassett
8938c565aSEliot Blennerhassett Extended Message Function With Response Caching
9719f82d3SEliot Blennerhassett
10719f82d3SEliot Blennerhassett (C) Copyright AudioScience Inc. 2002
11719f82d3SEliot Blennerhassett *****************************************************************************/
12719f82d3SEliot Blennerhassett #define SOURCEFILE_NAME "hpimsgx.c"
13719f82d3SEliot Blennerhassett #include "hpi_internal.h"
14f6baaec2SEliot Blennerhassett #include "hpi_version.h"
15719f82d3SEliot Blennerhassett #include "hpimsginit.h"
163285ea10SEliot Blennerhassett #include "hpicmn.h"
17719f82d3SEliot Blennerhassett #include "hpimsgx.h"
18719f82d3SEliot Blennerhassett #include "hpidebug.h"
19719f82d3SEliot Blennerhassett
209ca7a0c9STakashi Iwai static const struct pci_device_id asihpi_pci_tbl[] = {
21719f82d3SEliot Blennerhassett #include "hpipcida.h"
22719f82d3SEliot Blennerhassett };
23719f82d3SEliot Blennerhassett
24719f82d3SEliot Blennerhassett static struct hpios_spinlock msgx_lock;
25719f82d3SEliot Blennerhassett
26719f82d3SEliot Blennerhassett static hpi_handler_func *hpi_entry_points[HPI_MAX_ADAPTERS];
275bc91f5bSEliot Blennerhassett static int logging_enabled = 1;
28719f82d3SEliot Blennerhassett
hpi_lookup_entry_point_function(const struct hpi_pci * pci_info)29719f82d3SEliot Blennerhassett static hpi_handler_func *hpi_lookup_entry_point_function(const struct hpi_pci
30719f82d3SEliot Blennerhassett *pci_info)
31719f82d3SEliot Blennerhassett {
32719f82d3SEliot Blennerhassett
33719f82d3SEliot Blennerhassett int i;
34719f82d3SEliot Blennerhassett
35719f82d3SEliot Blennerhassett for (i = 0; asihpi_pci_tbl[i].vendor != 0; i++) {
36719f82d3SEliot Blennerhassett if (asihpi_pci_tbl[i].vendor != PCI_ANY_ID
373285ea10SEliot Blennerhassett && asihpi_pci_tbl[i].vendor !=
383285ea10SEliot Blennerhassett pci_info->pci_dev->vendor)
39719f82d3SEliot Blennerhassett continue;
40719f82d3SEliot Blennerhassett if (asihpi_pci_tbl[i].device != PCI_ANY_ID
413285ea10SEliot Blennerhassett && asihpi_pci_tbl[i].device !=
423285ea10SEliot Blennerhassett pci_info->pci_dev->device)
43719f82d3SEliot Blennerhassett continue;
44719f82d3SEliot Blennerhassett if (asihpi_pci_tbl[i].subvendor != PCI_ANY_ID
45719f82d3SEliot Blennerhassett && asihpi_pci_tbl[i].subvendor !=
463285ea10SEliot Blennerhassett pci_info->pci_dev->subsystem_vendor)
47719f82d3SEliot Blennerhassett continue;
48719f82d3SEliot Blennerhassett if (asihpi_pci_tbl[i].subdevice != PCI_ANY_ID
49719f82d3SEliot Blennerhassett && asihpi_pci_tbl[i].subdevice !=
503285ea10SEliot Blennerhassett pci_info->pci_dev->subsystem_device)
51719f82d3SEliot Blennerhassett continue;
52719f82d3SEliot Blennerhassett
533285ea10SEliot Blennerhassett /* HPI_DEBUG_LOG(DEBUG, " %x,%lx\n", i,
543285ea10SEliot Blennerhassett asihpi_pci_tbl[i].driver_data); */
55719f82d3SEliot Blennerhassett return (hpi_handler_func *) asihpi_pci_tbl[i].driver_data;
56719f82d3SEliot Blennerhassett }
57719f82d3SEliot Blennerhassett
58719f82d3SEliot Blennerhassett return NULL;
59719f82d3SEliot Blennerhassett }
60719f82d3SEliot Blennerhassett
hw_entry_point(struct hpi_message * phm,struct hpi_response * phr)61719f82d3SEliot Blennerhassett static inline void hw_entry_point(struct hpi_message *phm,
62719f82d3SEliot Blennerhassett struct hpi_response *phr)
63719f82d3SEliot Blennerhassett {
643285ea10SEliot Blennerhassett if ((phm->adapter_index < HPI_MAX_ADAPTERS)
653285ea10SEliot Blennerhassett && hpi_entry_points[phm->adapter_index])
663285ea10SEliot Blennerhassett hpi_entry_points[phm->adapter_index] (phm, phr);
673285ea10SEliot Blennerhassett else
68719f82d3SEliot Blennerhassett hpi_init_response(phr, phm->object, phm->function,
69719f82d3SEliot Blennerhassett HPI_ERROR_PROCESSING_MESSAGE);
70719f82d3SEliot Blennerhassett }
71719f82d3SEliot Blennerhassett
72719f82d3SEliot Blennerhassett static void adapter_open(struct hpi_message *phm, struct hpi_response *phr);
73719f82d3SEliot Blennerhassett static void adapter_close(struct hpi_message *phm, struct hpi_response *phr);
74719f82d3SEliot Blennerhassett
75719f82d3SEliot Blennerhassett static void mixer_open(struct hpi_message *phm, struct hpi_response *phr);
76719f82d3SEliot Blennerhassett static void mixer_close(struct hpi_message *phm, struct hpi_response *phr);
77719f82d3SEliot Blennerhassett
78719f82d3SEliot Blennerhassett static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
79719f82d3SEliot Blennerhassett void *h_owner);
80719f82d3SEliot Blennerhassett static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
81719f82d3SEliot Blennerhassett void *h_owner);
82719f82d3SEliot Blennerhassett static void instream_open(struct hpi_message *phm, struct hpi_response *phr,
83719f82d3SEliot Blennerhassett void *h_owner);
84719f82d3SEliot Blennerhassett static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
85719f82d3SEliot Blennerhassett void *h_owner);
86719f82d3SEliot Blennerhassett
87719f82d3SEliot Blennerhassett static void HPIMSGX__reset(u16 adapter_index);
883285ea10SEliot Blennerhassett
89719f82d3SEliot Blennerhassett static u16 HPIMSGX__init(struct hpi_message *phm, struct hpi_response *phr);
90719f82d3SEliot Blennerhassett static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner);
91719f82d3SEliot Blennerhassett
92719f82d3SEliot Blennerhassett #ifndef DISABLE_PRAGMA_PACK1
93719f82d3SEliot Blennerhassett #pragma pack(push, 1)
94719f82d3SEliot Blennerhassett #endif
95719f82d3SEliot Blennerhassett
96719f82d3SEliot Blennerhassett struct hpi_adapter_response {
97719f82d3SEliot Blennerhassett struct hpi_response_header h;
98719f82d3SEliot Blennerhassett struct hpi_adapter_res a;
99719f82d3SEliot Blennerhassett };
100719f82d3SEliot Blennerhassett
101719f82d3SEliot Blennerhassett struct hpi_mixer_response {
102719f82d3SEliot Blennerhassett struct hpi_response_header h;
103719f82d3SEliot Blennerhassett struct hpi_mixer_res m;
104719f82d3SEliot Blennerhassett };
105719f82d3SEliot Blennerhassett
106719f82d3SEliot Blennerhassett struct hpi_stream_response {
107719f82d3SEliot Blennerhassett struct hpi_response_header h;
108719f82d3SEliot Blennerhassett struct hpi_stream_res d;
109719f82d3SEliot Blennerhassett };
110719f82d3SEliot Blennerhassett
111719f82d3SEliot Blennerhassett struct adapter_info {
112719f82d3SEliot Blennerhassett u16 type;
113719f82d3SEliot Blennerhassett u16 num_instreams;
114719f82d3SEliot Blennerhassett u16 num_outstreams;
115719f82d3SEliot Blennerhassett };
116719f82d3SEliot Blennerhassett
117719f82d3SEliot Blennerhassett struct asi_open_state {
118719f82d3SEliot Blennerhassett int open_flag;
119719f82d3SEliot Blennerhassett void *h_owner;
120719f82d3SEliot Blennerhassett };
121719f82d3SEliot Blennerhassett
122719f82d3SEliot Blennerhassett #ifndef DISABLE_PRAGMA_PACK1
123719f82d3SEliot Blennerhassett #pragma pack(pop)
124719f82d3SEliot Blennerhassett #endif
125719f82d3SEliot Blennerhassett
126719f82d3SEliot Blennerhassett /* Globals */
127719f82d3SEliot Blennerhassett static struct hpi_adapter_response rESP_HPI_ADAPTER_OPEN[HPI_MAX_ADAPTERS];
128719f82d3SEliot Blennerhassett
129719f82d3SEliot Blennerhassett static struct hpi_stream_response
130719f82d3SEliot Blennerhassett rESP_HPI_OSTREAM_OPEN[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
131719f82d3SEliot Blennerhassett
132719f82d3SEliot Blennerhassett static struct hpi_stream_response
133719f82d3SEliot Blennerhassett rESP_HPI_ISTREAM_OPEN[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
134719f82d3SEliot Blennerhassett
135719f82d3SEliot Blennerhassett static struct hpi_mixer_response rESP_HPI_MIXER_OPEN[HPI_MAX_ADAPTERS];
136719f82d3SEliot Blennerhassett
137719f82d3SEliot Blennerhassett static struct adapter_info aDAPTER_INFO[HPI_MAX_ADAPTERS];
138719f82d3SEliot Blennerhassett
139719f82d3SEliot Blennerhassett /* use these to keep track of opens from user mode apps/DLLs */
140719f82d3SEliot Blennerhassett static struct asi_open_state
141719f82d3SEliot Blennerhassett outstream_user_open[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
142719f82d3SEliot Blennerhassett
143719f82d3SEliot Blennerhassett static struct asi_open_state
144719f82d3SEliot Blennerhassett instream_user_open[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
145719f82d3SEliot Blennerhassett
subsys_message(struct hpi_message * phm,struct hpi_response * phr,void * h_owner)146719f82d3SEliot Blennerhassett static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
147719f82d3SEliot Blennerhassett void *h_owner)
148719f82d3SEliot Blennerhassett {
1493285ea10SEliot Blennerhassett if (phm->adapter_index != HPI_ADAPTER_INDEX_INVALID)
1503285ea10SEliot Blennerhassett HPI_DEBUG_LOG(WARNING,
1513285ea10SEliot Blennerhassett "suspicious adapter index %d in subsys message 0x%x.\n",
1523285ea10SEliot Blennerhassett phm->adapter_index, phm->function);
1533285ea10SEliot Blennerhassett
154719f82d3SEliot Blennerhassett switch (phm->function) {
155719f82d3SEliot Blennerhassett case HPI_SUBSYS_GET_VERSION:
156719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
157719f82d3SEliot Blennerhassett HPI_SUBSYS_GET_VERSION, 0);
158719f82d3SEliot Blennerhassett phr->u.s.version = HPI_VER >> 8; /* return major.minor */
159719f82d3SEliot Blennerhassett phr->u.s.data = HPI_VER; /* return major.minor.release */
160719f82d3SEliot Blennerhassett break;
161719f82d3SEliot Blennerhassett case HPI_SUBSYS_OPEN:
162719f82d3SEliot Blennerhassett /*do not propagate the message down the chain */
163719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_OPEN, 0);
164719f82d3SEliot Blennerhassett break;
165719f82d3SEliot Blennerhassett case HPI_SUBSYS_CLOSE:
166719f82d3SEliot Blennerhassett /*do not propagate the message down the chain */
167719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CLOSE,
168719f82d3SEliot Blennerhassett 0);
169719f82d3SEliot Blennerhassett HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner);
170719f82d3SEliot Blennerhassett break;
171719f82d3SEliot Blennerhassett case HPI_SUBSYS_DRIVER_LOAD:
172719f82d3SEliot Blennerhassett /* Initialize this module's internal state */
173719f82d3SEliot Blennerhassett hpios_msgxlock_init(&msgx_lock);
174719f82d3SEliot Blennerhassett memset(&hpi_entry_points, 0, sizeof(hpi_entry_points));
175719f82d3SEliot Blennerhassett /* Init subsys_findadapters response to no-adapters */
176719f82d3SEliot Blennerhassett HPIMSGX__reset(HPIMSGX_ALLADAPTERS);
177719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
178719f82d3SEliot Blennerhassett HPI_SUBSYS_DRIVER_LOAD, 0);
179719f82d3SEliot Blennerhassett /* individual HPIs dont implement driver load */
180719f82d3SEliot Blennerhassett HPI_COMMON(phm, phr);
181719f82d3SEliot Blennerhassett break;
182719f82d3SEliot Blennerhassett case HPI_SUBSYS_DRIVER_UNLOAD:
183719f82d3SEliot Blennerhassett HPI_COMMON(phm, phr);
184719f82d3SEliot Blennerhassett HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner);
185719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
186719f82d3SEliot Blennerhassett HPI_SUBSYS_DRIVER_UNLOAD, 0);
187719f82d3SEliot Blennerhassett return;
188719f82d3SEliot Blennerhassett
1893285ea10SEliot Blennerhassett case HPI_SUBSYS_GET_NUM_ADAPTERS:
1903285ea10SEliot Blennerhassett case HPI_SUBSYS_GET_ADAPTER:
191719f82d3SEliot Blennerhassett HPI_COMMON(phm, phr);
192719f82d3SEliot Blennerhassett break;
193719f82d3SEliot Blennerhassett
194719f82d3SEliot Blennerhassett case HPI_SUBSYS_CREATE_ADAPTER:
195719f82d3SEliot Blennerhassett HPIMSGX__init(phm, phr);
196719f82d3SEliot Blennerhassett break;
1973285ea10SEliot Blennerhassett
198719f82d3SEliot Blennerhassett default:
1991d595d2aSEliot Blennerhassett /* Must explicitly handle every subsys message in this switch */
2003285ea10SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function,
2013285ea10SEliot Blennerhassett HPI_ERROR_INVALID_FUNC);
202719f82d3SEliot Blennerhassett break;
203719f82d3SEliot Blennerhassett }
204719f82d3SEliot Blennerhassett }
205719f82d3SEliot Blennerhassett
adapter_message(struct hpi_message * phm,struct hpi_response * phr,void * h_owner)206719f82d3SEliot Blennerhassett static void adapter_message(struct hpi_message *phm, struct hpi_response *phr,
207719f82d3SEliot Blennerhassett void *h_owner)
208719f82d3SEliot Blennerhassett {
209719f82d3SEliot Blennerhassett switch (phm->function) {
210719f82d3SEliot Blennerhassett case HPI_ADAPTER_OPEN:
211719f82d3SEliot Blennerhassett adapter_open(phm, phr);
212719f82d3SEliot Blennerhassett break;
213719f82d3SEliot Blennerhassett case HPI_ADAPTER_CLOSE:
214719f82d3SEliot Blennerhassett adapter_close(phm, phr);
215719f82d3SEliot Blennerhassett break;
2166d0b898eSEliot Blennerhassett case HPI_ADAPTER_DELETE:
2176d0b898eSEliot Blennerhassett HPIMSGX__cleanup(phm->adapter_index, h_owner);
2186d0b898eSEliot Blennerhassett {
2196d0b898eSEliot Blennerhassett struct hpi_message hm;
2206d0b898eSEliot Blennerhassett struct hpi_response hr;
2216d0b898eSEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
2226d0b898eSEliot Blennerhassett HPI_ADAPTER_CLOSE);
2236d0b898eSEliot Blennerhassett hm.adapter_index = phm->adapter_index;
2246d0b898eSEliot Blennerhassett hw_entry_point(&hm, &hr);
2256d0b898eSEliot Blennerhassett }
2266d0b898eSEliot Blennerhassett hw_entry_point(phm, phr);
2276d0b898eSEliot Blennerhassett break;
2286d0b898eSEliot Blennerhassett
229719f82d3SEliot Blennerhassett default:
230719f82d3SEliot Blennerhassett hw_entry_point(phm, phr);
231719f82d3SEliot Blennerhassett break;
232719f82d3SEliot Blennerhassett }
233719f82d3SEliot Blennerhassett }
234719f82d3SEliot Blennerhassett
mixer_message(struct hpi_message * phm,struct hpi_response * phr)235719f82d3SEliot Blennerhassett static void mixer_message(struct hpi_message *phm, struct hpi_response *phr)
236719f82d3SEliot Blennerhassett {
237719f82d3SEliot Blennerhassett switch (phm->function) {
238719f82d3SEliot Blennerhassett case HPI_MIXER_OPEN:
239719f82d3SEliot Blennerhassett mixer_open(phm, phr);
240719f82d3SEliot Blennerhassett break;
241719f82d3SEliot Blennerhassett case HPI_MIXER_CLOSE:
242719f82d3SEliot Blennerhassett mixer_close(phm, phr);
243719f82d3SEliot Blennerhassett break;
244719f82d3SEliot Blennerhassett default:
245719f82d3SEliot Blennerhassett hw_entry_point(phm, phr);
246719f82d3SEliot Blennerhassett break;
247719f82d3SEliot Blennerhassett }
248719f82d3SEliot Blennerhassett }
249719f82d3SEliot Blennerhassett
outstream_message(struct hpi_message * phm,struct hpi_response * phr,void * h_owner)250719f82d3SEliot Blennerhassett static void outstream_message(struct hpi_message *phm,
251719f82d3SEliot Blennerhassett struct hpi_response *phr, void *h_owner)
252719f82d3SEliot Blennerhassett {
253719f82d3SEliot Blennerhassett if (phm->obj_index >= aDAPTER_INFO[phm->adapter_index].num_outstreams) {
254719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_OSTREAM, phm->function,
255719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ_INDEX);
256719f82d3SEliot Blennerhassett return;
257719f82d3SEliot Blennerhassett }
258719f82d3SEliot Blennerhassett
259719f82d3SEliot Blennerhassett switch (phm->function) {
260719f82d3SEliot Blennerhassett case HPI_OSTREAM_OPEN:
261719f82d3SEliot Blennerhassett outstream_open(phm, phr, h_owner);
262719f82d3SEliot Blennerhassett break;
263719f82d3SEliot Blennerhassett case HPI_OSTREAM_CLOSE:
264719f82d3SEliot Blennerhassett outstream_close(phm, phr, h_owner);
265719f82d3SEliot Blennerhassett break;
266719f82d3SEliot Blennerhassett default:
267719f82d3SEliot Blennerhassett hw_entry_point(phm, phr);
268719f82d3SEliot Blennerhassett break;
269719f82d3SEliot Blennerhassett }
270719f82d3SEliot Blennerhassett }
271719f82d3SEliot Blennerhassett
instream_message(struct hpi_message * phm,struct hpi_response * phr,void * h_owner)272719f82d3SEliot Blennerhassett static void instream_message(struct hpi_message *phm,
273719f82d3SEliot Blennerhassett struct hpi_response *phr, void *h_owner)
274719f82d3SEliot Blennerhassett {
275719f82d3SEliot Blennerhassett if (phm->obj_index >= aDAPTER_INFO[phm->adapter_index].num_instreams) {
276719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_ISTREAM, phm->function,
277719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ_INDEX);
278719f82d3SEliot Blennerhassett return;
279719f82d3SEliot Blennerhassett }
280719f82d3SEliot Blennerhassett
281719f82d3SEliot Blennerhassett switch (phm->function) {
282719f82d3SEliot Blennerhassett case HPI_ISTREAM_OPEN:
283719f82d3SEliot Blennerhassett instream_open(phm, phr, h_owner);
284719f82d3SEliot Blennerhassett break;
285719f82d3SEliot Blennerhassett case HPI_ISTREAM_CLOSE:
286719f82d3SEliot Blennerhassett instream_close(phm, phr, h_owner);
287719f82d3SEliot Blennerhassett break;
288719f82d3SEliot Blennerhassett default:
289719f82d3SEliot Blennerhassett hw_entry_point(phm, phr);
290719f82d3SEliot Blennerhassett break;
291719f82d3SEliot Blennerhassett }
292719f82d3SEliot Blennerhassett }
293719f82d3SEliot Blennerhassett
294719f82d3SEliot Blennerhassett /* NOTE: HPI_Message() must be defined in the driver as a wrapper for
295719f82d3SEliot Blennerhassett * HPI_MessageEx so that functions in hpifunc.c compile.
296719f82d3SEliot Blennerhassett */
hpi_send_recv_ex(struct hpi_message * phm,struct hpi_response * phr,void * h_owner)297719f82d3SEliot Blennerhassett void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr,
298719f82d3SEliot Blennerhassett void *h_owner)
299719f82d3SEliot Blennerhassett {
3005bc91f5bSEliot Blennerhassett
3015bc91f5bSEliot Blennerhassett if (logging_enabled)
302719f82d3SEliot Blennerhassett HPI_DEBUG_MESSAGE(DEBUG, phm);
303719f82d3SEliot Blennerhassett
30482b5774fSEliot Blennerhassett if (phm->type != HPI_TYPE_REQUEST) {
305719f82d3SEliot Blennerhassett hpi_init_response(phr, phm->object, phm->function,
306719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_TYPE);
307719f82d3SEliot Blennerhassett return;
308719f82d3SEliot Blennerhassett }
309719f82d3SEliot Blennerhassett
310719f82d3SEliot Blennerhassett if (phm->adapter_index >= HPI_MAX_ADAPTERS
311719f82d3SEliot Blennerhassett && phm->adapter_index != HPIMSGX_ALLADAPTERS) {
312719f82d3SEliot Blennerhassett hpi_init_response(phr, phm->object, phm->function,
313719f82d3SEliot Blennerhassett HPI_ERROR_BAD_ADAPTER_NUMBER);
314719f82d3SEliot Blennerhassett return;
315719f82d3SEliot Blennerhassett }
316719f82d3SEliot Blennerhassett
317719f82d3SEliot Blennerhassett switch (phm->object) {
318719f82d3SEliot Blennerhassett case HPI_OBJ_SUBSYSTEM:
319719f82d3SEliot Blennerhassett subsys_message(phm, phr, h_owner);
320719f82d3SEliot Blennerhassett break;
321719f82d3SEliot Blennerhassett
322719f82d3SEliot Blennerhassett case HPI_OBJ_ADAPTER:
323719f82d3SEliot Blennerhassett adapter_message(phm, phr, h_owner);
324719f82d3SEliot Blennerhassett break;
325719f82d3SEliot Blennerhassett
326719f82d3SEliot Blennerhassett case HPI_OBJ_MIXER:
327719f82d3SEliot Blennerhassett mixer_message(phm, phr);
328719f82d3SEliot Blennerhassett break;
329719f82d3SEliot Blennerhassett
330719f82d3SEliot Blennerhassett case HPI_OBJ_OSTREAM:
331719f82d3SEliot Blennerhassett outstream_message(phm, phr, h_owner);
332719f82d3SEliot Blennerhassett break;
333719f82d3SEliot Blennerhassett
334719f82d3SEliot Blennerhassett case HPI_OBJ_ISTREAM:
335719f82d3SEliot Blennerhassett instream_message(phm, phr, h_owner);
336719f82d3SEliot Blennerhassett break;
337719f82d3SEliot Blennerhassett
338719f82d3SEliot Blennerhassett default:
339719f82d3SEliot Blennerhassett hw_entry_point(phm, phr);
340719f82d3SEliot Blennerhassett break;
341719f82d3SEliot Blennerhassett }
3425bc91f5bSEliot Blennerhassett
3435bc91f5bSEliot Blennerhassett if (logging_enabled)
344719f82d3SEliot Blennerhassett HPI_DEBUG_RESPONSE(phr);
345719f82d3SEliot Blennerhassett
3465bc91f5bSEliot Blennerhassett if (phr->error >= HPI_ERROR_DSP_COMMUNICATION) {
3475bc91f5bSEliot Blennerhassett hpi_debug_level_set(HPI_DEBUG_LEVEL_ERROR);
3485bc91f5bSEliot Blennerhassett logging_enabled = 0;
3495bc91f5bSEliot Blennerhassett }
350719f82d3SEliot Blennerhassett }
351719f82d3SEliot Blennerhassett
adapter_open(struct hpi_message * phm,struct hpi_response * phr)352719f82d3SEliot Blennerhassett static void adapter_open(struct hpi_message *phm, struct hpi_response *phr)
353719f82d3SEliot Blennerhassett {
354719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(VERBOSE, "adapter_open\n");
355719f82d3SEliot Blennerhassett memcpy(phr, &rESP_HPI_ADAPTER_OPEN[phm->adapter_index],
356719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ADAPTER_OPEN[0]));
357719f82d3SEliot Blennerhassett }
358719f82d3SEliot Blennerhassett
adapter_close(struct hpi_message * phm,struct hpi_response * phr)359719f82d3SEliot Blennerhassett static void adapter_close(struct hpi_message *phm, struct hpi_response *phr)
360719f82d3SEliot Blennerhassett {
361719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(VERBOSE, "adapter_close\n");
362719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_ADAPTER, HPI_ADAPTER_CLOSE, 0);
363719f82d3SEliot Blennerhassett }
364719f82d3SEliot Blennerhassett
mixer_open(struct hpi_message * phm,struct hpi_response * phr)365719f82d3SEliot Blennerhassett static void mixer_open(struct hpi_message *phm, struct hpi_response *phr)
366719f82d3SEliot Blennerhassett {
367719f82d3SEliot Blennerhassett memcpy(phr, &rESP_HPI_MIXER_OPEN[phm->adapter_index],
368719f82d3SEliot Blennerhassett sizeof(rESP_HPI_MIXER_OPEN[0]));
369719f82d3SEliot Blennerhassett }
370719f82d3SEliot Blennerhassett
mixer_close(struct hpi_message * phm,struct hpi_response * phr)371719f82d3SEliot Blennerhassett static void mixer_close(struct hpi_message *phm, struct hpi_response *phr)
372719f82d3SEliot Blennerhassett {
373719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_MIXER, HPI_MIXER_CLOSE, 0);
374719f82d3SEliot Blennerhassett }
375719f82d3SEliot Blennerhassett
instream_open(struct hpi_message * phm,struct hpi_response * phr,void * h_owner)376719f82d3SEliot Blennerhassett static void instream_open(struct hpi_message *phm, struct hpi_response *phr,
377719f82d3SEliot Blennerhassett void *h_owner)
378719f82d3SEliot Blennerhassett {
379719f82d3SEliot Blennerhassett
380719f82d3SEliot Blennerhassett struct hpi_message hm;
381719f82d3SEliot Blennerhassett struct hpi_response hr;
382719f82d3SEliot Blennerhassett
383719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_ISTREAM, HPI_ISTREAM_OPEN, 0);
384719f82d3SEliot Blennerhassett
385719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock);
386719f82d3SEliot Blennerhassett
387719f82d3SEliot Blennerhassett if (instream_user_open[phm->adapter_index][phm->obj_index].open_flag)
388719f82d3SEliot Blennerhassett phr->error = HPI_ERROR_OBJ_ALREADY_OPEN;
389719f82d3SEliot Blennerhassett else if (rESP_HPI_ISTREAM_OPEN[phm->adapter_index]
390719f82d3SEliot Blennerhassett [phm->obj_index].h.error)
391719f82d3SEliot Blennerhassett memcpy(phr,
392719f82d3SEliot Blennerhassett &rESP_HPI_ISTREAM_OPEN[phm->adapter_index][phm->
393719f82d3SEliot Blennerhassett obj_index],
394719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
395719f82d3SEliot Blennerhassett else {
396719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm->
397719f82d3SEliot Blennerhassett obj_index].open_flag = 1;
3983285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock);
399719f82d3SEliot Blennerhassett
400719f82d3SEliot Blennerhassett /* issue a reset */
401719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
402719f82d3SEliot Blennerhassett HPI_ISTREAM_RESET);
403719f82d3SEliot Blennerhassett hm.adapter_index = phm->adapter_index;
404719f82d3SEliot Blennerhassett hm.obj_index = phm->obj_index;
405719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr);
406719f82d3SEliot Blennerhassett
407719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock);
408719f82d3SEliot Blennerhassett if (hr.error) {
409719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm->
410719f82d3SEliot Blennerhassett obj_index].open_flag = 0;
411719f82d3SEliot Blennerhassett phr->error = hr.error;
412719f82d3SEliot Blennerhassett } else {
413719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm->
414719f82d3SEliot Blennerhassett obj_index].open_flag = 1;
415719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm->
416719f82d3SEliot Blennerhassett obj_index].h_owner = h_owner;
417719f82d3SEliot Blennerhassett memcpy(phr,
418719f82d3SEliot Blennerhassett &rESP_HPI_ISTREAM_OPEN[phm->adapter_index]
419719f82d3SEliot Blennerhassett [phm->obj_index],
420719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
421719f82d3SEliot Blennerhassett }
422719f82d3SEliot Blennerhassett }
4233285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock);
424719f82d3SEliot Blennerhassett }
425719f82d3SEliot Blennerhassett
instream_close(struct hpi_message * phm,struct hpi_response * phr,void * h_owner)426719f82d3SEliot Blennerhassett static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
427719f82d3SEliot Blennerhassett void *h_owner)
428719f82d3SEliot Blennerhassett {
429719f82d3SEliot Blennerhassett
430719f82d3SEliot Blennerhassett struct hpi_message hm;
431719f82d3SEliot Blennerhassett struct hpi_response hr;
432719f82d3SEliot Blennerhassett
433719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_ISTREAM, HPI_ISTREAM_CLOSE, 0);
434719f82d3SEliot Blennerhassett
435719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock);
436719f82d3SEliot Blennerhassett if (h_owner ==
437719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm->
438719f82d3SEliot Blennerhassett obj_index].h_owner) {
439719f82d3SEliot Blennerhassett /* HPI_DEBUG_LOG(INFO,"closing adapter %d "
440719f82d3SEliot Blennerhassett "instream %d owned by %p\n",
441719f82d3SEliot Blennerhassett phm->wAdapterIndex, phm->wObjIndex, hOwner); */
442719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm->
443719f82d3SEliot Blennerhassett obj_index].h_owner = NULL;
4443285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock);
445719f82d3SEliot Blennerhassett /* issue a reset */
446719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
447719f82d3SEliot Blennerhassett HPI_ISTREAM_RESET);
448719f82d3SEliot Blennerhassett hm.adapter_index = phm->adapter_index;
449719f82d3SEliot Blennerhassett hm.obj_index = phm->obj_index;
450719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr);
451719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock);
452719f82d3SEliot Blennerhassett if (hr.error) {
453719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm->
454719f82d3SEliot Blennerhassett obj_index].h_owner = h_owner;
455719f82d3SEliot Blennerhassett phr->error = hr.error;
456719f82d3SEliot Blennerhassett } else {
457719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm->
458719f82d3SEliot Blennerhassett obj_index].open_flag = 0;
459719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm->
460719f82d3SEliot Blennerhassett obj_index].h_owner = NULL;
461719f82d3SEliot Blennerhassett }
462719f82d3SEliot Blennerhassett } else {
463719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(WARNING,
464719f82d3SEliot Blennerhassett "%p trying to close %d instream %d owned by %p\n",
465719f82d3SEliot Blennerhassett h_owner, phm->adapter_index, phm->obj_index,
466719f82d3SEliot Blennerhassett instream_user_open[phm->adapter_index][phm->
467719f82d3SEliot Blennerhassett obj_index].h_owner);
468719f82d3SEliot Blennerhassett phr->error = HPI_ERROR_OBJ_NOT_OPEN;
469719f82d3SEliot Blennerhassett }
4703285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock);
471719f82d3SEliot Blennerhassett }
472719f82d3SEliot Blennerhassett
outstream_open(struct hpi_message * phm,struct hpi_response * phr,void * h_owner)473719f82d3SEliot Blennerhassett static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
474719f82d3SEliot Blennerhassett void *h_owner)
475719f82d3SEliot Blennerhassett {
476719f82d3SEliot Blennerhassett
477719f82d3SEliot Blennerhassett struct hpi_message hm;
478719f82d3SEliot Blennerhassett struct hpi_response hr;
479719f82d3SEliot Blennerhassett
480719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_OSTREAM, HPI_OSTREAM_OPEN, 0);
481719f82d3SEliot Blennerhassett
482719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock);
483719f82d3SEliot Blennerhassett
484719f82d3SEliot Blennerhassett if (outstream_user_open[phm->adapter_index][phm->obj_index].open_flag)
485719f82d3SEliot Blennerhassett phr->error = HPI_ERROR_OBJ_ALREADY_OPEN;
486719f82d3SEliot Blennerhassett else if (rESP_HPI_OSTREAM_OPEN[phm->adapter_index]
487719f82d3SEliot Blennerhassett [phm->obj_index].h.error)
488719f82d3SEliot Blennerhassett memcpy(phr,
489719f82d3SEliot Blennerhassett &rESP_HPI_OSTREAM_OPEN[phm->adapter_index][phm->
490719f82d3SEliot Blennerhassett obj_index],
491719f82d3SEliot Blennerhassett sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
492719f82d3SEliot Blennerhassett else {
493719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm->
494719f82d3SEliot Blennerhassett obj_index].open_flag = 1;
4953285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock);
496719f82d3SEliot Blennerhassett
497719f82d3SEliot Blennerhassett /* issue a reset */
498719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
499719f82d3SEliot Blennerhassett HPI_OSTREAM_RESET);
500719f82d3SEliot Blennerhassett hm.adapter_index = phm->adapter_index;
501719f82d3SEliot Blennerhassett hm.obj_index = phm->obj_index;
502719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr);
503719f82d3SEliot Blennerhassett
504719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock);
505719f82d3SEliot Blennerhassett if (hr.error) {
506719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm->
507719f82d3SEliot Blennerhassett obj_index].open_flag = 0;
508719f82d3SEliot Blennerhassett phr->error = hr.error;
509719f82d3SEliot Blennerhassett } else {
510719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm->
511719f82d3SEliot Blennerhassett obj_index].open_flag = 1;
512719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm->
513719f82d3SEliot Blennerhassett obj_index].h_owner = h_owner;
514719f82d3SEliot Blennerhassett memcpy(phr,
515719f82d3SEliot Blennerhassett &rESP_HPI_OSTREAM_OPEN[phm->adapter_index]
516719f82d3SEliot Blennerhassett [phm->obj_index],
517719f82d3SEliot Blennerhassett sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
518719f82d3SEliot Blennerhassett }
519719f82d3SEliot Blennerhassett }
5203285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock);
521719f82d3SEliot Blennerhassett }
522719f82d3SEliot Blennerhassett
outstream_close(struct hpi_message * phm,struct hpi_response * phr,void * h_owner)523719f82d3SEliot Blennerhassett static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
524719f82d3SEliot Blennerhassett void *h_owner)
525719f82d3SEliot Blennerhassett {
526719f82d3SEliot Blennerhassett
527719f82d3SEliot Blennerhassett struct hpi_message hm;
528719f82d3SEliot Blennerhassett struct hpi_response hr;
529719f82d3SEliot Blennerhassett
530719f82d3SEliot Blennerhassett hpi_init_response(phr, HPI_OBJ_OSTREAM, HPI_OSTREAM_CLOSE, 0);
531719f82d3SEliot Blennerhassett
532719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock);
533719f82d3SEliot Blennerhassett
534719f82d3SEliot Blennerhassett if (h_owner ==
535719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm->
536719f82d3SEliot Blennerhassett obj_index].h_owner) {
537719f82d3SEliot Blennerhassett /* HPI_DEBUG_LOG(INFO,"closing adapter %d "
538719f82d3SEliot Blennerhassett "outstream %d owned by %p\n",
539719f82d3SEliot Blennerhassett phm->wAdapterIndex, phm->wObjIndex, hOwner); */
540719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm->
541719f82d3SEliot Blennerhassett obj_index].h_owner = NULL;
5423285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock);
543719f82d3SEliot Blennerhassett /* issue a reset */
544719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
545719f82d3SEliot Blennerhassett HPI_OSTREAM_RESET);
546719f82d3SEliot Blennerhassett hm.adapter_index = phm->adapter_index;
547719f82d3SEliot Blennerhassett hm.obj_index = phm->obj_index;
548719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr);
549719f82d3SEliot Blennerhassett hpios_msgxlock_lock(&msgx_lock);
550719f82d3SEliot Blennerhassett if (hr.error) {
551719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm->
552719f82d3SEliot Blennerhassett obj_index].h_owner = h_owner;
553719f82d3SEliot Blennerhassett phr->error = hr.error;
554719f82d3SEliot Blennerhassett } else {
555719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm->
556719f82d3SEliot Blennerhassett obj_index].open_flag = 0;
557719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm->
558719f82d3SEliot Blennerhassett obj_index].h_owner = NULL;
559719f82d3SEliot Blennerhassett }
560719f82d3SEliot Blennerhassett } else {
561719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(WARNING,
562719f82d3SEliot Blennerhassett "%p trying to close %d outstream %d owned by %p\n",
563719f82d3SEliot Blennerhassett h_owner, phm->adapter_index, phm->obj_index,
564719f82d3SEliot Blennerhassett outstream_user_open[phm->adapter_index][phm->
565719f82d3SEliot Blennerhassett obj_index].h_owner);
566719f82d3SEliot Blennerhassett phr->error = HPI_ERROR_OBJ_NOT_OPEN;
567719f82d3SEliot Blennerhassett }
5683285ea10SEliot Blennerhassett hpios_msgxlock_unlock(&msgx_lock);
569719f82d3SEliot Blennerhassett }
570719f82d3SEliot Blennerhassett
adapter_prepare(u16 adapter)571719f82d3SEliot Blennerhassett static u16 adapter_prepare(u16 adapter)
572719f82d3SEliot Blennerhassett {
573719f82d3SEliot Blennerhassett struct hpi_message hm;
574719f82d3SEliot Blennerhassett struct hpi_response hr;
575719f82d3SEliot Blennerhassett
576719f82d3SEliot Blennerhassett /* Open the adapter and streams */
577719f82d3SEliot Blennerhassett u16 i;
578719f82d3SEliot Blennerhassett
579719f82d3SEliot Blennerhassett /* call to HPI_ADAPTER_OPEN */
580719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
581719f82d3SEliot Blennerhassett HPI_ADAPTER_OPEN);
582719f82d3SEliot Blennerhassett hm.adapter_index = adapter;
583719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr);
584719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_ADAPTER_OPEN[adapter], &hr,
585719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ADAPTER_OPEN[0]));
586719f82d3SEliot Blennerhassett if (hr.error)
587719f82d3SEliot Blennerhassett return hr.error;
588719f82d3SEliot Blennerhassett
589719f82d3SEliot Blennerhassett /* call to HPI_ADAPTER_GET_INFO */
590719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
591719f82d3SEliot Blennerhassett HPI_ADAPTER_GET_INFO);
592719f82d3SEliot Blennerhassett hm.adapter_index = adapter;
593719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr);
594719f82d3SEliot Blennerhassett if (hr.error)
595719f82d3SEliot Blennerhassett return hr.error;
596719f82d3SEliot Blennerhassett
5973285ea10SEliot Blennerhassett aDAPTER_INFO[adapter].num_outstreams = hr.u.ax.info.num_outstreams;
5983285ea10SEliot Blennerhassett aDAPTER_INFO[adapter].num_instreams = hr.u.ax.info.num_instreams;
5993285ea10SEliot Blennerhassett aDAPTER_INFO[adapter].type = hr.u.ax.info.adapter_type;
600719f82d3SEliot Blennerhassett
601719f82d3SEliot Blennerhassett /* call to HPI_OSTREAM_OPEN */
602719f82d3SEliot Blennerhassett for (i = 0; i < aDAPTER_INFO[adapter].num_outstreams; i++) {
603719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
604719f82d3SEliot Blennerhassett HPI_OSTREAM_OPEN);
605719f82d3SEliot Blennerhassett hm.adapter_index = adapter;
606719f82d3SEliot Blennerhassett hm.obj_index = i;
607719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr);
608719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_OSTREAM_OPEN[adapter][i], &hr,
609719f82d3SEliot Blennerhassett sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
610719f82d3SEliot Blennerhassett outstream_user_open[adapter][i].open_flag = 0;
611719f82d3SEliot Blennerhassett outstream_user_open[adapter][i].h_owner = NULL;
612719f82d3SEliot Blennerhassett }
613719f82d3SEliot Blennerhassett
614719f82d3SEliot Blennerhassett /* call to HPI_ISTREAM_OPEN */
615719f82d3SEliot Blennerhassett for (i = 0; i < aDAPTER_INFO[adapter].num_instreams; i++) {
616719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
617719f82d3SEliot Blennerhassett HPI_ISTREAM_OPEN);
618719f82d3SEliot Blennerhassett hm.adapter_index = adapter;
619719f82d3SEliot Blennerhassett hm.obj_index = i;
620719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr);
621719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_ISTREAM_OPEN[adapter][i], &hr,
622719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
623719f82d3SEliot Blennerhassett instream_user_open[adapter][i].open_flag = 0;
624719f82d3SEliot Blennerhassett instream_user_open[adapter][i].h_owner = NULL;
625719f82d3SEliot Blennerhassett }
626719f82d3SEliot Blennerhassett
627719f82d3SEliot Blennerhassett /* call to HPI_MIXER_OPEN */
628719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN);
629719f82d3SEliot Blennerhassett hm.adapter_index = adapter;
630719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr);
631719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr,
632719f82d3SEliot Blennerhassett sizeof(rESP_HPI_MIXER_OPEN[0]));
633719f82d3SEliot Blennerhassett
6343285ea10SEliot Blennerhassett return 0;
635719f82d3SEliot Blennerhassett }
636719f82d3SEliot Blennerhassett
HPIMSGX__reset(u16 adapter_index)637719f82d3SEliot Blennerhassett static void HPIMSGX__reset(u16 adapter_index)
638719f82d3SEliot Blennerhassett {
639719f82d3SEliot Blennerhassett int i;
640719f82d3SEliot Blennerhassett u16 adapter;
641719f82d3SEliot Blennerhassett struct hpi_response hr;
642719f82d3SEliot Blennerhassett
643719f82d3SEliot Blennerhassett if (adapter_index == HPIMSGX_ALLADAPTERS) {
644719f82d3SEliot Blennerhassett for (adapter = 0; adapter < HPI_MAX_ADAPTERS; adapter++) {
645719f82d3SEliot Blennerhassett
646719f82d3SEliot Blennerhassett hpi_init_response(&hr, HPI_OBJ_ADAPTER,
647719f82d3SEliot Blennerhassett HPI_ADAPTER_OPEN, HPI_ERROR_BAD_ADAPTER);
648719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_ADAPTER_OPEN[adapter], &hr,
649719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ADAPTER_OPEN[adapter]));
650719f82d3SEliot Blennerhassett
651719f82d3SEliot Blennerhassett hpi_init_response(&hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN,
652719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ);
653719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr,
654719f82d3SEliot Blennerhassett sizeof(rESP_HPI_MIXER_OPEN[adapter]));
655719f82d3SEliot Blennerhassett
656719f82d3SEliot Blennerhassett for (i = 0; i < HPI_MAX_STREAMS; i++) {
657719f82d3SEliot Blennerhassett hpi_init_response(&hr, HPI_OBJ_OSTREAM,
658719f82d3SEliot Blennerhassett HPI_OSTREAM_OPEN,
659719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ);
660719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_OSTREAM_OPEN[adapter][i],
661719f82d3SEliot Blennerhassett &hr,
662719f82d3SEliot Blennerhassett sizeof(rESP_HPI_OSTREAM_OPEN[adapter]
663719f82d3SEliot Blennerhassett [i]));
664719f82d3SEliot Blennerhassett hpi_init_response(&hr, HPI_OBJ_ISTREAM,
665719f82d3SEliot Blennerhassett HPI_ISTREAM_OPEN,
666719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ);
667719f82d3SEliot Blennerhassett memcpy(&rESP_HPI_ISTREAM_OPEN[adapter][i],
668719f82d3SEliot Blennerhassett &hr,
669719f82d3SEliot Blennerhassett sizeof(rESP_HPI_ISTREAM_OPEN[adapter]
670719f82d3SEliot Blennerhassett [i]));
671719f82d3SEliot Blennerhassett }
672719f82d3SEliot Blennerhassett }
673719f82d3SEliot Blennerhassett } else if (adapter_index < HPI_MAX_ADAPTERS) {
674719f82d3SEliot Blennerhassett rESP_HPI_ADAPTER_OPEN[adapter_index].h.error =
675719f82d3SEliot Blennerhassett HPI_ERROR_BAD_ADAPTER;
676719f82d3SEliot Blennerhassett rESP_HPI_MIXER_OPEN[adapter_index].h.error =
677719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ;
678719f82d3SEliot Blennerhassett for (i = 0; i < HPI_MAX_STREAMS; i++) {
679719f82d3SEliot Blennerhassett rESP_HPI_OSTREAM_OPEN[adapter_index][i].h.error =
680719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ;
681719f82d3SEliot Blennerhassett rESP_HPI_ISTREAM_OPEN[adapter_index][i].h.error =
682719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ;
683719f82d3SEliot Blennerhassett }
684719f82d3SEliot Blennerhassett }
685719f82d3SEliot Blennerhassett }
686719f82d3SEliot Blennerhassett
HPIMSGX__init(struct hpi_message * phm,struct hpi_response * phr)687719f82d3SEliot Blennerhassett static u16 HPIMSGX__init(struct hpi_message *phm,
688719f82d3SEliot Blennerhassett /* HPI_SUBSYS_CREATE_ADAPTER structure with */
689719f82d3SEliot Blennerhassett /* resource list or NULL=find all */
690719f82d3SEliot Blennerhassett struct hpi_response *phr
691719f82d3SEliot Blennerhassett /* response from HPI_ADAPTER_GET_INFO */
692719f82d3SEliot Blennerhassett )
693719f82d3SEliot Blennerhassett {
694719f82d3SEliot Blennerhassett hpi_handler_func *entry_point_func;
695719f82d3SEliot Blennerhassett struct hpi_response hr;
696719f82d3SEliot Blennerhassett
697719f82d3SEliot Blennerhassett /* Init response here so we can pass in previous adapter list */
698719f82d3SEliot Blennerhassett hpi_init_response(&hr, phm->object, phm->function,
699719f82d3SEliot Blennerhassett HPI_ERROR_INVALID_OBJ);
700719f82d3SEliot Blennerhassett
701719f82d3SEliot Blennerhassett entry_point_func =
702719f82d3SEliot Blennerhassett hpi_lookup_entry_point_function(phm->u.s.resource.r.pci);
703719f82d3SEliot Blennerhassett
704719f82d3SEliot Blennerhassett if (entry_point_func) {
705719f82d3SEliot Blennerhassett HPI_DEBUG_MESSAGE(DEBUG, phm);
706719f82d3SEliot Blennerhassett entry_point_func(phm, &hr);
707719f82d3SEliot Blennerhassett } else {
708719f82d3SEliot Blennerhassett phr->error = HPI_ERROR_PROCESSING_MESSAGE;
709719f82d3SEliot Blennerhassett return phr->error;
710719f82d3SEliot Blennerhassett }
711*7a557409STakashi Iwai if (hr.error == 0 && hr.u.s.adapter_index < HPI_MAX_ADAPTERS) {
71225985edcSLucas De Marchi /* the adapter was created successfully
713719f82d3SEliot Blennerhassett save the mapping for future use */
714719f82d3SEliot Blennerhassett hpi_entry_points[hr.u.s.adapter_index] = entry_point_func;
715719f82d3SEliot Blennerhassett /* prepare adapter (pre-open streams etc.) */
716719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(DEBUG,
717719f82d3SEliot Blennerhassett "HPI_SUBSYS_CREATE_ADAPTER successful,"
718719f82d3SEliot Blennerhassett " preparing adapter\n");
719719f82d3SEliot Blennerhassett adapter_prepare(hr.u.s.adapter_index);
720719f82d3SEliot Blennerhassett }
721719f82d3SEliot Blennerhassett memcpy(phr, &hr, hr.size);
722719f82d3SEliot Blennerhassett return phr->error;
723719f82d3SEliot Blennerhassett }
724719f82d3SEliot Blennerhassett
HPIMSGX__cleanup(u16 adapter_index,void * h_owner)725719f82d3SEliot Blennerhassett static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner)
726719f82d3SEliot Blennerhassett {
727719f82d3SEliot Blennerhassett int i, adapter, adapter_limit;
728719f82d3SEliot Blennerhassett
729719f82d3SEliot Blennerhassett if (!h_owner)
730719f82d3SEliot Blennerhassett return;
731719f82d3SEliot Blennerhassett
732719f82d3SEliot Blennerhassett if (adapter_index == HPIMSGX_ALLADAPTERS) {
733719f82d3SEliot Blennerhassett adapter = 0;
734719f82d3SEliot Blennerhassett adapter_limit = HPI_MAX_ADAPTERS;
735719f82d3SEliot Blennerhassett } else {
736719f82d3SEliot Blennerhassett adapter = adapter_index;
737719f82d3SEliot Blennerhassett adapter_limit = adapter + 1;
738719f82d3SEliot Blennerhassett }
739719f82d3SEliot Blennerhassett
740719f82d3SEliot Blennerhassett for (; adapter < adapter_limit; adapter++) {
741719f82d3SEliot Blennerhassett /* printk(KERN_INFO "Cleanup adapter #%d\n",wAdapter); */
742719f82d3SEliot Blennerhassett for (i = 0; i < HPI_MAX_STREAMS; i++) {
743719f82d3SEliot Blennerhassett if (h_owner ==
744719f82d3SEliot Blennerhassett outstream_user_open[adapter][i].h_owner) {
745719f82d3SEliot Blennerhassett struct hpi_message hm;
746719f82d3SEliot Blennerhassett struct hpi_response hr;
747719f82d3SEliot Blennerhassett
748719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(DEBUG,
7493285ea10SEliot Blennerhassett "Close adapter %d ostream %d\n",
750719f82d3SEliot Blennerhassett adapter, i);
751719f82d3SEliot Blennerhassett
752719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr,
753719f82d3SEliot Blennerhassett HPI_OBJ_OSTREAM, HPI_OSTREAM_RESET);
754719f82d3SEliot Blennerhassett hm.adapter_index = (u16)adapter;
755719f82d3SEliot Blennerhassett hm.obj_index = (u16)i;
756719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr);
757719f82d3SEliot Blennerhassett
758719f82d3SEliot Blennerhassett hm.function = HPI_OSTREAM_HOSTBUFFER_FREE;
759719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr);
760719f82d3SEliot Blennerhassett
761719f82d3SEliot Blennerhassett hm.function = HPI_OSTREAM_GROUP_RESET;
762719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr);
763719f82d3SEliot Blennerhassett
764719f82d3SEliot Blennerhassett outstream_user_open[adapter][i].open_flag = 0;
765719f82d3SEliot Blennerhassett outstream_user_open[adapter][i].h_owner =
766719f82d3SEliot Blennerhassett NULL;
767719f82d3SEliot Blennerhassett }
768719f82d3SEliot Blennerhassett if (h_owner == instream_user_open[adapter][i].h_owner) {
769719f82d3SEliot Blennerhassett struct hpi_message hm;
770719f82d3SEliot Blennerhassett struct hpi_response hr;
771719f82d3SEliot Blennerhassett
772719f82d3SEliot Blennerhassett HPI_DEBUG_LOG(DEBUG,
7733285ea10SEliot Blennerhassett "Close adapter %d istream %d\n",
774719f82d3SEliot Blennerhassett adapter, i);
775719f82d3SEliot Blennerhassett
776719f82d3SEliot Blennerhassett hpi_init_message_response(&hm, &hr,
777719f82d3SEliot Blennerhassett HPI_OBJ_ISTREAM, HPI_ISTREAM_RESET);
778719f82d3SEliot Blennerhassett hm.adapter_index = (u16)adapter;
779719f82d3SEliot Blennerhassett hm.obj_index = (u16)i;
780719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr);
781719f82d3SEliot Blennerhassett
782719f82d3SEliot Blennerhassett hm.function = HPI_ISTREAM_HOSTBUFFER_FREE;
783719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr);
784719f82d3SEliot Blennerhassett
785719f82d3SEliot Blennerhassett hm.function = HPI_ISTREAM_GROUP_RESET;
786719f82d3SEliot Blennerhassett hw_entry_point(&hm, &hr);
787719f82d3SEliot Blennerhassett
788719f82d3SEliot Blennerhassett instream_user_open[adapter][i].open_flag = 0;
789719f82d3SEliot Blennerhassett instream_user_open[adapter][i].h_owner = NULL;
790719f82d3SEliot Blennerhassett }
791719f82d3SEliot Blennerhassett }
792719f82d3SEliot Blennerhassett }
793719f82d3SEliot Blennerhassett }
794