AJZaurusUSB

AJZaurusUSB Commit Details

Date:2010-06-26 17:04:49 (14 years 8 months ago)
Author:Nikolaus Schaller
Commit:26ef261b0ed19abb108734e51916393d8f3f632b
Parents: 4397254c88115bb4bf7f6b2b0782a3df161f9b25
Message:Issue 71: fixed kernel panic problem on sleep and compiled/tested on Mac OS X 10.6.4

Changes:
DSources/Logging.cpp (full)
DSources/Logging.h (full)
DSources/Power.cpp (full)
M.gitignore (1 diff)
MAJZaurusUSB.xcodeproj/project.pbxproj (9 diffs)
MHISTORY.rtf (2 diffs)
MInfo.plist (2 diffs)
MSources/CRC.cpp (1 diff)
MSources/CRC.h (3 diffs)
MSources/Client.cpp (29 diffs)
MSources/Driver.h (16 diffs)
MSources/Glue.cpp (12 diffs)
MSources/Provider.cpp (27 diffs)
Mmakefile (3 diffs)

File differences

.gitignore
11
22
33
4
4
5
56
67
8
9
10
11
12
# xcode noise
build/*
*.pbxuser
*.mode1v3
*.perspective*
*.mode1*
.svn
.DS_Store
*.tgz
*.pkg
*.app
core*
prepare.gdb
AJZaurusUSB.xcodeproj/project.pbxproj
2323
2424
2525
26
26
2727
2828
29
30
31
29
3230
33
3431
3532
3633
3734
3835
3936
40
4137
4238
4339
......
5248
5349
5450
55
56
57
58
51
52
5953
6054
6155
......
107101
108102
109103
110
104
105
111106
112107
113
114108
115
116
117
118
109
119110
120111
121112
......
152143
153144
154145
155
156146
157147
158148
......
251241
252242
253243
254
244
255245
256246
257247
......
260250
261251
262252
263
253
264254
265255
266
267
268
256
269257
270258
271259
......
475463
476464
477465
466
467
478468
479469
480470
......
487477
488478
489479
480
490481
491482
492483
......
499490
500491
501492
493
502494
503495
504496
/* Begin PBXBuildFile section */
EE0AD1610A9F39480042DD37 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
EE0AD16E0A9F39780042DD37 /* Driver.h in Headers */ = {isa = PBXBuildFile; fileRef = EE0AD16D0A9F39780042DD37 /* Driver.h */; };
EE0AD1790A9F48C30042DD37 /* Client.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE4572000A795A6700A7ACF7 /* Client.cpp */; };
EE0AD1790A9F48C30042DD37 /* NetworkClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE4572000A795A6700A7ACF7 /* NetworkClient.cpp */; };
EE0AD17A0A9F48C30042DD37 /* CRC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE4571F90A795A2500A7ACF7 /* CRC.cpp */; };
EE0AD17B0A9F48C30042DD37 /* Glue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE0A61350A9DE1B90042DD37 /* Glue.cpp */; };
EE0AD17C0A9F48C30042DD37 /* Logging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE4572010A795A8200A7ACF7 /* Logging.cpp */; };
EE0AD17D0A9F48C30042DD37 /* Power.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE4572130A795AE900A7ACF7 /* Power.cpp */; };
EE0AD17E0A9F48C30042DD37 /* Provider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE4571FA0A795A3300A7ACF7 /* Provider.cpp */; };
EE0AD17E0A9F48C30042DD37 /* USBProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE4571FA0A795A3300A7ACF7 /* USBProvider.cpp */; };
EE0AD17F0A9F48CE0042DD37 /* CRC.h in Headers */ = {isa = PBXBuildFile; fileRef = EE0A96570A9E40490042DD37 /* CRC.h */; };
EE0AD1800A9F48CE0042DD37 /* Logging.h in Headers */ = {isa = PBXBuildFile; fileRef = EE0A96540A9E3FC00042DD37 /* Logging.h */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; lineEnding = 0; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
EE03E0EE092D1CBA00893140 /* README.rtfd */ = {isa = PBXFileReference; lastKnownFileType = wrapper.rtfd; path = README.rtfd; sourceTree = "<group>"; };
EE0A61350A9DE1B90042DD37 /* Glue.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Glue.cpp; path = Sources/Glue.cpp; sourceTree = "<group>"; };
EE0A96540A9E3FC00042DD37 /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = Sources/Logging.h; sourceTree = "<group>"; };
EE0A96570A9E40490042DD37 /* CRC.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CRC.h; path = Sources/CRC.h; sourceTree = "<group>"; };
EE0AD16B0A9F39480042DD37 /* AJZaurusUSB.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AJZaurusUSB.kext; sourceTree = BUILT_PRODUCTS_DIR; };
EE0AD16C0A9F39480042DD37 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
EE1441910FC598B90071828E /* Versions.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Versions.def; path = ../Versions.def; sourceTree = SOURCE_ROOT; };
EE1450EB0A14F39D00C93F94 /* HISTORY.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = HISTORY.rtf; sourceTree = "<group>"; };
EE4571F90A795A2500A7ACF7 /* CRC.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CRC.cpp; path = Sources/CRC.cpp; sourceTree = "<group>"; };
EE4571FA0A795A3300A7ACF7 /* Provider.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Provider.cpp; path = Sources/Provider.cpp; sourceTree = "<group>"; };
EE4572000A795A6700A7ACF7 /* Client.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Client.cpp; path = Sources/Client.cpp; sourceTree = "<group>"; };
EE4572010A795A8200A7ACF7 /* Logging.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Logging.cpp; path = Sources/Logging.cpp; sourceTree = "<group>"; };
EE4572130A795AE900A7ACF7 /* Power.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Power.cpp; path = Sources/Power.cpp; sourceTree = "<group>"; };
EE4571FA0A795A3300A7ACF7 /* USBProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = USBProvider.cpp; path = Sources/Provider.cpp; sourceTree = "<group>"; };
EE4572000A795A6700A7ACF7 /* NetworkClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = NetworkClient.cpp; path = Sources/Client.cpp; sourceTree = "<group>"; };
EE75D7F10B09D5E000601180 /* prepare.gdb */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.sh; path = prepare.gdb; sourceTree = "<group>"; };
EEE642BC0D7D530900DB8215 /* AJZaurusUSB.pmdoc */ = {isa = PBXFileReference; lastKnownFileType = folder; path = AJZaurusUSB.pmdoc; sourceTree = "<group>"; };
F59C308D02C2AF4001000102 /* Kernel.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Kernel.framework; path = /System/Library/Frameworks/Kernel.framework; sourceTree = "<absolute>"; };
EE0A612A0A9DE1650042DD37 /* Sources */ = {
isa = PBXGroup;
children = (
EE4572000A795A6700A7ACF7 /* Client.cpp */,
EE0AD16D0A9F39780042DD37 /* Driver.h */,
EE4572000A795A6700A7ACF7 /* NetworkClient.cpp */,
EE0A96570A9E40490042DD37 /* CRC.h */,
EE4571F90A795A2500A7ACF7 /* CRC.cpp */,
EE0AD16D0A9F39780042DD37 /* Driver.h */,
EE0A61350A9DE1B90042DD37 /* Glue.cpp */,
EE0A96540A9E3FC00042DD37 /* Logging.h */,
EE4572010A795A8200A7ACF7 /* Logging.cpp */,
EE4572130A795AE900A7ACF7 /* Power.cpp */,
EE4571FA0A795A3300A7ACF7 /* Provider.cpp */,
EE4571FA0A795A3300A7ACF7 /* USBProvider.cpp */,
);
name = Sources;
sourceTree = "<group>";
buildActionMask = 2147483647;
files = (
EE0AD17F0A9F48CE0042DD37 /* CRC.h in Headers */,
EE0AD1800A9F48CE0042DD37 /* Logging.h in Headers */,
EE0AD16E0A9F39780042DD37 /* Driver.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "# shell script goes here\nopen -a Terminal cd .\nexit 0";
shellScript = "# shell script goes here\n\n### should be run from a terminal since it will ask for password (sudo)\n\nmake load\nexit 0";
};
/* End PBXShellScriptBuildPhase section */
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
EE0AD1790A9F48C30042DD37 /* Client.cpp in Sources */,
EE0AD1790A9F48C30042DD37 /* NetworkClient.cpp in Sources */,
EE0AD17A0A9F48C30042DD37 /* CRC.cpp in Sources */,
EE0AD17B0A9F48C30042DD37 /* Glue.cpp in Sources */,
EE0AD17C0A9F48C30042DD37 /* Logging.cpp in Sources */,
EE0AD17D0A9F48C30042DD37 /* Power.cpp in Sources */,
EE0AD17E0A9F48C30042DD37 /* Provider.cpp in Sources */,
EE0AD17E0A9F48C30042DD37 /* USBProvider.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
ppc,
i386,
);
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_VERSION = 4.0;
PREBINDING = NO;
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
};
ppc,
i386,
);
GCC_VERSION = 4.0;
PREBINDING = NO;
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
};
ppc,
i386,
);
GCC_VERSION = 4.0;
PREBINDING = NO;
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
};
HISTORY.rtf
1
1
22
33
44
......
88
99
1010
11
11
12
13
14
15
16
17
1218
1319
1420
{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf320
{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 ArialMT;}
{\colortbl;\red255\green255\blue255;\red0\green39\blue237;}
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\b \cf0 Version 0.5.4
\b \cf0 Version 0.6.0
\b0 \
* recompiled on 10.6.4\
* fixed ???\
\
\b Version 0.5.4
\b0 \
* recompiled on 10.5.2\
* fixed config bug for Motorola A1200 (Ming)\
Info.plist
77
88
99
10
10
1111
1212
1313
......
1919
2020
2121
22
22
2323
2424
2525
26
26
2727
2828
2929
<key>CFBundleExecutable</key>
<string>AJZaurusUSB</string>
<key>CFBundleGetInfoString</key>
<string>AJZaurusUSB version 0.5.4, Copyright 2002-2004 Andreas Junghans &amp; 2005-2009 Nikolaus Schaller, based on USBCDCEthernet, Copyright 1998-2002 Apple</string>
<string>AJZaurusUSB version 0.6.0, Copyright 2002-2004 Andreas Junghans &amp; 2005-2009 Nikolaus Schaller, based on USBCDCEthernet, Copyright 1998-2002 Apple</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<key>CFBundlePackageType</key>
<string>KEXT</string>
<key>CFBundleShortVersionString</key>
<string>0.5.4</string>
<string>0.6.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.5.4</string>
<string>0.6.0</string>
<key>IOKitPersonalities</key>
<dict>
<key>E28 E2831</key>
Sources/CRC.cpp
2121
2222
2323
24
24
2525
2626
2727
 with same name as enclosing class" will be issued. This warning can be ignored.
 
 Copyright:Copyright 2002, 2003 Andreas Junghans
 Copyright 2004-2006 H. Nikolaus Schaller
 Copyright 2004-2010 H. Nikolaus Schaller
 
 Disclaimer:This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
Sources/CRC.h
7777
7878
7979
80
81
80
81
8282
8383
8484
......
8686
8787
8888
89
90
89
90
9191
9292
9393
......
9595
9696
9797
98
99
98
99
100100
101101
102102
#define CRC32_FCS(fcs, c) (((fcs) >> 8) ^ crc32_table[((fcs) ^ (c)) & 0xff])
/* fcs_memcpy32 - memcpy and calculate fcs
* Perform a memcpy and calculate fcs using ppp 32bit CRC algorithm.
*/
 * Perform a memcpy and calculate fcs using ppp 32bit CRC algorithm.
 */
static inline UInt32 fcs_memcpy32(unsigned char *dp, unsigned char *sp, int len, UInt32 fcs)
{  
    for (;len-- > 0; fcs = CRC32_FCS(fcs, *dp++ = *sp++));
}
/* fcs_pad32 - pad and calculate fcs
* Pad and calculate fcs using ppp 32bit CRC algorithm.
*/
 * Pad and calculate fcs using ppp 32bit CRC algorithm.
 */
static inline UInt32 fcs_pad32(unsigned char *dp, int len, UInt32 fcs)
{
    for (;len-- > 0; fcs = CRC32_FCS(fcs, *dp++ = '\0'));
}
/* fcs_compute32 - calculate fcs
* Perform calculate fcs using ppp 32bit CRC algorithm.
*/
 * Perform calculate fcs using ppp 32bit CRC algorithm.
 */
static inline UInt32 fcs_compute32(unsigned char *sp, int len, UInt32 fcs)
{
    for (;len-- > 0; fcs = CRC32_FCS(fcs, *sp++));
Sources/Client.cpp
2323
2424
2525
26
26
2727
2828
2929
......
8686
8787
8888
89
89
9090
9191
9292
9393
9494
9595
96
9697
9798
9899
......
107108
108109
109110
110
111
111112
112113
113114
114115
115116
117
118
119
120
121
116122
117123
118124
......
130136
131137
132138
133
134
135
136
137
138
139
140
141
139
142140
143141
144142
......
161159
162160
163161
164
165
166
162
163
164
167165
168166
169167
......
183181
184182
185183
186
184
187185
188186
189187
......
204202
205203
206204
207
208
209
210
211
205
206
207
208
209
212210
213211
214212
......
273271
274272
275273
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
274
298275
299276
300277
301
302
303
304
305
278
279
280
281
282
306283
307284
308285
......
352329
353330
354331
355
332
356333
357334
358335
......
376353
377354
378355
379
356
380357
381
358
382359
383360
384361
......
409386
410387
411388
412
413
414389
415390
416391
......
419394
420395
421396
422
397
423398
424
399
425400
426401
427
428
429
430
431
432
402
403
404
405
406
407
433408
434409
435410
......
442417
443418
444419
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
470445
471
472
446
447
473448
474
475
449
450
476451
477
478
452
453
479454
480
481
455
456
482457
483
484
458
459
485460
486
487
461
462
488463
489
490
491
464
465
466
492467
493
468
494469
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
538512
539
540
541
513
514
515
542516
543
544
517
518
545519
546
547
520
521
548522
549
550
551
523
524
525
552526
553
554
555
527
528
529
556530
557531
558532
......
561535
562536
563537
564
538
565539
566540
567541
......
578552
579553
580554
581
555
556
557
558
559
582560
583561
584562
......
587565
588566
589567
590
591
592
593
594
595
568
569
570
571
572
573
596574
597575
598576
......
616594
617595
618596
619
597
620598
621599
622600
......
625603
626604
627605
628
629
630
606
607
608
631609
632610
633611
......
643621
644622
645623
646
624
647625
648626
649627
650
628
651629
652630
653631
654
632
655633
656634
657635
658
636
659637
660638
661639
662
640
663641
664642
665643
666
644
667645
668646
669647
670
648
671649
672650
673651
674
652
675653
676654
677655
678
656
679657
680658
681659
682
660
683661
684662
685663
686
664
687665
688666
689667
690
668
691669
692670
693671
694
672
695673
696674
697675
698
676
699677
700678
701679
......
731709
732710
733711
734
712
735713
736714
737715
......
758736
759737
760738
761
739
762740
763741
764742
765743
766744
767745
768
746
769747
770748
771749
......
777755
778756
779757
780
781
782
783
758
759
760
761
784762
785763
786764
......
789767
790768
791769
792
770
793771
794772
795773
796774
797775
798776
799
777
800778
801779
802780
803781
804
805
806
807
808
782
809783
810784
811785
......
843817
844818
845819
846
820
847821
848822
849823
......
874848
875849
876850
877
851
878852
879853
880854
......
979953
980954
981955
982
956
983957
984958
985959
986960
987961
988962
989
963
990964
991965
992966
......
997971
998972
999973
1000
1001
1002
974
975
976
1003977
1004978
1005979
......
1019993
1020994
1021995
1022
996
1023997
1024998
1025999
......
10601034
10611035
10621036
1063
1064
1065
1066
1067
1068
1037
10691038
10701039
10711040
10721041
10731042
10741043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
10751133
 with same name as enclosing class" will be issued. This warning can be ignored.
 
 Copyright:Copyright 2002, 2003 Andreas Junghans
 Copyright 2004-2006 H. Nikolaus Schaller
 Copyright 2004-2010 H. Nikolaus Schaller
 
 Disclaimer:This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 .     start()
 .       open()
 .         enable()
 any of:
 .             ((
 .             outputPacket()
 .             message()
 .             timeoutOccurred()
 .             [[wakeUp()]]
 .             [[putToSleep()]]
 .             terminate()
 .             ))
 .         disable()
 .       close()
 .       message()
 .        disable()
 .          [[putToSleep()]]
 .      setPowerState(0)
 . ----- sleeps -----
 . ----- Mac sleeps -----
 .      setPowerState(1)
 .          [[resetDevice()]]
 .        enable()
 .             wakeUp()
 
 NOTES:
 * [[ abc ]] means that it is an internal method
 * (( a b c )) means and sequence can occur
 * putToSleep(), wakeUp() refer to the interface/attached device and not the Mac
 
 */
/****************************************************************************************************/
bool net_lucid_cake_driver_AJZaurusUSB::init(OSDictionary *properties)
{
    UInt32i;
       
#if USE_ELG
    g.evLogBufp = NULL;
    AllocateEventLog(kEvLogSize);
    // ALERT(&g, g.evLogBufp, 'USBM', "net_lucid_cake_driver_AJZaurusUSB::init - event logging set up.");
   
    waitForService(resourceMatching("kdp"));
#endif /* USE_ELG */
   
    IOLog("AJZaurusUSB(%p)::init\n", this);
IOSleep(20);
   
   
    for (i=0; i<kOutBufPool; i++)
        { // initialize output buffer reference block
        fPipeOutBuff[i].pipeOutMDP = NULL;
        fPipeOutBuff[i].pipeOutBuffer = NULL;
        fPipeOutBuff[i].m = NULL;
fPipeOutBuff[i].pipeOutMDP = NULL;
fPipeOutBuff[i].pipeOutBuffer = NULL;
fPipeOutBuff[i].m = NULL;
        }
   
    fLock = IOSimpleLockAlloc();
//
/****************************************************************************************************/
#if 0// default method from superclass
#if 0// use default method from superclass
bool net_lucid_cake_driver_AJZaurusUSB::attach(IOService *provider)
{
}
IOService *net_lucid_cake_driver_AJZaurusUSB::probe(IOService *provider, SInt32 *score)
{
    IOService *res = super::probe(provider, score);
    IOLog("Probing - super::score is %ld\n", *score);
IOSleep(20);
*score=1000000;
// i.e. determine if we can connect, i.e. find the right interfaces
    return res;    
    IOLog("AJZaurusUSB::probe - super::score is %ld\n", *score);// is already 90000 (from Info.plist)
// determine if we can really connect, i.e. find the right interfaces
   
return res;    
}
/****************************************************************************************************/
        stop(provider);
        return false;
        }
    if(!initForPM(provider))
{
        IOLog("AJZaurusUSB::start - initForPM failed\n");
stop(provider);
return false;
}
#if 0
    IOLog("AJZaurusUSB::start - register as power controller\n");
    // initialize superclass variables from IOService.h
fPowerState = kCDCPowerOnState;
    PMinit();
    // join the tree from IOService.h
    provider->joinPMtree(this);
    // register as controlling driver from IOService.h
    if(registerPowerDriver( this, (IOPMPowerState *) ourPowerStates, kNumCDCStates ) != kIOReturnSuccess)
        {
        IOLog("AJZaurusUSB::start - failed to register as power controller\n");
        }
#endif
    IOLog("AJZaurusUSB::start - successful\n");
#if 0// fail for debugging
{
        IOLog("AJZaurusUSB::start - fails for debugging purposes\n");
        fpDevice->close(this);
        fpDevice = NULL;
        stop(provider);
        return false;
IOLog("AJZaurusUSB::start - fails for debugging purposes\n");
fpDevice->close(this);
fpDevice = NULL;
stop(provider);
return false;
}
#endif
    return true;
    // If an interface client has previously enabled us,
    // and we know there can only be one interface client
    // for this driver, then simply return success.
    if (fNetifEnabled)
        {
        IOLog("AJZaurusUSB::enable - already enabled\n");
    fLinkStatus = 1;
   
    medium = IONetworkMedium::getMediumWithType(fMediumDict, mediumType);
    IOLog("AJZaurusUSB::enable - medium type=%lu and medium=%p\n", mediumType, medium);
    setLinkStatus(kIONetworkLinkActive | kIONetworkLinkValid, medium, 10 * 1000000);// this should switch the Network status to green
    IOLog("AJZaurusUSB::enable - LinkStatus set\n");
   
//
/****************************************************************************************************/
// FIXME: we should try to receive kIOMessageSystemHasPoweredOn
IOReturn net_lucid_cake_driver_AJZaurusUSB::message(UInt32 type, IOService *provider, void *argument)
{
    IOReturnior;
   
    if (!fpDevice)// no USB provider
        return kIOReturnUnsupported;
    switch (type)
        {
{
// general messages
        case kIOMessageServiceIsTerminated:
            IOLog("AJZaurusUSB::message - kIOMessageServiceIsTerminated ready=%d type=%lu\n", fReady, type);
           
            if (fReady)
                {
                if (!fTerminate)// Check if we're already being terminated
                    {
IOLog("AJZaurusUSB::message - kIOMessageServiceIsTerminated ready=%d type=%lu\n", fReady, type);
if (fReady)
{
if (!fTerminate)// Check if we're already being terminated
{
                    IOLog("AJZaurusUSB::message - hardcoded message!\n");
                    // NOTE! This call below depends on the hard coded path of this KEXT. Make sure
                    // that if the KEXT moves, this path is changed!
                                                      "Unplug Header",// the header
                                                      "Unplug Notice",// the notice - look in Localizable.strings
                                                      "OK");
                    }
                }
else
                    {
                    if (fCommInterface)
                        {
                        if (fCommInterface != fDataInterface)
                            fCommInterface->close(this);
                        fCommInterface->release();
                        fCommInterface = NULL;
                        }
                   
                    if (fDataInterface)
                        {
                        fDataInterface->close(this);
                        fDataInterface->release();
                        fDataInterface = NULL;
                        }
                   
                    fpDevice->close(this); // need to close so we can get the free and stop calls, only if no sessions active (see putToSleep)
                    fpDevice = NULL;
                    }
               
                fTerminate = true;// we're being terminated (unplugged)
            return kIOReturnSuccess;
}
}
else
{
if (fCommInterface)
{
if (fCommInterface != fDataInterface)
fCommInterface->close(this);
fCommInterface->release();
fCommInterface = NULL;
}
if (fDataInterface)
{
fDataInterface->close(this);
fDataInterface->release();
fDataInterface = NULL;
}
fpDevice->close(this); // need to close so we can get the free and stop calls, only if no sessions active (see putToSleep)
fpDevice = NULL;
}
fTerminate = true;// we're being terminated (unplugged)
return kIOReturnSuccess;
        case kIOMessageServiceIsSuspended:
            IOLog("AJZaurusUSB::message - kIOMessageServiceIsSuspended\n");
            break;
IOLog("AJZaurusUSB::message - kIOMessageServiceIsSuspended\n");
break;
        case kIOMessageServiceIsResumed:
            IOLog("AJZaurusUSB::message - kIOMessageServiceIsResumed\n");
            break;
IOLog("AJZaurusUSB::message - kIOMessageServiceIsResumed\n");
break;
        case kIOMessageServiceIsRequestingClose:
            IOLog("AJZaurusUSB::message - kIOMessageServiceIsRequestingClose\n");
            break;
IOLog("AJZaurusUSB::message - kIOMessageServiceIsRequestingClose\n");
break;
        case kIOMessageServiceIsAttemptingOpen:
            IOLog("AJZaurusUSB::message - kIOMessageServiceAttemptingOpen\n");
            break;
IOLog("AJZaurusUSB::message - kIOMessageServiceAttemptingOpen\n");
break;
        case kIOMessageServiceWasClosed:
            IOLog("AJZaurusUSB::message - kIOMessageServiceWasClosed\n");
            break;
IOLog("AJZaurusUSB::message - kIOMessageServiceWasClosed\n");
break;
        case kIOMessageServiceBusyStateChange:
            IOLog("AJZaurusUSB::message - kIOMessageServiceBusyStateChange\n");
            break;
IOLog("AJZaurusUSB::message - kIOMessageServiceBusyStateChange\n");
break;
        case kIOMessageServicePropertyChange:
            IOLog("AJZaurusUSB::message - kIOMessageServicePropertyChange\n");
            break;
IOLog("AJZaurusUSB::message - kIOMessageServicePropertyChange\n");
break;
// USB messages
        case kIOUSBMessagePortHasBeenResumed:
            IOLog("AJZaurusUSB::message - kIOUSBMessagePortHasBeenResumed\n");
           
            // If the reads are dead try and resurrect them
           
            if (fCommDead && fCommPipe)
                {
ior = fCommPipe->Read(fCommPipeMDP,
5000,// 5 seconds until timeout
5000,
fCommPipeMDP->getLength(),
&fCommCompletionInfo,
NULL);
//               ior = fCommPipe->Read(fCommPipeMDP, , NULL);
                if (ior != kIOReturnSuccess)
                    {
                    IOLog("AJZaurusUSB::message - Failed to queue Comm pipe read: %d\n", ior);
                    }
                else
                    {
                    fCommDead = false;
                    }
                }
// and again...
                if (fDataDead)
                    {
ior = fInPipe->Read(fPipeInMDP,
 5000,// 5 seconds until timeout
 5000,
 fPipeInMDP->getLength(),
 &fReadCompletionInfo,
 NULL);
//ior = fInPipe->Read(fPipeInMDP, &fReadCompletionInfo, NULL);
                    if (ior != kIOReturnSuccess)
                        {
                        IOLog("AJZaurusUSB::message - Failed to queue Data pipe read: %d\n", ior);
                        }
                    else
                        {
                        fDataDead = false;
                        }
                    }
               
return kIOReturnSuccess;
IOLog("AJZaurusUSB::message - kIOUSBMessagePortHasBeenResumed\n");
// If the reads are dead try and resurrect them
if (fCommDead && fCommPipe)
{
ior = fCommPipe->Read(fCommPipeMDP,
 5000,// 5 seconds until timeout
 5000,
 fCommPipeMDP->getLength(),
 &fCommCompletionInfo,
 NULL);
//               ior = fCommPipe->Read(fCommPipeMDP, , NULL);
if (ior != kIOReturnSuccess)
{
IOLog("AJZaurusUSB::message - Failed to queue Comm pipe read: %d\n", ior);
}
else
{
fCommDead = false;
}
}
// and again...
if (fDataDead)
{
ior = fInPipe->Read(fPipeInMDP,
5000,// 5 seconds until timeout
5000,
fPipeInMDP->getLength(),
&fReadCompletionInfo,
NULL);
if (ior != kIOReturnSuccess)
{
IOLog("AJZaurusUSB::message - Failed to queue Data pipe read: %d\n", ior);
}
else
{
fDataDead = false;
}
}
return kIOReturnSuccess;
        case kIOUSBMessageHubResumePort:
            IOLog("AJZaurusUSB::message - kIOUSBMessageHubResumePort\n");
            break;
// power
IOLog("AJZaurusUSB::message - kIOUSBMessageHubResumePort\n");
break;
// power
        case kIOMessageDeviceHasPoweredOn:
            IOLog("AJZaurusUSB::message - kIOMessageDeviceHasPoweredOn\n");
            break;
IOLog("AJZaurusUSB::message - kIOMessageDeviceHasPoweredOn\n");
break;
        case kIOMessageSystemWillSleep:
            IOLog("AJZaurusUSB::message - kIOMessageSystemWillSleep\n");
            break;
IOLog("AJZaurusUSB::message - kIOMessageSystemWillSleep\n");
break;
        case kIOMessageSystemHasPoweredOn:
            IOLog("AJZaurusUSB::message - kIOMessageSystemHasPoweredOn\n");
            break;
// any other
IOLog("AJZaurusUSB::message - kIOMessageSystemHasPoweredOn\n");
break;
// any other
        default:
            IOLog("AJZaurusUSB::message - unknown message\n");
            break;
        }
IOLog("AJZaurusUSB::message - unknown message\n");
break;
}
IOSleep(20);    
    return kIOReturnUnsupported;
}/* end message */
//
//Method:net_lucid_cake_driver_AJZaurusUSB::outputPacket
//
//Inputs:mbuf - the packet
//Inputs:mbuf - the packet (may be NULL after awaking from sleep)
//param - optional parameter
//
//Outputs:Return code - kIOReturnOutputSuccess or kIOReturnOutputStall
    IOLog("AJZaurusUSB::outputPacket(%p)\n", pkt);
IOSleep(20);
#endif
    if(!fLinkStatus)
if(!pkt)
        {
        IOLog("AJZaurusUSB::outputPacket(NULL)\n");
}
else if(!fLinkStatus)
        {
        IOLog("AJZaurusUSB::outputPacket(%p) - link is down (%d)\n", pkt, fLinkStatus);
        if(fOutputErrsOK)
        }
    else if(!USBTransmitPacket(pkt))
        { // wasn't able to transmit
        ret = kIOReturnOutputStall;
        // ret = kIOReturnOutputDropped;
        IOLog("AJZaurusUSB::outputPacket(%p) - packet dropped\n", pkt);
        // If the driver returns kIOReturnDropped, it should also put the mbuf_t back into the network stack
        freePacket(pkt);
ret = kIOReturnOutputStall;
// ret = kIOReturnOutputDropped;
IOLog("AJZaurusUSB::outputPacket(%p) - packet dropped\n", pkt);
// If the driver returns kIOReturnDropped, it should also put the mbuf_t back into the network stack
freePacket(pkt);
        }
    return ret;
}/* end outputPacket */
    IOUSBDevRequest*STREQ;
    boolstatOk = false;
   
//    IOLog("AJZaurusUSB::timeoutOccurred\n");
//    IOLog("AJZaurusUSB::timeoutOccurred\n");
   
    if (fReady)
        fTransmitQueue->service(IOBasicOutputQueue::kServiceAsync); // AJ: revive a stalled queue (according to Apple's documentation, this call doesn't do any harm, even if the queue wasn't stalled).
   
    if ((fEthernetStatistics[0]|fEthernetStatistics[1]|fEthernetStatistics[2]|fEthernetStatistics[3]) == 0)
        { // no bit is set
 //       IOLog("AJZaurusUSB::timeoutOccurred - No Ethernet statistics defined\n");
        fTimerSource->setTimeoutMS(WATCHDOG_TIMER_MS);// AJ: set up the watchdog again
        return;
//       IOLog("AJZaurusUSB::timeoutOccurred - No Ethernet statistics defined\n");
fTimerSource->setTimeoutMS(WATCHDOG_TIMER_MS);// AJ: set up the watchdog again
return;
        }
   
   
            fCurrStat = 0;
        switch(currStat)
            {
            case kXMIT_OK_REQ:
case kXMIT_OK_REQ:
                if (fEthernetStatistics[0] & kXMIT_OK)
                    statOk = true;
                break;
            case kRCV_OK_REQ:
case kRCV_OK_REQ:
                if (fEthernetStatistics[0] & kRCV_OK)
                    statOk = true;
                break;
            case kXMIT_ERROR_REQ:
case kXMIT_ERROR_REQ:
                if (fEthernetStatistics[0] & kXMIT_ERROR_REQ)
                    statOk = true;
                break;
            case kRCV_ERROR_REQ:
case kRCV_ERROR_REQ:
                if (fEthernetStatistics[0] & kRCV_ERROR_REQ)
                    statOk = true;
                break;
            case kRCV_CRC_ERROR_REQ:
case kRCV_CRC_ERROR_REQ:
                if (fEthernetStatistics[2] & kRCV_CRC_ERROR)
                    statOk = true;
                break;
            case kRCV_ERROR_ALIGNMENT_REQ:
case kRCV_ERROR_ALIGNMENT_REQ:
                if (fEthernetStatistics[2] & kRCV_ERROR_ALIGNMENT)
                    statOk = true;
                break;
            case kXMIT_ONE_COLLISION_REQ:
case kXMIT_ONE_COLLISION_REQ:
                if (fEthernetStatistics[2] & kXMIT_ONE_COLLISION)
                    statOk = true;
                break;
            case kXMIT_MORE_COLLISIONS_REQ:
case kXMIT_MORE_COLLISIONS_REQ:
                if (fEthernetStatistics[2] & kXMIT_MORE_COLLISIONS)
                    statOk = true;
                break;
            case kXMIT_DEFERRED_REQ:
case kXMIT_DEFERRED_REQ:
                if (fEthernetStatistics[2] & kXMIT_DEFERRED)
                    statOk = true;
                break;
            case kXMIT_MAX_COLLISION_REQ:
case kXMIT_MAX_COLLISION_REQ:
                if (fEthernetStatistics[2] & kXMIT_MAX_COLLISION)
                    statOk = true;
                break;
            case kRCV_OVERRUN_REQ:
case kRCV_OVERRUN_REQ:
                if (fEthernetStatistics[3] & kRCV_OVERRUN)
                    statOk = true;
                break;
            case kXMIT_TIMES_CARRIER_LOST_REQ:
case kXMIT_TIMES_CARRIER_LOST_REQ:
                if (fEthernetStatistics[3] & kXMIT_TIMES_CARRIER_LOST)
                    statOk = true;
                break;
            case kXMIT_LATE_COLLISIONS_REQ:
case kXMIT_LATE_COLLISIONS_REQ:
                if (fEthernetStatistics[3] & kXMIT_LATE_COLLISIONS)
                    statOk = true;
                break;
            default:
default:
                break;
            }
        }
            }
        }
   
