Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/pci/asihpi/hpicmn.c
10817 views
1
/******************************************************************************
2
3
AudioScience HPI driver
4
Copyright (C) 1997-2010 AudioScience Inc. <[email protected]>
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
\file hpicmn.c
20
21
Common functions used by hpixxxx.c modules
22
23
(C) Copyright AudioScience Inc. 1998-2003
24
*******************************************************************************/
25
#define SOURCEFILE_NAME "hpicmn.c"
26
27
#include "hpi_internal.h"
28
#include "hpidebug.h"
29
#include "hpimsginit.h"
30
31
#include "hpicmn.h"
32
33
struct hpi_adapters_list {
34
struct hpios_spinlock list_lock;
35
struct hpi_adapter_obj adapter[HPI_MAX_ADAPTERS];
36
u16 gw_num_adapters;
37
};
38
39
static struct hpi_adapters_list adapters;
40
41
/**
42
* Given an HPI Message that was sent out and a response that was received,
43
* validate that the response has the correct fields filled in,
44
* i.e ObjectType, Function etc
45
**/
46
u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
47
{
48
if (phr->type != HPI_TYPE_RESPONSE) {
49
HPI_DEBUG_LOG(ERROR, "header type %d invalid\n", phr->type);
50
return HPI_ERROR_INVALID_RESPONSE;
51
}
52
53
if (phr->object != phm->object) {
54
HPI_DEBUG_LOG(ERROR, "header object %d invalid\n",
55
phr->object);
56
return HPI_ERROR_INVALID_RESPONSE;
57
}
58
59
if (phr->function != phm->function) {
60
HPI_DEBUG_LOG(ERROR, "header type %d invalid\n",
61
phr->function);
62
return HPI_ERROR_INVALID_RESPONSE;
63
}
64
65
return 0;
66
}
67
68
u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
69
{
70
u16 retval = 0;
71
/*HPI_ASSERT(pao->wAdapterType); */
72
73
hpios_alistlock_lock(&adapters);
74
75
if (pao->index >= HPI_MAX_ADAPTERS) {
76
retval = HPI_ERROR_BAD_ADAPTER_NUMBER;
77
goto unlock;
78
}
79
80
if (adapters.adapter[pao->index].adapter_type) {
81
int a;
82
for (a = HPI_MAX_ADAPTERS - 1; a >= 0; a--) {
83
if (!adapters.adapter[a].adapter_type) {
84
HPI_DEBUG_LOG(WARNING,
85
"ASI%X duplicate index %d moved to %d\n",
86
pao->adapter_type, pao->index, a);
87
pao->index = a;
88
break;
89
}
90
}
91
if (a < 0) {
92
retval = HPI_ERROR_DUPLICATE_ADAPTER_NUMBER;
93
goto unlock;
94
}
95
}
96
adapters.adapter[pao->index] = *pao;
97
hpios_dsplock_init(&adapters.adapter[pao->index]);
98
adapters.gw_num_adapters++;
99
100
unlock:
101
hpios_alistlock_unlock(&adapters);
102
return retval;
103
}
104
105
void hpi_delete_adapter(struct hpi_adapter_obj *pao)
106
{
107
if (!pao->adapter_type) {
108
HPI_DEBUG_LOG(ERROR, "removing null adapter?\n");
109
return;
110
}
111
112
hpios_alistlock_lock(&adapters);
113
if (adapters.adapter[pao->index].adapter_type)
114
adapters.gw_num_adapters--;
115
memset(&adapters.adapter[pao->index], 0, sizeof(adapters.adapter[0]));
116
hpios_alistlock_unlock(&adapters);
117
}
118
119
/**
120
* FindAdapter returns a pointer to the struct hpi_adapter_obj with
121
* index wAdapterIndex in an HPI_ADAPTERS_LIST structure.
122
*
123
*/
124
struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
125
{
126
struct hpi_adapter_obj *pao = NULL;
127
128
if (adapter_index >= HPI_MAX_ADAPTERS) {
129
HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d\n",
130
adapter_index);
131
return NULL;
132
}
133
134
pao = &adapters.adapter[adapter_index];
135
if (pao->adapter_type != 0) {
136
/*
137
HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n",
138
wAdapterIndex);
139
*/
140
return pao;
141
} else {
142
/*
143
HPI_DEBUG_LOG(VERBOSE, "No adapter index %d\n",
144
wAdapterIndex);
145
*/
146
return NULL;
147
}
148
}
149
150
/**
151
*
152
* wipe an HPI_ADAPTERS_LIST structure.
153
*
154
**/
155
static void wipe_adapter_list(void)
156
{
157
memset(&adapters, 0, sizeof(adapters));
158
}
159
160
static void subsys_get_adapter(struct hpi_message *phm,
161
struct hpi_response *phr)
162
{
163
int count = phm->obj_index;
164
u16 index = 0;
165
166
/* find the nCount'th nonzero adapter in array */
167
for (index = 0; index < HPI_MAX_ADAPTERS; index++) {
168
if (adapters.adapter[index].adapter_type) {
169
if (!count)
170
break;
171
count--;
172
}
173
}
174
175
if (index < HPI_MAX_ADAPTERS) {
176
phr->u.s.adapter_index = adapters.adapter[index].index;
177
phr->u.s.adapter_type = adapters.adapter[index].adapter_type;
178
} else {
179
phr->u.s.adapter_index = 0;
180
phr->u.s.adapter_type = 0;
181
phr->error = HPI_ERROR_BAD_ADAPTER_NUMBER;
182
}
183
}
184
185
static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
186
{
187
unsigned int i;
188
int cached = 0;
189
if (!pC)
190
return 0;
191
192
if (pC->init)
193
return pC->init;
194
195
if (!pC->p_cache)
196
return 0;
197
198
if (pC->control_count && pC->cache_size_in_bytes) {
199
char *p_master_cache;
200
unsigned int byte_count = 0;
201
202
p_master_cache = (char *)pC->p_cache;
203
HPI_DEBUG_LOG(DEBUG, "check %d controls\n",
204
pC->control_count);
205
for (i = 0; i < pC->control_count; i++) {
206
struct hpi_control_cache_info *info =
207
(struct hpi_control_cache_info *)
208
&p_master_cache[byte_count];
209
210
if (!info->size_in32bit_words) {
211
if (!i) {
212
HPI_DEBUG_LOG(INFO,
213
"adap %d cache not ready?\n",
214
pC->adap_idx);
215
return 0;
216
}
217
/* The cache is invalid.
218
* Minimum valid entry size is
219
* sizeof(struct hpi_control_cache_info)
220
*/
221
HPI_DEBUG_LOG(ERROR,
222
"adap %d zero size cache entry %d\n",
223
pC->adap_idx, i);
224
break;
225
}
226
227
if (info->control_type) {
228
pC->p_info[info->control_index] = info;
229
cached++;
230
} else { /* dummy cache entry */
231
pC->p_info[info->control_index] = NULL;
232
}
233
234
byte_count += info->size_in32bit_words * 4;
235
236
HPI_DEBUG_LOG(VERBOSE,
237
"cached %d, pinfo %p index %d type %d size %d\n",
238
cached, pC->p_info[info->control_index],
239
info->control_index, info->control_type,
240
info->size_in32bit_words);
241
242
/* quit loop early if whole cache has been scanned.
243
* dwControlCount is the maximum possible entries
244
* but some may be absent from the cache
245
*/
246
if (byte_count >= pC->cache_size_in_bytes)
247
break;
248
/* have seen last control index */
249
if (info->control_index == pC->control_count - 1)
250
break;
251
}
252
253
if (byte_count != pC->cache_size_in_bytes)
254
HPI_DEBUG_LOG(WARNING,
255
"adap %d bytecount %d != cache size %d\n",
256
pC->adap_idx, byte_count,
257
pC->cache_size_in_bytes);
258
else
259
HPI_DEBUG_LOG(DEBUG,
260
"adap %d cache good, bytecount == cache size = %d\n",
261
pC->adap_idx, byte_count);
262
263
pC->init = (u16)cached;
264
}
265
return pC->init;
266
}
267
268
/** Find a control.
269
*/
270
static short find_control(u16 control_index,
271
struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI)
272
{
273
if (!control_cache_alloc_check(p_cache)) {
274
HPI_DEBUG_LOG(VERBOSE,
275
"control_cache_alloc_check() failed %d\n",
276
control_index);
277
return 0;
278
}
279
280
*pI = p_cache->p_info[control_index];
281
if (!*pI) {
282
HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
283
control_index);
284
return 0;
285
} else {
286
HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
287
(*pI)->control_type);
288
}
289
return 1;
290
}
291
292
/* allow unified treatment of several string fields within struct */
293
#define HPICMN_PAD_OFS_AND_SIZE(m) {\
294
offsetof(struct hpi_control_cache_pad, m), \
295
sizeof(((struct hpi_control_cache_pad *)(NULL))->m) }
296
297
struct pad_ofs_size {
298
unsigned int offset;
299
unsigned int field_size;
300
};
301
302
static const struct pad_ofs_size pad_desc[] = {
303
HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */
304
HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */
305
HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */
306
HPICMN_PAD_OFS_AND_SIZE(c_comment), /* HPI_PAD_COMMENT */
307
};
308
309
/** CheckControlCache checks the cache and fills the struct hpi_response
310
* accordingly. It returns one if a cache hit occurred, zero otherwise.
311
*/
312
short hpi_check_control_cache(struct hpi_control_cache *p_cache,
313
struct hpi_message *phm, struct hpi_response *phr)
314
{
315
short found = 1;
316
struct hpi_control_cache_info *pI;
317
struct hpi_control_cache_single *pC;
318
struct hpi_control_cache_pad *p_pad;
319
320
if (!find_control(phm->obj_index, p_cache, &pI)) {
321
HPI_DEBUG_LOG(VERBOSE,
322
"HPICMN find_control() failed for adap %d\n",
323
phm->adapter_index);
324
return 0;
325
}
326
327
phr->error = 0;
328
329
/* pC is the default cached control strucure. May be cast to
330
something else in the following switch statement.
331
*/
332
pC = (struct hpi_control_cache_single *)pI;
333
p_pad = (struct hpi_control_cache_pad *)pI;
334
335
switch (pI->control_type) {
336
337
case HPI_CONTROL_METER:
338
if (phm->u.c.attribute == HPI_METER_PEAK) {
339
phr->u.c.an_log_value[0] = pC->u.meter.an_log_peak[0];
340
phr->u.c.an_log_value[1] = pC->u.meter.an_log_peak[1];
341
} else if (phm->u.c.attribute == HPI_METER_RMS) {
342
if (pC->u.meter.an_logRMS[0] ==
343
HPI_CACHE_INVALID_SHORT) {
344
phr->error =
345
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
346
phr->u.c.an_log_value[0] = HPI_METER_MINIMUM;
347
phr->u.c.an_log_value[1] = HPI_METER_MINIMUM;
348
} else {
349
phr->u.c.an_log_value[0] =
350
pC->u.meter.an_logRMS[0];
351
phr->u.c.an_log_value[1] =
352
pC->u.meter.an_logRMS[1];
353
}
354
} else
355
found = 0;
356
break;
357
case HPI_CONTROL_VOLUME:
358
if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
359
phr->u.c.an_log_value[0] = pC->u.vol.an_log[0];
360
phr->u.c.an_log_value[1] = pC->u.vol.an_log[1];
361
} else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
362
if (pC->u.vol.flags & HPI_VOLUME_FLAG_HAS_MUTE) {
363
if (pC->u.vol.flags & HPI_VOLUME_FLAG_MUTED)
364
phr->u.c.param1 =
365
HPI_BITMASK_ALL_CHANNELS;
366
else
367
phr->u.c.param1 = 0;
368
} else {
369
phr->error =
370
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
371
phr->u.c.param1 = 0;
372
}
373
} else {
374
found = 0;
375
}
376
break;
377
case HPI_CONTROL_MULTIPLEXER:
378
if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
379
phr->u.c.param1 = pC->u.mux.source_node_type;
380
phr->u.c.param2 = pC->u.mux.source_node_index;
381
} else {
382
found = 0;
383
}
384
break;
385
case HPI_CONTROL_CHANNEL_MODE:
386
if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
387
phr->u.c.param1 = pC->u.mode.mode;
388
else
389
found = 0;
390
break;
391
case HPI_CONTROL_LEVEL:
392
if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
393
phr->u.c.an_log_value[0] = pC->u.level.an_log[0];
394
phr->u.c.an_log_value[1] = pC->u.level.an_log[1];
395
} else
396
found = 0;
397
break;
398
case HPI_CONTROL_TUNER:
399
if (phm->u.c.attribute == HPI_TUNER_FREQ)
400
phr->u.c.param1 = pC->u.tuner.freq_ink_hz;
401
else if (phm->u.c.attribute == HPI_TUNER_BAND)
402
phr->u.c.param1 = pC->u.tuner.band;
403
else if (phm->u.c.attribute == HPI_TUNER_LEVEL_AVG)
404
if (pC->u.tuner.s_level_avg ==
405
HPI_CACHE_INVALID_SHORT) {
406
phr->u.cu.tuner.s_level = 0;
407
phr->error =
408
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
409
} else
410
phr->u.cu.tuner.s_level =
411
pC->u.tuner.s_level_avg;
412
else
413
found = 0;
414
break;
415
case HPI_CONTROL_AESEBU_RECEIVER:
416
if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS)
417
phr->u.c.param1 = pC->u.aes3rx.error_status;
418
else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
419
phr->u.c.param1 = pC->u.aes3rx.format;
420
else
421
found = 0;
422
break;
423
case HPI_CONTROL_AESEBU_TRANSMITTER:
424
if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
425
phr->u.c.param1 = pC->u.aes3tx.format;
426
else
427
found = 0;
428
break;
429
case HPI_CONTROL_TONEDETECTOR:
430
if (phm->u.c.attribute == HPI_TONEDETECTOR_STATE)
431
phr->u.c.param1 = pC->u.tone.state;
432
else
433
found = 0;
434
break;
435
case HPI_CONTROL_SILENCEDETECTOR:
436
if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
437
phr->u.c.param1 = pC->u.silence.state;
438
} else
439
found = 0;
440
break;
441
case HPI_CONTROL_MICROPHONE:
442
if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
443
phr->u.c.param1 = pC->u.microphone.phantom_state;
444
else
445
found = 0;
446
break;
447
case HPI_CONTROL_SAMPLECLOCK:
448
if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
449
phr->u.c.param1 = pC->u.clk.source;
450
else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) {
451
if (pC->u.clk.source_index ==
452
HPI_CACHE_INVALID_UINT16) {
453
phr->u.c.param1 = 0;
454
phr->error =
455
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
456
} else
457
phr->u.c.param1 = pC->u.clk.source_index;
458
} else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
459
phr->u.c.param1 = pC->u.clk.sample_rate;
460
else
461
found = 0;
462
break;
463
case HPI_CONTROL_PAD:{
464
struct hpi_control_cache_pad *p_pad;
465
p_pad = (struct hpi_control_cache_pad *)pI;
466
467
if (!(p_pad->field_valid_flags & (1 <<
468
HPI_CTL_ATTR_INDEX(phm->u.c.
469
attribute)))) {
470
phr->error =
471
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
472
break;
473
}
474
475
if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
476
phr->u.c.param1 = p_pad->pI;
477
else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
478
phr->u.c.param1 = p_pad->pTY;
479
else {
480
unsigned int index =
481
HPI_CTL_ATTR_INDEX(phm->u.c.
482
attribute) - 1;
483
unsigned int offset = phm->u.c.param1;
484
unsigned int pad_string_len, field_size;
485
char *pad_string;
486
unsigned int tocopy;
487
488
if (index > ARRAY_SIZE(pad_desc) - 1) {
489
phr->error =
490
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
491
break;
492
}
493
494
pad_string =
495
((char *)p_pad) +
496
pad_desc[index].offset;
497
field_size = pad_desc[index].field_size;
498
/* Ensure null terminator */
499
pad_string[field_size - 1] = 0;
500
501
pad_string_len = strlen(pad_string) + 1;
502
503
if (offset > pad_string_len) {
504
phr->error =
505
HPI_ERROR_INVALID_CONTROL_VALUE;
506
break;
507
}
508
509
tocopy = pad_string_len - offset;
510
if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
511
tocopy = sizeof(phr->u.cu.chars8.
512
sz_data);
513
514
memcpy(phr->u.cu.chars8.sz_data,
515
&pad_string[offset], tocopy);
516
517
phr->u.cu.chars8.remaining_chars =
518
pad_string_len - offset - tocopy;
519
}
520
}
521
break;
522
default:
523
found = 0;
524
break;
525
}
526
527
HPI_DEBUG_LOG(VERBOSE, "%s Adap %d, Ctl %d, Type %d, Attr %d\n",
528
found ? "Cached" : "Uncached", phm->adapter_index,
529
pI->control_index, pI->control_type, phm->u.c.attribute);
530
531
if (found)
532
phr->size =
533
sizeof(struct hpi_response_header) +
534
sizeof(struct hpi_control_res);
535
536
return found;
537
}
538
539
/** Updates the cache with Set values.
540
541
Only update if no error.
542
Volume and Level return the limited values in the response, so use these
543
Multiplexer does so use sent values
544
*/
545
void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache,
546
struct hpi_message *phm, struct hpi_response *phr)
547
{
548
struct hpi_control_cache_single *pC;
549
struct hpi_control_cache_info *pI;
550
551
if (phr->error)
552
return;
553
554
if (!find_control(phm->obj_index, p_cache, &pI)) {
555
HPI_DEBUG_LOG(VERBOSE,
556
"HPICMN find_control() failed for adap %d\n",
557
phm->adapter_index);
558
return;
559
}
560
561
/* pC is the default cached control strucure.
562
May be cast to something else in the following switch statement.
563
*/
564
pC = (struct hpi_control_cache_single *)pI;
565
566
switch (pI->control_type) {
567
case HPI_CONTROL_VOLUME:
568
if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
569
pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
570
pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
571
} else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
572
if (phm->u.c.param1)
573
pC->u.vol.flags |= HPI_VOLUME_FLAG_MUTED;
574
else
575
pC->u.vol.flags &= ~HPI_VOLUME_FLAG_MUTED;
576
}
577
break;
578
case HPI_CONTROL_MULTIPLEXER:
579
/* mux does not return its setting on Set command. */
580
if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
581
pC->u.mux.source_node_type = (u16)phm->u.c.param1;
582
pC->u.mux.source_node_index = (u16)phm->u.c.param2;
583
}
584
break;
585
case HPI_CONTROL_CHANNEL_MODE:
586
/* mode does not return its setting on Set command. */
587
if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
588
pC->u.mode.mode = (u16)phm->u.c.param1;
589
break;
590
case HPI_CONTROL_LEVEL:
591
if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
592
pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
593
pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
594
}
595
break;
596
case HPI_CONTROL_MICROPHONE:
597
if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
598
pC->u.microphone.phantom_state = (u16)phm->u.c.param1;
599
break;
600
case HPI_CONTROL_AESEBU_TRANSMITTER:
601
if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
602
pC->u.aes3tx.format = phm->u.c.param1;
603
break;
604
case HPI_CONTROL_AESEBU_RECEIVER:
605
if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
606
pC->u.aes3rx.format = phm->u.c.param1;
607
break;
608
case HPI_CONTROL_SAMPLECLOCK:
609
if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
610
pC->u.clk.source = (u16)phm->u.c.param1;
611
else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX)
612
pC->u.clk.source_index = (u16)phm->u.c.param1;
613
else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
614
pC->u.clk.sample_rate = phm->u.c.param1;
615
break;
616
default:
617
break;
618
}
619
}
620
621
/** Allocate control cache.
622
623
\return Cache pointer, or NULL if allocation fails.
624
*/
625
struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
626
const u32 size_in_bytes, u8 *p_dsp_control_buffer)
627
{
628
struct hpi_control_cache *p_cache =
629
kmalloc(sizeof(*p_cache), GFP_KERNEL);
630
if (!p_cache)
631
return NULL;
632
633
p_cache->p_info =
634
kmalloc(sizeof(*p_cache->p_info) * control_count, GFP_KERNEL);
635
if (!p_cache->p_info) {
636
kfree(p_cache);
637
return NULL;
638
}
639
memset(p_cache->p_info, 0, sizeof(*p_cache->p_info) * control_count);
640
p_cache->cache_size_in_bytes = size_in_bytes;
641
p_cache->control_count = control_count;
642
p_cache->p_cache = p_dsp_control_buffer;
643
p_cache->init = 0;
644
return p_cache;
645
}
646
647
void hpi_free_control_cache(struct hpi_control_cache *p_cache)
648
{
649
if (p_cache) {
650
kfree(p_cache->p_info);
651
kfree(p_cache);
652
}
653
}
654
655
static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
656
{
657
hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 0);
658
659
switch (phm->function) {
660
case HPI_SUBSYS_OPEN:
661
case HPI_SUBSYS_CLOSE:
662
case HPI_SUBSYS_DRIVER_UNLOAD:
663
break;
664
case HPI_SUBSYS_DRIVER_LOAD:
665
wipe_adapter_list();
666
hpios_alistlock_init(&adapters);
667
break;
668
case HPI_SUBSYS_GET_ADAPTER:
669
subsys_get_adapter(phm, phr);
670
break;
671
case HPI_SUBSYS_GET_NUM_ADAPTERS:
672
phr->u.s.num_adapters = adapters.gw_num_adapters;
673
break;
674
case HPI_SUBSYS_CREATE_ADAPTER:
675
break;
676
default:
677
phr->error = HPI_ERROR_INVALID_FUNC;
678
break;
679
}
680
}
681
682
void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
683
{
684
switch (phm->type) {
685
case HPI_TYPE_MESSAGE:
686
switch (phm->object) {
687
case HPI_OBJ_SUBSYSTEM:
688
subsys_message(phm, phr);
689
break;
690
}
691
break;
692
693
default:
694
phr->error = HPI_ERROR_INVALID_TYPE;
695
break;
696
}
697
}
698
699