qmi-wwan: use common parser

This moves qmi-wwan to the common parser for CDC user
to reduce code duplication.

Signed-off-by: Oliver Neukum <oneukum@suse.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Oliver Neukum 2015-09-07 16:05:41 +02:00 committed by David S. Miller
parent 823bd34334
commit 8492ed45aa

View File

@ -229,11 +229,11 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
u8 *buf = intf->cur_altsetting->extra; u8 *buf = intf->cur_altsetting->extra;
int len = intf->cur_altsetting->extralen; int len = intf->cur_altsetting->extralen;
struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc; struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc;
struct usb_cdc_union_desc *cdc_union = NULL; struct usb_cdc_union_desc *cdc_union;
struct usb_cdc_ether_desc *cdc_ether = NULL; struct usb_cdc_ether_desc *cdc_ether;
u32 found = 0;
struct usb_driver *driver = driver_of(intf); struct usb_driver *driver = driver_of(intf);
struct qmi_wwan_state *info = (void *)&dev->data; struct qmi_wwan_state *info = (void *)&dev->data;
struct usb_cdc_parsed_header hdr;
BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) < BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) <
sizeof(struct qmi_wwan_state))); sizeof(struct qmi_wwan_state)));
@ -243,63 +243,9 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
info->data = intf; info->data = intf;
/* and a number of CDC descriptors */ /* and a number of CDC descriptors */
while (len > 3) { cdc_parse_cdc_header(&hdr, intf, buf, len);
struct usb_descriptor_header *h = (void *)buf; cdc_union = hdr.usb_cdc_union_desc;
cdc_ether = hdr.usb_cdc_ether_desc;
/* ignore any misplaced descriptors */
if (h->bDescriptorType != USB_DT_CS_INTERFACE)
goto next_desc;
/* buf[2] is CDC descriptor subtype */
switch (buf[2]) {
case USB_CDC_HEADER_TYPE:
if (found & 1 << USB_CDC_HEADER_TYPE) {
dev_dbg(&intf->dev, "extra CDC header\n");
goto err;
}
if (h->bLength != sizeof(struct usb_cdc_header_desc)) {
dev_dbg(&intf->dev, "CDC header len %u\n",
h->bLength);
goto err;
}
break;
case USB_CDC_UNION_TYPE:
if (found & 1 << USB_CDC_UNION_TYPE) {
dev_dbg(&intf->dev, "extra CDC union\n");
goto err;
}
if (h->bLength != sizeof(struct usb_cdc_union_desc)) {
dev_dbg(&intf->dev, "CDC union len %u\n",
h->bLength);
goto err;
}
cdc_union = (struct usb_cdc_union_desc *)buf;
break;
case USB_CDC_ETHERNET_TYPE:
if (found & 1 << USB_CDC_ETHERNET_TYPE) {
dev_dbg(&intf->dev, "extra CDC ether\n");
goto err;
}
if (h->bLength != sizeof(struct usb_cdc_ether_desc)) {
dev_dbg(&intf->dev, "CDC ether len %u\n",
h->bLength);
goto err;
}
cdc_ether = (struct usb_cdc_ether_desc *)buf;
break;
}
/* Remember which CDC functional descriptors we've seen. Works
* for all types we care about, of which USB_CDC_ETHERNET_TYPE
* (0x0f) is the highest numbered
*/
if (buf[2] < 32)
found |= 1 << buf[2];
next_desc:
len -= h->bLength;
buf += h->bLength;
}
/* Use separate control and data interfaces if we found a CDC Union */ /* Use separate control and data interfaces if we found a CDC Union */
if (cdc_union) { if (cdc_union) {