//    IOLog("AJZaurusUSB::timeoutOccurred - Ethernet statistics done\n");
//    IOLog("AJZaurusUSB::timeoutOccurred - Ethernet statistics done\n");
   
    // Restart the watchdog timer
   
   
    IOLog("AJZaurusUSB::wakeUp\n");
 IOSleep(20);
   
    fReady = false;
   
    if (fTimerSource)
        fTimerSource->cancelTimeout();// cancel any running timer
   
    setLinkStatus(0, 0);// Initialize the link state
       
    if (!allocateResources())
        {
        return false;
    fCommCompletionInfo.action = commReadComplete;
    fCommCompletionInfo.parameter = NULL;
   
//    if(fCommPipe)
  //      {
        //rtn = fCommPipe->Read(fCommPipeMDP, &fCommCompletionInfo, NULL);
        rtn = kIOReturnSuccess;
//    if(fCommPipe)
//      {
//rtn = fCommPipe->Read(fCommPipeMDP, &fCommCompletionInfo, NULL);
rtn = kIOReturnSuccess;
    //    }
    if(rtn == kIOReturnSuccess)
        {
        fReadCompletionInfo.target = this;
        fReadCompletionInfo.action = dataReadComplete;
        fReadCompletionInfo.parameter = NULL;
 
rtn = fInPipe->Read(fPipeInMDP,
5000,// 5 seconds until timeout
5000,
fPipeInMDP->getLength(),
&fReadCompletionInfo,
NULL);
     
        if (rtn == kIOReturnSuccess)
            {
            // Set up the data-out bulk pipe:
           
            //fWriteCompletionInfo.target= this;
            //fWriteCompletionInfo.action= dataWriteComplete;
            //fWriteCompletionInfo.parameter = NULL;// for now, filled in with the mbuf address when sent
           
            for (int i=0; i<kOutBufPool; i++)
for (int i=0; i<kOutBufPool; i++)
                {
                fPipeOutBuff[i].writeCompletionInfo.target = this;
                fPipeOutBuff[i].writeCompletionInfo.action = dataWriteComplete;
releaseResources();
return false;
}
        fTimerSource->setTimeoutMS(WATCHDOG_TIMER_MS);
        fReady = true;
        }
   
    if (fTimerSource)
        fTimerSource->cancelTimeout();
    setLinkStatus(0, 0);
   
    // Release all resources
{
    IOLog("AJZaurusUSB::stop\n");
 IOSleep(20);
   
    if (fNetworkInterface)
        {
        detachInterface(fNetworkInterface);
        fNetworkInterface->release();
        fNetworkInterface = NULL;
        }
       
    if (fCommInterface)
        {
if (fCommInterface != fDataInterface)
   
    if (fDataInterface)
        {
        fDataInterface->close(this);
        fDataInterface->release();
        fDataInterface = NULL;
fDataInterface->close(this);
fDataInterface->release();
fDataInterface = NULL;
        }
   
    if (fpDevice)
        fTransmitQueue->release();
        fTransmitQueue = NULL;
        }
   
    super::stop(provider);
   
    return;
{
   
    IOLog("AJZaurusUSB::free\n");
   
#if USE_ELG
    if (g.evLogBuf)
        IOFree(g.evLogBuf, kEvLogSize);
#endif /* USE_ELG */
   
    super::free();
    IOSimpleLockFree(fLock);
    return;
   
}/* end free */
/****************************************************************************************************/
//
//Method:net_lucid_cake_driver_AJZaurusUSB::registerWithPolicyMaker
//
//Inputs:provider - my provider
//
//Outputs:return code - true(initialized), false(failed)
//
//Desc:Add ourselves to the power management tree so we can do
//the right thing on sleep/wakeup.
//
//see:http://developer.apple.com/mac/library/documentation/DeviceDrivers/Conceptual/IOKitFundamentals/PowerMgmt/PowerMgmt.html#//apple_ref/doc/uid/TP0000020-BABCCBIJ
//and section "Network / Power Management" of http://developer.apple.com/mac/library/documentation/DeviceDrivers/Conceptual/IOKitFundamentals/Families_Ref/Families_Ref.html#//apple_ref/doc/uid/TP0000021-BABFBCFG
//
/****************************************************************************************************/
IOReturn net_lucid_cake_driver_AJZaurusUSB::registerWithPolicyMaker( IOService * policyMaker )
{
    IOReturn ioreturn;
static IOPMPowerState gOurPowerStates[kNumCDCStates] =
{
    {kIOPMPowerStateVersion1,0,0,0,0,0,0,0,0,0,0,0},
    {kIOPMPowerStateVersion1,kIOPMDeviceUsable,kIOPMPowerOn,kIOPMPowerOn,0,0,0,0,0,0,0,0}
};
IOLog("AJZaurusUSB::registerWithPolicyMaker\n");
    fPowerState = kCDCPowerOnState;// init our power state to be 'on'
ioreturn = policyMaker->registerPowerDriver( this, gOurPowerStates, kNumCDCStates);
    return ioreturn;
   
}/* end initForPM */
/****************************************************************************************************/
//
//Method:net_lucid_cake_driver_AJZaurusUSB::initialPowerStateForDomainState
//
//Inputs:flags -
//
//Outputs:return code - Current power state
//
//Desc:Request for our initial power state.
//
/****************************************************************************************************/
unsigned long net_lucid_cake_driver_AJZaurusUSB::initialPowerStateForDomainState(IOPMPowerFlags flags)
{
    return fPowerState;
   
}/* end initialPowerStateForDomainState */
/****************************************************************************************************/
//
//Method:net_lucid_cake_driver_AJZaurusUSB::setPowerState
//
//Inputs:whatState - new state
//
//Outputs:Return code - IOPMAckImplied
//
//Desc:We are notified to turn power on/off
//
/****************************************************************************************************/
IOReturn net_lucid_cake_driver_AJZaurusUSB::setPowerState(unsigned long whatState, IOService *whatDevice)
{ // turn your device on/off here
    IOLog("AJZaurusUSB::setPowerState - power %lu\n", whatState);
    if(!(whatState == kCDCPowerOffState || whatState == kCDCPowerOnState))
return IOPMNoSuchState;
if(whatState == fPowerState)
return IOPMAckImplied;// unchanged
fPowerState=whatState;
if(fPowerState == kCDCPowerOnState)
{
IOLog("AJZaurusUSB::setPowerState - power on\n");
// do whatever we need to do
resetDevice();
}
else
{
IOLog("AJZaurusUSB::setPowerState - power off\n");
}
return IOPMNoErr;
}
/* EOF */
Sources/Driver.h
11
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
4132
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
6756
6857
6958
......
9281
9382
9483
95
96
84
85
9786
9887
9988
10089
101
102
10390
10491
10592
......
11097
11198
11299
113
114100
115101
116
117
102
103
118104
119105
120106
121
107
122108
123109
124110
......
139125
140126
141127
142
128
143129
144130
145131
......
151137
152138
153139
154
140
155141
156142
157143
158144
159145
160
146
161147
162148
163149
164150
165
151
166152
167153
168154
......
170156
171157
172158
173
159
174160
175161
176162
177163
178164
179165
180
166
181167
182168
183169
184170
185171
186
187
172
173
188174
189175
190176
191177
192178
193179
194
180
195181
196182
197183
198184
199185
200186
201
187
202188
203189
204190
......
211197
212198
213199
214
215
200
201
216202
217203
218204
......
237223
238224
239225
240
226
241227
242228
243229
......
272258
273259
274260
275
261
276262
277
263
278264
279265
280266
281267
282268
283269
284
270
285271
286272
287
273
288274
289275
290276
291277
292278
293279
294
280
295281
296282
297283
......
301287
302288
303289
304
290
305291
306292
307293
......
312298
313299
314300
315
301
316302
317303
318304
......
321307
322308
323309
324
310
325311
326312
327313
......
343329
344330
345331
346
332
347333
348334
349335
350336
351337
352
338
353339
354340
355341
......
377363
378364
379365
380
366
381367
382
383
384
385
386
368
369
370
371
372
387373
388374
389375
390376
391377
392378
393
394
395
379
380
381
396382
397383
398384
......
403389
404390
405391
406
392
393
407394
408395
409396
......
411398
412399
413400
414
401
415402
416
417
418
403
404
419405
420406
/*
    File:Driver.h
    Description:This is an experimental driver that enables Mac OS X to communicate with a Sharp Zaurus
                   over IP over USB. It is based on the USBCDCEthernet example which is
Copyright 1998-2002 Apple Computer, Inc. All rights reserved.
Portions have been ported from usbdnet.c (Linux driver) written by
Stuart Lynne <sl@lineo.com> and Tom Rushworth <tbr@lineo.com> with some
algorithms adopted from usbnet.c written by
David Brownell <dbrownell@users.sourceforge.net>.
Original description for USBCDCEthernet:
                     This is a sample USB Communication Device Class (CDC) driver, Ethernet model.
                        Note that this sample has not been tested against any actual hardware since there
                        are very few CDC Ethernet devices currently in existence.
                       
                        This sample requires Mac OS X 10.1 and later. If built on a version prior to
                        Mac OS X 10.2, a compiler warning "warning: ANSI C++ forbids data member `ip_opts'
                        with same name as enclosing class" will be issued. This warning can be ignored.
                       
    Copyright:Copyright 2002, 2003 Andreas Junghans
    Disclaimer:This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Change History (most recent first):
       
<0.5.1>     Dec 2006    fixed a Kernel Panic on MacBook Pro
<0.5.0>     Nov 2006    increased stability; made work on Intel Macs
 File:Driver.h
 
 Description:This is an experimental driver that enables Mac OS X to communicate with a Sharp Zaurus
 over IP over USB. It is based on the USBCDCEthernet example which is
 Copyright 1998-2002 Apple Computer, Inc. All rights reserved.
 Portions have been ported from usbdnet.c (Linux driver) written by
 Stuart Lynne <sl@lineo.com> and Tom Rushworth <tbr@lineo.com> with some
 algorithms adopted from usbnet.c written by
 David Brownell <dbrownell@users.sourceforge.net>.
 
 Original description for USBCDCEthernet:
 This is a sample USB Communication Device Class (CDC) driver, Ethernet model.
 Note that this sample has not been tested against any actual hardware since there
 are very few CDC Ethernet devices currently in existence.
 
 This sample requires Mac OS X 10.1 and later. If built on a version prior to
 Mac OS X 10.2, a compiler warning "warning: ANSI C++ forbids data member `ip_opts'
 with same name as enclosing class" will be issued. This warning can be ignored.
 
 Copyright:Copyright 2002, 2003 Andreas Junghans
 
 Disclaimer:This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
<0.3.4>     Aug 2006    Source file split into modules
....
<7>  07/04/03Support for Zaurus C760.
<6>  02/18/03Increased stability + support for iPaq/Opie.
<5>  02/10/03Bug fix (introduced a workloop).
<4>  01/24/03Support for more Zaurus models.
        <3>  01/11/03Modified to include latest changes to the sample driver
(provided by Russ Winsper <russw@apple.com>)
<2>  12/22/02Modified to support the Sharp Zaurus
            <1> 11/08/02New sample (provided by Apple Computer, Inc.)
       
*/
/*****For fans of kprintf, IOLog and debugging infrastructure of the*****/
/*****string ilk, please modify the ELG and PAUSE macros or their*****/
/*****associated EvLog and Pause functions to suit your taste. These*****/
/*****macros currently are set up to log events to a wraparound*****/
/*****buffer with minimal performance impact. They take 2 UInt32*****/
/*****parameters so that when the buffer is dumped 16 bytes per line,*****/
/*****time stamps (~1 microsecond) run down the left side while*****/
/*****unique 4-byte ASCII codes can be read down the right side.*****/
/*****Preserving this convention facilitates different maintainers*****/
/*****using different debugging styles with minimal code clutter.*****/
       
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
 Change History (most recent first):
 
 <0.5.1>     Dec 2006    fixed a Kernel Panic on MacBook Pro
 <0.5.0>     Nov 2006    increased stability; made work on Intel Macs
 
 <0.3.4>     Aug 2006    Source file split into modules
 
 ....
 <7>  07/04/03Support for Zaurus C760.
 <6>  02/18/03Increased stability + support for iPaq/Opie.
 <5>  02/10/03Bug fix (introduced a workloop).
 <4>  01/24/03Support for more Zaurus models.
 <3>  01/11/03Modified to include latest changes to the sample driver
 (provided by Russ Winsper <russw@apple.com>)
 <2>  12/22/02Modified to support the Sharp Zaurus
 <1> 11/08/02New sample (provided by Apple Computer, Inc.)
 
 */
#include <machine/limits.h>/* UINT_MAX */
#include <libkern/OSByteOrder.h>
extern "C"
{
    #include <sys/param.h>
    #include <sys/mbuf.h>
#include <sys/param.h>
#include <sys/mbuf.h>
}
#define DEBUG1
#include "Logging.h"
#define TRANSMIT_QUEUE_SIZE     5// How does this relate to MAX_BLOCK_SIZE?
#define WATCHDOG_TIMER_MS       1000
#define kPipeStalled1
#define kOutBufPool100
// try to lower this in future versions (without producing stalls)
#define kOutBuffThreshold10
        // USB CDC Definitions (Ethernet Control Model)
// USB CDC Definitions (Ethernet Control Model)
#define kEthernetControlModel6
#define kMDLM 0x0a
    //Requests
//Requests
enum
{
    kScan= 0xFF
};
    // Notifications
// Notifications
enum
{
enum
{
    CS_INTERFACE= 0x24,
    Header_FunctionalDescriptor= 0x00,
    CM_FunctionalDescriptor= 0x01,
    Union_FunctionalDescriptor= 0x06,
    CS_FunctionalDescriptor= 0x07,
    Enet_Functional_Descriptor= 0x0f,
    CM_ManagementData= 0x01,
    CM_ManagementOnData= 0x02
};
    // Stats of interest in bmEthernetStatistics (bit definitions)
// Stats of interest in bmEthernetStatistics (bit definitions)
enum
{
    kRCV_OK =0x02,
    kXMIT_ERROR =0x04,
    kRCV_ERROR =0x08,
    kRCV_CRC_ERROR =0x02,// Byte 3
    kRCV_ERROR_ALIGNMENT =0x08,
    kXMIT_ONE_COLLISION =0x10,
    kXMIT_MORE_COLLISIONS =0x20,
    kXMIT_DEFERRED =0x40,
    kXMIT_MAX_COLLISION =0x80,
    kRCV_OVERRUN =0x01,// Byte 4
    kXMIT_TIMES_CARRIER_LOST =0x08,
    kXMIT_LATE_COLLISIONS =0x10
};
    // Stats request definitions
 
// Stats request definitions
enum
{
    kXMIT_OK_REQ =0x0001,
    kRCV_OK_REQ =0x0002,
    kXMIT_ERROR_REQ =0x0003,
    kRCV_ERROR_REQ =0x0004,
    kRCV_CRC_ERROR_REQ =0x0012,
    kRCV_ERROR_ALIGNMENT_REQ =0x0014,
    kXMIT_ONE_COLLISION_REQ =0x0015,
    kXMIT_MORE_COLLISIONS_REQ =0x0016,
    kXMIT_DEFERRED_REQ =0x0017,
    kXMIT_MAX_COLLISION_REQ =0x0018,
    kRCV_OVERRUN_REQ =0x0019,
    kXMIT_TIMES_CARRIER_LOST_REQ =0x001c,
    kXMIT_LATE_COLLISIONS_REQ =0x001d
    kNumCDCStates= 2
};
    // Packet Filter definitions
 
// Packet Filter definitions
enum
{
    kPACKET_TYPE_PROMISCUOUS =0x0001,
    UInt8 bmCapabilities;
    UInt8 bDataInterface;
} CMFunctionalDescriptor;
typedef struct
{
    UInt8 bFunctionLength;
class net_lucid_cake_driver_AJZaurusUSB : public IOEthernetController
{
    OSDeclareDefaultStructors(net_lucid_cake_driver_AJZaurusUSB);// Constructor & Destructor stuff
private:
    boolfTerminate;// Are we being terminated (ie the device was unplugged)
    boolfTerminate;// we are being terminated (ie the device was unplugged)
    UInt8fbmAttributes;// Device attributes
    UInt16fVendorID;
    UInt16fProductID;
charvendorString[50];
charmodelString[50];
charserialString[50];
       
    IOEthernetInterface*fNetworkInterface;// the interface of which we are the Client
    IOBasicOutputQueue*fTransmitQueue;
    IOWorkLoop*fWorkLoop;
    IONetworkStats*fpNetStats;
    IOEthernetStats*fpEtherStats;
    IOTimerEventSource*fTimerSource;
   
    OSDictionary*fMediumDict;
    boolfReady;
    boolfNetifEnabled;
    boolfWOL;
    UInt32fUpSpeed;
    UInt32fDownSpeed;
    UInt16fPacketFilter;
     
    IOUSBInterface*fCommInterface;
    IOUSBInterface*fDataInterface;
   
    IOBufferMemoryDescriptor*fCommPipeMDP;
    IOBufferMemoryDescriptor*fPipeInMDP;
    //IOBufferMemoryDescriptor*fPipeOutMDP;
    UInt8*fCommPipeBuffer;
    UInt8*fPipeInBuffer;
    pipeOutBuffersfPipeOutBuff[kOutBufPool];
    UInt8fDataInterfaceNumber;
    UInt32fCount;
    UInt32fOutPacketSize;
boolfPadded;
boolfChecksum;
UInt8fInterfaceClass;// interface class
    boolfInputErrsOK;
    boolfOutputPktsOK;
    boolfOutputErrsOK;
    IOUSBCompletionfCommCompletionInfo;
    IOUSBCompletionfReadCompletionInfo;
    //IOUSBCompletionfWriteCompletionInfo;
    IOUSBCompletionfMERCompletionInfo;
    IOUSBCompletionfStatsCompletionInfo;
// callbacks
    static voidcommReadComplete(void *obj, void *param, IOReturn ior, UInt32 remaining);
    voidreceivePacket(UInt8 *packet, UInt32 size);
    static void timerFired(OSObject *owner, IOTimerEventSource *sender);
    voidtimeoutOccurred(IOTimerEventSource *timer);
public:
    IOUSBDevice*fpDevice;// our provider (USB device)
        // IOKit methods
       
    IOUSBDevice*fpDevice;// our provider (i.e. the USB device)
// IOKit methods
    virtual boolinit(OSDictionary *properties = 0);
virtualIOService*probe(IOService *provider, SInt32 *score);
    virtual boolstart(IOService *provider);
    virtual IOReturnmessage(UInt32 type, IOService *provider, void *argument = 0);
    virtual voidfree(void);
    virtual voidstop(IOService *provider);
        // IOEthernetController methods
// IOEthernetController methods
    virtual IOReturnenable(IONetworkInterface *netif);
    UInt32outputPacket(mbuf_t pkt, void *param);
    virtual IOReturndisable(IONetworkInterface *netif);
    virtual IOReturnsetMulticastMode(IOEnetMulticastMode mode);
    virtual IOReturnsetMulticastList(IOEthernetAddress *addrs, UInt32 count);
    virtual IOReturnsetPromiscuousMode(IOEnetPromiscuousMode mode);
    virtual IOOutputQueue*createOutputQueue(void);
virtual IOReturnregisterWithPolicyMaker(IOService * policyMaker);
virtual IOOutputQueue*createOutputQueue(void);
    virtual const OSString*newVendorString(void) const;
    virtual const OSString*newModelString(void) const;
    virtual const OSString*newRevisionString(void) const;
virtual boolcreateWorkLoop();
virtual IOWorkLoop*getWorkLoop() const;
// Power Manager
// Power Manager
boolinitForPM(IOService *provider);
unsigned longinitialPowerStateForDomainState(IOPMPowerFlags flags);
IOReturnsetPowerState(unsigned long, IOService *);
virtual unsigned longinitialPowerStateForDomainState(IOPMPowerFlags flags);
virtual IOReturnsetPowerState(unsigned long, IOService *);
}; /* end class net_lucid_cake_driver_AJZaurusUSB */
Sources/Glue.cpp
2424
2525
2626
27
27
2828
2929
3030
......
108108
109109
110110
111
111
112112
113113
114114
115115
116116
117117
118
118
119119
120120
121121
122
122
123123
124124
125125
126126
127
127
128128
129129
130130
......
141141
142142
143143
144
145
146
147
148
149
144
145
146
147
148
149
150150
151151
152152
......
159159
160160
161161
162
162
163163
164164
165165
......
204204
205205
206206
207
207
208208
209209
210210
211211
212212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230230
231231
232
232
233233
234
234
235235
236
237
238
239
240
241
236
237
238
239
240
241
242242
243243
244244
245245
246246
247
247
248248
249249
250250
......
252252
253253
254254
255
255
256256
257257
258258
......
260260
261261
262262
263
263
264264
265265
266266
......
281281
282282
283283
284
285284
286
287285
288286
289287
......
318316
319317
320318
321
319
322320
323321
324322
......
331329
332330
333331
334
335332
336333
337334
......
418415
419416
420417
421
418
422419
423420
424
421
425422
426423
427
424
428425
429426
430
427
431428
432429
433
430
434431
435432
436
433
437434
438435
439
436
440437
441438
442
439
443440
444441
445
442
446443
447444
448
445
449446
450447
451
448
452449
453450
454
451
455452
456453
457
454
458455
459456
460
457
461458
462459
463460
......
563560
564561
565562
566
567
563
564
568565
569566
570567
 with same name as enclosing class" will be issued. This warning can be ignored.
 
 Copyright:Copyright 2002, 2003 Andreas Junghans
 Copyright 2004-2006 H. Nikolaus Schaller
 Copyright 2004-2010 H. Nikolaus Schaller
 
 Disclaimer:This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
       
        // Now look at the state stuff
       
        LogData(kUSBAnyDirn, dLen, me->fCommPipeBuffer);
 //       LogData(kUSBAnyDirn, dLen, me->fCommPipeBuffer);
       
        notif = me->fCommPipeBuffer[1];
        if (dLen > 7)
            {
            switch(notif)
                {
                case kNetwork_Connection:
case kNetwork_Connection:
                    me->fLinkStatus = me->fCommPipeBuffer[2];
                    IOLog("AJZaurusUSB::commReadComplete - kNetwork_Connection - link Status %d\n", me->fLinkStatus);
                    break;
                case kConnection_Speed_Change:// In you-know-whose format
case kConnection_Speed_Change:// In you-know-whose format
                    me->fUpSpeed = USBToHostLong(*((UInt32 *)&me->fCommPipeBuffer[8]));
                    me->fDownSpeed = USBToHostLong(*((UInt32 *)&me->fCommPipeBuffer[13]));
                    IOLog("AJZaurusUSB::commReadComplete - kConnection_Speed_Change up=%lu down=%lu\n", me->fUpSpeed, me->fDownSpeed);
                    break;
                default:
default:
                    IOLog("AJZaurusUSB::commReadComplete - Unknown notification: %d\n", notif);
                    break;
                }
    if (rc != kIOReturnAborted)
        {
ior = me->fCommPipe->Read(me->fCommPipeMDP,
5000,// 5 seconds until timeout
5000,
me->fCommPipeMDP->getLength(),
&me->fCommCompletionInfo,
NULL);
//        ior = me->fCommPipe->Read(me->fCommPipeMDP, &me->fCommCompletionInfo, NULL);
 5000,// 5 seconds until timeout
 5000,
 me->fCommPipeMDP->getLength(),
 &me->fCommCompletionInfo,
 NULL);
        if (ior != kIOReturnSuccess)
            {
            IOLog("AJZaurusUSB::commReadComplete - Failed to queue next read: %d %s\n", ior, me->stringFromReturn(ior));
 me->fCommPipeMDP->getLength(),
 &me->fCommCompletionInfo,
 NULL);
//                ior = me->fCommPipe->Read(me->fCommPipeMDP, &me->fCommCompletionInfo, NULL);
                if (ior != kIOReturnSuccess)
                    {
                    IOLog("AJZaurusUSB::commReadComplete - Failed, read dead: %d %s\n", ior, me->stringFromReturn(ior));
#if 0
        IOLog("AJZaurusUSB::dataReadComplete - len=%lu\n", dLen);
#endif  
        LogData(kUSBIn, dlen, me->fPipeInBuffer);
//        LogData(kUSBIn, dlen, me->fPipeInBuffer);
        me->receivePacket(me->fPipeInBuffer, dLen);// Move the incoming bytes up the stack
        }
    else
        { // some error
#if 1
        if(rc == kIOUSBPipeStalled)
            {
IOLog("AJZaurusUSB::dataReadComplete - err=kIOUSBPipeStalled\n");
            // rc = me->clearPipeStall(me->fInPipe);
            rc = me->fInPipe->ClearPipeStall(true);
            if(rc != kIOReturnSuccess)
                IOLog("AJZaurusUSB::dataReadComplete - clear pipe stall failed: %d %s\n", rc, me->fDataInterface->stringFromReturn(rc));
            }
else if(rc == kIOUSBTransactionTimeout)
{
IOLog("AJZaurusUSB::dataReadComplete - Timeout err: %d %s\n", rc, me->fDataInterface->stringFromReturn(rc));
            rc = me->fInPipe->ClearPipeStall(true);
            if(rc != kIOReturnSuccess)
                IOLog("AJZaurusUSB::dataReadComplete - clear pipe stall failed: %d %s\n", rc, me->fDataInterface->stringFromReturn(rc));
}
else
IOLog("AJZaurusUSB::dataReadComplete - IO err: %d %s\n", rc, me->fDataInterface->stringFromReturn(rc));
if(rc == kIOUSBPipeStalled)
{
IOLog("AJZaurusUSB::dataReadComplete - err=kIOUSBPipeStalled\n");
// rc = me->clearPipeStall(me->fInPipe);
rc = me->fInPipe->ClearPipeStall(true);
if(rc != kIOReturnSuccess)
IOLog("AJZaurusUSB::dataReadComplete - clear pipe stall failed: %d %s\n", rc, me->fDataInterface->stringFromReturn(rc));
}
else if(rc == kIOUSBTransactionTimeout)
{
IOLog("AJZaurusUSB::dataReadComplete - Timeout err: %d %s\n", rc, me->fDataInterface->stringFromReturn(rc));
rc = me->fInPipe->ClearPipeStall(true);
if(rc != kIOReturnSuccess)
IOLog("AJZaurusUSB::dataReadComplete - clear pipe stall failed: %d %s\n", rc, me->fDataInterface->stringFromReturn(rc));
}
else
IOLog("AJZaurusUSB::dataReadComplete - IO err: %d %s\n", rc, me->fDataInterface->stringFromReturn(rc));
#endif
        }
    // Queue the next read
ior = me->fInPipe->Read(me->fPipeInMDP,
 10000,// 10 seconds until timeout
 10000,
 me->fPipeInMDP->getLength(),
 &me->fReadCompletionInfo,
 NULL);
//    ior = me->fInPipe->Read(me->fPipeInMDP, &me->fReadCompletionInfo, NULL);
10000,// 10 seconds until timeout
10000,
me->fPipeInMDP->getLength(),
&me->fReadCompletionInfo,
NULL);
    if(ior != kIOReturnSuccess)
        {
        IOLog("AJZaurusUSB::dataReadComplete - Failed to queue read: %d %s\n", ior, me->fDataInterface->stringFromReturn(rc));
        if(ior == kIOUSBPipeStalled)
            {
//IOLog("AJZaurusUSB::dataReadComplete - err=kIOUSBPipeStalled\n");
//IOLog("AJZaurusUSB::dataReadComplete - err=kIOUSBPipeStalled\n");
            me->fInPipe->ClearPipeStall(true);
ior = me->fInPipe->Read(me->fPipeInMDP,
10000,// 10 seconds until timeout
me->fPipeInMDP->getLength(),
&me->fReadCompletionInfo,
NULL);
//            ior = me->fInPipe->Read(me->fPipeInMDP, &me->fReadCompletionInfo, NULL);
            if(ior != kIOReturnSuccess)
                {
                IOLog("AJZaurusUSB::dataReadComplete - Failed again, read dead: %d %s\n", ior, me->fDataInterface->stringFromReturn(rc));
                }
            }
        }
} /* end dataReadComplete */
/****************************************************************************************************/
void net_lucid_cake_driver_AJZaurusUSB::dataWriteComplete(void *obj, void *param, IOReturn rc, UInt32 remaining)
{
    net_lucid_cake_driver_AJZaurusUSB*me = (net_lucid_cake_driver_AJZaurusUSB *)obj;
    //mbuf_tm;
    //UInt32pktLen = 0;
    //UInt32numbufs = 0;
    UInt32poolIndx;
    SInt32dataCount = 0;
    boolstalled = FALSE;
        // FIXME: what do we do with the buffer?
        if (rc != kIOReturnAborted)
            {
       //     rc = me->clearPipeStall(me->fOutPipe);
            rc = me->fOutPipe->ClearPipeStall(true);
            if (rc != kIOReturnSuccess)
                {
        IOLog("AJZaurusUSB:dataWriteComplete - trying to revive a stalled queue\n");
        me->fTransmitQueue->service(IOBasicOutputQueue::kServiceAsync);// revive a stalled transmit queue
        }
 // me->fTransmitQueue->service();// always revive a stalled queue
   
    return;
   
            currStat = STREQ->wValue;
            switch(currStat)
                {
                case kXMIT_OK_REQ:
case kXMIT_OK_REQ:
                    me->fpNetStats->outputPackets = USBToHostLong(me->fStatValue);
                    break;
                case kRCV_OK_REQ:
case kRCV_OK_REQ:
                    me->fpNetStats->inputPackets = USBToHostLong(me->fStatValue);
                    break;
                case kXMIT_ERROR_REQ:
case kXMIT_ERROR_REQ:
                    me->fpNetStats->outputErrors = USBToHostLong(me->fStatValue);
                    break;
                case kRCV_ERROR_REQ:
case kRCV_ERROR_REQ:
                    me->fpNetStats->inputErrors = USBToHostLong(me->fStatValue);
                    break;
                case kRCV_CRC_ERROR_REQ:
case kRCV_CRC_ERROR_REQ:
                    me->fpEtherStats->dot3StatsEntry.fcsErrors = USBToHostLong(me->fStatValue);
                    break;
                case kRCV_ERROR_ALIGNMENT_REQ:
case kRCV_ERROR_ALIGNMENT_REQ:
                    me->fpEtherStats->dot3StatsEntry.alignmentErrors = USBToHostLong(me->fStatValue);
                    break;
                case kXMIT_ONE_COLLISION_REQ:
case kXMIT_ONE_COLLISION_REQ:
                    me->fpEtherStats->dot3StatsEntry.singleCollisionFrames = USBToHostLong(me->fStatValue);
                    break;
                case kXMIT_MORE_COLLISIONS_REQ:
case kXMIT_MORE_COLLISIONS_REQ:
                    me->fpEtherStats->dot3StatsEntry.multipleCollisionFrames = USBToHostLong(me->fStatValue);
                    break;
                case kXMIT_DEFERRED_REQ:
case kXMIT_DEFERRED_REQ:
                    me->fpEtherStats->dot3StatsEntry.deferredTransmissions = USBToHostLong(me->fStatValue);
                    break;
                case kXMIT_MAX_COLLISION_REQ:
case kXMIT_MAX_COLLISION_REQ:
                    me->fpNetStats->collisions = USBToHostLong(me->fStatValue);
                    break;
                case kRCV_OVERRUN_REQ:
case kRCV_OVERRUN_REQ:
                    me->fpEtherStats->dot3StatsEntry.frameTooLongs = USBToHostLong(me->fStatValue);
                    break;
                case kXMIT_TIMES_CARRIER_LOST_REQ:
case kXMIT_TIMES_CARRIER_LOST_REQ:
                    me->fpEtherStats->dot3StatsEntry.carrierSenseErrors = USBToHostLong(me->fStatValue);
                    break;
                case kXMIT_LATE_COLLISIONS_REQ:
case kXMIT_LATE_COLLISIONS_REQ:
                    me->fpEtherStats->dot3StatsEntry.lateCollisions = USBToHostLong(me->fStatValue);
                    break;
                default:
default:
                    IOLog("AJZaurusUSB::statsWriteComplete - Invalid stats code (currstat=%d): %d\n", currStat, rc);
                    break;
                }
   
    if (!attachInterface((IONetworkInterface **)&fNetworkInterface, true))
        {
        IOLog("AJZaurusUSB::createNetworkInterface - attachInterface failed\n");      
        return false;
IOLog("AJZaurusUSB::createNetworkInterface - attachInterface failed\n");      
return false;
        }
   
    // Ready to service interface requests
Sources/Logging.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
/*
 File:Logging.cpp
 
 Description:This is an experimental driver that enables Mac OS X to communicate with a Sharp Zaurus
 over IP over USB.
 
 It is based on the USBCDCEthernet example which is
 Copyright 1998-2002 Apple Computer, Inc. All rights reserved.
 Portions have been ported from usbdnet.c (Linux driver) written by
 Stuart Lynne <sl@lineo.com> and Tom Rushworth <tbr@lineo.com> with some
 algorithms adopted from usbnet.c written by
 David Brownell <dbrownell@users.sourceforge.net>.
 
 Original description for USBCDCEthernet:
 This is a sample USB Communication Device Class (CDC) driver, Ethernet model.
 Note that this sample has not been tested against any actual hardware since there
 are very few CDC Ethernet devices currently in existence.
 
 This sample requires Mac OS X 10.1 and later. If built on a version prior to
 Mac OS X 10.2, a compiler warning "warning: ANSI C++ forbids data member `ip_opts'
 with same name as enclosing class" will be issued. This warning can be ignored.
 
 Copyright:Copyright 2002, 2003 Andreas Junghans
 Copyright 2004-2006 H. Nikolaus Schaller
 
 Disclaimer:This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
 Change History (most recent first):
 
 <x>     2004-2005   Support for Zaurus C1000, C3000
 made compile on MacOS X 10.4 with Xcode 2.0
 power management added
 <7>  07/04/03Support for Zaurus C760.
 <6>  02/18/03Increased stability + support for iPaq/Opie.
 <5>  02/10/03Bug fix (introduces a workloop).
 <4>  01/24/03Support for more Zaurus models.
 <3>  01/11/03Modified to include latest changes from sample driver
 (provided by Russ Winsper <russw@apple.com>)
 <2>  12/22/02Modified to support the Sharp Zaurus (and some bug fixes)
 <1> 11/08/02New sample (provided by Apple Computer, Inc.)
 
 */
#include "Driver.h"
#if USE_ELG
static globalsg;// Instantiate the globals
/****************************************************************************************************/
//
//Function:AllocateEventLog
//
//Inputs:size - amount of memory to allocate
//
//Outputs:None
//
//Desc:Allocates the event log buffer
//
/****************************************************************************************************/
static void AllocateEventLog(UInt32 size)
{
    if (g.evLogBuf)
        return;
   
    g.evLogFlag = 0;            // assume insufficient memory
    g.evLogBuf = (UInt8*)IOMalloc(size);
    if (!g.evLogBuf)
        {
        kprintf("net_lucid_cake_driver_AJZaurusUSB evLog allocation failed ");
        return;
        }
   
    bzero(g.evLogBuf, size);
    g.evLogBufp= g.evLogBuf;
    g.evLogBufe= g.evLogBufp + kEvLogSize - 0x20; // ??? overran buffer?
    g.evLogFlag  = 0xFEEDBEEF;// continuous wraparound
                                //g.evLogFlag  = 'step';// stop at each ELG
                                //g.evLogFlag  = 0x0333;// any nonzero - don't wrap - stop logging at buffer end
   
    IOLog("AllocateEventLog - &globals=%8x buffer=%8x\n", (unsigned int)&g, (unsigned int)g.evLogBuf);
   
    return;
   
}/* end AllocateEventLog */
/****************************************************************************************************/
//
//Function:EvLog
//
//Inputs:a - anything, b - anything, ascii - 4 charater tag, str - any info string
//
//Outputs:None
//
//Desc:Writes the various inputs to the event log buffer
//
/****************************************************************************************************/
static void EvLog(UInt32 a, UInt32 b, UInt32 ascii, char* str)
{
    register UInt32*lp;           // Long pointer
    mach_timespec_ttime;
   
    if (g.evLogFlag == 0)
        return;
   
    IOGetTime(&time);
   
    lp = (UInt32*)g.evLogBufp;
    g.evLogBufp += 0x10;
   
    if (g.evLogBufp >= g.evLogBufe)       // handle buffer wrap around if any
        {    
        g.evLogBufp  = g.evLogBuf;
        if (g.evLogFlag != 0xFEEDBEEF)    // make 0xFEEDBEEF a symbolic ???
            g.evLogFlag = 0;                // stop tracing if wrap undesired
        }
   
    // compose interrupt level with 3 byte time stamp:
   
    *lp++ = (g.intLevel << 24) | ((time.tv_nsec >> 10) & 0x003FFFFF);   // ~ 1 microsec resolution
    *lp++ = a;
    *lp++ = b;
    *lp   = ascii;
   
    if(g.evLogFlag == 'step')
        {
        static charcode[ 5 ] = {0,0,0,0,0};
        *(UInt32*)&code = ascii;
        IOLog("%8x AJZaurusUSB: %8x %8x %s\n", time.tv_nsec>>10, (unsigned int)a, (unsigned int)b, code);
        }
   
    return;
   
}/* end EvLog */
#endif // USE_ELG
#if LOG_DATA
/****************************************************************************************************/
//
//Function:Asciify
//
//Inputs:i - the nibble
//
//Outputs:return byte - ascii byte
//
//Desc:Converts to ascii.
//
/****************************************************************************************************/
static UInt8 Asciify(UInt8 i)
{
   
    i &= 0xF;
    if (i < 10)
        return('0' + i);
    else return(('A'-10)  + i);
   
}/* end Asciify */
#define dumplen32// Set this to the number of bytes to dump and the rest should work out correct
#define buflen((dumplen*2)+dumplen)+3
#define Asciistart(dumplen*2)+3
/****************************************************************************************************/
//
//Function:USBLogData
//
//Inputs:Dir - direction
//Count - number of bytes
//buf - the data
//
//Outputs:
//
//Desc:Puts the data in the log.
//
/****************************************************************************************************/
static void USBLogData(UInt8 Dir, UInt32 Count, char *buf)
{
    UInt8wlen, i, Aspnt, Hxpnt;
    UInt8wchr;
    charLocBuf[buflen+1];
   
    for (i=0; i<=buflen; i++)
        {
        LocBuf[i] = 0x20;
        }
    LocBuf[i] = 0x00;
   
    if (Dir == kUSBIn)
        {
        IOLog("AJZaurusUSB:: USBLogData - Read Complete, size = %8x\n", Count);
        }
    else
        {
        if (Dir == kUSBOut)
            {
            IOLog("AJZaurusUSB:: USBLogData - Write, size = %8x\n", Count);
            }
        else
            {
            if (Dir == kUSBAnyDirn)
                {
                IOLog("AJZaurusUSB:: USBLogData - Other, size = %8x\n", Count);
                }
            }
        }
   
    if (Count > dumplen)
        {
        wlen = dumplen;
        }
    else
        {
        wlen = Count;
        }
   
    if (wlen > 0)
        {
        Aspnt = Asciistart;
        Hxpnt = 0;
        for (i=1; i<=wlen; i++)
            {
            wchr = buf[i-1];
            LocBuf[Hxpnt++] = Asciify(wchr >> 4);
            LocBuf[Hxpnt++] = Asciify(wchr);
            if ((wchr < 0x20) || (wchr > 0x7F)) // Non printable characters
                {
                LocBuf[Aspnt++] = 0x2E;// Replace with a period
                }
            else
                {
                LocBuf[Aspnt++] = wchr;
                }
            }
        LocBuf[(wlen + Asciistart) + 1] = 0x00;
        IOLog("%s\n", LocBuf);
        IOSleep(Sleep_Time);// Try and keep the log from overflowing
        }
    else
        {
        IOLog("AJZaurusUSB: USBLogData - No data, Count=0\n");
        }
   
}/* end USBLogData */
#endif // LOG_DATA
/* EOF */
Sources/Logging.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
    File:Logging.h
    Description:This is an experimental driver that enables Mac OS X to communicate with a Sharp Zaurus
                   over IP over USB. It is based on the USBCDCEthernet example which is
Copyright 1998-2002 Apple Computer, Inc. All rights reserved.
Portions have been ported from usbdnet.c (Linux driver) written by
Stuart Lynne <sl@lineo.com> and Tom Rushworth <tbr@lineo.com> with some
algorithms adopted from usbnet.c written by
David Brownell <dbrownell@users.sourceforge.net>.
Original description for USBCDCEthernet:
                     This is a sample USB Communication Device Class (CDC) driver, Ethernet model.
                        Note that this sample has not been tested against any actual hardware since there
                        are very few CDC Ethernet devices currently in existence.
                       
                        This sample requires Mac OS X 10.1 and later. If built on a version prior to
                        Mac OS X 10.2, a compiler warning "warning: ANSI C++ forbids data member `ip_opts'
                        with same name as enclosing class" will be issued. This warning can be ignored.
                       
    Copyright:Copyright 2002, 2003 Andreas Junghans
    Disclaimer:This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Change History (most recent first):
       
<7>  07/04/03Support for Zaurus C760.
<6>  02/18/03Increased stability + support for iPaq/Opie.
<5>  02/10/03Bug fix (introduced a workloop).
<4>  01/24/03Support for more Zaurus models.
        <3>  01/11/03Modified to include latest changes to the sample driver
(provided by Russ Winsper <russw@apple.com>)
<2>  12/22/02Modified to support the Sharp Zaurus
            <1> 11/08/02New sample (provided by Apple Computer, Inc.)
       
*/
/*****For fans of kprintf, IOLog and debugging infrastructure of the*****/
/*****string ilk, please modify the ELG and PAUSE macros or their*****/
/*****associated EvLog and Pause functions to suit your taste. These*****/
/*****macros currently are set up to log events to a wraparound*****/
/*****buffer with minimal performance impact. They take 2 UInt32*****/
/*****parameters so that when the buffer is dumped 16 bytes per line,*****/
/*****time stamps (~1 microsecond) run down the left side while*****/
/*****unique 4-byte ASCII codes can be read down the right side.*****/
/*****Preserving this convention facilitates different maintainers*****/
/*****using different debugging styles with minimal code clutter.*****/
#ifndef INCLUDE_LOGGING_H
#define INCLUDE_LOGGING_H
#include <machine/limits.h>/* UINT_MAX */
#include <libkern/OSByteOrder.h>
#include <IOKit/assert.h>
#include <IOKit/IOLib.h>
#include <IOKit/IOMessage.h>
#include <sys/kpi_mbuf.h>
#include <UserNotification/KUNCUserNotifications.h>
extern "C"
{
    #include <sys/param.h>
    #include <sys/mbuf.h>
}
#define LDEBUG0// for debugging
#define USE_ELG0// to event log - LDEBUG must also be set
#define kEvLogSize  (4096*16)// 16 pages = 64K = 4096 events
#defineLOG_DATA0// logs data to the IOLog - LDEBUG must also be set
#define Sleep_Time20
#if LDEBUG
    #if USE_ELG
        #define ELG(A,B,ASCI,STRING)    EvLog((UInt32)(A), (UInt32)(B), (UInt32)(ASCI), STRING)
    #else /* not USE_ELG */
        #define ELG(A,B,ASCI,STRING){IOLog("AJZaurusUSB: %8x %8x " STRING "\n", (unsigned int)(A), (unsigned int)(B));IOSleep(Sleep_Time);}
    #endif /* USE_ELG */
    #if LOG_DATA
        #define LogData(D, C, b)USBLogData((UInt8)D, (UInt32)C, (char *)b)
    #else /* not LOG_DATA */
        #define LogData(D, C, b)
    #endif /* LOG_DATA */
#else /* not LDEBUG */
    #define ELG(A,B,ASCI,S)
    #define LogData(D, C, b)
    #undef USE_ELG
    #undef LOG_DATA
#endif /* LDEBUG */
#if DEBUG
// nothing
#else
#define IOLog(...)// remove all logging code
#endif
// #define ALERT(A,B,ASCI,STRING){IOLog("AJZaurusUSB: %8x %8x " STRING "\n", (unsigned int)(A), (unsigned int)(B));}
    // Globals
typedef struct globals      // Globals for this module (not per instance)
{
    UInt32      evLogFlag; // debugging only
    UInt8       *evLogBuf;
    UInt8       *evLogBufe;
    UInt8       *evLogBufp;
    UInt8       intLevel;
} globals;
#endif INCLUDE_LOGGING_H
/* EOF */
Sources/Power.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
 File:Power.cpp
 
 This module manages power up and down of the Mac
 
 Description:This is an experimental driver that enables Mac OS X to communicate with a Sharp Zaurus
 over IP over USB.
 
 It is based on the USBCDCEthernet example which is
 Copyright 1998-2002 Apple Computer, Inc. All rights reserved.
 Portions have been ported from usbdnet.c (Linux driver) written by
 Stuart Lynne <sl@lineo.com> and Tom Rushworth <tbr@lineo.com> with some
 algorithms adopted from usbnet.c written by
 David Brownell <dbrownell@users.sourceforge.net>.
 
 Original description for USBCDCEthernet:
 This is a sample USB Communication Device Class (CDC) driver, Ethernet model.
 Note that this sample has not been tested against any actual hardware since there
 are very few CDC Ethernet devices currently in existence.
 
 This sample requires Mac OS X 10.1 and later. If built on a version prior to
 Mac OS X 10.2, a compiler warning "warning: ANSI C++ forbids data member `ip_opts'
 with same name as enclosing class" will be issued. This warning can be ignored.
 
 Copyright:Copyright 2002, 2003 Andreas Junghans
 Copyright 2004-2006 H. Nikolaus Schaller
 
 Disclaimer:This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
 Change History (most recent first):
 
 <x>     2004-2005   Support for Zaurus C1000, C3000
 made compile on MacOS X 10.4 with Xcode 2.0
 power management added
 <7>  07/04/03Support for Zaurus C760.
 <6>  02/18/03Increased stability + support for iPaq/Opie.
 <5>  02/10/03Bug fix (introduces a workloop).
 <4>  01/24/03Support for more Zaurus models.
 <3>  01/11/03Modified to include latest changes from sample driver
 (provided by Russ Winsper <russw@apple.com>)
 <2>  12/22/02Modified to support the Sharp Zaurus (and some bug fixes)
 <1> 11/08/02New sample (provided by Apple Computer, Inc.)
 
 */
#include "Driver.h"
static IOPMPowerState gOurPowerStates[kNumCDCStates] =
{
    {1,0,0,0,0,0,0,0,0,0,0,0},
    {1,IOPMDeviceUsable,IOPMPowerOn,IOPMPowerOn,0,0,0,0,0,0,0,0}
};
/****************************************************************************************************/
//
//Method:net_lucid_cake_driver_AJZaurusUSB::initForPM
//
//Inputs:provider - my provider
//
//Outputs:return code - true(initialized), false(failed)
//
//Desc:Add ourselves to the power management tree so we can do
//the right thing on sleep/wakeup.
//
/****************************************************************************************************/
bool net_lucid_cake_driver_AJZaurusUSB::initForPM(IOService *provider)
{
   
    fPowerState = kCDCPowerOnState;// init our power state to be 'on'
    PMinit();// init power manager instance variables
    provider->joinPMtree(this);// add us to the power management tree
    if (pm_vars != NULL)
{
// register ourselves with ourself as policy-maker
       
        registerPowerDriver(this, gOurPowerStates, kNumCDCStates);
        return true;
}
else
{
IOLog("AJZaurusUSB::initForPM - Initializing power manager failed\n");
}
    return false;
   
}/* end initForPM */
/****************************************************************************************************/
//
//Method:net_lucid_cake_driver_AJZaurusUSB::initialPowerStateForDomainState
//
//Inputs:flags -
//
//Outputs:return code - Current power state
//
//Desc:Request for our initial power state.
//
/****************************************************************************************************/
unsigned long net_lucid_cake_driver_AJZaurusUSB::initialPowerStateForDomainState(IOPMPowerFlags flags)
{
    return fPowerState;
   
}/* end initialPowerStateForDomainState */
/****************************************************************************************************/
//
//Method:net_lucid_cake_driver_AJZaurusUSB::setPowerState
//
//Inputs:whatState - new state
//
//Outputs:Return code - IOPMAckImplied
//
//Desc:We are notified to turn power on/off
//
/****************************************************************************************************/
IOReturn net_lucid_cake_driver_AJZaurusUSB::setPowerState(unsigned long whatState, IOService *whatDevice)
{ // turn your device on/off here
    IOLog("AJZaurusUSB::setPowerState state:%lu\n", whatState);
    if(whatState == kCDCPowerOffState || whatState == kCDCPowerOnState)
        {
        IOLog("AJZaurusUSB::setPowerState - power %lu\n", whatState);
if(whatState == fPowerState)
return IOPMAckImplied;// unchanged
fPowerState=whatState;
if(fPowerState == kCDCPowerOnState)
{
IOLog("AJZaurusUSB::setPowerState - powered on\n");
// do whatever we need to do
resetDevice();
}
return IOPMNoErr;
        }
    return IOPMNoSuchState;
}
/* EOF */
Sources/Provider.cpp
2323
2424
2525
26
26
2727
2828
2929
......
4040
4141
4242
43
43
4444
4545
4646
......
9898
9999
100100
101
102101
103102
104103
......
121120
122121
123122
124
123
125124
126125
127126
......
157156
158157
159158
160
161
162
163
159
160
161
162
164163
165
166
167
168
169
170
171
164
165
166
167
168
169
170
172171
173
172
174173
175
176
177
178
179
180
174
175
176
177
178
179
181180
182
183
181
182
184183
185
186
187
188
189
190
184
185
186
187
188
189
191190
192
193
191
192
194193
195
196
197
198
194
195
196
197
199198
200199
201200
202
203
204
201
202
203
205204
206205
207206
......
209208
210209
211210
212
211
213212
214213
215214
......
220219
221220
222221
223
222
224223
225224
226225
......
245244
246245
247246
248
247
249248
250249
251250
......
254253
255254
256255
257
256
258257
259258
260259
261260
262
263
264
265
266
267
268
269
270
271
272
273
274
275
261
262
263
264
265
266
267
268
269
270
271
272
273
274
276275
277
278
279
280
281
282
283
276
284277
285
286
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
287293
288
294
295
296
297
298
299
289300
290
301
302
291303
292304
293305
294
295
296
297
298
299
300
301
302
303
304
305
306
307306
308307
309308
......
369368
370369
371370
372
371
373372
374373
375374
......
387386
388387
389388
390
389
391390
392391
393392
......
498497
499498
500499
501
502
503
500
501
502
504503
505504
506505
......
522521
523522
524523
524
525525
526
526
527527
528528
529529
530
530
531531
532
532
533533
534534
535
535
536536
537537
538538
539
539
540540
541541
542
542
543543
544544
545545
546
546
547547
548548
549549
550550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593593
594
595
596
597
598
599
600
601
602
603
604
605
594
595
596
597
598
599
600
601
602
603
604
605
606606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625625
626626
627627
628
628
629629
630630
631631
......
940940
941941
942942
943
944
945
943
946944
947945
948
946
949947
950948
951949
......
954952
955953
956954
957
955
958956
959957
960958
......
963961
964962
965963
966
967964
968965
969
966
970967
971
968
972969
973970
974971
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
994991
995992
996993
......
1001998
1002999
10031000
1004
1005
1006
10071001
10081002
10091003
1010
1004
10111005
1012
1013
1014
1015
1016
1017
1018
1006
1007
1008
1009
1010
1011
1012
10191013
1020
1021
1022
1023
1014
1015
1016
10241017
10251018
10261019
......
10421035
10431036
10441037
1045
1046
1047
1048
1049
1038
10501039
10511040
10521041
......
10561045
10571046
10581047
1059
10601048
10611049
10621050
10631051
1064
1052
10651053
10661054
10671055
......
10701058
10711059
10721060
1073
1061
10741062
10751063
10761064
......
10831071
10841072
10851073
1086
1087
1088
1089
1090
1074
1075
1076
1077
1078
10911079
10921080
10931081
......
12281216
12291217
12301218
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1219
1220
1221
1222
1223
1224
1225
1226
1227
12431228
12441229
12451230
......
12791264
12801265
12811266
1282
1283
1284
12851267
12861268
12871269
......
13061288
13071289
13081290
1309
1291
13101292
13111293
13121294
......
13161298
13171299
13181300
1319
1301
13201302
13211303
13221304
......
15131495
15141496
15151497
1516
1498
15171499
1518
1519
1520
1521
1522
1523
1524
1525
1500
1501
1502
1503
1504
1505
1506
1507
15261508
1527
1509
15281510
15291511
1530
1512
15311513
15321514
15331515
1534
1516
15351517
15361518
15371519
......
15851567
15861568
15871569
1588
1589
1570
1571
15901572
15911573
15921574
15931575
1594
1595
1576
1577
15961578
15971579
15981580
1599
1600
1581
1582
16011583
16021584
16031585
 with same name as enclosing class" will be issued. This warning can be ignored.
 
 Copyright:Copyright 2002, 2003 Andreas Junghans
 Copyright 2004-2006 H. Nikolaus Schaller
 Copyright 2004-2010 H. Nikolaus Schaller
 
 Disclaimer:This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
 Change History (most recent first):
 
 
 <x>     2004-2005   Support for Zaurus C1000, C3000
 made compile on MacOS X 10.4 with Xcode 2.0
 power management added
    UInt16numends = 0;
    UInt16alt;
const IOUSBConfigurationDescriptor*cd = NULL;// configuration descriptor
//IOUSBInterfaceDescriptor *intf = NULL;// interface descriptor
UInt8cval;
UInt8config = 0;
UInt8idx;
22Interrupt interface of RNDIS for Familiar - skip
2550found - has only Data pipe (CDC Ethernet Subclass)
*/
for(cval=0; cval<numConfigs; cval++)
{
IOUSBInterface*interface;
while(interface=fpDevice->FindNextInterface(interface, &req))
{ // got next interface
#if 1
IOLog("AJZaurusUSB::configureDevice -   InterfaceClass=%d\n", interface->GetInterfaceClass());
IOLog("AJZaurusUSB::configureDevice -   InterfaceSubClass=%d\n", interface->GetInterfaceSubClass());
IOLog("AJZaurusUSB::configureDevice -   InterfaceProtocol=%d\n", interface->GetInterfaceProtocol());
IOSleep(20);
IOLog("AJZaurusUSB::configureDevice -   InterfaceClass=%d\n", interface->GetInterfaceClass());
IOLog("AJZaurusUSB::configureDevice -   InterfaceSubClass=%d\n", interface->GetInterfaceSubClass());
IOLog("AJZaurusUSB::configureDevice -   InterfaceProtocol=%d\n", interface->GetInterfaceProtocol());
IOSleep(20);
#endif
if(!interface)
{
IOLog("AJZaurusUSB::configureDevice -   no interface for interface descriptor\n");
continue;
}
if(interface->GetInterfaceClass() == 2 && interface->GetInterfaceSubClass() == kMDLM)
{ // found a Zaurus compatible configuration
if(!interface)
{
IOLog("AJZaurusUSB::configureDevice -   no interface for interface descriptor\n");
continue;
}
if(interface->GetInterfaceClass() == 2 && interface->GetInterfaceSubClass() == kMDLM)
{ // found a Zaurus compatible configuration
#if 1
IOLog("AJZaurusUSB::configureDevice -   MDLM interface found\n");
IOLog("AJZaurusUSB::configureDevice -   MDLM interface found\n");
#endif
fPadded = true;
fChecksum = true;
break;
}
if(interface->GetInterfaceClass() == 2 && interface->GetInterfaceSubClass() == kEthernetControlModel)
{ // found a Familiar Handheld Linux compatible configuration
fPadded = true;
fChecksum = true;
break;
}
if(interface->GetInterfaceClass() == 2 && interface->GetInterfaceSubClass() == kEthernetControlModel)
{ // found a Familiar Handheld Linux compatible configuration
#if 1
IOLog("AJZaurusUSB::configureDevice -   ECM interface found\n");
IOSleep(20);
IOLog("AJZaurusUSB::configureDevice -   ECM interface found\n");
IOSleep(20);
#endif
fPadded = false;
fChecksum = false;
break;
}
if(interface->GetInterfaceClass() == 255 && interface->GetInterfaceSubClass() == 0)
{ // found a special configuration
fPadded = false;
fChecksum = false;
break;
}
if(interface->GetInterfaceClass() == 255 && interface->GetInterfaceSubClass() == 0)
{ // found a special configuration
#if 1
IOLog("AJZaurusUSB::configureDevice -   CDC Ethernet Subset found\n");
IOSleep(20);
IOLog("AJZaurusUSB::configureDevice -   CDC Ethernet Subset found\n");
IOSleep(20);
#endif
fPadded = false;
fChecksum = false;
break;
}
fPadded = false;
fChecksum = false;
break;
}
}
if(!interface)
{ // we have checked all interfaces - try next configuration
IOLog("AJZaurusUSB::configureDevice -   no matching interface for configuration %d\n", cval);
IOSleep(20);
continue;
IOLog("AJZaurusUSB::configureDevice -   no matching interface for configuration %d\n", cval);
IOSleep(20);
continue;
}
fCommInterface=interface;// we have found the Comm interface
fCommInterfaceNumber = interface->GetInterfaceNumber();
fInterfaceSubClass = interface->GetInterfaceSubClass();
break;
}
if(cval == numConfigs)
{
IOLog("AJZaurusUSB::configureDevice -  no matching Interface descriptor found\n");
fVendorID = fpDevice->GetVendorID();
fProductID = fpDevice->GetProductID();
#if 1
IOLog("AJZaurusUSB::configureDevice - comm Interface=%p\n", fCommInterface);
IOLog("AJZaurusUSB::configureDevice - vendor  id=%d (0x%04x)\n", fVendorID, fVendorID);
IOLog("AJZaurusUSB::configureDevice - serial number=%s idx=%u\n", serialString, idx);
IOSleep(20);
#endif
    if(!getFunctionalDescriptors())
        {
        IOLog("AJZaurusUSB::configureDevice - getFunctionalDescriptors failed\n");
   
    if(fInterfaceSubClass != kEthernetControlModel)
        { // Zaurus (MDLM) uses a single interface for comm&data but separates endpoints
        fDataInterface = fCommInterface;// use the same
fDataInterface = fCommInterface;// use the same
}
    else
        { // open the separate comm interface here if we have a ECM device
#if 1
IOLog("AJZaurusUSB::configureDevice - comm interface %p\n", fCommInterface);
IOLog("AJZaurusUSB::configureDevice -   ConfigValue %d\n", fCommInterface->GetConfigValue());
IOLog("AJZaurusUSB::configureDevice -   AlternateSetting %d\n", fCommInterface->GetAlternateSetting());
IOLog("AJZaurusUSB::configureDevice -   InterfaceClass %d\n", fCommInterface->GetInterfaceClass());
IOLog("AJZaurusUSB::configureDevice -   InterfaceSubClass %d\n", fCommInterface->GetInterfaceSubClass());
IOLog("AJZaurusUSB::configureDevice -   InterfaceProtocol %d\n", fCommInterface->GetInterfaceProtocol());
IOSleep(20);
IOLog("AJZaurusUSB::configureDevice -   InterfaceNumber %d\n", fCommInterface->GetInterfaceNumber());
IOLog("AJZaurusUSB::configureDevice -   NumEndpoints %d\n", fCommInterface->GetNumEndpoints());
IOLog("AJZaurusUSB::configureDevice -   BusyState %lu\n", fCommInterface->getBusyState());
IOLog("AJZaurusUSB::configureDevice -   Inactive %d\n", fCommInterface->isInactive());
IOLog("AJZaurusUSB::configureDevice -   Open(any) %d\n", fCommInterface->isOpen());
IOLog("AJZaurusUSB::configureDevice -   Open(this) %d\n", fCommInterface->isOpen(this));
IOSleep(20);
IOLog("AJZaurusUSB::configureDevice - comm interface %p\n", fCommInterface);
IOLog("AJZaurusUSB::configureDevice -   ConfigValue %d\n", fCommInterface->GetConfigValue());
IOLog("AJZaurusUSB::configureDevice -   AlternateSetting %d\n", fCommInterface->GetAlternateSetting());
IOLog("AJZaurusUSB::configureDevice -   InterfaceClass %d\n", fCommInterface->GetInterfaceClass());
IOLog("AJZaurusUSB::configureDevice -   InterfaceSubClass %d\n", fCommInterface->GetInterfaceSubClass());
IOLog("AJZaurusUSB::configureDevice -   InterfaceProtocol %d\n", fCommInterface->GetInterfaceProtocol());
IOSleep(20);
IOLog("AJZaurusUSB::configureDevice -   InterfaceNumber %d\n", fCommInterface->GetInterfaceNumber());
IOLog("AJZaurusUSB::configureDevice -   NumEndpoints %d\n", fCommInterface->GetNumEndpoints());
IOLog("AJZaurusUSB::configureDevice -   BusyState %lu\n", fCommInterface->getBusyState());
IOLog("AJZaurusUSB::configureDevice -   Inactive %d\n", fCommInterface->isInactive());
IOLog("AJZaurusUSB::configureDevice -   Open(any) %d\n", fCommInterface->isOpen());
IOLog("AJZaurusUSB::configureDevice -   Open(this) %d\n", fCommInterface->isOpen(this));
IOSleep(20);
#endif
        if(!fCommInterface->open(this, kIOServiceSeize))
            {
            IOLog("AJZaurusUSB::configureDevice - open comm interface failed %p\n", fCommInterface);
//
// This is a Horrible Hack if some other driver has already opened our channel!!!
//
while(fCommInterface->isOpen())
if(!fCommInterface->open(this, kIOServiceSeize))
{
IOLog("AJZaurusUSB::configureDevice - forced close of interfering comm interface for client %p\n", fCommInterface->getClient());
fCommInterface->close(fCommInterface->getClient());
IOLog("AJZaurusUSB::configureDevice - open comm interface failed %p\n", fCommInterface);
//
// This is a Horrible Hack if some other driver has already opened our channel!!!
//
while(fCommInterface->isOpen())
{
IOLog("AJZaurusUSB::configureDevice - forced close of interfering comm interface for client %p\n", fCommInterface->getClient());
fCommInterface->close(fCommInterface->getClient());
}
if(!fCommInterface->open(this, kIOServiceSeize))
{
IOLog("AJZaurusUSB::configureDevice - open comm interface failed again %p\n", fCommInterface);
fCommInterface = NULL;
return false;
}
}
if(!fCommInterface->open(this, kIOServiceSeize))
req.bInterfaceClass = 10;
req.bInterfaceSubClass = 0;
req.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
req.bAlternateSetting = kIOUSBFindInterfaceDontCare;
fDataInterface = fpDevice->FindNextInterface(NULL, &req);// find matching data interface with 2 endpoints
if(!fDataInterface)
{
IOLog("AJZaurusUSB::configureDevice - open comm interface failed again %p\n", fCommInterface);
IOLog("AJZaurusUSB::configureDevice - Find(Next)Interface for Communications-Data failed\n");
fCommInterface->close(this);// close
fCommInterface = NULL;
return false;
}
            }
 req.bInterfaceClass = 10;
        req.bInterfaceSubClass = 0;
        req.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
        req.bAlternateSetting = kIOUSBFindInterfaceDontCare;
        fDataInterface = fpDevice->FindNextInterface(NULL, &req);// find matching data interface with 2 endpoints
if(!fDataInterface)
{
IOLog("AJZaurusUSB::configureDevice - Find(Next)Interface for Communications-Data failed\n");
            fCommInterface->close(this);// close
fCommInterface = NULL;
return false;
}
}
numends = fDataInterface->GetNumEndpoints();
fDataInterface = NULL;
        return false;
        }
       
fCommInterface->retain();
fDataInterface->retain();
fDataInterface = NULL;
return false;
}
       
    return true;
   
}/* end configureDevice */
                IOLog("AJZaurusUSB::dumpDevice -     bNumEndpoints=%d\n", intf->bNumEndpoints);
                IOLog("AJZaurusUSB::dumpDevice -     iInterface=%d\n", intf->iInterface);
IOSleep(20);
               }
        }
    }
}
}
}
}
    HeaderFunctionalDescriptor *funcDesc = NULL;
    EnetFunctionalDescriptor *ENETFDesc = NULL;
   
