128861Skato/*	$NetBSD$	*/
2139790Simp/*-
328861Skato * [NetBSD for NEC PC98 series]
428861Skato *  Copyright (c) 1994, 1995, 1996 NetBSD/pc98 porting staff.
528861Skato *  All rights reserved.
628861Skato *
728861Skato *  Redistribution and use in source and binary forms, with or without
828861Skato *  modification, are permitted provided that the following conditions
928861Skato *  are met:
1028861Skato *  1. Redistributions of source code must retain the above copyright
1128861Skato *     notice, this list of conditions and the following disclaimer.
1228861Skato *  2. Redistributions in binary form must reproduce the above copyright
1328861Skato *     notice, this list of conditions and the following disclaimer in the
1428861Skato *     documentation and/or other materials provided with the distribution.
1528861Skato *  3. The name of the author may not be used to endorse or promote products
1628861Skato *     derived from this software without specific prior written permission.
1728861Skato *
1828861Skato * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1928861Skato * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2028861Skato * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2128861Skato * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
2228861Skato * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2328861Skato * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2428861Skato * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2528861Skato * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
2628861Skato * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
2728861Skato * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2828861Skato * POSSIBILITY OF SUCH DAMAGE.
2959490Snyan *
3059490Snyan * $FreeBSD$
3128861Skato */
3228861Skato/*
3328861Skato * Common command control queue funcs.
3428861Skato * Written by N. Honda.
3528861Skato */
3628861Skato
3728861Skato#ifndef	_CCBQUE_H_
3828861Skato#define	_CCBQUE_H_
3928861Skato
4028861Skato#define	CCB_MWANTED 0x01
4128861Skato
4228861Skato/* (I)  structure and prototype */
4328861Skato#define GENERIC_CCB_ASSERT(DEV, CCBTYPE)				\
4460938SjakeTAILQ_HEAD(CCBTYPE##tab, CCBTYPE);					\
4528861Skatostruct CCBTYPE##que {							\
4628861Skato	struct CCBTYPE##tab CCBTYPE##tab;				\
4728861Skato	int count;							\
4828861Skato	int maxccb;							\
4928861Skato	u_int flags;							\
5028861Skato};									\
5128861Skato									\
5292765Salfredvoid DEV##_init_ccbque(int);					\
5392765Salfredstruct CCBTYPE *DEV##_get_ccb(void);				\
5492765Salfredvoid DEV##_free_ccb(register struct CCBTYPE *);
5528861Skato
5628861Skato/* (II)  static allocated memory */
5728861Skato#define GENERIC_CCB_STATIC_ALLOC(DEV, CCBTYPE)				\
5828861Skatostatic struct CCBTYPE##que CCBTYPE##que;
5928861Skato
6028861Skato/* (III)  functions */
6128861Skato#define GENERIC_CCB(DEV, CCBTYPE, CHAIN)				\
6228861Skato									\
6328861Skatovoid									\
6428861SkatoDEV##_init_ccbque(count)						\
6528861Skato	int count;							\
6628861Skato{									\
6728861Skato	if (CCBTYPE##que.maxccb == 0)					\
6833841Skato		TAILQ_INIT(&CCBTYPE##que.CCBTYPE##tab);			\
6928861Skato	CCBTYPE##que.maxccb += count;					\
7028861Skato}									\
7128861Skato									\
7228861Skatostruct CCBTYPE *							\
7342118SkatoDEV##_get_ccb()								\
7428861Skato{									\
7528861Skato	register struct CCBTYPE *cb;					\
7659490Snyan	int s = splcam();						\
7728861Skato									\
7828861Skato	if (CCBTYPE##que.count < CCBTYPE##que.maxccb)			\
7928861Skato	{								\
8028861Skato		CCBTYPE##que.count ++;					\
8171988Sphk		cb = TAILQ_FIRST(&(CCBTYPE##que.CCBTYPE##tab));		\
8228861Skato		if (cb != NULL)						\
8328861Skato		{							\
8433841Skato			TAILQ_REMOVE(&CCBTYPE##que.CCBTYPE##tab, cb, CHAIN);\
8528861Skato			goto out;					\
8628861Skato		}							\
8728861Skato		else							\
8828861Skato		{							\
8942118Skato			cb = malloc(sizeof(*cb), M_DEVBUF, M_NOWAIT);	\
9028861Skato			if (cb != NULL)					\
9128861Skato			{						\
9228861Skato				bzero(cb, sizeof(*cb));			\
9328861Skato				goto out;				\
9428861Skato			}						\
9528861Skato		}							\
9628861Skato		CCBTYPE##que.count --;					\
9728861Skato	}								\
9828861Skato									\
9928861Skato	cb = NULL;							\
10028861Skato									\
10128861Skatoout:									\
10228861Skato	splx(s);							\
10328861Skato	return cb;							\
10428861Skato}									\
10528861Skato									\
10628861Skatovoid									\
10728861SkatoDEV##_free_ccb(cb)							\
10828861Skato	register struct CCBTYPE *cb;					\
10928861Skato{									\
11059490Snyan	int s = splcam();						\
11128861Skato									\
11233841Skato	TAILQ_INSERT_TAIL(&CCBTYPE##que.CCBTYPE##tab, cb, CHAIN);	\
11328861Skato	CCBTYPE##que.count --;						\
11428861Skato									\
11528861Skato	if (CCBTYPE##que.flags & CCB_MWANTED)				\
11628861Skato	{								\
11728861Skato		CCBTYPE##que.flags &= ~CCB_MWANTED;			\
11828861Skato		wakeup ((caddr_t) &CCBTYPE##que.count);			\
11928861Skato	}								\
12028861Skato	splx(s);							\
12128861Skato}
12228861Skato#endif	/* !_CCBQUE_H_ */
123