Merge tag 'LA.UM.7.4.r1-05300-8x98.0' into lineage-16.0

"LA.UM.7.4.r1-05300-8x98.0"

Change-Id: I8e27939efccb7d0bda0ac7c4e32afdf3c6d62507
This commit is contained in:
codeworkx 2019-06-16 08:15:21 +02:00
commit 15f81a19b5
70 changed files with 3601 additions and 1016 deletions

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2017,2019 The 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
@ -38,6 +38,12 @@
qcom,display-type = "primary";
};
&mdss_fb2 {
qcom,cont-splash-memory {
linux,contiguous-region = <&cont_splash_mem>;
};
};
&slim_aud {
tasha_codec {
wsa_spkr_sd1: msm_cdc_pinctrll {

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2019, The 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
@ -984,7 +984,7 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
int save_req_uid = 0;
struct diag_dci_pkt_rsp_header_t pkt_rsp_header;
if (!buf) {
if (!buf || len <= 0) {
pr_err("diag: Invalid pointer in %s\n", __func__);
return;
}
@ -998,6 +998,8 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
dci_cmd_code);
return;
}
if (len < (cmd_code_len + sizeof(int)))
return;
temp += cmd_code_len;
tag = *(int *)temp;
temp += sizeof(int);
@ -1006,12 +1008,18 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
* The size of the response is (total length) - (length of the command
* code, the tag (int)
*/
if (len >= cmd_code_len + sizeof(int)) {
rsp_len = len - (cmd_code_len + sizeof(int));
if ((rsp_len == 0) || (rsp_len > (len - 5))) {
pr_err("diag: Invalid length in %s, len: %d, rsp_len: %d",
pr_err("diag: Invalid length in %s, len: %d, rsp_len: %d\n",
__func__, len, rsp_len);
return;
}
} else {
pr_err("diag:%s: Invalid length(%d) for calculating rsp_len\n",
__func__, len);
return;
}
mutex_lock(&driver->dci_mutex);
req_entry = diag_dci_get_request_entry(tag);
@ -2296,8 +2304,8 @@ struct diag_dci_client_tbl *dci_lookup_client_entry_pid(int tgid)
pid_struct = find_get_pid(entry->tgid);
if (!pid_struct) {
DIAG_LOG(DIAG_DEBUG_DCI,
"diag: valid pid doesn't exist for pid = %d\n",
entry->tgid);
"diag: Exited pid (%d) doesn't match dci client of pid (%d)\n",
tgid, entry->tgid);
continue;
}
task_s = get_pid_task(pid_struct, PIDTYPE_PID);

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2008-2019, The 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
@ -705,7 +705,7 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
mask_info = (!info) ? &msg_mask : info->msg_mask;
if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
!mask_info) {
!mask_info || (src_len < sizeof(struct diag_build_mask_req_t))) {
pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
__func__, src_buf, src_len, dest_buf, dest_len,
mask_info);

View file

@ -139,8 +139,11 @@ static void diag_usb_buf_tbl_remove(struct diag_usb_info *usb_info,
* Remove reference from the table if it is the
* only instance of the buffer
*/
if (atomic_read(&entry->ref_count) == 0)
if (atomic_read(&entry->ref_count) == 0) {
list_del(&entry->track);
kfree(entry);
entry = NULL;
}
break;
}
}
@ -308,28 +311,31 @@ static void diag_usb_write_done(struct diag_usb_info *ch,
if (!ch || !req)
return;
spin_lock_irqsave(&ch->write_lock, flags);
ch->write_cnt++;
entry = diag_usb_buf_tbl_get(ch, req->context);
if (!entry) {
pr_err_ratelimited("diag: In %s, unable to find entry %pK in the table\n",
__func__, req->context);
spin_unlock_irqrestore(&ch->write_lock, flags);
return;
}
if (atomic_read(&entry->ref_count) != 0) {
DIAG_LOG(DIAG_DEBUG_MUX, "partial write_done ref %d\n",
atomic_read(&entry->ref_count));
diag_ws_on_copy_complete(DIAG_WS_MUX);
spin_unlock_irqrestore(&ch->write_lock, flags);
diagmem_free(driver, req, ch->mempool);
return;
}
DIAG_LOG(DIAG_DEBUG_MUX, "full write_done, ctxt: %d\n",
ctxt);
spin_lock_irqsave(&ch->write_lock, flags);
list_del(&entry->track);
ctxt = entry->ctxt;
buf = entry->buf;
len = entry->len;
kfree(entry);
entry = NULL;
diag_ws_on_copy_complete(DIAG_WS_MUX);
if (ch->ops && ch->ops->write_done)

View file

@ -583,8 +583,8 @@ static int diag_remove_client_entry(struct file *file)
static int diagchar_close(struct inode *inode, struct file *file)
{
int ret;
DIAG_LOG(DIAG_DEBUG_USERSPACE, "diag: process exit %s\n",
current->comm);
DIAG_LOG(DIAG_DEBUG_USERSPACE, "diag: %s process exit with pid = %d\n",
current->comm, current->tgid);
ret = diag_remove_client_entry(file);
mutex_lock(&driver->diag_maskclear_mutex);
driver->mask_clear = 0;
@ -3124,6 +3124,8 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
int exit_stat = 0;
int write_len = 0;
struct diag_md_session_t *session_info = NULL;
struct pid *pid_struct = NULL;
struct task_struct *task_s = NULL;
mutex_lock(&driver->diagchar_mutex);
for (i = 0; i < driver->num_clients; i++)
@ -3331,6 +3333,17 @@ exit:
list_for_each_safe(start, temp, &driver->dci_client_list) {
entry = list_entry(start, struct diag_dci_client_tbl,
track);
pid_struct = find_get_pid(entry->tgid);
if (!pid_struct)
continue;
task_s = get_pid_task(pid_struct, PIDTYPE_PID);
if (!task_s) {
DIAG_LOG(DIAG_DEBUG_DCI,
"diag: valid task doesn't exist for pid = %d\n",
entry->tgid);
continue;
}
if (task_s == entry->client)
if (entry->client->tgid != current->tgid)
continue;
if (!entry->in_service)

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2008-2019, The 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
@ -684,7 +684,8 @@ int diag_process_time_sync_query_cmd(unsigned char *src_buf, int src_len,
struct diag_cmd_time_sync_query_req_t *req = NULL;
struct diag_cmd_time_sync_query_rsp_t rsp;
if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) {
if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
src_len < sizeof(struct diag_cmd_time_sync_query_req_t)) {
pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d",
__func__, src_buf, src_len, dest_buf, dest_len);
return -EINVAL;
@ -711,7 +712,8 @@ int diag_process_time_sync_switch_cmd(unsigned char *src_buf, int src_len,
int msg_size = sizeof(struct diag_ctrl_msg_time_sync);
int err = 0, write_len = 0;
if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) {
if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
src_len < sizeof(struct diag_cmd_time_sync_switch_req_t)) {
pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d",
__func__, src_buf, src_len, dest_buf, dest_len);
return -EINVAL;
@ -952,7 +954,7 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
struct diag_cmd_reg_t *reg_item = NULL;
struct diag_md_session_t *info = NULL;
if (!buf)
if (!buf || len <= 0)
return -EIO;
/* Check if the command is a supported mask command */
@ -963,18 +965,31 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
}
temp = buf;
if (len >= sizeof(uint8_t)) {
entry.cmd_code = (uint16_t)(*(uint8_t *)temp);
pr_debug("diag: received cmd_code %02x\n", entry.cmd_code);
}
if (len >= (2 * sizeof(uint8_t))) {
temp += sizeof(uint8_t);
entry.subsys_id = (uint16_t)(*(uint8_t *)temp);
pr_debug("diag: received subsys_id %02x\n", entry.subsys_id);
}
if (len == (3 * sizeof(uint8_t))) {
temp += sizeof(uint8_t);
entry.cmd_code_hi = (uint16_t)(*(uint8_t *)temp);
entry.cmd_code_lo = (uint16_t)(*(uint8_t *)temp);
pr_debug("diag: received cmd_code_hi %02x\n",
entry.cmd_code_hi);
} else if (len >= (2 * sizeof(uint8_t)) + sizeof(uint16_t)) {
temp += sizeof(uint8_t);
entry.cmd_code_hi = (uint16_t)(*(uint16_t *)temp);
entry.cmd_code_lo = (uint16_t)(*(uint16_t *)temp);
temp += sizeof(uint16_t);
pr_debug("diag: received cmd_code_hi %02x\n",
entry.cmd_code_hi);
}
pr_debug("diag: In %s, received cmd %02x %02x %02x\n",
__func__, entry.cmd_code, entry.subsys_id, entry.cmd_code_hi);
if (*buf == DIAG_CMD_LOG_ON_DMND && driver->log_on_demand_support &&
if ((len >= sizeof(uint8_t)) && *buf == DIAG_CMD_LOG_ON_DMND &&
driver->log_on_demand_support &&
driver->feature[PERIPHERAL_MODEM].rcvd_feature_mask) {
write_len = diag_cmd_log_on_demand(buf, len,
driver->apps_rsp_buf,
@ -1014,14 +1029,16 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
#if defined(CONFIG_DIAG_OVER_USB)
/* Check for the command/respond msg for the maximum packet length */
if ((*buf == 0x4b) && (*(buf+1) == 0x12) &&
if ((len >= (4 * sizeof(uint8_t))) &&
(*buf == 0x4b) && (*(buf+1) == 0x12) &&
(*(uint16_t *)(buf+2) == 0x0055)) {
for (i = 0; i < 4; i++)
*(driver->apps_rsp_buf+i) = *(buf+i);
*(uint32_t *)(driver->apps_rsp_buf+4) = DIAG_MAX_REQ_SIZE;
diag_send_rsp(driver->apps_rsp_buf, 8, pid);
return 0;
} else if ((*buf == 0x4b) && (*(buf+1) == 0x12) &&
} else if ((len >= ((2 * sizeof(uint8_t)) + sizeof(uint16_t))) &&
(*buf == 0x4b) && (*(buf+1) == 0x12) &&
(*(uint16_t *)(buf+2) == DIAG_DIAG_STM)) {
len = diag_process_stm_cmd(buf, driver->apps_rsp_buf);
if (len > 0) {
@ -1031,7 +1048,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return len;
}
/* Check for time sync query command */
else if ((*buf == DIAG_CMD_DIAG_SUBSYS) &&
else if ((len >= ((2 * sizeof(uint8_t)) + sizeof(uint16_t))) &&
(*buf == DIAG_CMD_DIAG_SUBSYS) &&
(*(buf+1) == DIAG_SS_DIAG) &&
(*(uint16_t *)(buf+2) == DIAG_GET_TIME_API)) {
write_len = diag_process_time_sync_query_cmd(buf, len,
@ -1042,7 +1060,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return 0;
}
/* Check for time sync switch command */
else if ((*buf == DIAG_CMD_DIAG_SUBSYS) &&
else if ((len >= ((2 * sizeof(uint8_t)) + sizeof(uint16_t))) &&
(*buf == DIAG_CMD_DIAG_SUBSYS) &&
(*(buf+1) == DIAG_SS_DIAG) &&
(*(uint16_t *)(buf+2) == DIAG_SET_TIME_API)) {
write_len = diag_process_time_sync_switch_cmd(buf, len,
@ -1053,7 +1072,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return 0;
}
/* Check for download command */
else if ((chk_apps_master()) && (*buf == 0x3A)) {
else if ((len >= sizeof(uint8_t)) && (chk_apps_master()) &&
(*buf == 0x3A)) {
/* send response back */
driver->apps_rsp_buf[0] = *buf;
diag_send_rsp(driver->apps_rsp_buf, 1, pid);
@ -1066,8 +1086,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return 0;
}
/* Check for polling for Apps only DIAG */
else if ((*buf == 0x4b) && (*(buf+1) == 0x32) &&
(*(buf+2) == 0x03)) {
else if ((len >= (3 * sizeof(uint8_t))) &&
(*buf == 0x4b) && (*(buf+1) == 0x32) && (*(buf+2) == 0x03)) {
/* If no one has registered for polling */
if (chk_polling_response()) {
/* Respond to polling for Apps only DIAG */
@ -1081,7 +1101,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
}
}
/* Return the Delayed Response Wrap Status */
else if ((*buf == 0x4b) && (*(buf+1) == 0x32) &&
else if ((len >= (4 * sizeof(uint8_t))) &&
(*buf == 0x4b) && (*(buf+1) == 0x32) &&
(*(buf+2) == 0x04) && (*(buf+3) == 0x0)) {
memcpy(driver->apps_rsp_buf, buf, 4);
driver->apps_rsp_buf[4] = wrap_enabled;
@ -1089,7 +1110,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return 0;
}
/* Wrap the Delayed Rsp ID */
else if ((*buf == 0x4b) && (*(buf+1) == 0x32) &&
else if ((len >= (4 * sizeof(uint8_t))) &&
(*buf == 0x4b) && (*(buf+1) == 0x32) &&
(*(buf+2) == 0x05) && (*(buf+3) == 0x0)) {
wrap_enabled = true;
memcpy(driver->apps_rsp_buf, buf, 4);
@ -1098,7 +1120,8 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return 0;
}
/* Mobile ID Rsp */
else if ((*buf == DIAG_CMD_DIAG_SUBSYS) &&
else if ((len >= (4 * sizeof(uint8_t))) &&
(*buf == DIAG_CMD_DIAG_SUBSYS) &&
(*(buf+1) == DIAG_SS_PARAMS) &&
(*(buf+2) == DIAG_EXT_MOBILE_ID) && (*(buf+3) == 0x0)) {
write_len = diag_cmd_get_mobile_id(buf, len,
@ -1121,7 +1144,7 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
!(driver->diagfwd_cntl[PERIPHERAL_MODEM]->ch_open) &&
!(driver->feature[PERIPHERAL_MODEM].rcvd_feature_mask)) {
/* respond to 0x0 command */
if (*buf == 0x00) {
if ((len >= sizeof(uint8_t)) && *buf == 0x00) {
for (i = 0; i < 55; i++)
driver->apps_rsp_buf[i] = 0;
@ -1129,7 +1152,7 @@ int diag_process_apps_pkt(unsigned char *buf, int len, int pid)
return 0;
}
/* respond to 0x7c command */
else if (*buf == 0x7c) {
else if ((len >= sizeof(uint8_t)) && *buf == 0x7c) {
driver->apps_rsp_buf[0] = 0x7c;
for (i = 1; i < 8; i++)
driver->apps_rsp_buf[i] = 0;

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2019, The 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
@ -1727,7 +1727,7 @@ int qcom_ice_setup_ice_hw(const char *storage_type, int enable)
if (ice_dev == ERR_PTR(-EPROBE_DEFER))
return -EPROBE_DEFER;
if (!ice_dev)
if (!ice_dev || (ice_dev->is_ice_enabled == false))
return ret;
if (enable)

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2008-2019, The 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
@ -328,7 +328,7 @@ kgsl_mem_entry_destroy(struct kref *kref)
entry->memdesc.sgt->nents, i) {
page = sg_page(sg);
for (j = 0; j < (sg->length >> PAGE_SHIFT); j++)
set_page_dirty(nth_page(page, j));
set_page_dirty_lock(nth_page(page, j));
}
}
@ -536,14 +536,21 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv,
int ret = 0, id;
struct kgsl_process_private *proc_priv = dev_priv->process_priv;
/*
* Read and increment the context count under lock to make sure
* no process goes beyond the specified context limit.
*/
spin_lock(&proc_priv->ctxt_count_lock);
if (atomic_read(&proc_priv->ctxt_count) > KGSL_MAX_CONTEXTS_PER_PROC) {
KGSL_DRV_ERR(device,
KGSL_DRV_ERR_RATELIMIT(device,
"Per process context limit reached for pid %u",
dev_priv->process_priv->pid);
spin_unlock(&proc_priv->ctxt_count_lock);
return -ENOSPC;
}
atomic_inc(&proc_priv->ctxt_count);
spin_unlock(&proc_priv->ctxt_count_lock);
id = _kgsl_get_context_id(device);
if (id == -ENOSPC) {
@ -929,6 +936,7 @@ static struct kgsl_process_private *kgsl_process_private_new(
spin_lock_init(&private->mem_lock);
spin_lock_init(&private->syncsource_lock);
spin_lock_init(&private->ctxt_count_lock);
idr_init(&private->mem_idr);
idr_init(&private->syncsource_idr);

View file

@ -423,6 +423,7 @@ struct kgsl_context {
* @syncsource_lock: Spinlock to protect the syncsource idr
* @fd_count: Counter for the number of FDs for this process
* @ctxt_count: Count for the number of contexts for this process
* @ctxt_count_lock: Spinlock to protect ctxt_count
*/
struct kgsl_process_private {
unsigned long priv;
@ -444,6 +445,7 @@ struct kgsl_process_private {
spinlock_t syncsource_lock;
int fd_count;
atomic_t ctxt_count;
spinlock_t ctxt_count_lock;
};
/**

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2017,2019, The 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
@ -513,12 +513,22 @@ static void *fast_smmu_alloc(struct device *dev, size_t size,
av8l_fast_iopte *ptep;
unsigned long flags;
struct sg_mapping_iter miter;
unsigned int count = ALIGN(size, SZ_4K) >> PAGE_SHIFT;
size_t count = ALIGN(size, SZ_4K) >> PAGE_SHIFT;
int prot = IOMMU_READ | IOMMU_WRITE; /* TODO: extract from attrs */
bool is_coherent = is_dma_coherent(dev, attrs);
pgprot_t remap_prot = __get_dma_pgprot(attrs, PAGE_KERNEL, is_coherent);
struct page **pages;
/*
* sg_alloc_table_from_pages accepts unsigned int value for count
* so check count doesn't exceed UINT_MAX.
*/
if (count > UINT_MAX) {
dev_err(dev, "count: %zx exceeds UNIT_MAX\n", count);
return NULL;
}
prot = __get_iommu_pgprot(attrs, prot, is_coherent);
*handle = DMA_ERROR_CODE;

View file

@ -1403,7 +1403,7 @@ static ssize_t iommu_debug_virt_addr_read(struct file *file, char __user *ubuf,
else
snprintf(buf, 100, "0x%pK\n", virt_addr);
buflen = min(count, strlen(buf)+1);
buflen = min(count, strlen(buf));
if (copy_to_user(ubuf, buf, buflen)) {
pr_err("Couldn't copy_to_user\n");
retval = -EFAULT;
@ -1527,7 +1527,7 @@ static ssize_t iommu_debug_pte_read(struct file *file, char __user *ubuf,
else
snprintf(buf, 100, "pte=%016llx\n", pte);
buflen = min(count, strlen(buf)+1);
buflen = min(count, strlen(buf));
if (copy_to_user(ubuf, buf, buflen)) {
pr_err("Couldn't copy_to_user\n");
retval = -EFAULT;
@ -1596,7 +1596,7 @@ static ssize_t iommu_debug_atos_read(struct file *file, char __user *ubuf,
snprintf(buf, 100, "%pa\n", &phys);
}
buflen = min(count, strlen(buf)+1);
buflen = min(count, strlen(buf));
if (copy_to_user(ubuf, buf, buflen)) {
pr_err("Couldn't copy_to_user\n");
retval = -EFAULT;
@ -1649,7 +1649,7 @@ static ssize_t iommu_debug_dma_atos_read(struct file *file, char __user *ubuf,
else
snprintf(buf, 100, "%pa\n", &phys);
buflen = min(count, strlen(buf)+1);
buflen = min(count, strlen(buf));
if (copy_to_user(ubuf, buf, buflen)) {
pr_err("Couldn't copy_to_user\n");
retval = -EFAULT;
@ -1880,7 +1880,7 @@ static ssize_t iommu_debug_dma_map_read(struct file *file, char __user *ubuf,
iova = ddev->iova;
snprintf(buf, 100, "%pa\n", &iova);
buflen = min(count, strlen(buf)+1);
buflen = min(count, strlen(buf));
if (copy_to_user(ubuf, buf, buflen)) {
pr_err("Couldn't copy_to_user\n");
retval = -EFAULT;

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2019, The 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
@ -370,8 +370,12 @@ static int camera_v4l2_s_fmt_vid_cap_mplane(struct file *filep, void *fh,
if (pfmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
if (WARN_ON(!sp->vb2_q.drv_priv))
return -ENOMEM;
mutex_lock(sp->vb2_q.lock);
if (WARN_ON(!sp->vb2_q.drv_priv)) {
rc = -ENOMEM;
mutex_unlock(sp->vb2_q.lock);
goto done;
}
memcpy(sp->vb2_q.drv_priv, pfmt->fmt.raw_data,
sizeof(struct msm_v4l2_format_data));
@ -382,27 +386,30 @@ static int camera_v4l2_s_fmt_vid_cap_mplane(struct file *filep, void *fh,
/* num_planes need to bound checked, otherwise for loop
* can execute forever
*/
if (WARN_ON(user_fmt->num_planes > VIDEO_MAX_PLANES))
return -EINVAL;
if (WARN_ON(user_fmt->num_planes > VIDEO_MAX_PLANES)) {
rc = -EINVAL;
mutex_unlock(sp->vb2_q.lock);
goto done;
}
for (i = 0; i < user_fmt->num_planes; i++)
pr_debug("%s: plane size[%d]\n", __func__,
user_fmt->plane_sizes[i]);
mutex_unlock(sp->vb2_q.lock);
if (msm_is_daemon_present() != false) {
camera_pack_event(filep, MSM_CAMERA_SET_PARM,
MSM_CAMERA_PRIV_S_FMT, -1, &event);
rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
if (rc < 0)
return rc;
goto done;
rc = camera_check_event_status(&event);
if (rc < 0)
return rc;
goto done;
}
sp->is_vb2_valid = 1;
}
done:
return rc;
}
@ -600,6 +607,12 @@ static int camera_v4l2_vb2_q_init(struct file *filep)
pr_err("%s : memory not available\n", __func__);
return -ENOMEM;
}
q->lock = kzalloc(sizeof(struct mutex), GFP_KERNEL);
if (!q->lock) {
kzfree(q->drv_priv);
return -ENOMEM;
}
mutex_init(q->lock);
q->mem_ops = msm_vb2_get_q_mem_ops();
q->ops = msm_vb2_get_q_ops();
@ -619,6 +632,8 @@ static void camera_v4l2_vb2_q_release(struct file *filep)
kzfree(sp->vb2_q.drv_priv);
mutex_lock(&sp->lock);
vb2_queue_release(&sp->vb2_q);
mutex_destroy(sp->vb2_q.lock);
kzfree(sp->vb2_q.lock);
mutex_unlock(&sp->lock);
}

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2019, The 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
@ -357,12 +357,13 @@ int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
}
} else {
for (i = num_clk - 1; i >= 0; i--) {
if (clk_ptr[i] != NULL) {
if (!IS_ERR_OR_NULL(clk_ptr[i])) {
CDBG("%s disable %s\n", __func__,
clk_info[i].clk_name);
clk_disable(clk_ptr[i]);
clk_unprepare(clk_ptr[i]);
clk_put(clk_ptr[i]);
clk_ptr[i] = NULL;
}
}
}
@ -378,10 +379,11 @@ cam_clk_set_err:
clk_put(clk_ptr[i]);
cam_clk_get_err:
for (i--; i >= 0; i--) {
if (clk_ptr[i] != NULL) {
if (!IS_ERR_OR_NULL(clk_ptr[i])) {
clk_disable(clk_ptr[i]);
clk_unprepare(clk_ptr[i]);
clk_put(clk_ptr[i]);
clk_ptr[i] = NULL;
}
}
return rc;

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2019, The 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
@ -19,15 +19,19 @@ static int msm_vb2_queue_setup(struct vb2_queue *q,
unsigned int sizes[], void *alloc_ctxs[])
{
int i;
struct msm_v4l2_format_data *data = q->drv_priv;
struct msm_v4l2_format_data *data = NULL;
int rc = -EINVAL;
mutex_lock(q->lock);
data = q->drv_priv;
if (!data) {
pr_err("%s: drv_priv NULL\n", __func__);
return -EINVAL;
goto done;
}
if (data->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
if (WARN_ON(data->num_planes > VIDEO_MAX_PLANES))
return -EINVAL;
goto done;
*num_planes = data->num_planes;
@ -36,9 +40,13 @@ static int msm_vb2_queue_setup(struct vb2_queue *q,
} else {
pr_err("%s: Unsupported buf type :%d\n", __func__,
data->type);
return -EINVAL;
goto done;
}
return 0;
rc = 0;
done:
mutex_unlock(q->lock);
return rc;
}
static int msm_vb2_buf_init(struct vb2_buffer *vb)

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2019, The 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
@ -366,9 +366,12 @@ static int camera_v4l2_s_fmt_vid_cap_mplane(struct file *filep, void *fh,
if (pfmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
if (WARN_ON(!sp->vb2_q.drv_priv))
return -ENOMEM;
mutex_lock(sp->vb2_q.lock);
if (WARN_ON(!sp->vb2_q.drv_priv)) {
rc = -ENOMEM;
mutex_unlock(sp->vb2_q.lock);
goto done;
}
memcpy(sp->vb2_q.drv_priv, pfmt->fmt.raw_data,
sizeof(struct msm_v4l2_format_data));
user_fmt = (struct msm_v4l2_format_data *)sp->vb2_q.drv_priv;
@ -377,27 +380,29 @@ static int camera_v4l2_s_fmt_vid_cap_mplane(struct file *filep, void *fh,
user_fmt->num_planes);
/*num_planes need to bound checked, otherwise for loop
can execute forever */
if (WARN_ON(user_fmt->num_planes > VIDEO_MAX_PLANES))
return -EINVAL;
if (WARN_ON(user_fmt->num_planes > VIDEO_MAX_PLANES)) {
rc = -EINVAL;
mutex_unlock(sp->vb2_q.lock);
goto done;
}
for (i = 0; i < user_fmt->num_planes; i++)
pr_debug("%s: plane size[%d]\n", __func__,
user_fmt->plane_sizes[i]);
mutex_unlock(sp->vb2_q.lock);
if (msm_is_daemon_present() != false) {
camera_pack_event(filep, MSM_CAMERA_SET_PARM,
MSM_CAMERA_PRIV_S_FMT, -1, &event);
rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT);
if (rc < 0)
return rc;
goto done;
rc = camera_check_event_status(&event);
if (rc < 0)
return rc;
goto done;
}
sp->is_vb2_valid = 1;
}
done:
return rc;
}
@ -597,6 +602,12 @@ static int camera_v4l2_vb2_q_init(struct file *filep)
pr_err("%s : memory not available\n", __func__);
return -ENOMEM;
}
q->lock = kzalloc(sizeof(struct mutex), GFP_KERNEL);
if (!q->lock) {
kzfree(q->drv_priv);
return -ENOMEM;
}
mutex_init(q->lock);
q->mem_ops = msm_vb2_get_q_mem_ops();
q->ops = msm_vb2_get_q_ops();
@ -616,6 +627,8 @@ static void camera_v4l2_vb2_q_release(struct file *filep)
kzfree(sp->vb2_q.drv_priv);
mutex_lock(&sp->lock);
vb2_queue_release(&sp->vb2_q);
mutex_destroy(sp->vb2_q.lock);
kzfree(sp->vb2_q.lock);
mutex_unlock(&sp->lock);
}

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2011-2014, 2017, The Linux Foundataion. All rights reserved.
/* Copyright (c) 2011-2014, 2017, 2019 The Linux Foundataion.
* 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
@ -364,12 +365,13 @@ int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
}
} else {
for (i = num_clk - 1; i >= 0; i--) {
if (clk_ptr[i] != NULL) {
if (!IS_ERR_OR_NULL(clk_ptr[i])) {
CDBG("%s disable %s\n", __func__,
clk_info[i].clk_name);
clk_disable(clk_ptr[i]);
clk_unprepare(clk_ptr[i]);
clk_put(clk_ptr[i]);
clk_ptr[i] = NULL;
}
}
}
@ -383,10 +385,11 @@ cam_clk_set_err:
clk_put(clk_ptr[i]);
cam_clk_get_err:
for (i--; i >= 0; i--) {
if (clk_ptr[i] != NULL) {
if (!IS_ERR_OR_NULL(clk_ptr[i])) {
clk_disable(clk_ptr[i]);
clk_unprepare(clk_ptr[i]);
clk_put(clk_ptr[i]);
clk_ptr[i] = NULL;
}
}
return rc;

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2019, The 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
@ -19,15 +19,19 @@ static int msm_vb2_queue_setup(struct vb2_queue *q,
unsigned int sizes[], void *alloc_ctxs[])
{
int i;
struct msm_v4l2_format_data *data = q->drv_priv;
struct msm_v4l2_format_data *data = NULL;
int rc = -EINVAL;
mutex_lock(q->lock);
data = q->drv_priv;
if (!data) {
pr_err("%s: drv_priv NULL\n", __func__);
return -EINVAL;
goto done;
}
if (data->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
if (WARN_ON(data->num_planes > VIDEO_MAX_PLANES))
return -EINVAL;
goto done;
*num_planes = data->num_planes;
@ -36,9 +40,13 @@ static int msm_vb2_queue_setup(struct vb2_queue *q,
} else {
pr_err("%s: Unsupported buf type :%d\n", __func__,
data->type);
return -EINVAL;
goto done;
}
return 0;
rc = 0;
done:
mutex_unlock(q->lock);
return rc;
}
int msm_vb2_buf_init(struct vb2_buffer *vb)

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2016, 2019 The 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
@ -316,9 +316,10 @@ static int hfi_process_session_error(u32 device_id,
}
static int hfi_process_event_notify(u32 device_id,
struct hfi_msg_event_notify_packet *pkt,
void *_pkt,
struct msm_vidc_cb_info *info)
{
struct hfi_msg_event_notify_packet *pkt = _pkt;
dprintk(VIDC_DBG, "Received: EVENT_NOTIFY\n");
if (pkt->size < sizeof(struct hfi_msg_event_notify_packet)) {
@ -357,9 +358,10 @@ static int hfi_process_event_notify(u32 device_id,
}
static int hfi_process_sys_init_done(u32 device_id,
struct hfi_msg_sys_init_done_packet *pkt,
void *_pkt,
struct msm_vidc_cb_info *info)
{
struct hfi_msg_sys_init_done_packet *pkt = _pkt;
struct msm_vidc_cb_cmd_done cmd_done = {0};
enum vidc_status status = VIDC_ERR_NONE;
@ -396,9 +398,10 @@ err_no_prop:
}
static int hfi_process_sys_rel_resource_done(u32 device_id,
struct hfi_msg_sys_release_resource_done_packet *pkt,
void *_pkt,
struct msm_vidc_cb_info *info)
{
struct hfi_msg_sys_release_resource_done_packet *pkt = _pkt;
struct msm_vidc_cb_cmd_done cmd_done = {0};
enum vidc_status status = VIDC_ERR_NONE;
u32 pkt_size;
@ -603,6 +606,11 @@ static int hfi_fill_codec_info(u8 *data_ptr,
vidc_get_hal_codec((1 << i) & codecs);
capability->domain =
vidc_get_hal_domain(HFI_VIDEO_DOMAIN_DECODER);
if (codec_count == VIDC_MAX_DECODE_SESSIONS) {
dprintk(VIDC_ERR,
"Max supported decoder sessions reached");
break;
}
}
}
codecs = sys_init_done->enc_codec_supported;
@ -614,6 +622,11 @@ static int hfi_fill_codec_info(u8 *data_ptr,
vidc_get_hal_codec((1 << i) & codecs);
capability->domain =
vidc_get_hal_domain(HFI_VIDEO_DOMAIN_ENCODER);
if (codec_count == VIDC_MAX_SESSIONS) {
dprintk(VIDC_ERR,
"Max supported sessions reached");
break;
}
}
}
sys_init_done->codec_count = codec_count;
@ -1211,9 +1224,10 @@ static void hfi_process_sess_get_prop_buf_req(
}
static int hfi_process_session_prop_info(u32 device_id,
struct hfi_msg_session_property_info_packet *pkt,
void *_pkt,
struct msm_vidc_cb_info *info)
{
struct hfi_msg_session_property_info_packet *pkt = _pkt;
struct msm_vidc_cb_cmd_done cmd_done = {0};
struct hfi_profile_level profile_level = {0};
enum hal_h264_entropy entropy = {0};
@ -1286,9 +1300,10 @@ static int hfi_process_session_prop_info(u32 device_id,
}
static int hfi_process_session_init_done(u32 device_id,
struct hfi_msg_sys_session_init_done_packet *pkt,
void *_pkt,
struct msm_vidc_cb_info *info)
{
struct hfi_msg_sys_session_init_done_packet *pkt = _pkt;
struct msm_vidc_cb_cmd_done cmd_done = {0};
struct vidc_hal_session_init_done session_init_done = { {0} };
@ -1320,9 +1335,10 @@ static int hfi_process_session_init_done(u32 device_id,
}
static int hfi_process_session_load_res_done(u32 device_id,
struct hfi_msg_session_load_resources_done_packet *pkt,
void *_pkt,
struct msm_vidc_cb_info *info)
{
struct hfi_msg_session_load_resources_done_packet *pkt = _pkt;
struct msm_vidc_cb_cmd_done cmd_done = {0};
dprintk(VIDC_DBG, "RECEIVED: SESSION_LOAD_RESOURCES_DONE[%#x]\n",
pkt->session_id);
@ -1349,9 +1365,10 @@ static int hfi_process_session_load_res_done(u32 device_id,
}
static int hfi_process_session_flush_done(u32 device_id,
struct hfi_msg_session_flush_done_packet *pkt,
void *_pkt,
struct msm_vidc_cb_info *info)
{
struct hfi_msg_session_flush_done_packet *pkt = _pkt;
struct msm_vidc_cb_cmd_done cmd_done = {0};
dprintk(VIDC_DBG, "RECEIVED: SESSION_FLUSH_DONE[%#x]\n",
@ -1394,9 +1411,10 @@ static int hfi_process_session_flush_done(u32 device_id,
}
static int hfi_process_session_etb_done(u32 device_id,
struct hfi_msg_session_empty_buffer_done_packet *pkt,
void *_pkt,
struct msm_vidc_cb_info *info)
{
struct hfi_msg_session_empty_buffer_done_packet *pkt = _pkt;
struct msm_vidc_cb_data_done data_done = {0};
struct hfi_picture_type *hfi_picture_type = NULL;
@ -1445,9 +1463,10 @@ static int hfi_process_session_etb_done(u32 device_id,
}
static int hfi_process_session_ftb_done(
u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr,
u32 device_id, void *_pkt,
struct msm_vidc_cb_info *info)
{
struct vidc_hal_msg_pkt_hdr *msg_hdr = _pkt;
struct msm_vidc_cb_data_done data_done = {0};
bool is_decoder = false, is_encoder = false;
@ -1572,9 +1591,10 @@ static int hfi_process_session_ftb_done(
}
static int hfi_process_session_start_done(u32 device_id,
struct hfi_msg_session_start_done_packet *pkt,
void *_pkt,
struct msm_vidc_cb_info *info)
{
struct hfi_msg_session_start_done_packet *pkt = _pkt;
struct msm_vidc_cb_cmd_done cmd_done = {0};
dprintk(VIDC_DBG, "RECEIVED: SESSION_START_DONE[%#x]\n",
@ -1600,9 +1620,10 @@ static int hfi_process_session_start_done(u32 device_id,
}
static int hfi_process_session_stop_done(u32 device_id,
struct hfi_msg_session_stop_done_packet *pkt,
void *_pkt,
struct msm_vidc_cb_info *info)
{
struct hfi_msg_session_stop_done_packet *pkt = _pkt;
struct msm_vidc_cb_cmd_done cmd_done = {0};
dprintk(VIDC_DBG, "RECEIVED: SESSION_STOP_DONE[%#x]\n",
@ -1629,9 +1650,10 @@ static int hfi_process_session_stop_done(u32 device_id,
}
static int hfi_process_session_rel_res_done(u32 device_id,
struct hfi_msg_session_release_resources_done_packet *pkt,
void *_pkt,
struct msm_vidc_cb_info *info)
{
struct hfi_msg_session_release_resources_done_packet *pkt = _pkt;
struct msm_vidc_cb_cmd_done cmd_done = {0};
dprintk(VIDC_DBG, "RECEIVED: SESSION_RELEASE_RESOURCES_DONE[%#x]\n",
@ -1658,9 +1680,10 @@ static int hfi_process_session_rel_res_done(u32 device_id,
}
static int hfi_process_session_rel_buf_done(u32 device_id,
struct hfi_msg_session_release_buffers_done_packet *pkt,
void *_pkt,
struct msm_vidc_cb_info *info)
{
struct hfi_msg_session_release_buffers_done_packet *pkt = _pkt;
struct msm_vidc_cb_cmd_done cmd_done = {0};
if (!pkt || pkt->size <
@ -1693,9 +1716,10 @@ static int hfi_process_session_rel_buf_done(u32 device_id,
}
static int hfi_process_session_end_done(u32 device_id,
struct hfi_msg_sys_session_end_done_packet *pkt,
void *_pkt,
struct msm_vidc_cb_info *info)
{
struct hfi_msg_sys_session_end_done_packet *pkt = _pkt;
struct msm_vidc_cb_cmd_done cmd_done = {0};
dprintk(VIDC_DBG, "RECEIVED: SESSION_END_DONE[%#x]\n", pkt->session_id);
@ -1720,9 +1744,10 @@ static int hfi_process_session_end_done(u32 device_id,
}
static int hfi_process_session_abort_done(u32 device_id,
struct hfi_msg_sys_session_abort_done_packet *pkt,
void *_pkt,
struct msm_vidc_cb_info *info)
{
struct hfi_msg_sys_session_abort_done_packet *pkt = _pkt;
struct msm_vidc_cb_cmd_done cmd_done = {0};
dprintk(VIDC_DBG, "RECEIVED: SESSION_ABORT_DONE[%#x]\n",
@ -1827,9 +1852,10 @@ static void hfi_process_sys_get_prop_image_version(
}
static int hfi_process_sys_property_info(u32 device_id,
struct hfi_msg_sys_property_info_packet *pkt,
void *_pkt,
struct msm_vidc_cb_info *info)
{
struct hfi_msg_sys_property_info_packet *pkt = _pkt;
if (!pkt) {
dprintk(VIDC_ERR, "%s: invalid param\n", __func__);
return -EINVAL;
@ -1861,7 +1887,7 @@ static int hfi_process_sys_property_info(u32 device_id,
}
static int hfi_process_ignore(u32 device_id,
struct vidc_hal_msg_pkt_hdr *msg_hdr,
void *_pkt,
struct msm_vidc_cb_info *info)
{
*info = (struct msm_vidc_cb_info) {
@ -1945,5 +1971,6 @@ int hfi_process_msg_packet(u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr,
break;
}
return pkt_func ? pkt_func(device_id, msg_hdr, info) : -ENOTSUPP;
return pkt_func ?
pkt_func(device_id, (void *)msg_hdr, info) : -ENOTSUPP;
}

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2019, The 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
@ -1478,7 +1478,7 @@ void validate_output_buffers(struct msm_vidc_inst *inst)
}
mutex_lock(&inst->outputbufs.lock);
list_for_each_entry(binfo, &inst->outputbufs.list, list) {
if (binfo->buffer_ownership != DRIVER) {
if (binfo && binfo->buffer_ownership != DRIVER) {
dprintk(VIDC_DBG,
"This buffer is with FW %pa\n",
&binfo->handle->device_addr);
@ -3175,8 +3175,7 @@ static int set_output_buffers(struct msm_vidc_inst *inst,
if (!handle) {
dprintk(VIDC_ERR,
"Failed to allocate output memory\n");
rc = -ENOMEM;
goto err_no_mem;
return -ENOMEM;
}
rc = msm_comm_smem_cache_operations(inst,
handle, SMEM_CACHE_CLEAN, -1);
@ -3228,10 +3227,9 @@ static int set_output_buffers(struct msm_vidc_inst *inst,
}
return rc;
fail_set_buffers:
msm_comm_smem_free(inst, handle);
err_no_mem:
kfree(binfo);
fail_kzalloc:
msm_comm_smem_free(inst, handle);
return rc;
}

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2019, The 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
@ -328,7 +328,7 @@ static int __write_queue(struct vidc_iface_q_info *qinfo, u8 *packet,
{
struct hfi_queue_header *queue;
u32 packet_size_in_words, new_write_idx;
u32 empty_space, read_idx;
u32 empty_space, read_idx, write_idx;
u32 *write_ptr;
if (!qinfo || !packet) {
@ -351,16 +351,18 @@ static int __write_queue(struct vidc_iface_q_info *qinfo, u8 *packet,
}
packet_size_in_words = (*(u32 *)packet) >> 2;
if (!packet_size_in_words) {
dprintk(VIDC_ERR, "Zero packet size\n");
if (!packet_size_in_words || packet_size_in_words >
qinfo->q_array.mem_size>>2) {
dprintk(VIDC_ERR, "Invalid packet size\n");
return -ENODATA;
}
read_idx = queue->qhdr_read_idx;
write_idx = queue->qhdr_write_idx;
empty_space = (queue->qhdr_write_idx >= read_idx) ?
(queue->qhdr_q_size - (queue->qhdr_write_idx - read_idx)) :
(read_idx - queue->qhdr_write_idx);
empty_space = (write_idx >= read_idx) ?
((qinfo->q_array.mem_size>>2) - (write_idx - read_idx)) :
(read_idx - write_idx);
if (empty_space <= packet_size_in_words) {
queue->qhdr_tx_req = 1;
dprintk(VIDC_ERR, "Insufficient size (%d) to write (%d)\n",
@ -370,13 +372,20 @@ static int __write_queue(struct vidc_iface_q_info *qinfo, u8 *packet,
queue->qhdr_tx_req = 0;
new_write_idx = (queue->qhdr_write_idx + packet_size_in_words);
new_write_idx = write_idx + packet_size_in_words;
write_ptr = (u32 *)((qinfo->q_array.align_virtual_addr) +
(queue->qhdr_write_idx << 2));
if (new_write_idx < queue->qhdr_q_size) {
(write_idx << 2));
if (write_ptr < (u32 *)qinfo->q_array.align_virtual_addr ||
write_ptr > (u32 *)(qinfo->q_array.align_virtual_addr +
qinfo->q_array.mem_size)) {
dprintk(VIDC_ERR, "Invalid write index");
return -ENODATA;
}
if (new_write_idx < (qinfo->q_array.mem_size >> 2)) {
memcpy(write_ptr, packet, packet_size_in_words << 2);
} else {
new_write_idx -= queue->qhdr_q_size;
new_write_idx -= qinfo->q_array.mem_size >> 2;
memcpy(write_ptr, packet, (packet_size_in_words -
new_write_idx) << 2);
memcpy((void *)qinfo->q_array.align_virtual_addr,
@ -468,6 +477,7 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet,
u32 packet_size_in_words, new_read_idx;
u32 *read_ptr;
u32 receive_request = 0;
u32 read_idx, write_idx;
int rc = 0;
if (!qinfo || !packet || !pb_tx_req_is_set) {
@ -499,8 +509,16 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet,
if (queue->qhdr_type & HFI_Q_ID_CTRL_TO_HOST_MSG_Q)
receive_request = 1;
if (queue->qhdr_read_idx == queue->qhdr_write_idx) {
read_idx = queue->qhdr_read_idx;
write_idx = queue->qhdr_write_idx;
if (read_idx == write_idx) {
queue->qhdr_rx_req = receive_request;
/*
* mb() to ensure qhdr is updated in main memory
* so that venus reads the updated header values
*/
mb();
*pb_tx_req_is_set = 0;
dprintk(VIDC_DBG,
"%s queue is empty, rx_req = %u, tx_req = %u, read_idx = %u\n",
@ -511,21 +529,28 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet,
}
read_ptr = (u32 *)((qinfo->q_array.align_virtual_addr) +
(queue->qhdr_read_idx << 2));
(read_idx << 2));
if (read_ptr < (u32 *)qinfo->q_array.align_virtual_addr ||
read_ptr > (u32 *)(qinfo->q_array.align_virtual_addr +
qinfo->q_array.mem_size - sizeof(*read_ptr))) {
dprintk(VIDC_ERR, "Invalid read index\n");
return -ENODATA;
}
packet_size_in_words = (*read_ptr) >> 2;
if (!packet_size_in_words) {
dprintk(VIDC_ERR, "Zero packet size\n");
return -ENODATA;
}
new_read_idx = queue->qhdr_read_idx + packet_size_in_words;
if (((packet_size_in_words << 2) <= VIDC_IFACEQ_VAR_HUGE_PKT_SIZE)
&& queue->qhdr_read_idx <= queue->qhdr_q_size) {
if (new_read_idx < queue->qhdr_q_size) {
new_read_idx = read_idx + packet_size_in_words;
if (((packet_size_in_words << 2) <= VIDC_IFACEQ_VAR_HUGE_PKT_SIZE) &&
read_idx <= (qinfo->q_array.mem_size >> 2)) {
if (new_read_idx < (qinfo->q_array.mem_size >> 2)) {
memcpy(packet, read_ptr,
packet_size_in_words << 2);
} else {
new_read_idx -= queue->qhdr_q_size;
new_read_idx -= (qinfo->q_array.mem_size >> 2);
memcpy(packet, read_ptr,
(packet_size_in_words - new_read_idx) << 2);
memcpy(packet + ((packet_size_in_words -
@ -536,18 +561,23 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet,
} else {
dprintk(VIDC_WARN,
"BAD packet received, read_idx: %#x, pkt_size: %d\n",
queue->qhdr_read_idx, packet_size_in_words << 2);
read_idx, packet_size_in_words << 2);
dprintk(VIDC_WARN, "Dropping this packet\n");
new_read_idx = queue->qhdr_write_idx;
new_read_idx = write_idx;
rc = -ENODATA;
}
queue->qhdr_read_idx = new_read_idx;
if (queue->qhdr_read_idx != queue->qhdr_write_idx)
if (new_read_idx != write_idx)
queue->qhdr_rx_req = 0;
else
queue->qhdr_rx_req = receive_request;
/*
* mb() to ensure qhdr is updated in main memory
* so that venus reads the updated header values
*/
mb();
queue->qhdr_read_idx = new_read_idx;
*pb_tx_req_is_set = (1 == queue->qhdr_tx_req) ? 1 : 0;
@ -1652,7 +1682,7 @@ static int __iface_cmdq_write_relaxed(struct venus_hfi_device *device,
__strict_check(device);
if (!__core_in_valid_state(device)) {
dprintk(VIDC_DBG, "%s - fw not in init state\n", __func__);
dprintk(VIDC_ERR, "%s - fw not in init state\n", __func__);
result = -EINVAL;
goto err_q_null;
}
@ -3378,8 +3408,6 @@ static void __process_sys_error(struct venus_hfi_device *device)
{
struct hfi_sfr_struct *vsfr = NULL;
__set_state(device, VENUS_STATE_DEINIT);
/* Once SYS_ERROR received from HW, it is safe to halt the AXI.
* With SYS_ERROR, Venus FW may have crashed and HW might be
* active and causing unnecessary transactions. Hence it is
@ -3626,6 +3654,10 @@ static int __response_handler(struct venus_hfi_device *device)
"Too many packets in message queue to handle at once, deferring read\n");
break;
}
/* do not read packets after sys error packet */
if (info->response_type == HAL_SYS_ERROR)
break;
}
if (requeue_pm_work && device->res->sw_power_collapsible) {
@ -3687,7 +3719,12 @@ err_no_work:
for (i = 0; !IS_ERR_OR_NULL(device->response_pkt) &&
i < num_responses; ++i) {
struct msm_vidc_cb_info *r = &device->response_pkt[i];
if (!__core_in_valid_state(device)) {
dprintk(VIDC_ERR,
"Ignore responses from %d to %d as device is in invalid state",
(i + 1), num_responses);
break;
}
device->callback(r->response_type, &r->response);
}

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2017, 2019 The 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
@ -66,6 +66,9 @@
/* 16 encoder and 16 decoder sessions */
#define VIDC_MAX_SESSIONS 32
#define VIDC_MAX_DECODE_SESSIONS 16
#define VIDC_MAX_ENCODE_SESSIONS 16
enum vidc_status {
VIDC_ERR_NONE = 0x0,

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2010-2016, 2019 The 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
@ -879,8 +879,7 @@ ssize_t audio_in_write(struct file *file,
__func__, audio->ac->session);
}
}
xfer = (count > (audio->pcm_cfg.buffer_size)) ?
(audio->pcm_cfg.buffer_size) : count;
xfer = (count > size) ? size : count;
if (copy_from_user(cpy_ptr, buf, xfer)) {
rc = -EFAULT;

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2016, 2019, The 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
@ -507,6 +507,12 @@ static int32_t q6usm_mmapcallback(struct apr_client_data *data, void *priv)
uint32_t token;
uint32_t *payload = data->payload;
if (data->payload_size < (2 * sizeof(uint32_t))) {
pr_err("%s: payload has invalid size[%d]\n", __func__,
data->payload_size);
return -EINVAL;
}
pr_debug("%s: ptr0[0x%x]; ptr1[0x%x]; opcode[0x%x]\n",
__func__, payload[0], payload[1], data->opcode);
pr_debug("%s: token[0x%x]; payload_size[%d]; src[%d]; dest[%d];\n",
@ -567,6 +573,11 @@ static int32_t q6usm_callback(struct apr_client_data *data, void *priv)
}
if (data->opcode == APR_BASIC_RSP_RESULT) {
if (data->payload_size < (2 * sizeof(uint32_t))) {
pr_err("%s: payload has invalid size[%d]\n", __func__,
data->payload_size);
return -EINVAL;
}
/* status field check */
if (payload[1]) {
pr_err("%s: wrong response[%d] on cmd [%d]\n",
@ -630,6 +641,14 @@ static int32_t q6usm_callback(struct apr_client_data *data, void *priv)
opcode = Q6USM_EVENT_READ_DONE;
spin_lock_irqsave(&port->dsp_lock, dsp_flags);
if (data->payload_size <
(sizeof(uint32_t)*(READDONE_IDX_STATUS + 1))) {
pr_err("%s: Invalid payload size for READDONE[%d]\n",
__func__, data->payload_size);
spin_unlock_irqrestore(&port->dsp_lock,
dsp_flags);
return -EINVAL;
}
if (payload[READDONE_IDX_STATUS]) {
pr_err("%s: wrong READDONE[%d]; token[%d]\n",
__func__,
@ -675,6 +694,12 @@ static int32_t q6usm_callback(struct apr_client_data *data, void *priv)
struct us_port_data *port = &usc->port[IN];
opcode = Q6USM_EVENT_WRITE_DONE;
if (data->payload_size <
(sizeof(uint32_t)*(WRITEDONE_IDX_STATUS + 1))) {
pr_err("%s: Invalid payload size for WRITEDONE[%d]\n",
__func__, data->payload_size);
return -EINVAL;
}
if (payload[WRITEDONE_IDX_STATUS]) {
pr_err("%s: wrong WRITEDONE_IDX_STATUS[%d]\n",
__func__,

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2019, The 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
@ -735,6 +735,12 @@ ssize_t ipa_read(struct file *filp, char __user *buf, size_t count,
IPADBG("msg=%pK\n", msg);
locked = 0;
mutex_unlock(&ipa_ctx->msg_lock);
if (count < sizeof(struct ipa_msg_meta)) {
kfree(msg);
msg = NULL;
ret = -EFAULT;
break;
}
if (copy_to_user(buf, &msg->meta,
sizeof(struct ipa_msg_meta))) {
kfree(msg);
@ -745,6 +751,7 @@ ssize_t ipa_read(struct file *filp, char __user *buf, size_t count,
buf += sizeof(struct ipa_msg_meta);
count -= sizeof(struct ipa_msg_meta);
if (msg->buff) {
if (count >= msg->meta.msg_len) {
if (copy_to_user(buf, msg->buff,
msg->meta.msg_len)) {
kfree(msg);
@ -752,6 +759,12 @@ ssize_t ipa_read(struct file *filp, char __user *buf, size_t count,
ret = -EFAULT;
break;
}
} else {
kfree(msg);
msg = NULL;
ret = -EFAULT;
break;
}
buf += msg->meta.msg_len;
count -= msg->meta.msg_len;
msg->callback(msg->buff, msg->meta.msg_len,

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2019, The 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
@ -742,6 +742,12 @@ ssize_t ipa3_read(struct file *filp, char __user *buf, size_t count,
if (msg) {
locked = 0;
mutex_unlock(&ipa3_ctx->msg_lock);
if (count < sizeof(struct ipa_msg_meta)) {
kfree(msg);
msg = NULL;
ret = -EFAULT;
break;
}
if (copy_to_user(buf, &msg->meta,
sizeof(struct ipa_msg_meta))) {
ret = -EFAULT;
@ -752,6 +758,7 @@ ssize_t ipa3_read(struct file *filp, char __user *buf, size_t count,
buf += sizeof(struct ipa_msg_meta);
count -= sizeof(struct ipa_msg_meta);
if (msg->buff) {
if (count >= msg->meta.msg_len) {
if (copy_to_user(buf, msg->buff,
msg->meta.msg_len)) {
ret = -EFAULT;
@ -759,6 +766,12 @@ ssize_t ipa3_read(struct file *filp, char __user *buf, size_t count,
msg = NULL;
break;
}
} else {
ret = -EFAULT;
kfree(msg);
msg = NULL;
break;
}
buf += msg->meta.msg_len;
count -= msg->meta.msg_len;
msg->callback(msg->buff, msg->meta.msg_len,

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2019, The 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
@ -779,7 +779,7 @@ int ipa3_qmi_ul_filter_request_send(
{
struct ipa_configure_ul_firewall_rules_resp_msg_v01 resp;
struct msg_desc req_desc, resp_desc;
int rc;
int rc, i;
IPAWANDBG("IPACM pass %u rules to Q6\n",
req->firewall_rules_list_len);
@ -799,6 +799,37 @@ int ipa3_qmi_ul_filter_request_send(
}
mutex_unlock(&ipa3_qmi_lock);
/* check if modem is up */
if (!ipa3_qmi_indication_fin ||
!ipa3_qmi_modem_init_fin ||
!ipa_q6_clnt) {
IPAWANDBG("modem QMI service is not up yet\n");
return -EINVAL;
}
/* Passing 0 rules means that firewall is disabled */
if (req->firewall_rules_list_len == 0)
IPAWANDBG("IPACM passed 0 rules to Q6\n");
if (req->firewall_rules_list_len >= QMI_IPA_MAX_UL_FIREWALL_RULES_V01) {
IPAWANERR(
"Number of rules passed by IPACM, %d, exceed limit %d\n",
req->firewall_rules_list_len,
QMI_IPA_MAX_UL_FIREWALL_RULES_V01);
return -EINVAL;
}
/* Check for valid IP type */
for (i = 0; i < req->firewall_rules_list_len; i++) {
if (req->firewall_rules_list[i].ip_type !=
QMI_IPA_IP_TYPE_V4_V01 &&
req->firewall_rules_list[i].ip_type !=
QMI_IPA_IP_TYPE_V6_V01)
IPAWANERR("Invalid IP type %d\n",
req->firewall_rules_list[i].ip_type);
return -EINVAL;
}
req_desc.max_msg_len =
QMI_IPA_INSTALL_UL_FIREWALL_RULES_REQ_MAX_MSG_LEN_V01;
req_desc.msg_id = QMI_IPA_INSTALL_UL_FIREWALL_RULES_REQ_V01;

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2019, The 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
@ -677,7 +677,8 @@ int sps_get_bam_debug_info(unsigned long dev, u32 option, u32 para,
/* Search for the target BAM device */
bam = sps_h2bam(dev);
if (bam == NULL) {
pr_err("sps:Can't find any BAM with handle 0x%lx.", dev);
pr_err("sps:Can't find any BAM with handle 0x%pK.",
(void *)dev);
mutex_unlock(&sps->lock);
return SPS_ERROR;
}
@ -1212,7 +1213,7 @@ struct sps_bam *sps_h2bam(unsigned long h)
{
struct sps_bam *bam;
SPS_DBG1(sps, "sps:%s: BAM handle:0x%lx.", __func__, h);
SPS_DBG1(sps, "sps:%s: BAM handle:0x%pK.", __func__, (void *)h);
if (h == SPS_DEV_HANDLE_MEM || h == SPS_DEV_HANDLE_INVALID)
return NULL;
@ -1222,7 +1223,7 @@ struct sps_bam *sps_h2bam(unsigned long h)
return bam;
}
SPS_ERR(sps, "sps:Can't find BAM device for handle 0x%lx.", h);
SPS_ERR(sps, "sps:Can't find BAM device for handle 0x%pK.", (void *)h);
return NULL;
}
@ -1327,16 +1328,17 @@ int sps_connect(struct sps_pipe *h, struct sps_connect *connect)
bam = sps_h2bam(dev);
if (bam == NULL) {
SPS_ERR(sps, "sps:Invalid BAM device handle: 0x%lx", dev);
SPS_ERR(sps, "sps:Invalid BAM device handle: 0x%pK",
(void *)dev);
result = SPS_ERROR;
goto exit_err;
}
mutex_lock(&bam->lock);
SPS_DBG2(bam, "sps:sps_connect: bam %pa src 0x%lx dest 0x%lx mode %s",
SPS_DBG2(bam, "sps:sps_connect: bam %pa src 0x%pK dest 0x%pK mode %s",
BAM_ID(bam),
connect->source,
connect->destination,
(void *)connect->source,
(void *)connect->destination,
connect->mode == SPS_MODE_SRC ? "SRC" : "DEST");
/* Allocate resources for the specified connection */
@ -1400,10 +1402,10 @@ int sps_disconnect(struct sps_pipe *h)
}
SPS_DBG2(bam,
"sps:sps_disconnect: bam %pa src 0x%lx dest 0x%lx mode %s",
"sps:sps_disconnect: bam %pa src 0x%pK dest 0x%pK mode %s",
BAM_ID(bam),
pipe->connect.source,
pipe->connect.destination,
(void *)pipe->connect.source,
(void *)pipe->connect.destination,
pipe->connect.mode == SPS_MODE_SRC ? "SRC" : "DEST");
result = SPS_ERROR;
@ -1799,7 +1801,8 @@ int sps_device_reset(unsigned long dev)
/* Search for the target BAM device */
bam = sps_h2bam(dev);
if (bam == NULL) {
SPS_ERR(sps, "sps:Invalid BAM device handle: 0x%lx", dev);
SPS_ERR(sps, "sps:Invalid BAM device handle: 0x%pK",
(void *)dev);
result = SPS_ERROR;
goto exit_err;
}
@ -1810,7 +1813,8 @@ int sps_device_reset(unsigned long dev)
result = sps_bam_reset(bam);
mutex_unlock(&bam->lock);
if (result) {
SPS_ERR(sps, "sps:Fail to reset BAM device: 0x%lx", dev);
SPS_ERR(sps, "sps:Fail to reset BAM device: 0x%pK",
(void *)dev);
goto exit_err;
}

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2017, 2019, The 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
@ -884,8 +884,8 @@ int sps_bam_pipe_connect(struct sps_pipe *bam_pipe,
else
iova = bam_pipe->connect.source_iova;
SPS_DBG2(dev,
"sps:BAM %pa pipe %d uses IOVA 0x%lx.\n",
BAM_ID(dev), pipe_index, iova);
"sps:BAM %pa pipe %d uses IOVA 0x%pK.\n",
BAM_ID(dev), pipe_index, (void *)iova);
hw_params.peer_phys_addr = (u32)iova;
} else {
hw_params.peer_phys_addr = peer_bam->props.phys_addr;
@ -907,9 +907,9 @@ int sps_bam_pipe_connect(struct sps_pipe *bam_pipe,
hw_params.data_base =
(phys_addr_t)bam_pipe->connect.data.iova;
SPS_DBG2(dev,
"sps:BAM %pa pipe %d uses IOVA 0x%lx for data FIFO.\n",
"sps:BAM %pa pipe %d uses IOVA 0x%pK for data FIFO.\n",
BAM_ID(dev), pipe_index,
bam_pipe->connect.data.iova);
(void *)(bam_pipe->connect.data.iova));
} else {
hw_params.data_base = map->data.phys_base;
}
@ -960,9 +960,9 @@ int sps_bam_pipe_connect(struct sps_pipe *bam_pipe,
hw_params.desc_base =
(phys_addr_t)bam_pipe->connect.desc.iova;
SPS_DBG2(dev,
"sps:BAM %pa pipe %d uses IOVA 0x%lx for desc FIFO.\n",
"sps:BAM %pa pipe %d uses IOVA 0x%pK for desc FIFO.\n",
BAM_ID(dev), pipe_index,
bam_pipe->connect.desc.iova);
(void *)(bam_pipe->connect.desc.iova));
} else {
hw_params.desc_base = map->desc.phys_base;
}
@ -1412,8 +1412,9 @@ int sps_bam_pipe_transfer_one(struct sps_bam *dev,
u32 next_write;
static int show_recom;
SPS_DBG(dev, "sps:BAM %pa pipe %d addr 0x%x size 0x%x flags 0x%x\n",
BAM_ID(dev), pipe_index, addr, size, flags);
SPS_DBG(dev, "sps:BAM %pa pipe %d addr 0x%pK size 0x%x flags 0x%x\n",
BAM_ID(dev), pipe_index,
(void *)(long)addr, size, flags);
/* Is this a BAM-to-BAM or satellite connection? */
if ((pipe->state & (BAM_STATE_BAM2BAM | BAM_STATE_REMOTE))) {
@ -1937,8 +1938,8 @@ static void pipe_handler_eot(struct sps_bam *dev, struct sps_pipe *pipe)
user = &pipe->sys.user_ptrs[offset / sizeof(struct sps_iovec)];
for (;;) {
SPS_DBG(dev,
"sps:%s; pipe index:%d; iovec addr:0x%x; size:0x%x; flags:0x%x; enabled:0x%x; *user is %s NULL.\n",
__func__, pipe->pipe_index, cache->addr,
"sps:%s; pipe index:%d; iovec addr:0x%pK; size:0x%x; flags:0x%x; enabled:0x%x; *user is %s NULL.\n",
__func__, pipe->pipe_index, (void *)(long)cache->addr,
cache->size, cache->flags, enabled,
(*user == NULL) ? "" : "not");
@ -2226,8 +2227,8 @@ int sps_bam_pipe_get_iovec(struct sps_bam *dev, u32 pipe_index,
pipe->sys.acked_offset = 0;
SPS_DBG(dev,
"sps:%s; pipe index:%d; iovec addr:0x%x; size:0x%x; flags:0x%x; acked_offset:0x%x.\n",
__func__, pipe->pipe_index, desc->addr,
"sps:%s; pipe index:%d; iovec addr:0x%pK; size:0x%x; flags:0x%x; acked_offset:0x%x.\n",
__func__, pipe->pipe_index, (void *)(long)desc->addr,
desc->size, desc->flags, pipe->sys.acked_offset);
return 0;

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2011-2013, 2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2013, 2015, 2019 The 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
@ -380,7 +381,7 @@ int sps_dma_device_de_init(unsigned long h)
dev = sps_dma_find_device(h);
if (dev == NULL) {
SPS_ERR(sps, "sps:BAM-DMA: not registered: %lx", h);
SPS_ERR(sps, "sps:BAM-DMA: not registered: %pK", (void *)h);
result = SPS_ERROR;
goto exit_err;
}
@ -546,8 +547,8 @@ int sps_alloc_dma_chan(const struct sps_alloc_dma_chan *alloc,
dev = sps_dma_find_device(alloc->dev);
if (dev == NULL) {
SPS_ERR(sps, "sps:BAM-DMA: invalid BAM handle: %lx",
alloc->dev);
SPS_ERR(sps, "sps:BAM-DMA: invalid BAM handle: %pK",
(void *)alloc->dev);
goto exit_err;
}
@ -620,7 +621,8 @@ int sps_free_dma_chan(struct sps_dma_chan *chan)
dev = sps_dma_find_device(chan->dev);
if (dev == NULL) {
SPS_ERR(sps, "sps:BAM-DMA: invalid BAM handle: %lx", chan->dev);
SPS_ERR(sps, "sps:BAM-DMA: invalid BAM handle: %pK",
(void *)chan->dev);
result = SPS_ERROR;
goto exit_err;
}

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2013, 2015, 2017, The Linux Foundation.
/* Copyright (c) 2011-2013, 2015, 2017, 2019, The Linux Foundation.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@ -75,8 +75,8 @@ phys_addr_t sps_mem_alloc_io(u32 bytes)
return SPS_ADDR_INVALID;
}
SPS_DBG3(sps, "sps:sps_mem_alloc_io.phys=%pa.virt=0x%lx.size=0x%x.",
&phys_addr, virt_addr, bytes);
SPS_DBG3(sps, "sps:sps_mem_alloc_io.phys=%pa.virt=0x%pK.size=0x%x.",
&phys_addr, (void *)virt_addr, bytes);
return phys_addr;
}
@ -92,8 +92,8 @@ void sps_mem_free_io(phys_addr_t phys_addr, u32 bytes)
iomem_offset = phys_addr - iomem_phys;
virt_addr = (uintptr_t) iomem_virt + iomem_offset;
SPS_DBG3(sps, "sps:sps_mem_free_io.phys=%pa.virt=0x%lx.size=0x%x.",
&phys_addr, virt_addr, bytes);
SPS_DBG3(sps, "sps:sps_mem_free_io.phys=%pa.virt=0x%pK.size=0x%x.",
&phys_addr, (void *)virt_addr, bytes);
gen_pool_free(pool, virt_addr, bytes);
total_free += bytes;

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2011-2015, 2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2015, 2017, 2019, The 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
@ -380,8 +381,8 @@ static struct sps_connection *sps_rm_create(struct sps_pipe *pipe)
map->src.bam = sps_h2bam(map->src.dev);
if (map->src.bam == NULL) {
if (map->src.dev != SPS_DEV_HANDLE_MEM) {
SPS_ERR(sps, "sps:Invalid BAM handle: %pa",
&map->src.dev);
SPS_ERR(sps, "sps:Invalid BAM handle: %pK",
(void *)(&map->src.dev));
goto exit_err;
}
map->src.pipe_index = SPS_BAM_PIPE_INVALID;
@ -389,8 +390,8 @@ static struct sps_connection *sps_rm_create(struct sps_pipe *pipe)
map->dest.bam = sps_h2bam(map->dest.dev);
if (map->dest.bam == NULL) {
if (map->dest.dev != SPS_DEV_HANDLE_MEM) {
SPS_ERR(sps, "sps:Invalid BAM handle: %pa",
&map->dest.dev);
SPS_ERR(sps, "sps:Invalid BAM handle: %pK",
(void *)(&map->dest.dev));
goto exit_err;
}
map->dest.pipe_index = SPS_BAM_PIPE_INVALID;
@ -399,8 +400,8 @@ static struct sps_connection *sps_rm_create(struct sps_pipe *pipe)
/* Check the BAM device for the pipe */
if ((dir == SPS_MODE_SRC && map->src.bam == NULL) ||
(dir != SPS_MODE_SRC && map->dest.bam == NULL)) {
SPS_ERR(sps, "sps:Invalid BAM endpt: dir %d src %pa dest %pa",
dir, &map->src.dev, &map->dest.dev);
SPS_ERR(sps, "sps:Invalid BAM endpt: dir %d src %pK dest %pK",
dir, (void *)(&map->src.dev), (void *)(&map->dest.dev));
goto exit_err;
}

View file

@ -375,7 +375,7 @@ static void tx_func(struct kthread_work *work);
static struct channel_ctx *ch_name_to_ch_ctx_create(
struct glink_core_xprt_ctx *xprt_ctx,
const char *name);
const char *name, bool local);
static void ch_push_remote_rx_intent(struct channel_ctx *ctx, size_t size,
uint32_t riid, void *cookie);
@ -1870,13 +1870,14 @@ static void glink_ch_ctx_release(struct rwref_lock *ch_st_lock)
* it is not found and get reference of context.
* @xprt_ctx: Transport to search for a matching channel.
* @name: Name of the desired channel.
* @local: If called from local open or not
*
* Return: The channel corresponding to @name, NULL if a matching channel was
* not found AND a new channel could not be created.
*/
static struct channel_ctx *ch_name_to_ch_ctx_create(
struct glink_core_xprt_ctx *xprt_ctx,
const char *name)
const char *name, bool local)
{
struct channel_ctx *entry;
struct channel_ctx *ctx;
@ -1920,10 +1921,23 @@ check_ctx:
list_for_each_entry_safe(entry, temp, &xprt_ctx->channels,
port_list_node)
if (!strcmp(entry->name, name) && !entry->pending_delete) {
rwref_get(&entry->ch_state_lhb2);
/* port already exists */
if (entry->local_open_state != GLINK_CHANNEL_CLOSED
&& local) {
/* not ready to be re-opened */
GLINK_INFO_CH_XPRT(entry, xprt_ctx,
"%s: Ch not ready. State: %u\n",
__func__, entry->local_open_state);
rwref_put(&entry->ch_state_lhb2);
entry = NULL;
} else if (local) {
entry->local_open_state =
GLINK_CHANNEL_OPENING;
}
spin_unlock_irqrestore(&xprt_ctx->xprt_ctx_lock_lhb1,
flags);
kfree(ctx);
rwref_get(&entry->ch_state_lhb2);
rwref_write_put(&xprt_ctx->xprt_state_lhb0);
return entry;
}
@ -1954,6 +1968,8 @@ check_ctx:
ctx->transport_ptr = xprt_ctx;
rwref_get(&ctx->ch_state_lhb2);
if (local)
ctx->local_open_state = GLINK_CHANNEL_OPENING;
list_add_tail(&ctx->port_list_node, &xprt_ctx->channels);
GLINK_INFO_PERF_CH_XPRT(ctx, xprt_ctx,
@ -2639,23 +2655,13 @@ void *glink_open(const struct glink_open_config *cfg)
* look for an existing port structure which can occur in
* reopen and remote-open-first cases
*/
ctx = ch_name_to_ch_ctx_create(transport_ptr, cfg->name);
ctx = ch_name_to_ch_ctx_create(transport_ptr, cfg->name, true);
if (ctx == NULL) {
GLINK_ERR("%s:%s %s: Error - unable to allocate new channel\n",
cfg->transport, cfg->edge, __func__);
return ERR_PTR(-ENOMEM);
}
/* port already exists */
if (ctx->local_open_state != GLINK_CHANNEL_CLOSED) {
/* not ready to be re-opened */
GLINK_INFO_CH_XPRT(ctx, transport_ptr,
"%s: Channel not ready to be re-opened. State: %u\n",
__func__, ctx->local_open_state);
rwref_put(&ctx->ch_state_lhb2);
return ERR_PTR(-EBUSY);
}
/* initialize port structure */
ctx->user_priv = cfg->priv;
ctx->rx_intent_req_timeout_jiffies =
@ -2686,7 +2692,6 @@ void *glink_open(const struct glink_open_config *cfg)
ctx->local_xprt_req = best_id;
ctx->no_migrate = cfg->transport &&
!(cfg->options & GLINK_OPT_INITIAL_XPORT);
ctx->local_open_state = GLINK_CHANNEL_OPENING;
GLINK_INFO_PERF_CH(ctx,
"%s: local:GLINK_CHANNEL_CLOSED->GLINK_CHANNEL_OPENING\n",
__func__);
@ -4943,7 +4948,7 @@ static void glink_core_rx_cmd_ch_remote_open(struct glink_transport_if *if_ptr,
bool do_migrate;
glink_core_migration_edge_lock(if_ptr->glink_core_priv);
ctx = ch_name_to_ch_ctx_create(if_ptr->glink_core_priv, name);
ctx = ch_name_to_ch_ctx_create(if_ptr->glink_core_priv, name, false);
if (ctx == NULL) {
GLINK_ERR_XPRT(if_ptr->glink_core_priv,
"%s: invalid rcid %u received, name '%s'\n",
@ -5045,6 +5050,7 @@ static void glink_core_rx_cmd_ch_remote_close(
struct channel_ctx *ctx;
bool is_ch_fully_closed;
struct glink_core_xprt_ctx *xprt_ptr = if_ptr->glink_core_priv;
unsigned long flags;
ctx = xprt_rcid_to_ch_ctx_get(if_ptr->glink_core_priv, rcid);
if (!ctx) {
@ -5062,11 +5068,13 @@ static void glink_core_rx_cmd_ch_remote_close(
rwref_put(&ctx->ch_state_lhb2);
return;
}
spin_lock_irqsave(&ctx->transport_ptr->xprt_ctx_lock_lhb1, flags);
ctx->pending_delete = true;
spin_unlock_irqrestore(&ctx->transport_ptr->xprt_ctx_lock_lhb1, flags);
GLINK_INFO_CH(ctx, "%s: remote: OPENED->CLOSED\n", __func__);
is_ch_fully_closed = glink_core_remote_close_common(ctx, false);
ctx->pending_delete = true;
if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, rcid);
if (is_ch_fully_closed) {

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2019, The 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
@ -446,6 +446,9 @@ static int fifo_read(struct edge_info *einfo, void *_data, int len)
uint32_t fifo_size = einfo->rx_fifo_size;
uint32_t n;
if (read_index >= fifo_size || write_index >= fifo_size)
return 0;
while (len) {
ptr = einfo->rx_fifo + read_index;
if (read_index <= write_index)
@ -489,6 +492,9 @@ static uint32_t fifo_write_body(struct edge_info *einfo, const void *_data,
uint32_t fifo_size = einfo->tx_fifo_size;
uint32_t n;
if (read_index >= fifo_size || *write_index >= fifo_size)
return 0;
while (len) {
ptr = einfo->tx_fifo + *write_index;
if (*write_index < read_index) {

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2019, The 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
@ -77,6 +77,8 @@ module_param(qmi_timeout, ulong, 0600);
#define ICNSS_MAX_PROBE_CNT 2
#define PROBE_TIMEOUT 5000
#define icnss_ipc_log_string(_x...) do { \
if (icnss_ipc_log_context) \
ipc_log_string(icnss_ipc_log_context, _x); \
@ -301,6 +303,7 @@ enum icnss_driver_state {
ICNSS_FW_DOWN,
ICNSS_DRIVER_UNLOADING,
ICNSS_REJUVENATE,
ICNSS_BLOCK_SHUTDOWN,
};
struct ce_irq_list {
@ -493,6 +496,7 @@ static struct icnss_priv {
u8 requesting_sub_system;
u16 line_number;
char function_name[QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1];
struct completion unblock_shutdown;
} *penv;
#ifdef CONFIG_ICNSS_DEBUG
@ -1180,6 +1184,21 @@ bool icnss_is_fw_ready(void)
}
EXPORT_SYMBOL(icnss_is_fw_ready);
void icnss_block_shutdown(bool status)
{
if (!penv)
return;
if (status) {
set_bit(ICNSS_BLOCK_SHUTDOWN, &penv->state);
reinit_completion(&penv->unblock_shutdown);
} else {
clear_bit(ICNSS_BLOCK_SHUTDOWN, &penv->state);
complete(&penv->unblock_shutdown);
}
}
EXPORT_SYMBOL(icnss_block_shutdown);
bool icnss_is_fw_down(void)
{
if (!penv)
@ -1223,6 +1242,7 @@ static int wlfw_msa_mem_info_send_sync_msg(void)
struct wlfw_msa_info_req_msg_v01 req;
struct wlfw_msa_info_resp_msg_v01 resp;
struct msg_desc req_desc, resp_desc;
uint64_t max_mapped_addr;
if (!penv || !penv->wlfw_clnt)
return -ENODEV;
@ -1269,9 +1289,23 @@ static int wlfw_msa_mem_info_send_sync_msg(void)
goto out;
}
max_mapped_addr = penv->msa_pa + penv->msa_mem_size;
penv->stats.msa_info_resp++;
penv->nr_mem_region = resp.mem_region_info_len;
for (i = 0; i < resp.mem_region_info_len; i++) {
if (resp.mem_region_info[i].size > penv->msa_mem_size ||
resp.mem_region_info[i].region_addr > max_mapped_addr ||
resp.mem_region_info[i].region_addr < penv->msa_pa ||
resp.mem_region_info[i].size +
resp.mem_region_info[i].region_addr > max_mapped_addr) {
icnss_pr_dbg("Received out of range Addr: 0x%llx Size: 0x%x\n",
resp.mem_region_info[i].region_addr,
resp.mem_region_info[i].size);
ret = -EINVAL;
goto fail_unwind;
}
penv->mem_region[i].reg_addr =
resp.mem_region_info[i].region_addr;
penv->mem_region[i].size =
@ -1286,6 +1320,8 @@ static int wlfw_msa_mem_info_send_sync_msg(void)
return 0;
fail_unwind:
memset(&penv->mem_region[0], 0, sizeof(penv->mem_region[0]) * i);
out:
penv->stats.msa_info_err++;
ICNSS_QMI_ASSERT();
@ -1638,6 +1674,56 @@ out:
return ret;
}
static int wlfw_send_modem_shutdown_msg(void)
{
int ret;
struct wlfw_shutdown_req_msg_v01 req;
struct wlfw_shutdown_resp_msg_v01 resp;
struct msg_desc req_desc, resp_desc;
if (!penv || !penv->wlfw_clnt)
return -ENODEV;
icnss_pr_dbg("Sending modem shutdown request, state: 0x%lx\n",
penv->state);
memset(&req, 0, sizeof(req));
memset(&resp, 0, sizeof(resp));
req.shutdown_valid = 1;
req.shutdown = 1;
req_desc.max_msg_len = WLFW_SHUTDOWN_REQ_MSG_V01_MAX_MSG_LEN;
req_desc.msg_id = QMI_WLFW_SHUTDOWN_REQ_V01;
req_desc.ei_array = wlfw_shutdown_req_msg_v01_ei;
resp_desc.max_msg_len = WLFW_SHUTDOWN_RESP_MSG_V01_MAX_MSG_LEN;
resp_desc.msg_id = QMI_WLFW_SHUTDOWN_RESP_V01;
resp_desc.ei_array = wlfw_shutdown_resp_msg_v01_ei;
ret = qmi_send_req_wait(penv->wlfw_clnt, &req_desc, &req, sizeof(req),
&resp_desc, &resp, sizeof(resp),
WLFW_TIMEOUT_MS);
if (ret < 0) {
icnss_pr_err("Send modem shutdown req failed, ret: %d\n", ret);
goto out;
}
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
icnss_pr_err("QMI modem shutdown request rejected result:%d error:%d\n",
resp.resp.result, resp.resp.error);
ret = -resp.resp.result;
goto out;
}
icnss_pr_dbg("modem shutdown request sent successfully, state: 0x%lx\n",
penv->state);
return 0;
out:
return ret;
}
static int wlfw_athdiag_read_send_sync_msg(struct icnss_priv *priv,
uint32_t offset, uint32_t mem_type,
uint32_t data_len, uint8_t *data)
@ -2155,6 +2241,7 @@ static int icnss_call_driver_probe(struct icnss_priv *priv)
icnss_hw_power_on(priv);
icnss_block_shutdown(true);
while (probe_cnt < ICNSS_MAX_PROBE_CNT) {
ret = priv->ops->probe(&priv->pdev->dev);
probe_cnt++;
@ -2164,9 +2251,11 @@ static int icnss_call_driver_probe(struct icnss_priv *priv)
if (ret < 0) {
icnss_pr_err("Driver probe failed: %d, state: 0x%lx, probe_cnt: %d\n",
ret, priv->state, probe_cnt);
icnss_block_shutdown(false);
goto out;
}
icnss_block_shutdown(false);
set_bit(ICNSS_DRIVER_PROBED, &priv->state);
return 0;
@ -2302,6 +2391,7 @@ static int icnss_driver_event_register_driver(void *data)
if (ret)
goto out;
icnss_block_shutdown(true);
while (probe_cnt < ICNSS_MAX_PROBE_CNT) {
ret = penv->ops->probe(&penv->pdev->dev);
probe_cnt++;
@ -2311,9 +2401,11 @@ static int icnss_driver_event_register_driver(void *data)
if (ret) {
icnss_pr_err("Driver probe failed: %d, state: 0x%lx, probe_cnt: %d\n",
ret, penv->state, probe_cnt);
icnss_block_shutdown(false);
goto power_off;
}
icnss_block_shutdown(false);
set_bit(ICNSS_DRIVER_PROBED, &penv->state);
return 0;
@ -2536,6 +2628,20 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb,
if (code != SUBSYS_BEFORE_SHUTDOWN)
return NOTIFY_OK;
if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed &&
test_bit(ICNSS_BLOCK_SHUTDOWN, &priv->state)) {
if (!wait_for_completion_timeout(&priv->unblock_shutdown,
PROBE_TIMEOUT))
icnss_pr_err("wlan driver probe timeout\n");
}
if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed) {
ret = wlfw_send_modem_shutdown_msg();
if (ret)
icnss_pr_dbg("Fail to send modem shutdown Indication %d\n",
ret);
}
if (test_bit(ICNSS_PDR_REGISTERED, &priv->state)) {
set_bit(ICNSS_FW_DOWN, &priv->state);
icnss_ignore_qmi_timeout(true);
@ -3925,6 +4031,9 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv)
continue;
case ICNSS_DRIVER_UNLOADING:
seq_puts(s, "DRIVER UNLOADING");
continue;
case ICNSS_BLOCK_SHUTDOWN:
seq_puts(s, "BLOCK SHUTDOWN");
}
seq_printf(s, "UNKNOWN-%d", i);
@ -4614,9 +4723,13 @@ static int icnss_probe(struct platform_device *pdev)
penv = priv;
#if 1
/* Create device file */
device_create_file(&penv->pdev->dev, &dev_attr_cnss_version_information);
push_component_info(WCN, "WCN3990", "QualComm");
#endif
init_completion(&priv->unblock_shutdown);
icnss_pr_info("Platform driver probed successfully\n");
@ -4640,7 +4753,11 @@ static int icnss_remove(struct platform_device *pdev)
icnss_debugfs_destroy(penv);
#if 1
device_remove_file(&penv->pdev->dev, &dev_attr_cnss_version_information);
#endif
complete_all(&penv->unblock_shutdown);
icnss_modem_ssr_unregister_notifier(penv);

View file

@ -601,6 +601,12 @@ void apr_cb_func(void *buf, int len, void *priv)
pr_err("APR: Wrong paket size\n");
return;
}
if (hdr->pkt_size < hdr_size) {
pr_err("APR: Packet size less than header size\n");
return;
}
msg_type = hdr->hdr_field;
msg_type = (msg_type >> 0x08) & 0x0003;
if (msg_type >= APR_MSG_TYPE_MAX && msg_type != APR_BASIC_RSP_RESULT) {

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2019, The 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
@ -68,8 +68,9 @@ static void *dummy_q6_mvm;
static void *dummy_q6_cvs;
dev_t device_num;
static struct mutex session_lock;
static spinlock_t voicesvc_lock;
static bool is_released;
static bool is_released = 1;
static int voice_svc_dummy_reg(void);
static int voice_svc_dummy_dereg(void);
@ -645,14 +646,23 @@ static int voice_svc_dummy_dereg(void)
static int voice_svc_open(struct inode *inode, struct file *file)
{
struct voice_svc_prvt *prtd = NULL;
int ret = 0;
pr_debug("%s\n", __func__);
mutex_lock(&session_lock);
if (is_released == 0) {
pr_err("%s: Access denied to device\n", __func__);
ret = -EBUSY;
goto done;
}
prtd = kmalloc(sizeof(struct voice_svc_prvt), GFP_KERNEL);
if (prtd == NULL) {
pr_err("%s: kmalloc failed\n", __func__);
return -ENOMEM;
ret = -ENOMEM;
goto done;
}
memset(prtd, 0, sizeof(struct voice_svc_prvt));
@ -676,7 +686,9 @@ static int voice_svc_open(struct inode *inode, struct file *file)
voice_svc_dummy_reg();
reg_dummy_sess = 1;
}
return 0;
done:
mutex_unlock(&session_lock);
return ret;
}
static int voice_svc_release(struct inode *inode, struct file *file)
@ -810,6 +822,7 @@ static int voice_svc_probe(struct platform_device *pdev)
}
pr_debug("%s: Device created\n", __func__);
spin_lock_init(&voicesvc_lock);
mutex_init(&session_lock);
goto done;
add_err:
@ -832,6 +845,7 @@ static int voice_svc_remove(struct platform_device *pdev)
kfree(voice_svc_dev->cdev);
device_destroy(voice_svc_class, device_num);
class_destroy(voice_svc_class);
mutex_destroy(&session_lock);
unregister_chrdev_region(0, MINOR_NUMBER);
return 0;

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 2011 Google, Inc
* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2011-2019, The 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
@ -56,8 +56,8 @@ struct dest_vm_and_perm_info {
u32 ctx_size;
};
static void *qcom_secure_mem;
#define QCOM_SECURE_MEM_SIZE (512*1024)
#define BATCH_MAX_SIZE SZ_2M
#define BATCH_MAX_SECTIONS 32
static int secure_buffer_change_chunk(u32 chunks,
u32 nchunks,
@ -219,42 +219,67 @@ populate_dest_info(int *dest_vmids, int nelements, int *dest_perms,
}
/* Must hold secure_buffer_mutex while allocated buffer is in use */
static struct mem_prot_info *get_info_list_from_table(struct sg_table *table,
size_t *size_in_bytes)
static unsigned int get_batches_from_sgl(struct mem_prot_info *sg_table_copy,
struct scatterlist *sgl,
struct scatterlist **next_sgl)
{
int i;
struct scatterlist *sg;
struct mem_prot_info *info;
size_t size;
u64 batch_size = 0;
unsigned int i = 0;
struct scatterlist *curr_sgl = sgl;
size = table->nents * sizeof(*info);
/* Ensure no zero size batches */
do {
sg_table_copy[i].addr = page_to_phys(sg_page(curr_sgl));
sg_table_copy[i].size = curr_sgl->length;
batch_size += sg_table_copy[i].size;
curr_sgl = sg_next(curr_sgl);
i++;
} while (curr_sgl && i < BATCH_MAX_SECTIONS &&
curr_sgl->length + batch_size < BATCH_MAX_SIZE);
if (size >= QCOM_SECURE_MEM_SIZE) {
pr_err("%s: Not enough memory allocated. Required size %zd\n",
__func__, size);
return NULL;
}
if (!qcom_secure_mem) {
pr_err("%s is not functional as qcom_secure_mem is not allocated.\n",
__func__);
return NULL;
}
/* "Allocate" it */
info = qcom_secure_mem;
for_each_sg(table->sgl, sg, table->nents, i) {
info[i].addr = page_to_phys(sg_page(sg));
info[i].size = sg->length;
}
*size_in_bytes = size;
return info;
*next_sgl = curr_sgl;
return i;
}
#define BATCH_MAX_SIZE SZ_2M
#define BATCH_MAX_SECTIONS 32
static int batched_hyp_assign(struct sg_table *table, struct scm_desc *desc)
{
unsigned int entries_size;
unsigned int batch_start = 0;
unsigned int batches_processed;
struct scatterlist *curr_sgl = table->sgl;
struct scatterlist *next_sgl;
int ret = 0;
struct mem_prot_info *sg_table_copy = kcalloc(BATCH_MAX_SECTIONS,
sizeof(*sg_table_copy),
GFP_KERNEL);
if (!sg_table_copy)
return -ENOMEM;
while (batch_start < table->nents) {
batches_processed = get_batches_from_sgl(sg_table_copy,
curr_sgl, &next_sgl);
curr_sgl = next_sgl;
entries_size = batches_processed * sizeof(*sg_table_copy);
dmac_flush_range(sg_table_copy,
(void *)sg_table_copy + entries_size);
desc->args[0] = virt_to_phys(sg_table_copy);
desc->args[1] = entries_size;
ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP,
MEM_PROT_ASSIGN_ID), desc);
if (ret) {
pr_info("%s: Failed to assign memory protection, ret = %d\n",
__func__, ret);
break;
}
batch_start += batches_processed;
}
kfree(sg_table_copy);
return ret;
}
int hyp_assign_table(struct sg_table *table,
u32 *source_vm_list, int source_nelems,
@ -267,11 +292,10 @@ int hyp_assign_table(struct sg_table *table,
size_t source_vm_copy_size;
struct dest_vm_and_perm_info *dest_vm_copy;
size_t dest_vm_copy_size;
struct mem_prot_info *sg_table_copy;
size_t sg_table_copy_size;
int batch_start, batch_end;
u64 batch_size;
if (!table || !table->sgl || !source_vm_list || !source_nelems ||
!dest_vmids || !dest_perms || !dest_nelems)
return -EINVAL;
/*
* We can only pass cache-aligned sizes to hypervisor, so we need
@ -289,19 +313,11 @@ int hyp_assign_table(struct sg_table *table,
&dest_vm_copy_size);
if (!dest_vm_copy) {
ret = -ENOMEM;
goto out_free;
goto out_free_source;
}
mutex_lock(&secure_buffer_mutex);
sg_table_copy = get_info_list_from_table(table, &sg_table_copy_size);
if (!sg_table_copy) {
ret = -ENOMEM;
goto out_unlock;
}
desc.args[0] = virt_to_phys(sg_table_copy);
desc.args[1] = sg_table_copy_size;
desc.args[2] = virt_to_phys(source_vm_copy);
desc.args[3] = source_vm_copy_size;
desc.args[4] = virt_to_phys(dest_vm_copy);
@ -313,50 +329,14 @@ int hyp_assign_table(struct sg_table *table,
dmac_flush_range(source_vm_copy,
(void *)source_vm_copy + source_vm_copy_size);
dmac_flush_range(sg_table_copy,
(void *)sg_table_copy + sg_table_copy_size);
dmac_flush_range(dest_vm_copy,
(void *)dest_vm_copy + dest_vm_copy_size);
batch_start = 0;
while (batch_start < table->nents) {
/* Ensure no size zero batches */
batch_size = sg_table_copy[batch_start].size;
batch_end = batch_start + 1;
while (1) {
u64 size;
ret = batched_hyp_assign(table, &desc);
if (batch_end >= table->nents)
break;
if (batch_end - batch_start >= BATCH_MAX_SECTIONS)
break;
size = sg_table_copy[batch_end].size;
if (size + batch_size >= BATCH_MAX_SIZE)
break;
batch_size += size;
batch_end++;
}
desc.args[0] = virt_to_phys(&sg_table_copy[batch_start]);
desc.args[1] = (batch_end - batch_start) *
sizeof(sg_table_copy[0]);
ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP,
MEM_PROT_ASSIGN_ID), &desc);
if (ret) {
pr_info("%s: Failed to assign memory protection, ret = %d\n",
__func__, ret);
break;
}
batch_start = batch_end;
}
out_unlock:
mutex_unlock(&secure_buffer_mutex);
kfree(dest_vm_copy);
out_free:
out_free_source:
kfree(source_vm_copy);
return ret;
}
@ -436,23 +416,3 @@ bool msm_secure_v2_is_supported(void)
*/
return (ret == 0) && (version >= MAKE_CP_VERSION(1, 1, 0));
}
static int __init alloc_secure_shared_memory(void)
{
int ret = 0;
dma_addr_t dma_handle;
qcom_secure_mem = kzalloc(QCOM_SECURE_MEM_SIZE, GFP_KERNEL);
if (!qcom_secure_mem) {
/* Fallback to CMA-DMA memory */
qcom_secure_mem = dma_alloc_coherent(NULL, QCOM_SECURE_MEM_SIZE,
&dma_handle, GFP_KERNEL);
if (!qcom_secure_mem) {
pr_err("Couldn't allocate memory for secure use-cases. hyp_assign_table will not work\n");
return -ENOMEM;
}
}
return ret;
}
pure_initcall(alloc_secure_shared_memory);

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2019, The 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
@ -109,6 +109,8 @@ struct wdsp_glink_priv {
/* Respone buffer related */
u8 rsp_cnt;
struct wdsp_glink_rsp_que rsp[RESP_QUEUE_SIZE];
u8 write_idx;
u8 read_idx;
struct completion rsp_complete;
struct mutex rsp_mutex;
@ -202,13 +204,19 @@ static void wdsp_glink_notify_rx(void *handle, const void *priv,
mutex_lock(&wpriv->rsp_mutex);
rsp_cnt = wpriv->rsp_cnt;
if (rsp_cnt >= RESP_QUEUE_SIZE) {
dev_err(wpriv->dev, "%s: Resp Queue is Full\n", __func__);
rsp_cnt = 0;
dev_err(wpriv->dev, "%s: Resp Queue is Full. Ignore latest and keep oldest.\n",
__func__);
mutex_unlock(&wpriv->rsp_mutex);
glink_rx_done(handle, ptr, true);
return;
}
dev_dbg(wpriv->dev, "%s: copy into buffer %d\n", __func__, rsp_cnt);
dev_dbg(wpriv->dev, "%s: rsp_cnt = %d copy into buffer %d\n",
__func__, rsp_cnt, wpriv->write_idx);
memcpy(wpriv->rsp[rsp_cnt].buf, rx_buf, size);
wpriv->rsp[rsp_cnt].buf_size = size;
memcpy(wpriv->rsp[wpriv->write_idx].buf, rx_buf, size);
wpriv->rsp[wpriv->write_idx].buf_size = size;
wpriv->write_idx = (wpriv->write_idx + 1) % RESP_QUEUE_SIZE;
wpriv->rsp_cnt = ++rsp_cnt;
mutex_unlock(&wpriv->rsp_mutex);
@ -781,10 +789,11 @@ static ssize_t wdsp_glink_read(struct file *file, char __user *buf,
mutex_lock(&wpriv->rsp_mutex);
if (wpriv->rsp_cnt) {
wpriv->rsp_cnt--;
dev_dbg(wpriv->dev, "%s: read from buffer %d\n",
__func__, wpriv->rsp_cnt);
dev_dbg(wpriv->dev, "%s: rsp_cnt=%d read from buffer %d\n",
__func__, wpriv->rsp_cnt, wpriv->read_idx);
rsp = &wpriv->rsp[wpriv->rsp_cnt];
rsp = &wpriv->rsp[wpriv->read_idx];
wpriv->read_idx = (wpriv->read_idx + 1) % RESP_QUEUE_SIZE;
if (count < rsp->buf_size) {
ret1 = copy_to_user(buf, &rsp->buf, count);
/* Return the number of bytes copied */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -2,7 +2,7 @@
* drivers/staging/android/ion/ion_system_heap.c
*
* Copyright (C) 2011 Google, Inc.
* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@ -270,6 +270,9 @@ static struct page_info *alloc_from_pool_preferred(
struct page_info *info;
int i;
if (buffer->flags & ION_FLAG_POOL_FORCE_ALLOC)
goto force_alloc;
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return NULL;
@ -301,6 +304,7 @@ static struct page_info *alloc_from_pool_preferred(
}
kfree(info);
force_alloc:
return alloc_largest_available(heap, buffer, size, max_order);
}

View file

@ -2674,41 +2674,55 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
static void dwc3_disconnect_gadget(struct dwc3 *dwc)
{
struct usb_gadget_driver *gadget_driver;
if (dwc->gadget_driver && dwc->gadget_driver->disconnect) {
gadget_driver = dwc->gadget_driver;
spin_unlock(&dwc->lock);
dwc->gadget_driver->disconnect(&dwc->gadget);
dbg_event(0xFF, "DISCONNECT", 0);
gadget_driver->disconnect(&dwc->gadget);
spin_lock(&dwc->lock);
}
}
static void dwc3_suspend_gadget(struct dwc3 *dwc)
{
struct usb_gadget_driver *gadget_driver;
if (dwc->gadget_driver && dwc->gadget_driver->suspend) {
gadget_driver = dwc->gadget_driver;
spin_unlock(&dwc->lock);
dbg_event(0xFF, "SUSPEND", 0);
dwc->gadget_driver->suspend(&dwc->gadget);
gadget_driver->suspend(&dwc->gadget);
spin_lock(&dwc->lock);
}
}
static void dwc3_resume_gadget(struct dwc3 *dwc)
{
struct usb_gadget_driver *gadget_driver;
if (dwc->gadget_driver && dwc->gadget_driver->resume) {
gadget_driver = dwc->gadget_driver;
spin_unlock(&dwc->lock);
dbg_event(0xFF, "RESUME", 0);
dwc->gadget_driver->resume(&dwc->gadget);
gadget_driver->resume(&dwc->gadget);
spin_lock(&dwc->lock);
}
}
static void dwc3_reset_gadget(struct dwc3 *dwc)
{
struct usb_gadget_driver *gadget_driver;
if (!dwc->gadget_driver)
return;
if (dwc->gadget.speed != USB_SPEED_UNKNOWN) {
gadget_driver = dwc->gadget_driver;
spin_unlock(&dwc->lock);
usb_gadget_udc_reset(&dwc->gadget, dwc->gadget_driver);
dbg_event(0xFF, "UDC RESET", 0);
usb_gadget_udc_reset(&dwc->gadget, gadget_driver);
spin_lock(&dwc->lock);
}
}

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2009-2019, The 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
@ -1450,6 +1450,9 @@ static inline struct mdss_mdp_misr_map *mdss_misr_get_map(u32 block_id,
case MDSS_MDP_INTF2:
block_id = DISPLAY_MISR_DSI1;
break;
case MDSS_MDP_INTF3:
block_id = DISPLAY_MISR_HDMI;
break;
default:
pr_err("Unmatch INTF for Dual LM single display configuration, INTF:%d\n",
ctl->intf_num);

View file

@ -1,7 +1,7 @@
/*
* Core MDSS framebuffer driver.
*
* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2008-2019, The Linux Foundation. All rights reserved.
* Copyright (C) 2007 Google Incorporated
*
* This software is licensed under the terms of the GNU General Public
@ -3768,16 +3768,19 @@ static int mdss_fb_pan_display(struct fb_var_screeninfo *var,
{
struct mdp_display_commit disp_commit;
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
struct mdss_data_type *mdata = mfd_to_mdata(mfd);
/*
* during mode switch through mode sysfs node, it will trigger a
* Abort pan_display operations in following cases:
* 1. during mode switch through mode sysfs node, it will trigger a
* pan_display after switch. This assumes that fb has been adjusted,
* however when using overlays we may not have the right size at this
* point, so it needs to go through PREPARE first. Abort pan_display
* operations until that happens
* point, so it needs to go through PREPARE first.
* 2. When the splash handoff is pending.
*/
if (mfd->switch_state != MDSS_MDP_NO_UPDATE_REQUESTED) {
pr_debug("fb%d: pan_display skipped during switch\n",
if ((mfd->switch_state != MDSS_MDP_NO_UPDATE_REQUESTED) ||
mdata->handoff_pending) {
pr_debug("fb%d: pan_display skipped during switch or handoff\n",
mfd->index);
return 0;
}

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2010-2017, 2019, The 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
@ -200,6 +200,7 @@ static int hdmi_edid_reset_parser(struct hdmi_edid_ctrl *edid_ctrl)
/* reset resolution related sink data */
memset(&edid_ctrl->sink_data, 0, sizeof(edid_ctrl->sink_data));
memset(&edid_ctrl->sink_caps, 0, sizeof(edid_ctrl->sink_caps));
/* reset audio related data */
memset(edid_ctrl->audio_data_block, 0,

View file

@ -2577,6 +2577,7 @@ struct mdss_mdp_mixer *mdss_mdp_mixer_alloc(
mixer_pool += ctl->mdata->ndspp;
nmixers -= ctl->mdata->ndspp;
} else if ((ctl->panel_data->panel_info.is_pluggable) &&
!(ctl->panel_data->panel_info.is_prim_panel) &&
nmixers_active) {
mixer_pool += ctl->mdata->ndspp;
nmixers -= ctl->mdata->ndspp;

View file

@ -6382,6 +6382,15 @@ void mdss_mdp_footswitch_ctrl_handler(bool on)
static void mdss_mdp_signal_retire_fence(struct msm_fb_data_type *mfd,
int retire_cnt)
{
struct mdss_overlay_private *mdp5_data;
if (!mfd)
return;
mdp5_data = mfd_to_mdp5_data(mfd);
if (!mdp5_data->ctl || !mdp5_data->ctl->ops.remove_vsync_handler)
return;
__vsync_retire_signal(mfd, retire_cnt);
pr_debug("Signaled (%d) pending retire fence\n", retire_cnt);
}

View file

@ -404,7 +404,7 @@ struct kioctx_table;
struct mm_struct {
struct vm_area_struct *mmap; /* list of VMAs */
struct rb_root mm_rb;
u32 vmacache_seqnum; /* per-thread vmacache */
u64 vmacache_seqnum; /* per-thread vmacache */
#ifdef CONFIG_MMU
unsigned long (*get_unmapped_area) (struct file *filp,
unsigned long addr, unsigned long len,

View file

@ -231,7 +231,7 @@ struct pmu {
int capabilities;
int * __percpu pmu_disable_count;
struct perf_cpu_context * __percpu pmu_cpu_context;
struct perf_cpu_context __percpu *pmu_cpu_context;
atomic_t exclusive_cnt; /* < 0: cpu; > 0: tsk */
int task_ctx_nr;
int hrtimer_interval_ms;

View file

@ -1738,7 +1738,7 @@ struct task_struct {
struct mm_struct *mm, *active_mm;
/* per-thread vma caching */
u32 vmacache_seqnum;
u64 vmacache_seqnum;
struct vm_area_struct *vmacache[VMACACHE_SIZE];
#if defined(SPLIT_RSS_COUNTING)
struct task_rss_stat rss_stat;

View file

@ -89,7 +89,6 @@ enum vm_event_item { PGPGIN, PGPGOUT, PGPGOUTCLEAN, PSWPIN, PSWPOUT,
#ifdef CONFIG_DEBUG_VM_VMACACHE
VMACACHE_FIND_CALLS,
VMACACHE_FIND_HITS,
VMACACHE_FULL_FLUSHES,
#endif
NR_VM_EVENT_ITEMS
};

View file

@ -15,7 +15,6 @@ static inline void vmacache_flush(struct task_struct *tsk)
memset(tsk->vmacache, 0, sizeof(tsk->vmacache));
}
extern void vmacache_flush_all(struct mm_struct *mm);
extern void vmacache_update(unsigned long addr, struct vm_area_struct *newvma);
extern struct vm_area_struct *vmacache_find(struct mm_struct *mm,
unsigned long addr);
@ -29,10 +28,6 @@ extern struct vm_area_struct *vmacache_find_exact(struct mm_struct *mm,
static inline void vmacache_invalidate(struct mm_struct *mm)
{
mm->vmacache_seqnum++;
/* deal with overflows */
if (unlikely(mm->vmacache_seqnum == 0))
vmacache_flush_all(mm);
}
#endif /* __LINUX_VMACACHE_H */

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2019, The 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
@ -157,12 +157,8 @@ extern bool icnss_is_rejuvenate(void);
extern int icnss_set_wlan_mac_address(const u8 *in, const uint32_t len);
extern u8 *icnss_get_wlan_mac_address(struct device *dev, uint32_t *num);
extern int icnss_trigger_recovery(struct device *dev);
extern void cnss_set_cc_source(enum cnss_cc_src cc_source);
extern enum cnss_cc_src cnss_get_cc_source(void);
extern int icnss_get_driver_load_cnt(void);
extern void icnss_increment_driver_load_cnt(void);
extern void icnss_set_cc_source(enum cnss_cc_src cc_source);
extern enum cnss_cc_src icnss_get_cc_source(void);
extern void icnss_block_shutdown(bool status);
#if 1
extern void cnss_set_fw_version(u32 version);
#endif
#endif /* _ICNSS_WLAN_H_ */

View file

@ -1,5 +1,5 @@
/*
* 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
@ -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;

View file

@ -9654,13 +9654,26 @@ static void __perf_event_stop_swclock(void *__info)
static void perf_event_exit_cpu_context(int cpu)
{
struct perf_cpu_context *cpuctx;
struct perf_event_context *ctx;
unsigned long flags;
struct pmu *pmu;
int idx;
idx = srcu_read_lock(&pmus_srcu);
list_for_each_entry_rcu(pmu, &pmus, entry) {
ctx = &per_cpu_ptr(pmu->pmu_cpu_context, cpu)->ctx;
cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu);
ctx = &cpuctx->ctx;
/* Cancel the mux hrtimer to avoid CPU migration */
if (pmu->task_ctx_nr != perf_sw_context) {
raw_spin_lock_irqsave(&cpuctx->hrtimer_lock, flags);
hrtimer_cancel(&cpuctx->hrtimer);
cpuctx->hrtimer_active = 0;
raw_spin_unlock_irqrestore(&cpuctx->hrtimer_lock,
flags);
}
mutex_lock(&ctx->mutex);
/*
* If keeping events across hotplugging is supported, do not

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2015, 2019 The 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
@ -710,8 +710,8 @@ static int qmi_decode_string_elem(struct elem_info *ei_array, void *buf_dst,
decoded_bytes += rc;
}
if (string_len > temp_ei->elem_len) {
pr_err("%s: String len %d > Max Len %d\n",
if (string_len >= temp_ei->elem_len) {
pr_err("%s: String len %d >= Max Len %d\n",
__func__, string_len, temp_ei->elem_len);
return -ETOOSMALL;
} else if (string_len > tlv_len) {

View file

@ -184,7 +184,7 @@ EXPORT_SYMBOL(dump_vma);
void dump_mm(const struct mm_struct *mm)
{
pr_emerg("mm %p mmap %p seqnum %d task_size %lu\n"
pr_emerg("mm %p mmap %p seqnum %llu task_size %lu\n"
#ifdef CONFIG_MMU
"get_unmapped_area %p\n"
#endif
@ -214,7 +214,7 @@ void dump_mm(const struct mm_struct *mm)
#endif
"%s", /* This is here to hold the comma */
mm, mm->mmap, mm->vmacache_seqnum, mm->task_size,
mm, mm->mmap, (long long) mm->vmacache_seqnum, mm->task_size,
#ifdef CONFIG_MMU
mm->get_unmapped_area,
#endif

View file

@ -5,44 +5,6 @@
#include <linux/mm.h>
#include <linux/vmacache.h>
/*
* Flush vma caches for threads that share a given mm.
*
* The operation is safe because the caller holds the mmap_sem
* exclusively and other threads accessing the vma cache will
* have mmap_sem held at least for read, so no extra locking
* is required to maintain the vma cache.
*/
void vmacache_flush_all(struct mm_struct *mm)
{
struct task_struct *g, *p;
count_vm_vmacache_event(VMACACHE_FULL_FLUSHES);
/*
* Single threaded tasks need not iterate the entire
* list of process. We can avoid the flushing as well
* since the mm's seqnum was increased and don't have
* to worry about other threads' seqnum. Current's
* flush will occur upon the next lookup.
*/
if (atomic_read(&mm->mm_users) == 1)
return;
rcu_read_lock();
for_each_process_thread(g, p) {
/*
* Only flush the vmacache pointers as the
* mm seqnum is already set and curr's will
* be set upon invalidation when the next
* lookup is done.
*/
if (mm == p->mm)
vmacache_flush(p);
}
rcu_read_unlock();
}
/*
* This task may be accessing a foreign mm via (for example)
* get_user_pages()->find_vma(). The vmacache is task-local and this

View file

@ -872,7 +872,6 @@ const char * const vmstat_text[] = {
#ifdef CONFIG_DEBUG_VM_VMACACHE
"vmacache_find_calls",
"vmacache_find_hits",
"vmacache_full_flushes",
#endif
#endif /* CONFIG_VM_EVENTS_COUNTERS */
};

View file

@ -73,11 +73,13 @@ static int sockev_client_cb(struct notifier_block *nb,
sock = (struct socket *)data;
if (!socknlmsgsk || !sock)
goto done;
goto sk_null;
sk = sock->sk;
if (!sk)
goto done;
goto sk_null;
sock_hold(sk);
if (sk->sk_family != AF_INET && sk->sk_family != AF_INET6)
goto done;
@ -108,6 +110,8 @@ static int sockev_client_cb(struct notifier_block *nb,
smsg->skflags = sk->sk_flags;
nlmsg_notify(socknlmsgsk, skb, 0, SKNLGRP_SOCKEV, 0, GFP_KERNEL);
done:
sock_put(sk);
sk_null:
return 0;
}

View file

@ -579,8 +579,8 @@ country IT: DFS-ETSI
country JM: DFS-FCC
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (24), AUTO-BW
(5250 - 5330 @ 80), (24), DFS, AUTO-BW
(5490 - 5730 @ 160), (24), DFS
(5250 - 5330 @ 80), (24), AUTO-BW
(5490 - 5730 @ 160), (24)
(5735 - 5835 @ 80), (30)
# 60 gHz band channels 1-3, FCC
(57240 - 63720 @ 2160), (40)
@ -1134,10 +1134,11 @@ country TR: DFS-ETSI
(5490 - 5730 @ 160), (30), DFS
(5735 - 5875 @ 80), (14)
country TT:
country TT: DFS-FCC
(2402 - 2482 @ 40), (20)
(5170 - 5330 @ 160), (24)
(5490 - 5730 @ 160), (24)
(5170 - 5250 @ 80), (24)
(5250 - 5330 @ 80), (24), DFS
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
# 60 gHz band channels 1-3, FCC
(57240 - 63720 @ 2160), (40)

View file

@ -55,7 +55,7 @@ def interpret_warning(line):
line = line.rstrip('\n')
m = warning_re.match(line)
if m and m.group(2) not in allowed_warnings:
print "error, forbidden warning:", m.group(2)
print >> sys.stderr, "error, forbidden warning:", m.group(2)
# If there is a warning, remove any object if it exists.
if ofile:
@ -80,17 +80,17 @@ def run_gcc():
try:
proc = subprocess.Popen(args, stderr=subprocess.PIPE)
for line in proc.stderr:
print line,
print >> sys.stderr, line,
interpret_warning(line)
result = proc.wait()
except OSError as e:
result = e.errno
if result == errno.ENOENT:
print args[0] + ':',e.strerror
print 'Is your PATH set correctly?'
print >> sys.stderr, args[0] + ':',e.strerror
print >> sys.stderr, 'Is your PATH set correctly?'
else:
print ' '.join(args), str(e)
print >> sys.stderr, ' '.join(args), str(e)
return result

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2019, The 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
@ -40,6 +40,7 @@
#define CF_MIN_3DB_75HZ 0x1
#define CF_MIN_3DB_150HZ 0x2
#define DEC_SVA 5
#define MSM_DIG_CDC_VERSION_ENTRY_SIZE 32
static unsigned long rx_digital_gain_reg[] = {
@ -213,6 +214,9 @@ static int msm_dig_cdc_put_dec_enum(struct snd_kcontrol *kcontrol,
tx_mux_ctl_reg =
MSM89XX_CDC_CORE_TX1_MUX_CTL + 32 * (decimator - 1);
if (decimator == DEC_SVA)
tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX5_MUX_CTL;
snd_soc_update_bits(codec, tx_mux_ctl_reg, 0x1, adc_dmic_sel);
ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
@ -939,7 +943,7 @@ static int msm_dig_cdc_codec_enable_dec(struct snd_soc_dapm_widget *w,
32 * (decimator - 1);
tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX1_MUX_CTL +
32 * (decimator - 1);
if (decimator == 5) {
if (decimator == DEC_SVA) {
tx_vol_ctl_reg = MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG;
tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX5_MUX_CTL;
}
@ -1250,14 +1254,18 @@ static void sdm660_tx_mute_update_callback(struct work_struct *work)
dig_cdc = tx_mute_dwork->dig_cdc;
codec = dig_cdc->codec;
for (i = 0; i < (NUM_DECIMATORS - 1); i++) {
for (i = 0; i < NUM_DECIMATORS; i++) {
if (dig_cdc->dec_active[i])
decimator = i + 1;
if (decimator && decimator < NUM_DECIMATORS) {
if (decimator && decimator <= NUM_DECIMATORS) {
/* unmute decimators corresponding to Tx DAI's*/
tx_vol_ctl_reg =
MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG +
32 * (decimator - 1);
if (decimator == DEC_SVA)
tx_vol_ctl_reg =
MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG;
snd_soc_update_bits(codec, tx_vol_ctl_reg,
0x01, 0x00);
}

View file

@ -1,5 +1,5 @@
/*
* 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
@ -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;
@ -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;
@ -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;
@ -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];
@ -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,

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2019, The 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
@ -1020,6 +1020,13 @@ int msm_adsp_inform_mixer_ctl(struct snd_soc_pcm_runtime *rtd,
}
event_data = (struct msm_adsp_event_data *)payload;
if (event_data->payload_len < sizeof(struct msm_adsp_event_data)) {
pr_err("%s: event_data size of %x is less than expected.\n",
__func__, event_data->payload_len);
ret = -EINVAL;
goto done;
}
kctl->info(kctl, &kctl_info);
if (event_data->payload_len >

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2019, The 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
@ -1230,12 +1230,22 @@ static int adm_process_get_param_response(u32 opcode, u32 idx, u32 *payload,
switch (opcode) {
case ADM_CMDRSP_GET_PP_PARAMS_V5:
struct_size = sizeof(struct adm_cmd_rsp_get_pp_params_v5);
if (payload_size < struct_size) {
pr_err("%s: payload size %d < expected size %d\n",
__func__, payload_size, struct_size);
break;
}
v5_rsp = (struct adm_cmd_rsp_get_pp_params_v5 *) payload;
data_size = v5_rsp->param_hdr.param_size;
param_data = v5_rsp->param_data;
break;
case ADM_CMDRSP_GET_PP_PARAMS_V6:
struct_size = sizeof(struct adm_cmd_rsp_get_pp_params_v6);
if (payload_size < struct_size) {
pr_err("%s: payload size %d < expected size %d\n",
__func__, payload_size, struct_size);
break;
}
v6_rsp = (struct adm_cmd_rsp_get_pp_params_v6 *) payload;
data_size = v6_rsp->param_hdr.param_size;
param_data = v6_rsp->param_data;
@ -1399,7 +1409,7 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv)
}
adm_callback_debug_print(data);
if (data->payload_size) {
if (data->payload_size >= sizeof(uint32_t)) {
copp_idx = (data->token) & 0XFF;
port_idx = ((data->token) >> 16) & 0xFF;
client_id = ((data->token) >> 8) & 0xFF;
@ -1421,6 +1431,16 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv)
if (data->opcode == APR_BASIC_RSP_RESULT) {
pr_debug("%s: APR_BASIC_RSP_RESULT id 0x%x\n",
__func__, payload[0]);
if (!((client_id != ADM_CLIENT_ID_SOURCE_TRACKING) &&
((payload[0] == ADM_CMD_SET_PP_PARAMS_V5) ||
(payload[0] == ADM_CMD_SET_PP_PARAMS_V6)))) {
if (data->payload_size <
(2 * sizeof(uint32_t))) {
pr_err("%s: Invalid payload size %d\n",
__func__, data->payload_size);
return 0;
}
}
if (payload[1] != 0) {
pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
__func__, payload[0], payload[1]);
@ -1545,9 +1565,16 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv)
case ADM_CMDRSP_DEVICE_OPEN_V5:
case ADM_CMDRSP_DEVICE_OPEN_V6:
case ADM_CMDRSP_DEVICE_OPEN_V8: {
struct adm_cmd_rsp_device_open_v5 *open =
(struct adm_cmd_rsp_device_open_v5 *)data->payload;
struct adm_cmd_rsp_device_open_v5 *open = NULL;
if (data->payload_size <
sizeof(struct adm_cmd_rsp_device_open_v5)) {
pr_err("%s: Invalid payload size %d\n",
__func__, data->payload_size);
return 0;
}
open =
(struct adm_cmd_rsp_device_open_v5 *)data->payload;
if (open->copp_id == INVALID_COPP_ID) {
pr_err("%s: invalid coppid rxed %d\n",
__func__, open->copp_id);
@ -1603,8 +1630,10 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv)
case ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST_V2:
pr_debug("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST\n",
__func__);
if (data->payload_size >= (2 * sizeof(uint32_t))) {
num_modules = payload[1];
pr_debug("%s: Num modules %d\n", __func__, num_modules);
pr_debug("%s: Num modules %d\n", __func__,
num_modules);
if (payload[0]) {
pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST, error = %d\n",
__func__, payload[0]);
@ -1612,13 +1641,18 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv)
pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST invalid num modules received, num modules = %d\n",
__func__, num_modules);
} else {
ret = adm_process_get_topo_list_response(
data->opcode, copp_idx, num_modules,
payload, data->payload_size);
ret = adm_process_get_topo_list_response
(data->opcode, copp_idx,
num_modules, payload,
data->payload_size);
if (ret)
pr_err("%s: Failed to process get topo modules list response, error %d\n",
__func__, ret);
}
} else {
pr_err("%s: Invalid payload size %d\n",
__func__, data->payload_size);
}
atomic_set(&this_adm.copp.stat[port_idx][copp_idx],
payload[0]);
wake_up(&this_adm.copp.wait[port_idx][copp_idx]);

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2019, The 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
@ -332,6 +332,11 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload,
/* Set command specific details */
switch (opcode) {
case AFE_PORT_CMDRSP_GET_PARAM_V2:
if (payload_size < (5 * sizeof(uint32_t))) {
pr_err("%s: Error: size %d is less than expected\n",
__func__, payload_size);
return -EINVAL;
}
expected_size += sizeof(struct param_hdr_v1);
param_hdr.module_id = payload[1];
param_hdr.instance_id = INSTANCE_ID_0;
@ -340,7 +345,17 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload,
data_start = &payload[4];
break;
case AFE_PORT_CMDRSP_GET_PARAM_V3:
if (payload_size < (6 * sizeof(uint32_t))) {
pr_err("%s: Error: size %d is less than expected\n",
__func__, payload_size);
return -EINVAL;
}
expected_size += sizeof(struct param_hdr_v3);
if (payload_size < expected_size) {
pr_err("%s: Error: size %d is less than expected\n",
__func__, payload_size);
return -EINVAL;
}
memcpy(&param_hdr, &payload[1], sizeof(struct param_hdr_v3));
data_start = &payload[5];
break;
@ -482,6 +497,15 @@ static int32_t afe_lpass_resources_callback(struct apr_client_data *data)
return 0;
}
static bool afe_token_is_valid(uint32_t token)
{
if (token >= AFE_MAX_PORTS) {
pr_err("%s: token %d is invalid.\n", __func__, token);
return false;
}
return true;
}
static int32_t afe_callback(struct apr_client_data *data, void *priv)
{
if (!data) {
@ -545,6 +569,7 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) {
uint32_t *payload = data->payload;
uint32_t param_id;
uint32_t param_id_pos = 0;
if (!payload || (data->token >= AFE_MAX_PORTS)) {
pr_err("%s: Error: size %d payload %pK token %d\n",
@ -553,17 +578,26 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
return -EINVAL;
}
param_id = (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) ?
payload[3] :
payload[2];
if (param_id == AFE_PARAM_ID_DEV_TIMING_STATS) {
av_dev_drift_afe_cb_handler(data->opcode, data->payload,
data->payload_size);
} else {
if (rtac_make_afe_callback(data->payload,
data->payload_size))
return 0;
if (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3)
param_id_pos = 4;
else
param_id_pos = 3;
if (data->payload_size >= param_id_pos * sizeof(uint32_t))
param_id = payload[param_id_pos - 1];
else {
pr_err("%s: Error: size %d is less than expected\n",
__func__, data->payload_size);
return -EINVAL;
}
if (param_id == AFE_PARAM_ID_DEV_TIMING_STATS) {
av_dev_drift_afe_cb_handler(data->opcode, data->payload,
data->payload_size);
} else {
if (sp_make_afe_callback(data->opcode, data->payload,
data->payload_size))
return -EINVAL;
@ -574,7 +608,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
ret = afe_lpass_resources_callback(data);
atomic_set(&this_afe.state, 0);
if (afe_token_is_valid(data->token))
wake_up(&this_afe.wait[data->token]);
else
return -EINVAL;
if (!ret) {
return ret;
}
@ -583,6 +620,11 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
uint16_t port_id = 0;
payload = data->payload;
if (data->opcode == APR_BASIC_RSP_RESULT) {
if (data->payload_size < (2 * sizeof(uint32_t))) {
pr_err("%s: Error: size %d is less than expected\n",
__func__, data->payload_size);
return -EINVAL;
}
pr_debug("%s:opcode = 0x%x cmd = 0x%x status = 0x%x token=%d\n",
__func__, data->opcode,
payload[0], payload[1], data->token);
@ -610,7 +652,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
case AFE_SVC_CMD_SET_PARAM_V2:
case AFE_CMD_REQUEST_LPASS_RESOURCES:
atomic_set(&this_afe.state, 0);
if (afe_token_is_valid(data->token))
wake_up(&this_afe.wait[data->token]);
else
return -EINVAL;
break;
case AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER:
break;
@ -622,7 +667,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
break;
case AFE_CMD_ADD_TOPOLOGIES:
atomic_set(&this_afe.state, 0);
if (afe_token_is_valid(data->token))
wake_up(&this_afe.wait[data->token]);
else
return -EINVAL;
pr_debug("%s: AFE_CMD_ADD_TOPOLOGIES cmd 0x%x\n",
__func__, payload[1]);
break;
@ -678,7 +726,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
else
this_afe.mmap_handle = payload[0];
atomic_set(&this_afe.state, 0);
if (afe_token_is_valid(data->token))
wake_up(&this_afe.wait[data->token]);
else
return -EINVAL;
} else if (data->opcode == AFE_EVENT_RT_PROXY_PORT_STATUS) {
port_id = (uint16_t)(0x0000FFFF & payload[0]);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
@ -1722,14 +1722,14 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv)
return 0;
}
if (data->payload_size > sizeof(int)) {
if (data->payload_size >= 2 * sizeof(uint32_t)) {
pr_debug("%s:ptr0[0x%x]ptr1[0x%x]opcode[0x%x] token[0x%x]payload_s[%d] src[%d] dest[%d]sid[%d]dir[%d]\n",
__func__, payload[0], payload[1], data->opcode,
data->token, data->payload_size, data->src_port,
data->dest_port, asm_token._token.session_id, dir);
pr_debug("%s:Payload = [0x%x] status[0x%x]\n",
__func__, payload[0], payload[1]);
} else if (data->payload_size == sizeof(int)) {
} else if (data->payload_size == sizeof(uint32_t)) {
pr_debug("%s:ptr0[0x%x]opcode[0x%x] token[0x%x]payload_s[%d] src[%d] dest[%d]sid[%d]dir[%d]\n",
__func__, payload[0], data->opcode,
data->token, data->payload_size, data->src_port,
@ -1743,7 +1743,8 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv)
case ASM_CMD_SHARED_MEM_MAP_REGIONS:
case ASM_CMD_SHARED_MEM_UNMAP_REGIONS:
case ASM_CMD_ADD_TOPOLOGIES:
if (payload[1] != 0) {
if (data->payload_size >= 2 * sizeof(uint32_t)
&& payload[1] != 0) {
pr_err("%s: cmd = 0x%x returned error = 0x%x sid:%d\n",
__func__, payload[0], payload[1],
asm_token._token.session_id);
@ -1761,8 +1762,12 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv)
if (atomic_cmpxchg(&ac->mem_state, -1, 0) == -1)
wake_up(&ac->mem_wait);
if (data->payload_size >= 2 * sizeof(uint32_t))
dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x]\n",
__func__, payload[0], payload[1]);
else
dev_vdbg(ac->dev, "%s: Payload size of %d is less than expected.\n",
__func__, data->payload_size);
break;
default:
pr_debug("%s: command[0x%x] not expecting rsp\n",
@ -1791,8 +1796,13 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv)
break;
}
case ASM_CMD_SHARED_MEM_UNMAP_REGIONS:{
if (data->payload_size >= 2 * sizeof(uint32_t))
pr_debug("%s: PL#0[0x%x]PL#1 [0x%x]\n",
__func__, payload[0], payload[1]);
else
pr_debug("%s: Payload size of %d is less than expected.\n",
__func__, data->payload_size);
spin_lock_irqsave(&port->dsp_lock, dsp_flags);
if (atomic_cmpxchg(&ac->mem_state, -1, 0) == -1)
wake_up(&ac->mem_wait);
@ -1801,8 +1811,12 @@ static int32_t q6asm_srvc_callback(struct apr_client_data *data, void *priv)
break;
}
default:
if (data->payload_size >= 2 * sizeof(uint32_t))
pr_debug("%s: command[0x%x]success [0x%x]\n",
__func__, payload[0], payload[1]);
else
pr_debug("%s: Payload size of %d is less than expected.\n",
__func__, data->payload_size);
}
if (ac->cb)
ac->cb(data->opcode, data->token,
@ -1948,6 +1962,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
data->dest_port);
if ((data->opcode != ASM_DATA_EVENT_RENDERED_EOS) &&
(data->opcode != ASM_DATA_EVENT_EOS) &&
(data->opcode != ASM_SESSION_EVENTX_OVERFLOW) &&
(data->opcode != ASM_SESSION_EVENT_RX_UNDERFLOW)) {
if (payload == NULL) {
pr_err("%s: payload is null\n", __func__);
@ -1955,8 +1970,12 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
&(session[session_id].session_lock), flags);
return -EINVAL;
}
if (data->payload_size >= 2 * sizeof(uint32_t))
dev_vdbg(ac->dev, "%s: Payload = [0x%x] status[0x%x] opcode 0x%x\n",
__func__, payload[0], payload[1], data->opcode);
else
dev_vdbg(ac->dev, "%s: Payload size of %d is less than expected.\n",
__func__, data->payload_size);
}
if (data->opcode == APR_BASIC_RSP_RESULT) {
switch (payload[0]) {
@ -2001,25 +2020,30 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
case ASM_DATA_CMD_REMOVE_TRAILING_SILENCE:
case ASM_SESSION_CMD_REGISTER_FOR_RX_UNDERFLOW_EVENTS:
case ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED:
if (data->payload_size >=
2 * sizeof(uint32_t) &&
payload[1] != 0) {
pr_debug("%s: session %d opcode 0x%x token 0x%x Payload = [0x%x] stat 0x%x src %d dest %d\n",
__func__, ac->session,
data->opcode, data->token,
payload[0], payload[1],
data->src_port, data->dest_port);
if (payload[1] != 0) {
pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
__func__, payload[0], payload[1]);
__func__,
payload[0],
payload[1]);
if (wakeup_flag) {
if ((is_adsp_reg_event(payload[0]) >=
0) ||
(payload[0] ==
ASM_STREAM_CMD_SET_PP_PARAMS_V2) ||
(payload[0] ==
if ((is_adsp_reg_event(payload[0]) >= 0)
|| (payload[0] ==
ASM_STREAM_CMD_SET_PP_PARAMS_V2)
|| (payload[0] ==
ASM_STREAM_CMD_SET_PP_PARAMS_V3))
atomic_set(&ac->cmd_state_pp,
atomic_set(
&ac->cmd_state_pp,
payload[1]);
else
atomic_set(&ac->cmd_state,
atomic_set(
&ac->cmd_state,
payload[1]);
wake_up(&ac->cmd_wait);
}
@ -2027,6 +2051,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
&(session[session_id].session_lock),
flags);
return 0;
} else {
pr_err("%s: payload size of %x is less than expected.\n",
__func__, data->payload_size);
}
if ((is_adsp_reg_event(payload[0]) >= 0) ||
(payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V2) ||
@ -2048,9 +2075,11 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
(uint32_t *)data->payload, ac->priv);
break;
case ASM_CMD_ADD_TOPOLOGIES:
if (data->payload_size >=
2 * sizeof(uint32_t) &&
payload[1] != 0) {
pr_debug("%s:Payload = [0x%x]stat[0x%x]\n",
__func__, payload[0], payload[1]);
if (payload[1] != 0) {
pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
__func__, payload[0], payload[1]);
if (wakeup_flag) {
@ -2071,8 +2100,12 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
(uint32_t *)data->payload, ac->priv);
break;
case ASM_DATA_EVENT_WATERMARK: {
if (data->payload_size >= 2 * sizeof(uint32_t))
pr_debug("%s: Watermark opcode[0x%x] status[0x%x]",
__func__, payload[0], payload[1]);
else
pr_err("%s: payload size of %x is less than expected.\n",
__func__, data->payload_size);
break;
}
case ASM_STREAM_CMD_GET_PP_PARAMS_V2:
@ -2084,23 +2117,34 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
/* error or malformed APR packet. Otherwise */
/* response will be returned as */
/* ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 */
if (data->payload_size >= 2 * sizeof(uint32_t)) {
if (payload[1] != 0) {
pr_err("%s: ASM get param error = %d, resuming\n",
__func__, payload[1]);
rtac_make_asm_callback(ac->session, payload,
rtac_make_asm_callback(ac->session,
payload,
data->payload_size);
}
} else {
pr_err("%s: payload size of %x is less than expected.\n",
__func__, data->payload_size);
}
break;
case ASM_STREAM_CMD_REGISTER_PP_EVENTS:
pr_debug("%s: ASM_STREAM_CMD_REGISTER_PP_EVENTS session %d opcode 0x%x token 0x%x src %d dest %d\n",
__func__, ac->session,
data->opcode, data->token,
data->src_port, data->dest_port);
if (data->payload_size >= 2 * sizeof(uint32_t)) {
if (payload[1] != 0)
pr_err("%s: ASM get param error = %d, resuming\n",
__func__, payload[1]);
atomic_set(&ac->cmd_state_pp, payload[1]);
wake_up(&ac->cmd_wait);
} else {
pr_err("%s: payload size of %x is less than expected.\n",
__func__, data->payload_size);
}
break;
default:
pr_debug("%s: command[0x%x] not expecting rsp\n",
@ -2116,9 +2160,13 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
switch (data->opcode) {
case ASM_DATA_EVENT_WRITE_DONE_V2:{
struct audio_port_data *port = &ac->port[IN];
if (data->payload_size >= 2 * sizeof(uint32_t))
dev_vdbg(ac->dev, "%s: Rxed opcode[0x%x] status[0x%x] token[%d]",
__func__, payload[0], payload[1],
data->token);
else
dev_err(ac->dev, "%s: payload size of %x is less than expected.\n",
__func__, data->payload_size);
if (ac->io_mode & SYNC_IO_MODE) {
if (port->buf == NULL) {
pr_err("%s: Unexpected Write Done\n",
@ -2130,10 +2178,23 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
}
spin_lock_irqsave(&port->dsp_lock, dsp_flags);
buf_index = asm_token._token.buf_index;
if (lower_32_bits(port->buf[buf_index].phys) !=
if (buf_index < 0 ||
buf_index >= port->max_buf_cnt) {
pr_err("%s: Invalid buffer index %u\n",
__func__, buf_index);
spin_unlock_irqrestore(&port->dsp_lock,
dsp_flags);
spin_unlock_irqrestore(
&(session[session_id].session_lock),
flags);
return -EINVAL;
}
if (data->payload_size >= 2 * sizeof(uint32_t) &&
(lower_32_bits(port->buf[buf_index].phys) !=
payload[0] ||
msm_audio_populate_upper_32_bits(
port->buf[buf_index].phys) != payload[1]) {
port->buf[buf_index].phys) !=
payload[1])) {
pr_debug("%s: Expected addr %pK\n",
__func__, &port->buf[buf_index].phys);
pr_err("%s: rxedl[0x%x] rxedu [0x%x]\n",
@ -2168,14 +2229,32 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
} else if (generic_get_data) {
generic_get_data->valid = 1;
if (generic_get_data->is_inband) {
if (data->payload_size >= 4 * sizeof(uint32_t))
pr_debug("%s: payload[1] = 0x%x, payload[2]=0x%x, payload[3]=0x%x\n",
__func__, payload[1], payload[2], payload[3]);
generic_get_data->size_in_ints = payload[3]>>2;
__func__,
payload[1],
payload[2],
payload[3]);
else
pr_err("%s: payload size of %x is less than expected.\n",
__func__,
data->payload_size);
if (data->payload_size >=
(4 + (payload[3]>>2))
* sizeof(uint32_t)) {
generic_get_data->size_in_ints =
payload[3]>>2;
for (i = 0; i < payload[3]>>2; i++) {
generic_get_data->ints[i] =
payload[4+i];
pr_debug("%s: ASM callback val %i = %i\n",
__func__, i, payload[4+i]);
__func__, i,
payload[4+i]);
}
} else {
pr_err("%s: payload size of %x is less than expected.\n",
__func__, data->payload_size);
}
pr_debug("%s: callback size in ints = %i\n",
__func__,
@ -2220,6 +2299,16 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
}
spin_lock_irqsave(&port->dsp_lock, dsp_flags);
buf_index = asm_token._token.buf_index;
if (buf_index < 0 || buf_index >= port->max_buf_cnt) {
pr_err("%s: Invalid buffer index %u\n",
__func__, buf_index);
spin_unlock_irqrestore(&port->dsp_lock,
dsp_flags);
spin_unlock_irqrestore(
&(session[session_id].session_lock),
flags);
return -EINVAL;
}
port->buf[buf_index].used = 0;
if (lower_32_bits(port->buf[buf_index].phys) !=
payload[READDONE_IDX_BUFADD_LSW] ||
@ -2262,11 +2351,17 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
data->src_port, data->dest_port);
break;
case ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3:
if (data->payload_size >= 3 * sizeof(uint32_t)) {
dev_vdbg(ac->dev, "%s: ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3, payload[0] = %d, payload[1] = %d, payload[2] = %d\n",
__func__,
payload[0], payload[1], payload[2]);
ac->time_stamp = (uint64_t)(((uint64_t)payload[2] << 32) |
ac->time_stamp =
(uint64_t)(((uint64_t)payload[2] << 32) |
payload[1]);
} else {
dev_err(ac->dev, "%s: payload size of %x is less than expected.n",
__func__, data->payload_size);
}
if (atomic_cmpxchg(&ac->time_flag, 1, 0))
wake_up(&ac->time_wait);
break;
@ -2276,10 +2371,14 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
__func__, ac->session,
data->opcode, data->token,
data->src_port, data->dest_port);
if (data->payload_size >= 4 * sizeof(uint32_t))
pr_debug("%s: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, payload[0] = %d, payload[1] = %d, payload[2] = %d, payload[3] = %d\n",
__func__,
payload[0], payload[1], payload[2],
payload[3]);
else
pr_debug("%s: payload size of %x is less than expected.\n",
__func__, data->payload_size);
break;
case ASM_SESSION_CMDRSP_GET_MTMX_STRTR_PARAMS_V2:
q6asm_process_mtmx_get_param_rsp(ac, (void *) payload);
@ -2287,8 +2386,12 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
case ASM_STREAM_PP_EVENT:
case ASM_STREAM_CMD_ENCDEC_EVENTS:
case ASM_STREAM_CMD_REGISTER_IEC_61937_FMT_UPDATE:
if (data->payload_size >= 2 * sizeof(uint32_t))
pr_debug("%s: ASM_STREAM_EVENT payload[0][0x%x] payload[1][0x%x]",
__func__, payload[0], payload[1]);
else
pr_debug("%s: payload size of %x is less than expected.\n",
__func__, data->payload_size);
i = is_adsp_raise_event(data->opcode);
if (i < 0) {
spin_unlock_irqrestore(
@ -2300,6 +2403,14 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
* package is composed of event type + size + actual payload
*/
payload_size = data->payload_size;
if (payload_size > UINT_MAX -
sizeof(struct msm_adsp_event_data)) {
pr_err("%s: payload size = %d exceeds limit.\n",
__func__, payload_size);
spin_unlock(&(session[session_id].session_lock));
return -EINVAL;
}
pp_event_package = kzalloc(payload_size
+ sizeof(struct msm_adsp_event_data),
GFP_ATOMIC);
@ -2320,16 +2431,29 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
&(session[session_id].session_lock), flags);
return 0;
case ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2:
if (data->payload_size >= 3 * sizeof(uint32_t))
pr_debug("%s: ASM_SESSION_CMDRSP_ADJUST_SESSION_CLOCK_V2 sesion %d status 0x%x msw %u lsw %u\n",
__func__, ac->session, payload[0], payload[2],
__func__, ac->session,
payload[0],
payload[2],
payload[1]);
else
pr_err("%s: payload size of %x is less than expected.\n",
__func__, data->payload_size);
wake_up(&ac->cmd_wait);
break;
case ASM_SESSION_CMDRSP_GET_PATH_DELAY_V2:
if (data->payload_size >= 3 * sizeof(uint32_t))
pr_debug("%s: ASM_SESSION_CMDRSP_GET_PATH_DELAY_V2 session %d status 0x%x msw %u lsw %u\n",
__func__, ac->session, payload[0], payload[2],
__func__, ac->session,
payload[0], payload[2],
payload[1]);
if (payload[0] == 0) {
else
pr_err("%s: payload size of %x is less than expected.\n",
__func__, data->payload_size);
if (payload[0] == 0 &&
data->payload_size >=
2 * sizeof(uint32_t)) {
atomic_set(&ac->cmd_state, 0);
/* ignore msw, as a delay that large shouldn't happen */
ac->path_delay = payload[1];
@ -3973,6 +4097,12 @@ int q6asm_open_shared_io(struct audio_client *ac,
if (!ac || !config)
return -EINVAL;
if (config->channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
pr_err("%s: Invalid channel count %d\n", __func__,
config->channels);
return -EINVAL;
}
bufsz = config->bufsz;
bufcnt = config->bufcnt;
num_watermarks = 0;
@ -4432,6 +4562,13 @@ int q6asm_set_encdec_chan_map(struct audio_client *ac,
int rc = 0;
pr_debug("%s: Session %d, num_channels = %d\n",
__func__, ac->session, num_channels);
if (num_channels > MAX_CHAN_MAP_CHANNELS) {
pr_err("%s: Invalid channel count %d\n", __func__,
num_channels);
return -EINVAL;
}
q6asm_add_hdr(ac, &chan_map.hdr, sizeof(chan_map), TRUE);
atomic_set(&ac->cmd_state, -1);
chan_map.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
@ -4510,6 +4647,12 @@ static int q6asm_enc_cfg_blk_pcm_v5(struct audio_client *ac,
goto fail_cmd;
}
if (channels > PCM_FORMAT_MAX_NUM_CHANNEL_V2) {
pr_err("%s: Invalid channel count %d\n", __func__, channels);
rc = -EINVAL;
goto fail_cmd;
}
pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
ac->session, rate, channels,
bits_per_sample, sample_word_size);
@ -4612,6 +4755,12 @@ int q6asm_enc_cfg_blk_pcm_v4(struct audio_client *ac,
goto fail_cmd;
}
if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
pr_err("%s: Invalid channel count %d\n", __func__, channels);
rc = -EINVAL;
goto fail_cmd;
}
pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
ac->session, rate, channels,
bits_per_sample, sample_word_size);
@ -4711,6 +4860,12 @@ int q6asm_enc_cfg_blk_pcm_v3(struct audio_client *ac,
goto fail_cmd;
}
if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
pr_err("%s: Invalid channel count %d\n", __func__, channels);
rc = -EINVAL;
goto fail_cmd;
}
pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
ac->session, rate, channels,
bits_per_sample, sample_word_size);
@ -4793,6 +4948,11 @@ int q6asm_enc_cfg_blk_pcm_v2(struct audio_client *ac,
return -EINVAL;
}
if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
pr_err("%s: Invalid channel count %d\n", __func__, channels);
return -EINVAL;
}
pr_debug("%s: Session %d, rate = %d, channels = %d\n", __func__,
ac->session, rate, channels);
@ -4985,9 +5145,13 @@ int q6asm_enc_cfg_blk_pcm_native(struct audio_client *ac,
struct asm_multi_channel_pcm_enc_cfg_v2 enc_cfg;
u8 *channel_mapping;
u32 frames_per_buf = 0;
int rc = 0;
if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
pr_err("%s: Invalid channel count %d\n", __func__, channels);
return -EINVAL;
}
pr_debug("%s: Session %d, rate = %d, channels = %d\n", __func__,
ac->session, rate, channels);
@ -5535,6 +5699,11 @@ static int __q6asm_media_format_block_pcm(struct audio_client *ac,
u8 *channel_mapping;
int rc = 0;
if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
pr_err("%s: Invalid channel count %d\n", __func__, channels);
return -EINVAL;
}
pr_debug("%s: session[%d]rate[%d]ch[%d]\n", __func__, ac->session, rate,
channels);
@ -5617,6 +5786,11 @@ static int __q6asm_media_format_block_pcm_v3(struct audio_client *ac,
u8 *channel_mapping;
int rc;
if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
pr_err("%s: Invalid channel count %d\n", __func__, channels);
return -EINVAL;
}
pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
ac->session, rate, channels,
bits_per_sample, sample_word_size);
@ -5700,6 +5874,11 @@ static int __q6asm_media_format_block_pcm_v4(struct audio_client *ac,
u8 *channel_mapping;
int rc;
if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
pr_err("%s: Invalid channel count %d\n", __func__, channels);
return -EINVAL;
}
pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
ac->session, rate, channels,
bits_per_sample, sample_word_size);
@ -5888,6 +6067,11 @@ static int __q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
u8 *channel_mapping;
int rc = 0;
if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
pr_err("%s: Invalid channel count %d\n", __func__, channels);
return -EINVAL;
}
pr_debug("%s: session[%d]rate[%d]ch[%d]\n", __func__, ac->session, rate,
channels);
@ -5955,6 +6139,11 @@ static int __q6asm_media_format_block_multi_ch_pcm_v3(struct audio_client *ac,
u8 *channel_mapping;
int rc;
if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
pr_err("%s: Invalid channel count %d\n", __func__, channels);
return -EINVAL;
}
pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
ac->session, rate, channels,
bits_per_sample, sample_word_size);
@ -6026,6 +6215,11 @@ static int __q6asm_media_format_block_multi_ch_pcm_v4(struct audio_client *ac,
u8 *channel_mapping;
int rc;
if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
pr_err("%s: Invalid channel count %d\n", __func__, channels);
return -EINVAL;
}
pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
ac->session, rate, channels,
bits_per_sample, sample_word_size);
@ -6099,6 +6293,12 @@ static int __q6asm_media_format_block_multi_ch_pcm_v5(struct audio_client *ac,
u8 *channel_mapping;
int rc;
if (channels > PCM_FORMAT_MAX_NUM_CHANNEL_V2) {
pr_err("%s: Invalid channel count %d\n", __func__, channels);
rc = -EINVAL;
goto fail_cmd;
}
pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
ac->session, rate, channels,
bits_per_sample, sample_word_size);
@ -6290,6 +6490,11 @@ int q6asm_media_format_block_gen_compr(struct audio_client *ac,
u8 *channel_mapping;
int rc = 0;
if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
pr_err("%s: Invalid channel count %d\n", __func__, channels);
return -EINVAL;
}
pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]\n",
__func__, ac->session, rate,
channels, bits_per_sample);

View file

@ -1,5 +1,5 @@
/*
* 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
@ -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));
@ -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) {
@ -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",
@ -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;
}
@ -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);
@ -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;
}

View file

@ -6398,7 +6398,7 @@ void voc_config_vocoder(uint32_t media_type,
static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv)
{
uint32_t *ptr = NULL;
uint32_t *ptr = NULL, min_payload_size = 0;
struct common_data *c = NULL;
struct voice_data *v = NULL;
int i = 0;
@ -6468,7 +6468,7 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv)
}
if (data->opcode == APR_BASIC_RSP_RESULT) {
if (data->payload_size) {
if (data->payload_size >= sizeof(ptr[0]) * 2) {
ptr = data->payload;
pr_debug("%x %x\n", ptr[0], ptr[1]);
@ -6535,6 +6535,12 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv)
} else if (data->opcode == VSS_IMEMORY_RSP_MAP) {
pr_debug("%s, Revd VSS_IMEMORY_RSP_MAP response\n", __func__);
if (data->payload_size < sizeof(ptr[0])) {
pr_err("%s: payload has invalid size[%d]\n", __func__,
data->payload_size);
return -EINVAL;
}
if (data->payload_size && data->token == VOIP_MEM_MAP_TOKEN) {
ptr = data->payload;
if (ptr[0]) {
@ -6602,10 +6608,15 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv)
pr_debug("%s: Received VSS_IVERSION_RSP_GET\n", __func__);
if (data->payload_size) {
min_payload_size = (data->payload_size >
CVD_VERSION_STRING_MAX_SIZE)
? CVD_VERSION_STRING_MAX_SIZE :
data->payload_size;
version_rsp =
(struct vss_iversion_rsp_get_t *)data->payload;
memcpy(common.cvd_version, version_rsp->version,
CVD_VERSION_STRING_MAX_SIZE);
min_payload_size);
common.cvd_version[min_payload_size - 1] = '\0';
pr_debug("%s: CVD Version = %s\n",
__func__, common.cvd_version);
@ -6782,6 +6793,11 @@ static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv)
cvs_voc_pkt = v->shmem_info.sh_buf.buf[1].data;
if (cvs_voc_pkt != NULL && common.mvs_info.ul_cb != NULL) {
if (v->shmem_info.sh_buf.buf[1].size <
((3 * sizeof(uint32_t)) + cvs_voc_pkt[2])) {
pr_err("%s: invalid voc pkt size\n", __func__);
return -EINVAL;
}
/* cvs_voc_pkt[0] contains tx timestamp */
common.mvs_info.ul_cb((uint8_t *)&cvs_voc_pkt[3],
cvs_voc_pkt[2],