Loading include/sound/q6lsm.h +2 −2 Original line number Diff line number Diff line /* * Copyright (c) 2013-2017, Linux Foundation. All rights reserved. * Copyright (c) 2013-2017, 2019 Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -26,7 +26,7 @@ #define LSM_MAX_NUM_CHANNELS 8 typedef void (*lsm_app_cb)(uint32_t opcode, uint32_t token, uint32_t *payload, void *priv); uint32_t *payload, uint16_t client_size, void *priv); struct lsm_sound_model { dma_addr_t phys; Loading sound/soc/msm/qdsp6v2/msm-lsm-client.c +37 −8 Original line number Diff line number Diff line /* * Copyright (c) 2013-2017, Linux Foundation. All rights reserved. * Copyright (c) 2013-2017, 2019 Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -195,7 +195,8 @@ static int lsm_lab_buffer_sanity(struct lsm_priv *prtd, } static void lsm_event_handler(uint32_t opcode, uint32_t token, void *payload, void *priv) void *payload, uint16_t client_size, void *priv) { unsigned long flags; struct lsm_priv *prtd = priv; Loading Loading @@ -263,6 +264,12 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, } case LSM_SESSION_EVENT_DETECTION_STATUS: if (client_size < 3 * sizeof(uint8_t)) { dev_err(rtd->dev, "%s: client_size has invalid size[%d]\n", __func__, client_size); return; } status = (uint16_t)((uint8_t *)payload)[0]; payload_size = (uint16_t)((uint8_t *)payload)[2]; index = 4; Loading @@ -272,6 +279,12 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, break; case LSM_SESSION_EVENT_DETECTION_STATUS_V2: if (client_size < 2 * sizeof(uint8_t)) { dev_err(rtd->dev, "%s: client_size has invalid size[%d]\n", __func__, client_size); return; } status = (uint16_t)((uint8_t *)payload)[0]; payload_size = (uint16_t)((uint8_t *)payload)[1]; index = 2; Loading @@ -281,6 +294,12 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, break; case LSM_SESSION_EVENT_DETECTION_STATUS_V3: if (client_size < 2 * (sizeof(uint32_t) + sizeof(uint8_t))) { dev_err(rtd->dev, "%s: client_size has invalid size[%d]\n", __func__, client_size); return; } event_ts_lsw = ((uint32_t *)payload)[0]; event_ts_msw = ((uint32_t *)payload)[1]; status = (uint16_t)((uint8_t *)payload)[8]; Loading Loading @@ -318,12 +337,22 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, prtd->event_status->payload_size = payload_size; if (likely(prtd->event_status)) { if (client_size >= (payload_size + index)) { memcpy(prtd->event_status->payload, &((uint8_t *)payload)[index], payload_size); prtd->event_avail = 1; spin_unlock_irqrestore(&prtd->event_lock, flags); spin_unlock_irqrestore(&prtd->event_lock, flags); wake_up(&prtd->event_wait); } else { spin_unlock_irqrestore(&prtd->event_lock, flags); dev_err(rtd->dev, "%s: Failed to copy memory with invalid size = %d\n", __func__, payload_size); return; } } else { spin_unlock_irqrestore(&prtd->event_lock, flags); dev_err(rtd->dev, Loading sound/soc/msm/qdsp6v2/q6lsm.c +14 −4 Original line number Diff line number Diff line /* * Copyright (c) 2013-2018, Linux Foundation. All rights reserved. * Copyright (c) 2013-2019, Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -127,7 +127,8 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) if (data->opcode == LSM_DATA_EVENT_READ_DONE) { struct lsm_cmd_read_done read_done; token = data->token; if (data->payload_size > sizeof(read_done)) { if (data->payload_size > sizeof(read_done) || data->payload_size < 6 * sizeof(payload[0])) { pr_err("%s: read done error payload size %d expected size %zd\n", __func__, data->payload_size, sizeof(read_done)); Loading @@ -145,6 +146,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) if (client->cb) client->cb(data->opcode, data->token, (void *)&read_done, sizeof(read_done), client->priv); return 0; } else if (data->opcode == APR_BASIC_RSP_RESULT) { Loading @@ -171,6 +173,11 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) __func__, token, client->session); return -EINVAL; } if (data->payload_size < 2 * sizeof(payload[0])) { pr_err("%s: payload has invalid size[%d]\n", __func__, data->payload_size); return -EINVAL; } client->cmd_err_code = payload[1]; if (client->cmd_err_code) pr_err("%s: cmd 0x%x failed status %d\n", Loading @@ -191,7 +198,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) if (client->cb) client->cb(data->opcode, data->token, data->payload, client->priv); data->payload_size, client->priv); return 0; } Loading Loading @@ -1365,6 +1372,8 @@ static int q6lsm_mmapcallback(struct apr_client_data *data, void *priv) pr_debug("%s: SSR event received 0x%x, event 0x%x,\n" "proc 0x%x SID 0x%x\n", __func__, data->opcode, data->reset_event, data->reset_proc, sid); if (sid < LSM_MIN_SESSION_ID || sid > LSM_MAX_SESSION_ID) pr_err("%s: Invalid session %d\n", __func__, sid); lsm_common.common_client[sid].lsm_cal_phy_addr = 0; cal_utils_clear_cal_block_q6maps(LSM_MAX_CAL_IDX, lsm_common.cal_data); Loading Loading @@ -1426,7 +1435,8 @@ static int q6lsm_mmapcallback(struct apr_client_data *data, void *priv) } if (client->cb) client->cb(data->opcode, data->token, data->payload, client->priv); data->payload, data->payload_size, client->priv); return 0; } Loading Loading
include/sound/q6lsm.h +2 −2 Original line number Diff line number Diff line /* * Copyright (c) 2013-2017, Linux Foundation. All rights reserved. * Copyright (c) 2013-2017, 2019 Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -26,7 +26,7 @@ #define LSM_MAX_NUM_CHANNELS 8 typedef void (*lsm_app_cb)(uint32_t opcode, uint32_t token, uint32_t *payload, void *priv); uint32_t *payload, uint16_t client_size, void *priv); struct lsm_sound_model { dma_addr_t phys; Loading
sound/soc/msm/qdsp6v2/msm-lsm-client.c +37 −8 Original line number Diff line number Diff line /* * Copyright (c) 2013-2017, Linux Foundation. All rights reserved. * Copyright (c) 2013-2017, 2019 Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -195,7 +195,8 @@ static int lsm_lab_buffer_sanity(struct lsm_priv *prtd, } static void lsm_event_handler(uint32_t opcode, uint32_t token, void *payload, void *priv) void *payload, uint16_t client_size, void *priv) { unsigned long flags; struct lsm_priv *prtd = priv; Loading Loading @@ -263,6 +264,12 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, } case LSM_SESSION_EVENT_DETECTION_STATUS: if (client_size < 3 * sizeof(uint8_t)) { dev_err(rtd->dev, "%s: client_size has invalid size[%d]\n", __func__, client_size); return; } status = (uint16_t)((uint8_t *)payload)[0]; payload_size = (uint16_t)((uint8_t *)payload)[2]; index = 4; Loading @@ -272,6 +279,12 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, break; case LSM_SESSION_EVENT_DETECTION_STATUS_V2: if (client_size < 2 * sizeof(uint8_t)) { dev_err(rtd->dev, "%s: client_size has invalid size[%d]\n", __func__, client_size); return; } status = (uint16_t)((uint8_t *)payload)[0]; payload_size = (uint16_t)((uint8_t *)payload)[1]; index = 2; Loading @@ -281,6 +294,12 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, break; case LSM_SESSION_EVENT_DETECTION_STATUS_V3: if (client_size < 2 * (sizeof(uint32_t) + sizeof(uint8_t))) { dev_err(rtd->dev, "%s: client_size has invalid size[%d]\n", __func__, client_size); return; } event_ts_lsw = ((uint32_t *)payload)[0]; event_ts_msw = ((uint32_t *)payload)[1]; status = (uint16_t)((uint8_t *)payload)[8]; Loading Loading @@ -318,12 +337,22 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token, prtd->event_status->payload_size = payload_size; if (likely(prtd->event_status)) { if (client_size >= (payload_size + index)) { memcpy(prtd->event_status->payload, &((uint8_t *)payload)[index], payload_size); prtd->event_avail = 1; spin_unlock_irqrestore(&prtd->event_lock, flags); spin_unlock_irqrestore(&prtd->event_lock, flags); wake_up(&prtd->event_wait); } else { spin_unlock_irqrestore(&prtd->event_lock, flags); dev_err(rtd->dev, "%s: Failed to copy memory with invalid size = %d\n", __func__, payload_size); return; } } else { spin_unlock_irqrestore(&prtd->event_lock, flags); dev_err(rtd->dev, Loading
sound/soc/msm/qdsp6v2/q6lsm.c +14 −4 Original line number Diff line number Diff line /* * Copyright (c) 2013-2018, Linux Foundation. All rights reserved. * Copyright (c) 2013-2019, Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -127,7 +127,8 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) if (data->opcode == LSM_DATA_EVENT_READ_DONE) { struct lsm_cmd_read_done read_done; token = data->token; if (data->payload_size > sizeof(read_done)) { if (data->payload_size > sizeof(read_done) || data->payload_size < 6 * sizeof(payload[0])) { pr_err("%s: read done error payload size %d expected size %zd\n", __func__, data->payload_size, sizeof(read_done)); Loading @@ -145,6 +146,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) if (client->cb) client->cb(data->opcode, data->token, (void *)&read_done, sizeof(read_done), client->priv); return 0; } else if (data->opcode == APR_BASIC_RSP_RESULT) { Loading @@ -171,6 +173,11 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) __func__, token, client->session); return -EINVAL; } if (data->payload_size < 2 * sizeof(payload[0])) { pr_err("%s: payload has invalid size[%d]\n", __func__, data->payload_size); return -EINVAL; } client->cmd_err_code = payload[1]; if (client->cmd_err_code) pr_err("%s: cmd 0x%x failed status %d\n", Loading @@ -191,7 +198,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) if (client->cb) client->cb(data->opcode, data->token, data->payload, client->priv); data->payload_size, client->priv); return 0; } Loading Loading @@ -1365,6 +1372,8 @@ static int q6lsm_mmapcallback(struct apr_client_data *data, void *priv) pr_debug("%s: SSR event received 0x%x, event 0x%x,\n" "proc 0x%x SID 0x%x\n", __func__, data->opcode, data->reset_event, data->reset_proc, sid); if (sid < LSM_MIN_SESSION_ID || sid > LSM_MAX_SESSION_ID) pr_err("%s: Invalid session %d\n", __func__, sid); lsm_common.common_client[sid].lsm_cal_phy_addr = 0; cal_utils_clear_cal_block_q6maps(LSM_MAX_CAL_IDX, lsm_common.cal_data); Loading Loading @@ -1426,7 +1435,8 @@ static int q6lsm_mmapcallback(struct apr_client_data *data, void *priv) } if (client->cb) client->cb(data->opcode, data->token, data->payload, client->priv); data->payload, data->payload_size, client->priv); return 0; } Loading