static int __devexit omap34xx_bridge_remove(struct platform_device *pdev)
{
	dev_t devno;
	bool ret;
	DSP_STATUS dsp_status = DSP_SOK;
	HANDLE hDrvObject = NULL;

	dsp_status = CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT);
	if (DSP_FAILED(dsp_status))
		goto func_cont;

#ifdef CONFIG_BRIDGE_DVFS
	if (clk_notifier_unregister(clk_handle, &iva_clk_notifier))
		pr_err("%s: clk_notifier_unregister failed for iva2_ck\n",
								__func__);
#endif /* #ifdef CONFIG_BRIDGE_DVFS */

	if (driverContext) {
		/* Put the DSP in reset state */
		ret = DSP_Deinit(driverContext);
		driverContext = 0;
		DBC_Assert(ret == true);
	}

#ifdef CONFIG_BRIDGE_DVFS
	clk_put(clk_handle);
	clk_handle = NULL;
#endif

func_cont:

#ifdef CONFIG_PM
	/* The suspend wait queue should not have anything waiting on it
	   since remove won't be called while the file is open */
	DBC_Assert(!waitqueue_active(&bridge_suspend_data.suspend_wq));
#endif
	MEM_ExtPhysPoolRelease();

	SERVICES_Exit();
	GT_exit();

	/* Remove driver sysfs entries */
	bridge_destroy_sysfs();

	devno = MKDEV(driver_major, 0);
	cdev_del(&bridge_cdev);
	unregister_chrdev_region(devno, 1);
	if (bridge_class) {
		/* remove the device from sysfs */
		device_destroy(bridge_class, MKDEV(driver_major, 0));
		class_destroy(bridge_class);

	}
	return 0;
}
Example #2
0
/** ============================================================================
 *  @func   KFILEDEF_Tell
 *
 *  @desc   Returns the current file pointer position for the specified
 *          file handle.
 *
 *  @modif  None
 *  ============================================================================
 */
EXPORT_API
DSP_STATUS
KFILEDEF_Tell (IN  Void *        fileHandle,
               OUT Int32 *       pos)
{
    DSP_STATUS   status = DSP_SOK ;
    KFILEDEF_Object * fileObj = NULL ;

    TRC_2ENTER ("KFILEDEF_Tell", fileObj, pos) ;

    DBC_Require (fileHandle != NULL) ;
    DBC_Require (pos != NULL) ;

    if (pos == NULL) {
        status = DSP_EINVALIDARG ;
        SET_FAILURE_REASON ;
    }
    else {
        fileObj = (KFILEDEF_Object *) fileHandle ;
        *pos = fileObj->curPos ;
        DBC_Assert (*pos == fileObj->fileDesc->f_pos) ;
    }

    DBC_Ensure (   (DSP_SUCCEEDED (status) && (pos != NULL) && (*pos >= 0))
                   || (DSP_FAILED (status))) ;

    TRC_1LEAVE ("KFILEDEF_Tell", status) ;

    return status ;
}
Example #3
0
/** ============================================================================
 *  @func   LIST_PutTail
 *
 *  @desc   Adds the specified element to the tail of the list.
 *
 *  @modif  None
 *  ============================================================================
 */
EXPORT_API
DSP_STATUS
LIST_PutTail (IN List * list, IN ListElement * element)
{
    DSP_STATUS status = DSP_SOK ;

    TRC_2ENTER ("LIST_PutTail", list, element) ;

    DBC_Require (list != NULL) ;
    DBC_Require (element != NULL) ;

    if ((list == NULL) || (element == NULL)) {
        status = DSP_EINVALIDARG ;
        SET_FAILURE_REASON ;
    }
    else {
        element->prev       = list->head.prev ;
        element->next       = &list->head ;
        list->head.prev     = element ;
        element->prev->next = element ;
    }

    DBC_Assert (   (DSP_SUCCEEDED (status) && (!LIST_IsEmpty (list)))
                || (DSP_FAILED (status)));

    TRC_1LEAVE ("LIST_PutTail", status) ;

    return status ;
}
Example #4
0
/*
 *  ======== NTFY_Delete ========
 *  Purpose:
 *      Free resources allocated in NTFY_Create.
 */
void NTFY_Delete(struct NTFY_OBJECT *hNtfy)
{
	struct NOTIFICATION *pNotify;

	DBC_Require(MEM_IsValidHandle(hNtfy, NTFY_SIGNATURE));

	/* Remove any elements remaining in list */
	if (hNtfy->notifyList) {

		(void) SYNC_EnterCS(hNtfy->hSync);
	
		while ((pNotify = (struct NOTIFICATION *)LST_GetHead(hNtfy->
								notifyList))) {
			DeleteNotify(pNotify);
		}
		DBC_Assert(LST_IsEmpty(hNtfy->notifyList));
		kfree(hNtfy->notifyList);

		(void) SYNC_LeaveCS(hNtfy->hSync);
	}

	
	if (hNtfy->hSync)
		(void)SYNC_DeleteCS(hNtfy->hSync);

	MEM_FreeObject(hNtfy);
}
Example #5
0
/*
 *  ======== STRM_FreeBuffer ========
 *  Purpose:
 *      Frees the buffers allocated for a stream.
 */
