static void sst_byt_stream_update(struct sst_byt *byt, struct ipc_message *msg)
 {
        struct sst_byt_stream *stream;
-       u64 header = msg->header;
+       u64 header = msg->tx.header;
        u8 stream_id = sst_byt_header_str_id(header);
        u8 stream_msg = sst_byt_header_msg_id(header);
 
        if (msg == NULL)
                return 1;
 
+       msg->rx.header = header;
        if (header & IPC_HEADER_LARGE(true)) {
-               msg->rx_size = sst_byt_header_data(header);
-               sst_dsp_inbox_read(byt->dsp, msg->rx_data, msg->rx_size);
+               msg->rx.size = sst_byt_header_data(header);
+               sst_dsp_inbox_read(byt->dsp, msg->rx.data, msg->rx.size);
        }
 
        /* update any stream states */
 
 int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream)
 {
-       struct sst_byt_alloc_params *str_req = &stream->request;
-       struct sst_byt_alloc_response *reply = &stream->reply;
-       u64 header;
+       struct sst_ipc_message request, reply = {0};
        int ret;
 
-       header = sst_byt_header(IPC_IA_ALLOC_STREAM,
-                               sizeof(*str_req) + sizeof(u32),
+       request.header = sst_byt_header(IPC_IA_ALLOC_STREAM,
+                               sizeof(stream->request) + sizeof(u32),
                                true, stream->str_id);
-       ret = sst_ipc_tx_message_wait(&byt->ipc, header, str_req,
-                                     sizeof(*str_req),
-                                     reply, sizeof(*reply));
+       request.data = &stream->request;
+       request.size = sizeof(stream->request);
+       reply.data = &stream->reply;
+       reply.size = sizeof(stream->reply);
+
+       ret = sst_ipc_tx_message_wait(&byt->ipc, request, &reply);
        if (ret < 0) {
                dev_err(byt->dev, "ipc: error stream commit failed\n");
                return ret;
 
 int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream)
 {
-       u64 header;
+       struct sst_ipc_message request = {0};
        int ret = 0;
        struct sst_dsp *sst = byt->dsp;
        unsigned long flags;
        if (!stream->commited)
                goto out;
 
-       header = sst_byt_header(IPC_IA_FREE_STREAM, 0, false, stream->str_id);
-       ret = sst_ipc_tx_message_wait(&byt->ipc, header, NULL, 0, NULL, 0);
+       request.header = sst_byt_header(IPC_IA_FREE_STREAM,
+                       0, false, stream->str_id);
+       ret = sst_ipc_tx_message_wait(&byt->ipc, request, NULL);
        if (ret < 0) {
                dev_err(byt->dev, "ipc: free stream %d failed\n",
                        stream->str_id);
 static int sst_byt_stream_operations(struct sst_byt *byt, int type,
                                     int stream_id, int wait)
 {
-       u64 header;
+       struct sst_ipc_message request = {0};
 
-       header = sst_byt_header(type, 0, false, stream_id);
+       request.header = sst_byt_header(type, 0, false, stream_id);
        if (wait)
-               return sst_ipc_tx_message_wait(&byt->ipc, header, NULL,
-                                               0, NULL, 0);
+               return sst_ipc_tx_message_wait(&byt->ipc, request, NULL);
        else
-               return sst_ipc_tx_message_nowait(&byt->ipc, header,
-                                               NULL, 0);
+               return sst_ipc_tx_message_nowait(&byt->ipc, request);
 }
 
 /* stream ALSA trigger operations */
                         u32 start_offset)
 {
        struct sst_byt_start_stream_params start_stream;
-       void *tx_msg;
-       size_t size;
-       u64 header;
+       struct sst_ipc_message request;
        int ret;
 
        start_stream.byte_offset = start_offset;
-       header = sst_byt_header(IPC_IA_START_STREAM,
+       request.header = sst_byt_header(IPC_IA_START_STREAM,
                                sizeof(start_stream) + sizeof(u32),
                                true, stream->str_id);
-       tx_msg = &start_stream;
-       size = sizeof(start_stream);
+       request.data = &start_stream;
+       request.size = sizeof(start_stream);
 
-       ret = sst_ipc_tx_message_nowait(&byt->ipc, header, tx_msg, size);
+       ret = sst_ipc_tx_message_nowait(&byt->ipc, request);
        if (ret < 0)
                dev_err(byt->dev, "ipc: error failed to start stream %d\n",
                        stream->str_id);
 
 static void byt_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
 {
-       if (msg->header & IPC_HEADER_LARGE(true))
-               sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size);
+       if (msg->tx.header & IPC_HEADER_LARGE(true))
+               sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size);
 
-       sst_dsp_shim_write64_unlocked(ipc->dsp, SST_IPCX, msg->header);
+       sst_dsp_shim_write64_unlocked(ipc->dsp, SST_IPCX, msg->tx.header);
 }
 
 static void byt_shim_dbg(struct sst_generic_ipc *ipc, const char *text)
        size_t tx_size)
 {
        /* msg content = lower 32-bit of the header + data */
-       *(u32 *)msg->tx_data = (u32)(msg->header & (u32)-1);
-       memcpy(msg->tx_data + sizeof(u32), tx_data, tx_size);
-       msg->tx_size += sizeof(u32);
+       *(u32 *)msg->tx.data = (u32)(msg->tx.header & (u32)-1);
+       memcpy(msg->tx.data + sizeof(u32), tx_data, tx_size);
+       msg->tx.size += sizeof(u32);
 }
 
 static u64 byt_reply_msg_match(u64 header, u64 *mask)
 
 }
 
 static int tx_wait_done(struct sst_generic_ipc *ipc,
-       struct ipc_message *msg, void *rx_data)
+       struct ipc_message *msg, struct sst_ipc_message *reply)
 {
        unsigned long flags;
        int ret;
        } else {
 
                /* copy the data returned from DSP */
-               if (rx_data)
-                       memcpy(rx_data, msg->rx_data, msg->rx_size);
+               if (reply) {
+                       reply->header = msg->rx.header;
+                       if (reply->data)
+                               memcpy(reply->data, msg->rx.data, msg->rx.size);
+               }
                ret = msg->errno;
        }
 
        return ret;
 }
 
