@@ -60,6 +60,8 @@ struct gadget_info {
6060 bool use_os_desc ;
6161 char b_vendor_code ;
6262 char qw_sign [OS_STRING_QW_SIGN_LEN ];
63+ spinlock_t spinlock ;
64+ bool unbind ;
6365};
6466
6567static inline struct gadget_info * to_gadget_info (struct config_item * item )
@@ -1243,6 +1245,7 @@ static int configfs_composite_bind(struct usb_gadget *gadget,
12431245 int ret ;
12441246
12451247 /* the gi->lock is hold by the caller */
1248+ gi -> unbind = 0 ;
12461249 cdev -> gadget = gadget ;
12471250 set_gadget_data (gadget , cdev );
12481251 ret = composite_dev_prepare (composite , cdev );
@@ -1375,31 +1378,128 @@ static void configfs_composite_unbind(struct usb_gadget *gadget)
13751378{
13761379 struct usb_composite_dev * cdev ;
13771380 struct gadget_info * gi ;
1381+ unsigned long flags ;
13781382
13791383 /* the gi->lock is hold by the caller */
13801384
13811385 cdev = get_gadget_data (gadget );
13821386 gi = container_of (cdev , struct gadget_info , cdev );
1387+ spin_lock_irqsave (& gi -> spinlock , flags );
1388+ gi -> unbind = 1 ;
1389+ spin_unlock_irqrestore (& gi -> spinlock , flags );
13831390
13841391 kfree (otg_desc [0 ]);
13851392 otg_desc [0 ] = NULL ;
13861393 purge_configs_funcs (gi );
13871394 composite_dev_cleanup (cdev );
13881395 usb_ep_autoconfig_reset (cdev -> gadget );
1396+ spin_lock_irqsave (& gi -> spinlock , flags );
13891397 cdev -> gadget = NULL ;
13901398 set_gadget_data (gadget , NULL );
1399+ spin_unlock_irqrestore (& gi -> spinlock , flags );
1400+ }
1401+
1402+ static int configfs_composite_setup (struct usb_gadget * gadget ,
1403+ const struct usb_ctrlrequest * ctrl )
1404+ {
1405+ struct usb_composite_dev * cdev ;
1406+ struct gadget_info * gi ;
1407+ unsigned long flags ;
1408+ int ret ;
1409+
1410+ cdev = get_gadget_data (gadget );
1411+ if (!cdev )
1412+ return 0 ;
1413+
1414+ gi = container_of (cdev , struct gadget_info , cdev );
1415+ spin_lock_irqsave (& gi -> spinlock , flags );
1416+ cdev = get_gadget_data (gadget );
1417+ if (!cdev || gi -> unbind ) {
1418+ spin_unlock_irqrestore (& gi -> spinlock , flags );
1419+ return 0 ;
1420+ }
1421+
1422+ ret = composite_setup (gadget , ctrl );
1423+ spin_unlock_irqrestore (& gi -> spinlock , flags );
1424+ return ret ;
1425+ }
1426+
1427+ static void configfs_composite_disconnect (struct usb_gadget * gadget )
1428+ {
1429+ struct usb_composite_dev * cdev ;
1430+ struct gadget_info * gi ;
1431+ unsigned long flags ;
1432+
1433+ cdev = get_gadget_data (gadget );
1434+ if (!cdev )
1435+ return ;
1436+
1437+ gi = container_of (cdev , struct gadget_info , cdev );
1438+ spin_lock_irqsave (& gi -> spinlock , flags );
1439+ cdev = get_gadget_data (gadget );
1440+ if (!cdev || gi -> unbind ) {
1441+ spin_unlock_irqrestore (& gi -> spinlock , flags );
1442+ return ;
1443+ }
1444+
1445+ composite_disconnect (gadget );
1446+ spin_unlock_irqrestore (& gi -> spinlock , flags );
1447+ }
1448+
1449+ static void configfs_composite_suspend (struct usb_gadget * gadget )
1450+ {
1451+ struct usb_composite_dev * cdev ;
1452+ struct gadget_info * gi ;
1453+ unsigned long flags ;
1454+
1455+ cdev = get_gadget_data (gadget );
1456+ if (!cdev )
1457+ return ;
1458+
1459+ gi = container_of (cdev , struct gadget_info , cdev );
1460+ spin_lock_irqsave (& gi -> spinlock , flags );
1461+ cdev = get_gadget_data (gadget );
1462+ if (!cdev || gi -> unbind ) {
1463+ spin_unlock_irqrestore (& gi -> spinlock , flags );
1464+ return ;
1465+ }
1466+
1467+ composite_suspend (gadget );
1468+ spin_unlock_irqrestore (& gi -> spinlock , flags );
1469+ }
1470+
1471+ static void configfs_composite_resume (struct usb_gadget * gadget )
1472+ {
1473+ struct usb_composite_dev * cdev ;
1474+ struct gadget_info * gi ;
1475+ unsigned long flags ;
1476+
1477+ cdev = get_gadget_data (gadget );
1478+ if (!cdev )
1479+ return ;
1480+
1481+ gi = container_of (cdev , struct gadget_info , cdev );
1482+ spin_lock_irqsave (& gi -> spinlock , flags );
1483+ cdev = get_gadget_data (gadget );
1484+ if (!cdev || gi -> unbind ) {
1485+ spin_unlock_irqrestore (& gi -> spinlock , flags );
1486+ return ;
1487+ }
1488+
1489+ composite_resume (gadget );
1490+ spin_unlock_irqrestore (& gi -> spinlock , flags );
13911491}
13921492
13931493static const struct usb_gadget_driver configfs_driver_template = {
13941494 .bind = configfs_composite_bind ,
13951495 .unbind = configfs_composite_unbind ,
13961496
1397- .setup = composite_setup ,
1398- .reset = composite_disconnect ,
1399- .disconnect = composite_disconnect ,
1497+ .setup = configfs_composite_setup ,
1498+ .reset = configfs_composite_disconnect ,
1499+ .disconnect = configfs_composite_disconnect ,
14001500
1401- .suspend = composite_suspend ,
1402- .resume = composite_resume ,
1501+ .suspend = configfs_composite_suspend ,
1502+ .resume = configfs_composite_resume ,
14031503
14041504 .max_speed = USB_SPEED_SUPER ,
14051505 .driver = {
0 commit comments