Commit 277c6960 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: ctxfi: Check the error for index mapping

The ctxfi driver blindly assumed a proper value returned from
daio_device_index(), but it's not always true.  Add a proper error
check to deal with the error from the function.

Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/87cy149n6k.wl-tiwai@suse.de
Link: https://patch.msgid.link/20260329091240.420194-2-tiwai@suse.de


Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent b045ab3d
Loading
Loading
Loading
Loading
+52 −33
Original line number Diff line number Diff line
@@ -99,7 +99,7 @@ static const struct rsc_ops daio_in_rsc_ops_20k2 = {
	.output_slot	= daio_index,
};

static unsigned int daio_device_index(enum DAIOTYP type, struct hw *hw)
static int daio_device_index(enum DAIOTYP type, struct hw *hw)
{
	switch (hw->chip_type) {
	case ATC20K1:
@@ -112,7 +112,9 @@ static unsigned int daio_device_index(enum DAIOTYP type, struct hw *hw)
		case LINEO3:	return 5;
		case LINEO4:	return 6;
		case LINEIM:	return 7;
		default:	return -EINVAL;
		default:
			pr_err("ctxfi: Invalid type %d for hw20k1\n", type);
			return -EINVAL;
		}
	case ATC20K2:
		switch (type) {
@@ -126,9 +128,12 @@ static unsigned int daio_device_index(enum DAIOTYP type, struct hw *hw)
		case LINEIM:	return 4;
		case MIC:	return 5;
		case RCA:	return 3;
		default:	return -EINVAL;
		default:
			pr_err("ctxfi: Invalid type %d for hw20k2\n", type);
			return -EINVAL;
		}
	default:
		pr_err("ctxfi: Invalid chip type %d\n", hw->chip_type);
		return -EINVAL;
	}
}
@@ -149,8 +154,11 @@ static int dao_spdif_set_spos(struct dao *dao, unsigned int spos)

static int dao_commit_write(struct dao *dao)
{
	dao->hw->dao_commit_write(dao->hw,
		daio_device_index(dao->daio.type, dao->hw), dao->ctrl_blk);
	int idx = daio_device_index(dao->daio.type, dao->hw);

	if (idx < 0)
		return idx;
	dao->hw->dao_commit_write(dao->hw, idx, dao->ctrl_blk);
	return 0;
}

@@ -288,8 +296,11 @@ static int dai_set_enb_srt(struct dai *dai, unsigned int enb)

static int dai_commit_write(struct dai *dai)
{
	dai->hw->dai_commit_write(dai->hw,
		daio_device_index(dai->daio.type, dai->hw), dai->ctrl_blk);
	int idx = daio_device_index(dai->daio.type, dai->hw);

	if (idx < 0)
		return idx;
	dai->hw->dai_commit_write(dai->hw, idx, dai->ctrl_blk);
	return 0;
}

@@ -368,7 +379,7 @@ static int dao_rsc_init(struct dao *dao,
{
	struct hw *hw = mgr->mgr.hw;
	unsigned int conf;
	int err;
	int idx, err;

	err = daio_rsc_init(&dao->daio, desc, mgr->mgr.hw);
	if (err)
@@ -387,15 +398,18 @@ static int dao_rsc_init(struct dao *dao,
	if (err)
		goto error2;

	hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk,
			daio_device_index(dao->daio.type, hw));
	idx = daio_device_index(dao->daio.type, hw);
	if (idx < 0) {
		err = idx;
		goto error2;
	}

	hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk, idx);
	hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk);

	conf = (desc->msr & 0x7) | (desc->passthru << 3);
	hw->daio_mgr_dao_init(hw, mgr->mgr.ctrl_blk,
			daio_device_index(dao->daio.type, hw), conf);
	hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk,
			daio_device_index(dao->daio.type, hw));
	hw->daio_mgr_dao_init(hw, mgr->mgr.ctrl_blk, idx, conf);
	hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk, idx);
	hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk);

	return 0;
@@ -444,7 +458,7 @@ static int dai_rsc_init(struct dai *dai,
			const struct daio_desc *desc,
			struct daio_mgr *mgr)
{
	int err;
	int idx, err;
	struct hw *hw = mgr->mgr.hw;
	unsigned int rsr, msr;

@@ -458,6 +472,12 @@ static int dai_rsc_init(struct dai *dai,
	if (err)
		goto error1;

	idx = daio_device_index(dai->daio.type, dai->hw);
	if (idx < 0) {
		err = idx;
		goto error1;
	}

	for (rsr = 0, msr = desc->msr; msr > 1; msr >>= 1)
		rsr++;

@@ -466,8 +486,7 @@ static int dai_rsc_init(struct dai *dai,
	/* default to disabling control of a SRC */
	hw->dai_srt_set_ec(dai->ctrl_blk, 0);
	hw->dai_srt_set_et(dai->ctrl_blk, 0); /* default to disabling SRT */
	hw->dai_commit_write(hw,
		daio_device_index(dai->daio.type, dai->hw), dai->ctrl_blk);
	hw->dai_commit_write(hw, idx, dai->ctrl_blk);

	return 0;

@@ -582,28 +601,28 @@ static int put_daio_rsc(struct daio_mgr *mgr, struct daio *daio)
static int daio_mgr_enb_daio(struct daio_mgr *mgr, struct daio *daio)
{
	struct hw *hw = mgr->mgr.hw;

	if (daio->output) {
		hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk,
				daio_device_index(daio->type, hw));
	} else {
		hw->daio_mgr_enb_dai(mgr->mgr.ctrl_blk,
				daio_device_index(daio->type, hw));
	}
	int idx = daio_device_index(daio->type, hw);

	if (idx < 0)
		return idx;
	if (daio->output)
		hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk, idx);
	else
		hw->daio_mgr_enb_dai(mgr->mgr.ctrl_blk, idx);
	return 0;
}

static int daio_mgr_dsb_daio(struct daio_mgr *mgr, struct daio *daio)
{
	struct hw *hw = mgr->mgr.hw;

	if (daio->output) {
		hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk,
				daio_device_index(daio->type, hw));
	} else {
		hw->daio_mgr_dsb_dai(mgr->mgr.ctrl_blk,
				daio_device_index(daio->type, hw));
	}
	int idx = daio_device_index(daio->type, hw);

	if (idx < 0)
		return idx;
	if (daio->output)
		hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk, idx);
	else
		hw->daio_mgr_dsb_dai(mgr->mgr.ctrl_blk, idx);
	return 0;
}