-static int ipc_tx_message(struct sst_generic_ipc *ipc, u64 header,
-       void *tx_data, size_t tx_bytes, void *rx_data,
-       size_t rx_bytes, int wait)
+static int ipc_tx_message(struct sst_generic_ipc *ipc,
+       struct sst_ipc_message request,
+       struct sst_ipc_message *reply, int wait)
 {
        struct ipc_message *msg;
        unsigned long flags;
                return -EBUSY;
        }
 
-       msg->header = header;
-       msg->tx_size = tx_bytes;
-       msg->rx_size = rx_bytes;
+       msg->tx.header = request.header;
+       msg->tx.size = request.size;
+       msg->rx.header = 0;
+       msg->rx.size = reply ? reply->size : 0;
        msg->wait = wait;
        msg->errno = 0;
        msg->pending = false;
        msg->complete = false;
 
-       if ((tx_bytes) && (ipc->ops.tx_data_copy != NULL))
-               ipc->ops.tx_data_copy(msg, tx_data, tx_bytes);
+       if ((request.size) && (ipc->ops.tx_data_copy != NULL))
+               ipc->ops.tx_data_copy(msg, request.data, request.size);
 
        list_add_tail(&msg->list, &ipc->tx_list);
        schedule_work(&ipc->kwork);
        spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
 
        if (wait)
-               return tx_wait_done(ipc, msg, rx_data);
+               return tx_wait_done(ipc, msg, reply);
        else
                return 0;
 }
                return -ENOMEM;
 
        for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) {
-               ipc->msg[i].tx_data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL);
-               if (ipc->msg[i].tx_data == NULL)
+               ipc->msg[i].tx.data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL);
+               if (ipc->msg[i].tx.data == NULL)
                        goto free_mem;
 
-               ipc->msg[i].rx_data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL);
-               if (ipc->msg[i].rx_data == NULL) {
-                       kfree(ipc->msg[i].tx_data);
+               ipc->msg[i].rx.data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL);
+               if (ipc->msg[i].rx.data == NULL) {
+                       kfree(ipc->msg[i].tx.data);
                        goto free_mem;
                }
 
 
 free_mem:
        while (i > 0) {
-               kfree(ipc->msg[i-1].tx_data);
-               kfree(ipc->msg[i-1].rx_data);
+               kfree(ipc->msg[i-1].tx.data);
+               kfree(ipc->msg[i-1].rx.data);
                --i;
        }
        kfree(ipc->msg);
        spin_unlock_irq(&ipc->dsp->spinlock);
 }
 
-int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header,
-       void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes)
+int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc,
+       struct sst_ipc_message request, struct sst_ipc_message *reply)
 {
        int ret;
 
                if (ipc->ops.check_dsp_lp_on(ipc->dsp, true))
                        return -EIO;
 
-       ret = ipc_tx_message(ipc, header, tx_data, tx_bytes,
-               rx_data, rx_bytes, 1);
+       ret = ipc_tx_message(ipc, request, reply, 1);
 
        if (ipc->ops.check_dsp_lp_on)
                if (ipc->ops.check_dsp_lp_on(ipc->dsp, false))
 }
 EXPORT_SYMBOL_GPL(sst_ipc_tx_message_wait);
 
-int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, u64 header,
-       void *tx_data, size_t tx_bytes)
+int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc,
+       struct sst_ipc_message request)
 {
-       return ipc_tx_message(ipc, header, tx_data, tx_bytes,
-               NULL, 0, 0);
+       return ipc_tx_message(ipc, request, NULL, 0);
 }
 EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nowait);
 
