1 /*
   2  * mr_sas_list.h: header for mr_sas
   3  *
   4  * Solaris MegaRAID driver for SAS2.0 controllers
   5  * Copyright (c) 2008-2012, LSI Logic Corporation.
   6  * All rights reserved.
   7  */
   8 
   9 /* Copyright 2012 Nexenta Systems, Inc. All rights reserved. */
  10 
  11 /*
  12  * Extract C functions from LSI-provided mr_sas_list.h such that we can both
  13  * be lint-clean and provide a slightly better source organizational model
  14  * beyond preprocessor abuse.
  15  */
  16 
  17 #include "mr_sas_list.h"
  18 
  19 /*
  20  * Insert a new entry between two known consecutive entries.
  21  *
  22  * This is only for internal list manipulation where we know
  23  * the prev/next entries already!
  24  */
  25 static inline void
  26 __list_add(struct mlist_head *new, struct mlist_head *prev,
  27     struct mlist_head *next)
  28 {
  29         next->prev = new;
  30         new->next = next;
  31         new->prev = prev;
  32         prev->next = new;
  33 }
  34 
  35 /*
  36  * mlist_add - add a new entry
  37  * @new: new entry to be added
  38  * @head: list head to add it after
  39  *
  40  * Insert a new entry after the specified head.
  41  * This is good for implementing stacks.
  42  */
  43 void
  44 mlist_add(struct mlist_head *new, struct mlist_head *head)
  45 {
  46         __list_add(new, head, head->next);
  47 }
  48 
  49 /*
  50  * mlist_add_tail - add a new entry
  51  * @new: new entry to be added
  52  * @head: list head to add it before
  53  *
  54  * Insert a new entry before the specified head.
  55  * This is useful for implementing queues.
  56  */
  57 void
  58 mlist_add_tail(struct mlist_head *new, struct mlist_head *head)
  59 {
  60         __list_add(new, head->prev, head);
  61 }
  62 
  63 /*
  64  * Delete a list entry by making the prev/next entries
  65  * point to each other.
  66  *
  67  * This is only for internal list manipulation where we know
  68  * the prev/next entries already!
  69  */
  70 static inline void
  71 __list_del(struct mlist_head *prev, struct mlist_head *next)
  72 {
  73         next->prev = prev;
  74         prev->next = next;
  75 }
  76 
  77 #if 0
  78 /*
  79  * mlist_del - deletes entry from list.
  80  * @entry:      the element to delete from the list.
  81  * Note:        list_empty on entry does not return true after this, the entry
  82  * is in an undefined state.
  83  */
  84 
  85 void
  86 mlist_del(struct mlist_head *entry)
  87 {
  88         __list_del(entry->prev, entry->next);
  89         entry->next = entry->prev = 0;
  90 }
  91 #endif
  92 
  93 /*
  94  * mlist_del_init - deletes entry from list and reinitialize it.
  95  * @entry: the element to delete from the list.
  96  */
  97 void
  98 mlist_del_init(struct mlist_head *entry)
  99 {
 100         __list_del(entry->prev, entry->next);
 101         INIT_LIST_HEAD(entry);
 102 }
 103 
 104 /*
 105  * mlist_empty - tests whether a list is empty
 106  * @head: the list to test.
 107  */
 108 int
 109 mlist_empty(struct mlist_head *head)
 110 {
 111         return (head->next == head);
 112 }
 113 
 114 /*
 115  * mlist_splice - join two lists
 116  * @list: the new list to add.
 117  * @head: the place to add it in the first list.
 118  */
 119 void
 120 mlist_splice(struct mlist_head *list, struct mlist_head *head)
 121 {
 122         struct mlist_head *first = list->next;
 123 
 124         if (first != list) {
 125                 struct mlist_head *last = list->prev;
 126                 struct mlist_head *at = head->next;
 127 
 128                 first->prev = head;
 129                 head->next = first;
 130 
 131                 last->next = at;
 132                 at->prev = last;
 133         }
 134 }