IOSleep(1);
    IOLog("AJZaurusUSB::getFunctionalDescriptors\n");
IOSleep(20);
IOSleep(1);
   
    while((funcDesc = (HeaderFunctionalDescriptor*) fCommInterface->FindNextAssociatedDescriptor((void *)funcDesc, CS_INTERFACE)))
        { // loop through all functional descriptors
        switch (funcDesc->bDescriptorSubtype)
switch (funcDesc->bDescriptorSubtype)
            {
            case Header_FunctionalDescriptor:
case Header_FunctionalDescriptor:
                IOLog("AJZaurusUSB::getFunctionalDescriptors - Header Functional Descriptor - type=%d subtype=%d\n", funcDesc->bDescriptorType, funcDesc->bDescriptorSubtype);
                break;
            case Enet_Functional_Descriptor:
case Enet_Functional_Descriptor:
                ENETFDesc = (EnetFunctionalDescriptor *) funcDesc;
                IOLog("AJZaurusUSB::getFunctionalDescriptors - Ethernet Functional Descriptor - type=%d subtype=%d\n", funcDesc->bDescriptorType, funcDesc->bDescriptorSubtype);
                break;
            case Union_FunctionalDescriptor:
case Union_FunctionalDescriptor:
                IOLog("AJZaurusUSB::getFunctionalDescriptors - Union Functional Descriptor - type=%d subtype=%d\n", funcDesc->bDescriptorType, funcDesc->bDescriptorSubtype);
                break;
            default:
default:
                IOLog("AJZaurusUSB::getFunctionalDescriptors - unknown Functional Descriptor - type=%d subtype=%d\n", funcDesc->bDescriptorType, funcDesc->bDescriptorSubtype);
                break;
            }
IOSleep(20);
IOSleep(20);
        }
   
    if(ENETFDesc)
        { // The Enet Func. Desc.  must be present
       
        // Determine who is collecting the input/output network stats.
       
        fOutputPktsOK = !(ENETFDesc->bmEthernetStatistics[0] & kXMIT_OK);
        fInputPktsOK = !(ENETFDesc->bmEthernetStatistics[0] & kRCV_OK);
        fOutputErrsOK = !(ENETFDesc->bmEthernetStatistics[0] & kXMIT_ERROR);
        fInputErrsOK = !(ENETFDesc->bmEthernetStatistics[0] & kRCV_ERROR);
       
        // Save the stats (it's bit mapped)
       
        fEthernetStatistics[0] = ENETFDesc->bmEthernetStatistics[0];
        fEthernetStatistics[1] = ENETFDesc->bmEthernetStatistics[1];
        fEthernetStatistics[2] = ENETFDesc->bmEthernetStatistics[2];
        fEthernetStatistics[3] = ENETFDesc->bmEthernetStatistics[3];
       
        // Save the multicast filters (remember it's intel format)
       
        fMcFilters = USBToHostWord(*(UInt16 *)ENETFDesc->wNumberMCFilters);
       
        // Get the Ethernet address
       
        if (ENETFDesc->iMACAddress != 0)
            {
// check Info.plist if we should override
char etherbuf[6*3];// ASCII string for Ethernet Address
ior = fpDevice->GetStringDescriptor(ENETFDesc->iMACAddress, etherbuf, sizeof(etherbuf));
            if (ior == kIOReturnSuccess)
                { // convert string
int i;
IOLog("AJZaurusUSB::getFunctionalDescriptors - Ethernet string=%s\n", etherbuf);
IOSleep(20);
for(i=0; i<6; i++)
{ // convert ASCII to bitmask
int c=etherbuf[2*i];
int byte;
if(c >= '9') c-=('A'-10);
byte=(c&0xf)<<4;
c=etherbuf[2*i+1];
if(c >= '9') c-=('A'-10);
byte+=(c&0xf);
fEaddr[i]=byte;
}
// Determine who is collecting the input/output network stats.
fOutputPktsOK = !(ENETFDesc->bmEthernetStatistics[0] & kXMIT_OK);
fInputPktsOK = !(ENETFDesc->bmEthernetStatistics[0] & kRCV_OK);
fOutputErrsOK = !(ENETFDesc->bmEthernetStatistics[0] & kXMIT_ERROR);
fInputErrsOK = !(ENETFDesc->bmEthernetStatistics[0] & kRCV_ERROR);
// Save the stats (it's bit mapped)
fEthernetStatistics[0] = ENETFDesc->bmEthernetStatistics[0];
fEthernetStatistics[1] = ENETFDesc->bmEthernetStatistics[1];
fEthernetStatistics[2] = ENETFDesc->bmEthernetStatistics[2];
fEthernetStatistics[3] = ENETFDesc->bmEthernetStatistics[3];
// Save the multicast filters (remember it's intel format)
fMcFilters = USBToHostWord(*(UInt16 *)ENETFDesc->wNumberMCFilters);
// Get the Ethernet address
if (ENETFDesc->iMACAddress != 0)
{
// check Info.plist if we should override
char etherbuf[6*3];// ASCII string for Ethernet Address
ior = fpDevice->GetStringDescriptor(ENETFDesc->iMACAddress, etherbuf, sizeof(etherbuf));
if (ior == kIOReturnSuccess)
{ // convert string
int i;
IOLog("AJZaurusUSB::getFunctionalDescriptors - Ethernet string=%s\n", etherbuf);
IOSleep(20);
for(i=0; i<6; i++)
{ // convert ASCII to bitmask
int c=etherbuf[2*i];
int byte;
if(c >= '9') c-=('A'-10);
byte=(c&0xf)<<4;
c=etherbuf[2*i+1];
if(c >= '9') c-=('A'-10);
byte+=(c&0xf);
fEaddr[i]=byte;
}
#if 1// OVERRIDE
{ // compute a MAC address that distinguishes different devices as good as possible but is constant for each one
UInt32 fcs=CRC32_INITFCS;
fcs=fcs_compute32((unsigned char *)vendorString, strlen(vendorString), fcs);
fcs=fcs_compute32((unsigned char *)modelString, strlen(modelString), fcs);
fcs=fcs_compute32((unsigned char *)serialString, strlen(serialString), fcs);
fEaddr[0]=0x40;
fEaddr[1]=0x00;
fEaddr[2]=fcs>>24;
fEaddr[3]=fcs>>16;
fEaddr[4]=fcs>>8;
fEaddr[5]=fcs>>0;
}
{ // compute a MAC address that distinguishes different devices as good as possible but is constant for each one
UInt32 fcs=CRC32_INITFCS;
fcs=fcs_compute32((unsigned char *)vendorString, strlen(vendorString), fcs);
fcs=fcs_compute32((unsigned char *)modelString, strlen(modelString), fcs);
fcs=fcs_compute32((unsigned char *)serialString, strlen(serialString), fcs);
fEaddr[0]=0x40;
fEaddr[1]=0x00;
fEaddr[2]=fcs>>24;
fEaddr[3]=fcs>>16;
fEaddr[4]=fcs>>8;
fEaddr[5]=fcs>>0;
}
#endif
IOLog("AJZaurusUSB::getFunctionalDescriptors - Ethernet address (string %d): %02x.%02x.%02x.%02x.%02x.%02x\n",
                      ENETFDesc->iMACAddress,
                      (unsigned) fEaddr[0],
                      (unsigned) fEaddr[1],
                      (unsigned) fEaddr[2],
                      (unsigned) fEaddr[3],
                      (unsigned) fEaddr[4],
                      (unsigned) fEaddr[5]                      
                      );
                //                LogData(kUSBAnyDirn, 6, fEaddr);
               
                fMax_Block_Size = USBToHostWord(*(UInt16 *)ENETFDesc->wMaxSegmentSize);
                IOLog("AJZaurusUSB::getFunctionalDescriptors - Maximum segment size %d\n", fMax_Block_Size);
IOSleep(20);
return true;// all ok!
                }
IOLog("AJZaurusUSB::getFunctionalDescriptors - Error retrieving Ethernet address\n");
            }
IOLog("AJZaurusUSB::getFunctionalDescriptors - Ethernet address (string %d): %02x.%02x.%02x.%02x.%02x.%02x\n",
 ENETFDesc->iMACAddress,
 (unsigned) fEaddr[0],
 (unsigned) fEaddr[1],
 (unsigned) fEaddr[2],
 (unsigned) fEaddr[3],
 (unsigned) fEaddr[4],
 (unsigned) fEaddr[5]                      
 );
//                LogData(kUSBAnyDirn, 6, fEaddr);
fMax_Block_Size = USBToHostWord(*(UInt16 *)ENETFDesc->wMaxSegmentSize);
IOLog("AJZaurusUSB::getFunctionalDescriptors - Maximum segment size %d\n", fMax_Block_Size);
IOSleep(20);
return true;// all ok!
}
IOLog("AJZaurusUSB::getFunctionalDescriptors - Error retrieving Ethernet address\n");
}
        }
   
