CTC++ Coverage Report - Execution Profile    #640/1532

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last


File: drivers/usb/gadget/ether.c
Instrumentation mode: function-decision-multicondition
TER: 0 % ( 0/818)

Start/ End/    
True False - Line Source

  1 /*
  2  * ether.c -- Ethernet gadget driver, with CDC and non-CDC options
  3  *
  4  * Copyright (C) 2003-2005 David Brownell
  5  * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
  6  *
  7  * This program is free software; you can redistribute it and/or modify
  8  * it under the terms of the GNU General Public License as published by
  9  * the Free Software Foundation; either version 2 of the License, or
  10  * (at your option) any later version.
  11  *
  12  * This program is distributed in the hope that it will be useful,
  13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15  * GNU General Public License for more details.
  16  *
  17  * You should have received a copy of the GNU General Public License
  18  * along with this program; if not, write to the Free Software
  19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  20  */
  21 
  22 
  23 // #define DEBUG 1
  24 // #define VERBOSE
  25 
  26 #include <linux/config.h>
  27 #include <linux/module.h>
  28 #include <linux/kernel.h>
  29 #include <linux/delay.h>
  30 #include <linux/ioport.h>
  31 #include <linux/sched.h>
  32 #include <linux/slab.h>
  33 #include <linux/smp_lock.h>
  34 #include <linux/errno.h>
  35 #include <linux/init.h>
  36 #include <linux/timer.h>
  37 #include <linux/list.h>
  38 #include <linux/interrupt.h>
  39 #include <linux/utsname.h>
  40 #include <linux/device.h>
  41 #include <linux/moduleparam.h>
  42 #include <linux/ctype.h>
  43 
  44 #include <asm/byteorder.h>
  45 #include <asm/io.h>
  46 #include <asm/irq.h>
  47 #include <asm/system.h>
  48 #include <asm/uaccess.h>
  49 #include <asm/unaligned.h>
  50 
  51 #include <linux/usb_ch9.h>
  52 #include <linux/usb_cdc.h>
  53 #include <linux/usb_gadget.h>
  54 
  55 #include <linux/random.h>
  56 #include <linux/netdevice.h>
  57 #include <linux/etherdevice.h>
  58 #include <linux/ethtool.h>
  59 
  60 #include "gadget_chips.h"
  61 
  62 /*-------------------------------------------------------------------------*/
  63 
  64 /*
  65  * Ethernet gadget driver -- with CDC and non-CDC options
  66  * Builds on hardware support for a full duplex link.
  67  *
  68  * CDC Ethernet is the standard USB solution for sending Ethernet frames
  69  * using USB.  Real hardware tends to use the same framing protocol but look
  70  * different for control features.  This driver strongly prefers to use
  71  * this USB-IF standard as its open-systems interoperability solution;
  72  * most host side USB stacks (except from Microsoft) support it.
  73  *
  74  * There's some hardware that can't talk CDC.  We make that hardware
  75  * implement a "minimalist" vendor-agnostic CDC core:  same framing, but
  76  * link-level setup only requires activating the configuration.
  77  * Linux supports it, but other host operating systems may not.
  78  * (This is a subset of CDC Ethernet.)
  79  *
  80  * A third option is also in use.  Rather than CDC Ethernet, or something
  81  * simpler, Microsoft pushes their own approach: RNDIS.  The published
  82  * RNDIS specs are ambiguous and appear to be incomplete, and are also
  83  * needlessly complex.
  84  */
  85 
  86 #define DRIVER_DESC      "Ethernet Gadget"
  87 #define DRIVER_VERSION      "May Day 2005"
  88 
  89 static const char shortname [] = "ether";
  90 static const char driver_desc [] = DRIVER_DESC;
  91 
  92 #define RX_EXTRA   20      /* guard against rx overflows */
  93 
  94 #include "rndis.h"
  95 
  96 #ifndef   CONFIG_USB_ETH_RNDIS
  97 #define rndis_uninit(x)      do{}while(0)
  98 #define rndis_deregister(c)   do{}while(0)
  99 #define rndis_exit()      do{}while(0)
  100 #endif
  101 
  102 /* CDC and RNDIS support the same host-chosen outgoing packet filters. */
  103 #define   DEFAULT_FILTER   (USB_CDC_PACKET_TYPE_BROADCAST \
  104           |USB_CDC_PACKET_TYPE_ALL_MULTICAST \
  105           |USB_CDC_PACKET_TYPE_PROMISCUOUS \
  106           |USB_CDC_PACKET_TYPE_DIRECTED)
  107 
  108 
  109 /*-------------------------------------------------------------------------*/
  110 
  111 struct eth_dev {
  112    spinlock_t      lock;
  113    struct usb_gadget   *gadget;
  114    struct usb_request   *req;      /* for control responses */
  115    struct usb_request   *stat_req;   /* for cdc & rndis status */
  116 
  117    u8         config;
  118    struct usb_ep      *in_ep, *out_ep, *status_ep;
  119    const struct usb_endpoint_descriptor
  120             *in, *out, *status;
  121    struct list_head   tx_reqs, rx_reqs;
  122 
  123    struct net_device   *net;
  124    struct net_device_stats   stats;
  125    atomic_t      tx_qlen;
  126 
  127    struct work_struct   work;
  128    unsigned      zlp:1;
  129    unsigned      cdc:1;
  130    unsigned      rndis:1;
  131    unsigned      suspended:1;
  132    u16         cdc_filter;
  133    unsigned long      todo;
  134 #define   WORK_RX_MEMORY      0
  135    int         rndis_config;
  136    u8         host_mac [ETH_ALEN];
  137 };
  138 
  139 /* This version autoconfigures as much as possible at run-time.
  140  *
  141  * It also ASSUMES a self-powered device, without remote wakeup,
  142  * although remote wakeup support would make sense.
  143  */
  144 
  145 /*-------------------------------------------------------------------------*/
  146 
  147 /* DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!!
  148  * Instead:  allocate your own, using normal USB-IF procedures.
  149  */
  150 
  151 /* Thanks to NetChip Technologies for donating this product ID.
  152  * It's for devices with only CDC Ethernet configurations.
  153  */
  154 #define CDC_VENDOR_NUM   0x0525      /* NetChip */
  155 #define CDC_PRODUCT_NUM   0xa4a1      /* Linux-USB Ethernet Gadget */
  156 
  157 /* For hardware that can't talk CDC, we use the same vendor ID that
  158  * ARM Linux has used for ethernet-over-usb, both with sa1100 and
  159  * with pxa250.  We're protocol-compatible, if the host-side drivers
  160  * use the endpoint descriptors.  bcdDevice (version) is nonzero, so
  161  * drivers that need to hard-wire endpoint numbers have a hook.
  162  *
  163  * The protocol is a minimal subset of CDC Ether, which works on any bulk
  164  * hardware that's not deeply broken ... even on hardware that can't talk
  165  * RNDIS (like SA-1100, with no interrupt endpoint, or anything that
  166  * doesn't handle control-OUT).
  167  */
  168 #define   SIMPLE_VENDOR_NUM   0x049f
  169 #define   SIMPLE_PRODUCT_NUM   0x505a
  170 
  171 /* For hardware that can talk RNDIS and either of the above protocols,
  172  * use this ID ... the windows INF files will know it.  Unless it's
  173  * used with CDC Ethernet, Linux 2.4 hosts will need updates to choose
  174  * the non-RNDIS configuration.
  175  */
  176 #define RNDIS_VENDOR_NUM   0x0525   /* NetChip */
  177 #define RNDIS_PRODUCT_NUM   0xa4a2   /* Ethernet/RNDIS Gadget */
  178 
  179 
  180 /* Some systems will want different product identifers published in the
  181  * device descriptor, either numbers or strings or both.  These string
  182  * parameters are in UTF-8 (superset of ASCII's 7 bit characters).
  183  */
  184 
  185 static ushort __initdata idVendor;
 
