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