6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * list.h: header for mega_sas
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * Solaris MegaRAID driver for SAS controllers
6029a2d88c01674debfd7c2e16c941a97302b739susans * Copyright (c) 2004-2008, LSI Logic Corporation.
6029a2d88c01674debfd7c2e16c941a97302b739susans * All rights reserved.
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * Redistribution and use in source and binary forms, with or without
6029a2d88c01674debfd7c2e16c941a97302b739susans * modification, are permitted provided that the following conditions are met:
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * 1. Redistributions of source code must retain the above copyright notice,
6029a2d88c01674debfd7c2e16c941a97302b739susans * this list of conditions and the following disclaimer.
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * 2. Redistributions in binary form must reproduce the above copyright notice,
6029a2d88c01674debfd7c2e16c941a97302b739susans * this list of conditions and the following disclaimer in the documentation
6029a2d88c01674debfd7c2e16c941a97302b739susans * and/or other materials provided with the distribution.
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * 3. Neither the name of the author nor the names of its contributors may be
6029a2d88c01674debfd7c2e16c941a97302b739susans * used to endorse or promote products derived from this software without
6029a2d88c01674debfd7c2e16c941a97302b739susans * specific prior written permission.
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6029a2d88c01674debfd7c2e16c941a97302b739susans * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6029a2d88c01674debfd7c2e16c941a97302b739susans * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
6029a2d88c01674debfd7c2e16c941a97302b739susans * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
6029a2d88c01674debfd7c2e16c941a97302b739susans * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
6029a2d88c01674debfd7c2e16c941a97302b739susans * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
6029a2d88c01674debfd7c2e16c941a97302b739susans * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
6029a2d88c01674debfd7c2e16c941a97302b739susans * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
6029a2d88c01674debfd7c2e16c941a97302b739susans * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
6029a2d88c01674debfd7c2e16c941a97302b739susans * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
6029a2d88c01674debfd7c2e16c941a97302b739susans * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
6029a2d88c01674debfd7c2e16c941a97302b739susans * DAMAGE.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
6029a2d88c01674debfd7c2e16c941a97302b739susans * Use is subject to license terms.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans#ifndef _LIST_H_
6029a2d88c01674debfd7c2e16c941a97302b739susans#define _LIST_H_
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans#ifdef __cplusplus
6029a2d88c01674debfd7c2e16c941a97302b739susansextern "C" {
6029a2d88c01674debfd7c2e16c941a97302b739susans#endif
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * Simple doubly linked list implementation.
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * Some of the internal functions ("__xxx") are useful when
6029a2d88c01674debfd7c2e16c941a97302b739susans * manipulating whole lists rather than single entries, as
6029a2d88c01674debfd7c2e16c941a97302b739susans * sometimes we already know the next/prev entries and we can
6029a2d88c01674debfd7c2e16c941a97302b739susans * generate better code by using them directly rather than
6029a2d88c01674debfd7c2e16c941a97302b739susans * using the generic single-entry routines.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susansstruct mlist_head {
6029a2d88c01674debfd7c2e16c941a97302b739susans struct mlist_head *next, *prev;
6029a2d88c01674debfd7c2e16c941a97302b739susans};
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susanstypedef struct mlist_head mlist_t;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans#define LIST_HEAD_INIT(name) { &(name), &(name) }
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans#define LIST_HEAD(name) \
6029a2d88c01674debfd7c2e16c941a97302b739susans struct mlist_head name = LIST_HEAD_INIT(name)
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans#define INIT_LIST_HEAD(ptr) { \
6029a2d88c01674debfd7c2e16c941a97302b739susans (ptr)->next = (ptr); (ptr)->prev = (ptr); \
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * Insert a new entry between two known consecutive entries.
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * This is only for internal list manipulation where we know
6029a2d88c01674debfd7c2e16c941a97302b739susans * the prev/next entries already!
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void __list_add(struct mlist_head *new,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct mlist_head *prev,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct mlist_head *next)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans next->prev = new;
6029a2d88c01674debfd7c2e16c941a97302b739susans new->next = next;
6029a2d88c01674debfd7c2e16c941a97302b739susans new->prev = prev;
6029a2d88c01674debfd7c2e16c941a97302b739susans prev->next = new;
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * mlist_add - add a new entry
6029a2d88c01674debfd7c2e16c941a97302b739susans * @new: new entry to be added
6029a2d88c01674debfd7c2e16c941a97302b739susans * @head: list head to add it after
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * Insert a new entry after the specified head.
6029a2d88c01674debfd7c2e16c941a97302b739susans * This is good for implementing stacks.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void mlist_add(struct mlist_head *new, struct mlist_head *head)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans __list_add(new, head, head->next);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * mlist_add_tail - add a new entry
6029a2d88c01674debfd7c2e16c941a97302b739susans * @new: new entry to be added
6029a2d88c01674debfd7c2e16c941a97302b739susans * @head: list head to add it before
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * Insert a new entry before the specified head.
6029a2d88c01674debfd7c2e16c941a97302b739susans * This is useful for implementing queues.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void mlist_add_tail(struct mlist_head *new, struct mlist_head *head)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans __list_add(new, head->prev, head);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * Delete a list entry by making the prev/next entries
6029a2d88c01674debfd7c2e16c941a97302b739susans * point to each other.
6029a2d88c01674debfd7c2e16c941a97302b739susans *
6029a2d88c01674debfd7c2e16c941a97302b739susans * This is only for internal list manipulation where we know
6029a2d88c01674debfd7c2e16c941a97302b739susans * the prev/next entries already!
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void __list_del(struct mlist_head *prev,
6029a2d88c01674debfd7c2e16c941a97302b739susans struct mlist_head *next)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans next->prev = prev;
6029a2d88c01674debfd7c2e16c941a97302b739susans prev->next = next;
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6ec0e3088091a677d3f67cf54a25174b0eb6db4aSusan Scheufele#if 0
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * mlist_del - deletes entry from list.
6029a2d88c01674debfd7c2e16c941a97302b739susans * @entry: the element to delete from the list.
6029a2d88c01674debfd7c2e16c941a97302b739susans * Note: list_empty on entry does not return true after this, the entry
6029a2d88c01674debfd7c2e16c941a97302b739susans * is in an undefined state.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6ec0e3088091a677d3f67cf54a25174b0eb6db4aSusan Scheufele
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void mlist_del(struct mlist_head *entry)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans __list_del(entry->prev, entry->next);
6029a2d88c01674debfd7c2e16c941a97302b739susans entry->next = entry->prev = 0;
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6ec0e3088091a677d3f67cf54a25174b0eb6db4aSusan Scheufele#endif
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * mlist_del_init - deletes entry from list and reinitialize it.
6029a2d88c01674debfd7c2e16c941a97302b739susans * @entry: the element to delete from the list.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void mlist_del_init(struct mlist_head *entry)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans __list_del(entry->prev, entry->next);
6029a2d88c01674debfd7c2e16c941a97302b739susans INIT_LIST_HEAD(entry);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * mlist_empty - tests whether a list is empty
6029a2d88c01674debfd7c2e16c941a97302b739susans * @head: the list to test.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic int mlist_empty(struct mlist_head *head)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans return (head->next == head);
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * mlist_splice - join two lists
6029a2d88c01674debfd7c2e16c941a97302b739susans * @list: the new list to add.
6029a2d88c01674debfd7c2e16c941a97302b739susans * @head: the place to add it in the first list.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susansstatic void mlist_splice(struct mlist_head *list, struct mlist_head *head)
6029a2d88c01674debfd7c2e16c941a97302b739susans{
6029a2d88c01674debfd7c2e16c941a97302b739susans struct mlist_head *first = list->next;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans if (first != list) {
6029a2d88c01674debfd7c2e16c941a97302b739susans struct mlist_head *last = list->prev;
6029a2d88c01674debfd7c2e16c941a97302b739susans struct mlist_head *at = head->next;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans first->prev = head;
6029a2d88c01674debfd7c2e16c941a97302b739susans head->next = first;
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans last->next = at;
6029a2d88c01674debfd7c2e16c941a97302b739susans at->prev = last;
6029a2d88c01674debfd7c2e16c941a97302b739susans }
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/* TODO: set this */
6029a2d88c01674debfd7c2e16c941a97302b739susans#if 0
6029a2d88c01674debfd7c2e16c941a97302b739susans#pragma inline(list_add, list_add_tail, __list_del, list_del,
6029a2d88c01674debfd7c2e16c941a97302b739susans list_del_init, list_empty, list_splice)
6029a2d88c01674debfd7c2e16c941a97302b739susans#endif
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * mlist_entry - get the struct for this entry
6029a2d88c01674debfd7c2e16c941a97302b739susans * @ptr: the &struct mlist_head pointer.
6029a2d88c01674debfd7c2e16c941a97302b739susans * @type: the type of the struct this is embedded in.
6029a2d88c01674debfd7c2e16c941a97302b739susans * @member: the name of the list_struct within the struct.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans#define mlist_entry(ptr, type, member) \
6ec0e3088091a677d3f67cf54a25174b0eb6db4aSusan Scheufele ((type *)((size_t)(ptr) - offsetof(type, member)))
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * mlist_for_each - iterate over a list
6029a2d88c01674debfd7c2e16c941a97302b739susans * @pos: the &struct mlist_head to use as a loop counter.
6029a2d88c01674debfd7c2e16c941a97302b739susans * @head: the head for your list.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans#define mlist_for_each(pos, head) \
6029a2d88c01674debfd7c2e16c941a97302b739susans for (pos = (head)->next, prefetch(pos->next); pos != (head); \
6029a2d88c01674debfd7c2e16c941a97302b739susans pos = pos->next, prefetch(pos->next))
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans/*
6029a2d88c01674debfd7c2e16c941a97302b739susans * mlist_for_each_safe - iterate over a list safe against removal of list entry
6029a2d88c01674debfd7c2e16c941a97302b739susans * @pos: the &struct mlist_head to use as a loop counter.
6029a2d88c01674debfd7c2e16c941a97302b739susans * @n: another &struct mlist_head to use as temporary storage
6029a2d88c01674debfd7c2e16c941a97302b739susans * @head: the head for your list.
6029a2d88c01674debfd7c2e16c941a97302b739susans */
6029a2d88c01674debfd7c2e16c941a97302b739susans#define mlist_for_each_safe(pos, n, head) \
6029a2d88c01674debfd7c2e16c941a97302b739susans for (pos = (head)->next, n = pos->next; pos != (head); \
6029a2d88c01674debfd7c2e16c941a97302b739susans pos = n, n = pos->next)
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans#ifdef __cplusplus
6029a2d88c01674debfd7c2e16c941a97302b739susans}
6029a2d88c01674debfd7c2e16c941a97302b739susans#endif
6029a2d88c01674debfd7c2e16c941a97302b739susans
6029a2d88c01674debfd7c2e16c941a97302b739susans#endif /* _LIST_H_ */