- 186 module_param(idVendor, ushort, S_IRUGO);
 - 186 return ( & ( idVendor ) )
  187 MODULE_PARM_DESC(idVendor, "USB Vendor ID");
  188 
  189 static ushort __initdata idProduct;
 
- 190 module_param(idProduct, ushort, S_IRUGO);
 - 190 return ( & ( idProduct ) )
  191 MODULE_PARM_DESC(idProduct, "USB Product ID");
  192 
  193 static ushort __initdata bcdDevice;
 
- 194 module_param(bcdDevice, ushort, S_IRUGO);
 - 194 return ( & ( bcdDevice ) )
  195 MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)");
  196 
  197 static char *__initdata iManufacturer;
 
- 198 module_param(iManufacturer, charp, S_IRUGO);
 - 198 return ( & ( iManufacturer ) )
  199 MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string");
  200 
  201 static char *__initdata iProduct;
 
- 202 module_param(iProduct, charp, S_IRUGO);
 - 202 return ( & ( iProduct ) )
  203 MODULE_PARM_DESC(iProduct, "USB Product string");
  204 
  205 /* initial value, changed by "ifconfig usb0 hw ether xx:xx:xx:xx:xx:xx" */
  206 static char *__initdata dev_addr;
 
- 207 module_param(dev_addr, charp, S_IRUGO);
 - 207 return ( & ( dev_addr ) )
  208 MODULE_PARM_DESC(dev_addr, "Device Ethernet Address");
  209 
  210 /* this address is invisible to ifconfig */
  211 static char *__initdata host_addr;
 
