forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 072de836f53be56a70cecf70b43ae43b7ce17376
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
....@@ -1408,6 +1439,10 @@
14081439 goto err_purge_funcs;
14091440 }
14101441 }
1442
+ ret = usb_gadget_check_config(cdev->gadget);
1443
+ if (ret)
1444
+ goto err_purge_funcs;
1445
+
14111446 usb_ep_autoconfig_reset(cdev->gadget);
14121447 }
14131448 if (cdev->use_os_string) {
....@@ -1498,11 +1533,66 @@
14981533 usb_ep_autoconfig_reset(cdev->gadget);
14991534 spin_lock_irqsave(&gi->spinlock, flags);
15001535 cdev->gadget = NULL;
1536
+ cdev->deactivations = 0;
1537
+ gadget->deactivated = false;
15011538 set_gadget_data(gadget, NULL);
15021539 spin_unlock_irqrestore(&gi->spinlock, flags);
15031540 }
15041541
1505
-#ifndef CONFIG_USB_CONFIGFS_UEVENT
1542
+#ifdef CONFIG_USB_CONFIGFS_UEVENT
1543
+static int android_setup(struct usb_gadget *gadget,
1544
+ const struct usb_ctrlrequest *c)
1545
+{
1546
+ struct usb_composite_dev *cdev;
1547
+ unsigned long flags;
1548
+ struct gadget_info *gi;
1549
+ int value = -EOPNOTSUPP;
1550
+ struct usb_function_instance *fi;
1551
+
1552
+ if (!android_device)
1553
+ return 0;
1554
+
1555
+ gi = dev_get_drvdata(android_device);
1556
+ spin_lock_irqsave(&gi->spinlock, flags);
1557
+ cdev = get_gadget_data(gadget);
1558
+ if (!cdev || gi->unbind) {
1559
+ spin_unlock_irqrestore(&gi->spinlock, flags);
1560
+ return 0;
1561
+ }
1562
+
1563
+ if (c->bRequest == USB_REQ_GET_DESCRIPTOR &&
1564
+ (c->wValue >> 8) == USB_DT_CONFIG && !gi->connected) {
1565
+ gi->connected = 1;
1566
+ schedule_work(&gi->work);
1567
+ }
1568
+
1569
+ list_for_each_entry(fi, &gi->available_func, cfs_list) {
1570
+ if (fi != NULL && fi->f != NULL && fi->f->setup != NULL) {
1571
+ value = fi->f->setup(fi->f, c);
1572
+ if (value >= 0)
1573
+ break;
1574
+ }
1575
+ }
1576
+
1577
+#ifdef CONFIG_USB_CONFIGFS_F_ACC
1578
+ if (value < 0)
1579
+ value = acc_ctrlrequest_composite(cdev, c);
1580
+#endif
1581
+
1582
+ if (value < 0)
1583
+ value = composite_setup(gadget, c);
1584
+
1585
+ if (c->bRequest == USB_REQ_SET_CONFIGURATION &&
1586
+ cdev->config) {
1587
+ schedule_work(&gi->work);
1588
+ }
1589
+ spin_unlock_irqrestore(&gi->spinlock, flags);
1590
+
1591
+ return value;
1592
+}
1593
+
1594
+#else // CONFIG_USB_CONFIGFS_UEVENT
1595
+
15061596 static int configfs_composite_setup(struct usb_gadget *gadget,
15071597 const struct usb_ctrlrequest *ctrl)
15081598 {
....@@ -1528,7 +1618,43 @@
15281618 return ret;
15291619 }
15301620
1621
+#endif // CONFIG_USB_CONFIGFS_UEVENT
1622
+
15311623 static void configfs_composite_disconnect(struct usb_gadget *gadget)
1624
+{
1625
+ struct usb_composite_dev *cdev;
1626
+ struct gadget_info *gi;
1627
+ unsigned long flags;
1628
+
1629
+ cdev = get_gadget_data(gadget);
1630
+ if (!cdev)
1631
+ return;
1632
+
1633
+#ifdef CONFIG_USB_CONFIGFS_F_ACC
1634
+ /*
1635
+ * accessory HID support can be active while the
1636
+ * accessory function is not actually enabled,
1637
+ * so we need to inform it when we are disconnected.
1638
+ */
1639
+ acc_disconnect();
1640
+#endif
1641
+ gi = container_of(cdev, struct gadget_info, cdev);
1642
+ spin_lock_irqsave(&gi->spinlock, flags);
1643
+ cdev = get_gadget_data(gadget);
1644
+ if (!cdev || gi->unbind) {
1645
+ spin_unlock_irqrestore(&gi->spinlock, flags);
1646
+ return;
1647
+ }
1648
+
1649
+#ifdef CONFIG_USB_CONFIGFS_UEVENT
1650
+ gi->connected = 0;
1651
+ schedule_work(&gi->work);
1652
+#endif
1653
+ composite_disconnect(gadget);
1654
+ spin_unlock_irqrestore(&gi->spinlock, flags);
1655
+}
1656
+
1657
+static void configfs_composite_reset(struct usb_gadget *gadget)
15321658 {
15331659 struct usb_composite_dev *cdev;
15341660 struct gadget_info *gi;
....@@ -1546,10 +1672,9 @@
15461672 return;
15471673 }
15481674
1549
- composite_disconnect(gadget);
1675
+ composite_reset(gadget);
15501676 spin_unlock_irqrestore(&gi->spinlock, flags);
15511677 }
1552
-#endif
15531678
15541679 static void configfs_composite_suspend(struct usb_gadget *gadget)
15551680 {
....@@ -1595,101 +1720,17 @@
15951720 spin_unlock_irqrestore(&gi->spinlock, flags);
15961721 }
15971722
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;
1603
- unsigned long flags;
1604
- struct gadget_info *gi;
1605
- int value = -EOPNOTSUPP;
1606
- struct usb_function_instance *fi;
1607
-
1608
- if (!android_device)
1609
- return 0;
1610
-
1611
- gi = dev_get_drvdata(android_device);
1612
- spin_lock_irqsave(&gi->spinlock, flags);
1613
- cdev = get_gadget_data(gadget);
1614
- if (!cdev || gi->unbind) {
1615
- spin_unlock_irqrestore(&gi->spinlock, flags);
1616
- return 0;
1617
- };
1618
-
1619
- if (c->bRequest == USB_REQ_GET_DESCRIPTOR &&
1620
- (c->wValue >> 8) == USB_DT_CONFIG && !gi->connected) {
1621
- gi->connected = 1;
1622
- schedule_work(&gi->work);
1623
- }
1624
-
1625
- list_for_each_entry(fi, &gi->available_func, cfs_list) {
1626
- if (fi != NULL && fi->f != NULL && fi->f->setup != NULL) {
1627
- value = fi->f->setup(fi->f, c);
1628
- if (value >= 0)
1629
- break;
1630
- }
1631
- }
1632
-
1633
-#ifdef CONFIG_USB_CONFIGFS_F_ACC
1634
- if (value < 0)
1635
- value = acc_ctrlrequest(cdev, c);
1636
-#endif
1637
-
1638
- if (value < 0)
1639
- value = composite_setup(gadget, c);
1640
-
1641
- if (c->bRequest == USB_REQ_SET_CONFIGURATION &&
1642
- cdev->config) {
1643
- schedule_work(&gi->work);
1644
- }
1645
- spin_unlock_irqrestore(&gi->spinlock, flags);
1646
-
1647
- return value;
1648
-}
1649
-
1650
-static void android_disconnect(struct usb_gadget *gadget)
1651
-{
1652
- struct usb_composite_dev *cdev = get_gadget_data(gadget);
1653
- struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
1654
-
1655
- /* FIXME: There's a race between usb_gadget_udc_stop() which is likely
1656
- * to set the gadget driver to NULL in the udc driver and this drivers
1657
- * gadget disconnect fn which likely checks for the gadget driver to
1658
- * be a null ptr. It happens that unbind (doing set_gadget_data(NULL))
1659
- * is called before the gadget driver is set to NULL and the udc driver
1660
- * calls disconnect fn which results in cdev being a null ptr.
1661
- */
1662
- if (cdev == NULL) {
1663
- WARN(1, "%s: gadget driver already disconnected\n", __func__);
1664
- return;
1665
- }
1666
-
1667
- /* accessory HID support can be active while the
1668
- accessory function is not actually enabled,
1669
- so we need to inform it when we are disconnected.
1670
- */
1671
-
1672
-#ifdef CONFIG_USB_CONFIGFS_F_ACC
1673
- acc_disconnect();
1674
-#endif
1675
- gi->connected = 0;
1676
- schedule_work(&gi->work);
1677
- composite_disconnect(gadget);
1678
-}
1679
-#endif
1680
-
16811723 static const struct usb_gadget_driver configfs_driver_template = {
16821724 .bind = configfs_composite_bind,
16831725 .unbind = configfs_composite_unbind,
1726
+
16841727 #ifdef CONFIG_USB_CONFIGFS_UEVENT
16851728 .setup = android_setup,
1686
- .reset = android_disconnect,
1687
- .disconnect = android_disconnect,
16881729 #else
16891730 .setup = configfs_composite_setup,
1690
- .reset = configfs_composite_disconnect,
1691
- .disconnect = configfs_composite_disconnect,
16921731 #endif
1732
+ .reset = configfs_composite_reset,
1733
+ .disconnect = configfs_composite_disconnect,
16931734 .suspend = configfs_composite_suspend,
16941735 .resume = configfs_composite_resume,
16951736