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