- 212 module_param(host_addr, charp, S_IRUGO);
 - 212 return ( & ( host_addr ) )
  213 MODULE_PARM_DESC(host_addr, "Host Ethernet Address");
  214 
  215 
  216 /*-------------------------------------------------------------------------*/
  217 
  218 /* Include CDC support if we could run on CDC-capable hardware. */
  219 
  220 #ifdef CONFIG_USB_GADGET_NET2280
  221 #define   DEV_CONFIG_CDC
  222 #endif
  223 
  224 #ifdef CONFIG_USB_GADGET_DUMMY_HCD
  225 #define   DEV_CONFIG_CDC
  226 #endif
  227 
  228 #ifdef CONFIG_USB_GADGET_GOKU
  229 #define   DEV_CONFIG_CDC
  230 #endif
  231 
  232 #ifdef CONFIG_USB_GADGET_LH7A40X
  233 #define DEV_CONFIG_CDC
  234 #endif
  235 
  236 #ifdef CONFIG_USB_GADGET_MQ11XX
  237 #define   DEV_CONFIG_CDC
  238 #endif
  239 
  240 #ifdef CONFIG_USB_GADGET_OMAP
  241 #define   DEV_CONFIG_CDC
  242 #endif
  243 
  244 #ifdef CONFIG_USB_GADGET_N9604
  245 #define   DEV_CONFIG_CDC
  246 #endif
  247 
  248 #ifdef CONFIG_USB_GADGET_PXA27X
  249 #define DEV_CONFIG_CDC
  250 #endif
  251 
  252 #ifdef CONFIG_USB_GADGET_AT91
  253 #define DEV_CONFIG_CDC
  254 #endif
  255 
  256 
  257 /* For CDC-incapable hardware, choose the simple cdc subset.
  258  * Anything that talks bulk (without notable bugs) can do this.
  259  */
  260 #ifdef CONFIG_USB_GADGET_PXA2XX
  261 #define   DEV_CONFIG_SUBSET
  262 #endif
  263 
  264 #ifdef CONFIG_USB_GADGET_SH
  265 #define   DEV_CONFIG_SUBSET
  266 #endif
  267 
  268 #ifdef CONFIG_USB_GADGET_SA1100
  269 /* use non-CDC for backwards compatibility */
  270 #define   DEV_CONFIG_SUBSET
  271 #endif
  272 
  273 #ifdef CONFIG_USB_GADGET_S3C2410
  274 #define DEV_CONFIG_CDC
  275 #endif
  276 
  277 /*-------------------------------------------------------------------------*/
  278 
  279 /* "main" config is either CDC, or its simple subset */
 
- 280 static inline int is_cdc(struct eth_dev *dev)
  281 {
  282 #if   !defined(DEV_CONFIG_SUBSET)
 - 283    return 1;      /* only cdc possible */
  284 #elif   !defined (DEV_CONFIG_CDC)
  285    return 0;      /* only subset possible */
  286 #else
  287    return dev->cdc;   /* depends on what hardware we found */
  288 #endif
  289 }
  290 
  291 /* "secondary" RNDIS config may sometimes be activated */
 
- 292 static inline int rndis_active(struct eth_dev *dev)
  293 {
  294 #ifdef   CONFIG_USB_ETH_RNDIS
  295    return dev->rndis;
  296 #else
 - 297    return 0;
  298 #endif
  299 }
  300 
  301 #define   subset_active(dev)   (!is_cdc(dev) && !rndis_active(dev))
  302 #define   cdc_active(dev)      ( is_cdc(dev) && !rndis_active(dev))
  303 
  304 
  305 
  306 #define DEFAULT_QLEN   2   /* double buffering by default */
  307 
  308 /* peak bulk transfer bits-per-second */
  309 #define   HS_BPS       (13 * 512 * 8 * 1000 * 8)
  310 #define   FS_BPS      (19 *  64 * 1 * 1000 * 8)
  311 
  312 #ifdef CONFIG_USB_GADGET_DUALSPEED
  313 #define   DEVSPEED   USB_SPEED_HIGH
  314 
  315 static unsigned qmult = 5;
 
