/*
 * dbdcd.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * This file contains the implementation of the DSP/BIOS Bridge
 * Configuration Database (DCD).
 *
 * Notes:
 *   The fxn dcd_get_objects can apply a callback fxn to each DCD object
 *   that is located in a specified COFF file.  At the moment,
 *   dcd_auto_register, dcd_auto_unregister, and NLDR module all use
 *   dcd_get_objects.
 *
 * Copyright (C) 2005-2006 Texas Instruments, Inc.
 *
 * This package is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */
#include <linux/types.h>

/*  ----------------------------------- Host OS */
#include <dspbridge/host_os.h>

/*  ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/dbdefs.h>
/*  ----------------------------------- Trace & Debug */
#include <dspbridge/dbc.h>

/*  ----------------------------------- Platform Manager */
#include <dspbridge/cod.h>

/*  ----------------------------------- Others */
#include <dspbridge/uuidutil.h>

/*  ----------------------------------- This */
#include <dspbridge/dbdcd.h>

/*  ----------------------------------- Global defines. */
#define MAX_INT2CHAR_LENGTH     16	/* Max int2char len of 32 bit int */

/* Name of section containing dependent libraries */
#define DEPLIBSECT		".dspbridge_deplibs"

/* DCD specific structures. */
struct dcd_manager {
	struct cod_manager *cod_mgr;	/* Handle to COD manager object. */
};

/*  Pointer to the registry support key */
static struct list_head reg_key_list;
static DEFINE_SPINLOCK(dbdcd_lock);

/* Global reference variables. */
static u32 refs;
static u32 enum_refs;

/* Helper function prototypes. */
static s32 atoi(char *psz_buf);
static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size,
				     enum dsp_dcdobjtype obj_type,
				     struct dcd_genericobj *gen_obj);
static void compress_buf(char *psz_buf, u32 ul_buf_size, s32 char_size);
static char dsp_char2_gpp_char(char *word, s32 dsp_char_size);
static int get_dep_lib_info(struct dcd_manager *hdcd_mgr,
				   struct dsp_uuid *uuid_obj,
				   u16 *num_libs,
				   u16 *num_pers_libs,
				   struct dsp_uuid *dep_lib_uuids,
				   bool *prstnt_dep_libs,
				   enum nldr_phase phase);

/*
 *  ======== dcd_auto_register ========
 *  Purpose:
 *      Parses the supplied image and resigsters with DCD.
 */
int dcd_auto_register(struct dcd_manager *hdcd_mgr,
			     char *sz_coff_path)
{
	int status = 0;

	DBC_REQUIRE(refs > 0);

	if (hdcd_mgr)
		status = dcd_get_objects(hdcd_mgr, sz_coff_path,
					 (dcd_registerfxn) dcd_register_object,
					 (void *)sz_coff_path);
	else
		status = -EFAULT;

	return status;
}

/*
 *  ======== dcd_auto_unregister ========
 *  Purpose:
 *      Parses the supplied DSP image and unresiters from DCD.
 */
int dcd_auto_unregister(struct dcd_manager *hdcd_mgr,
			       char *sz_coff_path)
{
	int status = 0;

	DBC_REQUIRE(refs > 0);

	if (hdcd_mgr)
		status = dcd_get_objects(hdcd_mgr, sz_coff_path,
					 (dcd_registerfxn) dcd_register_object,
					 NULL);
	else
		status = -EFAULT;

	return status;
}

/*
 *  ======== dcd_create_manager ========
 *  Purpose:
 *      Creates DCD manager.
 */
int dcd_create_manager(char *sz_zl_dll_name,
			      struct dcd_manager **dcd_mgr)
{
	struct cod_manager *cod_mgr;	/* COD manager handle */
	struct dcd_manager *dcd_mgr_obj = NULL;	/* DCD Manager pointer */
	int status = 0;

	DBC_REQUIRE(refs >= 0);
	DBC_REQUIRE(dcd_mgr);

	status = cod_create(&cod_mgr, sz_zl_dll_name, NULL);
	if (status)
		goto func_end;

	/* Create a DCD object. */
	dcd_mgr_obj = kzalloc(sizeof(struct dcd_manager), GFP_KERNEL);
	if (dcd_mgr_obj != NULL) {
		/* Fill out the object. */
		dcd_mgr_obj->cod_mgr = cod_mgr;

		/* Return handle to this DCD interface. */
		*dcd_mgr = dcd_mgr_obj;
	} else {
		status = -ENOMEM;

		/*
		 * If allocation of DcdManager object failed, delete the
		 * COD manager.
		 */
		cod_delete(cod_mgr);
	}

	DBC_ENSURE((!status) ||
			((dcd_mgr_obj == NULL) && (status == -ENOMEM)));

func_end:
	return status;
}

/*
 *  ======== dcd_destroy_manager ========
 *  Purpose:
 *      Frees DCD Manager object.
 */
int dcd_destroy_manager(struct dcd_manager *hdcd_mgr)
{
	struct dcd_manager *dcd_mgr_obj = hdcd_mgr;
	int status = -EFAULT;

	DBC_REQUIRE(refs >= 0);

	if (hdcd_mgr) {
		/* Delete the COD manager. */
		cod_delete(dcd_mgr_obj->cod_mgr);

		/* Deallocate a DCD manager object. */
		kfree(dcd_mgr_obj);

		status = 0;
	}

	return status;
}

/*
 *  ======== dcd_enumerate_object ========
 *  Purpose:
 *      Enumerates objects in the DCD.
 */
int dcd_enumerate_object(s32 index, enum dsp_dcdobjtype obj_type,
				struct dsp_uuid *uuid_obj)
{
	int status = 0;
	char sz_reg_key[DCD_MAXPATHLENGTH];
	char sz_value[DCD_MAXPATHLENGTH];
	struct dsp_uuid dsp_uuid_obj;
	char sz_obj_type[MAX_INT2CHAR_LENGTH];	/* str. rep. of obj_type. */
	u32 dw_key_len = 0;
	struct dcd_key_elem *dcd_key;
	int len;

	DBC_REQUIRE(refs >= 0);
	DBC_REQUIRE(index >= 0);
	DBC_REQUIRE(uuid_obj != NULL);

