ALSA: asihpi: Simplify driver unload cleanup
[linux-2.6.git] / sound / pci / asihpi / hpi6205.c
index 620525b..5303734 100644 (file)
@@ -152,8 +152,8 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
 
 static void subsys_create_adapter(struct hpi_message *phm,
        struct hpi_response *phr);
-static void subsys_delete_adapter(struct hpi_message *phm,
-       struct hpi_response *phr);
+static void adapter_delete(struct hpi_adapter_obj *pao,
+       struct hpi_message *phm, struct hpi_response *phr);
 
 static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
        u32 *pos_error_code);
@@ -223,15 +223,13 @@ static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index);
 
 /*****************************************************************************/
 
-static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
+static void subsys_message(struct hpi_adapter_obj *pao,
+       struct hpi_message *phm, struct hpi_response *phr)
 {
        switch (phm->function) {
        case HPI_SUBSYS_CREATE_ADAPTER:
                subsys_create_adapter(phm, phr);
                break;
-       case HPI_SUBSYS_DELETE_ADAPTER:
-               subsys_delete_adapter(phm, phr);
-               break;
        default:
                phr->error = HPI_ERROR_INVALID_FUNC;
                break;
@@ -279,6 +277,10 @@ static void adapter_message(struct hpi_adapter_obj *pao,
        struct hpi_message *phm, struct hpi_response *phr)
 {
        switch (phm->function) {
+       case HPI_ADAPTER_DELETE:
+               adapter_delete(pao, phm, phr);
+               break;
+
        default:
                hw_message(pao, phm, phr);
                break;
@@ -371,36 +373,17 @@ static void instream_message(struct hpi_adapter_obj *pao,
 /** Entry point to this HPI backend
  * All calls to the HPI start here
  */
-void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
+void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
+       struct hpi_response *phr)
 {
-       struct hpi_adapter_obj *pao = NULL;
-
-       /* subsytem messages are processed by every HPI.
-        * All other messages are ignored unless the adapter index matches
-        * an adapter in the HPI
-        */
-       /* HPI_DEBUG_LOG(DEBUG, "HPI Obj=%d, Func=%d\n", phm->wObject,
-          phm->wFunction); */
-
-       /* if Dsp has crashed then do not communicate with it any more */
-       if (phm->object != HPI_OBJ_SUBSYSTEM) {
-               pao = hpi_find_adapter(phm->adapter_index);
-               if (!pao) {
-                       HPI_DEBUG_LOG(DEBUG,
-                               " %d,%d refused, for another HPI?\n",
-                               phm->object, phm->function);
-                       return;
-               }
-
-               if ((pao->dsp_crashed >= 10)
-                       && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
-                       /* allow last resort debug read even after crash */
-                       hpi_init_response(phr, phm->object, phm->function,
-                               HPI_ERROR_DSP_HARDWARE);
-                       HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n",
-                               phm->object, phm->function);
-                       return;
-               }
+       if (pao && (pao->dsp_crashed >= 10)
+               && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
+               /* allow last resort debug read even after crash */
+               hpi_init_response(phr, phm->object, phm->function,
+                       HPI_ERROR_DSP_HARDWARE);
+               HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n", phm->object,
+                       phm->function);
+               return;
        }
 
        /* Init default response  */
@@ -412,7 +395,7 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
        case HPI_TYPE_MESSAGE:
                switch (phm->object) {
                case HPI_OBJ_SUBSYSTEM:
-                       subsys_message(phm, phr);
+                       subsys_message(pao, phm, phr);
                        break;
 
                case HPI_OBJ_ADAPTER:
@@ -444,6 +427,26 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
        }
 }
 
+void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
+{
+       struct hpi_adapter_obj *pao = NULL;
+
+       if (phm->object != HPI_OBJ_SUBSYSTEM) {
+               /* normal messages must have valid adapter index */
+               pao = hpi_find_adapter(phm->adapter_index);
+       } else {
+               /* subsys messages don't address an adapter */
+               _HPI_6205(NULL, phm, phr);
+               return;
+       }
+
+       if (pao)
+               _HPI_6205(pao, phm, phr);
+       else
+               hpi_init_response(phr, phm->object, phm->function,
+                       HPI_ERROR_BAD_ADAPTER_NUMBER);
+}
+
 /*****************************************************************************/
 /* SUBSYSTEM */
 
@@ -491,13 +494,11 @@ static void subsys_create_adapter(struct hpi_message *phm,
 }
 
 /** delete an adapter - required by WDM driver */
-static void subsys_delete_adapter(struct hpi_message *phm,
-       struct hpi_response *phr)
+static void adapter_delete(struct hpi_adapter_obj *pao,
+       struct hpi_message *phm, struct hpi_response *phr)
 {
-       struct hpi_adapter_obj *pao;
        struct hpi_hw_obj *phw;
 
-       pao = hpi_find_adapter(phm->obj_index);
        if (!pao) {
                phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
                return;
@@ -563,11 +564,12 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
        }
 
        err = adapter_boot_load_dsp(pao, pos_error_code);
-       if (err)
+       if (err) {
+               HPI_DEBUG_LOG(ERROR, "DSP code load failed\n");
                /* no need to clean up as SubSysCreateAdapter */
                /* calls DeleteAdapter on error. */
                return err;
-
+       }
        HPI_DEBUG_LOG(INFO, "load DSP code OK\n");
 
        /* allow boot load even if mem alloc wont work */
@@ -604,6 +606,7 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
                                control_cache.number_of_controls,
                                interface->control_cache.size_in_bytes,
                                p_control_cache_virtual);
+
                        if (!phw->p_cache)
                                err = HPI_ERROR_MEMORY_ALLOC;
                }
@@ -675,16 +678,14 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
 }
 
 /** Free memory areas allocated by adapter
- * this routine is called from SubSysDeleteAdapter,
+ * this routine is called from AdapterDelete,
   * and SubSysCreateAdapter if duplicate index
 */
 static void delete_adapter_obj(struct hpi_adapter_obj *pao)
 {
-       struct hpi_hw_obj *phw;
+       struct hpi_hw_obj *phw = pao->priv;
        int i;
 
-       phw = pao->priv;
-
        if (hpios_locked_mem_valid(&phw->h_control_cache)) {
                hpios_locked_mem_free(&phw->h_control_cache);
                hpi_free_control_cache(phw->p_cache);
@@ -1275,6 +1276,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
        case HPI_ADAPTER_FAMILY_ASI(0x6300):
                boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6400);
                break;
+       case HPI_ADAPTER_FAMILY_ASI(0x5500):
        case HPI_ADAPTER_FAMILY_ASI(0x5600):
        case HPI_ADAPTER_FAMILY_ASI(0x6500):
                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)
 static void send_dsp_command(struct hpi_hw_obj *phw, int cmd)
 {
        struct bus_master_interface *interface = phw->p_interface_buffer;
-
        u32 r;
 
        interface->host_cmd = cmd;
@@ -2088,7 +2089,7 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao,
                phr->specific_error = sizeof(interface->u);
                phr->size = sizeof(struct hpi_response_header);
                HPI_DEBUG_LOG(ERROR,
-                       "message len %d too big for buffer %zd \n", phm->size,
+                       "message len %d too big for buffer %ld \n", phm->size,
                        sizeof(interface->u));
                return 0;
        }