Commit 7227b671 authored by Omar Ramirez Luna's avatar Omar Ramirez Luna Committed by Greg Kroah-Hartman
Browse files

staging: ti dspbridge: add generic utilities

parent 5cc28e62
Loading
Loading
Loading
Loading
+167 −0
Original line number Diff line number Diff line
/*
 * gb.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * Generic bitmap operations.
 *
 * Copyright (C) 2005-2006 Texas Instruments, Inc.
 *
 * This package is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/*  ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/std.h>
#include <linux/types.h>
/*  ----------------------------------- This */
#include <dspbridge/gs.h>
#include <dspbridge/gb.h>

struct gb_t_map {
	u32 len;
	u32 wcnt;
	u32 *words;
};

/*
 *  ======== gb_clear ========
 *  purpose:
 *      Clears a bit in the bit map.
 */

void gb_clear(struct gb_t_map *map, u32 bitn)
{
	u32 mask;

	mask = 1L << (bitn % BITS_PER_LONG);
	map->words[bitn / BITS_PER_LONG] &= ~mask;
}

/*
 *  ======== gb_create ========
 *  purpose:
 *      Creates a bit map.
 */

struct gb_t_map *gb_create(u32 len)
{
	struct gb_t_map *map;
	u32 i;
	map = (struct gb_t_map *)gs_alloc(sizeof(struct gb_t_map));
	if (map != NULL) {
		map->len = len;
		map->wcnt = len / BITS_PER_LONG + 1;
		map->words = (u32 *) gs_alloc(map->wcnt * sizeof(u32));
		if (map->words != NULL) {
			for (i = 0; i < map->wcnt; i++)
				map->words[i] = 0L;

		} else {
			gs_frees(map, sizeof(struct gb_t_map));
			map = NULL;
		}
	}

	return map;
}

/*
 *  ======== gb_delete ========
 *  purpose:
 *      Frees a bit map.
 */

void gb_delete(struct gb_t_map *map)
{
	gs_frees(map->words, map->wcnt * sizeof(u32));
	gs_frees(map, sizeof(struct gb_t_map));
}

/*
 *  ======== gb_findandset ========
 *  purpose:
 *      Finds a free bit and sets it.
 */
u32 gb_findandset(struct gb_t_map *map)
{
	u32 bitn;

	bitn = gb_minclear(map);

	if (bitn != GB_NOBITS)
		gb_set(map, bitn);

	return bitn;
}

/*
 *  ======== gb_minclear ========
 *  purpose:
 *      returns the location of the first unset bit in the bit map.
 */
u32 gb_minclear(struct gb_t_map *map)
{
	u32 bit_location = 0;
	u32 bit_acc = 0;
	u32 i;
	u32 bit;
	u32 *word;

	for (word = map->words, i = 0; i < map->wcnt; word++, i++) {
		if (~*word) {
			for (bit = 0; bit < BITS_PER_LONG; bit++, bit_acc++) {
				if (bit_acc == map->len)
					return GB_NOBITS;

				if (~*word & (1L << bit)) {
					bit_location = i * BITS_PER_LONG + bit;
					return bit_location;
				}

			}
		} else {
			bit_acc += BITS_PER_LONG;
		}
	}

	return GB_NOBITS;
}

/*
 *  ======== gb_set ========
 *  purpose:
 *      Sets a bit in the bit map.
 */

void gb_set(struct gb_t_map *map, u32 bitn)
{
	u32 mask;

	mask = 1L << (bitn % BITS_PER_LONG);
	map->words[bitn / BITS_PER_LONG] |= mask;
}

/*
 *  ======== gb_test ========
 *  purpose:
 *      Returns true if the bit is set in the specified location.
 */

bool gb_test(struct gb_t_map *map, u32 bitn)
{
	bool state;
	u32 mask;
	u32 word;

	mask = 1L << (bitn % BITS_PER_LONG);
	word = map->words[bitn / BITS_PER_LONG];
	state = word & mask ? TRUE : FALSE;

	return state;
}
+213 −0
Original line number Diff line number Diff line
/*
 * gh.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * Copyright (C) 2005-2006 Texas Instruments, Inc.
 *
 * This package is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include <dspbridge/std.h>

#include <dspbridge/host_os.h>

#include <dspbridge/gs.h>

#include <dspbridge/gh.h>

struct element {
	struct element *next;
	u8 data[1];
};

struct gh_t_hash_tab {
	u16 max_bucket;
	u16 val_size;
	struct element **buckets;
	 u16(*hash) (void *, u16);
	 bool(*match) (void *, void *);
	void (*delete) (void *);
};

static void noop(void *p);
static s32 cur_init;
static void myfree(void *ptr, s32 size);

/*
 *  ======== gh_create ========
 */

