diff options
Diffstat (limited to 'drivers/usb/gadget/rndis.c')
-rw-r--r-- | drivers/usb/gadget/rndis.c | 421 |
1 files changed, 85 insertions, 336 deletions
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index d0677f5d3cd5..7228e8562236 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c | |||
@@ -1,8 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * RNDIS MSG parser | 2 | * RNDIS MSG parser |
3 | * | 3 | * |
4 | * Version: $Id: rndis.c,v 1.19 2004/03/25 21:33:46 robert Exp $ | ||
5 | * | ||
6 | * Authors: Benedikt Spranger, Pengutronix | 4 | * Authors: Benedikt Spranger, Pengutronix |
7 | * Robert Schwebel, Pengutronix | 5 | * Robert Schwebel, Pengutronix |
8 | * | 6 | * |
@@ -30,6 +28,7 @@ | |||
30 | #include <linux/init.h> | 28 | #include <linux/init.h> |
31 | #include <linux/list.h> | 29 | #include <linux/list.h> |
32 | #include <linux/proc_fs.h> | 30 | #include <linux/proc_fs.h> |
31 | #include <linux/seq_file.h> | ||
33 | #include <linux/netdevice.h> | 32 | #include <linux/netdevice.h> |
34 | 33 | ||
35 | #include <asm/io.h> | 34 | #include <asm/io.h> |
@@ -38,9 +37,7 @@ | |||
38 | #include <asm/unaligned.h> | 37 | #include <asm/unaligned.h> |
39 | 38 | ||
40 | 39 | ||
41 | #undef RNDIS_PM | 40 | #undef VERBOSE_DEBUG |
42 | #undef RNDIS_WAKEUP | ||
43 | #undef VERBOSE | ||
44 | 41 | ||
45 | #include "rndis.h" | 42 | #include "rndis.h" |
46 | 43 | ||
@@ -96,9 +93,6 @@ static const u32 oid_supported_list [] = | |||
96 | OID_GEN_MAXIMUM_TOTAL_SIZE, | 93 | OID_GEN_MAXIMUM_TOTAL_SIZE, |
97 | OID_GEN_MEDIA_CONNECT_STATUS, | 94 | OID_GEN_MEDIA_CONNECT_STATUS, |
98 | OID_GEN_PHYSICAL_MEDIUM, | 95 | OID_GEN_PHYSICAL_MEDIUM, |
99 | #if 0 | ||
100 | OID_GEN_RNDIS_CONFIG_PARAMETER, | ||
101 | #endif | ||
102 | 96 | ||
103 | /* the statistical stuff */ | 97 | /* the statistical stuff */ |
104 | OID_GEN_XMIT_OK, | 98 | OID_GEN_XMIT_OK, |
@@ -146,7 +140,14 @@ static const u32 oid_supported_list [] = | |||
146 | #endif /* RNDIS_OPTIONAL_STATS */ | 140 | #endif /* RNDIS_OPTIONAL_STATS */ |
147 | 141 | ||
148 | #ifdef RNDIS_PM | 142 | #ifdef RNDIS_PM |
149 | /* PM and wakeup are mandatory for USB: */ | 143 | /* PM and wakeup are "mandatory" for USB, but the RNDIS specs |
144 | * don't say what they mean ... and the NDIS specs are often | ||
145 | * confusing and/or ambiguous in this context. (That is, more | ||
146 | * so than their specs for the other OIDs.) | ||
147 | * | ||
148 | * FIXME someone who knows what these should do, please | ||
149 | * implement them! | ||
150 | */ | ||
150 | 151 | ||
151 | /* power management */ | 152 | /* power management */ |
152 | OID_PNP_CAPABILITIES, | 153 | OID_PNP_CAPABILITIES, |
@@ -173,6 +174,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
173 | __le32 *outbuf; | 174 | __le32 *outbuf; |
174 | int i, count; | 175 | int i, count; |
175 | rndis_query_cmplt_type *resp; | 176 | rndis_query_cmplt_type *resp; |
177 | struct net_device *net; | ||
178 | struct net_device_stats *stats; | ||
176 | 179 | ||
177 | if (!r) return -ENOMEM; | 180 | if (!r) return -ENOMEM; |
178 | resp = (rndis_query_cmplt_type *) r->buf; | 181 | resp = (rndis_query_cmplt_type *) r->buf; |
@@ -194,6 +197,12 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
194 | outbuf = (__le32 *) &resp[1]; | 197 | outbuf = (__le32 *) &resp[1]; |
195 | resp->InformationBufferOffset = __constant_cpu_to_le32 (16); | 198 | resp->InformationBufferOffset = __constant_cpu_to_le32 (16); |
196 | 199 | ||
200 | net = rndis_per_dev_params[configNr].dev; | ||
201 | if (net->get_stats) | ||
202 | stats = net->get_stats(net); | ||
203 | else | ||
204 | stats = NULL; | ||
205 | |||
197 | switch (OID) { | 206 | switch (OID) { |
198 | 207 | ||
199 | /* general oids (table 4-1) */ | 208 | /* general oids (table 4-1) */ |
@@ -350,11 +359,9 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
350 | case OID_GEN_XMIT_OK: | 359 | case OID_GEN_XMIT_OK: |
351 | if (rndis_debug > 1) | 360 | if (rndis_debug > 1) |
352 | DBG("%s: OID_GEN_XMIT_OK\n", __func__); | 361 | DBG("%s: OID_GEN_XMIT_OK\n", __func__); |
353 | if (rndis_per_dev_params [configNr].stats) { | 362 | if (stats) { |
354 | *outbuf = cpu_to_le32 ( | 363 | *outbuf = cpu_to_le32(stats->tx_packets |
355 | rndis_per_dev_params [configNr].stats->tx_packets - | 364 | - stats->tx_errors - stats->tx_dropped); |
356 | rndis_per_dev_params [configNr].stats->tx_errors - | ||
357 | rndis_per_dev_params [configNr].stats->tx_dropped); | ||
358 | retval = 0; | 365 | retval = 0; |
359 | } | 366 | } |
360 | break; | 367 | break; |
@@ -363,11 +370,9 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
363 | case OID_GEN_RCV_OK: | 370 | case OID_GEN_RCV_OK: |
364 | if (rndis_debug > 1) | 371 | if (rndis_debug > 1) |
365 | DBG("%s: OID_GEN_RCV_OK\n", __func__); | 372 | DBG("%s: OID_GEN_RCV_OK\n", __func__); |
366 | if (rndis_per_dev_params [configNr].stats) { | 373 | if (stats) { |
367 | *outbuf = cpu_to_le32 ( | 374 | *outbuf = cpu_to_le32(stats->rx_packets |
368 | rndis_per_dev_params [configNr].stats->rx_packets - | 375 | - stats->rx_errors - stats->rx_dropped); |
369 | rndis_per_dev_params [configNr].stats->rx_errors - | ||
370 | rndis_per_dev_params [configNr].stats->rx_dropped); | ||
371 | retval = 0; | 376 | retval = 0; |
372 | } | 377 | } |
373 | break; | 378 | break; |
@@ -376,9 +381,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
376 | case OID_GEN_XMIT_ERROR: | 381 | case OID_GEN_XMIT_ERROR: |
377 | if (rndis_debug > 1) | 382 | if (rndis_debug > 1) |
378 | DBG("%s: OID_GEN_XMIT_ERROR\n", __func__); | 383 | DBG("%s: OID_GEN_XMIT_ERROR\n", __func__); |
379 | if (rndis_per_dev_params [configNr].stats) { | 384 | if (stats) { |
380 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | 385 | *outbuf = cpu_to_le32(stats->tx_errors); |
381 | .stats->tx_errors); | ||
382 | retval = 0; | 386 | retval = 0; |
383 | } | 387 | } |
384 | break; | 388 | break; |
@@ -387,9 +391,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
387 | case OID_GEN_RCV_ERROR: | 391 | case OID_GEN_RCV_ERROR: |
388 | if (rndis_debug > 1) | 392 | if (rndis_debug > 1) |
389 | DBG("%s: OID_GEN_RCV_ERROR\n", __func__); | 393 | DBG("%s: OID_GEN_RCV_ERROR\n", __func__); |
390 | if (rndis_per_dev_params [configNr].stats) { | 394 | if (stats) { |
391 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | 395 | *outbuf = cpu_to_le32(stats->rx_errors); |
392 | .stats->rx_errors); | ||
393 | retval = 0; | 396 | retval = 0; |
394 | } | 397 | } |
395 | break; | 398 | break; |
@@ -397,150 +400,12 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
397 | /* mandatory */ | 400 | /* mandatory */ |
398 | case OID_GEN_RCV_NO_BUFFER: | 401 | case OID_GEN_RCV_NO_BUFFER: |
399 | DBG("%s: OID_GEN_RCV_NO_BUFFER\n", __func__); | 402 | DBG("%s: OID_GEN_RCV_NO_BUFFER\n", __func__); |
400 | if (rndis_per_dev_params [configNr].stats) { | 403 | if (stats) { |
401 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | 404 | *outbuf = cpu_to_le32(stats->rx_dropped); |
402 | .stats->rx_dropped); | ||
403 | retval = 0; | ||
404 | } | ||
405 | break; | ||
406 | |||
407 | #ifdef RNDIS_OPTIONAL_STATS | ||
408 | case OID_GEN_DIRECTED_BYTES_XMIT: | ||
409 | DBG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __func__); | ||
410 | /* | ||
411 | * Aunt Tilly's size of shoes | ||
412 | * minus antarctica count of penguins | ||
413 | * divided by weight of Alpha Centauri | ||
414 | */ | ||
415 | if (rndis_per_dev_params [configNr].stats) { | ||
416 | *outbuf = cpu_to_le32 ( | ||
417 | (rndis_per_dev_params [configNr] | ||
418 | .stats->tx_packets - | ||
419 | rndis_per_dev_params [configNr] | ||
420 | .stats->tx_errors - | ||
421 | rndis_per_dev_params [configNr] | ||
422 | .stats->tx_dropped) | ||
423 | * 123); | ||
424 | retval = 0; | ||
425 | } | ||
426 | break; | ||
427 | |||
428 | case OID_GEN_DIRECTED_FRAMES_XMIT: | ||
429 | DBG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __func__); | ||
430 | /* dito */ | ||
431 | if (rndis_per_dev_params [configNr].stats) { | ||
432 | *outbuf = cpu_to_le32 ( | ||
433 | (rndis_per_dev_params [configNr] | ||
434 | .stats->tx_packets - | ||
435 | rndis_per_dev_params [configNr] | ||
436 | .stats->tx_errors - | ||
437 | rndis_per_dev_params [configNr] | ||
438 | .stats->tx_dropped) | ||
439 | / 123); | ||
440 | retval = 0; | ||
441 | } | ||
442 | break; | ||
443 | |||
444 | case OID_GEN_MULTICAST_BYTES_XMIT: | ||
445 | DBG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __func__); | ||
446 | if (rndis_per_dev_params [configNr].stats) { | ||
447 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | ||
448 | .stats->multicast*1234); | ||
449 | retval = 0; | ||
450 | } | ||
451 | break; | ||
452 | |||
453 | case OID_GEN_MULTICAST_FRAMES_XMIT: | ||
454 | DBG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __func__); | ||
455 | if (rndis_per_dev_params [configNr].stats) { | ||
456 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | ||
457 | .stats->multicast); | ||
458 | retval = 0; | ||
459 | } | ||
460 | break; | ||
461 | |||
462 | case OID_GEN_BROADCAST_BYTES_XMIT: | ||
463 | DBG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __func__); | ||
464 | if (rndis_per_dev_params [configNr].stats) { | ||
465 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | ||
466 | .stats->tx_packets/42*255); | ||
467 | retval = 0; | ||
468 | } | ||
469 | break; | ||
470 | |||
471 | case OID_GEN_BROADCAST_FRAMES_XMIT: | ||
472 | DBG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __func__); | ||
473 | if (rndis_per_dev_params [configNr].stats) { | ||
474 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | ||
475 | .stats->tx_packets/42); | ||
476 | retval = 0; | ||
477 | } | ||
478 | break; | ||
479 | |||
480 | case OID_GEN_DIRECTED_BYTES_RCV: | ||
481 | DBG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __func__); | ||
482 | *outbuf = __constant_cpu_to_le32 (0); | ||
483 | retval = 0; | ||
484 | break; | ||
485 | |||
486 | case OID_GEN_DIRECTED_FRAMES_RCV: | ||
487 | DBG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __func__); | ||
488 | *outbuf = __constant_cpu_to_le32 (0); | ||
489 | retval = 0; | ||
490 | break; | ||
491 | |||
492 | case OID_GEN_MULTICAST_BYTES_RCV: | ||
493 | DBG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __func__); | ||
494 | if (rndis_per_dev_params [configNr].stats) { | ||
495 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | ||
496 | .stats->multicast * 1111); | ||
497 | retval = 0; | ||
498 | } | ||
499 | break; | ||
500 | |||
501 | case OID_GEN_MULTICAST_FRAMES_RCV: | ||
502 | DBG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __func__); | ||
503 | if (rndis_per_dev_params [configNr].stats) { | ||
504 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | ||
505 | .stats->multicast); | ||
506 | retval = 0; | ||
507 | } | ||
508 | break; | ||
509 | |||
510 | case OID_GEN_BROADCAST_BYTES_RCV: | ||
511 | DBG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __func__); | ||
512 | if (rndis_per_dev_params [configNr].stats) { | ||
513 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | ||
514 | .stats->rx_packets/42*255); | ||
515 | retval = 0; | ||
516 | } | ||
517 | break; | ||
518 | |||
519 | case OID_GEN_BROADCAST_FRAMES_RCV: | ||
520 | DBG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __func__); | ||
521 | if (rndis_per_dev_params [configNr].stats) { | ||
522 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | ||
523 | .stats->rx_packets/42); | ||
524 | retval = 0; | 405 | retval = 0; |
525 | } | 406 | } |
526 | break; | 407 | break; |
527 | 408 | ||
528 | case OID_GEN_RCV_CRC_ERROR: | ||
529 | DBG("%s: OID_GEN_RCV_CRC_ERROR\n", __func__); | ||
530 | if (rndis_per_dev_params [configNr].stats) { | ||
531 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | ||
532 | .stats->rx_crc_errors); | ||
533 | retval = 0; | ||
534 | } | ||
535 | break; | ||
536 | |||
537 | case OID_GEN_TRANSMIT_QUEUE_LENGTH: | ||
538 | DBG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __func__); | ||
539 | *outbuf = __constant_cpu_to_le32 (0); | ||
540 | retval = 0; | ||
541 | break; | ||
542 | #endif /* RNDIS_OPTIONAL_STATS */ | ||
543 | |||
544 | /* ieee802.3 OIDs (table 4-3) */ | 409 | /* ieee802.3 OIDs (table 4-3) */ |
545 | 410 | ||
546 | /* mandatory */ | 411 | /* mandatory */ |
@@ -592,9 +457,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
592 | /* mandatory */ | 457 | /* mandatory */ |
593 | case OID_802_3_RCV_ERROR_ALIGNMENT: | 458 | case OID_802_3_RCV_ERROR_ALIGNMENT: |
594 | DBG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__); | 459 | DBG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__); |
595 | if (rndis_per_dev_params [configNr].stats) { | 460 | if (stats) { |
596 | *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] | 461 | *outbuf = cpu_to_le32(stats->rx_frame_errors); |
597 | .stats->rx_frame_errors); | ||
598 | retval = 0; | 462 | retval = 0; |
599 | } | 463 | } |
600 | break; | 464 | break; |
@@ -613,64 +477,6 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
613 | retval = 0; | 477 | retval = 0; |
614 | break; | 478 | break; |
615 | 479 | ||
616 | #ifdef RNDIS_OPTIONAL_STATS | ||
617 | case OID_802_3_XMIT_DEFERRED: | ||
618 | DBG("%s: OID_802_3_XMIT_DEFERRED\n", __func__); | ||
619 | /* TODO */ | ||
620 | break; | ||
621 | |||
622 | case OID_802_3_XMIT_MAX_COLLISIONS: | ||
623 | DBG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __func__); | ||
624 | /* TODO */ | ||
625 | break; | ||
626 | |||
627 | case OID_802_3_RCV_OVERRUN: | ||
628 | DBG("%s: OID_802_3_RCV_OVERRUN\n", __func__); | ||
629 | /* TODO */ | ||
630 | break; | ||
631 | |||
632 | case OID_802_3_XMIT_UNDERRUN: | ||
633 | DBG("%s: OID_802_3_XMIT_UNDERRUN\n", __func__); | ||
634 | /* TODO */ | ||
635 | break; | ||
636 | |||
637 | case OID_802_3_XMIT_HEARTBEAT_FAILURE: | ||
638 | DBG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __func__); | ||
639 | /* TODO */ | ||
640 | break; | ||
641 | |||
642 | case OID_802_3_XMIT_TIMES_CRS_LOST: | ||
643 | DBG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __func__); | ||
644 | /* TODO */ | ||
645 | break; | ||
646 | |||
647 | case OID_802_3_XMIT_LATE_COLLISIONS: | ||
648 | DBG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __func__); | ||
649 | /* TODO */ | ||
650 | break; | ||
651 | #endif /* RNDIS_OPTIONAL_STATS */ | ||
652 | |||
653 | #ifdef RNDIS_PM | ||
654 | /* power management OIDs (table 4-5) */ | ||
655 | case OID_PNP_CAPABILITIES: | ||
656 | DBG("%s: OID_PNP_CAPABILITIES\n", __func__); | ||
657 | |||
658 | /* for now, no wakeup capabilities */ | ||
659 | length = sizeof (struct NDIS_PNP_CAPABILITIES); | ||
660 | memset(outbuf, 0, length); | ||
661 | retval = 0; | ||
662 | break; | ||
663 | case OID_PNP_QUERY_POWER: | ||
664 | DBG("%s: OID_PNP_QUERY_POWER D%d\n", __func__, | ||
665 | get_unaligned_le32(buf) - 1); | ||
666 | /* only suspend is a real power state, and | ||
667 | * it can't be entered by OID_PNP_SET_POWER... | ||
668 | */ | ||
669 | length = 0; | ||
670 | retval = 0; | ||
671 | break; | ||
672 | #endif | ||
673 | |||
674 | default: | 480 | default: |
675 | pr_warning("%s: query unknown OID 0x%08X\n", | 481 | pr_warning("%s: query unknown OID 0x%08X\n", |
676 | __func__, OID); | 482 | __func__, OID); |
@@ -726,9 +532,6 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, | |||
726 | * what makes the packet flow start and stop, like | 532 | * what makes the packet flow start and stop, like |
727 | * activating the CDC Ethernet altsetting. | 533 | * activating the CDC Ethernet altsetting. |
728 | */ | 534 | */ |
729 | #ifdef RNDIS_PM | ||
730 | update_linkstate: | ||
731 | #endif | ||
732 | retval = 0; | 535 | retval = 0; |
733 | if (*params->filter) { | 536 | if (*params->filter) { |
734 | params->state = RNDIS_DATA_INITIALIZED; | 537 | params->state = RNDIS_DATA_INITIALIZED; |
@@ -747,49 +550,6 @@ update_linkstate: | |||
747 | DBG("%s: OID_802_3_MULTICAST_LIST\n", __func__); | 550 | DBG("%s: OID_802_3_MULTICAST_LIST\n", __func__); |
748 | retval = 0; | 551 | retval = 0; |
749 | break; | 552 | break; |
750 | #if 0 | ||
751 | case OID_GEN_RNDIS_CONFIG_PARAMETER: | ||
752 | { | ||
753 | struct rndis_config_parameter *param; | ||
754 | param = (struct rndis_config_parameter *) buf; | ||
755 | DBG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER '%*s'\n", | ||
756 | __func__, | ||
757 | min(cpu_to_le32(param->ParameterNameLength),80), | ||
758 | buf + param->ParameterNameOffset); | ||
759 | retval = 0; | ||
760 | } | ||
761 | break; | ||
762 | #endif | ||
763 | |||
764 | #ifdef RNDIS_PM | ||
765 | case OID_PNP_SET_POWER: | ||
766 | /* The only real power state is USB suspend, and RNDIS requests | ||
767 | * can't enter it; this one isn't really about power. After | ||
768 | * resuming, Windows forces a reset, and then SET_POWER D0. | ||
769 | * FIXME ... then things go batty; Windows wedges itself. | ||
770 | */ | ||
771 | i = get_unaligned_le32(buf); | ||
772 | DBG("%s: OID_PNP_SET_POWER D%d\n", __func__, i - 1); | ||
773 | switch (i) { | ||
774 | case NdisDeviceStateD0: | ||
775 | *params->filter = params->saved_filter; | ||
776 | goto update_linkstate; | ||
777 | case NdisDeviceStateD3: | ||
778 | case NdisDeviceStateD2: | ||
779 | case NdisDeviceStateD1: | ||
780 | params->saved_filter = *params->filter; | ||
781 | retval = 0; | ||
782 | break; | ||
783 | } | ||
784 | break; | ||
785 | |||
786 | #ifdef RNDIS_WAKEUP | ||
787 | // no wakeup support advertised, so wakeup OIDs always fail: | ||
788 | // - OID_PNP_ENABLE_WAKE_UP | ||
789 | // - OID_PNP_{ADD,REMOVE}_WAKE_UP_PATTERN | ||
790 | #endif | ||
791 | |||
792 | #endif /* RNDIS_PM */ | ||
793 | 553 | ||
794 | default: | 554 | default: |
795 | pr_warning("%s: set unknown OID 0x%08X, size %d\n", | 555 | pr_warning("%s: set unknown OID 0x%08X, size %d\n", |
@@ -807,8 +567,10 @@ static int rndis_init_response (int configNr, rndis_init_msg_type *buf) | |||
807 | { | 567 | { |
808 | rndis_init_cmplt_type *resp; | 568 | rndis_init_cmplt_type *resp; |
809 | rndis_resp_t *r; | 569 | rndis_resp_t *r; |
570 | struct rndis_params *params = rndis_per_dev_params + configNr; | ||
810 | 571 | ||
811 | if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; | 572 | if (!params->dev) |
573 | return -ENOTSUPP; | ||
812 | 574 | ||
813 | r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type)); | 575 | r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type)); |
814 | if (!r) | 576 | if (!r) |
@@ -826,7 +588,7 @@ static int rndis_init_response (int configNr, rndis_init_msg_type *buf) | |||
826 | resp->Medium = __constant_cpu_to_le32 (RNDIS_MEDIUM_802_3); | 588 | resp->Medium = __constant_cpu_to_le32 (RNDIS_MEDIUM_802_3); |
827 | resp->MaxPacketsPerTransfer = __constant_cpu_to_le32 (1); | 589 | resp->MaxPacketsPerTransfer = __constant_cpu_to_le32 (1); |
828 | resp->MaxTransferSize = cpu_to_le32 ( | 590 | resp->MaxTransferSize = cpu_to_le32 ( |
829 | rndis_per_dev_params [configNr].dev->mtu | 591 | params->dev->mtu |
830 | + sizeof (struct ethhdr) | 592 | + sizeof (struct ethhdr) |
831 | + sizeof (struct rndis_packet_msg_type) | 593 | + sizeof (struct rndis_packet_msg_type) |
832 | + 22); | 594 | + 22); |
@@ -834,10 +596,7 @@ static int rndis_init_response (int configNr, rndis_init_msg_type *buf) | |||
834 | resp->AFListOffset = __constant_cpu_to_le32 (0); | 596 | resp->AFListOffset = __constant_cpu_to_le32 (0); |
835 | resp->AFListSize = __constant_cpu_to_le32 (0); | 597 | resp->AFListSize = __constant_cpu_to_le32 (0); |
836 | 598 | ||
837 | if (rndis_per_dev_params [configNr].ack) | 599 | params->resp_avail(params->v); |
838 | rndis_per_dev_params [configNr].ack ( | ||
839 | rndis_per_dev_params [configNr].dev); | ||
840 | |||
841 | return 0; | 600 | return 0; |
842 | } | 601 | } |
843 | 602 | ||
@@ -845,9 +604,11 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf) | |||
845 | { | 604 | { |
846 | rndis_query_cmplt_type *resp; | 605 | rndis_query_cmplt_type *resp; |
847 | rndis_resp_t *r; | 606 | rndis_resp_t *r; |
607 | struct rndis_params *params = rndis_per_dev_params + configNr; | ||
848 | 608 | ||
849 | // DBG("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID)); | 609 | // DBG("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID)); |
850 | if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; | 610 | if (!params->dev) |
611 | return -ENOTSUPP; | ||
851 | 612 | ||
852 | /* | 613 | /* |
853 | * we need more memory: | 614 | * we need more memory: |
@@ -878,9 +639,7 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf) | |||
878 | } else | 639 | } else |
879 | resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); | 640 | resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); |
880 | 641 | ||
881 | if (rndis_per_dev_params [configNr].ack) | 642 | params->resp_avail(params->v); |
882 | rndis_per_dev_params [configNr].ack ( | ||
883 | rndis_per_dev_params [configNr].dev); | ||
884 | return 0; | 643 | return 0; |
885 | } | 644 | } |
886 | 645 | ||
@@ -889,6 +648,7 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf) | |||
889 | u32 BufLength, BufOffset; | 648 | u32 BufLength, BufOffset; |
890 | rndis_set_cmplt_type *resp; | 649 | rndis_set_cmplt_type *resp; |
891 | rndis_resp_t *r; | 650 | rndis_resp_t *r; |
651 | struct rndis_params *params = rndis_per_dev_params + configNr; | ||
892 | 652 | ||
893 | r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type)); | 653 | r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type)); |
894 | if (!r) | 654 | if (!r) |
@@ -898,7 +658,7 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf) | |||
898 | BufLength = le32_to_cpu (buf->InformationBufferLength); | 658 | BufLength = le32_to_cpu (buf->InformationBufferLength); |
899 | BufOffset = le32_to_cpu (buf->InformationBufferOffset); | 659 | BufOffset = le32_to_cpu (buf->InformationBufferOffset); |
900 | 660 | ||
901 | #ifdef VERBOSE | 661 | #ifdef VERBOSE_DEBUG |
902 | DBG("%s: Length: %d\n", __func__, BufLength); | 662 | DBG("%s: Length: %d\n", __func__, BufLength); |
903 | DBG("%s: Offset: %d\n", __func__, BufOffset); | 663 | DBG("%s: Offset: %d\n", __func__, BufOffset); |
904 | DBG("%s: InfoBuffer: ", __func__); | 664 | DBG("%s: InfoBuffer: ", __func__); |
@@ -919,10 +679,7 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf) | |||
919 | else | 679 | else |
920 | resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); | 680 | resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); |
921 | 681 | ||
922 | if (rndis_per_dev_params [configNr].ack) | 682 | params->resp_avail(params->v); |
923 | rndis_per_dev_params [configNr].ack ( | ||
924 | rndis_per_dev_params [configNr].dev); | ||
925 | |||
926 | return 0; | 683 | return 0; |
927 | } | 684 | } |
928 | 685 | ||
@@ -930,6 +687,7 @@ static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf) | |||
930 | { | 687 | { |
931 | rndis_reset_cmplt_type *resp; | 688 | rndis_reset_cmplt_type *resp; |
932 | rndis_resp_t *r; | 689 | rndis_resp_t *r; |
690 | struct rndis_params *params = rndis_per_dev_params + configNr; | ||
933 | 691 | ||
934 | r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type)); | 692 | r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type)); |
935 | if (!r) | 693 | if (!r) |
@@ -942,10 +700,7 @@ static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf) | |||
942 | /* resent information */ | 700 | /* resent information */ |
943 | resp->AddressingReset = __constant_cpu_to_le32 (1); | 701 | resp->AddressingReset = __constant_cpu_to_le32 (1); |
944 | 702 | ||
945 | if (rndis_per_dev_params [configNr].ack) | 703 | params->resp_avail(params->v); |
946 | rndis_per_dev_params [configNr].ack ( | ||
947 | rndis_per_dev_params [configNr].dev); | ||
948 | |||
949 | return 0; | 704 | return 0; |
950 | } | 705 | } |
951 | 706 | ||
@@ -954,6 +709,7 @@ static int rndis_keepalive_response (int configNr, | |||
954 | { | 709 | { |
955 | rndis_keepalive_cmplt_type *resp; | 710 | rndis_keepalive_cmplt_type *resp; |
956 | rndis_resp_t *r; | 711 | rndis_resp_t *r; |
712 | struct rndis_params *params = rndis_per_dev_params + configNr; | ||
957 | 713 | ||
958 | /* host "should" check only in RNDIS_DATA_INITIALIZED state */ | 714 | /* host "should" check only in RNDIS_DATA_INITIALIZED state */ |
959 | 715 | ||
@@ -968,10 +724,7 @@ static int rndis_keepalive_response (int configNr, | |||
968 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ | 724 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ |
969 | resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); | 725 | resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); |
970 | 726 | ||
971 | if (rndis_per_dev_params [configNr].ack) | 727 | params->resp_avail(params->v); |
972 | rndis_per_dev_params [configNr].ack ( | ||
973 | rndis_per_dev_params [configNr].dev); | ||
974 | |||
975 | return 0; | 728 | return 0; |
976 | } | 729 | } |
977 | 730 | ||
@@ -983,8 +736,9 @@ static int rndis_indicate_status_msg (int configNr, u32 status) | |||
983 | { | 736 | { |
984 | rndis_indicate_status_msg_type *resp; | 737 | rndis_indicate_status_msg_type *resp; |
985 | rndis_resp_t *r; | 738 | rndis_resp_t *r; |
739 | struct rndis_params *params = rndis_per_dev_params + configNr; | ||
986 | 740 | ||
987 | if (rndis_per_dev_params [configNr].state == RNDIS_UNINITIALIZED) | 741 | if (params->state == RNDIS_UNINITIALIZED) |
988 | return -ENOTSUPP; | 742 | return -ENOTSUPP; |
989 | 743 | ||
990 | r = rndis_add_response (configNr, | 744 | r = rndis_add_response (configNr, |
@@ -1000,9 +754,7 @@ static int rndis_indicate_status_msg (int configNr, u32 status) | |||
1000 | resp->StatusBufferLength = __constant_cpu_to_le32 (0); | 754 | resp->StatusBufferLength = __constant_cpu_to_le32 (0); |
1001 | resp->StatusBufferOffset = __constant_cpu_to_le32 (0); | 755 | resp->StatusBufferOffset = __constant_cpu_to_le32 (0); |
1002 | 756 | ||
1003 | if (rndis_per_dev_params [configNr].ack) | 757 | params->resp_avail(params->v); |
1004 | rndis_per_dev_params [configNr].ack ( | ||
1005 | rndis_per_dev_params [configNr].dev); | ||
1006 | return 0; | 758 | return 0; |
1007 | } | 759 | } |
1008 | 760 | ||
@@ -1029,7 +781,6 @@ void rndis_uninit (int configNr) | |||
1029 | 781 | ||
1030 | if (configNr >= RNDIS_MAX_CONFIGS) | 782 | if (configNr >= RNDIS_MAX_CONFIGS) |
1031 | return; | 783 | return; |
1032 | rndis_per_dev_params [configNr].used = 0; | ||
1033 | rndis_per_dev_params [configNr].state = RNDIS_UNINITIALIZED; | 784 | rndis_per_dev_params [configNr].state = RNDIS_UNINITIALIZED; |
1034 | 785 | ||
1035 | /* drain the response queue */ | 786 | /* drain the response queue */ |
@@ -1142,21 +893,25 @@ int rndis_msg_parser (u8 configNr, u8 *buf) | |||
1142 | return -ENOTSUPP; | 893 | return -ENOTSUPP; |
1143 | } | 894 | } |
1144 | 895 | ||
1145 | int rndis_register (int (* rndis_control_ack) (struct net_device *)) | 896 | int rndis_register(void (*resp_avail)(void *v), void *v) |
1146 | { | 897 | { |
1147 | u8 i; | 898 | u8 i; |
1148 | 899 | ||
900 | if (!resp_avail) | ||
901 | return -EINVAL; | ||
902 | |||
1149 | for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { | 903 | for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { |
1150 | if (!rndis_per_dev_params [i].used) { | 904 | if (!rndis_per_dev_params [i].used) { |
1151 | rndis_per_dev_params [i].used = 1; | 905 | rndis_per_dev_params [i].used = 1; |
1152 | rndis_per_dev_params [i].ack = rndis_control_ack; | 906 | rndis_per_dev_params [i].resp_avail = resp_avail; |
907 | rndis_per_dev_params [i].v = v; | ||
1153 | DBG("%s: configNr = %d\n", __func__, i); | 908 | DBG("%s: configNr = %d\n", __func__, i); |
1154 | return i; | 909 | return i; |
1155 | } | 910 | } |
1156 | } | 911 | } |
1157 | DBG("failed\n"); | 912 | DBG("failed\n"); |
1158 | 913 | ||
1159 | return -1; | 914 | return -ENODEV; |
1160 | } | 915 | } |
1161 | 916 | ||
1162 | void rndis_deregister (int configNr) | 917 | void rndis_deregister (int configNr) |
@@ -1169,16 +924,14 @@ void rndis_deregister (int configNr) | |||
1169 | return; | 924 | return; |
1170 | } | 925 | } |
1171 | 926 | ||
1172 | int rndis_set_param_dev (u8 configNr, struct net_device *dev, | 927 | int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter) |
1173 | struct net_device_stats *stats, | ||
1174 | u16 *cdc_filter) | ||
1175 | { | 928 | { |
1176 | DBG("%s:\n", __func__ ); | 929 | DBG("%s:\n", __func__ ); |
1177 | if (!dev || !stats) return -1; | 930 | if (!dev) |
931 | return -EINVAL; | ||
1178 | if (configNr >= RNDIS_MAX_CONFIGS) return -1; | 932 | if (configNr >= RNDIS_MAX_CONFIGS) return -1; |
1179 | 933 | ||
1180 | rndis_per_dev_params [configNr].dev = dev; | 934 | rndis_per_dev_params [configNr].dev = dev; |
1181 | rndis_per_dev_params [configNr].stats = stats; | ||
1182 | rndis_per_dev_params [configNr].filter = cdc_filter; | 935 | rndis_per_dev_params [configNr].filter = cdc_filter; |
1183 | 936 | ||
1184 | return 0; | 937 | return 0; |
@@ -1296,14 +1049,11 @@ int rndis_rm_hdr(struct sk_buff *skb) | |||
1296 | 1049 | ||
1297 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | 1050 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES |
1298 | 1051 | ||
1299 | static int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof, | 1052 | static int rndis_proc_show(struct seq_file *m, void *v) |
1300 | void *data) | ||
1301 | { | 1053 | { |
1302 | char *out = page; | 1054 | rndis_params *param = m->private; |
1303 | int len; | ||
1304 | rndis_params *param = (rndis_params *) data; | ||
1305 | 1055 | ||
1306 | out += snprintf (out, count, | 1056 | seq_printf(m, |
1307 | "Config Nr. %d\n" | 1057 | "Config Nr. %d\n" |
1308 | "used : %s\n" | 1058 | "used : %s\n" |
1309 | "state : %s\n" | 1059 | "state : %s\n" |
@@ -1326,25 +1076,13 @@ static int rndis_proc_read (char *page, char **start, off_t off, int count, int | |||
1326 | (param->media_state) ? 0 : param->speed*100, | 1076 | (param->media_state) ? 0 : param->speed*100, |
1327 | (param->media_state) ? "disconnected" : "connected", | 1077 | (param->media_state) ? "disconnected" : "connected", |
1328 | param->vendorID, param->vendorDescr); | 1078 | param->vendorID, param->vendorDescr); |
1329 | 1079 | return 0; | |
1330 | len = out - page; | ||
1331 | len -= off; | ||
1332 | |||
1333 | if (len < count) { | ||
1334 | *eof = 1; | ||
1335 | if (len <= 0) | ||
1336 | return 0; | ||
1337 | } else | ||
1338 | len = count; | ||
1339 | |||
1340 | *start = page + off; | ||
1341 | return len; | ||
1342 | } | 1080 | } |
1343 | 1081 | ||
1344 | static int rndis_proc_write (struct file *file, const char __user *buffer, | 1082 | static ssize_t rndis_proc_write(struct file *file, const char __user *buffer, |
1345 | unsigned long count, void *data) | 1083 | size_t count, loff_t *ppos) |
1346 | { | 1084 | { |
1347 | rndis_params *p = data; | 1085 | rndis_params *p = PDE(file->f_path.dentry->d_inode)->data; |
1348 | u32 speed = 0; | 1086 | u32 speed = 0; |
1349 | int i, fl_speed = 0; | 1087 | int i, fl_speed = 0; |
1350 | 1088 | ||
@@ -1386,6 +1124,20 @@ static int rndis_proc_write (struct file *file, const char __user *buffer, | |||
1386 | return count; | 1124 | return count; |
1387 | } | 1125 | } |
1388 | 1126 | ||
1127 | static int rndis_proc_open(struct inode *inode, struct file *file) | ||
1128 | { | ||
1129 | return single_open(file, rndis_proc_show, PDE(inode)->data); | ||
1130 | } | ||
1131 | |||
1132 | static const struct file_operations rndis_proc_fops = { | ||
1133 | .owner = THIS_MODULE, | ||
1134 | .open = rndis_proc_open, | ||
1135 | .read = seq_read, | ||
1136 | .llseek = seq_lseek, | ||
1137 | .release = single_release, | ||
1138 | .write = rndis_proc_write, | ||
1139 | }; | ||
1140 | |||
1389 | #define NAME_TEMPLATE "driver/rndis-%03d" | 1141 | #define NAME_TEMPLATE "driver/rndis-%03d" |
1390 | 1142 | ||
1391 | static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS]; | 1143 | static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS]; |
@@ -1403,7 +1155,9 @@ int __init rndis_init (void) | |||
1403 | 1155 | ||
1404 | sprintf (name, NAME_TEMPLATE, i); | 1156 | sprintf (name, NAME_TEMPLATE, i); |
1405 | if (!(rndis_connect_state [i] | 1157 | if (!(rndis_connect_state [i] |
1406 | = create_proc_entry (name, 0660, NULL))) | 1158 | = proc_create_data(name, 0660, NULL, |
1159 | &rndis_proc_fops, | ||
1160 | (void *)(rndis_per_dev_params + i)))) | ||
1407 | { | 1161 | { |
1408 | DBG("%s :remove entries", __func__); | 1162 | DBG("%s :remove entries", __func__); |
1409 | while (i) { | 1163 | while (i) { |
@@ -1413,11 +1167,6 @@ int __init rndis_init (void) | |||
1413 | DBG("\n"); | 1167 | DBG("\n"); |
1414 | return -EIO; | 1168 | return -EIO; |
1415 | } | 1169 | } |
1416 | |||
1417 | rndis_connect_state [i]->write_proc = rndis_proc_write; | ||
1418 | rndis_connect_state [i]->read_proc = rndis_proc_read; | ||
1419 | rndis_connect_state [i]->data = (void *) | ||
1420 | (rndis_per_dev_params + i); | ||
1421 | #endif | 1170 | #endif |
1422 | rndis_per_dev_params [i].confignr = i; | 1171 | rndis_per_dev_params [i].confignr = i; |
1423 | rndis_per_dev_params [i].used = 0; | 1172 | rndis_per_dev_params [i].used = 0; |