~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/pci/asihpi/hpimsgx.c

Version: ~ [ linux-6.1-rc7 ] ~ [ linux-6.0.10 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.80 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.156 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.225 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.267 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.300 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.334 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.302 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp