aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorEliot Blennerhassett <eblennerhassett@audioscience.com>2011-04-05 04:55:47 -0400
committerTakashi Iwai <tiwai@suse.de>2011-04-05 05:50:13 -0400
commit6d0b898e9c402d6b7d0d07adacdbee2ebedafdcd (patch)
treefb6cfb6c5ef00c1efdf425654a5fd534fdf6f0e6 /sound
parentb0096a65677fa8d7e50975dc7282ce313610d9e8 (diff)
ALSA: asihpi: Simplify driver unload cleanup
Replacing subsys_delete_adapter with adapter_delete allows some special-case adapter lookup code to be removed. Signed-off-by: Eliot Blennerhassett <eblennerhassett@audioscience.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/asihpi/hpi6000.c39
-rw-r--r--sound/pci/asihpi/hpi6205.c97
-rw-r--r--sound/pci/asihpi/hpi_internal.h17
-rw-r--r--sound/pci/asihpi/hpicmn.c1
-rw-r--r--sound/pci/asihpi/hpimsgx.c31
-rw-r--r--sound/pci/asihpi/hpioctl.c54
6 files changed, 113 insertions, 126 deletions
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c
index 3e3c2ef6efd8..09befdafe09f 100644
--- a/sound/pci/asihpi/hpi6000.c
+++ b/sound/pci/asihpi/hpi6000.c
@@ -200,8 +200,8 @@ static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
200static void subsys_create_adapter(struct hpi_message *phm, 200static void subsys_create_adapter(struct hpi_message *phm,
201 struct hpi_response *phr); 201 struct hpi_response *phr);
202 202
203static void subsys_delete_adapter(struct hpi_message *phm, 203static void adapter_delete(struct hpi_adapter_obj *pao,
204 struct hpi_response *phr); 204 struct hpi_message *phm, struct hpi_response *phr);
205 205
206static void adapter_get_asserts(struct hpi_adapter_obj *pao, 206static void adapter_get_asserts(struct hpi_adapter_obj *pao,
207 struct hpi_message *phm, struct hpi_response *phr); 207 struct hpi_message *phm, struct hpi_response *phr);
@@ -222,9 +222,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
222 case HPI_SUBSYS_CREATE_ADAPTER: 222 case HPI_SUBSYS_CREATE_ADAPTER:
223 subsys_create_adapter(phm, phr); 223 subsys_create_adapter(phm, phr);
224 break; 224 break;
225 case HPI_SUBSYS_DELETE_ADAPTER:
226 subsys_delete_adapter(phm, phr);
227 break;
228 default: 225 default:
229 phr->error = HPI_ERROR_INVALID_FUNC; 226 phr->error = HPI_ERROR_INVALID_FUNC;
230 break; 227 break;
@@ -279,6 +276,10 @@ static void adapter_message(struct hpi_adapter_obj *pao,
279 adapter_get_asserts(pao, phm, phr); 276 adapter_get_asserts(pao, phm, phr);
280 break; 277 break;
281 278
279 case HPI_ADAPTER_DELETE:
280 adapter_delete(pao, phm, phr);
281 break;
282
282 default: 283 default:
283 hw_message(pao, phm, phr); 284 hw_message(pao, phm, phr);
284 break; 285 break;
@@ -333,26 +334,22 @@ void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
333{ 334{
334 struct hpi_adapter_obj *pao = NULL; 335 struct hpi_adapter_obj *pao = NULL;
335 336
336 /* subsytem messages get executed by every HPI. */
337 /* All other messages are ignored unless the adapter index matches */
338 /* an adapter in the HPI */
339 /*HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->wObject, phm->wFunction); */
340
341 /* if Dsp has crashed then do not communicate with it any more */
342 if (phm->object != HPI_OBJ_SUBSYSTEM) { 337 if (phm->object != HPI_OBJ_SUBSYSTEM) {
343 pao = hpi_find_adapter(phm->adapter_index); 338 pao = hpi_find_adapter(phm->adapter_index);
344 if (!pao) { 339 if (!pao) {
345 HPI_DEBUG_LOG(DEBUG, 340 hpi_init_response(phr, phm->object, phm->function,
346 " %d,%d refused, for another HPI?\n", 341 HPI_ERROR_BAD_ADAPTER_NUMBER);
347 phm->object, phm->function); 342 HPI_DEBUG_LOG(DEBUG, "invalid adapter index: %d \n",
343 phm->adapter_index);
348 return; 344 return;
349 } 345 }
350 346
347 /* Don't even try to communicate with crashed DSP */
351 if (pao->dsp_crashed >= 10) { 348 if (pao->dsp_crashed >= 10) {
352 hpi_init_response(phr, phm->object, phm->function, 349 hpi_init_response(phr, phm->object, phm->function,
353 HPI_ERROR_DSP_HARDWARE); 350 HPI_ERROR_DSP_HARDWARE);
354 HPI_DEBUG_LOG(DEBUG, " %d,%d dsp crashed.\n", 351 HPI_DEBUG_LOG(DEBUG, "adapter %d dsp crashed\n",
355 phm->object, phm->function); 352 phm->adapter_index);
356 return; 353 return;
357 } 354 }
358 } 355 }
@@ -463,15 +460,9 @@ static void subsys_create_adapter(struct hpi_message *phm,
463 phr->error = 0; 460 phr->error = 0;
464} 461}
465 462
466static void subsys_delete_adapter(struct hpi_message *phm, 463static void adapter_delete(struct hpi_adapter_obj *pao,
467 struct hpi_response *phr) 464 struct hpi_message *phm, struct hpi_response *phr)
468{ 465{
469 struct hpi_adapter_obj *pao = NULL;
470
471 pao = hpi_find_adapter(phm->obj_index);
472 if (!pao)
473 return;
474
475 delete_adapter_obj(pao); 466 delete_adapter_obj(pao);
476 hpi_delete_adapter(pao); 467 hpi_delete_adapter(pao);
477 phr->error = 0; 468 phr->error = 0;
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c
index 620525bdac59..53037342cd29 100644
--- a/sound/pci/asihpi/hpi6205.c
+++ b/sound/pci/asihpi/hpi6205.c
@@ -152,8 +152,8 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
152 152
153static void subsys_create_adapter(struct hpi_message *phm, 153static void subsys_create_adapter(struct hpi_message *phm,
154 struct hpi_response *phr); 154 struct hpi_response *phr);
155static void subsys_delete_adapter(struct hpi_message *phm, 155static void adapter_delete(struct hpi_adapter_obj *pao,
156 struct hpi_response *phr); 156 struct hpi_message *phm, struct hpi_response *phr);
157 157
158static u16 create_adapter_obj(struct hpi_adapter_obj *pao, 158static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
159 u32 *pos_error_code); 159 u32 *pos_error_code);
@@ -223,15 +223,13 @@ static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index);
223 223
224/*****************************************************************************/ 224/*****************************************************************************/
225 225
226static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) 226static void subsys_message(struct hpi_adapter_obj *pao,
227 struct hpi_message *phm, struct hpi_response *phr)
227{ 228{
228 switch (phm->function) { 229 switch (phm->function) {
229 case HPI_SUBSYS_CREATE_ADAPTER: 230 case HPI_SUBSYS_CREATE_ADAPTER:
230 subsys_create_adapter(phm, phr); 231 subsys_create_adapter(phm, phr);
231 break; 232 break;
232 case HPI_SUBSYS_DELETE_ADAPTER:
233 subsys_delete_adapter(phm, phr);
234 break;
235 default: 233 default:
236 phr->error = HPI_ERROR_INVALID_FUNC; 234 phr->error = HPI_ERROR_INVALID_FUNC;
237 break; 235 break;
@@ -279,6 +277,10 @@ static void adapter_message(struct hpi_adapter_obj *pao,
279 struct hpi_message *phm, struct hpi_response *phr) 277 struct hpi_message *phm, struct hpi_response *phr)
280{ 278{
281 switch (phm->function) { 279 switch (phm->function) {
280 case HPI_ADAPTER_DELETE:
281 adapter_delete(pao, phm, phr);
282 break;
283
282 default: 284 default:
283 hw_message(pao, phm, phr); 285 hw_message(pao, phm, phr);
284 break; 286 break;
@@ -371,36 +373,17 @@ static void instream_message(struct hpi_adapter_obj *pao,
371/** Entry point to this HPI backend 373/** Entry point to this HPI backend
372 * All calls to the HPI start here 374 * All calls to the HPI start here
373 */ 375 */
374void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) 376void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
377 struct hpi_response *phr)
375{ 378{
376 struct hpi_adapter_obj *pao = NULL; 379 if (pao && (pao->dsp_crashed >= 10)
377 380 && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
378 /* subsytem messages are processed by every HPI. 381 /* allow last resort debug read even after crash */
379 * All other messages are ignored unless the adapter index matches 382 hpi_init_response(phr, phm->object, phm->function,
380 * an adapter in the HPI 383 HPI_ERROR_DSP_HARDWARE);
381 */ 384 HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n", phm->object,
382 /* HPI_DEBUG_LOG(DEBUG, "HPI Obj=%d, Func=%d\n", phm->wObject, 385 phm->function);
383 phm->wFunction); */ 386 return;
384
385 /* if Dsp has crashed then do not communicate with it any more */
386 if (phm->object != HPI_OBJ_SUBSYSTEM) {
387 pao = hpi_find_adapter(phm->adapter_index);
388 if (!pao) {
389 HPI_DEBUG_LOG(DEBUG,
390 " %d,%d refused, for another HPI?\n",
391 phm->object, phm->function);
392 return;
393 }
394
395 if ((pao->dsp_crashed >= 10)
396 && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
397 /* allow last resort debug read even after crash */
398 hpi_init_response(phr, phm->object, phm->function,
399 HPI_ERROR_DSP_HARDWARE);
400 HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n",
401 phm->object, phm->function);
402 return;
403 }
404 } 387 }
405 388
406 /* Init default response */ 389 /* Init default response */
@@ -412,7 +395,7 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
412 case HPI_TYPE_MESSAGE: 395 case HPI_TYPE_MESSAGE:
413 switch (phm->object) { 396 switch (phm->object) {
414 case HPI_OBJ_SUBSYSTEM: 397 case HPI_OBJ_SUBSYSTEM:
415 subsys_message(phm, phr); 398 subsys_message(pao, phm, phr);
416 break; 399 break;
417 400
418 case HPI_OBJ_ADAPTER: 401 case HPI_OBJ_ADAPTER:
@@ -444,6 +427,26 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
444 } 427 }
445} 428}
446 429
430void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
431{
432 struct hpi_adapter_obj *pao = NULL;
433
434 if (phm->object != HPI_OBJ_SUBSYSTEM) {
435 /* normal messages must have valid adapter index */
436 pao = hpi_find_adapter(phm->adapter_index);
437 } else {
438 /* subsys messages don't address an adapter */
439 _HPI_6205(NULL, phm, phr);
440 return;
441 }
442
443 if (pao)
444 _HPI_6205(pao, phm, phr);
445 else
446 hpi_init_response(phr, phm->object, phm->function,
447 HPI_ERROR_BAD_ADAPTER_NUMBER);
448}
449
447/*****************************************************************************/ 450/*****************************************************************************/
448/* SUBSYSTEM */ 451/* SUBSYSTEM */
449 452
@@ -491,13 +494,11 @@ static void subsys_create_adapter(struct hpi_message *phm,
491} 494}
492 495
493/** delete an adapter - required by WDM driver */ 496/** delete an adapter - required by WDM driver */
494static void subsys_delete_adapter(struct hpi_message *phm, 497static void adapter_delete(struct hpi_adapter_obj *pao,
495 struct hpi_response *phr) 498 struct hpi_message *phm, struct hpi_response *phr)
496{ 499{
497 struct hpi_adapter_obj *pao;
498 struct hpi_hw_obj *phw; 500 struct hpi_hw_obj *phw;
499 501
500 pao = hpi_find_adapter(phm->obj_index);
501 if (!pao) { 502 if (!pao) {
502 phr->error = HPI_ERROR_INVALID_OBJ_INDEX; 503 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
503 return; 504 return;
@@ -563,11 +564,12 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
563 } 564 }
564 565
565 err = adapter_boot_load_dsp(pao, pos_error_code); 566 err = adapter_boot_load_dsp(pao, pos_error_code);
566 if (err) 567 if (err) {
568 HPI_DEBUG_LOG(ERROR, "DSP code load failed\n");
567 /* no need to clean up as SubSysCreateAdapter */ 569 /* no need to clean up as SubSysCreateAdapter */
568 /* calls DeleteAdapter on error. */ 570 /* calls DeleteAdapter on error. */
569 return err; 571 return err;
570 572 }
571 HPI_DEBUG_LOG(INFO, "load DSP code OK\n"); 573 HPI_DEBUG_LOG(INFO, "load DSP code OK\n");
572 574
573 /* allow boot load even if mem alloc wont work */ 575 /* allow boot load even if mem alloc wont work */
@@ -604,6 +606,7 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
604 control_cache.number_of_controls, 606 control_cache.number_of_controls,
605 interface->control_cache.size_in_bytes, 607 interface->control_cache.size_in_bytes,
606 p_control_cache_virtual); 608 p_control_cache_virtual);
609
607 if (!phw->p_cache) 610 if (!phw->p_cache)
608 err = HPI_ERROR_MEMORY_ALLOC; 611 err = HPI_ERROR_MEMORY_ALLOC;
609 } 612 }
@@ -675,16 +678,14 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
675} 678}
676 679
677/** Free memory areas allocated by adapter 680/** Free memory areas allocated by adapter
678 * this routine is called from SubSysDeleteAdapter, 681 * this routine is called from AdapterDelete,
679 * and SubSysCreateAdapter if duplicate index 682 * and SubSysCreateAdapter if duplicate index
680*/ 683*/
681static void delete_adapter_obj(struct hpi_adapter_obj *pao) 684static void delete_adapter_obj(struct hpi_adapter_obj *pao)
682{ 685{
683 struct hpi_hw_obj *phw; 686 struct hpi_hw_obj *phw = pao->priv;
684 int i; 687 int i;
685 688
686 phw = pao->priv;
687
688 if (hpios_locked_mem_valid(&phw->h_control_cache)) { 689 if (hpios_locked_mem_valid(&phw->h_control_cache)) {
689 hpios_locked_mem_free(&phw->h_control_cache); 690 hpios_locked_mem_free(&phw->h_control_cache);
690 hpi_free_control_cache(phw->p_cache); 691 hpi_free_control_cache(phw->p_cache);
@@ -1275,6 +1276,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1275 case HPI_ADAPTER_FAMILY_ASI(0x6300): 1276 case HPI_ADAPTER_FAMILY_ASI(0x6300):
1276 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6400); 1277 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6400);
1277 break; 1278 break;
1279 case HPI_ADAPTER_FAMILY_ASI(0x5500):
1278 case HPI_ADAPTER_FAMILY_ASI(0x5600): 1280 case HPI_ADAPTER_FAMILY_ASI(0x5600):
1279 case HPI_ADAPTER_FAMILY_ASI(0x6500): 1281 case HPI_ADAPTER_FAMILY_ASI(0x6500):
1280 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6600); 1282 boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6600);
@@ -2059,7 +2061,6 @@ static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us)
2059static void send_dsp_command(struct hpi_hw_obj *phw, int cmd) 2061static void send_dsp_command(struct hpi_hw_obj *phw, int cmd)
2060{ 2062{
2061 struct bus_master_interface *interface = phw->p_interface_buffer; 2063 struct bus_master_interface *interface = phw->p_interface_buffer;
2062
2063 u32 r; 2064 u32 r;
2064 2065
2065 interface->host_cmd = cmd; 2066 interface->host_cmd = cmd;
@@ -2088,7 +2089,7 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao,
2088 phr->specific_error = sizeof(interface->u); 2089 phr->specific_error = sizeof(interface->u);
2089 phr->size = sizeof(struct hpi_response_header); 2090 phr->size = sizeof(struct hpi_response_header);
2090 HPI_DEBUG_LOG(ERROR, 2091 HPI_DEBUG_LOG(ERROR,
2091 "message len %d too big for buffer %zd \n", phm->size, 2092 "message len %d too big for buffer %ld \n", phm->size,
2092 sizeof(interface->u)); 2093 sizeof(interface->u));
2093 return 0; 2094 return 0;
2094 } 2095 }
diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h
index af678be0aa15..d829a65f47d0 100644
--- a/sound/pci/asihpi/hpi_internal.h
+++ b/sound/pci/asihpi/hpi_internal.h
@@ -294,7 +294,7 @@ enum HPI_CONTROL_ATTRIBUTES {
294 294
295/* These defines are used to fill in protocol information for an Ethernet packet 295/* These defines are used to fill in protocol information for an Ethernet packet
296 sent using HMI on CS18102 */ 296 sent using HMI on CS18102 */
297/** ID supplied by Cirrius for ASI packets. */ 297/** ID supplied by Cirrus for ASI packets. */
298#define HPI_ETHERNET_PACKET_ID 0x85 298#define HPI_ETHERNET_PACKET_ID 0x85
299/** Simple packet - no special routing required */ 299/** Simple packet - no special routing required */
300#define HPI_ETHERNET_PACKET_V1 0x01 300#define HPI_ETHERNET_PACKET_V1 0x01
@@ -307,7 +307,7 @@ enum HPI_CONTROL_ATTRIBUTES {
307/** This packet must make its way to the host across the HPI interface */ 307/** This packet must make its way to the host across the HPI interface */
308#define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI_V1 0x41 308#define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI_V1 0x41
309 309
310#define HPI_ETHERNET_UDP_PORT (44600) /*!< UDP messaging port */ 310#define HPI_ETHERNET_UDP_PORT 44600 /**< HPI UDP service */
311 311
312/** Default network timeout in milli-seconds. */ 312/** Default network timeout in milli-seconds. */
313#define HPI_ETHERNET_TIMEOUT_MS 500 313#define HPI_ETHERNET_TIMEOUT_MS 500
@@ -397,14 +397,14 @@ enum HPI_FUNCTION_IDS {
397 HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1), 397 HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1),
398 HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2), 398 HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2),
399 HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3), 399 HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3),
400 HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4), 400 /* HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4), */
401 HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5), 401 HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5),
402 HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6), 402 HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6),
403 HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7), 403 /* HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7), */
404 HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8), 404 HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8),
405 HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9), 405 HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9),
406 HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10), 406 /* HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10), */
407 HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11), 407 /* HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11), */
408 HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12), 408 HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12),
409 HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13), 409 HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13),
410 HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14), 410 HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14),
@@ -433,7 +433,8 @@ enum HPI_FUNCTION_IDS {
433 HPI_ADAPTER_DEBUG_READ = HPI_FUNC_ID(ADAPTER, 18), 433 HPI_ADAPTER_DEBUG_READ = HPI_FUNC_ID(ADAPTER, 18),
434 HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19), 434 HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19),
435 HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20), 435 HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20),
436#define HPI_ADAPTER_FUNCTION_COUNT 20 436 HPI_ADAPTER_DELETE = HPI_FUNC_ID(ADAPTER, 21),
437#define HPI_ADAPTER_FUNCTION_COUNT 21
437 438
438 HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1), 439 HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1),
439 HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2), 440 HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2),
@@ -1561,8 +1562,6 @@ void hpi_send_recv(struct hpi_message *phm, struct hpi_response *phr);
1561u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource, 1562u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource,
1562 u16 *pw_adapter_index); 1563 u16 *pw_adapter_index);
1563 1564
1564u16 hpi_subsys_delete_adapter(u16 adapter_index);
1565
1566u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer, 1565u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer,
1567 struct hpi_hostbuffer_status **pp_status); 1566 struct hpi_hostbuffer_status **pp_status);
1568 1567
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c
index 3e9c5c289764..0428f285725d 100644
--- a/sound/pci/asihpi/hpicmn.c
+++ b/sound/pci/asihpi/hpicmn.c
@@ -667,7 +667,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
667 phr->u.s.num_adapters = adapters.gw_num_adapters; 667 phr->u.s.num_adapters = adapters.gw_num_adapters;
668 break; 668 break;
669 case HPI_SUBSYS_CREATE_ADAPTER: 669 case HPI_SUBSYS_CREATE_ADAPTER:
670 case HPI_SUBSYS_DELETE_ADAPTER:
671 break; 670 break;
672 default: 671 default:
673 phr->error = HPI_ERROR_INVALID_FUNC; 672 phr->error = HPI_ERROR_INVALID_FUNC;
diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c
index bcbdf30a6aa0..888e37966c3f 100644
--- a/sound/pci/asihpi/hpimsgx.c
+++ b/sound/pci/asihpi/hpimsgx.c
@@ -211,24 +211,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
211 HPIMSGX__init(phm, phr); 211 HPIMSGX__init(phm, phr);
212 break; 212 break;
213 213
214 case HPI_SUBSYS_DELETE_ADAPTER:
215 HPIMSGX__cleanup(phm->obj_index, h_owner);
216 {
217 struct hpi_message hm;
218 struct hpi_response hr;
219 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
220 HPI_ADAPTER_CLOSE);
221 hm.adapter_index = phm->obj_index;
222 hw_entry_point(&hm, &hr);
223 }
224 if ((phm->obj_index < HPI_MAX_ADAPTERS)
225 && hpi_entry_points[phm->obj_index]) {
226 hpi_entry_points[phm->obj_index] (phm, phr);
227 hpi_entry_points[phm->obj_index] = NULL;
228 } else
229 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
230
231 break;
232 default: 214 default:
233 /* Must explicitly handle every subsys message in this switch */ 215 /* Must explicitly handle every subsys message in this switch */
234 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 216 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function,
@@ -247,6 +229,19 @@ static void adapter_message(struct hpi_message *phm, struct hpi_response *phr,
247 case HPI_ADAPTER_CLOSE: 229 case HPI_ADAPTER_CLOSE:
248 adapter_close(phm, phr); 230 adapter_close(phm, phr);
249 break; 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
250 default: 245 default:
251 hw_entry_point(phm, phr); 246 hw_entry_point(phm, phr);
252 break; 247 break;
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
index cd624f13ff8e..484f41189867 100644
--- a/sound/pci/asihpi/hpioctl.c
+++ b/sound/pci/asihpi/hpioctl.c
@@ -25,6 +25,7 @@ Common Linux HPI ioctl and module probe/remove functions
25#include "hpidebug.h" 25#include "hpidebug.h"
26#include "hpimsgx.h" 26#include "hpimsgx.h"
27#include "hpioctl.h" 27#include "hpioctl.h"
28#include "hpicmn.h"
28 29
29#include <linux/fs.h> 30#include <linux/fs.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
@@ -161,26 +162,24 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
161 goto out; 162 goto out;
162 } 163 }
163 164
164 pa = &adapters[hm->h.adapter_index]; 165 switch (hm->h.function) {
166 case HPI_SUBSYS_CREATE_ADAPTER:
167 case HPI_ADAPTER_DELETE:
168 /* Application must not use these functions! */
169 hr->h.size = sizeof(hr->h);
170 hr->h.error = HPI_ERROR_INVALID_OPERATION;
171 hr->h.function = hm->h.function;
172 uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
173 if (uncopied_bytes)
174 err = -EFAULT;
175 else
176 err = 0;
177 goto out;
178 }
179
165 hr->h.size = res_max_size; 180 hr->h.size = res_max_size;
166 if (hm->h.object == HPI_OBJ_SUBSYSTEM) { 181 if (hm->h.object == HPI_OBJ_SUBSYSTEM) {
167 switch (hm->h.function) { 182 hpi_send_recv_f(&hm->m0, &hr->r0, file);
168 case HPI_SUBSYS_CREATE_ADAPTER:
169 case HPI_SUBSYS_DELETE_ADAPTER:
170 /* Application must not use these functions! */
171 hr->h.size = sizeof(hr->h);
172 hr->h.error = HPI_ERROR_INVALID_OPERATION;
173 hr->h.function = hm->h.function;
174 uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
175 if (uncopied_bytes)
176 err = -EFAULT;
177 else
178 err = 0;
179 goto out;
180
181 default:
182 hpi_send_recv_f(&hm->m0, &hr->r0, file);
183 }
184 } else { 183 } else {
185 u16 __user *ptr = NULL; 184 u16 __user *ptr = NULL;
186 u32 size = 0; 185 u32 size = 0;
@@ -188,8 +187,9 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
188 /* -1=no data 0=read from user mem, 1=write to user mem */ 187 /* -1=no data 0=read from user mem, 1=write to user mem */
189 int wrflag = -1; 188 int wrflag = -1;
190 u32 adapter = hm->h.adapter_index; 189 u32 adapter = hm->h.adapter_index;
190 pa = &adapters[adapter];
191 191
192 if ((hm->h.adapter_index > HPI_MAX_ADAPTERS) || (!pa->type)) { 192 if ((adapter > HPI_MAX_ADAPTERS) || (!pa->type)) {
193 hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER, 193 hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER,
194 HPI_ADAPTER_OPEN, 194 HPI_ADAPTER_OPEN,
195 HPI_ERROR_BAD_ADAPTER_NUMBER); 195 HPI_ERROR_BAD_ADAPTER_NUMBER);
@@ -395,17 +395,20 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
395 395
396 adapter.index = hr.u.s.adapter_index; 396 adapter.index = hr.u.s.adapter_index;
397 adapter.type = hr.u.s.adapter_type; 397 adapter.type = hr.u.s.adapter_type;
398
399 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
400 HPI_ADAPTER_OPEN);
398 hm.adapter_index = adapter.index; 401 hm.adapter_index = adapter.index;
402 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
399 403
400 err = hpi_adapter_open(adapter.index); 404 if (hr.error)
401 if (err)
402 goto err; 405 goto err;
403 406
404 adapter.snd_card_asihpi = NULL; 407 adapter.snd_card_asihpi = NULL;
405 /* WARNING can't init mutex in 'adapter' 408 /* WARNING can't init mutex in 'adapter'
406 * and then copy it to adapters[] ?!?! 409 * and then copy it to adapters[] ?!?!
407 */ 410 */
408 adapters[hr.u.s.adapter_index] = adapter; 411 adapters[adapter.index] = adapter;
409 mutex_init(&adapters[adapter.index].mutex); 412 mutex_init(&adapters[adapter.index].mutex);
410 pci_set_drvdata(pci_dev, &adapters[adapter.index]); 413 pci_set_drvdata(pci_dev, &adapters[adapter.index]);
411 414
@@ -440,10 +443,9 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
440 struct hpi_adapter *pa; 443 struct hpi_adapter *pa;
441 pa = pci_get_drvdata(pci_dev); 444 pa = pci_get_drvdata(pci_dev);
442 445
443 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, 446 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
444 HPI_SUBSYS_DELETE_ADAPTER); 447 HPI_ADAPTER_DELETE);
445 hm.obj_index = pa->index; 448 hm.adapter_index = pa->index;
446 hm.adapter_index = HPI_ADAPTER_INDEX_INVALID;
447 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); 449 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
448 450
449 /* unmap PCI memory space, mapped during device init. */ 451 /* unmap PCI memory space, mapped during device init. */