forked from rubenslte/android_kernel_samsung_msm8226
USB: Add super speed descriptors for android functions
Update android function drivers like diag, adb, modem, rmnet, mtp and accessory to operate in super speed. The burst capability is not enabled for now. Change-Id: Ie95cbfc9444c56c8268b70e2916713190699c71a Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
This commit is contained in:
committed by
Manu Gautam
parent
7028e4d0a9
commit
6f94bc9840
@@ -132,6 +132,41 @@ static struct usb_interface_descriptor acc_interface_desc = {
|
||||
.bInterfaceProtocol = 0,
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor acc_superspeed_in_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(1024),
|
||||
};
|
||||
|
||||
static struct usb_ss_ep_comp_descriptor acc_superspeed_in_comp_desc = {
|
||||
.bLength = sizeof acc_superspeed_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 acc_superspeed_out_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(1024),
|
||||
};
|
||||
|
||||
static struct usb_ss_ep_comp_descriptor acc_superspeed_out_comp_desc = {
|
||||
.bLength = sizeof acc_superspeed_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_endpoint_descriptor acc_highspeed_in_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
@@ -176,6 +211,15 @@ static struct usb_descriptor_header *hs_acc_descs[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *ss_acc_descs[] = {
|
||||
(struct usb_descriptor_header *) &acc_interface_desc,
|
||||
(struct usb_descriptor_header *) &acc_superspeed_in_desc,
|
||||
(struct usb_descriptor_header *) &acc_superspeed_in_comp_desc,
|
||||
(struct usb_descriptor_header *) &acc_superspeed_out_desc,
|
||||
(struct usb_descriptor_header *) &acc_superspeed_out_comp_desc,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct usb_string acc_string_defs[] = {
|
||||
[INTERFACE_STRING_INDEX].s = "Android Accessory Interface",
|
||||
{ }, /* end of list */
|
||||
@@ -907,6 +951,14 @@ acc_function_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
acc_fullspeed_out_desc.bEndpointAddress;
|
||||
}
|
||||
|
||||
/* support super speed hardware */
|
||||
if (gadget_is_superspeed(c->cdev->gadget)) {
|
||||
acc_superspeed_in_desc.bEndpointAddress =
|
||||
acc_fullspeed_in_desc.bEndpointAddress;
|
||||
acc_superspeed_out_desc.bEndpointAddress =
|
||||
acc_fullspeed_out_desc.bEndpointAddress;
|
||||
}
|
||||
|
||||
DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
|
||||
gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
|
||||
f->name, dev->ep_in->name, dev->ep_out->name);
|
||||
@@ -1135,6 +1187,8 @@ static int acc_bind_config(struct usb_configuration *c)
|
||||
dev->function.strings = acc_strings,
|
||||
dev->function.descriptors = fs_acc_descs;
|
||||
dev->function.hs_descriptors = hs_acc_descs;
|
||||
if (gadget_is_superspeed(c->cdev->gadget))
|
||||
dev->function.ss_descriptors = ss_acc_descs;
|
||||
dev->function.bind = acc_function_bind;
|
||||
dev->function.unbind = acc_function_unbind;
|
||||
dev->function.set_alt = acc_function_set_alt;
|
||||
|
||||
@@ -69,6 +69,40 @@ static struct usb_interface_descriptor adb_interface_desc = {
|
||||
.bInterfaceProtocol = 1,
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor adb_superspeed_in_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(1024),
|
||||
};
|
||||
|
||||
static struct usb_ss_ep_comp_descriptor adb_superspeed_in_comp_desc = {
|
||||
.bLength = sizeof adb_superspeed_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 adb_superspeed_out_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(1024),
|
||||
};
|
||||
|
||||
static struct usb_ss_ep_comp_descriptor adb_superspeed_out_comp_desc = {
|
||||
.bLength = sizeof adb_superspeed_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_endpoint_descriptor adb_highspeed_in_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
@@ -113,6 +147,15 @@ static struct usb_descriptor_header *hs_adb_descs[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *ss_adb_descs[] = {
|
||||
(struct usb_descriptor_header *) &adb_interface_desc,
|
||||
(struct usb_descriptor_header *) &adb_superspeed_in_desc,
|
||||
(struct usb_descriptor_header *) &adb_superspeed_in_comp_desc,
|
||||
(struct usb_descriptor_header *) &adb_superspeed_out_desc,
|
||||
(struct usb_descriptor_header *) &adb_superspeed_out_comp_desc,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static void adb_ready_callback(void);
|
||||
static void adb_closed_callback(void);
|
||||
|
||||
@@ -503,6 +546,13 @@ adb_function_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
adb_highspeed_out_desc.bEndpointAddress =
|
||||
adb_fullspeed_out_desc.bEndpointAddress;
|
||||
}
|
||||
/* support super speed hardware */
|
||||
if (gadget_is_superspeed(c->cdev->gadget)) {
|
||||
adb_superspeed_in_desc.bEndpointAddress =
|
||||
adb_fullspeed_in_desc.bEndpointAddress;
|
||||
adb_superspeed_out_desc.bEndpointAddress =
|
||||
adb_fullspeed_out_desc.bEndpointAddress;
|
||||
}
|
||||
|
||||
DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
|
||||
gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
|
||||
@@ -605,6 +655,8 @@ static int adb_bind_config(struct usb_configuration *c)
|
||||
dev->function.name = "adb";
|
||||
dev->function.descriptors = fs_adb_descs;
|
||||
dev->function.hs_descriptors = hs_adb_descs;
|
||||
if (gadget_is_superspeed(c->cdev->gadget))
|
||||
dev->function.ss_descriptors = ss_adb_descs;
|
||||
dev->function.bind = adb_function_bind;
|
||||
dev->function.unbind = adb_function_unbind;
|
||||
dev->function.set_alt = adb_function_set_alt;
|
||||
|
||||
@@ -73,6 +73,40 @@ static struct usb_endpoint_descriptor fs_bulk_out_desc = {
|
||||
.bInterval = 0,
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor ss_bulk_in_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(1024),
|
||||
};
|
||||
|
||||
static struct usb_ss_ep_comp_descriptor ss_bulk_in_comp_desc = {
|
||||
.bLength = sizeof ss_bulk_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 ss_bulk_out_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(1024),
|
||||
};
|
||||
|
||||
static struct usb_ss_ep_comp_descriptor ss_bulk_out_comp_desc = {
|
||||
.bLength = sizeof ss_bulk_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 *fs_diag_desc[] = {
|
||||
(struct usb_descriptor_header *) &intf_desc,
|
||||
(struct usb_descriptor_header *) &fs_bulk_in_desc,
|
||||
@@ -86,6 +120,15 @@ static struct usb_descriptor_header *hs_diag_desc[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *ss_diag_desc[] = {
|
||||
(struct usb_descriptor_header *) &intf_desc,
|
||||
(struct usb_descriptor_header *) &ss_bulk_in_desc,
|
||||
(struct usb_descriptor_header *) &ss_bulk_in_comp_desc,
|
||||
(struct usb_descriptor_header *) &ss_bulk_out_desc,
|
||||
(struct usb_descriptor_header *) &ss_bulk_out_comp_desc,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct diag_context - USB diag function driver private structure
|
||||
* @function: function structure for USB interface
|
||||
@@ -551,6 +594,8 @@ static void diag_function_unbind(struct usb_configuration *c,
|
||||
{
|
||||
struct diag_context *ctxt = func_to_diag(f);
|
||||
|
||||
if (gadget_is_superspeed(c->cdev->gadget))
|
||||
usb_free_descriptors(f->ss_descriptors);
|
||||
if (gadget_is_dualspeed(c->cdev->gadget))
|
||||
usb_free_descriptors(f->hs_descriptors);
|
||||
|
||||
@@ -580,6 +625,7 @@ static int diag_function_bind(struct usb_configuration *c,
|
||||
ctxt->out = ep;
|
||||
ep->driver_data = ctxt;
|
||||
|
||||
status = -ENOMEM;
|
||||
/* copy descriptors, and track endpoint copies */
|
||||
f->descriptors = usb_copy_descriptors(fs_diag_desc);
|
||||
if (!f->descriptors)
|
||||
@@ -593,9 +639,29 @@ static int diag_function_bind(struct usb_configuration *c,
|
||||
|
||||
/* copy descriptors, and track endpoint copies */
|
||||
f->hs_descriptors = usb_copy_descriptors(hs_diag_desc);
|
||||
if (!f->hs_descriptors)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (gadget_is_superspeed(c->cdev->gadget)) {
|
||||
ss_bulk_in_desc.bEndpointAddress =
|
||||
fs_bulk_in_desc.bEndpointAddress;
|
||||
ss_bulk_out_desc.bEndpointAddress =
|
||||
fs_bulk_out_desc.bEndpointAddress;
|
||||
|
||||
/* copy descriptors, and track endpoint copies */
|
||||
f->ss_descriptors = usb_copy_descriptors(ss_diag_desc);
|
||||
if (!f->ss_descriptors)
|
||||
goto fail;
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
if (f->ss_descriptors)
|
||||
usb_free_descriptors(f->ss_descriptors);
|
||||
if (f->hs_descriptors)
|
||||
usb_free_descriptors(f->hs_descriptors);
|
||||
if (f->descriptors)
|
||||
usb_free_descriptors(f->descriptors);
|
||||
if (ctxt->out)
|
||||
ctxt->out->driver_data = NULL;
|
||||
if (ctxt->in)
|
||||
|
||||
@@ -129,6 +129,40 @@ static struct usb_interface_descriptor ptp_interface_desc = {
|
||||
.bInterfaceProtocol = 1,
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor mtp_superspeed_in_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(1024),
|
||||
};
|
||||
|
||||
static struct usb_ss_ep_comp_descriptor mtp_superspeed_in_comp_desc = {
|
||||
.bLength = sizeof mtp_superspeed_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 mtp_superspeed_out_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(1024),
|
||||
};
|
||||
|
||||
static struct usb_ss_ep_comp_descriptor mtp_superspeed_out_comp_desc = {
|
||||
.bLength = sizeof mtp_superspeed_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_endpoint_descriptor mtp_highspeed_in_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
@@ -168,6 +202,16 @@ static struct usb_endpoint_descriptor mtp_intr_desc = {
|
||||
.bInterval = 6,
|
||||
};
|
||||
|
||||
static struct usb_ss_ep_comp_descriptor mtp_superspeed_intr_comp_desc = {
|
||||
.bLength = sizeof mtp_superspeed_intr_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(INTR_BUFFER_SIZE),
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *fs_mtp_descs[] = {
|
||||
(struct usb_descriptor_header *) &mtp_interface_desc,
|
||||
(struct usb_descriptor_header *) &mtp_fullspeed_in_desc,
|
||||
@@ -184,6 +228,17 @@ static struct usb_descriptor_header *hs_mtp_descs[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *ss_mtp_descs[] = {
|
||||
(struct usb_descriptor_header *) &mtp_interface_desc,
|
||||
(struct usb_descriptor_header *) &mtp_superspeed_in_desc,
|
||||
(struct usb_descriptor_header *) &mtp_superspeed_in_comp_desc,
|
||||
(struct usb_descriptor_header *) &mtp_superspeed_out_desc,
|
||||
(struct usb_descriptor_header *) &mtp_superspeed_out_comp_desc,
|
||||
(struct usb_descriptor_header *) &mtp_intr_desc,
|
||||
(struct usb_descriptor_header *) &mtp_superspeed_intr_comp_desc,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *fs_ptp_descs[] = {
|
||||
(struct usb_descriptor_header *) &ptp_interface_desc,
|
||||
(struct usb_descriptor_header *) &mtp_fullspeed_in_desc,
|
||||
@@ -200,6 +255,17 @@ static struct usb_descriptor_header *hs_ptp_descs[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *ss_ptp_descs[] = {
|
||||
(struct usb_descriptor_header *) &ptp_interface_desc,
|
||||
(struct usb_descriptor_header *) &mtp_superspeed_in_desc,
|
||||
(struct usb_descriptor_header *) &mtp_superspeed_in_comp_desc,
|
||||
(struct usb_descriptor_header *) &mtp_superspeed_out_desc,
|
||||
(struct usb_descriptor_header *) &mtp_superspeed_out_comp_desc,
|
||||
(struct usb_descriptor_header *) &mtp_intr_desc,
|
||||
(struct usb_descriptor_header *) &mtp_superspeed_intr_comp_desc,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct usb_string mtp_string_defs[] = {
|
||||
/* Naming interface "MTP" so libmtp will recognize us */
|
||||
[INTERFACE_STRING_INDEX].s = "MTP",
|
||||
@@ -1126,6 +1192,14 @@ mtp_function_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
mtp_fullspeed_out_desc.bEndpointAddress;
|
||||
}
|
||||
|
||||
/* support super speed hardware */
|
||||
if (gadget_is_superspeed(c->cdev->gadget)) {
|
||||
mtp_superspeed_in_desc.bEndpointAddress =
|
||||
mtp_fullspeed_in_desc.bEndpointAddress;
|
||||
mtp_superspeed_out_desc.bEndpointAddress =
|
||||
mtp_fullspeed_out_desc.bEndpointAddress;
|
||||
}
|
||||
|
||||
DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
|
||||
gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
|
||||
f->name, dev->ep_in->name, dev->ep_out->name);
|
||||
@@ -1239,9 +1313,13 @@ static int mtp_bind_config(struct usb_configuration *c, bool ptp_config)
|
||||
if (ptp_config) {
|
||||
dev->function.descriptors = fs_ptp_descs;
|
||||
dev->function.hs_descriptors = hs_ptp_descs;
|
||||
if (gadget_is_superspeed(c->cdev->gadget))
|
||||
dev->function.ss_descriptors = ss_ptp_descs;
|
||||
} else {
|
||||
dev->function.descriptors = fs_mtp_descs;
|
||||
dev->function.hs_descriptors = hs_mtp_descs;
|
||||
if (gadget_is_superspeed(c->cdev->gadget))
|
||||
dev->function.ss_descriptors = ss_mtp_descs;
|
||||
}
|
||||
dev->function.bind = mtp_function_bind;
|
||||
dev->function.unbind = mtp_function_unbind;
|
||||
|
||||
@@ -147,6 +147,71 @@ static struct usb_descriptor_header *rmnet_hs_function[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* Super speed support */
|
||||
static struct usb_endpoint_descriptor rmnet_ss_notify_desc = {
|
||||
.bLength = sizeof rmnet_ss_notify_desc,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(RMNET_MAX_NOTIFY_SIZE),
|
||||
.bInterval = RMNET_NOTIFY_INTERVAL + 4,
|
||||
};
|
||||
|
||||
static struct usb_ss_ep_comp_descriptor rmnet_ss_notify_comp_desc = {
|
||||
.bLength = sizeof rmnet_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(RMNET_MAX_NOTIFY_SIZE),
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor rmnet_ss_in_desc = {
|
||||
.bLength = sizeof rmnet_ss_in_desc,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(1024),
|
||||
};
|
||||
|
||||
static struct usb_ss_ep_comp_descriptor rmnet_ss_in_comp_desc = {
|
||||
.bLength = sizeof rmnet_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 rmnet_ss_out_desc = {
|
||||
.bLength = sizeof rmnet_ss_out_desc,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(1024),
|
||||
};
|
||||
|
||||
static struct usb_ss_ep_comp_descriptor rmnet_ss_out_comp_desc = {
|
||||
.bLength = sizeof rmnet_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 *rmnet_ss_function[] = {
|
||||
(struct usb_descriptor_header *) &rmnet_interface_desc,
|
||||
(struct usb_descriptor_header *) &rmnet_ss_notify_desc,
|
||||
(struct usb_descriptor_header *) &rmnet_ss_notify_comp_desc,
|
||||
(struct usb_descriptor_header *) &rmnet_ss_in_desc,
|
||||
(struct usb_descriptor_header *) &rmnet_ss_in_comp_desc,
|
||||
(struct usb_descriptor_header *) &rmnet_ss_out_desc,
|
||||
(struct usb_descriptor_header *) &rmnet_ss_out_comp_desc,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* String descriptors */
|
||||
|
||||
static struct usb_string rmnet_string_defs[] = {
|
||||
@@ -460,6 +525,8 @@ static void frmnet_unbind(struct usb_configuration *c, struct usb_function *f)
|
||||
|
||||
pr_debug("%s: portno:%d\n", __func__, dev->port_num);
|
||||
|
||||
if (gadget_is_superspeed(c->cdev->gadget))
|
||||
usb_free_descriptors(f->ss_descriptors);
|
||||
if (gadget_is_dualspeed(c->cdev->gadget))
|
||||
usb_free_descriptors(f->hs_descriptors);
|
||||
usb_free_descriptors(f->descriptors);
|
||||
@@ -964,6 +1031,7 @@ static int frmnet_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
dev->notify_req->complete = frmnet_notify_complete;
|
||||
dev->notify_req->context = dev;
|
||||
|
||||
ret = -ENOMEM;
|
||||
f->descriptors = usb_copy_descriptors(rmnet_fs_function);
|
||||
|
||||
if (!f->descriptors)
|
||||
@@ -984,6 +1052,21 @@ static int frmnet_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (gadget_is_superspeed(cdev->gadget)) {
|
||||
rmnet_ss_in_desc.bEndpointAddress =
|
||||
rmnet_fs_in_desc.bEndpointAddress;
|
||||
rmnet_ss_out_desc.bEndpointAddress =
|
||||
rmnet_fs_out_desc.bEndpointAddress;
|
||||
rmnet_ss_notify_desc.bEndpointAddress =
|
||||
rmnet_fs_notify_desc.bEndpointAddress;
|
||||
|
||||
/* copy descriptors, and track endpoint copies */
|
||||
f->ss_descriptors = usb_copy_descriptors(rmnet_ss_function);
|
||||
|
||||
if (!f->ss_descriptors)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pr_info("%s: RmNet(%d) %s Speed, IN:%s OUT:%s\n",
|
||||
__func__, dev->port_num,
|
||||
gadget_is_dualspeed(cdev->gadget) ? "dual" : "full",
|
||||
@@ -992,8 +1075,14 @@ static int frmnet_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (f->ss_descriptors)
|
||||
usb_free_descriptors(f->ss_descriptors);
|
||||
if (f->hs_descriptors)
|
||||
usb_free_descriptors(f->hs_descriptors);
|
||||
if (f->descriptors)
|
||||
usb_free_descriptors(f->descriptors);
|
||||
if (dev->notify_req)
|
||||
frmnet_free_req(dev->notify, dev->notify_req);
|
||||
ep_notify_alloc_fail:
|
||||
dev->notify->driver_data = NULL;
|
||||
dev->notify = NULL;
|
||||
|
||||
@@ -244,8 +244,37 @@ static struct usb_ss_ep_comp_descriptor gser_ss_bulk_comp_desc = {
|
||||
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MODEM_SUPPORT
|
||||
static struct usb_endpoint_descriptor gser_ss_notify_desc = {
|
||||
.bLength = sizeof gser_ss_notify_desc,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
.wMaxPacketSize = __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET),
|
||||
.bInterval = GS_LOG2_NOTIFY_INTERVAL+4,
|
||||
};
|
||||
|
||||
static struct usb_ss_ep_comp_descriptor gser_ss_notify_comp_desc = {
|
||||
.bLength = sizeof gser_ss_notify_comp_desc,
|
||||
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
||||
|
||||
/* the following 2 values can be tweaked if necessary */
|
||||
/* .bMaxBurst = 0, */
|
||||
/* .bmAttributes = 0, */
|
||||
.wBytesPerInterval = cpu_to_le16(GS_NOTIFY_MAXPACKET),
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct usb_descriptor_header *gser_ss_function[] = {
|
||||
(struct usb_descriptor_header *) &gser_interface_desc,
|
||||
#ifdef CONFIG_MODEM_SUPPORT
|
||||
(struct usb_descriptor_header *) &gser_header_desc,
|
||||
(struct usb_descriptor_header *) &gser_call_mgmt_descriptor,
|
||||
(struct usb_descriptor_header *) &gser_descriptor,
|
||||
(struct usb_descriptor_header *) &gser_union_desc,
|
||||
(struct usb_descriptor_header *) &gser_ss_notify_desc,
|
||||
(struct usb_descriptor_header *) &gser_ss_notify_comp_desc,
|
||||
#endif
|
||||
(struct usb_descriptor_header *) &gser_ss_in_desc,
|
||||
(struct usb_descriptor_header *) &gser_ss_bulk_comp_desc,
|
||||
(struct usb_descriptor_header *) &gser_ss_out_desc,
|
||||
@@ -821,6 +850,10 @@ gser_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
gser_fs_in_desc.bEndpointAddress;
|
||||
gser_ss_out_desc.bEndpointAddress =
|
||||
gser_fs_out_desc.bEndpointAddress;
|
||||
#ifdef CONFIG_MODEM_SUPPORT
|
||||
gser_ss_notify_desc.bEndpointAddress =
|
||||
gser_fs_notify_desc.bEndpointAddress;
|
||||
#endif
|
||||
|
||||
/* copy descriptors, and track endpoint copies */
|
||||
f->ss_descriptors = usb_copy_descriptors(gser_ss_function);
|
||||
@@ -836,6 +869,10 @@ gser_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (f->ss_descriptors)
|
||||
usb_free_descriptors(f->ss_descriptors);
|
||||
if (f->hs_descriptors)
|
||||
usb_free_descriptors(f->hs_descriptors);
|
||||
if (f->descriptors)
|
||||
usb_free_descriptors(f->descriptors);
|
||||
#ifdef CONFIG_MODEM_SUPPORT
|
||||
|
||||
Reference in New Issue
Block a user