-int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, u64 header,
-       void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes)
+int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc,
+       struct sst_ipc_message request, struct sst_ipc_message *reply)
 {
-       return ipc_tx_message(ipc, header, tx_data, tx_bytes,
-               rx_data, rx_bytes, 1);
+       return ipc_tx_message(ipc, request, reply, 1);
 }
 EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nopm);
 
        }
 
        list_for_each_entry(msg, &ipc->rx_list, list) {
-               if ((msg->header & mask) == header)
+               if ((msg->tx.header & mask) == header)
                        return msg;
        }
 
 
        if (ipc->msg) {
                for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) {
-                       kfree(ipc->msg[i].tx_data);
-                       kfree(ipc->msg[i].rx_data);
+                       kfree(ipc->msg[i].tx.data);
+                       kfree(ipc->msg[i].rx.data);
                }
                kfree(ipc->msg);
        }
 
 
 #define IPC_MAX_MAILBOX_BYTES  256
 
-struct ipc_message {
-       struct list_head list;
+struct sst_ipc_message {
        u64 header;
+       void *data;
+       size_t size;
+};
 
-       /* direction wrt host CPU */
-       char *tx_data;
-       size_t tx_size;
-       char *rx_data;
-       size_t rx_size;
+struct ipc_message {
+       struct list_head list;
+       struct sst_ipc_message tx;
+       struct sst_ipc_message rx;
 
        wait_queue_head_t waitq;
        bool pending;
        struct sst_plat_ipc_ops ops;
 };
 
-int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header,
-       void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes);
+int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc,
+       struct sst_ipc_message request, struct sst_ipc_message *reply);
 
-int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, u64 header,
-       void *tx_data, size_t tx_bytes);
+int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc,
+       struct sst_ipc_message request);
 
-int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc, u64 header,
-       void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes);
+int sst_ipc_tx_message_nopm(struct sst_generic_ipc *ipc,
+       struct sst_ipc_message request, struct sst_ipc_message *reply);
 
 struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc,
        u64 header);
 
 static void hsw_stream_update(struct sst_hsw *hsw, struct ipc_message *msg)
 {
        struct sst_hsw_stream *stream;
-       u32 header = msg->header & ~(IPC_STATUS_MASK | IPC_GLB_REPLY_MASK);
+       u32 header = msg->tx.header & ~(IPC_STATUS_MASK | IPC_GLB_REPLY_MASK);
        u32 stream_id = msg_get_stream_id(header);
        u32 stream_msg = msg_get_stream_type(header);
 
                return -EIO;
        }
 
+       msg->rx.header = header;
        /* first process the header */
        switch (reply) {
        case IPC_GLB_REPLY_PENDING:
        case IPC_GLB_REPLY_SUCCESS:
                if (msg->pending) {
                        trace_ipc_pending_reply("completed", header);
-                       sst_dsp_inbox_read(hsw->dsp, msg->rx_data,
-                               msg->rx_size);
+                       sst_dsp_inbox_read(hsw->dsp, msg->rx.data,
+                               msg->rx.size);
                        hsw->ipc.pending = false;
                } else {
                        /* copy data from the DSP */
-                       sst_dsp_outbox_read(hsw->dsp, msg->rx_data,
-                               msg->rx_size);
+                       sst_dsp_outbox_read(hsw->dsp, msg->rx.data,
+                               msg->rx.size);
                }
                break;
        /* these will be rare - but useful for debug */
 int sst_hsw_fw_get_version(struct sst_hsw *hsw,
        struct sst_hsw_ipc_fw_version *version)
 {
+       struct sst_ipc_message request = {0}, reply = {0};
        int ret;
 
-       ret = sst_ipc_tx_message_wait(&hsw->ipc,
-               IPC_GLB_TYPE(IPC_GLB_GET_FW_VERSION),
-               NULL, 0, version, sizeof(*version));
+       request.header = IPC_GLB_TYPE(IPC_GLB_GET_FW_VERSION);
+       reply.data = version;
+       reply.size = sizeof(*version);
+       ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply);
        if (ret < 0)
                dev_err(hsw->dev, "error: get version failed\n");
 
        struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume)
 {
        struct sst_hsw_ipc_volume_req *req;
-       u32 header;
+       struct sst_ipc_message request;
        int ret;
 
        trace_ipc_request("set stream volume", stream->reply.stream_hw_id);
        if (channel >= 2 && channel != SST_HSW_CHANNELS_ALL)
                return -EINVAL;
 
-       header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) |
+       request.header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) |
                IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE);
-       header |= (stream->reply.stream_hw_id << IPC_STR_ID_SHIFT);
-       header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT);
-       header |= (stage_id << IPC_STG_ID_SHIFT);
+       request.header |= (stream->reply.stream_hw_id << IPC_STR_ID_SHIFT);
+       request.header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT);
+       request.header |= (stage_id << IPC_STG_ID_SHIFT);
 
        req = &stream->vol_req;
        req->target_volume = volume;
                req->channel = channel;
        }
 