struct gh_t_hash_tab *gh_create(u16 max_bucket, u16 val_size,
				u16(*hash) (void *, u16), bool(*match) (void *,
									void *),
				void (*delete) (void *))
{
	struct gh_t_hash_tab *hash_tab;
	u16 i;
	hash_tab =
	    (struct gh_t_hash_tab *)gs_alloc(sizeof(struct gh_t_hash_tab));
	if (hash_tab == NULL)
		return NULL;
	hash_tab->max_bucket = max_bucket;
	hash_tab->val_size = val_size;
	hash_tab->hash = hash;
	hash_tab->match = match;
	hash_tab->delete = delete == NULL ? noop : delete;

	hash_tab->buckets = (struct element **)
	    gs_alloc(sizeof(struct element *) * max_bucket);
	if (hash_tab->buckets == NULL) {
		gh_delete(hash_tab);
		return NULL;
	}

	for (i = 0; i < max_bucket; i++)
		hash_tab->buckets[i] = NULL;

	return hash_tab;
}

/*
 *  ======== gh_delete ========
 */
void gh_delete(struct gh_t_hash_tab *hash_tab)
{
	struct element *elem, *next;
	u16 i;

	if (hash_tab != NULL) {
		if (hash_tab->buckets != NULL) {
			for (i = 0; i < hash_tab->max_bucket; i++) {
				for (elem = hash_tab->buckets[i]; elem != NULL;
				     elem = next) {
					next = elem->next;
					(*hash_tab->delete) (elem->data);
					myfree(elem,
					       sizeof(struct element) - 1 +
					       hash_tab->val_size);
				}
			}

			myfree(hash_tab->buckets, sizeof(struct element *)
			       * hash_tab->max_bucket);
		}

		myfree(hash_tab, sizeof(struct gh_t_hash_tab));
	}
}

/*
 *  ======== gh_exit ========
 */

void gh_exit(void)
{
	if (cur_init-- == 1)
		gs_exit();

}

/*
 *  ======== gh_find ========
 */

void *gh_find(struct gh_t_hash_tab *hash_tab, void *key)
{
	struct element *elem;

	elem = hash_tab->buckets[(*hash_tab->hash) (key, hash_tab->max_bucket)];

	for (; elem; elem = elem->next) {
		if ((*hash_tab->match) (key, elem->data))
			return elem->data;
	}

	return NULL;
}

/*
 *  ======== gh_init ========
 */

void gh_init(void)
{
	if (cur_init++ == 0)
		gs_init();
}

/*
 *  ======== gh_insert ========
 */

void *gh_insert(struct gh_t_hash_tab *hash_tab, void *key, void *value)
{
	struct element *elem;
	u16 i;
	char *src, *dst;

	elem = (struct element *)gs_alloc(sizeof(struct element) - 1 +
					  hash_tab->val_size);
	if (elem != NULL) {

		dst = (char *)elem->data;
		src = (char *)value;
		for (i = 0; i < hash_tab->val_size; i++)
			*dst++ = *src++;

		i = (*hash_tab->hash) (key, hash_tab->max_bucket);
		elem->next = hash_tab->buckets[i];
		hash_tab->buckets[i] = elem;

		return elem->data;
	}

	return NULL;
}

/*
 *  ======== noop ========
 */
/* ARGSUSED */
static void noop(void *p)
{
	p = p;			/* stifle compiler warning */
}

/*
 *  ======== myfree ========
 */
static void myfree(void *ptr, s32 size)
{
	gs_free(ptr);
}

/**
 * gh_iterate() - This function goes through all the elements in the hash table
 *		looking for the dsp symbols.
 * @hash_tab:	Hash table
 * @callback:	pointer to callback function
 * @user_data:	User data, contains the find_symbol_context pointer
 *
 */
void gh_iterate(struct gh_t_hash_tab *hash_tab,
		void (*callback)(void *, void *), void *user_data)
{
	struct element *elem;
	u32 i;

	if (hash_tab && hash_tab->buckets)
		for (i = 0; i < hash_tab->max_bucket; i++) {
			elem = hash_tab->buckets[i];
			while (elem) {
				callback(&elem->data, user_data);
				elem = elem->next;
			}
		}
}
+89 −0
Original line number Diff line number Diff line
/*
 * gs.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * General storage memory allocator services.
 *
 * 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.
 */

/*  ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/std.h>
#include <dspbridge/dbdefs.h>
#include <linux/types.h>

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

#include <linux/slab.h>

/*  ----------------------------------- Globals */
static u32 cumsize;

/*
 *  ======== gs_alloc ========
 *  purpose:
 *      Allocates memory of the specified size.
 */
void *gs_alloc(u32 size)
{
	void *p;

	p = kzalloc(size, GFP_KERNEL);
	if (p == NULL)
		return NULL;
	cumsize += size;
	return p;
}

/*
 *  ======== gs_exit ========
 *  purpose:
 *      Discontinue the usage of the GS module.
 */
void gs_exit(void)
{
	/* Do nothing */
}

/*
 *  ======== gs_free ========
 *  purpose:
 *      Frees the memory.
 */
void gs_free(void *ptr)
{
	kfree(ptr);
	/* ack! no size info */
	/* cumsize -= size; */
}

/*
 *  ======== gs_frees ========
 *  purpose:
 *      Frees the memory.
 */
