162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family 462306a36Sopenharmony_ci * of PCI-SCSI IO processors. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (C) 1999-2001 Gerard Roudier <groudier@free.fr> 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * This driver is derived from the Linux sym53c8xx driver. 962306a36Sopenharmony_ci * Copyright (C) 1998-2000 Gerard Roudier 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * The sym53c8xx driver is derived from the ncr53c8xx driver that had been 1262306a36Sopenharmony_ci * a port of the FreeBSD ncr driver to Linux-1.2.13. 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * The original ncr driver has been written for 386bsd and FreeBSD by 1562306a36Sopenharmony_ci * Wolfgang Stanglmeier <wolf@cologne.de> 1662306a36Sopenharmony_ci * Stefan Esser <se@mi.Uni-Koeln.de> 1762306a36Sopenharmony_ci * Copyright (C) 1994 Wolfgang Stanglmeier 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * Other major contributions: 2062306a36Sopenharmony_ci * 2162306a36Sopenharmony_ci * NVRAM detection and reading. 2262306a36Sopenharmony_ci * Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk> 2362306a36Sopenharmony_ci * 2462306a36Sopenharmony_ci *----------------------------------------------------------------------------- 2562306a36Sopenharmony_ci */ 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#ifndef SYM_MISC_H 2862306a36Sopenharmony_ci#define SYM_MISC_H 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci/* 3162306a36Sopenharmony_ci * A la VMS/CAM-3 queue management. 3262306a36Sopenharmony_ci */ 3362306a36Sopenharmony_citypedef struct sym_quehead { 3462306a36Sopenharmony_ci struct sym_quehead *flink; /* Forward pointer */ 3562306a36Sopenharmony_ci struct sym_quehead *blink; /* Backward pointer */ 3662306a36Sopenharmony_ci} SYM_QUEHEAD; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci#define sym_que_init(ptr) do { \ 3962306a36Sopenharmony_ci (ptr)->flink = (ptr); (ptr)->blink = (ptr); \ 4062306a36Sopenharmony_ci} while (0) 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_cistatic inline struct sym_quehead *sym_que_first(struct sym_quehead *head) 4362306a36Sopenharmony_ci{ 4462306a36Sopenharmony_ci return (head->flink == head) ? 0 : head->flink; 4562306a36Sopenharmony_ci} 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_cistatic inline struct sym_quehead *sym_que_last(struct sym_quehead *head) 4862306a36Sopenharmony_ci{ 4962306a36Sopenharmony_ci return (head->blink == head) ? 0 : head->blink; 5062306a36Sopenharmony_ci} 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_cistatic inline void __sym_que_add(struct sym_quehead * new, 5362306a36Sopenharmony_ci struct sym_quehead * blink, 5462306a36Sopenharmony_ci struct sym_quehead * flink) 5562306a36Sopenharmony_ci{ 5662306a36Sopenharmony_ci flink->blink = new; 5762306a36Sopenharmony_ci new->flink = flink; 5862306a36Sopenharmony_ci new->blink = blink; 5962306a36Sopenharmony_ci blink->flink = new; 6062306a36Sopenharmony_ci} 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_cistatic inline void __sym_que_del(struct sym_quehead * blink, 6362306a36Sopenharmony_ci struct sym_quehead * flink) 6462306a36Sopenharmony_ci{ 6562306a36Sopenharmony_ci flink->blink = blink; 6662306a36Sopenharmony_ci blink->flink = flink; 6762306a36Sopenharmony_ci} 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_cistatic inline int sym_que_empty(struct sym_quehead *head) 7062306a36Sopenharmony_ci{ 7162306a36Sopenharmony_ci return head->flink == head; 7262306a36Sopenharmony_ci} 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_cistatic inline void sym_que_splice(struct sym_quehead *list, 7562306a36Sopenharmony_ci struct sym_quehead *head) 7662306a36Sopenharmony_ci{ 7762306a36Sopenharmony_ci struct sym_quehead *first = list->flink; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci if (first != list) { 8062306a36Sopenharmony_ci struct sym_quehead *last = list->blink; 8162306a36Sopenharmony_ci struct sym_quehead *at = head->flink; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci first->blink = head; 8462306a36Sopenharmony_ci head->flink = first; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci last->flink = at; 8762306a36Sopenharmony_ci at->blink = last; 8862306a36Sopenharmony_ci } 8962306a36Sopenharmony_ci} 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_cistatic inline void sym_que_move(struct sym_quehead *orig, 9262306a36Sopenharmony_ci struct sym_quehead *dest) 9362306a36Sopenharmony_ci{ 9462306a36Sopenharmony_ci struct sym_quehead *first, *last; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci first = orig->flink; 9762306a36Sopenharmony_ci if (first != orig) { 9862306a36Sopenharmony_ci first->blink = dest; 9962306a36Sopenharmony_ci dest->flink = first; 10062306a36Sopenharmony_ci last = orig->blink; 10162306a36Sopenharmony_ci last->flink = dest; 10262306a36Sopenharmony_ci dest->blink = last; 10362306a36Sopenharmony_ci orig->flink = orig; 10462306a36Sopenharmony_ci orig->blink = orig; 10562306a36Sopenharmony_ci } else { 10662306a36Sopenharmony_ci dest->flink = dest; 10762306a36Sopenharmony_ci dest->blink = dest; 10862306a36Sopenharmony_ci } 10962306a36Sopenharmony_ci} 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci#define sym_que_entry(ptr, type, member) container_of(ptr, type, member) 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci#define sym_insque(new, pos) __sym_que_add(new, pos, (pos)->flink) 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci#define sym_remque(el) __sym_que_del((el)->blink, (el)->flink) 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci#define sym_insque_head(new, head) __sym_que_add(new, head, (head)->flink) 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_cistatic inline struct sym_quehead *sym_remque_head(struct sym_quehead *head) 12062306a36Sopenharmony_ci{ 12162306a36Sopenharmony_ci struct sym_quehead *elem = head->flink; 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci if (elem != head) 12462306a36Sopenharmony_ci __sym_que_del(head, elem->flink); 12562306a36Sopenharmony_ci else 12662306a36Sopenharmony_ci elem = NULL; 12762306a36Sopenharmony_ci return elem; 12862306a36Sopenharmony_ci} 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci#define sym_insque_tail(new, head) __sym_que_add(new, (head)->blink, head) 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_cistatic inline struct sym_quehead *sym_remque_tail(struct sym_quehead *head) 13362306a36Sopenharmony_ci{ 13462306a36Sopenharmony_ci struct sym_quehead *elem = head->blink; 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci if (elem != head) 13762306a36Sopenharmony_ci __sym_que_del(elem->blink, head); 13862306a36Sopenharmony_ci else 13962306a36Sopenharmony_ci elem = 0; 14062306a36Sopenharmony_ci return elem; 14162306a36Sopenharmony_ci} 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci/* 14462306a36Sopenharmony_ci * This one may be useful. 14562306a36Sopenharmony_ci */ 14662306a36Sopenharmony_ci#define FOR_EACH_QUEUED_ELEMENT(head, qp) \ 14762306a36Sopenharmony_ci for (qp = (head)->flink; qp != (head); qp = qp->flink) 14862306a36Sopenharmony_ci/* 14962306a36Sopenharmony_ci * FreeBSD does not offer our kind of queue in the CAM CCB. 15062306a36Sopenharmony_ci * So, we have to cast. 15162306a36Sopenharmony_ci */ 15262306a36Sopenharmony_ci#define sym_qptr(p) ((struct sym_quehead *) (p)) 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci/* 15562306a36Sopenharmony_ci * Simple bitmap operations. 15662306a36Sopenharmony_ci */ 15762306a36Sopenharmony_ci#define sym_set_bit(p, n) (((u32 *)(p))[(n)>>5] |= (1<<((n)&0x1f))) 15862306a36Sopenharmony_ci#define sym_clr_bit(p, n) (((u32 *)(p))[(n)>>5] &= ~(1<<((n)&0x1f))) 15962306a36Sopenharmony_ci#define sym_is_bit(p, n) (((u32 *)(p))[(n)>>5] & (1<<((n)&0x1f))) 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci/* 16262306a36Sopenharmony_ci * The below round up/down macros are to be used with a constant 16362306a36Sopenharmony_ci * as argument (sizeof(...) for example), for the compiler to 16462306a36Sopenharmony_ci * optimize the whole thing. 16562306a36Sopenharmony_ci */ 16662306a36Sopenharmony_ci#define _U_(a,m) (a)<=(1<<m)?m: 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci/* 16962306a36Sopenharmony_ci * Round up logarithm to base 2 of a 16 bit constant. 17062306a36Sopenharmony_ci */ 17162306a36Sopenharmony_ci#define _LGRU16_(a) \ 17262306a36Sopenharmony_ci( \ 17362306a36Sopenharmony_ci _U_(a, 0)_U_(a, 1)_U_(a, 2)_U_(a, 3)_U_(a, 4)_U_(a, 5)_U_(a, 6)_U_(a, 7) \ 17462306a36Sopenharmony_ci _U_(a, 8)_U_(a, 9)_U_(a,10)_U_(a,11)_U_(a,12)_U_(a,13)_U_(a,14)_U_(a,15) \ 17562306a36Sopenharmony_ci 16) 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci#endif /* SYM_MISC_H */ 178