11
11
#include <linux/usb/hcd.h>
12
12
#include "usb.h"
13
13
14
- struct quirk_entry {
15
- u16 vid ;
16
- u16 pid ;
17
- u32 flags ;
18
- };
19
-
20
- static DEFINE_MUTEX (quirk_mutex );
21
-
22
- static struct quirk_entry * quirk_list ;
23
- static unsigned int quirk_count ;
24
-
25
- static char quirks_param [128 ];
26
-
27
- static int quirks_param_set (const char * val , const struct kernel_param * kp )
28
- {
29
- char * p , * field ;
30
- u16 vid , pid ;
31
- u32 flags ;
32
- size_t i ;
33
-
34
- mutex_lock (& quirk_mutex );
35
-
36
- if (!val || !* val ) {
37
- quirk_count = 0 ;
38
- kfree (quirk_list );
39
- quirk_list = NULL ;
40
- goto unlock ;
41
- }
42
-
43
- for (quirk_count = 1 , i = 0 ; val [i ]; i ++ )
44
- if (val [i ] == ',' )
45
- quirk_count ++ ;
46
-
47
- if (quirk_list ) {
48
- kfree (quirk_list );
49
- quirk_list = NULL ;
50
- }
51
-
52
- quirk_list = kcalloc (quirk_count , sizeof (struct quirk_entry ),
53
- GFP_KERNEL );
54
- if (!quirk_list ) {
55
- mutex_unlock (& quirk_mutex );
56
- return - ENOMEM ;
57
- }
58
-
59
- for (i = 0 , p = (char * )val ; p && * p ;) {
60
- /* Each entry consists of VID:PID:flags */
61
- field = strsep (& p , ":" );
62
- if (!field )
63
- break ;
64
-
65
- if (kstrtou16 (field , 16 , & vid ))
66
- break ;
67
-
68
- field = strsep (& p , ":" );
69
- if (!field )
70
- break ;
71
-
72
- if (kstrtou16 (field , 16 , & pid ))
73
- break ;
74
-
75
- field = strsep (& p , "," );
76
- if (!field || !* field )
77
- break ;
78
-
79
- /* Collect the flags */
80
- for (flags = 0 ; * field ; field ++ ) {
81
- switch (* field ) {
82
- case 'a' :
83
- flags |= USB_QUIRK_STRING_FETCH_255 ;
84
- break ;
85
- case 'b' :
86
- flags |= USB_QUIRK_RESET_RESUME ;
87
- break ;
88
- case 'c' :
89
- flags |= USB_QUIRK_NO_SET_INTF ;
90
- break ;
91
- case 'd' :
92
- flags |= USB_QUIRK_CONFIG_INTF_STRINGS ;
93
- break ;
94
- case 'e' :
95
- flags |= USB_QUIRK_RESET ;
96
- break ;
97
- case 'f' :
98
- flags |= USB_QUIRK_HONOR_BNUMINTERFACES ;
99
- break ;
100
- case 'g' :
101
- flags |= USB_QUIRK_DELAY_INIT ;
102
- break ;
103
- case 'h' :
104
- flags |= USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL ;
105
- break ;
106
- case 'i' :
107
- flags |= USB_QUIRK_DEVICE_QUALIFIER ;
108
- break ;
109
- case 'j' :
110
- flags |= USB_QUIRK_IGNORE_REMOTE_WAKEUP ;
111
- break ;
112
- case 'k' :
113
- flags |= USB_QUIRK_NO_LPM ;
114
- break ;
115
- case 'l' :
116
- flags |= USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL ;
117
- break ;
118
- case 'm' :
119
- flags |= USB_QUIRK_DISCONNECT_SUSPEND ;
120
- break ;
121
- /* Ignore unrecognized flag characters */
122
- }
123
- }
124
-
125
- quirk_list [i ++ ] = (struct quirk_entry )
126
- { .vid = vid , .pid = pid , .flags = flags };
127
- }
128
-
129
- if (i < quirk_count )
130
- quirk_count = i ;
131
-
132
- unlock :
133
- mutex_unlock (& quirk_mutex );
134
-
135
- return param_set_copystring (val , kp );
136
- }
137
-
138
- static const struct kernel_param_ops quirks_param_ops = {
139
- .set = quirks_param_set ,
140
- .get = param_get_string ,
141
- };
142
-
143
- static struct kparam_string quirks_param_string = {
144
- .maxlen = sizeof (quirks_param ),
145
- .string = quirks_param ,
146
- };
147
-
148
- module_param_cb (quirks , & quirks_param_ops , & quirks_param_string , 0644 );
149
- MODULE_PARM_DESC (quirks , "Add/modify USB quirks by specifying quirks=vendorID:productID:quirks" );
150
-
151
14
/* Lists of quirky USB devices, split in device quirks and interface quirks.
152
15
* Device quirks are applied at the very beginning of the enumeration process,
153
16
* right after reading the device descriptor. They can thus only match on device
@@ -457,8 +320,8 @@ static int usb_amd_resume_quirk(struct usb_device *udev)
457
320
return 0 ;
458
321
}
459
322
460
- static u32 usb_detect_static_quirks (struct usb_device * udev ,
461
- const struct usb_device_id * id )
323
+ static u32 __usb_detect_quirks (struct usb_device * udev ,
324
+ const struct usb_device_id * id )
462
325
{
463
326
u32 quirks = 0 ;
464
327
@@ -476,43 +339,21 @@ static u32 usb_detect_static_quirks(struct usb_device *udev,
476
339
return quirks ;
477
340
}
478
341
479
- static u32 usb_detect_dynamic_quirks (struct usb_device * udev )
480
- {
481
- u16 vid = le16_to_cpu (udev -> descriptor .idVendor );
482
- u16 pid = le16_to_cpu (udev -> descriptor .idProduct );
483
- int i , flags = 0 ;
484
-
485
- mutex_lock (& quirk_mutex );
486
-
487
- for (i = 0 ; i < quirk_count ; i ++ ) {
488
- if (vid == quirk_list [i ].vid && pid == quirk_list [i ].pid ) {
489
- flags = quirk_list [i ].flags ;
490
- break ;
491
- }
492
- }
493
-
494
- mutex_unlock (& quirk_mutex );
495
-
496
- return flags ;
497
- }
498
-
499
342
/*
500
343
* Detect any quirks the device has, and do any housekeeping for it if needed.
501
344
*/
502
345
void usb_detect_quirks (struct usb_device * udev )
503
346
{
504
- udev -> quirks = usb_detect_static_quirks (udev , usb_quirk_list );
347
+ udev -> quirks = __usb_detect_quirks (udev , usb_quirk_list );
505
348
506
349
/*
507
350
* Pixart-based mice would trigger remote wakeup issue on AMD
508
351
* Yangtze chipset, so set them as RESET_RESUME flag.
509
352
*/
510
353
if (usb_amd_resume_quirk (udev ))
511
- udev -> quirks |= usb_detect_static_quirks (udev ,
354
+ udev -> quirks |= __usb_detect_quirks (udev ,
512
355
usb_amd_resume_quirk_list );
513
356
514
- udev -> quirks ^= usb_detect_dynamic_quirks (udev );
515
-
516
357
if (udev -> quirks )
517
358
dev_dbg (& udev -> dev , "USB quirks for this device: %x\n" ,
518
359
udev -> quirks );
@@ -531,19 +372,11 @@ void usb_detect_interface_quirks(struct usb_device *udev)
531
372
{
532
373
u32 quirks ;
533
374
534
- quirks = usb_detect_static_quirks (udev , usb_interface_quirk_list );
375
+ quirks = __usb_detect_quirks (udev , usb_interface_quirk_list );
535
376
if (quirks == 0 )
536
377
return ;
537
378
538
379
dev_dbg (& udev -> dev , "USB interface quirks for this device: %x\n" ,
539
380
quirks );
540
381
udev -> quirks |= quirks ;
541
382
}
542
-
543
- void usb_release_quirk_list (void )
544
- {
545
- mutex_lock (& quirk_mutex );
546
- kfree (quirk_list );
547
- quirk_list = NULL ;
548
- mutex_unlock (& quirk_mutex );
549
- }
0 commit comments