1/* $NetBSD$ */ 2/*- 3 * [NetBSD for NEC PC98 series] 4 * Copyright (c) 1994, 1995, 1996 NetBSD/pc98 porting staff. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 * 30 * $FreeBSD$ 31 */ 32/* 33 * Common command control queue funcs. 34 * Written by N. Honda. 35 */ 36 37#ifndef _CCBQUE_H_ 38#define _CCBQUE_H_ 39 40#define CCB_MWANTED 0x01 41 42/* (I) structure and prototype */ 43#define GENERIC_CCB_ASSERT(DEV, CCBTYPE) \ 44TAILQ_HEAD(CCBTYPE##tab, CCBTYPE); \ 45struct CCBTYPE##que { \ 46 struct CCBTYPE##tab CCBTYPE##tab; \ 47 int count; \ 48 int maxccb; \ 49 u_int flags; \ 50}; \ 51 \ 52void DEV##_init_ccbque(int); \ 53struct CCBTYPE *DEV##_get_ccb(void); \ 54void DEV##_free_ccb(register struct CCBTYPE *); 55 56/* (II) static allocated memory */ 57#define GENERIC_CCB_STATIC_ALLOC(DEV, CCBTYPE) \ 58static struct CCBTYPE##que CCBTYPE##que; 59 60/* (III) functions */ 61#define GENERIC_CCB(DEV, CCBTYPE, CHAIN) \ 62 \ 63void \ 64DEV##_init_ccbque(count) \ 65 int count; \ 66{ \ 67 if (CCBTYPE##que.maxccb == 0) \ 68 TAILQ_INIT(&CCBTYPE##que.CCBTYPE##tab); \ 69 CCBTYPE##que.maxccb += count; \ 70} \ 71 \ 72struct CCBTYPE * \ 73DEV##_get_ccb() \ 74{ \ 75 register struct CCBTYPE *cb; \ 76 int s = splcam(); \ 77 \ 78 if (CCBTYPE##que.count < CCBTYPE##que.maxccb) \ 79 { \ 80 CCBTYPE##que.count ++; \ 81 cb = TAILQ_FIRST(&(CCBTYPE##que.CCBTYPE##tab)); \ 82 if (cb != NULL) \ 83 { \ 84 TAILQ_REMOVE(&CCBTYPE##que.CCBTYPE##tab, cb, CHAIN);\ 85 goto out; \ 86 } \ 87 else \ 88 { \ 89 cb = malloc(sizeof(*cb), M_DEVBUF, M_NOWAIT); \ 90 if (cb != NULL) \ 91 { \ 92 bzero(cb, sizeof(*cb)); \ 93 goto out; \ 94 } \ 95 } \ 96 CCBTYPE##que.count --; \ 97 } \ 98 \ 99 cb = NULL; \ 100 \ 101out: \ 102 splx(s); \ 103 return cb; \ 104} \ 105 \ 106void \ 107DEV##_free_ccb(cb) \ 108 register struct CCBTYPE *cb; \ 109{ \ 110 int s = splcam(); \ 111 \ 112 TAILQ_INSERT_TAIL(&CCBTYPE##que.CCBTYPE##tab, cb, CHAIN); \ 113 CCBTYPE##que.count --; \ 114 \ 115 if (CCBTYPE##que.flags & CCB_MWANTED) \ 116 { \ 117 CCBTYPE##que.flags &= ~CCB_MWANTED; \ 118 wakeup ((caddr_t) &CCBTYPE##que.count); \ 119 } \ 120 splx(s); \ 121} 122#endif /* !_CCBQUE_H_ */ 123