DSP_STATUS STRM_FreeBuffer(struct STRM_OBJECT *hStrm, u8 **apBuffer,
		u32 uNumBufs, struct PROCESS_CONTEXT *pr_ctxt)
{
	DSP_STATUS status = DSP_SOK;
	u32 i = 0;

	HANDLE hSTRMRes = NULL;

	DBC_Require(cRefs > 0);
	DBC_Require(apBuffer != NULL);

	for (i = 0; i < uNumBufs; i++) {
		DBC_Assert(hStrm->hXlator != NULL);
		status = CMM_XlatorFreeBuf(hStrm->hXlator, apBuffer[i]);
		if (DSP_FAILED(status))
			break;
		apBuffer[i] = NULL;
	}

	if (DSP_SUCCEEDED(status)) {
		if (DRV_GetSTRMResElement(hStrm, hSTRMRes, pr_ctxt) !=
				DSP_ENOTFOUND)
			DRV_ProcUpdateSTRMRes(uNumBufs-i, hSTRMRes);
	}
	return status;
}
Example #6
0
/*
 *  ======== MGR_Init ========
 *      Initialize MGR's private state, keeping a reference count on each call.
 */
bool MGR_Init(void)
{
	bool fRetval = true;
	bool fInitDCD = false;

	DBC_Require(cRefs >= 0);

	if (cRefs == 0) {

		/* Set the Trace mask */
		DBC_Assert(!MGR_DebugMask.flags);

		GT_create(&MGR_DebugMask, "MG");	/* "MG" for Manager */
		fInitDCD = DCD_Init();	/*  DCD Module */

		if (!fInitDCD) {
			fRetval = false;
			GT_0trace(MGR_DebugMask, GT_6CLASS,
				 "MGR_Init failed\n");
		}
	}

	if (fRetval)
		cRefs++;


	GT_1trace(MGR_DebugMask, GT_5CLASS,
		 "Entered MGR_Init, ref count:  0x%x\n", cRefs);
	DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0)));

	return fRetval;
}
/* This function maps kernel space memory to user space memory. */
static int bridge_mmap(struct file *filp, struct vm_area_struct *vma)
{
#if GT_TRACE
	u32 offset = vma->vm_pgoff << PAGE_SHIFT;
#endif
	u32 status;

	DBC_Assert(vma->vm_start < vma->vm_end);

	/* TODO: Check for valid size. */
	/* It looks right now like this can map all of kernel memory if requested */

	vma->vm_flags |= VM_RESERVED | VM_IO;
	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);

	GT_6trace(driverTrace, GT_3CLASS,
		 "vm filp %p offset %lx start %lx end %lx"
		 " page_prot %lx flags %lx\n", filp, offset, vma->vm_start,
		 vma->vm_end, vma->vm_page_prot, vma->vm_flags);

	status = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
				vma->vm_end - vma->vm_start, vma->vm_page_prot);
	if (status != 0)
		status = -EAGAIN;

	return status;
}
/*
 *  ======== WMD_CHNL_Close ========
 *  Purpose:
 *      Ensures all pending I/O on this channel is cancelled, discards all
 *      queued I/O completion notifications, then frees the resources allocated
 *      for this channel, and makes the corresponding logical channel id
 *      available for subsequent use.
 */
DSP_STATUS WMD_CHNL_Close(struct CHNL_OBJECT *hChnl)
{
	DSP_STATUS status;
	struct CHNL_OBJECT *pChnl = (struct CHNL_OBJECT *)hChnl;

	/* Check args: */
	if (!MEM_IsValidHandle(pChnl, CHNL_SIGNATURE)) {
		status = DSP_EHANDLE;
		goto func_cont;
	}
	{
		/* Cancel IO: this ensures no further IO requests or
		 * notifications.*/
		status = WMD_CHNL_CancelIO(hChnl);
	}
func_cont:
	if (DSP_SUCCEEDED(status)) {
		/* Assert I/O on this channel is now cancelled: Protects
		 * from IO_DPC. */
		DBC_Assert((pChnl->dwState & CHNL_STATECANCEL));
		/* Invalidate channel object: Protects from
		 * CHNL_GetIOCompletion(). */
		pChnl->dwSignature = 0x0000;
		/* Free the slot in the channel manager: */
		pChnl->pChnlMgr->apChannel[pChnl->uId] = NULL;
		pChnl->pChnlMgr->cOpenChannels -= 1;
		if (pChnl->hNtfy) {
			NTFY_Delete(pChnl->hNtfy);
			pChnl->hNtfy = NULL;
		}
		/* Reset channel event: (NOTE: hUserEvent freed in user
		 * context.). */
		if (pChnl->hSyncEvent) {
			SYNC_ResetEvent(pChnl->hSyncEvent);
			SYNC_CloseEvent(pChnl->hSyncEvent);
			pChnl->hSyncEvent = NULL;
		}
		/* Free I/O request and I/O completion queues:  */
		if (pChnl->pIOCompletions) {
			FreeChirpList(pChnl->pIOCompletions);
			pChnl->pIOCompletions = NULL;
			pChnl->cIOCs = 0;
		}
		if (pChnl->pIORequests) {
			FreeChirpList(pChnl->pIORequests);
			pChnl->pIORequests = NULL;
			pChnl->cIOReqs = 0;
		}
		if (pChnl->pFreeList) {
			FreeChirpList(pChnl->pFreeList);
			pChnl->pFreeList = NULL;
		}
		/* Release channel object. */
		MEM_FreeObject(pChnl);
		pChnl = NULL;
	}
	DBC_Ensure(DSP_FAILED(status) ||
		  !MEM_IsValidHandle(pChnl, CHNL_SIGNATURE));
	return status;
}
Example #9
0
/** ============================================================================
 *  @func   LDRV_MPLIST_isEmpty
 *
 *  @desc   check for an empty list.
 *
 *  @modif  None.
 *  ============================================================================
 */