	if ((index != 0) && (enum_refs == 0)) {
		/*
		 * If an enumeration is being performed on an index greater
		 * than zero, then the current enum_refs must have been
		 * incremented to greater than zero.
		 */
		status = -EIDRM;
	} else {
		/*
		 * Pre-determine final key length. It's length of DCD_REGKEY +
		 *  "_\0" + length of sz_obj_type string + terminating NULL.
		 */
		dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1;
		DBC_ASSERT(dw_key_len < DCD_MAXPATHLENGTH);

		/* Create proper REG key; concatenate DCD_REGKEY with
		 * obj_type. */
		strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
		if ((strlen(sz_reg_key) + strlen("_\0")) <
		    DCD_MAXPATHLENGTH) {
			strncat(sz_reg_key, "_\0", 2);
		} else {
			status = -EPERM;
		}

		/* This snprintf is guaranteed not to exceed max size of an
		 * integer. */
		status = snprintf(sz_obj_type, MAX_INT2CHAR_LENGTH, "%d",
				  obj_type);

		if (status == -1) {
			status = -EPERM;
		} else {
			status = 0;
			if ((strlen(sz_reg_key) + strlen(sz_obj_type)) <
			    DCD_MAXPATHLENGTH) {
				strncat(sz_reg_key, sz_obj_type,
					strlen(sz_obj_type) + 1);
			} else {
				status = -EPERM;
			}
		}

		if (!status) {
			len = strlen(sz_reg_key);
			spin_lock(&dbdcd_lock);
			list_for_each_entry(dcd_key, &reg_key_list, link) {
				if (!strncmp(dcd_key->name, sz_reg_key, len)
						&& !index--) {
					strncpy(sz_value, &dcd_key->name[len],
					       strlen(&dcd_key->name[len]) + 1);
						break;
				}
			}
			spin_unlock(&dbdcd_lock);

			if (&dcd_key->link == &reg_key_list)
				status = -ENODATA;
		}

		if (!status) {
			/* Create UUID value using string retrieved from
			 * registry. */
			uuid_uuid_from_string(sz_value, &dsp_uuid_obj);

			*uuid_obj = dsp_uuid_obj;

			/* Increment enum_refs to update reference count. */
			enum_refs++;

			status = 0;
		} else if (status == -ENODATA) {
			/* At the end of enumeration. Reset enum_refs. */
			enum_refs = 0;

			/*
			 * TODO: Revisit, this is not an errror case but code
			 * expects non-zero value.
			 */
			status = ENODATA;
		} else {
			status = -EPERM;
		}
	}

	DBC_ENSURE(uuid_obj || (status == -EPERM));

	return status;
}

/*
 *  ======== dcd_exit ========
 *  Purpose:
 *      Discontinue usage of the DCD module.
 */
void dcd_exit(void)
{
	struct dcd_key_elem *rv, *rv_tmp;
	DBC_REQUIRE(refs > 0);

	refs--;
	if (refs == 0) {
		cod_exit();
		list_for_each_entry_safe(rv, rv_tmp, &reg_key_list, link) {
			list_del(&rv->link);
			kfree(rv->path);
			kfree(rv);
		}
	}

	DBC_ENSURE(refs >= 0);
}

/*
 *  ======== dcd_get_dep_libs ========
 */
int dcd_get_dep_libs(struct dcd_manager *hdcd_mgr,
			    struct dsp_uuid *uuid_obj,
			    u16 num_libs, struct dsp_uuid *dep_lib_uuids,
			    bool *prstnt_dep_libs,
			    enum nldr_phase phase)
{
	int status = 0;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(hdcd_mgr);
	DBC_REQUIRE(uuid_obj != NULL);
	DBC_REQUIRE(dep_lib_uuids != NULL);
	DBC_REQUIRE(prstnt_dep_libs != NULL);

	status =
	    get_dep_lib_info(hdcd_mgr, uuid_obj, &num_libs, NULL, dep_lib_uuids,
			     prstnt_dep_libs, phase);

	return status;
}

/*
 *  ======== dcd_get_num_dep_libs ========
 */
int dcd_get_num_dep_libs(struct dcd_manager *hdcd_mgr,
				struct dsp_uuid *uuid_obj,
				u16 *num_libs, u16 *num_pers_libs,
				enum nldr_phase phase)
{
	int status = 0;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(hdcd_mgr);
	DBC_REQUIRE(num_libs != NULL);
	DBC_REQUIRE(num_pers_libs != NULL);
	DBC_REQUIRE(uuid_obj != NULL);

	status = get_dep_lib_info(hdcd_mgr, uuid_obj, num_libs, num_pers_libs,
				  NULL, NULL, phase);

	return status;
}

/*
 *  ======== dcd_get_object_def ========
 *  Purpose:
 *      Retrieves the properties of a node or processor based on the UUID and
 *      object type.
 */
int dcd_get_object_def(struct dcd_manager *hdcd_mgr,
			      struct dsp_uuid *obj_uuid,
			      enum dsp_dcdobjtype obj_type,
			      struct dcd_genericobj *obj_def)
{
	struct dcd_manager *dcd_mgr_obj = hdcd_mgr;	/* ptr to DCD mgr */
	struct cod_libraryobj *lib = NULL;
	int status = 0;
	u32 ul_addr = 0;	/* Used by cod_get_section */
	u32 ul_len = 0;		/* Used by cod_get_section */
	u32 dw_buf_size;	/* Used by REG functions */
	char sz_reg_key[DCD_MAXPATHLENGTH];
	char *sz_uuid;		/*[MAXUUIDLEN]; */
	struct dcd_key_elem *dcd_key = NULL;
	char sz_sect_name[MAXUUIDLEN + 2];	/* ".[UUID]\0" */
	char *psz_coff_buf;
	u32 dw_key_len;		/* Len of REG key. */
	char sz_obj_type[MAX_INT2CHAR_LENGTH];	/* str. rep. of obj_type. */

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(obj_def != NULL);
	DBC_REQUIRE(obj_uuid != NULL);

	sz_uuid = kzalloc(MAXUUIDLEN, GFP_KERNEL);
	if (!sz_uuid) {
		status = -ENOMEM;
		goto func_end;
	}

	if (!hdcd_mgr) {
		status = -EFAULT;
		goto func_end;
	}