-       ret = sst_ipc_tx_message_wait(&hsw->ipc, header, req,
-               sizeof(*req), NULL, 0);
+       request.data = req;
+       request.size = sizeof(*req);
+       ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
        if (ret < 0) {
                dev_err(hsw->dev, "error: set stream volume failed\n");
                return ret;
        u32 volume)
 {
        struct sst_hsw_ipc_volume_req req;
-       u32 header;
+       struct sst_ipc_message request;
        int ret;
 
        trace_ipc_request("set mixer volume", volume);
                req.channel = channel;
        }
 
-       header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) |
+       request.header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) |
                IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE);
-       header |= (hsw->mixer_info.mixer_hw_id << IPC_STR_ID_SHIFT);
-       header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT);
-       header |= (stage_id << IPC_STG_ID_SHIFT);
+       request.header |= (hsw->mixer_info.mixer_hw_id << IPC_STR_ID_SHIFT);
+       request.header |= (IPC_STG_SET_VOLUME << IPC_STG_TYPE_SHIFT);
+       request.header |= (stage_id << IPC_STG_ID_SHIFT);
 
        req.curve_duration = hsw->curve_duration;
        req.curve_type = hsw->curve_type;
        req.target_volume = volume;
 
-       ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &req,
-               sizeof(req), NULL, 0);
+       request.data = &req;
+       request.size = sizeof(req);
+       ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
        if (ret < 0) {
                dev_err(hsw->dev, "error: set mixer volume failed\n");
                return ret;
 
 int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
 {
-       u32 header;
+       struct sst_ipc_message request;
        int ret = 0;
        struct sst_dsp *sst = hsw->dsp;
        unsigned long flags;
        trace_ipc_request("stream free", stream->host_id);
 
        stream->free_req.stream_id = stream->reply.stream_hw_id;
-       header = IPC_GLB_TYPE(IPC_GLB_FREE_STREAM);
+       request.header = IPC_GLB_TYPE(IPC_GLB_FREE_STREAM);
+       request.data = &stream->free_req;
+       request.size = sizeof(stream->free_req);
 
-       ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &stream->free_req,
-               sizeof(stream->free_req), NULL, 0);
+       ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
        if (ret < 0) {
                dev_err(hsw->dev, "error: free stream %d failed\n",
                        stream->free_req.stream_id);
 
 int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
 {
-       struct sst_hsw_ipc_stream_alloc_req *str_req = &stream->request;
-       struct sst_hsw_ipc_stream_alloc_reply *reply = &stream->reply;
-       u32 header;
+       struct sst_ipc_message request, reply = {0};
        int ret;
 
        if (!stream) {
 
        trace_ipc_request("stream alloc", stream->host_id);
 
-       header = IPC_GLB_TYPE(IPC_GLB_ALLOCATE_STREAM);
+       request.header = IPC_GLB_TYPE(IPC_GLB_ALLOCATE_STREAM);
+       request.data = &stream->request;
+       request.size = sizeof(stream->request);
+       reply.data = &stream->reply;
+       reply.size = sizeof(stream->reply);
 
-       ret = sst_ipc_tx_message_wait(&hsw->ipc, header, str_req,
-               sizeof(*str_req), reply, sizeof(*reply));
+       ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply);
        if (ret < 0) {
                dev_err(hsw->dev, "error: stream commit failed\n");
                return ret;
  ABI to be opaque to client PCM drivers to cope with any future ABI changes */
 int sst_hsw_mixer_get_info(struct sst_hsw *hsw)
 {
-       struct sst_hsw_ipc_stream_info_reply *reply;
-       u32 header;
+       struct sst_ipc_message request = {0}, reply = {0};
        int ret;
 
-       reply = &hsw->mixer_info;
-       header = IPC_GLB_TYPE(IPC_GLB_GET_MIXER_STREAM_INFO);
+       request.header = IPC_GLB_TYPE(IPC_GLB_GET_MIXER_STREAM_INFO);
+       reply.data = &hsw->mixer_info;
+       reply.size = sizeof(hsw->mixer_info);
 
        trace_ipc_request("get global mixer info", 0);
 
-       ret = sst_ipc_tx_message_wait(&hsw->ipc, header, NULL, 0,
-               reply, sizeof(*reply));
+       ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply);
        if (ret < 0) {
                dev_err(hsw->dev, "error: get stream info failed\n");
                return ret;
        }
 
-       trace_hsw_mixer_info_reply(reply);
+       trace_hsw_mixer_info_reply(&hsw->mixer_info);
 
        return 0;
 }
 static int sst_hsw_stream_operations(struct sst_hsw *hsw, int type,
        int stream_id, int wait)
 {
-       u32 header;
+       struct sst_ipc_message request = {0};
 
-       header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) | IPC_STR_TYPE(type);
-       header |= (stream_id << IPC_STR_ID_SHIFT);
+       request.header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE);
+       request.header |= IPC_STR_TYPE(type) | (stream_id << IPC_STR_ID_SHIFT);
 
        if (wait)
-               return sst_ipc_tx_message_wait(&hsw->ipc, header,
-                       NULL, 0, NULL, 0);
+               return sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
        else
-               return sst_ipc_tx_message_nowait(&hsw->ipc, header, NULL, 0);
+               return sst_ipc_tx_message_nowait(&hsw->ipc, request);
 }
 
 /* Stream ALSA trigger operations */
        enum sst_hsw_device_id dev, enum sst_hsw_device_mclk mclk,
        enum sst_hsw_device_mode mode, u32 clock_divider)
 {
+       struct sst_ipc_message request;
        struct sst_hsw_ipc_device_config_req config;
-       u32 header;
        int ret;
 
        trace_ipc_request("set device config", dev);
 
        trace_hsw_device_config_req(&config);
 
-       header = IPC_GLB_TYPE(IPC_GLB_SET_DEVICE_FORMATS);
+       request.header = IPC_GLB_TYPE(IPC_GLB_SET_DEVICE_FORMATS);
+       request.data = &config;
+       request.size = sizeof(config);
 
-       ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &config,
-               sizeof(config), NULL, 0);
+       ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
        if (ret < 0)
                dev_err(hsw->dev, "error: set device formats failed\n");
 
 int sst_hsw_dx_set_state(struct sst_hsw *hsw,
        enum sst_hsw_dx_state state, struct sst_hsw_ipc_dx_reply *dx)
 {
-       u32 header, state_;
+       struct sst_ipc_message request, reply = {0};
+       u32 state_;
        int ret, item;
 
-       header = IPC_GLB_TYPE(IPC_GLB_ENTER_DX_STATE);
        state_ = state;
+       request.header = IPC_GLB_TYPE(IPC_GLB_ENTER_DX_STATE);
+       request.data = &state_;
+       request.size = sizeof(state_);
+       reply.data = dx;
+       reply.size = sizeof(*dx);
 
        trace_ipc_request("PM enter Dx state", state);
 
-       ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &state_,
-               sizeof(state_), dx, sizeof(*dx));
+       ret = sst_ipc_tx_message_wait(&hsw->ipc, request, &reply);
        if (ret < 0) {
                dev_err(hsw->dev, "ipc: error set dx state %d failed\n", state);
                return ret;
        u32 module_id, u32 instance_id)
 {
        int ret;
-       u32 header = 0;
+       struct sst_ipc_message request;
        struct sst_hsw_ipc_module_config config;
        struct sst_module *module;
        struct sst_module_runtime *runtime;
                return -ENXIO;
        }
 