IOLog("AJZaurusUSB::getFunctionalDescriptors -  Using defaults 'cause all else failed\n");
fOutputPktsOK = false;
fInputPktsOK = false;
fOutputErrsOK = false;
        m = mbuf_next(m);
        }
   
    // AJ: Calculate size including CRC and padding
    // -->
    checksum_length = fChecksum?4:0;
    checksum_length = fChecksum?4:0;// Calculate size including CRC and padding
    if (fPadded)
        { // we need to pad so that after appending the CRC we have a multiple of packetsize less one
        new_pkt_length = fOutPacketSize * ( ((total_pkt_length + checksum_length) / fOutPacketSize) + 1) - 1;
new_pkt_length = fOutPacketSize * ( ((total_pkt_length + checksum_length) / fOutPacketSize) + 1) - 1;
        }
    else
        {
        else
            new_pkt_length = total_pkt_length;
        }
    // <--
#if 0
    IOLog("AJZaurusUSB::USBTransmitPacket %p padded:%d checksum:%d length:%lu mbufs:%lu\n", packet, fPadded, fChecksum, new_pkt_length, numbufs);
#endif
        IOLog("AJZaurusUSB::USBTransmitPacket - Bad packet size\n");// Note for now and revisit later
        if (fOutputErrsOK)
            fpNetStats->outputErrors++;
        // OSIncrementAtomic(&fSyncCount);
        return false;
        }
    // Find a free ouput buffer in the pool
    IOSimpleLockLock(fLock);
    while(TRUE)
        { // try to get a buffer
        for(poolIndx=0; poolIndx<kOutBufPool; poolIndx++)
{
            if(fPipeOutBuff[poolIndx].m == NULL)
                break;  // got one
}
        if(poolIndx<kOutBufPool)
            break;  // break while loop
        tryCount++;
        if(tryCount > kOutBuffThreshold)
            { // waited too long
            IOLog("AJZaurusUSB::USBTransmitPacket - Exceeded output buffer wait threshold - output stalled\n");
            if(fOutputErrsOK)
                fpNetStats->outputErrors++;
            IOSimpleLockUnlock(fLock);
            fOutputStalled = true;
            return false;
            }
        IOLog("AJZaurusUSB::USBTransmitPacket - Waiting %d-th time for output buffer\n", tryCount);
        IOSleep(1);// sleep 1 second
for(poolIndx=0; poolIndx<kOutBufPool; poolIndx++)
{
if(fPipeOutBuff[poolIndx].m == NULL)
break;  // got one
}
if(poolIndx<kOutBufPool)
break;  // break while loop
tryCount++;
if(tryCount > kOutBuffThreshold)
{ // waited too long
IOLog("AJZaurusUSB::USBTransmitPacket - Exceeded output buffer wait threshold - output stalled\n");
if(fOutputErrsOK)
fpNetStats->outputErrors++;
IOSimpleLockUnlock(fLock);
fOutputStalled = true;
return false;
}
IOLog("AJZaurusUSB::USBTransmitPacket - Waiting %d-th time for output buffer\n", tryCount);
IOSleep(1);// sleep 1 second
        }
    fPipeOutBuff[poolIndx].m = packet;
    ++fDataCount;
    fOutputStalled = false;
    IOSimpleLockUnlock(fLock);
   
    // Start filling in the send buffer
    // AJ: modified to do CRC calculation and padding
    // -->
    fcs = CRC32_INITFCS;
    m = packet;// start with the first mbuf of the packet
    rTotal = 0;// running total
    do
    while(m)
        {  
            if (mbuf_len(m) == 0)// Ignore zero length mbufs
                continue;
            fcs = fcs_memcpy32(&(fPipeOutBuff[poolIndx].pipeOutBuffer[rTotal]), (unsigned char*) mbuf_data(m), mbuf_len(m), fcs);
            //bcopy(mtod(m, unsigned char *), &fPipeOutBuff[poolIndx].pipeOutBuffer[rTotal], mbuf_len(m));
            rTotal += mbuf_len(m);
           
        } while ((m = mbuf_next(m)) != 0);
            if (mbuf_len(m) > 0)// Ignore zero length mbufs
{
fcs = fcs_memcpy32(&(fPipeOutBuff[poolIndx].pipeOutBuffer[rTotal]), (unsigned char*) mbuf_data(m), mbuf_len(m), fcs);
rTotal += mbuf_len(m);
}
            m = mbuf_next(m);
        }
    if ((pad = new_pkt_length - rTotal - checksum_length) > 0)
        {
        // pad to required length less four (CRC), copy fcs and append pad byte if required
        fcs = fcs_pad32(&(fPipeOutBuff[poolIndx].pipeOutBuffer[rTotal]), pad, fcs);
        rTotal += pad;
        { // pad to required length less four (CRC), copy fcs and append pad byte if required
fcs = fcs_pad32(&(fPipeOutBuff[poolIndx].pipeOutBuffer[rTotal]), pad, fcs);
rTotal += pad;
        }
    fcs = ~fcs;
    if (fChecksum)
#if 0
    IOLog("AJZaurusUSB::USBTransmitPacket - length=%lu checksum=%08lx\n", rTotal, fcs);
#endif
    // <--
   
//    LogData(kUSBOut, rTotal, fPipeOutBuff[poolIndx].pipeOutBuffer);
   
    //fPipeOutBuff[poolIndx].m = packet;
    fPipeOutBuff[poolIndx].writeCompletionInfo.parameter = (void *)poolIndx;
    fPipeOutBuff[poolIndx].pipeOutMDP->setLength(rTotal);
    ior = fOutPipe->Write(fPipeOutBuff[poolIndx].pipeOutMDP,
 &(fPipeOutBuff[poolIndx].writeCompletionInfo));
    if (ior != kIOReturnSuccess)
        {
        //OSIncrementAtomic(&fSyncCount);
        IOLog("AJZaurusUSB::USBTransmitPacket - Write failed: ior=%d %s\n", ior, this->stringFromReturn(ior));
        if (ior == kIOUSBPipeStalled)
            {
            IOLog("AJZaurusUSB::USBTransmitPacket - Pipe stalled\n");
            //OSDecrementAtomic(&fSyncCount);
            fOutPipe->ClearPipeStall(true);  // reset and try again
            ior = fOutPipe->Write(fPipeOutBuff[poolIndx].pipeOutMDP,
 5000,
 &(fPipeOutBuff[poolIndx].writeCompletionInfo));
            if (ior != kIOReturnSuccess)
                {
                //OSIncrementAtomic(&fSyncCount);
                IOLog("AJZaurusUSB::USBTransmitPacket - Write really failed: %d %s\n", ior, this->stringFromReturn(ior));
                if(fOutputErrsOK)
                    fpNetStats->outputErrors++;
            }
        else
            { // other error
            IOSimpleLockLock(fLock);
            --fDataCount;
            fPipeOutBuff[poolIndx].m = NULL;
            IOSimpleLockUnlock(fLock);
            return false;
IOSimpleLockLock(fLock);
--fDataCount;
fPipeOutBuff[poolIndx].m = NULL;
IOSimpleLockUnlock(fLock);
return false;
            }
        }
   
        {
        IOLog("AJZaurusUSB::USBSetPacketFilter - DeviceRequest error for %d: %d %s\n", MER->bRequest, rc, this->stringFromReturn(rc));
        if (rc == kIOUSBPipeStalled)
            {
           
            // Clear the stall and try it once more
           
            fpDevice->GetPipeZero()->ClearPipeStall(true);
            rc = fpDevice->DeviceRequest(MER, &fMERCompletionInfo);
            if (rc != kIOReturnSuccess)
                {
                IOLog("AJZaurusUSB::USBSetPacketFilter - DeviceRequest for %d, error a second time: %d %s\n", MER->bRequest, rc, this->stringFromReturn(rc));
                IOFree(MER, sizeof(IOUSBDevRequest));
                return false;
                }
            { // Clear the stall and try it once more
fpDevice->GetPipeZero()->ClearPipeStall(true);
rc = fpDevice->DeviceRequest(MER, &fMERCompletionInfo);
if (rc != kIOReturnSuccess)
{
IOLog("AJZaurusUSB::USBSetPacketFilter - DeviceRequest for %d, error a second time: %d %s\n", MER->bRequest, rc, this->stringFromReturn(rc));
IOFree(MER, sizeof(IOUSBDevRequest));
return false;
}
            }
        }
   
    else
        IOLog("AJZaurusUSB::clearPipeStall - Pipe not stalled: status=%d\n", pipeStatus);
   
    // rewritten to prevent nasty issues when doing synchronous stuff here
    //rtn = thePipe->ClearPipeStall(true);
   
    return rtn;
   
}/* end clearPipeStall */
   
if(!fpDevice)
return;
if(fpDevice->GetDeviceStatus(&status) != kIOReturnSuccess)// try to get device status
{
        IOLog("AJZaurusUSB::resetDevice - could not get device status; needs to reset and reenumerate\n");
else
fpDevice->ReEnumerateDevice(0);
}
}/* end resetDevice */
/****************************************************************************************************/
else
{ // there is a comm pipe
#if 0
IOLog("AJZaurusUSB::allocateResources - comm pipe - myPacketSize=%u interval=%u pipe=%p\n", epReq.maxPacketSize, epReq.interval, fCommPipe);
IOLog("AJZaurusUSB::allocateResources - comm pipe - myPacketSize=%u interval=%u pipe=%p\n", epReq.maxPacketSize, epReq.interval, fCommPipe);
#endif
// Allocate Memory Descriptor Pointer with memory for the Comm pipe:
       
fCommPipeMDP = IOBufferMemoryDescriptor::withCapacity(COMM_BUFF_SIZE, kIODirectionIn);
if (!fCommPipeMDP)
return false;
       
fCommPipeMDP->setLength(COMM_BUFF_SIZE);
fCommPipeBuffer = (UInt8*)fCommPipeMDP->getBytesNoCopy();
// Allocate Memory Descriptor Pointer with memory for the Comm pipe:
fCommPipeMDP = IOBufferMemoryDescriptor::withCapacity(COMM_BUFF_SIZE, kIODirectionIn);
if (!fCommPipeMDP)
return false;
fCommPipeMDP->setLength(COMM_BUFF_SIZE);
fCommPipeBuffer = (UInt8*)fCommPipeMDP->getBytesNoCopy();
#if 0
IOLog("AJZaurusUSB::allocateResources - comm buffer %p\n", fCommPipeBuffer);
IOLog("AJZaurusUSB::allocateResources - comm buffer %p\n", fCommPipeBuffer);
#endif
}
    // Allocate Memory Descriptor Pointer with memory for the data-in bulk pipe:
   
fMax_Block_Size = 64*((fMax_Block_Size+(64-1))/64);// 64 is the Max Block Size we should read from the endpoint descriptor
    fPipeInMDP = IOBufferMemoryDescriptor::withCapacity(fMax_Block_Size, kIODirectionIn);
    if (!fPipeInMDP)
        return false;
        {
        if (fPipeOutBuff[i].pipeOutMDP)
            {
            fPipeOutBuff[i].pipeOutMDP->release();
            fPipeOutBuff[i].pipeOutMDP = NULL;
fPipeOutBuff[i].pipeOutMDP->release();
fPipeOutBuff[i].pipeOutMDP = NULL;
            }
        }
    if (fPipeInMDP)
        {
        fPipeInMDP->release();
        fPipeInMDP = NULL;
fPipeInMDP->release();
fPipeInMDP = NULL;
        }
    if (fCommPipeMDP)
        {
        fCommPipeMDP->release();
        fCommPipeMDP = NULL;
fCommPipeMDP->release();
fCommPipeMDP = NULL;
        }
   
}/* end releaseResources */
makefile
130130
131131
132132
133
133
134134
135135
136136
......
142142
143143
144144
145
145
146146
147147
148148
149
149
150150
151
151
152152
153153
154154
......
163163
164164
165165
166
167
168
169
170
171
166
167
168
169
170
171
172
172173
173
174
174175
175176
176
177
177178
178179
179
180
181
182
183
184
185
186
187
188
189
180
181
182
183
184
190185
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
186
187
188
189
190
206191
#
# use 'make enable-kdb' to enable debugging, reboot debug machine and 'make gdb'
#
# please refer to http://developer.apple.com/documentation/Darwin/Conceptual/KEXTConcept/KEXTConceptDebugger/hello_debugger.html
# please refer to http://developer.apple.com/mac/library/documentation/Darwin/Conceptual/KEXTConcept/KEXTConceptIntro/introduction.html
#
# same user id on debug machine
sudo:
@echo "*** reset sudo timeout ***"
@echo "first password is for authentication of debug ssh access, second one is for debug sudo"
ssh $(USER)@$(TARGET) sudo -v# update timestamp
ssh -t $(USER)@$(TARGET) sudo -v# update timestamp
# enable kernel debugging on debug machine (and switch a Core2 Duo to single processor mode)
enable-kdb: sudo
open http://developer.apple.com/documentation/Darwin/Conceptual/KEXTConcept/KEXTConceptDebugger/hello_debugger.html
open "http://developer.apple.com/mac/library/documentation/Darwin/Conceptual/KEXTConcept/KEXTConceptDebugger/debug_tutorial.html#//apple_ref/doc/uid/20002367-CHDIHFDI"
ssh $(USER)@$(TARGET) sh -c 'cd; cat >~/.ssh/authorized_keys' <~/.ssh/id_rsa.pub
ssh $(USER)@$(TARGET) sh -c 'cd; sudo nvram boot-args="cpus=1 debug=0x14e"'
ssh $(USER)@$(TARGET) sh -c 'cd; sudo nvram boot-args="debug=0xd4e kdp_match_name=firewire _panic_ip=1.2.3.4 cpus=1"'
@echo "*** reboot target machine to activate changes ***"
# disable kernel debugging on debug machine
@echo "next password is for authentication of debug ssh access; may also ask for sudo password on debug machine"
(cd pkg && tar czpf - AJZaurusUSB.kext) | ssh $(USER)@$(TARGET) sh -c 'cd; cd ~ && sudo rm -rf AJZaurusUSB.kext && tar xzf - && sudo chown -R root:wheel ~/AJZaurusUSB.kext && sudo chmod -R go-w ~/AJZaurusUSB.kext'
getsymtab: copy2target
@echo "*** create symbol files, fetch from debug machine ***"
@echo "next password is for authentication of debug ssh access"
ssh $(USER)@$(TARGET) sh -c 'cd; mkdir -p /tmp/AJZaurusUSB && sudo kextload -lvs /tmp/AJZaurusUSB ~/AJZaurusUSB.kext'
@mkdir -p symbols
ssh $(USER)@$(TARGET) sh -c 'cd; cd /tmp/AJZaurusUSB && tar czf - .' | (cd symbols && tar xvzf - -m)
getsymtab:
#@echo "*** create symbol files, fetch from debug machine ***"
#@echo "next password is for authentication of debug ssh access"
#ssh $(USER)@$(TARGET) sh -c 'cd; mkdir -p /tmp/AJZaurusUSB && sudo kextload -lvs /tmp/AJZaurusUSB ~/AJZaurusUSB.kext'
#@mkdir -p symbols
#ssh $(USER)@$(TARGET) sh -c 'cd; cd /tmp/AJZaurusUSB && tar czf - .' | (cd symbols && tar xvzf - -m)
loadremote: sudo
loadremote: copy2target
@echo "*** finally load/match driver on remote side ***"
@echo "next password is for authentication of debug ssh access"
ssh $(USER)@$(TARGET) sudo /bin/bash -c 'cd; kextload -m ~/AJZaurusUSB.kext'
ssh $(USER)@$(TARGET) /bin/bash -c 'cd; sudo kextload ~/AJZaurusUSB.kext; kextstat | fgrep AJZaurusUSB'
# launch a complete debugging session
gdb:
@echo "*** launch and attach debugger ***"
@( echo make getsymtab loadremote; \
echo add-symbol-file symbols/net.lucid-cake.driver.AJZaurusUSB.sym; \
echo add-symbol-file symbols/com.apple.iokit.IONetworkingFamily.sym; \
echo add-symbol-file symbols/com.apple.iokit.IOUSBFamily.sym; \
echo add-symbol-file symbols/com.apple.kpi.bsd.sym; \
echo add-symbol-file symbols/com.apple.kpi.iokit.sym; \
echo add-symbol-file symbols/com.apple.kpi.libkern.sym; \
echo add-symbol-file symbols/com.apple.kpi.mach.sym; \
echo add-symbol-file symbols/com.apple.kpi.unsupported.sym; \
gdb: getsymtab
@echo "*** launch and attach kernel debugger ***"
#open "/Volumes/KernelDebugKit/Kernel Debug Kit Read Me.html"
fwkdp&# run firewire KDP debugging proxy (unless already running)
@( echo source /Volumes/KernelDebugKit/kgmacros; \
echo target remote-kdp; \
echo shell echo; \
echo shell echo; \
echo shell echo "Please break on debug machine into debugger and press Return on this machine (often NMI or Power button)."; \
echo shell echo "If successful, a console message will be shown on the screen."; \
echo shell read WAIT; \
echo shell echo "Attaching..."; \
echo attach $(TARGET); \
: echo break 'net_lucid_cake_driver_AJZaurusUSB::start(IOService *)'; \
echo shell echo "Remotely loading and starting the driver..."; \
echo "shell ssh $(USER)@$(TARGET) sh -c 'cd; sudo kextload -m ~/AJZaurusUSB.kext' &"; \
echo shell echo "Continuing the kernel..."; \
echo shell echo "If successful, the clock in the Status bar will continue to run."; \
echo continue ) >prepare.gdb
gdb -arch $(ARCH) -x prepare.gdb /mach_kernel
echo kdp-reattach localhost; \
echo set kext-symbol-file-path pkg; \
echo add-kext pkg/AJZaurusUSB.kext; \
) >prepare.gdb
gdb -arch $(ARCH) -x prepare.gdb /Volumes/KernelDebugKit/mach_kernel

Archive Download the corresponding diff file

Branches

Tags