mirror of
https://github.com/torvalds/linux.git
synced 2026-07-31 03:27:03 +02:00
Merge "coresight: byte-cntr: Add the length check in reading data"
This commit is contained in:
commit
3c7f6a083d
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#define CSR_BYTECNTVAL (0x06C)
|
||||
|
||||
static void tmc_etr_read_bytes(struct byte_cntr *byte_cntr_data, loff_t *ppos,
|
||||
static void tmc_etr_read_bytes(struct byte_cntr *byte_cntr_data, long offset,
|
||||
size_t bytes, size_t *len, char **bufp)
|
||||
{
|
||||
struct tmc_drvdata *tmcdrvdata = byte_cntr_data->tmcdrvdata;
|
||||
|
|
@ -27,12 +27,12 @@ static void tmc_etr_read_bytes(struct byte_cntr *byte_cntr_data, loff_t *ppos,
|
|||
|
||||
if (*len >= bytes)
|
||||
*len = bytes;
|
||||
else if (((uint32_t)*ppos % bytes) + *len > bytes)
|
||||
*len = bytes - ((uint32_t)*ppos % bytes);
|
||||
else if (((uint32_t)offset % bytes) + *len > bytes)
|
||||
*len = bytes - ((uint32_t)offset % bytes);
|
||||
|
||||
actual = tmc_etr_buf_get_data(etr_buf, *ppos, *len, bufp);
|
||||
actual = tmc_etr_buf_get_data(etr_buf, offset, *len, bufp);
|
||||
*len = actual;
|
||||
if (actual == bytes || (actual + (uint32_t)*ppos) % bytes == 0)
|
||||
if (actual == bytes || (actual + (uint32_t)offset) % bytes == 0)
|
||||
atomic_dec(&byte_cntr_data->irq_cnt);
|
||||
}
|
||||
|
||||
|
|
@ -50,22 +50,42 @@ static irqreturn_t etr_handler(int irq, void *data)
|
|||
wake_up(&byte_cntr_data->wq);
|
||||
}
|
||||
|
||||
byte_cntr_data->total_irq++;
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
static long tmc_etr_flush_remaining_bytes(struct tmc_drvdata *tmcdrvdata, loff_t *ppos,
|
||||
char **bufpp)
|
||||
static long tmc_etr_flush_remaining_bytes(struct tmc_drvdata *tmcdrvdata, long offset,
|
||||
size_t len, char **bufpp)
|
||||
{
|
||||
long rwp_offset, req_size, actual = 0;
|
||||
struct etr_buf *etr_buf = tmcdrvdata->sysfs_buf;
|
||||
struct etr_buf *etr_buf;
|
||||
struct device *dev;
|
||||
int rc = 0;
|
||||
|
||||
if (!tmcdrvdata)
|
||||
return -EINVAL;
|
||||
|
||||
etr_buf = tmcdrvdata->sysfs_buf;
|
||||
dev = &tmcdrvdata->csdev->dev;
|
||||
|
||||
rc = pm_runtime_get_sync(dev->parent);
|
||||
if (rc < 0) {
|
||||
pm_runtime_put_noidle(dev->parent);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rwp_offset = tmc_get_rwp_offset(tmcdrvdata);
|
||||
req_size = ((rwp_offset < *ppos) ? tmcdrvdata->size : 0) +
|
||||
rwp_offset - *ppos;
|
||||
pm_runtime_put(dev->parent);
|
||||
req_size = ((rwp_offset < offset) ? tmcdrvdata->size : 0) +
|
||||
rwp_offset - offset;
|
||||
|
||||
if (req_size > len)
|
||||
req_size = len;
|
||||
|
||||
if (req_size > 0)
|
||||
actual = tmc_etr_buf_get_data(etr_buf, *ppos, req_size, bufpp);
|
||||
actual = tmc_etr_buf_get_data(etr_buf, offset, req_size, bufpp);
|
||||
|
||||
return actual;
|
||||
}
|
||||
|
|
@ -85,7 +105,8 @@ static ssize_t tmc_etr_byte_cntr_read(struct file *fp, char __user *data,
|
|||
|
||||
mutex_lock(&byte_cntr_data->byte_cntr_lock);
|
||||
if (!byte_cntr_data->read_active) {
|
||||
actual = tmc_etr_flush_remaining_bytes(tmcdrvdata, ppos, &bufp);
|
||||
actual = tmc_etr_flush_remaining_bytes(tmcdrvdata,
|
||||
byte_cntr_data->offset, len, &bufp);
|
||||
if (actual > 0) {
|
||||
len = actual;
|
||||
goto copy;
|
||||
|
|
@ -104,7 +125,8 @@ static ssize_t tmc_etr_byte_cntr_read(struct file *fp, char __user *data,
|
|||
return -ERESTARTSYS;
|
||||
mutex_lock(&byte_cntr_data->byte_cntr_lock);
|
||||
if (!byte_cntr_data->read_active) {
|
||||
actual = tmc_etr_flush_remaining_bytes(tmcdrvdata, ppos, &bufp);
|
||||
actual = tmc_etr_flush_remaining_bytes(tmcdrvdata,
|
||||
byte_cntr_data->offset, len, &bufp);
|
||||
if (actual > 0) {
|
||||
len = actual;
|
||||
goto copy;
|
||||
|
|
@ -115,11 +137,12 @@ static ssize_t tmc_etr_byte_cntr_read(struct file *fp, char __user *data,
|
|||
}
|
||||
}
|
||||
|
||||
tmc_etr_read_bytes(byte_cntr_data, ppos,
|
||||
tmc_etr_read_bytes(byte_cntr_data, byte_cntr_data->offset,
|
||||
byte_cntr_data->block_size, &len, &bufp);
|
||||
|
||||
} else {
|
||||
actual = tmc_etr_flush_remaining_bytes(tmcdrvdata, ppos, &bufp);
|
||||
actual = tmc_etr_flush_remaining_bytes(tmcdrvdata,
|
||||
byte_cntr_data->offset, len, &bufp);
|
||||
if (actual > 0) {
|
||||
len = actual;
|
||||
goto copy;
|
||||
|
|
@ -137,10 +160,12 @@ static ssize_t tmc_etr_byte_cntr_read(struct file *fp, char __user *data,
|
|||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (*ppos + len >= tmcdrvdata->size)
|
||||
*ppos = 0;
|
||||
byte_cntr_data->total_size += len;
|
||||
|
||||
if (byte_cntr_data->offset + len >= tmcdrvdata->size)
|
||||
byte_cntr_data->offset = 0;
|
||||
else
|
||||
*ppos += len;
|
||||
byte_cntr_data->offset += len;
|
||||
|
||||
goto out;
|
||||
|
||||
|
|
@ -192,6 +217,8 @@ EXPORT_SYMBOL(tmc_etr_byte_cntr_stop);
|
|||
static int tmc_etr_byte_cntr_release(struct inode *in, struct file *fp)
|
||||
{
|
||||
struct byte_cntr *byte_cntr_data = fp->private_data;
|
||||
struct device *dev = &byte_cntr_data->tmcdrvdata->csdev->dev;
|
||||
int rc;
|
||||
|
||||
mutex_lock(&byte_cntr_data->byte_cntr_lock);
|
||||
byte_cntr_data->read_active = false;
|
||||
|
|
@ -203,6 +230,21 @@ static int tmc_etr_byte_cntr_release(struct inode *in, struct file *fp)
|
|||
byte_cntr_data->irqctrl_offset, 0);
|
||||
|
||||
disable_irq_wake(byte_cntr_data->byte_cntr_irq);
|
||||
|
||||
rc = pm_runtime_get_sync(dev->parent);
|
||||
if (rc < 0) {
|
||||
pm_runtime_put_noidle(dev->parent);
|
||||
} else {
|
||||
byte_cntr_data->rwp_offset =
|
||||
tmc_get_rwp_offset(byte_cntr_data->tmcdrvdata);
|
||||
|
||||
pm_runtime_put(dev->parent);
|
||||
}
|
||||
|
||||
dev_dbg(dev, "send data total size: %lld bytes, irq_cnt: %lld, offset: %lld rwp_offset: %lld\n",
|
||||
byte_cntr_data->total_size, byte_cntr_data->total_irq,
|
||||
byte_cntr_data->offset, byte_cntr_data->rwp_offset);
|
||||
byte_cntr_data->total_irq = 0;
|
||||
mutex_unlock(&byte_cntr_data->byte_cntr_lock);
|
||||
|
||||
return 0;
|
||||
|
|
@ -239,6 +281,8 @@ static int tmc_etr_byte_cntr_open(struct inode *in, struct file *fp)
|
|||
nonseekable_open(in, fp);
|
||||
byte_cntr_data->enable = true;
|
||||
byte_cntr_data->read_active = true;
|
||||
byte_cntr_data->total_size = 0;
|
||||
byte_cntr_data->offset = tmc_get_rwp_offset(tmcdrvdata);
|
||||
mutex_unlock(&byte_cntr_data->byte_cntr_lock);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CORESIGHT_BYTE_CNTR_H
|
||||
|
|
@ -34,6 +34,10 @@ struct byte_cntr {
|
|||
const char *class_name;
|
||||
int irqctrl_offset;
|
||||
unsigned long offset;
|
||||
unsigned long rwp_offset;
|
||||
uint64_t total_size;
|
||||
uint64_t total_irq;
|
||||
|
||||
};
|
||||
|
||||
extern void tmc_etr_byte_cntr_start(struct byte_cntr *byte_cntr_data);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* Description: CoreSight TMC USB driver
|
||||
*/
|
||||
|
|
@ -82,6 +82,7 @@ static int usb_bypass_start(struct byte_cntr *byte_cntr_data)
|
|||
USB_BLK_SIZE / 8);
|
||||
|
||||
atomic_set(&byte_cntr_data->irq_cnt, 0);
|
||||
byte_cntr_data->total_size = 0;
|
||||
mutex_unlock(&byte_cntr_data->usb_bypass_lock);
|
||||
|
||||
return 0;
|
||||
|
|
@ -102,6 +103,10 @@ static void usb_bypass_stop(struct byte_cntr *byte_cntr_data)
|
|||
wake_up(&byte_cntr_data->usb_wait_wq);
|
||||
pr_info("coresight: stop usb bypass\n");
|
||||
coresight_csr_set_byte_cntr(byte_cntr_data->csr, byte_cntr_data->irqctrl_offset, 0);
|
||||
dev_dbg(&byte_cntr_data->tmcdrvdata->csdev->dev,
|
||||
"write to usb data total size: %lld bytes, irq_cnt: %lld, offset: %ld\n",
|
||||
byte_cntr_data->total_size, byte_cntr_data->total_irq, byte_cntr_data->offset);
|
||||
byte_cntr_data->total_irq = 0;
|
||||
mutex_unlock(&byte_cntr_data->usb_bypass_lock);
|
||||
|
||||
}
|
||||
|
|
@ -172,7 +177,7 @@ static int usb_transfer_small_packet(struct byte_cntr *drvdata, size_t *small_si
|
|||
"Write data failed:%d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
drvdata->total_size += actual;
|
||||
atomic_dec(&drvdata->usb_free_buf);
|
||||
} else {
|
||||
dev_dbg(&tmcdrvdata->csdev->dev,
|
||||
|
|
@ -289,6 +294,7 @@ static void usb_read_work_fn(struct work_struct *work)
|
|||
continue;
|
||||
return;
|
||||
}
|
||||
drvdata->total_size += actual_total;
|
||||
atomic_dec(&drvdata->usb_free_buf);
|
||||
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user