linux/drivers/scsi/sym53c8xx_2/sym_misc.h
<<
>>
Prefs
   1/*
   2 * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family 
   3 * of PCI-SCSI IO processors.
   4 *
   5 * Copyright (C) 1999-2001  Gerard Roudier <groudier@free.fr>
   6 *
   7 * This driver is derived from the Linux sym53c8xx driver.
   8 * Copyright (C) 1998-2000  Gerard Roudier
   9 *
  10 * The sym53c8xx driver is derived from the ncr53c8xx driver that had been 
  11 * a port of the FreeBSD ncr driver to Linux-1.2.13.
  12 *
  13 * The original ncr driver has been written for 386bsd and FreeBSD by
  14 *         Wolfgang Stanglmeier        <wolf@cologne.de>
  15 *         Stefan Esser                <se@mi.Uni-Koeln.de>
  16 * Copyright (C) 1994  Wolfgang Stanglmeier
  17 *
  18 * Other major contributions:
  19 *
  20 * NVRAM detection and reading.
  21 * Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
  22 *
  23 *-----------------------------------------------------------------------------
  24 *
  25 * This program is free software; you can redistribute it and/or modify
  26 * it under the terms of the GNU General Public License as published by
  27 * the Free Software Foundation; either version 2 of the License, or
  28 * (at your option) any later version.
  29 *
  30 * This program is distributed in the hope that it will be useful,
  31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  33 * GNU General Public License for more details.
  34 *
  35 * You should have received a copy of the GNU General Public License
  36 * along with this program; if not, write to the Free Software
  37 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  38 */
  39
  40#ifndef SYM_MISC_H
  41#define SYM_MISC_H
  42
  43/*
  44 *  A la VMS/CAM-3 queue management.
  45 */
  46typedef struct sym_quehead {
  47        struct sym_quehead *flink;      /* Forward  pointer */
  48        struct sym_quehead *blink;      /* Backward pointer */
  49} SYM_QUEHEAD;
  50
  51#define sym_que_init(ptr) do { \
  52        (ptr)->flink = (ptr); (ptr)->blink = (ptr); \
  53} while (0)
  54
  55static inline struct sym_quehead *sym_que_first(struct sym_quehead *head)
  56{
  57        return (head->flink == head) ? 0 : head->flink;
  58}
  59
  60static inline struct sym_quehead *sym_que_last(struct sym_quehead *head)
  61{
  62        return (head->blink == head) ? 0 : head->blink;
  63}
  64
  65static inline void __sym_que_add(struct sym_quehead * new,
  66        struct sym_quehead * blink,
  67        struct sym_quehead * flink)
  68{
  69        flink->blink    = new;
  70        new->flink      = flink;
  71        new->blink      = blink;
  72        blink->flink    = new;
  73}
  74
  75static inline void __sym_que_del(struct sym_quehead * blink,
  76        struct sym_quehead * flink)
  77{
  78        flink->blink = blink;
  79        blink->flink = flink;
  80}
  81
  82static inline int sym_que_empty(struct sym_quehead *head)
  83{
  84        return head->flink == head;
  85}
  86
  87static inline void sym_que_splice(struct sym_quehead *list,
  88        struct sym_quehead *head)
  89{
  90        struct sym_quehead *first = list->flink;
  91
  92        if (first != list) {
  93                struct sym_quehead *last = list->blink;
  94                struct sym_quehead *at   = head->flink;
  95
  96                first->blink = head;
  97                head->flink  = first;
  98
  99                last->flink = at;
 100                at->blink   = last;
 101        }
 102}
 103
 104static inline void sym_que_move(struct sym_quehead *orig,
 105        struct sym_quehead *dest)
 106{
 107        struct sym_quehead *first, *last;
 108
 109        first = orig->flink;
 110        if (first != orig) {
 111                first->blink = dest;
 112                dest->flink  = first;
 113                last = orig->blink;
 114                last->flink  = dest;
 115                dest->blink  = last;
 116                orig->flink  = orig;
 117                orig->blink  = orig;
 118        } else {
 119                dest->flink  = dest;
 120                dest->blink  = dest;
 121        }
 122}
 123
 124#define sym_que_entry(ptr, type, member) container_of(ptr, type, member)
 125
 126#define sym_insque(new, pos)            __sym_que_add(new, pos, (pos)->flink)
 127
 128#define sym_remque(el)                  __sym_que_del((el)->blink, (el)->flink)
 129
 130#define sym_insque_head(new, head)      __sym_que_add(new, head, (head)->flink)
 131
 132static inline struct sym_quehead *sym_remque_head(struct sym_quehead *head)
 133{
 134        struct sym_quehead *elem = head->flink;
 135
 136        if (elem != head)
 137                __sym_que_del(head, elem->flink);
 138        else
 139                elem = NULL;
 140        return elem;
 141}
 142
 143#define sym_insque_tail(new, head)      __sym_que_add(new, (head)->blink, head)
 144
 145static inline struct sym_quehead *sym_remque_tail(struct sym_quehead *head)
 146{
 147        struct sym_quehead *elem = head->blink;
 148
 149        if (elem != head)
 150                __sym_que_del(elem->blink, head);
 151        else
 152                elem = 0;
 153        return elem;
 154}
 155
 156/*
 157 *  This one may be useful.
 158 */
 159#define FOR_EACH_QUEUED_ELEMENT(head, qp) \
 160        for (qp = (head)->flink; qp != (head); qp = qp->flink)
 161/*
 162 *  FreeBSD does not offer our kind of queue in the CAM CCB.
 163 *  So, we have to cast.
 164 */
 165#define sym_qptr(p)     ((struct sym_quehead *) (p))
 166
 167/*
 168 *  Simple bitmap operations.
 169 */ 
 170#define sym_set_bit(p, n)       (((u32 *)(p))[(n)>>5] |=  (1<<((n)&0x1f)))
 171#define sym_clr_bit(p, n)       (((u32 *)(p))[(n)>>5] &= ~(1<<((n)&0x1f)))
 172#define sym_is_bit(p, n)        (((u32 *)(p))[(n)>>5] &   (1<<((n)&0x1f)))
 173
 174/*
 175 * The below round up/down macros are to be used with a constant 
 176 * as argument (sizeof(...) for example), for the compiler to 
 177 * optimize the whole thing.
 178 */
 179#define _U_(a,m)        (a)<=(1<<m)?m:
 180
 181/*
 182 * Round up logarithm to base 2 of a 16 bit constant.
 183 */
 184#define _LGRU16_(a) \
 185( \
 186 _U_(a, 0)_U_(a, 1)_U_(a, 2)_U_(a, 3)_U_(a, 4)_U_(a, 5)_U_(a, 6)_U_(a, 7) \
 187 _U_(a, 8)_U_(a, 9)_U_(a,10)_U_(a,11)_U_(a,12)_U_(a,13)_U_(a,14)_U_(a,15) \
 188 16)
 189
 190#endif /* SYM_MISC_H */
 191