	/* Pre-determine final key length. It's length of DCD_REGKEY +
	 *  "_\0" + length of sz_obj_type string + terminating NULL */
	dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1;
	DBC_ASSERT(dw_key_len < DCD_MAXPATHLENGTH);

	/* Create proper REG key; concatenate DCD_REGKEY with obj_type. */
	strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);

	if ((strlen(sz_reg_key) + strlen("_\0")) < DCD_MAXPATHLENGTH)
		strncat(sz_reg_key, "_\0", 2);
	else
		status = -EPERM;

	status = snprintf(sz_obj_type, MAX_INT2CHAR_LENGTH, "%d", obj_type);
	if (status == -1) {
		status = -EPERM;
	} else {
		status = 0;

		if ((strlen(sz_reg_key) + strlen(sz_obj_type)) <
		    DCD_MAXPATHLENGTH) {
			strncat(sz_reg_key, sz_obj_type,
				strlen(sz_obj_type) + 1);
		} else {
			status = -EPERM;
		}

		/* Create UUID value to set in registry. */
		uuid_uuid_to_string(obj_uuid, sz_uuid, MAXUUIDLEN);

		if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH)
			strncat(sz_reg_key, sz_uuid, MAXUUIDLEN);
		else
			status = -EPERM;

		/* Retrieve paths from the registry based on struct dsp_uuid */
		dw_buf_size = DCD_MAXPATHLENGTH;
	}
	if (!status) {
		spin_lock(&dbdcd_lock);
		list_for_each_entry(dcd_key, &reg_key_list, link) {
			if (!strncmp(dcd_key->name, sz_reg_key,
						strlen(sz_reg_key) + 1))
				break;
		}
		spin_unlock(&dbdcd_lock);
		if (&dcd_key->link == &reg_key_list) {
			status = -ENOKEY;
			goto func_end;
		}
	}


	/* Open COFF file. */
	status = cod_open(dcd_mgr_obj->cod_mgr, dcd_key->path,
							COD_NOLOAD, &lib);
	if (status) {
		status = -EACCES;
		goto func_end;
	}

	/* Ensure sz_uuid + 1 is not greater than sizeof sz_sect_name. */
	DBC_ASSERT((strlen(sz_uuid) + 1) < sizeof(sz_sect_name));

	/* Create section name based on node UUID. A period is
	 * pre-pended to the UUID string to form the section name.
	 * I.e. ".24BC8D90_BB45_11d4_B756_006008BDB66F" */
	strncpy(sz_sect_name, ".", 2);
	strncat(sz_sect_name, sz_uuid, strlen(sz_uuid));

	/* Get section information. */
	status = cod_get_section(lib, sz_sect_name, &ul_addr, &ul_len);
	if (status) {
		status = -EACCES;
		goto func_end;
	}

	/* Allocate zeroed buffer. */
	psz_coff_buf = kzalloc(ul_len + 4, GFP_KERNEL);
	if (psz_coff_buf == NULL) {
		status = -ENOMEM;
		goto func_end;
	}
#ifdef _DB_TIOMAP
	if (strstr(dcd_key->path, "iva") == NULL) {
		/* Locate section by objectID and read its content. */
		status =
		    cod_read_section(lib, sz_sect_name, psz_coff_buf, ul_len);
	} else {
		status =
		    cod_read_section(lib, sz_sect_name, psz_coff_buf, ul_len);
		dev_dbg(bridge, "%s: Skipped Byte swap for IVA!!\n", __func__);
	}
#else
	status = cod_read_section(lib, sz_sect_name, psz_coff_buf, ul_len);
#endif
	if (!status) {
		/* Compres DSP buffer to conform to PC format. */
		if (strstr(dcd_key->path, "iva") == NULL) {
			compress_buf(psz_coff_buf, ul_len, DSPWORDSIZE);
		} else {
			compress_buf(psz_coff_buf, ul_len, 1);
			dev_dbg(bridge, "%s: Compressing IVA COFF buffer by 1 "
				"for IVA!!\n", __func__);
		}

		/* Parse the content of the COFF buffer. */
		status =
		    get_attrs_from_buf(psz_coff_buf, ul_len, obj_type, obj_def);
		if (status)
			status = -EACCES;
	} else {
		status = -EACCES;
	}

	/* Free the previously allocated dynamic buffer. */
	kfree(psz_coff_buf);
func_end:
	if (lib)
		cod_close(lib);

	kfree(sz_uuid);

	return status;
}

/*
 *  ======== dcd_get_objects ========
 */
int dcd_get_objects(struct dcd_manager *hdcd_mgr,
			   char *sz_coff_path, dcd_registerfxn register_fxn,
			   void *handle)
{
	struct dcd_manager *dcd_mgr_obj = hdcd_mgr;
	int status = 0;
	char *psz_coff_buf;
	char *psz_cur;
	struct cod_libraryobj *lib = NULL;
	u32 ul_addr = 0;	/* Used by cod_get_section */
	u32 ul_len = 0;		/* Used by cod_get_section */
	char seps[] = ":, ";
	char *token = NULL;
	struct dsp_uuid dsp_uuid_obj;
	s32 object_type;

	DBC_REQUIRE(refs > 0);
	if (!hdcd_mgr) {
		status = -EFAULT;
		goto func_end;
	}

	/* Open DSP coff file, don't load symbols. */
	status = cod_open(dcd_mgr_obj->cod_mgr, sz_coff_path, COD_NOLOAD, &lib);
	if (status) {
		status = -EACCES;
		goto func_cont;
	}

	/* Get DCD_RESIGER_SECTION section information. */
	status = cod_get_section(lib, DCD_REGISTER_SECTION, &ul_addr, &ul_len);
	if (status || !(ul_len > 0)) {
		status = -EACCES;
		goto func_cont;
	}

	/* Allocate zeroed buffer. */
	psz_coff_buf = kzalloc(ul_len + 4, GFP_KERNEL);
	if (psz_coff_buf == NULL) {
		status = -ENOMEM;
		goto func_cont;
	}
#ifdef _DB_TIOMAP
	if (strstr(sz_coff_path, "iva") == NULL) {
		/* Locate section by objectID and read its content. */
		status = cod_read_section(lib, DCD_REGISTER_SECTION,
					  psz_coff_buf, ul_len);
	} else {
		dev_dbg(bridge, "%s: Skipped Byte swap for IVA!!\n", __func__);
		status = cod_read_section(lib, DCD_REGISTER_SECTION,
					  psz_coff_buf, ul_len);
	}
#else
	status =
	    cod_read_section(lib, DCD_REGISTER_SECTION, psz_coff_buf, ul_len);
#endif
	if (!status) {
		/* Compress DSP buffer to conform to PC format. */
		if (strstr(sz_coff_path, "iva") == NULL) {
			compress_buf(psz_coff_buf, ul_len, DSPWORDSIZE);
		} else {
			compress_buf(psz_coff_buf, ul_len, 1);
			dev_dbg(bridge, "%s: Compress COFF buffer with 1 word "
				"for IVA!!\n", __func__);
		}

		/* Read from buffer and register object in buffer. */
		psz_cur = psz_coff_buf;
		while ((token = strsep(&psz_cur, seps)) && *token != '\0') {
			/*  Retrieve UUID string. */
			uuid_uuid_from_string(token, &dsp_uuid_obj);

			/*  Retrieve object type */
			token = strsep(&psz_cur, seps);

			/*  Retrieve object type */
			object_type = atoi(token);

			/*
			 *  Apply register_fxn to the found DCD object.
			 *  Possible actions include:
			 *
			 *  1) Register found DCD object.
			 *  2) Unregister found DCD object (when handle == NULL)
			 *  3) Add overlay node.
			 */
			status =
			    register_fxn(&dsp_uuid_obj, object_type, handle);
			if (status) {
				/* if error occurs, break from while loop. */
				break;
			}
		}
	} else {
		status = -EACCES;
	}

	/* Free the previously allocated dynamic buffer. */
	kfree(psz_coff_buf);
func_cont:
	if (lib)
		cod_close(lib);

func_end:
	return status;
}