EXPORT_API
Bool
LDRV_MPLIST_isEmpty (IN     ProcessorId dspId,
                     IN     List *      list )
{
    Bool                 retVal = FALSE ;
    LDRV_MPLIST_Object * mplistState ;
    Uint32               temp   ;

    TRC_2ENTER ("LDRV_MPLIST_isEmpty", dspId, list) ;

    DBC_Require (IS_VALID_PROCID(dspId)) ;
    DBC_Require (list != NULL) ;
    DBC_Assert  (LDRV_MPLIST_IsInitialized [dspId] == TRUE) ;

    mplistState = &(LDRV_MPLIST_State [dspId]) ;

    temp = SWAP_LONG (DSP_addrConvert (dspId,
                                       (Uint32) &((list)->head),
                                       GppToDsp),
                      mplistState->wordSwap) ;

    if ( ((Uint32) (list)->head.next) == temp) {
        retVal = TRUE ;
    }

    TRC_1LEAVE ("LDRV_MPLIST_isEmpty", retVal) ;

    return retVal ;
}
Example #10
0
/*
 *  ======== DBLL_init ========
 */
bool DBLL_init(void)
{
	bool retVal = true;

	DBC_Require(cRefs >= 0);

	if (cRefs == 0) {
		DBC_Assert(!DBLL_debugMask.flags);
		GT_create(&DBLL_debugMask, "DL"); 	/* "DL" for dbDL */
		GH_init();
		retVal = MEM_Init();
		if (!retVal)
			MEM_Exit();

	}

	if (retVal)
		cRefs++;


	GT_1trace(DBLL_debugMask, GT_5CLASS, "DBLL_init(), ref count:  0x%x\n",
		 cRefs);

	DBC_Ensure((retVal && (cRefs > 0)) || (!retVal && (cRefs >= 0)));

	return retVal;
}
Example #11
0
/*
 *  ======== WMD_CHNL_Destroy ========
 *  Purpose:
 *      Close all open channels, and destroy the channel manager.
 */
DSP_STATUS WMD_CHNL_Destroy(struct CHNL_MGR *hChnlMgr)
{
	DSP_STATUS status = DSP_SOK;
	struct CHNL_MGR *pChnlMgr = hChnlMgr;
	u32 iChnl;

	if (MEM_IsValidHandle(hChnlMgr, CHNL_MGRSIGNATURE)) {
		/* Close all open channels: */
		for (iChnl = 0; iChnl < pChnlMgr->cChannels; iChnl++) {
			if (DSP_SUCCEEDED
			    (WMD_CHNL_Close(pChnlMgr->apChannel[iChnl]))) {
				DBC_Assert(pChnlMgr->apChannel[iChnl] == NULL);
			}
		}
		/* release critical section */
		if (pChnlMgr->hCSObj)
			SYNC_DeleteCS(pChnlMgr->hCSObj);

		/* Free channel manager object: */
		if (pChnlMgr->apChannel)
			MEM_Free(pChnlMgr->apChannel);

		/* Set hChnlMgr to NULL in device object. */
		DEV_SetChnlMgr(pChnlMgr->hDevObject, NULL);
		/* Free this Chnl Mgr object: */
		MEM_FreeObject(hChnlMgr);
	} else {
		status = DSP_EHANDLE;
	}
	return status;
}
Example #12
0
/** ============================================================================
 *  @func   LIST_InsertBefore
 *
 *  @desc   Insert the element before the existing element.
 *
 *  @modif  None
 *  ============================================================================
 */
EXPORT_API
DSP_STATUS
LIST_InsertBefore (IN  List *          list,
                   IN  ListElement *   insertElement,
                   IN  ListElement *   existingElement)
{
    DSP_STATUS status = DSP_SOK ;

    TRC_3ENTER ("LIST_InsertBefore", list, insertElement, existingElement) ;

    DBC_Require(list != NULL) ;
    DBC_Require(insertElement != NULL) ;
    DBC_Require(existingElement != NULL) ;

    if (   (list ==  NULL)
        || (insertElement == NULL)
        || (existingElement == NULL)) {
        status = DSP_EINVALIDARG ;
        SET_FAILURE_REASON ;
    }
    else {
        existingElement->prev->next = insertElement ;
        insertElement->prev         = existingElement->prev ;
        insertElement->next         = existingElement ;
        existingElement->prev       = insertElement ;
    }

    DBC_Assert (   (DSP_SUCCEEDED (status) && (!LIST_IsEmpty (list)))
                || (DSP_FAILED (status)));

    TRC_1LEAVE ("LIST_InsertBefore", status) ;

    return status ;
}
Example #13
0
/*
 *  ======== RMM_init ========
 */
bool RMM_init(void)
{
	bool retVal = true;

	DBC_Require(cRefs >= 0);

	if (cRefs == 0) {
		DBC_Assert(!RMM_debugMask.flags);
		GT_create(&RMM_debugMask, "RM");	/* "RM" for RMm */

		retVal = MEM_Init();

		if (!retVal)
			MEM_Exit();

	}

	if (retVal)
		cRefs++;

	GT_1trace(RMM_debugMask, GT_5CLASS,
		 "RMM_init(), ref count:  0x%x\n",
		 cRefs);

	DBC_Ensure((retVal && (cRefs > 0)) || (!retVal && (cRefs >= 0)));

	return retVal;
}
Example #14
0
/*
 *  ======== WMD_CHNL_Create ========
 *      Create a channel manager object, responsible for opening new channels
 *      and closing old ones for a given board.
 */
