From 373f05b16af8013ad95717d2a6bf952d3357760a Mon Sep 17 00:00:00 2001 From: Mayank Rana Date: Mon, 9 Mar 2015 11:31:18 -0700 Subject: [PATCH] usb: gadget: ncm: Add super speed descriptors for NCM function This change adds super speed descriptors which is required to get NCM function to work with SSUSB mode. The burst capability is not enabled for now. CRs-Fixed: 804486 Change-Id: I6239ad9e64969afb4e9af87d76837b940c3d1348 Signed-off-by: Mayank Rana --- drivers/usb/gadget/function/f_ncm.c | 82 ++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index 7ad798ace1e5..4e35ed9654b7 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c @@ -333,6 +333,77 @@ static struct usb_descriptor_header *ncm_hs_function[] = { NULL, }; +/* Super Speed Support */ +static struct usb_endpoint_descriptor ncm_ss_notify_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_INT, + .wMaxPacketSize = cpu_to_le16(NCM_STATUS_BYTECOUNT), + .bInterval = USB_MS_TO_HS_INTERVAL(NCM_STATUS_INTERVAL_MS), +}; + +static struct usb_ss_ep_comp_descriptor ncm_ss_notify_comp_desc = { + .bLength = sizeof(ncm_ss_notify_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + /* the following 3 values can be tweaked if necessary */ + /* .bMaxBurst = 0, */ + /* .bmAttributes = 0, */ + .wBytesPerInterval = cpu_to_le16(NCM_STATUS_BYTECOUNT), +}; + +static struct usb_endpoint_descriptor ncm_ss_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(1024), +}; + +static struct usb_ss_ep_comp_descriptor ncm_ss_in_comp_desc = { + .bLength = sizeof(ncm_ss_in_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + /* the following 2 values can be tweaked if necessary */ + /* .bMaxBurst = 0, */ + /* .bmAttributes = 0, */ +}; + +static struct usb_endpoint_descriptor ncm_ss_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(1024), +}; + +static struct usb_ss_ep_comp_descriptor ncm_ss_out_comp_desc = { + .bLength = sizeof(ncm_ss_out_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + /* the following 2 values can be tweaked if necessary */ + /* .bMaxBurst = 0, */ + /* .bmAttributes = 0, */ +}; + +static struct usb_descriptor_header *ncm_ss_function[] = { + (struct usb_descriptor_header *) &ncm_iad_desc, + /* CDC NCM control descriptors */ + (struct usb_descriptor_header *) &ncm_control_intf, + (struct usb_descriptor_header *) &ncm_header_desc, + (struct usb_descriptor_header *) &ncm_union_desc, + (struct usb_descriptor_header *) &ecm_desc, + (struct usb_descriptor_header *) &ncm_desc, + (struct usb_descriptor_header *) &ncm_ss_notify_desc, + (struct usb_descriptor_header *) &ncm_ss_notify_comp_desc, + /* data interface, altsettings 0 and 1 */ + (struct usb_descriptor_header *) &ncm_data_nop_intf, + (struct usb_descriptor_header *) &ncm_data_intf, + (struct usb_descriptor_header *) &ncm_ss_in_desc, + (struct usb_descriptor_header *) &ncm_ss_in_comp_desc, + (struct usb_descriptor_header *) &ncm_ss_out_desc, + (struct usb_descriptor_header *) &ncm_ss_out_comp_desc, + NULL, +}; + /* string descriptors: */ #define STRING_CTRL_IDX 0 @@ -1431,8 +1502,17 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) hs_ncm_notify_desc.bEndpointAddress = fs_ncm_notify_desc.bEndpointAddress; + if (gadget_is_superspeed(c->cdev->gadget)) { + ncm_ss_in_desc.bEndpointAddress = + fs_ncm_in_desc.bEndpointAddress; + ncm_ss_out_desc.bEndpointAddress = + fs_ncm_out_desc.bEndpointAddress; + ncm_ss_notify_desc.bEndpointAddress = + fs_ncm_notify_desc.bEndpointAddress; + } + status = usb_assign_descriptors(f, ncm_fs_function, ncm_hs_function, - NULL); + ncm_ss_function); if (status) goto fail;