Rock Band 3 Pro instruments only send navigation reports until they receive a magic SET_REPORT feature request. When such a report is seen, rb3_pro_instrument_raw_event() sends that request directly through rb3_pro_instrument_enable_full_report(), which does a GFP_KERNEL allocation and a synchronous hid_hw_raw_request(). The raw event handler is called from the URB completion handler in softirq context, and on USB hid_hw_raw_request() ends up in usb_control_msg(), which sleeps. Plugging in an RB3 Pro instrument therefore triggers: BUG: scheduling while atomic ... softirq: huh, entered softirq 0 HI ... preempt_count 101, exited with 0 This was reported on a Mustang guitar (12ba:2430). Move the request to process context by registering rb3_pro_instrument_enable_full_report() as the send_output_report callback of the existing state worker. The raw event handler now only schedules the work, keeping the 8 second rate limit. The state worker is already cancelled by sony_cleanup() on remove and on probe failure, and sony_schedule_work() is a no-op once cancellation has started, so no new teardown is needed. Fixes: 7245b0017d12 ("HID: sony: add support for more instruments") Cc: stable@vger.kernel.org Signed-off-by: Sanjay Govind --- Notes: Reproduced and tested with a Santroller device emulating a 12ba:2430 guitar: without the fix, 'BUG: scheduling while atomic' is logged every 8 seconds; with the fix no more warnings are logged. The fix and changelog were written with the help of an AI coding assistant (Claude Opus 5.5). drivers/hid/hid-sony.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 50f5ad6bbeb4..9ee175f9e58d 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -630,7 +630,7 @@ static int ghl_init_urb(struct sony_sc *sc, struct usb_device *usbdev, * Sending HID_REQ_SET_REPORT enables the full report. Without this * Rock Band 3 Pro instruments only report navigation events */ -static int rb3_pro_instrument_enable_full_report(struct sony_sc *sc) +static void rb3_pro_instrument_enable_full_report(struct sony_sc *sc) { struct hid_device *hdev = sc->hdev; static const u8 report[] = { 0x00, 0xE9, 0x00, 0x89, 0x1B, @@ -647,14 +647,14 @@ static int rb3_pro_instrument_enable_full_report(struct sony_sc *sc) buf = kmemdup(report, sizeof(report), GFP_KERNEL); if (!buf) - return -ENOMEM; + return; ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(report), HID_FEATURE_REPORT, HID_REQ_SET_REPORT); + if (ret < 0) + hid_dbg(hdev, "failed to enable full report: %d\n", ret); kfree(buf); - - return ret; } static int djh_turntable_mapping(struct hid_device *hdev, struct hid_input *hi, @@ -1098,10 +1098,10 @@ static int rb3_pro_instrument_raw_event(struct sony_sc *sc, u8 *rd, int size) if (size < 25 || rd[24] != 0x02) return 0; - /* Only attempt to enable full report every 8 seconds */ + /* Only attempt to enable full report every 8 seconds, from the worker */ if (time_after(jiffies, sc->rb3_pro_poke_jiffies)) { sc->rb3_pro_poke_jiffies = jiffies + secs_to_jiffies(8); - rb3_pro_instrument_enable_full_report(sc); + sony_schedule_work(sc); } return 0; @@ -2217,6 +2217,7 @@ static int sony_input_configured(struct hid_device *hdev, hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID; sony_init_raw_event_handler(sc, rb3_pro_instrument_raw_event); + sony_init_output_report(sc, rb3_pro_instrument_enable_full_report); } else if (sc->quirks & SIXAXIS_CONTROLLER_USB) { /* * The Sony Sixaxis does not handle HID Output Reports on the -- 2.56.0