DSP_STATUS WMD_CHNL_Create(OUT struct CHNL_MGR **phChnlMgr,
			  struct DEV_OBJECT *hDevObject,
			  IN CONST struct CHNL_MGRATTRS *pMgrAttrs)
{
	DSP_STATUS status = DSP_SOK;
	struct CHNL_MGR *pChnlMgr = NULL;
	s32 cChannels;

	/* Check DBC requirements:  */
	DBC_Require(phChnlMgr != NULL);
	DBC_Require(pMgrAttrs != NULL);
	DBC_Require(pMgrAttrs->cChannels > 0);
	DBC_Require(pMgrAttrs->cChannels <= CHNL_MAXCHANNELS);
	DBC_Require(pMgrAttrs->uWordSize != 0);

	/* Allocate channel manager object: */
	MEM_AllocObject(pChnlMgr, struct CHNL_MGR, CHNL_MGRSIGNATURE);
	if (pChnlMgr) {
		/* The cChannels attr must equal the # of supported
		 * chnls for each transport(# chnls for PCPY = DDMA =
		 * ZCPY): i.e. pMgrAttrs->cChannels = CHNL_MAXCHANNELS =
		 * DDMA_MAXDDMACHNLS = DDMA_MAXZCPYCHNLS.  */
		DBC_Assert(pMgrAttrs->cChannels == CHNL_MAXCHANNELS);
		cChannels = CHNL_MAXCHANNELS + CHNL_MAXCHANNELS * CHNL_PCPY;
		/* Create array of channels: */
		pChnlMgr->apChannel = MEM_Calloc(
				sizeof(struct CHNL_OBJECT *) *
				cChannels, MEM_NONPAGED);
		if (pChnlMgr->apChannel) {
			/* Initialize CHNL_MGR object: */
			/* Shared memory driver. */
			pChnlMgr->dwType = CHNL_TYPESM;
			pChnlMgr->uWordSize = pMgrAttrs->uWordSize;
			/* total # chnls supported */
			pChnlMgr->cChannels = cChannels;
			pChnlMgr->cOpenChannels = 0;
			pChnlMgr->dwOutputMask = 0;
			pChnlMgr->dwLastOutput = 0;
			pChnlMgr->hDevObject = hDevObject;
			if (DSP_SUCCEEDED(status))
				status = SYNC_InitializeDPCCS(
							&pChnlMgr->hCSObj);
		} else {
			status = DSP_EMEMORY;
		}
	} else {
		status = DSP_EMEMORY;
	}

	if (DSP_FAILED(status)) {
		WMD_CHNL_Destroy(pChnlMgr);
		*phChnlMgr = NULL;
	} else {
		/* Return channel manager object to caller... */
		*phChnlMgr = pChnlMgr;
	}
	return status;
}
Example #15
0
/** ============================================================================
 *  @func   LDRV_MPLIST_removeElement
 *
 *  @desc   Removes (unlinks) the given element from the list, if the list is
 *          not empty.  Does not free the list element. This function works on
 *          the list object and element fields in DSP address space.If the
 *          element is from pool memory, it does the  invalidate and writeback
 *          operations on the element. If the element is from a non pool shared
 *          memory, invalidate writeback operations  are not performed.
 *
 *  @modif  None.
 *  ============================================================================
 */
EXPORT_API
Void
LDRV_MPLIST_removeElement (IN     ProcessorId    dspId,
                           IN     List *         list,
                           IN     ListElement *  element )
{
    PoolId               poolId        = POOL_INVALIDID ;
    LDRV_MPLIST_Object * mplistState ;
    ListElement *        temp   ;

    TRC_4ENTER ("LDRV_MPLIST_removeElement", dspId, list, element, poolId) ;

    DBC_Require (IS_VALID_PROCID (dspId)) ;
    DBC_Require (list    != NULL) ;
    DBC_Require (element != NULL) ;
    DBC_Assert  (LDRV_MPLIST_IsInitialized [dspId] == TRUE) ;

    mplistState = &(LDRV_MPLIST_State [dspId]) ;

    if (LDRV_MPLIST_isEmpty (dspId, list) == FALSE) {
        temp = (ListElement *)
                  DSP_addrConvert (dspId,
                                   SWAP_LONG ((Uint32) (element->prev),
                                              mplistState->wordSwap),
                                   DspToGpp) ;

        LDRV_POOL_getPoolId (dspId,
                             temp,
                             AddrType_Knl,
                             &poolId );
        if (IS_VALID_POOLID (poolId)) {
            LDRV_POOL_invalidate (poolId, temp, sizeof (ListElement)) ;
        }
        temp->next = element->next ;
        if (IS_VALID_POOLID (poolId)) {
            LDRV_POOL_writeback (poolId, temp, sizeof (ListElement)) ;
        }

        temp = (ListElement *)
                  DSP_addrConvert (dspId,
                                   SWAP_LONG ((Uint32) (element->next),
                                              mplistState->wordSwap),
                                   DspToGpp) ;
        LDRV_POOL_getPoolId (dspId,
                             temp,
                             AddrType_Knl,
                             &poolId );
        if (IS_VALID_POOLID (poolId)) {
            LDRV_POOL_invalidate (poolId, temp, sizeof (ListElement)) ;
        }
        temp->prev = element->prev ;
        if (IS_VALID_POOLID (poolId)) {
            LDRV_POOL_writeback (poolId, temp, sizeof (ListElement)) ;
        }
    }

    TRC_0LEAVE ("LDRV_MPLIST_removeElement") ;
}
Example #16
0
/*
 *  ======== STRM_GetInfo ========
 *  Purpose:
 *      Retrieves information about a stream.
 */
