forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-11 04dd17822334871b23ea2862f7798fb0e0007777
kernel/drivers/usb/gadget/configfs.c
....@@ -16,7 +16,7 @@
1616 #include <linux/usb/ch9.h>
1717
1818 #ifdef CONFIG_USB_CONFIGFS_F_ACC
19
-extern int acc_ctrlrequest(struct usb_composite_dev *cdev,
19
+extern int acc_ctrlrequest_composite(struct usb_composite_dev *cdev,
2020 const struct usb_ctrlrequest *ctrl);
2121 void acc_disconnect(void);
2222 #endif
....@@ -39,8 +39,6 @@
3939 int check_user_usb_string(const char *name,
4040 struct usb_gadget_strings *stringtab_dev)
4141 {
42
- unsigned primary_lang;
43
- unsigned sub_lang;
4442 u16 num;
4543 int ret;
4644
....@@ -48,17 +46,7 @@
4846 if (ret)
4947 return ret;
5048
51
- primary_lang = num & 0x3ff;
52
- sub_lang = num >> 10;
53
-
54
- /* simple sanity check for valid langid */
55
- switch (primary_lang) {
56
- case 0:
57
- case 0x62 ... 0xfe:
58
- case 0x100 ... 0x3ff:
59
- return -EINVAL;
60
- }
61
- if (!sub_lang)
49
+ if (!usb_validate_langid(num))
6250 return -EINVAL;
6351
6452 stringtab_dev->language = num;
....@@ -341,6 +329,47 @@
341329 return ret;
342330 }
343331
332
+static ssize_t gadget_dev_desc_max_speed_show(struct config_item *item,
333
+ char *page)
334
+{
335
+ enum usb_device_speed speed = to_gadget_info(item)->composite.max_speed;
336
+
337
+ return sprintf(page, "%s\n", usb_speed_string(speed));
338
+}
339
+
340
+static ssize_t gadget_dev_desc_max_speed_store(struct config_item *item,
341
+ const char *page, size_t len)
342
+{
343
+ struct gadget_info *gi = to_gadget_info(item);
344
+
345
+ mutex_lock(&gi->lock);
346
+
347
+ /* Prevent changing of max_speed after the driver is binded */
348
+ if (gi->composite.gadget_driver.udc_name)
349
+ goto err;
350
+
351
+ if (strncmp(page, "super-speed-plus", 16) == 0)
352
+ gi->composite.max_speed = USB_SPEED_SUPER_PLUS;
353
+ else if (strncmp(page, "super-speed", 11) == 0)
354
+ gi->composite.max_speed = USB_SPEED_SUPER;
355
+ else if (strncmp(page, "high-speed", 10) == 0)
356
+ gi->composite.max_speed = USB_SPEED_HIGH;
357
+ else if (strncmp(page, "full-speed", 10) == 0)
358
+ gi->composite.max_speed = USB_SPEED_FULL;
359
+ else if (strncmp(page, "low-speed", 9) == 0)
360
+ gi->composite.max_speed = USB_SPEED_LOW;
361
+ else
362
+ goto err;
363
+
364
+ gi->composite.gadget_driver.max_speed = gi->composite.max_speed;
365
+
366
+ mutex_unlock(&gi->lock);
367
+ return len;
368
+err:
369
+ mutex_unlock(&gi->lock);
370
+ return -EINVAL;
371
+}
372
+
344373 CONFIGFS_ATTR(gadget_dev_desc_, bDeviceClass);
345374 CONFIGFS_ATTR(gadget_dev_desc_, bDeviceSubClass);
346375 CONFIGFS_ATTR(gadget_dev_desc_, bDeviceProtocol);
....@@ -350,6 +379,7 @@
350379 CONFIGFS_ATTR(gadget_dev_desc_, bcdDevice);
351380 CONFIGFS_ATTR(gadget_dev_desc_, bcdUSB);
352381 CONFIGFS_ATTR(gadget_dev_desc_, UDC);
382
+CONFIGFS_ATTR(gadget_dev_desc_, max_speed);
353383
354384 static struct configfs_attribute *gadget_root_attrs[] = {
355385 &gadget_dev_desc_attr_bDeviceClass,
....@@ -361,6 +391,7 @@
361391 &gadget_dev_desc_attr_bcdDevice,
362392 &gadget_dev_desc_attr_bcdUSB,
363393 &gadget_dev_desc_attr_UDC,
394
+ &gadget_dev_desc_attr_max_speed,
364395 NULL,
365396 };
366397
....@@ -430,6 +461,12 @@
430461 * from another gadget or a random directory.
431462 * Also a function instance can only be linked once.
432463 */
464
+
465
+ if (gi->composite.gadget_driver.udc_name) {
466
+ ret = -EINVAL;
467
+ goto out;
468
+ }
469
+
433470 list_for_each_entry(a_fi, &gi->available_func, cfs_list) {
434471 if (a_fi == fi)
435472 break;
....@@ -1408,6 +1445,10 @@
14081445 goto err_purge_funcs;
14091446 }
14101447 }
1448
+ ret = usb_gadget_check_config(cdev->gadget);
1449
+ if (ret)
1450
+ goto err_purge_funcs;
1451
+
14111452 usb_ep_autoconfig_reset(cdev->gadget);
14121453 }
14131454 if (cdev->use_os_string) {
....@@ -1498,11 +1539,67 @@
14981539 usb_ep_autoconfig_reset(cdev->gadget);
14991540 spin_lock_irqsave(&gi->spinlock, flags);
15001541 cdev->gadget = NULL;
1542
+ cdev->deactivations = 0;
1543
+ gadget->deactivated = false;
15011544 set_gadget_data(gadget, NULL);
15021545 spin_unlock_irqrestore(&gi->spinlock, flags);
15031546 }
15041547
1505
-#ifndef CONFIG_USB_CONFIGFS_UEVENT
1548
+#ifdef CONFIG_USB_CONFIGFS_UEVENT
1549
+static int android_setup(struct usb_gadget *gadget,
1550
+ const struct usb_ctrlrequest *c)
1551
+{
1552
+ struct usb_composite_dev *cdev;
1553
+ unsigned long flags;
1554
+ struct gadget_info *gi;
1555
+ int value = -EOPNOTSUPP;
1556
+ struct usb_function_instance *fi;
1557
+
1558
+ cdev = get_gadget_data(gadget);
1559
+ if (!cdev)
1560
+ return 0;
1561
+
1562
+ gi = container_of(cdev, struct gadget_info, cdev);
1563
+ spin_lock_irqsave(&gi->spinlock, flags);
1564
+ cdev = get_gadget_data(gadget);
1565
+ if (!cdev || gi->unbind) {
1566
+ spin_unlock_irqrestore(&gi->spinlock, flags);
1567
+ return 0;
1568
+ }
1569
+
1570
+ if (c->bRequest == USB_REQ_GET_DESCRIPTOR &&
1571
+ (c->wValue >> 8) == USB_DT_CONFIG && !gi->connected) {
1572
+ gi->connected = 1;
1573
+ schedule_work(&gi->work);
1574
+ }
1575
+
1576
+ list_for_each_entry(fi, &gi->available_func, cfs_list) {
1577
+ if (fi != NULL && fi->f != NULL && fi->f->setup != NULL) {
1578
+ value = fi->f->setup(fi->f, c);
1579
+ if (value >= 0)
1580
+ break;
1581
+ }
1582
+ }
1583
+
1584
+#ifdef CONFIG_USB_CONFIGFS_F_ACC
1585
+ if (value < 0)
1586
+ value = acc_ctrlrequest_composite(cdev, c);
1587
+#endif
1588
+
1589
+ if (value < 0)
1590
+ value = composite_setup(gadget, c);
1591
+
1592
+ if (c->bRequest == USB_REQ_SET_CONFIGURATION &&
1593
+ cdev->config) {
1594
+ schedule_work(&gi->work);
1595
+ }
1596
+ spin_unlock_irqrestore(&gi->spinlock, flags);
1597
+
1598
+ return value;
1599
+}
1600
+
1601
+#else // CONFIG_USB_CONFIGFS_UEVENT
1602
+
15061603 static int configfs_composite_setup(struct usb_gadget *gadget,
15071604 const struct usb_ctrlrequest *ctrl)
15081605 {
....@@ -1528,7 +1625,43 @@
15281625 return ret;
15291626 }
15301627
1628
+#endif // CONFIG_USB_CONFIGFS_UEVENT
1629
+
15311630 static void configfs_composite_disconnect(struct usb_gadget *gadget)
1631
+{
1632
+ struct usb_composite_dev *cdev;
1633
+ struct gadget_info *gi;
1634
+ unsigned long flags;
1635
+
1636
+ cdev = get_gadget_data(gadget);
1637
+ if (!cdev)
1638
+ return;
1639
+
1640
+#ifdef CONFIG_USB_CONFIGFS_F_ACC
1641
+ /*
1642
+ * accessory HID support can be active while the
1643
+ * accessory function is not actually enabled,
1644
+ * so we need to inform it when we are disconnected.
1645
+ */
1646
+ acc_disconnect();
1647
+#endif
1648
+ gi = container_of(cdev, struct gadget_info, cdev);
1649
+ spin_lock_irqsave(&gi->spinlock, flags);
1650
+ cdev = get_gadget_data(gadget);
1651
+ if (!cdev || gi->unbind) {
1652
+ spin_unlock_irqrestore(&gi->spinlock, flags);
1653
+ return;
1654
+ }
1655
+
1656
+#ifdef CONFIG_USB_CONFIGFS_UEVENT
1657
+ gi->connected = 0;
1658
+ schedule_work(&gi->work);
1659
+#endif
1660
+ composite_disconnect(gadget);
1661
+ spin_unlock_irqrestore(&gi->spinlock, flags);
1662
+}
1663
+
1664
+static void configfs_composite_reset(struct usb_gadget *gadget)
15321665 {
15331666 struct usb_composite_dev *cdev;
15341667 struct gadget_info *gi;
....@@ -1546,10 +1679,9 @@
15461679 return;
15471680 }
15481681
1549
- composite_disconnect(gadget);
1682
+ composite_reset(gadget);
15501683 spin_unlock_irqrestore(&gi->spinlock, flags);
15511684 }
1552
-#endif
15531685
15541686 static void configfs_composite_suspend(struct usb_gadget *gadget)
15551687 {
....@@ -1595,92 +1727,17 @@
15951727 spin_unlock_irqrestore(&gi->spinlock, flags);
15961728 }
15971729
1598
-#ifdef CONFIG_USB_CONFIGFS_UEVENT
1599
-static int android_setup(struct usb_gadget *gadget,
1600
- const struct usb_ctrlrequest *c)
1601
-{
1602
- struct usb_composite_dev *cdev = get_gadget_data(gadget);
1603
- unsigned long flags;
1604
- struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
1605
- int value = -EOPNOTSUPP;
1606
- struct usb_function_instance *fi;
1607
-
1608
- spin_lock_irqsave(&cdev->lock, flags);
1609
- if (c->bRequest == USB_REQ_GET_DESCRIPTOR &&
1610
- (c->wValue >> 8) == USB_DT_CONFIG && !gi->connected) {
1611
- gi->connected = 1;
1612
- schedule_work(&gi->work);
1613
- }
1614
- spin_unlock_irqrestore(&cdev->lock, flags);
1615
- list_for_each_entry(fi, &gi->available_func, cfs_list) {
1616
- if (fi != NULL && fi->f != NULL && fi->f->setup != NULL) {
1617
- value = fi->f->setup(fi->f, c);
1618
- if (value >= 0)
1619
- break;
1620
- }
1621
- }
1622
-
1623
-#ifdef CONFIG_USB_CONFIGFS_F_ACC
1624
- if (value < 0)
1625
- value = acc_ctrlrequest(cdev, c);
1626
-#endif
1627
-
1628
- if (value < 0)
1629
- value = composite_setup(gadget, c);
1630
-
1631
- spin_lock_irqsave(&cdev->lock, flags);
1632
- if (c->bRequest == USB_REQ_SET_CONFIGURATION &&
1633
- cdev->config) {
1634
- schedule_work(&gi->work);
1635
- }
1636
- spin_unlock_irqrestore(&cdev->lock, flags);
1637
-
1638
- return value;
1639
-}
1640
-
1641
-static void android_disconnect(struct usb_gadget *gadget)
1642
-{
1643
- struct usb_composite_dev *cdev = get_gadget_data(gadget);
1644
- struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
1645
-
1646
- /* FIXME: There's a race between usb_gadget_udc_stop() which is likely
1647
- * to set the gadget driver to NULL in the udc driver and this drivers
1648
- * gadget disconnect fn which likely checks for the gadget driver to
1649
- * be a null ptr. It happens that unbind (doing set_gadget_data(NULL))
1650
- * is called before the gadget driver is set to NULL and the udc driver
1651
- * calls disconnect fn which results in cdev being a null ptr.
1652
- */
1653
- if (cdev == NULL) {
1654
- WARN(1, "%s: gadget driver already disconnected\n", __func__);
1655
- return;
1656
- }
1657
-
1658
- /* accessory HID support can be active while the
1659
- accessory function is not actually enabled,
1660
- so we need to inform it when we are disconnected.
1661
- */
1662
-
1663
-#ifdef CONFIG_USB_CONFIGFS_F_ACC
1664
- acc_disconnect();
1665
-#endif
1666
- gi->connected = 0;
1667
- schedule_work(&gi->work);
1668
- composite_disconnect(gadget);
1669
-}
1670
-#endif
1671
-
16721730 static const struct usb_gadget_driver configfs_driver_template = {
16731731 .bind = configfs_composite_bind,
16741732 .unbind = configfs_composite_unbind,
1733
+
16751734 #ifdef CONFIG_USB_CONFIGFS_UEVENT
16761735 .setup = android_setup,
1677
- .reset = android_disconnect,
1678
- .disconnect = android_disconnect,
16791736 #else
16801737 .setup = configfs_composite_setup,
1681
- .reset = configfs_composite_disconnect,
1682
- .disconnect = configfs_composite_disconnect,
16831738 #endif
1739
+ .reset = configfs_composite_reset,
1740
+ .disconnect = configfs_composite_disconnect,
16841741 .suspend = configfs_composite_suspend,
16851742 .resume = configfs_composite_resume,
16861743