[PATCH] media: saa7146: hexium_orion: Unwind failed attachment
From: Wentao Liang
Date: Tue Nov 03 2026 - 03:45:58 EST
hexium_probe() registers an I2C adapter and stores the allocated private
data in dev->ext_priv. If hexium_attach() then fails to initialize the VV
layer or register the video device, the core frees its own resources
without calling the extension's detach callback.
Release the I2C adapter and private data on both attachment failures, and
release the VV layer when video registration fails after successful VV
initialization. Clear the private pointer and return the actual video
registration error. This follows the cleanup already used for video
registration failure by the sibling Hexium Gemini driver.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: DeepSeek-V4.1-Flash and OpenAI Codex
Signed-off-by: Wentao Liang <vulab@xxxxxxxxxxx>
---
drivers/media/pci/saa7146/hexium_orion.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/media/pci/saa7146/hexium_orion.c b/drivers/media/pci/saa7146/hexium_orion.c
index 8ef2a4e8235d..95b3efee33ac 100644
--- a/drivers/media/pci/saa7146/hexium_orion.c
+++ b/drivers/media/pci/saa7146/hexium_orion.c
@@ -363,15 +363,16 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
ret = saa7146_vv_init(dev, &vv_data);
if (ret) {
pr_err("Error in saa7146_vv_init()\n");
- return ret;
+ goto err_i2c;
}
vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
- if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_VIDEO)) {
+ ret = saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_VIDEO);
+ if (ret) {
pr_err("cannot register capture v4l2 device. skipping.\n");
- return -1;
+ goto err_vv;
}
pr_err("found 'hexium orion' frame grabber-%d\n", hexium_num);
@@ -383,6 +384,14 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
hexium_set_input(hexium, 0);
return 0;
+
+err_vv:
+ saa7146_vv_release(dev);
+err_i2c:
+ i2c_del_adapter(&hexium->i2c_adapter);
+ kfree(hexium);
+ dev->ext_priv = NULL;
+ return ret;
}
static int hexium_detach(struct saa7146_dev *dev)
--
2.34.1