diff options
Diffstat (limited to 'drivers/staging/tidspbridge/pmgr')
-rw-r--r-- | drivers/staging/tidspbridge/pmgr/chnl.c | 115 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/pmgr/chnlobj.h | 46 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/pmgr/cmm.c | 915 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/pmgr/cod.c | 537 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/pmgr/dbll.c | 1421 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/pmgr/dev.c | 969 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/pmgr/dmm.c | 487 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/pmgr/dspapi.c | 1843 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/pmgr/io.c | 93 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/pmgr/ioobj.h | 38 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/pmgr/msg.c | 91 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/pmgr/msgobj.h | 38 |
12 files changed, 0 insertions, 6593 deletions
diff --git a/drivers/staging/tidspbridge/pmgr/chnl.c b/drivers/staging/tidspbridge/pmgr/chnl.c deleted file mode 100644 index 4bd8686f2355..000000000000 --- a/drivers/staging/tidspbridge/pmgr/chnl.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * chnl.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * DSP API channel interface: multiplexes data streams through the single - * physical link managed by a Bridge Bridge driver. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include <linux/types.h> -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- OS Adaptation Layer */ -#include <dspbridge/sync.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/proc.h> -#include <dspbridge/dev.h> - -/* ----------------------------------- Others */ -#include <dspbridge/chnlpriv.h> -#include <chnlobj.h> - -/* ----------------------------------- This */ -#include <dspbridge/chnl.h> - -/* - * ======== chnl_create ======== - * Purpose: - * Create a channel manager object, responsible for opening new channels - * and closing old ones for a given 'Bridge board. - */ -int chnl_create(struct chnl_mgr **channel_mgr, - struct dev_object *hdev_obj, - const struct chnl_mgrattrs *mgr_attrts) -{ - int status; - struct chnl_mgr *hchnl_mgr; - struct chnl_mgr_ *chnl_mgr_obj = NULL; - - *channel_mgr = NULL; - - /* Validate args: */ - if ((0 < mgr_attrts->max_channels) && - (mgr_attrts->max_channels <= CHNL_MAXCHANNELS)) - status = 0; - else if (mgr_attrts->max_channels == 0) - status = -EINVAL; - else - status = -ECHRNG; - - if (mgr_attrts->word_size == 0) - status = -EINVAL; - - if (!status) { - status = dev_get_chnl_mgr(hdev_obj, &hchnl_mgr); - if (!status && hchnl_mgr != NULL) - status = -EEXIST; - - } - - if (!status) { - struct bridge_drv_interface *intf_fxns; - dev_get_intf_fxns(hdev_obj, &intf_fxns); - /* Let Bridge channel module finish the create: */ - status = (*intf_fxns->chnl_create) (&hchnl_mgr, hdev_obj, - mgr_attrts); - if (!status) { - /* Fill in DSP API channel module's fields of the - * chnl_mgr structure */ - chnl_mgr_obj = (struct chnl_mgr_ *)hchnl_mgr; - chnl_mgr_obj->intf_fxns = intf_fxns; - /* Finally, return the new channel manager handle: */ - *channel_mgr = hchnl_mgr; - } - } - - return status; -} - -/* - * ======== chnl_destroy ======== - * Purpose: - * Close all open channels, and destroy the channel manager. - */ -int chnl_destroy(struct chnl_mgr *hchnl_mgr) -{ - struct chnl_mgr_ *chnl_mgr_obj = (struct chnl_mgr_ *)hchnl_mgr; - struct bridge_drv_interface *intf_fxns; - int status; - - if (chnl_mgr_obj) { - intf_fxns = chnl_mgr_obj->intf_fxns; - /* Let Bridge channel module destroy the chnl_mgr: */ - status = (*intf_fxns->chnl_destroy) (hchnl_mgr); - } else { - status = -EFAULT; - } - - return status; -} diff --git a/drivers/staging/tidspbridge/pmgr/chnlobj.h b/drivers/staging/tidspbridge/pmgr/chnlobj.h deleted file mode 100644 index 6795e0aa8fd6..000000000000 --- a/drivers/staging/tidspbridge/pmgr/chnlobj.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * chnlobj.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Structure subcomponents of channel class library channel objects which - * are exposed to DSP API from Bridge driver. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef CHNLOBJ_ -#define CHNLOBJ_ - -#include <dspbridge/chnldefs.h> -#include <dspbridge/dspdefs.h> - -/* - * This struct is the first field in a chnl_mgr struct. Other. implementation - * specific fields follow this structure in memory. - */ -struct chnl_mgr_ { - /* These must be the first fields in a chnl_mgr struct: */ - - /* Function interface to Bridge driver. */ - struct bridge_drv_interface *intf_fxns; -}; - -/* - * This struct is the first field in a chnl_object struct. Other, - * implementation specific fields follow this structure in memory. - */ -struct chnl_object_ { - /* These must be the first fields in a chnl_object struct: */ - struct chnl_mgr_ *chnl_mgr_obj; /* Pointer back to channel manager. */ -}; - -#endif /* CHNLOBJ_ */ diff --git a/drivers/staging/tidspbridge/pmgr/cmm.c b/drivers/staging/tidspbridge/pmgr/cmm.c deleted file mode 100644 index f961e0ec9da8..000000000000 --- a/drivers/staging/tidspbridge/pmgr/cmm.c +++ /dev/null @@ -1,915 +0,0 @@ -/* - * cmm.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * The Communication(Shared) Memory Management(CMM) module provides - * shared memory management services for DSP/BIOS Bridge data streaming - * and messaging. - * - * Multiple shared memory segments can be registered with CMM. - * Each registered SM segment is represented by a SM "allocator" that - * describes a block of physically contiguous shared memory used for - * future allocations by CMM. - * - * Memory is coalesced back to the appropriate heap when a buffer is - * freed. - * - * Notes: - * Va: Virtual address. - * Pa: Physical or kernel system address. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ -#include <linux/types.h> -#include <linux/list.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- OS Adaptation Layer */ -#include <dspbridge/sync.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/dev.h> -#include <dspbridge/proc.h> - -/* ----------------------------------- This */ -#include <dspbridge/cmm.h> - -/* ----------------------------------- Defines, Data Structures, Typedefs */ -#define NEXT_PA(pnode) (pnode->pa + pnode->size) - -/* Other bus/platform translations */ -#define DSPPA2GPPPA(base, x, y) ((x)+(y)) -#define GPPPA2DSPPA(base, x, y) ((x)-(y)) - -/* - * Allocators define a block of contiguous memory used for future allocations. - * - * sma - shared memory allocator. - * vma - virtual memory allocator.(not used). - */ -struct cmm_allocator { /* sma */ - unsigned int shm_base; /* Start of physical SM block */ - u32 sm_size; /* Size of SM block in bytes */ - unsigned int vm_base; /* Start of VM block. (Dev driver - * context for 'sma') */ - u32 dsp_phys_addr_offset; /* DSP PA to GPP PA offset for this - * SM space */ - s8 c_factor; /* DSPPa to GPPPa Conversion Factor */ - unsigned int dsp_base; /* DSP virt base byte address */ - u32 dsp_size; /* DSP seg size in bytes */ - struct cmm_object *cmm_mgr; /* back ref to parent mgr */ - /* node list of available memory */ - struct list_head free_list; - /* node list of memory in use */ - struct list_head in_use_list; -}; - -struct cmm_xlator { /* Pa<->Va translator object */ - /* CMM object this translator associated */ - struct cmm_object *cmm_mgr; - /* - * Client process virtual base address that corresponds to phys SM - * base address for translator's seg_id. - * Only 1 segment ID currently supported. - */ - unsigned int virt_base; /* virtual base address */ - u32 virt_size; /* size of virt space in bytes */ - u32 seg_id; /* Segment Id */ -}; - -/* CMM Mgr */ -struct cmm_object { - /* - * Cmm Lock is used to serialize access mem manager for multi-threads. - */ - struct mutex cmm_lock; /* Lock to access cmm mgr */ - struct list_head node_free_list; /* Free list of memory nodes */ - u32 min_block_size; /* Min SM block; default 16 bytes */ - u32 page_size; /* Memory Page size (1k/4k) */ - /* GPP SM segment ptrs */ - struct cmm_allocator *pa_gppsm_seg_tab[CMM_MAXGPPSEGS]; -}; - -/* Default CMM Mgr attributes */ -static struct cmm_mgrattrs cmm_dfltmgrattrs = { - /* min_block_size, min block size(bytes) allocated by cmm mgr */ - 16 -}; - -/* Default allocation attributes */ -static struct cmm_attrs cmm_dfltalctattrs = { - 1 /* seg_id, default segment Id for allocator */ -}; - -/* Address translator default attrs */ -static struct cmm_xlatorattrs cmm_dfltxlatorattrs = { - /* seg_id, does not have to match cmm_dfltalctattrs ul_seg_id */ - 1, - 0, /* dsp_bufs */ - 0, /* dsp_buf_size */ - NULL, /* vm_base */ - 0, /* vm_size */ -}; - -/* SM node representing a block of memory. */ -struct cmm_mnode { - struct list_head link; /* must be 1st element */ - u32 pa; /* Phys addr */ - u32 va; /* Virtual address in device process context */ - u32 size; /* SM block size in bytes */ - u32 client_proc; /* Process that allocated this mem block */ -}; - -/* ----------------------------------- Function Prototypes */ -static void add_to_free_list(struct cmm_allocator *allocator, - struct cmm_mnode *pnode); -static struct cmm_allocator *get_allocator(struct cmm_object *cmm_mgr_obj, - u32 ul_seg_id); -static struct cmm_mnode *get_free_block(struct cmm_allocator *allocator, - u32 usize); -static struct cmm_mnode *get_node(struct cmm_object *cmm_mgr_obj, u32 dw_pa, - u32 dw_va, u32 ul_size); -/* get available slot for new allocator */ -static s32 get_slot(struct cmm_object *cmm_mgr_obj); -static void un_register_gppsm_seg(struct cmm_allocator *psma); - -/* - * ======== cmm_calloc_buf ======== - * Purpose: - * Allocate a SM buffer, zero contents, and return the physical address - * and optional driver context virtual address(pp_buf_va). - * - * The freelist is sorted in increasing size order. Get the first - * block that satifies the request and sort the remaining back on - * the freelist; if large enough. The kept block is placed on the - * inUseList. - */ -void *cmm_calloc_buf(struct cmm_object *hcmm_mgr, u32 usize, - struct cmm_attrs *pattrs, void **pp_buf_va) -{ - struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr; - void *buf_pa = NULL; - struct cmm_mnode *pnode = NULL; - struct cmm_mnode *new_node = NULL; - struct cmm_allocator *allocator = NULL; - u32 delta_size; - u8 *pbyte = NULL; - s32 cnt; - - if (pattrs == NULL) - pattrs = &cmm_dfltalctattrs; - - if (pp_buf_va != NULL) - *pp_buf_va = NULL; - - if (cmm_mgr_obj && (usize != 0)) { - if (pattrs->seg_id > 0) { - /* SegId > 0 is SM */ - /* get the allocator object for this segment id */ - allocator = - get_allocator(cmm_mgr_obj, pattrs->seg_id); - /* keep block size a multiple of min_block_size */ - usize = - ((usize - 1) & ~(cmm_mgr_obj->min_block_size - - 1)) - + cmm_mgr_obj->min_block_size; - mutex_lock(&cmm_mgr_obj->cmm_lock); - pnode = get_free_block(allocator, usize); - } - if (pnode) { - delta_size = (pnode->size - usize); - if (delta_size >= cmm_mgr_obj->min_block_size) { - /* create a new block with the leftovers and - * add to freelist */ - new_node = - get_node(cmm_mgr_obj, pnode->pa + usize, - pnode->va + usize, - (u32) delta_size); - /* leftovers go free */ - add_to_free_list(allocator, new_node); - /* adjust our node's size */ - pnode->size = usize; - } - /* Tag node with client process requesting allocation - * We'll need to free up a process's alloc'd SM if the - * client process goes away. - */ - /* Return TGID instead of process handle */ - pnode->client_proc = current->tgid; - - /* put our node on InUse list */ - list_add_tail(&pnode->link, &allocator->in_use_list); - buf_pa = (void *)pnode->pa; /* physical address */ - /* clear mem */ - pbyte = (u8 *) pnode->va; - for (cnt = 0; cnt < (s32) usize; cnt++, pbyte++) - *pbyte = 0; - - if (pp_buf_va != NULL) { - /* Virtual address */ - *pp_buf_va = (void *)pnode->va; - } - } - mutex_unlock(&cmm_mgr_obj->cmm_lock); - } - return buf_pa; -} - -/* - * ======== cmm_create ======== - * Purpose: - * Create a communication memory manager object. - */ -int cmm_create(struct cmm_object **ph_cmm_mgr, - struct dev_object *hdev_obj, - const struct cmm_mgrattrs *mgr_attrts) -{ - struct cmm_object *cmm_obj = NULL; - int status = 0; - - *ph_cmm_mgr = NULL; - /* create, zero, and tag a cmm mgr object */ - cmm_obj = kzalloc(sizeof(struct cmm_object), GFP_KERNEL); - if (!cmm_obj) - return -ENOMEM; - - if (mgr_attrts == NULL) - mgr_attrts = &cmm_dfltmgrattrs; /* set defaults */ - - /* save away smallest block allocation for this cmm mgr */ - cmm_obj->min_block_size = mgr_attrts->min_block_size; - cmm_obj->page_size = PAGE_SIZE; - - /* create node free list */ - INIT_LIST_HEAD(&cmm_obj->node_free_list); - mutex_init(&cmm_obj->cmm_lock); - *ph_cmm_mgr = cmm_obj; - - return status; -} - -/* - * ======== cmm_destroy ======== - * Purpose: - * Release the communication memory manager resources. - */ -int cmm_destroy(struct cmm_object *hcmm_mgr, bool force) -{ - 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 *node, *tmp; - - if (!hcmm_mgr) { - status = -EFAULT; - return status; - } - mutex_lock(&cmm_mgr_obj->cmm_lock); - /* If not force then fail if outstanding allocations exist */ - if (!force) { - /* Check for outstanding memory allocations */ - status = cmm_get_info(hcmm_mgr, &temp_info); - if (!status) { - if (temp_info.total_in_use_cnt > 0) { - /* outstanding allocations */ - status = -EPERM; - } - } - } - if (!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; - } - } - } - list_for_each_entry_safe(node, tmp, &cmm_mgr_obj->node_free_list, - link) { - list_del(&node->link); - kfree(node); - } - mutex_unlock(&cmm_mgr_obj->cmm_lock); - if (!status) { - /* delete CS & cmm mgr object */ - mutex_destroy(&cmm_mgr_obj->cmm_lock); - kfree(cmm_mgr_obj); - } - return status; -} - -/* - * ======== 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 *curr, *tmp; - struct cmm_allocator *allocator; - struct cmm_attrs *pattrs; - - if (ul_seg_id == 0) { - pattrs = &cmm_dfltalctattrs; - ul_seg_id = pattrs->seg_id; - } - if (!hcmm_mgr || !(ul_seg_id > 0)) { - status = -EFAULT; - return status; - } - - allocator = get_allocator(cmm_mgr_obj, ul_seg_id); - if (!allocator) - return status; - - mutex_lock(&cmm_mgr_obj->cmm_lock); - list_for_each_entry_safe(curr, tmp, &allocator->in_use_list, link) { - if (curr->pa == (u32) buf_pa) { - list_del(&curr->link); - add_to_free_list(allocator, curr); - status = 0; - break; - } - } - mutex_unlock(&cmm_mgr_obj->cmm_lock); - - return status; -} - -/* - * ======== 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, struct cmm_object **ph_cmm_mgr) -{ - int status = 0; - struct dev_object *hdev_obj; - - if (hprocessor != NULL) - status = proc_get_dev_object(hprocessor, &hdev_obj); - else - hdev_obj = dev_get_first(); /* default */ - - if (!status) - status = dev_get_cmm_mgr(hdev_obj, ph_cmm_mgr); - - return status; -} - -/* - * ======== cmm_get_info ======== - * Purpose: - * Return the current memory utilization information. - */ -int cmm_get_info(struct cmm_object *hcmm_mgr, - struct cmm_info *cmm_info_obj) -{ - struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr; - u32 ul_seg; - int status = 0; - struct cmm_allocator *altr; - struct cmm_mnode *curr; - - if (!hcmm_mgr) { - status = -EFAULT; - return status; - } - mutex_lock(&cmm_mgr_obj->cmm_lock); - cmm_info_obj->num_gppsm_segs = 0; /* # of SM segments */ - /* Total # of outstanding alloc */ - cmm_info_obj->total_in_use_cnt = 0; - /* min block size */ - cmm_info_obj->min_block_size = cmm_mgr_obj->min_block_size; - /* check SM memory segments */ - for (ul_seg = 1; ul_seg <= CMM_MAXGPPSEGS; ul_seg++) { - /* get the allocator object for this segment id */ - altr = get_allocator(cmm_mgr_obj, ul_seg); - if (!altr) - continue; - cmm_info_obj->num_gppsm_segs++; - cmm_info_obj->seg_info[ul_seg - 1].seg_base_pa = - altr->shm_base - altr->dsp_size; - cmm_info_obj->seg_info[ul_seg - 1].total_seg_size = - altr->dsp_size + altr->sm_size; - cmm_info_obj->seg_info[ul_seg - 1].gpp_base_pa = - altr->shm_base; - cmm_info_obj->seg_info[ul_seg - 1].gpp_size = - altr->sm_size; - cmm_info_obj->seg_info[ul_seg - 1].dsp_base_va = - altr->dsp_base; - cmm_info_obj->seg_info[ul_seg - 1].dsp_size = - altr->dsp_size; - cmm_info_obj->seg_info[ul_seg - 1].seg_base_va = - altr->vm_base - altr->dsp_size; - cmm_info_obj->seg_info[ul_seg - 1].in_use_cnt = 0; - - list_for_each_entry(curr, &altr->in_use_list, link) { - cmm_info_obj->total_in_use_cnt++; - cmm_info_obj->seg_info[ul_seg - 1].in_use_cnt++; - } - } - mutex_unlock(&cmm_mgr_obj->cmm_lock); - return status; -} - -/* - * ======== cmm_register_gppsm_seg ======== - * Purpose: - * Register a block of SM with the CMM to be used for later GPP SM - * allocations. - */ -int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr, - u32 dw_gpp_base_pa, u32 ul_size, - u32 dsp_addr_offset, s8 c_factor, - u32 dw_dsp_base, u32 ul_dsp_size, - u32 *sgmt_id, u32 gpp_base_va) -{ - struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr; - struct cmm_allocator *psma = NULL; - int status = 0; - struct cmm_mnode *new_node; - s32 slot_seg; - - dev_dbg(bridge, "%s: dw_gpp_base_pa %x ul_size %x dsp_addr_offset %x dw_dsp_base %x ul_dsp_size %x gpp_base_va %x\n", - __func__, dw_gpp_base_pa, ul_size, dsp_addr_offset, - dw_dsp_base, ul_dsp_size, gpp_base_va); - - if (!hcmm_mgr) - return -EFAULT; - - /* make sure we have room for another allocator */ - mutex_lock(&cmm_mgr_obj->cmm_lock); - - slot_seg = get_slot(cmm_mgr_obj); - if (slot_seg < 0) { - status = -EPERM; - goto func_end; - } - - /* Check if input ul_size is big enough to alloc at least one block */ - if (ul_size < cmm_mgr_obj->min_block_size) { - status = -EINVAL; - goto func_end; - } - - /* create, zero, and tag an SM allocator object */ - psma = kzalloc(sizeof(struct cmm_allocator), GFP_KERNEL); - if (!psma) { - status = -ENOMEM; - goto func_end; - } - - psma->cmm_mgr = hcmm_mgr; /* ref to parent */ - psma->shm_base = dw_gpp_base_pa; /* SM Base phys */ - psma->sm_size = ul_size; /* SM segment size in bytes */ - psma->vm_base = gpp_base_va; - psma->dsp_phys_addr_offset = dsp_addr_offset; - psma->c_factor = c_factor; - psma->dsp_base = dw_dsp_base; - psma->dsp_size = ul_dsp_size; - if (psma->vm_base == 0) { - status = -EPERM; - goto func_end; - } - /* return the actual segment identifier */ - *sgmt_id = (u32) slot_seg + 1; - - INIT_LIST_HEAD(&psma->free_list); - INIT_LIST_HEAD(&psma->in_use_list); - - /* Get a mem node for this hunk-o-memory */ - new_node = get_node(cmm_mgr_obj, dw_gpp_base_pa, - psma->vm_base, ul_size); - /* Place node on the SM allocator's free list */ - if (new_node) { - list_add_tail(&new_node->link, &psma->free_list); - } else { - status = -ENOMEM; - goto func_end; - } - /* make entry */ - cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg] = psma; - -func_end: - /* Cleanup allocator */ - if (status && psma) - un_register_gppsm_seg(psma); - mutex_unlock(&cmm_mgr_obj->cmm_lock); - - return status; -} - -/* - * ======== cmm_un_register_gppsm_seg ======== - * Purpose: - * UnRegister GPP SM segments with the CMM. - */ -int cmm_un_register_gppsm_seg(struct cmm_object *hcmm_mgr, - u32 ul_seg_id) -{ - struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr; - int status = 0; - struct cmm_allocator *psma; - u32 ul_id = ul_seg_id; - - if (!hcmm_mgr) - return -EFAULT; - - if (ul_seg_id == CMM_ALLSEGMENTS) - ul_id = 1; - - if ((ul_id <= 0) || (ul_id > CMM_MAXGPPSEGS)) - return -EINVAL; - - /* - * FIXME: CMM_MAXGPPSEGS == 1. why use a while cycle? Seems to me like - * the ul_seg_id is not needed here. It must be always 1. - */ - while (ul_id <= CMM_MAXGPPSEGS) { - mutex_lock(&cmm_mgr_obj->cmm_lock); - /* slot = seg_id-1 */ - psma = cmm_mgr_obj->pa_gppsm_seg_tab[ul_id - 1]; - if (psma != NULL) { - un_register_gppsm_seg(psma); - /* Set alctr ptr to NULL for future reuse */ - cmm_mgr_obj->pa_gppsm_seg_tab[ul_id - 1] = NULL; - } else if (ul_seg_id != CMM_ALLSEGMENTS) { - status = -EPERM; - } - mutex_unlock(&cmm_mgr_obj->cmm_lock); - if (ul_seg_id != CMM_ALLSEGMENTS) - break; - - ul_id++; - } /* end while */ - return status; -} - -/* - * ======== un_register_gppsm_seg ======== - * Purpose: - * UnRegister the SM allocator by freeing all its resources and - * nulling cmm mgr table entry. - * Note: - * This routine is always called within cmm lock crit sect. - */ -static void un_register_gppsm_seg(struct cmm_allocator *psma) -{ - struct cmm_mnode *curr, *tmp; - - /* free nodes on free list */ - list_for_each_entry_safe(curr, tmp, &psma->free_list, link) { - list_del(&curr->link); - kfree(curr); - } - - /* free nodes on InUse list */ - list_for_each_entry_safe(curr, tmp, &psma->in_use_list, link) { - list_del(&curr->link); - kfree(curr); - } - - if ((void *)psma->vm_base != NULL) - MEM_UNMAP_LINEAR_ADDRESS((void *)psma->vm_base); - - /* Free allocator itself */ - kfree(psma); -} - -/* - * ======== get_slot ======== - * Purpose: - * An available slot # is returned. Returns negative on failure. - */ -static s32 get_slot(struct cmm_object *cmm_mgr_obj) -{ - s32 slot_seg = -1; /* neg on failure */ - /* get first available slot in cmm mgr SMSegTab[] */ - for (slot_seg = 0; slot_seg < CMM_MAXGPPSEGS; slot_seg++) { - if (cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg] == NULL) - break; - - } - if (slot_seg == CMM_MAXGPPSEGS) - slot_seg = -1; /* failed */ - - return slot_seg; -} - -/* - * ======== get_node ======== - * Purpose: - * Get a memory node from freelist or create a new one. - */ -static struct cmm_mnode *get_node(struct cmm_object *cmm_mgr_obj, u32 dw_pa, - u32 dw_va, u32 ul_size) -{ - struct cmm_mnode *pnode; - - /* Check cmm mgr's node freelist */ - if (list_empty(&cmm_mgr_obj->node_free_list)) { - pnode = kzalloc(sizeof(struct cmm_mnode), GFP_KERNEL); - if (!pnode) - return NULL; - } else { - /* surely a valid element */ - pnode = list_first_entry(&cmm_mgr_obj->node_free_list, - struct cmm_mnode, link); - list_del_init(&pnode->link); - } - - pnode->pa = dw_pa; - pnode->va = dw_va; - pnode->size = ul_size; - - return pnode; -} - -/* - * ======== delete_node ======== - * Purpose: - * Put a memory node on the cmm nodelist for later use. - * Doesn't actually delete the node. Heap thrashing friendly. - */ -static void delete_node(struct cmm_object *cmm_mgr_obj, struct cmm_mnode *pnode) -{ - list_add_tail(&pnode->link, &cmm_mgr_obj->node_free_list); -} - -/* - * ====== get_free_block ======== - * Purpose: - * Scan the free block list and return the first block that satisfies - * the size. - */ -static struct cmm_mnode *get_free_block(struct cmm_allocator *allocator, - u32 usize) -{ - struct cmm_mnode *node, *tmp; - - if (!allocator) - return NULL; - - list_for_each_entry_safe(node, tmp, &allocator->free_list, link) { - if (usize <= node->size) { - list_del(&node->link); - return node; - } - } - - return NULL; -} - -/* - * ======== add_to_free_list ======== - * Purpose: - * Coalesce node into the freelist in ascending size order. - */ -static void add_to_free_list(struct cmm_allocator *allocator, - struct cmm_mnode *node) -{ - struct cmm_mnode *curr; - - if (!node) { - pr_err("%s: failed - node is NULL\n", __func__); - return; - } - - list_for_each_entry(curr, &allocator->free_list, link) { - if (NEXT_PA(curr) == node->pa) { - curr->size += node->size; - delete_node(allocator->cmm_mgr, node); - return; - } - if (curr->pa == NEXT_PA(node)) { - curr->pa = node->pa; - curr->va = node->va; - curr->size += node->size; - delete_node(allocator->cmm_mgr, node); - return; - } - } - list_for_each_entry(curr, &allocator->free_list, link) { - if (curr->size >= node->size) { - list_add_tail(&node->link, &curr->link); - return; - } - } - list_add_tail(&node->link, &allocator->free_list); -} - -/* - * ======== 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) -{ - return cmm_mgr_obj->pa_gppsm_seg_tab[ul_seg_id - 1]; -} - -/* - * The CMM_Xlator[xxx] routines below are used by Node and Stream - * to perform SM address translation to the client process address space. - * A "translator" object is created by a node/stream for each SM seg used. - */ - -/* - * ======== cmm_xlator_create ======== - * Purpose: - * Create an address translator object. - */ -int cmm_xlator_create(struct cmm_xlatorobject **xlator, - struct cmm_object *hcmm_mgr, - struct cmm_xlatorattrs *xlator_attrs) -{ - struct cmm_xlator *xlator_object = NULL; - int status = 0; - - *xlator = NULL; - if (xlator_attrs == NULL) - xlator_attrs = &cmm_dfltxlatorattrs; /* set defaults */ - - xlator_object = kzalloc(sizeof(struct cmm_xlator), GFP_KERNEL); - if (xlator_object != NULL) { - xlator_object->cmm_mgr = hcmm_mgr; /* ref back to CMM */ - /* SM seg_id */ - xlator_object->seg_id = xlator_attrs->seg_id; - } else { - status = -ENOMEM; - } - if (!status) - *xlator = (struct cmm_xlatorobject *)xlator_object; - - return status; -} - -/* - * ======== cmm_xlator_alloc_buf ======== - */ -void *cmm_xlator_alloc_buf(struct cmm_xlatorobject *xlator, void *va_buf, - u32 pa_size) -{ - struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator; - void *pbuf = NULL; - void *tmp_va_buff; - struct cmm_attrs attrs; - - if (xlator_obj) { - attrs.seg_id = xlator_obj->seg_id; - __raw_writel(0, va_buf); - /* Alloc SM */ - pbuf = - cmm_calloc_buf(xlator_obj->cmm_mgr, pa_size, &attrs, NULL); - if (pbuf) { - /* convert to translator(node/strm) process Virtual - * address */ - tmp_va_buff = cmm_xlator_translate(xlator, - pbuf, CMM_PA2VA); - __raw_writel((u32)tmp_va_buff, va_buf); - } - } - return pbuf; -} - -/* - * ======== cmm_xlator_free_buf ======== - * Purpose: - * Free the given SM buffer and descriptor. - * Does not free virtual memory. - */ -int cmm_xlator_free_buf(struct cmm_xlatorobject *xlator, void *buf_va) -{ - struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator; - int status = -EPERM; - void *buf_pa = NULL; - - if (xlator_obj) { - /* convert Va to Pa so we can free it. */ - buf_pa = cmm_xlator_translate(xlator, buf_va, CMM_VA2PA); - if (buf_pa) { - status = cmm_free_buf(xlator_obj->cmm_mgr, buf_pa, - xlator_obj->seg_id); - if (status) { - /* Uh oh, this shouldn't happen. Descriptor - * gone! */ - pr_err("%s, line %d: Assertion failed\n", - __FILE__, __LINE__); - } - } - } - return status; -} - -/* - * ======== cmm_xlator_info ======== - * Purpose: - * Set/Get translator info. - */ -int cmm_xlator_info(struct cmm_xlatorobject *xlator, u8 **paddr, - u32 ul_size, u32 segm_id, bool set_info) -{ - struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator; - int status = 0; - - if (xlator_obj) { - if (set_info) { - /* set translators virtual address range */ - xlator_obj->virt_base = (u32) *paddr; - xlator_obj->virt_size = ul_size; - } else { /* return virt base address */ - *paddr = (u8 *) xlator_obj->virt_base; - } - } else { - status = -EFAULT; - } - return status; -} - -/* - * ======== cmm_xlator_translate ======== - */ -void *cmm_xlator_translate(struct cmm_xlatorobject *xlator, void *paddr, - enum cmm_xlatetype xtype) -{ - u32 dw_addr_xlate = 0; - struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator; - struct cmm_object *cmm_mgr_obj = NULL; - struct cmm_allocator *allocator = NULL; - u32 dw_offset = 0; - - if (!xlator_obj) - goto loop_cont; - - cmm_mgr_obj = (struct cmm_object *)xlator_obj->cmm_mgr; - /* get this translator's default SM allocator */ - allocator = cmm_mgr_obj->pa_gppsm_seg_tab[xlator_obj->seg_id - 1]; - if (!allocator) - goto loop_cont; - - if ((xtype == CMM_VA2DSPPA) || (xtype == CMM_VA2PA) || - (xtype == CMM_PA2VA)) { - if (xtype == CMM_PA2VA) { - /* Gpp Va = Va Base + offset */ - dw_offset = (u8 *) paddr - (u8 *) (allocator->shm_base - - allocator-> - dsp_size); - dw_addr_xlate = xlator_obj->virt_base + dw_offset; - /* Check if translated Va base is in range */ - if ((dw_addr_xlate < xlator_obj->virt_base) || - (dw_addr_xlate >= - (xlator_obj->virt_base + - xlator_obj->virt_size))) { - dw_addr_xlate = 0; /* bad address */ - } - } else { - /* Gpp PA = Gpp Base + offset */ - dw_offset = - (u8 *) paddr - (u8 *) xlator_obj->virt_base; - dw_addr_xlate = - allocator->shm_base - allocator->dsp_size + - dw_offset; - } - } else { - dw_addr_xlate = (u32) paddr; - } - /*Now convert address to proper target physical address if needed */ - if ((xtype == CMM_VA2DSPPA) || (xtype == CMM_PA2DSPPA)) { - /* Got Gpp Pa now, convert to DSP Pa */ - dw_addr_xlate = - GPPPA2DSPPA((allocator->shm_base - allocator->dsp_size), - dw_addr_xlate, - allocator->dsp_phys_addr_offset * - allocator->c_factor); - } else if (xtype == CMM_DSPPA2PA) { - /* Got DSP Pa, convert to GPP Pa */ - dw_addr_xlate = - DSPPA2GPPPA(allocator->shm_base - allocator->dsp_size, - dw_addr_xlate, - allocator->dsp_phys_addr_offset * - allocator->c_factor); - } -loop_cont: - return (void *)dw_addr_xlate; -} diff --git a/drivers/staging/tidspbridge/pmgr/cod.c b/drivers/staging/tidspbridge/pmgr/cod.c deleted file mode 100644 index 6c29379baf60..000000000000 --- a/drivers/staging/tidspbridge/pmgr/cod.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * cod.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * This module implements DSP code management for the DSP/BIOS Bridge - * environment. It is mostly a thin wrapper. - * - * This module provides an interface for loading both static and - * dynamic code objects onto DSP systems. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include <linux/types.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> -#include <linux/fs.h> -#include <linux/uaccess.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- Platform Manager */ -/* Include appropriate loader header file */ -#include <dspbridge/dbll.h> - -/* ----------------------------------- This */ -#include <dspbridge/cod.h> - -/* - * ======== cod_manager ======== - */ -struct cod_manager { - struct dbll_tar_obj *target; - struct dbll_library_obj *base_lib; - bool loaded; /* Base library loaded? */ - u32 entry; - struct dbll_fxns fxns; - struct dbll_attrs attrs; - char sz_zl_file[COD_MAXPATHLENGTH]; -}; - -/* - * ======== cod_libraryobj ======== - */ -struct cod_libraryobj { - struct dbll_library_obj *dbll_lib; - struct cod_manager *cod_mgr; -}; - -static struct dbll_fxns ldr_fxns = { - (dbll_close_fxn) dbll_close, - (dbll_create_fxn) dbll_create, - (dbll_delete_fxn) dbll_delete, - (dbll_exit_fxn) dbll_exit, - (dbll_get_attrs_fxn) dbll_get_attrs, - (dbll_get_addr_fxn) dbll_get_addr, - (dbll_get_c_addr_fxn) dbll_get_c_addr, - (dbll_get_sect_fxn) dbll_get_sect, - (dbll_init_fxn) dbll_init, - (dbll_load_fxn) dbll_load, - (dbll_open_fxn) dbll_open, - (dbll_read_sect_fxn) dbll_read_sect, - (dbll_unload_fxn) dbll_unload, -}; - -static bool no_op(void); - -/* - * File operations (originally were under kfile.c) - */ -static s32 cod_f_close(struct file *filp) -{ - /* Check for valid handle */ - if (!filp) - return -EFAULT; - - filp_close(filp, NULL); - - /* we can't use 0 here */ - return 0; -} - -static struct file *cod_f_open(const char *psz_file_name, const char *sz_mode) -{ - mm_segment_t fs; - struct file *filp; - - fs = get_fs(); - set_fs(get_ds()); - - /* ignore given mode and open file as read-only */ - filp = filp_open(psz_file_name, O_RDONLY, 0); - - if (IS_ERR(filp)) - filp = NULL; - - set_fs(fs); - - return filp; -} - -static s32 cod_f_read(void __user *pbuffer, s32 size, s32 count, - struct file *filp) -{ - /* check for valid file handle */ - if (!filp) - return -EFAULT; - - if ((size > 0) && (count > 0) && pbuffer) { - u32 dw_bytes_read; - mm_segment_t fs; - - /* read from file */ - fs = get_fs(); - set_fs(get_ds()); - dw_bytes_read = filp->f_op->read(filp, pbuffer, size * count, - &(filp->f_pos)); - set_fs(fs); - - if (!dw_bytes_read) - return -EBADF; - - return dw_bytes_read / size; - } - - return -EINVAL; -} - -static s32 cod_f_seek(struct file *filp, s32 offset, s32 origin) -{ - loff_t dw_cur_pos; - - /* check for valid file handle */ - if (!filp) - return -EFAULT; - - /* based on the origin flag, move the internal pointer */ - dw_cur_pos = filp->f_op->llseek(filp, offset, origin); - - if ((s32) dw_cur_pos < 0) - return -EPERM; - - /* we can't use 0 here */ - return 0; -} - -static s32 cod_f_tell(struct file *filp) -{ - loff_t dw_cur_pos; - - if (!filp) - return -EFAULT; - - /* Get current position */ - dw_cur_pos = filp->f_op->llseek(filp, 0, SEEK_CUR); - - if ((s32) dw_cur_pos < 0) - return -EPERM; - - return dw_cur_pos; -} - -/* - * ======== cod_close ======== - */ -void cod_close(struct cod_libraryobj *lib) -{ - struct cod_manager *hmgr; - - hmgr = lib->cod_mgr; - hmgr->fxns.close_fxn(lib->dbll_lib); - - kfree(lib); -} - -/* - * ======== cod_create ======== - * Purpose: - * Create an object to manage code on a DSP system. - * This object can be used to load an initial program image with - * arguments that can later be expanded with - * dynamically loaded object files. - * - */ -int cod_create(struct cod_manager **mgr, char *str_zl_file) -{ - struct cod_manager *mgr_new; - struct dbll_attrs zl_attrs; - int status = 0; - - /* assume failure */ - *mgr = NULL; - - mgr_new = kzalloc(sizeof(struct cod_manager), GFP_KERNEL); - if (mgr_new == NULL) - return -ENOMEM; - - /* Set up loader functions */ - mgr_new->fxns = ldr_fxns; - - /* initialize the ZL module */ - mgr_new->fxns.init_fxn(); - - zl_attrs.alloc = (dbll_alloc_fxn) no_op; - zl_attrs.free = (dbll_free_fxn) no_op; - zl_attrs.fread = (dbll_read_fxn) cod_f_read; - zl_attrs.fseek = (dbll_seek_fxn) cod_f_seek; - zl_attrs.ftell = (dbll_tell_fxn) cod_f_tell; - zl_attrs.fclose = (dbll_f_close_fxn) cod_f_close; - zl_attrs.fopen = (dbll_f_open_fxn) cod_f_open; - zl_attrs.sym_lookup = NULL; - zl_attrs.base_image = true; - zl_attrs.log_write = NULL; - zl_attrs.log_write_handle = NULL; - zl_attrs.write = NULL; - zl_attrs.rmm_handle = NULL; - zl_attrs.input_params = NULL; - zl_attrs.sym_handle = NULL; - zl_attrs.sym_arg = NULL; - - mgr_new->attrs = zl_attrs; - - status = mgr_new->fxns.create_fxn(&mgr_new->target, &zl_attrs); - - if (status) { - cod_delete(mgr_new); - return -ESPIPE; - } - - /* return the new manager */ - *mgr = mgr_new; - - return 0; -} - -/* - * ======== cod_delete ======== - * Purpose: - * Delete a code manager object. - */ -void cod_delete(struct cod_manager *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); -} - -/* - * ======== cod_get_base_lib ======== - * Purpose: - * Get handle to the base image DBL library. - */ -int cod_get_base_lib(struct cod_manager *cod_mgr_obj, - struct dbll_library_obj **plib) -{ - int status = 0; - - *plib = (struct dbll_library_obj *)cod_mgr_obj->base_lib; - - return status; -} - -/* - * ======== cod_get_base_name ======== - */ -int cod_get_base_name(struct cod_manager *cod_mgr_obj, char *sz_name, - u32 usize) -{ - int status = 0; - - if (usize <= COD_MAXPATHLENGTH) - strlcpy(sz_name, cod_mgr_obj->sz_zl_file, usize); - else - status = -EPERM; - - return status; -} - -/* - * ======== cod_get_entry ======== - * Purpose: - * Retrieve the entry point of a loaded DSP program image - * - */ -int cod_get_entry(struct cod_manager *cod_mgr_obj, u32 *entry_pt) -{ - *entry_pt = cod_mgr_obj->entry; - - return 0; -} - -/* - * ======== cod_get_loader ======== - * Purpose: - * Get handle to the DBLL loader. - */ -int cod_get_loader(struct cod_manager *cod_mgr_obj, - struct dbll_tar_obj **loader) -{ - int status = 0; - - *loader = (struct dbll_tar_obj *)cod_mgr_obj->target; - - return status; -} - -/* - * ======== cod_get_section ======== - * Purpose: - * Retrieve the starting address and length of a section in the COFF file - * given the section name. - */ -int cod_get_section(struct cod_libraryobj *lib, char *str_sect, - u32 *addr, u32 *len) -{ - struct cod_manager *cod_mgr_obj; - int status = 0; - - *addr = 0; - *len = 0; - if (lib != NULL) { - cod_mgr_obj = lib->cod_mgr; - status = cod_mgr_obj->fxns.get_sect_fxn(lib->dbll_lib, str_sect, - addr, len); - } else { - status = -ESPIPE; - } - - return status; -} - -/* - * ======== cod_get_sym_value ======== - * Purpose: - * Retrieve the value for the specified symbol. The symbol is first - * searched for literally and then, if not found, searched for as a - * C symbol. - * - */ -int cod_get_sym_value(struct cod_manager *cod_mgr_obj, char *str_sym, - u32 *pul_value) -{ - struct dbll_sym_val *dbll_sym; - - dev_dbg(bridge, "%s: cod_mgr_obj: %p str_sym: %s pul_value: %p\n", - __func__, cod_mgr_obj, str_sym, pul_value); - if (cod_mgr_obj->base_lib) { - if (!cod_mgr_obj->fxns. - get_addr_fxn(cod_mgr_obj->base_lib, str_sym, &dbll_sym)) { - if (!cod_mgr_obj->fxns. - get_c_addr_fxn(cod_mgr_obj->base_lib, str_sym, - &dbll_sym)) - return -ESPIPE; - } - } else { - return -ESPIPE; - } - - *pul_value = dbll_sym->value; - - return 0; -} - -/* - * ======== cod_load_base ======== - * Purpose: - * Load the initial program image, optionally with command-line arguments, - * on the DSP system managed by the supplied handle. The program to be - * loaded must be the first element of the args array and must be a fully - * qualified pathname. - * Details: - * if num_argc doesn't match the number of arguments in the args array, the - * args array is searched for a NULL terminating entry, and argc is - * recalculated to reflect this. In this way, we can support NULL - * terminating args arrays, if num_argc is very large. - */ -int cod_load_base(struct cod_manager *cod_mgr_obj, u32 num_argc, char *args[], - cod_writefxn pfn_write, void *arb, char *envp[]) -{ - dbll_flags flags; - struct dbll_attrs save_attrs; - struct dbll_attrs new_attrs; - int status; - u32 i; - - /* - * Make sure every argv[] stated in argc has a value, or change argc to - * reflect true number in NULL terminated argv array. - */ - for (i = 0; i < num_argc; i++) { - if (args[i] == NULL) { - num_argc = i; - break; - } - } - - /* set the write function for this operation */ - cod_mgr_obj->fxns.get_attrs_fxn(cod_mgr_obj->target, &save_attrs); - - new_attrs = save_attrs; - new_attrs.write = (dbll_write_fxn) pfn_write; - new_attrs.input_params = arb; - new_attrs.alloc = (dbll_alloc_fxn) no_op; - new_attrs.free = (dbll_free_fxn) no_op; - new_attrs.log_write = NULL; - new_attrs.log_write_handle = NULL; - - /* Load the image */ - flags = DBLL_CODE | DBLL_DATA | DBLL_SYMB; - status = cod_mgr_obj->fxns.load_fxn(cod_mgr_obj->base_lib, flags, - &new_attrs, - &cod_mgr_obj->entry); - if (status) - cod_mgr_obj->fxns.close_fxn(cod_mgr_obj->base_lib); - - if (!status) - cod_mgr_obj->loaded = true; - else - cod_mgr_obj->base_lib = NULL; - - return status; -} - -/* - * ======== cod_open ======== - * Open library for reading sections. - */ -int cod_open(struct cod_manager *hmgr, char *sz_coff_path, - u32 flags, struct cod_libraryobj **lib_obj) -{ - int status = 0; - struct cod_libraryobj *lib = NULL; - - *lib_obj = NULL; - - lib = kzalloc(sizeof(struct cod_libraryobj), GFP_KERNEL); - if (lib == NULL) - status = -ENOMEM; - - if (!status) { - lib->cod_mgr = hmgr; - status = hmgr->fxns.open_fxn(hmgr->target, sz_coff_path, flags, - &lib->dbll_lib); - if (!status) - *lib_obj = lib; - } - - if (status) - pr_err("%s: error status 0x%x, sz_coff_path: %s flags: 0x%x\n", - __func__, status, sz_coff_path, flags); - return status; -} - -/* - * ======== cod_open_base ======== - * Purpose: - * Open base image for reading sections. - */ -int cod_open_base(struct cod_manager *hmgr, char *sz_coff_path, - dbll_flags flags) -{ - int status = 0; - struct dbll_library_obj *lib; - - /* if we previously opened a base image, close it now */ - if (hmgr->base_lib) { - if (hmgr->loaded) { - hmgr->fxns.unload_fxn(hmgr->base_lib, &hmgr->attrs); - hmgr->loaded = false; - } - hmgr->fxns.close_fxn(hmgr->base_lib); - hmgr->base_lib = NULL; - } - status = hmgr->fxns.open_fxn(hmgr->target, sz_coff_path, flags, &lib); - if (!status) { - /* hang onto the library for subsequent sym table usage */ - hmgr->base_lib = lib; - strncpy(hmgr->sz_zl_file, sz_coff_path, COD_MAXPATHLENGTH - 1); - hmgr->sz_zl_file[COD_MAXPATHLENGTH - 1] = '\0'; - } - - if (status) - pr_err("%s: error status 0x%x sz_coff_path: %s\n", __func__, - status, sz_coff_path); - return status; -} - -/* - * ======== 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; - - 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; -} - -/* - * ======== no_op ======== - * Purpose: - * No Operation. - * - */ -static bool no_op(void) -{ - return true; -} diff --git a/drivers/staging/tidspbridge/pmgr/dbll.c b/drivers/staging/tidspbridge/pmgr/dbll.c deleted file mode 100644 index 8e21d1e47c9c..000000000000 --- a/drivers/staging/tidspbridge/pmgr/dbll.c +++ /dev/null @@ -1,1421 +0,0 @@ -/* - * dbll.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ -#include <linux/types.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -#include <dspbridge/gh.h> - -/* ----------------------------------- OS Adaptation Layer */ - -/* Dynamic loader library interface */ -#include <dspbridge/dynamic_loader.h> -#include <dspbridge/getsection.h> - -/* ----------------------------------- This */ -#include <dspbridge/dbll.h> -#include <dspbridge/rmm.h> - -/* Max buffer length */ -#define MAXEXPR 128 - -#define DOFF_ALIGN(x) (((x) + 3) & ~3UL) - -/* - * ======== struct dbll_tar_obj* ======== - * A target may have one or more libraries of symbols/code/data loaded - * onto it, where a library is simply the symbols/code/data contained - * in a DOFF file. - */ -/* - * ======== dbll_tar_obj ======== - */ -struct dbll_tar_obj { - struct dbll_attrs attrs; - struct dbll_library_obj *head; /* List of all opened libraries */ -}; - -/* - * The following 4 typedefs are "super classes" of the dynamic loader - * library types used in dynamic loader functions (dynamic_loader.h). - */ -/* - * ======== dbll_stream ======== - * Contains dynamic_loader_stream - */ -struct dbll_stream { - struct dynamic_loader_stream dl_stream; - struct dbll_library_obj *lib; -}; - -/* - * ======== ldr_symbol ======== - */ -struct ldr_symbol { - struct dynamic_loader_sym dl_symbol; - struct dbll_library_obj *lib; -}; - -/* - * ======== dbll_alloc ======== - */ -struct dbll_alloc { - struct dynamic_loader_allocate dl_alloc; - struct dbll_library_obj *lib; -}; - -/* - * ======== dbll_init_obj ======== - */ -struct dbll_init_obj { - struct dynamic_loader_initialize dl_init; - struct dbll_library_obj *lib; -}; - -/* - * ======== DBLL_Library ======== - * A library handle is returned by DBLL_Open() and is passed to dbll_load() - * to load symbols/code/data, and to dbll_unload(), to remove the - * symbols/code/data loaded by dbll_load(). - */ - -/* - * ======== dbll_library_obj ======== - */ -struct dbll_library_obj { - struct dbll_library_obj *next; /* Next library in target's list */ - struct dbll_library_obj *prev; /* Previous in the list */ - struct dbll_tar_obj *target_obj; /* target for this library */ - - /* Objects needed by dynamic loader */ - struct dbll_stream stream; - struct ldr_symbol symbol; - struct dbll_alloc allocate; - struct dbll_init_obj init; - void *dload_mod_obj; - - char *file_name; /* COFF file name */ - void *fp; /* Opaque file handle */ - u32 entry; /* Entry point */ - void *desc; /* desc of DOFF file loaded */ - u32 open_ref; /* Number of times opened */ - u32 load_ref; /* Number of times loaded */ - struct gh_t_hash_tab *sym_tab; /* Hash table of symbols */ - u32 pos; -}; - -/* - * ======== dbll_symbol ======== - */ -struct dbll_symbol { - struct dbll_sym_val value; - char *name; -}; - -static void dof_close(struct dbll_library_obj *zl_lib); -static int dof_open(struct dbll_library_obj *zl_lib); -static s32 no_op(struct dynamic_loader_initialize *thisptr, void *bufr, - ldr_addr locn, struct ldr_section_info *info, - unsigned bytsize); - -/* - * Functions called by dynamic loader - * - */ -/* dynamic_loader_stream */ -static int dbll_read_buffer(struct dynamic_loader_stream *this, void *buffer, - unsigned bufsize); -static int dbll_set_file_posn(struct dynamic_loader_stream *this, - unsigned int pos); -/* dynamic_loader_sym */ -static struct dynload_symbol *dbll_find_symbol(struct dynamic_loader_sym *this, - const char *name); -static struct dynload_symbol *dbll_add_to_symbol_table(struct dynamic_loader_sym - *this, const char *name, - unsigned module_id); -static struct dynload_symbol *find_in_symbol_table(struct dynamic_loader_sym - *this, const char *name, - unsigned moduleid); -static void dbll_purge_symbol_table(struct dynamic_loader_sym *this, - unsigned module_id); -static void *allocate(struct dynamic_loader_sym *this, unsigned memsize); -static void deallocate(struct dynamic_loader_sym *this, void *mem_ptr); -static void dbll_err_report(struct dynamic_loader_sym *this, const char *errstr, - va_list args); -/* dynamic_loader_allocate */ -static int dbll_rmm_alloc(struct dynamic_loader_allocate *this, - struct ldr_section_info *info, unsigned align); -static void rmm_dealloc(struct dynamic_loader_allocate *this, - struct ldr_section_info *info); - -/* dynamic_loader_initialize */ -static int connect(struct dynamic_loader_initialize *this); -static int read_mem(struct dynamic_loader_initialize *this, void *buf, - ldr_addr addr, struct ldr_section_info *info, - unsigned bytes); -static int write_mem(struct dynamic_loader_initialize *this, void *buf, - ldr_addr addr, struct ldr_section_info *info, - unsigned nbytes); -static int fill_mem(struct dynamic_loader_initialize *this, ldr_addr addr, - struct ldr_section_info *info, unsigned bytes, - unsigned val); -static int execute(struct dynamic_loader_initialize *this, ldr_addr start); -static void release(struct dynamic_loader_initialize *this); - -/* symbol table hash functions */ -static u32 name_hash(const void *key); -static bool name_match(const void *key, const void *sp); -static void sym_delete(void *value); - -/* Symbol Redefinition */ -static int redefined_symbol; -static int gbl_search = 1; - -/* - * ======== dbll_close ======== - */ -void dbll_close(struct dbll_library_obj *zl_lib) -{ - struct dbll_tar_obj *zl_target; - - zl_target = zl_lib->target_obj; - zl_lib->open_ref--; - if (zl_lib->open_ref == 0) { - /* Remove library from list */ - if (zl_target->head == zl_lib) - zl_target->head = zl_lib->next; - - if (zl_lib->prev) - (zl_lib->prev)->next = zl_lib->next; - - if (zl_lib->next) - (zl_lib->next)->prev = zl_lib->prev; - - /* Free DOF resources */ - dof_close(zl_lib); - kfree(zl_lib->file_name); - - /* remove symbols from symbol table */ - if (zl_lib->sym_tab) - gh_delete(zl_lib->sym_tab); - - /* remove the library object itself */ - kfree(zl_lib); - zl_lib = NULL; - } -} - -/* - * ======== dbll_create ======== - */ -int dbll_create(struct dbll_tar_obj **target_obj, - struct dbll_attrs *pattrs) -{ - struct dbll_tar_obj *pzl_target; - int status = 0; - - /* Allocate DBL target object */ - pzl_target = kzalloc(sizeof(struct dbll_tar_obj), GFP_KERNEL); - if (target_obj != NULL) { - if (pzl_target == NULL) { - *target_obj = NULL; - status = -ENOMEM; - } else { - pzl_target->attrs = *pattrs; - *target_obj = (struct dbll_tar_obj *)pzl_target; - } - } - - return status; -} - -/* - * ======== dbll_delete ======== - */ -void dbll_delete(struct dbll_tar_obj *target) -{ - struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target; - - kfree(zl_target); - -} - -/* - * ======== dbll_exit ======== - * Discontinue usage of DBL module. - */ -void dbll_exit(void) -{ - /* do nothing */ -} - -/* - * ======== dbll_get_addr ======== - * Get address of name in the specified library. - */ -bool dbll_get_addr(struct dbll_library_obj *zl_lib, char *name, - struct dbll_sym_val **sym_val) -{ - struct dbll_symbol *sym; - - sym = (struct dbll_symbol *)gh_find(zl_lib->sym_tab, name); - if (IS_ERR(sym)) - return false; - - *sym_val = &sym->value; - - dev_dbg(bridge, "%s: lib: %p name: %s paddr: %p\n", - __func__, zl_lib, name, sym_val); - return true; -} - -/* - * ======== dbll_get_attrs ======== - * Retrieve the attributes of the target. - */ -void dbll_get_attrs(struct dbll_tar_obj *target, struct dbll_attrs *pattrs) -{ - struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target; - - if ((pattrs != NULL) && (zl_target != NULL)) - *pattrs = zl_target->attrs; - -} - -/* - * ======== dbll_get_c_addr ======== - * Get address of a "C" name in the specified library. - */ -bool dbll_get_c_addr(struct dbll_library_obj *zl_lib, char *name, - struct dbll_sym_val **sym_val) -{ - struct dbll_symbol *sym; - char cname[MAXEXPR + 1]; - - cname[0] = '_'; - - strncpy(cname + 1, name, sizeof(cname) - 2); - cname[MAXEXPR] = '\0'; /* insure '\0' string termination */ - - /* Check for C name, if not found */ - sym = (struct dbll_symbol *)gh_find(zl_lib->sym_tab, cname); - if (IS_ERR(sym)) - return false; - - *sym_val = &sym->value; - - return true; -} - -/* - * ======== dbll_get_sect ======== - * Get the base address and size (in bytes) of a COFF section. - */ -int dbll_get_sect(struct dbll_library_obj *lib, char *name, u32 *paddr, - u32 *psize) -{ - u32 byte_size; - bool opened_doff = false; - const struct ldr_section_info *sect = NULL; - struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib; - int status = 0; - - /* If DOFF file is not open, we open it. */ - if (zl_lib != NULL) { - if (zl_lib->fp == NULL) { - status = dof_open(zl_lib); - if (!status) - opened_doff = true; - - } else { - (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp, - zl_lib->pos, - SEEK_SET); - } - } else { - status = -EFAULT; - } - if (!status) { - byte_size = 1; - if (dload_get_section_info(zl_lib->desc, name, §)) { - *paddr = sect->load_addr; - *psize = sect->size * byte_size; - /* Make sure size is even for good swap */ - if (*psize % 2) - (*psize)++; - - /* Align size */ - *psize = DOFF_ALIGN(*psize); - } else { - status = -ENXIO; - } - } - if (opened_doff) { - dof_close(zl_lib); - opened_doff = false; - } - - dev_dbg(bridge, "%s: lib: %p name: %s paddr: %p psize: %p, status 0x%x\n", - __func__, lib, name, paddr, psize, status); - - return status; -} - -/* - * ======== dbll_init ======== - */ -bool dbll_init(void) -{ - /* do nothing */ - - return true; -} - -/* - * ======== dbll_load ======== - */ -int dbll_load(struct dbll_library_obj *lib, dbll_flags flags, - struct dbll_attrs *attrs, u32 *entry) -{ - struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib; - struct dbll_tar_obj *dbzl; - bool got_symbols = true; - s32 err; - int status = 0; - bool opened_doff = false; - - /* - * Load if not already loaded. - */ - if (zl_lib->load_ref == 0 || !(flags & DBLL_DYNAMIC)) { - dbzl = zl_lib->target_obj; - dbzl->attrs = *attrs; - /* Create a hash table for symbols if not already created */ - if (zl_lib->sym_tab == NULL) { - got_symbols = false; - zl_lib->sym_tab = gh_create(sizeof(struct dbll_symbol), - name_hash, - name_match, sym_delete); - if (IS_ERR(zl_lib->sym_tab)) { - status = PTR_ERR(zl_lib->sym_tab); - zl_lib->sym_tab = NULL; - } - - } - /* - * Set up objects needed by the dynamic loader - */ - /* Stream */ - zl_lib->stream.dl_stream.read_buffer = dbll_read_buffer; - zl_lib->stream.dl_stream.set_file_posn = dbll_set_file_posn; - zl_lib->stream.lib = zl_lib; - /* Symbol */ - zl_lib->symbol.dl_symbol.find_matching_symbol = - dbll_find_symbol; - if (got_symbols) { - zl_lib->symbol.dl_symbol.add_to_symbol_table = - find_in_symbol_table; - } else { - zl_lib->symbol.dl_symbol.add_to_symbol_table = - dbll_add_to_symbol_table; - } - zl_lib->symbol.dl_symbol.purge_symbol_table = - dbll_purge_symbol_table; - zl_lib->symbol.dl_symbol.dload_allocate = allocate; - zl_lib->symbol.dl_symbol.dload_deallocate = deallocate; - zl_lib->symbol.dl_symbol.error_report = dbll_err_report; - zl_lib->symbol.lib = zl_lib; - /* Allocate */ - zl_lib->allocate.dl_alloc.dload_allocate = dbll_rmm_alloc; - zl_lib->allocate.dl_alloc.dload_deallocate = rmm_dealloc; - zl_lib->allocate.lib = zl_lib; - /* Init */ - zl_lib->init.dl_init.connect = connect; - zl_lib->init.dl_init.readmem = read_mem; - zl_lib->init.dl_init.writemem = write_mem; - zl_lib->init.dl_init.fillmem = fill_mem; - zl_lib->init.dl_init.execute = execute; - zl_lib->init.dl_init.release = release; - zl_lib->init.lib = zl_lib; - /* If COFF file is not open, we open it. */ - if (zl_lib->fp == NULL) { - status = dof_open(zl_lib); - if (!status) - opened_doff = true; - - } - if (!status) { - zl_lib->pos = (*(zl_lib->target_obj->attrs.ftell)) - (zl_lib->fp); - /* Reset file cursor */ - (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp, - (long)0, - SEEK_SET); - symbols_reloaded = true; - /* The 5th argument, DLOAD_INITBSS, tells the DLL - * module to zero-init all BSS sections. In general, - * this is not necessary and also increases load time. - * We may want to make this configurable by the user */ - err = dynamic_load_module(&zl_lib->stream.dl_stream, - &zl_lib->symbol.dl_symbol, - &zl_lib->allocate.dl_alloc, - &zl_lib->init.dl_init, - DLOAD_INITBSS, - &zl_lib->dload_mod_obj); - - if (err != 0) { - status = -EILSEQ; - } else if (redefined_symbol) { - zl_lib->load_ref++; - dbll_unload(zl_lib, (struct dbll_attrs *)attrs); - redefined_symbol = false; - status = -EILSEQ; - } else { - *entry = zl_lib->entry; - } - } - } - if (!status) - zl_lib->load_ref++; - - /* Clean up DOFF resources */ - if (opened_doff) - dof_close(zl_lib); - - dev_dbg(bridge, "%s: lib: %p flags: 0x%x entry: %p, status 0x%x\n", - __func__, lib, flags, entry, status); - - return status; -} - -/* - * ======== dbll_open ======== - */ -int dbll_open(struct dbll_tar_obj *target, char *file, dbll_flags flags, - struct dbll_library_obj **lib_obj) -{ - struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target; - struct dbll_library_obj *zl_lib = NULL; - s32 err; - int status = 0; - - zl_lib = zl_target->head; - while (zl_lib != NULL) { - if (strcmp(zl_lib->file_name, file) == 0) { - /* Library is already opened */ - zl_lib->open_ref++; - break; - } - zl_lib = zl_lib->next; - } - if (zl_lib == NULL) { - /* Allocate DBL library object */ - zl_lib = kzalloc(sizeof(struct dbll_library_obj), GFP_KERNEL); - if (zl_lib == NULL) { - status = -ENOMEM; - } else { - zl_lib->pos = 0; - /* Increment ref count to allow close on failure - * later on */ - zl_lib->open_ref++; - zl_lib->target_obj = zl_target; - /* Keep a copy of the file name */ - zl_lib->file_name = kzalloc(strlen(file) + 1, - GFP_KERNEL); - if (zl_lib->file_name == NULL) { - status = -ENOMEM; - } else { - strncpy(zl_lib->file_name, file, - strlen(file) + 1); - } - zl_lib->sym_tab = NULL; - } - } - /* - * Set up objects needed by the dynamic loader - */ - if (status) - goto func_cont; - - /* Stream */ - zl_lib->stream.dl_stream.read_buffer = dbll_read_buffer; - zl_lib->stream.dl_stream.set_file_posn = dbll_set_file_posn; - zl_lib->stream.lib = zl_lib; - /* Symbol */ - zl_lib->symbol.dl_symbol.add_to_symbol_table = dbll_add_to_symbol_table; - zl_lib->symbol.dl_symbol.find_matching_symbol = dbll_find_symbol; - zl_lib->symbol.dl_symbol.purge_symbol_table = dbll_purge_symbol_table; - zl_lib->symbol.dl_symbol.dload_allocate = allocate; - zl_lib->symbol.dl_symbol.dload_deallocate = deallocate; - zl_lib->symbol.dl_symbol.error_report = dbll_err_report; - zl_lib->symbol.lib = zl_lib; - /* Allocate */ - zl_lib->allocate.dl_alloc.dload_allocate = dbll_rmm_alloc; - zl_lib->allocate.dl_alloc.dload_deallocate = rmm_dealloc; - zl_lib->allocate.lib = zl_lib; - /* Init */ - zl_lib->init.dl_init.connect = connect; - zl_lib->init.dl_init.readmem = read_mem; - zl_lib->init.dl_init.writemem = write_mem; - zl_lib->init.dl_init.fillmem = fill_mem; - zl_lib->init.dl_init.execute = execute; - zl_lib->init.dl_init.release = release; - zl_lib->init.lib = zl_lib; - if (!status && zl_lib->fp == NULL) - status = dof_open(zl_lib); - - zl_lib->pos = (*(zl_lib->target_obj->attrs.ftell)) (zl_lib->fp); - (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp, (long)0, SEEK_SET); - /* Create a hash table for symbols if flag is set */ - if (zl_lib->sym_tab != NULL || !(flags & DBLL_SYMB)) - goto func_cont; - - zl_lib->sym_tab = - gh_create(sizeof(struct dbll_symbol), name_hash, name_match, - sym_delete); - if (IS_ERR(zl_lib->sym_tab)) { - status = PTR_ERR(zl_lib->sym_tab); - zl_lib->sym_tab = NULL; - } else { - /* Do a fake load to get symbols - set write func to no_op */ - zl_lib->init.dl_init.writemem = no_op; - err = dynamic_open_module(&zl_lib->stream.dl_stream, - &zl_lib->symbol.dl_symbol, - &zl_lib->allocate.dl_alloc, - &zl_lib->init.dl_init, 0, - &zl_lib->dload_mod_obj); - if (err != 0) { - status = -EILSEQ; - } else { - /* Now that we have the symbol table, we can unload */ - err = dynamic_unload_module(zl_lib->dload_mod_obj, - &zl_lib->symbol.dl_symbol, - &zl_lib->allocate.dl_alloc, - &zl_lib->init.dl_init); - if (err != 0) - status = -EILSEQ; - - zl_lib->dload_mod_obj = NULL; - } - } -func_cont: - if (!status) { - if (zl_lib->open_ref == 1) { - /* First time opened - insert in list */ - if (zl_target->head) - (zl_target->head)->prev = zl_lib; - - zl_lib->prev = NULL; - zl_lib->next = zl_target->head; - zl_target->head = zl_lib; - } - *lib_obj = (struct dbll_library_obj *)zl_lib; - } else { - *lib_obj = NULL; - if (zl_lib != NULL) - dbll_close((struct dbll_library_obj *)zl_lib); - - } - - dev_dbg(bridge, "%s: target: %p file: %s lib_obj: %p, status 0x%x\n", - __func__, target, file, lib_obj, status); - - return status; -} - -/* - * ======== dbll_read_sect ======== - * Get the content of a COFF section. - */ -int dbll_read_sect(struct dbll_library_obj *lib, char *name, - char *buf, u32 size) -{ - struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib; - bool opened_doff = false; - u32 byte_size; /* size of bytes */ - u32 ul_sect_size; /* size of section */ - const struct ldr_section_info *sect = NULL; - int status = 0; - - /* If DOFF file is not open, we open it. */ - if (zl_lib != NULL) { - if (zl_lib->fp == NULL) { - status = dof_open(zl_lib); - if (!status) - opened_doff = true; - - } else { - (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp, - zl_lib->pos, - SEEK_SET); - } - } else { - status = -EFAULT; - } - if (status) - goto func_cont; - - byte_size = 1; - if (!dload_get_section_info(zl_lib->desc, name, §)) { - status = -ENXIO; - goto func_cont; - } - /* - * Ensure the supplied buffer size is sufficient to store - * the section buf to be read. - */ - ul_sect_size = sect->size * byte_size; - /* Make sure size is even for good swap */ - if (ul_sect_size % 2) - ul_sect_size++; - - /* Align size */ - ul_sect_size = DOFF_ALIGN(ul_sect_size); - if (ul_sect_size > size) { - status = -EPERM; - } else { - if (!dload_get_section(zl_lib->desc, sect, buf)) - status = -EBADF; - - } -func_cont: - if (opened_doff) { - dof_close(zl_lib); - opened_doff = false; - } - - dev_dbg(bridge, "%s: lib: %p name: %s buf: %p size: 0x%x, status 0x%x\n", - __func__, lib, name, buf, size, status); - return status; -} - -/* - * ======== dbll_unload ======== - */ -void dbll_unload(struct dbll_library_obj *lib, struct dbll_attrs *attrs) -{ - struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib; - s32 err = 0; - - dev_dbg(bridge, "%s: lib: %p\n", __func__, lib); - zl_lib->load_ref--; - /* Unload only if reference count is 0 */ - if (zl_lib->load_ref != 0) - return; - - zl_lib->target_obj->attrs = *attrs; - if (zl_lib->dload_mod_obj) { - err = dynamic_unload_module(zl_lib->dload_mod_obj, - &zl_lib->symbol.dl_symbol, - &zl_lib->allocate.dl_alloc, - &zl_lib->init.dl_init); - if (err != 0) - dev_dbg(bridge, "%s: failed: 0x%x\n", __func__, err); - } - /* remove symbols from symbol table */ - if (zl_lib->sym_tab != NULL) { - gh_delete(zl_lib->sym_tab); - zl_lib->sym_tab = NULL; - } - /* delete DOFF desc since it holds *lots* of host OS - * resources */ - dof_close(zl_lib); -} - -/* - * ======== dof_close ======== - */ -static void dof_close(struct dbll_library_obj *zl_lib) -{ - if (zl_lib->desc) { - dload_module_close(zl_lib->desc); - zl_lib->desc = NULL; - } - /* close file */ - if (zl_lib->fp) { - (zl_lib->target_obj->attrs.fclose) (zl_lib->fp); - zl_lib->fp = NULL; - } -} - -/* - * ======== dof_open ======== - */ -static int dof_open(struct dbll_library_obj *zl_lib) -{ - void *open = *(zl_lib->target_obj->attrs.fopen); - int status = 0; - - /* First open the file for the dynamic loader, then open COF */ - zl_lib->fp = - (void *)((dbll_f_open_fxn) (open)) (zl_lib->file_name, "rb"); - - /* Open DOFF module */ - if (zl_lib->fp && zl_lib->desc == NULL) { - (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp, (long)0, - SEEK_SET); - zl_lib->desc = - dload_module_open(&zl_lib->stream.dl_stream, - &zl_lib->symbol.dl_symbol); - if (zl_lib->desc == NULL) { - (zl_lib->target_obj->attrs.fclose) (zl_lib->fp); - zl_lib->fp = NULL; - status = -EBADF; - } - } else { - status = -EBADF; - } - - return status; -} - -/* - * ======== name_hash ======== - */ -static u32 name_hash(const void *key) -{ - u32 hash; - const char *name = key; - - hash = 0; - - while (*name) { - hash <<= 1; - hash ^= *name++; - } - - return hash; -} - -/* - * ======== name_match ======== - */ -static bool name_match(const void *key, const void *sp) -{ - if ((key != NULL) && (sp != NULL)) { - if (strcmp(key, ((struct dbll_symbol *)sp)->name) == 0) - return true; - } - return false; -} - -/* - * ======== no_op ======== - */ -static int no_op(struct dynamic_loader_initialize *thisptr, void *bufr, - ldr_addr locn, struct ldr_section_info *info, unsigned bytsize) -{ - return 1; -} - -/* - * ======== sym_delete ======== - */ -static void sym_delete(void *value) -{ - struct dbll_symbol *sp = (struct dbll_symbol *)value; - - kfree(sp->name); -} - -/* - * Dynamic Loader Functions - */ - -/* dynamic_loader_stream */ -/* - * ======== dbll_read_buffer ======== - */ -static int dbll_read_buffer(struct dynamic_loader_stream *this, void *buffer, - unsigned bufsize) -{ - struct dbll_stream *pstream = (struct dbll_stream *)this; - struct dbll_library_obj *lib; - int bytes_read = 0; - - lib = pstream->lib; - if (lib != NULL) { - bytes_read = - (*(lib->target_obj->attrs.fread)) (buffer, 1, bufsize, - lib->fp); - } - return bytes_read; -} - -/* - * ======== dbll_set_file_posn ======== - */ -static int dbll_set_file_posn(struct dynamic_loader_stream *this, - unsigned int pos) -{ - struct dbll_stream *pstream = (struct dbll_stream *)this; - struct dbll_library_obj *lib; - int status = 0; /* Success */ - - lib = pstream->lib; - if (lib != NULL) { - status = (*(lib->target_obj->attrs.fseek)) (lib->fp, (long)pos, - SEEK_SET); - } - - return status; -} - -/* dynamic_loader_sym */ - -/* - * ======== dbll_find_symbol ======== - */ -static struct dynload_symbol *dbll_find_symbol(struct dynamic_loader_sym *this, - const char *name) -{ - struct dynload_symbol *ret_sym; - struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this; - struct dbll_library_obj *lib; - struct dbll_sym_val *dbll_sym = NULL; - bool status = false; /* Symbol not found yet */ - - lib = ldr_sym->lib; - if (lib != NULL) { - if (lib->target_obj->attrs.sym_lookup) { - /* Check current lib + base lib + dep lib + - * persistent lib */ - status = (*(lib->target_obj->attrs.sym_lookup)) - (lib->target_obj->attrs.sym_handle, - lib->target_obj->attrs.sym_arg, - lib->target_obj->attrs.rmm_handle, name, - &dbll_sym); - } else { - /* Just check current lib for symbol */ - status = dbll_get_addr((struct dbll_library_obj *)lib, - (char *)name, &dbll_sym); - if (!status) { - status = dbll_get_c_addr( - (struct dbll_library_obj *) - lib, (char *)name, - &dbll_sym); - } - } - } - - if (!status && gbl_search) - dev_dbg(bridge, "%s: Symbol not found: %s\n", __func__, name); - - ret_sym = (struct dynload_symbol *)dbll_sym; - return ret_sym; -} - -/* - * ======== find_in_symbol_table ======== - */ -static struct dynload_symbol *find_in_symbol_table(struct dynamic_loader_sym - *this, const char *name, - unsigned moduleid) -{ - struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this; - struct dbll_library_obj *lib; - struct dbll_symbol *sym; - - lib = ldr_sym->lib; - sym = (struct dbll_symbol *)gh_find(lib->sym_tab, (char *)name); - - if (IS_ERR(sym)) - return NULL; - - return (struct dynload_symbol *)&sym->value; -} - -/* - * ======== dbll_add_to_symbol_table ======== - */ -static struct dynload_symbol *dbll_add_to_symbol_table(struct dynamic_loader_sym - *this, const char *name, - unsigned module_id) -{ - struct dbll_symbol *sym_ptr = NULL; - struct dbll_symbol symbol; - struct dynload_symbol *dbll_sym = NULL; - struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this; - struct dbll_library_obj *lib; - struct dynload_symbol *ret; - - lib = ldr_sym->lib; - - /* Check to see if symbol is already defined in symbol table */ - if (!(lib->target_obj->attrs.base_image)) { - gbl_search = false; - dbll_sym = dbll_find_symbol(this, name); - gbl_search = true; - if (dbll_sym) { - redefined_symbol = true; - dev_dbg(bridge, "%s already defined in symbol table\n", - name); - return NULL; - } - } - /* Allocate string to copy symbol name */ - symbol.name = kzalloc(strlen((char *const)name) + 1, GFP_KERNEL); - if (symbol.name == NULL) - return NULL; - - if (symbol.name != NULL) { - /* Just copy name (value will be filled in by dynamic loader) */ - strncpy(symbol.name, (char *const)name, - strlen((char *const)name) + 1); - - /* Add symbol to symbol table */ - sym_ptr = - (struct dbll_symbol *)gh_insert(lib->sym_tab, (void *)name, - (void *)&symbol); - if (IS_ERR(sym_ptr)) { - kfree(symbol.name); - sym_ptr = NULL; - } - - } - if (sym_ptr != NULL) - ret = (struct dynload_symbol *)&sym_ptr->value; - else - ret = NULL; - - return ret; -} - -/* - * ======== dbll_purge_symbol_table ======== - */ -static void dbll_purge_symbol_table(struct dynamic_loader_sym *this, - unsigned module_id) -{ - struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this; - struct dbll_library_obj *lib; - - lib = ldr_sym->lib; - /* May not need to do anything */ -} - -/* - * ======== allocate ======== - */ -static void *allocate(struct dynamic_loader_sym *this, unsigned memsize) -{ - struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this; - struct dbll_library_obj *lib; - void *buf; - - lib = ldr_sym->lib; - - buf = kzalloc(memsize, GFP_KERNEL); - - return buf; -} - -/* - * ======== deallocate ======== - */ -static void deallocate(struct dynamic_loader_sym *this, void *mem_ptr) -{ - struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this; - struct dbll_library_obj *lib; - - lib = ldr_sym->lib; - - kfree(mem_ptr); -} - -/* - * ======== dbll_err_report ======== - */ -static void dbll_err_report(struct dynamic_loader_sym *this, const char *errstr, - va_list args) -{ - struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this; - struct dbll_library_obj *lib; - char temp_buf[MAXEXPR]; - - lib = ldr_sym->lib; - vsnprintf((char *)temp_buf, MAXEXPR, (char *)errstr, args); - dev_dbg(bridge, "%s\n", temp_buf); -} - -/* dynamic_loader_allocate */ - -/* - * ======== dbll_rmm_alloc ======== - */ -static int dbll_rmm_alloc(struct dynamic_loader_allocate *this, - struct ldr_section_info *info, unsigned align) -{ - struct dbll_alloc *dbll_alloc_obj = (struct dbll_alloc *)this; - struct dbll_library_obj *lib; - int status = 0; - u32 mem_sect_type; - struct rmm_addr rmm_addr_obj; - s32 ret = true; - unsigned stype = DLOAD_SECTION_TYPE(info->type); - char *token = NULL; - char *sz_sec_last_token = NULL; - char *sz_last_token = NULL; - char *sz_sect_name = NULL; - char *psz_cur; - s32 token_len = 0; - s32 seg_id = -1; - s32 req = -1; - s32 count = 0; - u32 alloc_size = 0; - u32 run_addr_flag = 0; - - lib = dbll_alloc_obj->lib; - - mem_sect_type = - (stype == DLOAD_TEXT) ? DBLL_CODE : (stype == - DLOAD_BSS) ? DBLL_BSS : - DBLL_DATA; - - /* Attempt to extract the segment ID and requirement information from - the name of the section */ - token_len = strlen((char *)(info->name)) + 1; - - sz_sect_name = kzalloc(token_len, GFP_KERNEL); - sz_last_token = kzalloc(token_len, GFP_KERNEL); - sz_sec_last_token = kzalloc(token_len, GFP_KERNEL); - - if (sz_sect_name == NULL || sz_sec_last_token == NULL || - sz_last_token == NULL) { - status = -ENOMEM; - goto func_cont; - } - strncpy(sz_sect_name, (char *)(info->name), token_len); - psz_cur = sz_sect_name; - while ((token = strsep(&psz_cur, ":")) && *token != '\0') { - strncpy(sz_sec_last_token, sz_last_token, - strlen(sz_last_token) + 1); - strncpy(sz_last_token, token, strlen(token) + 1); - token = strsep(&psz_cur, ":"); - count++; /* optimizes processing */ - } - /* If token is 0 or 1, and sz_sec_last_token is DYN_DARAM or DYN_SARAM, - or DYN_EXTERNAL, then mem granularity information is present - within the section name - only process if there are at least three - tokens within the section name (just a minor optimization) */ - if (count >= 3) { - status = kstrtos32(sz_last_token, 10, &req); - if (status) - goto func_cont; - } - - if ((req == 0) || (req == 1)) { - if (strcmp(sz_sec_last_token, "DYN_DARAM") == 0) { - seg_id = 0; - } else { - if (strcmp(sz_sec_last_token, "DYN_SARAM") == 0) { - seg_id = 1; - } else { - if (strcmp(sz_sec_last_token, - "DYN_EXTERNAL") == 0) - seg_id = 2; - } - } - } -func_cont: - kfree(sz_sect_name); - sz_sect_name = NULL; - kfree(sz_last_token); - sz_last_token = NULL; - kfree(sz_sec_last_token); - sz_sec_last_token = NULL; - - if (mem_sect_type == DBLL_CODE) - alloc_size = info->size + GEM_L1P_PREFETCH_SIZE; - else - alloc_size = info->size; - - if (info->load_addr != info->run_addr) - run_addr_flag = 1; - /* TODO - ideally, we can pass the alignment requirement also - * from here */ - if (lib != NULL) { - status = - (lib->target_obj->attrs.alloc) (lib->target_obj->attrs. - rmm_handle, mem_sect_type, - alloc_size, align, - (u32 *) &rmm_addr_obj, - seg_id, req, false); - } - if (status) { - ret = false; - } else { - /* RMM gives word address. Need to convert to byte address */ - info->load_addr = rmm_addr_obj.addr * DSPWORDSIZE; - if (!run_addr_flag) - info->run_addr = info->load_addr; - info->context = (u32) rmm_addr_obj.segid; - dev_dbg(bridge, "%s: %s base = 0x%x len = 0x%x, info->run_addr 0x%x, info->load_addr 0x%x\n", - __func__, info->name, info->load_addr / DSPWORDSIZE, - info->size / DSPWORDSIZE, info->run_addr, - info->load_addr); - } - return ret; -} - -/* - * ======== rmm_dealloc ======== - */ -static void rmm_dealloc(struct dynamic_loader_allocate *this, - struct ldr_section_info *info) -{ - struct dbll_alloc *dbll_alloc_obj = (struct dbll_alloc *)this; - struct dbll_library_obj *lib; - u32 segid; - int status = 0; - unsigned stype = DLOAD_SECTION_TYPE(info->type); - u32 mem_sect_type; - u32 free_size = 0; - - mem_sect_type = - (stype == DLOAD_TEXT) ? DBLL_CODE : (stype == - DLOAD_BSS) ? DBLL_BSS : - DBLL_DATA; - lib = dbll_alloc_obj->lib; - /* segid was set by alloc function */ - segid = (u32) info->context; - if (mem_sect_type == DBLL_CODE) - free_size = info->size + GEM_L1P_PREFETCH_SIZE; - else - free_size = info->size; - if (lib != NULL) { - status = - (lib->target_obj->attrs.free) (lib->target_obj->attrs. - sym_handle, segid, - info->load_addr / - DSPWORDSIZE, free_size, - false); - } -} - -/* dynamic_loader_initialize */ -/* - * ======== connect ======== - */ -static int connect(struct dynamic_loader_initialize *this) -{ - return true; -} - -/* - * ======== read_mem ======== - * This function does not need to be implemented. - */ -static int read_mem(struct dynamic_loader_initialize *this, void *buf, - ldr_addr addr, struct ldr_section_info *info, - unsigned nbytes) -{ - struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this; - struct dbll_library_obj *lib; - int bytes_read = 0; - - lib = init_obj->lib; - /* Need bridge_brd_read function */ - return bytes_read; -} - -/* - * ======== write_mem ======== - */ -static int write_mem(struct dynamic_loader_initialize *this, void *buf, - ldr_addr addr, struct ldr_section_info *info, - unsigned bytes) -{ - struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this; - struct dbll_library_obj *lib; - struct dbll_tar_obj *target_obj; - struct dbll_sect_info sect_info; - u32 mem_sect_type; - bool ret = true; - - lib = init_obj->lib; - if (!lib) - return false; - - target_obj = lib->target_obj; - - mem_sect_type = - (DLOAD_SECTION_TYPE(info->type) == - DLOAD_TEXT) ? DBLL_CODE : DBLL_DATA; - if (target_obj && target_obj->attrs.write) { - ret = - (*target_obj->attrs.write) (target_obj->attrs.input_params, - addr, buf, bytes, - mem_sect_type); - - if (target_obj->attrs.log_write) { - sect_info.name = info->name; - sect_info.sect_run_addr = info->run_addr; - sect_info.sect_load_addr = info->load_addr; - sect_info.size = info->size; - sect_info.type = mem_sect_type; - /* Pass the information about what we've written to - * another module */ - (*target_obj->attrs.log_write) (target_obj->attrs. - log_write_handle, - §_info, addr, - bytes); - } - } - return ret; -} - -/* - * ======== fill_mem ======== - * Fill bytes of memory at a given address with a given value by - * writing from a buffer containing the given value. Write in - * sets of MAXEXPR (128) bytes to avoid large stack buffer issues. - */ -static int fill_mem(struct dynamic_loader_initialize *this, ldr_addr addr, - struct ldr_section_info *info, unsigned bytes, unsigned val) -{ - bool ret = true; - char *pbuf; - struct dbll_library_obj *lib; - struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this; - - lib = init_obj->lib; - pbuf = NULL; - /* Pass the NULL pointer to write_mem to get the start address of Shared - memory. This is a trick to just get the start address, there is no - writing taking place with this Writemem - */ - if ((lib->target_obj->attrs.write) != (dbll_write_fxn) no_op) - write_mem(this, &pbuf, addr, info, 0); - if (pbuf) - memset(pbuf, val, bytes); - - return ret; -} - -/* - * ======== execute ======== - */ -static int execute(struct dynamic_loader_initialize *this, ldr_addr start) -{ - struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this; - struct dbll_library_obj *lib; - bool ret = true; - - lib = init_obj->lib; - /* Save entry point */ - if (lib != NULL) - lib->entry = (u32) start; - - return ret; -} - -/* - * ======== release ======== - */ -static void release(struct dynamic_loader_initialize *this) -{ -} - -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE -/** - * find_symbol_context - Basic symbol context structure - * @address: Symbol Address - * @offset_range: Offset range where the search for the DSP symbol - * started. - * @cur_best_offset: Best offset to start looking for the DSP symbol - * @sym_addr: Address of the DSP symbol - * @name: Symbol name - * - */ -struct find_symbol_context { - /* input */ - u32 address; - u32 offset_range; - /* state */ - u32 cur_best_offset; - /* output */ - u32 sym_addr; - char name[120]; -}; - -/** - * find_symbol_callback() - Validates symbol address and copies the symbol name - * to the user data. - * @elem: dsp library context - * @user_data: Find symbol context - * - */ -void find_symbol_callback(void *elem, void *user_data) -{ - struct dbll_symbol *symbol = elem; - struct find_symbol_context *context = user_data; - u32 symbol_addr = symbol->value.value; - u32 offset = context->address - symbol_addr; - - /* - * Address given should be greater than symbol address, - * symbol address should be within specified range - * and the offset should be better than previous one - */ - if (context->address >= symbol_addr && symbol_addr < (u32)-1 && - offset < context->cur_best_offset) { - context->cur_best_offset = offset; - context->sym_addr = symbol_addr; - strlcpy(context->name, symbol->name, sizeof(context->name)); - } - - return; -} - -/** - * dbll_find_dsp_symbol() - This function retrieves the dsp symbol from the dsp binary. - * @zl_lib: DSP binary obj library pointer - * @address: Given address to find the dsp symbol - * @offset_range: offset range to look for dsp symbol - * @sym_addr_output: Symbol Output address - * @name_output: String with the dsp symbol - * - * This function retrieves the dsp symbol from the dsp binary. - */ -bool dbll_find_dsp_symbol(struct dbll_library_obj *zl_lib, u32 address, - u32 offset_range, u32 *sym_addr_output, - char *name_output) -{ - bool status = false; - struct find_symbol_context context; - - context.address = address; - context.offset_range = offset_range; - context.cur_best_offset = offset_range; - context.sym_addr = 0; - context.name[0] = '\0'; - - gh_iterate(zl_lib->sym_tab, find_symbol_callback, &context); - - if (context.name[0]) { - status = true; - strcpy(name_output, context.name); - *sym_addr_output = context.sym_addr; - } - - return status; -} -#endif diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c deleted file mode 100644 index 616dc1f63070..000000000000 --- a/drivers/staging/tidspbridge/pmgr/dev.c +++ /dev/null @@ -1,969 +0,0 @@ -/* - * dev.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Implementation of Bridge Bridge driver device operations. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ -#include <linux/types.h> -#include <linux/list.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/cod.h> -#include <dspbridge/drv.h> -#include <dspbridge/proc.h> -#include <dspbridge/dmm.h> - -/* ----------------------------------- Resource Manager */ -#include <dspbridge/mgr.h> -#include <dspbridge/node.h> - -/* ----------------------------------- Others */ -#include <dspbridge/dspapi.h> /* DSP API version info. */ - -#include <dspbridge/chnl.h> -#include <dspbridge/io.h> -#include <dspbridge/msg.h> -#include <dspbridge/cmm.h> -#include <dspbridge/dspdeh.h> - -/* ----------------------------------- This */ -#include <dspbridge/dev.h> - -/* ----------------------------------- Defines, Data Structures, Typedefs */ - -#define MAKEVERSION(major, minor) (major * 10 + minor) -#define BRD_API_VERSION MAKEVERSION(BRD_API_MAJOR_VERSION, \ - BRD_API_MINOR_VERSION) - -/* The Bridge device object: */ -struct dev_object { - struct list_head link; /* Link to next dev_object. */ - u8 dev_type; /* Device Type */ - struct cfg_devnode *dev_node_obj; /* Platform specific dev id */ - /* Bridge Context Handle */ - struct bridge_dev_context *bridge_context; - /* Function interface to Bridge driver. */ - struct bridge_drv_interface bridge_interface; - struct brd_object *lock_owner; /* Client with exclusive access. */ - struct cod_manager *cod_mgr; /* Code manager handle. */ - struct chnl_mgr *chnl_mgr; /* Channel manager. */ - struct deh_mgr *deh_mgr; /* DEH manager. */ - struct msg_mgr *msg_mgr; /* Message manager. */ - struct io_mgr *iomgr; /* IO manager (CHNL, msg_ctrl) */ - struct cmm_object *cmm_mgr; /* SM memory manager. */ - struct dmm_object *dmm_mgr; /* Dynamic memory manager. */ - u32 word_size; /* DSP word size: quick access. */ - struct drv_object *drv_obj; /* Driver Object */ - /* List of Processors attached to this device */ - struct list_head proc_list; - struct node_mgr *node_mgr; -}; - -struct drv_ext { - struct list_head link; - char sz_string[MAXREGPATHLENGTH]; -}; - -/* ----------------------------------- Function Prototypes */ -static int fxn_not_implemented(int arg, ...); -static int init_cod_mgr(struct dev_object *dev_obj); -static void store_interface_fxns(struct bridge_drv_interface *drv_fxns, - struct bridge_drv_interface *intf_fxns); -/* - * ======== dev_brd_write_fxn ======== - * Purpose: - * Exported function to be used as the COD write function. This function - * is passed a handle to a DEV_hObject, then calls the - * device's bridge_brd_write() function. - */ -u32 dev_brd_write_fxn(void *arb, u32 dsp_add, void *host_buf, - u32 ul_num_bytes, u32 mem_space) -{ - struct dev_object *dev_obj = (struct dev_object *)arb; - u32 ul_written = 0; - int status; - - if (dev_obj) { - /* Require of BrdWrite() */ - status = (*dev_obj->bridge_interface.brd_write) ( - dev_obj->bridge_context, host_buf, - dsp_add, ul_num_bytes, mem_space); - /* Special case of getting the address only */ - if (ul_num_bytes == 0) - ul_num_bytes = 1; - if (!status) - ul_written = ul_num_bytes; - - } - return ul_written; -} - -/* - * ======== dev_create_device ======== - * Purpose: - * Called by the operating system to load the PM Bridge Driver for a - * PM board (device). - */ -int dev_create_device(struct dev_object **device_obj, - const char *driver_file_name, - struct cfg_devnode *dev_node_obj) -{ - struct cfg_hostres *host_res; - struct bridge_drv_interface *drv_fxns = NULL; - struct dev_object *dev_obj = NULL; - struct chnl_mgrattrs mgr_attrs; - struct io_attrs io_mgr_attrs; - u32 num_windows; - struct drv_object *hdrv_obj = NULL; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - int status = 0; - - status = drv_request_bridge_res_dsp((void *)&host_res); - - if (status) { - dev_dbg(bridge, "%s: Failed to reserve bridge resources\n", - __func__); - goto leave; - } - - /* Get the Bridge driver interface functions */ - bridge_drv_entry(&drv_fxns, driver_file_name); - - /* Retrieve the Object handle from the driver data */ - if (drv_datap && drv_datap->drv_object) { - hdrv_obj = drv_datap->drv_object; - } else { - status = -EPERM; - pr_err("%s: Failed to retrieve the object handle\n", __func__); - } - - /* Create the device object, and pass a handle to the Bridge driver for - * storage. */ - if (!status) { - dev_obj = kzalloc(sizeof(struct dev_object), GFP_KERNEL); - if (dev_obj) { - /* Fill out the rest of the Dev Object structure: */ - dev_obj->dev_node_obj = dev_node_obj; - dev_obj->cod_mgr = NULL; - dev_obj->chnl_mgr = NULL; - dev_obj->deh_mgr = NULL; - dev_obj->lock_owner = NULL; - dev_obj->word_size = DSPWORDSIZE; - dev_obj->drv_obj = hdrv_obj; - dev_obj->dev_type = DSP_UNIT; - /* Store this Bridge's interface functions, based on its - * version. */ - store_interface_fxns(drv_fxns, - &dev_obj->bridge_interface); - - /* Call fxn_dev_create() to get the Bridge's device - * context handle. */ - status = (dev_obj->bridge_interface.dev_create) - (&dev_obj->bridge_context, dev_obj, - host_res); - } else { - status = -ENOMEM; - } - } - /* Attempt to create the COD manager for this device: */ - if (!status) - status = init_cod_mgr(dev_obj); - - /* Attempt to create the channel manager for this device: */ - if (!status) { - mgr_attrs.max_channels = CHNL_MAXCHANNELS; - io_mgr_attrs.birq = host_res->birq_registers; - io_mgr_attrs.irq_shared = - (host_res->birq_attrib & CFG_IRQSHARED); - io_mgr_attrs.word_size = DSPWORDSIZE; - mgr_attrs.word_size = DSPWORDSIZE; - num_windows = host_res->num_mem_windows; - if (num_windows) { - /* Assume last memory window is for CHNL */ - io_mgr_attrs.shm_base = host_res->mem_base[1] + - host_res->offset_for_monitor; - io_mgr_attrs.sm_length = - host_res->mem_length[1] - - host_res->offset_for_monitor; - } else { - io_mgr_attrs.shm_base = 0; - io_mgr_attrs.sm_length = 0; - pr_err("%s: No memory reserved for shared structures\n", - __func__); - } - status = chnl_create(&dev_obj->chnl_mgr, dev_obj, &mgr_attrs); - if (status == -ENOSYS) { - /* It's OK for a device not to have a channel - * manager: */ - status = 0; - } - /* Create CMM mgr even if Msg Mgr not impl. */ - status = cmm_create(&dev_obj->cmm_mgr, - (struct dev_object *)dev_obj, NULL); - /* Only create IO manager if we have a channel manager */ - if (!status && dev_obj->chnl_mgr) { - status = io_create(&dev_obj->iomgr, dev_obj, - &io_mgr_attrs); - } - /* Only create DEH manager if we have an IO manager */ - if (!status) { - /* Instantiate the DEH module */ - status = bridge_deh_create(&dev_obj->deh_mgr, dev_obj); - } - /* Create DMM mgr . */ - status = dmm_create(&dev_obj->dmm_mgr, - (struct dev_object *)dev_obj, NULL); - } - /* Add the new DEV_Object to the global list: */ - if (!status) - status = drv_insert_dev_object(hdrv_obj, dev_obj); - - /* Create the Processor List */ - if (!status) - INIT_LIST_HEAD(&dev_obj->proc_list); -leave: - /* If all went well, return a handle to the dev object; - * else, cleanup and return NULL in the OUT parameter. */ - if (!status) { - *device_obj = dev_obj; - } else { - if (dev_obj) { - if (dev_obj->cod_mgr) - cod_delete(dev_obj->cod_mgr); - if (dev_obj->dmm_mgr) - dmm_destroy(dev_obj->dmm_mgr); - kfree(dev_obj); - } - - *device_obj = NULL; - } - - 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; - - /* There can be only one Node Manager per DEV object */ - status = node_create_mgr(&dev_obj->node_mgr, hdev_obj); - if (status) - dev_obj->node_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; - - if (dev_obj->node_mgr) { - if (node_delete_mgr(dev_obj->node_mgr)) - status = -EPERM; - else - dev_obj->node_mgr = NULL; - - } - - return status; -} - -/* - * ======== dev_destroy_device ======== - * Purpose: - * Destroys the channel manager for this device, if any, calls - * bridge_dev_destroy(), and then attempts to unload the Bridge module. - */ -int dev_destroy_device(struct dev_object *hdev_obj) -{ - int status = 0; - struct dev_object *dev_obj = hdev_obj; - - if (hdev_obj) { - if (dev_obj->cod_mgr) { - cod_delete(dev_obj->cod_mgr); - dev_obj->cod_mgr = NULL; - } - - if (dev_obj->node_mgr) { - node_delete_mgr(dev_obj->node_mgr); - dev_obj->node_mgr = NULL; - } - - /* Free the io, channel, and message managers for this board: */ - if (dev_obj->iomgr) { - io_destroy(dev_obj->iomgr); - dev_obj->iomgr = NULL; - } - if (dev_obj->chnl_mgr) { - chnl_destroy(dev_obj->chnl_mgr); - dev_obj->chnl_mgr = NULL; - } - if (dev_obj->msg_mgr) { - msg_delete(dev_obj->msg_mgr); - dev_obj->msg_mgr = NULL; - } - - if (dev_obj->deh_mgr) { - /* Uninitialize DEH module. */ - bridge_deh_destroy(dev_obj->deh_mgr); - dev_obj->deh_mgr = NULL; - } - if (dev_obj->cmm_mgr) { - cmm_destroy(dev_obj->cmm_mgr, true); - dev_obj->cmm_mgr = NULL; - } - - if (dev_obj->dmm_mgr) { - dmm_destroy(dev_obj->dmm_mgr); - dev_obj->dmm_mgr = NULL; - } - - /* Call the driver's bridge_dev_destroy() function: */ - /* Require of DevDestroy */ - if (dev_obj->bridge_context) { - status = (*dev_obj->bridge_interface.dev_destroy) - (dev_obj->bridge_context); - dev_obj->bridge_context = NULL; - } else - status = -EPERM; - if (!status) { - /* Remove this DEV_Object from the global list: */ - drv_remove_dev_object(dev_obj->drv_obj, dev_obj); - /* Free The library * LDR_FreeModule - * (dev_obj->module_obj); */ - /* Free this dev object: */ - kfree(dev_obj); - dev_obj = NULL; - } - } else { - status = -EFAULT; - } - - return status; -} - -/* - * ======== dev_get_chnl_mgr ======== - * Purpose: - * Retrieve the handle to the channel manager handle created for this - * device. - */ -int dev_get_chnl_mgr(struct dev_object *hdev_obj, - struct chnl_mgr **mgr) -{ - int status = 0; - struct dev_object *dev_obj = hdev_obj; - - if (hdev_obj) { - *mgr = dev_obj->chnl_mgr; - } else { - *mgr = NULL; - status = -EFAULT; - } - - return status; -} - -/* - * ======== dev_get_cmm_mgr ======== - * Purpose: - * Retrieve the handle to the shared memory manager created for this - * device. - */ -int dev_get_cmm_mgr(struct dev_object *hdev_obj, - struct cmm_object **mgr) -{ - int status = 0; - struct dev_object *dev_obj = hdev_obj; - - if (hdev_obj) { - *mgr = dev_obj->cmm_mgr; - } else { - *mgr = NULL; - status = -EFAULT; - } - - 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; - - if (hdev_obj) { - *mgr = dev_obj->dmm_mgr; - } else { - *mgr = NULL; - status = -EFAULT; - } - - return status; -} - -/* - * ======== 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; - - if (hdev_obj) { - *cod_mgr = dev_obj->cod_mgr; - } else { - *cod_mgr = NULL; - status = -EFAULT; - } - - return status; -} - -/* - * ========= dev_get_deh_mgr ======== - */ -int dev_get_deh_mgr(struct dev_object *hdev_obj, - struct deh_mgr **deh_manager) -{ - int status = 0; - - if (hdev_obj) { - *deh_manager = hdev_obj->deh_mgr; - } else { - *deh_manager = NULL; - status = -EFAULT; - } - 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; - - if (hdev_obj) { - *dev_nde = dev_obj->dev_node_obj; - } else { - *dev_nde = NULL; - status = -EFAULT; - } - - return status; -} - -/* - * ======== dev_get_first ======== - * Purpose: - * Retrieve the first Device Object handle from an internal linked list - * DEV_OBJECTs maintained by DEV. - */ -struct dev_object *dev_get_first(void) -{ - struct dev_object *dev_obj = NULL; - - dev_obj = (struct dev_object *)drv_get_first_dev_object(); - - return dev_obj; -} - -/* - * ======== 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; - - if (hdev_obj) { - *if_fxns = &dev_obj->bridge_interface; - } else { - *if_fxns = NULL; - status = -EFAULT; - } - - return status; -} - -/* - * ========= dev_get_io_mgr ======== - */ -int dev_get_io_mgr(struct dev_object *hdev_obj, - struct io_mgr **io_man) -{ - int status = 0; - - if (hdev_obj) { - *io_man = hdev_obj->iomgr; - } else { - *io_man = NULL; - status = -EFAULT; - } - - return status; -} - -/* - * ======== dev_get_next ======== - * Purpose: - * Retrieve the next Device Object handle from an internal linked list - * of DEV_OBJECTs maintained by DEV, after having previously called - * dev_get_first() and zero or more dev_get_next - */ -struct dev_object *dev_get_next(struct dev_object *hdev_obj) -{ - struct dev_object *next_dev_object = NULL; - - if (hdev_obj) { - next_dev_object = (struct dev_object *) - drv_get_next_dev_object((u32) hdev_obj); - } - - return next_dev_object; -} - -/* - * ========= dev_get_msg_mgr ======== - */ -void dev_get_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr **msg_man) -{ - *msg_man = hdev_obj->msg_mgr; -} - -/* - * ======== 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; - - if (hdev_obj) { - *node_man = dev_obj->node_mgr; - } else { - *node_man = NULL; - status = -EFAULT; - } - - 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; - - 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_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; - - if (hdev_obj) { - *phbridge_context = dev_obj->bridge_context; - } else { - *phbridge_context = NULL; - status = -EFAULT; - } - - return status; -} - -/* - * ======== dev_notify_clients ======== - * Purpose: - * Notify all clients of this device of a change in device status. - */ -int dev_notify_clients(struct dev_object *dev_obj, u32 ret) -{ - struct list_head *curr; - - /* - * FIXME: this code needs struct proc_object to have a list_head - * at the beginning. If not, this can go horribly wrong. - */ - list_for_each(curr, &dev_obj->proc_list) - proc_notify_clients((void *)curr, ret); - - return 0; -} - -/* - * ======== dev_remove_device ======== - */ -int dev_remove_device(struct cfg_devnode *dev_node_obj) -{ - struct dev_object *hdev_obj; /* handle to device object */ - int status = 0; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - - if (!drv_datap) - status = -ENODATA; - - if (!dev_node_obj) - status = -EFAULT; - - /* Retrieve the device object handle originally stored with - * the dev_node: */ - if (!status) { - /* check the device string and then store dev object */ - if (!strcmp((char *)((struct drv_ext *)dev_node_obj)->sz_string, - "TIOMAP1510")) { - hdev_obj = drv_datap->dev_object; - /* Destroy the device object. */ - status = dev_destroy_device(hdev_obj); - } else { - status = -EPERM; - } - } - - if (status) - pr_err("%s: Failed, status 0x%x\n", __func__, status); - - return status; -} - -/* - * ======== dev_set_chnl_mgr ======== - * Purpose: - * Set the channel manager for this device. - */ -int dev_set_chnl_mgr(struct dev_object *hdev_obj, - struct chnl_mgr *hmgr) -{ - int status = 0; - struct dev_object *dev_obj = hdev_obj; - - if (hdev_obj) - dev_obj->chnl_mgr = hmgr; - else - status = -EFAULT; - - return status; -} - -/* - * ======== dev_set_msg_mgr ======== - * Purpose: - * Set the message manager for this device. - */ -void dev_set_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr *hmgr) -{ - hdev_obj->msg_mgr = hmgr; -} - -/* - * ======== dev_start_device ======== - * Purpose: - * Initializes the new device with the BRIDGE environment. - */ -int dev_start_device(struct cfg_devnode *dev_node_obj) -{ - struct dev_object *hdev_obj = NULL; /* handle to 'Bridge Device */ - /* Bridge driver filename */ - char *bridge_file_name = "UMA"; - int status; - struct mgr_object *hmgr_obj = NULL; - struct drv_data *drv_datap = dev_get_drvdata(bridge); - - /* Given all resources, create a device object. */ - status = dev_create_device(&hdev_obj, bridge_file_name, - dev_node_obj); - if (!status) { - /* Store away the hdev_obj with the DEVNODE */ - if (!drv_datap || !dev_node_obj) { - status = -EFAULT; - pr_err("%s: Failed, status 0x%x\n", __func__, status); - } else if (!(strcmp((char *)dev_node_obj, "TIOMAP1510"))) { - drv_datap->dev_object = (void *) hdev_obj; - } - if (!status) { - /* Create the Manager Object */ - status = mgr_create(&hmgr_obj, dev_node_obj); - if (status && !(strcmp((char *)dev_node_obj, - "TIOMAP1510"))) { - /* Ensure the device extension is NULL */ - drv_datap->dev_object = NULL; - } - } - if (status) { - /* Clean up */ - dev_destroy_device(hdev_obj); - hdev_obj = NULL; - } - } - - return status; -} - -/* - * ======== fxn_not_implemented ======== - * Purpose: - * Takes the place of a Bridge Null Function. - * Parameters: - * Multiple, optional. - * Returns: - * -ENOSYS: Always. - */ -static int fxn_not_implemented(int arg, ...) -{ - return -ENOSYS; -} - -/* - * ======== init_cod_mgr ======== - * Purpose: - * Create a COD manager for this device. - * Parameters: - * dev_obj: Pointer to device object created with - * dev_create_device() - * Returns: - * 0: Success. - * -EFAULT: Invalid hdev_obj. - * Requires: - * Should only be called once by dev_create_device() for a given DevObject. - * Ensures: - */ -static int init_cod_mgr(struct dev_object *dev_obj) -{ - int status = 0; - char *sz_dummy_file = "dummy"; - - status = cod_create(&dev_obj->cod_mgr, sz_dummy_file); - - return status; -} - -/* - * ======== dev_insert_proc_object ======== - * Purpose: - * Insert a ProcObject into the list maintained by DEV. - * Parameters: - * p_proc_object: Ptr to ProcObject to insert. - * dev_obj: Ptr to Dev Object where the list is. - * already_attached: Ptr to return the bool - * Returns: - * 0: If successful. - * Requires: - * List Exists - * hdev_obj is Valid handle - * DEV Initialized - * already_attached != NULL - * proc_obj != 0 - * Ensures: - * 0 and List is not Empty. - */ -int dev_insert_proc_object(struct dev_object *hdev_obj, - u32 proc_obj, bool *already_attached) -{ - struct dev_object *dev_obj = (struct dev_object *)hdev_obj; - - if (!list_empty(&dev_obj->proc_list)) - *already_attached = true; - - /* Add DevObject to tail. */ - /* - * FIXME: this code needs struct proc_object to have a list_head - * at the beginning. If not, this can go horribly wrong. - */ - list_add_tail((struct list_head *)proc_obj, &dev_obj->proc_list); - - return 0; -} - -/* - * ======== dev_remove_proc_object ======== - * Purpose: - * Search for and remove a Proc object from the given list maintained - * by the DEV - * Parameters: - * p_proc_object: Ptr to ProcObject to insert. - * dev_obj Ptr to Dev Object where the list is. - * Returns: - * 0: If successful. - * Requires: - * List exists and is not empty - * proc_obj != 0 - * hdev_obj is a valid Dev handle. - * Ensures: - * Details: - * List will be deleted when the DEV is destroyed. - */ -int dev_remove_proc_object(struct dev_object *hdev_obj, u32 proc_obj) -{ - int status = -EPERM; - struct list_head *cur_elem; - struct dev_object *dev_obj = (struct dev_object *)hdev_obj; - - /* Search list for dev_obj: */ - list_for_each(cur_elem, &dev_obj->proc_list) { - if ((u32) cur_elem == proc_obj) { - list_del(cur_elem); - status = 0; - break; - } - } - - return status; -} - -int dev_get_dev_type(struct dev_object *dev_obj, u8 *dev_type) -{ - *dev_type = dev_obj->dev_type; - return 0; -} - -/* - * ======== store_interface_fxns ======== - * Purpose: - * Copy the Bridge's interface functions into the device object, - * ensuring that fxn_not_implemented() is set for: - * - * 1. All Bridge function pointers which are NULL; and - * 2. All function slots in the struct dev_object structure which have no - * corresponding slots in the the Bridge's interface, because the Bridge - * is of an *older* version. - * Parameters: - * intf_fxns: Interface fxn Structure of the Bridge's Dev Object. - * drv_fxns: Interface Fxns offered by the Bridge during DEV_Create(). - * Returns: - * Requires: - * Input pointers are valid. - * Bridge driver is *not* written for a newer DSP API. - * Ensures: - * All function pointers in the dev object's fxn interface are not NULL. - */ -static void store_interface_fxns(struct bridge_drv_interface *drv_fxns, - struct bridge_drv_interface *intf_fxns) -{ - u32 bridge_version; - - /* Local helper macro: */ -#define STORE_FXN(cast, pfn) \ - (intf_fxns->pfn = ((drv_fxns->pfn != NULL) ? drv_fxns->pfn : \ - (cast)fxn_not_implemented)) - - bridge_version = MAKEVERSION(drv_fxns->brd_api_major_version, - drv_fxns->brd_api_minor_version); - intf_fxns->brd_api_major_version = drv_fxns->brd_api_major_version; - intf_fxns->brd_api_minor_version = drv_fxns->brd_api_minor_version; - /* Install functions up to DSP API version .80 (first alpha): */ - if (bridge_version > 0) { - STORE_FXN(fxn_dev_create, dev_create); - STORE_FXN(fxn_dev_destroy, dev_destroy); - STORE_FXN(fxn_dev_ctrl, dev_cntrl); - STORE_FXN(fxn_brd_monitor, brd_monitor); - STORE_FXN(fxn_brd_start, brd_start); - STORE_FXN(fxn_brd_stop, brd_stop); - STORE_FXN(fxn_brd_status, brd_status); - STORE_FXN(fxn_brd_read, brd_read); - STORE_FXN(fxn_brd_write, brd_write); - STORE_FXN(fxn_brd_setstate, brd_set_state); - STORE_FXN(fxn_brd_memcopy, brd_mem_copy); - STORE_FXN(fxn_brd_memwrite, brd_mem_write); - STORE_FXN(fxn_brd_memmap, brd_mem_map); - STORE_FXN(fxn_brd_memunmap, brd_mem_un_map); - STORE_FXN(fxn_chnl_create, chnl_create); - STORE_FXN(fxn_chnl_destroy, chnl_destroy); - STORE_FXN(fxn_chnl_open, chnl_open); - STORE_FXN(fxn_chnl_close, chnl_close); - STORE_FXN(fxn_chnl_addioreq, chnl_add_io_req); - STORE_FXN(fxn_chnl_getioc, chnl_get_ioc); - STORE_FXN(fxn_chnl_cancelio, chnl_cancel_io); - STORE_FXN(fxn_chnl_flushio, chnl_flush_io); - STORE_FXN(fxn_chnl_getinfo, chnl_get_info); - STORE_FXN(fxn_chnl_getmgrinfo, chnl_get_mgr_info); - STORE_FXN(fxn_chnl_idle, chnl_idle); - STORE_FXN(fxn_chnl_registernotify, chnl_register_notify); - STORE_FXN(fxn_io_create, io_create); - STORE_FXN(fxn_io_destroy, io_destroy); - STORE_FXN(fxn_io_onloaded, io_on_loaded); - STORE_FXN(fxn_io_getprocload, io_get_proc_load); - STORE_FXN(fxn_msg_create, msg_create); - STORE_FXN(fxn_msg_createqueue, msg_create_queue); - STORE_FXN(fxn_msg_delete, msg_delete); - STORE_FXN(fxn_msg_deletequeue, msg_delete_queue); - STORE_FXN(fxn_msg_get, msg_get); - STORE_FXN(fxn_msg_put, msg_put); - STORE_FXN(fxn_msg_registernotify, msg_register_notify); - STORE_FXN(fxn_msg_setqueueid, msg_set_queue_id); - } - /* Add code for any additional functions in newerBridge versions here */ -#undef STORE_FXN -} diff --git a/drivers/staging/tidspbridge/pmgr/dmm.c b/drivers/staging/tidspbridge/pmgr/dmm.c deleted file mode 100644 index fcf564aa566d..000000000000 --- a/drivers/staging/tidspbridge/pmgr/dmm.c +++ /dev/null @@ -1,487 +0,0 @@ -/* - * dmm.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * The Dynamic Memory Manager (DMM) module manages the DSP Virtual address - * space that can be directly mapped to any MPU buffer or memory region - * - * Notes: - * Region: Generic memory entitiy having a start address and a size - * Chunk: Reserved region - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ -#include <linux/types.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- OS Adaptation Layer */ -#include <dspbridge/sync.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/dev.h> -#include <dspbridge/proc.h> - -/* ----------------------------------- This */ -#include <dspbridge/dmm.h> - -/* ----------------------------------- Defines, Data Structures, Typedefs */ -#define DMM_ADDR_VIRTUAL(a) \ - (((struct map_page *)(a) - virtual_mapping_table) * PG_SIZE4K +\ - dyn_mem_map_beg) -#define DMM_ADDR_TO_INDEX(a) (((a) - dyn_mem_map_beg) / PG_SIZE4K) - -/* DMM Mgr */ -struct dmm_object { - /* Dmm Lock is used to serialize access mem manager for - * multi-threads. */ - spinlock_t dmm_lock; /* Lock to access dmm mgr */ -}; - -struct map_page { - u32 region_size:15; - u32 mapped_size:15; - u32 reserved:1; - u32 mapped:1; -}; - -/* Create the free list */ -static struct map_page *virtual_mapping_table; -static u32 free_region; /* The index of free region */ -static u32 free_size; -static u32 dyn_mem_map_beg; /* The Beginning of dynamic memory mapping */ -static u32 table_size; /* The size of virt and phys pages tables */ - -/* ----------------------------------- Function Prototypes */ -static struct map_page *get_region(u32 addr); -static struct map_page *get_free_region(u32 len); -static struct map_page *get_mapped_region(u32 addrs); - -/* ======== dmm_create_tables ======== - * Purpose: - * Create table to hold the information of physical address - * the buffer pages that is passed by the user, and the table - * to hold the information of the virtual memory that is reserved - * for DSP. - */ -int dmm_create_tables(struct dmm_object *dmm_mgr, u32 addr, u32 size) -{ - struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; - int status = 0; - - status = dmm_delete_tables(dmm_obj); - if (!status) { - dyn_mem_map_beg = addr; - table_size = PG_ALIGN_HIGH(size, PG_SIZE4K) / PG_SIZE4K; - /* Create the free list */ - virtual_mapping_table = __vmalloc(table_size * - sizeof(struct map_page), GFP_KERNEL | - __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL); - if (virtual_mapping_table == NULL) - status = -ENOMEM; - else { - /* On successful allocation, - * all entries are zero ('free') */ - free_region = 0; - free_size = table_size * PG_SIZE4K; - virtual_mapping_table[0].region_size = table_size; - } - } - - if (status) - pr_err("%s: failure, status 0x%x\n", __func__, status); - - return status; -} - -/* - * ======== dmm_create ======== - * Purpose: - * Create a dynamic memory manager object. - */ -int dmm_create(struct dmm_object **dmm_manager, - struct dev_object *hdev_obj, - const struct dmm_mgrattrs *mgr_attrts) -{ - struct dmm_object *dmm_obj = NULL; - int status = 0; - - *dmm_manager = NULL; - /* create, zero, and tag a cmm mgr object */ - dmm_obj = kzalloc(sizeof(struct dmm_object), GFP_KERNEL); - if (dmm_obj != NULL) { - spin_lock_init(&dmm_obj->dmm_lock); - *dmm_manager = dmm_obj; - } else { - status = -ENOMEM; - } - - return status; -} - -/* - * ======== dmm_destroy ======== - * Purpose: - * Release the communication memory manager resources. - */ -int dmm_destroy(struct dmm_object *dmm_mgr) -{ - struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; - int status = 0; - - if (dmm_mgr) { - status = dmm_delete_tables(dmm_obj); - if (!status) - kfree(dmm_obj); - } else - status = -EFAULT; - - return status; -} - -/* - * ======== dmm_delete_tables ======== - * Purpose: - * Delete DMM Tables. - */ -int dmm_delete_tables(struct dmm_object *dmm_mgr) -{ - int status = 0; - - /* Delete all DMM tables */ - if (dmm_mgr) - vfree(virtual_mapping_table); - else - status = -EFAULT; - return status; -} - -/* - * ======== dmm_get_handle ======== - * Purpose: - * Return the dynamic memory manager object for this device. - * This is typically called from the client process. - */ -int dmm_get_handle(void *hprocessor, struct dmm_object **dmm_manager) -{ - int status = 0; - struct dev_object *hdev_obj; - - if (hprocessor != NULL) - status = proc_get_dev_object(hprocessor, &hdev_obj); - else - hdev_obj = dev_get_first(); /* default */ - - if (!status) - status = dev_get_dmm_mgr(hdev_obj, dmm_manager); - - return status; -} - -/* - * ======== dmm_map_memory ======== - * Purpose: - * Add a mapping block to the reserved chunk. DMM assumes that this block - * will be mapped in the DSP/IVA's address space. DMM returns an error if a - * mapping overlaps another one. This function stores the info that will be - * required later while unmapping the block. - */ -int dmm_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 size) -{ - struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; - struct map_page *chunk; - int status = 0; - - spin_lock(&dmm_obj->dmm_lock); - /* Find the Reserved memory chunk containing the DSP block to - * be mapped */ - chunk = (struct map_page *)get_region(addr); - if (chunk != NULL) { - /* Mark the region 'mapped', leave the 'reserved' info as-is */ - chunk->mapped = true; - chunk->mapped_size = (size / PG_SIZE4K); - } else - status = -ENOENT; - spin_unlock(&dmm_obj->dmm_lock); - - dev_dbg(bridge, "%s dmm_mgr %p, addr %x, size %x\n\tstatus %x, chunk %p", - __func__, dmm_mgr, addr, size, status, chunk); - - return status; -} - -/* - * ======== dmm_reserve_memory ======== - * Purpose: - * Reserve a chunk of virtually contiguous DSP/IVA address space. - */ -int dmm_reserve_memory(struct dmm_object *dmm_mgr, u32 size, - u32 *prsv_addr) -{ - int status = 0; - struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; - struct map_page *node; - u32 rsv_addr = 0; - u32 rsv_size = 0; - - spin_lock(&dmm_obj->dmm_lock); - - /* Try to get a DSP chunk from the free list */ - node = get_free_region(size); - if (node != NULL) { - /* DSP chunk of given size is available. */ - rsv_addr = DMM_ADDR_VIRTUAL(node); - /* Calculate the number entries to use */ - rsv_size = size / PG_SIZE4K; - if (rsv_size < node->region_size) { - /* Mark remainder of free region */ - node[rsv_size].mapped = false; - node[rsv_size].reserved = false; - node[rsv_size].region_size = - node->region_size - rsv_size; - node[rsv_size].mapped_size = 0; - } - /* get_region will return first fit chunk. But we only use what - is requested. */ - node->mapped = false; - node->reserved = true; - node->region_size = rsv_size; - node->mapped_size = 0; - /* Return the chunk's starting address */ - *prsv_addr = rsv_addr; - } else - /*dSP chunk of given size is not available */ - status = -ENOMEM; - - spin_unlock(&dmm_obj->dmm_lock); - - dev_dbg(bridge, "%s dmm_mgr %p, size %x, prsv_addr %p\n\tstatus %x, rsv_addr %x, rsv_size %x\n", - __func__, dmm_mgr, size, - prsv_addr, status, rsv_addr, rsv_size); - - return status; -} - -/* - * ======== dmm_un_map_memory ======== - * Purpose: - * Remove the mapped block from the reserved chunk. - */ -int dmm_un_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 *psize) -{ - struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; - struct map_page *chunk; - int status = 0; - - spin_lock(&dmm_obj->dmm_lock); - chunk = get_mapped_region(addr); - if (chunk == NULL) - status = -ENOENT; - - if (!status) { - /* Unmap the region */ - *psize = chunk->mapped_size * PG_SIZE4K; - chunk->mapped = false; - chunk->mapped_size = 0; - } - spin_unlock(&dmm_obj->dmm_lock); - - dev_dbg(bridge, "%s: dmm_mgr %p, addr %x, psize %p\n\tstatus %x, chunk %p\n", - __func__, dmm_mgr, addr, psize, status, chunk); - - return status; -} - -/* - * ======== dmm_un_reserve_memory ======== - * Purpose: - * Free a chunk of reserved DSP/IVA address space. - */ -int dmm_un_reserve_memory(struct dmm_object *dmm_mgr, u32 rsv_addr) -{ - struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; - struct map_page *chunk; - u32 i; - int status = 0; - u32 chunk_size; - - spin_lock(&dmm_obj->dmm_lock); - - /* Find the chunk containing the reserved address */ - chunk = get_mapped_region(rsv_addr); - if (chunk == NULL) - status = -ENOENT; - - if (!status) { - /* Free all the mapped pages for this reserved region */ - i = 0; - while (i < chunk->region_size) { - if (chunk[i].mapped) { - /* Remove mapping from the page tables. */ - chunk_size = chunk[i].mapped_size; - /* Clear the mapping flags */ - chunk[i].mapped = false; - chunk[i].mapped_size = 0; - i += chunk_size; - } else - i++; - } - /* Clear the flags (mark the region 'free') */ - chunk->reserved = false; - /* NOTE: We do NOT coalesce free regions here. - * Free regions are coalesced in get_region(), as it traverses - *the whole mapping table - */ - } - spin_unlock(&dmm_obj->dmm_lock); - - dev_dbg(bridge, "%s: dmm_mgr %p, rsv_addr %x\n\tstatus %x chunk %p", - __func__, dmm_mgr, rsv_addr, status, chunk); - - return status; -} - -/* - * ======== get_region ======== - * Purpose: - * Returns a region containing the specified memory region - */ -static struct map_page *get_region(u32 addr) -{ - struct map_page *curr_region = NULL; - u32 i = 0; - - if (virtual_mapping_table != NULL) { - /* find page mapped by this address */ - i = DMM_ADDR_TO_INDEX(addr); - if (i < table_size) - curr_region = virtual_mapping_table + i; - } - - dev_dbg(bridge, "%s: curr_region %p, free_region %d, free_size %d\n", - __func__, curr_region, free_region, free_size); - return curr_region; -} - -/* - * ======== get_free_region ======== - * Purpose: - * Returns the requested free region - */ -static struct map_page *get_free_region(u32 len) -{ - struct map_page *curr_region = NULL; - u32 i = 0; - u32 region_size = 0; - u32 next_i = 0; - - if (virtual_mapping_table == NULL) - return curr_region; - if (len > free_size) { - /* Find the largest free region - * (coalesce during the traversal) */ - while (i < table_size) { - region_size = virtual_mapping_table[i].region_size; - next_i = i + region_size; - if (virtual_mapping_table[i].reserved == false) { - /* Coalesce, if possible */ - if (next_i < table_size && - virtual_mapping_table[next_i].reserved - == false) { - virtual_mapping_table[i].region_size += - virtual_mapping_table - [next_i].region_size; - continue; - } - region_size *= PG_SIZE4K; - if (region_size > free_size) { - free_region = i; - free_size = region_size; - } - } - i = next_i; - } - } - if (len <= free_size) { - curr_region = virtual_mapping_table + free_region; - free_region += (len / PG_SIZE4K); - free_size -= len; - } - return curr_region; -} - -/* - * ======== get_mapped_region ======== - * Purpose: - * Returns the requestedmapped region - */ -static struct map_page *get_mapped_region(u32 addrs) -{ - u32 i = 0; - struct map_page *curr_region = NULL; - - if (virtual_mapping_table == NULL) - return curr_region; - - i = DMM_ADDR_TO_INDEX(addrs); - if (i < table_size && (virtual_mapping_table[i].mapped || - virtual_mapping_table[i].reserved)) - curr_region = virtual_mapping_table + i; - return curr_region; -} - -#ifdef DSP_DMM_DEBUG -u32 dmm_mem_map_dump(struct dmm_object *dmm_mgr) -{ - struct map_page *curr_node = NULL; - u32 i; - u32 freemem = 0; - u32 bigsize = 0; - - spin_lock(&dmm_mgr->dmm_lock); - - if (virtual_mapping_table != NULL) { - for (i = 0; i < table_size; i += - virtual_mapping_table[i].region_size) { - curr_node = virtual_mapping_table + i; - if (curr_node->reserved) { - /*printk("RESERVED size = 0x%x, " - "Map size = 0x%x\n", - (curr_node->region_size * PG_SIZE4K), - (curr_node->mapped == false) ? 0 : - (curr_node->mapped_size * PG_SIZE4K)); - */ - } else { -/* printk("UNRESERVED size = 0x%x\n", - (curr_node->region_size * PG_SIZE4K)); - */ - freemem += (curr_node->region_size * PG_SIZE4K); - if (curr_node->region_size > bigsize) - bigsize = curr_node->region_size; - } - } - } - spin_unlock(&dmm_mgr->dmm_lock); - dev_info(bridge, "Total DSP VA FREE memory = %d Mbytes\n", - freemem / (1024 * 1024)); - dev_info(bridge, "Total DSP VA USED memory= %d Mbytes\n", - (((table_size * PG_SIZE4K) - freemem)) / (1024 * 1024)); - dev_info(bridge, "DSP VA - Biggest FREE block = %d Mbytes\n", - (bigsize * PG_SIZE4K / (1024 * 1024))); - - return 0; -} -#endif diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c deleted file mode 100644 index b7d5c8cbb2a1..000000000000 --- a/drivers/staging/tidspbridge/pmgr/dspapi.c +++ /dev/null @@ -1,1843 +0,0 @@ -/* - * dspapi.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Common DSP API functions, also includes the wrapper - * functions called directly by the DeviceIOControl interface. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ -#include <linux/types.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- OS Adaptation Layer */ -#include <dspbridge/ntfy.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/chnl.h> -#include <dspbridge/dev.h> -#include <dspbridge/drv.h> - -#include <dspbridge/proc.h> -#include <dspbridge/strm.h> - -/* ----------------------------------- Resource Manager */ -#include <dspbridge/disp.h> -#include <dspbridge/mgr.h> -#include <dspbridge/node.h> -#include <dspbridge/rmm.h> - -/* ----------------------------------- Others */ -#include <dspbridge/msg.h> -#include <dspbridge/cmm.h> -#include <dspbridge/io.h> - -/* ----------------------------------- This */ -#include <dspbridge/dspapi.h> -#include <dspbridge/dbdcd.h> - -#include <dspbridge/resourcecleanup.h> - -/* ----------------------------------- Defines, Data Structures, Typedefs */ -#define MAX_TRACEBUFLEN 255 -#define MAX_LOADARGS 16 -#define MAX_NODES 64 -#define MAX_STREAMS 16 -#define MAX_BUFS 64 - -/* Used to get dspbridge ioctl table */ -#define DB_GET_IOC_TABLE(cmd) (DB_GET_MODULE(cmd) >> DB_MODULE_SHIFT) - -/* Device IOCtl function pointer */ -struct api_cmd { - u32(*fxn) (union trapped_args *args, void *pr_ctxt); - u32 index; -}; - -/* ----------------------------------- Globals */ -static u32 api_c_refs; - -/* - * Function tables. - * The order of these functions MUST be the same as the order of the command - * numbers defined in dspapi-ioctl.h This is how an IOCTL number in user mode - * turns into a function call in kernel mode. - */ - -/* MGR wrapper functions */ -static struct api_cmd mgr_cmd[] = { - {mgrwrap_enum_node_info}, /* MGR_ENUMNODE_INFO */ - {mgrwrap_enum_proc_info}, /* MGR_ENUMPROC_INFO */ - {mgrwrap_register_object}, /* MGR_REGISTEROBJECT */ - {mgrwrap_unregister_object}, /* MGR_UNREGISTEROBJECT */ - {mgrwrap_wait_for_bridge_events}, /* MGR_WAIT */ - {mgrwrap_get_process_resources_info}, /* MGR_GET_PROC_RES */ -}; - -/* PROC wrapper functions */ -static struct api_cmd proc_cmd[] = { - {procwrap_attach}, /* PROC_ATTACH */ - {procwrap_ctrl}, /* PROC_CTRL */ - {procwrap_detach}, /* PROC_DETACH */ - {procwrap_enum_node_info}, /* PROC_ENUMNODE */ - {procwrap_enum_resources}, /* PROC_ENUMRESOURCES */ - {procwrap_get_state}, /* PROC_GET_STATE */ - {procwrap_get_trace}, /* PROC_GET_TRACE */ - {procwrap_load}, /* PROC_LOAD */ - {procwrap_register_notify}, /* PROC_REGISTERNOTIFY */ - {procwrap_start}, /* PROC_START */ - {procwrap_reserve_memory}, /* PROC_RSVMEM */ - {procwrap_un_reserve_memory}, /* PROC_UNRSVMEM */ - {procwrap_map}, /* PROC_MAPMEM */ - {procwrap_un_map}, /* PROC_UNMAPMEM */ - {procwrap_flush_memory}, /* PROC_FLUSHMEMORY */ - {procwrap_stop}, /* PROC_STOP */ - {procwrap_invalidate_memory}, /* PROC_INVALIDATEMEMORY */ - {procwrap_begin_dma}, /* PROC_BEGINDMA */ - {procwrap_end_dma}, /* PROC_ENDDMA */ -}; - -/* NODE wrapper functions */ -static struct api_cmd node_cmd[] = { - {nodewrap_allocate}, /* NODE_ALLOCATE */ - {nodewrap_alloc_msg_buf}, /* NODE_ALLOCMSGBUF */ - {nodewrap_change_priority}, /* NODE_CHANGEPRIORITY */ - {nodewrap_connect}, /* NODE_CONNECT */ - {nodewrap_create}, /* NODE_CREATE */ - {nodewrap_delete}, /* NODE_DELETE */ - {nodewrap_free_msg_buf}, /* NODE_FREEMSGBUF */ - {nodewrap_get_attr}, /* NODE_GETATTR */ - {nodewrap_get_message}, /* NODE_GETMESSAGE */ - {nodewrap_pause}, /* NODE_PAUSE */ - {nodewrap_put_message}, /* NODE_PUTMESSAGE */ - {nodewrap_register_notify}, /* NODE_REGISTERNOTIFY */ - {nodewrap_run}, /* NODE_RUN */ - {nodewrap_terminate}, /* NODE_TERMINATE */ - {nodewrap_get_uuid_props}, /* NODE_GETUUIDPROPS */ -}; - -/* STRM wrapper functions */ -static struct api_cmd strm_cmd[] = { - {strmwrap_allocate_buffer}, /* STRM_ALLOCATEBUFFER */ - {strmwrap_close}, /* STRM_CLOSE */ - {strmwrap_free_buffer}, /* STRM_FREEBUFFER */ - {strmwrap_get_event_handle}, /* STRM_GETEVENTHANDLE */ - {strmwrap_get_info}, /* STRM_GETINFO */ - {strmwrap_idle}, /* STRM_IDLE */ - {strmwrap_issue}, /* STRM_ISSUE */ - {strmwrap_open}, /* STRM_OPEN */ - {strmwrap_reclaim}, /* STRM_RECLAIM */ - {strmwrap_register_notify}, /* STRM_REGISTERNOTIFY */ - {strmwrap_select}, /* STRM_SELECT */ -}; - -/* CMM wrapper functions */ -static struct api_cmd cmm_cmd[] = { - {cmmwrap_calloc_buf}, /* CMM_ALLOCBUF */ - {cmmwrap_free_buf}, /* CMM_FREEBUF */ - {cmmwrap_get_handle}, /* CMM_GETHANDLE */ - {cmmwrap_get_info}, /* CMM_GETINFO */ -}; - -/* Array used to store ioctl table sizes. It can hold up to 8 entries */ -static u8 size_cmd[] = { - ARRAY_SIZE(mgr_cmd), - ARRAY_SIZE(proc_cmd), - ARRAY_SIZE(node_cmd), - ARRAY_SIZE(strm_cmd), - ARRAY_SIZE(cmm_cmd), -}; - -static inline void _cp_fm_usr(void *to, const void __user *from, - int *err, unsigned long bytes) -{ - if (*err) - return; - - if (unlikely(!from)) { - *err = -EFAULT; - return; - } - - if (unlikely(copy_from_user(to, from, bytes))) - *err = -EFAULT; -} - -#define CP_FM_USR(to, from, err, n) \ - _cp_fm_usr(to, from, &(err), (n) * sizeof(*(to))) - -static inline void _cp_to_usr(void __user *to, const void *from, - int *err, unsigned long bytes) -{ - if (*err) - return; - - if (unlikely(!to)) { - *err = -EFAULT; - return; - } - - if (unlikely(copy_to_user(to, from, bytes))) - *err = -EFAULT; -} - -#define CP_TO_USR(to, from, err, n) \ - _cp_to_usr(to, from, &(err), (n) * sizeof(*(from))) - -/* - * ======== api_call_dev_ioctl ======== - * Purpose: - * Call the (wrapper) function for the corresponding API IOCTL. - */ -inline int api_call_dev_ioctl(u32 cmd, union trapped_args *args, - u32 *result, void *pr_ctxt) -{ - u32(*ioctl_cmd) (union trapped_args *args, void *pr_ctxt) = NULL; - int i; - - if (_IOC_TYPE(cmd) != DB) { - pr_err("%s: Incompatible dspbridge ioctl number\n", __func__); - goto err; - } - - if (DB_GET_IOC_TABLE(cmd) > ARRAY_SIZE(size_cmd)) { - pr_err("%s: undefined ioctl module\n", __func__); - goto err; - } - - /* Check the size of the required cmd table */ - i = DB_GET_IOC(cmd); - if (i > size_cmd[DB_GET_IOC_TABLE(cmd)]) { - pr_err("%s: requested ioctl %d out of bounds for table %d\n", - __func__, i, DB_GET_IOC_TABLE(cmd)); - goto err; - } - - switch (DB_GET_MODULE(cmd)) { - case DB_MGR: - ioctl_cmd = mgr_cmd[i].fxn; - break; - case DB_PROC: - ioctl_cmd = proc_cmd[i].fxn; - break; - case DB_NODE: - ioctl_cmd = node_cmd[i].fxn; - break; - case DB_STRM: - ioctl_cmd = strm_cmd[i].fxn; - break; - case DB_CMM: - ioctl_cmd = cmm_cmd[i].fxn; - break; - } - - if (!ioctl_cmd) { - pr_err("%s: requested ioctl not defined\n", __func__); - goto err; - } else { - *result = (*ioctl_cmd) (args, pr_ctxt); - } - - return 0; - -err: - return -EINVAL; -} - -/* - * ======== api_exit ======== - */ -void api_exit(void) -{ - api_c_refs--; - - if (api_c_refs == 0) - mgr_exit(); -} - -/* - * ======== api_init ======== - * Purpose: - * Module initialization used by Bridge API. - */ -bool api_init(void) -{ - bool ret = true; - - if (api_c_refs == 0) - ret = mgr_init(); - - if (ret) - api_c_refs++; - - return ret; -} - -/* - * ======== api_init_complete2 ======== - * Purpose: - * Perform any required bridge initialization which cannot - * be performed in api_init() or dev_start_device() due - * to the fact that some services are not yet - * completely initialized. - * Parameters: - * Returns: - * 0: Allow this device to load - * -EPERM: Failure. - * Requires: - * Bridge API initialized. - * Ensures: - */ -int api_init_complete2(void) -{ - int status = 0; - struct cfg_devnode *dev_node; - struct dev_object *hdev_obj; - struct drv_data *drv_datap; - u8 dev_type; - - /* Walk the list of DevObjects, get each devnode, and attempting to - * autostart the board. Note that this requires COF loading, which - * requires KFILE. */ - for (hdev_obj = dev_get_first(); hdev_obj != NULL; - hdev_obj = dev_get_next(hdev_obj)) { - if (dev_get_dev_node(hdev_obj, &dev_node)) - continue; - - if (dev_get_dev_type(hdev_obj, &dev_type)) - continue; - - if ((dev_type == DSP_UNIT) || (dev_type == IVA_UNIT)) { - drv_datap = dev_get_drvdata(bridge); - - if (drv_datap && drv_datap->base_img) - proc_auto_start(dev_node, hdev_obj); - } - } - - return status; -} - -/* TODO: Remove deprecated and not implemented ioctl wrappers */ - -/* - * ======== mgrwrap_enum_node_info ======== - */ -u32 mgrwrap_enum_node_info(union trapped_args *args, void *pr_ctxt) -{ - u8 *pndb_props; - u32 num_nodes; - int status = 0; - u32 size = args->args_mgr_enumnode_info.ndb_props_size; - - if (size < sizeof(struct dsp_ndbprops)) - return -EINVAL; - - pndb_props = kmalloc(size, GFP_KERNEL); - if (pndb_props == NULL) - status = -ENOMEM; - - if (!status) { - status = - mgr_enum_node_info(args->args_mgr_enumnode_info.node_id, - (struct dsp_ndbprops *)pndb_props, size, - &num_nodes); - } - CP_TO_USR(args->args_mgr_enumnode_info.ndb_props, pndb_props, status, - size); - CP_TO_USR(args->args_mgr_enumnode_info.num_nodes, &num_nodes, status, - 1); - kfree(pndb_props); - - return status; -} - -/* - * ======== mgrwrap_enum_proc_info ======== - */ -u32 mgrwrap_enum_proc_info(union trapped_args *args, void *pr_ctxt) -{ - u8 *processor_info; - u8 num_procs; - int status = 0; - u32 size = args->args_mgr_enumproc_info.processor_info_size; - - if (size < sizeof(struct dsp_processorinfo)) - return -EINVAL; - - processor_info = kmalloc(size, GFP_KERNEL); - if (processor_info == NULL) - status = -ENOMEM; - - if (!status) { - status = - mgr_enum_processor_info(args->args_mgr_enumproc_info. - processor_id, - (struct dsp_processorinfo *) - processor_info, size, &num_procs); - } - CP_TO_USR(args->args_mgr_enumproc_info.processor_info, processor_info, - status, size); - CP_TO_USR(args->args_mgr_enumproc_info.num_procs, &num_procs, - status, 1); - kfree(processor_info); - - return status; -} - -#define WRAP_MAP2CALLER(x) x -/* - * ======== mgrwrap_register_object ======== - */ -u32 mgrwrap_register_object(union trapped_args *args, void *pr_ctxt) -{ - u32 ret; - struct dsp_uuid uuid_obj; - u32 path_size = 0; - char *psz_path_name = NULL; - int status = 0; - - CP_FM_USR(&uuid_obj, args->args_mgr_registerobject.uuid_obj, status, 1); - if (status) - goto func_end; - path_size = strlen_user((char *) - args->args_mgr_registerobject.sz_path_name); - if (!path_size) { - status = -EINVAL; - goto func_end; - } - - psz_path_name = kmalloc(path_size, GFP_KERNEL); - if (!psz_path_name) { - status = -ENOMEM; - goto func_end; - } - ret = strncpy_from_user(psz_path_name, - (char *)args->args_mgr_registerobject. - sz_path_name, path_size); - if (!ret) { - status = -EFAULT; - goto func_end; - } - - if (args->args_mgr_registerobject.obj_type >= DSP_DCDMAXOBJTYPE) { - status = -EINVAL; - goto func_end; - } - - status = dcd_register_object(&uuid_obj, - args->args_mgr_registerobject.obj_type, - (char *)psz_path_name); -func_end: - kfree(psz_path_name); - return status; -} - -/* - * ======== mgrwrap_unregister_object ======== - */ -u32 mgrwrap_unregister_object(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_uuid uuid_obj; - - CP_FM_USR(&uuid_obj, args->args_mgr_registerobject.uuid_obj, status, 1); - if (status) - goto func_end; - - status = dcd_unregister_object(&uuid_obj, - args->args_mgr_unregisterobject. - obj_type); -func_end: - return status; - -} - -/* - * ======== mgrwrap_wait_for_bridge_events ======== - */ -u32 mgrwrap_wait_for_bridge_events(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_notification *anotifications[MAX_EVENTS]; - struct dsp_notification notifications[MAX_EVENTS]; - u32 index, i; - u32 count = args->args_mgr_wait.count; - - if (count > MAX_EVENTS) - status = -EINVAL; - - /* get the array of pointers to user structures */ - CP_FM_USR(anotifications, args->args_mgr_wait.anotifications, - status, count); - /* get the events */ - for (i = 0; i < count; i++) { - CP_FM_USR(¬ifications[i], anotifications[i], status, 1); - if (status || !notifications[i].handle) { - status = -EINVAL; - break; - } - /* set the array of pointers to kernel structures */ - anotifications[i] = ¬ifications[i]; - } - if (!status) { - status = mgr_wait_for_bridge_events(anotifications, count, - &index, - args->args_mgr_wait. - timeout); - } - CP_TO_USR(args->args_mgr_wait.index, &index, status, 1); - return status; -} - -/* - * ======== MGRWRAP_GetProcessResourceInfo ======== - */ -u32 __deprecated mgrwrap_get_process_resources_info(union trapped_args *args, - void *pr_ctxt) -{ - pr_err("%s: deprecated dspbridge ioctl\n", __func__); - return 0; -} - -/* - * ======== procwrap_attach ======== - */ -u32 procwrap_attach(union trapped_args *args, void *pr_ctxt) -{ - void *processor; - int status = 0; - struct dsp_processorattrin proc_attr_in, *attr_in = NULL; - - /* Optional argument */ - if (args->args_proc_attach.attr_in) { - CP_FM_USR(&proc_attr_in, args->args_proc_attach.attr_in, status, - 1); - if (!status) - attr_in = &proc_attr_in; - else - goto func_end; - - } - status = proc_attach(args->args_proc_attach.processor_id, attr_in, - &processor, pr_ctxt); - CP_TO_USR(args->args_proc_attach.ph_processor, &processor, status, 1); -func_end: - return status; -} - -/* - * ======== procwrap_ctrl ======== - */ -u32 procwrap_ctrl(union trapped_args *args, void *pr_ctxt) -{ - u32 cb_data_size, __user * psize = (u32 __user *) - args->args_proc_ctrl.args; - u8 *pargs = NULL; - int status = 0; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - if (psize) { - if (get_user(cb_data_size, psize)) { - status = -EPERM; - goto func_end; - } - cb_data_size += sizeof(u32); - pargs = kmalloc(cb_data_size, GFP_KERNEL); - if (pargs == NULL) { - status = -ENOMEM; - goto func_end; - } - - CP_FM_USR(pargs, args->args_proc_ctrl.args, status, - cb_data_size); - } - if (!status) { - status = proc_ctrl(hprocessor, - args->args_proc_ctrl.cmd, - (struct dsp_cbdata *)pargs); - } - - /* CP_TO_USR(args->args_proc_ctrl.args, pargs, status, 1); */ - kfree(pargs); -func_end: - return status; -} - -/* - * ======== procwrap_detach ======== - */ -u32 __deprecated procwrap_detach(union trapped_args *args, void *pr_ctxt) -{ - /* proc_detach called at bridge_release only */ - pr_err("%s: deprecated dspbridge ioctl\n", __func__); - return 0; -} - -/* - * ======== procwrap_enum_node_info ======== - */ -u32 procwrap_enum_node_info(union trapped_args *args, void *pr_ctxt) -{ - int status; - void *node_tab[MAX_NODES]; - u32 num_nodes; - u32 alloc_cnt; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - if (!args->args_proc_enumnode_info.node_tab_size) - return -EINVAL; - - status = proc_enum_nodes(hprocessor, - node_tab, - args->args_proc_enumnode_info.node_tab_size, - &num_nodes, &alloc_cnt); - CP_TO_USR(args->args_proc_enumnode_info.node_tab, node_tab, status, - num_nodes); - CP_TO_USR(args->args_proc_enumnode_info.num_nodes, &num_nodes, - status, 1); - CP_TO_USR(args->args_proc_enumnode_info.allocated, &alloc_cnt, - status, 1); - return status; -} - -u32 procwrap_end_dma(union trapped_args *args, void *pr_ctxt) -{ - int status; - - if (args->args_proc_dma.dir >= DMA_NONE) - return -EINVAL; - - status = proc_end_dma(pr_ctxt, - args->args_proc_dma.mpu_addr, - args->args_proc_dma.size, - args->args_proc_dma.dir); - return status; -} - -u32 procwrap_begin_dma(union trapped_args *args, void *pr_ctxt) -{ - int status; - - if (args->args_proc_dma.dir >= DMA_NONE) - return -EINVAL; - - status = proc_begin_dma(pr_ctxt, - args->args_proc_dma.mpu_addr, - args->args_proc_dma.size, - args->args_proc_dma.dir); - return status; -} - -/* - * ======== procwrap_flush_memory ======== - */ -u32 procwrap_flush_memory(union trapped_args *args, void *pr_ctxt) -{ - int status; - - if (args->args_proc_flushmemory.flags > - PROC_WRITEBACK_INVALIDATE_MEM) - return -EINVAL; - - status = proc_flush_memory(pr_ctxt, - args->args_proc_flushmemory.mpu_addr, - args->args_proc_flushmemory.size, - args->args_proc_flushmemory.flags); - return status; -} - -/* - * ======== procwrap_invalidate_memory ======== - */ -u32 procwrap_invalidate_memory(union trapped_args *args, void *pr_ctxt) -{ - int status; - - status = - proc_invalidate_memory(pr_ctxt, - args->args_proc_invalidatememory.mpu_addr, - args->args_proc_invalidatememory.size); - return status; -} - -/* - * ======== procwrap_enum_resources ======== - */ -u32 procwrap_enum_resources(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_resourceinfo resource_info; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - if (args->args_proc_enumresources.resource_info_size < - sizeof(struct dsp_resourceinfo)) - return -EINVAL; - - status = - proc_get_resource_info(hprocessor, - args->args_proc_enumresources.resource_type, - &resource_info, - args->args_proc_enumresources. - resource_info_size); - - CP_TO_USR(args->args_proc_enumresources.resource_info, &resource_info, - status, 1); - - return status; - -} - -/* - * ======== procwrap_get_state ======== - */ -u32 procwrap_get_state(union trapped_args *args, void *pr_ctxt) -{ - int status; - struct dsp_processorstate proc_state; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - if (args->args_proc_getstate.state_info_size < - sizeof(struct dsp_processorstate)) - return -EINVAL; - - status = proc_get_state(hprocessor, &proc_state, - args->args_proc_getstate.state_info_size); - CP_TO_USR(args->args_proc_getstate.proc_state_obj, &proc_state, status, - 1); - return status; - -} - -/* - * ======== procwrap_get_trace ======== - */ -u32 procwrap_get_trace(union trapped_args *args, void *pr_ctxt) -{ - int status; - u8 *pbuf; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - if (args->args_proc_gettrace.max_size > MAX_TRACEBUFLEN) - return -EINVAL; - - pbuf = kzalloc(args->args_proc_gettrace.max_size, GFP_KERNEL); - if (pbuf != NULL) { - status = proc_get_trace(hprocessor, pbuf, - args->args_proc_gettrace.max_size); - } else { - status = -ENOMEM; - } - CP_TO_USR(args->args_proc_gettrace.buf, pbuf, status, - args->args_proc_gettrace.max_size); - kfree(pbuf); - - return status; -} - -/* - * ======== procwrap_load ======== - */ -u32 procwrap_load(union trapped_args *args, void *pr_ctxt) -{ - s32 i, len; - int status = 0; - char *temp; - s32 count = args->args_proc_load.argc_index; - u8 **argv = NULL, **envp = NULL; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - if (count <= 0 || count > MAX_LOADARGS) { - status = -EINVAL; - goto func_cont; - } - - argv = kmalloc(count * sizeof(u8 *), GFP_KERNEL); - if (!argv) { - status = -ENOMEM; - goto func_cont; - } - - CP_FM_USR(argv, args->args_proc_load.user_args, status, count); - if (status) { - kfree(argv); - argv = NULL; - goto func_cont; - } - - for (i = 0; i < count; i++) { - if (argv[i]) { - /* User space pointer to argument */ - temp = (char *)argv[i]; - /* len is increased by 1 to accommodate NULL */ - len = strlen_user((char *)temp) + 1; - /* Kernel space pointer to argument */ - argv[i] = kmalloc(len, GFP_KERNEL); - if (argv[i]) { - CP_FM_USR(argv[i], temp, status, len); - if (status) { - kfree(argv[i]); - argv[i] = NULL; - goto func_cont; - } - } else { - status = -ENOMEM; - goto func_cont; - } - } - } - /* TODO: validate this */ - if (args->args_proc_load.user_envp) { - /* number of elements in the envp array including NULL */ - count = 0; - do { - if (get_user(temp, - args->args_proc_load.user_envp + count)) { - status = -EFAULT; - goto func_cont; - } - count++; - } while (temp); - envp = kmalloc(count * sizeof(u8 *), GFP_KERNEL); - if (!envp) { - status = -ENOMEM; - goto func_cont; - } - - CP_FM_USR(envp, args->args_proc_load.user_envp, status, count); - if (status) { - kfree(envp); - envp = NULL; - goto func_cont; - } - for (i = 0; envp[i]; i++) { - /* User space pointer to argument */ - temp = (char *)envp[i]; - /* len is increased by 1 to accommodate NULL */ - len = strlen_user((char *)temp) + 1; - /* Kernel space pointer to argument */ - envp[i] = kmalloc(len, GFP_KERNEL); - if (envp[i]) { - CP_FM_USR(envp[i], temp, status, len); - if (status) { - kfree(envp[i]); - envp[i] = NULL; - goto func_cont; - } - } else { - status = -ENOMEM; - goto func_cont; - } - } - } - - if (!status) { - status = proc_load(hprocessor, - args->args_proc_load.argc_index, - (const char **)argv, (const char **)envp); - } -func_cont: - if (envp) { - i = 0; - while (envp[i]) - kfree(envp[i++]); - - kfree(envp); - } - - if (argv) { - count = args->args_proc_load.argc_index; - for (i = 0; (i < count) && argv[i]; i++) - kfree(argv[i]); - - kfree(argv); - } - - return status; -} - -/* - * ======== procwrap_map ======== - */ -u32 procwrap_map(union trapped_args *args, void *pr_ctxt) -{ - int status; - void *map_addr; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - if (!args->args_proc_mapmem.size) - return -EINVAL; - - status = proc_map(args->args_proc_mapmem.processor, - args->args_proc_mapmem.mpu_addr, - args->args_proc_mapmem.size, - args->args_proc_mapmem.req_addr, &map_addr, - args->args_proc_mapmem.map_attr, pr_ctxt); - if (!status) { - if (put_user(map_addr, args->args_proc_mapmem.map_addr)) { - status = -EINVAL; - proc_un_map(hprocessor, map_addr, pr_ctxt); - } - - } - return status; -} - -/* - * ======== procwrap_register_notify ======== - */ -u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt) -{ - int status; - struct dsp_notification notification; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - /* Initialize the notification data structure */ - notification.name = NULL; - notification.handle = NULL; - - status = proc_register_notify(hprocessor, - args->args_proc_register_notify.event_mask, - args->args_proc_register_notify.notify_type, - ¬ification); - CP_TO_USR(args->args_proc_register_notify.notification, ¬ification, - status, 1); - return status; -} - -/* - * ======== procwrap_reserve_memory ======== - */ -u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt) -{ - int status; - void *prsv_addr; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - if ((args->args_proc_rsvmem.size <= 0) || - (args->args_proc_rsvmem.size & (PG_SIZE4K - 1)) != 0) - return -EINVAL; - - status = proc_reserve_memory(hprocessor, - args->args_proc_rsvmem.size, &prsv_addr, - pr_ctxt); - if (!status) { - if (put_user(prsv_addr, args->args_proc_rsvmem.rsv_addr)) { - status = -EINVAL; - proc_un_reserve_memory(args->args_proc_rsvmem. - processor, prsv_addr, pr_ctxt); - } - } - return status; -} - -/* - * ======== procwrap_start ======== - */ -u32 procwrap_start(union trapped_args *args, void *pr_ctxt) -{ - u32 ret; - - ret = proc_start(((struct process_context *)pr_ctxt)->processor); - return ret; -} - -/* - * ======== procwrap_un_map ======== - */ -u32 procwrap_un_map(union trapped_args *args, void *pr_ctxt) -{ - int status; - - status = proc_un_map(((struct process_context *)pr_ctxt)->processor, - args->args_proc_unmapmem.map_addr, pr_ctxt); - return status; -} - -/* - * ======== procwrap_un_reserve_memory ======== - */ -u32 procwrap_un_reserve_memory(union trapped_args *args, void *pr_ctxt) -{ - int status; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - status = proc_un_reserve_memory(hprocessor, - args->args_proc_unrsvmem.rsv_addr, - pr_ctxt); - return status; -} - -/* - * ======== procwrap_stop ======== - */ -u32 procwrap_stop(union trapped_args *args, void *pr_ctxt) -{ - u32 ret; - - ret = proc_stop(((struct process_context *)pr_ctxt)->processor); - - return ret; -} - -/* - * ======== find_handle ========= - */ -inline void find_node_handle(struct node_res_object **noderes, - void *pr_ctxt, void *hnode) -{ - rcu_read_lock(); - *noderes = idr_find(((struct process_context *)pr_ctxt)->node_id, - (int)hnode - 1); - rcu_read_unlock(); - return; -} - - -/* - * ======== nodewrap_allocate ======== - */ -u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_uuid node_uuid; - u32 cb_data_size = 0; - u32 __user *psize = (u32 __user *) args->args_node_allocate.args; - u8 *pargs = NULL; - struct dsp_nodeattrin proc_attr_in, *attr_in = NULL; - struct node_res_object *node_res; - int nodeid; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - /* Optional argument */ - if (psize) { - if (get_user(cb_data_size, psize)) - status = -EPERM; - - cb_data_size += sizeof(u32); - if (!status) { - pargs = kmalloc(cb_data_size, GFP_KERNEL); - if (pargs == NULL) - status = -ENOMEM; - - } - CP_FM_USR(pargs, args->args_node_allocate.args, status, - cb_data_size); - } - CP_FM_USR(&node_uuid, args->args_node_allocate.node_id_ptr, status, 1); - if (status) - goto func_cont; - /* Optional argument */ - if (args->args_node_allocate.attr_in) { - CP_FM_USR(&proc_attr_in, args->args_node_allocate.attr_in, - status, 1); - if (!status) - attr_in = &proc_attr_in; - else - status = -ENOMEM; - - } - if (!status) { - status = node_allocate(hprocessor, - &node_uuid, (struct dsp_cbdata *)pargs, - attr_in, &node_res, pr_ctxt); - } - if (!status) { - nodeid = node_res->id + 1; - CP_TO_USR(args->args_node_allocate.node, &nodeid, - status, 1); - if (status) { - status = -EFAULT; - node_delete(node_res, pr_ctxt); - } - } -func_cont: - kfree(pargs); - - return status; -} - -/* - * ======== nodewrap_alloc_msg_buf ======== - */ -u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_bufferattr *pattr = NULL; - struct dsp_bufferattr attr; - u8 *pbuffer = NULL; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, - args->args_node_allocmsgbuf.node); - - if (!node_res) - return -EFAULT; - - if (!args->args_node_allocmsgbuf.size) - return -EINVAL; - - if (args->args_node_allocmsgbuf.attr) { /* Optional argument */ - CP_FM_USR(&attr, args->args_node_allocmsgbuf.attr, status, 1); - if (!status) - pattr = &attr; - - } - /* argument */ - CP_FM_USR(&pbuffer, args->args_node_allocmsgbuf.buffer, status, 1); - if (!status) { - status = node_alloc_msg_buf(node_res->node, - args->args_node_allocmsgbuf.size, - pattr, &pbuffer); - } - CP_TO_USR(args->args_node_allocmsgbuf.buffer, &pbuffer, status, 1); - return status; -} - -/* - * ======== nodewrap_change_priority ======== - */ -u32 nodewrap_change_priority(union trapped_args *args, void *pr_ctxt) -{ - u32 ret; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, - args->args_node_changepriority.node); - - if (!node_res) - return -EFAULT; - - ret = node_change_priority(node_res->node, - args->args_node_changepriority.prio); - - return ret; -} - -/* - * ======== nodewrap_connect ======== - */ -u32 nodewrap_connect(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_strmattr attrs; - struct dsp_strmattr *pattrs = NULL; - u32 cb_data_size; - u32 __user *psize = (u32 __user *) args->args_node_connect.conn_param; - u8 *pargs = NULL; - struct node_res_object *node_res1, *node_res2; - struct node_object *node1 = NULL, *node2 = NULL; - - if ((int)args->args_node_connect.node != DSP_HGPPNODE) { - find_node_handle(&node_res1, pr_ctxt, - args->args_node_connect.node); - if (node_res1) - node1 = node_res1->node; - } else { - node1 = args->args_node_connect.node; - } - - if ((int)args->args_node_connect.other_node != DSP_HGPPNODE) { - find_node_handle(&node_res2, pr_ctxt, - args->args_node_connect.other_node); - if (node_res2) - node2 = node_res2->node; - } else { - node2 = args->args_node_connect.other_node; - } - - if (!node1 || !node2) - return -EFAULT; - - /* Optional argument */ - if (psize) { - if (get_user(cb_data_size, psize)) - status = -EPERM; - - cb_data_size += sizeof(u32); - if (!status) { - pargs = kmalloc(cb_data_size, GFP_KERNEL); - if (pargs == NULL) { - status = -ENOMEM; - goto func_cont; - } - - } - CP_FM_USR(pargs, args->args_node_connect.conn_param, status, - cb_data_size); - if (status) - goto func_cont; - } - if (args->args_node_connect.attrs) { /* Optional argument */ - CP_FM_USR(&attrs, args->args_node_connect.attrs, status, 1); - if (!status) - pattrs = &attrs; - - } - if (!status) { - status = node_connect(node1, - args->args_node_connect.stream_id, - node2, - args->args_node_connect.other_stream, - pattrs, (struct dsp_cbdata *)pargs); - } -func_cont: - kfree(pargs); - - return status; -} - -/* - * ======== nodewrap_create ======== - */ -u32 nodewrap_create(union trapped_args *args, void *pr_ctxt) -{ - u32 ret; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, args->args_node_create.node); - - if (!node_res) - return -EFAULT; - - ret = node_create(node_res->node); - - return ret; -} - -/* - * ======== nodewrap_delete ======== - */ -u32 nodewrap_delete(union trapped_args *args, void *pr_ctxt) -{ - u32 ret; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, args->args_node_delete.node); - - if (!node_res) - return -EFAULT; - - ret = node_delete(node_res, pr_ctxt); - - return ret; -} - -/* - * ======== nodewrap_free_msg_buf ======== - */ -u32 nodewrap_free_msg_buf(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_bufferattr *pattr = NULL; - struct dsp_bufferattr attr; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, args->args_node_freemsgbuf.node); - - if (!node_res) - return -EFAULT; - - if (args->args_node_freemsgbuf.attr) { /* Optional argument */ - CP_FM_USR(&attr, args->args_node_freemsgbuf.attr, status, 1); - if (!status) - pattr = &attr; - - } - - if (!args->args_node_freemsgbuf.buffer) - return -EFAULT; - - if (!status) { - status = node_free_msg_buf(node_res->node, - args->args_node_freemsgbuf.buffer, - pattr); - } - - return status; -} - -/* - * ======== nodewrap_get_attr ======== - */ -u32 nodewrap_get_attr(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_nodeattr attr; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, args->args_node_getattr.node); - - if (!node_res) - return -EFAULT; - - status = node_get_attr(node_res->node, &attr, - args->args_node_getattr.attr_size); - CP_TO_USR(args->args_node_getattr.attr, &attr, status, 1); - - return status; -} - -/* - * ======== nodewrap_get_message ======== - */ -u32 nodewrap_get_message(union trapped_args *args, void *pr_ctxt) -{ - int status; - struct dsp_msg msg; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, args->args_node_getmessage.node); - - if (!node_res) - return -EFAULT; - - status = node_get_message(node_res->node, &msg, - args->args_node_getmessage.timeout); - - CP_TO_USR(args->args_node_getmessage.message, &msg, status, 1); - - return status; -} - -/* - * ======== nodewrap_pause ======== - */ -u32 nodewrap_pause(union trapped_args *args, void *pr_ctxt) -{ - u32 ret; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, args->args_node_pause.node); - - if (!node_res) - return -EFAULT; - - ret = node_pause(node_res->node); - - return ret; -} - -/* - * ======== nodewrap_put_message ======== - */ -u32 nodewrap_put_message(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_msg msg; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, args->args_node_putmessage.node); - - if (!node_res) - return -EFAULT; - - CP_FM_USR(&msg, args->args_node_putmessage.message, status, 1); - - if (!status) { - status = - node_put_message(node_res->node, &msg, - args->args_node_putmessage.timeout); - } - - return status; -} - -/* - * ======== nodewrap_register_notify ======== - */ -u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_notification notification; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, - args->args_node_registernotify.node); - - if (!node_res) - return -EFAULT; - - /* Initialize the notification data structure */ - notification.name = NULL; - notification.handle = NULL; - - if (!args->args_proc_register_notify.event_mask) - CP_FM_USR(¬ification, - args->args_proc_register_notify.notification, - status, 1); - - status = node_register_notify(node_res->node, - args->args_node_registernotify.event_mask, - args->args_node_registernotify. - notify_type, ¬ification); - CP_TO_USR(args->args_node_registernotify.notification, ¬ification, - status, 1); - return status; -} - -/* - * ======== nodewrap_run ======== - */ -u32 nodewrap_run(union trapped_args *args, void *pr_ctxt) -{ - u32 ret; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, args->args_node_run.node); - - if (!node_res) - return -EFAULT; - - ret = node_run(node_res->node); - - return ret; -} - -/* - * ======== nodewrap_terminate ======== - */ -u32 nodewrap_terminate(union trapped_args *args, void *pr_ctxt) -{ - int status; - int tempstatus; - struct node_res_object *node_res; - - find_node_handle(&node_res, pr_ctxt, args->args_node_terminate.node); - - if (!node_res) - return -EFAULT; - - status = node_terminate(node_res->node, &tempstatus); - - CP_TO_USR(args->args_node_terminate.status, &tempstatus, status, 1); - - return status; -} - -/* - * ======== nodewrap_get_uuid_props ======== - */ -u32 nodewrap_get_uuid_props(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_uuid node_uuid; - struct dsp_ndbprops *pnode_props = NULL; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - CP_FM_USR(&node_uuid, args->args_node_getuuidprops.node_id_ptr, status, - 1); - if (status) - goto func_cont; - pnode_props = kmalloc(sizeof(struct dsp_ndbprops), GFP_KERNEL); - if (pnode_props != NULL) { - status = - node_get_uuid_props(hprocessor, &node_uuid, pnode_props); - CP_TO_USR(args->args_node_getuuidprops.node_props, pnode_props, - status, 1); - } else - status = -ENOMEM; -func_cont: - kfree(pnode_props); - return status; -} - -/* - * ======== find_strm_handle ========= - */ -inline void find_strm_handle(struct strm_res_object **strmres, - void *pr_ctxt, void *hstream) -{ - rcu_read_lock(); - *strmres = idr_find(((struct process_context *)pr_ctxt)->stream_id, - (int)hstream - 1); - rcu_read_unlock(); - return; -} - -/* - * ======== strmwrap_allocate_buffer ======== - */ -u32 strmwrap_allocate_buffer(union trapped_args *args, void *pr_ctxt) -{ - int status; - u8 **ap_buffer = NULL; - u32 num_bufs = args->args_strm_allocatebuffer.num_bufs; - struct strm_res_object *strm_res; - - find_strm_handle(&strm_res, pr_ctxt, - args->args_strm_allocatebuffer.stream); - - if (!strm_res) - return -EFAULT; - - if (num_bufs > MAX_BUFS) - return -EINVAL; - - ap_buffer = kmalloc((num_bufs * sizeof(u8 *)), GFP_KERNEL); - if (ap_buffer == NULL) - return -ENOMEM; - - status = strm_allocate_buffer(strm_res, - args->args_strm_allocatebuffer.size, - ap_buffer, num_bufs, pr_ctxt); - if (!status) { - CP_TO_USR(args->args_strm_allocatebuffer.ap_buffer, ap_buffer, - status, num_bufs); - if (status) { - status = -EFAULT; - strm_free_buffer(strm_res, - ap_buffer, num_bufs, pr_ctxt); - } - } - kfree(ap_buffer); - - return status; -} - -/* - * ======== strmwrap_close ======== - */ -u32 strmwrap_close(union trapped_args *args, void *pr_ctxt) -{ - struct strm_res_object *strm_res; - - find_strm_handle(&strm_res, pr_ctxt, args->args_strm_close.stream); - - if (!strm_res) - return -EFAULT; - - return strm_close(strm_res, pr_ctxt); -} - -/* - * ======== strmwrap_free_buffer ======== - */ -u32 strmwrap_free_buffer(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - u8 **ap_buffer = NULL; - u32 num_bufs = args->args_strm_freebuffer.num_bufs; - struct strm_res_object *strm_res; - - find_strm_handle(&strm_res, pr_ctxt, - args->args_strm_freebuffer.stream); - - if (!strm_res) - return -EFAULT; - - if (num_bufs > MAX_BUFS) - return -EINVAL; - - ap_buffer = kmalloc_array(num_bufs, sizeof(u8 *), GFP_KERNEL); - if (ap_buffer == NULL) - return -ENOMEM; - - CP_FM_USR(ap_buffer, args->args_strm_freebuffer.ap_buffer, status, - num_bufs); - - if (!status) - status = strm_free_buffer(strm_res, - ap_buffer, num_bufs, pr_ctxt); - - CP_TO_USR(args->args_strm_freebuffer.ap_buffer, ap_buffer, status, - num_bufs); - kfree(ap_buffer); - - return status; -} - -/* - * ======== strmwrap_get_event_handle ======== - */ -u32 __deprecated strmwrap_get_event_handle(union trapped_args *args, - void *pr_ctxt) -{ - pr_err("%s: deprecated dspbridge ioctl\n", __func__); - return -ENOSYS; -} - -/* - * ======== strmwrap_get_info ======== - */ -u32 strmwrap_get_info(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct stream_info strm_info; - struct dsp_streaminfo user; - struct dsp_streaminfo *temp; - struct strm_res_object *strm_res; - - find_strm_handle(&strm_res, pr_ctxt, - args->args_strm_getinfo.stream); - - if (!strm_res) - return -EFAULT; - - CP_FM_USR(&strm_info, args->args_strm_getinfo.stream_info, status, 1); - temp = strm_info.user_strm; - - strm_info.user_strm = &user; - - if (!status) { - status = strm_get_info(strm_res->stream, - &strm_info, - args->args_strm_getinfo. - stream_info_size); - } - CP_TO_USR(temp, strm_info.user_strm, status, 1); - strm_info.user_strm = temp; - CP_TO_USR(args->args_strm_getinfo.stream_info, &strm_info, status, 1); - return status; -} - -/* - * ======== strmwrap_idle ======== - */ -u32 strmwrap_idle(union trapped_args *args, void *pr_ctxt) -{ - u32 ret; - struct strm_res_object *strm_res; - - find_strm_handle(&strm_res, pr_ctxt, args->args_strm_idle.stream); - - if (!strm_res) - return -EFAULT; - - ret = strm_idle(strm_res->stream, args->args_strm_idle.flush_flag); - - return ret; -} - -/* - * ======== strmwrap_issue ======== - */ -u32 strmwrap_issue(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct strm_res_object *strm_res; - - find_strm_handle(&strm_res, pr_ctxt, args->args_strm_issue.stream); - - if (!strm_res) - return -EFAULT; - - if (!args->args_strm_issue.buffer) - return -EFAULT; - - /* No need of doing CP_FM_USR for the user buffer (pbuffer) - as this is done in Bridge internal function bridge_chnl_add_io_req - in chnl_sm.c */ - status = strm_issue(strm_res->stream, - args->args_strm_issue.buffer, - args->args_strm_issue.bytes, - args->args_strm_issue.buf_size, - args->args_strm_issue.arg); - - return status; -} - -/* - * ======== strmwrap_open ======== - */ -u32 strmwrap_open(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct strm_attr attr; - struct strm_res_object *strm_res_obj; - struct dsp_streamattrin strm_attr_in; - struct node_res_object *node_res; - int strmid; - - find_node_handle(&node_res, pr_ctxt, args->args_strm_open.node); - - if (!node_res) - return -EFAULT; - - CP_FM_USR(&attr, args->args_strm_open.attr_in, status, 1); - - if (attr.stream_attr_in != NULL) { /* Optional argument */ - CP_FM_USR(&strm_attr_in, attr.stream_attr_in, status, 1); - if (!status) { - attr.stream_attr_in = &strm_attr_in; - if (attr.stream_attr_in->strm_mode == STRMMODE_LDMA) - return -ENOSYS; - } - - } - status = strm_open(node_res->node, - args->args_strm_open.direction, - args->args_strm_open.index, &attr, &strm_res_obj, - pr_ctxt); - if (!status) { - strmid = strm_res_obj->id + 1; - CP_TO_USR(args->args_strm_open.stream, &strmid, status, 1); - } - return status; -} - -/* - * ======== strmwrap_reclaim ======== - */ -u32 strmwrap_reclaim(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - u8 *buf_ptr; - u32 ul_bytes; - u32 dw_arg; - u32 ul_buf_size; - struct strm_res_object *strm_res; - - find_strm_handle(&strm_res, pr_ctxt, args->args_strm_reclaim.stream); - - if (!strm_res) - return -EFAULT; - - status = strm_reclaim(strm_res->stream, &buf_ptr, - &ul_bytes, &ul_buf_size, &dw_arg); - CP_TO_USR(args->args_strm_reclaim.buf_ptr, &buf_ptr, status, 1); - CP_TO_USR(args->args_strm_reclaim.bytes, &ul_bytes, status, 1); - CP_TO_USR(args->args_strm_reclaim.arg, &dw_arg, status, 1); - - if (args->args_strm_reclaim.buf_size_ptr != NULL) { - CP_TO_USR(args->args_strm_reclaim.buf_size_ptr, &ul_buf_size, - status, 1); - } - - return status; -} - -/* - * ======== strmwrap_register_notify ======== - */ -u32 strmwrap_register_notify(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct dsp_notification notification; - struct strm_res_object *strm_res; - - find_strm_handle(&strm_res, pr_ctxt, - args->args_strm_registernotify.stream); - - if (!strm_res) - return -EFAULT; - - /* Initialize the notification data structure */ - notification.name = NULL; - notification.handle = NULL; - - status = strm_register_notify(strm_res->stream, - args->args_strm_registernotify.event_mask, - args->args_strm_registernotify. - notify_type, ¬ification); - CP_TO_USR(args->args_strm_registernotify.notification, ¬ification, - status, 1); - - return status; -} - -/* - * ======== strmwrap_select ======== - */ -u32 strmwrap_select(union trapped_args *args, void *pr_ctxt) -{ - u32 mask; - struct strm_object *strm_tab[MAX_STREAMS]; - int status = 0; - struct strm_res_object *strm_res; - int *ids[MAX_STREAMS]; - int i; - - if (args->args_strm_select.strm_num > MAX_STREAMS) - return -EINVAL; - - CP_FM_USR(ids, args->args_strm_select.stream_tab, status, - args->args_strm_select.strm_num); - - if (status) - return status; - - for (i = 0; i < args->args_strm_select.strm_num; i++) { - find_strm_handle(&strm_res, pr_ctxt, ids[i]); - - if (!strm_res) - return -EFAULT; - - strm_tab[i] = strm_res->stream; - } - - if (!status) { - status = strm_select(strm_tab, args->args_strm_select.strm_num, - &mask, args->args_strm_select.timeout); - } - CP_TO_USR(args->args_strm_select.mask, &mask, status, 1); - return status; -} - -/* CMM */ - -/* - * ======== cmmwrap_calloc_buf ======== - */ -u32 __deprecated cmmwrap_calloc_buf(union trapped_args *args, void *pr_ctxt) -{ - /* This operation is done in kernel */ - pr_err("%s: deprecated dspbridge ioctl\n", __func__); - return -ENOSYS; -} - -/* - * ======== cmmwrap_free_buf ======== - */ -u32 __deprecated cmmwrap_free_buf(union trapped_args *args, void *pr_ctxt) -{ - /* This operation is done in kernel */ - pr_err("%s: deprecated dspbridge ioctl\n", __func__); - return -ENOSYS; -} - -/* - * ======== cmmwrap_get_handle ======== - */ -u32 cmmwrap_get_handle(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct cmm_object *hcmm_mgr; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - status = cmm_get_handle(hprocessor, &hcmm_mgr); - - CP_TO_USR(args->args_cmm_gethandle.cmm_mgr, &hcmm_mgr, status, 1); - - return status; -} - -/* - * ======== cmmwrap_get_info ======== - */ -u32 cmmwrap_get_info(union trapped_args *args, void *pr_ctxt) -{ - int status = 0; - struct cmm_info cmm_info_obj; - - status = cmm_get_info(args->args_cmm_getinfo.cmm_mgr, &cmm_info_obj); - - CP_TO_USR(args->args_cmm_getinfo.cmm_info_obj, &cmm_info_obj, status, - 1); - - return status; -} diff --git a/drivers/staging/tidspbridge/pmgr/io.c b/drivers/staging/tidspbridge/pmgr/io.c deleted file mode 100644 index 4073c9c672fd..000000000000 --- a/drivers/staging/tidspbridge/pmgr/io.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * io.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * IO manager interface: Manages IO between CHNL and msg_ctrl. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ -#include <linux/types.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/dev.h> - -/* ----------------------------------- This */ -#include <ioobj.h> -#include <dspbridge/io.h> - -/* - * ======== io_create ======== - * Purpose: - * Create an IO manager object, responsible for managing IO between - * CHNL and msg_ctrl - */ -int io_create(struct io_mgr **io_man, struct dev_object *hdev_obj, - const struct io_attrs *mgr_attrts) -{ - struct bridge_drv_interface *intf_fxns; - struct io_mgr *hio_mgr = NULL; - struct io_mgr_ *pio_mgr = NULL; - int status = 0; - - *io_man = NULL; - - /* A memory base of 0 implies no memory base: */ - if ((mgr_attrts->shm_base != 0) && (mgr_attrts->sm_length == 0)) - status = -EINVAL; - - if (mgr_attrts->word_size == 0) - status = -EINVAL; - - if (!status) { - dev_get_intf_fxns(hdev_obj, &intf_fxns); - - /* Let Bridge channel module finish the create: */ - status = (*intf_fxns->io_create) (&hio_mgr, hdev_obj, - mgr_attrts); - - if (!status) { - pio_mgr = (struct io_mgr_ *)hio_mgr; - pio_mgr->intf_fxns = intf_fxns; - pio_mgr->dev_obj = hdev_obj; - - /* Return the new channel manager handle: */ - *io_man = hio_mgr; - } - } - - return status; -} - -/* - * ======== io_destroy ======== - * Purpose: - * Delete IO manager. - */ -int io_destroy(struct io_mgr *hio_mgr) -{ - struct bridge_drv_interface *intf_fxns; - struct io_mgr_ *pio_mgr = (struct io_mgr_ *)hio_mgr; - int status; - - intf_fxns = pio_mgr->intf_fxns; - - /* Let Bridge channel module destroy the io_mgr: */ - status = (*intf_fxns->io_destroy) (hio_mgr); - - return status; -} diff --git a/drivers/staging/tidspbridge/pmgr/ioobj.h b/drivers/staging/tidspbridge/pmgr/ioobj.h deleted file mode 100644 index 7defd9481458..000000000000 --- a/drivers/staging/tidspbridge/pmgr/ioobj.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * ioobj.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Structure subcomponents of channel class library IO objects which - * are exposed to DSP API from Bridge driver. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef IOOBJ_ -#define IOOBJ_ - -#include <dspbridge/devdefs.h> -#include <dspbridge/dspdefs.h> - -/* - * This struct is the first field in a io_mgr struct. Other, implementation - * specific fields follow this structure in memory. - */ -struct io_mgr_ { - /* These must be the first fields in a io_mgr struct: */ - struct bridge_dev_context *bridge_context; /* Bridge context. */ - /* Function interface to Bridge driver. */ - struct bridge_drv_interface *intf_fxns; - struct dev_object *dev_obj; /* Device this board represents. */ -}; - -#endif /* IOOBJ_ */ diff --git a/drivers/staging/tidspbridge/pmgr/msg.c b/drivers/staging/tidspbridge/pmgr/msg.c deleted file mode 100644 index f093cfb51c00..000000000000 --- a/drivers/staging/tidspbridge/pmgr/msg.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * msg.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * DSP/BIOS Bridge msg_ctrl Module. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ -#include <linux/types.h> - -/* ----------------------------------- Host OS */ -#include <dspbridge/host_os.h> - -/* ----------------------------------- DSP/BIOS Bridge */ -#include <dspbridge/dbdefs.h> - -/* ----------------------------------- Bridge Driver */ -#include <dspbridge/dspdefs.h> - -/* ----------------------------------- Platform Manager */ -#include <dspbridge/dev.h> - -/* ----------------------------------- This */ -#include <msgobj.h> -#include <dspbridge/msg.h> - -/* - * ======== msg_create ======== - * Purpose: - * Create an object to manage message queues. Only one of these objects - * can exist per device object. - */ -int msg_create(struct msg_mgr **msg_man, - struct dev_object *hdev_obj, msg_onexit msg_callback) -{ - struct bridge_drv_interface *intf_fxns; - struct msg_mgr_ *msg_mgr_obj; - struct msg_mgr *hmsg_mgr; - int status = 0; - - *msg_man = NULL; - - dev_get_intf_fxns(hdev_obj, &intf_fxns); - - /* Let Bridge message module finish the create: */ - status = - (*intf_fxns->msg_create) (&hmsg_mgr, hdev_obj, msg_callback); - - if (!status) { - /* Fill in DSP API message module's fields of the msg_mgr - * structure */ - msg_mgr_obj = (struct msg_mgr_ *)hmsg_mgr; - msg_mgr_obj->intf_fxns = intf_fxns; - - /* Finally, return the new message manager handle: */ - *msg_man = hmsg_mgr; - } else { - status = -EPERM; - } - return status; -} - -/* - * ======== msg_delete ======== - * Purpose: - * Delete a msg_ctrl manager allocated in msg_create(). - */ -void msg_delete(struct msg_mgr *hmsg_mgr) -{ - struct msg_mgr_ *msg_mgr_obj = (struct msg_mgr_ *)hmsg_mgr; - struct bridge_drv_interface *intf_fxns; - - if (msg_mgr_obj) { - intf_fxns = msg_mgr_obj->intf_fxns; - - /* Let Bridge message module destroy the msg_mgr: */ - (*intf_fxns->msg_delete) (hmsg_mgr); - } else { - dev_dbg(bridge, "%s: Error hmsg_mgr handle: %p\n", - __func__, hmsg_mgr); - } -} diff --git a/drivers/staging/tidspbridge/pmgr/msgobj.h b/drivers/staging/tidspbridge/pmgr/msgobj.h deleted file mode 100644 index 14ca633c56cb..000000000000 --- a/drivers/staging/tidspbridge/pmgr/msgobj.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * msgobj.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Structure subcomponents of channel class library msg_ctrl objects which - * are exposed to DSP API from Bridge driver. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef MSGOBJ_ -#define MSGOBJ_ - -#include <dspbridge/dspdefs.h> - -#include <dspbridge/msgdefs.h> - -/* - * This struct is the first field in a msg_mgr struct. Other, implementation - * specific fields follow this structure in memory. - */ -struct msg_mgr_ { - /* The first field must match that in _msg_sm.h */ - - /* Function interface to Bridge driver. */ - struct bridge_drv_interface *intf_fxns; -}; - -#endif /* MSGOBJ_ */ |