xref: /openbmc/linux/sound/pci/asihpi/hpimsgx.c (revision 719f82d3987aad4cc9f46d19c35f362672545cad)
1*719f82d3SEliot Blennerhassett /******************************************************************************
2*719f82d3SEliot Blennerhassett 
3*719f82d3SEliot Blennerhassett     AudioScience HPI driver
4*719f82d3SEliot Blennerhassett     Copyright (C) 1997-2010  AudioScience Inc. <support@audioscience.com>
5*719f82d3SEliot Blennerhassett 
6*719f82d3SEliot Blennerhassett     This program is free software; you can redistribute it and/or modify
7*719f82d3SEliot Blennerhassett     it under the terms of version 2 of the GNU General Public License as
8*719f82d3SEliot Blennerhassett     published by the Free Software Foundation;
9*719f82d3SEliot Blennerhassett 
10*719f82d3SEliot Blennerhassett     This program is distributed in the hope that it will be useful,
11*719f82d3SEliot Blennerhassett     but WITHOUT ANY WARRANTY; without even the implied warranty of
12*719f82d3SEliot Blennerhassett     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13*719f82d3SEliot Blennerhassett     GNU General Public License for more details.
14*719f82d3SEliot Blennerhassett 
15*719f82d3SEliot Blennerhassett     You should have received a copy of the GNU General Public License
16*719f82d3SEliot Blennerhassett     along with this program; if not, write to the Free Software
17*719f82d3SEliot Blennerhassett     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18*719f82d3SEliot Blennerhassett 
19*719f82d3SEliot Blennerhassett Extended Message Function With Response Cacheing
20*719f82d3SEliot Blennerhassett 
21*719f82d3SEliot Blennerhassett (C) Copyright AudioScience Inc. 2002
22*719f82d3SEliot Blennerhassett *****************************************************************************/
23*719f82d3SEliot Blennerhassett #define SOURCEFILE_NAME "hpimsgx.c"
24*719f82d3SEliot Blennerhassett #include "hpi_internal.h"
25*719f82d3SEliot Blennerhassett #include "hpimsginit.h"
26*719f82d3SEliot Blennerhassett #include "hpimsgx.h"
27*719f82d3SEliot Blennerhassett #include "hpidebug.h"
28*719f82d3SEliot Blennerhassett 
29*719f82d3SEliot Blennerhassett static struct pci_device_id asihpi_pci_tbl[] = {
30*719f82d3SEliot Blennerhassett #include "hpipcida.h"
31*719f82d3SEliot Blennerhassett };
32*719f82d3SEliot Blennerhassett 
33*719f82d3SEliot Blennerhassett static struct hpios_spinlock msgx_lock;
34*719f82d3SEliot Blennerhassett 
35*719f82d3SEliot Blennerhassett static hpi_handler_func *hpi_entry_points[HPI_MAX_ADAPTERS];
36*719f82d3SEliot Blennerhassett 
37*719f82d3SEliot Blennerhassett static hpi_handler_func *hpi_lookup_entry_point_function(const struct hpi_pci
38*719f82d3SEliot Blennerhassett 	*pci_info)
39*719f82d3SEliot Blennerhassett {
40*719f82d3SEliot Blennerhassett 
41*719f82d3SEliot Blennerhassett 	int i;
42*719f82d3SEliot Blennerhassett 
43*719f82d3SEliot Blennerhassett 	for (i = 0; asihpi_pci_tbl[i].vendor != 0; i++) {
44*719f82d3SEliot Blennerhassett 		if (asihpi_pci_tbl[i].vendor != PCI_ANY_ID
45*719f82d3SEliot Blennerhassett 			&& asihpi_pci_tbl[i].vendor != pci_info->vendor_id)
46*719f82d3SEliot Blennerhassett 			continue;
47*719f82d3SEliot Blennerhassett 		if (asihpi_pci_tbl[i].device != PCI_ANY_ID
48*719f82d3SEliot Blennerhassett 			&& asihpi_pci_tbl[i].device != pci_info->device_id)
49*719f82d3SEliot Blennerhassett 			continue;
50*719f82d3SEliot Blennerhassett 		if (asihpi_pci_tbl[i].subvendor != PCI_ANY_ID
51*719f82d3SEliot Blennerhassett 			&& asihpi_pci_tbl[i].subvendor !=
52*719f82d3SEliot Blennerhassett 			pci_info->subsys_vendor_id)
53*719f82d3SEliot Blennerhassett 			continue;
54*719f82d3SEliot Blennerhassett 		if (asihpi_pci_tbl[i].subdevice != PCI_ANY_ID
55*719f82d3SEliot Blennerhassett 			&& asihpi_pci_tbl[i].subdevice !=
56*719f82d3SEliot Blennerhassett 			pci_info->subsys_device_id)
57*719f82d3SEliot Blennerhassett 			continue;
58*719f82d3SEliot Blennerhassett 
59*719f82d3SEliot Blennerhassett 		HPI_DEBUG_LOG(DEBUG, " %x,%lu\n", i,
60*719f82d3SEliot Blennerhassett 			asihpi_pci_tbl[i].driver_data);
61*719f82d3SEliot Blennerhassett 		return (hpi_handler_func *) asihpi_pci_tbl[i].driver_data;
62*719f82d3SEliot Blennerhassett 	}
63*719f82d3SEliot Blennerhassett 
64*719f82d3SEliot Blennerhassett 	return NULL;
65*719f82d3SEliot Blennerhassett }
66*719f82d3SEliot Blennerhassett 
67*719f82d3SEliot Blennerhassett static inline void hw_entry_point(struct hpi_message *phm,
68*719f82d3SEliot Blennerhassett 	struct hpi_response *phr)
69*719f82d3SEliot Blennerhassett {
70*719f82d3SEliot Blennerhassett 
71*719f82d3SEliot Blennerhassett 	hpi_handler_func *ep;
72*719f82d3SEliot Blennerhassett 
73*719f82d3SEliot Blennerhassett 	if (phm->adapter_index < HPI_MAX_ADAPTERS) {
74*719f82d3SEliot Blennerhassett 		ep = (hpi_handler_func *) hpi_entry_points[phm->
75*719f82d3SEliot Blennerhassett 			adapter_index];
76*719f82d3SEliot Blennerhassett 		if (ep) {
77*719f82d3SEliot Blennerhassett 			HPI_DEBUG_MESSAGE(DEBUG, phm);
78*719f82d3SEliot Blennerhassett 			ep(phm, phr);
79*719f82d3SEliot Blennerhassett 			HPI_DEBUG_RESPONSE(phr);
80*719f82d3SEliot Blennerhassett 			return;
81*719f82d3SEliot Blennerhassett 		}
82*719f82d3SEliot Blennerhassett 	}
83*719f82d3SEliot Blennerhassett 	hpi_init_response(phr, phm->object, phm->function,
84*719f82d3SEliot Blennerhassett 		HPI_ERROR_PROCESSING_MESSAGE);
85*719f82d3SEliot Blennerhassett }
86*719f82d3SEliot Blennerhassett 
87*719f82d3SEliot Blennerhassett static void adapter_open(struct hpi_message *phm, struct hpi_response *phr);
88*719f82d3SEliot Blennerhassett static void adapter_close(struct hpi_message *phm, struct hpi_response *phr);
89*719f82d3SEliot Blennerhassett 
90*719f82d3SEliot Blennerhassett static void mixer_open(struct hpi_message *phm, struct hpi_response *phr);
91*719f82d3SEliot Blennerhassett static void mixer_close(struct hpi_message *phm, struct hpi_response *phr);
92*719f82d3SEliot Blennerhassett 
93*719f82d3SEliot Blennerhassett static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
94*719f82d3SEliot Blennerhassett 	void *h_owner);
95*719f82d3SEliot Blennerhassett static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
96*719f82d3SEliot Blennerhassett 	void *h_owner);
97*719f82d3SEliot Blennerhassett static void instream_open(struct hpi_message *phm, struct hpi_response *phr,
98*719f82d3SEliot Blennerhassett 	void *h_owner);
99*719f82d3SEliot Blennerhassett static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
100*719f82d3SEliot Blennerhassett 	void *h_owner);
101*719f82d3SEliot Blennerhassett 
102*719f82d3SEliot Blennerhassett static void HPIMSGX__reset(u16 adapter_index);
103*719f82d3SEliot Blennerhassett static u16 HPIMSGX__init(struct hpi_message *phm, struct hpi_response *phr);
104*719f82d3SEliot Blennerhassett static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner);
105*719f82d3SEliot Blennerhassett 
106*719f82d3SEliot Blennerhassett #ifndef DISABLE_PRAGMA_PACK1
107*719f82d3SEliot Blennerhassett #pragma pack(push, 1)
108*719f82d3SEliot Blennerhassett #endif
109*719f82d3SEliot Blennerhassett 
110*719f82d3SEliot Blennerhassett struct hpi_subsys_response {
111*719f82d3SEliot Blennerhassett 	struct hpi_response_header h;
112*719f82d3SEliot Blennerhassett 	struct hpi_subsys_res s;
113*719f82d3SEliot Blennerhassett };
114*719f82d3SEliot Blennerhassett 
115*719f82d3SEliot Blennerhassett struct hpi_adapter_response {
116*719f82d3SEliot Blennerhassett 	struct hpi_response_header h;
117*719f82d3SEliot Blennerhassett 	struct hpi_adapter_res a;
118*719f82d3SEliot Blennerhassett };
119*719f82d3SEliot Blennerhassett 
120*719f82d3SEliot Blennerhassett struct hpi_mixer_response {
121*719f82d3SEliot Blennerhassett 	struct hpi_response_header h;
122*719f82d3SEliot Blennerhassett 	struct hpi_mixer_res m;
123*719f82d3SEliot Blennerhassett };
124*719f82d3SEliot Blennerhassett 
125*719f82d3SEliot Blennerhassett struct hpi_stream_response {
126*719f82d3SEliot Blennerhassett 	struct hpi_response_header h;
127*719f82d3SEliot Blennerhassett 	struct hpi_stream_res d;
128*719f82d3SEliot Blennerhassett };
129*719f82d3SEliot Blennerhassett 
130*719f82d3SEliot Blennerhassett struct adapter_info {
131*719f82d3SEliot Blennerhassett 	u16 type;
132*719f82d3SEliot Blennerhassett 	u16 num_instreams;
133*719f82d3SEliot Blennerhassett 	u16 num_outstreams;
134*719f82d3SEliot Blennerhassett };
135*719f82d3SEliot Blennerhassett 
136*719f82d3SEliot Blennerhassett struct asi_open_state {
137*719f82d3SEliot Blennerhassett 	int open_flag;
138*719f82d3SEliot Blennerhassett 	void *h_owner;
139*719f82d3SEliot Blennerhassett };
140*719f82d3SEliot Blennerhassett 
141*719f82d3SEliot Blennerhassett #ifndef DISABLE_PRAGMA_PACK1
142*719f82d3SEliot Blennerhassett #pragma pack(pop)
143*719f82d3SEliot Blennerhassett #endif
144*719f82d3SEliot Blennerhassett 
145*719f82d3SEliot Blennerhassett /* Globals */
146*719f82d3SEliot Blennerhassett static struct hpi_adapter_response rESP_HPI_ADAPTER_OPEN[HPI_MAX_ADAPTERS];
147*719f82d3SEliot Blennerhassett 
148*719f82d3SEliot Blennerhassett static struct hpi_stream_response
149*719f82d3SEliot Blennerhassett 	rESP_HPI_OSTREAM_OPEN[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
150*719f82d3SEliot Blennerhassett 
151*719f82d3SEliot Blennerhassett static struct hpi_stream_response
152*719f82d3SEliot Blennerhassett 	rESP_HPI_ISTREAM_OPEN[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
153*719f82d3SEliot Blennerhassett 
154*719f82d3SEliot Blennerhassett static struct hpi_mixer_response rESP_HPI_MIXER_OPEN[HPI_MAX_ADAPTERS];
155*719f82d3SEliot Blennerhassett 
156*719f82d3SEliot Blennerhassett static struct hpi_subsys_response gRESP_HPI_SUBSYS_FIND_ADAPTERS;
157*719f82d3SEliot Blennerhassett 
158*719f82d3SEliot Blennerhassett static struct adapter_info aDAPTER_INFO[HPI_MAX_ADAPTERS];
159*719f82d3SEliot Blennerhassett 
160*719f82d3SEliot Blennerhassett /* use these to keep track of opens from user mode apps/DLLs */
161*719f82d3SEliot Blennerhassett static struct asi_open_state
162*719f82d3SEliot Blennerhassett 	outstream_user_open[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
163*719f82d3SEliot Blennerhassett 
164*719f82d3SEliot Blennerhassett static struct asi_open_state
165*719f82d3SEliot Blennerhassett 	instream_user_open[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
166*719f82d3SEliot Blennerhassett 
167*719f82d3SEliot Blennerhassett static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
168*719f82d3SEliot Blennerhassett 	void *h_owner)
169*719f82d3SEliot Blennerhassett {
170*719f82d3SEliot Blennerhassett 	switch (phm->function) {
171*719f82d3SEliot Blennerhassett 	case HPI_SUBSYS_GET_VERSION:
172*719f82d3SEliot Blennerhassett 		hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
173*719f82d3SEliot Blennerhassett 			HPI_SUBSYS_GET_VERSION, 0);
174*719f82d3SEliot Blennerhassett 		phr->u.s.version = HPI_VER >> 8;	/* return major.minor */
175*719f82d3SEliot Blennerhassett 		phr->u.s.data = HPI_VER;	/* return major.minor.release */
176*719f82d3SEliot Blennerhassett 		break;
177*719f82d3SEliot Blennerhassett 	case HPI_SUBSYS_OPEN:
178*719f82d3SEliot Blennerhassett 		/*do not propagate the message down the chain */
179*719f82d3SEliot Blennerhassett 		hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_OPEN, 0);
180*719f82d3SEliot Blennerhassett 		break;
181*719f82d3SEliot Blennerhassett 	case HPI_SUBSYS_CLOSE:
182*719f82d3SEliot Blennerhassett 		/*do not propagate the message down the chain */
183*719f82d3SEliot Blennerhassett 		hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CLOSE,
184*719f82d3SEliot Blennerhassett 			0);
185*719f82d3SEliot Blennerhassett 		HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner);
186*719f82d3SEliot Blennerhassett 		break;
187*719f82d3SEliot Blennerhassett 	case HPI_SUBSYS_DRIVER_LOAD:
188*719f82d3SEliot Blennerhassett 		/* Initialize this module's internal state */
189*719f82d3SEliot Blennerhassett 		hpios_msgxlock_init(&msgx_lock);
190*719f82d3SEliot Blennerhassett 		memset(&hpi_entry_points, 0, sizeof(hpi_entry_points));
191*719f82d3SEliot Blennerhassett 		hpios_locked_mem_init();
192*719f82d3SEliot Blennerhassett 		/* Init subsys_findadapters response to no-adapters */
193*719f82d3SEliot Blennerhassett 		HPIMSGX__reset(HPIMSGX_ALLADAPTERS);
194*719f82d3SEliot Blennerhassett 		hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
195*719f82d3SEliot Blennerhassett 			HPI_SUBSYS_DRIVER_LOAD, 0);
196*719f82d3SEliot Blennerhassett 		/* individual HPIs dont implement driver load */
197*719f82d3SEliot Blennerhassett 		HPI_COMMON(phm, phr);
198*719f82d3SEliot Blennerhassett 		break;
199*719f82d3SEliot Blennerhassett 	case HPI_SUBSYS_DRIVER_UNLOAD:
200*719f82d3SEliot Blennerhassett 		HPI_COMMON(phm, phr);
201*719f82d3SEliot Blennerhassett 		HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner);
202*719f82d3SEliot Blennerhassett 		hpios_locked_mem_free_all();
203*719f82d3SEliot Blennerhassett 		hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
204*719f82d3SEliot Blennerhassett 			HPI_SUBSYS_DRIVER_UNLOAD, 0);
205*719f82d3SEliot Blennerhassett 		return;
206*719f82d3SEliot Blennerhassett 
207*719f82d3SEliot Blennerhassett 	case HPI_SUBSYS_GET_INFO:
208*719f82d3SEliot Blennerhassett 		HPI_COMMON(phm, phr);
209*719f82d3SEliot Blennerhassett 		break;
210*719f82d3SEliot Blennerhassett 
211*719f82d3SEliot Blennerhassett 	case HPI_SUBSYS_FIND_ADAPTERS:
212*719f82d3SEliot Blennerhassett 		memcpy(phr, &gRESP_HPI_SUBSYS_FIND_ADAPTERS,
213*719f82d3SEliot Blennerhassett 			sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS));
214*719f82d3SEliot Blennerhassett 		break;
215*719f82d3SEliot Blennerhassett 	case HPI_SUBSYS_GET_NUM_ADAPTERS:
216*719f82d3SEliot Blennerhassett 		memcpy(phr, &gRESP_HPI_SUBSYS_FIND_ADAPTERS,
217*719f82d3SEliot Blennerhassett 			sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS));
218*719f82d3SEliot Blennerhassett 		phr->function = HPI_SUBSYS_GET_NUM_ADAPTERS;
219*719f82d3SEliot Blennerhassett 		break;
220*719f82d3SEliot Blennerhassett 	case HPI_SUBSYS_GET_ADAPTER:
221*719f82d3SEliot Blennerhassett 		{
222*719f82d3SEliot Blennerhassett 			int count = phm->adapter_index;
223*719f82d3SEliot Blennerhassett 			int index = 0;
224*719f82d3SEliot Blennerhassett 			hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
225*719f82d3SEliot Blennerhassett 				HPI_SUBSYS_GET_ADAPTER, 0);
226*719f82d3SEliot Blennerhassett 
227*719f82d3SEliot Blennerhassett 			/* This is complicated by the fact that we want to
228*719f82d3SEliot Blennerhassett 			 * "skip" 0's in the adapter list.
229*719f82d3SEliot Blennerhassett 			 * First, make sure we are pointing to a
230*719f82d3SEliot Blennerhassett 			 * non-zero adapter type.
231*719f82d3SEliot Blennerhassett 			 */
232*719f82d3SEliot Blennerhassett 			while (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
233*719f82d3SEliot Blennerhassett 				s.aw_adapter_list[index] == 0) {
234*719f82d3SEliot Blennerhassett 				index++;
235*719f82d3SEliot Blennerhassett 				if (index >= HPI_MAX_ADAPTERS)
236*719f82d3SEliot Blennerhassett 					break;
237*719f82d3SEliot Blennerhassett 			}
238*719f82d3SEliot Blennerhassett 			while (count) {
239*719f82d3SEliot Blennerhassett 				/* move on to the next adapter */
240*719f82d3SEliot Blennerhassett 				index++;
241*719f82d3SEliot Blennerhassett 				if (index >= HPI_MAX_ADAPTERS)
242*719f82d3SEliot Blennerhassett 					break;
243*719f82d3SEliot Blennerhassett 				while (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
244*719f82d3SEliot Blennerhassett 					s.aw_adapter_list[index] == 0) {
245*719f82d3SEliot Blennerhassett 					index++;
246*719f82d3SEliot Blennerhassett 					if (index >= HPI_MAX_ADAPTERS)
247*719f82d3SEliot Blennerhassett 						break;
248*719f82d3SEliot Blennerhassett 				}
249*719f82d3SEliot Blennerhassett 				count--;
250*719f82d3SEliot Blennerhassett 			}
251*719f82d3SEliot Blennerhassett 
252*719f82d3SEliot Blennerhassett 			if (index < HPI_MAX_ADAPTERS) {
253*719f82d3SEliot Blennerhassett 				phr->u.s.adapter_index = (u16)index;
254*719f82d3SEliot Blennerhassett 				phr->u.s.aw_adapter_list[0] =
255*719f82d3SEliot Blennerhassett 					gRESP_HPI_SUBSYS_FIND_ADAPTERS.
256*719f82d3SEliot Blennerhassett 					s.aw_adapter_list[index];
257*719f82d3SEliot Blennerhassett 			} else {
258*719f82d3SEliot Blennerhassett 				phr->u.s.adapter_index = 0;
259*719f82d3SEliot Blennerhassett 				phr->u.s.aw_adapter_list[0] = 0;
260*719f82d3SEliot Blennerhassett 				phr->error = HPI_ERROR_BAD_ADAPTER_NUMBER;
261*719f82d3SEliot Blennerhassett 			}
262*719f82d3SEliot Blennerhassett 			break;
263*719f82d3SEliot Blennerhassett 		}
264*719f82d3SEliot Blennerhassett 	case HPI_SUBSYS_CREATE_ADAPTER:
265*719f82d3SEliot Blennerhassett 		HPIMSGX__init(phm, phr);
266*719f82d3SEliot Blennerhassett 		break;
267*719f82d3SEliot Blennerhassett 	case HPI_SUBSYS_DELETE_ADAPTER:
268*719f82d3SEliot Blennerhassett 		HPIMSGX__cleanup(phm->adapter_index, h_owner);
269*719f82d3SEliot Blennerhassett 		{
270*719f82d3SEliot Blennerhassett 			struct hpi_message hm;
271*719f82d3SEliot Blennerhassett 			struct hpi_response hr;
272*719f82d3SEliot Blennerhassett 			/* call to HPI_ADAPTER_CLOSE */
273*719f82d3SEliot Blennerhassett 			hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
274*719f82d3SEliot Blennerhassett 				HPI_ADAPTER_CLOSE);
275*719f82d3SEliot Blennerhassett 			hm.adapter_index = phm->adapter_index;
276*719f82d3SEliot Blennerhassett 			hw_entry_point(&hm, &hr);
277*719f82d3SEliot Blennerhassett 		}
278*719f82d3SEliot Blennerhassett 		hw_entry_point(phm, phr);
279*719f82d3SEliot Blennerhassett 		gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.
280*719f82d3SEliot Blennerhassett 			aw_adapter_list[phm->adapter_index]
281*719f82d3SEliot Blennerhassett 			= 0;
282*719f82d3SEliot Blennerhassett 		hpi_entry_points[phm->adapter_index] = NULL;
283*719f82d3SEliot Blennerhassett 		break;
284*719f82d3SEliot Blennerhassett 	default:
285*719f82d3SEliot Blennerhassett 		hw_entry_point(phm, phr);
286*719f82d3SEliot Blennerhassett 		break;
287*719f82d3SEliot Blennerhassett 	}
288*719f82d3SEliot Blennerhassett }
289*719f82d3SEliot Blennerhassett 
290*719f82d3SEliot Blennerhassett static void adapter_message(struct hpi_message *phm, struct hpi_response *phr,
291*719f82d3SEliot Blennerhassett 	void *h_owner)
292*719f82d3SEliot Blennerhassett {
293*719f82d3SEliot Blennerhassett 	switch (phm->function) {
294*719f82d3SEliot Blennerhassett 	case HPI_ADAPTER_OPEN:
295*719f82d3SEliot Blennerhassett 		adapter_open(phm, phr);
296*719f82d3SEliot Blennerhassett 		break;
297*719f82d3SEliot Blennerhassett 	case HPI_ADAPTER_CLOSE:
298*719f82d3SEliot Blennerhassett 		adapter_close(phm, phr);
299*719f82d3SEliot Blennerhassett 		break;
300*719f82d3SEliot Blennerhassett 	default:
301*719f82d3SEliot Blennerhassett 		hw_entry_point(phm, phr);
302*719f82d3SEliot Blennerhassett 		break;
303*719f82d3SEliot Blennerhassett 	}
304*719f82d3SEliot Blennerhassett }
305*719f82d3SEliot Blennerhassett 
306*719f82d3SEliot Blennerhassett static void mixer_message(struct hpi_message *phm, struct hpi_response *phr)
307*719f82d3SEliot Blennerhassett {
308*719f82d3SEliot Blennerhassett 	switch (phm->function) {
309*719f82d3SEliot Blennerhassett 	case HPI_MIXER_OPEN:
310*719f82d3SEliot Blennerhassett 		mixer_open(phm, phr);
311*719f82d3SEliot Blennerhassett 		break;
312*719f82d3SEliot Blennerhassett 	case HPI_MIXER_CLOSE:
313*719f82d3SEliot Blennerhassett 		mixer_close(phm, phr);
314*719f82d3SEliot Blennerhassett 		break;
315*719f82d3SEliot Blennerhassett 	default:
316*719f82d3SEliot Blennerhassett 		hw_entry_point(phm, phr);
317*719f82d3SEliot Blennerhassett 		break;
318*719f82d3SEliot Blennerhassett 	}
319*719f82d3SEliot Blennerhassett }
320*719f82d3SEliot Blennerhassett 
321*719f82d3SEliot Blennerhassett static void outstream_message(struct hpi_message *phm,
322*719f82d3SEliot Blennerhassett 	struct hpi_response *phr, void *h_owner)
323*719f82d3SEliot Blennerhassett {
324*719f82d3SEliot Blennerhassett 	if (phm->obj_index >= aDAPTER_INFO[phm->adapter_index].num_outstreams) {
325*719f82d3SEliot Blennerhassett 		hpi_init_response(phr, HPI_OBJ_OSTREAM, phm->function,
326*719f82d3SEliot Blennerhassett 			HPI_ERROR_INVALID_OBJ_INDEX);
327*719f82d3SEliot Blennerhassett 		return;
328*719f82d3SEliot Blennerhassett 	}
329*719f82d3SEliot Blennerhassett 
330*719f82d3SEliot Blennerhassett 	switch (phm->function) {
331*719f82d3SEliot Blennerhassett 	case HPI_OSTREAM_OPEN:
332*719f82d3SEliot Blennerhassett 		outstream_open(phm, phr, h_owner);
333*719f82d3SEliot Blennerhassett 		break;
334*719f82d3SEliot Blennerhassett 	case HPI_OSTREAM_CLOSE:
335*719f82d3SEliot Blennerhassett 		outstream_close(phm, phr, h_owner);
336*719f82d3SEliot Blennerhassett 		break;
337*719f82d3SEliot Blennerhassett 	default:
338*719f82d3SEliot Blennerhassett 		hw_entry_point(phm, phr);
339*719f82d3SEliot Blennerhassett 		break;
340*719f82d3SEliot Blennerhassett 	}
341*719f82d3SEliot Blennerhassett }
342*719f82d3SEliot Blennerhassett 
343*719f82d3SEliot Blennerhassett static void instream_message(struct hpi_message *phm,
344*719f82d3SEliot Blennerhassett 	struct hpi_response *phr, void *h_owner)
345*719f82d3SEliot Blennerhassett {
346*719f82d3SEliot Blennerhassett 	if (phm->obj_index >= aDAPTER_INFO[phm->adapter_index].num_instreams) {
347*719f82d3SEliot Blennerhassett 		hpi_init_response(phr, HPI_OBJ_ISTREAM, phm->function,
348*719f82d3SEliot Blennerhassett 			HPI_ERROR_INVALID_OBJ_INDEX);
349*719f82d3SEliot Blennerhassett 		return;
350*719f82d3SEliot Blennerhassett 	}
351*719f82d3SEliot Blennerhassett 
352*719f82d3SEliot Blennerhassett 	switch (phm->function) {
353*719f82d3SEliot Blennerhassett 	case HPI_ISTREAM_OPEN:
354*719f82d3SEliot Blennerhassett 		instream_open(phm, phr, h_owner);
355*719f82d3SEliot Blennerhassett 		break;
356*719f82d3SEliot Blennerhassett 	case HPI_ISTREAM_CLOSE:
357*719f82d3SEliot Blennerhassett 		instream_close(phm, phr, h_owner);
358*719f82d3SEliot Blennerhassett 		break;
359*719f82d3SEliot Blennerhassett 	default:
360*719f82d3SEliot Blennerhassett 		hw_entry_point(phm, phr);
361*719f82d3SEliot Blennerhassett 		break;
362*719f82d3SEliot Blennerhassett 	}
363*719f82d3SEliot Blennerhassett }
364*719f82d3SEliot Blennerhassett 
365*719f82d3SEliot Blennerhassett /* NOTE: HPI_Message() must be defined in the driver as a wrapper for
366*719f82d3SEliot Blennerhassett  * HPI_MessageEx so that functions in hpifunc.c compile.
367*719f82d3SEliot Blennerhassett  */
368*719f82d3SEliot Blennerhassett void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr,
369*719f82d3SEliot Blennerhassett 	void *h_owner)
370*719f82d3SEliot Blennerhassett {
371*719f82d3SEliot Blennerhassett 	HPI_DEBUG_MESSAGE(DEBUG, phm);
372*719f82d3SEliot Blennerhassett 
373*719f82d3SEliot Blennerhassett 	if (phm->type != HPI_TYPE_MESSAGE) {
374*719f82d3SEliot Blennerhassett 		hpi_init_response(phr, phm->object, phm->function,
375*719f82d3SEliot Blennerhassett 			HPI_ERROR_INVALID_TYPE);
376*719f82d3SEliot Blennerhassett 		return;
377*719f82d3SEliot Blennerhassett 	}
378*719f82d3SEliot Blennerhassett 
379*719f82d3SEliot Blennerhassett 	if (phm->adapter_index >= HPI_MAX_ADAPTERS
380*719f82d3SEliot Blennerhassett 		&& phm->adapter_index != HPIMSGX_ALLADAPTERS) {
381*719f82d3SEliot Blennerhassett 		hpi_init_response(phr, phm->object, phm->function,
382*719f82d3SEliot Blennerhassett 			HPI_ERROR_BAD_ADAPTER_NUMBER);
383*719f82d3SEliot Blennerhassett 		return;
384*719f82d3SEliot Blennerhassett 	}
385*719f82d3SEliot Blennerhassett 
386*719f82d3SEliot Blennerhassett 	switch (phm->object) {
387*719f82d3SEliot Blennerhassett 	case HPI_OBJ_SUBSYSTEM:
388*719f82d3SEliot Blennerhassett 		subsys_message(phm, phr, h_owner);
389*719f82d3SEliot Blennerhassett 		break;
390*719f82d3SEliot Blennerhassett 
391*719f82d3SEliot Blennerhassett 	case HPI_OBJ_ADAPTER:
392*719f82d3SEliot Blennerhassett 		adapter_message(phm, phr, h_owner);
393*719f82d3SEliot Blennerhassett 		break;
394*719f82d3SEliot Blennerhassett 
395*719f82d3SEliot Blennerhassett 	case HPI_OBJ_MIXER:
396*719f82d3SEliot Blennerhassett 		mixer_message(phm, phr);
397*719f82d3SEliot Blennerhassett 		break;
398*719f82d3SEliot Blennerhassett 
399*719f82d3SEliot Blennerhassett 	case HPI_OBJ_OSTREAM:
400*719f82d3SEliot Blennerhassett 		outstream_message(phm, phr, h_owner);
401*719f82d3SEliot Blennerhassett 		break;
402*719f82d3SEliot Blennerhassett 
403*719f82d3SEliot Blennerhassett 	case HPI_OBJ_ISTREAM:
404*719f82d3SEliot Blennerhassett 		instream_message(phm, phr, h_owner);
405*719f82d3SEliot Blennerhassett 		break;
406*719f82d3SEliot Blennerhassett 
407*719f82d3SEliot Blennerhassett 	default:
408*719f82d3SEliot Blennerhassett 		hw_entry_point(phm, phr);
409*719f82d3SEliot Blennerhassett 		break;
410*719f82d3SEliot Blennerhassett 	}
411*719f82d3SEliot Blennerhassett 	HPI_DEBUG_RESPONSE(phr);
412*719f82d3SEliot Blennerhassett #if 1
413*719f82d3SEliot Blennerhassett 	if (phr->error >= HPI_ERROR_BACKEND_BASE) {
414*719f82d3SEliot Blennerhassett 		void *ep = NULL;
415*719f82d3SEliot Blennerhassett 		char *ep_name;
416*719f82d3SEliot Blennerhassett 
417*719f82d3SEliot Blennerhassett 		HPI_DEBUG_MESSAGE(ERROR, phm);
418*719f82d3SEliot Blennerhassett 
419*719f82d3SEliot Blennerhassett 		if (phm->adapter_index < HPI_MAX_ADAPTERS)
420*719f82d3SEliot Blennerhassett 			ep = hpi_entry_points[phm->adapter_index];
421*719f82d3SEliot Blennerhassett 
422*719f82d3SEliot Blennerhassett 		/* Don't need this? Have adapter index in debug info
423*719f82d3SEliot Blennerhassett 		   Know at driver load time index->backend mapping */
424*719f82d3SEliot Blennerhassett 		if (ep == HPI_6000)
425*719f82d3SEliot Blennerhassett 			ep_name = "HPI_6000";
426*719f82d3SEliot Blennerhassett 		else if (ep == HPI_6205)
427*719f82d3SEliot Blennerhassett 			ep_name = "HPI_6205";
428*719f82d3SEliot Blennerhassett 		else
429*719f82d3SEliot Blennerhassett 			ep_name = "unknown";
430*719f82d3SEliot Blennerhassett 
431*719f82d3SEliot Blennerhassett 		HPI_DEBUG_LOG(ERROR, "HPI %s response - error# %d\n", ep_name,
432*719f82d3SEliot Blennerhassett 			phr->error);
433*719f82d3SEliot Blennerhassett 
434*719f82d3SEliot Blennerhassett 		if (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE)
435*719f82d3SEliot Blennerhassett 			hpi_debug_data((u16 *)phm,
436*719f82d3SEliot Blennerhassett 				sizeof(*phm) / sizeof(u16));
437*719f82d3SEliot Blennerhassett 	}
438*719f82d3SEliot Blennerhassett #endif
439*719f82d3SEliot Blennerhassett }
440*719f82d3SEliot Blennerhassett 
441*719f82d3SEliot Blennerhassett static void adapter_open(struct hpi_message *phm, struct hpi_response *phr)
442*719f82d3SEliot Blennerhassett {
443*719f82d3SEliot Blennerhassett 	HPI_DEBUG_LOG(VERBOSE, "adapter_open\n");
444*719f82d3SEliot Blennerhassett 	memcpy(phr, &rESP_HPI_ADAPTER_OPEN[phm->adapter_index],
445*719f82d3SEliot Blennerhassett 		sizeof(rESP_HPI_ADAPTER_OPEN[0]));
446*719f82d3SEliot Blennerhassett }
447*719f82d3SEliot Blennerhassett 
448*719f82d3SEliot Blennerhassett static void adapter_close(struct hpi_message *phm, struct hpi_response *phr)
449*719f82d3SEliot Blennerhassett {
450*719f82d3SEliot Blennerhassett 	HPI_DEBUG_LOG(VERBOSE, "adapter_close\n");
451*719f82d3SEliot Blennerhassett 	hpi_init_response(phr, HPI_OBJ_ADAPTER, HPI_ADAPTER_CLOSE, 0);
452*719f82d3SEliot Blennerhassett }
453*719f82d3SEliot Blennerhassett 
454*719f82d3SEliot Blennerhassett static void mixer_open(struct hpi_message *phm, struct hpi_response *phr)
455*719f82d3SEliot Blennerhassett {
456*719f82d3SEliot Blennerhassett 	memcpy(phr, &rESP_HPI_MIXER_OPEN[phm->adapter_index],
457*719f82d3SEliot Blennerhassett 		sizeof(rESP_HPI_MIXER_OPEN[0]));
458*719f82d3SEliot Blennerhassett }
459*719f82d3SEliot Blennerhassett 
460*719f82d3SEliot Blennerhassett static void mixer_close(struct hpi_message *phm, struct hpi_response *phr)
461*719f82d3SEliot Blennerhassett {
462*719f82d3SEliot Blennerhassett 	hpi_init_response(phr, HPI_OBJ_MIXER, HPI_MIXER_CLOSE, 0);
463*719f82d3SEliot Blennerhassett }
464*719f82d3SEliot Blennerhassett 
465*719f82d3SEliot Blennerhassett static void instream_open(struct hpi_message *phm, struct hpi_response *phr,
466*719f82d3SEliot Blennerhassett 	void *h_owner)
467*719f82d3SEliot Blennerhassett {
468*719f82d3SEliot Blennerhassett 
469*719f82d3SEliot Blennerhassett 	struct hpi_message hm;
470*719f82d3SEliot Blennerhassett 	struct hpi_response hr;
471*719f82d3SEliot Blennerhassett 
472*719f82d3SEliot Blennerhassett 	hpi_init_response(phr, HPI_OBJ_ISTREAM, HPI_ISTREAM_OPEN, 0);
473*719f82d3SEliot Blennerhassett 
474*719f82d3SEliot Blennerhassett 	hpios_msgxlock_lock(&msgx_lock);
475*719f82d3SEliot Blennerhassett 
476*719f82d3SEliot Blennerhassett 	if (instream_user_open[phm->adapter_index][phm->obj_index].open_flag)
477*719f82d3SEliot Blennerhassett 		phr->error = HPI_ERROR_OBJ_ALREADY_OPEN;
478*719f82d3SEliot Blennerhassett 	else if (rESP_HPI_ISTREAM_OPEN[phm->adapter_index]
479*719f82d3SEliot Blennerhassett 		[phm->obj_index].h.error)
480*719f82d3SEliot Blennerhassett 		memcpy(phr,
481*719f82d3SEliot Blennerhassett 			&rESP_HPI_ISTREAM_OPEN[phm->adapter_index][phm->
482*719f82d3SEliot Blennerhassett 				obj_index],
483*719f82d3SEliot Blennerhassett 			sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
484*719f82d3SEliot Blennerhassett 	else {
485*719f82d3SEliot Blennerhassett 		instream_user_open[phm->adapter_index][phm->
486*719f82d3SEliot Blennerhassett 			obj_index].open_flag = 1;
487*719f82d3SEliot Blennerhassett 		hpios_msgxlock_un_lock(&msgx_lock);
488*719f82d3SEliot Blennerhassett 
489*719f82d3SEliot Blennerhassett 		/* issue a reset */
490*719f82d3SEliot Blennerhassett 		hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
491*719f82d3SEliot Blennerhassett 			HPI_ISTREAM_RESET);
492*719f82d3SEliot Blennerhassett 		hm.adapter_index = phm->adapter_index;
493*719f82d3SEliot Blennerhassett 		hm.obj_index = phm->obj_index;
494*719f82d3SEliot Blennerhassett 		hw_entry_point(&hm, &hr);
495*719f82d3SEliot Blennerhassett 
496*719f82d3SEliot Blennerhassett 		hpios_msgxlock_lock(&msgx_lock);
497*719f82d3SEliot Blennerhassett 		if (hr.error) {
498*719f82d3SEliot Blennerhassett 			instream_user_open[phm->adapter_index][phm->
499*719f82d3SEliot Blennerhassett 				obj_index].open_flag = 0;
500*719f82d3SEliot Blennerhassett 			phr->error = hr.error;
501*719f82d3SEliot Blennerhassett 		} else {
502*719f82d3SEliot Blennerhassett 			instream_user_open[phm->adapter_index][phm->
503*719f82d3SEliot Blennerhassett 				obj_index].open_flag = 1;
504*719f82d3SEliot Blennerhassett 			instream_user_open[phm->adapter_index][phm->
505*719f82d3SEliot Blennerhassett 				obj_index].h_owner = h_owner;
506*719f82d3SEliot Blennerhassett 			memcpy(phr,
507*719f82d3SEliot Blennerhassett 				&rESP_HPI_ISTREAM_OPEN[phm->adapter_index]
508*719f82d3SEliot Blennerhassett 				[phm->obj_index],
509*719f82d3SEliot Blennerhassett 				sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
510*719f82d3SEliot Blennerhassett 		}
511*719f82d3SEliot Blennerhassett 	}
512*719f82d3SEliot Blennerhassett 	hpios_msgxlock_un_lock(&msgx_lock);
513*719f82d3SEliot Blennerhassett }
514*719f82d3SEliot Blennerhassett 
515*719f82d3SEliot Blennerhassett static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
516*719f82d3SEliot Blennerhassett 	void *h_owner)
517*719f82d3SEliot Blennerhassett {
518*719f82d3SEliot Blennerhassett 
519*719f82d3SEliot Blennerhassett 	struct hpi_message hm;
520*719f82d3SEliot Blennerhassett 	struct hpi_response hr;
521*719f82d3SEliot Blennerhassett 
522*719f82d3SEliot Blennerhassett 	hpi_init_response(phr, HPI_OBJ_ISTREAM, HPI_ISTREAM_CLOSE, 0);
523*719f82d3SEliot Blennerhassett 
524*719f82d3SEliot Blennerhassett 	hpios_msgxlock_lock(&msgx_lock);
525*719f82d3SEliot Blennerhassett 	if (h_owner ==
526*719f82d3SEliot Blennerhassett 		instream_user_open[phm->adapter_index][phm->
527*719f82d3SEliot Blennerhassett 			obj_index].h_owner) {
528*719f82d3SEliot Blennerhassett 		/* HPI_DEBUG_LOG(INFO,"closing adapter %d "
529*719f82d3SEliot Blennerhassett 		   "instream %d owned by %p\n",
530*719f82d3SEliot Blennerhassett 		   phm->wAdapterIndex, phm->wObjIndex, hOwner); */
531*719f82d3SEliot Blennerhassett 		instream_user_open[phm->adapter_index][phm->
532*719f82d3SEliot Blennerhassett 			obj_index].h_owner = NULL;
533*719f82d3SEliot Blennerhassett 		hpios_msgxlock_un_lock(&msgx_lock);
534*719f82d3SEliot Blennerhassett 		/* issue a reset */
535*719f82d3SEliot Blennerhassett 		hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
536*719f82d3SEliot Blennerhassett 			HPI_ISTREAM_RESET);
537*719f82d3SEliot Blennerhassett 		hm.adapter_index = phm->adapter_index;
538*719f82d3SEliot Blennerhassett 		hm.obj_index = phm->obj_index;
539*719f82d3SEliot Blennerhassett 		hw_entry_point(&hm, &hr);
540*719f82d3SEliot Blennerhassett 		hpios_msgxlock_lock(&msgx_lock);
541*719f82d3SEliot Blennerhassett 		if (hr.error) {
542*719f82d3SEliot Blennerhassett 			instream_user_open[phm->adapter_index][phm->
543*719f82d3SEliot Blennerhassett 				obj_index].h_owner = h_owner;
544*719f82d3SEliot Blennerhassett 			phr->error = hr.error;
545*719f82d3SEliot Blennerhassett 		} else {
546*719f82d3SEliot Blennerhassett 			instream_user_open[phm->adapter_index][phm->
547*719f82d3SEliot Blennerhassett 				obj_index].open_flag = 0;
548*719f82d3SEliot Blennerhassett 			instream_user_open[phm->adapter_index][phm->
549*719f82d3SEliot Blennerhassett 				obj_index].h_owner = NULL;
550*719f82d3SEliot Blennerhassett 		}
551*719f82d3SEliot Blennerhassett 	} else {
552*719f82d3SEliot Blennerhassett 		HPI_DEBUG_LOG(WARNING,
553*719f82d3SEliot Blennerhassett 			"%p trying to close %d instream %d owned by %p\n",
554*719f82d3SEliot Blennerhassett 			h_owner, phm->adapter_index, phm->obj_index,
555*719f82d3SEliot Blennerhassett 			instream_user_open[phm->adapter_index][phm->
556*719f82d3SEliot Blennerhassett 				obj_index].h_owner);
557*719f82d3SEliot Blennerhassett 		phr->error = HPI_ERROR_OBJ_NOT_OPEN;
558*719f82d3SEliot Blennerhassett 	}
559*719f82d3SEliot Blennerhassett 	hpios_msgxlock_un_lock(&msgx_lock);
560*719f82d3SEliot Blennerhassett }
561*719f82d3SEliot Blennerhassett 
562*719f82d3SEliot Blennerhassett static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
563*719f82d3SEliot Blennerhassett 	void *h_owner)
564*719f82d3SEliot Blennerhassett {
565*719f82d3SEliot Blennerhassett 
566*719f82d3SEliot Blennerhassett 	struct hpi_message hm;
567*719f82d3SEliot Blennerhassett 	struct hpi_response hr;
568*719f82d3SEliot Blennerhassett 
569*719f82d3SEliot Blennerhassett 	hpi_init_response(phr, HPI_OBJ_OSTREAM, HPI_OSTREAM_OPEN, 0);
570*719f82d3SEliot Blennerhassett 
571*719f82d3SEliot Blennerhassett 	hpios_msgxlock_lock(&msgx_lock);
572*719f82d3SEliot Blennerhassett 
573*719f82d3SEliot Blennerhassett 	if (outstream_user_open[phm->adapter_index][phm->obj_index].open_flag)
574*719f82d3SEliot Blennerhassett 		phr->error = HPI_ERROR_OBJ_ALREADY_OPEN;
575*719f82d3SEliot Blennerhassett 	else if (rESP_HPI_OSTREAM_OPEN[phm->adapter_index]
576*719f82d3SEliot Blennerhassett 		[phm->obj_index].h.error)
577*719f82d3SEliot Blennerhassett 		memcpy(phr,
578*719f82d3SEliot Blennerhassett 			&rESP_HPI_OSTREAM_OPEN[phm->adapter_index][phm->
579*719f82d3SEliot Blennerhassett 				obj_index],
580*719f82d3SEliot Blennerhassett 			sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
581*719f82d3SEliot Blennerhassett 	else {
582*719f82d3SEliot Blennerhassett 		outstream_user_open[phm->adapter_index][phm->
583*719f82d3SEliot Blennerhassett 			obj_index].open_flag = 1;
584*719f82d3SEliot Blennerhassett 		hpios_msgxlock_un_lock(&msgx_lock);
585*719f82d3SEliot Blennerhassett 
586*719f82d3SEliot Blennerhassett 		/* issue a reset */
587*719f82d3SEliot Blennerhassett 		hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
588*719f82d3SEliot Blennerhassett 			HPI_OSTREAM_RESET);
589*719f82d3SEliot Blennerhassett 		hm.adapter_index = phm->adapter_index;
590*719f82d3SEliot Blennerhassett 		hm.obj_index = phm->obj_index;
591*719f82d3SEliot Blennerhassett 		hw_entry_point(&hm, &hr);
592*719f82d3SEliot Blennerhassett 
593*719f82d3SEliot Blennerhassett 		hpios_msgxlock_lock(&msgx_lock);
594*719f82d3SEliot Blennerhassett 		if (hr.error) {
595*719f82d3SEliot Blennerhassett 			outstream_user_open[phm->adapter_index][phm->
596*719f82d3SEliot Blennerhassett 				obj_index].open_flag = 0;
597*719f82d3SEliot Blennerhassett 			phr->error = hr.error;
598*719f82d3SEliot Blennerhassett 		} else {
599*719f82d3SEliot Blennerhassett 			outstream_user_open[phm->adapter_index][phm->
600*719f82d3SEliot Blennerhassett 				obj_index].open_flag = 1;
601*719f82d3SEliot Blennerhassett 			outstream_user_open[phm->adapter_index][phm->
602*719f82d3SEliot Blennerhassett 				obj_index].h_owner = h_owner;
603*719f82d3SEliot Blennerhassett 			memcpy(phr,
604*719f82d3SEliot Blennerhassett 				&rESP_HPI_OSTREAM_OPEN[phm->adapter_index]
605*719f82d3SEliot Blennerhassett 				[phm->obj_index],
606*719f82d3SEliot Blennerhassett 				sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
607*719f82d3SEliot Blennerhassett 		}
608*719f82d3SEliot Blennerhassett 	}
609*719f82d3SEliot Blennerhassett 	hpios_msgxlock_un_lock(&msgx_lock);
610*719f82d3SEliot Blennerhassett }
611*719f82d3SEliot Blennerhassett 
612*719f82d3SEliot Blennerhassett static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
613*719f82d3SEliot Blennerhassett 	void *h_owner)
614*719f82d3SEliot Blennerhassett {
615*719f82d3SEliot Blennerhassett 
616*719f82d3SEliot Blennerhassett 	struct hpi_message hm;
617*719f82d3SEliot Blennerhassett 	struct hpi_response hr;
618*719f82d3SEliot Blennerhassett 
619*719f82d3SEliot Blennerhassett 	hpi_init_response(phr, HPI_OBJ_OSTREAM, HPI_OSTREAM_CLOSE, 0);
620*719f82d3SEliot Blennerhassett 
621*719f82d3SEliot Blennerhassett 	hpios_msgxlock_lock(&msgx_lock);
622*719f82d3SEliot Blennerhassett 
623*719f82d3SEliot Blennerhassett 	if (h_owner ==
624*719f82d3SEliot Blennerhassett 		outstream_user_open[phm->adapter_index][phm->
625*719f82d3SEliot Blennerhassett 			obj_index].h_owner) {
626*719f82d3SEliot Blennerhassett 		/* HPI_DEBUG_LOG(INFO,"closing adapter %d "
627*719f82d3SEliot Blennerhassett 		   "outstream %d owned by %p\n",
628*719f82d3SEliot Blennerhassett 		   phm->wAdapterIndex, phm->wObjIndex, hOwner); */
629*719f82d3SEliot Blennerhassett 		outstream_user_open[phm->adapter_index][phm->
630*719f82d3SEliot Blennerhassett 			obj_index].h_owner = NULL;
631*719f82d3SEliot Blennerhassett 		hpios_msgxlock_un_lock(&msgx_lock);
632*719f82d3SEliot Blennerhassett 		/* issue a reset */
633*719f82d3SEliot Blennerhassett 		hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
634*719f82d3SEliot Blennerhassett 			HPI_OSTREAM_RESET);
635*719f82d3SEliot Blennerhassett 		hm.adapter_index = phm->adapter_index;
636*719f82d3SEliot Blennerhassett 		hm.obj_index = phm->obj_index;
637*719f82d3SEliot Blennerhassett 		hw_entry_point(&hm, &hr);
638*719f82d3SEliot Blennerhassett 		hpios_msgxlock_lock(&msgx_lock);
639*719f82d3SEliot Blennerhassett 		if (hr.error) {
640*719f82d3SEliot Blennerhassett 			outstream_user_open[phm->adapter_index][phm->
641*719f82d3SEliot Blennerhassett 				obj_index].h_owner = h_owner;
642*719f82d3SEliot Blennerhassett 			phr->error = hr.error;
643*719f82d3SEliot Blennerhassett 		} else {
644*719f82d3SEliot Blennerhassett 			outstream_user_open[phm->adapter_index][phm->
645*719f82d3SEliot Blennerhassett 				obj_index].open_flag = 0;
646*719f82d3SEliot Blennerhassett 			outstream_user_open[phm->adapter_index][phm->
647*719f82d3SEliot Blennerhassett 				obj_index].h_owner = NULL;
648*719f82d3SEliot Blennerhassett 		}
649*719f82d3SEliot Blennerhassett 	} else {
650*719f82d3SEliot Blennerhassett 		HPI_DEBUG_LOG(WARNING,
651*719f82d3SEliot Blennerhassett 			"%p trying to close %d outstream %d owned by %p\n",
652*719f82d3SEliot Blennerhassett 			h_owner, phm->adapter_index, phm->obj_index,
653*719f82d3SEliot Blennerhassett 			outstream_user_open[phm->adapter_index][phm->
654*719f82d3SEliot Blennerhassett 				obj_index].h_owner);
655*719f82d3SEliot Blennerhassett 		phr->error = HPI_ERROR_OBJ_NOT_OPEN;
656*719f82d3SEliot Blennerhassett 	}
657*719f82d3SEliot Blennerhassett 	hpios_msgxlock_un_lock(&msgx_lock);
658*719f82d3SEliot Blennerhassett }
659*719f82d3SEliot Blennerhassett 
660*719f82d3SEliot Blennerhassett static u16 adapter_prepare(u16 adapter)
661*719f82d3SEliot Blennerhassett {
662*719f82d3SEliot Blennerhassett 	struct hpi_message hm;
663*719f82d3SEliot Blennerhassett 	struct hpi_response hr;
664*719f82d3SEliot Blennerhassett 
665*719f82d3SEliot Blennerhassett 	/* Open the adapter and streams */
666*719f82d3SEliot Blennerhassett 	u16 i;
667*719f82d3SEliot Blennerhassett 
668*719f82d3SEliot Blennerhassett 	/* call to HPI_ADAPTER_OPEN */
669*719f82d3SEliot Blennerhassett 	hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
670*719f82d3SEliot Blennerhassett 		HPI_ADAPTER_OPEN);
671*719f82d3SEliot Blennerhassett 	hm.adapter_index = adapter;
672*719f82d3SEliot Blennerhassett 	hw_entry_point(&hm, &hr);
673*719f82d3SEliot Blennerhassett 	memcpy(&rESP_HPI_ADAPTER_OPEN[adapter], &hr,
674*719f82d3SEliot Blennerhassett 		sizeof(rESP_HPI_ADAPTER_OPEN[0]));
675*719f82d3SEliot Blennerhassett 	if (hr.error)
676*719f82d3SEliot Blennerhassett 		return hr.error;
677*719f82d3SEliot Blennerhassett 
678*719f82d3SEliot Blennerhassett 	/* call to HPI_ADAPTER_GET_INFO */
679*719f82d3SEliot Blennerhassett 	hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
680*719f82d3SEliot Blennerhassett 		HPI_ADAPTER_GET_INFO);
681*719f82d3SEliot Blennerhassett 	hm.adapter_index = adapter;
682*719f82d3SEliot Blennerhassett 	hw_entry_point(&hm, &hr);
683*719f82d3SEliot Blennerhassett 	if (hr.error)
684*719f82d3SEliot Blennerhassett 		return hr.error;
685*719f82d3SEliot Blennerhassett 
686*719f82d3SEliot Blennerhassett 	aDAPTER_INFO[adapter].num_outstreams = hr.u.a.num_outstreams;
687*719f82d3SEliot Blennerhassett 	aDAPTER_INFO[adapter].num_instreams = hr.u.a.num_instreams;
688*719f82d3SEliot Blennerhassett 	aDAPTER_INFO[adapter].type = hr.u.a.adapter_type;
689*719f82d3SEliot Blennerhassett 
690*719f82d3SEliot Blennerhassett 	gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list[adapter] =
691*719f82d3SEliot Blennerhassett 		hr.u.a.adapter_type;
692*719f82d3SEliot Blennerhassett 	gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters++;
693*719f82d3SEliot Blennerhassett 	if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters > HPI_MAX_ADAPTERS)
694*719f82d3SEliot Blennerhassett 		gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters =
695*719f82d3SEliot Blennerhassett 			HPI_MAX_ADAPTERS;
696*719f82d3SEliot Blennerhassett 
697*719f82d3SEliot Blennerhassett 	/* call to HPI_OSTREAM_OPEN */
698*719f82d3SEliot Blennerhassett 	for (i = 0; i < aDAPTER_INFO[adapter].num_outstreams; i++) {
699*719f82d3SEliot Blennerhassett 		hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
700*719f82d3SEliot Blennerhassett 			HPI_OSTREAM_OPEN);
701*719f82d3SEliot Blennerhassett 		hm.adapter_index = adapter;
702*719f82d3SEliot Blennerhassett 		hm.obj_index = i;
703*719f82d3SEliot Blennerhassett 		hw_entry_point(&hm, &hr);
704*719f82d3SEliot Blennerhassett 		memcpy(&rESP_HPI_OSTREAM_OPEN[adapter][i], &hr,
705*719f82d3SEliot Blennerhassett 			sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
706*719f82d3SEliot Blennerhassett 		outstream_user_open[adapter][i].open_flag = 0;
707*719f82d3SEliot Blennerhassett 		outstream_user_open[adapter][i].h_owner = NULL;
708*719f82d3SEliot Blennerhassett 	}
709*719f82d3SEliot Blennerhassett 
710*719f82d3SEliot Blennerhassett 	/* call to HPI_ISTREAM_OPEN */
711*719f82d3SEliot Blennerhassett 	for (i = 0; i < aDAPTER_INFO[adapter].num_instreams; i++) {
712*719f82d3SEliot Blennerhassett 		hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
713*719f82d3SEliot Blennerhassett 			HPI_ISTREAM_OPEN);
714*719f82d3SEliot Blennerhassett 		hm.adapter_index = adapter;
715*719f82d3SEliot Blennerhassett 		hm.obj_index = i;
716*719f82d3SEliot Blennerhassett 		hw_entry_point(&hm, &hr);
717*719f82d3SEliot Blennerhassett 		memcpy(&rESP_HPI_ISTREAM_OPEN[adapter][i], &hr,
718*719f82d3SEliot Blennerhassett 			sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
719*719f82d3SEliot Blennerhassett 		instream_user_open[adapter][i].open_flag = 0;
720*719f82d3SEliot Blennerhassett 		instream_user_open[adapter][i].h_owner = NULL;
721*719f82d3SEliot Blennerhassett 	}
722*719f82d3SEliot Blennerhassett 
723*719f82d3SEliot Blennerhassett 	/* call to HPI_MIXER_OPEN */
724*719f82d3SEliot Blennerhassett 	hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN);
725*719f82d3SEliot Blennerhassett 	hm.adapter_index = adapter;
726*719f82d3SEliot Blennerhassett 	hw_entry_point(&hm, &hr);
727*719f82d3SEliot Blennerhassett 	memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr,
728*719f82d3SEliot Blennerhassett 		sizeof(rESP_HPI_MIXER_OPEN[0]));
729*719f82d3SEliot Blennerhassett 
730*719f82d3SEliot Blennerhassett 	return gRESP_HPI_SUBSYS_FIND_ADAPTERS.h.error;
731*719f82d3SEliot Blennerhassett }
732*719f82d3SEliot Blennerhassett 
733*719f82d3SEliot Blennerhassett static void HPIMSGX__reset(u16 adapter_index)
734*719f82d3SEliot Blennerhassett {
735*719f82d3SEliot Blennerhassett 	int i;
736*719f82d3SEliot Blennerhassett 	u16 adapter;
737*719f82d3SEliot Blennerhassett 	struct hpi_response hr;
738*719f82d3SEliot Blennerhassett 
739*719f82d3SEliot Blennerhassett 	if (adapter_index == HPIMSGX_ALLADAPTERS) {
740*719f82d3SEliot Blennerhassett 		/* reset all responses to contain errors */
741*719f82d3SEliot Blennerhassett 		hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM,
742*719f82d3SEliot Blennerhassett 			HPI_SUBSYS_FIND_ADAPTERS, 0);
743*719f82d3SEliot Blennerhassett 		memcpy(&gRESP_HPI_SUBSYS_FIND_ADAPTERS, &hr,
744*719f82d3SEliot Blennerhassett 			sizeof(&gRESP_HPI_SUBSYS_FIND_ADAPTERS));
745*719f82d3SEliot Blennerhassett 
746*719f82d3SEliot Blennerhassett 		for (adapter = 0; adapter < HPI_MAX_ADAPTERS; adapter++) {
747*719f82d3SEliot Blennerhassett 
748*719f82d3SEliot Blennerhassett 			hpi_init_response(&hr, HPI_OBJ_ADAPTER,
749*719f82d3SEliot Blennerhassett 				HPI_ADAPTER_OPEN, HPI_ERROR_BAD_ADAPTER);
750*719f82d3SEliot Blennerhassett 			memcpy(&rESP_HPI_ADAPTER_OPEN[adapter], &hr,
751*719f82d3SEliot Blennerhassett 				sizeof(rESP_HPI_ADAPTER_OPEN[adapter]));
752*719f82d3SEliot Blennerhassett 
753*719f82d3SEliot Blennerhassett 			hpi_init_response(&hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN,
754*719f82d3SEliot Blennerhassett 				HPI_ERROR_INVALID_OBJ);
755*719f82d3SEliot Blennerhassett 			memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr,
756*719f82d3SEliot Blennerhassett 				sizeof(rESP_HPI_MIXER_OPEN[adapter]));
757*719f82d3SEliot Blennerhassett 
758*719f82d3SEliot Blennerhassett 			for (i = 0; i < HPI_MAX_STREAMS; i++) {
759*719f82d3SEliot Blennerhassett 				hpi_init_response(&hr, HPI_OBJ_OSTREAM,
760*719f82d3SEliot Blennerhassett 					HPI_OSTREAM_OPEN,
761*719f82d3SEliot Blennerhassett 					HPI_ERROR_INVALID_OBJ);
762*719f82d3SEliot Blennerhassett 				memcpy(&rESP_HPI_OSTREAM_OPEN[adapter][i],
763*719f82d3SEliot Blennerhassett 					&hr,
764*719f82d3SEliot Blennerhassett 					sizeof(rESP_HPI_OSTREAM_OPEN[adapter]
765*719f82d3SEliot Blennerhassett 						[i]));
766*719f82d3SEliot Blennerhassett 				hpi_init_response(&hr, HPI_OBJ_ISTREAM,
767*719f82d3SEliot Blennerhassett 					HPI_ISTREAM_OPEN,
768*719f82d3SEliot Blennerhassett 					HPI_ERROR_INVALID_OBJ);
769*719f82d3SEliot Blennerhassett 				memcpy(&rESP_HPI_ISTREAM_OPEN[adapter][i],
770*719f82d3SEliot Blennerhassett 					&hr,
771*719f82d3SEliot Blennerhassett 					sizeof(rESP_HPI_ISTREAM_OPEN[adapter]
772*719f82d3SEliot Blennerhassett 						[i]));
773*719f82d3SEliot Blennerhassett 			}
774*719f82d3SEliot Blennerhassett 		}
775*719f82d3SEliot Blennerhassett 	} else if (adapter_index < HPI_MAX_ADAPTERS) {
776*719f82d3SEliot Blennerhassett 		rESP_HPI_ADAPTER_OPEN[adapter_index].h.error =
777*719f82d3SEliot Blennerhassett 			HPI_ERROR_BAD_ADAPTER;
778*719f82d3SEliot Blennerhassett 		rESP_HPI_MIXER_OPEN[adapter_index].h.error =
779*719f82d3SEliot Blennerhassett 			HPI_ERROR_INVALID_OBJ;
780*719f82d3SEliot Blennerhassett 		for (i = 0; i < HPI_MAX_STREAMS; i++) {
781*719f82d3SEliot Blennerhassett 			rESP_HPI_OSTREAM_OPEN[adapter_index][i].h.error =
782*719f82d3SEliot Blennerhassett 				HPI_ERROR_INVALID_OBJ;
783*719f82d3SEliot Blennerhassett 			rESP_HPI_ISTREAM_OPEN[adapter_index][i].h.error =
784*719f82d3SEliot Blennerhassett 				HPI_ERROR_INVALID_OBJ;
785*719f82d3SEliot Blennerhassett 		}
786*719f82d3SEliot Blennerhassett 		if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
787*719f82d3SEliot Blennerhassett 			s.aw_adapter_list[adapter_index]) {
788*719f82d3SEliot Blennerhassett 			gRESP_HPI_SUBSYS_FIND_ADAPTERS.
789*719f82d3SEliot Blennerhassett 				s.aw_adapter_list[adapter_index] = 0;
790*719f82d3SEliot Blennerhassett 			gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters--;
791*719f82d3SEliot Blennerhassett 		}
792*719f82d3SEliot Blennerhassett 	}
793*719f82d3SEliot Blennerhassett }
794*719f82d3SEliot Blennerhassett 
795*719f82d3SEliot Blennerhassett static u16 HPIMSGX__init(struct hpi_message *phm,
796*719f82d3SEliot Blennerhassett 	/* HPI_SUBSYS_CREATE_ADAPTER structure with */
797*719f82d3SEliot Blennerhassett 	/* resource list or NULL=find all */
798*719f82d3SEliot Blennerhassett 	struct hpi_response *phr
799*719f82d3SEliot Blennerhassett 	/* response from HPI_ADAPTER_GET_INFO */
800*719f82d3SEliot Blennerhassett 	)
801*719f82d3SEliot Blennerhassett {
802*719f82d3SEliot Blennerhassett 	hpi_handler_func *entry_point_func;
803*719f82d3SEliot Blennerhassett 	struct hpi_response hr;
804*719f82d3SEliot Blennerhassett 
805*719f82d3SEliot Blennerhassett 	if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters >= HPI_MAX_ADAPTERS)
806*719f82d3SEliot Blennerhassett 		return HPI_ERROR_BAD_ADAPTER_NUMBER;
807*719f82d3SEliot Blennerhassett 
808*719f82d3SEliot Blennerhassett 	/* Init response here so we can pass in previous adapter list */
809*719f82d3SEliot Blennerhassett 	hpi_init_response(&hr, phm->object, phm->function,
810*719f82d3SEliot Blennerhassett 		HPI_ERROR_INVALID_OBJ);
811*719f82d3SEliot Blennerhassett 	memcpy(hr.u.s.aw_adapter_list,
812*719f82d3SEliot Blennerhassett 		gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list,
813*719f82d3SEliot Blennerhassett 		sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list));
814*719f82d3SEliot Blennerhassett 
815*719f82d3SEliot Blennerhassett 	entry_point_func =
816*719f82d3SEliot Blennerhassett 		hpi_lookup_entry_point_function(phm->u.s.resource.r.pci);
817*719f82d3SEliot Blennerhassett 
818*719f82d3SEliot Blennerhassett 	if (entry_point_func) {
819*719f82d3SEliot Blennerhassett 		HPI_DEBUG_MESSAGE(DEBUG, phm);
820*719f82d3SEliot Blennerhassett 		entry_point_func(phm, &hr);
821*719f82d3SEliot Blennerhassett 	} else {
822*719f82d3SEliot Blennerhassett 		phr->error = HPI_ERROR_PROCESSING_MESSAGE;
823*719f82d3SEliot Blennerhassett 		return phr->error;
824*719f82d3SEliot Blennerhassett 	}
825*719f82d3SEliot Blennerhassett 	if (hr.error == 0) {
826*719f82d3SEliot Blennerhassett 		/* the adapter was created succesfully
827*719f82d3SEliot Blennerhassett 		   save the mapping for future use */
828*719f82d3SEliot Blennerhassett 		hpi_entry_points[hr.u.s.adapter_index] = entry_point_func;
829*719f82d3SEliot Blennerhassett 		/* prepare adapter (pre-open streams etc.) */
830*719f82d3SEliot Blennerhassett 		HPI_DEBUG_LOG(DEBUG,
831*719f82d3SEliot Blennerhassett 			"HPI_SUBSYS_CREATE_ADAPTER successful,"
832*719f82d3SEliot Blennerhassett 			" preparing adapter\n");
833*719f82d3SEliot Blennerhassett 		adapter_prepare(hr.u.s.adapter_index);
834*719f82d3SEliot Blennerhassett 	}
835*719f82d3SEliot Blennerhassett 	memcpy(phr, &hr, hr.size);
836*719f82d3SEliot Blennerhassett 	return phr->error;
837*719f82d3SEliot Blennerhassett }
838*719f82d3SEliot Blennerhassett 
839*719f82d3SEliot Blennerhassett static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner)
840*719f82d3SEliot Blennerhassett {
841*719f82d3SEliot Blennerhassett 	int i, adapter, adapter_limit;
842*719f82d3SEliot Blennerhassett 
843*719f82d3SEliot Blennerhassett 	if (!h_owner)
844*719f82d3SEliot Blennerhassett 		return;
845*719f82d3SEliot Blennerhassett 
846*719f82d3SEliot Blennerhassett 	if (adapter_index == HPIMSGX_ALLADAPTERS) {
847*719f82d3SEliot Blennerhassett 		adapter = 0;
848*719f82d3SEliot Blennerhassett 		adapter_limit = HPI_MAX_ADAPTERS;
849*719f82d3SEliot Blennerhassett 	} else {
850*719f82d3SEliot Blennerhassett 		adapter = adapter_index;
851*719f82d3SEliot Blennerhassett 		adapter_limit = adapter + 1;
852*719f82d3SEliot Blennerhassett 	}
853*719f82d3SEliot Blennerhassett 
854*719f82d3SEliot Blennerhassett 	for (; adapter < adapter_limit; adapter++) {
855*719f82d3SEliot Blennerhassett 		/*      printk(KERN_INFO "Cleanup adapter #%d\n",wAdapter); */
856*719f82d3SEliot Blennerhassett 		for (i = 0; i < HPI_MAX_STREAMS; i++) {
857*719f82d3SEliot Blennerhassett 			if (h_owner ==
858*719f82d3SEliot Blennerhassett 				outstream_user_open[adapter][i].h_owner) {
859*719f82d3SEliot Blennerhassett 				struct hpi_message hm;
860*719f82d3SEliot Blennerhassett 				struct hpi_response hr;
861*719f82d3SEliot Blennerhassett 
862*719f82d3SEliot Blennerhassett 				HPI_DEBUG_LOG(DEBUG,
863*719f82d3SEliot Blennerhassett 					"close adapter %d ostream %d\n",
864*719f82d3SEliot Blennerhassett 					adapter, i);
865*719f82d3SEliot Blennerhassett 
866*719f82d3SEliot Blennerhassett 				hpi_init_message_response(&hm, &hr,
867*719f82d3SEliot Blennerhassett 					HPI_OBJ_OSTREAM, HPI_OSTREAM_RESET);
868*719f82d3SEliot Blennerhassett 				hm.adapter_index = (u16)adapter;
869*719f82d3SEliot Blennerhassett 				hm.obj_index = (u16)i;
870*719f82d3SEliot Blennerhassett 				hw_entry_point(&hm, &hr);
871*719f82d3SEliot Blennerhassett 
872*719f82d3SEliot Blennerhassett 				hm.function = HPI_OSTREAM_HOSTBUFFER_FREE;
873*719f82d3SEliot Blennerhassett 				hw_entry_point(&hm, &hr);
874*719f82d3SEliot Blennerhassett 
875*719f82d3SEliot Blennerhassett 				hm.function = HPI_OSTREAM_GROUP_RESET;
876*719f82d3SEliot Blennerhassett 				hw_entry_point(&hm, &hr);
877*719f82d3SEliot Blennerhassett 
878*719f82d3SEliot Blennerhassett 				outstream_user_open[adapter][i].open_flag = 0;
879*719f82d3SEliot Blennerhassett 				outstream_user_open[adapter][i].h_owner =
880*719f82d3SEliot Blennerhassett 					NULL;
881*719f82d3SEliot Blennerhassett 			}
882*719f82d3SEliot Blennerhassett 			if (h_owner == instream_user_open[adapter][i].h_owner) {
883*719f82d3SEliot Blennerhassett 				struct hpi_message hm;
884*719f82d3SEliot Blennerhassett 				struct hpi_response hr;
885*719f82d3SEliot Blennerhassett 
886*719f82d3SEliot Blennerhassett 				HPI_DEBUG_LOG(DEBUG,
887*719f82d3SEliot Blennerhassett 					"close adapter %d istream %d\n",
888*719f82d3SEliot Blennerhassett 					adapter, i);
889*719f82d3SEliot Blennerhassett 
890*719f82d3SEliot Blennerhassett 				hpi_init_message_response(&hm, &hr,
891*719f82d3SEliot Blennerhassett 					HPI_OBJ_ISTREAM, HPI_ISTREAM_RESET);
892*719f82d3SEliot Blennerhassett 				hm.adapter_index = (u16)adapter;
893*719f82d3SEliot Blennerhassett 				hm.obj_index = (u16)i;
894*719f82d3SEliot Blennerhassett 				hw_entry_point(&hm, &hr);
895*719f82d3SEliot Blennerhassett 
896*719f82d3SEliot Blennerhassett 				hm.function = HPI_ISTREAM_HOSTBUFFER_FREE;
897*719f82d3SEliot Blennerhassett 				hw_entry_point(&hm, &hr);
898*719f82d3SEliot Blennerhassett 
899*719f82d3SEliot Blennerhassett 				hm.function = HPI_ISTREAM_GROUP_RESET;
900*719f82d3SEliot Blennerhassett 				hw_entry_point(&hm, &hr);
901*719f82d3SEliot Blennerhassett 
902*719f82d3SEliot Blennerhassett 				instream_user_open[adapter][i].open_flag = 0;
903*719f82d3SEliot Blennerhassett 				instream_user_open[adapter][i].h_owner = NULL;
904*719f82d3SEliot Blennerhassett 			}
905*719f82d3SEliot Blennerhassett 		}
906*719f82d3SEliot Blennerhassett 	}
907*719f82d3SEliot Blennerhassett }
908