-       header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
+       request.header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
                        IPC_MODULE_OPERATION(IPC_MODULE_ENABLE) |
                        IPC_MODULE_ID(module_id);
-       dev_dbg(dev, "module enable header: %x\n", header);
+       dev_dbg(dev, "module enable header: %x\n", (u32)request.header);
 
        config.map.module_entries_count = 1;
        config.map.module_entries[0].module_id = module->id;
                config.scratch_mem.size, config.scratch_mem.offset,
                config.map.module_entries[0].entry_point);
 
-       ret = sst_ipc_tx_message_wait(&hsw->ipc, header,
-                       &config, sizeof(config), NULL, 0);
+       request.data = &config;
+       request.size = sizeof(config);
+       ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
        if (ret < 0)
                dev_err(dev, "ipc: module enable failed - %d\n", ret);
        else
        u32 module_id, u32 instance_id)
 {
        int ret;
-       u32 header;
+       struct sst_ipc_message request = {0};
        struct sst_module *module;
        struct device *dev = hsw->dev;
        struct sst_dsp *dsp = hsw->dsp;
                return -ENXIO;
        }
 
-       header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
+       request.header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
                        IPC_MODULE_OPERATION(IPC_MODULE_DISABLE) |
                        IPC_MODULE_ID(module_id);
 
