Instead of iterate to find usb_udc according to usb_gadget, this
way is easier.

Alan Stern suggests this way too:
http://marc.info/?l=linux-usb&m=142168496528894&w=2

Signed-off-by: Peter Chen <[email protected]>
---
 drivers/usb/gadget/udc/udc-core.c | 51 +++++++--------------------------------
 include/linux/usb/gadget.h        | 20 +++++++++++++++
 2 files changed, 29 insertions(+), 42 deletions(-)

diff --git a/drivers/usb/gadget/udc/udc-core.c 
b/drivers/usb/gadget/udc/udc-core.c
index 5a81cb0..a1d269c 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -29,23 +29,6 @@
 #include <linux/usb/gadget.h>
 #include <linux/usb.h>
 
-/**
- * struct usb_udc - describes one usb device controller
- * @driver - the gadget driver pointer. For use by the class code
- * @dev - the child device to the actual controller
- * @gadget - the gadget. For use by the class code
- * @list - for use by the udc class driver
- *
- * This represents the internal data structure which is used by the UDC-class
- * to hold information about udc driver and gadget together.
- */
-struct usb_udc {
-       struct usb_gadget_driver        *driver;
-       struct usb_gadget               *gadget;
-       struct device                   dev;
-       struct list_head                list;
-};
-
 static struct class *udc_class;
 static LIST_HEAD(udc_list);
 static DEFINE_MUTEX(udc_lock);
@@ -128,21 +111,11 @@ EXPORT_SYMBOL_GPL(usb_gadget_giveback_request);
 
 static void usb_gadget_state_work(struct work_struct *work)
 {
-       struct usb_gadget       *gadget = work_to_gadget(work);
-       struct usb_udc          *udc = NULL;
-
-       mutex_lock(&udc_lock);
-       list_for_each_entry(udc, &udc_list, list)
-               if (udc->gadget == gadget)
-                       goto found;
-       mutex_unlock(&udc_lock);
-
-       return;
-
-found:
-       mutex_unlock(&udc_lock);
+       struct usb_gadget *gadget = work_to_gadget(work);
+       struct usb_udc *udc = gadget->udc;
 
-       sysfs_notify(&udc->dev.kobj, NULL, "state");
+       if (udc)
+               sysfs_notify(&udc->dev.kobj, NULL, "state");
 }
 
 void usb_gadget_set_state(struct usb_gadget *gadget,
@@ -278,6 +251,7 @@ int usb_add_gadget_udc_release(struct device *parent, 
struct usb_gadget *gadget,
                goto err3;
 
        udc->gadget = gadget;
+       gadget->udc = udc;
 
        mutex_lock(&udc_lock);
        list_add_tail(&udc->list, &udc_list);
@@ -348,21 +322,14 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)
  */
 void usb_del_gadget_udc(struct usb_gadget *gadget)
 {
-       struct usb_udc          *udc = NULL;
-
-       mutex_lock(&udc_lock);
-       list_for_each_entry(udc, &udc_list, list)
-               if (udc->gadget == gadget)
-                       goto found;
+       struct usb_udc *udc = gadget->udc;
 
-       dev_err(gadget->dev.parent, "gadget not registered.\n");
-       mutex_unlock(&udc_lock);
-
-       return;
+       if (!udc)
+               return;
 
-found:
        dev_vdbg(gadget->dev.parent, "unregistering gadget\n");
 
+       mutex_lock(&udc_lock);
        list_del(&udc->list);
        mutex_unlock(&udc_lock);
 
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index e2f00fd..8cbfe20 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -475,6 +475,24 @@ struct usb_dcd_config_params {
 struct usb_gadget;
 struct usb_gadget_driver;
 
+/**
+ * struct usb_udc - describes one usb device controller
+ * @driver - the gadget driver pointer. For use by the class code
+ * @dev - the child device to the actual controller
+ * @gadget - the gadget. For use by the class code
+ * @list - for use by the udc class driver
+ *
+ * This represents the internal data structure which is used by the UDC-class
+ * to hold information about udc driver and gadget together.
+ */
+struct usb_udc {
+       struct usb_gadget_driver        *driver;
+       struct usb_gadget               *gadget;
+       struct device                   dev;
+       struct list_head                list;
+};
+
+
 /* the rest of the api to the controller hardware: device operations,
  * which don't involve endpoints (or i/o).
  */
@@ -496,6 +514,7 @@ struct usb_gadget_ops {
 /**
  * struct usb_gadget - represents a usb slave device
  * @work: (internal use) Workqueue to be used for sysfs_notify()
+ * @udc: struct usb_udc pointer for this gadget
  * @ops: Function pointers used to access hardware-specific operations.
  * @ep0: Endpoint zero, used when reading or writing responses to
  *     driver setup() requests
@@ -545,6 +564,7 @@ struct usb_gadget_ops {
  */
 struct usb_gadget {
        struct work_struct              work;
+       struct usb_udc                  *udc;
        /* readonly to gadget driver */
        const struct usb_gadget_ops     *ops;
        struct usb_ep                   *ep0;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to