1/* 2 * RNDIS MSG parser 3 * 4 * Authors: Benedikt Spranger, Pengutronix 5 * Robert Schwebel, Pengutronix 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * version 2, as published by the Free Software Foundation. 10 * 11 * This software was originally developed in conformance with 12 * Microsoft's Remote NDIS Specification License Agreement. 13 * 14 * 03/12/2004 Kai-Uwe Bloem <linux-development@auerswald.de> 15 * Fixed message length bug in init_response 16 * 17 * 03/25/2004 Kai-Uwe Bloem <linux-development@auerswald.de> 18 * Fixed rndis_rm_hdr length bug. 19 * 20 * Copyright (C) 2004 by David Brownell 21 * updates to merge with Linux 2.6, better match RNDIS spec 22 */ 23 24#include <linux/module.h> 25#include <linux/moduleparam.h> 26#include <linux/kernel.h> 27#include <linux/errno.h> 28#include <linux/list.h> 29#include <linux/proc_fs.h> 30#include <linux/slab.h> 31#include <linux/seq_file.h> 32#include <linux/netdevice.h> 33 34#include <asm/io.h> 35#include <asm/byteorder.h> 36#include <asm/unaligned.h> 37 38#include "u_rndis.h" 39 40#undef VERBOSE_DEBUG 41 42#include "rndis.h" 43 44 45/* The driver for your USB chip needs to support ep0 OUT to work with 46 * RNDIS, plus all three CDC Ethernet endpoints (interrupt not optional). 47 * 48 * Windows hosts need an INF file like Documentation/usb/linux.inf 49 * and will be happier if you provide the host_addr module parameter. 50 */ 51 52#if 0 53static int rndis_debug = 0; 54module_param (rndis_debug, int, 0); 55MODULE_PARM_DESC (rndis_debug, "enable debugging"); 56#else 57#define rndis_debug 0 58#endif 59 60#define RNDIS_MAX_CONFIGS 1 61 62int rndis_ul_max_pkt_per_xfer_rcvd; 63module_param(rndis_ul_max_pkt_per_xfer_rcvd, int, S_IRUGO); 64MODULE_PARM_DESC(rndis_ul_max_pkt_per_xfer_rcvd, 65 "Max num of REMOTE_NDIS_PACKET_MSGs received in a single transfer"); 66 67int rndis_ul_max_xfer_size_rcvd; 68module_param(rndis_ul_max_xfer_size_rcvd, int, S_IRUGO); 69MODULE_PARM_DESC(rndis_ul_max_xfer_size_rcvd, 70 "Max size of bus transfer received"); 71 72 73static rndis_params rndis_per_dev_params[RNDIS_MAX_CONFIGS]; 74 75/* Driver Version */ 76static const __le32 rndis_driver_version = cpu_to_le32(1); 77 78/* Function Prototypes */ 79static rndis_resp_t *rndis_add_response(int configNr, u32 length); 80 81 82/* supported OIDs */ 83static const u32 oid_supported_list[] = 84{ 85 /* the general stuff */ 86 RNDIS_OID_GEN_SUPPORTED_LIST, 87 RNDIS_OID_GEN_HARDWARE_STATUS, 88 RNDIS_OID_GEN_MEDIA_SUPPORTED, 89 RNDIS_OID_GEN_MEDIA_IN_USE, 90 RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE, 91 RNDIS_OID_GEN_LINK_SPEED, 92 RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE, 93 RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE, 94 RNDIS_OID_GEN_VENDOR_ID, 95 RNDIS_OID_GEN_VENDOR_DESCRIPTION, 96 RNDIS_OID_GEN_VENDOR_DRIVER_VERSION, 97 RNDIS_OID_GEN_CURRENT_PACKET_FILTER, 98 RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE, 99 RNDIS_OID_GEN_MEDIA_CONNECT_STATUS, 100 RNDIS_OID_GEN_PHYSICAL_MEDIUM, 101 102 /* the statistical stuff */ 103 RNDIS_OID_GEN_XMIT_OK, 104 RNDIS_OID_GEN_RCV_OK, 105 RNDIS_OID_GEN_XMIT_ERROR, 106 RNDIS_OID_GEN_RCV_ERROR, 107 RNDIS_OID_GEN_RCV_NO_BUFFER, 108#ifdef RNDIS_OPTIONAL_STATS 109 RNDIS_OID_GEN_DIRECTED_BYTES_XMIT, 110 RNDIS_OID_GEN_DIRECTED_FRAMES_XMIT, 111 RNDIS_OID_GEN_MULTICAST_BYTES_XMIT, 112 RNDIS_OID_GEN_MULTICAST_FRAMES_XMIT, 113 RNDIS_OID_GEN_BROADCAST_BYTES_XMIT, 114 RNDIS_OID_GEN_BROADCAST_FRAMES_XMIT, 115 RNDIS_OID_GEN_DIRECTED_BYTES_RCV, 116 RNDIS_OID_GEN_DIRECTED_FRAMES_RCV, 117 RNDIS_OID_GEN_MULTICAST_BYTES_RCV, 118 RNDIS_OID_GEN_MULTICAST_FRAMES_RCV, 119 RNDIS_OID_GEN_BROADCAST_BYTES_RCV, 120 RNDIS_OID_GEN_BROADCAST_FRAMES_RCV, 121 RNDIS_OID_GEN_RCV_CRC_ERROR, 122 RNDIS_OID_GEN_TRANSMIT_QUEUE_LENGTH, 123#endif /* RNDIS_OPTIONAL_STATS */ 124 125 /* mandatory 802.3 */ 126 /* the general stuff */ 127 RNDIS_OID_802_3_PERMANENT_ADDRESS, 128 RNDIS_OID_802_3_CURRENT_ADDRESS, 129 RNDIS_OID_802_3_MULTICAST_LIST, 130 RNDIS_OID_802_3_MAC_OPTIONS, 131 RNDIS_OID_802_3_MAXIMUM_LIST_SIZE, 132 133 /* the statistical stuff */ 134 RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT, 135 RNDIS_OID_802_3_XMIT_ONE_COLLISION, 136 RNDIS_OID_802_3_XMIT_MORE_COLLISIONS, 137#ifdef RNDIS_OPTIONAL_STATS 138 RNDIS_OID_802_3_XMIT_DEFERRED, 139 RNDIS_OID_802_3_XMIT_MAX_COLLISIONS, 140 RNDIS_OID_802_3_RCV_OVERRUN, 141 RNDIS_OID_802_3_XMIT_UNDERRUN, 142 RNDIS_OID_802_3_XMIT_HEARTBEAT_FAILURE, 143 RNDIS_OID_802_3_XMIT_TIMES_CRS_LOST, 144 RNDIS_OID_802_3_XMIT_LATE_COLLISIONS, 145#endif /* RNDIS_OPTIONAL_STATS */ 146 147#ifdef RNDIS_PM 148 /* PM and wakeup are "mandatory" for USB, but the RNDIS specs 149 * don't say what they mean ... and the NDIS specs are often 150 * confusing and/or ambiguous in this context. (That is, more 151 * so than their specs for the other OIDs.) 152 * 153 * FIXME someone who knows what these should do, please 154 * implement them! 155 */ 156 157 /* power management */ 158 OID_PNP_CAPABILITIES, 159 OID_PNP_QUERY_POWER, 160 OID_PNP_SET_POWER, 161 162#ifdef RNDIS_WAKEUP 163 /* wake up host */ 164 OID_PNP_ENABLE_WAKE_UP, 165 OID_PNP_ADD_WAKE_UP_PATTERN, 166 OID_PNP_REMOVE_WAKE_UP_PATTERN, 167#endif /* RNDIS_WAKEUP */ 168#endif /* RNDIS_PM */ 169}; 170 171 172/* NDIS Functions */ 173static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf, 174 unsigned buf_len, rndis_resp_t *r) 175{ 176 int retval = -ENOTSUPP; 177 u32 length = 4; /* usually */ 178 __le32 *outbuf; 179 int i, count; 180 rndis_query_cmplt_type *resp; 181 struct net_device *net; 182 struct rtnl_link_stats64 temp; 183 const struct rtnl_link_stats64 *stats; 184 185 if (!r) return -ENOMEM; 186 resp = (rndis_query_cmplt_type *)r->buf; 187 188 if (!resp) return -ENOMEM; 189 190 if (buf_len && rndis_debug > 1) { 191 pr_debug("query OID %08x value, len %d:\n", OID, buf_len); 192 for (i = 0; i < buf_len; i += 16) { 193 pr_debug("%03d: %08x %08x %08x %08x\n", i, 194 get_unaligned_le32(&buf[i]), 195 get_unaligned_le32(&buf[i + 4]), 196 get_unaligned_le32(&buf[i + 8]), 197 get_unaligned_le32(&buf[i + 12])); 198 } 199 } 200 201 /* response goes here, right after the header */ 202 outbuf = (__le32 *)&resp[1]; 203 resp->InformationBufferOffset = cpu_to_le32(16); 204 205 net = rndis_per_dev_params[configNr].dev; 206 stats = dev_get_stats(net, &temp); 207 208 switch (OID) { 209 210 /* general oids (table 4-1) */ 211 212 /* mandatory */ 213 case RNDIS_OID_GEN_SUPPORTED_LIST: 214 pr_debug("%s: RNDIS_OID_GEN_SUPPORTED_LIST\n", __func__); 215 length = sizeof(oid_supported_list); 216 count = length / sizeof(u32); 217 for (i = 0; i < count; i++) 218 outbuf[i] = cpu_to_le32(oid_supported_list[i]); 219 retval = 0; 220 break; 221 222 /* mandatory */ 223 case RNDIS_OID_GEN_HARDWARE_STATUS: 224 pr_debug("%s: RNDIS_OID_GEN_HARDWARE_STATUS\n", __func__); 225 /* Bogus question! 226 * Hardware must be ready to receive high level protocols. 227 * BTW: 228 * reddite ergo quae sunt Caesaris Caesari 229 * et quae sunt Dei Deo! 230 */ 231 *outbuf = cpu_to_le32(0); 232 retval = 0; 233 break; 234 235 /* mandatory */ 236 case RNDIS_OID_GEN_MEDIA_SUPPORTED: 237 pr_debug("%s: RNDIS_OID_GEN_MEDIA_SUPPORTED\n", __func__); 238 *outbuf = cpu_to_le32(rndis_per_dev_params[configNr].medium); 239 retval = 0; 240 break; 241 242 /* mandatory */ 243 case RNDIS_OID_GEN_MEDIA_IN_USE: 244 pr_debug("%s: RNDIS_OID_GEN_MEDIA_IN_USE\n", __func__); 245 /* one medium, one transport... (maybe you do it better) */ 246 *outbuf = cpu_to_le32(rndis_per_dev_params[configNr].medium); 247 retval = 0; 248 break; 249 250 /* mandatory */ 251 case RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE: 252 pr_debug("%s: RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__); 253 if (rndis_per_dev_params[configNr].dev) { 254 *outbuf = cpu_to_le32( 255 rndis_per_dev_params[configNr].dev->mtu); 256 retval = 0; 257 } 258 break; 259 260 /* mandatory */ 261 case RNDIS_OID_GEN_LINK_SPEED: 262 if (rndis_debug > 1) 263 pr_debug("%s: RNDIS_OID_GEN_LINK_SPEED\n", __func__); 264 if (rndis_per_dev_params[configNr].media_state 265 == RNDIS_MEDIA_STATE_DISCONNECTED) 266 *outbuf = cpu_to_le32(0); 267 else 268 *outbuf = cpu_to_le32( 269 rndis_per_dev_params[configNr].speed); 270 retval = 0; 271 break; 272 273 /* mandatory */ 274 case RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE: 275 pr_debug("%s: RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__); 276 if (rndis_per_dev_params[configNr].dev) { 277 *outbuf = cpu_to_le32( 278 rndis_per_dev_params[configNr].dev->mtu); 279 retval = 0; 280 } 281 break; 282 283 /* mandatory */ 284 case RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE: 285 pr_debug("%s: RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__); 286 if (rndis_per_dev_params[configNr].dev) { 287 *outbuf = cpu_to_le32( 288 rndis_per_dev_params[configNr].dev->mtu); 289 retval = 0; 290 } 291 break; 292 293 /* mandatory */ 294 case RNDIS_OID_GEN_VENDOR_ID: 295 pr_debug("%s: RNDIS_OID_GEN_VENDOR_ID\n", __func__); 296 *outbuf = cpu_to_le32( 297 rndis_per_dev_params[configNr].vendorID); 298 retval = 0; 299 break; 300 301 /* mandatory */ 302 case RNDIS_OID_GEN_VENDOR_DESCRIPTION: 303 pr_debug("%s: RNDIS_OID_GEN_VENDOR_DESCRIPTION\n", __func__); 304 if (rndis_per_dev_params[configNr].vendorDescr) { 305 length = strlen(rndis_per_dev_params[configNr]. 306 vendorDescr); 307 memcpy(outbuf, 308 rndis_per_dev_params[configNr].vendorDescr, 309 length); 310 } else { 311 outbuf[0] = 0; 312 } 313 retval = 0; 314 break; 315 316 case RNDIS_OID_GEN_VENDOR_DRIVER_VERSION: 317 pr_debug("%s: RNDIS_OID_GEN_VENDOR_DRIVER_VERSION\n", __func__); 318 /* Created as LE */ 319 *outbuf = rndis_driver_version; 320 retval = 0; 321 break; 322 323 /* mandatory */ 324 case RNDIS_OID_GEN_CURRENT_PACKET_FILTER: 325 pr_debug("%s: RNDIS_OID_GEN_CURRENT_PACKET_FILTER\n", __func__); 326 *outbuf = cpu_to_le32(*rndis_per_dev_params[configNr].filter); 327 retval = 0; 328 break; 329 330 /* mandatory */ 331 case RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE: 332 pr_debug("%s: RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__); 333 *outbuf = cpu_to_le32(RNDIS_MAX_TOTAL_SIZE); 334 retval = 0; 335 break; 336 337 /* mandatory */ 338 case RNDIS_OID_GEN_MEDIA_CONNECT_STATUS: 339 if (rndis_debug > 1) 340 pr_debug("%s: RNDIS_OID_GEN_MEDIA_CONNECT_STATUS\n", __func__); 341 *outbuf = cpu_to_le32(rndis_per_dev_params[configNr] 342 .media_state); 343 retval = 0; 344 break; 345 346 case RNDIS_OID_GEN_PHYSICAL_MEDIUM: 347 pr_debug("%s: RNDIS_OID_GEN_PHYSICAL_MEDIUM\n", __func__); 348 *outbuf = cpu_to_le32(0); 349 retval = 0; 350 break; 351 352 /* The RNDIS specification is incomplete/wrong. Some versions 353 * of MS-Windows expect OIDs that aren't specified there. Other 354 * versions emit undefined RNDIS messages. DOCUMENT ALL THESE! 355 */ 356 case RNDIS_OID_GEN_MAC_OPTIONS: /* from WinME */ 357 pr_debug("%s: RNDIS_OID_GEN_MAC_OPTIONS\n", __func__); 358 *outbuf = cpu_to_le32( 359 RNDIS_MAC_OPTION_RECEIVE_SERIALIZED 360 | RNDIS_MAC_OPTION_FULL_DUPLEX); 361 retval = 0; 362 break; 363 364 /* statistics OIDs (table 4-2) */ 365 366 /* mandatory */ 367 case RNDIS_OID_GEN_XMIT_OK: 368 if (rndis_debug > 1) 369 pr_debug("%s: RNDIS_OID_GEN_XMIT_OK\n", __func__); 370 if (stats) { 371 *outbuf = cpu_to_le32(stats->tx_packets 372 - stats->tx_errors - stats->tx_dropped); 373 retval = 0; 374 } 375 break; 376 377 /* mandatory */ 378 case RNDIS_OID_GEN_RCV_OK: 379 if (rndis_debug > 1) 380 pr_debug("%s: RNDIS_OID_GEN_RCV_OK\n", __func__); 381 if (stats) { 382 *outbuf = cpu_to_le32(stats->rx_packets 383 - stats->rx_errors - stats->rx_dropped); 384 retval = 0; 385 } 386 break; 387 388 /* mandatory */ 389 case RNDIS_OID_GEN_XMIT_ERROR: 390 if (rndis_debug > 1) 391 pr_debug("%s: RNDIS_OID_GEN_XMIT_ERROR\n", __func__); 392 if (stats) { 393 *outbuf = cpu_to_le32(stats->tx_errors); 394 retval = 0; 395 } 396 break; 397 398 /* mandatory */ 399 case RNDIS_OID_GEN_RCV_ERROR: 400 if (rndis_debug > 1) 401 pr_debug("%s: RNDIS_OID_GEN_RCV_ERROR\n", __func__); 402 if (stats) { 403 *outbuf = cpu_to_le32(stats->rx_errors); 404 retval = 0; 405 } 406 break; 407 408 /* mandatory */ 409 case RNDIS_OID_GEN_RCV_NO_BUFFER: 410 pr_debug("%s: RNDIS_OID_GEN_RCV_NO_BUFFER\n", __func__); 411 if (stats) { 412 *outbuf = cpu_to_le32(stats->rx_dropped); 413 retval = 0; 414 } 415 break; 416 417 /* ieee802.3 OIDs (table 4-3) */ 418 419 /* mandatory */ 420 case RNDIS_OID_802_3_PERMANENT_ADDRESS: 421 pr_debug("%s: RNDIS_OID_802_3_PERMANENT_ADDRESS\n", __func__); 422 if (rndis_per_dev_params[configNr].dev) { 423 length = ETH_ALEN; 424 memcpy(outbuf, 425 rndis_per_dev_params[configNr].host_mac, 426 length); 427 retval = 0; 428 } 429 break; 430 431 /* mandatory */ 432 case RNDIS_OID_802_3_CURRENT_ADDRESS: 433 pr_debug("%s: RNDIS_OID_802_3_CURRENT_ADDRESS\n", __func__); 434 if (rndis_per_dev_params[configNr].dev) { 435 length = ETH_ALEN; 436 memcpy(outbuf, 437 rndis_per_dev_params [configNr].host_mac, 438 length); 439 retval = 0; 440 } 441 break; 442 443 /* mandatory */ 444 case RNDIS_OID_802_3_MULTICAST_LIST: 445 pr_debug("%s: RNDIS_OID_802_3_MULTICAST_LIST\n", __func__); 446 /* Multicast base address only */ 447 *outbuf = cpu_to_le32(0xE0000000); 448 retval = 0; 449 break; 450 451 /* mandatory */ 452 case RNDIS_OID_802_3_MAXIMUM_LIST_SIZE: 453 pr_debug("%s: RNDIS_OID_802_3_MAXIMUM_LIST_SIZE\n", __func__); 454 /* Multicast base address only */ 455 *outbuf = cpu_to_le32(1); 456 retval = 0; 457 break; 458 459 case RNDIS_OID_802_3_MAC_OPTIONS: 460 pr_debug("%s: RNDIS_OID_802_3_MAC_OPTIONS\n", __func__); 461 *outbuf = cpu_to_le32(0); 462 retval = 0; 463 break; 464 465 /* ieee802.3 statistics OIDs (table 4-4) */ 466 467 /* mandatory */ 468 case RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT: 469 pr_debug("%s: RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__); 470 if (stats) { 471 *outbuf = cpu_to_le32(stats->rx_frame_errors); 472 retval = 0; 473 } 474 break; 475 476 /* mandatory */ 477 case RNDIS_OID_802_3_XMIT_ONE_COLLISION: 478 pr_debug("%s: RNDIS_OID_802_3_XMIT_ONE_COLLISION\n", __func__); 479 *outbuf = cpu_to_le32(0); 480 retval = 0; 481 break; 482 483 /* mandatory */ 484 case RNDIS_OID_802_3_XMIT_MORE_COLLISIONS: 485 pr_debug("%s: RNDIS_OID_802_3_XMIT_MORE_COLLISIONS\n", __func__); 486 *outbuf = cpu_to_le32(0); 487 retval = 0; 488 break; 489 490 default: 491 pr_warning("%s: query unknown OID 0x%08X\n", 492 __func__, OID); 493 } 494 if (retval < 0) 495 length = 0; 496 497 resp->InformationBufferLength = cpu_to_le32(length); 498 r->length = length + sizeof(*resp); 499 resp->MessageLength = cpu_to_le32(r->length); 500 return retval; 501} 502 503static int gen_ndis_set_resp(u8 configNr, u32 OID, u8 *buf, u32 buf_len, 504 rndis_resp_t *r) 505{ 506 rndis_set_cmplt_type *resp; 507 int i, retval = -ENOTSUPP; 508 struct rndis_params *params; 509 510 if (!r) 511 return -ENOMEM; 512 resp = (rndis_set_cmplt_type *)r->buf; 513 if (!resp) 514 return -ENOMEM; 515 516 if (buf_len && rndis_debug > 1) { 517 pr_debug("set OID %08x value, len %d:\n", OID, buf_len); 518 for (i = 0; i < buf_len; i += 16) { 519 pr_debug("%03d: %08x %08x %08x %08x\n", i, 520 get_unaligned_le32(&buf[i]), 521 get_unaligned_le32(&buf[i + 4]), 522 get_unaligned_le32(&buf[i + 8]), 523 get_unaligned_le32(&buf[i + 12])); 524 } 525 } 526 527 params = &rndis_per_dev_params[configNr]; 528 switch (OID) { 529 case RNDIS_OID_GEN_CURRENT_PACKET_FILTER: 530 531 /* these NDIS_PACKET_TYPE_* bitflags are shared with 532 * cdc_filter; it's not RNDIS-specific 533 * NDIS_PACKET_TYPE_x == USB_CDC_PACKET_TYPE_x for x in: 534 * PROMISCUOUS, DIRECTED, 535 * MULTICAST, ALL_MULTICAST, BROADCAST 536 */ 537 *params->filter = (u16)get_unaligned_le32(buf); 538 pr_debug("%s: RNDIS_OID_GEN_CURRENT_PACKET_FILTER %08x\n", 539 __func__, *params->filter); 540 541 /* this call has a significant side effect: it's 542 * what makes the packet flow start and stop, like 543 * activating the CDC Ethernet altsetting. 544 */ 545 retval = 0; 546 if (*params->filter) { 547 params->state = RNDIS_DATA_INITIALIZED; 548 netif_carrier_on(params->dev); 549 if (netif_running(params->dev)) 550 netif_wake_queue(params->dev); 551 } else { 552 params->state = RNDIS_INITIALIZED; 553 netif_carrier_off(params->dev); 554 netif_stop_queue(params->dev); 555 } 556 break; 557 558 case RNDIS_OID_802_3_MULTICAST_LIST: 559 /* I think we can ignore this */ 560 pr_debug("%s: RNDIS_OID_802_3_MULTICAST_LIST\n", __func__); 561 retval = 0; 562 break; 563 564 default: 565 pr_warning("%s: set unknown OID 0x%08X, size %d\n", 566 __func__, OID, buf_len); 567 } 568 569 return retval; 570} 571 572/* 573 * Response Functions 574 */ 575 576static int rndis_init_response(int configNr, rndis_init_msg_type *buf) 577{ 578 rndis_init_cmplt_type *resp; 579 rndis_resp_t *r; 580 struct rndis_params *params = rndis_per_dev_params + configNr; 581 582 if (!params->dev) 583 return -ENOTSUPP; 584 585 r = rndis_add_response(configNr, sizeof(rndis_init_cmplt_type)); 586 if (!r) 587 return -ENOMEM; 588 resp = (rndis_init_cmplt_type *)r->buf; 589 590 resp->MessageType = cpu_to_le32(RNDIS_MSG_INIT_C); 591 resp->MessageLength = cpu_to_le32(52); 592 resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ 593 resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); 594 resp->MajorVersion = cpu_to_le32(RNDIS_MAJOR_VERSION); 595 resp->MinorVersion = cpu_to_le32(RNDIS_MINOR_VERSION); 596 resp->DeviceFlags = cpu_to_le32(RNDIS_DF_CONNECTIONLESS); 597 resp->Medium = cpu_to_le32(RNDIS_MEDIUM_802_3); 598 resp->MaxPacketsPerTransfer = cpu_to_le32(params->max_pkt_per_xfer); 599 resp->MaxTransferSize = cpu_to_le32(params->max_pkt_per_xfer * 600 (params->dev->mtu 601 + sizeof(struct ethhdr) 602 + sizeof(struct rndis_packet_msg_type) 603 + 22)); 604 resp->PacketAlignmentFactor = cpu_to_le32(0); 605 resp->AFListOffset = cpu_to_le32(0); 606 resp->AFListSize = cpu_to_le32(0); 607 608 params->resp_avail(params->v); 609 return 0; 610} 611 612static int rndis_query_response(int configNr, rndis_query_msg_type *buf) 613{ 614 rndis_query_cmplt_type *resp; 615 rndis_resp_t *r; 616 struct rndis_params *params = rndis_per_dev_params + configNr; 617 618 /* pr_debug("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID)); */ 619 if (!params->dev) 620 return -ENOTSUPP; 621 622 /* 623 * we need more memory: 624 * gen_ndis_query_resp expects enough space for 625 * rndis_query_cmplt_type followed by data. 626 * oid_supported_list is the largest data reply 627 */ 628 r = rndis_add_response(configNr, 629 sizeof(oid_supported_list) + sizeof(rndis_query_cmplt_type)); 630 if (!r) 631 return -ENOMEM; 632 resp = (rndis_query_cmplt_type *)r->buf; 633 634 resp->MessageType = cpu_to_le32(RNDIS_MSG_QUERY_C); 635 resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ 636 637 if (gen_ndis_query_resp(configNr, le32_to_cpu(buf->OID), 638 le32_to_cpu(buf->InformationBufferOffset) 639 + 8 + (u8 *)buf, 640 le32_to_cpu(buf->InformationBufferLength), 641 r)) { 642 /* OID not supported */ 643 resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED); 644 resp->MessageLength = cpu_to_le32(sizeof *resp); 645 resp->InformationBufferLength = cpu_to_le32(0); 646 resp->InformationBufferOffset = cpu_to_le32(0); 647 } else 648 resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); 649 650 params->resp_avail(params->v); 651 return 0; 652} 653 654static int rndis_set_response(int configNr, rndis_set_msg_type *buf) 655{ 656 u32 BufLength, BufOffset; 657 rndis_set_cmplt_type *resp; 658 rndis_resp_t *r; 659 struct rndis_params *params = rndis_per_dev_params + configNr; 660 661 r = rndis_add_response(configNr, sizeof(rndis_set_cmplt_type)); 662 if (!r) 663 return -ENOMEM; 664 resp = (rndis_set_cmplt_type *)r->buf; 665 666 BufLength = le32_to_cpu(buf->InformationBufferLength); 667 BufOffset = le32_to_cpu(buf->InformationBufferOffset); 668 669#ifdef VERBOSE_DEBUG 670 pr_debug("%s: Length: %d\n", __func__, BufLength); 671 pr_debug("%s: Offset: %d\n", __func__, BufOffset); 672 pr_debug("%s: InfoBuffer: ", __func__); 673 674 for (i = 0; i < BufLength; i++) { 675 pr_debug("%02x ", *(((u8 *) buf) + i + 8 + BufOffset)); 676 } 677 678 pr_debug("\n"); 679#endif 680 681 resp->MessageType = cpu_to_le32(RNDIS_MSG_SET_C); 682 resp->MessageLength = cpu_to_le32(16); 683 resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ 684 if (gen_ndis_set_resp(configNr, le32_to_cpu(buf->OID), 685 ((u8 *)buf) + 8 + BufOffset, BufLength, r)) 686 resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED); 687 else 688 resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); 689 690 params->resp_avail(params->v); 691 return 0; 692} 693 694static int rndis_reset_response(int configNr, rndis_reset_msg_type *buf) 695{ 696 rndis_reset_cmplt_type *resp; 697 rndis_resp_t *r; 698 struct rndis_params *params = rndis_per_dev_params + configNr; 699 u32 length; 700 u8 *xbuf; 701 702 /* drain the response queue */ 703 while ((xbuf = rndis_get_next_response(configNr, &length))) 704 rndis_free_response(configNr, xbuf); 705 706 r = rndis_add_response(configNr, sizeof(rndis_reset_cmplt_type)); 707 if (!r) 708 return -ENOMEM; 709 resp = (rndis_reset_cmplt_type *)r->buf; 710 711 resp->MessageType = cpu_to_le32(RNDIS_MSG_RESET_C); 712 resp->MessageLength = cpu_to_le32(16); 713 resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); 714 /* resent information */ 715 resp->AddressingReset = cpu_to_le32(1); 716 717 params->resp_avail(params->v); 718 return 0; 719} 720 721static int rndis_keepalive_response(int configNr, 722 rndis_keepalive_msg_type *buf) 723{ 724 rndis_keepalive_cmplt_type *resp; 725 rndis_resp_t *r; 726 struct rndis_params *params = rndis_per_dev_params + configNr; 727 728 /* host "should" check only in RNDIS_DATA_INITIALIZED state */ 729 730 r = rndis_add_response(configNr, sizeof(rndis_keepalive_cmplt_type)); 731 if (!r) 732 return -ENOMEM; 733 resp = (rndis_keepalive_cmplt_type *)r->buf; 734 735 resp->MessageType = cpu_to_le32(RNDIS_MSG_KEEPALIVE_C); 736 resp->MessageLength = cpu_to_le32(16); 737 resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ 738 resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); 739 740 params->resp_avail(params->v); 741 return 0; 742} 743 744 745/* 746 * Device to Host Comunication 747 */ 748static int rndis_indicate_status_msg(int configNr, u32 status) 749{ 750 rndis_indicate_status_msg_type *resp; 751 rndis_resp_t *r; 752 struct rndis_params *params = rndis_per_dev_params + configNr; 753 754 if (params->state == RNDIS_UNINITIALIZED) 755 return -ENOTSUPP; 756 757 r = rndis_add_response(configNr, 758 sizeof(rndis_indicate_status_msg_type)); 759 if (!r) 760 return -ENOMEM; 761 resp = (rndis_indicate_status_msg_type *)r->buf; 762 763 resp->MessageType = cpu_to_le32(RNDIS_MSG_INDICATE); 764 resp->MessageLength = cpu_to_le32(20); 765 resp->Status = cpu_to_le32(status); 766 resp->StatusBufferLength = cpu_to_le32(0); 767 resp->StatusBufferOffset = cpu_to_le32(0); 768 769 params->resp_avail(params->v); 770 return 0; 771} 772 773int rndis_signal_connect(int configNr) 774{ 775 rndis_per_dev_params[configNr].media_state 776 = RNDIS_MEDIA_STATE_CONNECTED; 777 return rndis_indicate_status_msg(configNr, 778 RNDIS_STATUS_MEDIA_CONNECT); 779} 780EXPORT_SYMBOL_GPL(rndis_signal_connect); 781 782int rndis_signal_disconnect(int configNr) 783{ 784 rndis_per_dev_params[configNr].media_state 785 = RNDIS_MEDIA_STATE_DISCONNECTED; 786 return rndis_indicate_status_msg(configNr, 787 RNDIS_STATUS_MEDIA_DISCONNECT); 788} 789EXPORT_SYMBOL_GPL(rndis_signal_disconnect); 790 791void rndis_uninit(int configNr) 792{ 793 u8 *buf; 794 u32 length; 795 796 if (configNr >= RNDIS_MAX_CONFIGS) 797 return; 798 rndis_per_dev_params[configNr].state = RNDIS_UNINITIALIZED; 799 800 /* drain the response queue */ 801 while ((buf = rndis_get_next_response(configNr, &length))) 802 rndis_free_response(configNr, buf); 803} 804EXPORT_SYMBOL_GPL(rndis_uninit); 805 806void rndis_set_host_mac(int configNr, const u8 *addr) 807{ 808 rndis_per_dev_params[configNr].host_mac = addr; 809} 810EXPORT_SYMBOL_GPL(rndis_set_host_mac); 811 812/* 813 * Message Parser 814 */ 815int rndis_msg_parser(u8 configNr, u8 *buf) 816{ 817 u32 MsgType, MsgLength; 818 __le32 *tmp; 819 struct rndis_params *params; 820 821 if (!buf) 822 return -ENOMEM; 823 824 tmp = (__le32 *)buf; 825 MsgType = get_unaligned_le32(tmp++); 826 MsgLength = get_unaligned_le32(tmp++); 827 828 if (configNr >= RNDIS_MAX_CONFIGS) 829 return -ENOTSUPP; 830 params = &rndis_per_dev_params[configNr]; 831 832 /* NOTE: RNDIS is *EXTREMELY* chatty ... Windows constantly polls for 833 * rx/tx statistics and link status, in addition to KEEPALIVE traffic 834 * and normal HC level polling to see if there's any IN traffic. 835 */ 836 837 /* For USB: responses may take up to 10 seconds */ 838 switch (MsgType) { 839 case RNDIS_MSG_INIT: 840 pr_debug("%s: RNDIS_MSG_INIT\n", 841 __func__); 842 params->state = RNDIS_INITIALIZED; 843 return rndis_init_response(configNr, 844 (rndis_init_msg_type *)buf); 845 846 case RNDIS_MSG_HALT: 847 pr_debug("%s: RNDIS_MSG_HALT\n", 848 __func__); 849 params->state = RNDIS_UNINITIALIZED; 850 if (params->dev) { 851 netif_carrier_off(params->dev); 852 netif_stop_queue(params->dev); 853 } 854 return 0; 855 856 case RNDIS_MSG_QUERY: 857 return rndis_query_response(configNr, 858 (rndis_query_msg_type *)buf); 859 860 case RNDIS_MSG_SET: 861 return rndis_set_response(configNr, 862 (rndis_set_msg_type *)buf); 863 864 case RNDIS_MSG_RESET: 865 pr_debug("%s: RNDIS_MSG_RESET\n", 866 __func__); 867 return rndis_reset_response(configNr, 868 (rndis_reset_msg_type *)buf); 869 870 case RNDIS_MSG_KEEPALIVE: 871 /* For USB: host does this every 5 seconds */ 872 if (rndis_debug > 1) 873 pr_debug("%s: RNDIS_MSG_KEEPALIVE\n", 874 __func__); 875 return rndis_keepalive_response(configNr, 876 (rndis_keepalive_msg_type *) 877 buf); 878 879 default: 880 /* At least Windows XP emits some undefined RNDIS messages. 881 * In one case those messages seemed to relate to the host 882 * suspending itself. 883 */ 884 pr_warning("%s: unknown RNDIS message 0x%08X len %d\n", 885 __func__, MsgType, MsgLength); 886 print_hex_dump_bytes(__func__, DUMP_PREFIX_OFFSET, 887 buf, MsgLength); 888 break; 889 } 890 891 return -ENOTSUPP; 892} 893EXPORT_SYMBOL_GPL(rndis_msg_parser); 894 895int rndis_register(void (*resp_avail)(void *v), void *v) 896{ 897 u8 i; 898 899 if (!resp_avail) 900 return -EINVAL; 901 902 for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { 903 if (!rndis_per_dev_params[i].used) { 904 rndis_per_dev_params[i].used = 1; 905 rndis_per_dev_params[i].resp_avail = resp_avail; 906 rndis_per_dev_params[i].v = v; 907 pr_debug("%s: configNr = %d\n", __func__, i); 908 return i; 909 } 910 } 911 pr_debug("failed\n"); 912 913 return -ENODEV; 914} 915EXPORT_SYMBOL_GPL(rndis_register); 916 917void rndis_deregister(int configNr) 918{ 919 pr_debug("%s:\n", __func__); 920 921 if (configNr >= RNDIS_MAX_CONFIGS) return; 922 rndis_per_dev_params[configNr].used = 0; 923} 924EXPORT_SYMBOL_GPL(rndis_deregister); 925 926int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter) 927{ 928 pr_debug("%s:\n", __func__); 929 if (!dev) 930 return -EINVAL; 931 if (configNr >= RNDIS_MAX_CONFIGS) return -1; 932 933 rndis_per_dev_params[configNr].dev = dev; 934 rndis_per_dev_params[configNr].filter = cdc_filter; 935 936 rndis_ul_max_xfer_size_rcvd = 0; 937 rndis_ul_max_pkt_per_xfer_rcvd = 0; 938 return 0; 939} 940EXPORT_SYMBOL_GPL(rndis_set_param_dev); 941 942int rndis_set_param_vendor(u8 configNr, u32 vendorID, const char *vendorDescr) 943{ 944 pr_debug("%s:\n", __func__); 945 if (!vendorDescr) return -1; 946 if (configNr >= RNDIS_MAX_CONFIGS) return -1; 947 948 rndis_per_dev_params[configNr].vendorID = vendorID; 949 rndis_per_dev_params[configNr].vendorDescr = vendorDescr; 950 951 return 0; 952} 953EXPORT_SYMBOL_GPL(rndis_set_param_vendor); 954 955int rndis_set_param_medium(u8 configNr, u32 medium, u32 speed) 956{ 957 pr_debug("%s: %u %u\n", __func__, medium, speed); 958 if (configNr >= RNDIS_MAX_CONFIGS) return -1; 959 960 rndis_per_dev_params[configNr].medium = medium; 961 rndis_per_dev_params[configNr].speed = speed; 962 963 return 0; 964} 965EXPORT_SYMBOL_GPL(rndis_set_param_medium); 966 967void rndis_set_max_pkt_xfer(u8 configNr, u8 max_pkt_per_xfer) 968{ 969 pr_debug("%s:\n", __func__); 970 971 rndis_per_dev_params[configNr].max_pkt_per_xfer = max_pkt_per_xfer; 972} 973 974void rndis_add_hdr(struct sk_buff *skb) 975{ 976 struct rndis_packet_msg_type *header; 977 978 if (!skb) 979 return; 980 header = (void *)skb_push(skb, sizeof(*header)); 981 memset(header, 0, sizeof *header); 982 header->MessageType = cpu_to_le32(RNDIS_MSG_PACKET); 983 header->MessageLength = cpu_to_le32(skb->len); 984 header->DataOffset = cpu_to_le32(36); 985 header->DataLength = cpu_to_le32(skb->len - sizeof(*header)); 986} 987EXPORT_SYMBOL_GPL(rndis_add_hdr); 988 989void rndis_free_response(int configNr, u8 *buf) 990{ 991 rndis_resp_t *r; 992 struct list_head *act, *tmp; 993 994 list_for_each_safe(act, tmp, 995 &(rndis_per_dev_params[configNr].resp_queue)) 996 { 997 r = list_entry(act, rndis_resp_t, list); 998 if (r && r->buf == buf) { 999 list_del(&r->list); 1000 kfree(r); 1001 } 1002 } 1003} 1004EXPORT_SYMBOL_GPL(rndis_free_response); 1005 1006u8 *rndis_get_next_response(int configNr, u32 *length) 1007{ 1008 rndis_resp_t *r; 1009 struct list_head *act, *tmp; 1010 1011 if (!length) return NULL; 1012 1013 list_for_each_safe(act, tmp, 1014 &(rndis_per_dev_params[configNr].resp_queue)) 1015 { 1016 r = list_entry(act, rndis_resp_t, list); 1017 if (!r->send) { 1018 r->send = 1; 1019 *length = r->length; 1020 return r->buf; 1021 } 1022 } 1023 1024 return NULL; 1025} 1026EXPORT_SYMBOL_GPL(rndis_get_next_response); 1027 1028static rndis_resp_t *rndis_add_response(int configNr, u32 length) 1029{ 1030 rndis_resp_t *r; 1031 1032 /* NOTE: this gets copied into ether.c USB_BUFSIZ bytes ... */ 1033 r = kmalloc(sizeof(rndis_resp_t) + length, GFP_ATOMIC); 1034 if (!r) return NULL; 1035 1036 r->buf = (u8 *)(r + 1); 1037 r->length = length; 1038 r->send = 0; 1039 1040 list_add_tail(&r->list, 1041 &(rndis_per_dev_params[configNr].resp_queue)); 1042 return r; 1043} 1044 1045int rndis_rm_hdr(struct gether *port, 1046 struct sk_buff *skb, 1047 struct sk_buff_head *list) 1048{ 1049 int num_pkts = 1; 1050 1051 if (skb->len > rndis_ul_max_xfer_size_rcvd) 1052 rndis_ul_max_xfer_size_rcvd = skb->len; 1053 1054 while (skb->len) { 1055 struct rndis_packet_msg_type *hdr; 1056 struct sk_buff *skb2; 1057 u32 msg_len, data_offset, data_len; 1058 1059 /* some rndis hosts send extra byte to avoid zlp, ignore it */ 1060 if (skb->len == 1) { 1061 dev_kfree_skb_any(skb); 1062 return 0; 1063 } 1064 1065 if (skb->len < sizeof *hdr) { 1066 pr_err("invalid rndis pkt: skblen:%u hdr_len:%u", 1067 skb->len, sizeof *hdr); 1068 dev_kfree_skb_any(skb); 1069 return -EINVAL; 1070 } 1071 1072 hdr = (void *)skb->data; 1073 msg_len = le32_to_cpu(hdr->MessageLength); 1074 data_offset = le32_to_cpu(hdr->DataOffset); 1075 data_len = le32_to_cpu(hdr->DataLength); 1076 1077 if (skb->len < msg_len || 1078 ((data_offset + data_len + 8) > msg_len)) { 1079 pr_err("invalid rndis message: %d/%d/%d/%d, len:%d\n", 1080 le32_to_cpu(hdr->MessageType), 1081 msg_len, data_offset, data_len, skb->len); 1082 dev_kfree_skb_any(skb); 1083 return -EOVERFLOW; 1084 } 1085 if (le32_to_cpu(hdr->MessageType) != RNDIS_MSG_PACKET) { 1086 pr_err("invalid rndis message: %d/%d/%d/%d, len:%d\n", 1087 le32_to_cpu(hdr->MessageType), 1088 msg_len, data_offset, data_len, skb->len); 1089 dev_kfree_skb_any(skb); 1090 return -EINVAL; 1091 } 1092 1093 skb_pull(skb, data_offset + 8); 1094 1095 if (msg_len == skb->len) { 1096 skb_trim(skb, data_len); 1097 break; 1098 } 1099 1100 skb2 = skb_clone(skb, GFP_ATOMIC); 1101 if (!skb2) { 1102 pr_err("%s:skb clone failed\n", __func__); 1103 dev_kfree_skb_any(skb); 1104 return -ENOMEM; 1105 } 1106 1107 skb_pull(skb, msg_len - sizeof *hdr); 1108 skb_trim(skb2, data_len); 1109 skb_queue_tail(list, skb2); 1110 1111 num_pkts++; 1112 } 1113 1114 if (num_pkts > rndis_ul_max_pkt_per_xfer_rcvd) 1115 rndis_ul_max_pkt_per_xfer_rcvd = num_pkts; 1116 1117 skb_queue_tail(list, skb); 1118 return 0; 1119} 1120EXPORT_SYMBOL_GPL(rndis_rm_hdr); 1121 1122#ifdef CONFIG_USB_GADGET_DEBUG_FILES 1123 1124static int rndis_proc_show(struct seq_file *m, void *v) 1125{ 1126 rndis_params *param = m->private; 1127 1128 seq_printf(m, 1129 "Config Nr. %d\n" 1130 "used : %s\n" 1131 "state : %s\n" 1132 "medium : 0x%08X\n" 1133 "speed : %d\n" 1134 "cable : %s\n" 1135 "vendor ID : 0x%08X\n" 1136 "vendor : %s\n", 1137 param->confignr, (param->used) ? "y" : "n", 1138 ({ char *s = "?"; 1139 switch (param->state) { 1140 case RNDIS_UNINITIALIZED: 1141 s = "RNDIS_UNINITIALIZED"; break; 1142 case RNDIS_INITIALIZED: 1143 s = "RNDIS_INITIALIZED"; break; 1144 case RNDIS_DATA_INITIALIZED: 1145 s = "RNDIS_DATA_INITIALIZED"; break; 1146 } s; }), 1147 param->medium, 1148 (param->media_state) ? 0 : param->speed*100, 1149 (param->media_state) ? "disconnected" : "connected", 1150 param->vendorID, param->vendorDescr); 1151 return 0; 1152} 1153 1154static ssize_t rndis_proc_write(struct file *file, const char __user *buffer, 1155 size_t count, loff_t *ppos) 1156{ 1157 rndis_params *p = PDE_DATA(file_inode(file)); 1158 u32 speed = 0; 1159 int i, fl_speed = 0; 1160 1161 for (i = 0; i < count; i++) { 1162 char c; 1163 if (get_user(c, buffer)) 1164 return -EFAULT; 1165 switch (c) { 1166 case '0': 1167 case '1': 1168 case '2': 1169 case '3': 1170 case '4': 1171 case '5': 1172 case '6': 1173 case '7': 1174 case '8': 1175 case '9': 1176 fl_speed = 1; 1177 speed = speed * 10 + c - '0'; 1178 break; 1179 case 'C': 1180 case 'c': 1181 rndis_signal_connect(p->confignr); 1182 break; 1183 case 'D': 1184 case 'd': 1185 rndis_signal_disconnect(p->confignr); 1186 break; 1187 default: 1188 if (fl_speed) p->speed = speed; 1189 else pr_debug("%c is not valid\n", c); 1190 break; 1191 } 1192 1193 buffer++; 1194 } 1195 1196 return count; 1197} 1198 1199static int rndis_proc_open(struct inode *inode, struct file *file) 1200{ 1201 return single_open(file, rndis_proc_show, PDE_DATA(inode)); 1202} 1203 1204static const struct file_operations rndis_proc_fops = { 1205 .owner = THIS_MODULE, 1206 .open = rndis_proc_open, 1207 .read = seq_read, 1208 .llseek = seq_lseek, 1209 .release = single_release, 1210 .write = rndis_proc_write, 1211}; 1212 1213#define NAME_TEMPLATE "driver/rndis-%03d" 1214 1215static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS]; 1216 1217#endif /* CONFIG_USB_GADGET_DEBUG_FILES */ 1218 1219 1220int rndis_init(void) 1221{ 1222 u8 i; 1223 1224 for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { 1225#ifdef CONFIG_USB_GADGET_DEBUG_FILES 1226 char name [20]; 1227 1228 sprintf(name, NAME_TEMPLATE, i); 1229 rndis_connect_state[i] = proc_create_data(name, 0660, NULL, 1230 &rndis_proc_fops, 1231 (void *)(rndis_per_dev_params + i)); 1232 if (!rndis_connect_state[i]) { 1233 pr_debug("%s: remove entries", __func__); 1234 while (i) { 1235 sprintf(name, NAME_TEMPLATE, --i); 1236 remove_proc_entry(name, NULL); 1237 } 1238 pr_debug("\n"); 1239 return -EIO; 1240 } 1241#endif 1242 rndis_per_dev_params[i].confignr = i; 1243 rndis_per_dev_params[i].used = 0; 1244 rndis_per_dev_params[i].state = RNDIS_UNINITIALIZED; 1245 rndis_per_dev_params[i].media_state 1246 = RNDIS_MEDIA_STATE_DISCONNECTED; 1247 INIT_LIST_HEAD(&(rndis_per_dev_params[i].resp_queue)); 1248 } 1249 1250 return 0; 1251} 1252 1253void rndis_exit(void) 1254{ 1255#ifdef CONFIG_USB_GADGET_DEBUG_FILES 1256 u8 i; 1257 char name[20]; 1258 1259 for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { 1260 sprintf(name, NAME_TEMPLATE, i); 1261 remove_proc_entry(name, NULL); 1262 } 1263#endif 1264} 1265 1266