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:
Pavankumar Kondeti
2012-11-05 12:59:11 +05:30
committed by Manu Gautam
parent 7028e4d0a9
commit 6f94bc9840
6 changed files with 376 additions and 0 deletions
+54
View File
@@ -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;
+52
View File
@@ -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;
+66
View File
@@ -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)
+78
View File
@@ -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;
+89
View File
@@ -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;
+37
View File
@@ -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