void gs_frees(void *ptr, u32 size)
{
	kfree(ptr);
	cumsize -= size;
}

/*
 *  ======== gs_init ========
 *  purpose:
 *      Initializes the GS module.
 */
void gs_init(void)
{
	/* Do nothing */
}
+223 −0
Original line number Diff line number Diff line
/*
 * uuidutil.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * This file contains the implementation of UUID helper functions.
 *
 * 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.
 */

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

/*  ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/std.h>
#include <dspbridge/dbdefs.h>

/*  ----------------------------------- Trace & Debug */
#include <dspbridge/dbc.h>

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

/*
 *  ======== uuid_uuid_to_string ========
 *  Purpose:
 *      Converts a struct dsp_uuid to a string.
 *      Note: snprintf format specifier is:
 *      %[flags] [width] [.precision] [{h | l | I64 | L}]type
 */
void uuid_uuid_to_string(IN struct dsp_uuid *uuid_obj, OUT char *pszUuid,
			 IN s32 size)
{
	s32 i;			/* return result from snprintf. */

	DBC_REQUIRE(uuid_obj && pszUuid);

	i = snprintf(pszUuid, size,
		     "%.8X_%.4X_%.4X_%.2X%.2X_%.2X%.2X%.2X%.2X%.2X%.2X",
		     uuid_obj->ul_data1, uuid_obj->us_data2, uuid_obj->us_data3,
		     uuid_obj->uc_data4, uuid_obj->uc_data5,
		     uuid_obj->uc_data6[0], uuid_obj->uc_data6[1],
		     uuid_obj->uc_data6[2], uuid_obj->uc_data6[3],
		     uuid_obj->uc_data6[4], uuid_obj->uc_data6[5]);

	DBC_ENSURE(i != -1);
}

/*
 *  ======== htoi ========
 *  Purpose:
 *      Converts a hex value to a decimal integer.
 */

static int htoi(char c)
{
	switch (c) {
	case '0':
		return 0;
	case '1':
		return 1;
	case '2':
		return 2;
	case '3':
		return 3;
	case '4':
		return 4;
	case '5':
		return 5;
	case '6':
		return 6;
	case '7':
		return 7;
	case '8':
		return 8;
	case '9':
		return 9;
	case 'A':
		return 10;
	case 'B':
		return 11;
	case 'C':
		return 12;
	case 'D':
		return 13;
	case 'E':
		return 14;
	case 'F':
		return 15;
	case 'a':
		return 10;
	case 'b':
		return 11;
	case 'c':
		return 12;
	case 'd':
		return 13;
	case 'e':
		return 14;
	case 'f':
		return 15;
	}
	return 0;
}

/*
 *  ======== uuid_uuid_from_string ========
 *  Purpose:
 *      Converts a string to a struct dsp_uuid.
 */
void uuid_uuid_from_string(IN char *pszUuid, OUT struct dsp_uuid *uuid_obj)
{
	char c;
	s32 i, j;
	s32 result;
	char *temp = pszUuid;

	result = 0;
	for (i = 0; i < 8; i++) {
		/* Get first character in string */
		c = *temp;

		/* Increase the results by new value */
		result *= 16;
		result += htoi(c);

		/* Go to next character in string */
		temp++;
	}
	uuid_obj->ul_data1 = result;

	/* Step over underscore */
	temp++;

	result = 0;
	for (i = 0; i < 4; i++) {
		/* Get first character in string */
		c = *temp;

		/* Increase the results by new value */
		result *= 16;
		result += htoi(c);

		/* Go to next character in string */
		temp++;
	}
	uuid_obj->us_data2 = (u16) result;

	/* Step over underscore */
	temp++;

	result = 0;
	for (i = 0; i < 4; i++) {
		/* Get first character in string */
		c = *temp;

		/* Increase the results by new value */
		result *= 16;
		result += htoi(c);

		/* Go to next character in string */
		temp++;
	}
	uuid_obj->us_data3 = (u16) result;

	/* Step over underscore */
	temp++;

	result = 0;
	for (i = 0; i < 2; i++) {
		/* Get first character in string */
		c = *temp;

		/* Increase the results by new value */
		result *= 16;
		result += htoi(c);

		/* Go to next character in string */
		temp++;
	}
	uuid_obj->uc_data4 = (u8) result;

	result = 0;
	for (i = 0; i < 2; i++) {
		/* Get first character in string */
		c = *temp;

		/* Increase the results by new value */
		result *= 16;
		result += htoi(c);

		/* Go to next character in string */
		temp++;
	}
	uuid_obj->uc_data5 = (u8) result;

	/* Step over underscore */
	temp++;

	for (j = 0; j < 6; j++) {
		result = 0;
		for (i = 0; i < 2; i++) {
			/* Get first character in string */
			c = *temp;

			/* Increase the results by new value */
			result *= 16;
			result += htoi(c);

			/* Go to next character in string */
			temp++;
		}
		uuid_obj->uc_data6[j] = (u8) result;
	}
}