printf: Remove unused 'bprintf'
[drm/drm-misc.git] / sound / pci / asihpi / hpicmn.c
blob7d1abaedb46acc37fb7c47dbfb7c7749b7b2c36e
1 // SPDX-License-Identifier: GPL-2.0-only
2 /******************************************************************************
4 AudioScience HPI driver
5 Copyright (C) 1997-2014 AudioScience Inc. <support@audioscience.com>
8 \file hpicmn.c
10 Common functions used by hpixxxx.c modules
12 (C) Copyright AudioScience Inc. 1998-2003
13 *******************************************************************************/
14 #define SOURCEFILE_NAME "hpicmn.c"
16 #include "hpi_internal.h"
17 #include "hpidebug.h"
18 #include "hpimsginit.h"
20 #include "hpicmn.h"
22 struct hpi_adapters_list {
23 struct hpios_spinlock list_lock;
24 struct hpi_adapter_obj adapter[HPI_MAX_ADAPTERS];
25 u16 gw_num_adapters;
28 static struct hpi_adapters_list adapters;
30 /**
31 * hpi_validate_response - Given an HPI Message that was sent out and
32 * a response that was received, validate that the response has the
33 * correct fields filled in, i.e ObjectType, Function etc
34 * @phm: message
35 * @phr: response
37 u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
39 if (phr->type != HPI_TYPE_RESPONSE) {
40 HPI_DEBUG_LOG(ERROR, "header type %d invalid\n", phr->type);
41 return HPI_ERROR_INVALID_RESPONSE;
44 if (phr->object != phm->object) {
45 HPI_DEBUG_LOG(ERROR, "header object %d invalid\n",
46 phr->object);
47 return HPI_ERROR_INVALID_RESPONSE;
50 if (phr->function != phm->function) {
51 HPI_DEBUG_LOG(ERROR, "header function %d invalid\n",
52 phr->function);
53 return HPI_ERROR_INVALID_RESPONSE;
56 return 0;
59 u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
61 u16 retval = 0;
62 /*HPI_ASSERT(pao->type); */
64 hpios_alistlock_lock(&adapters);
66 if (pao->index >= HPI_MAX_ADAPTERS) {
67 retval = HPI_ERROR_BAD_ADAPTER_NUMBER;
68 goto unlock;
71 if (adapters.adapter[pao->index].type) {
72 int a;
73 for (a = HPI_MAX_ADAPTERS - 1; a >= 0; a--) {
74 if (!adapters.adapter[a].type) {
75 HPI_DEBUG_LOG(WARNING,
76 "ASI%X duplicate index %d moved to %d\n",
77 pao->type, pao->index, a);
78 pao->index = a;
79 break;
82 if (a < 0) {
83 retval = HPI_ERROR_DUPLICATE_ADAPTER_NUMBER;
84 goto unlock;
87 adapters.adapter[pao->index] = *pao;
88 hpios_dsplock_init(&adapters.adapter[pao->index]);
89 adapters.gw_num_adapters++;
91 unlock:
92 hpios_alistlock_unlock(&adapters);
93 return retval;
96 void hpi_delete_adapter(struct hpi_adapter_obj *pao)
98 if (!pao->type) {
99 HPI_DEBUG_LOG(ERROR, "removing null adapter?\n");
100 return;
103 hpios_alistlock_lock(&adapters);
104 if (adapters.adapter[pao->index].type)
105 adapters.gw_num_adapters--;
106 memset(&adapters.adapter[pao->index], 0, sizeof(adapters.adapter[0]));
107 hpios_alistlock_unlock(&adapters);
111 * hpi_find_adapter - FindAdapter returns a pointer to the struct
112 * hpi_adapter_obj with index wAdapterIndex in an HPI_ADAPTERS_LIST
113 * structure.
114 * @adapter_index: value in [0, HPI_MAX_ADAPTERS[
116 struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
118 struct hpi_adapter_obj *pao = NULL;
120 if (adapter_index >= HPI_MAX_ADAPTERS) {
121 HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d\n",
122 adapter_index);
123 return NULL;
126 pao = &adapters.adapter[adapter_index];
127 if (pao->type != 0) {
129 HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n",
130 wAdapterIndex);
132 return pao;
133 } else {
135 HPI_DEBUG_LOG(VERBOSE, "No adapter index %d\n",
136 wAdapterIndex);
138 return NULL;
143 * wipe_adapter_list - wipe an HPI_ADAPTERS_LIST structure.
146 static void wipe_adapter_list(void)
148 memset(&adapters, 0, sizeof(adapters));
151 static void subsys_get_adapter(struct hpi_message *phm,
152 struct hpi_response *phr)
154 int count = phm->obj_index;
155 u16 index = 0;
157 /* find the nCount'th nonzero adapter in array */
158 for (index = 0; index < HPI_MAX_ADAPTERS; index++) {
159 if (adapters.adapter[index].type) {
160 if (!count)
161 break;
162 count--;
166 if (index < HPI_MAX_ADAPTERS) {
167 phr->u.s.adapter_index = adapters.adapter[index].index;
168 phr->u.s.adapter_type = adapters.adapter[index].type;
169 } else {
170 phr->u.s.adapter_index = 0;
171 phr->u.s.adapter_type = 0;
172 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
176 static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
178 unsigned int i;
179 int cached = 0;
180 if (!pC)
181 return 0;
183 if (pC->init)
184 return pC->init;
186 if (!pC->p_cache)
187 return 0;
189 if (pC->control_count && pC->cache_size_in_bytes) {
190 char *p_master_cache;
191 unsigned int byte_count = 0;
193 p_master_cache = (char *)pC->p_cache;
194 HPI_DEBUG_LOG(DEBUG, "check %d controls\n",
195 pC->control_count);
196 for (i = 0; i < pC->control_count; i++) {
197 struct hpi_control_cache_info *info =
198 (struct hpi_control_cache_info *)
199 &p_master_cache[byte_count];
200 u16 control_index = info->control_index;
202 if (control_index >= pC->control_count) {
203 HPI_DEBUG_LOG(INFO,
204 "adap %d control index %d out of range, cache not ready?\n",
205 pC->adap_idx, control_index);
206 return 0;
209 if (!info->size_in32bit_words) {
210 if (!i) {
211 HPI_DEBUG_LOG(INFO,
212 "adap %d cache not ready?\n",
213 pC->adap_idx);
214 return 0;
216 /* The cache is invalid.
217 * Minimum valid entry size is
218 * sizeof(struct hpi_control_cache_info)
220 HPI_DEBUG_LOG(ERROR,
221 "adap %d zero size cache entry %d\n",
222 pC->adap_idx, i);
223 break;
226 if (info->control_type) {
227 pC->p_info[control_index] = info;
228 cached++;
229 } else { /* dummy cache entry */
230 pC->p_info[control_index] = NULL;
233 byte_count += info->size_in32bit_words * 4;
235 HPI_DEBUG_LOG(VERBOSE,
236 "cached %d, pinfo %p index %d type %d size %d\n",
237 cached, pC->p_info[info->control_index],
238 info->control_index, info->control_type,
239 info->size_in32bit_words);
241 /* quit loop early if whole cache has been scanned.
242 * dwControlCount is the maximum possible entries
243 * but some may be absent from the cache
245 if (byte_count >= pC->cache_size_in_bytes)
246 break;
247 /* have seen last control index */
248 if (info->control_index == pC->control_count - 1)
249 break;
252 if (byte_count != pC->cache_size_in_bytes)
253 HPI_DEBUG_LOG(WARNING,
254 "adap %d bytecount %d != cache size %d\n",
255 pC->adap_idx, byte_count,
256 pC->cache_size_in_bytes);
257 else
258 HPI_DEBUG_LOG(DEBUG,
259 "adap %d cache good, bytecount == cache size = %d\n",
260 pC->adap_idx, byte_count);
262 pC->init = (u16)cached;
264 return pC->init;
267 /** Find a control.
269 static short find_control(u16 control_index,
270 struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI)
272 if (!control_cache_alloc_check(p_cache)) {
273 HPI_DEBUG_LOG(VERBOSE,
274 "control_cache_alloc_check() failed %d\n",
275 control_index);
276 return 0;
279 *pI = p_cache->p_info[control_index];
280 if (!*pI) {
281 HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
282 control_index);
283 return 0;
284 } else {
285 HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
286 (*pI)->control_type);
288 return 1;
291 /* allow unified treatment of several string fields within struct */
292 #define HPICMN_PAD_OFS_AND_SIZE(m) {\
293 offsetof(struct hpi_control_cache_pad, m), \
294 sizeof(((struct hpi_control_cache_pad *)(NULL))->m) }
296 struct pad_ofs_size {
297 unsigned int offset;
298 unsigned int field_size;
301 static const struct pad_ofs_size pad_desc[] = {
302 HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */
303 HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */
304 HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */
305 HPICMN_PAD_OFS_AND_SIZE(c_comment), /* HPI_PAD_COMMENT */
308 /** CheckControlCache checks the cache and fills the struct hpi_response
309 * accordingly. It returns one if a cache hit occurred, zero otherwise.
311 short hpi_check_control_cache_single(struct hpi_control_cache_single *pC,
312 struct hpi_message *phm, struct hpi_response *phr)
314 size_t response_size;
315 short found = 1;
317 /* set the default response size */
318 response_size =
319 sizeof(struct hpi_response_header) +
320 sizeof(struct hpi_control_res);
322 switch (pC->u.i.control_type) {
324 case HPI_CONTROL_METER:
325 if (phm->u.c.attribute == HPI_METER_PEAK) {
326 phr->u.c.an_log_value[0] = pC->u.meter.an_log_peak[0];
327 phr->u.c.an_log_value[1] = pC->u.meter.an_log_peak[1];
328 } else if (phm->u.c.attribute == HPI_METER_RMS) {
329 if (pC->u.meter.an_logRMS[0] ==
330 HPI_CACHE_INVALID_SHORT) {
331 phr->error =
332 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
333 phr->u.c.an_log_value[0] = HPI_METER_MINIMUM;
334 phr->u.c.an_log_value[1] = HPI_METER_MINIMUM;
335 } else {
336 phr->u.c.an_log_value[0] =
337 pC->u.meter.an_logRMS[0];
338 phr->u.c.an_log_value[1] =
339 pC->u.meter.an_logRMS[1];
341 } else
342 found = 0;
343 break;
344 case HPI_CONTROL_VOLUME:
345 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
346 phr->u.c.an_log_value[0] = pC->u.vol.an_log[0];
347 phr->u.c.an_log_value[1] = pC->u.vol.an_log[1];
348 } else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
349 if (pC->u.vol.flags & HPI_VOLUME_FLAG_HAS_MUTE) {
350 if (pC->u.vol.flags & HPI_VOLUME_FLAG_MUTED)
351 phr->u.c.param1 =
352 HPI_BITMASK_ALL_CHANNELS;
353 else
354 phr->u.c.param1 = 0;
355 } else {
356 phr->error =
357 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
358 phr->u.c.param1 = 0;
360 } else {
361 found = 0;
363 break;
364 case HPI_CONTROL_MULTIPLEXER:
365 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
366 phr->u.c.param1 = pC->u.mux.source_node_type;
367 phr->u.c.param2 = pC->u.mux.source_node_index;
368 } else {
369 found = 0;
371 break;
372 case HPI_CONTROL_CHANNEL_MODE:
373 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
374 phr->u.c.param1 = pC->u.mode.mode;
375 else
376 found = 0;
377 break;
378 case HPI_CONTROL_LEVEL:
379 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
380 phr->u.c.an_log_value[0] = pC->u.level.an_log[0];
381 phr->u.c.an_log_value[1] = pC->u.level.an_log[1];
382 } else
383 found = 0;
384 break;
385 case HPI_CONTROL_TUNER:
386 if (phm->u.c.attribute == HPI_TUNER_FREQ)
387 phr->u.c.param1 = pC->u.tuner.freq_ink_hz;
388 else if (phm->u.c.attribute == HPI_TUNER_BAND)
389 phr->u.c.param1 = pC->u.tuner.band;
390 else if (phm->u.c.attribute == HPI_TUNER_LEVEL_AVG)
391 if (pC->u.tuner.s_level_avg ==
392 HPI_CACHE_INVALID_SHORT) {
393 phr->u.cu.tuner.s_level = 0;
394 phr->error =
395 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
396 } else
397 phr->u.cu.tuner.s_level =
398 pC->u.tuner.s_level_avg;
399 else
400 found = 0;
401 break;
402 case HPI_CONTROL_AESEBU_RECEIVER:
403 if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS)
404 phr->u.c.param1 = pC->u.aes3rx.error_status;
405 else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
406 phr->u.c.param1 = pC->u.aes3rx.format;
407 else
408 found = 0;
409 break;
410 case HPI_CONTROL_AESEBU_TRANSMITTER:
411 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
412 phr->u.c.param1 = pC->u.aes3tx.format;
413 else
414 found = 0;
415 break;
416 case HPI_CONTROL_TONEDETECTOR:
417 if (phm->u.c.attribute == HPI_TONEDETECTOR_STATE)
418 phr->u.c.param1 = pC->u.tone.state;
419 else
420 found = 0;
421 break;
422 case HPI_CONTROL_SILENCEDETECTOR:
423 if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
424 phr->u.c.param1 = pC->u.silence.state;
425 } else
426 found = 0;
427 break;
428 case HPI_CONTROL_MICROPHONE:
429 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
430 phr->u.c.param1 = pC->u.microphone.phantom_state;
431 else
432 found = 0;
433 break;
434 case HPI_CONTROL_SAMPLECLOCK:
435 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
436 phr->u.c.param1 = pC->u.clk.source;
437 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) {
438 if (pC->u.clk.source_index ==
439 HPI_CACHE_INVALID_UINT16) {
440 phr->u.c.param1 = 0;
441 phr->error =
442 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
443 } else
444 phr->u.c.param1 = pC->u.clk.source_index;
445 } else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
446 phr->u.c.param1 = pC->u.clk.sample_rate;
447 else
448 found = 0;
449 break;
450 case HPI_CONTROL_PAD:{
451 struct hpi_control_cache_pad *p_pad;
452 p_pad = (struct hpi_control_cache_pad *)pC;
454 if (!(p_pad->field_valid_flags & (1 <<
455 HPI_CTL_ATTR_INDEX(phm->u.c.
456 attribute)))) {
457 phr->error =
458 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
459 break;
462 if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
463 phr->u.c.param1 = p_pad->pI;
464 else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
465 phr->u.c.param1 = p_pad->pTY;
466 else {
467 unsigned int index =
468 HPI_CTL_ATTR_INDEX(phm->u.c.
469 attribute) - 1;
470 unsigned int offset = phm->u.c.param1;
471 unsigned int pad_string_len, field_size;
472 char *pad_string;
473 unsigned int tocopy;
475 if (index > ARRAY_SIZE(pad_desc) - 1) {
476 phr->error =
477 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
478 break;
481 pad_string =
482 ((char *)p_pad) +
483 pad_desc[index].offset;
484 field_size = pad_desc[index].field_size;
485 /* Ensure null terminator */
486 pad_string[field_size - 1] = 0;
488 pad_string_len = strlen(pad_string) + 1;
490 if (offset > pad_string_len) {
491 phr->error =
492 HPI_ERROR_INVALID_CONTROL_VALUE;
493 break;
496 tocopy = pad_string_len - offset;
497 if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
498 tocopy = sizeof(phr->u.cu.chars8.
499 sz_data);
501 memcpy(phr->u.cu.chars8.sz_data,
502 &pad_string[offset], tocopy);
504 phr->u.cu.chars8.remaining_chars =
505 pad_string_len - offset - tocopy;
508 break;
509 default:
510 found = 0;
511 break;
514 HPI_DEBUG_LOG(VERBOSE, "%s Adap %d, Ctl %d, Type %d, Attr %d\n",
515 found ? "Cached" : "Uncached", phm->adapter_index,
516 pC->u.i.control_index, pC->u.i.control_type,
517 phm->u.c.attribute);
519 if (found) {
520 phr->size = (u16)response_size;
521 phr->type = HPI_TYPE_RESPONSE;
522 phr->object = phm->object;
523 phr->function = phm->function;
526 return found;
529 short hpi_check_control_cache(struct hpi_control_cache *p_cache,
530 struct hpi_message *phm, struct hpi_response *phr)
532 struct hpi_control_cache_info *pI;
534 if (!find_control(phm->obj_index, p_cache, &pI)) {
535 HPI_DEBUG_LOG(VERBOSE,
536 "HPICMN find_control() failed for adap %d\n",
537 phm->adapter_index);
538 return 0;
541 phr->error = 0;
542 phr->specific_error = 0;
543 phr->version = 0;
545 return hpi_check_control_cache_single((struct hpi_control_cache_single
546 *)pI, phm, phr);
549 /** Updates the cache with Set values.
551 Only update if no error.
552 Volume and Level return the limited values in the response, so use these
553 Multiplexer does so use sent values
555 void hpi_cmn_control_cache_sync_to_msg_single(struct hpi_control_cache_single
556 *pC, struct hpi_message *phm, struct hpi_response *phr)
558 switch (pC->u.i.control_type) {
559 case HPI_CONTROL_VOLUME:
560 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
561 pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
562 pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
563 } else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
564 if (phm->u.c.param1)
565 pC->u.vol.flags |= HPI_VOLUME_FLAG_MUTED;
566 else
567 pC->u.vol.flags &= ~HPI_VOLUME_FLAG_MUTED;
569 break;
570 case HPI_CONTROL_MULTIPLEXER:
571 /* mux does not return its setting on Set command. */
572 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
573 pC->u.mux.source_node_type = (u16)phm->u.c.param1;
574 pC->u.mux.source_node_index = (u16)phm->u.c.param2;
576 break;
577 case HPI_CONTROL_CHANNEL_MODE:
578 /* mode does not return its setting on Set command. */
579 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
580 pC->u.mode.mode = (u16)phm->u.c.param1;
581 break;
582 case HPI_CONTROL_LEVEL:
583 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
584 pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
585 pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
587 break;
588 case HPI_CONTROL_MICROPHONE:
589 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
590 pC->u.microphone.phantom_state = (u16)phm->u.c.param1;
591 break;
592 case HPI_CONTROL_AESEBU_TRANSMITTER:
593 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
594 pC->u.aes3tx.format = phm->u.c.param1;
595 break;
596 case HPI_CONTROL_AESEBU_RECEIVER:
597 if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
598 pC->u.aes3rx.format = phm->u.c.param1;
599 break;
600 case HPI_CONTROL_SAMPLECLOCK:
601 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
602 pC->u.clk.source = (u16)phm->u.c.param1;
603 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX)
604 pC->u.clk.source_index = (u16)phm->u.c.param1;
605 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
606 pC->u.clk.sample_rate = phm->u.c.param1;
607 break;
608 default:
609 break;
613 void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache,
614 struct hpi_message *phm, struct hpi_response *phr)
616 struct hpi_control_cache_single *pC;
617 struct hpi_control_cache_info *pI;
619 if (phr->error)
620 return;
622 if (!find_control(phm->obj_index, p_cache, &pI)) {
623 HPI_DEBUG_LOG(VERBOSE,
624 "HPICMN find_control() failed for adap %d\n",
625 phm->adapter_index);
626 return;
629 /* pC is the default cached control strucure.
630 May be cast to something else in the following switch statement.
632 pC = (struct hpi_control_cache_single *)pI;
634 hpi_cmn_control_cache_sync_to_msg_single(pC, phm, phr);
637 /** Allocate control cache.
639 \return Cache pointer, or NULL if allocation fails.
641 struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
642 const u32 size_in_bytes, u8 *p_dsp_control_buffer)
644 struct hpi_control_cache *p_cache =
645 kmalloc(sizeof(*p_cache), GFP_KERNEL);
646 if (!p_cache)
647 return NULL;
649 p_cache->p_info =
650 kcalloc(control_count, sizeof(*p_cache->p_info), GFP_KERNEL);
651 if (!p_cache->p_info) {
652 kfree(p_cache);
653 return NULL;
656 p_cache->cache_size_in_bytes = size_in_bytes;
657 p_cache->control_count = control_count;
658 p_cache->p_cache = p_dsp_control_buffer;
659 p_cache->init = 0;
660 return p_cache;
663 void hpi_free_control_cache(struct hpi_control_cache *p_cache)
665 if (p_cache) {
666 kfree(p_cache->p_info);
667 kfree(p_cache);
671 static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
673 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 0);
675 switch (phm->function) {
676 case HPI_SUBSYS_OPEN:
677 case HPI_SUBSYS_CLOSE:
678 case HPI_SUBSYS_DRIVER_UNLOAD:
679 break;
680 case HPI_SUBSYS_DRIVER_LOAD:
681 wipe_adapter_list();
682 hpios_alistlock_init(&adapters);
683 break;
684 case HPI_SUBSYS_GET_ADAPTER:
685 subsys_get_adapter(phm, phr);
686 break;
687 case HPI_SUBSYS_GET_NUM_ADAPTERS:
688 phr->u.s.num_adapters = adapters.gw_num_adapters;
689 break;
690 case HPI_SUBSYS_CREATE_ADAPTER:
691 break;
692 default:
693 phr->error = HPI_ERROR_INVALID_FUNC;
694 break;
698 void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
700 switch (phm->type) {
701 case HPI_TYPE_REQUEST:
702 switch (phm->object) {
703 case HPI_OBJ_SUBSYSTEM:
704 subsys_message(phm, phr);
705 break;
707 break;
709 default:
710 phr->error = HPI_ERROR_INVALID_TYPE;
711 break;