@@ -40,6 +40,11 @@ static const struct bus_type gadget_bus_type;
4040 * @allow_connect: Indicates whether UDC is allowed to be pulled up.
4141 * Set/cleared by gadget_(un)bind_driver() after gadget driver is bound or
4242 * unbound.
43+ * @connect_lock: protects udc->started, gadget->connect,
44+ * gadget->allow_connect and gadget->deactivate. The routines
45+ * usb_gadget_connect_locked(), usb_gadget_disconnect_locked(),
46+ * usb_udc_connect_control_locked(), usb_gadget_udc_start_locked() and
47+ * usb_gadget_udc_stop_locked() are called with this lock held.
4348 *
4449 * This represents the internal data structure which is used by the UDC-class
4550 * to hold information about udc driver and gadget together.
@@ -53,6 +58,7 @@ struct usb_udc {
5358 bool started ;
5459 bool allow_connect ;
5560 struct work_struct vbus_work ;
61+ struct mutex connect_lock ;
5662};
5763
5864static struct class * udc_class ;
@@ -692,17 +698,8 @@ int usb_gadget_vbus_disconnect(struct usb_gadget *gadget)
692698}
693699EXPORT_SYMBOL_GPL (usb_gadget_vbus_disconnect );
694700
695- /**
696- * usb_gadget_connect - software-controlled connect to USB host
697- * @gadget:the peripheral being connected
698- *
699- * Enables the D+ (or potentially D-) pullup. The host will start
700- * enumerating this gadget when the pullup is active and a VBUS session
701- * is active (the link is powered).
702- *
703- * Returns zero on success, else negative errno.
704- */
705- int usb_gadget_connect (struct usb_gadget * gadget )
701+ static int usb_gadget_connect_locked (struct usb_gadget * gadget )
702+ __must_hold (& gadget - > udc - > connect_lock )
706703{
707704 int ret = 0 ;
708705
@@ -711,10 +708,12 @@ int usb_gadget_connect(struct usb_gadget *gadget)
711708 goto out ;
712709 }
713710
714- if (gadget -> deactivated || !gadget -> udc -> allow_connect ) {
711+ if (gadget -> deactivated || !gadget -> udc -> allow_connect || ! gadget -> udc -> started ) {
715712 /*
716- * If gadget is deactivated we only save new state.
717- * Gadget will be connected automatically after activation.
713+ * If the gadget isn't usable (because it is deactivated,
714+ * unbound, or not yet started), we only save the new state.
715+ * The gadget will be connected automatically when it is
716+ * activated/bound/started.
718717 */
719718 gadget -> connected = true;
720719 goto out ;
@@ -729,22 +728,31 @@ int usb_gadget_connect(struct usb_gadget *gadget)
729728
730729 return ret ;
731730}
732- EXPORT_SYMBOL_GPL (usb_gadget_connect );
733731
734732/**
735- * usb_gadget_disconnect - software-controlled disconnect from USB host
736- * @gadget:the peripheral being disconnected
737- *
738- * Disables the D+ (or potentially D-) pullup, which the host may see
739- * as a disconnect (when a VBUS session is active). Not all systems
740- * support software pullup controls.
733+ * usb_gadget_connect - software-controlled connect to USB host
734+ * @gadget:the peripheral being connected
741735 *
742- * Following a successful disconnect, invoke the ->disconnect() callback
743- * for the current gadget driver so that UDC drivers don't need to.
736+ * Enables the D+ (or potentially D-) pullup. The host will start
737+ * enumerating this gadget when the pullup is active and a VBUS session
738+ * is active (the link is powered).
744739 *
745740 * Returns zero on success, else negative errno.
746741 */
747- int usb_gadget_disconnect (struct usb_gadget * gadget )
742+ int usb_gadget_connect (struct usb_gadget * gadget )
743+ {
744+ int ret ;
745+
746+ mutex_lock (& gadget -> udc -> connect_lock );
747+ ret = usb_gadget_connect_locked (gadget );
748+ mutex_unlock (& gadget -> udc -> connect_lock );
749+
750+ return ret ;
751+ }
752+ EXPORT_SYMBOL_GPL (usb_gadget_connect );
753+
754+ static int usb_gadget_disconnect_locked (struct usb_gadget * gadget )
755+ __must_hold (& gadget - > udc - > connect_lock )
748756{
749757 int ret = 0 ;
750758
@@ -756,7 +764,7 @@ int usb_gadget_disconnect(struct usb_gadget *gadget)
756764 if (!gadget -> connected )
757765 goto out ;
758766
759- if (gadget -> deactivated ) {
767+ if (gadget -> deactivated || ! gadget -> udc -> started ) {
760768 /*
761769 * If gadget is deactivated we only save new state.
762770 * Gadget will stay disconnected after activation.
@@ -779,6 +787,30 @@ int usb_gadget_disconnect(struct usb_gadget *gadget)
779787
780788 return ret ;
781789}
790+
791+ /**
792+ * usb_gadget_disconnect - software-controlled disconnect from USB host
793+ * @gadget:the peripheral being disconnected
794+ *
795+ * Disables the D+ (or potentially D-) pullup, which the host may see
796+ * as a disconnect (when a VBUS session is active). Not all systems
797+ * support software pullup controls.
798+ *
799+ * Following a successful disconnect, invoke the ->disconnect() callback
800+ * for the current gadget driver so that UDC drivers don't need to.
801+ *
802+ * Returns zero on success, else negative errno.
803+ */
804+ int usb_gadget_disconnect (struct usb_gadget * gadget )
805+ {
806+ int ret ;
807+
808+ mutex_lock (& gadget -> udc -> connect_lock );
809+ ret = usb_gadget_disconnect_locked (gadget );
810+ mutex_unlock (& gadget -> udc -> connect_lock );
811+
812+ return ret ;
813+ }
782814EXPORT_SYMBOL_GPL (usb_gadget_disconnect );
783815
784816/**
@@ -796,13 +828,14 @@ int usb_gadget_deactivate(struct usb_gadget *gadget)
796828{
797829 int ret = 0 ;
798830
831+ mutex_lock (& gadget -> udc -> connect_lock );
799832 if (gadget -> deactivated )
800- goto out ;
833+ goto unlock ;
801834
802835 if (gadget -> connected ) {
803- ret = usb_gadget_disconnect (gadget );
836+ ret = usb_gadget_disconnect_locked (gadget );
804837 if (ret )
805- goto out ;
838+ goto unlock ;
806839
807840 /*
808841 * If gadget was being connected before deactivation, we want
@@ -812,7 +845,8 @@ int usb_gadget_deactivate(struct usb_gadget *gadget)
812845 }
813846 gadget -> deactivated = true;
814847
815- out :
848+ unlock :
849+ mutex_unlock (& gadget -> udc -> connect_lock );
816850 trace_usb_gadget_deactivate (gadget , ret );
817851
818852 return ret ;
@@ -832,8 +866,9 @@ int usb_gadget_activate(struct usb_gadget *gadget)
832866{
833867 int ret = 0 ;
834868
869+ mutex_lock (& gadget -> udc -> connect_lock );
835870 if (!gadget -> deactivated )
836- goto out ;
871+ goto unlock ;
837872
838873 gadget -> deactivated = false;
839874
@@ -842,9 +877,11 @@ int usb_gadget_activate(struct usb_gadget *gadget)
842877 * while it was being deactivated, we call usb_gadget_connect().
843878 */
844879 if (gadget -> connected )
845- ret = usb_gadget_connect (gadget );
880+ ret = usb_gadget_connect_locked (gadget );
881+ mutex_unlock (& gadget -> udc -> connect_lock );
846882
847- out :
883+ unlock :
884+ mutex_unlock (& gadget -> udc -> connect_lock );
848885 trace_usb_gadget_activate (gadget , ret );
849886
850887 return ret ;
@@ -1083,19 +1120,22 @@ EXPORT_SYMBOL_GPL(usb_gadget_set_state);
10831120
10841121/* ------------------------------------------------------------------------- */
10851122
1086- static void usb_udc_connect_control (struct usb_udc * udc )
1123+ /* Acquire connect_lock before calling this function. */
1124+ static void usb_udc_connect_control_locked (struct usb_udc * udc ) __must_hold (& udc - > connect_lock )
10871125{
10881126 if (udc -> vbus )
1089- usb_gadget_connect (udc -> gadget );
1127+ usb_gadget_connect_locked (udc -> gadget );
10901128 else
1091- usb_gadget_disconnect (udc -> gadget );
1129+ usb_gadget_disconnect_locked (udc -> gadget );
10921130}
10931131
10941132static void vbus_event_work (struct work_struct * work )
10951133{
10961134 struct usb_udc * udc = container_of (work , struct usb_udc , vbus_work );
10971135
1098- usb_udc_connect_control (udc );
1136+ mutex_lock (& udc -> connect_lock );
1137+ usb_udc_connect_control_locked (udc );
1138+ mutex_unlock (& udc -> connect_lock );
10991139}
11001140
11011141/**
@@ -1144,7 +1184,7 @@ void usb_gadget_udc_reset(struct usb_gadget *gadget,
11441184EXPORT_SYMBOL_GPL (usb_gadget_udc_reset );
11451185
11461186/**
1147- * usb_gadget_udc_start - tells usb device controller to start up
1187+ * usb_gadget_udc_start_locked - tells usb device controller to start up
11481188 * @udc: The UDC to be started
11491189 *
11501190 * This call is issued by the UDC Class driver when it's about
@@ -1155,8 +1195,11 @@ EXPORT_SYMBOL_GPL(usb_gadget_udc_reset);
11551195 * necessary to have it powered on.
11561196 *
11571197 * Returns zero on success, else negative errno.
1198+ *
1199+ * Caller should acquire connect_lock before invoking this function.
11581200 */
1159- static inline int usb_gadget_udc_start (struct usb_udc * udc )
1201+ static inline int usb_gadget_udc_start_locked (struct usb_udc * udc )
1202+ __must_hold (& udc - > connect_lock )
11601203{
11611204 int ret ;
11621205
@@ -1173,7 +1216,7 @@ static inline int usb_gadget_udc_start(struct usb_udc *udc)
11731216}
11741217
11751218/**
1176- * usb_gadget_udc_stop - tells usb device controller we don't need it anymore
1219+ * usb_gadget_udc_stop_locked - tells usb device controller we don't need it anymore
11771220 * @udc: The UDC to be stopped
11781221 *
11791222 * This call is issued by the UDC Class driver after calling
@@ -1182,8 +1225,11 @@ static inline int usb_gadget_udc_start(struct usb_udc *udc)
11821225 * The details are implementation specific, but it can go as
11831226 * far as powering off UDC completely and disable its data
11841227 * line pullups.
1228+ *
1229+ * Caller should acquire connect lock before invoking this function.
11851230 */
1186- static inline void usb_gadget_udc_stop (struct usb_udc * udc )
1231+ static inline void usb_gadget_udc_stop_locked (struct usb_udc * udc )
1232+ __must_hold (& udc - > connect_lock )
11871233{
11881234 if (!udc -> started ) {
11891235 dev_err (& udc -> dev , "UDC had already stopped\n" );
@@ -1342,6 +1388,7 @@ int usb_add_gadget(struct usb_gadget *gadget)
13421388
13431389 udc -> gadget = gadget ;
13441390 gadget -> udc = udc ;
1391+ mutex_init (& udc -> connect_lock );
13451392
13461393 udc -> started = false;
13471394
@@ -1545,12 +1592,16 @@ static int gadget_bind_driver(struct device *dev)
15451592 if (ret )
15461593 goto err_bind ;
15471594
1548- ret = usb_gadget_udc_start (udc );
1549- if (ret )
1595+ mutex_lock (& udc -> connect_lock );
1596+ ret = usb_gadget_udc_start_locked (udc );
1597+ if (ret ) {
1598+ mutex_unlock (& udc -> connect_lock );
15501599 goto err_start ;
1600+ }
15511601 usb_gadget_enable_async_callbacks (udc );
15521602 udc -> allow_connect = true;
1553- usb_udc_connect_control (udc );
1603+ usb_udc_connect_control_locked (udc );
1604+ mutex_unlock (& udc -> connect_lock );
15541605
15551606 kobject_uevent (& udc -> dev .kobj , KOBJ_CHANGE );
15561607 return 0 ;
@@ -1583,12 +1634,14 @@ static void gadget_unbind_driver(struct device *dev)
15831634
15841635 udc -> allow_connect = false;
15851636 cancel_work_sync (& udc -> vbus_work );
1586- usb_gadget_disconnect (gadget );
1637+ mutex_lock (& udc -> connect_lock );
1638+ usb_gadget_disconnect_locked (gadget );
15871639 usb_gadget_disable_async_callbacks (udc );
15881640 if (gadget -> irq )
15891641 synchronize_irq (gadget -> irq );
15901642 udc -> driver -> unbind (gadget );
1591- usb_gadget_udc_stop (udc );
1643+ usb_gadget_udc_stop_locked (udc );
1644+ mutex_unlock (& udc -> connect_lock );
15921645
15931646 mutex_lock (& udc_lock );
15941647 driver -> is_bound = false;
@@ -1674,11 +1727,15 @@ static ssize_t soft_connect_store(struct device *dev,
16741727 }
16751728
16761729 if (sysfs_streq (buf , "connect" )) {
1677- usb_gadget_udc_start (udc );
1678- usb_gadget_connect (udc -> gadget );
1730+ mutex_lock (& udc -> connect_lock );
1731+ usb_gadget_udc_start_locked (udc );
1732+ usb_gadget_connect_locked (udc -> gadget );
1733+ mutex_unlock (& udc -> connect_lock );
16791734 } else if (sysfs_streq (buf , "disconnect" )) {
1680- usb_gadget_disconnect (udc -> gadget );
1681- usb_gadget_udc_stop (udc );
1735+ mutex_lock (& udc -> connect_lock );
1736+ usb_gadget_disconnect_locked (udc -> gadget );
1737+ usb_gadget_udc_stop_locked (udc );
1738+ mutex_unlock (& udc -> connect_lock );
16821739 } else {
16831740 dev_err (dev , "unsupported command '%s'\n" , buf );
16841741 ret = - EINVAL ;
0 commit comments