mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-02 21:26:44 +07:00
a116a05cb4
The following sequence of commands was triggering a kernel crash in cdev_get(): modprobe cx231xx rmmod cx231xx modprobe cx231xx v4l2grab -n 1 The problem was that cx231xx_usb_disconnect() was not doing anything because the test: if (!dev->udev) return; was reached (i.e, dev->udev was NULL). This is due to the fact that the 'dev' pointer placed as intfdata into the usb_interface structure had the wrong value, because cx231xx_probe() was doing the usb_set_intfdata() on the wrong usb_interface structure. For some reason, cx231xx_probe() was doing the following: static int cx231xx_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_interface *lif = NULL; [...] /* store the current interface */ lif = interface; [...] /* store the interface 0 back */ lif = udev->actconfig->interface[0]; [...] usb_set_intfdata(lif, dev); [...] retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); [...] } So, the usb_set_intfdata() was done on udev->actconfig->interface[0] and not on the 'interface' passed as argument to the ->probe() and ->disconnect() hooks. Later on, v4l2_device_register() was initializing the intfdata of the correct usb_interface structure as a pointer to the v4l2_device structure. Upon unregistration, the ->disconnect() hook was getting the intfdata of the usb_interface passed as argument... and casted it to a 'struct cx231xx *' while it was in fact a 'struct v4l2_device *'. The correct fix seems to just be to set the intfdata on the proper interface from the beginning. Now, loading/unloading/reloading the driver allows to use the device properly. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com> |
||
---|---|---|
.. | ||
common | ||
dvb | ||
radio | ||
rc | ||
video | ||
Kconfig | ||
Makefile | ||
media-device.c | ||
media-devnode.c | ||
media-entity.c |