blob: 6837b614073a828cac0626d5dd8bdc565503c5f5 [file] [log] [blame]
/*
* list.h
*
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
*
* Declarations of list management control structures and definitions
* of inline list management functions.
*
* Copyright (C) 2008 Texas Instruments, Inc.
*
* This package is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef LIST_
#define LIST_
#include <dspbridge/host_os.h>
#include <linux/list.h>
#define LST_IS_EMPTY(l) list_empty(&(l)->head)
struct lst_list {
struct list_head head;
};
/*
* ======== lst_first ========
* Purpose:
* Returns a pointer to the first element of the list, or NULL if the list
* is empty.
* Parameters:
* lst: Pointer to list control structure.
* Returns:
* Pointer to first list element, or NULL.
* Requires:
* - LST initialized.
* - lst != NULL.
* Ensures:
*/
static inline struct list_head *lst_first(struct lst_list *lst)
{
if (lst && !list_empty(&lst->head))
return lst->head.next;
return NULL;
}
/*
* ======== lst_get_head ========
* Purpose:
* Pops the head off the list and returns a pointer to it.
* Details:
* If the list is empty, returns NULL.
* Else, removes the element at the head of the list, making the next
* element the head of the list.
* The head is removed by making the tail element of the list point its
* "next" pointer at the next element after the head, and by making the
* "prev" pointer of the next element after the head point at the tail
* element. So the next element after the head becomes the new head of
* the list.
* Parameters:
* lst: Pointer to list control structure of list whose head
* element is to be removed
* Returns:
* Pointer to element that was at the head of the list (success)
* NULL No elements in list
* Requires:
* - LST initialized.
* - lst != NULL.
* Ensures:
* Notes:
* Because the tail of the list points forward (its "next" pointer) to
* the head of the list, and the head of the list points backward (its
* "prev" pointer) to the tail of the list, this list is circular.
*/
static inline struct list_head *lst_get_head(struct lst_list *lst)
{
struct list_head *elem_list;
if (!lst || list_empty(&lst->head))
return NULL;
elem_list = lst->head.next;
lst->head.next = elem_list->next;
elem_list->next->prev = &lst->head;
return elem_list;
}
/*
* ======== lst_init_elem ========
* Purpose:
* Initializes a list element to default (cleared) values
* Details:
* Parameters:
* elem_list: Pointer to list element to be reset
* Returns:
* Requires:
* LST initialized.
* Ensures:
* Notes:
* This function must not be called to "reset" an element in the middle
* of a list chain -- that would break the chain.
*
*/
static inline void lst_init_elem(struct list_head *elem_list)
{
if (elem_list) {
elem_list->next = NULL;
elem_list->prev = NULL;
}
}
/*
* ======== lst_insert_before ========
* Purpose:
* Insert the element before the existing element.
* Parameters:
* lst: Pointer to list control structure.
* elem_list: Pointer to element in list to insert.
* elem_existing: Pointer to existing list element.
* Returns:
* Requires:
* - LST initialized.
* - lst != NULL.
* - elem_list != NULL.
* - elem_existing != NULL.
* Ensures:
*/
static inline void lst_insert_before(struct lst_list *lst,
struct list_head *elem_list,
struct list_head *elem_existing)
{
if (lst && elem_list && elem_existing)
list_add_tail(elem_list, elem_existing);
}
/*
* ======== lst_next ========
* Purpose:
* Returns a pointer to the next element of the list, or NULL if the next
* element is the head of the list or the list is empty.
* Parameters:
* lst: Pointer to list control structure.
* cur_elem: Pointer to element in list to remove.
* Returns:
* Pointer to list element, or NULL.
* Requires:
* - LST initialized.
* - lst != NULL.
* - cur_elem != NULL.
* Ensures:
*/
static inline struct list_head *lst_next(struct lst_list *lst,
struct list_head *cur_elem)
{
if (lst && !list_empty(&lst->head) && cur_elem &&
(cur_elem->next != &lst->head))
return cur_elem->next;
return NULL;
}
/*
* ======== lst_put_tail ========
* Purpose:
* Adds the specified element to the tail of the list
* Details:
* Sets new element's "prev" pointer to the address previously held by
* the head element's prev pointer. This is the previous tail member of
* the list.
* Sets the new head's prev pointer to the address of the element.
* Sets next pointer of the previous tail member of the list to point to
* the new element (rather than the head, which it had been pointing at).
* Sets new element's next pointer to the address of the head element.
* Sets head's prev pointer to the address of the new element.
* Parameters:
* lst: Pointer to list control structure to which *elem_list will be
* added
* elem_list: Pointer to list element to be added
* Returns:
* Void
* Requires:
* *elem_list and *lst must both exist.
* LST initialized.
* Ensures:
* Notes:
* Because the tail is always "just before" the head of the list (the
* tail's "next" pointer points at the head of the list, and the head's
* "prev" pointer points at the tail of the list), the list is circular.
*/
static inline void lst_put_tail(struct lst_list *lst,
struct list_head *elem_list)
{
if (lst && elem_list)
list_add_tail(elem_list, &lst->head);
}
/*
* ======== lst_remove_elem ========
* Purpose:
* Removes (unlinks) the given element from the list, if the list is not
* empty. Does not free the list element.
* Parameters:
* lst: Pointer to list control structure.
* cur_elem: Pointer to element in list to remove.
* Returns:
* Requires:
* - LST initialized.
* - lst != NULL.
* - cur_elem != NULL.
* Ensures:
*/
static inline void lst_remove_elem(struct lst_list *lst,
struct list_head *cur_elem)
{
if (lst && !list_empty(&lst->head) && cur_elem)
list_del_init(cur_elem);
}
#endif /* LIST_ */