Skip to content

Commit

Permalink
HID: nintendo: reduce device removal subcommand errors
Browse files Browse the repository at this point in the history
This patch fixes meaningless error output from trying to send
subcommands immediately after controller removal. It now disables
subcommands as soon as possible on removal.

Signed-off-by: Daniel J. Ogorchock <djogorchock@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
  • Loading branch information
Daniel J. Ogorchock authored and Jiri Kosina committed Oct 27, 2021
1 parent c7d0d63 commit 012bd52
Showing 1 changed file with 22 additions and 2 deletions.
24 changes: 22 additions & 2 deletions drivers/hid/hid-nintendo.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ static const struct joycon_rumble_amp_data joycon_rumble_amplitudes[] = {
enum joycon_ctlr_state {
JOYCON_CTLR_STATE_INIT,
JOYCON_CTLR_STATE_READ,
JOYCON_CTLR_STATE_REMOVED,
};

struct joycon_stick_cal {
Expand Down Expand Up @@ -458,6 +459,14 @@ static int joycon_send_subcmd(struct joycon_ctlr *ctlr,
unsigned long flags;

spin_lock_irqsave(&ctlr->lock, flags);
/*
* If the controller has been removed, just return ENODEV so the LED
* subsystem doesn't print invalid errors on removal.
*/
if (ctlr->ctlr_state == JOYCON_CTLR_STATE_REMOVED) {
spin_unlock_irqrestore(&ctlr->lock, flags);
return -ENODEV;
}
memcpy(subcmd->rumble_data, ctlr->rumble_data[ctlr->rumble_queue_tail],
JC_RUMBLE_DATA_SIZE);
spin_unlock_irqrestore(&ctlr->lock, flags);
Expand Down Expand Up @@ -807,10 +816,13 @@ static void joycon_rumble_worker(struct work_struct *work)
mutex_lock(&ctlr->output_mutex);
ret = joycon_enable_rumble(ctlr);
mutex_unlock(&ctlr->output_mutex);
if (ret < 0)
hid_warn(ctlr->hdev, "Failed to set rumble; e=%d", ret);

/* -ENODEV means the controller was just unplugged */
spin_lock_irqsave(&ctlr->lock, flags);
if (ret < 0 && ret != -ENODEV &&
ctlr->ctlr_state != JOYCON_CTLR_STATE_REMOVED)
hid_warn(ctlr->hdev, "Failed to set rumble; e=%d", ret);

ctlr->rumble_msecs = jiffies_to_msecs(jiffies);
if (ctlr->rumble_queue_tail != ctlr->rumble_queue_head) {
if (++ctlr->rumble_queue_tail >= JC_RUMBLE_QUEUE_SIZE)
Expand Down Expand Up @@ -1529,9 +1541,17 @@ static int nintendo_hid_probe(struct hid_device *hdev,
static void nintendo_hid_remove(struct hid_device *hdev)
{
struct joycon_ctlr *ctlr = hid_get_drvdata(hdev);
unsigned long flags;

hid_dbg(hdev, "remove\n");

/* Prevent further attempts at sending subcommands. */
spin_lock_irqsave(&ctlr->lock, flags);
ctlr->ctlr_state = JOYCON_CTLR_STATE_REMOVED;
spin_unlock_irqrestore(&ctlr->lock, flags);

destroy_workqueue(ctlr->rumble_queue);

hid_hw_close(hdev);
hid_hw_stop(hdev);
}
Expand Down

0 comments on commit 012bd52

Please sign in to comment.