/* * Routines to access hardware * * Copyright (c) 2013 Realtek Semiconductor Corp. * */ #ifndef _HAL_UTIL_H_ #define _HAL_UTIL_H_ #ifdef __cplusplus extern "C" { #endif /* * Simple doubly linked list implementation. * * Some of the internal functions ("__xxx") are useful when * manipulating whole lists rather than single entries, as * sometimes we already know the next/prev entries and we can * generate better code by using them directly rather than * using the generic single-entry routines. */ struct LIST_HEADER { struct LIST_HEADER *Next, *Prev; }; typedef struct LIST_HEADER _LIST; //#define RTL_LIST_HEAD_INIT(name) { &(name), &(name) } #define RTL_INIT_LIST_HEAD(ptr) do { \ (ptr)->Next = (ptr); (ptr)->Prev = (ptr); \ } while (0) /* * Insert a new entry between two known consecutive entries. * * This is only for internal list manipulation where we know * the prev/next entries already! */ static __inline__ VOID __List_Add( IN struct LIST_HEADER * New, IN struct LIST_HEADER * Prev, IN struct LIST_HEADER * Next ) { Next->Prev = New; New->Next = Next; New->Prev = Prev; Prev->Next = New; } /* * Delete a list entry by making the prev/next entries * point to each other. * * This is only for internal list manipulation where we know * the prev/next entries already! */ static __inline__ VOID __List_Del( IN struct LIST_HEADER * Prev, IN struct LIST_HEADER * Next ) { Next->Prev = Prev; Prev->Next = Next; } /** * ListDel - deletes entry from list. * @entry: the element to delete from the list. * Note: list_empty on entry does not return true after this, the entry is in an undefined state. */ static __inline__ VOID ListDel( IN struct LIST_HEADER *Entry ) { __List_Del(Entry->Prev, Entry->Next); } /** * ListDelInit - deletes entry from list and reinitialize it. * @entry: the element to delete from the list. */ static __inline__ VOID ListDelInit( IN struct LIST_HEADER *Entry ) { __List_Del(Entry->Prev, Entry->Next); RTL_INIT_LIST_HEAD(Entry); } /** * ListEmpty - tests whether a list is empty * @head: the list to test. */ static __inline__ u32 ListEmpty( IN struct LIST_HEADER *Head ) { return Head->Next == Head; } /** * ListSplice - join two lists * @list: the new list to add. * @head: the place to add it in the first list. */ static __inline__ VOID ListSplice( IN struct LIST_HEADER *List, IN struct LIST_HEADER *Head ) { struct LIST_HEADER *First = List->Next; if (First != List) { struct LIST_HEADER *Last = List->Prev; struct LIST_HEADER *At = Head->Next; First->Prev = Head; Head->Next = First; Last->Next = At; At->Prev = Last; } } static __inline__ VOID ListAdd( IN struct LIST_HEADER *New, IN struct LIST_HEADER *head ) { __List_Add(New, head, head->Next); } static __inline__ VOID ListAddTail( IN struct LIST_HEADER *New, IN struct LIST_HEADER *head ) { __List_Add(New, head->Prev, head); } static __inline VOID RtlInitListhead( IN _LIST *list ) { RTL_INIT_LIST_HEAD(list); } /* For the following list_xxx operations, caller must guarantee the atomic context. Otherwise, there will be racing condition. */ static __inline u32 RtlIsListEmpty( IN _LIST *phead ) { if (ListEmpty(phead)) return _TRUE; else return _FALSE; } static __inline VOID RtlListInsertHead( IN _LIST *plist, IN _LIST *phead ) { ListAdd(plist, phead); } static __inline VOID RtlListInsertTail( IN _LIST *plist, IN _LIST *phead ) { ListAddTail(plist, phead); } static __inline _LIST *RtlListGetNext( IN _LIST *plist ) { return plist->Next; } static __inline VOID RtlListDelete( IN _LIST *plist ) { ListDelInit(plist); } #define RTL_LIST_CONTAINOR(ptr, type, member) \ ((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member))) #ifndef CONTAINER_OF #define CONTAINER_OF(ptr, type, member) \ ((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member))) #endif #if 0 #define list_entry(ptr, type, member) \ CONTAINER_OF(ptr, type, member) #define list_first_entry(ptr, type, member) \ list_entry((ptr)->Next, type, member) #define list_next_entry(pos, member, type) \ list_entry((pos)->member.Next, type, member) #define list_for_each_entry(pos, head, member, type) \ for (pos = list_first_entry(head, type, member); \ &pos->member != (head); \ pos = list_next_entry(pos, member, type)) #define list_for_each(pos, head) \ for (pos = (head)->Next; pos != (head); pos = pos->Next) #endif #ifndef BIT #define BIT(x) ( 1 << (x)) #endif #ifdef __cplusplus } #endif #endif //_HAL_UTIL_H_