commit 2d148ea63fe50bf30071cb3e6c87fbd32c081cba Author: Vladimir Serbinenko <phcoder@xxxxxxxxx> Date: Tue May 26 21:35:06 2015 +0200 dbgp: Supply config descriptor and accept set config command. This descriptor and commands are part of core USB specification and every USB device should have one. When g_dbgp is used in early printk or in coreboot through EHCI debug those descriptors are never read and hence this doesn't create a problem. However for coreboot payloads with full USB stack or Linux once booted those descriptors are essential, so without them both GRUB-as-payload and Linux refuse to recognize it. Tested and works as expected in coreboot and GRUB. Booted Linux recognizes and it works the same way as Net20DC if I change USBID. early_printk=dbgp is not tested for lack of kernel with this feature enabled under my hand. Signed-off-by: Vladimir Serbinenko <phcoder@xxxxxxxxx> diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c index 204b10b..256876ddd 100644 --- a/drivers/usb/gadget/legacy/dbgp.c +++ b/drivers/usb/gadget/legacy/dbgp.c @@ -18,7 +18,7 @@ #define DRIVER_VENDOR_ID 0x0525 /* NetChip */ #define DRIVER_PRODUCT_ID 0xc0de /* undefined */ -#define USB_DEBUG_MAX_PACKET_SIZE 8 +#define USB_DEBUG_MAX_PACKET_SIZE 512 #define DBGP_REQ_EP0_LEN 128 #define DBGP_REQ_LEN 512 @@ -61,6 +61,35 @@ static struct usb_endpoint_descriptor o_desc = { .bEndpointAddress = USB_DIR_OUT, }; +struct full_config_desc { + struct usb_config_descriptor config_desc; + struct usb_interface_descriptor iface_desc; + u8 ep[2 * USB_DT_ENDPOINT_SIZE]; +}; + +static struct usb_config_descriptor config_desc = { + .bLength = sizeof (struct usb_config_descriptor), + .bDescriptorType = USB_DT_CONFIG, + .wTotalLength = __constant_cpu_to_le16(sizeof (struct full_config_desc)), + .bNumInterfaces = 1, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = 0xc0, + .bMaxPower = 0, +}; + +static struct usb_interface_descriptor iface_desc = { + .bLength = sizeof (struct usb_interface_descriptor), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = 0, +}; + #ifdef CONFIG_USB_G_DBGP_PRINTK static int dbgp_consume(char *buf, unsigned len) { @@ -355,6 +384,7 @@ static int dbgp_setup(struct usb_gadget *gadget, int err = -EOPNOTSUPP; void *data = NULL; u16 len = 0; + struct full_config_desc full_cfg_desc; gadget->ep0->driver_data = gadget; @@ -371,13 +401,26 @@ static int dbgp_setup(struct usb_gadget *gadget, len = sizeof dbg_desc; data = &dbg_desc; break; + case USB_DT_CONFIG: + dev_dbg(&dbgp.gadget->dev, "setup: desc config\n"); + full_cfg_desc.config_desc = config_desc; + full_cfg_desc.iface_desc = iface_desc; + memcpy(full_cfg_desc.ep, &i_desc, USB_DT_ENDPOINT_SIZE); + memcpy(full_cfg_desc.ep + USB_DT_ENDPOINT_SIZE, &o_desc, USB_DT_ENDPOINT_SIZE); + data = &full_cfg_desc; + len = sizeof full_cfg_desc; + break; default: goto fail; } err = 0; - } else if (request == USB_REQ_SET_FEATURE && - value == USB_DEVICE_DEBUG_MODE) { - dev_dbg(&dbgp.gadget->dev, "setup: feat debug\n"); + } else if ((request == USB_REQ_SET_FEATURE && + value == USB_DEVICE_DEBUG_MODE) + || (request == USB_REQ_SET_CONFIGURATION && value == 1)) { + if (request == USB_REQ_SET_FEATURE) + dev_dbg(&dbgp.gadget->dev, "setup: feat debug\n"); + else + dev_dbg(&dbgp.gadget->dev, "setup: config 1\n"); #ifdef CONFIG_USB_G_DBGP_PRINTK err = dbgp_enable_ep(); #else
commit 2d148ea63fe50bf30071cb3e6c87fbd32c081cba Author: Vladimir Serbinenko <phcoder@gmail.com> Date: Tue May 26 21:35:06 2015 +0200 dbgp: Supply config descriptor and accept set config command. This descriptor and commands are part of core USB specification and every USB device should have one. When g_dbgp is used in early printk or in coreboot through EHCI debug those descriptors are never read and hence this doesn't create a problem. However for coreboot payloads with full USB stack or Linux once booted those descriptors are essential, so without them both GRUB-as-payload and Linux refuse to recognize it. Tested and works as expected in coreboot and GRUB. Booted Linux recognizes and it works the same way as Net20DC if I change USBID. early_printk=dbgp is not tested for lack of kernel with this feature enabled under my hand. Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com> diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c index 204b10b..256876ddd 100644 --- a/drivers/usb/gadget/legacy/dbgp.c +++ b/drivers/usb/gadget/legacy/dbgp.c @@ -18,7 +18,7 @@ #define DRIVER_VENDOR_ID 0x0525 /* NetChip */ #define DRIVER_PRODUCT_ID 0xc0de /* undefined */ -#define USB_DEBUG_MAX_PACKET_SIZE 8 +#define USB_DEBUG_MAX_PACKET_SIZE 512 #define DBGP_REQ_EP0_LEN 128 #define DBGP_REQ_LEN 512 @@ -61,6 +61,35 @@ static struct usb_endpoint_descriptor o_desc = { .bEndpointAddress = USB_DIR_OUT, }; +struct full_config_desc { + struct usb_config_descriptor config_desc; + struct usb_interface_descriptor iface_desc; + u8 ep[2 * USB_DT_ENDPOINT_SIZE]; +}; + +static struct usb_config_descriptor config_desc = { + .bLength = sizeof (struct usb_config_descriptor), + .bDescriptorType = USB_DT_CONFIG, + .wTotalLength = __constant_cpu_to_le16(sizeof (struct full_config_desc)), + .bNumInterfaces = 1, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = 0xc0, + .bMaxPower = 0, +}; + +static struct usb_interface_descriptor iface_desc = { + .bLength = sizeof (struct usb_interface_descriptor), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = 0, +}; + #ifdef CONFIG_USB_G_DBGP_PRINTK static int dbgp_consume(char *buf, unsigned len) { @@ -355,6 +384,7 @@ static int dbgp_setup(struct usb_gadget *gadget, int err = -EOPNOTSUPP; void *data = NULL; u16 len = 0; + struct full_config_desc full_cfg_desc; gadget->ep0->driver_data = gadget; @@ -371,13 +401,26 @@ static int dbgp_setup(struct usb_gadget *gadget, len = sizeof dbg_desc; data = &dbg_desc; break; + case USB_DT_CONFIG: + dev_dbg(&dbgp.gadget->dev, "setup: desc config\n"); + full_cfg_desc.config_desc = config_desc; + full_cfg_desc.iface_desc = iface_desc; + memcpy(full_cfg_desc.ep, &i_desc, USB_DT_ENDPOINT_SIZE); + memcpy(full_cfg_desc.ep + USB_DT_ENDPOINT_SIZE, &o_desc, USB_DT_ENDPOINT_SIZE); + data = &full_cfg_desc; + len = sizeof full_cfg_desc; + break; default: goto fail; } err = 0; - } else if (request == USB_REQ_SET_FEATURE && - value == USB_DEVICE_DEBUG_MODE) { - dev_dbg(&dbgp.gadget->dev, "setup: feat debug\n"); + } else if ((request == USB_REQ_SET_FEATURE && + value == USB_DEVICE_DEBUG_MODE) + || (request == USB_REQ_SET_CONFIGURATION && value == 1)) { + if (request == USB_REQ_SET_FEATURE) + dev_dbg(&dbgp.gadget->dev, "setup: feat debug\n"); + else + dev_dbg(&dbgp.gadget->dev, "setup: config 1\n"); #ifdef CONFIG_USB_G_DBGP_PRINTK err = dbgp_enable_ep(); #else
Attachment:
signature.asc
Description: OpenPGP digital signature