ccbque.h revision 33841
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/* 31 * Common command control queue funcs. 32 * Written by N. Honda. 33 */ 34 35#ifndef _CCBQUE_H_ 36#define _CCBQUE_H_ 37 38#define CCB_MWANTED 0x01 39#define CCB_WOK(fl) (((fl) == 0) ? M_WAITOK : M_NOWAIT) 40 41/* (I) structure and prototype */ 42#define GENERIC_CCB_ASSERT(DEV, CCBTYPE) \ 43TAILQ_HEAD(CCBTYPE##tab, CCBTYPE); \ 44struct CCBTYPE##que { \ 45 struct CCBTYPE##tab CCBTYPE##tab; \ 46 int count; \ 47 int maxccb; \ 48 u_int flags; \ 49}; \ 50 \ 51void DEV##_init_ccbque __P((int)); \ 52struct CCBTYPE *DEV##_get_ccb __P((int)); \ 53void DEV##_free_ccb __P((register struct CCBTYPE *)); 54 55/* (II) static allocated memory */ 56#define GENERIC_CCB_STATIC_ALLOC(DEV, CCBTYPE) \ 57static struct CCBTYPE##que CCBTYPE##que; 58 59/* (III) functions */ 60#define GENERIC_CCB(DEV, CCBTYPE, CHAIN) \ 61 \ 62void \ 63DEV##_init_ccbque(count) \ 64 int count; \ 65{ \ 66 if (CCBTYPE##que.maxccb == 0) \ 67 TAILQ_INIT(&CCBTYPE##que.CCBTYPE##tab); \ 68 CCBTYPE##que.maxccb += count; \ 69} \ 70 \ 71struct CCBTYPE * \ 72DEV##_get_ccb(flags) \ 73 int flags; \ 74{ \ 75 register struct CCBTYPE *cb; \ 76 int s = splbio(); \ 77 \ 78again: \ 79 if (CCBTYPE##que.count < CCBTYPE##que.maxccb) \ 80 { \ 81 CCBTYPE##que.count ++; \ 82 cb = CCBTYPE##que.CCBTYPE##tab.tqh_first; \ 83 if (cb != NULL) \ 84 { \ 85 TAILQ_REMOVE(&CCBTYPE##que.CCBTYPE##tab, cb, CHAIN);\ 86 goto out; \ 87 } \ 88 else \ 89 { \ 90 cb = malloc(sizeof(*cb), M_DEVBUF, CCB_WOK(flags));\ 91 if (cb != NULL) \ 92 { \ 93 bzero(cb, sizeof(*cb)); \ 94 goto out; \ 95 } \ 96 } \ 97 CCBTYPE##que.count --; \ 98 } \ 99 \ 100 if (flags == 0) \ 101 { \ 102 CCBTYPE##que.flags |= CCB_MWANTED; \ 103 tsleep((caddr_t) &CCBTYPE##que.count, PRIBIO, "ccbwait", 0);\ 104 goto again; \ 105 } \ 106 cb = NULL; \ 107 \ 108out: \ 109 splx(s); \ 110 return cb; \ 111} \ 112 \ 113void \ 114DEV##_free_ccb(cb) \ 115 register struct CCBTYPE *cb; \ 116{ \ 117 int s = splbio(); \ 118 \ 119 TAILQ_INSERT_TAIL(&CCBTYPE##que.CCBTYPE##tab, cb, CHAIN); \ 120 CCBTYPE##que.count --; \ 121 \ 122 if (CCBTYPE##que.flags & CCB_MWANTED) \ 123 { \ 124 CCBTYPE##que.flags &= ~CCB_MWANTED; \ 125 wakeup ((caddr_t) &CCBTYPE##que.count); \ 126 } \ 127 splx(s); \ 128} 129#endif /* !_CCBQUE_H_ */ 130