- 316 module_param (qmult, uint, S_IRUGO|S_IWUSR);
 - 316 return ( & ( qmult ) )
  317 
  318 
  319 /* for dual-speed hardware, use deeper queues at highspeed */
  320 #define qlen(gadget) \
  321    (DEFAULT_QLEN*((gadget->speed == USB_SPEED_HIGH) ? qmult : 1))
  322 
  323 /* also defer IRQs on highspeed TX */
  324 #define TX_DELAY   qmult
  325 
 
- 326 static inline int BITRATE(struct usb_gadget *g)
  327 {
    328    return (g->speed == USB_SPEED_HIGH) ? HS_BPS : FS_BPS;
- 328 ternary-?: ( g -> speed == USB_SPEED_HIGH )
 - 328 return ( g -> speed == USB_SPEED_HIGH ) ? ( 13..
  329 }
  330 
  331 #else   /* full speed (low speed doesn't do bulk) */
  332 #define   DEVSPEED   USB_SPEED_FULL
  333 
  334 #define qlen(gadget) DEFAULT_QLEN
  335 
  336 static inline int BITRATE(struct usb_gadget *g)
  337 {
  338    return FS_BPS;
  339 }
  340 #endif
  341 
  342 
  343 /*-------------------------------------------------------------------------*/
  344 
  345 #define xprintk(d,level,fmt,args...) \
  346    printk(level "%s: " fmt , (d)->net->name , ## args)
  347 
  348 #ifdef DEBUG
  349 #undef DEBUG
  350 #define DEBUG(dev,fmt,args...) \
  351    xprintk(dev , KERN_DEBUG , fmt , ## args)
  352 #else
  353 #define DEBUG(dev,fmt,args...) \
  354    do { } while (0)
  355 #endif /* DEBUG */
  356 
  357 #ifdef VERBOSE
  358 #define VDEBUG   DEBUG
  359 #else
  360 #define VDEBUG(dev,fmt,args...) \
  361    do { } while (0)
  362 #endif /* DEBUG */
  363 
  364 #define ERROR(dev,fmt,args...) \
  365    xprintk(dev , KERN_ERR , fmt , ## args)
  366 #define WARN(dev,fmt,args...) \
  367    xprintk(dev , KERN_WARNING , fmt , ## args)
  368 #define INFO(dev,fmt,args...) \
  369    xprintk(dev , KERN_INFO , fmt , ## args)
  370 
  371 /*-------------------------------------------------------------------------*/
  372 
  373 /* USB DRIVER HOOKUP (to the hardware driver, below us), mostly
  374  * ep0 implementation:  descriptors, config management, setup().
  375  * also optional class-specific notification interrupt transfer.
  376  */
  377 
  378 /*
  379  * DESCRIPTORS ... most are static, but strings and (full) configuration
  380  * descriptors are built on demand.  For now we do either full CDC, or
  381  * our simple subset, with RNDIS as an optional second configuration.
  382  *
  383  * RNDIS includes some CDC ACM descriptors ... like CDC Ethernet.  But
  384  * the class descriptors match a modem (they're ignored; it's really just
  385  * Ethernet functionality), they don't need the NOP altsetting, and the
  386  * status transfer endpoint isn't optional.
  387  */
  388 
  389 #define STRING_MANUFACTURER      1
  390 #define STRING_PRODUCT         2
  391 #define STRING_ETHADDR         3
  392 #define STRING_DATA         4
  393 #define STRING_CONTROL         5
  394 #define STRING_RNDIS_CONTROL      6
  395 #define STRING_CDC         7
  396 #define STRING_SUBSET         8
  397 #define STRING_RNDIS         9
  398 
  399 /* holds our biggest descriptor (or RNDIS response) */
  400 #define USB_BUFSIZ   256
  401 
  402 /*
  403  * This device advertises one configuration, eth_config, unless RNDIS
  404  * is enabled (rndis_config) on hardware supporting at least two configs.
  405  *
  406  * NOTE:  Controllers like superh_udc should probably be able to use
  407  * an RNDIS-only configuration.
  408  *
  409  * FIXME define some higher-powered configurations to make it easier
  410  * to recharge batteries ...
  411  */
  412 
  413 #define DEV_CONFIG_VALUE   1   /* cdc or subset */
  414 #define DEV_RNDIS_CONFIG_VALUE   2   /* rndis; optional */
  415 
  416 static struct usb_device_descriptor
  417 device_desc = {
  418    .bLength =      sizeof device_desc,
  419    .bDescriptorType =   USB_DT_DEVICE,
  420 
  421    .bcdUSB =      __constant_cpu_to_le16 (0x0200),
  422 
  423    .bDeviceClass =      USB_CLASS_COMM,
  424    .bDeviceSubClass =   0,
  425    .bDeviceProtocol =   0,
  426 
  427    .idVendor =      __constant_cpu_to_le16 (CDC_VENDOR_NUM),
  428    .idProduct =      __constant_cpu_to_le16 (CDC_PRODUCT_NUM),
  429    .iManufacturer =   STRING_MANUFACTURER,
  430    .iProduct =      STRING_PRODUCT,
  431    .bNumConfigurations =   1,
  432 };
  433 
  434 static struct usb_otg_descriptor
  435 otg_descriptor = {
  436    .bLength =      sizeof otg_descriptor,
  437    .bDescriptorType =   USB_DT_OTG,
  438 
  439    .bmAttributes =      USB_OTG_SRP,
  440 };
  441 
  442 static struct usb_config_descriptor
  443 eth_config = {
  444    .bLength =      sizeof eth_config,
  445    .bDescriptorType =   USB_DT_CONFIG,
  446 
  447    /* compute wTotalLength on the fly */
  448    .bNumInterfaces =   2,
  449    .bConfigurationValue =   DEV_CONFIG_VALUE,
  450    .iConfiguration =   STRING_CDC,
  451    .bmAttributes =      USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
  452    .bMaxPower =      50,
  453 };
  454 
  455 #ifdef   CONFIG_USB_ETH_RNDIS
  456 static struct usb_config_descriptor 
  457 rndis_config = {
  458    .bLength =              sizeof rndis_config,
  459    .bDescriptorType =      USB_DT_CONFIG,
  460 
  461    /* compute wTotalLength on the fly */
  462    .bNumInterfaces =       2,
  463    .bConfigurationValue =  DEV_RNDIS_CONFIG_VALUE,
  464    .iConfiguration =       STRING_RNDIS,
  465    .bmAttributes =      USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
  466    .bMaxPower =            50,
  467 };
  468 #endif
  469 
  470 /*
  471  * Compared to the simple CDC subset, the full CDC Ethernet model adds
  472  * three class descriptors, two interface descriptors, optional status
  473  * endpoint.  Both have a "data" interface and two bulk endpoints.
  474  * There are also differences in how control requests are handled.
  475  *
  476  * RNDIS shares a lot with CDC-Ethernet, since it's a variant of
  477  * the CDC-ACM (modem) spec.
  478  */
  479 
  480 #ifdef   DEV_CONFIG_CDC
  481 static struct usb_interface_descriptor
  482 control_intf = {
  483    .bLength =      sizeof control_intf,
  484    .bDescriptorType =   USB_DT_INTERFACE,
  485 
  486    .bInterfaceNumber =   0,
  487    /* status endpoint is optional; this may be patched later */
  488    .bNumEndpoints =   1,
  489    .bInterfaceClass =   USB_CLASS_COMM,
  490    .bInterfaceSubClass =   USB_CDC_SUBCLASS_ETHERNET,
  491    .bInterfaceProtocol =   USB_CDC_PROTO_NONE,
  492    .iInterface =      STRING_CONTROL,
  493 };
  494 #endif
  495 
  496 #ifdef   CONFIG_USB_ETH_RNDIS
  497 static const struct usb_interface_descriptor
  498 rndis_control_intf = {
  499    .bLength =              sizeof rndis_control_intf,
  500    .bDescriptorType =      USB_DT_INTERFACE,
  501      
  502    .bInterfaceNumber =     0,
  503    .bNumEndpoints =        1,
  504    .bInterfaceClass =      USB_CLASS_COMM,
  505    .bInterfaceSubClass =   USB_CDC_SUBCLASS_ACM,
  506    .bInterfaceProtocol =   USB_CDC_ACM_PROTO_VENDOR,
  507    .iInterface =           STRING_RNDIS_CONTROL,
  508 };
  509 #endif
  510 
  511 #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
  512 
  513 static const struct usb_cdc_header_desc header_desc = {
  514    .bLength =      sizeof header_desc,
  515    .bDescriptorType =   USB_DT_CS_INTERFACE,
  516    .bDescriptorSubType =   USB_CDC_HEADER_TYPE,
  517 
  518    .bcdCDC =      __constant_cpu_to_le16 (0x0110),
  519 };
  520 
  521 static const struct usb_cdc_union_desc union_desc = {
  522    .bLength =      sizeof union_desc,
  523    .bDescriptorType =   USB_DT_CS_INTERFACE,
  524    .bDescriptorSubType =   USB_CDC_UNION_TYPE,
  525 
  526    .bMasterInterface0 =   0,   /* index of control interface */
  527    .bSlaveInterface0 =   1,   /* index of DATA interface */
  528 };
  529 
  530 #endif   /* CDC || RNDIS */
  531 
  532 #ifdef   CONFIG_USB_ETH_RNDIS
  533 
  534 static const struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor = {
  535    .bLength =        sizeof call_mgmt_descriptor,
  536    .bDescriptorType =    USB_DT_CS_INTERFACE,
  537    .bDescriptorSubType =    USB_CDC_CALL_MANAGEMENT_TYPE,
  538 
  539    .bmCapabilities =    0x00,
  540    .bDataInterface =    0x01,
  541 };
  542 
  543 static const struct usb_cdc_acm_descriptor acm_descriptor = {
  544    .bLength =        sizeof acm_descriptor,
  545    .bDescriptorType =    USB_DT_CS_INTERFACE,
  546    .bDescriptorSubType =    USB_CDC_ACM_TYPE,
  547 
  548    .bmCapabilities =    0x00,
  549 };
  550 
  551 #endif
  552 
  553 #ifdef   DEV_CONFIG_CDC
  554 
  555 static const struct usb_cdc_ether_desc ether_desc = {
  556    .bLength =      sizeof ether_desc,
  557    .bDescriptorType =   USB_DT_CS_INTERFACE,
  558    .bDescriptorSubType =   USB_CDC_ETHERNET_TYPE,
  559 
  560    /* this descriptor actually adds value, surprise! */
  561    .iMACAddress =      STRING_ETHADDR,
  562    .bmEthernetStatistics =   __constant_cpu_to_le32 (0), /* no statistics */
  563    .wMaxSegmentSize =   __constant_cpu_to_le16 (ETH_FRAME_LEN),
  564    .wNumberMCFilters =   __constant_cpu_to_le16 (0),
  565    .bNumberPowerFilters =   0,
  566 };
  567 
  568 #endif
  569 
  570 #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
  571 
  572 /* include the status endpoint if we can, even where it's optional.
  573  * use wMaxPacketSize big enough to fit CDC_NOTIFY_SPEED_CHANGE in one
  574  * packet, to simplify cancellation; and a big transfer interval, to
  575  * waste less bandwidth.
  576  *
  577  * some drivers (like Linux 2.4 cdc-ether!) "need" it to exist even
  578  * if they ignore the connect/disconnect notifications that real aether
  579  * can provide.  more advanced cdc configurations might want to support
  580  * encapsulated commands (vendor-specific, using control-OUT).
  581  *
  582  * RNDIS requires the status endpoint, since it uses that encapsulation
  583  * mechanism for its funky RPC scheme.
  584  */
  585  
  586 #define LOG2_STATUS_INTERVAL_MSEC   5   /* 1 << 5 == 32 msec */
  587 #define STATUS_BYTECOUNT      16   /* 8 byte header + data */
  588 
  589 static struct usb_endpoint_descriptor
  590 fs_status_desc = {
  591    .bLength =      USB_DT_ENDPOINT_SIZE,
  592    .bDescriptorType =   USB_DT_ENDPOINT,
  593 
  594    .bEndpointAddress =   USB_DIR_IN,
  595    .bmAttributes =      USB_ENDPOINT_XFER_INT,
  596    .wMaxPacketSize =   __constant_cpu_to_le16 (STATUS_BYTECOUNT),
  597    .bInterval =      1 << LOG2_STATUS_INTERVAL_MSEC,
  598 };
  599 #endif
  600 
  601 #ifdef   DEV_CONFIG_CDC
  602 
  603 /* the default data interface has no endpoints ... */
  604 
  605 static const struct usb_interface_descriptor
  606 data_nop_intf = {
  607    .bLength =      sizeof data_nop_intf,