/* * ======== cmm_get_handle ======== * Purpose: * Return the communication memory manager object for this device. * This is typically called from the client process. */ int cmm_get_handle(void *hprocessor, OUT struct cmm_object ** ph_cmm_mgr) { int status = 0; struct dev_object *hdev_obj; DBC_REQUIRE(refs > 0); DBC_REQUIRE(ph_cmm_mgr != NULL); if (hprocessor != NULL) status = proc_get_dev_object(hprocessor, &hdev_obj); else hdev_obj = dev_get_first(); /* default */ if (DSP_SUCCEEDED(status)) status = dev_get_cmm_mgr(hdev_obj, ph_cmm_mgr); return status; }
/* * ======== get_allocator ======== * Purpose: * Return the allocator for the given SM Segid. * SegIds: 1,2,3..max. */ static struct cmm_allocator *get_allocator(struct cmm_object *cmm_mgr_obj, u32 ul_seg_id) { struct cmm_allocator *allocator = NULL; DBC_REQUIRE(cmm_mgr_obj != NULL); DBC_REQUIRE((ul_seg_id > 0) && (ul_seg_id <= CMM_MAXGPPSEGS)); allocator = cmm_mgr_obj->pa_gppsm_seg_tab[ul_seg_id - 1]; if (allocator != NULL) { /* make sure it's for real */ if (!allocator) { allocator = NULL; DBC_ASSERT(false); } } return allocator; }
/* * ======== cod_exit ======== * Purpose: * Discontinue usage of the COD module. * */ void cod_exit(void) { DBC_REQUIRE(refs > 0); refs--; DBC_ENSURE(refs >= 0); }
/* * ======== rmm_init ======== */ bool rmm_init(void) { DBC_REQUIRE(refs >= 0); refs++; return true; }
/* * ======== cmm_free_buf ======== * Purpose: * Free the given buffer. */ int cmm_free_buf(struct cmm_object *hcmm_mgr, void *buf_pa, u32 ul_seg_id) { struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr; int status = -EFAULT; struct cmm_mnode *mnode_obj = NULL; struct cmm_allocator *allocator = NULL; struct cmm_attrs *pattrs; DBC_REQUIRE(refs > 0); DBC_REQUIRE(buf_pa != NULL); if (ul_seg_id == 0) { pattrs = &cmm_dfltalctattrs; ul_seg_id = pattrs->ul_seg_id; } if (!hcmm_mgr || !(ul_seg_id > 0)) { status = -EFAULT; return status; } /* get the allocator for this segment id */ allocator = get_allocator(cmm_mgr_obj, ul_seg_id); if (allocator != NULL) { mutex_lock(&cmm_mgr_obj->cmm_lock); mnode_obj = (struct cmm_mnode *)lst_first(allocator->in_use_list_head); while (mnode_obj) { if ((u32) buf_pa == mnode_obj->dw_pa) { /* Found it */ lst_remove_elem(allocator->in_use_list_head, (struct list_head *)mnode_obj); /* back to freelist */ add_to_free_list(allocator, mnode_obj); status = 0; /* all right! */ break; } /* next node. */ mnode_obj = (struct cmm_mnode *) lst_next(allocator->in_use_list_head, (struct list_head *)mnode_obj); } mutex_unlock(&cmm_mgr_obj->cmm_lock); } return status; }
/* * ======== rmm_free ======== */ bool rmm_free(struct rmm_target_obj *target, u32 segid, u32 addr, u32 size, bool reserved) { struct rmm_ovly_sect *sect; bool ret = true; DBC_REQUIRE(target); DBC_REQUIRE(reserved || segid < target->num_segs); DBC_REQUIRE(reserved || (addr >= target->seg_tab[segid].base && (addr + size) <= (target->seg_tab[segid].base + target->seg_tab[segid]. length))); /* * Free or unreserve memory. */ if (!reserved) { ret = free_block(target, segid, addr, size); if (ret) target->seg_tab[segid].number--; } else { /* Unreserve memory */ sect = (struct rmm_ovly_sect *)lst_first(target->ovly_list); while (sect != NULL) { if (addr == sect->addr) { DBC_ASSERT(size == sect->size); /* Remove from list */ lst_remove_elem(target->ovly_list, (struct list_head *)sect); kfree(sect); break; } sect = (struct rmm_ovly_sect *)lst_next(target->ovly_list, (struct list_head *)sect); } if (sect == NULL) ret = false; } return ret; }
/* * ========= dev_get_io_mgr ======== */ int dev_get_io_mgr(struct dev_object *hdev_obj, struct io_mgr **io_man) { int status = 0; DBC_REQUIRE(refs > 0); DBC_REQUIRE(io_man != NULL); DBC_REQUIRE(hdev_obj); if (hdev_obj) { *io_man = hdev_obj->hio_mgr; } else { *io_man = NULL; status = -EFAULT; } return status; }
/* * ======== dev_create2 ======== * Purpose: * After successful loading of the image from api_init_complete2 * (PROC Auto_Start) or proc_load this fxn is called. This creates * the Node Manager and updates the DEV Object. */ int dev_create2(struct dev_object *hdev_obj) { int status = 0; struct dev_object *dev_obj = hdev_obj; DBC_REQUIRE(refs > 0); DBC_REQUIRE(hdev_obj); /* There can be only one Node Manager per DEV object */ DBC_ASSERT(!dev_obj->hnode_mgr); status = node_create_mgr(&dev_obj->hnode_mgr, hdev_obj); if (status) dev_obj->hnode_mgr = NULL; DBC_ENSURE((!status && dev_obj->hnode_mgr != NULL) || (status && dev_obj->hnode_mgr == NULL)); return status; }
/* * ======== mgr_exit ======== * Decrement reference count, and free resources when reference count is * 0. */ void mgr_exit(void) { DBC_REQUIRE(refs > 0); refs--; if (refs == 0) dcd_exit(); DBC_ENSURE(refs >= 0); }
/* * ======== cod_delete ======== * Purpose: * Delete a code manager object. */ void cod_delete(struct cod_manager *cod_mgr_obj) { DBC_REQUIRE(refs > 0); DBC_REQUIRE(cod_mgr_obj); if (cod_mgr_obj->base_lib) { if (cod_mgr_obj->loaded) cod_mgr_obj->fxns.unload_fxn(cod_mgr_obj->base_lib, &cod_mgr_obj->attrs); cod_mgr_obj->fxns.close_fxn(cod_mgr_obj->base_lib); } if (cod_mgr_obj->target) { cod_mgr_obj->fxns.delete_fxn(cod_mgr_obj->target); cod_mgr_obj->fxns.exit_fxn(); } kfree(cod_mgr_obj); }
/* * ========= dev_get_io_mgr ======== */ int dev_get_io_mgr(struct dev_object *hdev_obj, OUT struct io_mgr **phIOMgr) { int status = 0; DBC_REQUIRE(refs > 0); DBC_REQUIRE(phIOMgr != NULL); DBC_REQUIRE(hdev_obj); if (hdev_obj) { *phIOMgr = hdev_obj->hio_mgr; } else { *phIOMgr = NULL; status = -EFAULT; } return status; }
/* * ======== free_chirp_list ======== * Purpose: * Free the queue of Chirps. */ static void free_chirp_list(struct lst_list *chirp_list) { DBC_REQUIRE(chirp_list != NULL); while (!LST_IS_EMPTY(chirp_list)) kfree(lst_get_head(chirp_list)); kfree(chirp_list); }
/* * ======== dev_get_cod_mgr ======== * Purpose: * Retrieve the COD manager create for this device. */ int dev_get_cod_mgr(struct dev_object *hdev_obj, struct cod_manager **cod_mgr) { int status = 0; struct dev_object *dev_obj = hdev_obj; DBC_REQUIRE(refs > 0); DBC_REQUIRE(cod_mgr != NULL); if (hdev_obj) { *cod_mgr = dev_obj->cod_mgr; } else { *cod_mgr = NULL; status = -EFAULT; } DBC_ENSURE(!status || (cod_mgr != NULL && *cod_mgr == NULL)); return status; }
/* * ======== dev_get_dmm_mgr ======== * Purpose: * Retrieve the handle to the dynamic memory manager created for this * device. */ int dev_get_dmm_mgr(struct dev_object *hdev_obj, struct dmm_object **mgr) { int status = 0; struct dev_object *dev_obj = hdev_obj; DBC_REQUIRE(refs > 0); DBC_REQUIRE(mgr != NULL); if (hdev_obj) { *mgr = dev_obj->dmm_mgr; } else { *mgr = NULL; status = -EFAULT; } DBC_ENSURE(!status || (mgr != NULL && *mgr == NULL)); return status; }
/* * ======== dev_destroy2 ======== * Purpose: * Destroys the Node manager for this device. */ int dev_destroy2(struct dev_object *hdev_obj) { int status = 0; struct dev_object *dev_obj = hdev_obj; DBC_REQUIRE(refs > 0); DBC_REQUIRE(hdev_obj); if (dev_obj->hnode_mgr) { if (node_delete_mgr(dev_obj->hnode_mgr)) status = -EPERM; else dev_obj->hnode_mgr = NULL; } DBC_ENSURE((!status && dev_obj->hnode_mgr == NULL) || status); return status; }
/* * ======== dev_get_intf_fxns ======== * Purpose: * Retrieve the Bridge interface function structure for the loaded driver. * if_fxns != NULL. */ int dev_get_intf_fxns(struct dev_object *hdev_obj, struct bridge_drv_interface **if_fxns) { int status = 0; struct dev_object *dev_obj = hdev_obj; DBC_REQUIRE(refs > 0); DBC_REQUIRE(if_fxns != NULL); if (hdev_obj) { *if_fxns = &dev_obj->bridge_interface; } else { *if_fxns = NULL; status = -EFAULT; } DBC_ENSURE(!status || ((if_fxns != NULL) && (*if_fxns == NULL))); return status; }
/* * ======== dev_get_dev_node ======== * Purpose: * Retrieve the platform specific device ID for this device. */ int dev_get_dev_node(struct dev_object *hdev_obj, struct cfg_devnode **dev_nde) { int status = 0; struct dev_object *dev_obj = hdev_obj; DBC_REQUIRE(refs > 0); DBC_REQUIRE(dev_nde != NULL); if (hdev_obj) { *dev_nde = dev_obj->dev_node_obj; } else { *dev_nde = NULL; status = -EFAULT; } DBC_ENSURE(!status || (dev_nde != NULL && *dev_nde == NULL)); return status; }
/* * ======== msg_mod_init ======== */ bool msg_mod_init(void) { DBC_REQUIRE(refs >= 0); refs++; DBC_ENSURE(refs >= 0); return true; }
/* * ======== mgr_get_dcd_handle ======== * Retrieves the MGR handle. Accessor Function. */ int mgr_get_dcd_handle(struct mgr_object *mgr_handle, u32 *dcd_handle) { int status = -EPERM; struct mgr_object *pmgr_obj = (struct mgr_object *)mgr_handle; DBC_REQUIRE(refs > 0); DBC_REQUIRE(dcd_handle != NULL); *dcd_handle = (u32) NULL; if (pmgr_obj) { *dcd_handle = (u32) pmgr_obj->dcd_mgr; status = 0; } DBC_ENSURE((!status && *dcd_handle != (u32) NULL) || (status && *dcd_handle == (u32) NULL)); return status; }
/* * ======== dev_get_node_manager ======== * Purpose: * Retrieve the Node Manager Handle */ int dev_get_node_manager(struct dev_object *hdev_obj, struct node_mgr **node_man) { int status = 0; struct dev_object *dev_obj = hdev_obj; DBC_REQUIRE(refs > 0); DBC_REQUIRE(node_man != NULL); if (hdev_obj) { *node_man = dev_obj->hnode_mgr; } else { *node_man = NULL; status = -EFAULT; } DBC_ENSURE(!status || (node_man != NULL && *node_man == NULL)); return status; }
/* * ======== dev_get_dev_node ======== * Purpose: * Retrieve the platform specific device ID for this device. */ int dev_get_dev_node(struct dev_object *hdev_obj, OUT struct cfg_devnode **phDevNode) { int status = 0; struct dev_object *dev_obj = hdev_obj; DBC_REQUIRE(refs > 0); DBC_REQUIRE(phDevNode != NULL); if (hdev_obj) { *phDevNode = dev_obj->dev_node_obj; } else { *phDevNode = NULL; status = -EFAULT; } DBC_ENSURE(DSP_SUCCEEDED(status) || ((phDevNode != NULL) && (*phDevNode == NULL))); return status; }
/* * ======== dbll_init ======== */ bool dbll_init(void) { DBC_REQUIRE(refs >= 0); if (refs == 0) gh_init(); refs++; return true; }
/* * ======== dbll_exit ======== * Discontinue usage of DBL module. */ void dbll_exit(void) { DBC_REQUIRE(refs > 0); refs--; if (refs == 0) gh_exit(); DBC_ENSURE(refs >= 0); }
/* * ======== cod_read_section ======== * Purpose: * Retrieve the content of a code section given the section name. */ int cod_read_section(struct cod_libraryobj *lib, char *str_sect, char *str_content, u32 content_size) { int status = 0; DBC_REQUIRE(refs > 0); DBC_REQUIRE(lib != NULL); DBC_REQUIRE(lib->cod_mgr); DBC_REQUIRE(str_sect != NULL); DBC_REQUIRE(str_content != NULL); if (lib != NULL) status = lib->cod_mgr->fxns.read_sect_fxn(lib->dbll_lib, str_sect, str_content, content_size); else status = -ESPIPE; return status; }
/* * ======== dev_get_node_manager ======== * Purpose: * Retrieve the Node Manager Handle */ int dev_get_node_manager(struct dev_object *hdev_obj, OUT struct node_mgr **phNodeMgr) { int status = 0; struct dev_object *dev_obj = hdev_obj; DBC_REQUIRE(refs > 0); DBC_REQUIRE(phNodeMgr != NULL); if (hdev_obj) { *phNodeMgr = dev_obj->hnode_mgr; } else { *phNodeMgr = NULL; status = -EFAULT; } DBC_ENSURE(DSP_SUCCEEDED(status) || ((phNodeMgr != NULL) && (*phNodeMgr == NULL))); return status; }
/* * ======== dev_get_wmd_context ======== * Purpose: * Retrieve the WMD Context handle, as returned by the WMD_Create fxn. */ int dev_get_wmd_context(struct dev_object *hdev_obj, OUT struct wmd_dev_context **phWmdContext) { int status = 0; struct dev_object *dev_obj = hdev_obj; DBC_REQUIRE(refs > 0); DBC_REQUIRE(phWmdContext != NULL); if (hdev_obj) { *phWmdContext = dev_obj->hwmd_context; } else { *phWmdContext = NULL; status = -EFAULT; } DBC_ENSURE(DSP_SUCCEEDED(status) || ((phWmdContext != NULL) && (*phWmdContext == NULL))); return status; }
/* * ======== cmm_destroy ======== * Purpose: * Release the communication memory manager resources. */ int cmm_destroy(struct cmm_object *hcmm_mgr, bool bForce) { struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr; struct cmm_info temp_info; int status = 0; s32 slot_seg; struct cmm_mnode *pnode; DBC_REQUIRE(refs > 0); if (!hcmm_mgr) { status = -EFAULT; return status; } mutex_lock(&cmm_mgr_obj->cmm_lock); /* If not force then fail if outstanding allocations exist */ if (!bForce) { /* Check for outstanding memory allocations */ status = cmm_get_info(hcmm_mgr, &temp_info); if (DSP_SUCCEEDED(status)) { if (temp_info.ul_total_in_use_cnt > 0) { /* outstanding allocations */ status = -EPERM; } } } if (DSP_SUCCEEDED(status)) { /* UnRegister SM allocator */ for (slot_seg = 0; slot_seg < CMM_MAXGPPSEGS; slot_seg++) { if (cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg] != NULL) { un_register_gppsm_seg (cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg]); /* Set slot to NULL for future reuse */ cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg] = NULL; } } } if (cmm_mgr_obj->node_free_list_head != NULL) { /* Free the free nodes */ while (!LST_IS_EMPTY(cmm_mgr_obj->node_free_list_head)) { pnode = (struct cmm_mnode *) lst_get_head(cmm_mgr_obj->node_free_list_head); kfree(pnode); } /* delete NodeFreeList list */ kfree(cmm_mgr_obj->node_free_list_head); } mutex_unlock(&cmm_mgr_obj->cmm_lock); if (DSP_SUCCEEDED(status)) { /* delete CS & cmm mgr object */ mutex_destroy(&cmm_mgr_obj->cmm_lock); kfree(cmm_mgr_obj); } return status; }
/* * ======== dev_get_bridge_context ======== * Purpose: * Retrieve the Bridge Context handle, as returned by the * bridge_dev_create fxn. */ int dev_get_bridge_context(struct dev_object *hdev_obj, struct bridge_dev_context **phbridge_context) { int status = 0; struct dev_object *dev_obj = hdev_obj; DBC_REQUIRE(refs > 0); DBC_REQUIRE(phbridge_context != NULL); if (hdev_obj) { *phbridge_context = dev_obj->hbridge_context; } else { *phbridge_context = NULL; status = -EFAULT; } DBC_ENSURE(!status || ((phbridge_context != NULL) && (*phbridge_context == NULL))); return status; }
/* * ======== dev_get_symbol ======== */ int dev_get_symbol(struct dev_object *hdev_obj, const char *str_sym, u32 * pul_value) { int status = 0; struct cod_manager *cod_mgr; DBC_REQUIRE(refs > 0); DBC_REQUIRE(str_sym != NULL && pul_value != NULL); if (hdev_obj) { status = dev_get_cod_mgr(hdev_obj, &cod_mgr); if (cod_mgr) status = cod_get_sym_value(cod_mgr, (char *)str_sym, pul_value); else status = -EFAULT; } return status; }
/* * ======== dev_get_intf_fxns ======== * Purpose: * Retrieve the WMD interface function structure for the loaded WMD. * ppIntfFxns != NULL. */ int dev_get_intf_fxns(struct dev_object *hdev_obj, OUT struct bridge_drv_interface **ppIntfFxns) { int status = 0; struct dev_object *dev_obj = hdev_obj; DBC_REQUIRE(refs > 0); DBC_REQUIRE(ppIntfFxns != NULL); if (hdev_obj) { *ppIntfFxns = &dev_obj->wmd_interface; } else { *ppIntfFxns = NULL; status = -EFAULT; } DBC_ENSURE(DSP_SUCCEEDED(status) || ((ppIntfFxns != NULL) && (*ppIntfFxns == NULL))); return status; }