[PATCH v3 5/5] rust: usb: let a driver keep its interface usable while unbinding
Mike Lothian <[email protected]>
| Newsgroups | org.kernel.vger.rust-for-linux,org.kernel.vger.linux-kernel,org.kernel.vger.linux-usb |
|---|---|
| Message-ID | <[email protected]> |
The USB core kills every outstanding URB and disables an interface's endpoints before it calls any driver callback. A driver with something left to say to the device on the way out therefore cannot say it: the transfer names an endpoint that no longer exists and is refused. Expose the core's soft-unbind flag as a driver constant. Setting it defers that teardown until the callbacks return, which makes cancelling outstanding transfers the driver's own responsibility. This matters to a driver that leaves the device in a state a user can see. A display bridge that simply stops sending pixels leaves the monitor lit on whatever it decoded last. Assisted-by: Claude:claude-opus-5 Signed-off-by: Mike Lothian <[email protected]> --- rust/kernel/usb.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/rust/kernel/usb.rs b/rust/kernel/usb.rs index b2a0fb104ddf..1d8f5bc8a545 100644 --- a/rust/kernel/usb.rs +++ b/rust/kernel/usb.rs @@ -107,6 +107,7 @@ unsafe fn register( (*udrv.get()).pre_reset = Some(Self::pre_reset_callback); (*udrv.get()).post_reset = Some(Self::post_reset_callback); (*udrv.get()).id_table = T::ID_TABLE.as_ptr(); + (*udrv.get()).set_soft_unbind(T::SOFT_UNBIND as core::ffi::c_uint); } // SAFETY: `udrv` is guaranteed to be a valid `DriverType`. @@ -474,6 +475,19 @@ pub trait Driver { /// The table of device ids supported by the driver. const ID_TABLE: IdTable<Self::IdInfo>; + /// Whether the USB core must leave this interface usable until the driver has let go of it. + /// + /// By default the core kills every outstanding URB and disables the interface's endpoints + /// *before* it calls any driver callback, so a driver that has something to say to the device + /// on the way out cannot say it: the transfer is refused with [`ENOENT`] because the endpoint + /// it names no longer exists. Setting this defers that teardown until after the callbacks + /// return, which makes cancelling outstanding transfers the driver's own responsibility. + /// + /// Only useful to a driver that leaves the device in a state a user can see -- a display that + /// otherwise goes on scanning out its last frame, an interface that must be told to power + /// down. + const SOFT_UNBIND: bool = false; + /// USB driver probe. /// /// Called when a new USB interface is bound to this driver.