| /* |
| * 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_ */ |