/*
 *  ======== dcd_get_library_name ========
 *  Purpose:
 *      Retrieves the library name for the given UUID.
 *
 */
int dcd_get_library_name(struct dcd_manager *hdcd_mgr,
				struct dsp_uuid *uuid_obj,
				char *str_lib_name,
				u32 *buff_size,
				enum nldr_phase phase, bool *phase_split)
{
	char sz_reg_key[DCD_MAXPATHLENGTH];
	char sz_uuid[MAXUUIDLEN];
	u32 dw_key_len;		/* Len of REG key. */
	char sz_obj_type[MAX_INT2CHAR_LENGTH];	/* str. rep. of obj_type. */
	int status = 0;
	struct dcd_key_elem *dcd_key = NULL;

	DBC_REQUIRE(uuid_obj != NULL);
	DBC_REQUIRE(str_lib_name != NULL);
	DBC_REQUIRE(buff_size != NULL);
	DBC_REQUIRE(hdcd_mgr);

	dev_dbg(bridge, "%s: hdcd_mgr %p, uuid_obj %p, str_lib_name %p,"
		" buff_size %p\n", __func__, hdcd_mgr, uuid_obj, str_lib_name,
		buff_size);

	/*
	 *  Pre-determine final key length. It's length of DCD_REGKEY +
	 *  "_\0" + length of sz_obj_type string + terminating NULL.
	 */
	dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1;
	DBC_ASSERT(dw_key_len < DCD_MAXPATHLENGTH);

	/* Create proper REG key; concatenate DCD_REGKEY with obj_type. */
	strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
	if ((strlen(sz_reg_key) + strlen("_\0")) < DCD_MAXPATHLENGTH)
		strncat(sz_reg_key, "_\0", 2);
	else
		status = -EPERM;

	switch (phase) {
	case NLDR_CREATE:
		/* create phase type */
		sprintf(sz_obj_type, "%d", DSP_DCDCREATELIBTYPE);
		break;
	case NLDR_EXECUTE:
		/* execute phase type */
		sprintf(sz_obj_type, "%d", DSP_DCDEXECUTELIBTYPE);
		break;
	case NLDR_DELETE:
		/* delete phase type */
		sprintf(sz_obj_type, "%d", DSP_DCDDELETELIBTYPE);
		break;
	case NLDR_NOPHASE:
		/* known to be a dependent library */
		sprintf(sz_obj_type, "%d", DSP_DCDLIBRARYTYPE);
		break;
	default:
		status = -EINVAL;
		DBC_ASSERT(false);
	}
	if (!status) {
		if ((strlen(sz_reg_key) + strlen(sz_obj_type)) <
		    DCD_MAXPATHLENGTH) {
			strncat(sz_reg_key, sz_obj_type,
				strlen(sz_obj_type) + 1);
		} else {
			status = -EPERM;
		}
		/* Create UUID value to find match in registry. */
		uuid_uuid_to_string(uuid_obj, sz_uuid, MAXUUIDLEN);
		if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH)
			strncat(sz_reg_key, sz_uuid, MAXUUIDLEN);
		else
			status = -EPERM;
	}
	if (!status) {
		spin_lock(&dbdcd_lock);
		list_for_each_entry(dcd_key, &reg_key_list, link) {
			/*  See if the name matches. */
			if (!strncmp(dcd_key->name, sz_reg_key,
						strlen(sz_reg_key) + 1))
				break;
		}
		spin_unlock(&dbdcd_lock);
	}

	if (&dcd_key->link == &reg_key_list)
		status = -ENOKEY;

	/* If can't find, phases might be registered as generic LIBRARYTYPE */
	if (status && phase != NLDR_NOPHASE) {
		if (phase_split)
			*phase_split = false;

		strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
		if ((strlen(sz_reg_key) + strlen("_\0")) <
		    DCD_MAXPATHLENGTH) {
			strncat(sz_reg_key, "_\0", 2);
		} else {
			status = -EPERM;
		}
		sprintf(sz_obj_type, "%d", DSP_DCDLIBRARYTYPE);
		if ((strlen(sz_reg_key) + strlen(sz_obj_type))
		    < DCD_MAXPATHLENGTH) {
			strncat(sz_reg_key, sz_obj_type,
				strlen(sz_obj_type) + 1);
		} else {
			status = -EPERM;
		}
		uuid_uuid_to_string(uuid_obj, sz_uuid, MAXUUIDLEN);
		if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH)
			strncat(sz_reg_key, sz_uuid, MAXUUIDLEN);
		else
			status = -EPERM;

		spin_lock(&dbdcd_lock);
		list_for_each_entry(dcd_key, &reg_key_list, link) {
			/*  See if the name matches. */
			if (!strncmp(dcd_key->name, sz_reg_key,
						strlen(sz_reg_key) + 1))
				break;
		}
		spin_unlock(&dbdcd_lock);

		status = (&dcd_key->link != &reg_key_list) ?
						0 : -ENOKEY;
	}

	if (!status)
		memcpy(str_lib_name, dcd_key->path, strlen(dcd_key->path) + 1);
	return status;
}

