Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a1189634 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: soundwire: fix out of boundary access issues"

parents 5a8db41e bba5b5a2
Loading
Loading
Loading
Loading
+13 −11
Original line number Diff line number Diff line
@@ -20,15 +20,14 @@

static int regmap_swr_gather_write(void *context,
				const void *reg, size_t reg_size,
				const void *val, size_t val_size)
				const void *val, size_t val_len)
{
	struct device *dev = context;
	struct swr_device *swr = to_swr_device(dev);
	struct regmap *map = dev_get_regmap(dev, NULL);
	size_t addr_bytes;
	int ret = 0;
	int i;
	u32 reg_addr = 0;
	size_t addr_bytes, val_bytes;
	int i, ret = 0;
	u16 reg_addr = 0;

	if (swr == NULL) {
		dev_err(dev, "%s: swr device is NULL\n", __func__);
@@ -45,12 +44,15 @@ static int regmap_swr_gather_write(void *context,
		return -EINVAL;
	}
	reg_addr = *(u16 *)reg;
	for (i = 0; i < val_size; i++) {
		ret = swr_write(swr, swr->dev_num, (reg_addr+i),
				(u32 *)(val+i));
	val_bytes = map->format.val_bytes;
	/* val_len = val_bytes * val_count */
	for (i = 0; i < (val_len / val_bytes); i++) {
		reg_addr = reg_addr + i;
		val = (u8 *)val + (val_bytes * i);
		ret = swr_write(swr, swr->dev_num, reg_addr, val);
		if (ret < 0) {
			dev_err(dev, "%s: write reg 0x%x failed, err %d\n",
				__func__, (reg_addr+i), ret);
				__func__, reg_addr, ret);
			break;
		}
	}
@@ -84,7 +86,7 @@ static int regmap_swr_read(void *context,
	struct regmap *map = dev_get_regmap(dev, NULL);
	size_t addr_bytes;
	int ret = 0;
	u32 reg_addr = 0;
	u16 reg_addr = 0;

	if (swr == NULL) {
		dev_err(dev, "%s: swr is NULL\n", __func__);
@@ -100,7 +102,7 @@ static int regmap_swr_read(void *context,
			__func__, reg_size);
		return -EINVAL;
	}
	reg_addr = *(u32 *)reg;
	reg_addr = *(u16 *)reg;
	ret = swr_read(swr, swr->dev_num, reg_addr, val, val_size);
	if (ret < 0)
		dev_err(dev, "%s: codec reg 0x%x read failed %d\n",
+4 −4
Original line number Diff line number Diff line
@@ -405,8 +405,8 @@ EXPORT_SYMBOL(swr_get_logical_dev_num);
 * This API will read the value of the register address from
 * soundwire slave device
 */
int swr_read(struct swr_device *dev, u8 dev_num, u32 reg_addr,
		u32 *buf, u32 len)
int swr_read(struct swr_device *dev, u8 dev_num, u16 reg_addr,
	     void *buf, u32 len)
{
	struct swr_master *master = dev->master;
	if (!master)
@@ -425,8 +425,8 @@ EXPORT_SYMBOL(swr_read);
 * This API will write the value of the register address to
 * soundwire slave device
 */
int swr_write(struct swr_device *dev, u8 dev_num, u32 reg_addr,
		u32 *buf)
int swr_write(struct swr_device *dev, u8 dev_num, u16 reg_addr,
	      const void *buf)
{
	struct swr_master *master = dev->master;
	if (!master)
+19 −28
Original line number Diff line number Diff line
@@ -389,7 +389,7 @@ static int swrm_get_master_port(u8 *mstr_port_id, u8 slv_port_id)
	return -EINVAL;
}

static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, u32 *cmd_data,
static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data,
				 u8 dev_addr, u8 cmd_id, u16 reg_addr,
				 u32 len)
{
@@ -453,11 +453,13 @@ err:
	return ret;
}

static int swrm_read(struct swr_master *master, u8 dev_num, u32 reg_addr,
		u32 *buf, u32 len)
static int swrm_read(struct swr_master *master, u8 dev_num, u16 reg_addr,
		     void *buf, u32 len)
{
	struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);
	int ret = 0;
	int val;
	u8 *reg_val = (u8 *)buf;

	if (!swrm) {
		dev_err(&master->dev, "%s: swrm is NULL\n", __func__);
@@ -465,29 +467,24 @@ static int swrm_read(struct swr_master *master, u8 dev_num, u32 reg_addr,
	}

	pm_runtime_get_sync(&swrm->pdev->dev);
	if (dev_num) {
		swrm_cmd_fifo_rd_cmd(swrm, buf, dev_num, 0, reg_addr,
					len);
	} else {
		if (swrm->read)
			buf[0] = swrm->read(swrm->handle, reg_addr);
		else {
			dev_err(&master->dev, "%s: handle is NULL 0x%x\n",
				__func__, reg_addr);
			ret = -EINVAL;
		}
	}
	if (dev_num)
		swrm_cmd_fifo_rd_cmd(swrm, &val, dev_num, 0, reg_addr, len);
	else
		val = swrm->read(swrm->handle, reg_addr);

	*reg_val = (u8)val;
	pm_runtime_mark_last_busy(&swrm->pdev->dev);
	pm_runtime_put_autosuspend(&swrm->pdev->dev);

	return ret;
}

static int swrm_write(struct swr_master *master, u8 dev_num, u32 reg_addr,
		u32 *buf)
static int swrm_write(struct swr_master *master, u8 dev_num, u16 reg_addr,
		      const void *buf)
{
	struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);
	int ret = 0;
	u8 reg_val = *(u8 *)buf;

	if (!swrm) {
		dev_err(&master->dev, "%s: swrm is NULL\n", __func__);
@@ -495,17 +492,11 @@ static int swrm_write(struct swr_master *master, u8 dev_num, u32 reg_addr,
	}

	pm_runtime_get_sync(&swrm->pdev->dev);
	if (dev_num) {
		ret = swrm_cmd_fifo_wr_cmd(swrm, buf[0], dev_num, 0, reg_addr);
	} else {
		if (swrm->write) {
			ret = swrm->write(swrm->handle, reg_addr, buf[0]);
		} else {
			dev_err(&master->dev, "%s: handle is NULL 0x%x\n",
				__func__, reg_addr);
			ret = -EINVAL;
		}
	}
	if (dev_num)
		ret = swrm_cmd_fifo_wr_cmd(swrm, reg_val, dev_num, 0, reg_addr);
	else
		ret = swrm->write(swrm->handle, reg_addr, reg_val);

	pm_runtime_mark_last_busy(&swrm->pdev->dev);
	pm_runtime_put_autosuspend(&swrm->pdev->dev);

+8 −8
Original line number Diff line number Diff line
@@ -133,10 +133,10 @@ struct swr_master {
	u8 num_dev;
	int (*connect_port)(struct swr_master *mstr, struct swr_params *txn);
	int (*disconnect_port)(struct swr_master *mstr, struct swr_params *txn);
	int (*read)(struct swr_master *mstr, u8 dev_num, u32 reg_addr,
			u32 *buf, u32 len);
	int (*write)(struct swr_master *mstr, u8 dev_num, u32 reg_addr,
			u32 *buf);
	int (*read)(struct swr_master *mstr, u8 dev_num, u16 reg_addr,
			void *buf, u32 len);
	int (*write)(struct swr_master *mstr, u8 dev_num, u16 reg_addr,
			const void *buf);
	int (*get_logical_dev_num)(struct swr_master *mstr, u64 dev_id,
				u8 *dev_num);
};
@@ -249,11 +249,11 @@ extern void swr_port_response(struct swr_master *mstr, u8 tid);
extern int swr_get_logical_dev_num(struct swr_device *dev, u64 dev_id,
			u8 *dev_num);

extern int swr_read(struct swr_device *dev, u8 dev_num, u32 reg_addr,
			u32 *buf, u32 len);
extern int swr_read(struct swr_device *dev, u8 dev_num, u16 reg_addr,
			void *buf, u32 len);

extern int swr_write(struct swr_device *dev, u8 dev_num, u32 reg_addr,
			u32 *buf);
extern int swr_write(struct swr_device *dev, u8 dev_num, u16 reg_addr,
			const void *buf);

extern int swr_connect_port(struct swr_device *dev, u8 *port_id, u8 num_port,
				u8 *ch_mask, u32 *ch_rate, u8 *num_ch);