-       ret = sst_ipc_tx_message_wait(&hsw->ipc, header,  NULL, 0, NULL, 0);
+       ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
        if (ret < 0)
                dev_err(dev, "module disable failed - %d\n", ret);
        else
        u32 param_size, char *param)
 {
        int ret;
-       u32 header = 0;
-       u32 payload_size = 0, transfer_parameter_size = 0;
+       struct sst_ipc_message request = {0};
+       u32 payload_size = 0;
        struct sst_hsw_transfer_parameter *parameter;
        struct device *dev = hsw->dev;
 
-       header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
+       request.header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
                        IPC_MODULE_OPERATION(IPC_MODULE_SET_PARAMETER) |
                        IPC_MODULE_ID(module_id);
-       dev_dbg(dev, "sst_hsw_module_set_param header=%x\n", header);
+       dev_dbg(dev, "sst_hsw_module_set_param header=%x\n",
+                       (u32)request.header);
 
        payload_size = param_size +
                sizeof(struct sst_hsw_transfer_parameter) -
 
        if (payload_size <= SST_HSW_IPC_MAX_SHORT_PARAMETER_SIZE) {
                /* short parameter, mailbox can contain data */
-               dev_dbg(dev, "transfer parameter size : %d\n",
-                       transfer_parameter_size);
+               dev_dbg(dev, "transfer parameter size : %lu\n",
+                       request.size);
 
-               transfer_parameter_size = ALIGN(payload_size, 4);
-               dev_dbg(dev, "transfer parameter aligned size : %d\n",
-                       transfer_parameter_size);
+               request.size = ALIGN(payload_size, 4);
+               dev_dbg(dev, "transfer parameter aligned size : %lu\n",
+                       request.size);
 
-               parameter = kzalloc(transfer_parameter_size, GFP_KERNEL);
+               parameter = kzalloc(request.size, GFP_KERNEL);
                if (parameter == NULL)
                        return -ENOMEM;
 
 
        parameter->parameter_id = parameter_id;
        parameter->data_size = param_size;
+       request.data = parameter;
 
-       ret = sst_ipc_tx_message_wait(&hsw->ipc, header,
-               parameter, transfer_parameter_size , NULL, 0);
+       ret = sst_ipc_tx_message_wait(&hsw->ipc, request, NULL);
        if (ret < 0)
                dev_err(dev, "ipc: module set parameter failed - %d\n", ret);
 
 static void hsw_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
 {
        /* send the message */
-       sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size);
-       sst_dsp_ipc_msg_tx(ipc->dsp, msg->header);
+       sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size);
+       sst_dsp_ipc_msg_tx(ipc->dsp, msg->tx.header);
 }
 
 static void hsw_shim_dbg(struct sst_generic_ipc *ipc, const char *text)
 static void hsw_tx_data_copy(struct ipc_message *msg, char *tx_data,
        size_t tx_size)
 {
-       memcpy(msg->tx_data, tx_data, tx_size);
+       memcpy(msg->tx.data, tx_data, tx_size);
 }
 
 static u64 hsw_reply_msg_match(u64 header, u64 *mask)
 
 
 static void cnl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
 {
-       struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->header);
+       struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->tx.header);
 
-       if (msg->tx_size)
-               sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size);
+       if (msg->tx.size)
+               sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size);
        sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDD,
                                    header->extension);
        sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDR,
 
                size_t tx_size)
 {
        if (tx_size)
-               memcpy(msg->tx_data, tx_data, tx_size);
+               memcpy(msg->tx.data, tx_data, tx_size);
 }
 
 static bool skl_ipc_is_dsp_busy(struct sst_dsp *dsp)
 /* Lock to be held by caller */
 static void skl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
 {
-       struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->header);
+       struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->tx.header);
 
-       if (msg->tx_size)
-               sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size);
+       if (msg->tx.size)
+               sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size);
        sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCIE,
                                                header->extension);
        sst_dsp_shim_write_unlocked(ipc->dsp, SKL_ADSP_REG_HIPCI,
                return;
        }
 