DSP_STATUS STRM_GetInfo(struct STRM_OBJECT *hStrm,
			OUT struct STRM_INFO *pStreamInfo,
			u32 uStreamInfoSize)
{
	struct WMD_DRV_INTERFACE *pIntfFxns;
	struct CHNL_INFO chnlInfo;
	DSP_STATUS status = DSP_SOK;
	void *pVirtBase = NULL;	/* NULL if no SM used */

	DBC_Require(cRefs > 0);
	DBC_Require(pStreamInfo != NULL);
	DBC_Require(uStreamInfoSize >= sizeof(struct STRM_INFO));


	if (uStreamInfoSize < sizeof(struct STRM_INFO)) {
		/* size of users info */
		status = DSP_ESIZE;
	}

	if (DSP_FAILED(status))
		goto func_end;

	pIntfFxns = hStrm->hStrmMgr->pIntfFxns;
	status = (*pIntfFxns->pfnChnlGetInfo) (hStrm->hChnl, &chnlInfo);
	if (DSP_FAILED(status))
		goto func_end;

	if (hStrm->hXlator) {
		/* We have a translator */
		DBC_Assert(hStrm->uSegment > 0);
		CMM_XlatorInfo(hStrm->hXlator, (u8 **)&pVirtBase, 0,
			      hStrm->uSegment, false);
	}
	pStreamInfo->uSegment = hStrm->uSegment;
	pStreamInfo->lMode = hStrm->lMode;
	pStreamInfo->pVirtBase = pVirtBase;
	pStreamInfo->pUser->uNumberBufsAllowed = hStrm->uNumBufs;
	pStreamInfo->pUser->uNumberBufsInStream = chnlInfo.cIOCs +
						 chnlInfo.cIOReqs;
	/* # of bytes transferred since last call to DSPStream_Idle() */
	pStreamInfo->pUser->ulNumberBytes = chnlInfo.cPosition;
	pStreamInfo->pUser->hSyncObjectHandle = chnlInfo.hEvent;
	/* Determine stream state based on channel state and info */
	if (chnlInfo.dwState & CHNL_STATEEOS) {
		pStreamInfo->pUser->ssStreamState = STREAM_DONE;
	} else {
		if (chnlInfo.cIOCs > 0)
			pStreamInfo->pUser->ssStreamState = STREAM_READY;
		else if (chnlInfo.cIOReqs > 0)
			pStreamInfo->pUser->ssStreamState = STREAM_PENDING;
		else
			pStreamInfo->pUser->ssStreamState = STREAM_IDLE;

	}
func_end:
	return status;
}
Example #17
0
/** ============================================================================
 *  @func   KFILEDEF_Read
 *
 *  @desc   Reads a specified number of items of specified size
 *          bytes from file to a buffer.
 *
 *  @modif  None
 *  ============================================================================
 */
EXPORT_API
DSP_STATUS
KFILEDEF_Read (IN OUT  Char8 *       buffer,
               IN      Uint32        size,
               IN      Uint32        count,
               IN      Void *        fileHandle)
{
    DSP_STATUS      status    = DSP_SOK ;
    Int32           bytesRead = 0       ;
    mm_segment_t    fs                  ;
    KFILEDEF_Object * fileObj = NULL    ;

    TRC_4ENTER ("KFILEDEF_Read", buffer, size, count, fileHandle) ;

    DBC_Require (fileHandle != NULL) ;
    DBC_Require (buffer != NULL) ;

    if (buffer == NULL) {
        status = DSP_EINVALIDARG ;
        SET_FAILURE_REASON ;
    }
    else if ((size != 0) && (count != 0)) {
        fileObj = (KFILEDEF_Object *) fileHandle ;

        if ((fileObj->curPos + (size * count)) > fileObj->size) {
            status = DSP_ERANGE ;
            SET_FAILURE_REASON  ;
        }
        else {
            /* read from file */
            fs = get_fs () ;
            set_fs (KERNEL_DS) ;

            bytesRead = fileObj->fileDesc->f_op->read (fileObj->fileDesc,
                        buffer,
                        size * count,
                        &(fileObj->fileDesc->f_pos));
            set_fs (fs) ;

            if (bytesRead >= 0) {
                fileObj->curPos += bytesRead ;
                DBC_Assert ((bytesRead / size) == (Uint32) count) ;
            }
            else {
                status = DSP_EFILE;
                TRC_2PRINT (TRC_LEVEL1,
                            "File Read failed with status [0x%x]\n"
                            "Error value[0x%x]\n",
                            status, bytesRead) ;
            }
        }
    }

    TRC_1LEAVE ("KFILEDEF_Read", status) ;

    return status ;
}
Example #18
0
/*
 *  ======== STRM_FreeBuffer ========
 *  Purpose:
 *      Frees the buffers allocated for a stream.
 */
DSP_STATUS STRM_FreeBuffer(struct STRM_OBJECT *hStrm, u8 **apBuffer,
			  u32 uNumBufs)
{
	DSP_STATUS status = DSP_SOK;
	u32 i = 0;

	#ifndef RES_CLEANUP_DISABLE
	DSP_STATUS res_status = DSP_SOK;
       u32                  hProcess;
	HANDLE	     pCtxt = NULL;
	HANDLE	     hDrvObject;
	HANDLE 		    hSTRMRes = NULL;
	#endif
	DBC_Require(cRefs > 0);
	DBC_Require(apBuffer != NULL);

	GT_3trace(STRM_debugMask, GT_ENTER, "STRM_FreeBuffer: hStrm: 0x%x\t"
		 "apBuffer: 0x%x\tuNumBufs: 0x%x\n", hStrm, apBuffer, uNumBufs);

	if (!MEM_IsValidHandle(hStrm, STRM_SIGNATURE))
		status = DSP_EHANDLE;

	if (DSP_SUCCEEDED(status)) {
		for (i = 0; i < uNumBufs; i++) {
			DBC_Assert(hStrm->hXlator != NULL);
			status = CMM_XlatorFreeBuf(hStrm->hXlator, apBuffer[i]);
			if (DSP_FAILED(status)) {
				GT_0trace(STRM_debugMask, GT_7CLASS,
					 "STRM_FreeBuffer: DSP_FAILED"
					 " to free shared memory.\n");
				break;
			}
			apBuffer[i] = NULL;
		}
	}
#ifndef RES_CLEANUP_DISABLE
	/* Update the node and stream resource status */
       /* Return PID instead of process handle */
       hProcess = current->pid;

	res_status = CFG_GetObject((u32 *)&hDrvObject, REG_DRV_OBJECT);
	if (DSP_SUCCEEDED(res_status)) {
               DRV_GetProcContext(hProcess,
				 (struct DRV_OBJECT *)hDrvObject, &pCtxt,
				 NULL, 0);
		if (pCtxt != NULL) {
			if (DRV_GetSTRMResElement(hStrm, hSTRMRes, pCtxt) !=
			   DSP_ENOTFOUND) {
				DRV_ProcUpdateSTRMRes(uNumBufs-i, hSTRMRes,
						     pCtxt);
			}
		}
	}
#endif
	return status;
}
Example #19
0
/*
 *  ======== WMD_CHNL_CancelIO ========
 *      Return all I/O requests to the client which have not yet been
 *      transferred.  The channel's I/O completion object is
 *      signalled, and all the I/O requests are queued as IOC's, with the
 *      status field set to CHNL_IOCSTATCANCEL.
 *      This call is typically used in abort situations, and is a prelude to
 *      CHNL_Close();
 */
