]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ALSA: ctxfi: Check the error for index mapping
authorTakashi Iwai <tiwai@suse.de>
Sun, 29 Mar 2026 09:12:38 +0000 (11:12 +0200)
committerTakashi Iwai <tiwai@suse.de>
Sun, 29 Mar 2026 09:13:53 +0000 (11:13 +0200)
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: Takashi Iwai <tiwai@suse.de>
sound/pci/ctxfi/ctdaio.c

index 19faa81d54005df7a8f68b49e0e89f35f0d5542b..4dbb1dd7af32ff12ace66ad723443c60a4757480 100644 (file)
@@ -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;
 }