/*
 *  ======== dcd_init ========
 *  Purpose:
 *      Initialize the DCD module.
 */
bool dcd_init(void)
{
	bool init_cod;
	bool ret = true;

	DBC_REQUIRE(refs >= 0);

	if (refs == 0) {
		/* Initialize required modules. */
		init_cod = cod_init();

		if (!init_cod) {
			ret = false;
			/* Exit initialized modules. */
			if (init_cod)
				cod_exit();
		}

		INIT_LIST_HEAD(&reg_key_list);
	}

	if (ret)
		refs++;

	DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs == 0)));

	return ret;
}

/*
 *  ======== dcd_register_object ========
 *  Purpose:
 *      Registers a node or a processor with the DCD.
 *      If psz_path_name == NULL, unregister the specified DCD object.
 */
int dcd_register_object(struct dsp_uuid *uuid_obj,
			       enum dsp_dcdobjtype obj_type,
			       char *psz_path_name)
{
	int status = 0;
	char sz_reg_key[DCD_MAXPATHLENGTH];
	char sz_uuid[MAXUUIDLEN + 1];
	u32 dw_path_size = 0;
	u32 dw_key_len;		/* Len of REG key. */
	char sz_obj_type[MAX_INT2CHAR_LENGTH];	/* str. rep. of obj_type. */
	struct dcd_key_elem *dcd_key = NULL;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(uuid_obj != NULL);
	DBC_REQUIRE((obj_type == DSP_DCDNODETYPE) ||
		    (obj_type == DSP_DCDPROCESSORTYPE) ||
		    (obj_type == DSP_DCDLIBRARYTYPE) ||
		    (obj_type == DSP_DCDCREATELIBTYPE) ||
		    (obj_type == DSP_DCDEXECUTELIBTYPE) ||
		    (obj_type == DSP_DCDDELETELIBTYPE));

	dev_dbg(bridge, "%s: object UUID %p, obj_type %d, szPathName %s\n",
		__func__, uuid_obj, obj_type, psz_path_name);

	/*
	 * Pre-determine final key length. It's length of DCD_REGKEY +
	 *  "_\0" + length of sz_obj_type string + terminating NULL.
	 */
	dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1;
	DBC_ASSERT(dw_key_len < DCD_MAXPATHLENGTH);

	/* Create proper REG key; concatenate DCD_REGKEY with obj_type. */
	strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
	if ((strlen(sz_reg_key) + strlen("_\0")) < DCD_MAXPATHLENGTH)
		strncat(sz_reg_key, "_\0", 2);
	else {
		status = -EPERM;
		goto func_end;
	}

	status = snprintf(sz_obj_type, MAX_INT2CHAR_LENGTH, "%d", obj_type);
	if (status == -1) {
		status = -EPERM;
	} else {
		status = 0;
		if ((strlen(sz_reg_key) + strlen(sz_obj_type)) <
		    DCD_MAXPATHLENGTH) {
			strncat(sz_reg_key, sz_obj_type,
				strlen(sz_obj_type) + 1);
		} else
			status = -EPERM;

		/* Create UUID value to set in registry. */
		uuid_uuid_to_string(uuid_obj, sz_uuid, MAXUUIDLEN);
		if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH)
			strncat(sz_reg_key, sz_uuid, MAXUUIDLEN);
		else
			status = -EPERM;
	}

	if (status)
		goto func_end;

	/*
	 * If psz_path_name != NULL, perform registration, otherwise,
	 * perform unregistration.
	 */

	if (psz_path_name) {
		dw_path_size = strlen(psz_path_name) + 1;
		spin_lock(&dbdcd_lock);
		list_for_each_entry(dcd_key, &reg_key_list, link) {
			/*  See if the name matches. */
			if (!strncmp(dcd_key->name, sz_reg_key,
						strlen(sz_reg_key) + 1))
				break;
		}
		spin_unlock(&dbdcd_lock);
		if (&dcd_key->link == &reg_key_list) {
			/*
			 * Add new reg value (UUID+obj_type)
			 * with COFF path info
			 */

			dcd_key = kmalloc(sizeof(struct dcd_key_elem),
								GFP_KERNEL);
			if (!dcd_key) {
				status = -ENOMEM;
				goto func_end;
			}

			dcd_key->path = kmalloc(strlen(sz_reg_key) + 1,
								GFP_KERNEL);

			if (!dcd_key->path) {
				kfree(dcd_key);
				status = -ENOMEM;
				goto func_end;
			}

			strncpy(dcd_key->name, sz_reg_key,
						strlen(sz_reg_key) + 1);
			strncpy(dcd_key->path, psz_path_name ,
						dw_path_size);
			spin_lock(&dbdcd_lock);
			list_add_tail(&dcd_key->link, &reg_key_list);
			spin_unlock(&dbdcd_lock);
		} else {
			/*  Make sure the new data is the same. */
			if (strncmp(dcd_key->path, psz_path_name,
							dw_path_size)) {
				/*  The caller needs a different data size! */
				kfree(dcd_key->path);
				dcd_key->path = kmalloc(dw_path_size,
								GFP_KERNEL);
				if (dcd_key->path == NULL) {
					status = -ENOMEM;
					goto func_end;
				}
			}

			/*  We have a match!  Copy out the data. */
			memcpy(dcd_key->path, psz_path_name, dw_path_size);
		}
		dev_dbg(bridge, "%s: psz_path_name=%s, dw_path_size=%d\n",
			__func__, psz_path_name, dw_path_size);
	} else {
		/* Deregister an existing object */
		spin_lock(&dbdcd_lock);
		list_for_each_entry(dcd_key, &reg_key_list, link) {
			if (!strncmp(dcd_key->name, sz_reg_key,
						strlen(sz_reg_key) + 1)) {
				list_del(&dcd_key->link);
				kfree(dcd_key->path);
				kfree(dcd_key);
				break;
			}
		}
		spin_unlock(&dbdcd_lock);
		if (&dcd_key->link == &reg_key_list)
			status = -EPERM;
	}

	if (!status) {
		/*
		 *  Because the node database has been updated through a
		 *  successful object registration/de-registration operation,
		 *  we need to reset the object enumeration counter to allow
		 *  current enumerations to reflect this update in the node
		 *  database.
		 */
		enum_refs = 0;
	}
