Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: add usb_set_intfdata() documentation

USB drivers do not need to call usb_set_intfdata(intf, NULL) in their
usb_driver::disconnect callback because the core already does it in [1].

However, this fact is widely unknown, c.f.:

$ git grep "usb_set_intfdata(.*NULL)" | wc -l
215

Especially, setting the interface to NULL before all action completed
can result in a NULL pointer dereference. Not calling
usb_set_intfdata() at all in disconnect() is the safest method.

Add documentation to usb_set_intfdata() to clarify this point.

Also remove the call in usb-skeletion's disconnect() not to confuse
the new comers.

[1] function usb_unbind_interface() from drivers/usb/core/driver.c
Link: https://elixir.bootlin.com/linux/v6.0/source/drivers/usb/core/driver.c#L497

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Link: https://lore.kernel.org/r/20221128102954.3615579-1-mailhol.vincent@wanadoo.fr
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Vincent Mailhol and committed by
Greg Kroah-Hartman
27ef1784 01792c60

+12 -1
-1
drivers/usb/usb-skeleton.c
··· 564 564 int minor = interface->minor; 565 565 566 566 dev = usb_get_intfdata(interface); 567 - usb_set_intfdata(interface, NULL); 568 567 569 568 /* give back our minor */ 570 569 usb_deregister_dev(interface, &skel_class);
+12
include/linux/usb.h
··· 265 265 return dev_get_drvdata(&intf->dev); 266 266 } 267 267 268 + /** 269 + * usb_set_intfdata() - associate driver-specific data with the interface 270 + * @intf: the usb interface 271 + * @data: pointer to the device priv structure or %NULL 272 + * 273 + * Drivers should use this function in their probe() to associate their 274 + * driver-specific data with the usb interface. 275 + * 276 + * When disconnecting, the core will take care of setting @intf back to %NULL, 277 + * so no actions are needed on the driver side. The interface should not be set 278 + * to %NULL before all actions completed (e.g. no outsanding URB remaining). 279 + */ 268 280 static inline void usb_set_intfdata(struct usb_interface *intf, void *data) 269 281 { 270 282 dev_set_drvdata(&intf->dev, data);