@@ -124,7 +124,7 @@ struct steam_device {
124
124
struct list_head list ;
125
125
spinlock_t lock ;
126
126
struct hid_device * hdev , * client_hdev ;
127
- struct mutex mutex ;
127
+ struct mutex report_mutex ;
128
128
bool client_opened ;
129
129
struct input_dev __rcu * input ;
130
130
unsigned long quirks ;
@@ -267,21 +267,26 @@ static int steam_get_serial(struct steam_device *steam)
267
267
* Send: 0xae 0x15 0x01
268
268
* Recv: 0xae 0x15 0x01 serialnumber (10 chars)
269
269
*/
270
- int ret ;
270
+ int ret = 0 ;
271
271
u8 cmd [] = {STEAM_CMD_GET_SERIAL , 0x15 , 0x01 };
272
272
u8 reply [3 + STEAM_SERIAL_LEN + 1 ];
273
273
274
+ mutex_lock (& steam -> report_mutex );
274
275
ret = steam_send_report (steam , cmd , sizeof (cmd ));
275
276
if (ret < 0 )
276
- return ret ;
277
+ goto out ;
277
278
ret = steam_recv_report (steam , reply , sizeof (reply ));
278
279
if (ret < 0 )
279
- return ret ;
280
- if (reply [0 ] != 0xae || reply [1 ] != 0x15 || reply [2 ] != 0x01 )
281
- return - EIO ;
280
+ goto out ;
281
+ if (reply [0 ] != 0xae || reply [1 ] != 0x15 || reply [2 ] != 0x01 ) {
282
+ ret = - EIO ;
283
+ goto out ;
284
+ }
282
285
reply [3 + STEAM_SERIAL_LEN ] = 0 ;
283
286
strscpy (steam -> serial_no , reply + 3 , sizeof (steam -> serial_no ));
284
- return 0 ;
287
+ out :
288
+ mutex_unlock (& steam -> report_mutex );
289
+ return ret ;
285
290
}
286
291
287
292
/*
@@ -291,13 +296,18 @@ static int steam_get_serial(struct steam_device *steam)
291
296
*/
292
297
static inline int steam_request_conn_status (struct steam_device * steam )
293
298
{
294
- return steam_send_report_byte (steam , STEAM_CMD_REQUEST_COMM_STATUS );
299
+ int ret ;
300
+ mutex_lock (& steam -> report_mutex );
301
+ ret = steam_send_report_byte (steam , STEAM_CMD_REQUEST_COMM_STATUS );
302
+ mutex_unlock (& steam -> report_mutex );
303
+ return ret ;
295
304
}
296
305
297
306
static inline int steam_haptic_rumble (struct steam_device * steam ,
298
307
u16 intensity , u16 left_speed , u16 right_speed ,
299
308
u8 left_gain , u8 right_gain )
300
309
{
310
+ int ret ;
301
311
u8 report [11 ] = {STEAM_CMD_HAPTIC_RUMBLE , 9 };
302
312
303
313
report [3 ] = intensity & 0xFF ;
@@ -309,7 +319,10 @@ static inline int steam_haptic_rumble(struct steam_device *steam,
309
319
report [9 ] = left_gain ;
310
320
report [10 ] = right_gain ;
311
321
312
- return steam_send_report (steam , report , sizeof (report ));
322
+ mutex_lock (& steam -> report_mutex );
323
+ ret = steam_send_report (steam , report , sizeof (report ));
324
+ mutex_unlock (& steam -> report_mutex );
325
+ return ret ;
313
326
}
314
327
315
328
static void steam_haptic_rumble_cb (struct work_struct * work )
@@ -336,11 +349,14 @@ static int steam_play_effect(struct input_dev *dev, void *data,
336
349
static void steam_set_lizard_mode (struct steam_device * steam , bool enable )
337
350
{
338
351
if (enable ) {
352
+ mutex_lock (& steam -> report_mutex );
339
353
/* enable esc, enter, cursors */
340
354
steam_send_report_byte (steam , STEAM_CMD_DEFAULT_MAPPINGS );
341
355
/* enable mouse */
342
356
steam_send_report_byte (steam , STEAM_CMD_DEFAULT_MOUSE );
357
+ mutex_unlock (& steam -> report_mutex );
343
358
} else {
359
+ mutex_lock (& steam -> report_mutex );
344
360
/* disable esc, enter, cursor */
345
361
steam_send_report_byte (steam , STEAM_CMD_CLEAR_MAPPINGS );
346
362
@@ -352,34 +368,43 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable)
352
368
STEAM_REG_RPAD_CLICK_PRESSURE , 0xFFFF , /* disable clicky pad */
353
369
STEAM_REG_WATCHDOG_ENABLE , 0 , /* disable watchdog that tests if Steam is active */
354
370
0 );
371
+ mutex_unlock (& steam -> report_mutex );
355
372
} else {
356
373
steam_write_registers (steam ,
357
374
STEAM_REG_LPAD_MODE , 0x07 , /* disable mouse */
358
375
STEAM_REG_RPAD_MODE , 0x07 , /* disable mouse */
359
376
0 );
377
+ mutex_unlock (& steam -> report_mutex );
360
378
}
361
379
}
362
380
}
363
381
364
382
static int steam_input_open (struct input_dev * dev )
365
383
{
366
384
struct steam_device * steam = input_get_drvdata (dev );
385
+ unsigned long flags ;
386
+ bool set_lizard_mode ;
367
387
368
- mutex_lock (& steam -> mutex );
369
- if (!steam -> client_opened && lizard_mode )
388
+ spin_lock_irqsave (& steam -> lock , flags );
389
+ set_lizard_mode = !steam -> client_opened && lizard_mode ;
390
+ spin_unlock_irqrestore (& steam -> lock , flags );
391
+ if (set_lizard_mode )
370
392
steam_set_lizard_mode (steam , false);
371
- mutex_unlock ( & steam -> mutex );
393
+
372
394
return 0 ;
373
395
}
374
396
375
397
static void steam_input_close (struct input_dev * dev )
376
398
{
377
399
struct steam_device * steam = input_get_drvdata (dev );
400
+ unsigned long flags ;
401
+ bool set_lizard_mode ;
378
402
379
- mutex_lock (& steam -> mutex );
380
- if (!steam -> client_opened && lizard_mode )
403
+ spin_lock_irqsave (& steam -> lock , flags );
404
+ set_lizard_mode = !steam -> client_opened && lizard_mode ;
405
+ spin_unlock_irqrestore (& steam -> lock , flags );
406
+ if (set_lizard_mode )
381
407
steam_set_lizard_mode (steam , true);
382
- mutex_unlock (& steam -> mutex );
383
408
}
384
409
385
410
static enum power_supply_property steam_battery_props [] = {
@@ -624,6 +649,7 @@ static int steam_register(struct steam_device *steam)
624
649
{
625
650
int ret ;
626
651
bool client_opened ;
652
+ unsigned long flags ;
627
653
628
654
/*
629
655
* This function can be called several times in a row with the
@@ -636,11 +662,9 @@ static int steam_register(struct steam_device *steam)
636
662
* Unlikely, but getting the serial could fail, and it is not so
637
663
* important, so make up a serial number and go on.
638
664
*/
639
- mutex_lock (& steam -> mutex );
640
665
if (steam_get_serial (steam ) < 0 )
641
666
strscpy (steam -> serial_no , "XXXXXXXXXX" ,
642
667
sizeof (steam -> serial_no ));
643
- mutex_unlock (& steam -> mutex );
644
668
645
669
hid_info (steam -> hdev , "Steam Controller '%s' connected" ,
646
670
steam -> serial_no );
@@ -655,15 +679,13 @@ static int steam_register(struct steam_device *steam)
655
679
mutex_unlock (& steam_devices_lock );
656
680
}
657
681
658
- mutex_lock (& steam -> mutex );
682
+ spin_lock_irqsave (& steam -> lock , flags );
659
683
client_opened = steam -> client_opened ;
660
- if (!client_opened )
684
+ spin_unlock_irqrestore (& steam -> lock , flags );
685
+ if (!client_opened ) {
661
686
steam_set_lizard_mode (steam , lizard_mode );
662
- mutex_unlock (& steam -> mutex );
663
-
664
- if (!client_opened )
665
687
ret = steam_input_register (steam );
666
- else
688
+ } else
667
689
ret = 0 ;
668
690
669
691
return ret ;
@@ -746,10 +768,11 @@ static void steam_client_ll_stop(struct hid_device *hdev)
746
768
static int steam_client_ll_open (struct hid_device * hdev )
747
769
{
748
770
struct steam_device * steam = hdev -> driver_data ;
771
+ unsigned long flags ;
749
772
750
- mutex_lock (& steam -> mutex );
773
+ spin_lock_irqsave (& steam -> lock , flags );
751
774
steam -> client_opened = true;
752
- mutex_unlock (& steam -> mutex );
775
+ spin_unlock_irqrestore (& steam -> lock , flags );
753
776
754
777
steam_input_unregister (steam );
755
778
@@ -764,17 +787,14 @@ static void steam_client_ll_close(struct hid_device *hdev)
764
787
bool connected ;
765
788
766
789
spin_lock_irqsave (& steam -> lock , flags );
767
- connected = steam -> connected ;
790
+ steam -> client_opened = false;
791
+ connected = steam -> connected && !steam -> client_opened ;
768
792
spin_unlock_irqrestore (& steam -> lock , flags );
769
793
770
- mutex_lock (& steam -> mutex );
771
- steam -> client_opened = false;
772
- if (connected )
794
+ if (connected ) {
773
795
steam_set_lizard_mode (steam , lizard_mode );
774
- mutex_unlock (& steam -> mutex );
775
-
776
- if (connected )
777
796
steam_input_register (steam );
797
+ }
778
798
}
779
799
780
800
static int steam_client_ll_raw_request (struct hid_device * hdev ,
@@ -860,19 +880,12 @@ static int steam_probe(struct hid_device *hdev,
860
880
steam -> hdev = hdev ;
861
881
hid_set_drvdata (hdev , steam );
862
882
spin_lock_init (& steam -> lock );
863
- mutex_init (& steam -> mutex );
883
+ mutex_init (& steam -> report_mutex );
864
884
steam -> quirks = id -> driver_data ;
865
885
INIT_WORK (& steam -> work_connect , steam_work_connect_cb );
866
886
INIT_LIST_HEAD (& steam -> list );
867
887
INIT_WORK (& steam -> rumble_work , steam_haptic_rumble_cb );
868
888
869
- steam -> client_hdev = steam_create_client_hid (hdev );
870
- if (IS_ERR (steam -> client_hdev )) {
871
- ret = PTR_ERR (steam -> client_hdev );
872
- goto client_hdev_fail ;
873
- }
874
- steam -> client_hdev -> driver_data = steam ;
875
-
876
889
/*
877
890
* With the real steam controller interface, do not connect hidraw.
878
891
* Instead, create the client_hid and connect that.
@@ -881,10 +894,6 @@ static int steam_probe(struct hid_device *hdev,
881
894
if (ret )
882
895
goto hid_hw_start_fail ;
883
896
884
- ret = hid_add_device (steam -> client_hdev );
885
- if (ret )
886
- goto client_hdev_add_fail ;
887
-
888
897
ret = hid_hw_open (hdev );
889
898
if (ret ) {
890
899
hid_err (hdev ,
@@ -910,15 +919,26 @@ static int steam_probe(struct hid_device *hdev,
910
919
}
911
920
}
912
921
922
+ steam -> client_hdev = steam_create_client_hid (hdev );
923
+ if (IS_ERR (steam -> client_hdev )) {
924
+ ret = PTR_ERR (steam -> client_hdev );
925
+ goto client_hdev_fail ;
926
+ }
927
+ steam -> client_hdev -> driver_data = steam ;
928
+
929
+ ret = hid_add_device (steam -> client_hdev );
930
+ if (ret )
931
+ goto client_hdev_add_fail ;
932
+
913
933
return 0 ;
914
934
915
- input_register_fail :
916
- hid_hw_open_fail :
917
935
client_hdev_add_fail :
918
936
hid_hw_stop (hdev );
919
- hid_hw_start_fail :
920
- hid_destroy_device (steam -> client_hdev );
921
937
client_hdev_fail :
938
+ hid_destroy_device (steam -> client_hdev );
939
+ input_register_fail :
940
+ hid_hw_open_fail :
941
+ hid_hw_start_fail :
922
942
cancel_work_sync (& steam -> work_connect );
923
943
cancel_work_sync (& steam -> rumble_work );
924
944
steam_alloc_fail :
@@ -936,12 +956,10 @@ static void steam_remove(struct hid_device *hdev)
936
956
return ;
937
957
}
938
958
959
+ cancel_work_sync (& steam -> work_connect );
939
960
hid_destroy_device (steam -> client_hdev );
940
- mutex_lock (& steam -> mutex );
941
961
steam -> client_hdev = NULL ;
942
962
steam -> client_opened = false;
943
- mutex_unlock (& steam -> mutex );
944
- cancel_work_sync (& steam -> work_connect );
945
963
if (steam -> quirks & STEAM_QUIRK_WIRELESS ) {
946
964
hid_info (hdev , "Steam wireless receiver disconnected" );
947
965
}
@@ -1408,10 +1426,8 @@ static int steam_param_set_lizard_mode(const char *val,
1408
1426
1409
1427
mutex_lock (& steam_devices_lock );
1410
1428
list_for_each_entry (steam , & steam_devices , list ) {
1411
- mutex_lock (& steam -> mutex );
1412
1429
if (!steam -> client_opened )
1413
1430
steam_set_lizard_mode (steam , lizard_mode );
1414
- mutex_unlock (& steam -> mutex );
1415
1431
}
1416
1432
mutex_unlock (& steam_devices_lock );
1417
1433
return 0 ;
0 commit comments