func_end:
	return status;
}

/*
 *  ======== dcd_unregister_object ========
 *  Call DCD_Register object with psz_path_name set to NULL to
 *  perform actual object de-registration.
 */
int dcd_unregister_object(struct dsp_uuid *uuid_obj,
				 enum dsp_dcdobjtype obj_type)
{
	int status = 0;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(uuid_obj != NULL);
	DBC_REQUIRE((obj_type == DSP_DCDNODETYPE) ||
		    (obj_type == DSP_DCDPROCESSORTYPE) ||
		    (obj_type == DSP_DCDLIBRARYTYPE) ||
		    (obj_type == DSP_DCDCREATELIBTYPE) ||
		    (obj_type == DSP_DCDEXECUTELIBTYPE) ||
		    (obj_type == DSP_DCDDELETELIBTYPE));

	/*
	 *  When dcd_register_object is called with NULL as pathname,
	 *  it indicates an unregister object operation.
	 */
	status = dcd_register_object(uuid_obj, obj_type, NULL);

	return status;
}

/*
 **********************************************************************
 * DCD Helper Functions
 **********************************************************************
 */

/*
 *  ======== atoi ========
 *  Purpose:
 *      This function converts strings in decimal or hex format to integers.
 */
static s32 atoi(char *psz_buf)
{
	char *pch = psz_buf;
	s32 base = 0;
	unsigned long res;
	int ret_val;

	while (isspace(*pch))
		pch++;

	if (*pch == '-' || *pch == '+') {
		base = 10;
		pch++;
	} else if (*pch && tolower(pch[strlen(pch) - 1]) == 'h') {
		base = 16;
	}

	ret_val = strict_strtoul(pch, base, &res);

	return ret_val ? : res;
}

/*
 *  ======== get_attrs_from_buf ========
 *  Purpose:
 *      Parse the content of a buffer filled with DSP-side data and
 *      retrieve an object's attributes from it. IMPORTANT: Assume the
 *      buffer has been converted from DSP format to GPP format.
 */
static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size,
				     enum dsp_dcdobjtype obj_type,
				     struct dcd_genericobj *gen_obj)
{
	int status = 0;
	char seps[] = ", ";
	char *psz_cur;
	char *token;
	s32 token_len = 0;
	u32 i = 0;
#ifdef _DB_TIOMAP
	s32 entry_id;
#endif

	DBC_REQUIRE(psz_buf != NULL);
	DBC_REQUIRE(ul_buf_size != 0);
	DBC_REQUIRE((obj_type == DSP_DCDNODETYPE)
		    || (obj_type == DSP_DCDPROCESSORTYPE));
	DBC_REQUIRE(gen_obj != NULL);

