diff options
author | Oliver Neukum <oneukum@suse.com> | 2015-09-07 16:05:39 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-09-15 12:43:19 -0700 |
commit | 77b0a099674ac1c43b631445d8d50453e4805b29 (patch) | |
tree | 55936fb926714c712da9fec3b47ff191c98417b9 /drivers/net/usb/cdc_ncm.c | |
parent | c40a2c8817e42273a4627c48c884b805475a733f (diff) | |
download | lwn-77b0a099674ac1c43b631445d8d50453e4805b29.tar.gz lwn-77b0a099674ac1c43b631445d8d50453e4805b29.zip |
cdc-ncm: use common parser
This moves cdc-ncm 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>
Diffstat (limited to 'drivers/net/usb/cdc_ncm.c')
-rw-r--r-- | drivers/net/usb/cdc_ncm.c | 69 |
1 files changed, 9 insertions, 60 deletions
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index db40175b1a0b..a187f08113ec 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -698,6 +698,7 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_ int len; int temp; u8 iface_no; + struct usb_cdc_parsed_header hdr; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) @@ -722,66 +723,14 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_ len = intf->cur_altsetting->extralen; /* parse through descriptors associated with control interface */ - while ((len > 0) && (buf[0] > 2) && (buf[0] <= len)) { - - if (buf[1] != USB_DT_CS_INTERFACE) - goto advance; - - switch (buf[2]) { - case USB_CDC_UNION_TYPE: - if (buf[0] < sizeof(*union_desc)) - break; - - union_desc = (const struct usb_cdc_union_desc *)buf; - /* the master must be the interface we are probing */ - if (intf->cur_altsetting->desc.bInterfaceNumber != - union_desc->bMasterInterface0) { - dev_dbg(&intf->dev, "bogus CDC Union\n"); - goto error; - } - ctx->data = usb_ifnum_to_if(dev->udev, - union_desc->bSlaveInterface0); - break; - - case USB_CDC_ETHERNET_TYPE: - if (buf[0] < sizeof(*(ctx->ether_desc))) - break; - - ctx->ether_desc = - (const struct usb_cdc_ether_desc *)buf; - break; - - case USB_CDC_NCM_TYPE: - if (buf[0] < sizeof(*(ctx->func_desc))) - break; - - ctx->func_desc = (const struct usb_cdc_ncm_desc *)buf; - break; - - case USB_CDC_MBIM_TYPE: - if (buf[0] < sizeof(*(ctx->mbim_desc))) - break; - - ctx->mbim_desc = (const struct usb_cdc_mbim_desc *)buf; - break; - - case USB_CDC_MBIM_EXTENDED_TYPE: - if (buf[0] < sizeof(*(ctx->mbim_extended_desc))) - break; - - ctx->mbim_extended_desc = - (const struct usb_cdc_mbim_extended_desc *)buf; - break; - - default: - break; - } -advance: - /* advance to next descriptor */ - temp = buf[0]; - buf += temp; - len -= temp; - } + cdc_parse_cdc_header(&hdr, intf, buf, len); + + ctx->data = usb_ifnum_to_if(dev->udev, + hdr.usb_cdc_union_desc->bSlaveInterface0); + ctx->ether_desc = hdr.usb_cdc_ether_desc; + ctx->func_desc = hdr.usb_cdc_ncm_desc; + ctx->mbim_desc = hdr.usb_cdc_mbim_desc; + ctx->mbim_extended_desc = hdr.usb_cdc_mbim_extended_desc; /* some buggy devices have an IAD but no CDC Union */ if (!union_desc && intf->intf_assoc && intf->intf_assoc->bInterfaceCount == 2) { |