1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate  * av1394 queue
31*0Sstevel@tonic-gate  *    Based on av1394 list, plus locking, works only with mblk's,
32*0Sstevel@tonic-gate  *    counts and limits amount of data on the queue.
33*0Sstevel@tonic-gate  */
34*0Sstevel@tonic-gate #include <sys/stream.h>
35*0Sstevel@tonic-gate #include <sys/strsun.h>
36*0Sstevel@tonic-gate #include <sys/1394/targets/av1394/av1394_impl.h>
37*0Sstevel@tonic-gate 
38*0Sstevel@tonic-gate typedef void (*putfunc_t)(av1394_list_t *, void *);
39*0Sstevel@tonic-gate 
40*0Sstevel@tonic-gate static mblk_t	*av1394_getq_locked(av1394_queue_t *);
41*0Sstevel@tonic-gate static int	av1394_put_common(av1394_queue_t *, mblk_t *, putfunc_t);
42*0Sstevel@tonic-gate 
43*0Sstevel@tonic-gate void
av1394_initq(av1394_queue_t * q,ddi_iblock_cookie_t ibc,int max)44*0Sstevel@tonic-gate av1394_initq(av1394_queue_t *q, ddi_iblock_cookie_t ibc, int max)
45*0Sstevel@tonic-gate {
46*0Sstevel@tonic-gate 	bzero(q, sizeof (av1394_queue_t));
47*0Sstevel@tonic-gate 
48*0Sstevel@tonic-gate 	mutex_init(&q->q_mutex, NULL, MUTEX_DRIVER, ibc);
49*0Sstevel@tonic-gate 	cv_init(&q->q_cv, NULL, CV_DRIVER, NULL);
50*0Sstevel@tonic-gate 
51*0Sstevel@tonic-gate 	AV1394_ENTERQ(q);
52*0Sstevel@tonic-gate 	av1394_list_init(&q->q_list);
53*0Sstevel@tonic-gate 	q->q_max = max;
54*0Sstevel@tonic-gate 	AV1394_LEAVEQ(q);
55*0Sstevel@tonic-gate }
56*0Sstevel@tonic-gate 
57*0Sstevel@tonic-gate void
av1394_destroyq(av1394_queue_t * q)58*0Sstevel@tonic-gate av1394_destroyq(av1394_queue_t *q)
59*0Sstevel@tonic-gate {
60*0Sstevel@tonic-gate 	av1394_flushq(q);
61*0Sstevel@tonic-gate 	mutex_destroy(&q->q_mutex);
62*0Sstevel@tonic-gate 	cv_destroy(&q->q_cv);
63*0Sstevel@tonic-gate }
64*0Sstevel@tonic-gate 
65*0Sstevel@tonic-gate void
av1394_setmaxq(av1394_queue_t * q,int max)66*0Sstevel@tonic-gate av1394_setmaxq(av1394_queue_t *q, int max)
67*0Sstevel@tonic-gate {
68*0Sstevel@tonic-gate 	AV1394_ENTERQ(q);
69*0Sstevel@tonic-gate 	q->q_max = max;
70*0Sstevel@tonic-gate 	AV1394_LEAVEQ(q);
71*0Sstevel@tonic-gate }
72*0Sstevel@tonic-gate 
73*0Sstevel@tonic-gate int
av1394_getmaxq(av1394_queue_t * q)74*0Sstevel@tonic-gate av1394_getmaxq(av1394_queue_t *q)
75*0Sstevel@tonic-gate {
76*0Sstevel@tonic-gate 	int	max;
77*0Sstevel@tonic-gate 
78*0Sstevel@tonic-gate 	AV1394_ENTERQ(q);
79*0Sstevel@tonic-gate 	max = q->q_max;
80*0Sstevel@tonic-gate 	AV1394_LEAVEQ(q);
81*0Sstevel@tonic-gate 	return (max);
82*0Sstevel@tonic-gate }
83*0Sstevel@tonic-gate 
84*0Sstevel@tonic-gate void
av1394_flushq(av1394_queue_t * q)85*0Sstevel@tonic-gate av1394_flushq(av1394_queue_t *q)
86*0Sstevel@tonic-gate {
87*0Sstevel@tonic-gate 	mblk_t	*bp;
88*0Sstevel@tonic-gate 
89*0Sstevel@tonic-gate 	AV1394_ENTERQ(q);
90*0Sstevel@tonic-gate 	while ((bp = av1394_getq_locked(q)) != NULL) {
91*0Sstevel@tonic-gate 		freemsg(bp);
92*0Sstevel@tonic-gate 	}
93*0Sstevel@tonic-gate 	ASSERT(q->q_size == 0);
94*0Sstevel@tonic-gate 	AV1394_LEAVEQ(q);
95*0Sstevel@tonic-gate }
96*0Sstevel@tonic-gate 
97*0Sstevel@tonic-gate int
av1394_putq(av1394_queue_t * q,mblk_t * bp)98*0Sstevel@tonic-gate av1394_putq(av1394_queue_t *q, mblk_t *bp)
99*0Sstevel@tonic-gate {
100*0Sstevel@tonic-gate 	return (av1394_put_common(q, bp, av1394_list_put_tail));
101*0Sstevel@tonic-gate }
102*0Sstevel@tonic-gate 
103*0Sstevel@tonic-gate int
av1394_putbq(av1394_queue_t * q,mblk_t * bp)104*0Sstevel@tonic-gate av1394_putbq(av1394_queue_t *q, mblk_t *bp)
105*0Sstevel@tonic-gate {
106*0Sstevel@tonic-gate 	return (av1394_put_common(q, bp, av1394_list_put_head));
107*0Sstevel@tonic-gate }
108*0Sstevel@tonic-gate 
109*0Sstevel@tonic-gate mblk_t *
av1394_getq(av1394_queue_t * q)110*0Sstevel@tonic-gate av1394_getq(av1394_queue_t *q)
111*0Sstevel@tonic-gate {
112*0Sstevel@tonic-gate 	mblk_t	*bp;
113*0Sstevel@tonic-gate 
114*0Sstevel@tonic-gate 	AV1394_ENTERQ(q);
115*0Sstevel@tonic-gate 	bp = av1394_getq_locked(q);
116*0Sstevel@tonic-gate 	AV1394_LEAVEQ(q);
117*0Sstevel@tonic-gate 
118*0Sstevel@tonic-gate 	return (bp);
119*0Sstevel@tonic-gate }
120*0Sstevel@tonic-gate 
121*0Sstevel@tonic-gate mblk_t *
av1394_peekq(av1394_queue_t * q)122*0Sstevel@tonic-gate av1394_peekq(av1394_queue_t *q)
123*0Sstevel@tonic-gate {
124*0Sstevel@tonic-gate 	mblk_t	*mp;
125*0Sstevel@tonic-gate 
126*0Sstevel@tonic-gate 	AV1394_ENTERQ(q);
127*0Sstevel@tonic-gate 	mp = av1394_peekq_locked(q);
128*0Sstevel@tonic-gate 	AV1394_LEAVEQ(q);
129*0Sstevel@tonic-gate 	return (mp);
130*0Sstevel@tonic-gate }
131*0Sstevel@tonic-gate 
132*0Sstevel@tonic-gate mblk_t *
av1394_peekq_locked(av1394_queue_t * q)133*0Sstevel@tonic-gate av1394_peekq_locked(av1394_queue_t *q)
134*0Sstevel@tonic-gate {
135*0Sstevel@tonic-gate 	ASSERT(mutex_owned(&q->q_mutex));
136*0Sstevel@tonic-gate 	return (av1394_list_head(&q->q_list));
137*0Sstevel@tonic-gate }
138*0Sstevel@tonic-gate 
139*0Sstevel@tonic-gate /*
140*0Sstevel@tonic-gate  * wait until queue is not empty or a signal arrives
141*0Sstevel@tonic-gate  */
142*0Sstevel@tonic-gate int
av1394_qwait_sig(av1394_queue_t * q)143*0Sstevel@tonic-gate av1394_qwait_sig(av1394_queue_t *q)
144*0Sstevel@tonic-gate {
145*0Sstevel@tonic-gate 	int	ret = 1;
146*0Sstevel@tonic-gate 
147*0Sstevel@tonic-gate 	AV1394_ENTERQ(q);
148*0Sstevel@tonic-gate 	while (av1394_peekq_locked(q) == NULL) {
149*0Sstevel@tonic-gate 		if ((ret = cv_wait_sig(&q->q_cv, &q->q_mutex)) <= 0) {
150*0Sstevel@tonic-gate 			break;
151*0Sstevel@tonic-gate 		}
152*0Sstevel@tonic-gate 	}
153*0Sstevel@tonic-gate 	AV1394_LEAVEQ(q);
154*0Sstevel@tonic-gate 
155*0Sstevel@tonic-gate 	return (ret);
156*0Sstevel@tonic-gate }
157*0Sstevel@tonic-gate 
158*0Sstevel@tonic-gate static int
av1394_put_common(av1394_queue_t * q,mblk_t * bp,putfunc_t put)159*0Sstevel@tonic-gate av1394_put_common(av1394_queue_t *q, mblk_t *bp, putfunc_t put)
160*0Sstevel@tonic-gate {
161*0Sstevel@tonic-gate 	int	ret;
162*0Sstevel@tonic-gate 	int	len = MBLKL(bp);
163*0Sstevel@tonic-gate 
164*0Sstevel@tonic-gate 	AV1394_ENTERQ(q);
165*0Sstevel@tonic-gate 	if (q->q_size + len > q->q_max) {
166*0Sstevel@tonic-gate 		ret = 0;
167*0Sstevel@tonic-gate 	} else {
168*0Sstevel@tonic-gate 		put(&q->q_list, bp);
169*0Sstevel@tonic-gate 		q->q_size += len;
170*0Sstevel@tonic-gate 		cv_broadcast(&q->q_cv);
171*0Sstevel@tonic-gate 		ret = 1;
172*0Sstevel@tonic-gate 	}
173*0Sstevel@tonic-gate 	AV1394_LEAVEQ(q);
174*0Sstevel@tonic-gate 
175*0Sstevel@tonic-gate 	return (ret);
176*0Sstevel@tonic-gate }
177*0Sstevel@tonic-gate 
178*0Sstevel@tonic-gate static mblk_t *
av1394_getq_locked(av1394_queue_t * q)179*0Sstevel@tonic-gate av1394_getq_locked(av1394_queue_t *q)
180*0Sstevel@tonic-gate {
181*0Sstevel@tonic-gate 	mblk_t	*bp;
182*0Sstevel@tonic-gate 
183*0Sstevel@tonic-gate 	if ((bp = av1394_list_get_head(&q->q_list)) != NULL) {
184*0Sstevel@tonic-gate 		q->q_size -= MBLKL(bp);
185*0Sstevel@tonic-gate 		ASSERT(q->q_size >= 0);
186*0Sstevel@tonic-gate 	}
187*0Sstevel@tonic-gate 	return (bp);
188*0Sstevel@tonic-gate }
189