+       msg->rx.header = *ipc_header;
        /* first process the header */
        if (reply == IPC_GLB_REPLY_SUCCESS) {
                dev_dbg(ipc->dev, "ipc FW reply %x: success\n", header.primary);
                /* copy the rx data from the mailbox */
-               sst_dsp_inbox_read(ipc->dsp, msg->rx_data, msg->rx_size);
+               sst_dsp_inbox_read(ipc->dsp, msg->rx.data, msg->rx.size);
                switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
                case IPC_GLB_LOAD_MULTIPLE_MODS:
                case IPC_GLB_LOAD_LIBRARY:
                u16 ppl_mem_size, u8 ppl_type, u8 instance_id, u8 lp_mode)
 {
        struct skl_ipc_header header = {0};
-       u64 *ipc_header = (u64 *)(&header);
+       struct sst_ipc_message request = {0};
        int ret;
 
        header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
        header.primary |= IPC_PPL_MEM_SIZE(ppl_mem_size);
 
        header.extension = IPC_PPL_LP_MODE(lp_mode);
+       request.header = *(u64 *)(&header);
 
        dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
-       ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
+       ret = sst_ipc_tx_message_wait(ipc, request, NULL);
        if (ret < 0) {
                dev_err(ipc->dev, "ipc: create pipeline fail, err: %d\n", ret);
                return ret;
 int skl_ipc_delete_pipeline(struct sst_generic_ipc *ipc, u8 instance_id)
 {
        struct skl_ipc_header header = {0};
-       u64 *ipc_header = (u64 *)(&header);
+       struct sst_ipc_message request = {0};
        int ret;
 
        header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
        header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
        header.primary |= IPC_GLB_TYPE(IPC_GLB_DELETE_PPL);
        header.primary |= IPC_INSTANCE_ID(instance_id);
+       request.header = *(u64 *)(&header);
 
        dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
-       ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
+       ret = sst_ipc_tx_message_wait(ipc, request, NULL);
        if (ret < 0) {
                dev_err(ipc->dev, "ipc: delete pipeline failed, err %d\n", ret);
                return ret;
                u8 instance_id, enum skl_ipc_pipeline_state state)
 {
        struct skl_ipc_header header = {0};
-       u64 *ipc_header = (u64 *)(&header);
+       struct sst_ipc_message request = {0};
        int ret;
 
        header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
        header.primary |= IPC_GLB_TYPE(IPC_GLB_SET_PPL_STATE);
        header.primary |= IPC_INSTANCE_ID(instance_id);
        header.primary |= IPC_PPL_STATE(state);
+       request.header = *(u64 *)(&header);
 
        dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
-       ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
+       ret = sst_ipc_tx_message_wait(ipc, request, NULL);
        if (ret < 0) {
                dev_err(ipc->dev, "ipc: set pipeline state failed, err: %d\n", ret);
                return ret;
 skl_ipc_save_pipeline(struct sst_generic_ipc *ipc, u8 instance_id, int dma_id)
 {
        struct skl_ipc_header header = {0};
-       u64 *ipc_header = (u64 *)(&header);
+       struct sst_ipc_message request = {0};
        int ret;
 
        header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
        header.primary |= IPC_INSTANCE_ID(instance_id);
 
        header.extension = IPC_DMA_ID(dma_id);
+       request.header = *(u64 *)(&header);
+
        dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
-       ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
+       ret = sst_ipc_tx_message_wait(ipc, request, NULL);
        if (ret < 0) {
                dev_err(ipc->dev, "ipc: save pipeline failed, err: %d\n", ret);
                return ret;
 int skl_ipc_restore_pipeline(struct sst_generic_ipc *ipc, u8 instance_id)
 {
        struct skl_ipc_header header = {0};
-       u64 *ipc_header = (u64 *)(&header);
+       struct sst_ipc_message request = {0};
        int ret;
 
        header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
        header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
        header.primary |= IPC_GLB_TYPE(IPC_GLB_RESTORE_PPL);
        header.primary |= IPC_INSTANCE_ID(instance_id);
+       request.header = *(u64 *)(&header);
 
        dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
-       ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
+       ret = sst_ipc_tx_message_wait(ipc, request, NULL);
        if (ret < 0) {
                dev_err(ipc->dev, "ipc: restore  pipeline failed, err: %d\n", ret);
                return ret;
                u16 module_id, struct skl_ipc_dxstate_info *dx)
 {
        struct skl_ipc_header header = {0};
-       u64 *ipc_header = (u64 *)(&header);
+       struct sst_ipc_message request;
        int ret;
 
        header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
        header.primary |= IPC_MOD_INSTANCE_ID(instance_id);
        header.primary |= IPC_MOD_ID(module_id);
 
+       request.header = *(u64 *)(&header);
+       request.data = dx;
+       request.size = sizeof(*dx);
+
        dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
                         header.primary, header.extension);
-       ret = sst_ipc_tx_message_wait(ipc, *ipc_header,
-                               dx, sizeof(*dx), NULL, 0);
+       ret = sst_ipc_tx_message_wait(ipc, request, NULL);
        if (ret < 0) {
                dev_err(ipc->dev, "ipc: set dx failed, err %d\n", ret);
                return ret;
                struct skl_ipc_init_instance_msg *msg, void *param_data)
 {
        struct skl_ipc_header header = {0};
-       u64 *ipc_header = (u64 *)(&header);
+       struct sst_ipc_message request;
        int ret;
        u32 *buffer = (u32 *)param_data;
         /* param_block_size must be in dwords */
        header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size);
        header.extension |= IPC_DOMAIN(msg->domain);
 
+       request.header = *(u64 *)(&header);
+       request.data = param_data;
+       request.size = msg->param_data_size;
+
        dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
                         header.primary, header.extension);
-       ret = sst_ipc_tx_message_wait(ipc, *ipc_header, param_data,
-                       msg->param_data_size, NULL, 0);
+       ret = sst_ipc_tx_message_wait(ipc, request, NULL);
 
        if (ret < 0) {
                dev_err(ipc->dev, "ipc: init instance failed\n");
                struct skl_ipc_bind_unbind_msg *msg)
 {
        struct skl_ipc_header header = {0};
-       u64 *ipc_header = (u64 *)(&header);
+       struct sst_ipc_message request = {0};
        u8 bind_unbind = msg->bind ? IPC_MOD_BIND : IPC_MOD_UNBIND;
        int ret;
 
        header.extension |= IPC_DST_MOD_INSTANCE_ID(msg->dst_instance_id);
        header.extension |= IPC_DST_QUEUE(msg->dst_queue);
        header.extension |= IPC_SRC_QUEUE(msg->src_queue);
+       request.header = *(u64 *)(&header);
 
        dev_dbg(ipc->dev, "In %s hdr=%x ext=%x\n", __func__, header.primary,
                         header.extension);
-       ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
+       ret = sst_ipc_tx_message_wait(ipc, request, NULL);
        if (ret < 0) {
                dev_err(ipc->dev, "ipc: bind/unbind failed\n");
                return ret;
                                u8 module_cnt, void *data)
 {
        struct skl_ipc_header header = {0};
-       u64 *ipc_header = (u64 *)(&header);
+       struct sst_ipc_message request;
        int ret;
 
        header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
        header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_MULTIPLE_MODS);
        header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
 
-       ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, data,
-                               (sizeof(u16) * module_cnt));
+       request.header = *(u64 *)(&header);
+       request.data = data;
+       request.size = sizeof(u16) * module_cnt;
+
+       ret = sst_ipc_tx_message_nowait(ipc, request);
        if (ret < 0)
                dev_err(ipc->dev, "ipc: load modules failed :%d\n", ret);
 
                                                        void *data)
 {
        struct skl_ipc_header header = {0};
-       u64 *ipc_header = (u64 *)(&header);
+       struct sst_ipc_message request;
        int ret;
 
        header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
        header.primary |= IPC_GLB_TYPE(IPC_GLB_UNLOAD_MULTIPLE_MODS);
        header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
 
-       ret = sst_ipc_tx_message_wait(ipc, *ipc_header, data,
-                               (sizeof(u16) * module_cnt), NULL, 0);
+       request.header = *(u64 *)(&header);
+       request.data = data;
+       request.size = sizeof(u16) * module_cnt;
+
+       ret = sst_ipc_tx_message_wait(ipc, request, NULL);
        if (ret < 0)
                dev_err(ipc->dev, "ipc: unload modules failed :%d\n", ret);
 
                struct skl_ipc_large_config_msg *msg, u32 *param)
 {
        struct skl_ipc_header header = {0};
-       u64 *ipc_header = (u64 *)(&header);
+       struct sst_ipc_message request;
        int ret = 0;
        size_t sz_remaining, tx_size, data_offset;
 
                        header.primary, header.extension);
                dev_dbg(ipc->dev, "transmitting offset: %#x, size: %#x\n",
                        (unsigned)data_offset, (unsigned)tx_size);
-               ret = sst_ipc_tx_message_wait(ipc, *ipc_header,
-                                         ((char *)param) + data_offset,
-                                         tx_size, NULL, 0);
+
+               request.header = *(u64 *)(&header);
+               request.data = ((char *)param) + data_offset;
+               request.size = tx_size;
+               ret = sst_ipc_tx_message_wait(ipc, request, NULL);
                if (ret < 0) {
                        dev_err(ipc->dev,
                                "ipc: set large config fail, err: %d\n", ret);
                struct skl_ipc_large_config_msg *msg, u32 *param)
 {
        struct skl_ipc_header header = {0};
-       u64 *ipc_header = (u64 *)(&header);
+       struct sst_ipc_message request = {0}, reply = {0};
        int ret = 0;
        size_t sz_remaining, rx_size, data_offset;
 
                if (rx_size == sz_remaining)
                        header.extension |= IPC_FINAL_BLOCK(1);
 
-               ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0,
-                                             ((char *)param) + data_offset,
-                                             msg->param_data_size);
+               request.header = *(u64 *)(&header);
+               reply.data = ((char *)param) + data_offset;
+               reply.size = msg->param_data_size;
+               ret = sst_ipc_tx_message_wait(ipc, request, &reply);
                if (ret < 0) {
                        dev_err(ipc->dev,
                                "ipc: get large config fail, err: %d\n", ret);
                                u8 dma_id, u8 table_id, bool wait)
 {
        struct skl_ipc_header header = {0};
-       u64 *ipc_header = (u64 *)(&header);
+       struct sst_ipc_message request = {0};
        int ret = 0;
 
        header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
        header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_LIBRARY);
        header.primary |= IPC_MOD_INSTANCE_ID(table_id);
        header.primary |= IPC_MOD_ID(dma_id);
+       request.header = *(u64 *)(&header);
 
        if (wait)
-               ret = sst_ipc_tx_message_wait(ipc, *ipc_header,
-                                       NULL, 0, NULL, 0);
+               ret = sst_ipc_tx_message_wait(ipc, request, NULL);
        else
-               ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, NULL, 0);
+               ret = sst_ipc_tx_message_nowait(ipc, request);
 
        if (ret < 0)
                dev_err(ipc->dev, "ipc: load lib failed\n");
 int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, struct skl_ipc_d0ix_msg *msg)
 {
        struct skl_ipc_header header = {0};
-       u64 *ipc_header = (u64 *)(&header);
+       struct sst_ipc_message request = {0};
        int ret;
 
        header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
 
        header.extension = IPC_D0IX_WAKE(msg->wake);
        header.extension |= IPC_D0IX_STREAMING(msg->streaming);
+       request.header = *(u64 *)(&header);
 
        dev_dbg(ipc->dev, "In %s primary=%x ext=%x\n", __func__,
                        header.primary, header.extension);
        /*
         * Use the nopm IPC here as we dont want it checking for D0iX
         */
-       ret = sst_ipc_tx_message_nopm(ipc, *ipc_header, NULL, 0, NULL, 0);
+       ret = sst_ipc_tx_message_nopm(ipc, request, NULL);
        if (ret < 0)
                dev_err(ipc->dev, "ipc: set d0ix failed, err %d\n", ret);