DSP_STATUS WMD_CHNL_CancelIO(struct CHNL_OBJECT *hChnl)
{
	DSP_STATUS status = DSP_SOK;
	struct CHNL_OBJECT *pChnl = (struct CHNL_OBJECT *)hChnl;
	u32 iChnl = -1;
	short int uMode;
	struct CHNL_IRP *pChirp;
	struct CHNL_MGR *pChnlMgr = NULL;

	/* Check args: */
	if (MEM_IsValidHandle(pChnl, CHNL_SIGNATURE) && pChnl->pChnlMgr) {
		iChnl = pChnl->uId;
		uMode = pChnl->uMode;
		pChnlMgr = pChnl->pChnlMgr;
	} else {
		status = DSP_EHANDLE;
	}
	if (DSP_FAILED(status))
		goto func_end;

	 /*  Mark this channel as cancelled, to prevent further IORequests or
	 *  IORequests or dispatching.  */
	SYNC_EnterCS(pChnlMgr->hCSObj);
	pChnl->dwState |= CHNL_STATECANCEL;
	if (LST_IsEmpty(pChnl->pIORequests))
		goto func_cont;

	if (pChnl->uChnlType == CHNL_PCPY) {
		/* Indicate we have no more buffers available for transfer: */
		if (CHNL_IsInput(pChnl->uMode)) {
			IO_CancelChnl(pChnlMgr->hIOMgr, iChnl);
		} else {
			/* Record that we no longer have output buffers
			 * available: */
			pChnlMgr->dwOutputMask &= ~(1 << iChnl);
		}
	}
	/* Move all IOR's to IOC queue:  */
	while (!LST_IsEmpty(pChnl->pIORequests)) {
		pChirp = (struct CHNL_IRP *)LST_GetHead(pChnl->pIORequests);
		if (pChirp) {
			pChirp->cBytes = 0;
			pChirp->status |= CHNL_IOCSTATCANCEL;
			LST_PutTail(pChnl->pIOCompletions,
				   (struct list_head *)pChirp);
			pChnl->cIOCs++;
			pChnl->cIOReqs--;
			DBC_Assert(pChnl->cIOReqs >= 0);
		}
	}
func_cont:
		SYNC_LeaveCS(pChnlMgr->hCSObj);
func_end:
	return status;
}
Example #20
0
/*
 *  ======== WMD_CHNL_RegisterNotify ========
 *      Registers for events on a particular channel.
 */
DSP_STATUS WMD_CHNL_RegisterNotify(struct CHNL_OBJECT *hChnl, u32 uEventMask,
				  u32 uNotifyType,
				  struct DSP_NOTIFICATION *hNotification)
{
	DSP_STATUS status = DSP_SOK;

	DBC_Assert(!(uEventMask & ~(DSP_STREAMDONE | DSP_STREAMIOCOMPLETION)));

	status = NTFY_Register(hChnl->hNtfy, hNotification, uEventMask,
			      uNotifyType);

	return status;
}
Example #21
0
/*
 *  ======== WMD_MSG_Create ========
 *      Create an object to manage message queues. Only one of these objects
 *      can exist per device object.
 */
DSP_STATUS WMD_MSG_Create(OUT struct MSG_MGR **phMsgMgr,
			 struct DEV_OBJECT *hDevObject, MSG_ONEXIT msgCallback)
{
	struct MSG_MGR *pMsgMgr;
	struct IO_MGR *hIOMgr;
	DSP_STATUS status = DSP_SOK;

	DBC_Require(phMsgMgr != NULL);
	DBC_Require(msgCallback != NULL);
	DBC_Require(hDevObject != NULL);
	DEV_GetIOMgr(hDevObject, &hIOMgr);
	DBC_Assert(hIOMgr != NULL);
	*phMsgMgr = NULL;
	/* Allocate MSG manager object */
	MEM_AllocObject(pMsgMgr, struct MSG_MGR, MSGMGR_SIGNATURE);

	if (pMsgMgr) {
		pMsgMgr->onExit = msgCallback;
		pMsgMgr->hIOMgr = hIOMgr;
		/* List of MSG_QUEUEs */
		pMsgMgr->queueList = LST_Create();
		 /*  Queues of message frames for messages to the DSP. Message
		  * frames will only be added to the free queue when a
		  * MSG_QUEUE object is created.  */
		pMsgMgr->msgFreeList = LST_Create();
		pMsgMgr->msgUsedList = LST_Create();
		if (pMsgMgr->queueList == NULL ||
		    pMsgMgr->msgFreeList == NULL ||
		    pMsgMgr->msgUsedList == NULL)
			status = DSP_EMEMORY;
		if (DSP_SUCCEEDED(status))
			status = SYNC_InitializeDPCCS(&pMsgMgr->hSyncCS);

		 /*  Create an event to be used by WMD_MSG_Put() in waiting
		 *  for an available free frame from the message manager.  */
		if (DSP_SUCCEEDED(status))
			status = SYNC_OpenEvent(&pMsgMgr->hSyncEvent, NULL);

		if (DSP_SUCCEEDED(status))
			*phMsgMgr = pMsgMgr;
		else
			DeleteMsgMgr(pMsgMgr);

	} else {
		status = DSP_EMEMORY;
	}
	return status;
}
Example #22
0
/*
 *  ======== FreeMsgList ========
 */
