usb_control_msg_send(9)
π usb_control_msg_send(9) β the Kernel API Manual page you've been waiting for
Okay bestie, this is usb_control_msg_send from the Kernel API Manual, and it is literally the function that builds a control "send" message, sends it off and waits for completion. No cap. Let's get into it π«Ά
β¨ SYNOPSIS β¨
int usb_control_msg_send (struct usb_device *dev , __u8 endpoint , __u8
request , __u8 requesttype , __u16 value , __u16 index , const void
*driver_data , __u16 size , int timeout , gfp_t memflags );
That's a whole lot of arguments and honestly? She ate. Let's meet them one by one π
π ARGUMENTS π
devβ pointer to the usb device to send the message to. This is your main character, the one getting the message πendpointβ endpoint to send the message torequestβ USB message request valuerequesttypeβ USB message request type valuevalueβ USB message valueindexβ USB message index valuedriver_dataβ pointer to the data to sendsizeβ length in bytes of the data to sendtimeoutβ time in msecs to wait for the message to complete before timing outmemflagsβ the flags for memory allocation for buffers
π¦ CONTEXT π¦
!in_interrupt ()
Read that again, bestie β not in interrupt context. That's the vibe check this function demands πΈ
π DESCRIPTION π
So what does she actually do? This function sends a control message to a specified endpoint that is not expected to fill in a response (i.e. a "send message") and waits for the message to complete, or timeout. That's it. That's the whole gig β¨
π¨ Do not use this function from within an interrupt context. Not me warning you twice. If you need an asynchronous message, or need to send a message from within interrupt context, use usb_submit_urb.
And the part everyone forgets: if a thread in your driver uses this call, make sure your disconnect method can wait for it to complete. Because β and this is the lowkey sad part π β since you don't have a handle on the URB used, you can't cancel the request. Not even a little bit. Periodt.
Okay but here's the iconic part π The data pointer can be made to a reference on the stack, or anywhere else, as it will not be modified at all. Unlike usb_control_msg, this one does not have the restriction where the data pointer must be to dynamically allocated memory (i.e. memory that can be successfully DMAed to a device). Stack pointer? Fine. Random pointer? Fine. She's flexible like that π
π₯ RETURN π₯
- If successful,
0is returned. Slay π - Otherwise, a negative error number. Rough, but honest π
π SEE ALSO π
Kernel file ./drivers/usb/core/message.c and this absolutely stacked friend group:
usb_control_msg(9)usb_control_msg_recv(9)usb_interrupt_msg(9)usb_bulk_msg(9)usb_bulk_msg_killable(9)usb_sg_init(9)usb_sg_wait(9)usb_sg_cancel(9)usb_get_descriptor(9)usb_get_string(9)usb_string(9)usb_cache_string(9)usb_get_status(9)usb_clear_halt(9)usb_disable_endpoint(9)usb_reset_endpoint(9)usb_disable_interface(9)usb_disable_device(9)usb_enable_endpoint(9)usb_enable_interface(9)usb_set_interface(9)usb_reset_configuration(9)usb_set_wireless_status(9)usb_driver_set_configuration(9)cdc_parse_cdc_header(9)
That's the whole page, bestie π§ go forth and send your control messages responsibly π
xoxo, dropping this from ./drivers/usb/core, October 2026 edition β stay iconic ππ
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms