hpicmn.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. /******************************************************************************
  2. AudioScience HPI driver
  3. Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of version 2 of the GNU General Public License as
  6. published by the Free Software Foundation;
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  14. \file hpicmn.c
  15. Common functions used by hpixxxx.c modules
  16. (C) Copyright AudioScience Inc. 1998-2003
  17. *******************************************************************************/
  18. #define SOURCEFILE_NAME "hpicmn.c"
  19. #include "hpi_internal.h"
  20. #include "hpidebug.h"
  21. #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;
  26. };
  27. static struct hpi_adapters_list adapters;
  28. /**
  29. * Given an HPI Message that was sent out and a response that was received,
  30. * validate that the response has the correct fields filled in,
  31. * i.e ObjectType, Function etc
  32. **/
  33. u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
  34. {
  35. u16 error = 0;
  36. if ((phr->type != HPI_TYPE_RESPONSE)
  37. || (phr->object != phm->object)
  38. || (phr->function != phm->function))
  39. error = HPI_ERROR_INVALID_RESPONSE;
  40. return error;
  41. }
  42. u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
  43. {
  44. u16 retval = 0;
  45. /*HPI_ASSERT(pao->wAdapterType); */
  46. hpios_alistlock_lock(&adapters);
  47. if (pao->index >= HPI_MAX_ADAPTERS) {
  48. retval = HPI_ERROR_BAD_ADAPTER_NUMBER;
  49. goto unlock;
  50. }
  51. if (adapters.adapter[pao->index].adapter_type) {
  52. {
  53. retval = HPI_DUPLICATE_ADAPTER_NUMBER;
  54. goto unlock;
  55. }
  56. }
  57. adapters.adapter[pao->index] = *pao;
  58. hpios_dsplock_init(&adapters.adapter[pao->index]);
  59. adapters.gw_num_adapters++;
  60. unlock:
  61. hpios_alistlock_un_lock(&adapters);
  62. return retval;
  63. }
  64. void hpi_delete_adapter(struct hpi_adapter_obj *pao)
  65. {
  66. memset(pao, 0, sizeof(struct hpi_adapter_obj));
  67. hpios_alistlock_lock(&adapters);
  68. adapters.gw_num_adapters--; /* dec the number of adapters */
  69. hpios_alistlock_un_lock(&adapters);
  70. }
  71. /**
  72. * FindAdapter returns a pointer to the struct hpi_adapter_obj with
  73. * index wAdapterIndex in an HPI_ADAPTERS_LIST structure.
  74. *
  75. */
  76. struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
  77. {
  78. struct hpi_adapter_obj *pao = NULL;
  79. if (adapter_index >= HPI_MAX_ADAPTERS) {
  80. HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d ",
  81. adapter_index);
  82. return NULL;
  83. }
  84. pao = &adapters.adapter[adapter_index];
  85. if (pao->adapter_type != 0) {
  86. /*
  87. HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n",
  88. wAdapterIndex);
  89. */
  90. return pao;
  91. } else {
  92. /*
  93. HPI_DEBUG_LOG(VERBOSE, "No adapter index %d\n",
  94. wAdapterIndex);
  95. */
  96. return NULL;
  97. }
  98. }
  99. /**
  100. *
  101. * wipe an HPI_ADAPTERS_LIST structure.
  102. *
  103. **/
  104. static void wipe_adapter_list(void
  105. )
  106. {
  107. memset(&adapters, 0, sizeof(adapters));
  108. }
  109. /**
  110. * SubSysGetAdapters fills awAdapterList in an struct hpi_response structure
  111. * with all adapters in the given HPI_ADAPTERS_LIST.
  112. *
  113. */
  114. static void subsys_get_adapters(struct hpi_response *phr)
  115. {
  116. /* fill in the response adapter array with the position */
  117. /* identified by the adapter number/index of the adapters in */
  118. /* this HPI */
  119. /* i.e. if we have an A120 with it's jumper set to */
  120. /* Adapter Number 2 then put an Adapter type A120 in the */
  121. /* array in position 1 */
  122. /* NOTE: AdapterNumber is 1..N, Index is 0..N-1 */
  123. /* input: NONE */
  124. /* output: wNumAdapters */
  125. /* awAdapter[] */
  126. /* */
  127. short i;
  128. struct hpi_adapter_obj *pao = NULL;
  129. HPI_DEBUG_LOG(VERBOSE, "subsys_get_adapters\n");
  130. /* for each adapter, place it's type in the position of the array */
  131. /* corresponding to it's adapter number */
  132. for (i = 0; i < adapters.gw_num_adapters; i++) {
  133. pao = &adapters.adapter[i];
  134. if (phr->u.s.aw_adapter_list[pao->index] != 0) {
  135. phr->error = HPI_DUPLICATE_ADAPTER_NUMBER;
  136. phr->specific_error = pao->index;
  137. return;
  138. }
  139. phr->u.s.aw_adapter_list[pao->index] = pao->adapter_type;
  140. }
  141. phr->u.s.num_adapters = adapters.gw_num_adapters;
  142. phr->error = 0; /* the function completed OK; */
  143. }
  144. static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
  145. {
  146. unsigned int i;
  147. int cached = 0;
  148. if (!pC)
  149. return 0;
  150. if ((!pC->init) && (pC->p_cache != NULL) && (pC->control_count)
  151. && (pC->cache_size_in_bytes)
  152. ) {
  153. u32 *p_master_cache;
  154. pC->init = 1;
  155. p_master_cache = (u32 *)pC->p_cache;
  156. HPI_DEBUG_LOG(VERBOSE, "check %d controls\n",
  157. pC->control_count);
  158. for (i = 0; i < pC->control_count; i++) {
  159. struct hpi_control_cache_info *info =
  160. (struct hpi_control_cache_info *)
  161. p_master_cache;
  162. if (info->control_type) {
  163. pC->p_info[i] = info;
  164. cached++;
  165. } else
  166. pC->p_info[i] = NULL;
  167. if (info->size_in32bit_words)
  168. p_master_cache += info->size_in32bit_words;
  169. else
  170. p_master_cache +=
  171. sizeof(struct
  172. hpi_control_cache_single) /
  173. sizeof(u32);
  174. HPI_DEBUG_LOG(VERBOSE,
  175. "cached %d, pinfo %p index %d type %d\n",
  176. cached, pC->p_info[i], info->control_index,
  177. info->control_type);
  178. }
  179. /*
  180. We didn't find anything to cache, so try again later !
  181. */
  182. if (!cached)
  183. pC->init = 0;
  184. }
  185. return pC->init;
  186. }
  187. /** Find a control.
  188. */
  189. static short find_control(struct hpi_message *phm,
  190. struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI,
  191. u16 *pw_control_index)
  192. {
  193. *pw_control_index = phm->obj_index;
  194. if (!control_cache_alloc_check(p_cache)) {
  195. HPI_DEBUG_LOG(VERBOSE,
  196. "control_cache_alloc_check() failed. adap%d ci%d\n",
  197. phm->adapter_index, *pw_control_index);
  198. return 0;
  199. }
  200. *pI = p_cache->p_info[*pw_control_index];
  201. if (!*pI) {
  202. HPI_DEBUG_LOG(VERBOSE, "uncached adap %d, control %d\n",
  203. phm->adapter_index, *pw_control_index);
  204. return 0;
  205. } else {
  206. HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
  207. (*pI)->control_type);
  208. }
  209. return 1;
  210. }
  211. /** Used by the kernel driver to figure out if a buffer needs mapping.
  212. */
  213. short hpi_check_buffer_mapping(struct hpi_control_cache *p_cache,
  214. struct hpi_message *phm, void **p, unsigned int *pN)
  215. {
  216. *pN = 0;
  217. *p = NULL;
  218. if ((phm->function == HPI_CONTROL_GET_STATE)
  219. && (phm->object == HPI_OBJ_CONTROLEX)
  220. ) {
  221. u16 control_index;
  222. struct hpi_control_cache_info *pI;
  223. if (!find_control(phm, p_cache, &pI, &control_index))
  224. return 0;
  225. }
  226. return 0;
  227. }
  228. /* allow unified treatment of several string fields within struct */
  229. #define HPICMN_PAD_OFS_AND_SIZE(m) {\
  230. offsetof(struct hpi_control_cache_pad, m), \
  231. sizeof(((struct hpi_control_cache_pad *)(NULL))->m) }
  232. struct pad_ofs_size {
  233. unsigned int offset;
  234. unsigned int field_size;
  235. };
  236. static struct pad_ofs_size pad_desc[] = {
  237. HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */
  238. HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */
  239. HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */
  240. HPICMN_PAD_OFS_AND_SIZE(c_comment), /* HPI_PAD_COMMENT */
  241. };
  242. /** CheckControlCache checks the cache and fills the struct hpi_response
  243. * accordingly. It returns one if a cache hit occurred, zero otherwise.
  244. */
  245. short hpi_check_control_cache(struct hpi_control_cache *p_cache,
  246. struct hpi_message *phm, struct hpi_response *phr)
  247. {
  248. short found = 1;
  249. u16 control_index;
  250. struct hpi_control_cache_info *pI;
  251. struct hpi_control_cache_single *pC;
  252. struct hpi_control_cache_pad *p_pad;
  253. if (!find_control(phm, p_cache, &pI, &control_index))
  254. return 0;
  255. phr->error = 0;
  256. /* pC is the default cached control strucure. May be cast to
  257. something else in the following switch statement.
  258. */
  259. pC = (struct hpi_control_cache_single *)pI;
  260. p_pad = (struct hpi_control_cache_pad *)pI;
  261. switch (pI->control_type) {
  262. case HPI_CONTROL_METER:
  263. if (phm->u.c.attribute == HPI_METER_PEAK) {
  264. phr->u.c.an_log_value[0] = pC->u.p.an_log_peak[0];
  265. phr->u.c.an_log_value[1] = pC->u.p.an_log_peak[1];
  266. } else if (phm->u.c.attribute == HPI_METER_RMS) {
  267. phr->u.c.an_log_value[0] = pC->u.p.an_logRMS[0];
  268. phr->u.c.an_log_value[1] = pC->u.p.an_logRMS[1];
  269. } else
  270. found = 0;
  271. break;
  272. case HPI_CONTROL_VOLUME:
  273. if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
  274. phr->u.c.an_log_value[0] = pC->u.v.an_log[0];
  275. phr->u.c.an_log_value[1] = pC->u.v.an_log[1];
  276. } else
  277. found = 0;
  278. break;
  279. case HPI_CONTROL_MULTIPLEXER:
  280. if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
  281. phr->u.c.param1 = pC->u.x.source_node_type;
  282. phr->u.c.param2 = pC->u.x.source_node_index;
  283. } else {
  284. found = 0;
  285. }
  286. break;
  287. case HPI_CONTROL_CHANNEL_MODE:
  288. if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
  289. phr->u.c.param1 = pC->u.m.mode;
  290. else
  291. found = 0;
  292. break;
  293. case HPI_CONTROL_LEVEL:
  294. if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
  295. phr->u.c.an_log_value[0] = pC->u.l.an_log[0];
  296. phr->u.c.an_log_value[1] = pC->u.l.an_log[1];
  297. } else
  298. found = 0;
  299. break;
  300. case HPI_CONTROL_TUNER:
  301. if (phm->u.c.attribute == HPI_TUNER_FREQ)
  302. phr->u.c.param1 = pC->u.t.freq_ink_hz;
  303. else if (phm->u.c.attribute == HPI_TUNER_BAND)
  304. phr->u.c.param1 = pC->u.t.band;
  305. else if ((phm->u.c.attribute == HPI_TUNER_LEVEL)
  306. && (phm->u.c.param1 == HPI_TUNER_LEVEL_AVERAGE))
  307. if (pC->u.t.level == HPI_ERROR_ILLEGAL_CACHE_VALUE) {
  308. phr->u.c.param1 = 0;
  309. phr->error =
  310. HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
  311. } else
  312. phr->u.c.param1 = pC->u.t.level;
  313. else
  314. found = 0;
  315. break;
  316. case HPI_CONTROL_AESEBU_RECEIVER:
  317. if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS)
  318. phr->u.c.param1 = pC->u.aes3rx.error_status;
  319. else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
  320. phr->u.c.param1 = pC->u.aes3rx.source;
  321. else
  322. found = 0;
  323. break;
  324. case HPI_CONTROL_AESEBU_TRANSMITTER:
  325. if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
  326. phr->u.c.param1 = pC->u.aes3tx.format;
  327. else
  328. found = 0;
  329. break;
  330. case HPI_CONTROL_TONEDETECTOR:
  331. if (phm->u.c.attribute == HPI_TONEDETECTOR_STATE)
  332. phr->u.c.param1 = pC->u.tone.state;
  333. else
  334. found = 0;
  335. break;
  336. case HPI_CONTROL_SILENCEDETECTOR:
  337. if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
  338. phr->u.c.param1 = pC->u.silence.state;
  339. phr->u.c.param2 = pC->u.silence.count;
  340. } else
  341. found = 0;
  342. break;
  343. case HPI_CONTROL_MICROPHONE:
  344. if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
  345. phr->u.c.param1 = pC->u.phantom_power.state;
  346. else
  347. found = 0;
  348. break;
  349. case HPI_CONTROL_SAMPLECLOCK:
  350. if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
  351. phr->u.c.param1 = pC->u.clk.source;
  352. else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) {
  353. if (pC->u.clk.source_index ==
  354. HPI_ERROR_ILLEGAL_CACHE_VALUE) {
  355. phr->u.c.param1 = 0;
  356. phr->error =
  357. HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
  358. } else
  359. phr->u.c.param1 = pC->u.clk.source_index;
  360. } else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
  361. phr->u.c.param1 = pC->u.clk.sample_rate;
  362. else
  363. found = 0;
  364. break;
  365. case HPI_CONTROL_PAD:
  366. if (!(p_pad->field_valid_flags & (1 <<
  367. HPI_CTL_ATTR_INDEX(phm->u.c.
  368. attribute)))) {
  369. phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
  370. break;
  371. }
  372. if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
  373. phr->u.c.param1 = p_pad->pI;
  374. else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
  375. phr->u.c.param1 = p_pad->pTY;
  376. else {
  377. unsigned int index =
  378. HPI_CTL_ATTR_INDEX(phm->u.c.attribute) - 1;
  379. unsigned int offset = phm->u.c.param1;
  380. unsigned int pad_string_len, field_size;
  381. char *pad_string;
  382. unsigned int tocopy;
  383. HPI_DEBUG_LOG(VERBOSE, "PADS HPI_PADS_ %d\n",
  384. phm->u.c.attribute);
  385. if (index > ARRAY_SIZE(pad_desc) - 1) {
  386. phr->error =
  387. HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
  388. break;
  389. }
  390. pad_string = ((char *)p_pad) + pad_desc[index].offset;
  391. field_size = pad_desc[index].field_size;
  392. /* Ensure null terminator */
  393. pad_string[field_size - 1] = 0;
  394. pad_string_len = strlen(pad_string) + 1;
  395. if (offset > pad_string_len) {
  396. phr->error = HPI_ERROR_INVALID_CONTROL_VALUE;
  397. break;
  398. }
  399. tocopy = pad_string_len - offset;
  400. if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
  401. tocopy = sizeof(phr->u.cu.chars8.sz_data);
  402. HPI_DEBUG_LOG(VERBOSE,
  403. "PADS memcpy(%d), offset %d \n", tocopy,
  404. offset);
  405. memcpy(phr->u.cu.chars8.sz_data, &pad_string[offset],
  406. tocopy);
  407. phr->u.cu.chars8.remaining_chars =
  408. pad_string_len - offset - tocopy;
  409. }
  410. break;
  411. default:
  412. found = 0;
  413. break;
  414. }
  415. if (found)
  416. HPI_DEBUG_LOG(VERBOSE,
  417. "cached adap %d, ctl %d, type %d, attr %d\n",
  418. phm->adapter_index, pI->control_index,
  419. pI->control_type, phm->u.c.attribute);
  420. else
  421. HPI_DEBUG_LOG(VERBOSE,
  422. "uncached adap %d, ctl %d, ctl type %d\n",
  423. phm->adapter_index, pI->control_index,
  424. pI->control_type);
  425. if (found)
  426. phr->size =
  427. sizeof(struct hpi_response_header) +
  428. sizeof(struct hpi_control_res);
  429. return found;
  430. }
  431. /** Updates the cache with Set values.
  432. Only update if no error.
  433. Volume and Level return the limited values in the response, so use these
  434. Multiplexer does so use sent values
  435. */
  436. void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
  437. struct hpi_message *phm, struct hpi_response *phr)
  438. {
  439. u16 control_index;
  440. struct hpi_control_cache_single *pC;
  441. struct hpi_control_cache_info *pI;
  442. if (phr->error)
  443. return;
  444. if (!find_control(phm, p_cache, &pI, &control_index))
  445. return;
  446. /* pC is the default cached control strucure.
  447. May be cast to something else in the following switch statement.
  448. */
  449. pC = (struct hpi_control_cache_single *)pI;
  450. switch (pI->control_type) {
  451. case HPI_CONTROL_VOLUME:
  452. if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
  453. pC->u.v.an_log[0] = phr->u.c.an_log_value[0];
  454. pC->u.v.an_log[1] = phr->u.c.an_log_value[1];
  455. }
  456. break;
  457. case HPI_CONTROL_MULTIPLEXER:
  458. /* mux does not return its setting on Set command. */
  459. if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
  460. pC->u.x.source_node_type = (u16)phm->u.c.param1;
  461. pC->u.x.source_node_index = (u16)phm->u.c.param2;
  462. }
  463. break;
  464. case HPI_CONTROL_CHANNEL_MODE:
  465. /* mode does not return its setting on Set command. */
  466. if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
  467. pC->u.m.mode = (u16)phm->u.c.param1;
  468. break;
  469. case HPI_CONTROL_LEVEL:
  470. if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
  471. pC->u.v.an_log[0] = phr->u.c.an_log_value[0];
  472. pC->u.v.an_log[1] = phr->u.c.an_log_value[1];
  473. }
  474. break;
  475. case HPI_CONTROL_MICROPHONE:
  476. if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
  477. pC->u.phantom_power.state = (u16)phm->u.c.param1;
  478. break;
  479. case HPI_CONTROL_AESEBU_TRANSMITTER:
  480. if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
  481. pC->u.aes3tx.format = phm->u.c.param1;
  482. break;
  483. case HPI_CONTROL_AESEBU_RECEIVER:
  484. if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
  485. pC->u.aes3rx.source = phm->u.c.param1;
  486. break;
  487. case HPI_CONTROL_SAMPLECLOCK:
  488. if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
  489. pC->u.clk.source = (u16)phm->u.c.param1;
  490. else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX)
  491. pC->u.clk.source_index = (u16)phm->u.c.param1;
  492. else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
  493. pC->u.clk.sample_rate = phm->u.c.param1;
  494. break;
  495. default:
  496. break;
  497. }
  498. }
  499. struct hpi_control_cache *hpi_alloc_control_cache(const u32
  500. number_of_controls, const u32 size_in_bytes,
  501. struct hpi_control_cache_info *pDSP_control_buffer)
  502. {
  503. struct hpi_control_cache *p_cache =
  504. kmalloc(sizeof(*p_cache), GFP_KERNEL);
  505. p_cache->cache_size_in_bytes = size_in_bytes;
  506. p_cache->control_count = number_of_controls;
  507. p_cache->p_cache =
  508. (struct hpi_control_cache_single *)pDSP_control_buffer;
  509. p_cache->init = 0;
  510. p_cache->p_info =
  511. kmalloc(sizeof(*p_cache->p_info) * p_cache->control_count,
  512. GFP_KERNEL);
  513. return p_cache;
  514. }
  515. void hpi_free_control_cache(struct hpi_control_cache *p_cache)
  516. {
  517. if (p_cache->init) {
  518. kfree(p_cache->p_info);
  519. p_cache->p_info = NULL;
  520. p_cache->init = 0;
  521. kfree(p_cache);
  522. }
  523. }
  524. static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
  525. {
  526. switch (phm->function) {
  527. case HPI_SUBSYS_OPEN:
  528. case HPI_SUBSYS_CLOSE:
  529. case HPI_SUBSYS_DRIVER_UNLOAD:
  530. phr->error = 0;
  531. break;
  532. case HPI_SUBSYS_DRIVER_LOAD:
  533. wipe_adapter_list();
  534. hpios_alistlock_init(&adapters);
  535. phr->error = 0;
  536. break;
  537. case HPI_SUBSYS_GET_INFO:
  538. subsys_get_adapters(phr);
  539. break;
  540. case HPI_SUBSYS_CREATE_ADAPTER:
  541. case HPI_SUBSYS_DELETE_ADAPTER:
  542. phr->error = 0;
  543. break;
  544. default:
  545. phr->error = HPI_ERROR_INVALID_FUNC;
  546. break;
  547. }
  548. }
  549. void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
  550. {
  551. switch (phm->type) {
  552. case HPI_TYPE_MESSAGE:
  553. switch (phm->object) {
  554. case HPI_OBJ_SUBSYSTEM:
  555. subsys_message(phm, phr);
  556. break;
  557. }
  558. break;
  559. default:
  560. phr->error = HPI_ERROR_INVALID_TYPE;
  561. break;
  562. }
  563. }