From 88f7819a86dfaa216243fdb96ed0fdf9e47a3a42 Mon Sep 17 00:00:00 2001
From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
Date: Fri, 15 Aug 2008 01:55:54 +0300
Subject: [PATCH 06/15] TI DSP BRIDGE: Platform Manager

Initial port from omapzoom
	http://omapzoom.org/gf/project/omapbridge

For details,
http://omapzoom.org/gf/project/omapbridge/docman/?subdir=3

Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
---
 drivers/dsp/bridge/pmgr/chnl.c    |  517 ++++++++++++
 drivers/dsp/bridge/pmgr/chnlobj.h |   71 ++
 drivers/dsp/bridge/pmgr/cmm.c     | 1290 +++++++++++++++++++++++++++++
 drivers/dsp/bridge/pmgr/cod.c     |  683 +++++++++++++++
 drivers/dsp/bridge/pmgr/dbl.c     | 1385 +++++++++++++++++++++++++++++++
 drivers/dsp/bridge/pmgr/dbll.c    | 1565 +++++++++++++++++++++++++++++++++++
 drivers/dsp/bridge/pmgr/dev.c     | 1475 +++++++++++++++++++++++++++++++++
 drivers/dsp/bridge/pmgr/dmm.c     |  646 +++++++++++++++
 drivers/dsp/bridge/pmgr/io.c      |  204 +++++
 drivers/dsp/bridge/pmgr/ioobj.h   |   52 ++
 drivers/dsp/bridge/pmgr/msg.c     |  173 ++++
 drivers/dsp/bridge/pmgr/msgobj.h  |   52 ++
 drivers/dsp/bridge/pmgr/wcd.c     | 1641 +++++++++++++++++++++++++++++++++++++
 13 files changed, 9754 insertions(+), 0 deletions(-)
 create mode 100644 drivers/dsp/bridge/pmgr/chnl.c
 create mode 100644 drivers/dsp/bridge/pmgr/chnlobj.h
 create mode 100644 drivers/dsp/bridge/pmgr/cmm.c
 create mode 100644 drivers/dsp/bridge/pmgr/cod.c
 create mode 100644 drivers/dsp/bridge/pmgr/dbl.c
 create mode 100644 drivers/dsp/bridge/pmgr/dbll.c
 create mode 100644 drivers/dsp/bridge/pmgr/dev.c
 create mode 100644 drivers/dsp/bridge/pmgr/dmm.c
 create mode 100644 drivers/dsp/bridge/pmgr/io.c
 create mode 100644 drivers/dsp/bridge/pmgr/ioobj.h
 create mode 100644 drivers/dsp/bridge/pmgr/msg.c
 create mode 100644 drivers/dsp/bridge/pmgr/msgobj.h
 create mode 100644 drivers/dsp/bridge/pmgr/wcd.c

diff --git a/drivers/dsp/bridge/pmgr/chnl.c b/drivers/dsp/bridge/pmgr/chnl.c
new file mode 100644
index 0000000..9742dac
--- /dev/null
+++ b/drivers/dsp/bridge/pmgr/chnl.c
@@ -0,0 +1,517 @@
+/*
+ * linux/drivers/dsp/bridge/pmgr/chnl.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.
+ */
+
+
+/*
+ *  ======== chnl.c ========
+ *  Description:
+ *      WCD channel interface: multiplexes data streams through the single
+ *      physical link managed by a 'Bridge mini-driver.
+ *
+ *  Public Functions:
+ *      CHNL_Close
+ *      CHNL_CloseOrphans
+ *      CHNL_Create
+ *      CHNL_Destroy
+ *      CHNL_Exit
+ *      CHNL_GetHandle
+ *      CHNL_GetProcessHandle
+ *      CHNL_Init
+ *      CHNL_Open
+ *
+ *  Notes:
+ *      This interface is basically a pass through to the WMD CHNL functions,
+ *      except for the CHNL_Get() accessor functions which call
+ *      WMD_CHNL_GetInfo().
+ *
+ *! Revision History:
+ *! ================
+ *! 24-Feb-2003 swa PMGR Code review comments incorporated.
+ *! 07-Jan-2002 ag  CHNL_CloseOrphans() now closes supported # of channels.
+ *! 17-Nov-2000 jeh Removed IRQ, shared memory stuff from CHNL_Create.
+ *! 28-Feb-2000 rr: New GT USage Implementation
+ *! 03-Feb-2000 rr: GT and Module init/exit Changes.(Done up front from
+ *!		    SERVICES)
+ *! 21-Jan-2000 ag: Added code review comments.
+ *! 13-Jan-2000 rr: CFG_Get/SetPrivateDword renamed to CFG_Get/SetDevObject.
+ *! 08-Dec-1999 ag: CHNL_[Alloc|Free]Buffer bufs taken from client process heap.
+ *! 02-Dec-1999 ag: Implemented CHNL_GetEventHandle().
+ *! 17-Nov-1999 ag: CHNL_AllocBuffer() allocs extra word for process mapping.
+ *! 28-Oct-1999 ag: WinCE port. Search for "WinCE" for changes(TBR).
+ *! 07-Jan-1998 gp: CHNL_[Alloc|Free]Buffer now call MEM_UMB functions.
+ *! 22-Oct-1997 gp: Removed requirement in CHNL_Open that hReserved1 != NULL.
+ *! 30-Aug-1997 cr: Renamed cfg.h wbwcd.h b/c of WINNT file name collision.
+ *! 10-Mar-1997 gp: Added GT trace.
+ *! 14-Jan-1997 gp: Updated based on code review feedback.
+ *! 03-Jan-1997 gp: Moved CHNL_AllocBuffer/CHNL_FreeBuffer code from udspsys.
+ *! 14-Dec-1996 gp: Added uChnlId parameter to CHNL_Open().
+ *! 09-Sep-1996 gp: Added CHNL_GetProcessHandle().
+ *! 15-Jul-1996 gp: Created.
+ */
+
+/*  ----------------------------------- Host OS */
+#include <host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <std.h>
+#include <dbdefs.h>
+#include <errbase.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dbc.h>
+#include <gt.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <cfg.h>
+#include <csl.h>
+#include <dpc.h>
+#include <isr.h>
+#include <list.h>
+#include <mem.h>
+#include <sync.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <proc.h>
+#include <dev.h>
+
+/*  ----------------------------------- Others */
+#include <chnlpriv.h>
+#include <chnlobj.h>
+
+/*  ----------------------------------- This */
+#include <chnl.h>
+
+/*  ----------------------------------- Globals */
+static u32 cRefs;
+#if GT_TRACE
+static struct GT_Mask CHNL_DebugMask = { NULL, NULL };	/* WCD CHNL Mask */
+#endif
+
+/*  ----------------------------------- Function Prototypes */
+static DSP_STATUS GetNumOpenChannels(struct CHNL_MGR *hChnlMgr,
+				    OUT u32 *pcOpenChannels);
+
+static DSP_STATUS GetNumChannels(struct CHNL_MGR *hChnlMgr,
+				 OUT u32 *pcChannels);
+
+/*
+ *  ======== 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 CHNL_Close(struct CHNL_OBJECT *hChnl)
+{
+	DSP_STATUS status;
+	struct CHNL_OBJECT_ *pChnl = (struct CHNL_OBJECT_ *)hChnl;
+	struct WMD_DRV_INTERFACE *pIntfFxns;
+
+	DBC_Require(cRefs > 0);
+
+	GT_1trace(CHNL_DebugMask, GT_ENTER,
+		  "Entered CHNL_Close:hChnl: 0x%x\n",
+		  hChnl);
+
+	if (CHNL_IsValidChnl(pChnl)) {
+		pIntfFxns = pChnl->pChnlMgr->pIntfFxns;
+		status = (*pIntfFxns->pfnChnlClose) (hChnl);
+	} else {
+		GT_0trace(CHNL_DebugMask, GT_7CLASS,
+			  "CHNL_Close:Invalid Handle\n");
+		status = DSP_EHANDLE;
+	}
+	GT_2trace(CHNL_DebugMask, GT_ENTER,
+		  "Exiting CHNL_Close:hChnl: 0x%x, status:"
+		  " 0x%x\n", hChnl, status);
+	return status;
+}
+
+/*
+ *  ======== CHNL_CloseOrphans ========
+ *  Purpose:
+ *      Close open channels orphaned by a closing process.
+ */
+DSP_STATUS CHNL_CloseOrphans(struct CHNL_MGR *hChnlMgr, HANDLE hProcess)
+{
+	u32 uChnlID;
+	DSP_STATUS status = DSP_SFALSE;
+	HANDLE hProc;
+	u32 cOpenChannels;
+	u32 cTotalChnls;
+	struct CHNL_OBJECT *hChnl;
+
+	DBC_Require(cRefs > 0);
+
+	GT_2trace(CHNL_DebugMask, GT_ENTER,
+		  "Enter CHNL_CloseOrphans hChnlMgr "
+		  "0x%x\t\nhProcess: 0x%x\n", hChnlMgr, hProcess);
+	if (!CHNL_IsValidMgr((struct CHNL_MGR_ *)hChnlMgr)) {
+		status = DSP_EHANDLE;
+		goto func_end;
+	}
+	if (DSP_SUCCEEDED(GetNumOpenChannels(hChnlMgr, &cOpenChannels)) &&
+			 (cOpenChannels > 0)) {
+		if (DSP_FAILED(GetNumChannels(hChnlMgr, &cTotalChnls)))
+			goto func_end;
+
+		/* For each channel (except for RMS), get process handle: */
+		for (uChnlID = 2; uChnlID < cTotalChnls; uChnlID++) {
+			if (DSP_FAILED(CHNL_GetHandle(hChnlMgr, uChnlID,
+			    &hChnl))) {
+				continue;
+			}
+			if (DSP_FAILED(CHNL_GetProcessHandle(hChnl,
+			    &hProc))) {
+				continue;
+			}
+			/* See if channel owned by this process: */
+			if (hProc == hProcess) {
+				/* If so, close it now. */
+				CHNL_Close(hChnl);
+				status = DSP_SOK;
+			}
+		}
+	}
+func_end:
+	GT_1trace(CHNL_DebugMask, GT_ENTER, "CHNL_CloseOrphans status 0x%x\n",
+		  status);
+
+	return status;
+}
+
+/*
+ *  ======== CHNL_Create ========
+ *  Purpose:
+ *      Create a channel manager object, responsible for opening new channels
+ *      and closing old ones for a given 'Bridge board.
+ */
+DSP_STATUS CHNL_Create(OUT struct CHNL_MGR **phChnlMgr,
+		       struct DEV_OBJECT *hDevObject,
+		       IN CONST struct CHNL_MGRATTRS *pMgrAttrs)
+{
+	DSP_STATUS status;
+	struct CHNL_MGR *hChnlMgr;
+	struct CHNL_MGR_ *pChnlMgr = NULL;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(phChnlMgr != NULL);
+	DBC_Require(pMgrAttrs != NULL);
+
+	GT_3trace(CHNL_DebugMask, GT_ENTER,
+		  "Entered CHNL_Create: phChnlMgr: 0x%x\t"
+		  "hDevObject: 0x%x\tpMgrAttrs:0x%x\n",
+		  phChnlMgr, hDevObject, pMgrAttrs);
+
+	*phChnlMgr = NULL;
+
+	/* Validate args: */
+	if ((0 < pMgrAttrs->cChannels) &&
+	   (pMgrAttrs->cChannels <= CHNL_MAXCHANNELS)) {
+		status = DSP_SOK;
+	} else if (pMgrAttrs->cChannels == 0) {
+		status = DSP_EINVALIDARG;
+		GT_0trace(CHNL_DebugMask, GT_7CLASS,
+			  "CHNL_Create:Invalid Args\n");
+	} else {
+		status = CHNL_E_MAXCHANNELS;
+		GT_0trace(CHNL_DebugMask, GT_7CLASS,
+			  "CHNL_Create:Error Max Channels\n");
+	}
+	if (pMgrAttrs->uWordSize == 0) {
+		status = CHNL_E_INVALIDWORDSIZE;
+		GT_0trace(CHNL_DebugMask, GT_7CLASS,
+			  "CHNL_Create:Invalid Word size\n");
+	}
+	if (DSP_SUCCEEDED(status)) {
+		status = DEV_GetChnlMgr(hDevObject, &hChnlMgr);
+		if (DSP_SUCCEEDED(status) && hChnlMgr != NULL)
+			status = CHNL_E_MGREXISTS;
+
+	}
+
+	if (DSP_SUCCEEDED(status)) {
+		struct WMD_DRV_INTERFACE *pIntfFxns;
+		DEV_GetIntfFxns(hDevObject, &pIntfFxns);
+		/* Let WMD channel module finish the create: */
+		status = (*pIntfFxns->pfnChnlCreate)(&hChnlMgr, hDevObject,
+			  pMgrAttrs);
+		if (DSP_SUCCEEDED(status)) {
+			/* Fill in WCD channel module's fields of the
+			 * CHNL_MGR structure */
+			pChnlMgr = (struct CHNL_MGR_ *)hChnlMgr;
+			pChnlMgr->pIntfFxns = pIntfFxns;
+			/* Finally, return the new channel manager handle: */
+			*phChnlMgr = hChnlMgr;
+			GT_1trace(CHNL_DebugMask, GT_1CLASS,
+				  "CHNL_Create: Success pChnlMgr:"
+				  "0x%x\n", pChnlMgr);
+		}
+	}
+
+	GT_2trace(CHNL_DebugMask, GT_ENTER,
+		  "Exiting CHNL_Create: pChnlMgr: 0x%x,"
+		  "status: 0x%x\n", pChnlMgr, status);
+	DBC_Ensure(DSP_FAILED(status) || CHNL_IsValidMgr(pChnlMgr));
+
+	return status;
+}
+
+/*
+ *  ======== CHNL_Destroy ========
+ *  Purpose:
+ *      Close all open channels, and destroy the channel manager.
+ */
+DSP_STATUS CHNL_Destroy(struct CHNL_MGR *hChnlMgr)
+{
+	struct CHNL_MGR_ *pChnlMgr = (struct CHNL_MGR_ *)hChnlMgr;
+	struct WMD_DRV_INTERFACE *pIntfFxns;
+	DSP_STATUS status;
+
+	DBC_Require(cRefs > 0);
+
+	GT_1trace(CHNL_DebugMask, GT_ENTER,
+		  "Entered CHNL_Destroy: hChnlMgr: 0x%x\n", hChnlMgr);
+	if (CHNL_IsValidMgr(pChnlMgr)) {
+		pIntfFxns = pChnlMgr->pIntfFxns;
+		/* Let WMD channel module destroy the CHNL_MGR: */
+		status = (*pIntfFxns->pfnChnlDestroy)(hChnlMgr);
+	} else {
+		GT_0trace(CHNL_DebugMask, GT_7CLASS,
+			  "CHNL_Destroy:Invalid Handle\n");
+		status = DSP_EHANDLE;
+	}
+
+	GT_2trace(CHNL_DebugMask, GT_ENTER,
+		  "Exiting CHNL_Destroy: pChnlMgr: 0x%x,"
+		  " status:0x%x\n", pChnlMgr, status);
+	DBC_Ensure(DSP_FAILED(status) || !CHNL_IsValidMgr(pChnlMgr));
+
+	return status;
+}
+
+/*
+ *  ======== CHNL_Exit ========
+ *  Purpose:
+ *      Discontinue usage of the CHNL module.
+ */
+void CHNL_Exit(void)
+{
+	DBC_Require(cRefs > 0);
+
+	cRefs--;
+
+	GT_1trace(CHNL_DebugMask, GT_5CLASS,
+		  "Entered CHNL_Exit, ref count: 0x%x\n", cRefs);
+
+	DBC_Ensure(cRefs >= 0);
+}
+
+/*
+ *  ======== CHNL_GetHandle ========
+ *  Purpose:
+ *      Retrieve the channel handle given the logical ID and channel manager.
+ */
+DSP_STATUS CHNL_GetHandle(struct CHNL_MGR *hChnlMgr, u32 uChnlID,
+			  OUT struct CHNL_OBJECT **phChnl)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct CHNL_MGR_ *pChnlMgr = (struct CHNL_MGR_ *)hChnlMgr;
+	struct WMD_DRV_INTERFACE *pIntfFxns;
+	struct CHNL_MGRINFO chnlMgrInfo;
+
+	DBC_Require(cRefs > 0);
+
+	GT_3trace(CHNL_DebugMask, GT_ENTER, "Entered CHNL_GetHandle: hChnlMgr: "
+		  "0x%x\tuChnlID: 0x%x\t\nphChnl: 0x%x\n", hChnlMgr, uChnlID,
+		  phChnl);
+	if (phChnl) {
+		*phChnl = NULL;
+		if (CHNL_IsValidMgr(pChnlMgr)) {
+			pIntfFxns = pChnlMgr->pIntfFxns;
+			status = (*pIntfFxns->pfnChnlGetMgrInfo)(hChnlMgr,
+				  uChnlID, &chnlMgrInfo);
+			if (DSP_SUCCEEDED(status))
+				*phChnl = chnlMgrInfo.hChnl;
+
+		} else {
+			status = DSP_EHANDLE;
+			GT_0trace(CHNL_DebugMask, GT_7CLASS,
+				  "CHNL_GetHandle:Invalid Handle\n");
+		}
+	} else {
+		status = DSP_EPOINTER;
+	}
+	GT_2trace(CHNL_DebugMask, GT_ENTER,
+		  "Exit CHNL_GetHandle: status: 0x%x\t\n"
+		  "hChnl: 0x%x\n", status, *phChnl);
+	return status;
+}
+
+/*
+ *  ======== CHNL_GetProcessHandle ========
+ *  Purpose:
+ *      Retrieve the handle of the process owning this channel.
+ */
+DSP_STATUS CHNL_GetProcessHandle(struct CHNL_OBJECT *hChnl,
+				 OUT HANDLE *phProcess)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct CHNL_OBJECT_ *pChnl = (struct CHNL_OBJECT_ *)hChnl;
+	struct WMD_DRV_INTERFACE *pIntfFxns;
+	struct CHNL_INFO chnlInfo;
+
+	DBC_Require(cRefs > 0);
+
+	GT_2trace(CHNL_DebugMask, GT_ENTER,
+		  "Enter CHNL_GetProcessHandle: hChnl: "
+		  "0x%x\t\n phProcess: 0x%x\n", hChnl, phProcess);
+	if (phProcess) {
+		*phProcess = NULL;
+		if (CHNL_IsValidChnl(pChnl)) {
+			pIntfFxns = pChnl->pChnlMgr->pIntfFxns;
+			status = (*pIntfFxns->pfnChnlGetInfo)(hChnl, &chnlInfo);
+			if (DSP_SUCCEEDED(status))
+				*phProcess = chnlInfo.hProcess;
+
+		} else {
+			status = DSP_EHANDLE;
+		}
+	} else {
+		status = DSP_EPOINTER;
+	}
+	GT_2trace(CHNL_DebugMask, GT_ENTER,
+		  "Exit CHNL_GetProcessHandle: status: "
+		  "0x%x\t\n phProcess: 0x%x\n", status, *phProcess);
+	return status;
+}
+
+/*
+ *  ======== CHNL_Init ========
+ *  Purpose:
+ *      Initialize the CHNL module's private state.
+ */
+bool CHNL_Init(void)
+{
+	bool fRetval = true;
+
+	DBC_Require(cRefs >= 0);
+
+	if (cRefs == 0) {
+		DBC_Assert(!CHNL_DebugMask.flags);
+		GT_create(&CHNL_DebugMask, "CH");   /* "CH" for CHannel */
+	}
+
+	if (fRetval)
+		cRefs++;
+
+	GT_1trace(CHNL_DebugMask, GT_5CLASS,
+		  "Entered CHNL_Init, ref count: 0x%x\n",
+		  cRefs);
+
+	DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0)));
+
+	return fRetval;
+}
+
+/*
+ *  ======== GetNumOpenChannels ========
+ *  Purpose:
+ *      Retrieve number of open channels
+ *  Parameters:
+ *      hChnlMgr:       Handle to a valid channel manager, or NULL.
+ *      pcOpenChannels: Location to store number of open channels.
+ *  Returns:
+ *      DSP_SOK:        Success;
+ *      DSP_EHANDLE:    Invalid hChnlMgr.
+ *      E_POINTER:      pcOpenChannels == NULL.
+ *  Requires:
+ *  Ensures:
+ *      DSP_SOK:        *pcOpenChannels points to a valid number
+ *                      if pcOpenChannels != NULL.
+ */
+static DSP_STATUS GetNumOpenChannels(struct CHNL_MGR *hChnlMgr,
+				     OUT u32 *pcOpenChannels)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct CHNL_MGR_ *pChnlMgr = (struct CHNL_MGR_ *)hChnlMgr;
+	struct WMD_DRV_INTERFACE *pIntfFxns;
+	struct CHNL_MGRINFO chnlMgrInfo;
+
+	DBC_Require(cRefs > 0);
+	if (pcOpenChannels) {
+		*pcOpenChannels = 0;
+		if (CHNL_IsValidMgr(pChnlMgr)) {
+			pIntfFxns = pChnlMgr->pIntfFxns;
+			status = (*pIntfFxns->pfnChnlGetMgrInfo)(hChnlMgr, 0,
+				 &chnlMgrInfo);
+			if (DSP_SUCCEEDED(status))
+				*pcOpenChannels = chnlMgrInfo.cOpenChannels;
+
+		} else {
+			status = DSP_EHANDLE;
+		}
+	} else {
+		status = DSP_EPOINTER;
+	}
+	return status;
+}
+
+/*
+ *  ======== GetNumOpenChannels ========
+ *  Purpose:
+ *      Retrieve number of total channels supported.
+ *  Parameters:
+ *      hChnlMgr:       Handle to a valid channel manager, or NULL.
+ *      pcChannels:     Location to store number of channels.
+ *  Returns:
+ *      DSP_SOK:        Success;
+ *      DSP_EHANDLE:    Invalid hChnlMgr.
+ *      E_POINTER:      pcOpenChannels == NULL.
+ *  Requires:
+ *  Ensures:
+ *      DSP_SOK:        *pcChannels points to a valid number
+ *                      if pcOpenChannels != NULL.
+ */
+static DSP_STATUS GetNumChannels(struct CHNL_MGR *hChnlMgr,
+				 OUT u32 *pcChannels)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct CHNL_MGR_ *pChnlMgr = (struct CHNL_MGR_ *)hChnlMgr;
+	struct WMD_DRV_INTERFACE *pIntfFxns;
+	struct CHNL_MGRINFO chnlMgrInfo;
+
+	DBC_Require(cRefs > 0);
+
+	if (pcChannels) {
+		*pcChannels = 0;
+		if (CHNL_IsValidMgr(pChnlMgr)) {
+			pIntfFxns = pChnlMgr->pIntfFxns;
+			status = (*pIntfFxns->pfnChnlGetMgrInfo)(hChnlMgr, 0,
+				 &chnlMgrInfo);
+			if (DSP_SUCCEEDED(status))
+				*pcChannels = chnlMgrInfo.cChannels;
+
+		} else {
+			status = DSP_EHANDLE;
+		}
+	} else {
+		status = DSP_EPOINTER;
+	}
+	return status;
+}
+
diff --git a/drivers/dsp/bridge/pmgr/chnlobj.h b/drivers/dsp/bridge/pmgr/chnlobj.h
new file mode 100644
index 0000000..267d5d9
--- /dev/null
+++ b/drivers/dsp/bridge/pmgr/chnlobj.h
@@ -0,0 +1,71 @@
+/*
+ * linux/drivers/dsp/bridge/pmgr/chnlobj.h
+ *
+ * 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.
+ */
+
+
+/*
+ *  ======== chnlobj.h ========
+ *  Description:
+ *      Structure subcomponents of channel class library channel objects which
+ *      are exposed to class driver from mini-driver.
+ *
+ *  Public Functions:
+ *      None.
+ *
+ *! Revision History:
+ *! ================
+ *! 24-Feb-2003 swa 	PMGR Code review comments incorporated.
+ *! 17-Nov-2000 jeh     Removed some fields from CHNL_MGR_ to match CHNL_MGR
+ *!                     structure defined in _chnl_sm.h.
+ *! 16-Jan-1997 gp:     Created from chnlpriv.h
+ */
+
+#ifndef CHNLOBJ_
+#define CHNLOBJ_
+
+#include <chnldefs.h>
+#include <wmd.h>
+
+/* Object validateion macros: */
+#define CHNL_IsValidMgr(h) \
+		((h != NULL) && ((h)->dwSignature == CHNL_MGRSIGNATURE))
+
+#define CHNL_IsValidChnl(h)\
+		((h != NULL) && ((h)->dwSignature == CHNL_SIGNATURE))
+
+/*
+ *  This struct is the first field in a CHNL_MGR struct, as implemented in
+ *  a WMD channel class library.  Other, implementation specific fields
+ *  follow this structure in memory.
+ */
+struct CHNL_MGR_ {
+	/* These must be the first fields in a CHNL_MGR struct: */
+	u32 dwSignature;	/* Used for object validation.   */
+	struct WMD_DRV_INTERFACE *pIntfFxns;	/* Function interface to WMD. */
+} ;
+
+/*
+ *  This struct is the first field in a CHNL_OBJECT struct, as implemented in
+ *  a WMD channel class library.  Other, implementation specific fields
+ *  follow this structure in memory.
+ */
+struct CHNL_OBJECT_ {
+	/* These must be the first fields in a CHNL_OBJECT struct: */
+	u32 dwSignature;	/* Used for object validation.      */
+	struct CHNL_MGR_ *pChnlMgr;	/* Pointer back to channel manager. */
+} ;
+
+#endif				/* CHNLOBJ_ */
+
diff --git a/drivers/dsp/bridge/pmgr/cmm.c b/drivers/dsp/bridge/pmgr/cmm.c
new file mode 100644
index 0000000..56d3c29
--- /dev/null
+++ b/drivers/dsp/bridge/pmgr/cmm.c
@@ -0,0 +1,1290 @@
+/*
+ * linux/drivers/dsp/bridge/pmgr/cmm.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.
+ */
+
+
+/*
+ *  ======== cmm.c ========
+ *  Purpose:
+ *      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 coelesced back to the appropriate heap when a buffer is
+ *      freed.
+ *
+ *  Public Functions:
+ *      CMM_CallocBuf
+ *      CMM_Create
+ *      CMM_Destroy
+ *      CMM_Exit
+ *      CMM_FreeBuf
+ *      CMM_GetHandle
+ *      CMM_GetInfo
+ *      CMM_Init
+ *      CMM_RegisterGPPSMSeg
+ *      CMM_UnRegisterGPPSMSeg
+ *
+ *      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.
+ *
+ *  Translator Routines:
+ *      CMM_XlatorAllocBuf
+ *      CMM_XlatorCreate
+ *      CMM_XlatorDelete
+ *      CMM_XlatorFreeBuf
+ *      CMM_XlatorInfo
+ *      CMM_XlatorTranslate
+ *
+ *  Private Functions:
+ *      AddToFreeList
+ *      GetAllocator
+ *      GetFreeBlock
+ *      GetNode
+ *      GetSlot
+ *      UnRegisterGPPSMSeg
+ *
+ *  Notes:
+ *      Va: Virtual address.
+ *      Pa: Physical or kernel system address.
+ *
+ *! Revision History:
+ *! ================
+ *! 24-Feb-2003 swa PMGR Code review comments incorporated.
+ *! 16-Feb-2002 ag  Code review cleanup.
+ *!                 PreOMAP address translation no longner supported.
+ *! 30-Jan-2002 ag  Updates to CMM_XlatorTranslate() per TII, ANSI C++
+ *!                 warnings.
+ *! 27-Jan-2002 ag  Removed unused CMM_[Alloc][Free]Desc() & #ifdef USELOOKUP,
+ *!                 & unused VALIDATECMM and VaPaConvert().
+ *!                 Removed bFastXlate from CMM_XLATOR. Always fast lookup.
+ *! 03-Jan-2002 ag  Clear SM in CMM_AllocBuf(). Renamed to CMM_CallocBuf().
+ *! 13-Nov-2001 ag  Now delete pNodeFreeListHead and nodes in CMM_Destroy().
+ *! 28-Aug-2001 ag  CMM_GetHandle() returns CMM Mgr hndle given HPROCESSOR.
+ *!                 Removed unused CMM_[Un]RegisterDSPSMSeg() &
+ *                  CMM_[Un}ReserveVirtSpace fxns. Some cleanup.
+ *! 12-Aug-2001 ag  Exposed CMM_UnRegisterGPP[DSP]SMSeg.
+ *! 13-Feb-2001 kc  DSP/BIOS Bridge name update.
+ *! 21-Dec-2000 rr  GetFreeBlock checks for pAllocator.
+ *! 09-Dec-2000 ag  Added GPPPA2DSPPA, DSPPA2GPPPA macros.
+ *! 05-Dec-2000 ag  CMM_XlatorDelete() optionally frees SM bufs and descriptors.
+ *! 30-Oct-2000 ag  Buf size bug fixed in CMM_AllocBuf() causing leak.
+ *!                 Revamped XlatorTranslate() routine.
+ *! 10-Oct-2000 ag  Added CMM_Xlator[xxx] functions.
+ *! 02-Aug-2000 ag  Created.
+ *!
+ */
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <std.h>
+#include <dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dbc.h>
+#include <errbase.h>
+#include <gt.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <cfg.h>
+#include <list.h>
+#include <mem.h>
+#include <prcs.h>
+#include <sync.h>
+#include <util.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dev.h>
+#include <proc.h>
+
+/*  ----------------------------------- This */
+#include <cmm.h>
+
+/*  ----------------------------------- Defines, Data Structures, Typedefs */
+/* Object signatures */
+#define CMMSIGNATURE       0x004d4d43	/* "CMM"   (in reverse) */
+#define SMEMSIGNATURE      0x4D454D53	/* "SMEM"  SM space     */
+#define CMMXLATESIGNATURE  0x584d4d43	/* "CMMX"  CMM Xlator   */
+
+#define NEXT_PA(pNode)   (pNode->dwPA + pNode->ulSize)
+
+/* 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 */
+	u32 dwSignature;	/* SMA allocator signature SMEMSIGNATURE */
+	unsigned int dwSmBase;		/* Start of physical SM block */
+	u32 ulSmSize;		/* Size of SM block in bytes */
+	unsigned int dwVmBase;		/* Start of VM block. (Dev driver
+				 * context for 'sma') */
+	u32 dwDSPPhysAddrOffset;	/* DSP PA to GPP PA offset for this
+					 * SM space */
+	/* CMM_ADDTO[SUBFROM]DSPPA, _POMAPEMIF2DSPBUS */
+	enum CMM_CNVTTYPE cFactor;
+	unsigned int dwDSPBase;	/* DSP virt base byte address */
+	u32 ulDSPSize;	/* DSP seg size in bytes */
+	struct CMM_OBJECT *hCmmMgr;	/* back ref to parent mgr */
+	struct LST_LIST *pFreeListHead;	/* node list of available memory */
+	struct LST_LIST *pInUseListHead;	/* node list of memory in use */
+} ;
+
+struct CMM_XLATOR {	/* Pa<->Va translator object */
+	u32 dwSignature;	/* "CMMX" */
+	struct CMM_OBJECT *hCmmMgr;  /* CMM object this translator associated */
+	/*
+	 *  Client process virtual base address that corresponds to phys SM
+	 *  base address for translator's ulSegId.
+	 *  Only 1 segment ID currently supported.
+	 */
+	unsigned int dwVirtBase;	/* virtual base address */
+	u32 ulVirtSize;	/* size of virt space in bytes */
+	u32 ulSegId;		/* Segment Id */
+} ;
+
+/* CMM Mgr */
+struct CMM_OBJECT {
+	u32 dwSignature;	/* Used for object validation */
+	/*
+	 * Cmm Lock is used to serialize access mem manager for multi-threads.
+	 */
+	struct SYNC_CSOBJECT *hCmmLock;	/* Lock to access cmm mgr */
+	struct LST_LIST *pNodeFreeListHead;	/* Free list of memory nodes */
+	u32 ulMinBlockSize;	/* Min SM block; default 16 bytes */
+	u32 dwPageSize;	/* Memory Page size (1k/4k) */
+	/* GPP SM segment ptrs */
+	struct CMM_ALLOCATOR *paGPPSMSegTab[CMM_MAXGPPSEGS];
+} ;
+
+/* Default CMM Mgr attributes */
+static struct CMM_MGRATTRS CMM_DFLTMGRATTRS = {
+	16	/* ulMinBlockSize, min block size(bytes) allocated by cmm mgr */
+};
+
+/* Default allocation attributes */
+static struct CMM_ATTRS CMM_DFLTALCTATTRS = {
+	1			/* ulSegId, default segment Id for allocator */
+};
+
+/* Address translator default attrs */
+struct CMM_XLATORATTRS CMM_DFLTXLATORATTRS = {
+	1,	/* ulSegId, does not have to match CMM_DFLTALCTATTRS ulSegId */
+	0,			/* dwDSPBufs */
+	0,			/* dwDSPBufSize */
+	NULL,			/* pVmBase */
+	0,			/* dwVmSize */
+};
+
+/* SM node representing a block of memory. */
+struct CMM_MNODE {
+	struct LST_ELEM link;		/* must be 1st element */
+	u32 dwPA;		/* Phys addr */
+	u32 dwVA;		/* Virtual address in device process context */
+	u32 ulSize;		/* SM block size in bytes */
+	HANDLE hClientProc;	/* Process that allocated this mem block */
+} ;
+
+
+/*  ----------------------------------- Globals */
+#if GT_TRACE
+static struct GT_Mask CMM_debugMask = { NULL, NULL };	/* GT trace variable */
+#endif
+
+static u32 cRefs;		/* module reference count */
+
+/*  ----------------------------------- Function Prototypes */
+static void AddToFreeList(struct CMM_ALLOCATOR *pAllocator,
+			  struct CMM_MNODE *pNode);
+static struct CMM_ALLOCATOR *GetAllocator(struct CMM_OBJECT *pCmmMgr,
+					  u32 ulSegId);
+static struct CMM_MNODE *GetFreeBlock(struct CMM_ALLOCATOR *pAllocator,
+				      u32 uSize);
+static struct CMM_MNODE *GetNode(struct CMM_OBJECT *pCmmMgr, u32 dwPA,
+				 u32 dwVA, u32 ulSize);
+/* get available slot for new allocator */
+static s32 GetSlot(struct CMM_OBJECT *hCmmMgr);
+static void UnRegisterGPPSMSeg(struct CMM_ALLOCATOR *pSMA);
+
+/*
+ *  ======== CMM_CallocBuf ========
+ *  Purpose:
+ *      Allocate a SM buffer, zero contents, and return the physical address
+ *      and optional driver context virtual address(ppBufVA).
+ *
+ *      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_CallocBuf(struct CMM_OBJECT *hCmmMgr, u32 uSize,
+		    struct CMM_ATTRS *pAttrs, OUT void **ppBufVA)
+{
+	struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr;
+	void *pBufPA = NULL;
+	struct CMM_MNODE *pNode = NULL;
+	struct CMM_MNODE *pNewNode = NULL;
+	struct CMM_ALLOCATOR *pAllocator = NULL;
+	u32 uDeltaSize;
+	u8 *pByte = NULL;
+	s32 cnt;
+
+	if (pAttrs == NULL)
+		pAttrs = &CMM_DFLTALCTATTRS;
+
+	if (ppBufVA != NULL)
+		*ppBufVA = NULL;
+
+	if ((MEM_IsValidHandle(pCmmMgr, CMMSIGNATURE)) && (uSize != 0)) {
+		if (pAttrs->ulSegId > 0) {
+			/* SegId > 0 is SM  */
+			/* get the allocator object for this segment id */
+			pAllocator = GetAllocator(pCmmMgr, pAttrs->ulSegId);
+			/* keep block size a multiple of ulMinBlockSize */
+			uSize = ((uSize - 1) & ~(pCmmMgr->ulMinBlockSize - 1))
+				+ pCmmMgr->ulMinBlockSize;
+			SYNC_EnterCS(pCmmMgr->hCmmLock);
+			pNode = GetFreeBlock(pAllocator, uSize);
+		}
+		if (pNode) {
+			uDeltaSize = (pNode->ulSize - uSize);
+			if (uDeltaSize >= pCmmMgr->ulMinBlockSize) {
+				/* create a new block with the leftovers and
+				 * add to freelist */
+				pNewNode = GetNode(pCmmMgr, pNode->dwPA + uSize,
+					   pNode->dwVA + uSize,
+					   (u32)uDeltaSize);
+				/* leftovers go free */
+				AddToFreeList(pAllocator, pNewNode);
+				/* adjust our node's size */
+				pNode->ulSize = 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.
+			 */
+			(void)PRCS_GetCurrentHandle(&pNode->hClientProc);
+			/* put our node on InUse list */
+			LST_PutTail(pAllocator->pInUseListHead,
+				   (struct LST_ELEM *)pNode);
+			pBufPA = (void *)pNode->dwPA;	/* physical address */
+			/* clear mem */
+			pByte = (u8 *)pNode->dwVA;
+			for (cnt = 0; cnt < (s32) uSize; cnt++, pByte++)
+				*pByte = 0;
+
+			if (ppBufVA != NULL) {
+				/* Virtual address */
+				*ppBufVA = (void *)pNode->dwVA;
+			}
+		}
+		GT_3trace(CMM_debugMask, GT_3CLASS,
+			  "CMM_CallocBuf dwPA %x, dwVA %x uSize"
+			  "%x\n", pNode->dwPA, pNode->dwVA, uSize);
+		SYNC_LeaveCS(pCmmMgr->hCmmLock);
+	}
+	return pBufPA;
+}
+
+/*
+ *  ======== CMM_Create ========
+ *  Purpose:
+ *      Create a communication memory manager object.
+ */
+DSP_STATUS CMM_Create(OUT struct CMM_OBJECT **phCmmMgr,
+		      struct DEV_OBJECT *hDevObject,
+		      IN CONST struct CMM_MGRATTRS *pMgrAttrs)
+{
+	struct CMM_OBJECT *pCmmObject = NULL;
+	DSP_STATUS status = DSP_SOK;
+	struct UTIL_SYSINFO sysInfo;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(phCmmMgr != NULL);
+
+	GT_3trace(CMM_debugMask, GT_ENTER,
+		  "CMM_Create: phCmmMgr: 0x%x\thDevObject: "
+		  "0x%x\tpMgrAttrs: 0x%x\n", phCmmMgr, hDevObject, pMgrAttrs);
+	*phCmmMgr = NULL;
+	/* create, zero, and tag a cmm mgr object */
+	MEM_AllocObject(pCmmObject, struct CMM_OBJECT, CMMSIGNATURE);
+	if (pCmmObject != NULL) {
+		if (pMgrAttrs == NULL)
+			pMgrAttrs = &CMM_DFLTMGRATTRS;	/* set defaults */
+
+		/* 4 bytes minimum */
+		DBC_Assert(pMgrAttrs->ulMinBlockSize >= 4);
+		/* save away smallest block allocation for this cmm mgr */
+		pCmmObject->ulMinBlockSize = pMgrAttrs->ulMinBlockSize;
+		/* save away the systems memory page size */
+		sysInfo.dwPageSize = PAGE_SIZE;
+		sysInfo.dwAllocationGranularity = PAGE_SIZE;
+		sysInfo.dwNumberOfProcessors = 1;
+		if (DSP_SUCCEEDED(status)) {
+			GT_1trace(CMM_debugMask, GT_5CLASS,
+				  "CMM_Create: Got system page size"
+				  "= 0x%x\t\n", sysInfo.dwPageSize);
+			pCmmObject->dwPageSize = sysInfo.dwPageSize;
+		} else {
+			GT_0trace(CMM_debugMask, GT_7CLASS,
+				  "CMM_Create: failed to get system"
+				  "page size\n");
+			pCmmObject->dwPageSize = 0;
+			status = DSP_EFAIL;
+		}
+		/* Note: DSP SM seg table(aDSPSMSegTab[]) zero'd by
+		 * MEM_AllocObject */
+		if (DSP_SUCCEEDED(status)) {
+			/* create node free list */
+			pCmmObject->pNodeFreeListHead = LST_Create();
+			if (pCmmObject->pNodeFreeListHead == NULL) {
+				GT_0trace(CMM_debugMask, GT_7CLASS,
+					  "CMM_Create: LST_Create() "
+					  "failed \n");
+				status = DSP_EMEMORY;
+			}
+		}
+		if (DSP_SUCCEEDED(status))
+			status = SYNC_InitializeCS(&pCmmObject->hCmmLock);
+
+		if (DSP_SUCCEEDED(status))
+			*phCmmMgr = pCmmObject;
+		else
+			CMM_Destroy(pCmmObject, true);
+
+	} else {
+		GT_0trace(CMM_debugMask, GT_6CLASS,
+			  "CMM_Create: Object Allocation "
+			  "Failure(CMM Object)\n");
+		status = DSP_EMEMORY;
+	}
+	return status;
+}
+
+/*
+ *  ======== CMM_Destroy ========
+ *  Purpose:
+ *      Release the communication memory manager resources.
+ */
+DSP_STATUS CMM_Destroy(struct CMM_OBJECT *hCmmMgr, bool bForce)
+{
+	struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr;
+	struct CMM_INFO tempInfo;
+	DSP_STATUS status = DSP_SOK;
+	s32 nSlot;
+	struct CMM_MNODE *pNode;
+
+	DBC_Require(cRefs > 0);
+	if (!MEM_IsValidHandle(hCmmMgr, CMMSIGNATURE)) {
+		status = DSP_EHANDLE;
+		return status;
+	}
+	SYNC_EnterCS(pCmmMgr->hCmmLock);
+	/* If not force then fail if outstanding allocations exist */
+	if (!bForce) {
+		/* Check for outstanding memory allocations */
+		status = CMM_GetInfo(hCmmMgr, &tempInfo);
+		if (DSP_SUCCEEDED(status)) {
+			if (tempInfo.ulTotalInUseCnt > 0) {
+				/* outstanding allocations */
+				status = DSP_EFAIL;
+			}
+		}
+	}
+	if (DSP_SUCCEEDED(status)) {
+		/* UnRegister SM allocator */
+		for (nSlot = 0; nSlot < CMM_MAXGPPSEGS; nSlot++) {
+			if (pCmmMgr->paGPPSMSegTab[nSlot] != NULL) {
+				UnRegisterGPPSMSeg(pCmmMgr->
+						   paGPPSMSegTab[nSlot]);
+				/* Set slot to NULL for future reuse */
+				pCmmMgr->paGPPSMSegTab[nSlot] = NULL;
+			}
+		}
+	}
+	if (pCmmMgr->pNodeFreeListHead != NULL) {
+		/* Free the free nodes */
+		while (!LST_IsEmpty(pCmmMgr->pNodeFreeListHead)) {
+			/* (struct LST_ELEM*) pNode =
+			 * LST_GetHead(pCmmMgr->pNodeFreeListHead);*/
+			pNode = (struct CMM_MNODE *)LST_GetHead(pCmmMgr->
+				 pNodeFreeListHead);
+			MEM_Free(pNode);
+		}
+		/* delete NodeFreeList list */
+		LST_Delete(pCmmMgr->pNodeFreeListHead);
+	}
+	SYNC_LeaveCS(pCmmMgr->hCmmLock);
+	if (DSP_SUCCEEDED(status)) {
+		/* delete CS & cmm mgr object */
+		SYNC_DeleteCS(pCmmMgr->hCmmLock);
+		MEM_FreeObject(pCmmMgr);
+	}
+	return status;
+}
+
+/*
+ *  ======== CMM_Exit ========
+ *  Purpose:
+ *      Discontinue usage of module; free resources when reference count
+ *      reaches 0.
+ */
+void CMM_Exit(void)
+{
+	DBC_Require(cRefs > 0);
+
+	cRefs--;
+
+	GT_1trace(CMM_debugMask, GT_ENTER,
+		  "exiting CMM_Exit,ref count:0x%x\n", cRefs);
+}
+
+/*
+ *  ======== CMM_FreeBuf ========
+ *  Purpose:
+ *      Free the given buffer.
+ */
+DSP_STATUS CMM_FreeBuf(struct CMM_OBJECT *hCmmMgr, void *pBufPA, u32 ulSegId)
+{
+	struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr;
+	DSP_STATUS status = DSP_EPOINTER;
+	struct CMM_MNODE *pCurNode = NULL;
+	struct CMM_ALLOCATOR *pAllocator = NULL;
+	struct CMM_ATTRS *pAttrs;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(pBufPA != NULL);
+	GT_1trace(CMM_debugMask, GT_ENTER, "CMM_FreeBuf pBufPA %x\n", pBufPA);
+	if (ulSegId == 0) {
+		pAttrs = &CMM_DFLTALCTATTRS;
+		ulSegId = pAttrs->ulSegId;
+	}
+	if (!(MEM_IsValidHandle(hCmmMgr, CMMSIGNATURE)) || !(ulSegId > 0)) {
+		status = DSP_EHANDLE;
+		return status;
+	}
+	/* get the allocator for this segment id */
+	pAllocator = GetAllocator(pCmmMgr, ulSegId);
+	if (pAllocator != NULL) {
+		SYNC_EnterCS(pCmmMgr->hCmmLock);
+		pCurNode = (struct CMM_MNODE *)LST_First(pAllocator->
+			    pInUseListHead);
+		while (pCurNode) {
+			if ((u32)pBufPA == pCurNode->dwPA) {
+				/* Found it */
+				LST_RemoveElem(pAllocator->pInUseListHead,
+					      (struct LST_ELEM *)pCurNode);
+				/* back to freelist */
+				AddToFreeList(pAllocator, pCurNode);
+				status = DSP_SOK;	/* all right! */
+				break;
+			}
+			/* next node. */
+			pCurNode = (struct CMM_MNODE *)LST_Next(pAllocator->
+				   pInUseListHead, (struct LST_ELEM *)pCurNode);
+		}
+		SYNC_LeaveCS(pCmmMgr->hCmmLock);
+	}
+	return status;
+}
+
+/*
+ *  ======== CMM_GetHandle ========
+ *  Purpose:
+ *      Return the communication memory manager object for this device.
+ *      This is typically called from the client process.
+ */
+DSP_STATUS CMM_GetHandle(DSP_HPROCESSOR hProcessor,
+			OUT struct CMM_OBJECT **phCmmMgr)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DEV_OBJECT *hDevObject;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(phCmmMgr != NULL);
+	if (hProcessor != NULL)
+		status = PROC_GetDevObject(hProcessor, &hDevObject);
+	else
+		hDevObject = DEV_GetFirst();	/* default */
+
+	if (DSP_SUCCEEDED(status))
+		status = DEV_GetCmmMgr(hDevObject, phCmmMgr);
+
+	return status;
+}
+
+/*
+ *  ======== CMM_GetInfo ========
+ *  Purpose:
+ *      Return the current memory utilization information.
+ */
+DSP_STATUS CMM_GetInfo(struct CMM_OBJECT *hCmmMgr,
+		       OUT struct CMM_INFO *pCmmInfo)
+{
+	struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr;
+	u32 ulSeg;
+	DSP_STATUS status = DSP_SOK;
+	struct CMM_ALLOCATOR *pAltr;
+	struct CMM_MNODE *pCurNode = NULL;
+
+	DBC_Require(pCmmInfo != NULL);
+
+	if (!MEM_IsValidHandle(hCmmMgr, CMMSIGNATURE)) {
+		status = DSP_EHANDLE;
+		return status;
+	}
+	SYNC_EnterCS(pCmmMgr->hCmmLock);
+	pCmmInfo->ulNumGPPSMSegs = 0;	/* # of SM segments */
+	pCmmInfo->ulTotalInUseCnt = 0;	/* Total # of outstanding alloc */
+	pCmmInfo->ulMinBlockSize = pCmmMgr->ulMinBlockSize; /* min block size */
+	/* check SM memory segments */
+	for (ulSeg = 1; ulSeg <= CMM_MAXGPPSEGS; ulSeg++) {
+		/* get the allocator object for this segment id */
+		pAltr = GetAllocator(pCmmMgr, ulSeg);
+		if (pAltr != NULL) {
+			pCmmInfo->ulNumGPPSMSegs++;
+			pCmmInfo->segInfo[ulSeg - 1].dwSegBasePa =
+				pAltr->dwSmBase - pAltr->ulDSPSize;
+			pCmmInfo->segInfo[ulSeg - 1].ulTotalSegSize =
+				pAltr->ulDSPSize + pAltr->ulSmSize;
+			pCmmInfo->segInfo[ulSeg - 1].dwGPPBasePA =
+				pAltr->dwSmBase;
+			pCmmInfo->segInfo[ulSeg - 1].ulGPPSize =
+				pAltr->ulSmSize;
+			pCmmInfo->segInfo[ulSeg - 1].dwDSPBaseVA =
+				pAltr->dwDSPBase;
+			pCmmInfo->segInfo[ulSeg - 1].ulDSPSize =
+				pAltr->ulDSPSize;
+			pCmmInfo->segInfo[ulSeg - 1].dwSegBaseVa =
+				pAltr->dwVmBase - pAltr->ulDSPSize;
+			pCmmInfo->segInfo[ulSeg - 1].ulInUseCnt = 0;
+			pCurNode = (struct CMM_MNODE *)LST_First(pAltr->
+				pInUseListHead);
+			/* Count inUse blocks */
+			while (pCurNode) {
+				pCmmInfo->ulTotalInUseCnt++;
+				pCmmInfo->segInfo[ulSeg - 1].ulInUseCnt++;
+				/* next node. */
+				pCurNode = (struct CMM_MNODE *)LST_Next(pAltr->
+					pInUseListHead,
+					(struct LST_ELEM *)pCurNode);
+			}
+		}
+	}		/* end for */
+	SYNC_LeaveCS(pCmmMgr->hCmmLock);
+	return status;
+}
+
+/*
+ *  ======== CMM_Init ========
+ *  Purpose:
+ *      Initializes private state of CMM module.
+ */
+bool CMM_Init(void)
+{
+	bool fRetval = true;
+
+	DBC_Require(cRefs >= 0);
+	if (cRefs == 0) {
+		/* Set the Trace mask */
+		/* "CM" for Comm Memory manager */
+		GT_create(&CMM_debugMask, "CM");
+	}
+	if (fRetval)
+		cRefs++;
+
+	GT_1trace(CMM_debugMask, GT_ENTER,
+		  "Entered CMM_Init,ref count:0x%x\n", cRefs);
+
+	DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0)));
+
+	return fRetval;
+}
+
+/*
+ *  ======== CMM_RegisterGPPSMSeg ========
+ *  Purpose:
+ *      Register a block of SM with the CMM to be used for later GPP SM
+ *      allocations.
+ */
+DSP_STATUS CMM_RegisterGPPSMSeg(struct CMM_OBJECT *hCmmMgr, u32 dwGPPBasePA,
+				u32 ulSize, u32 dwDSPAddrOffset,
+				enum CMM_CNVTTYPE cFactor, u32 dwDSPBase,
+				u32 ulDSPSize, u32 *pulSegId,
+				u32 dwGPPBaseVA)
+{
+	struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr;
+	struct CMM_ALLOCATOR *pSMA = NULL;
+	DSP_STATUS status = DSP_SOK;
+	struct CMM_MNODE *pNewNode;
+	s32 nSlot;
+
+	DBC_Require(ulSize > 0);
+	DBC_Require(pulSegId != NULL);
+	DBC_Require(dwGPPBasePA != 0);
+	DBC_Require(dwGPPBaseVA != 0);
+	DBC_Require((cFactor <= CMM_ADDTODSPPA) &&
+		   (cFactor >= CMM_SUBFROMDSPPA));
+	GT_6trace(CMM_debugMask, GT_ENTER,
+		  "CMM_RegisterGPPSMSeg dwGPPBasePA %x "
+		  "ulSize %x dwDSPAddrOffset %x dwDSPBase %x ulDSPSize %x "
+		  "dwGPPBaseVA %x\n", dwGPPBasePA, ulSize, dwDSPAddrOffset,
+		  dwDSPBase, ulDSPSize, dwGPPBaseVA);
+	if (!MEM_IsValidHandle(hCmmMgr, CMMSIGNATURE)) {
+		status = DSP_EHANDLE;
+		return status;
+	}
+	/* make sure we have room for another allocator */
+	SYNC_EnterCS(pCmmMgr->hCmmLock);
+	nSlot = GetSlot(pCmmMgr);
+	if (nSlot < 0) {
+		/* get a slot number */
+		status = DSP_EFAIL;
+		goto func_end;
+	}
+	/* Check if input ulSize is big enough to alloc at least one block */
+	if (DSP_SUCCEEDED(status)) {
+		if (ulSize < pCmmMgr->ulMinBlockSize) {
+			GT_0trace(CMM_debugMask, GT_7CLASS,
+				  "CMM_RegisterGPPSMSeg: "
+				  "ulSize too small\n");
+			status = DSP_EINVALIDARG;
+			goto func_end;
+		}
+	}
+	if (DSP_SUCCEEDED(status)) {
+		/* create, zero, and tag an SM allocator object */
+		MEM_AllocObject(pSMA, struct CMM_ALLOCATOR, SMEMSIGNATURE);
+	}
+	if (pSMA != NULL) {
+		pSMA->hCmmMgr = hCmmMgr;	/* ref to parent */
+		pSMA->dwSmBase = dwGPPBasePA;	/* SM Base phys */
+		pSMA->ulSmSize = ulSize;	/* SM segment size in bytes */
+		pSMA->dwVmBase = dwGPPBaseVA;
+		pSMA->dwDSPPhysAddrOffset = dwDSPAddrOffset;
+		pSMA->cFactor = cFactor;
+		pSMA->dwDSPBase = dwDSPBase;
+		pSMA->ulDSPSize = ulDSPSize;
+		if (pSMA->dwVmBase == 0) {
+			GT_0trace(CMM_debugMask, GT_7CLASS,
+				  "CMM_RegisterGPPSMSeg: Error"
+				  "MEM_LinearAddress()\n");
+			status = DSP_EFAIL;
+			goto func_end;
+		}
+		if (DSP_SUCCEEDED(status)) {
+			/* return the actual segment identifier */
+			*pulSegId = (u32) nSlot + 1;
+			/* create memory free list */
+			pSMA->pFreeListHead = LST_Create();
+			if (pSMA->pFreeListHead == NULL) {
+				GT_0trace(CMM_debugMask, GT_7CLASS,
+					  "CMM_RegisterGPPSMSeg: "
+					  "Out Of Memory \n");
+				status = DSP_EMEMORY;
+				goto func_end;
+			}
+		}
+		if (DSP_SUCCEEDED(status)) {
+			/* create memory in-use list */
+			pSMA->pInUseListHead = LST_Create();
+			if (pSMA->pInUseListHead == NULL) {
+				GT_0trace(CMM_debugMask, GT_7CLASS,
+					  "CMM_RegisterGPPSMSeg: "
+					  "LST_Create failed\n");
+				status = DSP_EMEMORY;
+				goto func_end;
+			}
+		}
+		if (DSP_SUCCEEDED(status)) {
+			/* Get a mem node for this hunk-o-memory */
+			pNewNode = GetNode(pCmmMgr, dwGPPBasePA,
+					   pSMA->dwVmBase, ulSize);
+			/* Place node on the SM allocator's free list */
+			if (pNewNode) {
+				LST_PutTail(pSMA->pFreeListHead,
+					   (struct LST_ELEM *)pNewNode);
+			} else {
+				status = DSP_EMEMORY;
+				goto func_end;
+			}
+		}
+		if (DSP_FAILED(status)) {
+			/* Cleanup allocator */
+			UnRegisterGPPSMSeg(pSMA);
+		}
+	} else {
+		GT_0trace(CMM_debugMask, GT_6CLASS,
+			  "CMM_RegisterGPPSMSeg: SMA Object "
+			  "Allocation Failure\n");
+		status = DSP_EMEMORY;
+		goto func_end;
+	}
+	 /* make entry */
+	if (DSP_SUCCEEDED(status))
+		pCmmMgr->paGPPSMSegTab[nSlot] = pSMA;
+
+func_end:
+	SYNC_LeaveCS(pCmmMgr->hCmmLock);
+	return status;
+}
+
+/*
+ *  ======== CMM_UnRegisterGPPSMSeg ========
+ *  Purpose:
+ *      UnRegister GPP SM segments with the CMM.
+ */
+DSP_STATUS CMM_UnRegisterGPPSMSeg(struct CMM_OBJECT *hCmmMgr, u32 ulSegId)
+{
+	struct CMM_OBJECT *pCmmMgr = (struct CMM_OBJECT *)hCmmMgr;
+	DSP_STATUS status = DSP_SOK;
+	struct CMM_ALLOCATOR *pSMA;
+	u32 ulId = ulSegId;
+
+	DBC_Require(ulSegId > 0);
+	if (MEM_IsValidHandle(hCmmMgr, CMMSIGNATURE)) {
+		if (ulSegId == CMM_ALLSEGMENTS)
+			ulId = 1;
+
+		if ((ulId > 0) && (ulId <= CMM_MAXGPPSEGS)) {
+			while (ulId <= CMM_MAXGPPSEGS) {
+				SYNC_EnterCS(pCmmMgr->hCmmLock);
+				/* slot = segId-1 */
+				pSMA = pCmmMgr->paGPPSMSegTab[ulId - 1];
+				if (pSMA != NULL) {
+					UnRegisterGPPSMSeg(pSMA);
+					/* Set alctr ptr to NULL for future
+					 * reuse */
+					pCmmMgr->paGPPSMSegTab[ulId - 1] = NULL;
+				} else if (ulSegId != CMM_ALLSEGMENTS) {
+					status = DSP_EFAIL;
+				}
+				SYNC_LeaveCS(pCmmMgr->hCmmLock);
+				if (ulSegId != CMM_ALLSEGMENTS)
+					break;
+
+				ulId++;
+			}	/* end while */
+		} else {
+			status = DSP_EINVALIDARG;
+			GT_0trace(CMM_debugMask, GT_7CLASS,
+				  "CMM_UnRegisterGPPSMSeg: Bad "
+				  "segment Id\n");
+		}
+	} else {
+		status = DSP_EHANDLE;
+	}
+	return status;
+}
+
+/*
+ *  ======== UnRegisterGPPSMSeg ========
+ *  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 UnRegisterGPPSMSeg(struct CMM_ALLOCATOR *pSMA)
+{
+	struct CMM_MNODE *pCurNode = NULL;
+	struct CMM_MNODE *pNextNode = NULL;
+
+	DBC_Require(pSMA != NULL);
+	if (pSMA->pFreeListHead != NULL) {
+		/* free nodes on free list */
+		pCurNode = (struct CMM_MNODE *)LST_First(pSMA->pFreeListHead);
+		while (pCurNode) {
+			pNextNode = (struct CMM_MNODE *)LST_Next(pSMA->
+				     pFreeListHead,
+				    (struct LST_ELEM *)pCurNode);
+			LST_RemoveElem(pSMA->pFreeListHead,
+				      (struct LST_ELEM *)pCurNode);
+			MEM_Free((void *) pCurNode);
+			/* next node. */
+			pCurNode = pNextNode;
+		}
+		LST_Delete(pSMA->pFreeListHead);	/* delete freelist */
+		/* free nodes on InUse list */
+		pCurNode = (struct CMM_MNODE *)LST_First(pSMA->pInUseListHead);
+		while (pCurNode) {
+			pNextNode = (struct CMM_MNODE *)LST_Next(pSMA->
+				    pInUseListHead,
+				    (struct LST_ELEM *)pCurNode);
+			LST_RemoveElem(pSMA->pInUseListHead,
+				      (struct LST_ELEM *)pCurNode);
+			MEM_Free((void *) pCurNode);
+			/* next node. */
+			pCurNode = pNextNode;
+		}
+		LST_Delete(pSMA->pInUseListHead);	/* delete InUse list */
+	}
+	if ((void *) pSMA->dwVmBase != NULL)
+		MEM_UnmapLinearAddress((void *) pSMA->dwVmBase);
+
+	/* Free allocator itself */
+	MEM_FreeObject(pSMA);
+}
+
+/*
+ *  ======== GetSlot ========
+ *  Purpose:
+ *      An available slot # is returned. Returns negative on failure.
+ */
+static s32 GetSlot(struct CMM_OBJECT *pCmmMgr)
+{
+	s32 nSlot = -1;		/* neg on failure */
+	DBC_Require(pCmmMgr != NULL);
+	/* get first available slot in cmm mgr SMSegTab[] */
+	for (nSlot = 0; nSlot < CMM_MAXGPPSEGS; nSlot++) {
+		if (pCmmMgr->paGPPSMSegTab[nSlot] == NULL)
+			break;
+
+	}
+	if (nSlot == CMM_MAXGPPSEGS) {
+		GT_0trace(CMM_debugMask, GT_7CLASS,
+			  "CMM_RegisterGPPSMSeg: Allocator "
+			  "entry failure, max exceeded\n");
+		nSlot = -1;	/* failed */
+	}
+	return nSlot;
+}
+
+/*
+ *  ======== GetNode ========
+ *  Purpose:
+ *      Get a memory node from freelist or create a new one.
+ */
+static struct CMM_MNODE *GetNode(struct CMM_OBJECT *pCmmMgr, u32 dwPA,
+				 u32 dwVA, u32 ulSize)
+{
+	struct CMM_MNODE *pNode = NULL;
+
+	DBC_Require(pCmmMgr != NULL);
+	DBC_Require(dwPA != 0);
+	DBC_Require(dwVA != 0);
+	DBC_Require(ulSize != 0);
+	/* Check cmm mgr's node freelist */
+	if (LST_IsEmpty(pCmmMgr->pNodeFreeListHead)) {
+		pNode = (struct CMM_MNODE *)MEM_Calloc(sizeof(struct CMM_MNODE),
+			MEM_PAGED);
+	} else {
+		/* surely a valid element */
+		/* (struct LST_ELEM*) pNode = LST_GetHead(pCmmMgr->
+		 * pNodeFreeListHead);*/
+		pNode = (struct CMM_MNODE *)LST_GetHead(pCmmMgr->
+			pNodeFreeListHead);
+	}
+	if (pNode == NULL) {
+		GT_0trace(CMM_debugMask, GT_7CLASS, "GetNode: Out Of Memory\n");
+	} else {
+		LST_InitElem((struct LST_ELEM *) pNode);	/* set self */
+		pNode->dwPA = dwPA;	/* Physical addr of start of block */
+		pNode->dwVA = dwVA;	/* Virtual   "            "        */
+		pNode->ulSize = ulSize;	/* Size of block */
+	}
+	return pNode;
+}
+
+/*
+ *  ======== DeleteNode ========
+ *  Purpose:
+ *      Put a memory node on the cmm nodelist for later use.
+ *      Doesn't actually delete the node. Heap thrashing friendly.
+ */
+static void DeleteNode(struct CMM_OBJECT *pCmmMgr, struct CMM_MNODE *pNode)
+{
+	DBC_Require(pNode != NULL);
+	LST_InitElem((struct LST_ELEM *) pNode);	/* init .self ptr */
+	LST_PutTail(pCmmMgr->pNodeFreeListHead, (struct LST_ELEM *) pNode);
+}
+
+/*
+ * ====== GetFreeBlock ========
+ *  Purpose:
+ *      Scan the free block list and return the first block that satisfies
+ *      the size.
+ */
+static struct CMM_MNODE *GetFreeBlock(struct CMM_ALLOCATOR *pAllocator,
+				      u32 uSize)
+{
+	if (pAllocator) {
+		struct CMM_MNODE *pCurNode = (struct CMM_MNODE *)
+					LST_First(pAllocator->pFreeListHead);
+		while (pCurNode) {
+			if (uSize <= (u32) pCurNode->ulSize) {
+				LST_RemoveElem(pAllocator->pFreeListHead,
+					      (struct LST_ELEM *)pCurNode);
+				return pCurNode;
+			}
+			/* next node. */
+			pCurNode = (struct CMM_MNODE *)LST_Next(pAllocator->
+				    pFreeListHead, (struct LST_ELEM *)pCurNode);
+		}
+	}
+	return NULL;
+}
+
+/*
+ *  ======== AddToFreeList ========
+ *  Purpose:
+ *      Coelesce node into the freelist in ascending size order.
+ */
+static void AddToFreeList(struct CMM_ALLOCATOR *pAllocator,
+			  struct CMM_MNODE *pNode)
+{
+	struct CMM_MNODE *pNodePrev = NULL;
+	struct CMM_MNODE *pNodeNext = NULL;
+	struct CMM_MNODE *pCurNode;
+	u32 dwThisPA;
+	u32 dwNextPA;
+
+	DBC_Require(pNode != NULL);
+	DBC_Require(pAllocator != NULL);
+	dwThisPA = pNode->dwPA;
+	dwNextPA = NEXT_PA(pNode);
+	pCurNode = (struct CMM_MNODE *)LST_First(pAllocator->pFreeListHead);
+	while (pCurNode) {
+		if (dwThisPA == NEXT_PA(pCurNode)) {
+			/* found the block ahead of this one */
+			pNodePrev = pCurNode;
+		} else if (dwNextPA == pCurNode->dwPA) {
+			pNodeNext = pCurNode;
+		}
+		if ((pNodePrev == NULL) || (pNodeNext == NULL)) {
+			/* next node. */
+			pCurNode = (struct CMM_MNODE *)LST_Next(pAllocator->
+				    pFreeListHead, (struct LST_ELEM *)pCurNode);
+		} else {
+			/* got 'em */
+			break;
+		}
+	}			/* while */
+	if (pNodePrev != NULL) {
+		/* combine with previous block */
+		LST_RemoveElem(pAllocator->pFreeListHead,
+			      (struct LST_ELEM *)pNodePrev);
+		/* grow node to hold both */
+		pNode->ulSize += pNodePrev->ulSize;
+		pNode->dwPA = pNodePrev->dwPA;
+		pNode->dwVA = pNodePrev->dwVA;
+		/* place node on mgr nodeFreeList */
+		DeleteNode((struct CMM_OBJECT *)pAllocator->hCmmMgr, pNodePrev);
+	}
+	if (pNodeNext != NULL) {
+		/* combine with next block */
+		LST_RemoveElem(pAllocator->pFreeListHead,
+			      (struct LST_ELEM *)pNodeNext);
+		/* grow da node */
+		pNode->ulSize += pNodeNext->ulSize;
+		/* place node on mgr nodeFreeList */
+		DeleteNode((struct CMM_OBJECT *)pAllocator->hCmmMgr, pNodeNext);
+	}
+	/* Now, let's add to freelist in increasing size order */
+	pCurNode = (struct CMM_MNODE *)LST_First(pAllocator->pFreeListHead);
+	while (pCurNode) {
+		if (pNode->ulSize <= pCurNode->ulSize)
+			break;
+
+		/* next node. */
+		pCurNode = (struct CMM_MNODE *)LST_Next(pAllocator->
+			   pFreeListHead, (struct LST_ELEM *)pCurNode);
+	}
+	/* if pCurNode is NULL then add our pNode to the end of the freelist */
+	if (pCurNode == NULL) {
+		LST_PutTail(pAllocator->pFreeListHead,
+			   (struct LST_ELEM *)pNode);
+	} else {
+		/* insert our node before the current traversed node */
+		LST_InsertBefore(pAllocator->pFreeListHead,
+				(struct LST_ELEM *)pNode,
+				(struct LST_ELEM *)pCurNode);
+	}
+}
+
+/*
+ * ======== GetAllocator ========
+ *  Purpose:
+ *      Return the allocator for the given SM Segid.
+ *      SegIds:  1,2,3..max.
+ */
+static struct CMM_ALLOCATOR *GetAllocator(struct CMM_OBJECT *pCmmMgr,
+					  u32 ulSegId)
+{
+	struct CMM_ALLOCATOR *pAllocator = NULL;
+
+	DBC_Require(pCmmMgr != NULL);
+	DBC_Require((ulSegId > 0) && (ulSegId <= CMM_MAXGPPSEGS));
+	pAllocator = pCmmMgr->paGPPSMSegTab[ulSegId - 1];
+	if (pAllocator != NULL) {
+		/* make sure it's for real */
+		if (!MEM_IsValidHandle(pAllocator, SMEMSIGNATURE)) {
+			pAllocator = NULL;
+			DBC_Assert(false);
+		}
+	}
+	return pAllocator;
+}
+
+/*
+ *  ======== CMM_XlatorCreate ========
+ *  Purpose:
+ *      Create an address translator object.
+ */
+DSP_STATUS CMM_XlatorCreate(OUT struct CMM_XLATOROBJECT **phXlator,
+				struct CMM_OBJECT *hCmmMgr,
+				struct CMM_XLATORATTRS *pXlatorAttrs)
+{
+	struct CMM_XLATOR *pXlatorObject = NULL;
+	DSP_STATUS status = DSP_SOK;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(phXlator != NULL);
+	DBC_Require(hCmmMgr != NULL);
+	GT_3trace(CMM_debugMask, GT_ENTER,
+		  "CMM_XlatorCreate: phXlator: 0x%x\t"
+		  "phCmmMgr: 0x%x\tpXlAttrs: 0x%x\n", phXlator,
+		  hCmmMgr, pXlatorAttrs);
+	*phXlator = NULL;
+	if (pXlatorAttrs == NULL)
+		pXlatorAttrs = &CMM_DFLTXLATORATTRS;	/* set defaults */
+
+	MEM_AllocObject(pXlatorObject, struct CMM_XLATOR, CMMXLATESIGNATURE);
+	if (pXlatorObject != NULL) {
+		pXlatorObject->hCmmMgr = hCmmMgr;	/* ref back to CMM */
+		pXlatorObject->ulSegId = pXlatorAttrs->ulSegId;	/* SM segId */
+	} else {
+		GT_0trace(CMM_debugMask, GT_6CLASS,
+			  "CMM_XlatorCreate: Object Allocation"
+			  "Failure(CMM Xlator)\n");
+		status = DSP_EMEMORY;
+	}
+	if (DSP_SUCCEEDED(status))
+		*phXlator = (struct CMM_XLATOROBJECT *) pXlatorObject;
+
+	return status;
+}
+
+/*
+ *  ======== CMM_XlatorDelete ========
+ *  Purpose:
+ *      Free the Xlator resources.
+ *      VM gets freed later.
+ */
+DSP_STATUS CMM_XlatorDelete(struct CMM_XLATOROBJECT *hXlator, bool bForce)
+{
+	struct CMM_XLATOR *pXlator = (struct CMM_XLATOR *)hXlator;
+	DSP_STATUS status = DSP_SOK;
+
+	DBC_Require(cRefs > 0);
+
+	if (MEM_IsValidHandle(pXlator, CMMXLATESIGNATURE)) {
+		MEM_FreeObject(pXlator);
+	} else {
+		status = DSP_EHANDLE;
+	}
+
+	return status;
+}
+
+/*
+ *  ======== CMM_XlatorAllocBuf ========
+ */
+void *CMM_XlatorAllocBuf(struct CMM_XLATOROBJECT *hXlator, void *pVaBuf,
+			u32 uPaSize)
+{
+	struct CMM_XLATOR *pXlator = (struct CMM_XLATOR *)hXlator;
+	void *pBuf = NULL;
+	struct CMM_ATTRS attrs;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(hXlator != NULL);
+	DBC_Require(pXlator->hCmmMgr != NULL);
+	DBC_Require(pVaBuf != NULL);
+	DBC_Require(uPaSize > 0);
+	DBC_Require(pXlator->ulSegId > 0);
+
+	if (MEM_IsValidHandle(pXlator, CMMXLATESIGNATURE)) {
+		attrs.ulSegId = pXlator->ulSegId;
+		*(volatile u32 *)pVaBuf = 0;
+		/* Alloc SM */
+		pBuf = CMM_CallocBuf(pXlator->hCmmMgr, uPaSize, &attrs,  NULL);
+		if (pBuf) {
+			/* convert to translator(node/strm) process Virtual
+			 * address */
+			*(volatile u32 **)pVaBuf =
+				 (u32 *)CMM_XlatorTranslate(hXlator,
+							      pBuf, CMM_PA2VA);
+		}
+	}
+	return pBuf;
+}
+
+/*
+ *  ======== CMM_XlatorFreeBuf ========
+ *  Purpose:
+ *      Free the given SM buffer and descriptor.
+ *      Does not free virtual memory.
+ */
+DSP_STATUS CMM_XlatorFreeBuf(struct CMM_XLATOROBJECT *hXlator, void *pBufVa)
+{
+	struct CMM_XLATOR *pXlator = (struct CMM_XLATOR *)hXlator;
+	DSP_STATUS status = DSP_EFAIL;
+	void *pBufPa = NULL;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(pBufVa != NULL);
+	DBC_Require(pXlator->ulSegId > 0);
+
+	if (MEM_IsValidHandle(pXlator, CMMXLATESIGNATURE)) {
+		/* convert Va to Pa so we can free it. */
+		pBufPa = CMM_XlatorTranslate(hXlator, pBufVa, CMM_VA2PA);
+		if (pBufPa) {
+			status = CMM_FreeBuf(pXlator->hCmmMgr, pBufPa,
+					     pXlator->ulSegId);
+			if (DSP_FAILED(status)) {
+				/* Uh oh, this shouldn't happen. Descriptor
+				 * gone! */
+				GT_2trace(CMM_debugMask, GT_7CLASS,
+					"Cannot free DMA/ZCPY buffer"
+					"not allocated by MPU. PA %x, VA %x\n",
+					pBufPa, pBufVa);
+				DBC_Assert(false);   /* CMM is leaking mem! */
+			}
+		}
+	}
+	return status;
+}
+
+/*
+ *  ======== CMM_XlatorInfo ========
+ *  Purpose:
+ *      Set/Get translator info.
+ */
+DSP_STATUS CMM_XlatorInfo(struct CMM_XLATOROBJECT *hXlator, IN OUT u8 **pAddr,
+			 u32 ulSize, u32 uSegId, bool bSetInfo)
+{
+	struct CMM_XLATOR *pXlator = (struct CMM_XLATOR *)hXlator;
+	DSP_STATUS status = DSP_SOK;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(pAddr != NULL);
+	DBC_Require((uSegId > 0) && (uSegId <= CMM_MAXGPPSEGS));
+
+	if (MEM_IsValidHandle(pXlator, CMMXLATESIGNATURE)) {
+		if (bSetInfo) {
+			/* set translators virtual address range */
+			pXlator->dwVirtBase = (u32)*pAddr;
+			pXlator->ulVirtSize = ulSize;
+			GT_2trace(CMM_debugMask, GT_3CLASS,
+				  "pXlator->dwVirtBase %x, "
+				  "ulVirtSize %x\n", pXlator->dwVirtBase,
+				  pXlator->ulVirtSize);
+		} else {	/* return virt base address */
+			*pAddr = (u8 *)pXlator->dwVirtBase;
+		}
+	} else {
+		status = DSP_EHANDLE;
+	}
+	return status;
+}
+
+/*
+ *  ======== CMM_XlatorTranslate ========
+ */
+void *CMM_XlatorTranslate(struct CMM_XLATOROBJECT *hXlator, void *pAddr,
+			  enum CMM_XLATETYPE xType)
+{
+	u32 dwAddrXlate = 0;
+	struct CMM_XLATOR *pXlator = (struct CMM_XLATOR *)hXlator;
+	struct CMM_OBJECT *pCmmMgr = NULL;
+	struct CMM_ALLOCATOR *pAlctr = NULL;
+	u32 dwOffset = 0;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(pAddr != NULL);
+	DBC_Require((xType >= CMM_VA2PA) && (xType <= CMM_DSPPA2PA));
+
+	if (!MEM_IsValidHandle(pXlator, CMMXLATESIGNATURE))
+		goto loop_cont;
+
+	pCmmMgr = (struct CMM_OBJECT *)pXlator->hCmmMgr;
+	/* get this translator's default SM allocator */
+	DBC_Assert(pXlator->ulSegId > 0);
+	pAlctr = pCmmMgr->paGPPSMSegTab[pXlator->ulSegId - 1];
+	if (!MEM_IsValidHandle(pAlctr, SMEMSIGNATURE))
+		goto loop_cont;
+
+	if ((xType == CMM_VA2DSPPA) || (xType == CMM_VA2PA) ||
+	    (xType == CMM_PA2VA)) {
+		if (xType == CMM_PA2VA) {
+			/* Gpp Va = Va Base + offset */
+			dwOffset = (u8 *)pAddr - (u8 *)(pAlctr->dwSmBase -
+				    pAlctr->ulDSPSize);
+			dwAddrXlate = pXlator->dwVirtBase + dwOffset;
+			/* Check if translated Va base is in range */
+			if ((dwAddrXlate < pXlator->dwVirtBase) ||
+			   (dwAddrXlate >=
+			   (pXlator->dwVirtBase + pXlator->ulVirtSize))) {
+				dwAddrXlate = 0;	/* bad address */
+				GT_0trace(CMM_debugMask, GT_7CLASS,
+					  "CMM_XlatorTranslate: "
+					  "Virt addr out of range\n");
+			}
+		} else {
+			/* Gpp PA =  Gpp Base + offset */
+			dwOffset = (u8 *)pAddr - (u8 *)pXlator->dwVirtBase;
+			dwAddrXlate = pAlctr->dwSmBase - pAlctr->ulDSPSize +
+				      dwOffset;
+		}
+	} else {
+		dwAddrXlate = (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 */
+		dwAddrXlate = GPPPA2DSPPA((pAlctr->dwSmBase - pAlctr->
+					 ulDSPSize), dwAddrXlate,
+					 pAlctr->dwDSPPhysAddrOffset *
+					 pAlctr->cFactor);
+	} else if (xType == CMM_DSPPA2PA) {
+		/* Got DSP Pa, convert to GPP Pa */
+		dwAddrXlate = DSPPA2GPPPA(pAlctr->dwSmBase - pAlctr->ulDSPSize,
+					  dwAddrXlate,
+					  pAlctr->dwDSPPhysAddrOffset *
+					  pAlctr->cFactor);
+	}
+loop_cont:
+	if (!dwAddrXlate) {
+		GT_2trace(CMM_debugMask, GT_7CLASS,
+			  "CMM_XlatorTranslate: Can't translate"
+			  " address: 0x%x xType %x\n", pAddr, xType);
+	} else {
+		GT_3trace(CMM_debugMask, GT_3CLASS,
+			  "CMM_XlatorTranslate: pAddr %x, xType"
+			  " %x, dwAddrXlate %x\n", pAddr, xType, dwAddrXlate);
+	}
+	return (void *)dwAddrXlate;
+}
diff --git a/drivers/dsp/bridge/pmgr/cod.c b/drivers/dsp/bridge/pmgr/cod.c
new file mode 100644
index 0000000..d1065e2
--- /dev/null
+++ b/drivers/dsp/bridge/pmgr/cod.c
@@ -0,0 +1,683 @@
+/*
+ * linux/drivers/dsp/bridge/pmgr/cod.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.
+ */
+
+
+/*
+ *  ======== cod.c ========
+ *  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.
+ *
+ *! Revision History
+ *! ================
+ *! 08-Apr-2003 map: Consolidated DBL to DBLL loader name
+ *! 24-Feb-2003 swa: PMGR Code review comments incorporated.
+ *! 18-Apr-2002 jeh: Added DBL function tables.
+ *! 20-Nov-2001 jeh: Removed call to ZL_loadArgs function.
+ *! 19-Oct-2001 jeh: Access DBL as a static library. Added COD_GetBaseLib,
+ *!		  COD_GetLoader, removed COD_LoadSection, COD_UnloadSection.
+ *! 07-Sep-2001 jeh: Added COD_LoadSection(), COD_UnloadSection().
+ *! 07-Aug-2001 rr:  hMgr->baseLib is updated after zlopen in COD_LoadBase.
+ *! 18-Apr-2001 jeh: Check for fLoaded flag before ZL_unload, to allow
+ *!		  COD_OpenBase to be used.
+ *! 11-Jan-2001 jeh: Added COD_OpenBase (not used yet, since there is an
+ *!		  occasional crash).
+ *! 02-Aug-2000 kc:  Added COD_ReadSection to COD module. Incorporates use
+ *!		  of ZL_readSect (new function in ZL module).
+ *! 28-Feb-2000 rr:  New GT Usage Implementation
+ *! 08-Dec-1999 ag:  Removed x86 specific __asm int 3.
+ *! 02-Oct-1999 ag:  Added #ifdef DEBUGINT3COD for debug.
+ *! 20-Sep-1999 ag:  Removed call to GT_set().
+ *! 04-Jun-1997 cr:  Added validation of argc/argv pair in COD_LoadBase, as it
+ *!		     is a requirement to ZL_loadArgs.
+ *! 31-May-1997 cr:  Changed COD_LoadBase argc value from u32 to int, added
+ *!	       DSP_ENOTIMPL return value to COD_Create when attrs != NULL.
+ *! 29-May-1997 cr:  Added debugging support.
+ *! 24-Oct-1996 gp:  Added COD_GetSection().
+ *! 18-Jun-1996 gp:  Updated GetSymValue() to check for lib; updated E_ codes.
+ *! 12-Jun-1996 gp:  Imported CSL_ services for strcpyn(); Added ref counting.
+ *! 20-May-1996 mg:  Adapted for new MEM and LDR modules.
+ *! 08-May-1996 mg:  Created.
+ */
+
+/*  ----------------------------------- Host OS */
+#include <host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <std.h>
+#include <dbdefs.h>
+#include <errbase.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dbc.h>
+#include <gt.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <csl.h>
+#include <kfile.h>
+#include <ldr.h>
+#include <mem.h>
+
+/*  ----------------------------------- Platform Manager */
+/* Include appropriate loader header file */
+#include <dbll.h>
+
+/*  ----------------------------------- This */
+#include <cod.h>
+
+/* magic number for handle validation */
+#define MAGIC	 0xc001beef
+
+/* macro to validate COD manager handles */
+#define IsValid(h)    ((h) != NULL && (h)->ulMagic == MAGIC)
+
+/*
+ *  ======== COD_MANAGER ========
+ */
+struct COD_MANAGER {
+	struct DBLL_TarObj *target;
+	struct DBLL_LibraryObj *baseLib;
+	bool fLoaded;		/* Base library loaded? */
+	u32 ulEntry;
+	struct LDR_MODULE *hDll;
+	struct DBLL_Fxns fxns;
+	struct DBLL_Attrs attrs;
+	char szZLFile[COD_MAXPATHLENGTH];
+	u32 ulMagic;
+} ;
+
+/*
+ *  ======== COD_LIBRARYOBJ ========
+ */
+struct COD_LIBRARYOBJ {
+	struct DBLL_LibraryObj *dbllLib;
+	struct COD_MANAGER *hCodMgr;
+} ;
+
+static u32 cRefs = 0L;
+
+#if GT_TRACE
+static struct GT_Mask COD_debugMask = { NULL, NULL };
+#endif
+
+static struct DBLL_Fxns dbllFxns = {
+	(DBLL_CloseFxn) DBLL_close,
+	(DBLL_CreateFxn) DBLL_create,
+	(DBLL_DeleteFxn) DBLL_delete,
+	(DBLL_ExitFxn) DBLL_exit,
+	(DBLL_GetAttrsFxn) DBLL_getAttrs,
+	(DBLL_GetAddrFxn) DBLL_getAddr,
+	(DBLL_GetCAddrFxn) DBLL_getCAddr,
+	(DBLL_GetSectFxn) DBLL_getSect,
+	(DBLL_InitFxn) DBLL_init,
+	(DBLL_LoadFxn) DBLL_load,
+	(DBLL_LoadSectFxn) DBLL_loadSect,
+	(DBLL_OpenFxn) DBLL_open,
+	(DBLL_ReadSectFxn) DBLL_readSect,
+	(DBLL_SetAttrsFxn) DBLL_setAttrs,
+	(DBLL_UnloadFxn) DBLL_unload,
+	(DBLL_UnloadSectFxn) DBLL_unloadSect,
+};
+
+static bool NoOp();
+
+/*
+ *  ======== COD_Close ========
+ */
+void CDECL COD_Close(struct COD_LIBRARYOBJ *lib)
+{
+	struct COD_MANAGER *hMgr;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(lib != NULL);
+	DBC_Require(IsValid(((struct COD_LIBRARYOBJ *)lib)->hCodMgr));
+
+	hMgr = lib->hCodMgr;
+	hMgr->fxns.closeFxn(lib->dbllLib);
+
+	MEM_Free(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.
+ *
+ */
+DSP_STATUS COD_Create(OUT struct COD_MANAGER **phMgr, char *pstrDummyFile,
+		     IN OPTIONAL CONST struct COD_ATTRS *attrs)
+{
+	struct COD_MANAGER *hMgrNew;
+	struct DBLL_Attrs zlAttrs;
+	DSP_STATUS status = DSP_SOK;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(phMgr != NULL);
+
+	GT_3trace(COD_debugMask, GT_ENTER,
+		  "Entered COD_Create, Args: \t\nphMgr: "
+		  "0x%x\t\npstrDummyFile: 0x%x\t\nattr: 0x%x\n",
+		  phMgr, pstrDummyFile, attrs);
+	/* assume failure */
+	*phMgr = NULL;
+
+	/* we don't support non-default attrs yet */
+	if (attrs != NULL)
+		return DSP_ENOTIMPL;
+
+	hMgrNew = MEM_Calloc(sizeof(struct COD_MANAGER), MEM_NONPAGED);
+	if (hMgrNew == NULL) {
+		GT_0trace(COD_debugMask, GT_7CLASS,
+			  "COD_Create: Out Of Memory\n");
+		return DSP_EMEMORY;
+	}
+
+	hMgrNew->ulMagic = MAGIC;
+
+	/* Set up loader functions */
+	hMgrNew->fxns = dbllFxns;
+
+	/* initialize the ZL module */
+	hMgrNew->fxns.initFxn();
+
+	zlAttrs.alloc = (DBLL_AllocFxn)NoOp;
+	zlAttrs.free = (DBLL_FreeFxn)NoOp;
+	zlAttrs.fread = (DBLL_ReadFxn)KFILE_Read;
+	zlAttrs.fseek = (DBLL_SeekFxn)KFILE_Seek;
+	zlAttrs.ftell = (DBLL_TellFxn)KFILE_Tell;
+	zlAttrs.fclose = (DBLL_FCloseFxn)KFILE_Close;
+	zlAttrs.fopen = (DBLL_FOpenFxn)KFILE_Open;
+	zlAttrs.symLookup = NULL;
+	zlAttrs.baseImage = true;
+	zlAttrs.logWrite = NULL;
+	zlAttrs.logWriteHandle = NULL;
+	zlAttrs.write = 0;
+	zlAttrs.rmmHandle = 0;
+	zlAttrs.wHandle = 0;
+	zlAttrs.symHandle = 0;
+	zlAttrs.symArg = 0;
+
+	hMgrNew->attrs = zlAttrs;
+
+	status = hMgrNew->fxns.createFxn(&hMgrNew->target, &zlAttrs);
+
+	if (DSP_FAILED(status)) {
+		COD_Delete(hMgrNew);
+		GT_1trace(COD_debugMask, GT_7CLASS,
+			  "COD_Create:ZL Create Failed: 0x%x\n", status);
+		return COD_E_ZLCREATEFAILED;
+	}
+
+	/* return the new manager */
+	*phMgr = hMgrNew;
+	GT_1trace(COD_debugMask, GT_1CLASS,
+		  "COD_Create: Success CodMgr: 0x%x\n",	*phMgr);
+	return DSP_SOK;
+}
+
+/*
+ *  ======== COD_Delete ========
+ *  Purpose:
+ *      Delete a code manager object.
+ */
+void COD_Delete(struct COD_MANAGER *hMgr)
+{
+	DBC_Require(cRefs > 0);
+	DBC_Require(IsValid(hMgr));
+
+	GT_1trace(COD_debugMask, GT_ENTER, "COD_Delete:hMgr 0x%x\n", hMgr);
+	if (hMgr->baseLib) {
+		if (hMgr->fLoaded)
+			hMgr->fxns.unloadFxn(hMgr->baseLib, &hMgr->attrs);
+
+		hMgr->fxns.closeFxn(hMgr->baseLib);
+	}
+	if (hMgr->target) {
+		hMgr->fxns.deleteFxn(hMgr->target);
+		hMgr->fxns.exitFxn();
+	}
+	hMgr->ulMagic = ~MAGIC;
+	MEM_Free(hMgr);
+}
+
+/*
+ *  ======== COD_Exit ========
+ *  Purpose:
+ *      Discontinue usage of the COD module.
+ *
+ */
+void COD_Exit(void)
+{
+	DBC_Require(cRefs > 0);
+
+	cRefs--;
+
+	GT_1trace(COD_debugMask, GT_ENTER,
+		  "Entered COD_Exit, ref count:  0x%x\n", cRefs);
+
+	DBC_Ensure(cRefs >= 0);
+}
+
+/*
+ *  ======== COD_GetBaseLib ========
+ *  Purpose:
+ *      Get handle to the base image DBL library.
+ */
+DSP_STATUS CDECL COD_GetBaseLib(struct COD_MANAGER *hManager,
+				struct DBLL_LibraryObj **plib)
+{
+	DSP_STATUS status = DSP_SOK;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(IsValid(hManager));
+	DBC_Require(plib != NULL);
+
+	*plib = (struct DBLL_LibraryObj *) hManager->baseLib;
+
+	return status;
+}
+
+/*
+ *  ======== COD_GetBaseName ========
+ */
+DSP_STATUS CDECL COD_GetBaseName(struct COD_MANAGER *hManager, char *pszName,
+				u32 uSize)
+{
+	DSP_STATUS status = DSP_SOK;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(IsValid(hManager));
+	DBC_Require(pszName != NULL);
+
+	if (uSize <= COD_MAXPATHLENGTH)
+		CSL_Strcpyn(pszName, hManager->szZLFile, uSize);
+	else
+		status = DSP_EFAIL;
+
+	return status;
+}
+
+/*
+ *  ======== COD_GetEntry ========
+ *  Purpose:
+ *      Retrieve the entry point of a loaded DSP program image
+ *
+ */
+DSP_STATUS COD_GetEntry(struct COD_MANAGER *hManager, u32 *pulEntry)
+{
+	DBC_Require(cRefs > 0);
+	DBC_Require(IsValid(hManager));
+	DBC_Require(pulEntry != NULL);
+
+	*pulEntry = hManager->ulEntry;
+
+	GT_1trace(COD_debugMask, GT_ENTER, "COD_GetEntry:ulEntr 0x%x\n",
+		  *pulEntry);
+
+	return DSP_SOK;
+}
+
+/*
+ *  ======== COD_GetLoader ========
+ *  Purpose:
+ *      Get handle to the DBLL loader.
+ */
+DSP_STATUS CDECL COD_GetLoader(struct COD_MANAGER *hManager,
+			       struct DBLL_TarObj **phLoader)
+{
+	DSP_STATUS status = DSP_SOK;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(IsValid(hManager));
+	DBC_Require(phLoader != NULL);
+
+	*phLoader = (struct DBLL_TarObj *)hManager->target;
+
+	return status;
+}
+
+/*
+ *  ======== COD_GetSection ========
+ *  Purpose:
+ *      Retrieve the starting address and length of a section in the COFF file
+ *      given the section name.
+ */
+DSP_STATUS COD_GetSection(struct COD_LIBRARYOBJ *lib, IN char *pstrSect,
+			  OUT u32 *puAddr, OUT u32 *puLen)
+{
+	struct COD_MANAGER *hManager;
+	DSP_STATUS status = DSP_SOK;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(lib != NULL);
+	DBC_Require(IsValid(lib->hCodMgr));
+	DBC_Require(pstrSect != NULL);
+	DBC_Require(puAddr != NULL);
+	DBC_Require(puLen != NULL);
+
+	GT_4trace(COD_debugMask, GT_ENTER,
+		  "Entered COD_GetSection Args \t\n lib: "
+		  "0x%x\t\npstrsect: 0x%x\t\npuAddr: 0x%x\t\npuLen: 0x%x\n",
+		  lib, pstrSect, puAddr, puLen);
+	*puAddr = 0;
+	*puLen = 0;
+	if (lib != NULL) {
+		hManager = lib->hCodMgr;
+		status = hManager->fxns.getSectFxn(lib->dbllLib, pstrSect,
+						   puAddr, puLen);
+		if (DSP_FAILED(status)) {
+			GT_1trace(COD_debugMask, GT_7CLASS,
+				 "COD_GetSection: Section %s not"
+				 "found\n", pstrSect);
+		}
+	} else {
+		status = COD_E_NOSYMBOLSLOADED;
+		GT_0trace(COD_debugMask, GT_7CLASS,
+			  "COD_GetSection:No Symbols loaded\n");
+	}
+
+	DBC_Ensure(DSP_SUCCEEDED(status) || ((*puAddr == 0) && (*puLen == 0)));
+
+	return status;
+}
+
+/*
+ *  ======== COD_GetSymValue ========
+ *  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.
+ *
+ */
+DSP_STATUS COD_GetSymValue(struct COD_MANAGER *hMgr, char *pstrSym,
+			   u32 *pulValue)
+{
+	struct DBLL_Symbol *pSym;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(IsValid(hMgr));
+	DBC_Require(pstrSym != NULL);
+	DBC_Require(pulValue != NULL);
+
+	GT_3trace(COD_debugMask, GT_ENTER, "Entered COD_GetSymValue Args \t\n"
+		  "hMgr: 0x%x\t\npstrSym: 0x%x\t\npulValue: 0x%x\n",
+		  hMgr, pstrSym, pulValue);
+	if (hMgr->baseLib) {
+		if (!hMgr->fxns.getAddrFxn(hMgr->baseLib, pstrSym, &pSym)) {
+			if (!hMgr->fxns.getCAddrFxn(hMgr->baseLib, pstrSym,
+			    &pSym)) {
+				GT_0trace(COD_debugMask, GT_7CLASS,
+					  "COD_GetSymValue: "
+					  "Symbols not found\n");
+				return COD_E_SYMBOLNOTFOUND;
+			}
+		}
+	} else {
+		GT_0trace(COD_debugMask, GT_7CLASS, "COD_GetSymValue: "
+			 "No Symbols loaded\n");
+		return COD_E_NOSYMBOLSLOADED;
+	}
+
+	*pulValue = pSym->value;
+
+	return DSP_SOK;
+}
+
+/*
+ *  ======== 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;
+}
+
+/*
+ *  ======== COD_LoadBase ========
+ *  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 nArgc doesn't match the number of arguments in the aArgs array, the
+ *      aArgs array is searched for a NULL terminating entry, and argc is
+ *      recalculated to reflect this.  In this way, we can support NULL
+ *      terminating aArgs arrays, if nArgc is very large.
+ */
+DSP_STATUS COD_LoadBase(struct COD_MANAGER *hMgr, u32 nArgc, char *aArgs[],
+			COD_WRITEFXN pfnWrite, void *pArb, char *envp[])
+{
+	DBLL_Flags flags;
+	struct DBLL_Attrs saveAttrs;
+	struct DBLL_Attrs newAttrs;
+	DSP_STATUS status;
+	u32 i;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(IsValid(hMgr));
+	DBC_Require(nArgc > 0);
+	DBC_Require(aArgs != NULL);
+	DBC_Require(aArgs[0] != NULL);
+	DBC_Require(pfnWrite != NULL);
+	DBC_Require(hMgr->baseLib != NULL);
+
+	GT_6trace(COD_debugMask, GT_ENTER,
+		 "Entered COD_LoadBase, hMgr:  0x%x\n \t"
+		 "nArgc:  0x%x\n\taArgs:  0x%x\n\tpfnWrite:  0x%x\n\tpArb:"
+		 " 0x%x\n \tenvp:  0x%x\n", hMgr, nArgc, aArgs, pfnWrite,
+		 pArb, envp);
+	/*
+	 *  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 < nArgc; i++) {
+		if (aArgs[i] == NULL) {
+			nArgc = i;
+			break;
+		}
+	}
+
+	/* set the write function for this operation */
+	hMgr->fxns.getAttrsFxn(hMgr->target, &saveAttrs);
+
+	newAttrs = saveAttrs;
+	newAttrs.write = (DBLL_WriteFxn)pfnWrite;
+	newAttrs.wHandle = pArb;
+	newAttrs.alloc = (DBLL_AllocFxn)NoOp;
+	newAttrs.free = (DBLL_FreeFxn)NoOp;
+	newAttrs.logWrite = NULL;
+	newAttrs.logWriteHandle = NULL;
+
+	/* Load the image */
+	flags = DBLL_CODE | DBLL_DATA | DBLL_SYMB;
+	status = hMgr->fxns.loadFxn(hMgr->baseLib, flags, &newAttrs,
+		 &hMgr->ulEntry);
+	if (DSP_FAILED(status)) {
+		hMgr->fxns.closeFxn(hMgr->baseLib);
+		GT_1trace(COD_debugMask, GT_7CLASS,
+			  "COD_LoadBase: COD Load failed: "
+			  "0x%x\n", status);
+	}
+	if (DSP_SUCCEEDED(status))
+		hMgr->fLoaded = true;
+	else
+		hMgr->baseLib = NULL;
+
+	return status;
+}
+
+/*
+ *  ======== COD_Open ========
+ *      Open library for reading sections.
+ */
+DSP_STATUS COD_Open(struct COD_MANAGER *hMgr, IN char *pszCoffPath,
+		    COD_FLAGS flags, struct COD_LIBRARYOBJ **pLib)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct COD_LIBRARYOBJ *lib = NULL;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(IsValid(hMgr));
+	DBC_Require(pszCoffPath != NULL);
+	DBC_Require(flags == COD_NOLOAD || flags == COD_SYMB);
+	DBC_Require(pLib != NULL);
+
+	GT_4trace(COD_debugMask, GT_ENTER, "Entered COD_Open, hMgr: 0x%x\n\t "
+		  "pszCoffPath:  0x%x\tflags: 0x%x\tlib: 0x%x\n", hMgr,
+		  pszCoffPath, flags, pLib);
+
+	*pLib = NULL;
+
+	lib = MEM_Calloc(sizeof(struct COD_LIBRARYOBJ), MEM_NONPAGED);
+	if (lib == NULL) {
+		GT_0trace(COD_debugMask, GT_7CLASS,
+			 "COD_Open: Out Of Memory\n");
+		status = DSP_EMEMORY;
+	}
+
+	if (DSP_SUCCEEDED(status)) {
+		lib->hCodMgr = hMgr;
+		status = hMgr->fxns.openFxn(hMgr->target, pszCoffPath, flags,
+					   &lib->dbllLib);
+		if (DSP_FAILED(status)) {
+			GT_1trace(COD_debugMask, GT_7CLASS,
+				 "COD_Open failed: 0x%x\n", status);
+		} else {
+			*pLib = lib;
+		}
+	}
+
+	return status;
+}
+
+/*
+ *  ======== COD_OpenBase ========
+ *  Purpose:
+ *      Open base image for reading sections.
+ */
+DSP_STATUS COD_OpenBase(struct COD_MANAGER *hMgr, IN char *pszCoffPath,
+			DBLL_Flags flags)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DBLL_LibraryObj *lib;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(IsValid(hMgr));
+	DBC_Require(pszCoffPath != NULL);
+
+	GT_2trace(COD_debugMask, GT_ENTER,
+		  "Entered COD_OpenBase, hMgr:  0x%x\n\t"
+		  "pszCoffPath:  0x%x\n", hMgr, pszCoffPath);
+
+	/* if we previously opened a base image, close it now */
+	if (hMgr->baseLib) {
+		if (hMgr->fLoaded) {
+			GT_0trace(COD_debugMask, GT_7CLASS,
+				 "Base Image is already loaded. "
+				 "Unloading it...\n");
+			hMgr->fxns.unloadFxn(hMgr->baseLib, &hMgr->attrs);
+			hMgr->fLoaded = false;
+		}
+		hMgr->fxns.closeFxn(hMgr->baseLib);
+		hMgr->baseLib = NULL;
+	} else {
+		GT_0trace(COD_debugMask, GT_1CLASS,
+			 "COD_OpenBase: Opening the base image ...\n");
+	}
+	status = hMgr->fxns.openFxn(hMgr->target, pszCoffPath, flags, &lib);
+	if (DSP_FAILED(status)) {
+		GT_0trace(COD_debugMask, GT_7CLASS,
+			 "COD_OpenBase: COD Open failed\n");
+	} else {
+		/* hang onto the library for subsequent sym table usage */
+		hMgr->baseLib = lib;
+		CSL_Strcpyn(hMgr->szZLFile, pszCoffPath, COD_MAXPATHLENGTH);
+	}
+
+	return status;
+}
+
+/*
+ *  ======== COD_ReadSection ========
+ *  Purpose:
+ *      Retrieve the content of a code section given the section name.
+ */
+DSP_STATUS COD_ReadSection(struct COD_LIBRARYOBJ *lib, IN char *pstrSect,
+			   OUT char *pstrContent, IN u32 cContentSize)
+{
+	DSP_STATUS status = DSP_SOK;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(lib != NULL);
+	DBC_Require(IsValid(lib->hCodMgr));
+	DBC_Require(pstrSect != NULL);
+	DBC_Require(pstrContent != NULL);
+
+	GT_4trace(COD_debugMask, GT_ENTER, "Entered COD_ReadSection Args: 0x%x,"
+		 " 0x%x, 0x%x, 0x%x\n", lib, pstrSect, pstrContent,
+		 cContentSize);
+
+	if (lib != NULL) {
+		status = lib->hCodMgr->fxns.readSectFxn(lib->dbllLib, pstrSect,
+							pstrContent,
+							cContentSize);
+		if (DSP_FAILED(status)) {
+			GT_1trace(COD_debugMask, GT_7CLASS,
+				 "COD_ReadSection failed: 0x%lx\n", status);
+		}
+	} else {
+		status = COD_E_NOSYMBOLSLOADED;
+		GT_0trace(COD_debugMask, GT_7CLASS,
+			  "COD_ReadSection: No Symbols loaded\n");
+	}
+	return status;
+}
+
+/*
+ *  ======== NoOp ========
+ *  Purpose:
+ *      No Operation.
+ *
+ */
+static bool NoOp(void)
+{
+	return true;
+}
+
diff --git a/drivers/dsp/bridge/pmgr/dbl.c b/drivers/dsp/bridge/pmgr/dbl.c
new file mode 100644
index 0000000..d4c68c0
--- /dev/null
+++ b/drivers/dsp/bridge/pmgr/dbl.c
@@ -0,0 +1,1385 @@
+/*
+ * linux/drivers/dsp/bridge/pmgr/linux/dbl/dbl.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.
+ */
+
+
+/*
+ *  ======== dbl.c ========
+ *  Dynamic BOF Loader library. Contains functions related to
+ *  loading and unloading symbols/code/data on DSP.
+ *  Also contains other support functions.
+ *
+ *! Revision History
+ *! ================
+ *! 24-Feb-2003 swa 	PMGR Code review comments incorporated.
+ *! 24-May-2002 jeh     Free DCD sects in DBL_close().
+ *! 19-Mar-2002 jeh     Changes made to match dynamic loader (dbll.c): Pass
+ *!		     DBL_Library to DBL_getAddr() instead of DBL_Target,
+ *!		     eliminate scope param, use DBL_Symbol. Pass attrs to
+ *!		     DBL_load(), DBL_unload().
+ *! 20-Nov-2001 jeh     Removed DBL_loadArgs().
+ *! 07-Sep-2001 jeh     Added overlay support.
+ *! 31-Jul-2001 jeh     Include windows.h.
+ *! 06-Jun-2001 jeh     Created.
+ */
+
+/*  ----------------------------------- Host OS */
+#include <host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <std.h>
+#include <dbdefs.h>
+#include <errbase.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dbc.h>
+#include <gt.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <csl.h>
+#include <mem.h>
+#include <kfile.h>
+
+/*  ----------------------------------- This */
+#include <dbof.h>
+#include <dbl.h>
+
+#define DBL_TARGSIGNATURE      0x544c4244	/* "TLBD" */
+#define DBL_LIBSIGNATURE       0x4c4c4244	/* "LLBD" */
+
+#define C54TARG	 0
+#define C55TARG	 1
+#define NUMTARGS	2
+
+#define C54MAGIC	0x98	/* Magic number for TI C54 COF  */
+#define C55MAGIC	0x9c	/* Magic number for LEAD3 (C55) COF  */
+
+/* Three task phases */
+#define CREATEPHASE 0
+#define DELETEPHASE 1
+#define EXECUTEPHASE 2
+#define NONE 3		/* For overlay section with phase not specified */
+
+/* Default load buffer size */
+#define LOADBUFSIZE     0x800
+
+#define SWAPLONG(x) ((((x) << 24) & 0xFF000000) | (((x) << 8) & 0xFF0000L) | \
+		      (((x) >> 8) & 0xFF00L) | (((x) >> 24) & 0xFF))
+
+#define SWAPWORD(x) ((((x) << 8) & 0xFF00) | (((x) >> 8) & 0xFF))
+
+/*
+ *  Macros for accessing the following types of overlay data within a
+ *  structure of type OvlyData:
+ *      - Overlay data not associated with a particular phase
+ *      - Create phase overlay data
+ *      - Delete phase overlay data
+ *      - Execute phase overlay data
+ */
+#define numOtherSects(pOvlyData)    ((pOvlyData)->hdr.dbofHdr.numOtherSects)
+#define numCreateSects(pOvlyData)   ((pOvlyData)->hdr.dbofHdr.numCreateSects)
+#define numDeleteSects(pOvlyData)   ((pOvlyData)->hdr.dbofHdr.numDeleteSects)
+#define numExecuteSects(pOvlyData)  ((pOvlyData)->hdr.dbofHdr.numExecuteSects)
+#define otherOffset(pOvlyData)      0
+#define createOffset(pOvlyData)     ((pOvlyData)->hdr.dbofHdr.numOtherSects)
+#define deleteOffset(pOvlyData)     (createOffset(pOvlyData) + \
+				     (pOvlyData->hdr.dbofHdr.numCreateSects))
+#define executeOffset(pOvlyData)    (deleteOffset(pOvlyData) + \
+				     (pOvlyData->hdr.dbofHdr.numDeleteSects))
+/*
+ *  ======== OvlyHdr ========
+ */
+struct OvlyHdr {
+	struct DBOF_OvlySectHdr dbofHdr;
+	char *pName; 		/* Name of overlay section */
+	u16 createRef; 	/* Reference count for create phase */
+	u16 deleteRef; 	/* Reference count for delete phase */
+	u16 executeRef; 	/* Execute phase ref count */
+	u16 otherRef; 		/* Unspecified phase ref count */
+} ;
+
+/*
+ *  ======== OvlyData ========
+ */
+struct OvlyData {
+	struct OvlyHdr hdr;
+	struct DBOF_OvlySectData data[1];
+} ;
+
+/*
+ *  ======== Symbol ========
+ */
+struct Symbol {
+	struct DBL_Symbol sym;
+	char *pSymName;
+};
+
+/*
+ *  ======== DCDSect ========
+ */
+struct DCDSect {
+	struct DBOF_DCDSectHdr sectHdr;
+	char *pData;
+} ;
+
+/*
+ *  ======== DBL_TargetObj ========
+ */
+struct DBL_TargetObj {
+	u32 dwSignature; 	/* For object validation */
+	struct DBL_Attrs dblAttrs; 	/* file read, write, etc. functions */
+	char *pBuf; 		/* Load buffer */
+};
+
+/*
+ *  ======== TargetInfo ========
+ */
+struct TargetInfo {
+	u16 dspType; 		/* eg, C54TARG, C55TARG */
+	u32 magic; 		/* COFF magic number, identifies target type */
+	u16 wordSize; 	/* Size of a DSP word */
+	u16 mauSize; 		/* Size of minimum addressable unit */
+	u16 charSize; 	/* For C55x, mausize = 1, but charsize = 2 */
+} ;
+
+/*
+ *  ======== DBL_LibraryObj ========
+ *  Represents a library loaded on a target.
+ */
+struct DBL_LibraryObj {
+	u32 dwSignature; 	/* For object validation */
+	struct DBL_TargetObj *pTarget; 	/* Target for this library */
+	struct KFILE_FileObj *file; 	/* DBOF file handle */
+	bool byteSwapped; 	/* Are bytes swapped? */
+	struct DBOF_FileHdr fileHdr; 	/* Header of DBOF file */
+	u16 nSymbols; 		/* Number of DSP/Bridge symbols */
+	struct Symbol *symbols; 	/* Table of DSP/Bridge symbols */
+	u16 nDCDSects; 	/* Number of DCD sections */
+	u16 nOvlySects; 	/* Number of overlay nodes */
+	struct DCDSect *dcdSects; 	/* DCD section data */
+	struct OvlyData **ppOvlyData; 	/* Array of overlay section data */
+	struct TargetInfo *pTargetInfo; 	/* Entry in targetTab[] below */
+} ;
+
+#if GT_TRACE
+static struct GT_Mask DBL_debugMask = { NULL, NULL }; 	/* GT trace variable */
+#endif
+
+static u32 cRefs; 		/* module reference count */
+
+static u32 magicTab[NUMTARGS] = { C54MAGIC, C55MAGIC };
+
+static struct TargetInfo targetTab[] = {
+	/* targ     magic       wordsize    mausize    charsize */
+	{C54TARG, C54MAGIC, 2, 2, 2}, 	/* C54  */
+	{C55TARG, C55MAGIC, 2, 1, 2}, 	/* C55  */
+};
+
+static void freeSects(struct DBL_TargetObj *dbl, struct OvlyData *pOvlyData,
+		     s32 offset, s32 nSects);
+static DSP_STATUS loadSect(struct DBL_TargetObj *dbl,
+			  struct DBL_LibraryObj *pdblLib);
+static DSP_STATUS readDCDSects(struct DBL_TargetObj *dbl,
+			      struct DBL_LibraryObj *pdblLib);
+static DSP_STATUS readHeader(struct DBL_TargetObj *dbl,
+			    struct DBL_LibraryObj *pdblLib);
+static DSP_STATUS readOvlySects(struct DBL_TargetObj *dbl,
+				struct DBL_LibraryObj *pdblLib);
+static DSP_STATUS readSymbols(struct DBL_TargetObj *dbl,
+			     struct DBL_LibraryObj *pdblLib);
+
+/*
+ *  ======== DBL_close ========
+ *  Purpose:
+ *  	Close library opened with DBL_open.
+ */
+void DBL_close(struct DBL_LibraryObj *lib)
+{
+	struct DBL_LibraryObj *pdblLib = (struct DBL_LibraryObj *)lib;
+	u16 i;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(pdblLib, DBL_LIBSIGNATURE));
+
+	GT_1trace(DBL_debugMask, GT_ENTER, "DBL_close: lib: 0x%x\n", lib);
+
+	/* Free symbols */
+	if (pdblLib->symbols) {
+		for (i = 0; i < pdblLib->nSymbols; i++) {
+			if (pdblLib->symbols[i].pSymName)
+				MEM_Free(pdblLib->symbols[i].pSymName);
+
+		}
+		MEM_Free(pdblLib->symbols);
+	}
+
+	/* Free DCD sects */
+	if (pdblLib->dcdSects) {
+		for (i = 0; i < pdblLib->nDCDSects; i++) {
+			if (pdblLib->dcdSects[i].pData)
+				MEM_Free(pdblLib->dcdSects[i].pData);
+
+		}
+		MEM_Free(pdblLib->dcdSects);
+	}
+
+	/* Free overlay sects */
+	if (pdblLib->ppOvlyData) {
+		for (i = 0;  i < pdblLib->nOvlySects;  i++) {
+			if (pdblLib->ppOvlyData[i]) {
+				if (pdblLib->ppOvlyData[i]->hdr.pName) {
+					MEM_Free(pdblLib->ppOvlyData[i]->
+						hdr.pName);
+				}
+				MEM_Free(pdblLib->ppOvlyData[i]);
+			}
+		}
+		MEM_Free(pdblLib->ppOvlyData);
+	}
+
+	/* Close the file */
+	if (pdblLib->file)
+		(*pdblLib->pTarget->dblAttrs.fclose) (pdblLib->file);
+
+
+	MEM_FreeObject(pdblLib);
+}
+
+/*
+ *  ======== DBL_create ========
+ *  Purpose:
+ *  	Create a target object by specifying the alloc, free, and
+ *  	write functions for the target.
+ */
+DSP_STATUS DBL_create(struct DBL_TargetObj **pTarget, struct DBL_Attrs *pAttrs)
+{
+	struct DBL_TargetObj *pdblTarget = NULL;
+	DSP_STATUS status = DSP_SOK;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(pAttrs != NULL);
+	DBC_Require(pTarget != NULL);
+
+	GT_2trace(DBL_debugMask, GT_ENTER,
+		 "DBL_create: pTarget: 0x%x pAttrs: 0x%x\n",
+		 pTarget, pAttrs);
+	/* Allocate DBL target object */
+	MEM_AllocObject(pdblTarget, struct DBL_TargetObj, DBL_TARGSIGNATURE);
+	if (pdblTarget == NULL) {
+		GT_0trace(DBL_debugMask, GT_6CLASS,
+			 "DBL_create: Memory allocation failed\n");
+		status = DSP_EMEMORY;
+	} else {
+		pdblTarget->dblAttrs = *pAttrs;
+		/* Allocate buffer for loading target */
+		pdblTarget->pBuf = MEM_Calloc(LOADBUFSIZE, MEM_PAGED);
+		if (pdblTarget->pBuf == NULL)
+			status = DSP_EMEMORY;
+
+	}
+	if (DSP_SUCCEEDED(status)) {
+		*pTarget = pdblTarget;
+	} else {
+		*pTarget = NULL;
+		if (pdblTarget)
+			DBL_delete(pdblTarget);
+
+	}
+	DBC_Ensure(DSP_SUCCEEDED(status) &&
+		  ((MEM_IsValidHandle((*pTarget), DBL_TARGSIGNATURE)) ||
+		  (DSP_FAILED(status) && *pTarget == NULL)));
+	return status;
+}
+
+/*
+ *  ======== DBL_delete ========
+ *  Purpose:
+ *  	Delete target object and free resources for any loaded libraries.
+ */
+void DBL_delete(struct DBL_TargetObj *target)
+{
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(target, DBL_TARGSIGNATURE));
+
+	GT_1trace(DBL_debugMask, GT_ENTER,
+		 "DBL_delete: target: 0x%x\n", target);
+
+	if (target->pBuf)
+		MEM_Free(target->pBuf);
+
+	MEM_FreeObject(target);
+}
+
+/*
+ *  ======== DBL_exit ========
+ *  Purpose
+ *  	Discontinue usage of DBL module.
+ */
+void DBL_exit()
+{
+	DBC_Require(cRefs > 0);
+	cRefs--;
+	GT_1trace(DBL_debugMask, GT_5CLASS,
+		 "DBL_exit() ref count: 0x%x\n", cRefs);
+	DBC_Ensure(cRefs >= 0);
+}
+
+/*
+ *  ======== DBL_getAddr ========
+ *  Purpose:
+ *  	Get address of name in the specified library.
+ */
+bool DBL_getAddr(struct DBL_LibraryObj *lib, char *name,
+		struct DBL_Symbol **ppSym)
+{
+	bool retVal = false;
+	struct Symbol *symbol;
+	u16 i;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(lib, DBL_LIBSIGNATURE));
+	DBC_Require(name != NULL);
+	DBC_Require(ppSym != NULL);
+
+	GT_3trace(DBL_debugMask, GT_ENTER,
+		 "DBL_getAddr: libt: 0x%x name: %s pAddr: "
+		 "0x%x\n", lib, name, ppSym);
+	for (i = 0; i < lib->nSymbols; i++) {
+		symbol = &lib->symbols[i];
+		if (CSL_Strcmp(name, symbol->pSymName) == 0) {
+			/* Found it */
+			*ppSym = &lib->symbols[i].sym;
+			retVal = true;
+			break;
+		}
+	}
+	return retVal;
+}
+
+/*
+ *  ======== DBL_getAttrs ========
+ *  Purpose:
+ *  	Retrieve the attributes of the target.
+ */
+void DBL_getAttrs(struct DBL_TargetObj *target, struct DBL_Attrs *pAttrs)
+{
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(target, DBL_TARGSIGNATURE));
+	DBC_Require(pAttrs != NULL);
+	GT_2trace(DBL_debugMask, GT_ENTER, "DBL_getAttrs: target: 0x%x pAttrs: "
+		  "0x%x\n", target, pAttrs);
+	*pAttrs = target->dblAttrs;
+}
+
+/*
+ *  ======== DBL_getCAddr ========
+ *  Purpose:
+ *  	Get address of "C" name in the specified library.
+ */
+bool DBL_getCAddr(struct DBL_LibraryObj *lib, char *name,
+		 struct DBL_Symbol **ppSym)
+{
+	bool retVal = false;
+	struct Symbol *symbol;
+	u16 i;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(lib, DBL_LIBSIGNATURE));
+	DBC_Require(name != NULL);
+	DBC_Require(ppSym != NULL);
+
+	GT_3trace(DBL_debugMask, GT_ENTER,
+		 "DBL_getCAddr: target: 0x%x name:%s pAddr:"
+		 " 0x%x\n", lib, name, ppSym);
+	for (i = 0;  i < lib->nSymbols;  i++) {
+		symbol = &lib->symbols[i];
+		if ((CSL_Strcmp(name, symbol->pSymName) == 0) ||
+		    (CSL_Strcmp(name, symbol->pSymName + 1) == 0 &&
+		     symbol->pSymName[0] == '_')) {
+			/* Found it */
+			*ppSym = &lib->symbols[i].sym;
+			retVal = true;
+			break;
+		}
+	}
+	return retVal;
+}
+
+/*
+ *  ======== DBL_getEntry ========
+ *  Purpose:
+ *  	Get program entry point.
+ *
+ */
+bool DBL_getEntry(struct DBL_LibraryObj *lib, u32 *pEntry)
+{
+	struct DBL_LibraryObj *pdblLib = (struct DBL_LibraryObj *)lib;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(pdblLib, DBL_LIBSIGNATURE));
+	DBC_Require(pEntry != NULL);
+
+	GT_2trace(DBL_debugMask, GT_ENTER,
+		 "DBL_getEntry: lib: 0x%x pEntry: 0x%x\n", lib, pEntry);
+	*pEntry = pdblLib->fileHdr.entry;
+
+	return true;
+}
+
+/*
+ *  ======== DBL_getSect ========
+ *  Purpose:
+ *  	Get address and size of a named section.
+ */
+DSP_STATUS DBL_getSect(struct DBL_LibraryObj *lib, char *name, u32 *pAddr,
+		      u32 *pSize)
+{
+	struct DBL_LibraryObj *pdblLib = (struct DBL_LibraryObj *)lib;
+	u16 i;
+	DSP_STATUS status = DSP_ENOSECT;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(name != NULL);
+	DBC_Require(pAddr != NULL);
+	DBC_Require(pSize != NULL);
+	DBC_Require(MEM_IsValidHandle(pdblLib, DBL_LIBSIGNATURE));
+
+	GT_4trace(DBL_debugMask, GT_ENTER,
+		 "DBL_getSect: lib: 0x%x name: %s pAddr:"
+		 " 0x%x pSize: 0x%x\n", lib, name, pAddr, pSize);
+
+	/*
+	 *  Check for DCD and overlay sections. Overlay loader uses DBL_getSect
+	 *  to determine whether or not a node has overlay sections.
+	 *  DCD section names begin with '.'
+	 */
+	if (name[0] == '.') {
+		/* Get DCD section size (address is 0, since it's a NOLOAD). */
+		for (i = 0; i < pdblLib->nDCDSects; i++) {
+			if (CSL_Strcmp(pdblLib->dcdSects[i].sectHdr.name,
+			   name) == 0) {
+				*pAddr = 0;
+				*pSize = pdblLib->dcdSects[i].sectHdr.size *
+					 pdblLib->pTargetInfo->mauSize;
+				status = DSP_SOK;
+				break;
+			}
+		}
+	} else {
+		/* Check for overlay section */
+		for (i = 0;  i < pdblLib->nOvlySects;  i++) {
+			if (CSL_Strcmp(pdblLib->ppOvlyData[i]->hdr.pName,
+			   name) == 0) {
+				/* Address and size are meaningless */
+				*pAddr = 0;
+				*pSize = 0;
+				status = DSP_SOK;
+				break;
+			}
+		}
+	}
+
+	return status;
+}
+
+/*
+ *  ======== DBL_init ========
+ *  Purpose:
+ *  	Initialize DBL module.
+ */
+bool DBL_init(void)
+{
+	bool retVal = true;
+
+	DBC_Require(cRefs >= 0);
+
+	if (cRefs == 0) {
+		DBC_Assert(!DBL_debugMask.flags);
+		GT_create(&DBL_debugMask, "BL"); 	/* "BL" for dBL */
+
+	}
+
+	if (retVal)
+		cRefs++;
+
+
+	GT_1trace(DBL_debugMask, GT_5CLASS, "DBL_init(), ref count:  0x%x\n",
+		  cRefs);
+
+	DBC_Ensure((retVal && (cRefs > 0)) || (!retVal && (cRefs >= 0)));
+
+	return retVal;
+}
+
+/*
+ *  ======== DBL_load ========
+ *  Purpose:
+ *  	Add symbols/code/data defined in file to that already present
+ *  	on the target.
+ */
+DSP_STATUS DBL_load(struct DBL_LibraryObj *lib, DBL_Flags flags,
+		   struct DBL_Attrs *attrs, u32 *pEntry)
+{
+	struct DBL_LibraryObj *pdblLib = (struct DBL_LibraryObj *)lib;
+	struct DBL_TargetObj *dbl;
+	u16 i;
+	u16 nSects;
+	DSP_STATUS status = DSP_EFAIL;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(pdblLib, DBL_LIBSIGNATURE));
+	DBC_Require(pEntry != NULL);
+	DBC_Require(attrs != NULL);
+
+	GT_4trace(DBL_debugMask, GT_ENTER, "DBL_load: lib: 0x%x flags: "
+		 "0x%x attrs: 0x%x pEntry: 0x%x\n", lib, flags, attrs, pEntry);
+
+	dbl = pdblLib->pTarget;
+	*pEntry = pdblLib->fileHdr.entry;
+	nSects = pdblLib->fileHdr.numSects;
+	dbl->dblAttrs = *attrs;
+
+	for (i = 0; i < nSects; i++) {
+		/* Load the section at the current file offset */
+		status = loadSect(dbl, lib);
+		if (DSP_FAILED(status))
+			break;
+
+	}
+
+	/* Done with file, we can close it */
+	if (pdblLib->file) {
+		(*pdblLib->pTarget->dblAttrs.fclose) (pdblLib->file);
+		pdblLib->file = NULL;
+	}
+	return status;
+}
+
+/*
+ *  ======== DBL_loadSect ========
+ *  Purpose:
+ *  	Load a named section from an library (for overlay support).
+ */
+DSP_STATUS DBL_loadSect(struct DBL_LibraryObj *lib, char *sectName,
+			struct DBL_Attrs *attrs)
+{
+	struct DBL_TargetObj *dbl;
+	s32 i;
+	s32 phase;
+	s32 offset = -1;
+	s32 nSects = -1;
+	s32 allocdSects = 0;
+	u32 loadAddr;
+	u32 runAddr;
+	u32 size;
+	u32 space;
+	u32 ulBytes;
+	u16 mauSize;
+	u16 wordSize;
+	u16 *phaseRef = NULL;
+	u16 *otherRef = NULL;
+	char *name = NULL;
+	struct OvlyData *pOvlyData;
+	DSP_STATUS status = DSP_ENOSECT;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(lib, DBL_LIBSIGNATURE));
+	DBC_Require(sectName != NULL);
+	DBC_Require(attrs != NULL);
+	DBC_Require(attrs->write != NULL);
+	GT_3trace(DBL_debugMask, GT_ENTER,
+		 "DBL_loadSect: lib: 0x%x sectName: %s "
+		 "attrs: 0x%x\n", lib, sectName, attrs);
+	dbl = lib->pTarget;
+	mauSize = lib->pTargetInfo->mauSize;
+	wordSize = lib->pTargetInfo->wordSize;
+	/* Check for match of sect name in overlay table */
+	for (i = 0; i < lib->nOvlySects; i++) {
+		name = lib->ppOvlyData[i]->hdr.pName;
+		if (!CSL_Strncmp(name, sectName, CSL_Strlen(name))) {
+			/* Match found */
+			status = DSP_SOK;
+			break;
+		}
+	}
+	if (DSP_SUCCEEDED(status)) {
+		DBC_Assert(i < lib->nOvlySects);
+		pOvlyData = lib->ppOvlyData[i];
+		/*
+		 *  If node overlay, phase will be encoded in name. If not node
+		 *  overlay, set phase to NONE.
+		 */
+		phase = (CSL_Strcmp(name, sectName)) ?
+			CSL_Atoi(sectName + CSL_Strlen(sectName) - 1) : NONE;
+		 /*  Get reference count of node phase to be loaded, offset into
+		 *  overlay data array, and number of sections to overlay.  */
+		switch (phase) {
+		case NONE:
+			/* Not a node overlay */
+			phaseRef = &pOvlyData->hdr.otherRef;
+			nSects = numOtherSects(pOvlyData);
+			offset = otherOffset(pOvlyData);
+			break;
+		case CREATEPHASE:
+			phaseRef = &pOvlyData->hdr.createRef;
+			otherRef = &pOvlyData->hdr.otherRef;
+			if (*otherRef) {
+				/* The overlay sections where node phase was
+				 * not specified, have already been loaded.  */
+				nSects = numCreateSects(pOvlyData);
+				offset = createOffset(pOvlyData);
+			} else {
+				/* Overlay sections where node phase was not
+				 * specified get loaded at create time, along
+				 * with create sects.  */
+				nSects = numCreateSects(pOvlyData) +
+					 numOtherSects(pOvlyData);
+				offset = otherOffset(pOvlyData);
+			}
+			break;
+		case DELETEPHASE:
+			phaseRef = &pOvlyData->hdr.deleteRef;
+			nSects = numDeleteSects(pOvlyData);
+			offset = deleteOffset(pOvlyData);
+			break;
+		case EXECUTEPHASE:
+			phaseRef = &pOvlyData->hdr.executeRef;
+			nSects = numExecuteSects(pOvlyData);
+			offset = executeOffset(pOvlyData);
+			break;
+		default:
+			/* ERROR */
+			DBC_Assert(false);
+			break;
+		}
+		/* Do overlay if reference count is 0 */
+		if (!(*phaseRef)) {
+			/* "Allocate" all sections */
+			for (i = 0; i < nSects; i++) {
+				runAddr = pOvlyData->data[offset + i].runAddr;
+				size = pOvlyData->data[offset + i].size;
+				space = pOvlyData->data[offset + i].page;
+				status = (dbl->dblAttrs.alloc)(dbl->dblAttrs.
+					 rmmHandle, space, size, 0,
+					 &runAddr, true);
+				if (DSP_FAILED(status))
+					break;
+
+				allocdSects++;
+			}
+			if (DSP_SUCCEEDED(status)) {
+				/* Load sections */
+				for (i = 0; i < nSects; i++) {
+					loadAddr = pOvlyData->data[offset + i].
+						   loadAddr;
+					runAddr = pOvlyData->data[offset + i].
+						  runAddr;
+					size = pOvlyData->data[offset + i].
+						size;
+					space = pOvlyData->data[offset + i].
+						page;
+					/* Convert to word address, call
+					 * write function */
+					loadAddr /= (wordSize / mauSize);
+					runAddr /= (wordSize / mauSize);
+					ulBytes = size * mauSize;
+					if ((*attrs->write)(attrs->wHandle,
+					   runAddr, (void *)loadAddr, ulBytes,
+					   space) != ulBytes) {
+						GT_0trace(DBL_debugMask,
+							GT_6CLASS,
+							"DBL_loadSect: write"
+							" failed\n");
+						status = DSP_EFWRITE;
+						break;
+					}
+				}
+			}
+			/* Free sections on failure */
+			if (DSP_FAILED(status))
+				freeSects(dbl, pOvlyData, offset, allocdSects);
+
+		}
+	}
+	if (DSP_SUCCEEDED(status)) {
+		/* Increment reference counts */
+		if (otherRef)
+			*otherRef = *otherRef + 1;
+
+		*phaseRef = *phaseRef + 1;
+	}
+	return status;
+}
+
+/*
+ *  ======== DBL_open ========
+ *  Purpose:
+ *  	DBL_open() returns a library handle that can be used to
+ *  	load/unload the symbols/code/data via DBL_load()/DBL_unload().
+ */
+DSP_STATUS DBL_open(struct DBL_TargetObj *target, char *file, DBL_Flags flags,
+		   struct DBL_LibraryObj **pLib)
+{
+	struct DBL_LibraryObj *pdblLib = NULL;
+	u16 nSymbols;
+	u16 nDCDSects;
+	DSP_STATUS status = DSP_SOK;
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(target, DBL_TARGSIGNATURE));
+	DBC_Require(target->dblAttrs.fopen != NULL);
+	DBC_Require(file != NULL);
+	DBC_Require(pLib != NULL);
+
+	GT_3trace(DBL_debugMask, GT_ENTER, "DBL_open: target: 0x%x file: %s "
+		 "pLib: 0x%x\n", target, file, pLib);
+	/* Allocate DBL library object */
+	MEM_AllocObject(pdblLib, struct DBL_LibraryObj, DBL_LIBSIGNATURE);
+	if (pdblLib == NULL)
+		status = DSP_EMEMORY;
+
+	/* Open the file */
+	if (DSP_SUCCEEDED(status)) {
+		pdblLib->pTarget = target;
+		pdblLib->file = (*target->dblAttrs.fopen)(file, "rb");
+		if (pdblLib->file == NULL)
+			status = DSP_EFOPEN;
+
+	}
+	/* Read file header */
+	if (DSP_SUCCEEDED(status)) {
+		status = readHeader(target, pdblLib);
+		if (DSP_FAILED(status)) {
+			GT_0trace(DBL_debugMask, GT_6CLASS,
+				 "DBL_open(): Failed to read file header\n");
+		}
+	}
+	/* Allocate symbol table */
+	if (DSP_SUCCEEDED(status)) {
+		nSymbols = pdblLib->nSymbols = pdblLib->fileHdr.numSymbols;
+		pdblLib->symbols = MEM_Calloc(nSymbols * sizeof(struct Symbol),
+					     MEM_PAGED);
+		if (pdblLib->symbols == NULL)
+			status = DSP_EMEMORY;
+
+	}
+	/* Read all the symbols */
+	if (DSP_SUCCEEDED(status)) {
+		status = readSymbols(target, pdblLib);
+		if (DSP_FAILED(status)) {
+			GT_0trace(DBL_debugMask, GT_6CLASS,
+				 "DBL_open(): Failed to read symbols\n");
+		}
+	}
+	/* Allocate DCD sect table */
+	if (DSP_SUCCEEDED(status)) {
+		nDCDSects = pdblLib->nDCDSects = pdblLib->fileHdr.numDCDSects;
+		pdblLib->dcdSects = MEM_Calloc(nDCDSects *
+					 sizeof(struct DCDSect), MEM_PAGED);
+		if (pdblLib->dcdSects == NULL)
+			status = DSP_EMEMORY;
+
+	}
+	/* Read DCD sections */
+	if (DSP_SUCCEEDED(status)) {
+		status = readDCDSects(target, pdblLib);
+		if (DSP_FAILED(status)) {
+			GT_0trace(DBL_debugMask, GT_6CLASS,
+				 "DBL_open(): Failed to read DCD sections\n");
+		}
+	}
+	/* Read overlay sections */
+	if (DSP_SUCCEEDED(status)) {
+		status = readOvlySects(target, pdblLib);
+		if (DSP_FAILED(status)) {
+			GT_0trace(DBL_debugMask, GT_6CLASS,
+				 "DBL_open(): Failed to read "
+				 "overlay sections\n");
+		}
+	}
+	if (DSP_FAILED(status)) {
+		*pLib = NULL;
+		if (pdblLib != NULL)
+			DBL_close((struct DBL_LibraryObj *) pdblLib);
+
+	} else {
+		*pLib = pdblLib;
+	}
+	DBC_Ensure((DSP_SUCCEEDED(status) &&
+		  (MEM_IsValidHandle((*pLib), DBL_LIBSIGNATURE))) ||
+		  (DSP_FAILED(status) && *pLib == NULL));
+	return status;
+}
+
+/*
+ *  ======== DBL_readSect ========
+ *  Purpose:
+ *  	Read COFF section into a character buffer.
+ */
+DSP_STATUS DBL_readSect(struct DBL_LibraryObj *lib, char *name, char *pContent,
+			u32 size)
+{
+	struct DBL_LibraryObj *pdblLib = (struct DBL_LibraryObj *)lib;
+	u16 i;
+	u32 mauSize;
+	u32 max;
+	DSP_STATUS status = DSP_ENOSECT;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(pdblLib, DBL_LIBSIGNATURE));
+	DBC_Require(name != NULL);
+	DBC_Require(pContent != NULL);
+	DBC_Require(size != 0);
+	GT_4trace(DBL_debugMask, GT_ENTER, "DBL_readSect: lib: 0x%x name: %s "
+		 "pContent: 0x%x size: 0x%x\n", lib, name, pContent, size);
+
+	mauSize = pdblLib->pTargetInfo->mauSize;
+
+	/* Attempt to find match with DCD section names. */
+	for (i = 0; i < pdblLib->nDCDSects; i++) {
+		if (CSL_Strcmp(pdblLib->dcdSects[i].sectHdr.name, name) == 0) {
+			/* Match found */
+			max = pdblLib->dcdSects[i].sectHdr.size * mauSize;
+			max = (max > size) ? size : max;
+			memcpy(pContent, pdblLib->dcdSects[i].pData, max);
+			status = DSP_SOK;
+			break;
+		}
+	}
+
+	return status;
+}
+
+/*
+ *  ======== DBL_setAttrs ========
+ *  Purpose:
+ *  	Set the attributes of the target.
+ */
+void DBL_setAttrs(struct DBL_TargetObj *target, struct DBL_Attrs *pAttrs)
+{
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(target, DBL_TARGSIGNATURE));
+	DBC_Require(pAttrs != NULL);
+
+	GT_2trace(DBL_debugMask, GT_ENTER, "DBL_setAttrs: target: 0x%x pAttrs: "
+		 "0x%x\n", target, pAttrs);
+
+	target->dblAttrs = *pAttrs;
+}
+
+/*
+ *  ======== DBL_unload ========
+ *  Purpose:
+ *  	Remove the symbols/code/data corresponding to the library lib.
+ */
+void DBL_unload(struct DBL_LibraryObj *lib, struct DBL_Attrs *attrs)
+{
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(lib, DBL_LIBSIGNATURE));
+
+	GT_1trace(DBL_debugMask, GT_ENTER, "DBL_unload: lib: 0x%x\n", lib);
+
+	/* Nothing to do for static loading */
+}
+
+/*
+ *  ======== DBL_unloadSect ========
+ *  Purpose:
+ *  	Unload a named section from an library (for overlay support).
+ */
+DSP_STATUS DBL_unloadSect(struct DBL_LibraryObj *lib, char *sectName,
+			  struct DBL_Attrs *attrs)
+{
+	struct DBL_TargetObj *dbl;
+	s32 i;
+	s32 phase;
+	s32 offset = -1;
+	s32 nSects = -1;
+	u16 *phaseRef = NULL;
+	u16 *otherRef = NULL;
+	char *pName = NULL;
+	struct OvlyData *pOvlyData;
+	DSP_STATUS status = DSP_ENOSECT;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(lib, DBL_LIBSIGNATURE));
+	DBC_Require(sectName != NULL);
+
+	GT_2trace(DBL_debugMask, GT_ENTER,
+		 "DBL_unloadSect: lib: 0x%x sectName: %s\n", lib, sectName);
+	dbl = lib->pTarget;
+	/* Check for match of sect name in overlay table */
+	for (i = 0; i < lib->nOvlySects; i++) {
+		pName = lib->ppOvlyData[i]->hdr.pName;
+		if (!CSL_Strncmp(pName, sectName, CSL_Strlen(pName))) {
+			/* Match found */
+			status = DSP_SOK;
+			break;
+		}
+	}
+	if (DSP_SUCCEEDED(status)) {
+		DBC_Assert(i < lib->nOvlySects);
+		pOvlyData = lib->ppOvlyData[i];
+		/* If node overlay, phase will be encoded in name. */
+		phase = (CSL_Strcmp(pName, sectName)) ?
+			CSL_Atoi(sectName + CSL_Strlen(sectName) - 1) : NONE;
+		switch (phase) {
+		case NONE:
+			nSects = numOtherSects(pOvlyData);
+			phaseRef = &pOvlyData->hdr.otherRef;
+			offset = otherOffset(pOvlyData);
+			break;
+		case CREATEPHASE:
+			nSects = numCreateSects(pOvlyData);
+			offset = createOffset(pOvlyData);
+			phaseRef = &pOvlyData->hdr.createRef;
+			break;
+		case DELETEPHASE:
+			nSects = numDeleteSects(pOvlyData);
+			offset = deleteOffset(pOvlyData);
+			phaseRef = &pOvlyData->hdr.deleteRef;
+			otherRef = &pOvlyData->hdr.otherRef;
+			break;
+		case EXECUTEPHASE:
+			nSects = numExecuteSects(pOvlyData);
+			offset = executeOffset(pOvlyData);
+			phaseRef = &pOvlyData->hdr.executeRef;
+			break;
+		default:
+			/* ERROR */
+			DBC_Assert(false);
+			break;
+		}
+		if (*phaseRef) {
+			*phaseRef = *phaseRef - 1;
+			if (*phaseRef == 0) {
+				/* Unload overlay sections for phase */
+				freeSects(dbl, pOvlyData, offset, nSects);
+			}
+			if (phase == DELETEPHASE) {
+				DBC_Assert(*otherRef);
+				*otherRef = *otherRef - 1;
+				if (*otherRef == 0) {
+					/* Unload other overlay sections */
+					nSects = numOtherSects(pOvlyData);
+					offset = otherOffset(pOvlyData);
+					freeSects(dbl, pOvlyData, offset,
+						 nSects);
+				}
+			}
+		}
+	}
+
+	return status;
+}
+
+/*
+ *  ======== freeSects ========
+ *  Purpose:
+ *  	Free section
+ */
+static void freeSects(struct DBL_TargetObj *dbl, struct OvlyData *pOvlyData,
+		     s32 offset, s32 nSects)
+{
+	u32 runAddr;
+	u32 size;
+	u32 space;
+	s32 i;
+
+	for (i = 0; i < nSects; i++) {
+		runAddr = pOvlyData->data[offset + i].runAddr;
+		size = pOvlyData->data[offset + i].size;
+		space = pOvlyData->data[offset + i].page;
+		if (!(dbl->dblAttrs.free)
+		    (dbl->dblAttrs.rmmHandle, space, runAddr, size, true)) {
+			/*
+			 *  Free function will not fail for overlay, unless
+			 *  address passed in is bad.
+			 */
+			DBC_Assert(false);
+		}
+	}
+}
+
+/*
+ *  ======== loadSect ========
+ *  Purpose:
+ *  	Load section to target
+ */
+static DSP_STATUS loadSect(struct DBL_TargetObj *dbl,
+			  struct DBL_LibraryObj *pdblLib)
+{
+	struct DBOF_SectHdr sectHdr;
+	char *pBuf;
+	struct KFILE_FileObj *file;
+	u32 space;
+	u32 addr;
+	u32 total;
+	u32 nWords = 0;
+	u32 nBytes = 0;
+	u16 mauSize;
+	u32 bufSize;
+	DSP_STATUS status = DSP_SOK;
+
+	file = pdblLib->file;
+	mauSize = pdblLib->pTargetInfo->mauSize;
+	bufSize = LOADBUFSIZE / mauSize;
+	pBuf = dbl->pBuf;
+
+	/* Read the section header */
+	if ((*dbl->dblAttrs.fread)(&sectHdr, sizeof(struct DBOF_SectHdr),
+	   1, file) != 1) {
+		GT_0trace(DBL_debugMask, GT_6CLASS,
+			 "Failed to read DCD sect header\n");
+		status = DSP_EFREAD;
+	} else {
+		if (pdblLib->byteSwapped) {
+			sectHdr.size = SWAPLONG(sectHdr.size);
+			sectHdr.addr = SWAPLONG(sectHdr.addr);
+			sectHdr.page = SWAPWORD(sectHdr.page);
+		}
+	}
+	if (DSP_SUCCEEDED(status)) {
+		addr = sectHdr.addr;
+		space = sectHdr.page;
+		for (total = sectHdr.size; total > 0; total -= nWords) {
+			nWords = min(total, bufSize);
+			nBytes = nWords * mauSize;
+			/* Read section data */
+			if ((*dbl->dblAttrs.fread)(pBuf, nBytes, 1,
+			   file) != 1) {
+				GT_0trace(DBL_debugMask, GT_6CLASS,
+					 "Failed to read DCD sect header\n");
+				status = DSP_EFREAD;
+				break;
+			}
+			/* Write section to target */
+			if (!(*dbl->dblAttrs.write)(dbl->dblAttrs.wHandle,
+			   addr, pBuf, nBytes, space)) {
+				GT_0trace(DBL_debugMask, GT_6CLASS,
+					 "Failed to write section data\n");
+				status = DSP_EFWRITE;
+				break;
+			}
+			addr += nWords;
+		}
+	}
+	return status;
+}
+
+/*
+ *  ======== readDCDSects ========
+ *  Purpose:
+ *  	Read DCD sections.
+ */
+static DSP_STATUS readDCDSects(struct DBL_TargetObj *dbl,
+			      struct DBL_LibraryObj *pdblLib)
+{
+	struct DBOF_DCDSectHdr *pSectHdr;
+	struct DCDSect *pSect;
+	struct KFILE_FileObj *file;
+	u16 nSects;
+	u16 i;
+	u16 mauSize;
+	DSP_STATUS status = DSP_SOK;
+
+	file = pdblLib->file;
+	mauSize = pdblLib->pTargetInfo->mauSize;
+	nSects = pdblLib->fileHdr.numDCDSects;
+	for (i = 0; i < nSects; i++) {
+		pSect = &pdblLib->dcdSects[i];
+		pSectHdr = &pdblLib->dcdSects[i].sectHdr;
+		/* Read sect header */
+		if ((*dbl->dblAttrs.fread)(pSectHdr,
+		   sizeof(struct DBOF_DCDSectHdr), 1, file) != 1) {
+			GT_0trace(DBL_debugMask, GT_6CLASS,
+				 "Failed to read DCD sect header\n");
+			status = DSP_EFREAD;
+			break;
+		}
+		if (pdblLib->byteSwapped)
+			pSectHdr->size = SWAPLONG(pSectHdr->size);
+
+		pSect->pData = (char *)MEM_Calloc(pSectHdr->size *
+				mauSize, MEM_PAGED);
+		if (pSect->pData == NULL) {
+			GT_2trace(DBL_debugMask, GT_6CLASS,
+				 "Memory allocation for sect %s "
+				 "data failed: Size: 0x%lx\n", pSectHdr->name,
+				 pSectHdr->size);
+			status = DSP_EMEMORY;
+			break;
+		}
+		/* Read DCD sect data */
+		if ((*dbl->dblAttrs.fread)(pSect->pData, mauSize,
+		   pSectHdr->size, file) != pSectHdr->size) {
+			GT_0trace(DBL_debugMask, GT_6CLASS,
+				  "Failed to read DCD sect data\n");
+			status = DSP_EFREAD;
+			break;
+		}
+	}
+
+	return status;
+}
+
+/*
+ *  ======== readHeader ========
+ *  Purpose:
+ *  	Read Header.
+ */
+static DSP_STATUS readHeader(struct DBL_TargetObj *dbl,
+			    struct DBL_LibraryObj *pdblLib)
+{
+	struct KFILE_FileObj *file;
+	s32 i;
+	struct DBOF_FileHdr *pHdr;
+	u32 swapMagic;
+	DSP_STATUS status = DSP_SOK;
+
+	pdblLib->byteSwapped = false;
+	file = pdblLib->file;
+	pHdr = &pdblLib->fileHdr;
+	if ((*dbl->dblAttrs.fread)(pHdr, sizeof(struct DBOF_FileHdr), 1,
+	   file) != 1) {
+		GT_0trace(DBL_debugMask, GT_6CLASS,
+			 "readHeader: Failed to read file header\n");
+		status = DSP_EFREAD;
+	}
+
+	if (DSP_SUCCEEDED(status)) {
+		/* Determine if byte swapped */
+		for (i = 0; i < NUMTARGS; i++) {
+			swapMagic = SWAPLONG(pHdr->magic);
+			if (pHdr->magic == magicTab[i] || swapMagic ==
+			   magicTab[i]) {
+				if (swapMagic == magicTab[i]) {
+					pdblLib->byteSwapped = true;
+					pHdr->magic = SWAPLONG(pHdr->magic);
+					pHdr->entry = SWAPLONG(pHdr->entry);
+					pHdr->symOffset = SWAPLONG(pHdr->
+								symOffset);
+					pHdr->dcdSectOffset = SWAPLONG(pHdr->
+								dcdSectOffset);
+					pHdr->loadSectOffset = SWAPLONG(pHdr->
+								loadSectOffset);
+					pHdr->ovlySectOffset = SWAPLONG(pHdr->
+								ovlySectOffset);
+					pHdr->numSymbols = SWAPWORD(pHdr->
+								numSymbols);
+					pHdr->numDCDSects = SWAPWORD(pHdr->
+								numDCDSects);
+					pHdr->numSects = SWAPWORD(pHdr->
+								numSects);
+					pHdr->numOvlySects = SWAPWORD(pHdr->
+								numOvlySects);
+				}
+				break;
+			}
+		}
+		if (i == NUMTARGS) {
+			GT_0trace(DBL_debugMask, GT_6CLASS,
+				 "readHeader: Failed to determine"
+				 " target type\n");
+			status = DSP_ECORRUPTFILE;
+		} else {
+			pdblLib->pTargetInfo = &targetTab[i];
+			GT_1trace(DBL_debugMask, GT_ENTER,
+				 "COF type: 0x%lx\n", pHdr->magic);
+			GT_1trace(DBL_debugMask, GT_ENTER,
+				 "Entry point:0x%lx\n", pHdr->entry);
+		}
+	}
+	return status;
+}
+
+/*
+ *  ======== readOvlySects ========
+ *  Purpose:
+ *  	Read Overlay Sections
+ */
+static DSP_STATUS readOvlySects(struct DBL_TargetObj *dbl,
+				struct DBL_LibraryObj *pdblLib)
+{
+	struct DBOF_OvlySectHdr hdr;
+	struct DBOF_OvlySectData *pData;
+	struct OvlyData *pOvlyData;
+	char *pName;
+	struct KFILE_FileObj *file;
+	u16 i, j;
+	u16 nSects;
+	u16 n;
+	DSP_STATUS status = DSP_SOK;
+
+	pdblLib->nOvlySects = nSects = pdblLib->fileHdr.numOvlySects;
+	file = pdblLib->file;
+	if (nSects > 0) {
+		pdblLib->ppOvlyData = MEM_Calloc(nSects * sizeof(OvlyData *),
+						 MEM_PAGED);
+		if (pdblLib->ppOvlyData == NULL) {
+			GT_0trace(DBL_debugMask, GT_7CLASS,
+				 "Failed to allocatate overlay "
+				 "data memory\n");
+			status = DSP_EMEMORY;
+		}
+	}
+	if (DSP_SUCCEEDED(status)) {
+		/* Read overlay data for each node */
+		for (i = 0; i < nSects; i++) {
+			/* Read overlay section header */
+			if ((*dbl->dblAttrs.fread)(&hdr,
+			   sizeof(struct DBOF_OvlySectHdr), 1, file) != 1) {
+				GT_0trace(DBL_debugMask, GT_6CLASS,
+					 "Failed to read overlay sect"
+					 " header\n");
+				status = DSP_EFREAD;
+				break;
+			}
+			if (pdblLib->byteSwapped) {
+				hdr.nameLen = SWAPWORD(hdr.nameLen);
+				hdr.numCreateSects =
+						SWAPWORD(hdr.numCreateSects);
+				hdr.numDeleteSects =
+						SWAPWORD(hdr.numDeleteSects);
+				hdr.numExecuteSects =
+						SWAPWORD(hdr.numExecuteSects);
+				hdr.numOtherSects =
+						SWAPWORD(hdr.numOtherSects);
+				hdr.resvd = SWAPWORD(hdr.resvd);
+			}
+			n = hdr.numCreateSects + hdr.numDeleteSects +
+			    hdr.numExecuteSects + hdr.numOtherSects;
+
+			/* Allocate memory for node's overlay data */
+			pOvlyData = (struct OvlyData *)MEM_Calloc
+				    (sizeof(struct OvlyHdr) +
+				    n * sizeof(struct DBOF_OvlySectData),
+				    MEM_PAGED);
+			if (pOvlyData == NULL) {
+				GT_0trace(DBL_debugMask, GT_7CLASS,
+					 "Failed to allocatate ovlyay"
+					 " data memory\n");
+				status = DSP_EMEMORY;
+				break;
+			}
+			pOvlyData->hdr.dbofHdr = hdr;
+			pdblLib->ppOvlyData[i] = pOvlyData;
+			/* Allocate memory for section name */
+			pName = (char *)MEM_Calloc(hdr.nameLen + 1, MEM_PAGED);
+			if (pName == NULL) {
+				GT_0trace(DBL_debugMask, GT_7CLASS,
+					 "Failed to allocatate ovlyay"
+					 " section name\n");
+				status = DSP_EMEMORY;
+				break;
+			}
+			pOvlyData->hdr.pName = pName;
+			/* Read the overlay section name */
+			if ((*dbl->dblAttrs.fread)(pName, sizeof(char),
+			   hdr.nameLen, file) != hdr.nameLen) {
+				GT_0trace(DBL_debugMask, GT_7CLASS,
+					 "readOvlySects: Unable to "
+					 "read overlay name.\n");
+				status = DSP_EFREAD;
+				break;
+			}
+			/* Read the overlay section data */
+			pData = pOvlyData->data;
+			if ((*dbl->dblAttrs.fread)(pData,
+			   sizeof(struct DBOF_OvlySectData), n, file) != n) {
+				GT_0trace(DBL_debugMask, GT_7CLASS,
+					 "readOvlySects: Unable to "
+					 "read overlay data.\n");
+				status = DSP_EFREAD;
+				break;
+			}
+			/* Swap overlay data, if necessary */
+			if (pdblLib->byteSwapped) {
+				for (j = 0; j < n; j++) {
+					pData[j].loadAddr =
+						 SWAPLONG(pData[j].loadAddr);
+					pData[j].runAddr =
+						 SWAPLONG(pData[j].runAddr);
+					pData[j].size =
+						 SWAPLONG(pData[j].size);
+					pData[j].page =
+						 SWAPWORD(pData[j].page);
+				}
+			}
+		}
+	}
+	return status;
+}
+
+/*
+ *  ======== readSymbols ========
+ *  Purpose:
+ *  	Read Symbols
+ */
+static DSP_STATUS readSymbols(struct DBL_TargetObj *dbl,
+			     struct DBL_LibraryObj *pdblLib)
+{
+	struct DBOF_SymbolHdr symHdr;
+	struct KFILE_FileObj *file;
+	u16 i;
+	u16 nSymbols;
+	u16 len;
+	char *pName = NULL;
+	DSP_STATUS status = DSP_SOK;
+
+	file = pdblLib->file;
+
+	nSymbols = pdblLib->fileHdr.numSymbols;
+
+	for (i = 0; i < nSymbols; i++) {
+		/* Read symbol value */
+		if ((*dbl->dblAttrs.fread)(&symHdr,
+		   sizeof(struct DBOF_SymbolHdr), 1, file) != 1) {
+			GT_0trace(DBL_debugMask, GT_6CLASS,
+				 "Failed to read symbol value\n");
+			status = DSP_EFREAD;
+			break;
+		}
+		if (pdblLib->byteSwapped) {
+			symHdr.nameLen = SWAPWORD(symHdr.nameLen);
+			symHdr.value = SWAPLONG(symHdr.value);
+		}
+		/* Allocate buffer for symbol name */
+		len = symHdr.nameLen;
+		pName = (char *)MEM_Calloc(len + 1, MEM_PAGED);
+		if (pName == NULL) {
+			GT_0trace(DBL_debugMask, GT_6CLASS,
+				 "Memory allocation failed\n");
+			status = DSP_EMEMORY;
+			break;
+		}
+		pdblLib->symbols[i].pSymName = pName;
+		pdblLib->symbols[i].sym.value = symHdr.value;
+		/* Read symbol name */
+		if ((*dbl->dblAttrs.fread) (pName, sizeof(char), len, file) !=
+		   len) {
+			GT_0trace(DBL_debugMask, GT_6CLASS,
+				 "Failed to read symbol value\n");
+			status = DSP_EFREAD;
+			break;
+		} else {
+			pName[len] = '\0';
+			GT_2trace(DBL_debugMask, GT_ENTER,
+				 "Symbol: %s  Value: 0x%lx\n",
+				 pName, symHdr.value);
+		}
+	}
+	return status;
+}
+
diff --git a/drivers/dsp/bridge/pmgr/dbll.c b/drivers/dsp/bridge/pmgr/dbll.c
new file mode 100644
index 0000000..d4c365f
--- /dev/null
+++ b/drivers/dsp/bridge/pmgr/dbll.c
@@ -0,0 +1,1565 @@
+/*
+ * linux/drivers/dsp/bridge/pmgr/linux/dbll/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.
+ */
+
+/*
+ *  ======== dbll.c ========
+ *
+ *! Revision History
+ *! ================
+ *! 25-Apr-2030 map:    Fixed symbol redefinition bug + unload and return error
+ *! 08-Apr-2003 map: 	Consolidated DBL with DBLL loader name
+ *! 24-Mar-2003 map:    Updated findSymbol to support dllview update
+ *! 23-Jan-2003 map:    Updated rmmAlloc to support memory granularity
+ *! 21-Nov-2002 map:    Combine fopen and DLOAD_module_open to increase
+ *!         performance on start.
+ *! 04-Oct-2002 map:    Integrated new TIP dynamic loader w/ DOF api.
+ *! 27-Sep-2002 map:    Changed handle passed to RemoteFree, instead of
+ *!         RMM_free;  added GT_trace to rmmDealloc
+ *! 20-Sep-2002 map:    Updated from Code Review
+ *! 08-Aug-2002 jeh:    Updated to support overlays.
+ *! 25-Jun-2002 jeh:    Pass RMM_Addr object to alloc function in rmmAlloc().
+ *! 20-Mar-2002 jeh:    Created.
+ */
+
+/*  ----------------------------------- Host OS */
+#include <host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <std.h>
+#include <dbdefs.h>
+#include <errbase.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <gt.h>
+#include <dbc.h>
+#include <gh.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <csl.h>
+#include <mem.h>
+
+/* Dynamic loader library interface */
+#include <dynamic_loader.h>
+#include <getsection.h>
+
+/*  ----------------------------------- This */
+#include <dbll.h>
+#include <rmm.h>
+
+#define DBLL_TARGSIGNATURE      0x544c4c44	/* "TLLD" */
+#define DBLL_LIBSIGNATURE       0x4c4c4c44	/* "LLLD" */
+
+/* Number of buckets for symbol hash table */
+#define MAXBUCKETS 211
+
+/* Max buffer length */
+#define MAXEXPR 128
+
+#ifndef UINT32_C
+#define UINT32_C(zzz) ((uint32_t)zzz)
+#endif
+#define DOFF_ALIGN(x) (((x) + 3) & ~UINT32_C(3))
+
+/*
+ *  ======== struct DBLL_TarObj* ========
+ *  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_TarObj ========
+ */
+struct DBLL_TarObj {
+	u32 dwSignature; 	/* For object validation */
+	struct DBLL_Attrs attrs;
+	struct DBLL_LibraryObj *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).
+ */
+/*
+ *  ======== DBLLStream ========
+ *  Contains Dynamic_Loader_Stream
+ */
+struct DBLLStream {
+	struct Dynamic_Loader_Stream dlStream;
+	struct DBLL_LibraryObj *lib;
+} ;
+
+/*
+ *  ======== DBLLSymbol ========
+ */
+struct DBLLSymbol {
+	struct Dynamic_Loader_Sym dlSymbol;
+	struct DBLL_LibraryObj *lib;
+} ;
+
+/*
+ *  ======== DBLLAlloc ========
+ */
+ struct DBLLAlloc {
+	struct Dynamic_Loader_Allocate dlAlloc;
+	struct DBLL_LibraryObj *lib;
+} ;
+
+/*
+ *  ======== DBLLInit ========
+ */
+struct DBLLInit {
+	struct Dynamic_Loader_Initialize dlInit;
+	struct DBLL_LibraryObj *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_LibraryObj ========
+ */
+ struct DBLL_LibraryObj {
+	u32 dwSignature; 	/* For object validation */
+	struct DBLL_LibraryObj *next; 	/* Next library in target's list */
+	struct DBLL_LibraryObj *prev; 	/* Previous in the list */
+	struct DBLL_TarObj *pTarget; 	/* target for this library */
+
+	/* Objects needed by dynamic loader */
+	struct DBLLStream stream;
+	struct DBLLSymbol symbol;
+	struct DBLLAlloc allocate;
+	struct DBLLInit init;
+	DLOAD_mhandle mHandle;
+
+	char *fileName; 	/* COFF file name */
+	void *fp; 		/* Opaque file handle */
+	u32 entry; 		/* Entry point */
+	DLOAD_mhandle desc; 	/* desc of DOFF file loaded */
+	u32 openRef; 		/* Number of times opened */
+	u32 loadRef; 		/* Number of times loaded */
+	struct GH_THashTab *symTab; 	/* Hash table of symbols */
+	u32 ulPos;
+} ;
+
+/*
+ *  ======== Symbol ========
+ */
+struct Symbol {
+	struct DBLL_Symbol value;
+	char *name;
+} ;
+extern bool bSymbolsReloaded;
+
+static void dofClose(struct DBLL_LibraryObj *zlLib);
+static DSP_STATUS dofOpen(struct DBLL_LibraryObj *zlLib);
+static s32 NoOp(struct Dynamic_Loader_Initialize *thisptr, void *bufr,
+		LDR_ADDR locn, struct LDR_SECTION_INFO *info, unsigned bytsiz);
+
+/*
+ *  Functions called by dynamic loader
+ *
+ */
+/* Dynamic_Loader_Stream */
+static int readBuffer(struct Dynamic_Loader_Stream *this, void *buffer,
+		     unsigned bufsize);
+static int setFilePosn(struct Dynamic_Loader_Stream *this, unsigned int pos);
+/* Dynamic_Loader_Sym */
+static struct dynload_symbol *findSymbol(struct Dynamic_Loader_Sym *this,
+					const char *name);
+static struct dynload_symbol *addToSymbolTable(struct Dynamic_Loader_Sym *this,
+					      const char *name,
+					      unsigned moduleId);
+static struct dynload_symbol *findInSymbolTable(struct Dynamic_Loader_Sym *this,
+						const char *name,
+						unsigned moduleid);
+static void purgeSymbolTable(struct Dynamic_Loader_Sym *this,
+			    unsigned moduleId);
+static void *allocate(struct Dynamic_Loader_Sym *this, unsigned memsize);
+static void deallocate(struct Dynamic_Loader_Sym *this, void *memPtr);
+static void errorReport(struct Dynamic_Loader_Sym *this, const char *errstr,
+			va_list args);
+/* Dynamic_Loader_Allocate */
+static int rmmAlloc(struct Dynamic_Loader_Allocate *this,
+		   struct LDR_SECTION_INFO *info, unsigned align);
+static void rmmDealloc(struct Dynamic_Loader_Allocate *this,
+		      struct LDR_SECTION_INFO *info);
+
+/* Dynamic_Loader_Initialize */
+static int connect(struct Dynamic_Loader_Initialize *this);
+static int readMem(struct Dynamic_Loader_Initialize *this, void *buf,
+		  LDR_ADDR addr, struct LDR_SECTION_INFO *info,
+		  unsigned nbytes);
+static int writeMem(struct Dynamic_Loader_Initialize *this, void *buf,
+		   LDR_ADDR addr, struct LDR_SECTION_INFO *info,
+		   unsigned nbytes);
+static int fillMem(struct Dynamic_Loader_Initialize *this, LDR_ADDR addr,
+		   struct LDR_SECTION_INFO *info, unsigned nbytes,
+		   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 u16 nameHash(void *name, u16 maxBucket);
+static bool nameMatch(void *name, void *sp);
+static void symDelete(void *sp);
+
+#if GT_TRACE
+static struct GT_Mask DBLL_debugMask = { NULL, NULL };     /* GT trace variable */
+#endif
+
+static u32 cRefs; 		/* module reference count */
+
+/* Symbol Redefinition */
+static int bRedefinedSymbol = 0;
+static int bGblSearch = 1;
+
+/*
+ *  ======== DBLL_close ========
+ */
+void DBLL_close(struct DBLL_LibraryObj *zlLib)
+{
+	struct DBLL_TarObj *zlTarget;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
+	DBC_Require(zlLib->openRef > 0);
+	zlTarget = zlLib->pTarget;
+	GT_1trace(DBLL_debugMask, GT_ENTER, "DBLL_close: lib: 0x%x\n", zlLib);
+	zlLib->openRef--;
+	if (zlLib->openRef == 0) {
+		/* Remove library from list */
+		if (zlTarget->head == zlLib)
+			zlTarget->head = zlLib->next;
+
+		if (zlLib->prev)
+			(zlLib->prev)->next = zlLib->next;
+
+		if (zlLib->next)
+			(zlLib->next)->prev = zlLib->prev;
+
+		/* Free DOF resources */
+		dofClose(zlLib);
+		if (zlLib->fileName)
+			MEM_Free(zlLib->fileName);
+
+		/* remove symbols from symbol table */
+		if (zlLib->symTab)
+			GH_delete(zlLib->symTab);
+
+		/* remove the library object itself */
+		MEM_FreeObject(zlLib);
+		zlLib = NULL;
+	}
+}
+
+/*
+ *  ======== DBLL_create ========
+ */
+DSP_STATUS DBLL_create(struct DBLL_TarObj **pTarget, struct DBLL_Attrs *pAttrs)
+{
+	struct DBLL_TarObj *pzlTarget;
+	DSP_STATUS status = DSP_SOK;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(pAttrs != NULL);
+	DBC_Require(pTarget != NULL);
+
+	GT_2trace(DBLL_debugMask, GT_ENTER,
+		  "DBLL_create: pTarget: 0x%x pAttrs: "
+		  "0x%x\n", pTarget, pAttrs);
+	/* Allocate DBL target object */
+	MEM_AllocObject(pzlTarget, struct DBLL_TarObj, DBLL_TARGSIGNATURE);
+	if (pTarget != NULL) {
+		if (pzlTarget == NULL) {
+			GT_0trace(DBLL_debugMask, GT_6CLASS,
+				 "DBLL_create: Memory allocation"
+				 " failed\n");
+			*pTarget = NULL;
+			status = DSP_EMEMORY;
+		} else {
+			pzlTarget->attrs = *pAttrs;
+			*pTarget = (struct DBLL_TarObj *)pzlTarget;
+		}
+		DBC_Ensure((DSP_SUCCEEDED(status) &&
+			  MEM_IsValidHandle(((struct DBLL_TarObj *)(*pTarget)),
+			  DBLL_TARGSIGNATURE)) || (DSP_FAILED(status) &&
+			  *pTarget == NULL));
+	}
+
+	return status;
+}
+
+/*
+ *  ======== DBLL_delete ========
+ */
+void DBLL_delete(struct DBLL_TarObj *target)
+{
+	struct DBLL_TarObj *zlTarget = (struct DBLL_TarObj *)target;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(zlTarget, DBLL_TARGSIGNATURE));
+
+	GT_1trace(DBLL_debugMask, GT_ENTER, "DBLL_delete: target: 0x%x\n",
+		 target);
+
+	if (zlTarget != NULL)
+		MEM_FreeObject(zlTarget);
+
+}
+
+/*
+ *  ======== DBLL_exit ========
+ *  Discontinue usage of DBL module.
+ */
+void DBLL_exit(void)
+{
+	DBC_Require(cRefs > 0);
+
+	cRefs--;
+
+	GT_1trace(DBLL_debugMask, GT_5CLASS, "DBLL_exit() ref count: 0x%x\n",
+		  cRefs);
+
+	if (cRefs == 0) {
+		MEM_Exit();
+		CSL_Exit();
+		GH_exit();
+#if GT_TRACE
+		DBLL_debugMask.flags = 0;
+#endif
+	}
+
+	DBC_Ensure(cRefs >= 0);
+}
+
+/*
+ *  ======== DBLL_getAddr ========
+ *  Get address of name in the specified library.
+ */
+bool DBLL_getAddr(struct DBLL_LibraryObj *zlLib, char *name,
+		  struct DBLL_Symbol **ppSym)
+{
+	struct Symbol *sym;
+	bool status = false;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
+	DBC_Require(name != NULL);
+	DBC_Require(ppSym != NULL);
+	DBC_Require(zlLib->symTab != NULL);
+
+	GT_3trace(DBLL_debugMask, GT_ENTER,
+		 "DBLL_getAddr: lib: 0x%x name: %s pAddr:"
+		 " 0x%x\n", zlLib, name, ppSym);
+	sym = (struct Symbol *)GH_find(zlLib->symTab, name);
+	if (sym != NULL) {
+		*ppSym = &sym->value;
+		status = true;
+	}
+	return status;
+}
+
+/*
+ *  ======== DBLL_getAttrs ========
+ *  Retrieve the attributes of the target.
+ */
+void DBLL_getAttrs(struct DBLL_TarObj *target, struct DBLL_Attrs *pAttrs)
+{
+	struct DBLL_TarObj *zlTarget = (struct DBLL_TarObj *)target;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(zlTarget, DBLL_TARGSIGNATURE));
+	DBC_Require(pAttrs != NULL);
+
+	if ((pAttrs != NULL) && (zlTarget != NULL))
+		*pAttrs = zlTarget->attrs;
+
+}
+
+/*
+ *  ======== DBLL_getCAddr ========
+ *  Get address of a "C" name in the specified library.
+ */
+bool DBLL_getCAddr(struct DBLL_LibraryObj *zlLib, char *name,
+		   struct DBLL_Symbol **ppSym)
+{
+	struct Symbol *sym;
+	char cname[MAXEXPR + 1];
+	bool status = false;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
+	DBC_Require(ppSym != NULL);
+	DBC_Require(zlLib->symTab != NULL);
+	DBC_Require(name != NULL);
+
+	cname[0] = '_';
+
+	CSL_Strcpyn(cname + 1, name, sizeof(cname) - 2);
+	cname[MAXEXPR] = '\0'; 	/* insure '\0' string termination */
+
+	/* Check for C name, if not found */
+	sym = (struct Symbol *)GH_find(zlLib->symTab, cname);
+
+	if (sym != NULL) {
+		*ppSym = &sym->value;
+		status = true;
+	}
+
+	return status;
+}
+
+/*
+ *  ======== DBLL_getSect ========
+ *  Get the base address and size (in bytes) of a COFF section.
+ */
+DSP_STATUS DBLL_getSect(struct DBLL_LibraryObj *lib, char *name, u32 *pAddr,
+			u32 *pSize)
+{
+	u32 uByteSize;
+	bool fOpenedDoff = false;
+	const struct LDR_SECTION_INFO *sect = NULL;
+	struct DBLL_LibraryObj *zlLib = (struct DBLL_LibraryObj *)lib;
+	DSP_STATUS status = DSP_SOK;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(name != NULL);
+	DBC_Require(pAddr != NULL);
+	DBC_Require(pSize != NULL);
+	DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
+
+	GT_4trace(DBLL_debugMask, GT_ENTER,
+		 "DBLL_getSect: lib: 0x%x name: %s pAddr:"
+		 " 0x%x pSize: 0x%x\n", lib, name, pAddr, pSize);
+	/* If DOFF file is not open, we open it. */
+	if (zlLib != NULL) {
+		if (zlLib->fp == NULL) {
+			status = dofOpen(zlLib);
+			if (DSP_SUCCEEDED(status))
+				fOpenedDoff = true;
+
+		} else {
+			(*(zlLib->pTarget->attrs.fseek))(zlLib->fp,
+			 zlLib->ulPos, SEEK_SET);
+		}
+	}
+	if (DSP_SUCCEEDED(status)) {
+		uByteSize = 1;
+		if (DLOAD_GetSectionInfo(zlLib->desc, name, &sect)) {
+			*pAddr = sect->load_addr;
+			*pSize = sect->size * uByteSize;
+			/* Make sure size is even for good swap */
+			if (*pSize % 2)
+				(*pSize)++;
+
+			/* Align size */
+			*pSize = DOFF_ALIGN(*pSize);
+		} else {
+			status = DSP_ENOSECT;
+		}
+	}
+	if (fOpenedDoff) {
+		dofClose(zlLib);
+		fOpenedDoff = false;
+	}
+
+	return status;
+}
+
+/*
+ *  ======== 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();
+		CSL_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;
+}
+
+/*
+ *  ======== DBLL_load ========
+ */
+DSP_STATUS DBLL_load(struct DBLL_LibraryObj *lib, DBLL_Flags flags,
+		     struct DBLL_Attrs *attrs, u32 *pEntry)
+{
+	struct DBLL_LibraryObj *zlLib = (struct DBLL_LibraryObj *)lib;
+	struct DBLL_TarObj *dbzl;
+	bool gotSymbols = true;
+	s32 err;
+	DSP_STATUS status = DSP_SOK;
+	bool fOpenedDoff = false;
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
+	DBC_Require(pEntry != NULL);
+	DBC_Require(attrs != NULL);
+
+	GT_4trace(DBLL_debugMask, GT_ENTER,
+		 "DBLL_load: lib: 0x%x flags: 0x%x pEntry:"
+		 " 0x%x\n", lib, flags, attrs, pEntry);
+	/*
+	 *  Load if not already loaded.
+	 */
+	if (zlLib->loadRef == 0 || !(flags & DBLL_DYNAMIC)) {
+		dbzl = zlLib->pTarget;
+		dbzl->attrs = *attrs;
+		/* Create a hash table for symbols if not already created */
+		if (zlLib->symTab == NULL) {
+			gotSymbols = false;
+			zlLib->symTab = GH_create(MAXBUCKETS,
+						 sizeof(struct Symbol),
+						 nameHash,
+						 nameMatch, symDelete);
+			if (zlLib->symTab == NULL)
+				status = DSP_EMEMORY;
+
+		}
+		/*
+		 *  Set up objects needed by the dynamic loader
+		 */
+		/* Stream */
+		zlLib->stream.dlStream.read_buffer = readBuffer;
+		zlLib->stream.dlStream.set_file_posn = setFilePosn;
+		zlLib->stream.lib = zlLib;
+		/* Symbol */
+		zlLib->symbol.dlSymbol.Find_Matching_Symbol = findSymbol;
+		if (gotSymbols) {
+			zlLib->symbol.dlSymbol.Add_To_Symbol_Table =
+							findInSymbolTable;
+		} else {
+			zlLib->symbol.dlSymbol.Add_To_Symbol_Table =
+							addToSymbolTable;
+		}
+		zlLib->symbol.dlSymbol.Purge_Symbol_Table = purgeSymbolTable;
+		zlLib->symbol.dlSymbol.Allocate = allocate;
+		zlLib->symbol.dlSymbol.Deallocate = deallocate;
+		zlLib->symbol.dlSymbol.Error_Report = errorReport;
+		zlLib->symbol.lib = zlLib;
+		/* Allocate */
+		zlLib->allocate.dlAlloc.Allocate = rmmAlloc;
+		zlLib->allocate.dlAlloc.Deallocate = rmmDealloc;
+		zlLib->allocate.lib = zlLib;
+		/* Init */
+		zlLib->init.dlInit.connect = connect;
+		zlLib->init.dlInit.readmem = readMem;
+		zlLib->init.dlInit.writemem = writeMem;
+		zlLib->init.dlInit.fillmem = fillMem;
+		zlLib->init.dlInit.execute = execute;
+		zlLib->init.dlInit.release = release;
+		zlLib->init.lib = zlLib;
+		/* If COFF file is not open, we open it. */
+		if (zlLib->fp == NULL) {
+			status = dofOpen(zlLib);
+			if (DSP_SUCCEEDED(status))
+				fOpenedDoff = true;
+
+		}
+		if (DSP_SUCCEEDED(status)) {
+			zlLib->ulPos = (*(zlLib->pTarget->attrs.ftell))
+					(zlLib->fp);
+			/* Reset file cursor */
+			(*(zlLib->pTarget->attrs.fseek))(zlLib->fp, (long)0,
+				 SEEK_SET);
+			bSymbolsReloaded = 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(&zlLib->stream.dlStream,
+			      &zlLib->symbol.dlSymbol, &zlLib->allocate.dlAlloc,
+			      &zlLib->init.dlInit, DLOAD_INITBSS,
+			      &zlLib->mHandle);
+
+			if (err != 0) {
+				GT_1trace(DBLL_debugMask, GT_6CLASS,
+					 "DBLL_load: "
+					 "Dynamic_Load_Module failed: 0x%lx\n",
+					 err);
+				status = DSP_EDYNLOAD;
+			} else if (bRedefinedSymbol) {
+				zlLib->loadRef++;
+				DBLL_unload(zlLib, (struct DBLL_Attrs *) attrs);
+				bRedefinedSymbol = false;
+				status = DSP_EDYNLOAD;
+			} else {
+				*pEntry = zlLib->entry;
+			}
+		}
+	}
+	if (DSP_SUCCEEDED(status))
+		zlLib->loadRef++;
+
+	/* Clean up DOFF resources */
+	if (fOpenedDoff)
+		dofClose(zlLib);
+
+	DBC_Ensure(DSP_FAILED(status) || zlLib->loadRef > 0);
+	return status;
+}
+
+/*
+ *  ======== DBLL_loadSect ========
+ *  Not supported for COFF.
+ */
+DSP_STATUS DBLL_loadSect(struct DBLL_LibraryObj *zlLib, char *sectName,
+			struct DBLL_Attrs *attrs)
+{
+	DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
+
+	return DSP_ENOTIMPL;
+}
+
+/*
+ *  ======== DBLL_open ========
+ */
+DSP_STATUS DBLL_open(struct DBLL_TarObj *target, char *file, DBLL_Flags flags,
+		    struct DBLL_LibraryObj **pLib)
+{
+	struct DBLL_TarObj *zlTarget = (struct DBLL_TarObj *)target;
+	struct DBLL_LibraryObj *zlLib = NULL;
+	s32 err;
+	DSP_STATUS status = DSP_SOK;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(zlTarget, DBLL_TARGSIGNATURE));
+	DBC_Require(zlTarget->attrs.fopen != NULL);
+	DBC_Require(file != NULL);
+	DBC_Require(pLib != NULL);
+
+	GT_3trace(DBLL_debugMask, GT_ENTER,
+		 "DBLL_open: target: 0x%x file: %s pLib:"
+		 " 0x%x\n", target, file, pLib);
+	zlLib = zlTarget->head;
+	while (zlLib != NULL) {
+		if (CSL_Strcmp(zlLib->fileName, file) == 0) {
+			/* Library is already opened */
+			zlLib->openRef++;
+			break;
+		}
+		zlLib = zlLib->next;
+	}
+	if (zlLib == NULL) {
+		/* Allocate DBL library object */
+		MEM_AllocObject(zlLib, struct DBLL_LibraryObj,
+				DBLL_LIBSIGNATURE);
+		if (zlLib == NULL) {
+			GT_0trace(DBLL_debugMask, GT_6CLASS,
+				 "DBLL_open: Memory allocation failed\n");
+			status = DSP_EMEMORY;
+		} else {
+			zlLib->ulPos = 0;
+			/* Increment ref count to allow close on failure
+			 * later on */
+			zlLib->openRef++;
+			zlLib->pTarget = zlTarget;
+			/* Keep a copy of the file name */
+			zlLib->fileName = MEM_Calloc(CSL_Strlen(file) + 1,
+							MEM_PAGED);
+			if (zlLib->fileName == NULL) {
+				GT_0trace(DBLL_debugMask, GT_6CLASS,
+					 "DBLL_open: Memory "
+					 "allocation failed\n");
+				status = DSP_EMEMORY;
+			} else {
+				CSL_Strcpyn(zlLib->fileName, file,
+					   CSL_Strlen(file) + 1);
+			}
+			zlLib->symTab = NULL;
+		}
+	}
+	/*
+	 *  Set up objects needed by the dynamic loader
+	 */
+	if (DSP_FAILED(status))
+		goto func_cont;
+
+	/* Stream */
+	zlLib->stream.dlStream.read_buffer = readBuffer;
+	zlLib->stream.dlStream.set_file_posn = setFilePosn;
+	zlLib->stream.lib = zlLib;
+	/* Symbol */
+	zlLib->symbol.dlSymbol.Add_To_Symbol_Table = addToSymbolTable;
+	zlLib->symbol.dlSymbol.Find_Matching_Symbol = findSymbol;
+	zlLib->symbol.dlSymbol.Purge_Symbol_Table = purgeSymbolTable;
+	zlLib->symbol.dlSymbol.Allocate = allocate;
+	zlLib->symbol.dlSymbol.Deallocate = deallocate;
+	zlLib->symbol.dlSymbol.Error_Report = errorReport;
+	zlLib->symbol.lib = zlLib;
+	/* Allocate */
+	zlLib->allocate.dlAlloc.Allocate = rmmAlloc;
+	zlLib->allocate.dlAlloc.Deallocate = rmmDealloc;
+	zlLib->allocate.lib = zlLib;
+	/* Init */
+	zlLib->init.dlInit.connect = connect;
+	zlLib->init.dlInit.readmem = readMem;
+	zlLib->init.dlInit.writemem = writeMem;
+	zlLib->init.dlInit.fillmem = fillMem;
+	zlLib->init.dlInit.execute = execute;
+	zlLib->init.dlInit.release = release;
+	zlLib->init.lib = zlLib;
+	if (DSP_SUCCEEDED(status) && zlLib->fp == NULL)
+		status = dofOpen(zlLib);
+
+	zlLib->ulPos = (*(zlLib->pTarget->attrs.ftell)) (zlLib->fp);
+	(*(zlLib->pTarget->attrs.fseek))(zlLib->fp, (long) 0, SEEK_SET);
+	/* Create a hash table for symbols if flag is set */
+	if (zlLib->symTab != NULL || !(flags & DBLL_SYMB))
+		goto func_cont;
+
+	zlLib->symTab = GH_create(MAXBUCKETS, sizeof(struct Symbol), nameHash,
+				 nameMatch, symDelete);
+	if (zlLib->symTab == NULL) {
+		status = DSP_EMEMORY;
+	} else {
+		/* Do a fake load to get symbols - set write function to NoOp */
+		zlLib->init.dlInit.writemem = NoOp;
+		err = Dynamic_Open_Module(&zlLib->stream.dlStream,
+					&zlLib->symbol.dlSymbol,
+					&zlLib->allocate.dlAlloc,
+					&zlLib->init.dlInit, 0,
+					&zlLib->mHandle);
+		if (err != 0) {
+			GT_1trace(DBLL_debugMask, GT_6CLASS, "DBLL_open: "
+				 "Dynamic_Load_Module failed: 0x%lx\n", err);
+			status = DSP_EDYNLOAD;
+		} else {
+			/* Now that we have the symbol table, we can unload */
+			err = Dynamic_Unload_Module(zlLib->mHandle,
+						   &zlLib->symbol.dlSymbol,
+						   &zlLib->allocate.dlAlloc,
+						   &zlLib->init.dlInit);
+			if (err != 0) {
+				GT_1trace(DBLL_debugMask, GT_6CLASS,
+					"DBLL_open: "
+					"Dynamic_Unload_Module failed: 0x%lx\n",
+					err);
+				status = DSP_EDYNLOAD;
+			}
+			zlLib->mHandle = NULL;
+		}
+	}
+func_cont:
+	if (DSP_SUCCEEDED(status)) {
+		if (zlLib->openRef == 1) {
+			/* First time opened - insert in list */
+			if (zlTarget->head)
+				(zlTarget->head)->prev = zlLib;
+
+			zlLib->prev = NULL;
+			zlLib->next = zlTarget->head;
+			zlTarget->head = zlLib;
+		}
+		*pLib = (struct DBLL_LibraryObj *)zlLib;
+	} else {
+		*pLib = NULL;
+		if (zlLib != NULL)
+			DBLL_close((struct DBLL_LibraryObj *)zlLib);
+
+	}
+	DBC_Ensure((DSP_SUCCEEDED(status) && (zlLib->openRef > 0) &&
+		  MEM_IsValidHandle(((struct DBLL_LibraryObj *)(*pLib)),
+		  DBLL_LIBSIGNATURE)) || (DSP_FAILED(status) && *pLib == NULL));
+	return status;
+}
+
+/*
+ *  ======== DBLL_readSect ========
+ *  Get the content of a COFF section.
+ */
+DSP_STATUS DBLL_readSect(struct DBLL_LibraryObj *lib, char *name,
+			 char *pContent, u32 size)
+{
+	struct DBLL_LibraryObj *zlLib = (struct DBLL_LibraryObj *)lib;
+	bool fOpenedDoff = false;
+	u32 uByteSize; 		/* size of bytes */
+	u32 ulSectSize; 		/* size of section */
+	const struct LDR_SECTION_INFO *sect = NULL;
+	DSP_STATUS status = DSP_SOK;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
+	DBC_Require(name != NULL);
+	DBC_Require(pContent != NULL);
+	DBC_Require(size != 0);
+
+	GT_4trace(DBLL_debugMask, GT_ENTER,
+		 "DBLL_readSect: lib: 0x%x name: %s "
+		 "pContent: 0x%x size: 0x%x\n", lib, name, pContent, size);
+	/* If DOFF file is not open, we open it. */
+	if (zlLib != NULL) {
+		if (zlLib->fp == NULL) {
+			status = dofOpen(zlLib);
+			if (DSP_SUCCEEDED(status))
+				fOpenedDoff = true;
+
+		} else {
+			(*(zlLib->pTarget->attrs.fseek))(zlLib->fp,
+				zlLib->ulPos, SEEK_SET);
+		}
+	}
+
+	if (DSP_FAILED(status))
+		goto func_cont;
+
+	uByteSize = 1;
+	if (!DLOAD_GetSectionInfo(zlLib->desc, name, &sect)) {
+		status = DSP_ENOSECT;
+		goto func_cont;
+	}
+	/*
+	 * Ensure the supplied buffer size is sufficient to store
+	 * the section content to be read.
+	 */
+	ulSectSize = sect->size * uByteSize;
+	/* Make sure size is even for good swap */
+	if (ulSectSize % 2)
+		ulSectSize++;
+
+	/* Align size */
+	ulSectSize = DOFF_ALIGN(ulSectSize);
+	if (ulSectSize > size) {
+		status = DSP_EFAIL;
+	} else {
+		if (!DLOAD_GetSection(zlLib->desc, sect, pContent))
+			status = DSP_EFREAD;
+
+	}
+func_cont:
+	if (fOpenedDoff) {
+		dofClose(zlLib);
+		fOpenedDoff = false;
+	}
+	return status;
+}
+
+/*
+ *  ======== DBLL_setAttrs ========
+ *  Set the attributes of the target.
+ */
+void DBLL_setAttrs(struct DBLL_TarObj *target, struct DBLL_Attrs *pAttrs)
+{
+	struct DBLL_TarObj *zlTarget = (struct DBLL_TarObj *)target;
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(zlTarget, DBLL_TARGSIGNATURE));
+	DBC_Require(pAttrs != NULL);
+	GT_2trace(DBLL_debugMask, GT_ENTER,
+		 "DBLL_setAttrs: target: 0x%x pAttrs: "
+		 "0x%x\n", target, pAttrs);
+	if ((pAttrs != NULL) && (zlTarget != NULL))
+		zlTarget->attrs = *pAttrs;
+
+}
+
+/*
+ *  ======== DBLL_unload ========
+ */
+void DBLL_unload(struct DBLL_LibraryObj *lib, struct DBLL_Attrs *attrs)
+{
+	struct DBLL_LibraryObj *zlLib = (struct DBLL_LibraryObj *)lib;
+	s32 err = 0;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(zlLib, DBLL_LIBSIGNATURE));
+	DBC_Require(zlLib->loadRef > 0);
+	GT_1trace(DBLL_debugMask, GT_ENTER, "DBLL_unload: lib: 0x%x\n", lib);
+	zlLib->loadRef--;
+	/* Unload only if reference count is 0 */
+	if (zlLib->loadRef != 0)
+		goto func_end;
+
+	zlLib->pTarget->attrs = *attrs;
+	if (zlLib != NULL) {
+		if (zlLib->mHandle) {
+			err = Dynamic_Unload_Module(zlLib->mHandle,
+				&zlLib->symbol.dlSymbol,
+				&zlLib->allocate.dlAlloc, &zlLib->init.dlInit);
+			if (err != 0) {
+				GT_1trace(DBLL_debugMask, GT_5CLASS,
+					 "Dynamic_Unload_Module "
+					 "failed: 0x%x\n", err);
+			}
+		}
+		/* remove symbols from symbol table */
+		if (zlLib->symTab != NULL) {
+			GH_delete(zlLib->symTab);
+			zlLib->symTab = NULL;
+		}
+		/* delete DOFF desc since it holds *lots* of host OS
+		 * resources */
+		dofClose(zlLib);
+	}
+func_end:
+	DBC_Ensure(zlLib->loadRef >= 0);
+}
+
+/*
+ *  ======== DBLL_unloadSect ========
+ *  Not supported for COFF.
+ */
+DSP_STATUS DBLL_unloadSect(struct DBLL_LibraryObj *lib, char *sectName,
+			  struct DBLL_Attrs *attrs)
+{
+	DBC_Require(cRefs > 0);
+	DBC_Require(sectName != NULL);
+	GT_2trace(DBLL_debugMask, GT_ENTER,
+		 "DBLL_unloadSect: lib: 0x%x sectName: "
+		 "%s\n", lib, sectName);
+	return DSP_ENOTIMPL;
+}
+
+/*
+ *  ======== dofClose ========
+ */
+static void dofClose(struct DBLL_LibraryObj *zlLib)
+{
+	if (zlLib->desc) {
+		DLOAD_module_close(zlLib->desc);
+		zlLib->desc = NULL;
+	}
+	/* close file */
+	if (zlLib->fp) {
+		(zlLib->pTarget->attrs.fclose) (zlLib->fp);
+		zlLib->fp = NULL;
+	}
+}
+
+/*
+ *  ======== dofOpen ========
+ */
+static DSP_STATUS dofOpen(struct DBLL_LibraryObj *zlLib)
+{
+	void *open = *(zlLib->pTarget->attrs.fopen);
+	DSP_STATUS status = DSP_SOK;
+
+	/* First open the file for the dynamic loader, then open COF */
+	zlLib->fp = (void *)((Fxn)(open))(zlLib->fileName, "rb");
+
+	/* Open DOFF module */
+	if (zlLib->fp && zlLib->desc == NULL) {
+		(*(zlLib->pTarget->attrs.fseek))(zlLib->fp, (long)0, SEEK_SET);
+		zlLib->desc = DLOAD_module_open(&zlLib->stream.dlStream,
+						&zlLib->symbol.dlSymbol);
+		if (zlLib->desc == NULL) {
+			(zlLib->pTarget->attrs.fclose)(zlLib->fp);
+			zlLib->fp = NULL;
+			status = DSP_EFOPEN;
+		}
+	} else {
+		status = DSP_EFOPEN;
+	}
+
+	return status;
+}
+
+/*
+ *  ======== nameHash ========
+ */
+static u16 nameHash(void *key, u16 maxBucket)
+{
+	u16 ret;
+	u16 hash;
+	char *name = (char *)key;
+
+	DBC_Require(name != NULL);
+
+	hash = 0;
+
+	while (*name) {
+		hash <<= 1;
+		hash ^= *name++;
+	}
+
+	ret = hash % maxBucket;
+
+	return ret;
+}
+
+/*
+ *  ======== nameMatch ========
+ */
+static bool nameMatch(void *key, void *value)
+{
+	DBC_Require(key != NULL);
+	DBC_Require(value != NULL);
+
+	if ((key != NULL) && (value != NULL)) {
+		if (CSL_Strcmp((char *)key, ((struct Symbol *)value)->
+		   name) == 0) {
+			return true;
+		}
+	}
+	return false;
+}
+
+/*
+ *  ======== NoOp ========
+ */
+static int NoOp(struct Dynamic_Loader_Initialize *thisptr, void *bufr,
+		LDR_ADDR locn, struct LDR_SECTION_INFO *info, unsigned bytsize)
+{
+	return 1;
+}
+
+/*
+ *  ======== symDelete ========
+ */
+static void symDelete(void *value)
+{
+	struct Symbol *sp = (struct Symbol *)value;
+
+	MEM_Free(sp->name);
+}
+
+/*
+ *  Dynamic Loader Functions
+ */
+
+/* Dynamic_Loader_Stream */
+/*
+ *  ======== readBuffer ========
+ */
+static int readBuffer(struct Dynamic_Loader_Stream *this, void *buffer,
+		     unsigned bufsize)
+{
+	struct DBLLStream *pStream = (struct DBLLStream *)this;
+	struct DBLL_LibraryObj *lib;
+	int bytesRead = 0;
+
+	DBC_Require(this != NULL);
+	lib = pStream->lib;
+	DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
+
+	if (lib != NULL) {
+		bytesRead = (*(lib->pTarget->attrs.fread))(buffer, 1, bufsize,
+			    lib->fp);
+	}
+	return bytesRead;
+}
+
+/*
+ *  ======== setFilePosn ========
+ */
+static int setFilePosn(struct Dynamic_Loader_Stream *this, unsigned int pos)
+{
+	struct DBLLStream *pStream = (struct DBLLStream *)this;
+	struct DBLL_LibraryObj *lib;
+	int status = 0; 		/* Success */
+
+	DBC_Require(this != NULL);
+	lib = pStream->lib;
+	DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
+
+	if (lib != NULL) {
+		status = (*(lib->pTarget->attrs.fseek))(lib->fp, (long)pos,
+			 SEEK_SET);
+	}
+
+	return status;
+}
+
+/* Dynamic_Loader_Sym */
+
+/*
+ *  ======== findSymbol ========
+ */
+static struct dynload_symbol *findSymbol(struct Dynamic_Loader_Sym *this,
+					const char *name)
+{
+	struct dynload_symbol *retSym;
+	struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
+	struct DBLL_LibraryObj *lib;
+	struct DBLL_Symbol *pSym = NULL;
+	bool status = false; 	/* Symbol not found yet */
+
+	DBC_Require(this != NULL);
+	lib = pSymbol->lib;
+	DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
+
+	if (lib != NULL) {
+		if (lib->pTarget->attrs.symLookup) {
+			/* Check current lib + base lib + dep lib +
+			 * persistent lib */
+			status = (*(lib->pTarget->attrs.symLookup))
+				 (lib->pTarget->attrs.symHandle,
+				 lib->pTarget->attrs.symArg,
+				 lib->pTarget->attrs.rmmHandle, name, &pSym);
+		} else {
+			/* Just check current lib for symbol */
+			status = DBLL_getAddr((struct DBLL_LibraryObj *)lib,
+				 (char *)name, &pSym);
+			if (!status) {
+				status =
+				   DBLL_getCAddr((struct DBLL_LibraryObj *)lib,
+				   (char *)name, &pSym);
+			}
+		}
+	}
+
+	if (!status && bGblSearch) {
+		GT_1trace(DBLL_debugMask, GT_6CLASS,
+			 "findSymbol: Symbol not found: %s\n", name);
+	}
+
+	DBC_Assert((status && (pSym != NULL)) || (!status && (pSym == NULL)));
+
+	retSym = (struct dynload_symbol *)pSym;
+	return retSym;
+}
+
+/*
+ *  ======== findInSymbolTable ========
+ */
+static struct dynload_symbol *findInSymbolTable(struct Dynamic_Loader_Sym *this,
+						const char *name,
+						unsigned moduleid)
+{
+	struct dynload_symbol *retSym;
+	struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
+	struct DBLL_LibraryObj *lib;
+	struct Symbol *sym;
+
+	DBC_Require(this != NULL);
+	lib = pSymbol->lib;
+	DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
+	DBC_Require(lib->symTab != NULL);
+
+	sym = (struct Symbol *)GH_find(lib->symTab, (char *) name);
+
+	retSym = (struct dynload_symbol *)&sym->value;
+	return retSym;
+}
+
+/*
+ *  ======== addToSymbolTable ========
+ */
+static struct dynload_symbol *addToSymbolTable(struct Dynamic_Loader_Sym *this,
+					      const char *name,
+					      unsigned moduleId)
+{
+	struct Symbol *symPtr = NULL;
+	struct Symbol symbol;
+	struct dynload_symbol *pSym = NULL;
+	struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
+	struct DBLL_LibraryObj *lib;
+	struct dynload_symbol *retVal;
+
+	DBC_Require(this != NULL);
+	lib = pSymbol->lib;
+	DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
+
+	/* Check to see if symbol is already defined in symbol table */
+	if (!(lib->pTarget->attrs.baseImage)) {
+		bGblSearch = false;
+		pSym = findSymbol(this, name);
+		bGblSearch = true;
+		if (pSym) {
+			bRedefinedSymbol = true;
+			GT_1trace(DBLL_debugMask, GT_6CLASS,
+				 "Symbol already defined in "
+				 "symbol table: %s\n", name);
+			return NULL;
+		}
+	}
+	/* Allocate string to copy symbol name */
+	symbol.name = (char *)MEM_Calloc(CSL_Strlen((char *const)name) + 1,
+							MEM_PAGED);
+	if (symbol.name == NULL)
+		return NULL;
+
+	if (symbol.name != NULL) {
+		/* Just copy name (value will be filled in by dynamic loader) */
+		CSL_Strcpyn(symbol.name, (char *const)name,
+			   CSL_Strlen((char *const)name) + 1);
+
+		/* Add symbol to symbol table */
+		symPtr = (struct Symbol *)GH_insert(lib->symTab, (void *)name,
+			 (void *)&symbol);
+		if (symPtr == NULL)
+			MEM_Free(symbol.name);
+
+	}
+	if (symPtr != NULL)
+		retVal = (struct dynload_symbol *)&symPtr->value;
+	else
+		retVal = NULL;
+
+	return retVal;
+}
+
+/*
+ *  ======== purgeSymbolTable ========
+ */
+static void purgeSymbolTable(struct Dynamic_Loader_Sym *this, unsigned moduleId)
+{
+	struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
+	struct DBLL_LibraryObj *lib;
+
+	DBC_Require(this != NULL);
+	lib = pSymbol->lib;
+	DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
+
+	/* May not need to do anything */
+}
+
+/*
+ *  ======== allocate ========
+ */
+static void *allocate(struct Dynamic_Loader_Sym *this, unsigned memsize)
+{
+	struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
+	struct DBLL_LibraryObj *lib;
+	void *buf;
+
+	DBC_Require(this != NULL);
+	lib = pSymbol->lib;
+	DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
+
+	buf = MEM_Calloc(memsize, MEM_PAGED);
+
+	return buf;
+}
+
+/*
+ *  ======== deallocate ========
+ */
+static void deallocate(struct Dynamic_Loader_Sym *this, void *memPtr)
+{
+	struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
+	struct DBLL_LibraryObj *lib;
+
+	DBC_Require(this != NULL);
+	lib = pSymbol->lib;
+	DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
+
+	MEM_Free(memPtr);
+}
+
+/*
+ *  ======== errorReport ========
+ */
+static void errorReport(struct Dynamic_Loader_Sym *this, const char *errstr,
+			va_list args)
+{
+	struct DBLLSymbol *pSymbol = (struct DBLLSymbol *)this;
+	struct DBLL_LibraryObj *lib;
+	char tempBuf[MAXEXPR];
+
+	DBC_Require(this != NULL);
+	lib = pSymbol->lib;
+	DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
+	vsnprintf((char *)tempBuf, MAXEXPR, (char *)errstr, args);
+	GT_1trace(DBLL_debugMask, GT_5CLASS, "%s\n", tempBuf);
+}
+
+/* Dynamic_Loader_Allocate */
+
+/*
+ *  ======== rmmAlloc ========
+ */
+static int rmmAlloc(struct Dynamic_Loader_Allocate *this,
+		   struct LDR_SECTION_INFO *info, unsigned align)
+{
+	struct DBLLAlloc *pAlloc = (struct DBLLAlloc *)this;
+	struct DBLL_LibraryObj *lib;
+	DSP_STATUS status = DSP_SOK;
+	u32 memType;
+	struct RMM_Addr rmmAddr;
+	s32 retVal = TRUE;
+	unsigned stype = DLOAD_SECTION_TYPE(info->type);
+	char *pToken = NULL;
+	char *szSecLastToken = NULL;
+	char *szLastToken = NULL;
+	char *szSectName = NULL;
+	char *pszCur;
+	s32 tokenLen = 0;
+	s32 segId = -1;
+	s32 req = -1;
+	s32 count = 0;
+	u32 allocSize = 0;
+
+	DBC_Require(this != NULL);
+	lib = pAlloc->lib;
+	DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
+
+	memType = (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 */
+	tokenLen = CSL_Strlen((char *)(info->name)) + 1;
+
+	szSectName = MEM_Calloc(tokenLen, MEM_PAGED);
+	szLastToken = MEM_Calloc(tokenLen, MEM_PAGED);
+	szSecLastToken = MEM_Calloc(tokenLen, MEM_PAGED);
+
+	if (szSectName == NULL || szSecLastToken == NULL ||
+	   szLastToken == NULL) {
+		status = DSP_EMEMORY;
+		goto func_cont;
+	}
+	CSL_Strcpyn(szSectName, (char *)(info->name), tokenLen);
+	pToken = CSL_Strtokr(szSectName, ":", &pszCur);
+	while (pToken) {
+		CSL_Strcpyn(szSecLastToken, szLastToken,
+			   CSL_Strlen(szLastToken) + 1);
+		CSL_Strcpyn(szLastToken, pToken, CSL_Strlen(pToken) + 1);
+		pToken = CSL_Strtokr(NULL, ":", &pszCur);
+		count++; 	/* optimizes processing*/
+	}
+	/* If pToken is 0 or 1, and szSecLastToken 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)
+		req = CSL_Atoi(szLastToken);
+
+	if ((req == 0) || (req == 1)) {
+		if (CSL_Strcmp(szSecLastToken, "DYN_DARAM") == 0) {
+			segId = 0;
+		} else {
+			if (CSL_Strcmp(szSecLastToken, "DYN_SARAM") == 0) {
+				segId = 1;
+			} else {
+				if (CSL_Strcmp(szSecLastToken,
+				   "DYN_EXTERNAL") == 0) {
+					segId = 2;
+				}
+			}
+		}
+		if (segId != -1) {
+			GT_2trace(DBLL_debugMask, GT_5CLASS,
+				 "Extracted values for memory"
+				 " granularity req [%d] segId [%d]\n",
+				 req, segId);
+		}
+	}
+	MEM_Free(szSectName);
+	szSectName = NULL;
+	MEM_Free(szLastToken);
+	szLastToken = NULL;
+	MEM_Free(szSecLastToken);
+	szSecLastToken = NULL;
+func_cont:
+	if (memType == DBLL_CODE)
+		allocSize = info->size + GEM_L1P_PREFETCH_SIZE;
+	else
+		allocSize = info->size;
+	/* TODO - ideally, we can pass the alignment requirement also
+	 * from here */
+	if (lib != NULL) {
+		status = (lib->pTarget->attrs.alloc)(lib->pTarget->
+			 attrs.rmmHandle, memType, allocSize, align,
+			 (u32 *)&rmmAddr, segId, req, FALSE);
+	}
+	if (DSP_FAILED(status)) {
+		retVal = false;
+	} else {
+		/* RMM gives word address. Need to convert to byte address */
+		info->load_addr = rmmAddr.addr * DSPWORDSIZE;
+		info->run_addr = info->load_addr;
+		info->context = (u32)rmmAddr.segid;
+		GT_3trace(DBLL_debugMask, GT_5CLASS,
+			 "Remote alloc: %s  base = 0x%lx len"
+			 "= 0x%lx\n", info->name, info->load_addr / DSPWORDSIZE,
+			 info->size / DSPWORDSIZE);
+	}
+	return retVal;
+}
+
+/*
+ *  ======== rmmDealloc ========
+ */
+static void rmmDealloc(struct Dynamic_Loader_Allocate *this,
+		       struct LDR_SECTION_INFO *info)
+{
+	struct DBLLAlloc *pAlloc = (struct DBLLAlloc *)this;
+	struct DBLL_LibraryObj *lib;
+	u32 segid;
+	DSP_STATUS status = DSP_SOK;
+	unsigned stype = DLOAD_SECTION_TYPE(info->type);
+	u32 memType;
+	u32 freeSize = 0;
+
+	memType = (stype == DLOAD_TEXT) ? DBLL_CODE : (stype == DLOAD_BSS) ?
+		  DBLL_BSS : DBLL_DATA;
+	DBC_Require(this != NULL);
+	lib = pAlloc->lib;
+	DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
+	/* segid was set by alloc function */
+	segid = (u32)info->context;
+	if (memType == DBLL_CODE)
+		freeSize = info->size + GEM_L1P_PREFETCH_SIZE;
+	else
+		freeSize = info->size;
+	if (lib != NULL) {
+		status = (lib->pTarget->attrs.free)(lib->pTarget->
+			 attrs.symHandle, segid, info->load_addr / DSPWORDSIZE,
+			 freeSize, false);
+	}
+	if (DSP_SUCCEEDED(status)) {
+		GT_2trace(DBLL_debugMask, GT_5CLASS,
+			 "Remote dealloc: base = 0x%lx len ="
+			 "0x%lx\n", info->load_addr / DSPWORDSIZE,
+			 freeSize / DSPWORDSIZE);
+	}
+}
+
+/* Dynamic_Loader_Initialize */
+/*
+ *  ======== connect ========
+ */
+static int connect(struct Dynamic_Loader_Initialize *this)
+{
+	return true;
+}
+
+/*
+ *  ======== readMem ========
+ *  This function does not need to be implemented.
+ */
+static int readMem(struct Dynamic_Loader_Initialize *this, void *buf,
+		  LDR_ADDR addr, struct LDR_SECTION_INFO *info,
+		  unsigned nbytes)
+{
+	struct DBLLInit *pInit = (struct DBLLInit *)this;
+	struct DBLL_LibraryObj *lib;
+	int bytesRead = 0;
+
+	DBC_Require(this != NULL);
+	lib = pInit->lib;
+	DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
+	/* Need WMD_BRD_Read function */
+	return bytesRead;
+}
+
+/*
+ *  ======== writeMem ========
+ */
+static int writeMem(struct Dynamic_Loader_Initialize *this, void *buf,
+		   LDR_ADDR addr, struct LDR_SECTION_INFO *info,
+		   unsigned nBytes)
+{
+	struct DBLLInit *pInit = (struct DBLLInit *)this;
+	struct DBLL_LibraryObj *lib;
+	struct DBLL_SectInfo sectInfo;
+	u32 memType;
+	bool retVal = true;
+
+	DBC_Require(this != NULL);
+	lib = pInit->lib;
+	DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
+
+	memType = (DLOAD_SECTION_TYPE(info->type) == DLOAD_TEXT) ? DBLL_CODE :
+		  DBLL_DATA;
+	if (lib != NULL) {
+		retVal = (*lib->pTarget->attrs.write)(lib->pTarget->
+			attrs.wHandle, addr, buf, nBytes, memType);
+	}
+	if (lib->pTarget->attrs.logWrite) {
+		sectInfo.name = info->name;
+		sectInfo.runAddr = info->run_addr;
+		sectInfo.loadAddr = info->load_addr;
+		sectInfo.size = info->size;
+		sectInfo.type = memType;
+		/* Pass the information about what we've written to
+		 * another module */
+		(*lib->pTarget->attrs.logWrite)(lib->pTarget->
+			attrs.logWriteHandle, &sectInfo, addr, nBytes);
+	}
+	return retVal;
+}
+
+/*
+ *  ======== fillMem ========
+ *  Fill nBytes 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 fillMem(struct Dynamic_Loader_Initialize *this, LDR_ADDR addr,
+		   struct LDR_SECTION_INFO *info, unsigned nBytes,
+		   unsigned val)
+{
+	bool retVal = true;
+	char *pBuf;
+	struct DBLL_LibraryObj *lib;
+	struct DBLLInit *pInit = (struct DBLLInit *)this;
+
+	DBC_Require(this != NULL);
+	lib = pInit->lib;
+	pBuf = NULL;
+	/* Pass the NULL pointer to writeMem 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->pTarget->attrs.write) != (DBLL_WriteFxn)NoOp)
+		writeMem(this, &pBuf, addr, info, 0);
+	if (pBuf)
+		memset(pBuf, val, nBytes);
+
+	return retVal;
+}
+
+/*
+ *  ======== execute ========
+ */
+static int execute(struct Dynamic_Loader_Initialize *this, LDR_ADDR start)
+{
+	struct DBLLInit *pInit = (struct DBLLInit *)this;
+	struct DBLL_LibraryObj *lib;
+	bool retVal = true;
+
+	DBC_Require(this != NULL);
+	lib = pInit->lib;
+	DBC_Require(MEM_IsValidHandle(lib, DBLL_LIBSIGNATURE));
+	/* Save entry point */
+	if (lib != NULL)
+		lib->entry = (u32)start;
+
+	return retVal;
+}
+
+/*
+ *  ======== release ========
+ */
+static void release(struct Dynamic_Loader_Initialize *this)
+{
+}
+
diff --git a/drivers/dsp/bridge/pmgr/dev.c b/drivers/dsp/bridge/pmgr/dev.c
new file mode 100644
index 0000000..7d80947
--- /dev/null
+++ b/drivers/dsp/bridge/pmgr/dev.c
@@ -0,0 +1,1475 @@
+/*
+ * linux/drivers/dsp/bridge/pmgr/dev.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.
+ */
+
+
+/*
+ *  ======== dev.c ========
+ *  Description:
+ *      Implementation of 'Bridge Mini-driver device operations.
+ *
+ *  Public Functions:
+ *      DEV_BrdWriteFxn
+ *      DEV_CreateDevice
+ *      DEV_Create2
+ *      DEV_Destroy2
+ *      DEV_DestroyDevice
+ *      DEV_GetChnlMgr
+ *      DEV_GetCmmMgr
+ *      DEV_GetCodMgr
+ *      DEV_GetDehMgr
+ *      DEV_GetDevNode
+ *      DEV_GetDSPWordSize
+ *      DEV_GetFirst
+ *      DEV_GetIntfFxns
+ *      DEV_GetIOMgr
+ *      DEV_GetNext
+ *      DEV_GetNodeManager
+ *      DEV_GetSymbol
+ *      DEV_GetWMDContext
+ *      DEV_Exit
+ *      DEV_Init
+ *      DEV_InsertProcObject
+ *      DEV_IsLocked
+ *      DEV_NotifyClient
+ *      DEV_RegisterNotify
+ *      DEV_ReleaseCodMgr
+ *      DEV_RemoveDevice
+ *      DEV_RemoveProcObject
+ *      DEV_SetChnlMgr
+ *      DEV_SetMsgMgr
+ *      DEV_SetLockOwner
+ *      DEV_StartDevice
+ *
+ *  Private Functions:
+ *      FxnNotImplemented
+ *      InitCodMgr
+ *      InsertDevObject
+ *      IsValidHandle
+ *      RemoveDevObject
+ *      StoreInterfaceFxns
+ *
+ *! Revision History:
+ *! ================
+ *! 03-Jan-2005 hn  Support for IVA DEH
+ *! 08-Mar-2004 sb  Added the Dynamic Memory Mapping feature
+ *! 09-Feb-2004 vp	Updated to support IVA.
+ *! 24-Feb-2003 swa PMGR Code review comments incorporated.
+ *! 29-Nov-2001 jeh Check for DSP_ENOTIMPL status of DEH create function.
+ *! 05-Nov-2001 kc  Added support for DEH module.
+ *! 05-Aug-2001 ag  Shared memory registration moved to WMD_IO_OnLoaded().
+ *! 11-Jul-2001 jeh Moved MGR_Create() from DSP_Init() to DEV_StartDevice().
+ *! 11-Apr-2001 rr: Removed CMM_RegisterGPPSMSeg.
+ *! 02-Apr-2001 rr: CHNL_Create failure is printed out.
+ *! 15-Jan-2001 jeh Removed call to IO_OnLoaded() from DEV_Create2().
+ *! 13-Feb-2001 kc: DSP/BIOS Bridge name update.
+ *! 15-Dec-2000 rr: Dev_Create2 returns error if NODE_CreateMgr fails.
+ *! 05-Dec-2000 jeh Moved IO_OnLoaded() to PROC_Load. Added DEV_SetMsgMgr.
+ *! 05-Dev-2000 ag  SM Heap for messaging registered via CMM_RegisterGPPSMSeg().
+ *!                 SM heap base and size currently taken from registry.
+ *! 29-Nov-2000 rr: Incorporated code review changes.
+ *! 17-Nov-2000 jeh Added calls to get IO manager (IO_Create), IO_OnLoaded().
+ *! 06-Oct-2000 rr: DEV_Destroy2 and DEV_Create2 added.
+ *! 02-Oct-2000 rr: DEV_GetNodeManager added.
+ *! 11-Aug-2000 ag: Added DEV_GetCmmMgr(), CMM_Init() & CMM_Exit().
+ *!                 Removed <std.h> & <stdwin.h>, added <dbtype.h>
+ *! 10-Aug-2000 rr: DEV_InsertProcObject/RemoveProcObject added.
+ *!                 DEV_Cleanup calls PROC_Detach if it is a matching process.
+ *! 27-Jul-2000 rr: DEV is in new directoy DEV and produces devlib.lib
+ *! 17-Jul-2000 rr: DRV Object holds the list of Dev Objects. DEV gets
+ *!                 the List and Next devices through DRV.
+ *!                 DEV object has a back pointer to DRV Object.
+ *! 06-Jun-2000 jeh Added DEV_GetSymbol().
+ *! 09-May-2000 rr: dwMemBase has index for multiple windows need.
+ *! 28-Feb-2000 rr: New GT Usage implemented.
+ *! 03-Feb-2000 rr: GT and Module init/exit Changes.(Done up front from
+ *!		    SERVICES)
+ *! 31-Jan-2000 rr: Comments changed after code review.
+ *! 21-Jan-2000 rr: windows.h, tchar.h, HMODULE removed. FreeLibrary replaced
+ *!                 with LDR_FreeModule
+ *! 17-Jan-2000 rr: CFG_Get/SetPrivateDword renamed to CFG_Get/SetDevObject.
+ *!                 StoreInterfaceFxns stores the new fxn WMD_BRD_SETSTATE.
+ *! 20-Nov-1999 ag: Actual uSMLength =  total - monitor offset.
+ *! 12-Nov-1999 rr: bIRQ and IRQAttrib taken from the struct CFG_HOSTRES.
+ *!		    dMemBase is added with offset for monitor taken from
+ *!		    registry.
+ *! 31-Oct-1999 ag: Added CHNL support.
+ *! 10-Sep-1999 rr: GT Enabled. DEV_Create will Load the Mini Driver and will
+ *!                 find its fxn table. Right now lot of things are hardcoded
+ *!                 as the REG is not ready.
+ *! 10-Jun-1996 rr: Created from WSX
+ */
+
+/*  ----------------------------------- Host OS */
+#include <host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <std.h>
+#include <dbdefs.h>
+#include <errbase.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dbc.h>
+#include <dbg.h>
+#include <gt.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <cfg.h>
+#include <ldr.h>
+#include <list.h>
+#include <mem.h>
+#include <util.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <cod.h>
+#include <drv.h>
+#include <proc.h>
+#include <dmm.h>
+
+/*  ----------------------------------- Resource Manager */
+#include <mgr.h>
+#include <node.h>
+
+/*  ----------------------------------- Others */
+#include <dbreg.h>
+#include <wcd.h>		/* WCD version info. */
+
+#include <chnl.h>
+#include <io.h>
+#include <msg.h>
+#include <cmm.h>
+
+/*  ----------------------------------- This */
+#include <dev.h>
+
+/*  ----------------------------------- Defines, Data Structures, Typedefs */
+
+#define SIGNATURE           0x5f564544	/* "DEV_" (in reverse) */
+#define MAKEVERSION(major, minor)   (major * 10 + minor)
+#define WCDVERSION          MAKEVERSION(WCD_MAJOR_VERSION, WCD_MINOR_VERSION)
+
+/* The WMD device object: */
+struct DEV_OBJECT {
+	/* LST requires "link" to be first field!                        */
+	struct LST_ELEM link;		/* Link to next DEV_OBJECT.      */
+	u32 devType;		/* Device Type */
+	u32 dwSignature;	/* Used for object validation.   */
+	struct CFG_DEVNODE *hDevNode;	/* Platform specific device id   */
+	struct WMD_DEV_CONTEXT *hWmdContext;	/* WMD Context Handle        */
+	struct WMD_DRV_INTERFACE intfFxns;	/* Function interface to WMD. */
+	struct BRD_OBJECT *lockOwner;	/* Client with exclusive access. */
+	struct COD_MANAGER *hCodMgr;	/* Code manager handle.          */
+	struct CHNL_MGR *hChnlMgr;	/* Channel manager.              */
+	struct DEH_MGR *hDehMgr;	/* DEH manager.                  */
+	struct MSG_MGR *hMsgMgr;	/* Message manager.              */
+	struct IO_MGR *hIOMgr;		/* IO manager (CHNL, MSG)        */
+	struct CMM_OBJECT *hCmmMgr;	/* SM memory manager.            */
+	struct DMM_OBJECT *hDmmMgr;	/* Dynamic memory manager.       */
+	struct LDR_MODULE *hModule;	/* WMD Module handle.            */
+	u32 uWordSize;	/* DSP word size: quick access.  */
+	struct DRV_OBJECT *hDrvObject;	/* Driver Object                 */
+	struct LST_LIST *procList;	/* List of Proceeosr attached to
+				 * this device  */
+	struct NODE_MGR *hNodeMgr;
+} ;
+
+/*  ----------------------------------- Globals */
+static u32 cRefs;		/* Module reference count */
+#if GT_TRACE
+static struct GT_Mask debugMask = { NULL, NULL };	/* For debugging */
+#endif
+
+/*  ----------------------------------- Function Prototypes */
+static DSP_STATUS FxnNotImplemented(int arg, ...);
+static DSP_STATUS InitCodMgr(struct DEV_OBJECT *pDevObject);
+static bool IsValidHandle(struct DEV_OBJECT *hObj);
+static void StoreInterfaceFxns(struct WMD_DRV_INTERFACE *pDrvFxns,
+			       OUT struct WMD_DRV_INTERFACE *pIntfFxns);
+/*
+ *  ======== DEV_BrdWriteFxn ========
+ *  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 WMD_BRD_Write() function.
+ */
+u32 DEV_BrdWriteFxn(void *pArb, u32 ulDspAddr, void *pHostBuf,
+		      u32 ulNumBytes, u32 nMemSpace)
+{
+	struct DEV_OBJECT *pDevObject = (struct DEV_OBJECT *)pArb;
+	u32 ulWritten = 0;
+	DSP_STATUS status;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(pHostBuf != NULL);	/* Required of BrdWrite(). */
+	GT_5trace(debugMask, GT_ENTER,
+		"Entered DEV_BrdWriteFxn, pArb: 0x%x\n\t\t"
+		"ulDspAddr: 0x%x\n\t\tpHostBuf: 0x%x\n \t\tulNumBytes:  0x%x\n"
+		"\t\tnMemSpace:  0x%x\n", pArb, ulDspAddr, pHostBuf,
+		ulNumBytes, nMemSpace);
+	if (IsValidHandle(pDevObject)) {
+		/* Require of BrdWrite() */
+		DBC_Assert(pDevObject->hWmdContext != NULL);
+		status = (*pDevObject->intfFxns.pfnBrdWrite)(pDevObject->
+			 hWmdContext, pHostBuf, ulDspAddr, ulNumBytes,
+			 nMemSpace);
+		 /* Special case of getting the address only */
+		if (ulNumBytes == 0)
+			ulNumBytes = 1;
+		if (DSP_SUCCEEDED(status))
+			ulWritten = ulNumBytes;
+
+	}
+	GT_1trace(debugMask, GT_ENTER, "Exit DEV_BrdWriteFxn ulWritten: 0x%x\n",
+		  ulWritten);
+	return ulWritten;
+}
+
+/*
+ *  ======== DEV_CreateDevice ========
+ *  Purpose:
+ *      Called by the operating system to load the PM Mini Driver for a
+ *      PM board (device).
+ */
+DSP_STATUS DEV_CreateDevice(OUT struct DEV_OBJECT **phDevObject,
+			    IN CONST char *pstrWMDFileName,
+			    IN CONST struct CFG_HOSTRES *pHostConfig,
+			    IN CONST struct CFG_DSPRES *pDspConfig,
+			    struct CFG_DEVNODE *hDevNode)
+{
+	struct LDR_MODULE *hModule = NULL;
+	struct WMD_DRV_INTERFACE *pDrvFxns = NULL;
+	struct DEV_OBJECT *pDevObject = NULL;
+	struct CHNL_MGRATTRS mgrAttrs;
+	struct IO_ATTRS ioMgrAttrs;
+	u32 uNumWindows;
+	struct DRV_OBJECT *hDrvObject = NULL;
+	DSP_STATUS status = DSP_SOK;
+	DBC_Require(cRefs > 0);
+	DBC_Require(phDevObject != NULL);
+	DBC_Require(pstrWMDFileName != NULL);
+	DBC_Require(pHostConfig != NULL);
+	DBC_Require(pDspConfig != NULL);
+
+	GT_5trace(debugMask, GT_ENTER,
+		  "Entered DEV_CreateDevice, phDevObject: 0x%x\n"
+		  "\t\tpstrWMDFileName:  0x%x\n\t\tpHostConfig:0x%x\n\t\t"
+		  "pDspConfig:  0x%x\n\t\tnhDevNode:  0x%x\n", phDevObject,
+		  pstrWMDFileName, pHostConfig, pDspConfig, hDevNode);
+	/*  Get the WMD interface functions*/
+	WMD_DRV_Entry(&pDrvFxns, pstrWMDFileName);
+	if (DSP_FAILED(CFG_GetObject((u32 *) &hDrvObject, REG_DRV_OBJECT))) {
+		/* don't propogate CFG errors from this PROC function */
+		GT_0trace(debugMask, GT_7CLASS,
+			  "Failed to get the DRV Object \n");
+		status = DSP_EFAIL;
+	}
+	/* Create the device object, and pass a handle to the WMD for
+	 * storage. */
+	if (DSP_SUCCEEDED(status)) {
+		DBC_Assert(pDrvFxns);
+		MEM_AllocObject(pDevObject, struct DEV_OBJECT, SIGNATURE);
+		if (pDevObject) {
+			/* Fill out the rest of the Dev Object structure: */
+			pDevObject->hDevNode = hDevNode;
+			pDevObject->hModule = hModule;
+			pDevObject->hCodMgr = NULL;
+			pDevObject->hChnlMgr = NULL;
+			pDevObject->hDehMgr = NULL;
+			pDevObject->lockOwner = NULL;
+			pDevObject->uWordSize = pDspConfig->uWordSize;
+			pDevObject->hDrvObject = hDrvObject;
+			pDevObject->devType = DSP_UNIT;
+			/* Store this WMD's interface functions, based on its
+			 * version. */
+			StoreInterfaceFxns(pDrvFxns, &pDevObject->intfFxns);
+			/* Call WMD_DEV_CREATE() to get the WMD's device
+			 * context handle. */
+			status = (pDevObject->intfFxns.pfnDevCreate)
+				 (&pDevObject->hWmdContext, pDevObject,
+				 pHostConfig, pDspConfig);
+			/* Assert WMD_DEV_Create()'s ensure clause: */
+			DBC_Assert(DSP_FAILED(status) || (pDevObject->
+				   hWmdContext != NULL));
+		} else {
+			GT_0trace(debugMask, GT_7CLASS,
+				  "DEV_Create: Out Of Memory");
+			status = DSP_EMEMORY;
+		}
+	}
+	/* Attempt to create the COD manager for this device: */
+	if (DSP_SUCCEEDED(status))
+		status = InitCodMgr(pDevObject);
+
+	/* Attempt to create the channel manager for this device: */
+	if (DSP_SUCCEEDED(status)) {
+		mgrAttrs.cChannels = CHNL_MAXCHANNELS;
+		ioMgrAttrs.bIRQ = pHostConfig->bIRQRegisters;
+		ioMgrAttrs.fShared = (pHostConfig->bIRQAttrib & CFG_IRQSHARED);
+		ioMgrAttrs.uWordSize = pDspConfig->uWordSize;
+		mgrAttrs.uWordSize = pDspConfig->uWordSize;
+		uNumWindows = pHostConfig->wNumMemWindows;
+		if (uNumWindows) {
+			/* Assume last memory window is for CHNL */
+			ioMgrAttrs.dwSMBase = pHostConfig->dwMemBase[1] +
+					      pHostConfig->dwOffsetForMonitor;
+			ioMgrAttrs.uSMLength = pHostConfig->dwMemLength[1] -
+					       pHostConfig->dwOffsetForMonitor;
+		} else {
+			ioMgrAttrs.dwSMBase = 0;
+			ioMgrAttrs.uSMLength = 0;
+			GT_0trace(debugMask, GT_7CLASS,
+				  "**There is no memory reserved for "
+				  "shared structures**\n");
+		}
+		status = CHNL_Create(&pDevObject->hChnlMgr, pDevObject,
+				    &mgrAttrs);
+		if (status == DSP_ENOTIMPL) {
+			/* It's OK for a device not to have a channel
+			 * manager: */
+			status = DSP_SOK;
+		}
+		/* Create CMM mgr even if Msg Mgr not impl.  */
+		status = CMM_Create(&pDevObject->hCmmMgr,
+				   (struct DEV_OBJECT *)pDevObject, NULL);
+		if (DSP_FAILED(status)) {
+			GT_0trace(debugMask, GT_7CLASS,
+				  "DEV_Create: Failed to Create SM "
+				  "Manager\n");
+		}
+		/* Only create IO manager if we have a channel manager */
+		if (DSP_SUCCEEDED(status) && pDevObject->hChnlMgr) {
+			status = IO_Create(&pDevObject->hIOMgr, pDevObject,
+					   &ioMgrAttrs);
+		}
+		/* Only create DEH manager if we have an IO manager */
+		if (DSP_SUCCEEDED(status)) {
+			/* Instantiate the DEH module */
+			status = (*pDevObject->intfFxns.pfnDehCreate)
+				 (&pDevObject->hDehMgr, 	pDevObject);
+		}
+		/* Create DMM mgr .  */
+		status = DMM_Create(&pDevObject->hDmmMgr,
+				   (struct DEV_OBJECT *)pDevObject, NULL);
+		if (DSP_FAILED(status)) {
+			GT_0trace(debugMask, GT_7CLASS,
+				  "DEV_Create: Failed to Create DMM "
+				  "Manager\n");
+		}
+	}
+	/* Add the new DEV_Object to the global list: */
+	if (DSP_SUCCEEDED(status)) {
+		LST_InitElem(&pDevObject->link);
+		status = DRV_InsertDevObject(hDrvObject, pDevObject);
+	}
+	/* Create the Processor List */
+	if (DSP_SUCCEEDED(status)) {
+		pDevObject->procList = LST_Create();
+		if (!(pDevObject->procList)) {
+			status = DSP_EFAIL;
+			GT_0trace(debugMask, GT_7CLASS, "DEV_Create: "
+				 "Failed to Create Proc List");
+		}
+	}
+	 /*  If all went well, return a handle to the dev object;
+	 *  else, cleanup and return NULL in the OUT parameter.  */
+	if (DSP_SUCCEEDED(status)) {
+		*phDevObject = pDevObject;
+		GT_1trace(debugMask, GT_1CLASS,
+			 "DEV_CreateDevice Succeeded \nDevObject "
+			 "0x%x\n", pDevObject);
+	} else {
+		if (pDevObject && pDevObject->procList)
+			LST_Delete(pDevObject->procList);
+
+		if (pDevObject && pDevObject->hCodMgr)
+			COD_Delete(pDevObject->hCodMgr);
+
+		if (pDevObject && pDevObject->hDmmMgr)
+			DMM_Destroy(pDevObject->hDmmMgr);
+
+		if (pDevObject)
+			MEM_FreeObject(pDevObject);
+
+		*phDevObject = NULL;
+		GT_0trace(debugMask, GT_7CLASS, "DEV_CreateDevice Failed\n");
+	}
+	GT_1trace(debugMask, GT_1CLASS, "Exiting DEV_Create: DevObject 0x%x\n",
+		 *phDevObject);
+	DBC_Ensure((DSP_SUCCEEDED(status) && IsValidHandle(*phDevObject)) ||
+		  (DSP_FAILED(status) && !*phDevObject));
+	return status;
+}
+
+/*
+ *  ======== DEV_Create2 ========
+ *  Purpose:
+ *      After successful loading of the image from WCD_InitComplete2
+ *      (PROC Auto_Start) or PROC_Load this fxn is called. This creates
+ *      the Node Manager and updates the DEV Object.
+ */
+DSP_STATUS CDECL DEV_Create2(struct DEV_OBJECT *hDevObject)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DEV_OBJECT *pDevObject = hDevObject;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(IsValidHandle(hDevObject));
+
+	GT_1trace(debugMask, GT_ENTER,
+		 "Entered DEV_Create2, hDevObject: 0x%x\n", hDevObject);
+	/* There can be only one Node Manager per DEV object */
+	DBC_Assert(!pDevObject->hNodeMgr);
+	status = NODE_CreateMgr(&pDevObject->hNodeMgr, hDevObject);
+	if (DSP_FAILED(status)) {
+		GT_1trace(debugMask, GT_7CLASS,
+			 "DEV_Create2: NODE_CreateMgr failed, "
+			 "0x%x!\n", status);
+		pDevObject->hNodeMgr = NULL;
+		GT_0trace(debugMask, GT_7CLASS, "DEV_Create2: Failed!!\n");
+	}
+	DBC_Ensure((DSP_SUCCEEDED(status) && pDevObject->hNodeMgr != NULL)
+		   || (DSP_FAILED(status) && pDevObject->hNodeMgr == NULL));
+	GT_2trace(debugMask, GT_ENTER,
+		  "Exiting DEV_Create2, hNodeMgr:  0x%x, status:"
+		  " 0x%x\n", pDevObject->hNodeMgr, status);
+	return status;
+}
+
+/*
+ *  ======== DEV_Destroy2 ========
+ *  Purpose:
+ *      Destroys the Node manager for this device.
+ */
+DSP_STATUS CDECL DEV_Destroy2(struct DEV_OBJECT *hDevObject)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DEV_OBJECT *pDevObject = hDevObject;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(IsValidHandle(hDevObject));
+
+	GT_1trace(debugMask, GT_ENTER,
+		 "Entered DEV_Destroy2, hDevObject: 0x%x\n",
+		 hDevObject);
+	if (pDevObject->hNodeMgr) {
+		if (DSP_FAILED(NODE_DeleteMgr(pDevObject->hNodeMgr)))
+			status = DSP_EFAIL;
+		else
+			pDevObject->hNodeMgr = NULL;
+
+	}
+	if (DSP_FAILED(status))
+		GT_0trace(debugMask, GT_7CLASS, "DEV_Destroy2 failed!!\n");
+
+	DBC_Ensure((DSP_SUCCEEDED(status) && pDevObject->hNodeMgr == NULL) ||
+		  DSP_FAILED(status));
+	GT_2trace(debugMask, GT_ENTER,
+		 "Exiting DEV_Destroy2, hNodeMgr: 0x%x, status"
+		 " = 0x%x\n", pDevObject->hNodeMgr, status);
+	return status;
+}
+
+/*
+ *  ======== DEV_DestroyDevice ========
+ *  Purpose:
+ *      Destroys the channel manager for this device, if any, calls
+ *      WMD_DEV_Destroy(), and then attempts to unload the WMD module.
+ */
+DSP_STATUS DEV_DestroyDevice(struct DEV_OBJECT *hDevObject)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DEV_OBJECT *pDevObject = hDevObject;
+
+	DBC_Require(cRefs > 0);
+
+	GT_1trace(debugMask, GT_ENTER, "Entered DEV_DestroyDevice, hDevObject: "
+		 "0x%x\n", hDevObject);
+	if (IsValidHandle(hDevObject)) {
+		if (pDevObject->hCodMgr)
+			COD_Delete(pDevObject->hCodMgr);
+
+		if (pDevObject->hNodeMgr)
+			NODE_DeleteMgr(pDevObject->hNodeMgr);
+
+		/* Free the io, channel, and message managers for this board: */
+		if (pDevObject->hIOMgr) {
+			IO_Destroy(pDevObject->hIOMgr);
+			pDevObject->hIOMgr = NULL;
+		}
+		if (pDevObject->hChnlMgr) {
+			CHNL_Destroy(pDevObject->hChnlMgr);
+			pDevObject->hChnlMgr = NULL;
+		}
+		if (pDevObject->hMsgMgr)
+			MSG_Delete(pDevObject->hMsgMgr);
+
+		if (pDevObject->hDehMgr) {
+			/* Uninitialize DEH module. */
+			(*pDevObject->intfFxns.pfnDehDestroy)
+			(pDevObject->hDehMgr);
+		}
+		if (pDevObject->hCmmMgr)
+			CMM_Destroy(pDevObject->hCmmMgr, true);
+
+		if (pDevObject->hDmmMgr)
+			DMM_Destroy(pDevObject->hDmmMgr);
+
+		/* Call the driver's WMD_DEV_Destroy() function: */
+		/* Require of DevDestroy */
+		DBC_Assert(pDevObject->hWmdContext != NULL);
+		status = (*pDevObject->intfFxns.pfnDevDestroy)
+			 (pDevObject->hWmdContext);
+		if (DSP_SUCCEEDED(status)) {
+			if (pDevObject->procList)
+				LST_Delete(pDevObject->procList);
+
+			/* Remove this DEV_Object from the global list: */
+			DRV_RemoveDevObject(pDevObject->hDrvObject, pDevObject);
+			/* Free The library * LDR_FreeModule
+			 * (pDevObject->hModule);*/
+			/* Free this dev object: */
+			MEM_FreeObject(pDevObject);
+		}
+	} else {
+		GT_0trace(debugMask, GT_7CLASS, "DEV_Destroy: Invlaid handle");
+		status = DSP_EHANDLE;
+	}
+	GT_1trace(debugMask, GT_ENTER, "Exit DEV_destroy: status 0x%x\n",
+		 status);
+	return status;
+}
+
+/*
+ *  ======== DEV_GetChnlMgr ========
+ *  Purpose:
+ *      Retrieve the handle to the channel manager handle created for this
+ *      device.
+ */
+DSP_STATUS DEV_GetChnlMgr(struct DEV_OBJECT *hDevObject,
+			 OUT struct CHNL_MGR **phMgr)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DEV_OBJECT *pDevObject = hDevObject;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(phMgr != NULL);
+
+	GT_2trace(debugMask, GT_ENTER,
+		 "Entered DEV_GetChnlMgr, hDevObject: 0x%x\n\t"
+		 "\tphMgr: 0x%x\n", hDevObject, phMgr);
+	if (IsValidHandle(hDevObject)) {
+		*phMgr = pDevObject->hChnlMgr;
+	} else {
+		*phMgr = NULL;
+		status = DSP_EHANDLE;
+		GT_0trace(debugMask, GT_7CLASS,
+			 "DEV_GetChnlMgr: Invalid handle");
+	}
+	GT_2trace(debugMask, GT_ENTER,
+		 "Exit DEV_GetChnlMgr: status 0x%x\t\n hMgr: "
+		 "0x%x\n", status, *phMgr);
+	DBC_Ensure(DSP_SUCCEEDED(status) || ((phMgr != NULL) &&
+		  (*phMgr == NULL)));
+	return status;
+}
+
+/*
+ *  ======== DEV_GetCmmMgr ========
+ *  Purpose:
+ *      Retrieve the handle to the shared memory manager created for this
+ *      device.
+ */
+DSP_STATUS DEV_GetCmmMgr(struct DEV_OBJECT *hDevObject,
+			OUT struct CMM_OBJECT **phMgr)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DEV_OBJECT *pDevObject = hDevObject;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(phMgr != NULL);
+	GT_2trace(debugMask, GT_ENTER,
+		 "Entered DEV_GetCmmMgr, hDevObject:  0x%x\n\t"
+		 "\tphMgr:  0x%x\n", hDevObject, phMgr);
+	if (IsValidHandle(hDevObject)) {
+		*phMgr = pDevObject->hCmmMgr;
+	} else {
+		*phMgr = NULL;
+		status = DSP_EHANDLE;
+		GT_0trace(debugMask, GT_7CLASS,
+			 "DEV_GetCmmMgr: Invalid handle");
+	}
+	GT_2trace(debugMask, GT_ENTER,
+		 "Exit DEV_GetCmmMgr: status 0x%x\t\nhMgr: "
+		 "0x%x\n", status, *phMgr);
+	DBC_Ensure(DSP_SUCCEEDED(status) || ((phMgr != NULL) &&
+		  (*phMgr == NULL)));
+	return status;
+}
+
+/*
+ *  ======== DEV_GetDmmMgr ========
+ *  Purpose:
+ *      Retrieve the handle to the dynamic memory manager created for this
+ *      device.
+ */
+DSP_STATUS DEV_GetDmmMgr(struct DEV_OBJECT *hDevObject,
+			OUT struct DMM_OBJECT **phMgr)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DEV_OBJECT *pDevObject = hDevObject;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(phMgr != NULL);
+
+	GT_2trace(debugMask, GT_ENTER, "Entered DEV_GetDmmMgr, hDevObject: "
+		 "0x%x\n\t\tphMgr: 0x%x\n", hDevObject, phMgr);
+	if (IsValidHandle(hDevObject)) {
+		*phMgr = pDevObject->hDmmMgr;
+	} else {
+		*phMgr = NULL;
+		status = DSP_EHANDLE;
+		GT_0trace(debugMask, GT_7CLASS,
+			 "DEV_GetDmmMgr: Invalid handle");
+	}
+	GT_2trace(debugMask, GT_ENTER,
+		 "Exit DEV_GetDmmMgr: status 0x%x\t\n hMgr: "
+		 "0x%x\n", status, *phMgr);
+	DBC_Ensure(DSP_SUCCEEDED(status) || ((phMgr != NULL) &&
+		  (*phMgr == NULL)));
+	return status;
+}
+
+/*
+ *  ======== DEV_GetCodMgr ========
+ *  Purpose:
+ *      Retrieve the COD manager create for this device.
+ */
+DSP_STATUS DEV_GetCodMgr(struct DEV_OBJECT *hDevObject,
+			OUT struct COD_MANAGER **phCodMgr)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DEV_OBJECT *pDevObject = hDevObject;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(phCodMgr != NULL);
+
+	GT_2trace(debugMask, GT_ENTER,
+		 "Entered DEV_GetCodMgr, hDevObject: 0x%x\n\t\t"
+		 "phCodMgr: 0x%x\n", hDevObject, phCodMgr);
+	if (IsValidHandle(hDevObject)) {
+		*phCodMgr = pDevObject->hCodMgr;
+	} else {
+		*phCodMgr = NULL;
+		status = DSP_EHANDLE;
+		GT_1trace(debugMask, GT_7CLASS,
+			 "DEV_GetCodMgr, invalid handle:  0x%x\n",
+			 hDevObject);
+	}
+	GT_2trace(debugMask, GT_ENTER,
+		 "Exit DEV_GetCodMgr: status 0x%x\t\n hCodMgr:"
+		 " 0x%x\n", status, *phCodMgr);
+	DBC_Ensure(DSP_SUCCEEDED(status) || ((phCodMgr != NULL) &&
+		  (*phCodMgr == NULL)));
+	return status;
+}
+
+/*
+ *  ========= DEV_GetDehMgr ========
+ */
+DSP_STATUS DEV_GetDehMgr(struct DEV_OBJECT *hDevObject,
+			OUT struct DEH_MGR **phDehMgr)
+{
+	DSP_STATUS status = DSP_SOK;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(phDehMgr != NULL);
+	DBC_Require(MEM_IsValidHandle(hDevObject, SIGNATURE));
+	if (IsValidHandle(hDevObject)) {
+		*phDehMgr = hDevObject->hDehMgr;
+	} else {
+		*phDehMgr = NULL;
+		status = DSP_EHANDLE;
+		GT_0trace(debugMask, GT_7CLASS,
+			 "DEV_GetDehMgr: Invalid handle");
+	}
+	return status;
+}
+
+/*
+ *  ======== DEV_GetDevNode ========
+ *  Purpose:
+ *      Retrieve the platform specific device ID for this device.
+ */
+DSP_STATUS DEV_GetDevNode(struct DEV_OBJECT *hDevObject,
+			 OUT struct CFG_DEVNODE **phDevNode)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DEV_OBJECT *pDevObject = hDevObject;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(phDevNode != NULL);
+
+	GT_2trace(debugMask, GT_ENTER,
+		 "Entered DEV_GetDevNode, hDevObject: 0x%x\n\t"
+		 "\tphDevNode: 0x%x\n", hDevObject, phDevNode);
+	if (IsValidHandle(hDevObject)) {
+		*phDevNode = pDevObject->hDevNode;
+	} else {
+		*phDevNode = NULL;
+		status = DSP_EHANDLE;
+		GT_0trace(debugMask, GT_7CLASS,
+			 "DEV_GetDevNode: Invalid handle");
+	}
+	GT_2trace(debugMask, GT_ENTER,
+		 "Exit DEV_GetDevNode: status 0x%x\t\nhDevNode:"
+		 "0x%x\n", status, *phDevNode);
+	DBC_Ensure(DSP_SUCCEEDED(status) || ((phDevNode != NULL) &&
+		  (*phDevNode == NULL)));
+	return status;
+}
+
+/*
+ *  ======== DEV_GetFirst ========
+ *  Purpose:
+ *      Retrieve the first Device Object handle from an internal linked list
+ *      DEV_OBJECTs maintained by DEV.
+ */
+struct DEV_OBJECT *DEV_GetFirst(void)
+{
+	struct DEV_OBJECT *pDevObject = NULL;
+
+	pDevObject = (struct DEV_OBJECT *)DRV_GetFirstDevObject();
+
+	DBC_Ensure((pDevObject == NULL) || IsValidHandle(pDevObject));
+
+	return pDevObject;
+}
+
+/*
+ *  ======== DEV_GetIntfFxns ========
+ *  Purpose:
+ *      Retrieve the WMD interface function structure for the loaded WMD.
+ *      ppIntfFxns != NULL.
+ */
+DSP_STATUS DEV_GetIntfFxns(struct DEV_OBJECT *hDevObject,
+			  OUT struct WMD_DRV_INTERFACE **ppIntfFxns)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DEV_OBJECT *pDevObject = hDevObject;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(ppIntfFxns != NULL);
+
+	GT_2trace(debugMask, GT_ENTER,
+		 "Entered DEV_GetIntfFxns, hDevObject: 0x%x\n\t"
+		 "\tppIntfFxns: 0x%x\n", hDevObject, ppIntfFxns);
+	if (IsValidHandle(hDevObject)) {
+		*ppIntfFxns = &pDevObject->intfFxns;
+	} else {
+		*ppIntfFxns = NULL;
+		status = DSP_EHANDLE;
+		GT_0trace(debugMask, GT_7CLASS,
+			  "DEV_GetIntDxns: Invalid handle");
+	}
+	GT_2trace(debugMask, GT_ENTER, "Exit DEV_GetIntFxns: status 0x%x\t\n"
+		 "ppIntFxns: 0x%x\n", status, *ppIntfFxns);
+	DBC_Ensure(DSP_SUCCEEDED(status) || ((ppIntfFxns != NULL) &&
+		  (*ppIntfFxns == NULL)));
+	return status;
+}
+
+/*
+ *  ========= DEV_GetIOMgr ========
+ */
+DSP_STATUS DEV_GetIOMgr(struct DEV_OBJECT *hDevObject,
+			OUT struct IO_MGR **phIOMgr)
+{
+	DSP_STATUS status = DSP_SOK;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(phIOMgr != NULL);
+	DBC_Require(MEM_IsValidHandle(hDevObject, SIGNATURE));
+
+	if (IsValidHandle(hDevObject)) {
+		*phIOMgr = hDevObject->hIOMgr;
+	} else {
+		*phIOMgr = NULL;
+		status = DSP_EHANDLE;
+		GT_0trace(debugMask, GT_7CLASS, "DEV_GetIOMgr: Invalid handle");
+	}
+
+	return status;
+}
+
+/*
+ *  ======== DEV_GetNext ========
+ *  Purpose:
+ *      Retrieve the next Device Object handle from an internal linked list
+ *      of DEV_OBJECTs maintained by DEV, after having previously called
+ *      DEV_GetFirst() and zero or more DEV_GetNext
+ */
+struct DEV_OBJECT *DEV_GetNext(struct DEV_OBJECT *hDevObject)
+{
+	struct DEV_OBJECT *pNextDevObject = NULL;
+
+	if (IsValidHandle(hDevObject)) {
+		pNextDevObject = (struct DEV_OBJECT *)
+				 DRV_GetNextDevObject((u32)hDevObject);
+	}
+	DBC_Ensure((pNextDevObject == NULL) || IsValidHandle(pNextDevObject));
+	return pNextDevObject;
+}
+
+/*
+ *  ========= DEV_GetMsgMgr ========
+ */
+void CDECL DEV_GetMsgMgr(struct DEV_OBJECT *hDevObject,
+			OUT struct MSG_MGR **phMsgMgr)
+{
+	DBC_Require(cRefs > 0);
+	DBC_Require(phMsgMgr != NULL);
+	DBC_Require(MEM_IsValidHandle(hDevObject, SIGNATURE));
+
+	*phMsgMgr = hDevObject->hMsgMgr;
+}
+
+/*
+ *  ======== DEV_GetNodeManager ========
+ *  Purpose:
+ *      Retrieve the Node Manager Handle
+ */
+DSP_STATUS CDECL DEV_GetNodeManager(struct DEV_OBJECT *hDevObject,
+				   OUT struct NODE_MGR **phNodeMgr)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DEV_OBJECT *pDevObject = hDevObject;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(phNodeMgr != NULL);
+
+	GT_2trace(debugMask, GT_ENTER,
+		 "Entered DEV_GetNodeManager, hDevObject: 0x%x"
+		 "\n\t\tphNodeMgr: 0x%x\n", hDevObject, phNodeMgr);
+	if (IsValidHandle(hDevObject)) {
+		*phNodeMgr = pDevObject->hNodeMgr;
+	} else {
+		*phNodeMgr = NULL;
+		status = DSP_EHANDLE;
+		GT_1trace(debugMask, GT_7CLASS,
+			 "DEV_GetNodeManager, invalid handle: 0x"
+			 "%x\n", hDevObject);
+	}
+	GT_2trace(debugMask, GT_ENTER,
+		 "Exit DEV_GetNodeManager: status 0x%x\t\nhMgr:"
+		 " 0x%x\n", status, *phNodeMgr);
+	DBC_Ensure(DSP_SUCCEEDED(status) || ((phNodeMgr != NULL) &&
+		  (*phNodeMgr == NULL)));
+	return status;
+}
+
+/*
+ *  ======== DEV_GetSymbol ========
+ */
+DSP_STATUS CDECL DEV_GetSymbol(struct DEV_OBJECT *hDevObject,
+			      IN CONST char *pstrSym, OUT u32 *pulValue)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct COD_MANAGER *hCodMgr;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(pstrSym != NULL && pulValue != NULL);
+
+	GT_3trace(debugMask, GT_ENTER,
+		 "Entered DEV_GetSymbol, hDevObject: 0x%x\n\t\t"
+		 "pstrSym: 0x%x\n\t\tpulValue: 0x%x\n", hDevObject, pstrSym,
+		 pulValue);
+	if (IsValidHandle(hDevObject)) {
+		status = DEV_GetCodMgr(hDevObject, &hCodMgr);
+		if (DSP_SUCCEEDED(status)) {
+			DBC_Assert(hCodMgr != NULL);
+			status = COD_GetSymValue(hCodMgr, (char *)pstrSym, pulValue);
+		}
+	} else {
+		status = DSP_EHANDLE;
+		GT_0trace(debugMask, GT_7CLASS,
+			 "DEV_GetSymbol: Invalid handle");
+	}
+	GT_2trace(debugMask, GT_ENTER, "Exit DEV_GetSymbol: status 0x%x\t\n"
+		 "hWmdContext: 0x%x\n", status, *pulValue);
+	return status;
+}
+
+/*
+ *  ======== DEV_GetWMDContext ========
+ *  Purpose:
+ *      Retrieve the WMD Context handle, as returned by the WMD_Create fxn.
+ */
+DSP_STATUS DEV_GetWMDContext(struct DEV_OBJECT *hDevObject,
+			    OUT struct WMD_DEV_CONTEXT **phWmdContext)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DEV_OBJECT *pDevObject = hDevObject;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(phWmdContext != NULL);
+	GT_2trace(debugMask, GT_ENTER,
+		  "Entered DEV_GetWMDContext, hDevObject: 0x%x\n"
+		  "\t\tphWmdContext: 0x%x\n", hDevObject, phWmdContext);
+	if (IsValidHandle(hDevObject)) {
+		*phWmdContext = pDevObject->hWmdContext;
+	} else {
+		*phWmdContext = NULL;
+		status = DSP_EHANDLE;
+		GT_0trace(debugMask, GT_7CLASS,
+			 "DEV_GetWMDContext: Invalid handle");
+	}
+
+	GT_2trace(debugMask, GT_ENTER,
+		 "Exit DEV_GetWMDContext: status 0x%x\t\n"
+		 "hWmdContext: 0x%x\n", status, *phWmdContext);
+	DBC_Ensure(DSP_SUCCEEDED(status) || ((phWmdContext != NULL) &&
+		  (*phWmdContext == NULL)));
+	return status;
+}
+
+/*
+ *  ======== DEV_Exit ========
+ *  Purpose:
+ *      Decrement reference count, and free resources when reference count is
+ *      0.
+ */
+void CDECL DEV_Exit(void)
+{
+	DBC_Require(cRefs > 0);
+
+	cRefs--;
+
+	if (cRefs == 0) {
+		CMM_Exit();
+		DMM_Exit();
+	}
+
+	GT_1trace(debugMask, GT_5CLASS, "Entered DEV_Exit, ref count: 0x%x\n",
+		 cRefs);
+
+	DBC_Ensure(cRefs >= 0);
+}
+
+/*
+ *  ======== DEV_Init ========
+ *  Purpose:
+ *      Initialize DEV's private state, keeping a reference count on each call.
+ */
+bool CDECL DEV_Init(void)
+{
+	bool fCmm, fDmm, fRetval = true;
+
+	DBC_Require(cRefs >= 0);
+
+	if (cRefs == 0) {
+		/* Set the Trace mask */
+		DBC_Assert(!debugMask.flags);
+		GT_create(&debugMask, "DV");	/* "DV" for DeVice */
+		fCmm = CMM_Init();
+		fDmm = DMM_Init();
+
+		fRetval = fCmm && fDmm;
+
+		if (!fRetval) {
+			if (fCmm)
+				CMM_Exit();
+
+
+			if (fDmm)
+				DMM_Exit();
+
+		}
+	}
+
+	if (fRetval)
+		cRefs++;
+
+
+	GT_1trace(debugMask, GT_5CLASS, "Entered DEV_Init, ref count: 0x%x\n",
+		 cRefs);
+
+	DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0)));
+
+	return fRetval;
+}
+
+/*
+ *  ======== DEV_NotifyClients ========
+ *  Purpose:
+ *      Notify all clients of this device of a change in device status.
+ */
+DSP_STATUS DEV_NotifyClients(struct DEV_OBJECT *hDevObject, u32 ulStatus)
+{
+	DSP_STATUS status = DSP_SOK;
+
+	struct DEV_OBJECT *pDevObject = hDevObject;
+	DSP_HPROCESSOR hProcObject;
+
+	GT_2trace(debugMask, GT_ENTER,
+		 "Entered DEV_NotifyClients, hDevObject: 0x%x\n"
+		 "\t\tulStatus: 0x%x\n", hDevObject, ulStatus);
+	for (hProcObject = (DSP_HPROCESSOR)LST_First(pDevObject->procList);
+		hProcObject != NULL;
+		hProcObject = (DSP_HPROCESSOR)LST_Next(pDevObject->procList,
+						(struct LST_ELEM *)hProcObject))
+		PROC_NotifyClients(hProcObject, (u32) ulStatus);
+
+	return status;
+}
+
+/*
+ *  ======== DEV_RemoveDevice ========
+ */
+DSP_STATUS CDECL DEV_RemoveDevice(struct CFG_DEVNODE *hDevNode)
+{
+	struct DEV_OBJECT *hDevObject;	/* handle to device object */
+	DSP_STATUS status = DSP_SOK;
+	struct DEV_OBJECT *pDevObject;
+
+	GT_1trace(debugMask, GT_ENTER,
+		 "Entered DEV_RemoveDevice, hDevNode:  0x%x\n", hDevNode);
+	/* Retrieve the device object handle originaly stored with
+	 * the DevNode: */
+	status = CFG_GetDevObject(hDevNode, (u32 *)&hDevObject);
+	if (DSP_SUCCEEDED(status)) {
+		/* Remove the Processor List */
+		pDevObject = (struct DEV_OBJECT *)hDevObject;
+		/* Destroy the device object. */
+		status = DEV_DestroyDevice(hDevObject);
+		if (DSP_SUCCEEDED(status)) {
+			/* Null out the handle stored with the DevNode. */
+			GT_0trace(debugMask, GT_1CLASS,
+				 "DEV_RemoveDevice, success");
+		}
+	}
+	GT_1trace(debugMask, GT_ENTER, "Exit DEV_RemoveDevice, status: 0x%x\n",
+		  status);
+	return status;
+}
+
+/*
+ *  ======== DEV_SetChnlMgr ========
+ *  Purpose:
+ *      Set the channel manager for this device.
+ */
+DSP_STATUS DEV_SetChnlMgr(struct DEV_OBJECT *hDevObject, struct CHNL_MGR *hMgr)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DEV_OBJECT *pDevObject = hDevObject;
+
+	DBC_Require(cRefs > 0);
+
+	GT_2trace(debugMask, GT_ENTER,
+		 "Entered DEV_SetChnlMgr, hDevObject: 0x%x\n\t"
+		 "\thMgr:0x%x\n", hDevObject, hMgr);
+	if (IsValidHandle(hDevObject)) {
+		pDevObject->hChnlMgr = hMgr;
+	} else {
+		status = DSP_EHANDLE;
+		GT_0trace(debugMask, GT_7CLASS,
+			 "DEV_SetChnlMgr, Invalid handle\n");
+	}
+	DBC_Ensure(DSP_FAILED(status) || (pDevObject->hChnlMgr == hMgr));
+	return status;
+}
+
+/*
+ *  ======== DEV_SetMsgMgr ========
+ *  Purpose:
+ *      Set the message manager for this device.
+ */
+void DEV_SetMsgMgr(struct DEV_OBJECT *hDevObject, struct MSG_MGR *hMgr)
+{
+	DBC_Require(cRefs > 0);
+	DBC_Require(IsValidHandle(hDevObject));
+	GT_2trace(debugMask, GT_ENTER,
+		 "Entered DEV_SetMsgMgr, hDevObject: 0x%x\n\t\t"
+		 "hMgr: 0x%x\n", hDevObject, hMgr);
+	hDevObject->hMsgMgr = hMgr;
+}
+
+/*
+ *  ======== DEV_StartDevice ========
+ *  Purpose:
+ *      Initializes the new device with the BRIDGE environment.
+ */
+DSP_STATUS CDECL DEV_StartDevice(struct CFG_DEVNODE *hDevNode)
+{
+	struct DEV_OBJECT *hDevObject = NULL;	/* handle to 'Bridge Device */
+	struct CFG_HOSTRES hostRes;	/* resources struct. */
+	struct CFG_DSPRES dspRes;	/* DSP resources struct */
+	char szWMDFileName[CFG_MAXSEARCHPATHLEN] = "UMA"; /* wmd filename */
+	DSP_STATUS status;
+	struct MGR_OBJECT *hMgrObject = NULL;
+
+	DBC_Require(cRefs > 0);
+
+	GT_1trace(debugMask, GT_ENTER,
+		 "Entered DEV_StartDevice, hDevObject: 0x%x\n", hDevNode);
+		status = CFG_GetHostResources(hDevNode, &hostRes);
+		if (DSP_SUCCEEDED(status)) {
+			/* Get DSP resources of device from Registry: */
+			status = CFG_GetDSPResources(hDevNode, &dspRes);
+			if (DSP_FAILED(status)) {
+				GT_1trace(debugMask, GT_7CLASS,
+					 "Failed to get WMD DSP resources"
+					 " from registry: 0x%x ", status);
+			}
+		} else {
+			GT_1trace(debugMask, GT_7CLASS,
+				 "Failed to get WMD Host resources "
+				 "from registry: 0x%x ", status);
+		}
+	if (DSP_SUCCEEDED(status)) {
+		/* Given all resources, create a device object. */
+		status = DEV_CreateDevice(&hDevObject, szWMDFileName, &hostRes,
+					 &dspRes, hDevNode);
+		if (DSP_SUCCEEDED(status)) {
+			/* Store away the hDevObject with the DEVNODE */
+			status = CFG_SetDevObject(hDevNode, (u32)hDevObject);
+			if (DSP_FAILED(status)) {
+				/* Clean up */
+				GT_1trace(debugMask, GT_7CLASS,
+					 "Failed to set DevObject in the "
+					 "Registry: 0x%x", status);
+				DEV_DestroyDevice(hDevObject);
+				hDevObject = NULL;
+			}
+		} else {
+			GT_1trace(debugMask, GT_7CLASS,
+				 "Failed to Create Device: 0x%x",
+				 status);
+		}
+	}
+	if (DSP_SUCCEEDED(status)) {
+		/* Create the Manager Object */
+		status = MGR_Create(&hMgrObject, hDevNode);
+	}
+	if (DSP_FAILED(status)) {
+		GT_1trace(debugMask, GT_7CLASS, "Failed to MGR object: 0x%x",
+			 status);
+		status = DSP_EFAIL;
+	}
+	if (DSP_FAILED(status)) {
+		if (hDevObject)
+			DEV_DestroyDevice(hDevObject);
+
+		/* Ensure the device extension is NULL */
+		CFG_SetDevObject(hDevNode, 0L);
+	}
+	GT_1trace(debugMask, GT_ENTER, "Exiting DEV_StartDevice status 0x%x\n",
+		 status);
+	return status;
+}
+
+/*
+ *  ======== FxnNotImplemented ========
+ *  Purpose:
+ *      Takes the place of a WMD Null Function.
+ *  Parameters:
+ *      Multiple, optional.
+ *  Returns:
+ *      DSP_ENOTIMPL:   Always.
+ */
+static DSP_STATUS FxnNotImplemented(int arg, ...)
+{
+	DBG_Trace(DBG_LEVEL1,
+		 "WARNING: Calling a non-implemented WMD function.\n");
+
+	return DSP_ENOTIMPL;
+}
+
+/*
+ *  ======== IsValidHandle ========
+ *  Purpose:
+ *      Validate the device object handle.
+ *  Parameters:
+ *      hDevObject:     Handle to device object created with
+ *                      DEV_CreateDevice().
+ *  Returns:
+ *      true if handle is valid; false otherwise.
+ *  Requires:
+ *  Ensures:
+ */
+static bool IsValidHandle(struct DEV_OBJECT *hObj)
+{
+	bool retVal;
+
+	retVal = (hObj != NULL) && (hObj->dwSignature == SIGNATURE);
+
+	return retVal;
+}
+
+/*
+ *  ======== InitCodMgr ========
+ *  Purpose:
+ *      Create a COD manager for this device.
+ *  Parameters:
+ *      pDevObject:             Pointer to device object created with
+ *                              DEV_CreateDevice()
+ *  Returns:
+ *      DSP_SOK:                Success.
+ *      DSP_EHANDLE:            Invalid hDevObject.
+ *  Requires:
+ *      Should only be called once by DEV_CreateDevice() for a given DevObject.
+ *  Ensures:
+ */
+static DSP_STATUS InitCodMgr(struct DEV_OBJECT *pDevObject)
+{
+	DSP_STATUS status = DSP_SOK;
+	char *szDummyFile = "dummy";
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(!IsValidHandle(pDevObject) ||
+		   (pDevObject->hCodMgr == NULL));
+	GT_1trace(debugMask, GT_ENTER, "Entering InitCodMgr pDevObject: 0x%x",
+		 pDevObject);
+	status = COD_Create(&pDevObject->hCodMgr, szDummyFile, NULL);
+	GT_1trace(debugMask, GT_ENTER, "Exiting InitCodMgr status 0x%x\n ",
+		 status);
+	return status;
+}
+
+/*
+ *  ======== DEV_InsertProcObject ========
+ *  Purpose:
+ *      Insert a ProcObject into the list maintained by DEV.
+ *  Parameters:
+ *      pProcObject:        Ptr to ProcObject to insert.
+ *      pDevObject:         Ptr to Dev Object where the list is.
+  *     pbAlreadyAttached:  Ptr to return the bool
+ *  Returns:
+ *      DSP_SOK:           If successful.
+ *  Requires:
+ *      List Exists
+ *      hDevObject is Valid handle
+ *      DEV Initialized
+ *      pbAlreadyAttached != NULL
+ *      hProcObject != 0
+ *  Ensures:
+ *      DSP_SOK and List is not Empty.
+ */
+DSP_STATUS CDECL DEV_InsertProcObject(struct DEV_OBJECT *hDevObject,
+				     u32 hProcObject,
+				     OUT bool *pbAlreadyAttached)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DEV_OBJECT *pDevObject = (struct DEV_OBJECT *)hDevObject;
+
+	GT_2trace(debugMask, GT_ENTER,
+		 "Entering DEV_InsetProcObject pProcObject 0x%x"
+		 "pDevObject 0x%x\n", hProcObject, hDevObject);
+	DBC_Require(cRefs > 0);
+	DBC_Require(IsValidHandle(pDevObject));
+	DBC_Require(hProcObject != 0);
+	DBC_Require(pDevObject->procList != NULL);
+	DBC_Require(pbAlreadyAttached != NULL);
+	if (!LST_IsEmpty(pDevObject->procList))
+		*pbAlreadyAttached = true;
+
+	/* Add DevObject to tail. */
+	LST_PutTail(pDevObject->procList, (struct LST_ELEM *)hProcObject);
+
+	GT_1trace(debugMask, GT_ENTER,
+		 "Exiting DEV_InsetProcObject status 0x%x\n", status);
+	DBC_Ensure(DSP_SUCCEEDED(status) && !LST_IsEmpty(pDevObject->procList));
+
+	return status;
+}
+
+/*
+ *  ======== DEV_RemoveProcObject ========
+ *  Purpose:
+ *      Search for and remove a Proc object from the given list maintained
+ *      by the DEV
+ *  Parameters:
+ *      pProcObject:        Ptr to ProcObject to insert.
+ *      pDevObject          Ptr to Dev Object where the list is.
+ *  Returns:
+ *      DSP_SOK:            If successful.
+ *  Requires:
+ *      List exists and is not empty
+ *      hProcObject != 0
+ *      hDevObject is a valid Dev handle.
+ *  Ensures:
+ *  Details:
+ *      List will be deleted when the DEV is destroyed.
+ */
+DSP_STATUS CDECL DEV_RemoveProcObject(struct DEV_OBJECT *hDevObject,
+				     u32 hProcObject)
+{
+	DSP_STATUS status = DSP_EFAIL;
+	struct LST_ELEM *pCurElem;
+	struct DEV_OBJECT *pDevObject = (struct DEV_OBJECT *)hDevObject;
+
+	DBC_Require(IsValidHandle(pDevObject));
+	DBC_Require(hProcObject != 0);
+	DBC_Require(pDevObject->procList != NULL);
+	DBC_Require(!LST_IsEmpty(pDevObject->procList));
+
+	GT_1trace(debugMask, GT_ENTER,
+		 "Entering DEV_RemoveProcObject hDevObject "
+		 "0x%x\n", hDevObject);
+	/* Search list for pDevObject: */
+	for (pCurElem = LST_First(pDevObject->procList); pCurElem != NULL;
+	    pCurElem = LST_Next(pDevObject->procList, pCurElem)) {
+		/* If found, remove it. */
+		if ((u32)pCurElem == hProcObject) {
+			LST_RemoveElem(pDevObject->procList, pCurElem);
+			status = DSP_SOK;
+			break;
+		}
+	}
+	GT_1trace(debugMask, GT_ENTER, "DEV_RemoveProcObject returning 0x%x\n",
+		 status);
+	return status;
+}
+
+DSP_STATUS CDECL DEV_GetDevType(struct DEV_OBJECT *hdevObject, u32 *devType)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DEV_OBJECT *pDevObject = (struct DEV_OBJECT *)hdevObject;
+
+	*devType = pDevObject->devType;
+
+	return status;
+}
+
+/*
+ *  ======== StoreInterfaceFxns ========
+ *  Purpose:
+ *      Copy the WMD's interface functions into the device object,
+ *      ensuring that FxnNotImplemented() is set for:
+ *
+ *      1. All WMD function pointers which are NULL; and
+ *      2. All function slots in the struct DEV_OBJECT structure which have no
+ *         corresponding slots in the the WMD's interface, because the WMD
+ *         is of an *older* version.
+ *  Parameters:
+ *      pIntfFxns:      Interface Fxn Structure of the WCD's Dev Object.
+ *      pDrvFxns:       Interface Fxns offered by the WMD during DEV_Create().
+ *  Returns:
+ *  Requires:
+ *      Input pointers are valid.
+ *      WMD is *not* written for a newer WCD.
+ *  Ensures:
+ *      All function pointers in the dev object's Fxn interface are not NULL.
+ */
+static void StoreInterfaceFxns(struct WMD_DRV_INTERFACE *pDrvFxns,
+			      OUT struct WMD_DRV_INTERFACE *pIntfFxns)
+{
+	u32 dwWMDVersion;
+
+	/* Local helper macro: */
+#define  StoreFxn(cast, pfn) \
+    (pIntfFxns->pfn = ((pDrvFxns->pfn != NULL) ? pDrvFxns->pfn : \
+    (cast)FxnNotImplemented))
+
+	DBC_Require(pIntfFxns != NULL);
+	DBC_Require(pDrvFxns != NULL);
+	DBC_Require(MAKEVERSION(pDrvFxns->dwWCDMajorVersion,
+		   pDrvFxns->dwWCDMinorVersion) <= WCDVERSION);
+	dwWMDVersion = MAKEVERSION(pDrvFxns->dwWCDMajorVersion,
+				  pDrvFxns->dwWCDMinorVersion);
+	pIntfFxns->dwWCDMajorVersion = pDrvFxns->dwWCDMajorVersion;
+	pIntfFxns->dwWCDMinorVersion = pDrvFxns->dwWCDMinorVersion;
+	/* Install functions up to WCD version .80 (first alpha): */
+	if (dwWMDVersion > 0) {
+		StoreFxn(WMD_DEV_CREATE, pfnDevCreate);
+		StoreFxn(WMD_DEV_DESTROY, pfnDevDestroy);
+		StoreFxn(WMD_DEV_CTRL, pfnDevCntrl);
+		StoreFxn(WMD_BRD_MONITOR, pfnBrdMonitor);
+		StoreFxn(WMD_BRD_START, pfnBrdStart);
+		StoreFxn(WMD_BRD_STOP, pfnBrdStop);
+		StoreFxn(WMD_BRD_STATUS, pfnBrdStatus);
+		StoreFxn(WMD_BRD_READ, pfnBrdRead);
+		StoreFxn(WMD_BRD_WRITE, pfnBrdWrite);
+		StoreFxn(WMD_BRD_SETSTATE, pfnBrdSetState);
+		StoreFxn(WMD_BRD_MEMCOPY, pfnBrdMemCopy);
+		StoreFxn(WMD_BRD_MEMWRITE, pfnBrdMemWrite);
+		StoreFxn(WMD_BRD_MEMMAP, pfnBrdMemMap);
+		StoreFxn(WMD_BRD_MEMUNMAP, pfnBrdMemUnMap);
+		StoreFxn(WMD_CHNL_CREATE, pfnChnlCreate);
+		StoreFxn(WMD_CHNL_DESTROY, pfnChnlDestroy);
+		StoreFxn(WMD_CHNL_OPEN, pfnChnlOpen);
+		StoreFxn(WMD_CHNL_CLOSE, pfnChnlClose);
+		StoreFxn(WMD_CHNL_ADDIOREQ, pfnChnlAddIOReq);
+		StoreFxn(WMD_CHNL_GETIOC, pfnChnlGetIOC);
+		StoreFxn(WMD_CHNL_CANCELIO, pfnChnlCancelIO);
+		StoreFxn(WMD_CHNL_FLUSHIO, pfnChnlFlushIO);
+		StoreFxn(WMD_CHNL_GETINFO, pfnChnlGetInfo);
+		StoreFxn(WMD_CHNL_GETMGRINFO, pfnChnlGetMgrInfo);
+		StoreFxn(WMD_CHNL_IDLE, pfnChnlIdle);
+		StoreFxn(WMD_CHNL_REGISTERNOTIFY, pfnChnlRegisterNotify);
+		StoreFxn(WMD_DEH_CREATE, pfnDehCreate);
+		StoreFxn(WMD_DEH_DESTROY, pfnDehDestroy);
+		StoreFxn(WMD_DEH_NOTIFY, pfnDehNotify);
+		StoreFxn(WMD_DEH_REGISTERNOTIFY, pfnDehRegisterNotify);
+		StoreFxn(WMD_DEH_GETINFO, pfnDehGetInfo);
+		StoreFxn(WMD_IO_CREATE, pfnIOCreate);
+		StoreFxn(WMD_IO_DESTROY, pfnIODestroy);
+		StoreFxn(WMD_IO_ONLOADED, pfnIOOnLoaded);
+		StoreFxn(WMD_IO_GETPROCLOAD, pfnIOGetProcLoad);
+		StoreFxn(WMD_MSG_CREATE, pfnMsgCreate);
+		StoreFxn(WMD_MSG_CREATEQUEUE, pfnMsgCreateQueue);
+		StoreFxn(WMD_MSG_DELETE, pfnMsgDelete);
+		StoreFxn(WMD_MSG_DELETEQUEUE, pfnMsgDeleteQueue);
+		StoreFxn(WMD_MSG_GET, pfnMsgGet);
+		StoreFxn(WMD_MSG_PUT, pfnMsgPut);
+		StoreFxn(WMD_MSG_REGISTERNOTIFY, pfnMsgRegisterNotify);
+		StoreFxn(WMD_MSG_SETQUEUEID, pfnMsgSetQueueId);
+	}
+	/* Add code for any additional functions in newer WMD versions here: */
+	/* Ensure postcondition: */
+	DBC_Ensure(pIntfFxns->pfnDevCreate != NULL);
+	DBC_Ensure(pIntfFxns->pfnDevDestroy != NULL);
+	DBC_Ensure(pIntfFxns->pfnDevCntrl != NULL);
+	DBC_Ensure(pIntfFxns->pfnBrdMonitor != NULL);
+	DBC_Ensure(pIntfFxns->pfnBrdStart != NULL);
+	DBC_Ensure(pIntfFxns->pfnBrdStop != NULL);
+	DBC_Ensure(pIntfFxns->pfnBrdStatus != NULL);
+	DBC_Ensure(pIntfFxns->pfnBrdRead != NULL);
+	DBC_Ensure(pIntfFxns->pfnBrdWrite != NULL);
+	DBC_Ensure(pIntfFxns->pfnChnlCreate != NULL);
+	DBC_Ensure(pIntfFxns->pfnChnlDestroy != NULL);
+	DBC_Ensure(pIntfFxns->pfnChnlOpen != NULL);
+	DBC_Ensure(pIntfFxns->pfnChnlClose != NULL);
+	DBC_Ensure(pIntfFxns->pfnChnlAddIOReq != NULL);
+	DBC_Ensure(pIntfFxns->pfnChnlGetIOC != NULL);
+	DBC_Ensure(pIntfFxns->pfnChnlCancelIO != NULL);
+	DBC_Ensure(pIntfFxns->pfnChnlFlushIO != NULL);
+	DBC_Ensure(pIntfFxns->pfnChnlGetInfo != NULL);
+	DBC_Ensure(pIntfFxns->pfnChnlGetMgrInfo != NULL);
+	DBC_Ensure(pIntfFxns->pfnChnlIdle != NULL);
+	DBC_Ensure(pIntfFxns->pfnChnlRegisterNotify != NULL);
+	DBC_Ensure(pIntfFxns->pfnDehCreate != NULL);
+	DBC_Ensure(pIntfFxns->pfnDehDestroy != NULL);
+	DBC_Ensure(pIntfFxns->pfnDehNotify != NULL);
+	DBC_Ensure(pIntfFxns->pfnDehRegisterNotify != NULL);
+	DBC_Ensure(pIntfFxns->pfnDehGetInfo != NULL);
+	DBC_Ensure(pIntfFxns->pfnIOCreate != NULL);
+	DBC_Ensure(pIntfFxns->pfnIODestroy != NULL);
+	DBC_Ensure(pIntfFxns->pfnIOOnLoaded != NULL);
+	DBC_Ensure(pIntfFxns->pfnIOGetProcLoad != NULL);
+	DBC_Ensure(pIntfFxns->pfnMsgSetQueueId != NULL);
+
+#undef  StoreFxn
+}
+
diff --git a/drivers/dsp/bridge/pmgr/dmm.c b/drivers/dsp/bridge/pmgr/dmm.c
new file mode 100644
index 0000000..a1baed3
--- /dev/null
+++ b/drivers/dsp/bridge/pmgr/dmm.c
@@ -0,0 +1,646 @@
+/*
+ * linux/drivers/dsp/bridge/pmgr/dmm.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.
+ */
+
+/*
+ *  ======== dmm.c ========
+ *  Purpose:
+ *      The Dynamic Memory Manager (DMM) module manages the DSP Virtual address
+ *      space that can be directly mapped to any MPU buffer or memory region
+ *
+ *  Public Functions:
+ *      DMM_CreateTables
+ *      DMM_Create
+ *      DMM_Destroy
+ *      DMM_Exit
+ *      DMM_Init
+ *      DMM_MapMemory
+ *      DMM_Reset
+ *      DMM_ReserveMemory
+ *      DMM_UnMapMemory
+ *      DMM_UnReserveMemory
+ *
+ *  Private Functions:
+ *      AddRegion
+ *      CreateRegion
+ *      GetRegion
+ *	GetFreeRegion
+ *	GetMappedRegion
+ *
+ *  Notes:
+ *      Region: Generic memory entitiy having a start address and a size
+ *      Chunk:  Reserved region
+ *
+ *
+ *! Revision History:
+ *! ================
+ *! 04-Jun-2008 Hari K : Optimized DMM implementation. Removed linked list
+ *!                                and instead used Table approach.
+ *! 19-Apr-2004 sb: Integrated Alan's code review updates.
+ *! 17-Mar-2004 ap: Fixed GetRegion for size=0 using tighter bound.
+ *! 20-Feb-2004 sb: Created.
+ *!
+ */
+
+/*  ----------------------------------- Host OS */
+#include <host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <std.h>
+#include <dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dbc.h>
+#include <errbase.h>
+#include <gt.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <list.h>
+#include <mem.h>
+#include <sync.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dev.h>
+#include <proc.h>
+
+/*  ----------------------------------- This */
+#include <dmm.h>
+
+/*  ----------------------------------- Defines, Data Structures, Typedefs */
+/* Object signatures */
+#define DMMSIGNATURE       0x004d4d44	/* "DMM"   (in reverse) */
+
+#define DMM_ADDR_VIRTUAL(a) \
+	(((struct MapPage *)(a) - pVirtualMappingTable) * PG_SIZE_4K +\
+	dynMemMapBeg)
+#define DMM_ADDR_TO_INDEX(a) (((a) - dynMemMapBeg) / PG_SIZE_4K)
+
+/* DMM Mgr */
+struct DMM_OBJECT {
+	u32 dwSignature;	/* Used for object validation */
+	/* Dmm Lock is used to serialize access mem manager for
+	 * multi-threads. */
+	struct SYNC_CSOBJECT *hDmmLock;	/* Lock to access dmm mgr */
+};
+
+
+/*  ----------------------------------- Globals */
+#if GT_TRACE
+static struct GT_Mask DMM_debugMask = { NULL, NULL };	/* GT trace variable */
+#endif
+
+static u32 cRefs;		/* module reference count */
+struct MapPage {
+	u32   RegionSize:15;
+	u32   MappedSize:15;
+	u32   bReserved:1;
+	u32   bMapped:1;
+};
+
+/*  Create the free list */
+static struct MapPage *pVirtualMappingTable;
+static u32  iFreeRegion;	/* The index of free region */
+static u32  iFreeSize;
+static u32  *pPhysicalAddrTable;	/* Physical address of MPU buffer */
+static u32  dynMemMapBeg;	/* The Beginning of dynamic memory mapping */
+static u32  TableSize;/* The size of virtual and physical pages tables */
+
+/*  ----------------------------------- Function Prototypes */
+static struct MapPage *GetRegion(u32 addr);
+static struct MapPage *GetFreeRegion(u32 aSize);
+static struct MapPage *GetMappedRegion(u32 aAddr);
+
+/*  ======== DMM_CreateTables ========
+ *  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.
+ */
+DSP_STATUS DMM_CreateTables(struct DMM_OBJECT *hDmmMgr, u32 addr, u32 size)
+{
+	struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
+	DSP_STATUS status = DSP_SOK;
+
+	GT_3trace(DMM_debugMask, GT_ENTER,
+		 "Entered DMM_CreateTables () hDmmMgr %x, addr"
+		 " %x, size %x\n", hDmmMgr, addr, size);
+	status = DMM_DeleteTables(pDmmObj);
+	if (DSP_SUCCEEDED(status)) {
+		SYNC_EnterCS(pDmmObj->hDmmLock);
+		dynMemMapBeg = addr;
+		TableSize = (size/PG_SIZE_4K) + 1;
+		/*  Create the free list */
+		pVirtualMappingTable = (struct MapPage *) MEM_Calloc
+		(TableSize*sizeof(struct MapPage), MEM_NONPAGED);
+		if (pVirtualMappingTable == NULL)
+			status = DSP_EMEMORY;
+		else {
+			/* This table will be used
+			* to store the virtual to physical
+			* address translations
+			*/
+			pPhysicalAddrTable = (u32 *)MEM_Calloc
+				(TableSize*sizeof(u32), MEM_NONPAGED);
+			GT_1trace(DMM_debugMask, GT_4CLASS,
+			"DMM_CreateTables: Allocate"
+			"memory for pPhysicalAddrTable=%d entries\n",
+			TableSize);
+			if (pPhysicalAddrTable == NULL) {
+				status = DSP_EMEMORY;
+				GT_0trace(DMM_debugMask, GT_7CLASS,
+				    "DMM_CreateTables: Memory allocation for "
+				    "pPhysicalAddrTable failed\n");
+			} else {
+			/* On successful allocation,
+			* all entries are zero ('free') */
+			iFreeRegion = 0;
+			iFreeSize = TableSize*PG_SIZE_4K;
+			pVirtualMappingTable[0].RegionSize = TableSize;
+			}
+		}
+		SYNC_LeaveCS(pDmmObj->hDmmLock);
+	} else
+		GT_0trace(DMM_debugMask, GT_7CLASS,
+			 "DMM_CreateTables: DMM_DeleteTables"
+			 "Failure\n");
+
+	GT_1trace(DMM_debugMask, GT_4CLASS, "Leaving DMM_CreateTables status"
+							"0x%x\n", status);
+	return status;
+}
+
+/*
+ *  ======== DMM_Create ========
+ *  Purpose:
+ *      Create a dynamic memory manager object.
+ */
+DSP_STATUS DMM_Create(OUT struct DMM_OBJECT **phDmmMgr,
+		     struct DEV_OBJECT *hDevObject,
+		     IN CONST struct DMM_MGRATTRS *pMgrAttrs)
+{
+	struct DMM_OBJECT *pDmmObject = NULL;
+	DSP_STATUS status = DSP_SOK;
+	DBC_Require(cRefs > 0);
+	DBC_Require(phDmmMgr != NULL);
+
+	GT_3trace(DMM_debugMask, GT_ENTER,
+		 "DMM_Create: phDmmMgr: 0x%x hDevObject: "
+		 "0x%x pMgrAttrs: 0x%x\n", phDmmMgr, hDevObject, pMgrAttrs);
+	*phDmmMgr = NULL;
+	/* create, zero, and tag a cmm mgr object */
+	MEM_AllocObject(pDmmObject, struct DMM_OBJECT, DMMSIGNATURE);
+	if (pDmmObject != NULL) {
+		status = SYNC_InitializeCS(&pDmmObject->hDmmLock);
+		if (DSP_SUCCEEDED(status))
+			*phDmmMgr = pDmmObject;
+		else
+			DMM_Destroy(pDmmObject);
+	} else {
+		GT_0trace(DMM_debugMask, GT_7CLASS,
+			 "DMM_Create: Object Allocation "
+			 "Failure(DMM Object)\n");
+		status = DSP_EMEMORY;
+	}
+	GT_2trace(DMM_debugMask, GT_4CLASS,
+			"Leaving DMM_Create status %x pDmmObject %x\n",
+			status, pDmmObject);
+
+	return status;
+}
+
+/*
+ *  ======== DMM_Destroy ========
+ *  Purpose:
+ *      Release the communication memory manager resources.
+ */
+DSP_STATUS DMM_Destroy(struct DMM_OBJECT *hDmmMgr)
+{
+	struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
+	DSP_STATUS status = DSP_SOK;
+
+	GT_1trace(DMM_debugMask, GT_ENTER,
+		"Entered DMM_Destroy () hDmmMgr %x\n", hDmmMgr);
+	DBC_Require(cRefs > 0);
+	if (MEM_IsValidHandle(hDmmMgr, DMMSIGNATURE)) {
+		status = DMM_DeleteTables(pDmmObj);
+		if (DSP_SUCCEEDED(status)) {
+			/* Delete CS & dmm mgr object */
+			SYNC_DeleteCS(pDmmObj->hDmmLock);
+			MEM_FreeObject(pDmmObj);
+		} else
+			GT_0trace(DMM_debugMask, GT_7CLASS,
+			 "DMM_Destroy: DMM_DeleteTables "
+			 "Failure\n");
+	} else
+		status = DSP_EHANDLE;
+	GT_1trace(DMM_debugMask, GT_4CLASS, "Leaving DMM_Destroy status %x\n",
+								status);
+	return status;
+}
+
+
+/*
+ *  ======== DMM_DeleteTables ========
+ *  Purpose:
+ *      Delete DMM Tables.
+ */
+DSP_STATUS DMM_DeleteTables(struct DMM_OBJECT *hDmmMgr)
+{
+	struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
+	DSP_STATUS status = DSP_SOK;
+
+	GT_1trace(DMM_debugMask, GT_ENTER,
+		"Entered DMM_DeleteTables () hDmmMgr %x\n", hDmmMgr);
+	DBC_Require(cRefs > 0);
+	if (MEM_IsValidHandle(hDmmMgr, DMMSIGNATURE)) {
+		/* Delete all DMM tables */
+		SYNC_EnterCS(pDmmObj->hDmmLock);
+
+		if (pVirtualMappingTable != NULL)
+			MEM_Free(pVirtualMappingTable);
+
+		if (pPhysicalAddrTable != NULL)
+			MEM_Free(pPhysicalAddrTable);
+
+		SYNC_LeaveCS(pDmmObj->hDmmLock);
+	} else
+		status = DSP_EHANDLE;
+	GT_1trace(DMM_debugMask, GT_4CLASS,
+		"Leaving DMM_DeleteTables status %x\n", status);
+	return status;
+}
+
+
+
+
+/*
+ *  ======== DMM_Exit ========
+ *  Purpose:
+ *      Discontinue usage of module; free resources when reference count
+ *      reaches 0.
+ */
+void DMM_Exit(void)
+{
+	DBC_Require(cRefs > 0);
+
+	cRefs--;
+
+	GT_1trace(DMM_debugMask, GT_ENTER,
+		 "exiting DMM_Exit, ref count:0x%x\n", cRefs);
+}
+
+/*
+ *  ======== DMM_GetHandle ========
+ *  Purpose:
+ *      Return the dynamic memory manager object for this device.
+ *      This is typically called from the client process.
+ */
+DSP_STATUS DMM_GetHandle(DSP_HPROCESSOR hProcessor,
+			OUT struct DMM_OBJECT **phDmmMgr)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DEV_OBJECT *hDevObject;
+
+	GT_2trace(DMM_debugMask, GT_ENTER,
+		 "DMM_GetHandle: hProcessor %x, phDmmMgr"
+		 "%x\n", hProcessor, phDmmMgr);
+	DBC_Require(cRefs > 0);
+	DBC_Require(phDmmMgr != NULL);
+	if (hProcessor != NULL)
+		status = PROC_GetDevObject(hProcessor, &hDevObject);
+	else
+		hDevObject = DEV_GetFirst();	/* default */
+
+	if (DSP_SUCCEEDED(status))
+		status = DEV_GetDmmMgr(hDevObject, phDmmMgr);
+
+	GT_2trace(DMM_debugMask, GT_4CLASS, "Leaving DMM_GetHandle status %x, "
+		 "*phDmmMgr %x\n", status, phDmmMgr ? *phDmmMgr : 0);
+	return status;
+}
+
+/*
+ *  ======== DMM_Init ========
+ *  Purpose:
+ *      Initializes private state of DMM module.
+ */
+bool DMM_Init(void)
+{
+	bool fRetval = true;
+
+	DBC_Require(cRefs >= 0);
+
+	if (cRefs == 0) {
+		/* Set the Trace mask */
+		/*"DM" for Dymanic Memory Manager */
+		GT_create(&DMM_debugMask, "DM");
+	}
+
+	if (fRetval)
+		cRefs++;
+
+	GT_1trace(DMM_debugMask, GT_ENTER,
+		 "Entered DMM_Init, ref count:0x%x\n", cRefs);
+
+	DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0)));
+
+	pVirtualMappingTable = NULL ;
+	pPhysicalAddrTable = NULL ;
+	TableSize = 0;
+
+	return fRetval;
+}
+
+/*
+ *  ======== DMM_MapMemory ========
+ *  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.
+ */
+DSP_STATUS DMM_MapMemory(struct DMM_OBJECT *hDmmMgr, u32 addr, u32 size)
+{
+	struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
+	struct MapPage *chunk;
+	DSP_STATUS status = DSP_SOK;
+
+	GT_3trace(DMM_debugMask, GT_ENTER,
+		 "Entered DMM_MapMemory () hDmmMgr %x, "
+		 "addr %x, size %x\n", hDmmMgr, addr, size);
+	SYNC_EnterCS(pDmmObj->hDmmLock);
+	/* Find the Reserved memory chunk containing the DSP block to
+	 * be mapped */
+	chunk = (struct MapPage *)GetRegion(addr);
+	if (chunk != NULL) {
+		/* Mark the region 'mapped', leave the 'reserved' info as-is */
+		chunk->bMapped = true;
+		chunk->MappedSize = (size/PG_SIZE_4K);
+	} else
+		status = DSP_ENOTFOUND;
+	SYNC_LeaveCS(pDmmObj->hDmmLock);
+	GT_2trace(DMM_debugMask, GT_4CLASS,
+		 "Leaving DMM_MapMemory status %x, chunk %x\n",
+		status, chunk);
+	return status;
+}
+
+/*
+ *  ======== DMM_ReserveMemory ========
+ *  Purpose:
+ *      Reserve a chunk of virtually contiguous DSP/IVA address space.
+ */
+DSP_STATUS DMM_ReserveMemory(struct DMM_OBJECT *hDmmMgr, u32 size,
+							u32 *pRsvAddr)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
+	struct MapPage *node;
+	u32 rsvAddr = 0;
+	u32 rsvSize = 0;
+
+	GT_3trace(DMM_debugMask, GT_ENTER,
+		 "Entered DMM_ReserveMemory () hDmmMgr %x, "
+		 "size %x, pRsvAddr %x\n", hDmmMgr, size, pRsvAddr);
+	SYNC_EnterCS(pDmmObj->hDmmLock);
+
+	/* Try to get a DSP chunk from the free list */
+	node = GetFreeRegion(size);
+	if (node != NULL) {
+		/*  DSP chunk of given size is available. */
+		rsvAddr = DMM_ADDR_VIRTUAL(node);
+		/* Calculate the number entries to use */
+		rsvSize = size/PG_SIZE_4K;
+		if (rsvSize < node->RegionSize) {
+			/* Mark remainder of free region */
+			node[rsvSize].bMapped = false;
+			node[rsvSize].bReserved = false;
+			node[rsvSize].RegionSize = node->RegionSize - rsvSize;
+			node[rsvSize].MappedSize = 0;
+		}
+		/*  GetRegion will return first fit chunk. But we only use what
+			is requested. */
+		node->bMapped = false;
+		node->bReserved = true;
+		node->RegionSize = rsvSize;
+		node->MappedSize = 0;
+		/* Return the chunk's starting address */
+		*pRsvAddr = rsvAddr;
+	} else
+		/*dSP chunk of given size is not available */
+		status = DSP_EMEMORY;
+
+	SYNC_LeaveCS(pDmmObj->hDmmLock);
+	GT_3trace(DMM_debugMask, GT_4CLASS,
+		 "Leaving ReserveMemory status %x, rsvAddr"
+		 " %x, rsvSize %x\n", status, rsvAddr, rsvSize);
+	return status;
+}
+
+
+/*
+ *  ======== DMM_UnMapMemory ========
+ *  Purpose:
+ *      Remove the mapped block from the reserved chunk.
+ */
+DSP_STATUS DMM_UnMapMemory(struct DMM_OBJECT *hDmmMgr, u32 addr, u32 *pSize)
+{
+	struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
+	struct MapPage *chunk;
+	DSP_STATUS status = DSP_SOK;
+
+	GT_3trace(DMM_debugMask, GT_ENTER,
+		 "Entered DMM_UnMapMemory () hDmmMgr %x, "
+		 "addr %x, pSize %x\n", hDmmMgr, addr, pSize);
+	SYNC_EnterCS(pDmmObj->hDmmLock);
+	chunk = GetMappedRegion(addr) ;
+	if (chunk == NULL)
+		status = DSP_ENOTFOUND ;
+
+	if (DSP_SUCCEEDED(status)) {
+		/* Unmap the region */
+		*pSize = chunk->MappedSize * PG_SIZE_4K;
+		chunk->bMapped = false;
+		chunk->MappedSize = 0;
+	}
+	SYNC_LeaveCS(pDmmObj->hDmmLock);
+	GT_3trace(DMM_debugMask, GT_ENTER,
+		 "Leaving DMM_UnMapMemory status %x, chunk"
+		 " %x,  *pSize %x\n", status, chunk, *pSize);
+
+	return status;
+}
+
+/*
+ *  ======== DMM_UnReserveMemory ========
+ *  Purpose:
+ *      Free a chunk of reserved DSP/IVA address space.
+ */
+DSP_STATUS DMM_UnReserveMemory(struct DMM_OBJECT *hDmmMgr, u32 rsvAddr)
+{
+	struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
+	struct MapPage *chunk;
+	u32 i;
+	DSP_STATUS status = DSP_SOK;
+	u32 chunkSize;
+
+	GT_2trace(DMM_debugMask, GT_ENTER,
+		 "Entered DMM_UnReserveMemory () hDmmMgr "
+		 "%x, rsvAddr %x\n", hDmmMgr, rsvAddr);
+
+	SYNC_EnterCS(pDmmObj->hDmmLock);
+
+	/* Find the chunk containing the reserved address */
+	chunk = GetMappedRegion(rsvAddr);
+	if (chunk == NULL)
+		status = DSP_ENOTFOUND;
+
+	if (DSP_SUCCEEDED(status)) {
+		/* Free all the mapped pages for this reserved region */
+		i = 0;
+		while (i < chunk->RegionSize) {
+			if (chunk[i].bMapped) {
+				/* Remove mapping from the page tables. */
+				chunkSize = chunk[i].MappedSize;
+				/* Clear the mapping flags */
+				chunk[i].bMapped = false;
+				chunk[i].MappedSize = 0;
+				i += chunkSize;
+			} else
+				i++;
+		}
+		/* Clear the flags (mark the region 'free') */
+		chunk->bReserved = false;
+		/* NOTE: We do NOT coalesce free regions here.
+		 * Free regions are coalesced in GetRegion(), as it traverses
+		 *the whole mapping table
+		 */
+	}
+	SYNC_LeaveCS(pDmmObj->hDmmLock);
+	GT_2trace(DMM_debugMask, GT_ENTER,
+		 "Leaving DMM_UnReserveMemory status %x"
+		 " chunk %x\n", status, chunk);
+	return status;
+}
+
+
+/*
+ *  ======== GetRegion ========
+ *  Purpose:
+ *      Returns a region containing the specified memory region
+ */
+struct MapPage *GetRegion(u32 aAddr)
+{
+	struct MapPage *currRegion = NULL;
+	u32   i = 0;
+
+	GT_1trace(DMM_debugMask, GT_ENTER, "Entered GetRegion () "
+		" aAddr %x\n", aAddr);
+
+	if (pVirtualMappingTable != NULL) {
+		/* find page mapped by this address */
+		i = DMM_ADDR_TO_INDEX(aAddr);
+		if (i < TableSize)
+			currRegion = pVirtualMappingTable + i;
+	}
+	GT_3trace(DMM_debugMask, GT_4CLASS,
+	       "Leaving GetRegion currRegion %x, iFreeRegion %d\n,"
+	       "iFreeSize %d\n", currRegion, iFreeRegion, iFreeSize) ;
+	return currRegion;
+}
+
+/*
+ *  ======== GetFreeRegion ========
+ *  Purpose:
+ *  Returns the requested free region
+ */
+struct MapPage *GetFreeRegion(u32 aSize)
+{
+	struct MapPage *currRegion = NULL;
+	u32   i = 0;
+	u32   RegionSize = 0;
+	u32   nextI = 0;
+	GT_1trace(DMM_debugMask, GT_ENTER, "Entered GetFreeRegion () "
+		"aSize 0x%x\n", aSize);
+
+	if (pVirtualMappingTable == NULL)
+		return currRegion;
+	if (aSize > iFreeSize) {
+		/* Find the largest free region
+		* (coalesce during the traversal) */
+		while (i < TableSize) {
+			RegionSize = pVirtualMappingTable[i].RegionSize;
+			nextI = i+RegionSize;
+			if (pVirtualMappingTable[i].bReserved == false) {
+				/* Coalesce, if possible */
+				if (nextI < TableSize &&
+				pVirtualMappingTable[nextI].bReserved
+							== false) {
+					pVirtualMappingTable[i].RegionSize +=
+					pVirtualMappingTable[nextI].RegionSize;
+					continue;
+				}
+				RegionSize *= PG_SIZE_4K;
+				if (RegionSize > iFreeSize) 	{
+					iFreeRegion = i;
+					iFreeSize = RegionSize;
+				}
+			}
+			i = nextI;
+		}
+	}
+	if (aSize <= iFreeSize) {
+		currRegion = pVirtualMappingTable + iFreeRegion;
+		iFreeRegion += (aSize / PG_SIZE_4K);
+		iFreeSize -= aSize;
+	}
+	return currRegion;
+}
+
+/*
+ *  ======== GetMappedRegion ========
+ *  Purpose:
+ *  Returns the requestedmapped region
+ */
+struct MapPage *GetMappedRegion(u32 aAddr)
+{
+	u32   i = 0;
+	struct MapPage *currRegion = NULL;
+	GT_1trace(DMM_debugMask, GT_ENTER, "Entered GetMappedRegion () "
+						"aAddr 0x%x\n", aAddr);
+
+	if (pVirtualMappingTable == NULL)
+		return currRegion;
+
+	i = DMM_ADDR_TO_INDEX(aAddr);
+	if (i < TableSize && (pVirtualMappingTable[i].bMapped ||
+			pVirtualMappingTable[i].bReserved))
+		currRegion = pVirtualMappingTable + i;
+	return currRegion;
+}
+
+/*
+ *  ======== DMM_GetPhysicalAddrTable ========
+ *  Purpose:
+ *  Returns the physical table address
+ */
+u32 *DMM_GetPhysicalAddrTable(void)
+{
+	GT_1trace(DMM_debugMask, GT_ENTER, "Entered "
+			"DMM_GetPhysicalAddrTable()- pPhysicalAddrTable 0x%x\n",
+			pPhysicalAddrTable);
+	return pPhysicalAddrTable;
+}
diff --git a/drivers/dsp/bridge/pmgr/io.c b/drivers/dsp/bridge/pmgr/io.c
new file mode 100644
index 0000000..5b32210
--- /dev/null
+++ b/drivers/dsp/bridge/pmgr/io.c
@@ -0,0 +1,204 @@
+/*
+ * linux/drivers/dsp/bridge/pmgr/io.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.
+ */
+
+
+/*
+ *  ======== io.c ========
+ *  Description:
+ *      IO manager interface: Manages IO between CHNL and MSG.
+ *
+ *  Public Functions:
+ *      IO_Create
+ *      IO_Destroy
+ *      IO_Exit
+ *      IO_Init
+ *      IO_OnLoaded
+ *
+ *  Notes:
+ *      This interface is basically a pass through to the WMD IO functions.
+ *
+ *! Revision History:
+ *! ================
+ *! 24-Feb-2003 swa 	PMGR Code review comments incorporated.
+ *! 04-Apr-2001 rr      WSX_STATUS initialized in IO_Create.
+ *! 07-Nov-2000 jeh     Created.
+ */
+
+/*  ----------------------------------- Host OS */
+#include <host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <std.h>
+#include <dbdefs.h>
+#include <errbase.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dbc.h>
+#include <gt.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <cfg.h>
+#include <mem.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dev.h>
+
+/*  ----------------------------------- This */
+#include <ioobj.h>
+#include <iodefs.h>
+
+/*  ----------------------------------- Globals */
+static u32 cRefs;
+
+#if GT_TRACE
+static struct GT_Mask IO_DebugMask = { NULL, NULL };	/* WCD IO Mask */
+#endif
+
+/*
+ *  ======== IO_Create ========
+ *  Purpose:
+ *      Create an IO manager object, responsible for managing IO between
+ *      CHNL and MSG
+ */
+DSP_STATUS IO_Create(OUT struct IO_MGR **phIOMgr, struct DEV_OBJECT *hDevObject,
+		    IN CONST struct IO_ATTRS *pMgrAttrs)
+{
+	struct WMD_DRV_INTERFACE *pIntfFxns;
+	struct IO_MGR *hIOMgr = NULL;
+	struct IO_MGR_ *pIOMgr = NULL;
+	DSP_STATUS status = DSP_SOK;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(phIOMgr != NULL);
+	DBC_Require(pMgrAttrs != NULL);
+
+	GT_3trace(IO_DebugMask, GT_ENTER, "Entered IO_Create: phIOMgr: 0x%x\t "
+		 "hDevObject: 0x%x\tpMgrAttrs: 0x%x\n",
+		 phIOMgr, hDevObject, pMgrAttrs);
+
+	*phIOMgr = NULL;
+
+	/* A memory base of 0 implies no memory base:  */
+	if ((pMgrAttrs->dwSMBase != 0) && (pMgrAttrs->uSMLength == 0)) {
+		status = CHNL_E_INVALIDMEMBASE;
+		GT_0trace(IO_DebugMask, GT_7CLASS,
+			 "IO_Create:Invalid Mem Base\n");
+	}
+
+	if (pMgrAttrs->uWordSize == 0) {
+		status = CHNL_E_INVALIDWORDSIZE;
+		GT_0trace(IO_DebugMask, GT_7CLASS,
+			 "IO_Create:Invalid Word size\n");
+	}
+
+	if (DSP_SUCCEEDED(status)) {
+		DEV_GetIntfFxns(hDevObject, &pIntfFxns);
+
+		/* Let WMD channel module finish the create: */
+		status = (*pIntfFxns->pfnIOCreate)(&hIOMgr, hDevObject,
+			 pMgrAttrs);
+
+		if (DSP_SUCCEEDED(status)) {
+			pIOMgr = (struct IO_MGR_ *) hIOMgr;
+			pIOMgr->pIntfFxns = pIntfFxns;
+			pIOMgr->hDevObject = hDevObject;
+
+			/* Return the new channel manager handle: */
+			*phIOMgr = hIOMgr;
+			GT_1trace(IO_DebugMask, GT_1CLASS,
+				 "IO_Create: Success hIOMgr: 0x%x\n",
+				 hIOMgr);
+		}
+	}
+
+	GT_2trace(IO_DebugMask, GT_ENTER,
+		 "Exiting IO_Create: hIOMgr: 0x%x, status:"
+		 " 0x%x\n", hIOMgr, status);
+
+	return status;
+}
+
+/*
+ *  ======== IO_Destroy ========
+ *  Purpose:
+ *      Delete IO manager.
+ */
+DSP_STATUS IO_Destroy(struct IO_MGR *hIOMgr)
+{
+	struct WMD_DRV_INTERFACE *pIntfFxns;
+	struct IO_MGR_ *pIOMgr = (struct IO_MGR_ *)hIOMgr;
+	DSP_STATUS status;
+
+	DBC_Require(cRefs > 0);
+
+	GT_1trace(IO_DebugMask, GT_ENTER, "Entered IO_Destroy: hIOMgr: 0x%x\n",
+		  hIOMgr);
+
+	pIntfFxns = pIOMgr->pIntfFxns;
+
+	/* Let WMD channel module destroy the IO_MGR: */
+	status = (*pIntfFxns->pfnIODestroy) (hIOMgr);
+
+	GT_2trace(IO_DebugMask, GT_ENTER,
+		 "Exiting IO_Destroy: pIOMgr: 0x%x, status:"
+		 " 0x%x\n", pIOMgr, status);
+	return status;
+}
+
+/*
+ *  ======== IO_Exit ========
+ *  Purpose:
+ *      Discontinue usage of the IO module.
+ */
+void IO_Exit(void)
+{
+	DBC_Require(cRefs > 0);
+
+	cRefs--;
+
+	GT_1trace(IO_DebugMask, GT_5CLASS,
+		 "Entered IO_Exit, ref count: 0x%x\n", cRefs);
+
+	DBC_Ensure(cRefs >= 0);
+}
+
+/*
+ *  ======== IO_Init ========
+ *  Purpose:
+ *      Initialize the IO module's private state.
+ */
+bool IO_Init(void)
+{
+	bool fRetval = true;
+
+	DBC_Require(cRefs >= 0);
+
+	if (cRefs == 0) {
+		DBC_Assert(!IO_DebugMask.flags);
+		GT_create(&IO_DebugMask, "IO");	/* "IO" for IO */
+	}
+
+	if (fRetval)
+		cRefs++;
+
+
+	GT_1trace(IO_DebugMask, GT_5CLASS,
+		 "Entered IO_Init, ref count: 0x%x\n", cRefs);
+
+	DBC_Ensure((fRetval && (cRefs > 0)) || (!fRetval && (cRefs >= 0)));
+
+	return fRetval;
+}
diff --git a/drivers/dsp/bridge/pmgr/ioobj.h b/drivers/dsp/bridge/pmgr/ioobj.h
new file mode 100644
index 0000000..9dc4ac1
--- /dev/null
+++ b/drivers/dsp/bridge/pmgr/ioobj.h
@@ -0,0 +1,52 @@
+/*
+ * linux/drivers/dsp/bridge/pmgr/ioobj.h
+ *
+ * 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.
+ */
+
+
+/*
+ *  ======== ioobj.h ========
+ *  Description:
+ *      Structure subcomponents of channel class library IO objects which
+ *      are exposed to class driver from mini-driver.
+ *
+ *  Public Functions:
+ *      None.
+ *
+ *! Revision History:
+ *! ================
+ *! 24-Feb-2003 swa PMGR Code review comments incorporated.
+ *! 01/16/97 gp: Created from chnlpriv.h
+ */
+
+#ifndef IOOBJ_
+#define IOOBJ_
+
+#include <devdefs.h>
+#include <wmd.h>
+
+/*
+ *  This struct is the first field in a IO_MGR struct, as implemented in
+ *  a WMD channel class library.  Other, implementation specific fields
+ *  follow this structure in memory.
+ */
+struct IO_MGR_ {
+	/* These must be the first fields in a IO_MGR struct: */
+	u32 dwSignature;	/* Used for object validation.   */
+	struct WMD_DEV_CONTEXT *hWmdContext;	/* WMD device context.  */
+	struct WMD_DRV_INTERFACE *pIntfFxns;	/* Function interface to WMD. */
+	struct DEV_OBJECT *hDevObject;	/* Device this board represents. */
+} ;
+
+#endif				/* IOOBJ_ */
diff --git a/drivers/dsp/bridge/pmgr/msg.c b/drivers/dsp/bridge/pmgr/msg.c
new file mode 100644
index 0000000..56f28c1
--- /dev/null
+++ b/drivers/dsp/bridge/pmgr/msg.c
@@ -0,0 +1,173 @@
+/*
+ * linux/drivers/dsp/bridge/pmgr/msg.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.
+ */
+
+
+/*
+ *  ======== msg.c ========
+ *  Description:
+ *      DSP/BIOS Bridge MSG Module.
+ *
+ *  Public Functions:
+ *      MSG_Create
+ *      MSG_Delete
+ *      MSG_Exit
+ *      MSG_Init
+ *
+ *! Revision History:
+ *! =================
+ *! 24-Feb-2003 swa 	PMGR Code review comments incorporated.
+ *! 15-May-2001 ag      Changed SUCCEEDED to DSP_SUCCEEDED.
+ *! 16-Feb-2001 jeh     Fixed some comments.
+ *! 15-Dec-2000 rr      MSG_Create returns DSP_EFAIL if pfnMsgCreate fails.
+ *! 12-Sep-2000 jeh     Created.
+ */
+
+/*  ----------------------------------- Host OS */
+#include <host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <std.h>
+#include <dbdefs.h>
+#include <errbase.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dbc.h>
+#include <gt.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <list.h>
+#include <mem.h>
+
+/*  ----------------------------------- Mini Driver */
+#include <wmd.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dev.h>
+
+/*  ----------------------------------- This */
+#include <msgobj.h>
+#include <msg.h>
+
+/*  ----------------------------------- Globals */
+#if GT_TRACE
+static struct GT_Mask MSG_debugMask = { NULL, NULL };	/* GT trace variable */
+#endif
+static u32 cRefs;		/* module reference count */
+
+/*
+ *  ======== MSG_Create ========
+ *  Purpose:
+ *      Create an object to manage message queues. Only one of these objects
+ *      can exist per device object.
+ */
+DSP_STATUS MSG_Create(OUT struct MSG_MGR **phMsgMgr,
+		      struct DEV_OBJECT *hDevObject, MSG_ONEXIT msgCallback)
+{
+	struct WMD_DRV_INTERFACE *pIntfFxns;
+	struct MSG_MGR_ *pMsgMgr;
+	struct MSG_MGR *hMsgMgr;
+	DSP_STATUS status = DSP_SOK;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(phMsgMgr != NULL);
+	DBC_Require(msgCallback != NULL);
+	DBC_Require(hDevObject != NULL);
+
+	GT_3trace(MSG_debugMask, GT_ENTER, "MSG_Create: phMsgMgr: 0x%x\t"
+		 "hDevObject: 0x%x\tmsgCallback: 0x%x\n",
+		 phMsgMgr, hDevObject, msgCallback);
+
+	*phMsgMgr = NULL;
+
+	DEV_GetIntfFxns(hDevObject, &pIntfFxns);
+
+	/* Let WMD message module finish the create: */
+	status = (*pIntfFxns->pfnMsgCreate)(&hMsgMgr, hDevObject, msgCallback);
+
+	if (DSP_SUCCEEDED(status)) {
+		/* Fill in WCD message module's fields of the MSG_MGR
+		 * structure */
+		pMsgMgr = (struct MSG_MGR_ *)hMsgMgr;
+		pMsgMgr->pIntfFxns = pIntfFxns;
+
+		/* Finally, return the new message manager handle: */
+		*phMsgMgr = hMsgMgr;
+		GT_1trace(MSG_debugMask, GT_1CLASS,
+			 "MSG_Create: Success pMsgMgr: 0x%x\n",	pMsgMgr);
+	} else {
+		status = DSP_EFAIL;
+	}
+	return status;
+}
+
+/*
+ *  ======== MSG_Delete ========
+ *  Purpose:
+ *      Delete a MSG manager allocated in MSG_Create().
+ */
+void MSG_Delete(struct MSG_MGR *hMsgMgr)
+{
+	struct MSG_MGR_ *pMsgMgr = (struct MSG_MGR_ *)hMsgMgr;
+	struct WMD_DRV_INTERFACE *pIntfFxns;
+
+	DBC_Require(cRefs > 0);
+	DBC_Require(MEM_IsValidHandle(pMsgMgr, MSGMGR_SIGNATURE));
+
+	GT_1trace(MSG_debugMask, GT_ENTER, "MSG_Delete: hMsgMgr: 0x%x\n",
+		 hMsgMgr);
+
+	pIntfFxns = pMsgMgr->pIntfFxns;
+
+	/* Let WMD message module destroy the MSG_MGR: */
+	(*pIntfFxns->pfnMsgDelete)(hMsgMgr);
+
+	DBC_Ensure(!MEM_IsValidHandle(pMsgMgr, MSGMGR_SIGNATURE));
+}
+
+/*
+ *  ======== MSG_Exit ========
+ */
+void MSG_Exit(void)
+{
+	DBC_Require(cRefs > 0);
+	cRefs--;
+	GT_1trace(MSG_debugMask, GT_5CLASS,
+		 "Entered MSG_Exit, ref count: 0x%x\n",	cRefs);
+	DBC_Ensure(cRefs >= 0);
+}
+
+/*
+ *  ======== MSG_Init ========
+ */
+bool MSG_Init(void)
+{
+	DBC_Require(cRefs >= 0);
+
+	if (cRefs == 0) {
+		DBC_Assert(!MSG_debugMask.flags);
+		GT_create(&MSG_debugMask, "MG");	/* "MG" for MsG */
+	}
+
+	cRefs++;
+
+	GT_1trace(MSG_debugMask, GT_5CLASS, "MSG_Init(), ref count:  0x%x\n",
+		 cRefs);
+
+	DBC_Ensure(cRefs >= 0);
+
+	return true;
+}
+
diff --git a/drivers/dsp/bridge/pmgr/msgobj.h b/drivers/dsp/bridge/pmgr/msgobj.h
new file mode 100644
index 0000000..14da8da
--- /dev/null
+++ b/drivers/dsp/bridge/pmgr/msgobj.h
@@ -0,0 +1,52 @@
+/*
+ * linux/drivers/dsp/bridge/pmgr/msgobj.h
+ *
+ * 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.
+ */
+
+
+/*
+ *  ======== msgobj.h ========
+ *  Description:
+ *      Structure subcomponents of channel class library MSG objects which
+ *      are exposed to class driver from mini-driver.
+ *
+ *  Public Functions:
+ *      None.
+ *
+ *! Revision History:
+ *! ================
+ *! 24-Feb-2003 swa 	PMGR Code review comments incorporated.
+ *! 17-Nov-2000 jeh     Created.
+ */
+
+#ifndef MSGOBJ_
+#define MSGOBJ_
+
+#include <wmd.h>
+
+#include <msgdefs.h>
+
+/*
+ *  This struct is the first field in a MSG_MGR struct, as implemented in
+ *  a WMD channel class library.  Other, implementation specific fields
+ *  follow this structure in memory.
+ */
+struct MSG_MGR_ {
+	/* The first two fields must match those in msgobj.h */
+	u32 dwSignature;
+	struct WMD_DRV_INTERFACE *pIntfFxns;	/* Function interface to WMD. */
+};
+
+#endif				/* MSGOBJ_ */
+
diff --git a/drivers/dsp/bridge/pmgr/wcd.c b/drivers/dsp/bridge/pmgr/wcd.c
new file mode 100644
index 0000000..7a6eb1a
--- /dev/null
+++ b/drivers/dsp/bridge/pmgr/wcd.c
@@ -0,0 +1,1641 @@
+/*
+ * linux/drivers/dsp/bridge/pmgr/wcd.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.
+ */
+
+/*
+ *  ======== wcd.c ========
+ *  Description:
+ *      Common WCD functions, also includes the wrapper
+ *      functions called directly by the DeviceIOControl interface.
+ *
+ *  Public Functions:
+ *      WCD_CallDevIOCtl
+ *      WCD_Init
+ *      WCD_InitComplete2
+ *      WCD_Exit
+ *      <MOD>WRAP_*
+ *
+ *! Revision History:
+ *! ================
+ *! 29-Apr-2004 hp  Call PROC_AutoStart only for DSP device
+ *! 19-Apr-2004 sb  Aligned DMM definitions with Symbian
+ *! 08-Mar-2004 sb  Added the Dynamic Memory Mapping APIs
+ *! 03-Apr-2003 sb  Process environment pointer in PROCWRAP_Load
+ *! 24-Feb-2003 swa PMGR Code review comments incorporated.
+ *! 30-Jan-2002 ag  CMMWRAP_AllocBuf name changed to CMMWRAP_CallocBuf
+ *! 15-Jan-2002 ag  Added actual bufSize param to STRMWRAP_Reclaim[issue].
+ *! 14-Dec-2001 rr  ARGS_NODE_CONNECT maps the pAttr.
+ *! 03-Oct-2001 rr  ARGS_NODE_ALLOCMSGBUF/FREEMSGBUF maps the pAttr.
+ *! 10-Sep-2001 ag  Added CMD_CMM_GETHANDLE.
+ *! 23-Apr-2001 jeh Pass pStatus to NODE_Terminate.
+ *! 11-Apr-2001 jeh STRMWRAP_Reclaim embedded pointer is mapped and unmapped.
+ *! 13-Feb-2001 kc: DSP/BIOS Bridge name updates.
+ *! 06-Dec-2000 jeh WRAP_MAP2CALLER pointers in RegisterNotify calls.
+ *! 05-Dec-2000 ag: Removed MAP2CALLER in NODEWRAP_FreeMsgBuf().
+ *! 22-Nov-2000 kc: Added MGRWRAP_GetPerf_Data().
+ *! 20-Nov-2000 jeh Added MSG_Init()/MSG_Exit(), IO_Init()/IO_Exit().
+ *!		 WRAP pointers to handles for PROC_Attach, NODE_Allocate.
+ *! 27-Oct-2000 jeh Added NODEWRAP_AllocMsgBuf, NODEWRAP_FreeMsgBuf. Removed
+ *!		 NODEWRAP_GetMessageStream.
+ *! 12-Oct-2000 ag: Added user CMM wrappers.
+ *! 05-Oct-2000 rr: WcdInitComplete2 will fail even if one BRD or PROC
+ *!		 AutoStart fails.
+ *! 25-Sep-2000 rr: Updated to Version 0.9
+ *! 13-Sep-2000 jeh Pass ARGS_NODE_CONNECT.pAttrs to NODE_Connect().
+ *! 11-Aug-2000 rr: Part of node enabled.
+ *! 31-Jul-2000 rr: UTIL_Wrap and MEM_Wrap added to RM.
+ *! 27-Jul-2000 rr: PROCWRAP, NODEWRAP and STRMWRAP implemented.
+ *!		 STRM and some NODE Wrappers are not implemented.
+ *! 27-Jun-2000 rr: MGRWRAP fxns added.IFDEF to build for PM or DSP/BIOS Bridge
+ *! 08-Feb-2000 rr  File name changed to wcd.c
+ *! 03-Feb-2000 rr: Module initialization are done by SERVICES init. GT Class
+ *!		 changes for module init/exit fxns.
+ *! 24-Jan-2000 rr: Merged with Scott's code.
+ *! 21-Jan-1999 sg: Changed ARGS_CHNL_GETMODE field name from pdwMode to pMode.
+ *! 17-Jan-2000 rr: BRD_GetStatus does WRAP_MAP2CALLER for state.
+ *! 14-Dec-1999 ag: Removed _MAP2CALLER in CHNL_GetMgr().
+ *! 13-Dec-1999 rr: BRDWRAP_GetSymbol, BRDWRAP_GetTrace uses WRAP_MAP2CALLER
+ *!		 macros.BRDWRAP_Load maps and unmaps embedded pointers.
+ *! 10-Dec-1999 ag: User CHNL bufs mapped in _AddIOReq & _GetIOCompletion.
+ *! 09-Dec-1999 rr: BRDWRAP_Open and CHNLWRAP_GetMgr does not map
+ *!		 pointer as there was a change in config.c
+ *! 06-Dec-1999 rr: BRD_Read and Write Maps the buf pointers.
+ *! 03-Dec-1999 rr: CHNLWRAP_GetMgr and BRDWRAP_Open maps  hDevNode pointer.
+ *!		 WCD_InitComplete2 Included for BRD_AutoStart.
+ *! 16-Nov-1999 ag: Map buf to process in CHNLWRAP_AllocBuffer().
+ *!		 CHNL_GetMgr() Mapping Fix.
+ *! 10-Nov-1999 ag: Removed unnecessary calls to WRAP_MAP2CALLER.
+ *! 08-Nov-1999 kc: Added MEMRY & enabled BRD_IOCtl for tests.
+ *! 29-Oct-1999 ag: Added CHNL.
+ *! 29-Oct-1999 kc: Added trace statements; added ptr mapping; updated
+ *!		 use of UTIL module API.
+ *! 29-Oct-1999 rr: Wrapper functions does the Mapping of the Pointers.
+ *!		 in WinCE all the explicit pointers will be converted
+ *!		 by the OS during interprocess but not the embedded pointers.
+ *! 16-Oct-1999 kc: Code review cleanup.
+ *! 07-Oct-1999 kc: Added UTILWRAP_TestDll() to run PM test harness. See
+ *!		 /src/doc/pmtest.doc for more detail.
+ *! 09-Sep-1999 rr: After exactly two years(!). Adopted for WinCE. GT Enabled.
+ *! 09-Sep-1997 gp: Created.
+ */
+
+/*  ----------------------------------- Host OS */
+#include <host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <std.h>
+#include <dbdefs.h>
+#include <errbase.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dbc.h>
+#include <gt.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <cfg.h>
+#include <mem.h>
+#include <ntfy.h>
+#include <services.h>
+#include <util.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <chnl.h>
+#include <dev.h>
+#include <drv.h>
+
+#include <proc.h>
+#include <strm.h>
+
+/*  ----------------------------------- Resource Manager */
+#include <disp.h>
+#include <mgr.h>
+#include <node.h>
+#include <rmm.h>
+
+
+/*  ----------------------------------- Others */
+#include <msg.h>
+#include <cmm.h>
+#include <io.h>
+
+/*  ----------------------------------- This */
+#include <_dcd.h>
+#include <dbdcd.h>
+
+#ifndef RES_CLEANUP_DISABLE
+#include <resourcecleanup.h>
+#endif
+
+/*  ----------------------------------- Defines, Data Structures, Typedefs */
+#define MAX_TRACEBUFLEN 255
+#define MAX_LOADARGS    16
+#define MAX_NODES       64
+#define MAX_STREAMS     16
+#define MAX_BUFS	64
+
+/* Following two macros should ideally have do{}while(0) */
+
+#define cp_fm_usr(dest, src, status, elements)    \
+    if (DSP_SUCCEEDED(status)) {\
+	    if (unlikely(src == NULL) ||				\
+		unlikely(copy_from_user(dest, src, elements * sizeof(*(dest))))) { \
+		GT_1trace(WCD_debugMask, GT_7CLASS, \
+		"copy_from_user failed, src=0x%x\n", src);  \
+		status = DSP_EPOINTER ; \
+	} \
+    }
+
+#define cp_to_usr(dest, src, status, elements)    \
+    if (DSP_SUCCEEDED(status)) {\
+	    if (unlikely(dest == NULL) ||				\
+		unlikely(copy_to_user(dest, src, elements * sizeof(*(src))))) { \
+		GT_1trace(WCD_debugMask, GT_7CLASS, \
+		"copy_to_user failed, dest=0x%x\n", dest); \
+		status = DSP_EPOINTER ;\
+	} \
+    }
+
+/* Device IOCtl function pointer */
+struct WCD_Cmd {
+	u32(*fxn)(union Trapped_Args *args);
+	u32 dwIndex;
+} ;
+
+/*  ----------------------------------- Globals */
+struct GT_Mask WCD_debugMask = { NULL, NULL };	/* Core VxD Mask */
+u32 WCD_cRefs;
+
+/*
+ *  Function table.
+ *  The order of these functions MUST be the same as the order of the command
+ *  numbers defined in wcdioctl.h  This is how an IOCTL number in user mode
+ *  turns into a function call in kernel mode.
+ */
+struct WCD_Cmd WCD_cmdTable[] = {
+	/* MGR module */
+	{MGRWRAP_EnumNode_Info, CMD_MGR_ENUMNODE_INFO_OFFSET},
+	{MGRWRAP_EnumProc_Info, CMD_MGR_ENUMPROC_INFO_OFFSET},
+	{MGRWRAP_RegisterObject, CMD_MGR_REGISTEROBJECT_OFFSET},
+	{MGRWRAP_UnregisterObject, CMD_MGR_UNREGISTEROBJECT_OFFSET},
+	{MGRWRAP_WaitForBridgeEvents, CMD_MGR_WAIT_OFFSET},
+#ifndef RES_CLEANUP_DISABLE
+	{MGRWRAP_GetProcessResourcesInfo, CMD_MGR_RESOUCES_OFFSET},
+#endif
+	/* PROC Module */
+	{PROCWRAP_Attach, CMD_PROC_ATTACH_OFFSET},
+	{PROCWRAP_Ctrl, CMD_PROC_CTRL_OFFSET},
+	{PROCWRAP_Detach, CMD_PROC_DETACH_OFFSET},
+	{PROCWRAP_EnumNode_Info, CMD_PROC_ENUMNODE_OFFSET},
+	{PROCWRAP_EnumResources, CMD_PROC_ENUMRESOURCES_OFFSET},
+	{PROCWRAP_GetState, CMD_PROC_GETSTATE_OFFSET},
+	{PROCWRAP_GetTrace, CMD_PROC_GETTRACE_OFFSET},
+	{PROCWRAP_Load, CMD_PROC_LOAD_OFFSET},
+	{PROCWRAP_RegisterNotify, CMD_PROC_REGISTERNOTIFY_OFFSET},
+	{PROCWRAP_Start, CMD_PROC_START_OFFSET},
+	{PROCWRAP_ReserveMemory, CMD_PROC_RSVMEM_OFFSET},
+	{PROCWRAP_UnReserveMemory, CMD_PROC_UNRSVMEM_OFFSET},
+	{PROCWRAP_Map, CMD_PROC_MAPMEM_OFFSET},
+	{PROCWRAP_UnMap, CMD_PROC_UNMAPMEM_OFFSET},
+	{PROCWRAP_FlushMemory, CMD_PROC_FLUSHMEMORY_OFFSET},
+	{PROCWRAP_Stop, CMD_PROC_STOP_OFFSET},
+	{PROCWRAP_InvalidateMemory, CMD_PROC_INVALIDATEMEMORY_OFFSET},
+	/* NODE Module */
+	{NODEWRAP_Allocate, CMD_NODE_ALLOCATE_OFFSET},
+	{NODEWRAP_AllocMsgBuf, CMD_NODE_ALLOCMSGBUF_OFFSET},
+	{NODEWRAP_ChangePriority, CMD_NODE_CHANGEPRIORITY_OFFSET},
+	{NODEWRAP_Connect, CMD_NODE_CONNECT_OFFSET},
+	{NODEWRAP_Create, CMD_NODE_CREATE_OFFSET},
+	{NODEWRAP_Delete, CMD_NODE_DELETE_OFFSET},
+	{NODEWRAP_FreeMsgBuf, CMD_NODE_FREEMSGBUF_OFFSET},
+	{NODEWRAP_GetAttr, CMD_NODE_GETATTR_OFFSET},
+	{NODEWRAP_GetMessage, CMD_NODE_GETMESSAGE_OFFSET},
+	{NODEWRAP_Pause, CMD_NODE_PAUSE_OFFSET},
+	{NODEWRAP_PutMessage, CMD_NODE_PUTMESSAGE_OFFSET},
+	{NODEWRAP_RegisterNotify, CMD_NODE_REGISTERNOTIFY_OFFSET},
+	{NODEWRAP_Run, CMD_NODE_RUN_OFFSET},
+	{NODEWRAP_Terminate, CMD_NODE_TERMINATE_OFFSET},
+	{NODEWRAP_GetUUIDProps, CMD_NODE_GETUUIDPROPS_OFFSET},
+	/* STRM wrapper functions */
+	{STRMWRAP_AllocateBuffer, CMD_STRM_ALLOCATEBUFFER_OFFSET},
+	{STRMWRAP_Close, CMD_STRM_CLOSE_OFFSET},
+	{STRMWRAP_FreeBuffer, CMD_STRM_FREEBUFFER_OFFSET},
+	{STRMWRAP_GetEventHandle, CMD_STRM_GETEVENTHANDLE_OFFSET},
+	{STRMWRAP_GetInfo, CMD_STRM_GETINFO_OFFSET},
+	{STRMWRAP_Idle, CMD_STRM_IDLE_OFFSET},
+	{STRMWRAP_Issue, CMD_STRM_ISSUE_OFFSET},
+	{STRMWRAP_Open, CMD_STRM_OPEN_OFFSET},
+	{STRMWRAP_Reclaim, CMD_STRM_RECLAIM_OFFSET},
+	{STRMWRAP_RegisterNotify, CMD_STRM_REGISTERNOTIFY_OFFSET},
+	{STRMWRAP_Select, CMD_STRM_SELECT_OFFSET},
+	/* CMM module */
+	{CMMWRAP_CallocBuf, CMD_CMM_ALLOCBUF_OFFSET},
+	{CMMWRAP_FreeBuf, CMD_CMM_FREEBUF_OFFSET},
+	{CMMWRAP_GetHandle, CMD_CMM_GETHANDLE_OFFSET},
+	{CMMWRAP_GetInfo, CMD_CMM_GETINFO_OFFSET}
+};
+
+/*
+ *  ======== WCD_CallDevIOCtl ========
+ *  Purpose:
+ *      Call the (wrapper) function for the corresponding WCD IOCTL.
+ */
+inline DSP_STATUS WCD_CallDevIOCtl(u32 cmd, union Trapped_Args *args,
+				    u32 *pResult)
+{
+	if ((cmd < (sizeof(WCD_cmdTable) / sizeof(struct WCD_Cmd)))) {
+		/* make the fxn call via the cmd table */
+		*pResult = (*WCD_cmdTable[cmd].fxn) (args);
+		return DSP_SOK;
+	} else {
+		return DSP_EINVALIDARG;
+	}
+}
+
+/*
+ *  ======== WCD_Exit ========
+ */
+void WCD_Exit(void)
+{
+	DBC_Require(WCD_cRefs > 0);
+	WCD_cRefs--;
+	GT_1trace(WCD_debugMask, GT_5CLASS,
+		 "Entered WCD_Exit, ref count:  0x%x\n", WCD_cRefs);
+	if (WCD_cRefs == 0) {
+		/* Release all WCD modules initialized in WCD_Init(). */
+		COD_Exit();
+		DEV_Exit();
+		CHNL_Exit();
+		MSG_Exit();
+		IO_Exit();
+		STRM_Exit();
+		NTFY_Exit();
+		DISP_Exit();
+		NODE_Exit();
+		PROC_Exit();
+		MGR_Exit();
+		RMM_exit();
+		DRV_Exit();
+		SERVICES_Exit();
+	}
+	DBC_Ensure(WCD_cRefs >= 0);
+}
+
+/*
+ *  ======== WCD_Init ========
+ *  Purpose:
+ *      Module initialization is done by SERVICES Init.
+ */
+bool WCD_Init(void)
+{
+	bool fInit = true;
+	bool fDRV, fDEV, fCOD, fSERVICES, fCHNL, fMSG, fIO;
+	bool fMGR, fPROC, fNODE, fDISP, fNTFY, fSTRM, fRMM;
+#ifdef DEBUG
+	/* runtime check of Device IOCtl array. */
+	u32 i;
+	for (i = 1; i < (sizeof(WCD_cmdTable) / sizeof(struct WCD_Cmd)); i++)
+		DBC_Assert(WCD_cmdTable[i - 1].dwIndex == i);
+
+#endif
+	if (WCD_cRefs == 0) {
+		/* initialize all SERVICES modules */
+		fSERVICES = SERVICES_Init();
+		/* initialize debugging module */
+		DBC_Assert(!WCD_debugMask.flags);
+		GT_create(&WCD_debugMask, "CD");    /* CD for class driver */
+		/* initialize class driver and other modules */
+		fDRV = DRV_Init();
+		fMGR = MGR_Init();
+		fPROC = PROC_Init();
+		fNODE = NODE_Init();
+		fDISP = DISP_Init();
+		fNTFY = NTFY_Init();
+		fSTRM = STRM_Init();
+		fRMM = RMM_init();
+		fCHNL = CHNL_Init();
+		fMSG = MSG_Init();
+		fIO = IO_Init();
+		fDEV = DEV_Init();
+		fCOD = COD_Init();
+		fInit = fSERVICES && fDRV && fDEV && fCHNL && fCOD &&
+			fMSG && fIO;
+		fInit = fInit && fMGR && fPROC && fRMM;
+		if (!fInit) {
+			if (fSERVICES)
+				SERVICES_Exit();
+
+			if (fDRV)
+				DRV_Exit();
+
+			if (fMGR)
+				MGR_Exit();
+
+			if (fSTRM)
+				STRM_Exit();
+
+			if (fPROC)
+				PROC_Exit();
+
+			if (fNODE)
+				NODE_Exit();
+
+			if (fDISP)
+				DISP_Exit();
+
+			if (fNTFY)
+				NTFY_Exit();
+
+			if (fCHNL)
+				CHNL_Exit();
+
+			if (fMSG)
+				MSG_Exit();
+
+			if (fIO)
+				IO_Exit();
+
+			if (fDEV)
+				DEV_Exit();
+
+			if (fCOD)
+				COD_Exit();
+
+			if (fRMM)
+				RMM_exit();
+
+		}
+	}
+	if (fInit)
+		WCD_cRefs++;
+
+	GT_1trace(WCD_debugMask, GT_5CLASS,
+		 "Entered WCD_Init, ref count: 0x%x\n",	WCD_cRefs);
+	return fInit;
+}
+
+/*
+ *  ======== WCD_InitComplete2 ========
+ *  Purpose:
+ *      Perform any required WCD, and WMD initialization which
+ *      cannot not be performed in WCD_Init() or DEV_StartDevice() due
+ *      to the fact that some services are not yet
+ *      completely initialized.
+ *  Parameters:
+ *  Returns:
+ *      DSP_SOK:	Allow this device to load
+ *      DSP_EFAIL:      Failure.
+ *  Requires:
+ *      WCD initialized.
+ *  Ensures:
+ */
+DSP_STATUS WCD_InitComplete2(void)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct CFG_DEVNODE *DevNode;
+	struct DEV_OBJECT *hDevObject;
+	u32 devType;
+
+	DBC_Require(WCD_cRefs > 0);
+	GT_0trace(WCD_debugMask, GT_ENTER, "Entered WCD_InitComplete\n");
+	 /*  Walk the list of DevObjects, get each devnode, and attempting to
+	 *  autostart the board. Note that this requires COF loading, which
+	 *  requires KFILE.  */
+	for (hDevObject = DEV_GetFirst(); hDevObject != NULL;
+	     hDevObject = DEV_GetNext(hDevObject)) {
+		if (DSP_FAILED(DEV_GetDevNode(hDevObject, &DevNode)))
+			continue;
+
+		if (DSP_FAILED(DEV_GetDevType(hDevObject, &devType)))
+			continue;
+
+		if ((devType == DSP_UNIT) || (devType == IVA_UNIT)) {
+			if (DSP_FAILED(PROC_AutoStart(DevNode, hDevObject))) {
+				GT_0trace(WCD_debugMask, GT_1CLASS,
+					 "WCD_InitComplete2 Failed\n");
+				status = DSP_EFAIL;
+				/* break; */
+			}
+		} else
+			GT_1trace(WCD_debugMask, GT_ENTER,
+				 "Ignoring PROC_AutoStart "
+				 "for Device Type = 0x%x \n", devType);
+	}			/* End For Loop */
+	GT_1trace(WCD_debugMask, GT_ENTER,
+		 "Exiting WCD_InitComplete status 0x%x\n", status);
+	return status;
+}
+
+/*
+ * ======== MGRWRAP_EnumNode_Info ========
+ */
+u32 MGRWRAP_EnumNode_Info(union Trapped_Args *args)
+{
+	u8 *pNDBProps;
+	u32 uNumNodes;
+	DSP_STATUS status = DSP_SOK;
+	u32 size = args->ARGS_MGR_ENUMNODE_INFO.uNDBPropsSize;
+
+	GT_4trace(WCD_debugMask, GT_ENTER,
+		 "MGR_EnumNodeInfo: entered args:\n0x%x"
+		 " uNode: 0x%x\tpNDBProps: 0x%x\tuNDBPropsSize: "
+		 "0x%x\tpuNumNodes\n", args->ARGS_MGR_ENUMNODE_INFO.uNode,
+		 args->ARGS_MGR_ENUMNODE_INFO.pNDBProps,
+		 args->ARGS_MGR_ENUMNODE_INFO.uNDBPropsSize,
+		 args->ARGS_MGR_ENUMNODE_INFO.puNumNodes);
+	pNDBProps = MEM_Alloc(size, MEM_NONPAGED);
+	if (pNDBProps == NULL)
+		status = DSP_EMEMORY;
+
+	if (DSP_SUCCEEDED(status)) {
+		status = MGR_EnumNodeInfo(args->ARGS_MGR_ENUMNODE_INFO.uNode,
+					 (struct DSP_NDBPROPS *)pNDBProps,
+					 size, &uNumNodes);
+	}
+	cp_to_usr(args->ARGS_MGR_ENUMNODE_INFO.pNDBProps, pNDBProps, status,
+		 size);
+	cp_to_usr(args->ARGS_MGR_ENUMNODE_INFO.puNumNodes, &uNumNodes, status,
+		 1);
+	if (pNDBProps)
+		MEM_Free(pNDBProps);
+
+	return status;
+}
+
+/*
+ * ======== MGRWRAP_EnumProc_Info ========
+ */
+u32 MGRWRAP_EnumProc_Info(union Trapped_Args *args)
+{
+	u8 *pProcessorInfo;
+	u32 uNumProcs;
+	DSP_STATUS status = DSP_SOK;
+	u32 size = args->ARGS_MGR_ENUMPROC_INFO.uProcessorInfoSize;
+
+	GT_4trace(WCD_debugMask, GT_ENTER,
+		 "MGRWRAP_EnumProc_Info: entered args:\n"
+		 "0x%x uProcessor: 0x%x\tpProcessorInfo: 0x%x\t"
+		 "uProcessorInfoSize: 0x%x\tpuNumProcs \n",
+		 args->ARGS_MGR_ENUMPROC_INFO.uProcessor,
+		 args->ARGS_MGR_ENUMPROC_INFO.pProcessorInfo,
+		 args->ARGS_MGR_ENUMPROC_INFO.uProcessorInfoSize,
+		 args->ARGS_MGR_ENUMPROC_INFO.puNumProcs);
+	pProcessorInfo = MEM_Alloc(size, MEM_NONPAGED);
+	if (pProcessorInfo == NULL)
+		status = DSP_EMEMORY;
+
+	if (DSP_SUCCEEDED(status)) {
+		status = MGR_EnumProcessorInfo(args->
+				ARGS_MGR_ENUMPROC_INFO.uProcessor,
+				(struct DSP_PROCESSORINFO *)pProcessorInfo,
+				size, &uNumProcs);
+	}
+	cp_to_usr(args->ARGS_MGR_ENUMPROC_INFO.pProcessorInfo, pProcessorInfo,
+		 status, size);
+	cp_to_usr(args->ARGS_MGR_ENUMPROC_INFO.puNumProcs, &uNumProcs,
+		 status, 1);
+	if (pProcessorInfo)
+		MEM_Free(pProcessorInfo);
+
+	return status;
+}
+
+#define WRAP_MAP2CALLER(x) x
+/*
+ * ======== MGRWRAP_RegisterObject ========
+ */
+u32 MGRWRAP_RegisterObject(union Trapped_Args *args)
+{
+	u32 retVal;
+
+	GT_1trace(WCD_debugMask, GT_ENTER,
+		 "MGRWRAP_RegisterObject: entered pg2hMsg "
+		 "0x%x\n", args->ARGS_MGR_REGISTEROBJECT.pUuid);
+	retVal = DCD_RegisterObject(WRAP_MAP2CALLER
+		    (args->ARGS_MGR_REGISTEROBJECT.pUuid),
+		    args->ARGS_MGR_REGISTEROBJECT.objType,
+		    WRAP_MAP2CALLER(args->ARGS_MGR_REGISTEROBJECT.pszPathName));
+	return retVal;
+}
+
+/*
+ * ======== MGRWRAP_UnregisterObject ========
+ */
+u32 MGRWRAP_UnregisterObject(union Trapped_Args *args)
+{
+	u32 retVal;
+
+	GT_1trace(WCD_debugMask, GT_ENTER,
+		 "MGRWRAP_UnregisterObject: entered pg2hMsg"
+		 " 0x%x\n", args->ARGS_MGR_UNREGISTEROBJECT.pUuid);
+	retVal = DCD_UnregisterObject(WRAP_MAP2CALLER
+			(args->ARGS_MGR_UNREGISTEROBJECT.pUuid),
+			args->ARGS_MGR_UNREGISTEROBJECT.objType);
+
+	return retVal;
+}
+
+/*
+ * ======== MGRWRAP_WaitForBridgeEvents ========
+ */
+u32 MGRWRAP_WaitForBridgeEvents(union Trapped_Args *args)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DSP_NOTIFICATION *aNotifications[MAX_EVENTS];
+	struct DSP_NOTIFICATION notifications[MAX_EVENTS];
+	u32 uIndex, i;
+	u32 uCount = args->ARGS_MGR_WAIT.uCount;
+
+	GT_0trace(WCD_debugMask, GT_ENTER,
+		 "MGRWRAP_WaitForBridgeEvents: entered\n");
+
+	if (uCount > MAX_EVENTS)
+		status = DSP_EINVALIDARG;
+
+	/* get the array of pointers to user structures */
+	cp_fm_usr(aNotifications, args->ARGS_MGR_WAIT.aNotifications,
+		 status, uCount);
+	/* get the events */
+	for (i = 0; i < uCount; i++) {
+		cp_fm_usr(&notifications[i], aNotifications[i], status, 1);
+		if (DSP_SUCCEEDED(status)) {
+			/* set the array of pointers to kernel structures*/
+			aNotifications[i] = &notifications[i];
+		}
+	}
+	if (DSP_SUCCEEDED(status)) {
+		status = MGR_WaitForBridgeEvents(aNotifications, uCount,
+			 &uIndex, args->ARGS_MGR_WAIT.uTimeout);
+	}
+	cp_to_usr(args->ARGS_MGR_WAIT.puIndex, &uIndex, status, 1);
+	return status;
+}
+
+
+#ifndef RES_CLEANUP_DISABLE
+/*
+ * ======== MGRWRAP_GetProcessResourceInfo ========
+ */
+u32 MGRWRAP_GetProcessResourcesInfo(union Trapped_Args *args)
+{
+    DSP_STATUS status = DSP_SOK;
+    u32 uSize = 0;
+    u8 *pBuf = MEM_Alloc(8092, MEM_NONPAGED);
+    status = DRV_ProcDisplayResInfo(pBuf, &uSize);
+    GT_1trace(WCD_debugMask, GT_ENTER,
+	     "MGRWRAP_GetProcessResourcesInfo:uSize=%d :\n", uSize);
+    cp_to_usr(args->ARGS_PROC_GETTRACE.pBuf, pBuf, status, uSize);
+    GT_0trace(WCD_debugMask, GT_ENTER, "\n***********"
+	     "123MGRWRAP_GetProcessResourcesInfo:**************\n");
+    GT_0trace(WCD_debugMask, GT_ENTER, "\n***********"
+	     "456MGRWRAP_GetProcessResourcesInfo:**************\n");
+    cp_to_usr(args->ARGS_PROC_GETTRACE.pSize, &uSize, status, 1);
+    MEM_Free(pBuf);
+    return status;
+}
+#endif
+
+
+/*
+ * ======== PROCWRAP_Attach ========
+ */
+u32 PROCWRAP_Attach(union Trapped_Args *args)
+{
+	DSP_HPROCESSOR processor;
+	DSP_STATUS status = DSP_SOK;
+	struct DSP_PROCESSORATTRIN attrIn, *pAttrIn = NULL;
+
+	GT_3trace(WCD_debugMask, GT_ENTER,
+		 "PROCWRAP_Attach: entered args:\n" "0x%x"
+		 " uProcessor: 0x%x\tpAttrIn: 0x%x\tphProcessor \n",
+		 args->ARGS_PROC_ATTACH.uProcessor,
+		 args->ARGS_PROC_ATTACH.pAttrIn,
+		 args->ARGS_PROC_ATTACH.phProcessor);
+	/* Optional argument */
+	if (args->ARGS_PROC_ATTACH.pAttrIn) {
+		cp_fm_usr(&attrIn, args->ARGS_PROC_ATTACH.pAttrIn, status, 1);
+		if (DSP_SUCCEEDED(status))
+			pAttrIn = &attrIn;
+
+	}
+	status = PROC_Attach(args->ARGS_PROC_ATTACH.uProcessor, pAttrIn,
+			    &processor);
+	cp_to_usr(args->ARGS_PROC_ATTACH.phProcessor, &processor, status, 1);
+	return status;
+}
+
+/*
+ * ======== PROCWRAP_Ctrl ========
+ */
+u32 PROCWRAP_Ctrl(union Trapped_Args *args)
+{
+	u32 cbDataSize, *pSize = (u32 *)args->ARGS_PROC_CTRL.pArgs;
+	u8 *pArgs = NULL;
+	DSP_STATUS status = DSP_SOK;
+
+	GT_3trace(WCD_debugMask, GT_ENTER,
+		 "PROCWRAP_Ctrl: entered args:\n 0x%x"
+		 " uProcessor: 0x%x\tdwCmd: 0x%x\tpArgs \n",
+		 args->ARGS_PROC_CTRL.hProcessor,
+		 args->ARGS_PROC_CTRL.dwCmd,
+		 args->ARGS_PROC_CTRL.pArgs);
+	if (pSize) {
+		if (get_user(cbDataSize, pSize))
+			status = DSP_EFAIL;
+
+		cbDataSize += sizeof(u32);
+		if (DSP_SUCCEEDED(status)) {
+			pArgs = MEM_Alloc(cbDataSize, MEM_NONPAGED);
+			if (pArgs == NULL)
+				status = DSP_EMEMORY;
+
+		}
+		cp_fm_usr(pArgs, args->ARGS_PROC_CTRL.pArgs, status,
+			 cbDataSize);
+	}
+	if (DSP_SUCCEEDED(status)) {
+		status = PROC_Ctrl(args->ARGS_PROC_CTRL.hProcessor,
+				  args->ARGS_PROC_CTRL.dwCmd,
+				  (struct DSP_CBDATA *)pArgs);
+	}
+
+	/* cp_to_usr(args->ARGS_PROC_CTRL.pArgs, pArgs, status, 1);*/
+	if (pArgs)
+		MEM_Free(pArgs);
+
+	return status;
+}
+
+/*
+ * ======== PROCWRAP_Detach ========
+ */
+u32 PROCWRAP_Detach(union Trapped_Args *args)
+{
+	u32 retVal;
+
+	GT_1trace(WCD_debugMask, GT_ENTER,
+		 "PROCWRAP_Detach: entered args\n0x%x "
+		 "hProceesor \n", args->ARGS_PROC_DETACH.hProcessor);
+	retVal = PROC_Detach(args->ARGS_PROC_DETACH.hProcessor);
+
+	return retVal;
+}
+
+/*
+ * ======== PROCWRAP_EnumNode_Info ========
+ */
+u32 PROCWRAP_EnumNode_Info(union Trapped_Args *args)
+{
+	DSP_STATUS status;
+	DSP_HNODE aNodeTab[MAX_NODES];
+	u32 uNumNodes;
+	u32 uAllocated;
+
+	GT_5trace(WCD_debugMask, GT_ENTER,
+		 "PROCWRAP_EnumNode_Info:entered args:\n0x"
+		 "%xhProcessor:0x%x\taNodeTab:0x%x\tuNodeTabSize:"
+		 "%0x%x\tpuNumNodes%\n0x%x puAllocated: \n",
+		 args->ARGS_PROC_ENUMNODE_INFO.hProcessor,
+		 args->ARGS_PROC_ENUMNODE_INFO.aNodeTab,
+		 args->ARGS_PROC_ENUMNODE_INFO.uNodeTabSize,
+		 args->ARGS_PROC_ENUMNODE_INFO.puNumNodes,
+		 args->ARGS_PROC_ENUMNODE_INFO.puAllocated);
+	DBC_Require(args->ARGS_PROC_ENUMNODE_INFO.uNodeTabSize <= MAX_NODES);
+	status = PROC_EnumNodes(args->ARGS_PROC_ENUMNODE_INFO.hProcessor,
+				aNodeTab,
+				args->ARGS_PROC_ENUMNODE_INFO.uNodeTabSize,
+				&uNumNodes, &uAllocated);
+	cp_to_usr(args->ARGS_PROC_ENUMNODE_INFO.aNodeTab, aNodeTab, status,
+		 uNumNodes);
+	cp_to_usr(args->ARGS_PROC_ENUMNODE_INFO.puNumNodes, &uNumNodes,
+		 status, 1);
+	cp_to_usr(args->ARGS_PROC_ENUMNODE_INFO.puAllocated, &uAllocated,
+		 status, 1);
+	return status;
+}
+
+/*
+ * ======== PROCWRAP_FlushMemory ========
+ */
+u32 PROCWRAP_FlushMemory(union Trapped_Args *args)
+{
+	DSP_STATUS status;
+
+	GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_FlushMemory: entered\n");
+
+	status = PROC_FlushMemory(args->ARGS_PROC_FLUSHMEMORY.hProcessor,
+				 args->ARGS_PROC_FLUSHMEMORY.pMpuAddr,
+				 args->ARGS_PROC_FLUSHMEMORY.ulSize,
+				 args->ARGS_PROC_FLUSHMEMORY.ulFlags);
+	return status;
+}
+
+
+/*
+ * ======== PROCWRAP_InvalidateMemory ========
+ */
+u32 PROCWRAP_InvalidateMemory(union Trapped_Args *args)
+{
+	DSP_STATUS status;
+
+	GT_0trace(WCD_debugMask, GT_ENTER,
+		 "PROCWRAP_InvalidateMemory:entered\n");
+
+	status = PROC_InvalidateMemory(
+				  args->ARGS_PROC_INVALIDATEMEMORY.hProcessor,
+				  args->ARGS_PROC_INVALIDATEMEMORY.pMpuAddr,
+				  args->ARGS_PROC_INVALIDATEMEMORY.ulSize);
+	return status;
+}
+
+
+/*
+ * ======== PROCWRAP_EnumResources ========
+ */
+u32 PROCWRAP_EnumResources(union Trapped_Args *args)
+{
+	u32 retVal;
+
+	GT_4trace(WCD_debugMask, GT_ENTER,
+		 "PROCWRAP_EnumResources: entered args:\n"
+		 "0x%x hProcessor: 0x%x\tuResourceMask: 0x%x\tpResourceInfo"
+		 " 0x%x\tuResourceInfoSixe \n",
+		 args->ARGS_PROC_ENUMRESOURCES.hProcessor,
+		 args->ARGS_PROC_ENUMRESOURCES.uResourceType,
+		 args->ARGS_PROC_ENUMRESOURCES.pResourceInfo,
+		 args->ARGS_PROC_ENUMRESOURCES.uResourceInfoSize);
+	retVal = PROC_GetResourceInfo(args->ARGS_PROC_ENUMRESOURCES.hProcessor,
+			args->ARGS_PROC_ENUMRESOURCES.uResourceType,
+			WRAP_MAP2CALLER(args->ARGS_PROC_ENUMRESOURCES.
+			pResourceInfo), args->ARGS_PROC_ENUMRESOURCES.
+			uResourceInfoSize);
+
+	return retVal;
+}
+
+/*
+ * ======== PROCWRAP_GetState ========
+ */
+u32 PROCWRAP_GetState(union Trapped_Args *args)
+{
+	DSP_STATUS status;
+	struct DSP_PROCESSORSTATE procStatus;
+	GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_GetState: entered\n");
+	status = PROC_GetState(args->ARGS_PROC_GETSTATE.hProcessor, &procStatus,
+			      args->ARGS_PROC_GETSTATE.uStateInfoSize);
+	cp_to_usr(args->ARGS_PROC_GETSTATE.pProcStatus, &procStatus, status, 1);
+	return status;
+
+}
+
+/*
+ * ======== PROCWRAP_GetTrace ========
+ */
+u32 PROCWRAP_GetTrace(union Trapped_Args *args)
+{
+	DSP_STATUS status;
+	u8 *pBuf;
+
+	GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_GetTrace: entered\n");
+
+	DBC_Require(args->ARGS_PROC_GETTRACE.uMaxSize <= MAX_TRACEBUFLEN);
+
+	pBuf = MEM_Calloc(args->ARGS_PROC_GETTRACE.uMaxSize, MEM_NONPAGED);
+	if (pBuf != NULL) {
+		status = PROC_GetTrace(args->ARGS_PROC_GETTRACE.hProcessor,
+				      pBuf, args->ARGS_PROC_GETTRACE.uMaxSize);
+	} else {
+		status = DSP_EMEMORY;
+	}
+	cp_to_usr(args->ARGS_PROC_GETTRACE.pBuf, pBuf, status,
+		 args->ARGS_PROC_GETTRACE.uMaxSize);
+	if (pBuf)
+		MEM_Free(pBuf);
+
+	return status;
+}
+
+/*
+ * ======== PROCWRAP_Load ========
+ */
+u32 PROCWRAP_Load(union Trapped_Args *args)
+{
+	s32 i, len;
+	DSP_STATUS status = DSP_SOK;
+	u8 *temp;
+	s32 argc = args->ARGS_PROC_LOAD.iArgc;
+	u8 **argv, **envp = NULL;
+
+	DBC_Require(argc > 0);
+	DBC_Require(argc <= MAX_LOADARGS);
+
+	argv = MEM_Alloc(argc * sizeof(u8 *), MEM_NONPAGED);
+	if (argv == NULL)
+		status = DSP_EMEMORY;
+
+	cp_fm_usr(argv, args->ARGS_PROC_LOAD.aArgv, status, argc);
+	for (i = 0; DSP_SUCCEEDED(status) && (i < argc); i++) {
+		if (argv[i] != NULL) {
+			temp = argv[i];	/* User space pointer to argument */
+			len = strlen_user((char *)temp);
+			/* Kernel space pointer to argument */
+			argv[i] = MEM_Alloc(len, MEM_NONPAGED);
+			if (argv[i] == NULL) {
+				status = DSP_EMEMORY;
+				break;
+			}
+			cp_fm_usr(argv[i], temp, status, len);
+		}
+	}
+	/* TODO: validate this */
+	if (args->ARGS_PROC_LOAD.aEnvp != NULL) {
+		/* number of elements in the envp array including NULL */
+		len = 0;
+		do {
+			len++;
+			get_user(temp, args->ARGS_PROC_LOAD.aEnvp);
+		} while (temp);
+		envp = MEM_Alloc(len * sizeof(u8 *), MEM_NONPAGED);
+		if (envp == NULL)
+			status = DSP_EMEMORY;
+
+		cp_fm_usr(envp, args->ARGS_PROC_LOAD.aEnvp, status, len);
+		for (i = 0; DSP_SUCCEEDED(status) && (envp[i] != NULL); i++) {
+			temp = envp[i];	/* User space pointer to argument */
+			len = strlen_user((char *)temp);
+			/* Kernel space pointer to argument */
+			envp[i] = MEM_Alloc(len, MEM_NONPAGED);
+			if (envp[i] == NULL) {
+				status = DSP_EMEMORY;
+				break;
+			}
+			cp_fm_usr(envp[i], temp, status, len);
+		}
+	}
+	GT_5trace(WCD_debugMask, GT_ENTER,
+		 "PROCWRAP_Load, hProcessor: 0x%x\n\tiArgc:"
+		 "0x%x\n\taArgv: 0x%x\n\taArgv[0]: %s\n\taEnvp: 0x%0x\n",
+		 args->ARGS_PROC_LOAD.hProcessor,
+		 args->ARGS_PROC_LOAD.iArgc, args->ARGS_PROC_LOAD.aArgv,
+		 argv[0], args->ARGS_PROC_LOAD.aEnvp);
+	if (DSP_SUCCEEDED(status)) {
+		status = PROC_Load(args->ARGS_PROC_LOAD.hProcessor,
+				  args->ARGS_PROC_LOAD.iArgc,
+				  (CONST char **)argv, (CONST char **)envp);
+	}
+	if (envp != NULL) {
+		i = 0;
+		while (envp[i] != NULL)
+			MEM_Free(envp[i++]);
+
+		MEM_Free(envp);
+	}
+	if (argv != NULL) {
+		for (i = 0; i < argc; i++) {
+			if (argv[i] != NULL)
+				MEM_Free(argv[i]);
+
+		}
+		MEM_Free(argv);
+	}
+	return status;
+}
+
+/*
+ * ======== PROCWRAP_Map ========
+ */
+u32 PROCWRAP_Map(union Trapped_Args *args)
+{
+	DSP_STATUS status;
+	void *pMapAddr;
+
+	GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_Map: entered\n");
+	status = PROC_Map(args->ARGS_PROC_MAPMEM.hProcessor,
+			 args->ARGS_PROC_MAPMEM.pMpuAddr,
+			 args->ARGS_PROC_MAPMEM.ulSize,
+			 args->ARGS_PROC_MAPMEM.pReqAddr, &pMapAddr,
+			 args->ARGS_PROC_MAPMEM.ulMapAttr);
+	if (DSP_SUCCEEDED(status)) {
+		if (put_user(pMapAddr, args->ARGS_PROC_MAPMEM.ppMapAddr))
+			status = DSP_EINVALIDARG;
+
+	}
+	return status;
+}
+
+/*
+ * ======== PROCWRAP_RegisterNotify ========
+ */
+u32 PROCWRAP_RegisterNotify(union Trapped_Args *args)
+{
+	DSP_STATUS status;
+	struct DSP_NOTIFICATION notification;
+
+	GT_0trace(WCD_debugMask, GT_ENTER,
+		 "PROCWRAP_RegisterNotify: entered\n");
+
+	/* Initialize the notification data structure  */
+	notification.psName = NULL;
+	notification.handle = NULL;
+
+	status = PROC_RegisterNotify(args->ARGS_PROC_REGISTER_NOTIFY.hProcessor,
+				    args->ARGS_PROC_REGISTER_NOTIFY.uEventMask,
+				    args->ARGS_PROC_REGISTER_NOTIFY.uNotifyType,
+				    &notification);
+	cp_to_usr(args->ARGS_PROC_REGISTER_NOTIFY.hNotification, &notification,
+		 status, 1);
+	return status;
+}
+
+/*
+ * ======== PROCWRAP_ReserveMemory ========
+ */
+u32 PROCWRAP_ReserveMemory(union Trapped_Args *args)
+{
+	DSP_STATUS status;
+	void *pRsvAddr;
+
+	GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_ReserveMemory: entered\n");
+	status = PROC_ReserveMemory(args->ARGS_PROC_RSVMEM.hProcessor,
+				   args->ARGS_PROC_RSVMEM.ulSize, &pRsvAddr);
+	if (put_user(pRsvAddr, args->ARGS_PROC_RSVMEM.ppRsvAddr))
+		status = DSP_EINVALIDARG;
+
+	return status;
+}
+
+/*
+ * ======== PROCWRAP_Start ========
+ */
+u32 PROCWRAP_Start(union Trapped_Args *args)
+{
+	u32 retVal;
+
+	GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_Start: entered\n");
+	retVal = PROC_Start(args->ARGS_PROC_START.hProcessor);
+	return retVal;
+}
+
+/*
+ * ======== PROCWRAP_UnMap ========
+ */
+u32 PROCWRAP_UnMap(union Trapped_Args *args)
+{
+	DSP_STATUS status;
+
+	GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_UnMap: entered\n");
+	status = PROC_UnMap(args->ARGS_PROC_UNMAPMEM.hProcessor,
+			   args->ARGS_PROC_UNMAPMEM.pMapAddr);
+	return status;
+}
+
+/*
+ * ======== PROCWRAP_UnReserveMemory ========
+ */
+u32 PROCWRAP_UnReserveMemory(union Trapped_Args *args)
+{
+	DSP_STATUS status;
+
+	GT_0trace(WCD_debugMask, GT_ENTER,
+		 "PROCWRAP_UnReserveMemory: entered\n");
+	status = PROC_UnReserveMemory(args->ARGS_PROC_UNRSVMEM.hProcessor,
+				     args->ARGS_PROC_UNRSVMEM.pRsvAddr);
+	return status;
+}
+
+/*
+ * ======== PROCWRAP_Stop ========
+ */
+u32 PROCWRAP_Stop(union Trapped_Args *args)
+{
+	u32 retVal;
+
+	GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_Stop: entered\n");
+	retVal = PROC_Stop(args->ARGS_PROC_STOP.hProcessor);
+
+	return retVal;
+}
+
+/*
+ * ======== NODEWRAP_Allocate ========
+ */
+u32 NODEWRAP_Allocate(union Trapped_Args *args)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DSP_UUID nodeId;
+	u32 cbDataSize;
+	u32 *pSize = (u32 *)args->ARGS_NODE_ALLOCATE.pArgs;
+	u8 *pArgs = NULL;
+	struct DSP_NODEATTRIN attrIn, *pAttrIn = NULL;
+	struct NODE_OBJECT *hNode;
+
+	GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Allocate: entered\n");
+
+	/* Optional argument */
+	if (pSize) {
+		if (get_user(cbDataSize, pSize))
+			status = DSP_EFAIL;
+
+		cbDataSize += sizeof(u32);
+		if (DSP_SUCCEEDED(status)) {
+			pArgs = MEM_Alloc(cbDataSize, MEM_NONPAGED);
+			if (pArgs == NULL)
+				status = DSP_EMEMORY;
+
+		}
+		cp_fm_usr(pArgs, args->ARGS_NODE_ALLOCATE.pArgs, status,
+			 cbDataSize);
+	}
+	cp_fm_usr(&nodeId, args->ARGS_NODE_ALLOCATE.pNodeID, status, 1);
+	/* Optional argument */
+	if (args->ARGS_NODE_ALLOCATE.pAttrIn) {
+		cp_fm_usr(&attrIn, args->ARGS_NODE_ALLOCATE.pAttrIn, status, 1);
+		if (DSP_SUCCEEDED(status))
+			pAttrIn = &attrIn;
+
+	}
+	if (DSP_SUCCEEDED(status)) {
+		status = NODE_Allocate(args->ARGS_NODE_ALLOCATE.hProcessor,
+				      &nodeId, (struct DSP_CBDATA *)pArgs,
+				      pAttrIn, &hNode);
+	}
+	cp_to_usr(args->ARGS_NODE_ALLOCATE.phNode, &hNode, status, 1);
+	if (pArgs)
+		MEM_Free(pArgs);
+
+	return status;
+}
+
+/*
+ *  ======== NODEWRAP_AllocMsgBuf ========
+ */
+u32 NODEWRAP_AllocMsgBuf(union Trapped_Args *args)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DSP_BUFFERATTR *pAttr = NULL;
+	struct DSP_BUFFERATTR attr;
+	u8 *pBuffer = NULL;
+
+	if (args->ARGS_NODE_ALLOCMSGBUF.pAttr) {	/* Optional argument */
+		cp_fm_usr(&attr, args->ARGS_NODE_ALLOCMSGBUF.pAttr, status, 1);
+		if (DSP_SUCCEEDED(status))
+			pAttr = &attr;
+
+	}
+	/* IN OUT argument */
+	cp_fm_usr(&pBuffer, args->ARGS_NODE_ALLOCMSGBUF.pBuffer, status, 1);
+	if (DSP_SUCCEEDED(status)) {
+		status = NODE_AllocMsgBuf(args->ARGS_NODE_ALLOCMSGBUF.hNode,
+					 args->ARGS_NODE_ALLOCMSGBUF.uSize,
+					 pAttr, &pBuffer);
+	}
+	cp_to_usr(args->ARGS_NODE_ALLOCMSGBUF.pBuffer, &pBuffer, status, 1)
+	return status;
+}
+
+/*
+ * ======== NODEWRAP_ChangePriority ========
+ */
+u32 NODEWRAP_ChangePriority(union Trapped_Args *args)
+{
+	u32 retVal;
+
+	GT_0trace(WCD_debugMask, GT_ENTER,
+		 "NODEWRAP_ChangePriority: entered\n");
+	retVal = NODE_ChangePriority(args->ARGS_NODE_CHANGEPRIORITY.hNode,
+			args->ARGS_NODE_CHANGEPRIORITY.iPriority);
+
+	return retVal;
+}
+
+/*
+ * ======== NODEWRAP_Connect ========
+ */
+u32 NODEWRAP_Connect(union Trapped_Args *args)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DSP_STRMATTR attrs;
+	struct DSP_STRMATTR *pAttrs = NULL;
+	u32 cbDataSize;
+	u32 *pSize = (u32 *)args->ARGS_NODE_CONNECT.pConnParam;
+	u8 *pArgs = NULL;
+
+	GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Connect: entered\n");
+
+	/* Optional argument */
+	if (pSize) {
+		if (get_user(cbDataSize, pSize))
+			status = DSP_EFAIL;
+
+		cbDataSize += sizeof(u32);
+		if (DSP_SUCCEEDED(status)) {
+			pArgs = MEM_Alloc(cbDataSize, MEM_NONPAGED);
+			if (pArgs == NULL)
+				status = DSP_EMEMORY;
+
+		}
+		cp_fm_usr(pArgs, args->ARGS_NODE_CONNECT.pConnParam, status,
+			 cbDataSize);
+	}
+	if (args->ARGS_NODE_CONNECT.pAttrs) {	/* Optional argument */
+		cp_fm_usr(&attrs, args->ARGS_NODE_CONNECT.pAttrs, status, 1);
+		if (DSP_SUCCEEDED(status))
+			pAttrs = &attrs;
+
+	}
+	if (DSP_SUCCEEDED(status)) {
+		status = NODE_Connect(args->ARGS_NODE_CONNECT.hNode,
+				     args->ARGS_NODE_CONNECT.uStream,
+				     args->ARGS_NODE_CONNECT.hOtherNode,
+				     args->ARGS_NODE_CONNECT.uOtherStream,
+				     pAttrs, (struct DSP_CBDATA *)pArgs);
+	}
+	if (pArgs)
+		MEM_Free(pArgs);
+
+	return status;
+}
+
+/*
+ * ======== NODEWRAP_Create ========
+ */
+u32 NODEWRAP_Create(union Trapped_Args *args)
+{
+	u32 retVal;
+
+	GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Create: entered\n");
+	retVal = NODE_Create(args->ARGS_NODE_CREATE.hNode);
+
+	return retVal;
+}
+
+/*
+ * ======== NODEWRAP_Delete ========
+ */
+u32 NODEWRAP_Delete(union Trapped_Args *args)
+{
+	u32 retVal;
+
+	GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Delete: entered\n");
+	retVal = NODE_Delete(args->ARGS_NODE_DELETE.hNode);
+
+	return retVal;
+}
+
+/*
+ *  ======== NODEWRAP_FreeMsgBuf ========
+ */
+u32 NODEWRAP_FreeMsgBuf(union Trapped_Args *args)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DSP_BUFFERATTR *pAttr = NULL;
+	struct DSP_BUFFERATTR attr;
+	if (args->ARGS_NODE_FREEMSGBUF.pAttr) {	/* Optional argument */
+		cp_fm_usr(&attr, args->ARGS_NODE_FREEMSGBUF.pAttr, status, 1);
+		if (DSP_SUCCEEDED(status))
+			pAttr = &attr;
+
+	}
+	if (DSP_SUCCEEDED(status)) {
+		status = NODE_FreeMsgBuf(args->ARGS_NODE_FREEMSGBUF.hNode,
+					args->ARGS_NODE_FREEMSGBUF.pBuffer,
+					pAttr);
+	}
+
+	return status;
+}
+
+/*
+ * ======== NODEWRAP_GetAttr ========
+ */
+u32 NODEWRAP_GetAttr(union Trapped_Args *args)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DSP_NODEATTR attr;
+
+	GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_GetAttr: entered\n");
+
+	status = NODE_GetAttr(args->ARGS_NODE_GETATTR.hNode, &attr,
+			     args->ARGS_NODE_GETATTR.uAttrSize);
+	cp_to_usr(args->ARGS_NODE_GETATTR.pAttr, &attr, status, 1);
+
+	return status;
+}
+
+/*
+ * ======== NODEWRAP_GetMessage ========
+ */
+u32 NODEWRAP_GetMessage(union Trapped_Args *args)
+{
+	DSP_STATUS status;
+	struct DSP_MSG msg;
+
+	GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_GetMessage: entered\n");
+
+	status = NODE_GetMessage(args->ARGS_NODE_GETMESSAGE.hNode, &msg,
+				args->ARGS_NODE_GETMESSAGE.uTimeout);
+
+	cp_to_usr(args->ARGS_NODE_GETMESSAGE.pMessage, &msg, status, 1);
+
+	return status;
+}
+
+/*
+ * ======== NODEWRAP_Pause ========
+ */
+u32 NODEWRAP_Pause(union Trapped_Args *args)
+{
+	u32 retVal;
+
+	GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Pause: entered\n");
+	retVal = NODE_Pause(args->ARGS_NODE_PAUSE.hNode);
+
+	return retVal;
+}
+
+/*
+ * ======== NODEWRAP_PutMessage ========
+ */
+u32 NODEWRAP_PutMessage(union Trapped_Args *args)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DSP_MSG msg;
+
+	GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_PutMessage: entered\n");
+
+	cp_fm_usr(&msg, args->ARGS_NODE_PUTMESSAGE.pMessage, status, 1);
+
+	if (DSP_SUCCEEDED(status)) {
+		status = NODE_PutMessage(args->ARGS_NODE_PUTMESSAGE.hNode, &msg,
+					args->ARGS_NODE_PUTMESSAGE.uTimeout);
+	}
+
+	return status;
+}
+
+/*
+ * ======== NODEWRAP_RegisterNotify ========
+ */
+u32 NODEWRAP_RegisterNotify(union Trapped_Args *args)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DSP_NOTIFICATION notification;
+
+	GT_0trace(WCD_debugMask, GT_ENTER,
+		 "NODEWRAP_RegisterNotify: entered\n");
+
+	/* Initialize the notification data structure  */
+	notification.psName = NULL;
+	notification.handle = NULL;
+
+	status = NODE_RegisterNotify(args->ARGS_NODE_REGISTERNOTIFY.hNode,
+				    args->ARGS_NODE_REGISTERNOTIFY.uEventMask,
+				    args->ARGS_NODE_REGISTERNOTIFY.uNotifyType,
+				    &notification);
+	cp_to_usr(args->ARGS_NODE_REGISTERNOTIFY.hNotification, &notification,
+		 status, 1);
+	return status;
+}
+
+/*
+ * ======== NODEWRAP_Run ========
+ */
+u32 NODEWRAP_Run(union Trapped_Args *args)
+{
+	u32 retVal;
+
+	GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Run: entered\n");
+	retVal = NODE_Run(args->ARGS_NODE_RUN.hNode);
+
+	return retVal;
+}
+
+/*
+ * ======== NODEWRAP_Terminate ========
+ */
+u32 NODEWRAP_Terminate(union Trapped_Args *args)
+{
+	DSP_STATUS status;
+	DSP_STATUS tempstatus;
+
+	GT_0trace(WCD_debugMask, GT_ENTER, "NODEWRAP_Terminate: entered\n");
+
+	status = NODE_Terminate(args->ARGS_NODE_TERMINATE.hNode, &tempstatus);
+
+	cp_to_usr(args->ARGS_NODE_TERMINATE.pStatus, &tempstatus, status, 1);
+
+	return status;
+}
+
+
+/*
+ * ======== NODEWRAP_GetUUIDProps ========
+ */
+u32 NODEWRAP_GetUUIDProps(union Trapped_Args *args)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DSP_UUID nodeId;
+	struct DSP_NDBPROPS    *pnodeProps = NULL;
+
+	GT_0trace(WCD_debugMask, GT_ENTER,
+		 "NODEWRAP_GetUUIDPropste: entered\n");
+
+
+	cp_fm_usr(&nodeId, args->ARGS_NODE_GETUUIDPROPS.pNodeID, status, 1);
+	pnodeProps = MEM_Alloc(sizeof(struct DSP_NDBPROPS), MEM_NONPAGED);
+	if (pnodeProps != NULL) {
+		status = NODE_GetUUIDProps(args->
+					  ARGS_NODE_GETUUIDPROPS.hProcessor,
+					  &nodeId, pnodeProps);
+		cp_to_usr(args->ARGS_NODE_GETUUIDPROPS.pNodeProps, pnodeProps,
+			 status, 1);
+	}	else
+		status = DSP_EMEMORY;
+	if (pnodeProps)
+		MEM_Free(pnodeProps);
+	return status;
+}
+
+/*
+ * ======== STRMWRAP_AllocateBuffer ========
+ */
+u32 STRMWRAP_AllocateBuffer(union Trapped_Args *args)
+{
+	DSP_STATUS status;
+	u8 **apBuffer = NULL;
+	u32 uNumBufs = args->ARGS_STRM_ALLOCATEBUFFER.uNumBufs;
+
+	DBC_Require(uNumBufs <= MAX_BUFS);
+
+	apBuffer = MEM_Alloc((uNumBufs * sizeof(u8 *)), MEM_NONPAGED);
+
+	status = STRM_AllocateBuffer(args->ARGS_STRM_ALLOCATEBUFFER.hStream,
+				     args->ARGS_STRM_ALLOCATEBUFFER.uSize,
+				     apBuffer, uNumBufs);
+	cp_to_usr(args->ARGS_STRM_ALLOCATEBUFFER.apBuffer, apBuffer, status,
+		 uNumBufs);
+	if (apBuffer)
+		MEM_Free(apBuffer);
+
+	return status;
+}
+
+/*
+ * ======== STRMWRAP_Close ========
+ */
+u32 STRMWRAP_Close(union Trapped_Args *args)
+{
+	u32 retVal;
+
+	retVal = STRM_Close(args->ARGS_STRM_CLOSE.hStream);
+
+	return retVal;
+}
+
+/*
+ * ======== STRMWRAP_FreeBuffer ========
+ */
+u32 STRMWRAP_FreeBuffer(union Trapped_Args *args)
+{
+	DSP_STATUS status = DSP_SOK;
+	u8 **apBuffer = NULL;
+	u32 uNumBufs = args->ARGS_STRM_FREEBUFFER.uNumBufs;
+
+	DBC_Require(uNumBufs <= MAX_BUFS);
+
+	apBuffer = MEM_Alloc((uNumBufs * sizeof(u8 *)), MEM_NONPAGED);
+
+	cp_fm_usr(apBuffer, args->ARGS_STRM_FREEBUFFER.apBuffer, status,
+		 uNumBufs);
+
+	if (DSP_SUCCEEDED(status)) {
+		status = STRM_FreeBuffer(args->ARGS_STRM_FREEBUFFER.hStream,
+					 apBuffer, uNumBufs);
+	}
+	cp_to_usr(args->ARGS_STRM_FREEBUFFER.apBuffer, apBuffer, status,
+		 uNumBufs);
+	if (apBuffer)
+		MEM_Free(apBuffer);
+
+	return status;
+}
+
+/*
+ * ======== STRMWRAP_GetEventHandle ========
+ */
+u32 STRMWRAP_GetEventHandle(union Trapped_Args *args)
+{
+	return DSP_ENOTIMPL;
+}
+
+/*
+ * ======== STRMWRAP_GetInfo ========
+ */
+u32 STRMWRAP_GetInfo(union Trapped_Args *args)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct STRM_INFO strmInfo;
+	struct DSP_STREAMINFO user;
+	struct DSP_STREAMINFO *temp;
+
+	cp_fm_usr(&strmInfo, args->ARGS_STRM_GETINFO.pStreamInfo, status, 1);
+	temp = strmInfo.pUser;
+
+	strmInfo.pUser = &user;
+
+	if (DSP_SUCCEEDED(status)) {
+		status = STRM_GetInfo(args->ARGS_STRM_GETINFO.hStream,
+			 &strmInfo, args->ARGS_STRM_GETINFO.uStreamInfoSize);
+	}
+	cp_to_usr(temp, strmInfo.pUser, status, 1);
+	strmInfo.pUser = temp;
+	cp_to_usr(args->ARGS_STRM_GETINFO.pStreamInfo, &strmInfo, status, 1);
+	return status;
+}
+
+/*
+ * ======== STRMWRAP_Idle ========
+ */
+u32 STRMWRAP_Idle(union Trapped_Args *args)
+{
+	u32 retVal;
+
+	retVal = STRM_Idle(args->ARGS_STRM_IDLE.hStream,
+			args->ARGS_STRM_IDLE.bFlush);
+
+	return retVal;
+}
+
+/*
+ * ======== STRMWRAP_Issue ========
+ */
+u32 STRMWRAP_Issue(union Trapped_Args *args)
+{
+	u32 retVal;
+
+	retVal = STRM_Issue(args->ARGS_STRM_ISSUE.hStream,
+			args->ARGS_STRM_ISSUE.pBuffer,
+			args->ARGS_STRM_ISSUE.dwBytes,
+			args->ARGS_STRM_ISSUE.dwBufSize,
+			args->ARGS_STRM_ISSUE.dwArg);
+
+	/* This is a user space pointer */
+	return retVal;
+}
+
+/*
+ * ======== STRMWRAP_Open ========
+ */
+u32 STRMWRAP_Open(union Trapped_Args *args)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct STRM_ATTR attr;
+	struct STRM_OBJECT *pStrm;
+	struct DSP_STREAMATTRIN strmAttrIn;
+
+	cp_fm_usr(&attr, args->ARGS_STRM_OPEN.pAttrIn, status, 1);
+
+	if (attr.pStreamAttrIn != NULL) {	/* Optional argument */
+		cp_fm_usr(&strmAttrIn, attr.pStreamAttrIn, status, 1);
+		if (DSP_SUCCEEDED(status))
+			attr.pStreamAttrIn = &strmAttrIn;
+
+	}
+	status = STRM_Open(args->ARGS_STRM_OPEN.hNode,
+			  args->ARGS_STRM_OPEN.uDirection,
+			  args->ARGS_STRM_OPEN.uIndex, &attr, &pStrm);
+	cp_to_usr(args->ARGS_STRM_OPEN.phStream, &pStrm, status, 1);
+	return status;
+}
+
+/*
+ * ======== STRMWRAP_Reclaim ========
+ */
+u32 STRMWRAP_Reclaim(union Trapped_Args *args)
+{
+	DSP_STATUS status = DSP_SOK;
+	u8 *pBufPtr;
+	u32 ulBytes;
+	u32 dwArg;
+	u32 ulBufSize;
+
+	status = STRM_Reclaim(args->ARGS_STRM_RECLAIM.hStream, &pBufPtr,
+			     &ulBytes, &ulBufSize, &dwArg);
+	cp_to_usr(args->ARGS_STRM_RECLAIM.pBufPtr, &pBufPtr, status, 1);
+	cp_to_usr(args->ARGS_STRM_RECLAIM.pBytes, &ulBytes, status, 1);
+	cp_to_usr(args->ARGS_STRM_RECLAIM.pdwArg, &dwArg, status, 1);
+
+	if (args->ARGS_STRM_RECLAIM.pBufSize != NULL) {
+		cp_to_usr(args->ARGS_STRM_RECLAIM.pBufSize, &ulBufSize,
+			 status, 1);
+	}
+
+	return status;
+}
+
+/*
+ * ======== STRMWRAP_RegisterNotify ========
+ */
+u32 STRMWRAP_RegisterNotify(union Trapped_Args *args)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct DSP_NOTIFICATION notification;
+
+	GT_0trace(WCD_debugMask, GT_ENTER,
+		 "NODEWRAP_RegisterNotify: entered\n");
+
+	/* Initialize the notification data structure  */
+	notification.psName = NULL;
+	notification.handle = NULL;
+
+	status = STRM_RegisterNotify(args->ARGS_STRM_REGISTERNOTIFY.hStream,
+				    args->ARGS_STRM_REGISTERNOTIFY.uEventMask,
+				    args->ARGS_STRM_REGISTERNOTIFY.uNotifyType,
+				    &notification);
+	cp_to_usr(args->ARGS_STRM_REGISTERNOTIFY.hNotification, &notification,
+		 status, 1);
+
+	return status;
+}
+
+/*
+ * ======== STRMWRAP_Select ========
+ */
+u32 STRMWRAP_Select(union Trapped_Args *args)
+{
+	u32 mask;
+	struct STRM_OBJECT *aStrmTab[MAX_STREAMS];
+	DSP_STATUS status = DSP_SOK;
+
+	DBC_Require(args->ARGS_STRM_SELECT.nStreams <= MAX_STREAMS);
+
+	cp_fm_usr(aStrmTab, args->ARGS_STRM_SELECT.aStreamTab, status,
+		 args->ARGS_STRM_SELECT.nStreams);
+	if (DSP_SUCCEEDED(status)) {
+		status = STRM_Select(aStrmTab, args->ARGS_STRM_SELECT.nStreams,
+				    &mask, args->ARGS_STRM_SELECT.uTimeout);
+	}
+	cp_to_usr(args->ARGS_STRM_SELECT.pMask, &mask, status, 1);
+	return status;
+}
+
+/* CMM */
+
+/*
+ * ======== CMMWRAP_CallocBuf ========
+ */
+u32 CMMWRAP_CallocBuf(union Trapped_Args *args)
+{
+	/* This operation is done in kernel */
+	return DSP_ENOTIMPL;
+}
+
+/*
+ * ======== CMMWRAP_FreeBuf ========
+ */
+u32 CMMWRAP_FreeBuf(union Trapped_Args *args)
+{
+	/* This operation is done in kernel */
+	return DSP_ENOTIMPL;
+}
+
+/*
+ * ======== CMMWRAP_GetHandle ========
+ */
+u32 CMMWRAP_GetHandle(union Trapped_Args *args)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct CMM_OBJECT *hCmmMgr;
+
+	status = CMM_GetHandle(args->ARGS_CMM_GETHANDLE.hProcessor, &hCmmMgr);
+
+	cp_to_usr(args->ARGS_CMM_GETHANDLE.phCmmMgr, &hCmmMgr, status, 1);
+
+	return status;
+}
+
+/*
+ * ======== CMMWRAP_GetInfo ========
+ */
+u32 CMMWRAP_GetInfo(union Trapped_Args *args)
+{
+	DSP_STATUS status = DSP_SOK;
+	struct CMM_INFO cmmInfo;
+
+	status = CMM_GetInfo(args->ARGS_CMM_GETINFO.hCmmMgr, &cmmInfo);
+
+	cp_to_usr(args->ARGS_CMM_GETINFO.pCmmInfo, &cmmInfo, status, 1);
+
+	return status;
+}
-- 
1.5.5.1.357.g1af8b