	switch (obj_type) {
	case DSP_DCDNODETYPE:
		/*
		 * Parse COFF sect buffer to retrieve individual tokens used
		 * to fill in object attrs.
		 */
		psz_cur = psz_buf;
		token = strsep(&psz_cur, seps);

		/* u32 cb_struct */
		gen_obj->obj_data.node_obj.ndb_props.cb_struct =
		    (u32) atoi(token);
		token = strsep(&psz_cur, seps);

		/* dsp_uuid ui_node_id */
		uuid_uuid_from_string(token,
				      &gen_obj->obj_data.node_obj.ndb_props.
				      ui_node_id);
		token = strsep(&psz_cur, seps);

		/* ac_name */
		DBC_REQUIRE(token);
		token_len = strlen(token);
		if (token_len > DSP_MAXNAMELEN - 1)
			token_len = DSP_MAXNAMELEN - 1;

		strncpy(gen_obj->obj_data.node_obj.ndb_props.ac_name,
			token, token_len);
		gen_obj->obj_data.node_obj.ndb_props.ac_name[token_len] = '\0';
		token = strsep(&psz_cur, seps);
		/* u32 ntype */
		gen_obj->obj_data.node_obj.ndb_props.ntype = atoi(token);
		token = strsep(&psz_cur, seps);
		/* u32 cache_on_gpp */
		gen_obj->obj_data.node_obj.ndb_props.cache_on_gpp = atoi(token);
		token = strsep(&psz_cur, seps);
		/* dsp_resourcereqmts dsp_resource_reqmts */
		gen_obj->obj_data.node_obj.ndb_props.dsp_resource_reqmts.
		    cb_struct = (u32) atoi(token);
		token = strsep(&psz_cur, seps);

		gen_obj->obj_data.node_obj.ndb_props.
		    dsp_resource_reqmts.static_data_size = atoi(token);
		token = strsep(&psz_cur, seps);
		gen_obj->obj_data.node_obj.ndb_props.
		    dsp_resource_reqmts.global_data_size = atoi(token);
		token = strsep(&psz_cur, seps);
		gen_obj->obj_data.node_obj.ndb_props.
		    dsp_resource_reqmts.program_mem_size = atoi(token);
		token = strsep(&psz_cur, seps);
		gen_obj->obj_data.node_obj.ndb_props.
		    dsp_resource_reqmts.uwc_execution_time = atoi(token);
		token = strsep(&psz_cur, seps);
		gen_obj->obj_data.node_obj.ndb_props.
		    dsp_resource_reqmts.uwc_period = atoi(token);
		token = strsep(&psz_cur, seps);

		gen_obj->obj_data.node_obj.ndb_props.
		    dsp_resource_reqmts.uwc_deadline = atoi(token);
		token = strsep(&psz_cur, seps);

		gen_obj->obj_data.node_obj.ndb_props.
		    dsp_resource_reqmts.avg_exection_time = atoi(token);
		token = strsep(&psz_cur, seps);

		gen_obj->obj_data.node_obj.ndb_props.
		    dsp_resource_reqmts.minimum_period = atoi(token);
		token = strsep(&psz_cur, seps);

		/* s32 prio */
		gen_obj->obj_data.node_obj.ndb_props.prio = atoi(token);
		token = strsep(&psz_cur, seps);

		/* u32 stack_size */
		gen_obj->obj_data.node_obj.ndb_props.stack_size = atoi(token);
		token = strsep(&psz_cur, seps);

		/* u32 sys_stack_size */
		gen_obj->obj_data.node_obj.ndb_props.sys_stack_size =
		    atoi(token);
		token = strsep(&psz_cur, seps);

		/* u32 stack_seg */
		gen_obj->obj_data.node_obj.ndb_props.stack_seg = atoi(token);
		token = strsep(&psz_cur, seps);

		/* u32 message_depth */
		gen_obj->obj_data.node_obj.ndb_props.message_depth =
		    atoi(token);
		token = strsep(&psz_cur, seps);

		/* u32 num_input_streams */
		gen_obj->obj_data.node_obj.ndb_props.num_input_streams =
		    atoi(token);
		token = strsep(&psz_cur, seps);

		/* u32 num_output_streams */
		gen_obj->obj_data.node_obj.ndb_props.num_output_streams =
		    atoi(token);
		token = strsep(&psz_cur, seps);

		/* u32 utimeout */
		gen_obj->obj_data.node_obj.ndb_props.utimeout = atoi(token);
		token = strsep(&psz_cur, seps);

		/* char *pstr_create_phase_fxn */
		DBC_REQUIRE(token);
		token_len = strlen(token);
		gen_obj->obj_data.node_obj.pstr_create_phase_fxn =
					kzalloc(token_len + 1, GFP_KERNEL);
		strncpy(gen_obj->obj_data.node_obj.pstr_create_phase_fxn,
			token, token_len);
		gen_obj->obj_data.node_obj.pstr_create_phase_fxn[token_len] =
		    '\0';
		token = strsep(&psz_cur, seps);

		/* char *pstr_execute_phase_fxn */
		DBC_REQUIRE(token);
		token_len = strlen(token);
		gen_obj->obj_data.node_obj.pstr_execute_phase_fxn =
					kzalloc(token_len + 1, GFP_KERNEL);
		strncpy(gen_obj->obj_data.node_obj.pstr_execute_phase_fxn,
			token, token_len);
		gen_obj->obj_data.node_obj.pstr_execute_phase_fxn[token_len] =
		    '\0';
		token = strsep(&psz_cur, seps);

		/* char *pstr_delete_phase_fxn */
		DBC_REQUIRE(token);
		token_len = strlen(token);
		gen_obj->obj_data.node_obj.pstr_delete_phase_fxn =
					kzalloc(token_len + 1, GFP_KERNEL);
		strncpy(gen_obj->obj_data.node_obj.pstr_delete_phase_fxn,
			token, token_len);
		gen_obj->obj_data.node_obj.pstr_delete_phase_fxn[token_len] =
		    '\0';
		token = strsep(&psz_cur, seps);

		/* Segment id for message buffers */
		gen_obj->obj_data.node_obj.msg_segid = atoi(token);
		token = strsep(&psz_cur, seps);

		/* Message notification type */
		gen_obj->obj_data.node_obj.msg_notify_type = atoi(token);
		token = strsep(&psz_cur, seps);

		/* char *pstr_i_alg_name */
		if (token) {
			token_len = strlen(token);
			gen_obj->obj_data.node_obj.pstr_i_alg_name =
					kzalloc(token_len + 1, GFP_KERNEL);
			strncpy(gen_obj->obj_data.node_obj.pstr_i_alg_name,
				token, token_len);
			gen_obj->obj_data.node_obj.pstr_i_alg_name[token_len] =
			    '\0';
			token = strsep(&psz_cur, seps);
		}

		/* Load type (static, dynamic, or overlay) */
		if (token) {
			gen_obj->obj_data.node_obj.us_load_type = atoi(token);
			token = strsep(&psz_cur, seps);
		}

		/* Dynamic load data requirements */
		if (token) {
			gen_obj->obj_data.node_obj.ul_data_mem_seg_mask =
			    atoi(token);
			token = strsep(&psz_cur, seps);
		}

		/* Dynamic load code requirements */
		if (token) {
			gen_obj->obj_data.node_obj.ul_code_mem_seg_mask =
			    atoi(token);
			token = strsep(&psz_cur, seps);
		}

		/* Extract node profiles into node properties */
		if (token) {

			gen_obj->obj_data.node_obj.ndb_props.count_profiles =
			    atoi(token);
			for (i = 0;
			     i <
			     gen_obj->obj_data.node_obj.
			     ndb_props.count_profiles; i++) {
				token = strsep(&psz_cur, seps);
				if (token) {
					/* Heap Size for the node */
					gen_obj->obj_data.node_obj.
					    ndb_props.node_profiles[i].
					    ul_heap_size = atoi(token);
				}
			}
		}
		token = strsep(&psz_cur, seps);
		if (token) {
			gen_obj->obj_data.node_obj.ndb_props.stack_seg_name =
			    (u32) (token);
		}

		break;

	case DSP_DCDPROCESSORTYPE:
		/*
		 * Parse COFF sect buffer to retrieve individual tokens used
		 * to fill in object attrs.
		 */
		psz_cur = psz_buf;
		token = strsep(&psz_cur, seps);

		gen_obj->obj_data.proc_info.cb_struct = atoi(token);
		token = strsep(&psz_cur, seps);

		gen_obj->obj_data.proc_info.processor_family = atoi(token);
		token = strsep(&psz_cur, seps);

		gen_obj->obj_data.proc_info.processor_type = atoi(token);
		token = strsep(&psz_cur, seps);

		gen_obj->obj_data.proc_info.clock_rate = atoi(token);
		token = strsep(&psz_cur, seps);

		gen_obj->obj_data.proc_info.ul_internal_mem_size = atoi(token);
		token = strsep(&psz_cur, seps);

		gen_obj->obj_data.proc_info.ul_external_mem_size = atoi(token);
		token = strsep(&psz_cur, seps);

		gen_obj->obj_data.proc_info.processor_id = atoi(token);
		token = strsep(&psz_cur, seps);

		gen_obj->obj_data.proc_info.ty_running_rtos = atoi(token);
		token = strsep(&psz_cur, seps);

		gen_obj->obj_data.proc_info.node_min_priority = atoi(token);
		token = strsep(&psz_cur, seps);

		gen_obj->obj_data.proc_info.node_max_priority = atoi(token);

#ifdef _DB_TIOMAP
		/* Proc object may contain additional(extended) attributes. */
		/* attr must match proc.hxx */
		for (entry_id = 0; entry_id < 7; entry_id++) {
			token = strsep(&psz_cur, seps);
			gen_obj->obj_data.ext_proc_obj.ty_tlb[entry_id].
			    ul_gpp_phys = atoi(token);

			token = strsep(&psz_cur, seps);
			gen_obj->obj_data.ext_proc_obj.ty_tlb[entry_id].
			    ul_dsp_virt = atoi(token);
		}
#endif

		break;

	default:
		status = -EPERM;
		break;
	}

