Skip to content

Commit 36dcfa4

Browse files
Hans de GoedeJiri Kosina
authored andcommitted
HID: logitech-dj: Fix probe failure when used with KVM
Since commit 6f20d32 ("HID: logitech-dj: Fix error handling in logi_dj_recv_switch_to_dj_mode()") logi_dj_recv_switch_to_dj_mode() will return an error when the hid_hw_raw_request() call to enable [dis]connect events fails. This can happen when used with a KVM like the Aten CS1784a and the PC does not have the KVM focus when probe() runs, which causes probe() to fail after which the receiver will simply not work. The logi_dj_recv_query_paired_devices() call done at the end of probe() already ignores any errors for the KVM without focus case. When focus is restored and an input report is received this will trigger logi_dj_recv_queue_unknown_work() which retries the query_paired_devices() call from a workqueue. To fix the probe() failure let it ignore logi_dj_recv_switch_to_dj_mode() errors too, track if a successful logi_dj_recv_switch_to_dj_mode() was done and retry if necessary from logi_dj_recv_queue_unknown_work(). Queurying paired devices while not in dj-mode is not useful and this will be redone after the unknown work has retried setting dj-mode, so skip queurying paired devices when not in dj-mode yet. The new bool to track successful setting of the dj-mode will also cause setting dj-mode to be retried from the unknown work, if setting dj-mode failed after a reset_resume. Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
1 parent ca389a5 commit 36dcfa4

1 file changed

Lines changed: 16 additions & 8 deletions

File tree

drivers/hid/hid-logitech-dj.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ struct dj_receiver_dev {
148148
struct kfifo notif_fifo;
149149
unsigned long last_query; /* in jiffies */
150150
bool ready;
151+
bool dj_mode;
151152
enum recvr_type type;
152153
unsigned int unnumbered_application;
153154
spinlock_t lock;
@@ -557,6 +558,8 @@ static const u8 hid_reportid_size_map[NUMBER_OF_HID_REPORTS] = {
557558
static const struct hid_ll_driver logi_dj_ll_driver;
558559

559560
static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev);
561+
static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
562+
unsigned int timeout);
560563
static void delayedwork_callback(struct work_struct *work);
561564

562565
static LIST_HEAD(dj_hdev_list);
@@ -841,6 +844,9 @@ static void delayedwork_callback(struct work_struct *work)
841844
logi_dj_recv_destroy_djhid_device(djrcv_dev, &workitem);
842845
break;
843846
case WORKITEM_TYPE_UNKNOWN:
847+
if (!djrcv_dev->dj_mode)
848+
logi_dj_recv_switch_to_dj_mode(djrcv_dev, 0);
849+
844850
logi_dj_recv_query_paired_devices(djrcv_dev);
845851
break;
846852
case WORKITEM_TYPE_EMPTY:
@@ -1234,6 +1240,9 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
12341240

12351241
djrcv_dev->last_query = jiffies;
12361242

1243+
if (!djrcv_dev->dj_mode)
1244+
return 0;
1245+
12371246
if (djrcv_dev->type != recvr_type_dj) {
12381247
retval = logi_dj_recv_query_hidpp_devices(djrcv_dev);
12391248
goto out;
@@ -1317,6 +1326,7 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
13171326
if (retval < 0)
13181327
hid_err(hdev, "%s error:%d\n", __func__, retval);
13191328

1329+
djrcv_dev->dj_mode = retval >= 0;
13201330
return retval;
13211331
}
13221332

@@ -1837,9 +1847,11 @@ static int logi_dj_probe(struct hid_device *hdev,
18371847
}
18381848

18391849
if (has_hidpp) {
1840-
retval = logi_dj_recv_switch_to_dj_mode(djrcv_dev, 0);
1841-
if (retval < 0)
1842-
goto switch_to_dj_mode_fail;
1850+
/*
1851+
* This can fail with a KVM. Ignore errors to let the probe
1852+
* succeed, logi_dj_recv_queue_unknown_work will retry later.
1853+
*/
1854+
logi_dj_recv_switch_to_dj_mode(djrcv_dev, 0);
18431855
}
18441856

18451857
/* This is enabling the polling urb on the IN endpoint */
@@ -1857,17 +1869,13 @@ static int logi_dj_probe(struct hid_device *hdev,
18571869
spin_lock_irqsave(&djrcv_dev->lock, flags);
18581870
djrcv_dev->ready = true;
18591871
spin_unlock_irqrestore(&djrcv_dev->lock, flags);
1860-
/*
1861-
* This can fail with a KVM. Ignore errors to let the probe
1862-
* succeed, logi_dj_recv_queue_unknown_work will retry later.
1863-
*/
1872+
/* This too can fail with a KVM, ignore errors. */
18641873
logi_dj_recv_query_paired_devices(djrcv_dev);
18651874
}
18661875

18671876
return 0;
18681877

18691878
llopen_failed:
1870-
switch_to_dj_mode_fail:
18711879
hid_hw_stop(hdev);
18721880

18731881
hid_hw_start_fail:

0 commit comments

Comments
 (0)