static void FreeMsgList(struct LST_LIST *msgList)
{
	struct MSG_FRAME *pMsg;

       if (!msgList)
               goto func_end;

	while ((pMsg = (struct MSG_FRAME *)LST_GetHead(msgList)) != NULL)
		MEM_Free(pMsg);

	DBC_Assert(LST_IsEmpty(msgList));

	LST_Delete(msgList);
func_end:
       return;
}
Example #23
0
/*
 *  ======== KFILE_Read ========
 *  Purpose:
 *      Reads a specified number of bytes into a buffer.
 */
s32
KFILE_Read(void __user*pBuffer, s32 cSize, s32 cCount,
			struct KFILE_FileObj *hFile)
{
	u32 dwBytesRead = 0;
	s32 cRetVal = 0;
	mm_segment_t fs;

	DBC_Require(pBuffer != NULL);

	GT_4trace(KFILE_debugMask, GT_4CLASS,
		  "KFILE_Read: buffer 0x%x, cSize 0x%x,"
		  "cCount 0x%x, hFile 0x%x\n", pBuffer, cSize, cCount, hFile);

	/* check for valid file handle */
	if (MEM_IsValidHandle(hFile, SIGNATURE)) {
		if ((cSize > 0) && (cCount > 0) && pBuffer) {
			/* read from file */
			fs = get_fs();
			set_fs(get_ds());
			dwBytesRead = hFile->fileDesc->f_op->read(hFile->
				      fileDesc, pBuffer, cSize *cCount,
				      &(hFile->fileDesc->f_pos));
			set_fs(fs);
			if (dwBytesRead) {
				cRetVal = dwBytesRead / cSize;
				hFile->curPos += dwBytesRead;
				DBC_Assert((dwBytesRead / cSize) <= \
					  (u32)cCount);
			} else {
				cRetVal = E_KFILE_ERROR;
				GT_0trace(KFILE_debugMask, GT_6CLASS,
					  "KFILE_Read: sys_read() failed\n");
			}
		} else {
			cRetVal = DSP_EINVALIDARG;
			GT_0trace(KFILE_debugMask, GT_6CLASS,
				  "KFILE_Read: Invalid argument(s)\n");
		}
	} else {
		cRetVal = E_KFILE_INVALIDHANDLE;
		GT_0trace(KFILE_debugMask, GT_6CLASS,
			  "KFILE_Read: invalid file handle\n");
	}

	return cRetVal;
}
Example #24
0
/*
 *  ======== STRM_Create ========
 *  Purpose:
 *      Create a STRM manager object.
 */
DSP_STATUS STRM_Create(OUT struct STRM_MGR **phStrmMgr, struct DEV_OBJECT *hDev)
{
	struct STRM_MGR *pStrmMgr;
	DSP_STATUS status = DSP_SOK;

	DBC_Require(cRefs > 0);
	DBC_Require(phStrmMgr != NULL);
	DBC_Require(hDev != NULL);

	GT_2trace(STRM_debugMask, GT_ENTER, "STRM_Create: phStrmMgr: "
		 "0x%x\thDev: 0x%x\n", phStrmMgr, hDev);
	*phStrmMgr = NULL;
	/* Allocate STRM manager object */
	MEM_AllocObject(pStrmMgr, struct STRM_MGR, STRMMGR_SIGNATURE);
	if (pStrmMgr == NULL) {
		status = DSP_EMEMORY;
		GT_0trace(STRM_debugMask, GT_6CLASS, "STRM_Create: "
			 "MEM_AllocObject() failed!\n ");
	} else {
		pStrmMgr->hDev = hDev;
	}
	/* Get Channel manager and WMD function interface */
	if (DSP_SUCCEEDED(status)) {
		status = DEV_GetChnlMgr(hDev, &(pStrmMgr->hChnlMgr));
		if (DSP_SUCCEEDED(status)) {
			(void) DEV_GetIntfFxns(hDev, &(pStrmMgr->pIntfFxns));
			DBC_Assert(pStrmMgr->pIntfFxns != NULL);
		} else {
			GT_1trace(STRM_debugMask, GT_6CLASS, "STRM_Create: "
				 "Failed to get channel manager! status = "
				 "0x%x\n", status);
		}
	}
	if (DSP_SUCCEEDED(status))
		status = SYNC_InitializeCS(&pStrmMgr->hSync);

	if (DSP_SUCCEEDED(status))
		*phStrmMgr = pStrmMgr;
	else
		DeleteStrmMgr(pStrmMgr);

	DBC_Ensure(DSP_SUCCEEDED(status) &&
		  (MEM_IsValidHandle((*phStrmMgr), STRMMGR_SIGNATURE) ||
		  (DSP_FAILED(status) && *phStrmMgr == NULL)));

	return status;
}
Example #25
0
/*
 *  ======== RMM_free ========
 */
bool RMM_free(struct RMM_TargetObj *target, u32 segid, u32 addr, u32 size,
	bool reserved)