	return status;
}

/*
 *  ======== CompressBuffer ========
 *  Purpose:
 *      Compress the DSP buffer, if necessary, to conform to PC format.
 */
static void compress_buf(char *psz_buf, u32 ul_buf_size, s32 char_size)
{
	char *p;
	char ch;
	char *q;

	p = psz_buf;
	if (p == NULL)
		return;

	for (q = psz_buf; q < (psz_buf + ul_buf_size);) {
		ch = dsp_char2_gpp_char(q, char_size);
		if (ch == '\\') {
			q += char_size;
			ch = dsp_char2_gpp_char(q, char_size);
			switch (ch) {
			case 't':
				*p = '\t';
				break;

			case 'n':
				*p = '\n';
				break;

			case 'r':
				*p = '\r';
				break;

			case '0':
				*p = '\0';
				break;

			default:
				*p = ch;
				break;
			}
		} else {
			*p = ch;
		}
		p++;
		q += char_size;
	}

	/* NULL out remainder of buffer. */
	while (p < q)
		*p++ = '\0';
}

/*
 *  ======== dsp_char2_gpp_char ========
 *  Purpose:
 *      Convert DSP char to host GPP char in a portable manner
 */
static char dsp_char2_gpp_char(char *word, s32 dsp_char_size)
{
	char ch = '\0';
	char *ch_src;
	s32 i;

	for (ch_src = word, i = dsp_char_size; i > 0; i--)
		ch |= *ch_src++;

	return ch;
}

/*
 *  ======== get_dep_lib_info ========
 */
static int get_dep_lib_info(struct dcd_manager *hdcd_mgr,
				   struct dsp_uuid *uuid_obj,
				   u16 *num_libs,
				   u16 *num_pers_libs,
				   struct dsp_uuid *dep_lib_uuids,
				   bool *prstnt_dep_libs,
				   enum nldr_phase phase)
{
	struct dcd_manager *dcd_mgr_obj = hdcd_mgr;
	char *psz_coff_buf = NULL;
	char *psz_cur;
	char *psz_file_name = NULL;
	struct cod_libraryobj *lib = NULL;
	u32 ul_addr = 0;	/* Used by cod_get_section */
	u32 ul_len = 0;		/* Used by cod_get_section */
	u32 dw_data_size = COD_MAXPATHLENGTH;
	char seps[] = ", ";
	char *token = NULL;
	bool get_uuids = (dep_lib_uuids != NULL);
	u16 dep_libs = 0;
	int status = 0;

	DBC_REQUIRE(refs > 0);

	DBC_REQUIRE(hdcd_mgr);
	DBC_REQUIRE(num_libs != NULL);
	DBC_REQUIRE(uuid_obj != NULL);

	/*  Initialize to 0 dependent libraries, if only counting number of
	 *  dependent libraries */
	if (!get_uuids) {
		*num_libs = 0;
		*num_pers_libs = 0;
	}

	/* Allocate a buffer for file name */
	psz_file_name = kzalloc(dw_data_size, GFP_KERNEL);
	if (psz_file_name == NULL) {
		status = -ENOMEM;
	} else {
		/* Get the name of the library */
		status = dcd_get_library_name(hdcd_mgr, uuid_obj, psz_file_name,
					      &dw_data_size, phase, NULL);
	}

	/* Open the library */
	if (!status) {
		status = cod_open(dcd_mgr_obj->cod_mgr, psz_file_name,
				  COD_NOLOAD, &lib);
	}
	if (!status) {
		/* Get dependent library section information. */
		status = cod_get_section(lib, DEPLIBSECT, &ul_addr, &ul_len);

		if (status) {
			/* Ok, no dependent libraries */
			ul_len = 0;
			status = 0;
		}
	}

	if (status || !(ul_len > 0))
		goto func_cont;

	/* Allocate zeroed buffer. */
	psz_coff_buf = kzalloc(ul_len + 4, GFP_KERNEL);
	if (psz_coff_buf == NULL)
		status = -ENOMEM;

	/* Read section contents. */
	status = cod_read_section(lib, DEPLIBSECT, psz_coff_buf, ul_len);
	if (status)
		goto func_cont;

	/* Compress and format DSP buffer to conform to PC format. */
	compress_buf(psz_coff_buf, ul_len, DSPWORDSIZE);

	/* Read from buffer */
	psz_cur = psz_coff_buf;
	while ((token = strsep(&psz_cur, seps)) && *token != '\0') {
		if (get_uuids) {
			if (dep_libs >= *num_libs) {
				/* Gone beyond the limit */
				break;
			} else {
				/* Retrieve UUID string. */
				uuid_uuid_from_string(token,
						      &(dep_lib_uuids
							[dep_libs]));
				/* Is this library persistent? */
				token = strsep(&psz_cur, seps);
				prstnt_dep_libs[dep_libs] = atoi(token);
				dep_libs++;
			}
		} else {
			/* Advanc to next token */
			token = strsep(&psz_cur, seps);
			if (atoi(token))
				(*num_pers_libs)++;

			/* Just counting number of dependent libraries */
			(*num_libs)++;
		}
	}
func_cont:
	if (lib)
		cod_close(lib);

	/* Free previously allocated dynamic buffers. */
	kfree(psz_file_name);

	kfree(psz_coff_buf);

	return status;
}
