linux/drivers/staging/intel_sst/intel_sst_stream.c
<<
>>
Prefs
   1/*
   2 *  intel_sst_stream.c - Intel SST Driver for audio engine
   3 *
   4 *  Copyright (C) 2008-10 Intel Corp
   5 *  Authors:    Vinod Koul <vinod.koul@intel.com>
   6 *              Harsha Priya <priya.harsha@intel.com>
   7 *              Dharageswari R <dharageswari.r@intel.com>
   8 *              KP Jeeja <jeeja.kp@intel.com>
   9 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  10 *
  11 *  This program is free software; you can redistribute it and/or modify
  12 *  it under the terms of the GNU General Public License as published by
  13 *  the Free Software Foundation; version 2 of the License.
  14 *
  15 *  This program is distributed in the hope that it will be useful, but
  16 *  WITHOUT ANY WARRANTY; without even the implied warranty of
  17 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18 *  General Public License for more details.
  19 *
  20 *  You should have received a copy of the GNU General Public License along
  21 *  with this program; if not, write to the Free Software Foundation, Inc.,
  22 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  23 *
  24 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  25 *
  26 *  This file contains the stream operations of SST driver
  27 */
  28
  29#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  30
  31#include <linux/pci.h>
  32#include <linux/firmware.h>
  33#include <linux/sched.h>
  34#include <linux/delay.h>
  35#include "intel_sst_ioctl.h"
  36#include "intel_sst.h"
  37#include "intel_sst_fw_ipc.h"
  38#include "intel_sst_common.h"
  39
  40/*
  41 * sst_check_device_type - Check the medfield device type
  42 *
  43 * @device: Device to be checked
  44 * @num_ch: Number of channels queried
  45 * @pcm_slot: slot to be enabled for this device
  46 *
  47 * This checks the deivce against the map and calculates pcm_slot value
  48 */
  49int sst_check_device_type(u32 device, u32 num_chan, u32 *pcm_slot)
  50{
  51        if (device >= MAX_NUM_STREAMS_MFLD) {
  52                pr_debug("device type invalid %d\n", device);
  53                return -EINVAL;
  54        }
  55        if (sst_drv_ctx->streams[device].status == STREAM_UN_INIT) {
  56                if (device == SND_SST_DEVICE_VIBRA && num_chan == 1)
  57                        *pcm_slot = 0x10;
  58                else if (device == SND_SST_DEVICE_HAPTIC && num_chan == 1)
  59                        *pcm_slot = 0x20;
  60                else if (device == SND_SST_DEVICE_IHF && num_chan == 1)
  61                        *pcm_slot = 0x04;
  62                else if (device == SND_SST_DEVICE_IHF && num_chan == 2)
  63                        *pcm_slot = 0x0C;
  64                else if (device == SND_SST_DEVICE_HEADSET && num_chan == 1)
  65                        *pcm_slot = 0x01;
  66                else if (device == SND_SST_DEVICE_HEADSET && num_chan == 2)
  67                        *pcm_slot = 0x03;
  68                else if (device == SND_SST_DEVICE_CAPTURE && num_chan == 1)
  69                        *pcm_slot = 0x01;
  70                else if (device == SND_SST_DEVICE_CAPTURE && num_chan == 2)
  71                        *pcm_slot = 0x03;
  72                else if (device == SND_SST_DEVICE_CAPTURE && num_chan == 3)
  73                        *pcm_slot = 0x07;
  74                else if (device == SND_SST_DEVICE_CAPTURE && num_chan == 4)
  75                        *pcm_slot = 0x0F;
  76                else if (device == SND_SST_DEVICE_CAPTURE && num_chan > 4)
  77                        *pcm_slot = 0x1F;
  78                else {
  79                        pr_debug("No condition satisfied.. ret err\n");
  80                        return -EINVAL;
  81                }
  82        } else {
  83                pr_debug("this stream state is not uni-init, is %d\n",
  84                                sst_drv_ctx->streams[device].status);
  85                return -EBADRQC;
  86        }
  87        pr_debug("returning slot %x\n", *pcm_slot);
  88        return 0;
  89}
  90/**
  91 * get_mrst_stream_id   -       gets a new stream id for use
  92 *
  93 * This functions searches the current streams and allocated an empty stream
  94 * lock stream_lock required to be held before calling this
  95 */
  96static unsigned int get_mrst_stream_id(void)
  97{
  98        int i;
  99
 100        for (i = 1; i <= MAX_NUM_STREAMS_MRST; i++) {
 101                if (sst_drv_ctx->streams[i].status == STREAM_UN_INIT)
 102                        return i;
 103        }
 104        pr_debug("Didn't find empty stream for mrst\n");
 105        return -EBUSY;
 106}
 107
 108/**
 109 * sst_alloc_stream - Send msg for a new stream ID
 110 *
 111 * @params:     stream params
 112 * @stream_ops: operation of stream PB/capture
 113 * @codec:      codec for stream
 114 * @device:     device stream to be allocated for
 115 *
 116 * This function is called by any function which wants to start
 117 * a new stream. This also check if a stream exists which is idle
 118 * it initializes idle stream id to this request
 119 */
 120int sst_alloc_stream(char *params, unsigned int stream_ops,
 121               u8 codec, unsigned int device)
 122{
 123        struct ipc_post *msg = NULL;
 124        struct snd_sst_alloc_params alloc_param;
 125        unsigned int pcm_slot = 0, num_ch;
 126        int str_id;
 127        struct snd_sst_stream_params *sparams;
 128        struct stream_info *str_info;
 129
 130        pr_debug("SST DBG:entering sst_alloc_stream\n");
 131        pr_debug("SST DBG:%d %d %d\n", stream_ops, codec, device);
 132
 133        BUG_ON(!params);
 134        sparams = (struct snd_sst_stream_params *)params;
 135        num_ch = sparams->uc.pcm_params.num_chan;
 136        /*check the device type*/
 137        if (sst_drv_ctx->pci_id == SST_MFLD_PCI_ID) {
 138                if (sst_check_device_type(device, num_ch, &pcm_slot))
 139                        return -EINVAL;
 140                mutex_lock(&sst_drv_ctx->stream_lock);
 141                str_id = device;
 142                mutex_unlock(&sst_drv_ctx->stream_lock);
 143                pr_debug("SST_DBG: slot %x\n", pcm_slot);
 144        } else {
 145                mutex_lock(&sst_drv_ctx->stream_lock);
 146                str_id = get_mrst_stream_id();
 147                mutex_unlock(&sst_drv_ctx->stream_lock);
 148                if (str_id <= 0)
 149                        return -EBUSY;
 150        }
 151        /*allocate device type context*/
 152        sst_init_stream(&sst_drv_ctx->streams[str_id], codec,
 153                        str_id, stream_ops, pcm_slot, device);
 154        /* send msg to FW to allocate a stream */
 155        if (sst_create_large_msg(&msg))
 156                return -ENOMEM;
 157
 158        sst_fill_header(&msg->header, IPC_IA_ALLOC_STREAM, 1, str_id);
 159        msg->header.part.data = sizeof(alloc_param) + sizeof(u32);
 160        alloc_param.str_type.codec_type = codec;
 161        alloc_param.str_type.str_type = SST_STREAM_TYPE_MUSIC;
 162        alloc_param.str_type.operation = stream_ops;
 163        alloc_param.str_type.protected_str = 0; /* non drm */
 164        alloc_param.str_type.time_slots = pcm_slot;
 165        alloc_param.str_type.result = alloc_param.str_type.reserved = 0;
 166        memcpy(&alloc_param.stream_params, params,
 167                        sizeof(struct snd_sst_stream_params));
 168
 169        memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
 170        memcpy(msg->mailbox_data + sizeof(u32), &alloc_param,
 171                        sizeof(alloc_param));
 172        str_info = &sst_drv_ctx->streams[str_id];
 173        str_info->ctrl_blk.condition = false;
 174        str_info->ctrl_blk.ret_code = 0;
 175        str_info->ctrl_blk.on = true;
 176        spin_lock(&sst_drv_ctx->list_spin_lock);
 177        list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
 178        spin_unlock(&sst_drv_ctx->list_spin_lock);
 179        sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
 180        pr_debug("SST DBG:alloc stream done\n");
 181        return str_id;
 182}
 183
 184
 185/*
 186 * sst_alloc_stream_response - process alloc reply
 187 *
 188 * @str_id:     stream id for which the stream has been allocated
 189 * @resp                the stream response from firware
 190 *
 191 * This function is called by firmware as a response to stream allcoation
 192 * request
 193 */
 194int sst_alloc_stream_response(unsigned int str_id,
 195                                struct snd_sst_alloc_response *resp)
 196{
 197        int retval = 0;
 198        struct stream_info *str_info;
 199        struct snd_sst_lib_download *lib_dnld;
 200
 201        pr_debug("SST DEBUG: stream number given = %d\n", str_id);
 202        str_info = &sst_drv_ctx->streams[str_id];
 203        if (resp->str_type.result == SST_LIB_ERR_LIB_DNLD_REQUIRED) {
 204                lib_dnld = kzalloc(sizeof(*lib_dnld), GFP_KERNEL);
 205                memcpy(lib_dnld, &resp->lib_dnld, sizeof(*lib_dnld));
 206        } else
 207                lib_dnld = NULL;
 208        if (str_info->ctrl_blk.on == true) {
 209                str_info->ctrl_blk.on = false;
 210                str_info->ctrl_blk.data = lib_dnld;
 211                str_info->ctrl_blk.condition = true;
 212                str_info->ctrl_blk.ret_code = resp->str_type.result;
 213                pr_debug("SST DEBUG: sst_alloc_stream_response: waking up.\n");
 214                wake_up(&sst_drv_ctx->wait_queue);
 215        }
 216        return retval;
 217}
 218
 219
 220/**
 221* sst_get_fw_info - Send msg to query for firmware configurations
 222* @info: out param that holds the firmare configurations
 223*
 224* This function is called when the firmware configurations are queiried for
 225*/
 226int sst_get_fw_info(struct snd_sst_fw_info *info)
 227{
 228        int retval = 0;
 229        struct ipc_post *msg = NULL;
 230
 231        pr_debug("SST DBG:sst_get_fw_info called\n");
 232
 233        if (sst_create_short_msg(&msg)) {
 234                pr_err("SST ERR: message creation failed\n");
 235                return -ENOMEM;
 236        }
 237
 238        sst_fill_header(&msg->header, IPC_IA_GET_FW_INFO, 0, 0);
 239        sst_drv_ctx->fw_info_blk.condition = false;
 240        sst_drv_ctx->fw_info_blk.ret_code = 0;
 241        sst_drv_ctx->fw_info_blk.on = true;
 242        sst_drv_ctx->fw_info_blk.data = info;
 243        spin_lock(&sst_drv_ctx->list_spin_lock);
 244        list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
 245        spin_unlock(&sst_drv_ctx->list_spin_lock);
 246        sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
 247        retval = sst_wait_interruptible_timeout(sst_drv_ctx,
 248                        &sst_drv_ctx->fw_info_blk, SST_BLOCK_TIMEOUT);
 249        if (retval) {
 250                pr_err("SST ERR: error in fw_info = %d\n", retval);
 251                retval = -EIO;
 252        }
 253        return retval;
 254}
 255
 256
 257/**
 258* sst_pause_stream - Send msg for a pausing stream
 259* @str_id:       stream ID
 260*
 261* This function is called by any function which wants to pause
 262* an already running stream.
 263*/
 264int sst_start_stream(int str_id)
 265{
 266        int retval = 0;
 267        struct ipc_post *msg = NULL;
 268        struct stream_info *str_info;
 269
 270        pr_debug("sst_start_stream for %d\n", str_id);
 271        retval = sst_validate_strid(str_id);
 272        if (retval)
 273                return retval;
 274        str_info = &sst_drv_ctx->streams[str_id];
 275        if (str_info->status != STREAM_INIT)
 276                return -EBADRQC;
 277        if (sst_create_short_msg(&msg))
 278                return -ENOMEM;
 279
 280        sst_fill_header(&msg->header, IPC_IA_START_STREAM, 0, str_id);
 281        spin_lock(&sst_drv_ctx->list_spin_lock);
 282        list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
 283        spin_unlock(&sst_drv_ctx->list_spin_lock);
 284        sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
 285        return retval;
 286}
 287
 288/*
 289 * sst_pause_stream - Send msg for a pausing stream
 290 * @str_id:      stream ID
 291 *
 292 * This function is called by any function which wants to pause
 293 * an already running stream.
 294 */
 295int sst_pause_stream(int str_id)
 296{
 297        int retval = 0;
 298        struct ipc_post *msg = NULL;
 299        struct stream_info *str_info;
 300
 301        pr_debug("SST DBG:sst_pause_stream for %d\n", str_id);
 302        retval = sst_validate_strid(str_id);
 303        if (retval)
 304                return retval;
 305        str_info = &sst_drv_ctx->streams[str_id];
 306        if (str_info->status == STREAM_PAUSED)
 307                return 0;
 308        if (str_info->status == STREAM_RUNNING ||
 309                str_info->status == STREAM_INIT) {
 310                if (str_info->prev == STREAM_UN_INIT)
 311                        return -EBADRQC;
 312                if (str_info->ctrl_blk.on == true) {
 313                        pr_err("SST ERR: control path is in use\n");
 314                        return -EINVAL;
 315                }
 316                if (sst_create_short_msg(&msg))
 317                        return -ENOMEM;
 318
 319                sst_fill_header(&msg->header, IPC_IA_PAUSE_STREAM, 0, str_id);
 320                str_info->ctrl_blk.condition = false;
 321                str_info->ctrl_blk.ret_code = 0;
 322                str_info->ctrl_blk.on = true;
 323                spin_lock(&sst_drv_ctx->list_spin_lock);
 324                list_add_tail(&msg->node,
 325                                &sst_drv_ctx->ipc_dispatch_list);
 326                spin_unlock(&sst_drv_ctx->list_spin_lock);
 327                sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
 328                retval = sst_wait_interruptible_timeout(sst_drv_ctx,
 329                                &str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
 330                if (retval == 0) {
 331                        str_info->prev = str_info->status;
 332                        str_info->status = STREAM_PAUSED;
 333                } else if (retval == SST_ERR_INVALID_STREAM_ID) {
 334                        retval = -EINVAL;
 335                        mutex_lock(&sst_drv_ctx->stream_lock);
 336                        sst_clean_stream(str_info);
 337                        mutex_unlock(&sst_drv_ctx->stream_lock);
 338                }
 339        } else {
 340                retval = -EBADRQC;
 341                pr_err("SST ERR: BADQRC for stream\n");
 342        }
 343
 344        return retval;
 345}
 346
 347/**
 348 * sst_resume_stream - Send msg for resuming stream
 349 * @str_id:             stream ID
 350 *
 351 * This function is called by any function which wants to resume
 352 * an already paused stream.
 353 */
 354int sst_resume_stream(int str_id)
 355{
 356        int retval = 0;
 357        struct ipc_post *msg = NULL;
 358        struct stream_info *str_info;
 359
 360        pr_debug("SST DBG:sst_resume_stream for %d\n", str_id);
 361        retval = sst_validate_strid(str_id);
 362        if (retval)
 363                return retval;
 364        str_info = &sst_drv_ctx->streams[str_id];
 365        if (str_info->status == STREAM_RUNNING)
 366                        return 0;
 367        if (str_info->status == STREAM_PAUSED) {
 368                if (str_info->ctrl_blk.on == true) {
 369                        pr_err("SST ERR: control path in use\n");
 370                        return -EINVAL;
 371                }
 372                if (sst_create_short_msg(&msg)) {
 373                        pr_err("SST ERR: mem allocation failed\n");
 374                        return -ENOMEM;
 375                }
 376                sst_fill_header(&msg->header, IPC_IA_RESUME_STREAM, 0, str_id);
 377                str_info->ctrl_blk.condition = false;
 378                str_info->ctrl_blk.ret_code = 0;
 379                str_info->ctrl_blk.on = true;
 380                spin_lock(&sst_drv_ctx->list_spin_lock);
 381                list_add_tail(&msg->node,
 382                                &sst_drv_ctx->ipc_dispatch_list);
 383                spin_unlock(&sst_drv_ctx->list_spin_lock);
 384                sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
 385                retval = sst_wait_interruptible_timeout(sst_drv_ctx,
 386                                &str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
 387                if (!retval) {
 388                        if (str_info->prev == STREAM_RUNNING)
 389                                str_info->status = STREAM_RUNNING;
 390                        else
 391                                str_info->status = STREAM_INIT;
 392                        str_info->prev = STREAM_PAUSED;
 393                } else if (retval == -SST_ERR_INVALID_STREAM_ID) {
 394                        retval = -EINVAL;
 395                        mutex_lock(&sst_drv_ctx->stream_lock);
 396                        sst_clean_stream(str_info);
 397                        mutex_unlock(&sst_drv_ctx->stream_lock);
 398                }
 399        } else {
 400                retval = -EBADRQC;
 401                pr_err("SST ERR: BADQRC for stream\n");
 402        }
 403
 404        return retval;
 405}
 406
 407
 408/**
 409 * sst_drop_stream - Send msg for stopping stream
 410 * @str_id:             stream ID
 411 *
 412 * This function is called by any function which wants to stop
 413 * a stream.
 414 */
 415int sst_drop_stream(int str_id)
 416{
 417        int retval = 0;
 418        struct ipc_post *msg = NULL;
 419        struct sst_stream_bufs *bufs = NULL, *_bufs;
 420        struct stream_info *str_info;
 421
 422        pr_debug("SST DBG:sst_drop_stream for %d\n", str_id);
 423        retval = sst_validate_strid(str_id);
 424        if (retval)
 425                return retval;
 426        str_info = &sst_drv_ctx->streams[str_id];
 427
 428        if (str_info->status != STREAM_UN_INIT &&
 429                str_info->status != STREAM_DECODE) {
 430                if (str_info->ctrl_blk.on == true) {
 431                        pr_err("SST ERR: control path in use\n");
 432                        return -EINVAL;
 433                }
 434                if (sst_create_short_msg(&msg)) {
 435                        pr_err("SST ERR: mem allocation failed\n");
 436                        return -ENOMEM;
 437                }
 438                sst_fill_header(&msg->header, IPC_IA_DROP_STREAM, 0, str_id);
 439                str_info->ctrl_blk.condition = false;
 440                str_info->ctrl_blk.ret_code = 0;
 441                str_info->ctrl_blk.on = true;
 442                spin_lock(&sst_drv_ctx->list_spin_lock);
 443                list_add_tail(&msg->node,
 444                                &sst_drv_ctx->ipc_dispatch_list);
 445                spin_unlock(&sst_drv_ctx->list_spin_lock);
 446                sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
 447                retval = sst_wait_interruptible_timeout(sst_drv_ctx,
 448                                &str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
 449                if (!retval) {
 450                        pr_debug("SST DBG:drop success\n");
 451                        str_info->prev = STREAM_UN_INIT;
 452                        str_info->status = STREAM_INIT;
 453                        if (str_info->src != MAD_DRV) {
 454                                mutex_lock(&str_info->lock);
 455                                list_for_each_entry_safe(bufs, _bufs,
 456                                                        &str_info->bufs, node) {
 457                                        list_del(&bufs->node);
 458                                        kfree(bufs);
 459                                }
 460                                mutex_unlock(&str_info->lock);
 461                        }
 462                        str_info->cumm_bytes += str_info->curr_bytes;
 463                } else if (retval == -SST_ERR_INVALID_STREAM_ID) {
 464                        retval = -EINVAL;
 465                        mutex_lock(&sst_drv_ctx->stream_lock);
 466                        sst_clean_stream(str_info);
 467                        mutex_unlock(&sst_drv_ctx->stream_lock);
 468                }
 469                if (str_info->data_blk.on == true) {
 470                        str_info->data_blk.condition = true;
 471                        str_info->data_blk.ret_code = retval;
 472                        wake_up(&sst_drv_ctx->wait_queue);
 473                }
 474        } else {
 475                retval = -EBADRQC;
 476                pr_err("SST ERR: BADQRC for stream\n");
 477        }
 478        return retval;
 479}
 480
 481/**
 482* sst_drain_stream - Send msg for draining stream
 483* @str_id:              stream ID
 484*
 485* This function is called by any function which wants to drain
 486* a stream.
 487*/
 488int sst_drain_stream(int str_id)
 489{
 490        int retval = 0;
 491        struct ipc_post *msg = NULL;
 492        struct stream_info *str_info;
 493
 494        pr_debug("SST DBG:sst_drain_stream for %d\n", str_id);
 495        retval = sst_validate_strid(str_id);
 496        if (retval)
 497                return retval;
 498        str_info = &sst_drv_ctx->streams[str_id];
 499
 500        if (str_info->status != STREAM_RUNNING &&
 501                str_info->status != STREAM_INIT &&
 502                str_info->status != STREAM_PAUSED) {
 503                        pr_err("SST ERR: BADQRC for stream = %d\n",
 504                                       str_info->status);
 505                        return -EBADRQC;
 506        }
 507
 508        if (str_info->status == STREAM_INIT) {
 509                if (sst_create_short_msg(&msg)) {
 510                        pr_err("SST ERR: mem allocation failed\n");
 511                        return -ENOMEM;
 512                }
 513                sst_fill_header(&msg->header, IPC_IA_DRAIN_STREAM, 0, str_id);
 514                spin_lock(&sst_drv_ctx->list_spin_lock);
 515                list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
 516                spin_unlock(&sst_drv_ctx->list_spin_lock);
 517                sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
 518        } else
 519                str_info->need_draining = true;
 520        str_info->data_blk.condition = false;
 521        str_info->data_blk.ret_code = 0;
 522        str_info->data_blk.on = true;
 523        retval = sst_wait_interruptible(sst_drv_ctx, &str_info->data_blk);
 524        str_info->need_draining = false;
 525        return retval;
 526}
 527
 528/**
 529 * sst_free_stream - Frees a stream
 530 * @str_id:             stream ID
 531 *
 532 * This function is called by any function which wants to free
 533 * a stream.
 534 */
 535int sst_free_stream(int str_id)
 536{
 537        int retval = 0;
 538        struct ipc_post *msg = NULL;
 539        struct stream_info *str_info;
 540
 541        pr_debug("SST DBG:sst_free_stream for %d\n", str_id);
 542
 543        retval = sst_validate_strid(str_id);
 544        if (retval)
 545                return retval;
 546        str_info = &sst_drv_ctx->streams[str_id];
 547
 548        if (str_info->status != STREAM_UN_INIT) {
 549                if (sst_create_short_msg(&msg)) {
 550                        pr_err("SST ERR: mem allocation failed\n");
 551                        return -ENOMEM;
 552                }
 553                sst_fill_header(&msg->header, IPC_IA_FREE_STREAM, 0, str_id);
 554                spin_lock(&sst_drv_ctx->list_spin_lock);
 555                list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
 556                spin_unlock(&sst_drv_ctx->list_spin_lock);
 557                sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
 558                str_info->prev =  str_info->status;
 559                str_info->status = STREAM_UN_INIT;
 560                if (str_info->data_blk.on == true) {
 561                        str_info->data_blk.condition = true;
 562                        str_info->data_blk.ret_code = 0;
 563                        wake_up(&sst_drv_ctx->wait_queue);
 564                }
 565                str_info->data_blk.on = true;
 566                str_info->data_blk.condition = false;
 567                retval = sst_wait_interruptible_timeout(sst_drv_ctx,
 568                                &str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
 569                pr_debug("wait for free returned %d\n", retval);
 570                msleep(100);
 571                mutex_lock(&sst_drv_ctx->stream_lock);
 572                sst_clean_stream(str_info);
 573                mutex_unlock(&sst_drv_ctx->stream_lock);
 574                pr_debug("SST DBG:Stream freed\n");
 575        } else {
 576                retval = -EBADRQC;
 577                pr_debug("SST DBG:BADQRC for stream\n");
 578        }
 579
 580        return retval;
 581}
 582
 583
 584