{
	struct RMM_OvlySect *sect;
	bool retVal = true;

	DBC_Require(MEM_IsValidHandle(target, RMM_TARGSIGNATURE));

	DBC_Require(reserved || segid < target->numSegs);
	DBC_Require(reserved || (addr >= target->segTab[segid].base &&
		   (addr + size) <= (target->segTab[segid].base +
		   target->segTab[segid].length)));

	GT_5trace(RMM_debugMask, GT_ENTER,
		 "RMM_free(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
		 "0x%lx)\n", target, segid, addr, size, reserved);
	/*
	 *  Free or unreserve memory.
	 */
	if (!reserved) {
		retVal = freeBlock(target, segid, addr, size);
		if (retVal)
			target->segTab[segid].number--;

	} else {
		/* Unreserve memory */
		sect = (struct RMM_OvlySect *)LST_First(target->ovlyList);
		while (sect != NULL) {
			if (addr == sect->addr) {
				DBC_Assert(size == sect->size);
				/* Remove from list */
				LST_RemoveElem(target->ovlyList,
					      (struct LST_ELEM *)sect);
				MEM_Free(sect);
				break;
			}
			sect = (struct RMM_OvlySect *)LST_Next(target->ovlyList,
			       (struct LST_ELEM *)sect);
		}
		if (sect == NULL)
			retVal = false;

	}
	return retVal;
}
Example #26
0
/*
 *  ======== MSG_Init ========
 */
bool MSG_Init(void)
{
    DBC_Require(cRefs >= 0);

    if (cRefs == 0) {
        DBC_Assert(!MSG_debugMask.flags);
        GT_create(&MSG_debugMask, "MS");	/* "MS" for MSg */
    }

    cRefs++;

    GT_1trace(MSG_debugMask, GT_5CLASS, "MSG_Init(), ref count:  0x%x\n",
              cRefs);

    DBC_Ensure(cRefs >= 0);

    return true;
}
Example #27
0
/*
 *  ======== STRM_AllocateBuffer ========
 *  Purpose:
 *      Allocates buffers for a stream.
 */
DSP_STATUS STRM_AllocateBuffer(struct STRM_OBJECT *hStrm, u32 uSize,
				OUT u8 **apBuffer, u32 uNumBufs,
				struct PROCESS_CONTEXT *pr_ctxt)
{
	DSP_STATUS status = DSP_SOK;
	u32 uAllocated = 0;
	u32 i;

	HANDLE hSTRMRes;

	DBC_Require(cRefs > 0);
	DBC_Require(apBuffer != NULL);

	/*
	 * Allocate from segment specified at time of stream open.
	 */
	if (uSize == 0)
		status = DSP_ESIZE;

	if (DSP_FAILED(status))
		goto func_end;

	for (i = 0; i < uNumBufs; i++) {
		DBC_Assert(hStrm->hXlator != NULL);
		(void)CMM_XlatorAllocBuf(hStrm->hXlator, &apBuffer[i], uSize);
		if (apBuffer[i] == NULL) {
			status = DSP_EMEMORY;
			uAllocated = i;
			break;
		}
	}
	if (DSP_FAILED(status))
		STRM_FreeBuffer(hStrm, apBuffer, uAllocated, pr_ctxt);

	if (DSP_FAILED(status))
		goto func_end;

	if (DRV_GetSTRMResElement(hStrm, &hSTRMRes, pr_ctxt) !=
			DSP_ENOTFOUND)
		DRV_ProcUpdateSTRMRes(uNumBufs, hSTRMRes);

func_end:
	return status;
}
Example #28
0
/*
 *  ======== RMM_stat ========
 */
bool RMM_stat(struct RMM_TargetObj *target, enum DSP_MEMTYPE segid,
	     struct DSP_MEMSTAT *pMemStatBuf)
{
	struct RMM_Header *head;
	bool retVal = false;
	u32 maxFreeSize = 0;
	u32 totalFreeSize = 0;
	u32 freeBlocks = 0;

	DBC_Require(pMemStatBuf != NULL);
	DBC_Assert(target != NULL);

	if ((u32) segid < target->numSegs) {
		head = target->freeList[segid];

		/* Collect data from freeList */
		while (head != NULL) {
			maxFreeSize = max(maxFreeSize, head->size);
			totalFreeSize += head->size;
			freeBlocks++;
			head = head->next;
		}

		/* ulSize */
		pMemStatBuf->ulSize = target->segTab[segid].length;

		/* ulNumFreeBlocks */
		pMemStatBuf->ulNumFreeBlocks = freeBlocks;

		/* ulTotalFreeSize */
		pMemStatBuf->ulTotalFreeSize = totalFreeSize;

		/* ulLenMaxFreeBlock */
		pMemStatBuf->ulLenMaxFreeBlock = maxFreeSize;

		/* ulNumAllocBlocks */
		pMemStatBuf->ulNumAllocBlocks = target->segTab[segid].number;

		retVal = true;
	}

	return retVal;
}
Example #29
0
/*
 *  ======== COD_Init ========
 *  Purpose:
 *      Initialize the COD module's private state.
 *
 */
bool COD_Init(void)
{
	bool fRetVal = true;

	DBC_Require(cRefs >= 0);

	if (cRefs == 0) {
		DBC_Assert(!COD_debugMask.flags);
		GT_create(&COD_debugMask, "CO");
	}

	if (fRetVal)
		cRefs++;


	GT_1trace(COD_debugMask, GT_1CLASS,
		  "Entered COD_Init, ref count: 0x%x\n", cRefs);
	DBC_Ensure((fRetVal && cRefs > 0) || (!fRetVal && cRefs >= 0));
	return fRetVal;
}
Example #30
0
/*
 *  ======== STRM_Init ========
 *  Purpose:
 *      Initialize the STRM module.
 */
bool STRM_Init(void)
{
	bool fRetVal = true;

	DBC_Require(cRefs >= 0);

	if (cRefs == 0) {
#if GT_TRACE
		DBC_Assert(!STRM_debugMask.flags);
		GT_create(&STRM_debugMask, "ST");	/* "ST" for STrm */
#endif
	}

	if (fRetVal)
		cRefs++;

	DBC_Ensure((fRetVal && (cRefs > 0)) || (!fRetVal && (cRefs >= 0)));

	return fRetVal;
}