Kernel may decide to detach our gadget in some cases.
A good example is when FFS daemon received a SIGSEGV
and all descriptors has been closed.

To avoid returning false informations to user we have
to refresh UDC attribute before returning cached pointer
to usbg_udc.

Signed-off-by: Krzysztof Opasiak <k.opas...@samsung.com>
---
 src/usbg.c |   37 +++++++++++++++++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/src/usbg.c b/src/usbg.c
index 3a8e656..998bce8 100644
--- a/src/usbg.c
+++ b/src/usbg.c
@@ -1931,7 +1931,36 @@ out:
 
 usbg_udc *usbg_get_gadget_udc(usbg_gadget *g)
 {
-       return g ? g->udc : NULL;
+       usbg_udc *u = NULL;
+
+       if (!g)
+               goto out;
+       /*
+        * if gadget was enabled we have to check if kernel
+        * didn't modify the UDC file due to some errors.
+        * For example some FFS daemon could just get
+        * a segmentation fault or sth
+        */
+       if (g->udc) {
+               char buf[USBG_MAX_STR_LENGTH];
+               int ret;
+
+               ret = usbg_read_string(g->path, g->name, "UDC", buf);
+               if (ret != USBG_SUCCESS)
+                       goto out;
+
+               if (!strcmp(g->udc->name, buf)) {
+                       /* Gadget is still assigned to this UDC */
+                       u = g->udc;
+               } else {
+                       /* Kernel decided to detach this gadget */
+                       g->udc->gadget = NULL;
+                       g->udc = NULL;
+               }
+       }
+
+out:
+       return u;
 }
 
 int usbg_set_gadget_attrs(usbg_gadget *g, usbg_gadget_attrs *g_attrs)
@@ -2510,8 +2539,12 @@ int usbg_enable_gadget(usbg_gadget *g, usbg_udc *udc)
        }
 
        ret = usbg_write_string(g->path, g->name, "UDC", udc->name);
-
        if (ret == USBG_SUCCESS) {
+               /* If gadget has been detached and we didn't noticed
+                * it we have to clean up now.
+                */
+               if (g->udc)
+                       g->udc->gadget = NULL;
                g->udc = udc;
                udc->gadget = g;
        }
-- 
1.7.9.5

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

Reply via email to