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