[PATCH 1/2] usb: gadget dbgp: Fix endpoint config after USB disconnect

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



SET_FEATURE request for DEBUG_MODE only worked the first time after module
initialisation. On USB host reset or cable disconnect gserial_disconnect()
clears the associations dbgp.serial->in->desc and dbgp_serial->out->desc.

Per the USB 2.0 debug device specification, SET_FEATURE with DEBUG_MODE
is to be treated as if it were a SET_CONFIGURATION request. Redo endpoint
configuration on this request.

Code has assumption that endpoint mapping remains unchanged from what was
previously returned as a GET_DESCRIPTOR DT_DEBUG response.

Signed-off-by: Kyösti Mälkki <kyosti.malkki@xxxxxxxxx>
---
 drivers/usb/gadget/legacy/dbgp.c | 39 ++++++++++++++++++++++++++-------------
 1 file changed, 26 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c
index 1b07513..afb49ef 100644
--- a/drivers/usb/gadget/legacy/dbgp.c
+++ b/drivers/usb/gadget/legacy/dbgp.c
@@ -214,6 +214,7 @@ static void dbgp_disconnect(struct usb_gadget *gadget)
 #ifdef CONFIG_USB_G_DBGP_PRINTK
 	dbgp_disable_ep();
 #else
+	dev_dbg(&dbgp.gadget->dev, "disconnected\n");
 	gserial_disconnect(dbgp.serial);
 #endif
 }
@@ -237,7 +238,7 @@ static void dbgp_unbind(struct usb_gadget *gadget)
 static unsigned char tty_line;
 #endif
 
-static int __init dbgp_configure_endpoints(struct usb_gadget *gadget)
+static int dbgp_configure_endpoints(struct usb_gadget *gadget)
 {
 	int stp;
 
@@ -273,19 +274,10 @@ static int __init dbgp_configure_endpoints(struct usb_gadget *gadget)
 
 	dbgp.serial->in->desc = &i_desc;
 	dbgp.serial->out->desc = &o_desc;
-
-	if (gserial_alloc_line(&tty_line)) {
-		stp = 3;
-		goto fail_3;
-	}
+#endif
 
 	return 0;
 
-fail_3:
-	dbgp.o_ep->driver_data = NULL;
-#else
-	return 0;
-#endif
 fail_2:
 	dbgp.i_ep->driver_data = NULL;
 fail_1:
@@ -324,10 +316,17 @@ static int __init dbgp_bind(struct usb_gadget *gadget,
 		err = -ENOMEM;
 		goto fail;
 	}
+
+	if (gserial_alloc_line(&tty_line)) {
+		stp = 4;
+		err = -ENODEV;
+		goto fail;
+	}
 #endif
+
 	err = dbgp_configure_endpoints(gadget);
 	if (err < 0) {
-		stp = 4;
+		stp = 5;
 		goto fail;
 	}
 
@@ -379,12 +378,26 @@ static int dbgp_setup(struct usb_gadget *gadget,
 		err = 0;
 	} else if (request == USB_REQ_SET_FEATURE &&
 		   value == USB_DEVICE_DEBUG_MODE) {
-		dev_dbg(&dbgp.gadget->dev, "setup: feat debug\n");
 #ifdef CONFIG_USB_G_DBGP_PRINTK
 		err = dbgp_enable_ep();
 #else
+		if (!(dbgp.serial->in && dbgp.serial->in->desc &&
+			dbgp.serial->out && dbgp.serial->out->desc)) {
+			dev_dbg(&dbgp.gadget->dev, "needs reconfiguration\n");
+			err = dbgp_configure_endpoints(gadget);
+			if (err < 0) {
+				goto fail;
+			}
+		}
+		if (dbgp.serial->in && dbgp.serial->in->desc &&
+			dbgp.serial->out && dbgp.serial->out->desc) {
+			dev_dbg(&dbgp.gadget->dev, "epIn %02x, epOut %02x\n",
+				dbgp.serial->in->desc->bEndpointAddress,
+				dbgp.serial->out->desc->bEndpointAddress);
+		}
 		err = gserial_connect(dbgp.serial, tty_line);
 #endif
+		dev_dbg(&dbgp.gadget->dev, "setup: feat debug (%d)\n", err);
 		if (err < 0)
 			goto fail;
 	} else
-- 
1.8.1.1

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




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux