0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/moduleparam.h>
0010 #include <linux/usb.h>
0011 #include <linux/usb/quirks.h>
0012 #include <linux/usb/hcd.h>
0013 #include "usb.h"
0014
0015 struct quirk_entry {
0016 u16 vid;
0017 u16 pid;
0018 u32 flags;
0019 };
0020
0021 static DEFINE_MUTEX(quirk_mutex);
0022
0023 static struct quirk_entry *quirk_list;
0024 static unsigned int quirk_count;
0025
0026 static char quirks_param[128];
0027
0028 static int quirks_param_set(const char *value, const struct kernel_param *kp)
0029 {
0030 char *val, *p, *field;
0031 u16 vid, pid;
0032 u32 flags;
0033 size_t i;
0034 int err;
0035
0036 val = kstrdup(value, GFP_KERNEL);
0037 if (!val)
0038 return -ENOMEM;
0039
0040 err = param_set_copystring(val, kp);
0041 if (err) {
0042 kfree(val);
0043 return err;
0044 }
0045
0046 mutex_lock(&quirk_mutex);
0047
0048 if (!*val) {
0049 quirk_count = 0;
0050 kfree(quirk_list);
0051 quirk_list = NULL;
0052 goto unlock;
0053 }
0054
0055 for (quirk_count = 1, i = 0; val[i]; i++)
0056 if (val[i] == ',')
0057 quirk_count++;
0058
0059 if (quirk_list) {
0060 kfree(quirk_list);
0061 quirk_list = NULL;
0062 }
0063
0064 quirk_list = kcalloc(quirk_count, sizeof(struct quirk_entry),
0065 GFP_KERNEL);
0066 if (!quirk_list) {
0067 quirk_count = 0;
0068 mutex_unlock(&quirk_mutex);
0069 kfree(val);
0070 return -ENOMEM;
0071 }
0072
0073 for (i = 0, p = val; p && *p;) {
0074
0075 field = strsep(&p, ":");
0076 if (!field)
0077 break;
0078
0079 if (kstrtou16(field, 16, &vid))
0080 break;
0081
0082 field = strsep(&p, ":");
0083 if (!field)
0084 break;
0085
0086 if (kstrtou16(field, 16, &pid))
0087 break;
0088
0089 field = strsep(&p, ",");
0090 if (!field || !*field)
0091 break;
0092
0093
0094 for (flags = 0; *field; field++) {
0095 switch (*field) {
0096 case 'a':
0097 flags |= USB_QUIRK_STRING_FETCH_255;
0098 break;
0099 case 'b':
0100 flags |= USB_QUIRK_RESET_RESUME;
0101 break;
0102 case 'c':
0103 flags |= USB_QUIRK_NO_SET_INTF;
0104 break;
0105 case 'd':
0106 flags |= USB_QUIRK_CONFIG_INTF_STRINGS;
0107 break;
0108 case 'e':
0109 flags |= USB_QUIRK_RESET;
0110 break;
0111 case 'f':
0112 flags |= USB_QUIRK_HONOR_BNUMINTERFACES;
0113 break;
0114 case 'g':
0115 flags |= USB_QUIRK_DELAY_INIT;
0116 break;
0117 case 'h':
0118 flags |= USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL;
0119 break;
0120 case 'i':
0121 flags |= USB_QUIRK_DEVICE_QUALIFIER;
0122 break;
0123 case 'j':
0124 flags |= USB_QUIRK_IGNORE_REMOTE_WAKEUP;
0125 break;
0126 case 'k':
0127 flags |= USB_QUIRK_NO_LPM;
0128 break;
0129 case 'l':
0130 flags |= USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL;
0131 break;
0132 case 'm':
0133 flags |= USB_QUIRK_DISCONNECT_SUSPEND;
0134 break;
0135 case 'n':
0136 flags |= USB_QUIRK_DELAY_CTRL_MSG;
0137 break;
0138 case 'o':
0139 flags |= USB_QUIRK_HUB_SLOW_RESET;
0140 break;
0141
0142 }
0143 }
0144
0145 quirk_list[i++] = (struct quirk_entry)
0146 { .vid = vid, .pid = pid, .flags = flags };
0147 }
0148
0149 if (i < quirk_count)
0150 quirk_count = i;
0151
0152 unlock:
0153 mutex_unlock(&quirk_mutex);
0154 kfree(val);
0155
0156 return 0;
0157 }
0158
0159 static const struct kernel_param_ops quirks_param_ops = {
0160 .set = quirks_param_set,
0161 .get = param_get_string,
0162 };
0163
0164 static struct kparam_string quirks_param_string = {
0165 .maxlen = sizeof(quirks_param),
0166 .string = quirks_param,
0167 };
0168
0169 device_param_cb(quirks, &quirks_param_ops, &quirks_param_string, 0644);
0170 MODULE_PARM_DESC(quirks, "Add/modify USB quirks by specifying quirks=vendorID:productID:quirks");
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189 static const struct usb_device_id usb_quirk_list[] = {
0190
0191 { USB_DEVICE(0x0204, 0x6025), .driver_info = USB_QUIRK_RESET_RESUME },
0192
0193
0194 { USB_DEVICE(0x0218, 0x0201), .driver_info =
0195 USB_QUIRK_CONFIG_INTF_STRINGS },
0196
0197
0198 { USB_DEVICE(0x0218, 0x0401), .driver_info =
0199 USB_QUIRK_CONFIG_INTF_STRINGS },
0200
0201
0202 { USB_DEVICE(0x03f0, 0x0701), .driver_info =
0203 USB_QUIRK_STRING_FETCH_255 },
0204
0205
0206 { USB_DEVICE(0x03f0, 0x3f40), .driver_info = USB_QUIRK_DELAY_INIT },
0207
0208
0209 { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
0210
0211
0212 { USB_DEVICE(0x0424, 0x3503), .driver_info = USB_QUIRK_RESET_RESUME },
0213
0214
0215 { USB_DEVICE(0x045e, 0x00e1), .driver_info = USB_QUIRK_RESET_RESUME },
0216
0217
0218 { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME },
0219
0220
0221 { USB_DEVICE(0x045e, 0x07c6), .driver_info = USB_QUIRK_NO_LPM },
0222
0223
0224 { USB_DEVICE(0x046a, 0x0023), .driver_info = USB_QUIRK_RESET_RESUME },
0225
0226
0227 { USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME },
0228
0229
0230 { USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT },
0231 { USB_DEVICE(0x046d, 0x0841), .driver_info = USB_QUIRK_DELAY_INIT },
0232 { USB_DEVICE(0x046d, 0x0843), .driver_info = USB_QUIRK_DELAY_INIT },
0233 { USB_DEVICE(0x046d, 0x085b), .driver_info = USB_QUIRK_DELAY_INIT },
0234 { USB_DEVICE(0x046d, 0x085c), .driver_info = USB_QUIRK_DELAY_INIT },
0235
0236
0237 { USB_DEVICE(0x046d, 0x0847), .driver_info = USB_QUIRK_DELAY_INIT },
0238 { USB_DEVICE(0x046d, 0x0848), .driver_info = USB_QUIRK_DELAY_INIT },
0239
0240
0241 { USB_DEVICE(0x046d, 0x0853), .driver_info = USB_QUIRK_DELAY_INIT },
0242
0243
0244 { USB_DEVICE(0x046d, 0x086c), .driver_info = USB_QUIRK_NO_LPM },
0245
0246
0247 { USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME },
0248
0249
0250 { USB_DEVICE(0x046d, 0x08c2), .driver_info = USB_QUIRK_RESET_RESUME },
0251
0252
0253 { USB_DEVICE(0x046d, 0x08c3), .driver_info = USB_QUIRK_RESET_RESUME },
0254
0255
0256 { USB_DEVICE(0x046d, 0x08c5), .driver_info = USB_QUIRK_RESET_RESUME },
0257
0258
0259 { USB_DEVICE(0x046d, 0x08c6), .driver_info = USB_QUIRK_RESET_RESUME },
0260
0261
0262 { USB_DEVICE(0x046d, 0x08c7), .driver_info = USB_QUIRK_RESET_RESUME },
0263
0264
0265 { USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT },
0266
0267
0268 { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME },
0269
0270
0271 { USB_DEVICE(0x047f, 0xc008), .driver_info = USB_QUIRK_RESET_RESUME },
0272
0273
0274 { USB_DEVICE(0x047f, 0xc013), .driver_info = USB_QUIRK_RESET_RESUME },
0275
0276
0277 { USB_DEVICE(0x04b4, 0x0526), .driver_info =
0278 USB_QUIRK_CONFIG_INTF_STRINGS },
0279
0280
0281 { USB_DEVICE(0x04d8, 0x000c), .driver_info =
0282 USB_QUIRK_CONFIG_INTF_STRINGS },
0283
0284
0285 { USB_DEVICE(0x04e7, 0x0009), .driver_info = USB_QUIRK_RESET_RESUME },
0286
0287
0288 { USB_DEVICE(0x04e7, 0x0030), .driver_info = USB_QUIRK_RESET_RESUME },
0289
0290
0291 { USB_DEVICE(0x04e8, 0x6601), .driver_info =
0292 USB_QUIRK_CONFIG_INTF_STRINGS },
0293
0294
0295 { USB_DEVICE(0x04f3, 0x0089), .driver_info =
0296 USB_QUIRK_DEVICE_QUALIFIER },
0297
0298 { USB_DEVICE(0x04f3, 0x009b), .driver_info =
0299 USB_QUIRK_DEVICE_QUALIFIER },
0300
0301 { USB_DEVICE(0x04f3, 0x010c), .driver_info =
0302 USB_QUIRK_DEVICE_QUALIFIER },
0303
0304 { USB_DEVICE(0x04f3, 0x0125), .driver_info =
0305 USB_QUIRK_DEVICE_QUALIFIER },
0306
0307 { USB_DEVICE(0x04f3, 0x016f), .driver_info =
0308 USB_QUIRK_DEVICE_QUALIFIER },
0309
0310 { USB_DEVICE(0x04f3, 0x0381), .driver_info =
0311 USB_QUIRK_NO_LPM },
0312
0313 { USB_DEVICE(0x04f3, 0x21b8), .driver_info =
0314 USB_QUIRK_DEVICE_QUALIFIER },
0315
0316
0317 { USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME },
0318
0319
0320 { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME },
0321
0322
0323 { USB_DEVICE(0x058f, 0x9254), .driver_info = USB_QUIRK_RESET_RESUME },
0324
0325
0326 { USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME },
0327
0328
0329 { USB_DEVICE(0x05e3, 0x0612), .driver_info = USB_QUIRK_NO_LPM },
0330
0331
0332 { USB_DEVICE(0x05cc, 0x2267), .driver_info = USB_QUIRK_RESET_RESUME },
0333
0334
0335 { USB_DEVICE(0x05e3, 0x0616), .driver_info = USB_QUIRK_NO_LPM },
0336
0337
0338 { USB_DEVICE(0x0638, 0x0a13), .driver_info =
0339 USB_QUIRK_STRING_FETCH_255 },
0340
0341
0342 { USB_DEVICE(0x06a3, 0x0006), .driver_info =
0343 USB_QUIRK_CONFIG_INTF_STRINGS },
0344
0345
0346 { USB_DEVICE(0x06bd, 0x0001), .driver_info = USB_QUIRK_RESET_RESUME },
0347
0348
0349 { USB_DEVICE(0x06f8, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME },
0350
0351
0352 { USB_DEVICE(0x06f8, 0x3005), .driver_info = USB_QUIRK_RESET_RESUME },
0353
0354
0355 { USB_DEVICE(0x06f8, 0xb000), .driver_info =
0356 USB_QUIRK_ENDPOINT_IGNORE },
0357
0358
0359 { USB_DEVICE(0x0763, 0x0192), .driver_info = USB_QUIRK_RESET_RESUME },
0360
0361
0362 { USB_DEVICE(0x0781, 0x5583), .driver_info = USB_QUIRK_NO_LPM },
0363 { USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM },
0364
0365
0366 { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
0367
0368
0369 { USB_DEVICE(0x0904, 0x6101), .driver_info =
0370 USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
0371 { USB_DEVICE(0x0904, 0x6102), .driver_info =
0372 USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
0373 { USB_DEVICE(0x0904, 0x6103), .driver_info =
0374 USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
0375
0376
0377 { USB_DEVICE(0x0926, 0x0202), .driver_info =
0378 USB_QUIRK_ENDPOINT_IGNORE },
0379
0380
0381 { USB_DEVICE(0x0926, 0x0208), .driver_info =
0382 USB_QUIRK_ENDPOINT_IGNORE },
0383
0384
0385 { USB_DEVICE(0x0926, 0x3333), .driver_info =
0386 USB_QUIRK_CONFIG_INTF_STRINGS },
0387
0388
0389 { USB_DEVICE(0x0951, 0x1666), .driver_info = USB_QUIRK_NO_LPM },
0390
0391
0392 { USB_DEVICE(0x0971, 0x2000), .driver_info = USB_QUIRK_NO_SET_INTF },
0393
0394
0395 { USB_DEVICE(0x09a1, 0x0028), .driver_info = USB_QUIRK_DELAY_CTRL_MSG },
0396
0397
0398 { USB_DEVICE(0x0a5c, 0x2021), .driver_info = USB_QUIRK_RESET_RESUME },
0399
0400
0401 { USB_DEVICE(0x0a92, 0x0091), .driver_info = USB_QUIRK_RESET_RESUME },
0402
0403
0404 { USB_DEVICE(0x0b05, 0x17e0), .driver_info =
0405 USB_QUIRK_IGNORE_REMOTE_WAKEUP },
0406
0407
0408 { USB_DEVICE(0x0bda, 0x0151), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS },
0409
0410
0411 { USB_DEVICE(0x0bda, 0x0487), .driver_info = USB_QUIRK_NO_LPM },
0412
0413
0414 { USB_DEVICE(0x0bda, 0x8153), .driver_info = USB_QUIRK_NO_LPM },
0415
0416
0417 { USB_DEVICE(0x0c45, 0x7056), .driver_info =
0418 USB_QUIRK_IGNORE_REMOTE_WAKEUP },
0419
0420
0421 { USB_DEVICE(0x10d6, 0x2200), .driver_info =
0422 USB_QUIRK_STRING_FETCH_255 },
0423
0424
0425 { USB_DEVICE(0x1235, 0x0061), .driver_info = USB_QUIRK_RESET_RESUME },
0426
0427
0428 { USB_DEVICE(0x12d1, 0x15bb), .driver_info =
0429 USB_QUIRK_DISCONNECT_SUSPEND },
0430 { USB_DEVICE(0x12d1, 0x15c3), .driver_info =
0431 USB_QUIRK_DISCONNECT_SUSPEND },
0432
0433
0434 { USB_DEVICE(0x1516, 0x8628), .driver_info = USB_QUIRK_RESET_RESUME },
0435
0436
0437 { USB_DEVICE(0x1532, 0x0116), .driver_info =
0438 USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
0439
0440
0441 { USB_DEVICE(0x17ef, 0x720c), .driver_info = USB_QUIRK_NO_LPM },
0442
0443
0444 { USB_DEVICE(0x17ef, 0x721e), .driver_info = USB_QUIRK_NO_LPM },
0445
0446
0447 { USB_DEVICE(0x17ef, 0xa012), .driver_info =
0448 USB_QUIRK_DISCONNECT_SUSPEND },
0449
0450
0451 { USB_DEVICE(0x17ef, 0xa387), .driver_info = USB_QUIRK_NO_LPM },
0452
0453
0454 { USB_DEVICE(0x1908, 0x1315), .driver_info =
0455 USB_QUIRK_HONOR_BNUMINTERFACES },
0456
0457
0458 { USB_DEVICE(0x1a0a, 0x0200), .driver_info =
0459 USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
0460
0461
0462 { USB_DEVICE(0x1a40, 0x0101), .driver_info = USB_QUIRK_HUB_SLOW_RESET },
0463
0464
0465 { USB_DEVICE(0x1b1c, 0x1b13), .driver_info = USB_QUIRK_DELAY_INIT |
0466 USB_QUIRK_DELAY_CTRL_MSG },
0467
0468
0469 { USB_DEVICE(0x1b1c, 0x1b15), .driver_info = USB_QUIRK_DELAY_INIT |
0470 USB_QUIRK_DELAY_CTRL_MSG },
0471
0472
0473 { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT |
0474 USB_QUIRK_DELAY_CTRL_MSG },
0475
0476
0477 { USB_DEVICE(0x1b1c, 0x1b33), .driver_info = USB_QUIRK_DELAY_INIT },
0478
0479
0480 { USB_DEVICE(0x1b1c, 0x1b36), .driver_info = USB_QUIRK_DELAY_INIT },
0481
0482
0483 { USB_DEVICE(0x1b1c, 0x1b38), .driver_info = USB_QUIRK_DELAY_INIT |
0484 USB_QUIRK_DELAY_CTRL_MSG },
0485
0486
0487 { USB_DEVICE(0x1c75, 0x0204), .driver_info =
0488 USB_QUIRK_CONFIG_INTF_STRINGS },
0489
0490
0491 { USB_DEVICE(0x1de1, 0xc102), .driver_info = USB_QUIRK_NO_LPM },
0492
0493
0494 { USB_DEVICE(0x1edb, 0xbd3b), .driver_info = USB_QUIRK_NO_LPM },
0495
0496
0497 { USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM },
0498
0499
0500 { USB_DEVICE(0x2040, 0x7200), .driver_info =
0501 USB_QUIRK_CONFIG_INTF_STRINGS },
0502
0503
0504 { USB_DEVICE(0x2386, 0x3114), .driver_info = USB_QUIRK_NO_LPM },
0505
0506 { USB_DEVICE(0x2386, 0x3119), .driver_info = USB_QUIRK_NO_LPM },
0507
0508 { USB_DEVICE(0x2386, 0x350e), .driver_info = USB_QUIRK_NO_LPM },
0509
0510
0511 { USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM },
0512
0513
0514 { USB_DEVICE(0x413c, 0xb062), .driver_info = USB_QUIRK_NO_LPM | USB_QUIRK_RESET_RESUME },
0515
0516
0517 { USB_DEVICE(0x4296, 0x7570), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS },
0518
0519
0520 { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
0521
0522 { }
0523 };
0524
0525 static const struct usb_device_id usb_interface_quirk_list[] = {
0526
0527 { USB_VENDOR_AND_INTERFACE_INFO(0x046d, USB_CLASS_VIDEO, 1, 0),
0528 .driver_info = USB_QUIRK_RESET_RESUME },
0529
0530 { }
0531 };
0532
0533 static const struct usb_device_id usb_amd_resume_quirk_list[] = {
0534
0535 { USB_DEVICE(0x17ef, 0x602e), .driver_info = USB_QUIRK_RESET_RESUME },
0536
0537
0538 { USB_DEVICE(0x093a, 0x2500), .driver_info = USB_QUIRK_RESET_RESUME },
0539 { USB_DEVICE(0x093a, 0x2510), .driver_info = USB_QUIRK_RESET_RESUME },
0540 { USB_DEVICE(0x093a, 0x2521), .driver_info = USB_QUIRK_RESET_RESUME },
0541 { USB_DEVICE(0x03f0, 0x2b4a), .driver_info = USB_QUIRK_RESET_RESUME },
0542
0543
0544 { USB_DEVICE(0x046d, 0xc05a), .driver_info = USB_QUIRK_RESET_RESUME },
0545
0546 { }
0547 };
0548
0549
0550
0551
0552
0553
0554
0555 static const struct usb_device_id usb_endpoint_ignore[] = {
0556 { USB_DEVICE_INTERFACE_NUMBER(0x06f8, 0xb000, 5), .driver_info = 0x01 },
0557 { USB_DEVICE_INTERFACE_NUMBER(0x06f8, 0xb000, 5), .driver_info = 0x81 },
0558 { USB_DEVICE_INTERFACE_NUMBER(0x0926, 0x0202, 1), .driver_info = 0x85 },
0559 { USB_DEVICE_INTERFACE_NUMBER(0x0926, 0x0208, 1), .driver_info = 0x85 },
0560 { }
0561 };
0562
0563 bool usb_endpoint_is_ignored(struct usb_device *udev,
0564 struct usb_host_interface *intf,
0565 struct usb_endpoint_descriptor *epd)
0566 {
0567 const struct usb_device_id *id;
0568 unsigned int address;
0569
0570 for (id = usb_endpoint_ignore; id->match_flags; ++id) {
0571 if (!usb_match_device(udev, id))
0572 continue;
0573
0574 if (!usb_match_one_id_intf(udev, intf, id))
0575 continue;
0576
0577 address = id->driver_info;
0578 if (address == epd->bEndpointAddress)
0579 return true;
0580 }
0581
0582 return false;
0583 }
0584
0585 static bool usb_match_any_interface(struct usb_device *udev,
0586 const struct usb_device_id *id)
0587 {
0588 unsigned int i;
0589
0590 for (i = 0; i < udev->descriptor.bNumConfigurations; ++i) {
0591 struct usb_host_config *cfg = &udev->config[i];
0592 unsigned int j;
0593
0594 for (j = 0; j < cfg->desc.bNumInterfaces; ++j) {
0595 struct usb_interface_cache *cache;
0596 struct usb_host_interface *intf;
0597
0598 cache = cfg->intf_cache[j];
0599 if (cache->num_altsetting == 0)
0600 continue;
0601
0602 intf = &cache->altsetting[0];
0603 if (usb_match_one_id_intf(udev, intf, id))
0604 return true;
0605 }
0606 }
0607
0608 return false;
0609 }
0610
0611 static int usb_amd_resume_quirk(struct usb_device *udev)
0612 {
0613 struct usb_hcd *hcd;
0614
0615 hcd = bus_to_hcd(udev->bus);
0616
0617 if (udev->level == 1 && hcd->amd_resume_bug == 1)
0618 return 1;
0619
0620 return 0;
0621 }
0622
0623 static u32 usb_detect_static_quirks(struct usb_device *udev,
0624 const struct usb_device_id *id)
0625 {
0626 u32 quirks = 0;
0627
0628 for (; id->match_flags; id++) {
0629 if (!usb_match_device(udev, id))
0630 continue;
0631
0632 if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_INFO) &&
0633 !usb_match_any_interface(udev, id))
0634 continue;
0635
0636 quirks |= (u32)(id->driver_info);
0637 }
0638
0639 return quirks;
0640 }
0641
0642 static u32 usb_detect_dynamic_quirks(struct usb_device *udev)
0643 {
0644 u16 vid = le16_to_cpu(udev->descriptor.idVendor);
0645 u16 pid = le16_to_cpu(udev->descriptor.idProduct);
0646 int i, flags = 0;
0647
0648 mutex_lock(&quirk_mutex);
0649
0650 for (i = 0; i < quirk_count; i++) {
0651 if (vid == quirk_list[i].vid && pid == quirk_list[i].pid) {
0652 flags = quirk_list[i].flags;
0653 break;
0654 }
0655 }
0656
0657 mutex_unlock(&quirk_mutex);
0658
0659 return flags;
0660 }
0661
0662
0663
0664
0665 void usb_detect_quirks(struct usb_device *udev)
0666 {
0667 udev->quirks = usb_detect_static_quirks(udev, usb_quirk_list);
0668
0669
0670
0671
0672
0673 if (usb_amd_resume_quirk(udev))
0674 udev->quirks |= usb_detect_static_quirks(udev,
0675 usb_amd_resume_quirk_list);
0676
0677 udev->quirks ^= usb_detect_dynamic_quirks(udev);
0678
0679 if (udev->quirks)
0680 dev_dbg(&udev->dev, "USB quirks for this device: %x\n",
0681 udev->quirks);
0682
0683 #ifdef CONFIG_USB_DEFAULT_PERSIST
0684 if (!(udev->quirks & USB_QUIRK_RESET))
0685 udev->persist_enabled = 1;
0686 #else
0687
0688 if (udev->descriptor.bDeviceClass == USB_CLASS_HUB)
0689 udev->persist_enabled = 1;
0690 #endif
0691 }
0692
0693 void usb_detect_interface_quirks(struct usb_device *udev)
0694 {
0695 u32 quirks;
0696
0697 quirks = usb_detect_static_quirks(udev, usb_interface_quirk_list);
0698 if (quirks == 0)
0699 return;
0700
0701 dev_dbg(&udev->dev, "USB interface quirks for this device: %x\n",
0702 quirks);
0703 udev->quirks |= quirks;
0704 }
0705
0706 void usb_release_quirk_list(void)
0707 {
0708 mutex_lock(&quirk_mutex);
0709 kfree(quirk_list);
0710 quirk_list = NULL;
0711 mutex_unlock(&quirk_mutex);
0712 }