1*2654012fSReza Sabdar /* 2*2654012fSReza Sabdar * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 3*2654012fSReza Sabdar * Use is subject to license terms. 4*2654012fSReza Sabdar */ 5*2654012fSReza Sabdar 6*2654012fSReza Sabdar /* 7*2654012fSReza Sabdar * BSD 3 Clause License 8*2654012fSReza Sabdar * 9*2654012fSReza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association. 10*2654012fSReza Sabdar * 11*2654012fSReza Sabdar * Redistribution and use in source and binary forms, with or without 12*2654012fSReza Sabdar * modification, are permitted provided that the following conditions 13*2654012fSReza Sabdar * are met: 14*2654012fSReza Sabdar * - Redistributions of source code must retain the above copyright 15*2654012fSReza Sabdar * notice, this list of conditions and the following disclaimer. 16*2654012fSReza Sabdar * 17*2654012fSReza Sabdar * - Redistributions in binary form must reproduce the above copyright 18*2654012fSReza Sabdar * notice, this list of conditions and the following disclaimer in 19*2654012fSReza Sabdar * the documentation and/or other materials provided with the 20*2654012fSReza Sabdar * distribution. 21*2654012fSReza Sabdar * 22*2654012fSReza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA) 23*2654012fSReza Sabdar * nor the names of its contributors may be used to endorse or promote 24*2654012fSReza Sabdar * products derived from this software without specific prior written 25*2654012fSReza Sabdar * permission. 26*2654012fSReza Sabdar * 27*2654012fSReza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28*2654012fSReza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29*2654012fSReza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30*2654012fSReza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 31*2654012fSReza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32*2654012fSReza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33*2654012fSReza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34*2654012fSReza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35*2654012fSReza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36*2654012fSReza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37*2654012fSReza Sabdar * POSSIBILITY OF SUCH DAMAGE. 38*2654012fSReza Sabdar */ 39*2654012fSReza Sabdar #include <stdio.h> 40*2654012fSReza Sabdar #include <stdlib.h> 41*2654012fSReza Sabdar #include <sys/errno.h> 42*2654012fSReza Sabdar #include <string.h> 43*2654012fSReza Sabdar #include <unistd.h> 44*2654012fSReza Sabdar #include <pthread.h> 45*2654012fSReza Sabdar #include <synch.h> 46*2654012fSReza Sabdar #include <tlm_buffers.h> 47*2654012fSReza Sabdar #include <tlm.h> 48*2654012fSReza Sabdar #include "tlm_proto.h" 49*2654012fSReza Sabdar 50*2654012fSReza Sabdar 51*2654012fSReza Sabdar /* 52*2654012fSReza Sabdar * tlm_allocate_buffers 53*2654012fSReza Sabdar * 54*2654012fSReza Sabdar * build a set of buffers 55*2654012fSReza Sabdar */ 56*2654012fSReza Sabdar tlm_buffers_t * 57*2654012fSReza Sabdar tlm_allocate_buffers(boolean_t write, long xfer_size) 58*2654012fSReza Sabdar { 59*2654012fSReza Sabdar tlm_buffers_t *buffers = ndmp_malloc(sizeof (tlm_buffers_t)); 60*2654012fSReza Sabdar int buf; 61*2654012fSReza Sabdar 62*2654012fSReza Sabdar if (buffers == 0) 63*2654012fSReza Sabdar return (0); 64*2654012fSReza Sabdar 65*2654012fSReza Sabdar for (buf = 0; buf < TLM_TAPE_BUFFERS; buf++) { 66*2654012fSReza Sabdar buffers->tbs_buffer[buf].tb_buffer_data = 67*2654012fSReza Sabdar ndmp_malloc(xfer_size); 68*2654012fSReza Sabdar if (buffers->tbs_buffer[buf].tb_buffer_data == 0) { 69*2654012fSReza Sabdar int i; 70*2654012fSReza Sabdar 71*2654012fSReza Sabdar /* Memory allocation failed. Give everything back */ 72*2654012fSReza Sabdar for (i = 0; i < buf; i++) 73*2654012fSReza Sabdar free(buffers->tbs_buffer[i].tb_buffer_data); 74*2654012fSReza Sabdar 75*2654012fSReza Sabdar free(buffers); 76*2654012fSReza Sabdar return (0); 77*2654012fSReza Sabdar } else { 78*2654012fSReza Sabdar buffers->tbs_buffer[buf].tb_buffer_size = (write) 79*2654012fSReza Sabdar ? xfer_size : 0; 80*2654012fSReza Sabdar buffers->tbs_buffer[buf].tb_full = FALSE; 81*2654012fSReza Sabdar buffers->tbs_buffer[buf].tb_eof = FALSE; 82*2654012fSReza Sabdar buffers->tbs_buffer[buf].tb_eot = FALSE; 83*2654012fSReza Sabdar buffers->tbs_buffer[buf].tb_errno = 0; 84*2654012fSReza Sabdar buffers->tbs_buffer[buf].tb_buffer_spot = 0; 85*2654012fSReza Sabdar } 86*2654012fSReza Sabdar 87*2654012fSReza Sabdar } 88*2654012fSReza Sabdar 89*2654012fSReza Sabdar (void) mutex_init(&buffers->tbs_mtx, 0, NULL); 90*2654012fSReza Sabdar (void) cond_init(&buffers->tbs_in_cv, 0, NULL); 91*2654012fSReza Sabdar (void) cond_init(&buffers->tbs_out_cv, 0, NULL); 92*2654012fSReza Sabdar 93*2654012fSReza Sabdar buffers->tbs_data_transfer_size = xfer_size; 94*2654012fSReza Sabdar buffers->tbs_ref = 1; 95*2654012fSReza Sabdar return (buffers); 96*2654012fSReza Sabdar } 97*2654012fSReza Sabdar 98*2654012fSReza Sabdar /* 99*2654012fSReza Sabdar * tlm_release_buffers 100*2654012fSReza Sabdar * 101*2654012fSReza Sabdar * give all memory back to the OS 102*2654012fSReza Sabdar */ 103*2654012fSReza Sabdar void 104*2654012fSReza Sabdar tlm_release_buffers(tlm_buffers_t *buffers) 105*2654012fSReza Sabdar { 106*2654012fSReza Sabdar int i; 107*2654012fSReza Sabdar 108*2654012fSReza Sabdar if (buffers != NULL) { 109*2654012fSReza Sabdar tlm_buffer_release_in_buf(buffers); 110*2654012fSReza Sabdar tlm_buffer_release_out_buf(buffers); 111*2654012fSReza Sabdar 112*2654012fSReza Sabdar (void) mutex_lock(&buffers->tbs_mtx); 113*2654012fSReza Sabdar 114*2654012fSReza Sabdar if (--buffers->tbs_ref <= 0) { 115*2654012fSReza Sabdar for (i = 0; i < TLM_TAPE_BUFFERS; i++) 116*2654012fSReza Sabdar free(buffers->tbs_buffer[i].tb_buffer_data); 117*2654012fSReza Sabdar 118*2654012fSReza Sabdar } 119*2654012fSReza Sabdar 120*2654012fSReza Sabdar (void) cond_destroy(&buffers->tbs_in_cv); 121*2654012fSReza Sabdar (void) cond_destroy(&buffers->tbs_out_cv); 122*2654012fSReza Sabdar (void) mutex_unlock(&buffers->tbs_mtx); 123*2654012fSReza Sabdar (void) mutex_destroy(&buffers->tbs_mtx); 124*2654012fSReza Sabdar free(buffers); 125*2654012fSReza Sabdar } 126*2654012fSReza Sabdar } 127*2654012fSReza Sabdar 128*2654012fSReza Sabdar /* 129*2654012fSReza Sabdar * tlm_buffer_mark_empty 130*2654012fSReza Sabdar * 131*2654012fSReza Sabdar * Mark a buffer empty and clear its flags. No lock is take here: 132*2654012fSReza Sabdar * the buffer should be marked empty before it is released for use 133*2654012fSReza Sabdar * by another thread. 134*2654012fSReza Sabdar */ 135*2654012fSReza Sabdar void 136*2654012fSReza Sabdar tlm_buffer_mark_empty(tlm_buffer_t *buf) 137*2654012fSReza Sabdar { 138*2654012fSReza Sabdar if (buf == NULL) 139*2654012fSReza Sabdar return; 140*2654012fSReza Sabdar 141*2654012fSReza Sabdar buf->tb_full = buf->tb_eof = buf->tb_eot = FALSE; 142*2654012fSReza Sabdar buf->tb_errno = 0; 143*2654012fSReza Sabdar } 144*2654012fSReza Sabdar 145*2654012fSReza Sabdar 146*2654012fSReza Sabdar /* 147*2654012fSReza Sabdar * tlm_buffer_advance_in_idx 148*2654012fSReza Sabdar * 149*2654012fSReza Sabdar * Advance the input index of the buffers(round-robin) and return pointer 150*2654012fSReza Sabdar * to the next buffer in the buffer pool. 151*2654012fSReza Sabdar */ 152*2654012fSReza Sabdar tlm_buffer_t * 153*2654012fSReza Sabdar tlm_buffer_advance_in_idx(tlm_buffers_t *bufs) 154*2654012fSReza Sabdar { 155*2654012fSReza Sabdar if (bufs == NULL) 156*2654012fSReza Sabdar return (NULL); 157*2654012fSReza Sabdar 158*2654012fSReza Sabdar (void) mutex_lock(&bufs->tbs_mtx); 159*2654012fSReza Sabdar if (++bufs->tbs_buffer_in >= TLM_TAPE_BUFFERS) 160*2654012fSReza Sabdar bufs->tbs_buffer_in = 0; 161*2654012fSReza Sabdar 162*2654012fSReza Sabdar (void) mutex_unlock(&bufs->tbs_mtx); 163*2654012fSReza Sabdar return (&bufs->tbs_buffer[bufs->tbs_buffer_in]); 164*2654012fSReza Sabdar } 165*2654012fSReza Sabdar 166*2654012fSReza Sabdar 167*2654012fSReza Sabdar /* 168*2654012fSReza Sabdar * tlm_buffer_advance_out_idx 169*2654012fSReza Sabdar * 170*2654012fSReza Sabdar * Advance the output index of the buffers(round-robin) and return pointer 171*2654012fSReza Sabdar * to the next buffer in the buffer pool. 172*2654012fSReza Sabdar */ 173*2654012fSReza Sabdar tlm_buffer_t * 174*2654012fSReza Sabdar tlm_buffer_advance_out_idx(tlm_buffers_t *bufs) 175*2654012fSReza Sabdar { 176*2654012fSReza Sabdar if (bufs == NULL) 177*2654012fSReza Sabdar return (NULL); 178*2654012fSReza Sabdar 179*2654012fSReza Sabdar (void) mutex_lock(&bufs->tbs_mtx); 180*2654012fSReza Sabdar if (++bufs->tbs_buffer_out >= TLM_TAPE_BUFFERS) 181*2654012fSReza Sabdar bufs->tbs_buffer_out = 0; 182*2654012fSReza Sabdar 183*2654012fSReza Sabdar (void) mutex_unlock(&bufs->tbs_mtx); 184*2654012fSReza Sabdar return (&bufs->tbs_buffer[bufs->tbs_buffer_out]); 185*2654012fSReza Sabdar } 186*2654012fSReza Sabdar 187*2654012fSReza Sabdar 188*2654012fSReza Sabdar /* 189*2654012fSReza Sabdar * tlm_buffer_in_buf 190*2654012fSReza Sabdar * 191*2654012fSReza Sabdar * Return pointer to the next buffer in the buffer pool. 192*2654012fSReza Sabdar */ 193*2654012fSReza Sabdar tlm_buffer_t * 194*2654012fSReza Sabdar tlm_buffer_in_buf(tlm_buffers_t *bufs, int *idx) 195*2654012fSReza Sabdar { 196*2654012fSReza Sabdar tlm_buffer_t *ret; 197*2654012fSReza Sabdar 198*2654012fSReza Sabdar if (bufs == NULL) 199*2654012fSReza Sabdar return (NULL); 200*2654012fSReza Sabdar 201*2654012fSReza Sabdar (void) mutex_lock(&bufs->tbs_mtx); 202*2654012fSReza Sabdar ret = &bufs->tbs_buffer[bufs->tbs_buffer_in]; 203*2654012fSReza Sabdar if (idx) 204*2654012fSReza Sabdar *idx = bufs->tbs_buffer_in; 205*2654012fSReza Sabdar (void) mutex_unlock(&bufs->tbs_mtx); 206*2654012fSReza Sabdar return (ret); 207*2654012fSReza Sabdar } 208*2654012fSReza Sabdar 209*2654012fSReza Sabdar 210*2654012fSReza Sabdar /* 211*2654012fSReza Sabdar * tlm_buffer_out_buf 212*2654012fSReza Sabdar * 213*2654012fSReza Sabdar * Return pointer to the next buffer in the buffer pool. 214*2654012fSReza Sabdar */ 215*2654012fSReza Sabdar tlm_buffer_t * 216*2654012fSReza Sabdar tlm_buffer_out_buf(tlm_buffers_t *bufs, int *idx) 217*2654012fSReza Sabdar { 218*2654012fSReza Sabdar tlm_buffer_t *ret; 219*2654012fSReza Sabdar 220*2654012fSReza Sabdar if (bufs == NULL) 221*2654012fSReza Sabdar return (NULL); 222*2654012fSReza Sabdar 223*2654012fSReza Sabdar (void) mutex_lock(&bufs->tbs_mtx); 224*2654012fSReza Sabdar ret = &bufs->tbs_buffer[bufs->tbs_buffer_out]; 225*2654012fSReza Sabdar if (idx) 226*2654012fSReza Sabdar *idx = bufs->tbs_buffer_out; 227*2654012fSReza Sabdar (void) mutex_unlock(&bufs->tbs_mtx); 228*2654012fSReza Sabdar return (ret); 229*2654012fSReza Sabdar } 230*2654012fSReza Sabdar 231*2654012fSReza Sabdar 232*2654012fSReza Sabdar /* 233*2654012fSReza Sabdar * tlm_buffer_release_in_buf 234*2654012fSReza Sabdar * 235*2654012fSReza Sabdar * Another buffer is filled. Wake up the consumer if it's waiting for it. 236*2654012fSReza Sabdar */ 237*2654012fSReza Sabdar void 238*2654012fSReza Sabdar tlm_buffer_release_in_buf(tlm_buffers_t *bufs) 239*2654012fSReza Sabdar { 240*2654012fSReza Sabdar (void) mutex_lock(&bufs->tbs_mtx); 241*2654012fSReza Sabdar bufs->tbs_flags |= TLM_BUF_IN_READY; 242*2654012fSReza Sabdar (void) cond_signal(&bufs->tbs_in_cv); 243*2654012fSReza Sabdar (void) mutex_unlock(&bufs->tbs_mtx); 244*2654012fSReza Sabdar } 245*2654012fSReza Sabdar 246*2654012fSReza Sabdar 247*2654012fSReza Sabdar /* 248*2654012fSReza Sabdar * tlm_buffer_release_out_buf 249*2654012fSReza Sabdar * 250*2654012fSReza Sabdar * A buffer is used. Wake up the producer to re-fill a buffer if it's waiting 251*2654012fSReza Sabdar * for the buffer to be used. 252*2654012fSReza Sabdar */ 253*2654012fSReza Sabdar void 254*2654012fSReza Sabdar tlm_buffer_release_out_buf(tlm_buffers_t *bufs) 255*2654012fSReza Sabdar { 256*2654012fSReza Sabdar (void) mutex_lock(&bufs->tbs_mtx); 257*2654012fSReza Sabdar bufs->tbs_flags |= TLM_BUF_OUT_READY; 258*2654012fSReza Sabdar (void) cond_signal(&bufs->tbs_out_cv); 259*2654012fSReza Sabdar (void) mutex_unlock(&bufs->tbs_mtx); 260*2654012fSReza Sabdar } 261*2654012fSReza Sabdar 262*2654012fSReza Sabdar /* 263*2654012fSReza Sabdar * tlm_buffer_in_buf_wait 264*2654012fSReza Sabdar * 265*2654012fSReza Sabdar * Wait for the input buffer to get available. 266*2654012fSReza Sabdar */ 267*2654012fSReza Sabdar void 268*2654012fSReza Sabdar tlm_buffer_in_buf_wait(tlm_buffers_t *bufs) 269*2654012fSReza Sabdar 270*2654012fSReza Sabdar { 271*2654012fSReza Sabdar (void) mutex_lock(&bufs->tbs_mtx); 272*2654012fSReza Sabdar 273*2654012fSReza Sabdar while ((bufs->tbs_flags & TLM_BUF_IN_READY) == 0) 274*2654012fSReza Sabdar (void) cond_wait(&bufs->tbs_in_cv, &bufs->tbs_mtx); 275*2654012fSReza Sabdar 276*2654012fSReza Sabdar bufs->tbs_flags &= ~TLM_BUF_IN_READY; 277*2654012fSReza Sabdar 278*2654012fSReza Sabdar (void) mutex_unlock(&bufs->tbs_mtx); 279*2654012fSReza Sabdar } 280*2654012fSReza Sabdar 281*2654012fSReza Sabdar /* 282*2654012fSReza Sabdar * tlm_buffer_setup_timer 283*2654012fSReza Sabdar * 284*2654012fSReza Sabdar * Set up the time out value. 285*2654012fSReza Sabdar */ 286*2654012fSReza Sabdar static inline void 287*2654012fSReza Sabdar tlm_buffer_setup_timer(timestruc_t *timo, unsigned milli_timo) 288*2654012fSReza Sabdar { 289*2654012fSReza Sabdar if (milli_timo == 0) 290*2654012fSReza Sabdar milli_timo = 1; 291*2654012fSReza Sabdar 292*2654012fSReza Sabdar if (milli_timo / 1000) 293*2654012fSReza Sabdar timo->tv_sec = (milli_timo / 1000); 294*2654012fSReza Sabdar else 295*2654012fSReza Sabdar timo->tv_sec = 0; 296*2654012fSReza Sabdar timo->tv_nsec = (milli_timo % 1000) * 1000000L; 297*2654012fSReza Sabdar } 298*2654012fSReza Sabdar 299*2654012fSReza Sabdar 300*2654012fSReza Sabdar /* 301*2654012fSReza Sabdar * tlm_buffer_in_buf_timed_wait 302*2654012fSReza Sabdar * 303*2654012fSReza Sabdar * Wait for the input buffer to get ready with a time out. 304*2654012fSReza Sabdar */ 305*2654012fSReza Sabdar void 306*2654012fSReza Sabdar tlm_buffer_in_buf_timed_wait(tlm_buffers_t *bufs, unsigned int milli_timo) 307*2654012fSReza Sabdar 308*2654012fSReza Sabdar { 309*2654012fSReza Sabdar timestruc_t timo; 310*2654012fSReza Sabdar 311*2654012fSReza Sabdar tlm_buffer_setup_timer(&timo, milli_timo); 312*2654012fSReza Sabdar 313*2654012fSReza Sabdar (void) mutex_lock(&bufs->tbs_mtx); 314*2654012fSReza Sabdar 315*2654012fSReza Sabdar (void) cond_reltimedwait(&bufs->tbs_in_cv, &bufs->tbs_mtx, &timo); 316*2654012fSReza Sabdar 317*2654012fSReza Sabdar /* 318*2654012fSReza Sabdar * TLM_BUF_IN_READY doesn't matter for timedwait but clear 319*2654012fSReza Sabdar * it here so that cond_wait doesn't get the wrong result. 320*2654012fSReza Sabdar */ 321*2654012fSReza Sabdar bufs->tbs_flags &= ~TLM_BUF_IN_READY; 322*2654012fSReza Sabdar 323*2654012fSReza Sabdar (void) mutex_unlock(&bufs->tbs_mtx); 324*2654012fSReza Sabdar } 325*2654012fSReza Sabdar 326*2654012fSReza Sabdar 327*2654012fSReza Sabdar /* 328*2654012fSReza Sabdar * tlm_buffer_out_buf_timed_wait 329*2654012fSReza Sabdar * 330*2654012fSReza Sabdar * Wait for the output buffer to get ready with a time out. 331*2654012fSReza Sabdar */ 332*2654012fSReza Sabdar void 333*2654012fSReza Sabdar tlm_buffer_out_buf_timed_wait(tlm_buffers_t *bufs, unsigned int milli_timo) 334*2654012fSReza Sabdar { 335*2654012fSReza Sabdar timestruc_t timo; 336*2654012fSReza Sabdar 337*2654012fSReza Sabdar tlm_buffer_setup_timer(&timo, milli_timo); 338*2654012fSReza Sabdar 339*2654012fSReza Sabdar (void) mutex_lock(&bufs->tbs_mtx); 340*2654012fSReza Sabdar 341*2654012fSReza Sabdar (void) cond_reltimedwait(&bufs->tbs_out_cv, &bufs->tbs_mtx, &timo); 342*2654012fSReza Sabdar 343*2654012fSReza Sabdar /* 344*2654012fSReza Sabdar * TLM_BUF_OUT_READY doesn't matter for timedwait but clear 345*2654012fSReza Sabdar * it here so that cond_wait doesn't get the wrong result. 346*2654012fSReza Sabdar */ 347*2654012fSReza Sabdar bufs->tbs_flags &= ~TLM_BUF_OUT_READY; 348*2654012fSReza Sabdar 349*2654012fSReza Sabdar (void) mutex_unlock(&bufs->tbs_mtx); 350*2654012fSReza Sabdar } 351*2654012fSReza Sabdar 352*2654012fSReza Sabdar 353*2654012fSReza Sabdar /* 354*2654012fSReza Sabdar * tlm_cmd_wait 355*2654012fSReza Sabdar * 356*2654012fSReza Sabdar * TLM command synchronization typically use by command 357*2654012fSReza Sabdar * parent threads to wait for launched threads to initialize. 358*2654012fSReza Sabdar */ 359*2654012fSReza Sabdar void 360*2654012fSReza Sabdar tlm_cmd_wait(tlm_cmd_t *cmd, uint32_t event_type) 361*2654012fSReza Sabdar { 362*2654012fSReza Sabdar (void) mutex_lock(&cmd->tc_mtx); 363*2654012fSReza Sabdar 364*2654012fSReza Sabdar while ((cmd->tc_flags & event_type) == 0) 365*2654012fSReza Sabdar (void) cond_wait(&cmd->tc_cv, &cmd->tc_mtx); 366*2654012fSReza Sabdar 367*2654012fSReza Sabdar cmd->tc_flags &= ~event_type; 368*2654012fSReza Sabdar (void) mutex_unlock(&cmd->tc_mtx); 369*2654012fSReza Sabdar } 370*2654012fSReza Sabdar 371*2654012fSReza Sabdar 372*2654012fSReza Sabdar /* 373*2654012fSReza Sabdar * tlm_cmd_signal 374*2654012fSReza Sabdar * 375*2654012fSReza Sabdar * TLM command synchronization typically use by launched threads 376*2654012fSReza Sabdar * to unleash the parent thread. 377*2654012fSReza Sabdar */ 378*2654012fSReza Sabdar void 379*2654012fSReza Sabdar tlm_cmd_signal(tlm_cmd_t *cmd, uint32_t event_type) 380*2654012fSReza Sabdar { 381*2654012fSReza Sabdar (void) mutex_lock(&cmd->tc_mtx); 382*2654012fSReza Sabdar 383*2654012fSReza Sabdar cmd->tc_flags |= event_type; 384*2654012fSReza Sabdar (void) cond_signal(&cmd->tc_cv); 385*2654012fSReza Sabdar 386*2654012fSReza Sabdar (void) mutex_unlock(&cmd->tc_mtx); 387*2654012fSReza Sabdar } 388