mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-15 16:05:10 +01:00
*Added new ehcmodules with better and more drives support on Hermes IOS (thx rodries)
*Fixed reset of the loader when loading game with IOS reload and disabled WiiTDB titles (Issue 1874) *Added new 'Inherit' or 'Use global' setting for game settings. If that option is set than the global setting is used for that option. (Issue 1842) *Fixed timeout timer on startup to count correctly. (Issue 1907) *Added two new video modes to force progressive video mode, 'FORCE PAL480p' and 'FORCE NTSC480p' (basically the same but oh well) (Issue 1902) *Added the new 'Return to' procedure for the d2x v4 IOS for Test purpose (didn't test it, need feedback on this one). The old method is used if this procedure fails. Please test it on problematic games (e.g. PoP). (Issue 1892)
This commit is contained in:
parent
0e7d37b18b
commit
e510233154
944
bin/ehcmodule_5.c
Normal file
944
bin/ehcmodule_5.c
Normal file
@ -0,0 +1,944 @@
|
|||||||
|
#define size_ehcmodule_5 26234
|
||||||
|
|
||||||
|
unsigned char ehcmodule_5[26234] __attribute__((aligned (32)))={
|
||||||
|
127, 69, 76, 70, 1, 2, 1, 97, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 40, 0, 0, 0, 1, 19, 112, 0, 0, 0, 0, 0, 52, 0, 0, 0,
|
||||||
|
0, 0, 0, 6, 6, 0, 52, 0, 32, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160,
|
||||||
|
0, 0, 0, 160, 0, 240, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 212, 0, 0, 0, 160, 0, 0, 0, 160, 0, 0, 0, 52, 0, 0, 0,
|
||||||
|
52, 0, 240, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 212, 0, 240, 0,
|
||||||
|
0, 0, 0, 64, 0, 0, 0, 0, 1, 0, 0, 1, 8, 19, 112, 0, 0, 19, 112, 0, 0, 0, 0, 90, 208, 0, 0, 90, 208, 0, 240, 0, 5, 0,
|
||||||
|
0, 0, 4, 0, 0, 0, 1, 0, 0, 91, 216, 19, 112, 96, 0, 19, 112, 96, 0, 0, 0, 10, 162, 0, 2, 153, 40, 0, 240, 0, 6, 0, 0,
|
||||||
|
0, 4, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 6, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 9, 19, 112, 0, 0, 0, 0, 0, 125, 0, 0, 0,
|
||||||
|
120, 0, 0, 0, 126, 0, 0, 48, 0, 0, 0, 0, 127, 19, 114, 247, 40, 227, 160, 0, 0, 227, 160, 16, 0, 229, 159, 49, 0, 225,
|
||||||
|
47, 255, 19, 229, 159, 192, 252, 229, 156, 192, 0, 225, 160, 0, 0, 231, 156, 193, 11, 225, 160, 0, 0, 225, 47, 255,
|
||||||
|
28, 225, 160, 0, 0, 225, 160, 0, 0, 227, 160, 176, 63, 234, 255, 255, 245, 225, 160, 0, 0, 225, 160, 0, 0, 227, 160,
|
||||||
|
176, 64, 234, 255, 255, 241, 227, 160, 0, 0, 238, 7, 15, 21, 225, 47, 255, 30, 225, 160, 0, 0, 225, 160, 0, 0, 225,
|
||||||
|
160, 0, 0, 227, 24, 0, 16, 10, 0, 0, 18, 227, 200, 128, 16, 227, 160, 32, 16, 229, 135, 32, 0, 225, 160, 0, 0, 225,
|
||||||
|
160, 32, 13, 225, 160, 0, 0, 229, 159, 208, 144, 225, 160, 0, 0, 233, 45, 95, 254, 225, 160, 0, 0, 235, 0, 0, 15, 232,
|
||||||
|
189, 95, 254, 225, 160, 0, 0, 225, 160, 208, 2, 227, 16, 0, 1, 10, 0, 0, 2, 225, 160, 0, 0, 227, 160, 0, 4, 235, 0,
|
||||||
|
0, 5, 227, 24, 0, 1, 10, 0, 0, 1, 229, 159, 240, 88, 225, 160, 0, 0, 229, 159, 240, 84, 225, 160, 0, 0, 229, 159, 240,
|
||||||
|
80, 225, 160, 0, 0, 229, 159, 32, 76, 225, 47, 255, 18, 225, 160, 0, 0, 238, 19, 15, 16, 225, 47, 255, 30, 225, 160,
|
||||||
|
0, 0, 225, 160, 0, 0, 238, 3, 15, 16, 225, 47, 255, 30, 225, 160, 0, 0, 225, 160, 0, 0, 69, 72, 67, 95, 67, 70, 71,
|
||||||
|
0, 18, 52, 0, 1, 0, 0, 0, 0, 19, 112, 16, 157, 19, 114, 195, 128, 19, 114, 249, 40, 255, 255, 30, 128, 255, 255, 30,
|
||||||
|
156, 255, 255, 29, 68, 19, 112, 13, 61, 225, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181, 0, 40,
|
||||||
|
2, 208, 16, 40, 2, 216, 4, 40, 0, 208, 7, 40, 1, 209, 19, 224, 7, 40, 16, 208, 12, 40, 17, 209, 14, 224, 11, 75, 8,
|
||||||
|
104, 24, 224, 11, 72, 7, 224, 9, 75, 7, 34, 1, 96, 26, 32, 0, 224, 4, 72, 6, 224, 2, 72, 6, 224, 0, 72, 6, 188, 2, 71,
|
||||||
|
8, 19, 112, 96, 48, 19, 112, 73, 29, 19, 112, 106, 200, 19, 112, 66, 25, 19, 112, 67, 97, 255, 255, 253, 102, 181, 112,
|
||||||
|
28, 12, 28, 5, 240, 5, 252, 105, 28, 6, 32, 1, 66, 64, 240, 5, 252, 88, 14, 43, 115, 35, 12, 43, 115, 99, 10, 43, 115,
|
||||||
|
163, 124, 34, 124, 99, 6, 18, 4, 27, 67, 19, 124, 162, 115, 229, 2, 18, 67, 19, 124, 226, 6, 45, 67, 19, 28, 32, 96,
|
||||||
|
29, 48, 12, 33, 4, 240, 5, 252, 88, 124, 35, 124, 96, 6, 27, 4, 0, 67, 24, 124, 163, 33, 4, 2, 27, 67, 24, 124, 227,
|
||||||
|
67, 24, 240, 5, 252, 75, 28, 48, 240, 5, 252, 48, 32, 0, 188, 112, 188, 2, 71, 8, 181, 8, 75, 12, 28, 1, 34, 32, 104,
|
||||||
|
24, 240, 5, 252, 81, 40, 0, 209, 13, 72, 9, 240, 5, 252, 40, 240, 4, 252, 99, 32, 200, 240, 0, 255, 33, 240, 4, 252,
|
||||||
|
104, 32, 200, 240, 0, 255, 28, 231, 244, 188, 8, 188, 2, 71, 8, 19, 112, 96, 48, 19, 112, 96, 84, 181, 8, 75, 4, 28,
|
||||||
|
1, 104, 24, 240, 5, 251, 252, 188, 8, 188, 1, 71, 0, 70, 192, 19, 112, 96, 48, 181, 240, 176, 139, 144, 4, 145, 5, 28,
|
||||||
|
8, 28, 17, 28, 23, 146, 7, 240, 5, 252, 8, 76, 129, 104, 35, 43, 0, 209, 0, 224, 241, 168, 9, 240, 3, 254, 8, 75, 126,
|
||||||
|
96, 24, 40, 0, 208, 4, 35, 128, 154, 9, 1, 27, 66, 154, 208, 4, 35, 1, 74, 122, 66, 91, 96, 19, 224, 224, 78, 121, 72,
|
||||||
|
122, 104, 51, 24, 26, 42, 0, 208, 104, 43, 0, 219, 102, 75, 116, 104, 26, 28, 81, 209, 98, 28, 53, 75, 112, 104, 48,
|
||||||
|
104, 28, 33, 31, 34, 16, 52, 31, 24, 18, 67, 140, 146, 2, 33, 16, 28, 34, 240, 3, 255, 166, 40, 0, 209, 0, 224, 195,
|
||||||
|
120, 35, 43, 67, 209, 11, 120, 99, 43, 73, 209, 8, 120, 163, 43, 83, 209, 5, 120, 227, 43, 79, 209, 2, 75, 103, 96,
|
||||||
|
51, 224, 8, 104, 43, 43, 0, 208, 2, 35, 0, 96, 43, 231, 218, 35, 1, 66, 91, 96, 43, 121, 98, 121, 163, 2, 18, 4, 27,
|
||||||
|
24, 211, 121, 34, 77, 95, 24, 155, 121, 226, 28, 40, 6, 18, 24, 155, 10, 219, 147, 3, 154, 3, 75, 91, 33, 0, 96, 26,
|
||||||
|
34, 128, 1, 18, 240, 5, 250, 143, 75, 84, 104, 26, 75, 85, 66, 154, 209, 30, 32, 7, 35, 0, 70, 132, 70, 102, 64, 30,
|
||||||
|
209, 4, 16, 218, 152, 2, 73, 82, 0, 146, 80, 80, 24, 226, 122, 18, 42, 0, 208, 10, 16, 218, 92, 168, 33, 1, 64, 177,
|
||||||
|
67, 8, 84, 168, 154, 2, 28, 16, 154, 3, 24, 128, 144, 2, 34, 128, 51, 1, 1, 210, 66, 147, 209, 227, 75, 63, 34, 31,
|
||||||
|
104, 27, 153, 5, 51, 31, 67, 147, 34, 128, 2, 18, 147, 3, 145, 2, 78, 60, 146, 6, 224, 97, 155, 4, 32, 15, 10, 93, 104,
|
||||||
|
51, 67, 133, 66, 157, 208, 63, 73, 56, 75, 57, 104, 10, 96, 53, 66, 154, 209, 33, 75, 57, 28, 40, 104, 28, 28, 33, 240,
|
||||||
|
5, 251, 33, 75, 55, 8, 193, 0, 138, 88, 210, 35, 0, 147, 1, 35, 7, 64, 24, 70, 140, 35, 0, 144, 0, 224, 9, 72, 47, 70,
|
||||||
|
97, 92, 64, 28, 1, 65, 25, 32, 1, 66, 8, 208, 0, 25, 18, 51, 1, 153, 0, 66, 139, 211, 242, 60, 1, 64, 44, 25, 21, 75,
|
||||||
|
34, 104, 28, 27, 100, 44, 16, 220, 10, 44, 16, 208, 9, 34, 128, 152, 3, 33, 0, 2, 18, 240, 5, 250, 34, 44, 0, 221, 8,
|
||||||
|
224, 0, 36, 16, 28, 40, 28, 33, 154, 3, 240, 3, 254, 255, 40, 0, 208, 29, 154, 4, 152, 6, 4, 209, 12, 73, 26, 67, 28,
|
||||||
|
60, 66, 187, 216, 0, 28, 28, 154, 3, 152, 2, 24, 137, 28, 34, 240, 5, 249, 198, 152, 2, 28, 33, 240, 5, 251, 28, 155,
|
||||||
|
2, 152, 4, 25, 27, 27, 63, 16, 164, 25, 0, 147, 2, 144, 4, 47, 0, 209, 155, 224, 5, 32, 128, 2, 0, 176, 11, 188, 240,
|
||||||
|
188, 2, 71, 8, 152, 5, 153, 7, 240, 5, 251, 39, 32, 0, 231, 245, 70, 192, 19, 112, 107, 88, 19, 112, 106, 208, 19, 112,
|
||||||
|
96, 24, 19, 112, 96, 12, 128, 0, 0, 1, 127, 255, 255, 255, 19, 112, 123, 128, 19, 112, 106, 212, 19, 112, 131, 128,
|
||||||
|
181, 56, 28, 12, 240, 5, 250, 214, 30, 5, 209, 38, 44, 0, 208, 36, 104, 34, 42, 0, 208, 33, 120, 17, 120, 83, 6, 9,
|
||||||
|
4, 27, 67, 11, 120, 145, 2, 9, 67, 11, 120, 209, 67, 11, 43, 6, 209, 21, 123, 17, 123, 83, 6, 9, 4, 27, 67, 11, 123,
|
||||||
|
145, 2, 9, 67, 11, 123, 209, 67, 11, 43, 122, 208, 2, 43, 136, 209, 7, 224, 2, 72, 5, 33, 21, 224, 1, 72, 4, 33, 20,
|
||||||
|
240, 4, 250, 238, 28, 40, 188, 56, 188, 2, 71, 8, 70, 192, 19, 112, 1, 153, 181, 240, 176, 145, 75, 206, 33, 128, 104,
|
||||||
|
24, 240, 5, 250, 97, 33, 32, 240, 5, 250, 144, 144, 8, 240, 0, 251, 131, 240, 5, 250, 211, 33, 120, 240, 5, 250, 140,
|
||||||
|
153, 8, 72, 199, 240, 5, 250, 120, 72, 198, 154, 8, 28, 1, 35, 0, 240, 5, 250, 72, 73, 196, 144, 9, 32, 205, 240, 4,
|
||||||
|
250, 109, 33, 0, 36, 1, 145, 7, 145, 11, 145, 6, 39, 0, 152, 8, 169, 15, 34, 0, 240, 5, 250, 122, 144, 14, 155, 14,
|
||||||
|
43, 0, 209, 246, 44, 0, 208, 2, 152, 9, 240, 5, 250, 67, 74, 185, 158, 15, 35, 0, 96, 19, 46, 0, 209, 87, 75, 183, 104,
|
||||||
|
27, 43, 0, 208, 5, 75, 182, 104, 27, 43, 0, 209, 1, 74, 181, 96, 19, 36, 0, 47, 0, 208, 222, 75, 178, 104, 27, 43, 0,
|
||||||
|
208, 218, 75, 175, 104, 27, 43, 0, 209, 214, 75, 175, 104, 27, 43, 0, 208, 9, 240, 3, 253, 88, 40, 0, 208, 5, 240, 3,
|
||||||
|
253, 84, 40, 0, 208, 1, 240, 3, 253, 80, 75, 168, 104, 27, 147, 4, 43, 0, 209, 36, 77, 167, 75, 167, 104, 42, 58, 1,
|
||||||
|
66, 154, 216, 30, 78, 159, 76, 165, 35, 1, 96, 51, 104, 32, 33, 1, 74, 164, 240, 3, 254, 26, 155, 4, 96, 51, 40, 0,
|
||||||
|
208, 9, 35, 128, 104, 42, 0, 155, 66, 154, 209, 4, 104, 35, 33, 128, 2, 9, 24, 91, 96, 35, 75, 154, 74, 156, 104, 25,
|
||||||
|
104, 18, 66, 145, 211, 1, 34, 0, 96, 26, 75, 145, 36, 0, 104, 27, 43, 0, 209, 153, 152, 9, 73, 138, 240, 5, 249, 219,
|
||||||
|
36, 1, 231, 147, 120, 51, 120, 112, 6, 27, 4, 0, 67, 24, 120, 179, 2, 27, 67, 24, 120, 243, 67, 24, 56, 1, 40, 6, 217,
|
||||||
|
0, 226, 152, 240, 4, 255, 69, 0, 10, 0, 73, 2, 151, 2, 151, 2, 151, 0, 7, 0, 92, 38, 1, 37, 1, 226, 150, 123, 51, 123,
|
||||||
|
116, 6, 27, 4, 36, 67, 28, 123, 179, 73, 119, 2, 27, 67, 28, 123, 243, 67, 28, 28, 32, 240, 5, 249, 53, 40, 0, 209,
|
||||||
|
11, 125, 51, 125, 117, 6, 27, 4, 45, 67, 29, 125, 179, 2, 27, 67, 29, 125, 243, 38, 1, 67, 29, 226, 122, 28, 32, 73,
|
||||||
|
120, 240, 5, 249, 35, 40, 0, 208, 0, 226, 108, 125, 51, 125, 117, 6, 27, 4, 45, 67, 29, 125, 179, 34, 1, 2, 27, 67,
|
||||||
|
29, 125, 243, 39, 0, 67, 29, 75, 103, 38, 1, 96, 26, 75, 103, 96, 24, 72, 110, 240, 0, 251, 48, 75, 109, 34, 4, 104,
|
||||||
|
27, 104, 155, 96, 154, 240, 1, 248, 39, 226, 87, 122, 50, 122, 115, 6, 18, 4, 27, 67, 19, 122, 178, 2, 18, 67, 19, 122,
|
||||||
|
242, 67, 19, 154, 6, 66, 154, 209, 0, 226, 70, 240, 1, 248, 46, 38, 1, 37, 0, 226, 68, 126, 51, 126, 116, 6, 27, 4,
|
||||||
|
36, 67, 28, 126, 179, 124, 50, 2, 27, 67, 28, 126, 243, 6, 18, 67, 28, 124, 115, 4, 27, 67, 19, 124, 178, 2, 18, 67,
|
||||||
|
19, 124, 242, 67, 26, 146, 4, 125, 51, 125, 117, 6, 27, 4, 45, 67, 29, 125, 179, 2, 27, 67, 29, 125, 243, 67, 29, 155,
|
||||||
|
6, 43, 0, 209, 16, 123, 51, 43, 0, 209, 13, 122, 50, 122, 115, 122, 176, 6, 18, 4, 27, 67, 19, 2, 0, 67, 3, 122, 240,
|
||||||
|
67, 24, 240, 1, 248, 10, 28, 6, 224, 0, 38, 0, 153, 4, 28, 32, 25, 73, 145, 10, 0, 201, 240, 5, 249, 164, 34, 0, 28,
|
||||||
|
37, 146, 5, 224, 7, 104, 40, 104, 105, 240, 5, 249, 156, 155, 5, 53, 8, 51, 1, 147, 5, 153, 5, 154, 10, 66, 145, 219,
|
||||||
|
243, 73, 48, 104, 11, 147, 5, 43, 0, 208, 0, 225, 213, 154, 15, 123, 16, 123, 83, 6, 0, 4, 27, 67, 3, 123, 144, 2, 0,
|
||||||
|
67, 3, 123, 208, 67, 3, 72, 51, 66, 131, 209, 0, 225, 38, 66, 131, 216, 31, 43, 6, 216, 11, 43, 5, 211, 0, 225, 180,
|
||||||
|
43, 1, 209, 0, 224, 159, 43, 0, 208, 119, 43, 2, 208, 0, 225, 70, 225, 171, 43, 27, 216, 6, 43, 26, 211, 0, 224, 172,
|
||||||
|
43, 12, 208, 0, 225, 61, 224, 156, 74, 37, 66, 147, 209, 0, 224, 167, 50, 1, 66, 147, 208, 0, 225, 52, 224, 246, 72,
|
||||||
|
34, 66, 131, 209, 0, 224, 226, 66, 131, 216, 68, 74, 32, 66, 147, 209, 0, 224, 182, 66, 147, 216, 8, 58, 12, 66, 147,
|
||||||
|
209, 0, 225, 17, 50, 2, 66, 147, 208, 0, 225, 31, 225, 20, 74, 25, 66, 147, 209, 0, 225, 22, 50, 1, 66, 147, 208, 0,
|
||||||
|
225, 22, 224, 169, 70, 192, 19, 112, 96, 48, 19, 112, 96, 109, 0, 152, 150, 128, 19, 112, 1, 65, 19, 112, 106, 240,
|
||||||
|
19, 112, 106, 196, 19, 112, 106, 200, 19, 112, 96, 20, 19, 112, 107, 84, 19, 114, 199, 32, 0, 0, 15, 254, 19, 112, 106,
|
||||||
|
192, 19, 112, 107, 128, 19, 114, 199, 36, 19, 112, 96, 121, 19, 112, 21, 69, 19, 112, 96, 60, 85, 77, 83, 3, 85, 77,
|
||||||
|
83, 1, 85, 77, 83, 130, 85, 77, 83, 16, 85, 77, 83, 128, 73, 196, 66, 139, 209, 0, 225, 63, 66, 139, 216, 7, 73, 194,
|
||||||
|
66, 139, 208, 119, 73, 194, 66, 139, 208, 0, 224, 219, 224, 220, 74, 192, 66, 147, 209, 0, 225, 36, 50, 1, 66, 147,
|
||||||
|
208, 0, 224, 210, 225, 20, 46, 0, 209, 0, 225, 55, 105, 162, 105, 35, 136, 21, 106, 34, 136, 27, 136, 16, 104, 34, 2,
|
||||||
|
25, 10, 27, 120, 18, 67, 11, 2, 41, 10, 45, 67, 13, 146, 5, 4, 45, 104, 162, 12, 45, 120, 18, 149, 0, 2, 5, 10, 0, 67,
|
||||||
|
40, 4, 0, 12, 0, 144, 1, 107, 32, 4, 27, 144, 2, 12, 27, 28, 48, 153, 5, 240, 1, 251, 44, 225, 3, 46, 0, 209, 0, 225,
|
||||||
|
17, 104, 35, 28, 48, 120, 25, 104, 163, 136, 26, 105, 35, 240, 1, 251, 12, 224, 247, 46, 0, 208, 0, 225, 5, 104, 35,
|
||||||
|
105, 34, 120, 24, 104, 163, 120, 25, 105, 163, 240, 0, 255, 46, 224, 235, 38, 0, 37, 1, 225, 4, 154, 11, 42, 0, 209,
|
||||||
|
1, 240, 0, 254, 203, 240, 3, 249, 119, 39, 0, 28, 5, 40, 0, 219, 3, 75, 151, 34, 1, 96, 26, 39, 1, 155, 15, 38, 1, 122,
|
||||||
|
25, 122, 90, 6, 9, 4, 18, 67, 10, 122, 153, 122, 219, 2, 9, 67, 10, 67, 19, 147, 6, 150, 11, 224, 230, 75, 141, 153,
|
||||||
|
5, 38, 1, 96, 25, 37, 0, 39, 0, 224, 223, 104, 35, 104, 26, 75, 138, 224, 97, 104, 35, 37, 0, 120, 222, 75, 136, 120,
|
||||||
|
27, 66, 179, 208, 16, 75, 135, 104, 27, 43, 0, 208, 12, 240, 3, 249, 40, 240, 0, 254, 206, 240, 0, 254, 180, 75, 129,
|
||||||
|
112, 30, 240, 0, 254, 146, 240, 3, 249, 62, 28, 5, 75, 126, 112, 30, 224, 165, 35, 1, 96, 11, 154, 5, 75, 121, 72, 124,
|
||||||
|
96, 26, 240, 0, 249, 164, 75, 123, 34, 4, 104, 27, 39, 0, 104, 155, 96, 154, 240, 0, 254, 154, 77, 120, 28, 40, 240,
|
||||||
|
3, 250, 74, 75, 119, 96, 24, 104, 35, 43, 0, 208, 1, 104, 42, 96, 26, 75, 116, 104, 29, 224, 135, 104, 35, 105, 34,
|
||||||
|
104, 24, 104, 163, 38, 1, 104, 25, 240, 3, 251, 254, 75, 111, 28, 5, 120, 26, 42, 0, 209, 0, 224, 148, 70, 105, 34,
|
||||||
|
23, 92, 81, 112, 25, 104, 35, 40, 0, 221, 2, 104, 25, 72, 105, 224, 1, 104, 25, 72, 105, 240, 1, 248, 24, 224, 133,
|
||||||
|
104, 35, 105, 34, 104, 24, 104, 163, 104, 25, 240, 3, 252, 134, 224, 97, 75, 100, 104, 26, 66, 81, 65, 74, 96, 26, 224,
|
||||||
|
105, 104, 35, 104, 26, 75, 85, 96, 26, 38, 1, 231, 106, 122, 17, 122, 83, 6, 9, 4, 27, 67, 11, 122, 145, 122, 210, 2,
|
||||||
|
9, 67, 11, 67, 26, 104, 37, 35, 0, 146, 6, 147, 13, 120, 42, 42, 95, 209, 26, 120, 106, 42, 68, 209, 23, 120, 170, 42,
|
||||||
|
86, 209, 20, 120, 234, 42, 68, 209, 17, 77, 82, 74, 69, 96, 43, 104, 227, 33, 1, 96, 17, 43, 4, 209, 6, 104, 161, 168,
|
||||||
|
13, 34, 4, 240, 4, 254, 134, 155, 13, 96, 43, 240, 3, 255, 12, 224, 17, 104, 227, 43, 4, 209, 4, 104, 161, 168, 13,
|
||||||
|
34, 4, 240, 4, 254, 121, 28, 40, 153, 13, 240, 3, 255, 67, 144, 7, 40, 0, 208, 46, 75, 53, 34, 1, 96, 26, 38, 1, 37,
|
||||||
|
0, 224, 43, 240, 3, 251, 66, 38, 1, 28, 5, 40, 0, 209, 42, 35, 1, 74, 60, 66, 91, 96, 19, 224, 37, 75, 45, 34, 1, 96,
|
||||||
|
26, 104, 35, 105, 33, 104, 24, 104, 163, 104, 26, 247, 255, 251, 159, 28, 5, 38, 1, 224, 24, 154, 7, 42, 0, 208, 18,
|
||||||
|
104, 35, 105, 34, 104, 25, 104, 163, 152, 7, 104, 27, 240, 4, 251, 17, 38, 1, 37, 0, 224, 10, 38, 1, 37, 6, 224, 6,
|
||||||
|
37, 1, 38, 1, 66, 109, 39, 1, 224, 2, 38, 1, 37, 1, 66, 109, 153, 4, 0, 203, 24, 228, 224, 7, 104, 32, 104, 97, 240,
|
||||||
|
4, 255, 141, 154, 4, 52, 8, 50, 1, 146, 4, 155, 4, 153, 10, 66, 139, 219, 243, 224, 9, 38, 1, 37, 1, 224, 1, 38, 1,
|
||||||
|
37, 6, 66, 109, 224, 2, 37, 0, 38, 1, 149, 6, 74, 12, 36, 0, 104, 19, 43, 0, 208, 4, 152, 9, 73, 23, 240, 4, 255, 31,
|
||||||
|
36, 1, 46, 0, 209, 0, 228, 213, 152, 15, 28, 41, 240, 4, 255, 117, 228, 208, 87, 70, 83, 2, 85, 77, 83, 131, 87, 70,
|
||||||
|
83, 1, 87, 70, 83, 3, 19, 112, 96, 20, 19, 112, 106, 196, 19, 112, 1, 12, 19, 112, 107, 56, 19, 112, 21, 69, 19, 112,
|
||||||
|
96, 60, 19, 114, 199, 32, 19, 114, 199, 36, 19, 112, 96, 16, 19, 112, 96, 137, 19, 112, 96, 164, 19, 112, 106, 204,
|
||||||
|
19, 112, 96, 12, 19, 112, 96, 24, 0, 152, 150, 128, 74, 3, 35, 128, 104, 17, 2, 27, 67, 11, 96, 19, 71, 112, 70, 192,
|
||||||
|
13, 4, 0, 204, 75, 2, 74, 3, 104, 25, 64, 10, 96, 26, 71, 112, 13, 4, 0, 204, 255, 255, 127, 255, 181, 16, 247, 255,
|
||||||
|
255, 243, 32, 128, 240, 3, 254, 16, 33, 32, 240, 4, 255, 1, 76, 9, 96, 32, 32, 4, 240, 4, 255, 12, 104, 33, 34, 0, 32,
|
||||||
|
4, 240, 4, 255, 47, 247, 255, 255, 215, 32, 4, 240, 4, 254, 216, 188, 16, 188, 1, 71, 0, 70, 192, 19, 112, 96, 32, 181,
|
||||||
|
16, 28, 4, 75, 15, 28, 8, 0, 137, 24, 9, 104, 26, 0, 73, 35, 1, 240, 4, 254, 171, 75, 12, 33, 16, 96, 24, 72, 11, 240,
|
||||||
|
3, 255, 18, 33, 16, 72, 10, 240, 3, 255, 25, 75, 10, 34, 55, 96, 28, 75, 9, 32, 4, 104, 27, 104, 155, 96, 154, 240,
|
||||||
|
4, 254, 179, 188, 16, 188, 1, 71, 0, 19, 112, 96, 32, 19, 112, 96, 28, 13, 128, 0, 56, 13, 128, 0, 60, 19, 112, 106,
|
||||||
|
224, 19, 112, 96, 60, 181, 112, 76, 21, 75, 21, 38, 2, 66, 118, 28, 33, 104, 24, 34, 0, 96, 38, 240, 4, 254, 191, 75,
|
||||||
|
18, 77, 18, 104, 27, 104, 154, 35, 0, 96, 147, 74, 17, 104, 40, 96, 19, 240, 4, 254, 134, 104, 40, 240, 4, 254, 205,
|
||||||
|
35, 1, 66, 91, 96, 43, 104, 35, 43, 0, 209, 3, 75, 11, 104, 27, 96, 35, 224, 0, 96, 38, 32, 4, 240, 4, 254, 125, 75,
|
||||||
|
2, 104, 24, 188, 112, 188, 2, 71, 8, 19, 112, 106, 216, 19, 112, 96, 32, 19, 112, 96, 60, 19, 112, 96, 28, 19, 112,
|
||||||
|
106, 224, 19, 112, 106, 220, 75, 2, 34, 0, 96, 24, 75, 2, 96, 26, 71, 112, 19, 112, 106, 228, 19, 112, 106, 224, 181,
|
||||||
|
248, 76, 34, 38, 16, 104, 35, 77, 33, 67, 179, 96, 35, 104, 43, 73, 32, 104, 154, 121, 19, 121, 87, 6, 27, 4, 63, 67,
|
||||||
|
31, 121, 147, 2, 27, 67, 31, 121, 211, 67, 31, 104, 11, 43, 0, 208, 18, 28, 56, 240, 0, 248, 56, 40, 0, 220, 20, 74,
|
||||||
|
22, 35, 0, 96, 19, 75, 22, 96, 24, 32, 4, 240, 4, 254, 66, 104, 43, 34, 55, 104, 155, 64, 23, 96, 95, 224, 22, 75, 17,
|
||||||
|
104, 27, 43, 0, 208, 8, 28, 56, 240, 0, 248, 33, 104, 43, 34, 55, 104, 155, 64, 23, 96, 95, 224, 2, 35, 55, 64, 31,
|
||||||
|
96, 87, 104, 35, 67, 51, 96, 35, 75, 9, 104, 26, 67, 22, 96, 30, 32, 0, 188, 248, 188, 2, 71, 8, 70, 192, 13, 128, 0,
|
||||||
|
60, 19, 112, 96, 60, 19, 112, 106, 224, 19, 112, 106, 220, 19, 112, 106, 228, 13, 128, 0, 56, 71, 24, 70, 192, 181,
|
||||||
|
112, 28, 12, 28, 5, 240, 4, 254, 67, 28, 6, 32, 1, 66, 64, 240, 4, 254, 50, 104, 34, 75, 17, 66, 154, 209, 25, 75, 16,
|
||||||
|
73, 17, 34, 1, 67, 19, 96, 75, 28, 32, 34, 8, 240, 4, 252, 219, 28, 32, 27, 100, 8, 164, 33, 8, 60, 2, 240, 4, 254,
|
||||||
|
54, 2, 36, 35, 234, 10, 36, 6, 27, 67, 35, 96, 43, 28, 40, 33, 4, 240, 4, 254, 44, 28, 48, 240, 4, 254, 17, 188, 112,
|
||||||
|
188, 1, 71, 0, 230, 0, 1, 112, 19, 112, 4, 153, 19, 112, 96, 36, 181, 56, 28, 4, 240, 4, 253, 202, 44, 38, 208, 72,
|
||||||
|
44, 38, 216, 5, 44, 36, 208, 9, 44, 37, 208, 0, 224, 169, 224, 14, 44, 57, 208, 112, 44, 60, 208, 0, 224, 163, 224,
|
||||||
|
110, 73, 83, 75, 84, 72, 84, 96, 75, 34, 8, 240, 4, 252, 163, 72, 82, 224, 150, 72, 82, 73, 82, 247, 255, 255, 171,
|
||||||
|
76, 77, 75, 81, 77, 82, 96, 99, 34, 8, 28, 40, 28, 33, 240, 4, 252, 148, 28, 40, 33, 8, 240, 4, 253, 242, 75, 77, 77,
|
||||||
|
78, 96, 99, 34, 8, 28, 40, 28, 33, 240, 4, 252, 136, 28, 40, 33, 8, 240, 4, 253, 230, 75, 73, 77, 74, 96, 99, 34, 8,
|
||||||
|
28, 33, 28, 40, 240, 4, 252, 124, 28, 40, 33, 8, 240, 4, 253, 218, 75, 59, 72, 69, 96, 99, 28, 33, 34, 8, 240, 4, 252,
|
||||||
|
113, 72, 66, 224, 100, 72, 66, 73, 66, 247, 255, 255, 121, 76, 52, 75, 65, 77, 57, 96, 99, 34, 8, 28, 40, 28, 33, 240,
|
||||||
|
4, 252, 98, 28, 40, 33, 8, 240, 4, 253, 192, 75, 60, 77, 53, 96, 99, 34, 8, 28, 40, 28, 33, 240, 4, 252, 86, 28, 40,
|
||||||
|
33, 8, 240, 4, 253, 180, 75, 55, 77, 49, 96, 99, 34, 8, 28, 33, 28, 40, 240, 4, 252, 74, 28, 40, 33, 8, 240, 4, 253,
|
||||||
|
168, 75, 34, 72, 50, 96, 99, 28, 33, 34, 8, 240, 4, 252, 63, 72, 47, 224, 50, 72, 47, 224, 0, 72, 47, 73, 47, 247, 255,
|
||||||
|
255, 69, 76, 26, 75, 46, 77, 31, 96, 99, 34, 8, 28, 40, 28, 33, 240, 4, 252, 46, 28, 40, 33, 8, 240, 4, 253, 140, 75,
|
||||||
|
41, 77, 27, 96, 99, 34, 8, 28, 40, 28, 33, 240, 4, 252, 34, 28, 40, 33, 8, 240, 4, 253, 128, 75, 36, 77, 23, 96, 99,
|
||||||
|
34, 8, 28, 33, 28, 40, 240, 4, 252, 22, 28, 40, 33, 8, 240, 4, 253, 116, 75, 8, 72, 31, 96, 99, 28, 33, 34, 8, 240,
|
||||||
|
4, 252, 11, 72, 28, 33, 8, 240, 4, 253, 105, 32, 0, 188, 56, 188, 2, 71, 8, 70, 192, 19, 112, 96, 36, 19, 112, 0, 96,
|
||||||
|
255, 255, 30, 120, 32, 32, 93, 232, 32, 32, 64, 140, 255, 255, 31, 112, 19, 112, 0, 188, 255, 255, 31, 140, 19, 112,
|
||||||
|
0, 196, 255, 255, 30, 52, 19, 112, 0, 204, 255, 255, 31, 104, 32, 32, 91, 20, 32, 32, 62, 108, 255, 255, 30, 176, 255,
|
||||||
|
255, 30, 204, 255, 255, 29, 116, 255, 255, 30, 168, 32, 32, 94, 132, 32, 32, 93, 148, 32, 32, 63, 96, 255, 255, 33,
|
||||||
|
48, 255, 255, 33, 76, 255, 255, 31, 244, 255, 255, 33, 40, 181, 56, 77, 11, 35, 0, 104, 42, 73, 10, 240, 4, 252, 201,
|
||||||
|
76, 10, 73, 10, 34, 0, 96, 32, 104, 40, 240, 4, 253, 4, 104, 32, 240, 4, 252, 211, 104, 32, 240, 4, 253, 26, 188, 56,
|
||||||
|
188, 1, 71, 0, 70, 192, 19, 112, 96, 44, 0, 152, 150, 128, 19, 112, 96, 52, 19, 112, 106, 232, 181, 8, 1, 67, 26, 27,
|
||||||
|
0, 155, 24, 24, 0, 192, 247, 255, 255, 216, 188, 8, 188, 1, 71, 0, 0, 0, 181, 0, 74, 5, 2, 192, 104, 19, 104, 17, 26,
|
||||||
|
201, 213, 0, 104, 19, 66, 129, 217, 249, 188, 1, 71, 0, 13, 128, 0, 16, 181, 8, 75, 24, 120, 26, 30, 83, 65, 154, 75,
|
||||||
|
23, 96, 26, 240, 3, 252, 204, 75, 22, 33, 4, 96, 24, 28, 24, 240, 4, 252, 225, 240, 3, 252, 206, 34, 0, 28, 1, 72, 18,
|
||||||
|
240, 3, 253, 3, 33, 160, 2, 73, 72, 16, 240, 4, 252, 201, 75, 16, 33, 128, 96, 24, 240, 4, 252, 122, 33, 32, 240, 4,
|
||||||
|
252, 169, 75, 13, 96, 24, 240, 3, 251, 37, 40, 0, 219, 3, 247, 255, 250, 7, 32, 0, 224, 1, 32, 1, 66, 64, 188, 8, 188,
|
||||||
|
2, 71, 8, 19, 112, 1, 12, 19, 112, 107, 80, 19, 114, 195, 128, 19, 112, 14, 77, 19, 113, 131, 128, 19, 112, 96, 48,
|
||||||
|
19, 112, 96, 44, 181, 240, 7, 65, 213, 27, 34, 128, 78, 14, 77, 15, 76, 15, 35, 0, 1, 146, 104, 49, 0, 152, 104, 137,
|
||||||
|
104, 47, 49, 68, 24, 9, 104, 8, 66, 187, 209, 5, 7, 193, 212, 7, 73, 9, 32, 2, 96, 8, 224, 3, 64, 32, 40, 3, 209, 0,
|
||||||
|
96, 10, 51, 1, 43, 4, 209, 233, 188, 240, 188, 1, 71, 0, 19, 112, 96, 60, 19, 112, 107, 80, 0, 0, 32, 3, 19, 112, 107,
|
||||||
|
84, 181, 240, 176, 131, 147, 1, 155, 8, 76, 14, 0, 91, 104, 38, 28, 13, 28, 23, 147, 0, 32, 10, 247, 255, 255, 79, 104,
|
||||||
|
43, 154, 1, 64, 59, 66, 147, 208, 9, 104, 35, 27, 155, 213, 0, 104, 38, 154, 0, 66, 147, 211, 240, 32, 2, 66, 64, 224,
|
||||||
|
0, 32, 0, 176, 3, 188, 240, 188, 2, 71, 8, 70, 192, 13, 128, 0, 16, 181, 56, 28, 4, 240, 3, 251, 27, 33, 0, 28, 5, 34,
|
||||||
|
96, 28, 32, 240, 4, 251, 64, 35, 64, 96, 163, 35, 128, 4, 91, 99, 101, 96, 35, 96, 99, 188, 56, 188, 1, 71, 0, 181,
|
||||||
|
16, 75, 12, 36, 0, 104, 27, 108, 26, 42, 7, 220, 13, 73, 10, 104, 12, 0, 228, 24, 164, 0, 97, 25, 12, 106, 25, 1, 100,
|
||||||
|
25, 12, 50, 1, 100, 26, 28, 32, 247, 255, 255, 215, 28, 32, 188, 16, 188, 2, 71, 8, 70, 192, 19, 112, 96, 60, 19, 112,
|
||||||
|
107, 64, 181, 240, 28, 4, 176, 133, 28, 8, 28, 14, 147, 3, 28, 23, 240, 4, 250, 147, 35, 0, 98, 35, 5, 53, 35, 128,
|
||||||
|
13, 45, 1, 91, 27, 93, 96, 224, 66, 175, 210, 1, 28, 61, 224, 49, 32, 128, 1, 64, 24, 54, 11, 54, 3, 54, 150, 2, 33,
|
||||||
|
1, 28, 38, 54, 16, 145, 1, 224, 20, 152, 2, 240, 4, 250, 121, 34, 0, 198, 1, 97, 50, 155, 2, 33, 128, 28, 24, 35, 128,
|
||||||
|
1, 91, 1, 73, 24, 192, 24, 109, 144, 2, 66, 189, 211, 0, 28, 61, 154, 1, 50, 1, 146, 1, 66, 189, 210, 8, 152, 1, 33,
|
||||||
|
0, 15, 195, 34, 4, 66, 130, 65, 75, 6, 27, 43, 0, 209, 223, 66, 189, 208, 4, 28, 40, 153, 10, 240, 4, 251, 194, 26,
|
||||||
|
109, 155, 3, 4, 40, 67, 24, 240, 4, 250, 80, 35, 128, 4, 91, 96, 160, 100, 37, 96, 35, 96, 99, 176, 5, 28, 40, 188,
|
||||||
|
240, 188, 2, 71, 8, 0, 0, 181, 240, 176, 139, 28, 5, 247, 255, 255, 133, 28, 6, 32, 0, 46, 0, 209, 0, 224, 145, 99,
|
||||||
|
245, 105, 42, 126, 107, 126, 47, 97, 104, 146, 3, 147, 7, 47, 0, 209, 25, 35, 8, 147, 0, 35, 160, 104, 105, 34, 8, 0,
|
||||||
|
155, 28, 48, 247, 255, 255, 140, 247, 255, 255, 108, 28, 4, 28, 56, 44, 0, 208, 121, 107, 96, 99, 229, 240, 4, 250,
|
||||||
|
30, 154, 3, 96, 48, 99, 180, 42, 0, 208, 4, 79, 58, 224, 3, 28, 52, 39, 128, 224, 0, 79, 56, 104, 235, 154, 7, 147,
|
||||||
|
4, 42, 0, 208, 2, 35, 128, 0, 91, 67, 31, 105, 235, 150, 9, 5, 91, 13, 91, 147, 5, 154, 5, 35, 128, 4, 91, 58, 1, 147,
|
||||||
|
6, 146, 8, 155, 5, 154, 3, 147, 0, 28, 32, 28, 59, 153, 4, 247, 255, 255, 92, 154, 3, 155, 4, 26, 18, 146, 3, 154, 7,
|
||||||
|
24, 27, 147, 4, 42, 0, 208, 1, 155, 6, 96, 99, 154, 8, 155, 5, 24, 128, 66, 3, 209, 2, 34, 128, 6, 18, 24, 191, 155,
|
||||||
|
3, 43, 0, 221, 11, 247, 255, 255, 38, 30, 6, 208, 52, 107, 112, 99, 245, 240, 4, 249, 218, 99, 166, 96, 32, 28, 52,
|
||||||
|
231, 213, 35, 128, 4, 91, 96, 99, 105, 43, 158, 9, 148, 3, 43, 0, 208, 29, 126, 42, 146, 4, 42, 0, 209, 25, 247, 255,
|
||||||
|
255, 14, 28, 4, 32, 0, 44, 0, 208, 27, 107, 96, 99, 229, 240, 4, 249, 192, 155, 3, 34, 128, 96, 24, 99, 156, 35, 128,
|
||||||
|
0, 91, 6, 18, 64, 123, 67, 19, 154, 4, 28, 32, 146, 0, 33, 0, 34, 0, 247, 255, 255, 20, 104, 162, 35, 128, 4, 27, 67,
|
||||||
|
19, 96, 163, 28, 48, 224, 0, 32, 0, 176, 11, 188, 240, 188, 2, 71, 8, 128, 0, 0, 128, 128, 0, 1, 128, 181, 56, 76, 19,
|
||||||
|
37, 32, 104, 35, 104, 155, 120, 25, 120, 90, 6, 9, 4, 18, 67, 10, 120, 153, 120, 219, 2, 9, 67, 10, 67, 19, 224, 18,
|
||||||
|
104, 34, 67, 171, 104, 146, 32, 10, 96, 19, 247, 255, 253, 243, 104, 35, 104, 155, 120, 25, 120, 90, 6, 9, 4, 18, 67,
|
||||||
|
10, 120, 153, 120, 219, 2, 9, 67, 10, 67, 19, 66, 29, 209, 234, 188, 56, 188, 1, 71, 0, 19, 112, 96, 60, 181, 56, 76,
|
||||||
|
19, 37, 32, 104, 35, 104, 155, 120, 25, 120, 90, 6, 9, 4, 18, 67, 10, 120, 153, 120, 219, 2, 9, 67, 10, 67, 19, 224,
|
||||||
|
18, 104, 34, 67, 43, 104, 146, 32, 10, 96, 19, 247, 255, 253, 201, 104, 35, 104, 155, 120, 25, 120, 90, 6, 9, 4, 18,
|
||||||
|
67, 10, 120, 153, 120, 219, 2, 9, 67, 10, 67, 19, 66, 29, 208, 234, 188, 56, 188, 1, 71, 0, 19, 112, 96, 60, 181, 248,
|
||||||
|
28, 12, 40, 0, 209, 33, 77, 28, 76, 29, 79, 29, 38, 0, 104, 43, 104, 155, 126, 25, 126, 90, 6, 9, 4, 18, 67, 10, 126,
|
||||||
|
153, 126, 219, 2, 9, 67, 10, 67, 19, 105, 34, 108, 82, 66, 147, 211, 6, 105, 98, 108, 82, 66, 147, 216, 2, 247, 255,
|
||||||
|
255, 142, 224, 25, 32, 10, 54, 1, 247, 255, 253, 147, 66, 190, 209, 226, 224, 18, 40, 1, 209, 16, 224, 6, 32, 10, 54,
|
||||||
|
1, 247, 255, 253, 137, 66, 190, 209, 3, 224, 8, 77, 6, 79, 8, 38, 0, 104, 43, 104, 155, 105, 154, 108, 99, 66, 154,
|
||||||
|
208, 239, 32, 0, 188, 248, 188, 2, 71, 8, 70, 192, 19, 112, 96, 60, 19, 114, 195, 160, 0, 0, 19, 136, 181, 0, 7, 67,
|
||||||
|
213, 21, 75, 12, 104, 27, 104, 154, 75, 11, 108, 81, 64, 11, 43, 3, 209, 2, 35, 128, 1, 155, 100, 83, 75, 6, 104, 27,
|
||||||
|
104, 154, 75, 6, 108, 145, 64, 11, 43, 3, 209, 2, 35, 128, 1, 155, 100, 147, 188, 1, 71, 0, 70, 192, 19, 112, 96, 60,
|
||||||
|
0, 0, 32, 3, 181, 16, 75, 19, 28, 4, 104, 27, 52, 16, 104, 155, 0, 164, 25, 28, 34, 128, 104, 99, 1, 146, 66, 19, 209,
|
||||||
|
0, 64, 83, 34, 46, 67, 147, 96, 99, 32, 5, 247, 255, 253, 106, 34, 128, 104, 99, 1, 146, 66, 19, 208, 0, 64, 83, 34,
|
||||||
|
46, 67, 147, 96, 99, 32, 5, 247, 255, 253, 94, 75, 4, 32, 5, 96, 99, 247, 255, 253, 89, 188, 16, 188, 1, 71, 0, 19,
|
||||||
|
112, 96, 60, 0, 0, 24, 1, 181, 240, 176, 131, 75, 36, 28, 5, 104, 27, 53, 16, 104, 155, 0, 173, 25, 93, 104, 107, 74,
|
||||||
|
33, 29, 44, 64, 26, 38, 4, 42, 1, 208, 4, 4, 154, 213, 51, 247, 255, 255, 192, 224, 48, 39, 136, 1, 127, 34, 4, 67,
|
||||||
|
147, 67, 59, 96, 35, 32, 60, 247, 255, 253, 40, 104, 35, 74, 24, 32, 50, 64, 19, 96, 35, 247, 255, 253, 33, 75, 22,
|
||||||
|
34, 128, 147, 0, 28, 32, 28, 33, 0, 82, 35, 0, 247, 255, 253, 156, 40, 0, 208, 2, 104, 107, 72, 17, 224, 20, 104, 35,
|
||||||
|
34, 4, 66, 26, 209, 16, 62, 1, 46, 0, 209, 220, 34, 128, 1, 146, 67, 19, 33, 42, 67, 139, 96, 107, 32, 10, 96, 106,
|
||||||
|
247, 255, 253, 2, 72, 8, 224, 1, 32, 1, 66, 64, 176, 3, 188, 240, 188, 2, 71, 8, 19, 112, 96, 60, 0, 0, 32, 1, 255,
|
||||||
|
255, 254, 213, 0, 0, 19, 136, 255, 255, 248, 48, 255, 255, 251, 161, 181, 16, 75, 20, 28, 4, 104, 27, 52, 16, 104, 155,
|
||||||
|
0, 164, 25, 28, 34, 128, 104, 99, 1, 146, 66, 19, 209, 0, 64, 83, 34, 46, 67, 147, 96, 99, 32, 5, 247, 255, 252, 230,
|
||||||
|
34, 128, 104, 99, 1, 146, 66, 19, 208, 0, 64, 83, 34, 46, 67, 147, 96, 99, 32, 5, 247, 255, 252, 218, 75, 5, 32, 60,
|
||||||
|
96, 99, 247, 255, 252, 213, 32, 1, 188, 16, 188, 2, 71, 8, 70, 192, 19, 112, 96, 60, 0, 0, 24, 1, 32, 0, 71, 112, 75,
|
||||||
|
5, 48, 16, 104, 27, 0, 128, 104, 155, 24, 24, 35, 128, 1, 155, 96, 67, 32, 0, 71, 112, 70, 192, 19, 112, 96, 60, 74,
|
||||||
|
5, 32, 0, 104, 19, 104, 153, 35, 128, 1, 155, 100, 75, 104, 18, 104, 146, 100, 147, 71, 112, 70, 192, 19, 112, 96, 60,
|
||||||
|
181, 0, 75, 10, 104, 27, 104, 154, 35, 128, 108, 81, 1, 155, 66, 25, 209, 0, 100, 83, 75, 5, 104, 27, 104, 154, 35,
|
||||||
|
128, 108, 145, 1, 155, 66, 25, 209, 0, 100, 147, 32, 0, 188, 2, 71, 8, 19, 112, 96, 60, 75, 6, 33, 0, 104, 26, 35, 1,
|
||||||
|
66, 91, 28, 16, 103, 17, 103, 147, 48, 152, 50, 160, 96, 1, 96, 19, 71, 112, 70, 192, 19, 112, 96, 60, 75, 6, 120, 27,
|
||||||
|
30, 90, 65, 147, 74, 5, 0, 152, 96, 19, 74, 5, 24, 195, 0, 219, 104, 16, 51, 88, 24, 192, 71, 112, 19, 112, 1, 12, 19,
|
||||||
|
112, 107, 80, 19, 112, 96, 60, 181, 16, 73, 19, 120, 9, 30, 72, 65, 129, 72, 18, 0, 140, 96, 1, 72, 17, 24, 97, 104,
|
||||||
|
0, 0, 201, 24, 64, 111, 4, 33, 0, 44, 0, 208, 16, 128, 25, 128, 89, 28, 1, 49, 96, 136, 8, 4, 0, 10, 4, 14, 0, 67, 32,
|
||||||
|
128, 152, 136, 73, 4, 9, 10, 8, 14, 9, 67, 1, 128, 217, 33, 1, 32, 0, 112, 17, 188, 16, 188, 2, 71, 8, 70, 192, 19,
|
||||||
|
112, 1, 12, 19, 112, 107, 80, 19, 112, 96, 60, 181, 0, 28, 3, 224, 8, 120, 90, 58, 4, 6, 18, 14, 18, 42, 1, 217, 4,
|
||||||
|
120, 26, 26, 137, 24, 155, 41, 0, 209, 244, 26, 24, 188, 2, 71, 8, 181, 240, 176, 133, 124, 130, 124, 195, 6, 18, 4,
|
||||||
|
27, 67, 19, 125, 2, 28, 5, 2, 18, 67, 19, 125, 66, 67, 26, 208, 103, 34, 0, 146, 3, 146, 1, 224, 83, 6, 36, 4, 9, 2,
|
||||||
|
18, 67, 12, 67, 20, 158, 3, 67, 35, 25, 156, 122, 98, 122, 163, 6, 18, 4, 27, 67, 19, 122, 226, 2, 18, 67, 19, 123,
|
||||||
|
34, 67, 26, 208, 58, 39, 0, 151, 2, 28, 46, 224, 36, 6, 0, 4, 9, 2, 18, 67, 8, 67, 16, 67, 3, 25, 221, 123, 170, 123,
|
||||||
|
235, 6, 18, 4, 27, 67, 19, 124, 42, 124, 104, 2, 18, 67, 19, 67, 24, 208, 1, 240, 2, 255, 250, 122, 106, 122, 171, 6,
|
||||||
|
18, 4, 27, 67, 19, 122, 234, 123, 40, 2, 18, 67, 19, 67, 24, 208, 1, 240, 2, 255, 237, 154, 2, 55, 18, 50, 1, 146, 2,
|
||||||
|
121, 35, 157, 2, 70, 156, 122, 96, 122, 161, 122, 226, 123, 35, 69, 101, 219, 209, 28, 53, 6, 6, 4, 8, 67, 48, 2, 18,
|
||||||
|
67, 16, 67, 24, 240, 2, 255, 215, 158, 1, 154, 3, 54, 1, 50, 13, 150, 1, 146, 3, 124, 104, 158, 1, 124, 172, 124, 233,
|
||||||
|
125, 42, 125, 107, 66, 134, 219, 163, 6, 36, 4, 8, 67, 32, 2, 18, 67, 16, 67, 24, 240, 2, 255, 193, 176, 5, 188, 240,
|
||||||
|
188, 1, 71, 0, 0, 0, 181, 248, 30, 5, 209, 4, 75, 28, 34, 48, 112, 26, 112, 93, 224, 47, 76, 26, 28, 46, 28, 48, 33,
|
||||||
|
10, 240, 4, 248, 128, 28, 48, 28, 15, 33, 10, 240, 4, 248, 119, 23, 251, 24, 255, 64, 95, 55, 48, 75, 20, 112, 39, 60,
|
||||||
|
1, 28, 6, 66, 156, 209, 236, 75, 15, 34, 0, 118, 154, 45, 0, 218, 2, 34, 45, 112, 26, 34, 1, 35, 16, 72, 10, 224, 0,
|
||||||
|
51, 1, 92, 193, 41, 48, 208, 251, 66, 72, 65, 65, 26, 91, 73, 6, 224, 2, 84, 136, 51, 1, 50, 1, 92, 200, 40, 0, 209,
|
||||||
|
249, 84, 136, 188, 248, 188, 1, 71, 0, 70, 192, 19, 114, 197, 96, 19, 114, 197, 121, 19, 114, 197, 111, 181, 248, 30,
|
||||||
|
4, 209, 4, 75, 24, 34, 48, 112, 26, 112, 92, 224, 40, 77, 22, 28, 47, 63, 10, 28, 32, 33, 10, 240, 4, 248, 23, 28, 32,
|
||||||
|
28, 14, 33, 10, 240, 4, 248, 30, 54, 48, 112, 46, 61, 1, 28, 4, 66, 189, 209, 240, 74, 12, 35, 0, 118, 147, 28, 17,
|
||||||
|
35, 16, 224, 0, 51, 1, 92, 202, 42, 48, 208, 251, 66, 81, 65, 74, 26, 155, 73, 6, 34, 0, 224, 2, 84, 136, 51, 1, 50,
|
||||||
|
1, 92, 200, 40, 0, 209, 249, 84, 136, 188, 248, 188, 1, 71, 0, 19, 114, 197, 96, 19, 114, 197, 121, 181, 16, 40, 0,
|
||||||
|
209, 4, 75, 24, 34, 48, 112, 26, 112, 88, 224, 40, 75, 22, 33, 15, 28, 28, 60, 8, 28, 10, 64, 2, 9, 0, 42, 9, 221, 0,
|
||||||
|
50, 7, 50, 48, 112, 26, 59, 1, 66, 163, 209, 244, 74, 14, 35, 0, 118, 19, 35, 48, 112, 19, 35, 120, 112, 83, 35, 16,
|
||||||
|
224, 0, 51, 1, 92, 209, 41, 48, 208, 251, 66, 74, 65, 74, 26, 155, 73, 6, 34, 2, 224, 2, 84, 136, 51, 1, 50, 1, 92,
|
||||||
|
200, 40, 0, 209, 249, 84, 136, 188, 16, 188, 1, 71, 0, 19, 114, 197, 96, 19, 114, 197, 119, 180, 15, 181, 240, 176,
|
||||||
|
133, 171, 10, 203, 64, 34, 128, 1, 146, 169, 3, 128, 10, 147, 2, 36, 0, 77, 46, 79, 46, 224, 81, 28, 114, 146, 1, 43,
|
||||||
|
37, 208, 12, 70, 106, 115, 19, 168, 3, 240, 3, 255, 41, 25, 4, 158, 1, 66, 172, 220, 68, 168, 3, 240, 3, 255, 222, 224,
|
||||||
|
64, 120, 115, 43, 115, 208, 46, 43, 115, 216, 4, 43, 100, 208, 7, 43, 105, 209, 53, 224, 4, 43, 117, 208, 9, 43, 120,
|
||||||
|
209, 48, 224, 20, 155, 2, 29, 26, 146, 2, 104, 24, 247, 255, 255, 26, 224, 19, 155, 2, 29, 26, 146, 2, 104, 24, 247,
|
||||||
|
255, 255, 85, 28, 56, 240, 3, 255, 2, 25, 4, 28, 56, 66, 172, 220, 27, 224, 24, 155, 2, 29, 26, 146, 2, 104, 24, 247,
|
||||||
|
255, 255, 127, 72, 16, 240, 3, 254, 244, 25, 4, 66, 172, 220, 14, 72, 13, 224, 10, 155, 2, 29, 26, 146, 2, 104, 30,
|
||||||
|
28, 48, 240, 3, 254, 232, 25, 4, 66, 172, 220, 2, 28, 48, 240, 3, 255, 158, 158, 1, 54, 1, 120, 51, 43, 0, 209, 170,
|
||||||
|
176, 5, 188, 240, 188, 8, 176, 4, 71, 24, 0, 0, 13, 171, 19, 114, 197, 96, 181, 240, 28, 12, 176, 133, 28, 6, 33, 0,
|
||||||
|
32, 0, 247, 255, 252, 176, 126, 35, 43, 0, 209, 6, 74, 218, 33, 8, 96, 19, 104, 32, 240, 2, 254, 69, 96, 96, 105, 33,
|
||||||
|
41, 0, 208, 9, 126, 99, 104, 160, 43, 0, 208, 2, 240, 2, 254, 59, 224, 1, 240, 2, 254, 64, 96, 224, 126, 35, 43, 0,
|
||||||
|
209, 3, 75, 207, 104, 27, 105, 219, 224, 6, 126, 99, 43, 0, 208, 1, 75, 205, 224, 0, 75, 205, 104, 27, 147, 2, 77, 204,
|
||||||
|
75, 205, 153, 2, 28, 40, 96, 25, 34, 96, 240, 2, 255, 104, 33, 0, 34, 48, 152, 2, 240, 3, 254, 69, 75, 195, 34, 0, 104,
|
||||||
|
27, 28, 32, 100, 26, 75, 197, 34, 1, 104, 25, 64, 74, 96, 26, 247, 255, 251, 121, 75, 195, 100, 168, 96, 24, 126, 34,
|
||||||
|
35, 15, 146, 1, 64, 26, 146, 3, 155, 3, 28, 7, 34, 128, 105, 176, 2, 29, 1, 146, 155, 1, 67, 2, 105, 225, 67, 42, 43,
|
||||||
|
0, 209, 1, 72, 186, 224, 5, 5, 72, 35, 128, 9, 64, 5, 219, 67, 3, 28, 24, 67, 16, 240, 3, 253, 158, 77, 176, 35, 64,
|
||||||
|
96, 171, 75, 180, 33, 255, 104, 27, 34, 255, 108, 91, 2, 9, 4, 18, 64, 25, 64, 26, 2, 9, 10, 18, 67, 10, 14, 25, 67,
|
||||||
|
10, 33, 224, 64, 11, 33, 2, 67, 11, 6, 27, 67, 26, 96, 104, 96, 42, 107, 120, 240, 3, 253, 130, 35, 128, 153, 1, 4,
|
||||||
|
91, 97, 40, 97, 107, 41, 0, 208, 16, 9, 203, 153, 3, 106, 114, 1, 27, 24, 91, 64, 218, 28, 19, 7, 218, 213, 3, 105,
|
||||||
|
170, 35, 128, 67, 19, 224, 2, 105, 171, 34, 128, 67, 147, 97, 171, 77, 150, 75, 156, 105, 170, 28, 40, 64, 19, 97, 171,
|
||||||
|
33, 96, 240, 2, 253, 195, 108, 173, 224, 4, 28, 40, 33, 96, 240, 2, 253, 189, 107, 173, 45, 0, 209, 248, 152, 2, 73,
|
||||||
|
141, 34, 96, 240, 2, 254, 224, 75, 146, 120, 27, 43, 0, 208, 4, 75, 145, 72, 145, 104, 25, 247, 255, 254, 218, 75, 144,
|
||||||
|
34, 1, 96, 26, 77, 130, 35, 0, 147, 1, 153, 1, 74, 139, 49, 1, 145, 1, 72, 140, 104, 17, 247, 254, 255, 192, 104, 43,
|
||||||
|
33, 32, 105, 152, 240, 2, 253, 173, 104, 42, 73, 124, 39, 2, 108, 75, 105, 145, 34, 255, 2, 18, 64, 26, 2, 16, 34, 255,
|
||||||
|
4, 18, 64, 26, 10, 18, 67, 2, 14, 24, 67, 2, 32, 224, 64, 3, 67, 59, 6, 24, 28, 19, 67, 3, 96, 11, 104, 43, 33, 32,
|
||||||
|
105, 152, 240, 2, 253, 125, 247, 255, 251, 163, 247, 254, 255, 201, 154, 1, 42, 4, 208, 6, 28, 3, 51, 9, 209, 3, 72,
|
||||||
|
118, 247, 255, 254, 158, 231, 200, 75, 114, 34, 0, 96, 26, 75, 109, 28, 7, 120, 27, 43, 0, 208, 3, 72, 113, 28, 57,
|
||||||
|
247, 255, 254, 145, 47, 0, 209, 3, 75, 93, 104, 27, 43, 0, 208, 15, 75, 92, 104, 27, 104, 154, 75, 107, 50, 68, 104,
|
||||||
|
27, 0, 155, 24, 211, 104, 27, 34, 5, 64, 19, 43, 5, 208, 2, 75, 84, 34, 1, 96, 26, 66, 121, 65, 121, 145, 1, 29, 122,
|
||||||
|
208, 1, 41, 0, 208, 65, 247, 255, 251, 66, 77, 79, 33, 32, 104, 43, 105, 152, 240, 3, 254, 144, 104, 43, 33, 32, 105,
|
||||||
|
152, 240, 2, 253, 39, 75, 82, 104, 42, 104, 27, 105, 145, 108, 91, 34, 255, 2, 18, 64, 26, 2, 16, 34, 255, 4, 18, 64,
|
||||||
|
26, 10, 18, 67, 2, 14, 24, 67, 2, 32, 224, 64, 3, 32, 2, 67, 3, 6, 24, 28, 19, 67, 3, 96, 11, 104, 43, 33, 32, 105,
|
||||||
|
152, 240, 3, 254, 78, 247, 255, 251, 66, 126, 34, 42, 0, 208, 98, 9, 211, 32, 15, 64, 16, 1, 27, 24, 27, 106, 113, 34,
|
||||||
|
1, 64, 154, 67, 145, 28, 10, 73, 70, 104, 9, 6, 9, 15, 201, 64, 153, 28, 11, 67, 19, 98, 115, 224, 79, 247, 255, 251,
|
||||||
|
0, 75, 49, 108, 157, 224, 4, 107, 104, 33, 96, 240, 2, 253, 15, 107, 173, 45, 0, 209, 248, 77, 44, 34, 32, 28, 40, 153,
|
||||||
|
2, 240, 2, 254, 42, 126, 34, 42, 0, 208, 16, 9, 211, 32, 15, 64, 16, 1, 27, 24, 27, 106, 113, 34, 1, 64, 154, 67, 145,
|
||||||
|
28, 10, 105, 169, 6, 9, 15, 201, 64, 153, 28, 11, 67, 19, 98, 115, 77, 28, 33, 32, 104, 43, 38, 2, 105, 152, 240, 3,
|
||||||
|
254, 41, 104, 43, 33, 32, 105, 152, 240, 2, 252, 192, 75, 30, 104, 42, 104, 27, 105, 145, 108, 91, 34, 255, 2, 18, 64,
|
||||||
|
26, 2, 16, 34, 255, 4, 18, 64, 26, 10, 18, 67, 2, 14, 24, 67, 2, 32, 224, 64, 3, 67, 51, 6, 24, 28, 19, 67, 3, 96, 11,
|
||||||
|
104, 43, 33, 32, 105, 152, 240, 3, 253, 232, 247, 255, 250, 220, 73, 10, 32, 1, 247, 255, 251, 2, 105, 33, 41, 0, 208,
|
||||||
|
48, 126, 99, 104, 224, 43, 0, 208, 42, 240, 2, 252, 175, 224, 41, 19, 112, 107, 84, 19, 112, 96, 60, 19, 112, 106, 244,
|
||||||
|
19, 112, 107, 72, 19, 114, 197, 0, 19, 112, 106, 252, 19, 112, 107, 64, 19, 112, 107, 20, 64, 64, 64, 0, 19, 112, 107,
|
||||||
|
68, 1, 0, 0, 128, 19, 112, 106, 248, 19, 112, 96, 56, 19, 112, 96, 194, 19, 112, 107, 16, 19, 112, 41, 229, 19, 112,
|
||||||
|
98, 156, 19, 112, 96, 240, 19, 112, 107, 80, 19, 112, 107, 4, 240, 2, 252, 138, 126, 35, 43, 0, 209, 3, 104, 96, 33,
|
||||||
|
8, 240, 2, 252, 125, 155, 1, 43, 0, 208, 0, 105, 103, 176, 5, 28, 56, 188, 240, 188, 2, 71, 8, 181, 48, 176, 137, 70,
|
||||||
|
108, 118, 33, 9, 201, 118, 97, 33, 128, 0, 137, 37, 0, 145, 7, 70, 105, 149, 0, 146, 4, 147, 2, 247, 255, 253, 246,
|
||||||
|
176, 9, 188, 48, 188, 2, 71, 8, 181, 240, 176, 139, 28, 6, 70, 104, 48, 70, 136, 4, 72, 43, 70, 156, 104, 0, 70, 107,
|
||||||
|
51, 66, 48, 248, 104, 0, 136, 27, 112, 66, 4, 27, 70, 98, 147, 1, 2, 19, 10, 18, 67, 19, 4, 26, 12, 19, 14, 18, 112,
|
||||||
|
1, 159, 18, 112, 130, 112, 195, 155, 1, 4, 36, 10, 26, 14, 27, 67, 19, 4, 27, 12, 37, 12, 26, 14, 27, 113, 3, 14, 36,
|
||||||
|
2, 43, 67, 35, 4, 27, 113, 66, 14, 26, 12, 27, 113, 195, 172, 2, 35, 0, 113, 130, 118, 35, 35, 64, 97, 227, 75, 21,
|
||||||
|
9, 201, 144, 2, 118, 97, 97, 37, 66, 159, 217, 22, 28, 40, 240, 2, 252, 52, 28, 42, 28, 57, 96, 160, 240, 3, 251, 237,
|
||||||
|
28, 33, 28, 48, 247, 255, 253, 171, 104, 164, 28, 6, 28, 33, 28, 56, 28, 42, 240, 3, 251, 226, 28, 32, 240, 2, 252,
|
||||||
|
63, 224, 5, 28, 48, 96, 167, 28, 33, 247, 255, 253, 155, 28, 6, 176, 11, 28, 48, 188, 240, 188, 2, 71, 8, 70, 192, 19,
|
||||||
|
112, 96, 60, 19, 136, 0, 0, 181, 0, 176, 133, 145, 0, 35, 0, 33, 2, 34, 1, 147, 1, 147, 2, 247, 255, 255, 148, 176,
|
||||||
|
5, 188, 2, 71, 8, 181, 0, 176, 133, 28, 19, 34, 0, 145, 0, 146, 1, 146, 2, 33, 1, 34, 11, 247, 255, 255, 134, 176, 5,
|
||||||
|
188, 2, 71, 8, 181, 0, 176, 133, 34, 0, 146, 0, 146, 1, 146, 2, 28, 11, 34, 9, 33, 0, 247, 255, 255, 120, 176, 5, 188,
|
||||||
|
2, 71, 8, 181, 112, 28, 4, 176, 132, 32, 1, 28, 14, 240, 2, 251, 224, 30, 5, 208, 18, 35, 0, 147, 0, 35, 1, 147, 1,
|
||||||
|
28, 32, 33, 128, 34, 8, 35, 0, 149, 2, 247, 255, 255, 97, 30, 4, 219, 1, 120, 43, 112, 51, 28, 40, 240, 2, 251, 234,
|
||||||
|
224, 1, 36, 4, 66, 100, 176, 4, 28, 32, 188, 112, 188, 2, 71, 8, 181, 16, 176, 132, 70, 108, 2, 18, 52, 27, 120, 36,
|
||||||
|
67, 19, 34, 0, 146, 0, 145, 2, 34, 6, 33, 128, 148, 1, 247, 255, 255, 67, 176, 4, 188, 16, 188, 2, 71, 8, 0, 0, 181,
|
||||||
|
240, 176, 137, 75, 65, 28, 2, 104, 30, 0, 129, 104, 179, 24, 9, 50, 16, 0, 201, 0, 146, 24, 154, 28, 11, 51, 88, 28,
|
||||||
|
7, 24, 240, 144, 5, 24, 113, 32, 0, 103, 8, 104, 81, 29, 21, 74, 56, 64, 10, 42, 1, 209, 99, 34, 4, 146, 4, 147, 7,
|
||||||
|
75, 54, 32, 10, 96, 43, 247, 254, 255, 156, 75, 52, 32, 100, 96, 43, 247, 254, 255, 151, 75, 51, 34, 128, 96, 43, 35,
|
||||||
|
250, 0, 219, 147, 0, 0, 82, 35, 0, 28, 40, 28, 41, 247, 255, 248, 15, 104, 42, 75, 45, 28, 4, 64, 19, 43, 5, 209, 50,
|
||||||
|
35, 192, 1, 27, 64, 26, 35, 128, 0, 219, 66, 154, 208, 43, 40, 0, 209, 43, 32, 100, 247, 254, 255, 121, 75, 38, 74,
|
||||||
|
38, 104, 24, 96, 26, 154, 7, 35, 22, 147, 1, 24, 179, 147, 2, 35, 128, 144, 6, 33, 128, 152, 5, 34, 6, 0, 91, 148, 0,
|
||||||
|
247, 255, 254, 231, 30, 4, 219, 12, 28, 123, 32, 0, 4, 27, 144, 0, 144, 1, 144, 2, 12, 27, 152, 5, 33, 0, 34, 5, 247,
|
||||||
|
255, 254, 217, 28, 4, 75, 21, 154, 6, 96, 26, 44, 0, 219, 2, 224, 8, 36, 1, 66, 100, 155, 4, 59, 1, 147, 4, 43, 0, 209,
|
||||||
|
169, 44, 0, 219, 10, 0, 187, 25, 219, 0, 219, 24, 246, 55, 1, 35, 0, 103, 243, 103, 55, 224, 1, 36, 1, 66, 100, 176,
|
||||||
|
9, 28, 32, 188, 240, 188, 2, 71, 8, 70, 192, 19, 112, 96, 60, 0, 0, 32, 1, 0, 0, 24, 3, 0, 0, 25, 3, 0, 0, 16, 1, 0,
|
||||||
|
0, 32, 5, 19, 112, 96, 56, 0, 6, 26, 128, 181, 248, 76, 25, 28, 6, 104, 35, 104, 157, 35, 1, 96, 171, 247, 255, 255,
|
||||||
|
97, 30, 7, 218, 24, 104, 35, 33, 55, 104, 155, 28, 52, 104, 90, 32, 10, 64, 10, 96, 90, 52, 16, 247, 254, 255, 18, 0,
|
||||||
|
164, 75, 15, 25, 44, 96, 99, 32, 50, 247, 254, 255, 11, 75, 13, 32, 100, 96, 99, 247, 254, 255, 6, 75, 11, 96, 99, 75,
|
||||||
|
7, 32, 55, 104, 26, 104, 146, 104, 81, 64, 1, 96, 81, 104, 27, 34, 4, 104, 155, 28, 56, 96, 154, 188, 248, 188, 2, 71,
|
||||||
|
8, 70, 192, 19, 112, 96, 60, 0, 0, 24, 3, 0, 0, 25, 3, 0, 0, 16, 1, 181, 240, 176, 137, 75, 126, 34, 0, 104, 31, 0,
|
||||||
|
131, 24, 27, 0, 219, 28, 30, 147, 5, 54, 88, 24, 251, 28, 4, 25, 190, 103, 26, 32, 50, 247, 254, 254, 218, 37, 3, 150,
|
||||||
|
6, 72, 118, 247, 255, 251, 219, 32, 50, 247, 254, 254, 210, 35, 22, 147, 1, 155, 6, 34, 0, 147, 2, 35, 128, 146, 0,
|
||||||
|
28, 48, 33, 128, 34, 6, 0, 91, 247, 255, 254, 69, 40, 0, 218, 12, 72, 109, 247, 255, 251, 198, 32, 50, 247, 254, 254,
|
||||||
|
189, 61, 1, 32, 100, 247, 254, 254, 185, 45, 0, 209, 222, 224, 2, 154, 5, 24, 187, 224, 38, 28, 32, 247, 255, 249, 106,
|
||||||
|
75, 100, 66, 152, 209, 0, 224, 184, 32, 100, 247, 254, 254, 169, 72, 98, 247, 255, 251, 172, 35, 22, 147, 1, 155, 6,
|
||||||
|
34, 0, 147, 2, 35, 128, 146, 0, 28, 48, 33, 128, 34, 6, 0, 91, 247, 255, 254, 25, 40, 0, 218, 6, 72, 90, 53, 1, 247,
|
||||||
|
255, 251, 153, 45, 3, 209, 221, 224, 12, 0, 163, 25, 27, 0, 219, 24, 251, 110, 26, 75, 85, 66, 154, 209, 46, 28, 32,
|
||||||
|
247, 255, 249, 199, 76, 83, 224, 144, 28, 32, 247, 255, 249, 14, 32, 100, 247, 254, 254, 125, 28, 32, 247, 255, 249,
|
||||||
|
52, 74, 73, 66, 144, 209, 0, 224, 130, 32, 100, 247, 254, 254, 115, 72, 75, 247, 255, 251, 118, 35, 0, 154, 6, 147,
|
||||||
|
0, 35, 22, 147, 1, 35, 128, 146, 2, 28, 48, 33, 128, 34, 6, 0, 91, 247, 255, 253, 227, 40, 0, 218, 7, 72, 63, 61, 1,
|
||||||
|
247, 255, 251, 99, 45, 0, 209, 215, 76, 64, 224, 102, 72, 64, 247, 255, 251, 92, 28, 99, 147, 5, 4, 27, 12, 27, 147,
|
||||||
|
7, 0, 163, 25, 28, 0, 228, 37, 0, 25, 63, 32, 50, 247, 254, 254, 73, 72, 57, 28, 41, 247, 255, 251, 75, 35, 0, 147,
|
||||||
|
0, 147, 1, 147, 2, 28, 48, 33, 0, 34, 5, 155, 7, 247, 255, 253, 187, 30, 4, 218, 7, 76, 50, 28, 41, 72, 50, 27, 100,
|
||||||
|
247, 255, 251, 57, 53, 1, 224, 3, 72, 48, 28, 41, 247, 255, 251, 51, 155, 5, 34, 0, 103, 250, 103, 59, 44, 0, 218, 47,
|
||||||
|
33, 0, 28, 48, 247, 255, 254, 5, 32, 50, 247, 254, 254, 32, 72, 40, 247, 255, 251, 35, 35, 22, 147, 1, 155, 6, 34, 0,
|
||||||
|
147, 2, 35, 128, 146, 0, 28, 48, 33, 128, 34, 6, 0, 91, 247, 255, 253, 144, 30, 4, 218, 6, 72, 32, 247, 255, 251, 17,
|
||||||
|
34, 0, 103, 58, 76, 31, 224, 2, 72, 31, 247, 255, 251, 10, 53, 1, 44, 0, 218, 7, 15, 233, 34, 0, 35, 4, 66, 171, 65,
|
||||||
|
74, 6, 18, 42, 0, 209, 172, 44, 0, 219, 4, 72, 24, 247, 255, 250, 250, 224, 0, 76, 6, 176, 9, 28, 32, 188, 240, 188,
|
||||||
|
2, 71, 8, 70, 192, 19, 112, 96, 60, 19, 112, 97, 75, 19, 112, 97, 0, 255, 255, 251, 161, 19, 112, 97, 30, 19, 112, 97,
|
||||||
|
69, 149, 11, 32, 119, 255, 255, 251, 160, 19, 112, 97, 106, 255, 255, 247, 103, 19, 112, 97, 155, 19, 112, 97, 181,
|
||||||
|
255, 255, 224, 192, 19, 112, 97, 212, 19, 112, 97, 243, 19, 112, 98, 55, 19, 112, 98, 14, 255, 255, 247, 62, 19, 112,
|
||||||
|
98, 52, 19, 112, 98, 87, 181, 16, 75, 10, 34, 1, 104, 27, 28, 4, 104, 155, 96, 154, 247, 255, 248, 117, 40, 0, 219,
|
||||||
|
2, 28, 32, 247, 255, 254, 202, 75, 3, 34, 4, 104, 27, 104, 155, 96, 154, 188, 16, 188, 2, 71, 8, 19, 112, 96, 60, 181,
|
||||||
|
240, 176, 141, 144, 6, 32, 22, 28, 13, 240, 2, 249, 151, 30, 7, 209, 0, 224, 214, 32, 10, 247, 254, 253, 159, 35, 18,
|
||||||
|
147, 0, 152, 6, 28, 57, 34, 1, 35, 0, 247, 255, 253, 197, 40, 0, 218, 54, 72, 180, 247, 255, 250, 152, 76, 179, 104,
|
||||||
|
32, 247, 255, 255, 202, 28, 6, 32, 20, 247, 254, 253, 138, 75, 176, 104, 32, 104, 27, 0, 130, 104, 155, 51, 68, 24,
|
||||||
|
155, 104, 26, 46, 0, 219, 4, 75, 172, 64, 26, 75, 172, 66, 154, 208, 13, 247, 255, 254, 81, 32, 20, 247, 254, 253, 118,
|
||||||
|
75, 166, 104, 27, 104, 154, 75, 164, 50, 68, 104, 27, 0, 155, 24, 211, 104, 27, 32, 30, 247, 254, 253, 106, 35, 18,
|
||||||
|
147, 0, 152, 6, 28, 57, 34, 1, 35, 0, 247, 255, 253, 144, 30, 4, 218, 1, 72, 158, 224, 165, 28, 57, 34, 18, 28, 40,
|
||||||
|
240, 3, 249, 9, 28, 56, 240, 2, 249, 102, 120, 170, 120, 235, 2, 18, 67, 26, 4, 18, 10, 19, 14, 18, 67, 19, 4, 27, 12,
|
||||||
|
26, 112, 234, 14, 27, 122, 42, 112, 171, 122, 107, 2, 18, 67, 26, 4, 18, 10, 19, 14, 18, 67, 19, 4, 27, 12, 26, 114,
|
||||||
|
106, 14, 27, 122, 170, 114, 43, 122, 235, 2, 18, 67, 26, 4, 18, 10, 19, 14, 18, 67, 19, 4, 27, 12, 26, 114, 234, 14,
|
||||||
|
27, 123, 42, 114, 171, 123, 107, 2, 18, 67, 26, 4, 18, 10, 19, 14, 18, 67, 19, 4, 27, 12, 26, 14, 27, 115, 43, 124,
|
||||||
|
107, 115, 106, 0, 88, 24, 192, 0, 128, 24, 192, 240, 2, 249, 13, 14, 3, 116, 171, 12, 3, 116, 235, 10, 3, 117, 43, 117,
|
||||||
|
104, 40, 0, 209, 1, 72, 120, 224, 204, 124, 107, 33, 0, 0, 90, 24, 210, 0, 146, 24, 210, 240, 3, 248, 250, 33, 0, 145,
|
||||||
|
10, 145, 5, 28, 46, 225, 51, 32, 9, 240, 2, 248, 242, 30, 4, 208, 49, 154, 5, 28, 33, 6, 19, 14, 27, 147, 3, 35, 9,
|
||||||
|
147, 0, 34, 2, 155, 3, 152, 6, 247, 255, 253, 32, 124, 179, 124, 245, 6, 27, 4, 45, 67, 29, 125, 51, 28, 33, 2, 27,
|
||||||
|
67, 29, 125, 115, 34, 9, 67, 29, 155, 10, 24, 237, 28, 40, 240, 3, 248, 145, 28, 32, 240, 2, 248, 238, 120, 170, 120,
|
||||||
|
235, 2, 18, 67, 26, 4, 18, 10, 19, 14, 18, 67, 19, 4, 27, 12, 28, 14, 27, 112, 171, 112, 236, 28, 32, 240, 2, 248, 192,
|
||||||
|
30, 7, 209, 6, 28, 53, 72, 86, 36, 4, 247, 255, 249, 205, 66, 100, 225, 3, 120, 235, 152, 6, 147, 0, 28, 57, 34, 2,
|
||||||
|
155, 3, 247, 255, 252, 235, 40, 0, 218, 5, 28, 4, 72, 78, 28, 53, 247, 255, 249, 188, 224, 238, 120, 41, 145, 2, 121,
|
||||||
|
43, 0, 216, 24, 192, 0, 64, 240, 2, 248, 159, 14, 3, 114, 107, 12, 3, 114, 171, 10, 3, 114, 235, 115, 40, 40, 0, 209,
|
||||||
|
2, 28, 53, 72, 68, 224, 93, 155, 2, 154, 2, 26, 228, 25, 210, 146, 3, 148, 4, 121, 43, 33, 0, 0, 218, 24, 210, 0, 82,
|
||||||
|
240, 3, 248, 134, 33, 0, 145, 11, 145, 8, 224, 177, 122, 107, 122, 172, 6, 27, 4, 36, 67, 28, 122, 235, 154, 11, 2,
|
||||||
|
27, 67, 28, 123, 43, 153, 3, 67, 28, 24, 164, 28, 32, 34, 9, 240, 3, 248, 47, 120, 35, 147, 2, 121, 35, 0, 216, 26,
|
||||||
|
192, 240, 2, 248, 106, 14, 3, 115, 163, 12, 3, 115, 227, 10, 3, 116, 35, 116, 96, 40, 0, 209, 2, 28, 53, 72, 42, 224,
|
||||||
|
40, 153, 3, 155, 4, 28, 10, 153, 2, 24, 82, 153, 2, 146, 3, 26, 91, 147, 4, 121, 35, 33, 0, 0, 218, 26, 210, 240, 3,
|
||||||
|
248, 79, 152, 3, 153, 4, 247, 255, 248, 33, 35, 11, 144, 2, 70, 106, 92, 154, 115, 98, 155, 2, 43, 0, 208, 31, 28, 24,
|
||||||
|
240, 2, 248, 64, 14, 3, 114, 99, 12, 3, 114, 163, 10, 3, 114, 227, 115, 32, 40, 0, 209, 6, 72, 23, 28, 53, 36, 4, 247,
|
||||||
|
255, 249, 70, 66, 100, 224, 119, 153, 3, 154, 2, 240, 2, 255, 234, 153, 3, 155, 4, 28, 10, 153, 2, 24, 82, 153, 2, 146,
|
||||||
|
3, 26, 91, 147, 4, 34, 0, 146, 7, 146, 9, 224, 68, 70, 192, 19, 112, 98, 121, 19, 112, 107, 80, 19, 112, 96, 60, 0,
|
||||||
|
0, 49, 5, 0, 0, 16, 5, 19, 112, 98, 163, 19, 112, 98, 198, 19, 112, 98, 96, 19, 112, 98, 236, 19, 112, 99, 22, 19, 112,
|
||||||
|
99, 56, 19, 112, 99, 89, 123, 162, 123, 227, 6, 18, 4, 27, 67, 19, 124, 34, 153, 7, 2, 18, 67, 19, 124, 98, 67, 19,
|
||||||
|
24, 201, 145, 2, 28, 8, 34, 7, 153, 3, 240, 2, 255, 178, 154, 2, 153, 3, 120, 19, 24, 201, 145, 3, 153, 2, 121, 18,
|
||||||
|
121, 75, 2, 18, 67, 26, 4, 18, 10, 17, 14, 19, 67, 11, 4, 27, 153, 2, 12, 26, 14, 27, 113, 11, 113, 74, 154, 9, 155,
|
||||||
|
7, 50, 1, 51, 7, 146, 9, 147, 7, 121, 35, 153, 9, 66, 153, 211, 207, 154, 8, 155, 11, 50, 1, 51, 18, 146, 8, 147, 11,
|
||||||
|
121, 43, 153, 8, 66, 153, 210, 0, 231, 72, 28, 56, 240, 1, 255, 230, 154, 5, 155, 10, 50, 1, 51, 13, 146, 5, 147, 10,
|
||||||
|
39, 0, 124, 115, 153, 5, 66, 153, 210, 0, 230, 198, 28, 53, 36, 0, 47, 0, 208, 7, 28, 56, 240, 1, 255, 211, 44, 0, 208,
|
||||||
|
2, 28, 40, 247, 254, 255, 151, 176, 13, 28, 32, 188, 240, 188, 2, 71, 8, 70, 192, 181, 248, 28, 4, 38, 3, 39, 64, 224,
|
||||||
|
79, 104, 160, 240, 2, 255, 38, 10, 3, 64, 51, 28, 5, 43, 2, 208, 7, 107, 227, 108, 34, 105, 89, 24, 138, 0, 65, 12,
|
||||||
|
73, 26, 82, 97, 90, 108, 35, 43, 0, 208, 59, 66, 47, 208, 57, 75, 36, 120, 27, 43, 0, 208, 2, 72, 35, 247, 255, 248,
|
||||||
|
157, 6, 235, 213, 6, 75, 32, 120, 27, 43, 0, 208, 2, 72, 32, 247, 255, 248, 148, 7, 107, 213, 6, 75, 27, 120, 27, 43,
|
||||||
|
0, 208, 2, 72, 28, 247, 255, 248, 139, 6, 171, 213, 6, 75, 23, 120, 27, 43, 0, 208, 2, 72, 25, 247, 255, 248, 130, 7,
|
||||||
|
43, 213, 6, 75, 18, 120, 27, 43, 0, 208, 2, 72, 21, 247, 255, 248, 121, 75, 15, 120, 27, 43, 0, 208, 2, 72, 19, 247,
|
||||||
|
255, 248, 114, 75, 11, 120, 27, 43, 0, 208, 8, 72, 16, 247, 255, 248, 107, 224, 4, 107, 164, 44, 0, 209, 173, 32, 0,
|
||||||
|
224, 3, 107, 227, 32, 1, 66, 64, 97, 88, 75, 11, 34, 0, 104, 27, 100, 26, 188, 248, 188, 2, 71, 8, 19, 112, 106, 248,
|
||||||
|
19, 112, 99, 118, 19, 112, 99, 131, 19, 112, 99, 139, 19, 112, 99, 160, 19, 112, 99, 179, 19, 112, 99, 190, 19, 112,
|
||||||
|
105, 116, 19, 112, 96, 60, 181, 240, 176, 131, 28, 5, 35, 9, 7, 193, 213, 60, 75, 58, 120, 27, 43, 0, 208, 2, 72, 57,
|
||||||
|
247, 255, 248, 59, 75, 57, 104, 28, 44, 0, 208, 9, 107, 96, 33, 96, 240, 3, 248, 79, 107, 96, 33, 96, 240, 1, 254, 239,
|
||||||
|
107, 164, 231, 243, 76, 51, 104, 35, 43, 0, 208, 24, 108, 88, 33, 32, 240, 3, 248, 65, 104, 35, 33, 32, 108, 88, 240,
|
||||||
|
1, 254, 224, 104, 35, 34, 128, 4, 82, 97, 26, 74, 43, 108, 88, 104, 18, 33, 32, 107, 82, 97, 90, 240, 3, 248, 32, 104,
|
||||||
|
35, 105, 154, 75, 39, 96, 26, 75, 35, 104, 24, 247, 255, 255, 78, 35, 0, 40, 0, 208, 4, 74, 36, 104, 18, 100, 19, 35,
|
||||||
|
5, 66, 91, 7, 106, 213, 40, 75, 26, 120, 27, 43, 0, 208, 2, 72, 31, 247, 254, 255, 251, 33, 128, 1, 137, 79, 28, 78,
|
||||||
|
29, 35, 1, 34, 0, 145, 1, 104, 56, 104, 49, 104, 128, 0, 148, 48, 68, 25, 0, 70, 140, 104, 4, 69, 98, 209, 7, 32, 1,
|
||||||
|
66, 32, 209, 10, 75, 22, 96, 24, 35, 1, 66, 91, 224, 5, 73, 20, 64, 12, 44, 3, 209, 1, 153, 1, 96, 1, 50, 1, 42, 4,
|
||||||
|
209, 228, 43, 0, 208, 4, 34, 18, 66, 42, 208, 1, 35, 6, 66, 91, 176, 3, 28, 24, 188, 240, 188, 2, 71, 8, 70, 192, 19,
|
||||||
|
112, 106, 248, 19, 112, 99, 207, 19, 112, 107, 20, 19, 112, 106, 252, 19, 112, 107, 8, 19, 112, 107, 4, 19, 112, 96,
|
||||||
|
60, 19, 112, 99, 240, 19, 112, 107, 80, 19, 112, 107, 84, 0, 0, 32, 3, 181, 240, 176, 131, 147, 1, 70, 107, 51, 39,
|
||||||
|
120, 30, 28, 5, 30, 115, 6, 27, 14, 27, 145, 0, 28, 23, 43, 15, 216, 61, 28, 4, 52, 160, 104, 32, 40, 0, 208, 56, 33,
|
||||||
|
0, 34, 31, 240, 2, 254, 139, 104, 35, 74, 29, 96, 26, 28, 43, 51, 152, 104, 24, 240, 2, 254, 7, 104, 35, 96, 88, 28,
|
||||||
|
56, 240, 2, 254, 2, 104, 35, 70, 105, 96, 152, 29, 202, 120, 17, 104, 35, 70, 106, 115, 25, 28, 209, 104, 35, 120, 10,
|
||||||
|
115, 90, 104, 34, 35, 6, 46, 6, 217, 0, 35, 10, 28, 44, 115, 147, 52, 160, 104, 32, 153, 8, 28, 50, 48, 15, 240, 2,
|
||||||
|
254, 34, 28, 43, 51, 144, 104, 24, 123, 105, 104, 35, 34, 31, 247, 255, 249, 214, 40, 31, 208, 6, 40, 0, 219, 5, 72,
|
||||||
|
5, 224, 3, 32, 3, 66, 64, 224, 0, 32, 0, 176, 3, 188, 240, 188, 2, 71, 8, 85, 83, 66, 67, 255, 255, 216, 238, 181, 240,
|
||||||
|
28, 4, 176, 131, 52, 160, 28, 5, 145, 0, 28, 23, 33, 255, 34, 13, 104, 32, 240, 2, 254, 62, 28, 43, 51, 144, 104, 24,
|
||||||
|
123, 41, 104, 35, 34, 13, 247, 255, 249, 176, 40, 13, 208, 1, 40, 0, 218, 40, 40, 0, 219, 43, 28, 43, 51, 160, 104,
|
||||||
|
28, 104, 32, 240, 2, 253, 174, 144, 1, 104, 96, 240, 2, 253, 170, 28, 6, 104, 160, 240, 2, 253, 166, 74, 16, 153, 1,
|
||||||
|
123, 35, 66, 145, 209, 21, 47, 0, 208, 0, 96, 56, 154, 0, 42, 0, 208, 0, 112, 19, 53, 152, 104, 43, 66, 158, 209, 12,
|
||||||
|
28, 179, 4, 27, 12, 54, 12, 27, 4, 54, 67, 30, 96, 46, 32, 0, 224, 4, 72, 5, 224, 2, 72, 5, 224, 0, 72, 5, 176, 3, 188,
|
||||||
|
240, 188, 2, 71, 8, 83, 66, 83, 85, 255, 255, 216, 237, 255, 255, 216, 236, 255, 255, 216, 235, 181, 240, 176, 135,
|
||||||
|
74, 75, 75, 76, 120, 18, 28, 6, 104, 31, 42, 0, 208, 1, 73, 74, 224, 0, 73, 74, 96, 25, 28, 51, 51, 144, 104, 24, 75,
|
||||||
|
72, 104, 27, 104, 153, 105, 195, 49, 68, 0, 155, 24, 203, 104, 25, 35, 1, 66, 11, 209, 6, 74, 68, 36, 1, 96, 19, 75,
|
||||||
|
62, 66, 100, 96, 31, 224, 113, 75, 60, 42, 0, 208, 1, 74, 60, 224, 0, 74, 60, 96, 26, 75, 62, 120, 27, 43, 0, 208, 17,
|
||||||
|
136, 243, 34, 255, 147, 0, 33, 33, 35, 0, 147, 1, 147, 2, 247, 255, 249, 80, 28, 4, 28, 33, 72, 55, 247, 254, 254, 209,
|
||||||
|
32, 60, 247, 254, 249, 200, 224, 6, 33, 0, 247, 255, 249, 166, 32, 5, 247, 254, 249, 193, 36, 0, 75, 41, 120, 26, 75,
|
||||||
|
41, 42, 0, 208, 1, 74, 41, 224, 0, 74, 41, 28, 53, 96, 26, 53, 144, 44, 0, 218, 10, 32, 50, 247, 254, 249, 176, 104,
|
||||||
|
40, 33, 0, 247, 255, 249, 142, 32, 5, 247, 254, 249, 169, 224, 48, 123, 49, 104, 40, 247, 255, 249, 134, 28, 4, 32,
|
||||||
|
5, 247, 254, 249, 160, 72, 33, 28, 33, 247, 254, 254, 162, 44, 0, 219, 34, 123, 113, 104, 40, 247, 255, 249, 120, 28,
|
||||||
|
4, 32, 5, 247, 254, 249, 146, 72, 27, 28, 33, 247, 254, 254, 148, 44, 0, 219, 20, 32, 10, 247, 254, 249, 137, 70, 105,
|
||||||
|
49, 23, 104, 40, 247, 255, 249, 143, 28, 4, 28, 33, 72, 20, 247, 254, 254, 133, 44, 0, 219, 5, 72, 19, 247, 254, 254,
|
||||||
|
128, 75, 7, 96, 31, 224, 4, 75, 6, 34, 1, 96, 31, 75, 8, 96, 26, 176, 7, 28, 32, 188, 240, 188, 2, 71, 8, 70, 192, 19,
|
||||||
|
112, 1, 15, 19, 112, 96, 56, 0, 15, 66, 64, 0, 3, 13, 64, 19, 112, 96, 60, 19, 112, 107, 84, 19, 112, 1, 13, 19, 112,
|
||||||
|
100, 17, 19, 112, 100, 50, 19, 112, 100, 89, 19, 112, 100, 129, 19, 112, 100, 176, 181, 240, 176, 141, 146, 6, 70, 106,
|
||||||
|
50, 79, 120, 18, 28, 31, 70, 107, 51, 95, 146, 7, 70, 106, 120, 27, 50, 83, 120, 18, 6, 27, 22, 27, 146, 8, 70, 106,
|
||||||
|
50, 47, 147, 4, 35, 0, 112, 19, 74, 147, 77, 148, 28, 6, 145, 5, 147, 10, 96, 19, 147, 3, 36, 0, 28, 163, 43, 1, 216,
|
||||||
|
0, 225, 6, 44, 0, 208, 33, 28, 48, 33, 0, 247, 255, 255, 38, 30, 4, 219, 1, 32, 5, 224, 0, 32, 60, 247, 254, 249, 37,
|
||||||
|
75, 137, 104, 27, 104, 154, 75, 136, 50, 68, 104, 27, 0, 155, 24, 211, 104, 27, 44, 0, 218, 9, 154, 3, 50, 1, 146, 3,
|
||||||
|
42, 2, 221, 0, 224, 232, 32, 10, 247, 254, 249, 17, 224, 219, 35, 0, 147, 3, 155, 4, 154, 8, 59, 1, 6, 27, 22, 27, 147,
|
||||||
|
4, 42, 0, 208, 59, 104, 43, 74, 123, 147, 2, 120, 19, 43, 0, 208, 1, 75, 121, 224, 0, 75, 121, 96, 43, 154, 7, 155,
|
||||||
|
18, 146, 1, 147, 0, 28, 58, 35, 0, 28, 48, 153, 5, 247, 255, 254, 66, 75, 110, 154, 2, 28, 4, 96, 26, 28, 131, 43, 1,
|
||||||
|
216, 0, 224, 190, 40, 0, 218, 0, 224, 178, 155, 6, 34, 144, 25, 146, 28, 60, 147, 2, 146, 9, 224, 18, 155, 9, 123, 113,
|
||||||
|
104, 24, 28, 34, 155, 2, 247, 255, 248, 69, 28, 131, 43, 1, 216, 0, 224, 159, 40, 0, 219, 69, 66, 160, 209, 67, 154,
|
||||||
|
2, 26, 36, 24, 18, 146, 2, 44, 0, 209, 234, 224, 62, 104, 43, 74, 93, 147, 2, 120, 19, 43, 0, 208, 1, 75, 91, 224, 0,
|
||||||
|
75, 91, 96, 43, 154, 7, 155, 18, 146, 1, 147, 0, 28, 58, 35, 128, 28, 48, 153, 5, 247, 255, 254, 6, 75, 80, 154, 2,
|
||||||
|
28, 4, 96, 26, 40, 0, 218, 3, 72, 83, 28, 33, 247, 254, 253, 178, 28, 163, 43, 1, 217, 125, 44, 0, 218, 22, 224, 113,
|
||||||
|
28, 51, 51, 144, 104, 24, 123, 49, 28, 58, 155, 6, 247, 255, 248, 10, 30, 4, 218, 3, 72, 74, 28, 33, 247, 254, 253,
|
||||||
|
158, 28, 163, 43, 1, 217, 96, 44, 0, 219, 5, 66, 188, 208, 5, 224, 2, 47, 0, 209, 231, 224, 1, 76, 68, 224, 86, 75,
|
||||||
|
59, 74, 61, 104, 27, 147, 2, 120, 19, 43, 0, 208, 1, 75, 59, 224, 0, 75, 59, 74, 54, 70, 105, 96, 19, 28, 48, 49, 47,
|
||||||
|
170, 10, 247, 255, 254, 33, 30, 4, 218, 34, 72, 58, 28, 33, 247, 254, 253, 121, 28, 99, 209, 3, 75, 46, 154, 2, 96,
|
||||||
|
26, 224, 65, 28, 52, 52, 144, 104, 32, 123, 49, 247, 255, 248, 73, 123, 51, 32, 15, 104, 34, 64, 24, 9, 219, 1, 27,
|
||||||
|
106, 81, 24, 27, 32, 1, 64, 152, 67, 129, 98, 81, 70, 105, 28, 48, 49, 47, 170, 10, 247, 255, 253, 253, 28, 4, 75, 31,
|
||||||
|
154, 2, 96, 26, 28, 163, 43, 1, 217, 34, 155, 10, 43, 0, 208, 7, 75, 37, 104, 27, 43, 0, 208, 3, 70, 107, 34, 1, 51,
|
||||||
|
47, 112, 26, 44, 0, 219, 12, 75, 32, 36, 0, 104, 27, 43, 0, 208, 7, 70, 107, 51, 47, 120, 27, 43, 0, 208, 2, 76, 28,
|
||||||
|
224, 0, 28, 4, 155, 4, 43, 0, 221, 2, 44, 0, 218, 0, 230, 247, 34, 0, 44, 0, 218, 0, 34, 1, 75, 9, 96, 26, 154, 21,
|
||||||
|
42, 0, 208, 3, 70, 107, 51, 47, 120, 27, 112, 19, 155, 22, 43, 0, 208, 2, 155, 10, 154, 22, 96, 19, 176, 13, 28, 32,
|
||||||
|
188, 240, 188, 2, 71, 8, 19, 112, 107, 84, 19, 112, 96, 56, 19, 112, 96, 60, 19, 112, 107, 80, 19, 112, 1, 15, 0, 15,
|
||||||
|
66, 64, 0, 3, 13, 64, 19, 112, 100, 186, 19, 112, 100, 205, 255, 255, 216, 233, 19, 112, 100, 229, 19, 112, 107, 28,
|
||||||
|
255, 255, 216, 234, 181, 240, 28, 3, 176, 143, 51, 160, 145, 7, 104, 30, 33, 128, 70, 111, 1, 9, 55, 55, 37, 0, 172,
|
||||||
|
9, 24, 118, 144, 6, 112, 61, 28, 32, 33, 0, 34, 16, 240, 2, 251, 218, 46, 0, 208, 87, 35, 6, 147, 1, 35, 1, 147, 2,
|
||||||
|
35, 10, 147, 5, 153, 7, 35, 0, 152, 6, 34, 0, 149, 4, 148, 0, 151, 3, 247, 255, 254, 131, 28, 5, 28, 41, 72, 40, 247,
|
||||||
|
254, 252, 216, 28, 107, 208, 69, 45, 0, 219, 2, 120, 59, 43, 0, 208, 64, 153, 7, 171, 9, 34, 3, 112, 26, 1, 74, 112,
|
||||||
|
90, 34, 18, 113, 26, 34, 0, 113, 90, 28, 48, 33, 0, 34, 18, 240, 2, 251, 174, 75, 28, 53, 2, 209, 1, 74, 28, 224, 0,
|
||||||
|
74, 28, 96, 26, 171, 9, 147, 0, 35, 6, 147, 1, 35, 0, 147, 2, 147, 3, 147, 4, 35, 10, 147, 5, 153, 7, 152, 6, 28, 50,
|
||||||
|
35, 18, 247, 255, 254, 81, 28, 5, 28, 41, 72, 19, 247, 254, 252, 166, 45, 0, 219, 19, 120, 179, 33, 15, 70, 108, 64,
|
||||||
|
25, 52, 55, 72, 15, 112, 33, 247, 254, 252, 155, 120, 35, 59, 2, 6, 27, 14, 27, 43, 2, 217, 3, 224, 3, 37, 4, 66, 109,
|
||||||
|
224, 0, 77, 9, 176, 15, 28, 40, 188, 240, 188, 2, 71, 8, 70, 192, 19, 112, 100, 244, 19, 112, 96, 56, 0, 38, 37, 160,
|
||||||
|
0, 152, 150, 128, 19, 112, 101, 21, 19, 112, 101, 52, 255, 255, 216, 239, 181, 240, 176, 147, 70, 106, 35, 0, 50, 71,
|
||||||
|
112, 19, 74, 197, 28, 4, 32, 16, 112, 16, 72, 196, 28, 34, 50, 152, 96, 16, 174, 12, 58, 8, 96, 17, 28, 8, 130, 115,
|
||||||
|
28, 49, 130, 179, 247, 255, 249, 179, 28, 5, 28, 41, 72, 190, 247, 254, 252, 96, 45, 0, 218, 0, 225, 195, 75, 188, 104,
|
||||||
|
27, 43, 0, 208, 37, 75, 187, 121, 50, 121, 153, 66, 145, 209, 23, 121, 217, 121, 114, 66, 145, 209, 19, 137, 25, 137,
|
||||||
|
50, 66, 145, 209, 15, 137, 89, 137, 114, 66, 145, 209, 11, 123, 25, 123, 178, 66, 145, 209, 7, 123, 89, 123, 242, 66,
|
||||||
|
145, 209, 3, 123, 154, 124, 51, 66, 154, 208, 8, 168, 12, 247, 254, 251, 12, 37, 1, 72, 171, 247, 254, 252, 53, 66,
|
||||||
|
109, 225, 167, 170, 12, 121, 17, 75, 167, 38, 0, 113, 153, 121, 81, 113, 217, 137, 17, 129, 25, 137, 81, 129, 89, 123,
|
||||||
|
145, 115, 25, 123, 209, 115, 89, 124, 18, 115, 154, 74, 161, 35, 128, 66, 91, 96, 19, 35, 0, 147, 10, 147, 5, 224, 221,
|
||||||
|
138, 111, 138, 171, 154, 10, 4, 63, 67, 31, 24, 191, 122, 58, 72, 155, 0, 82, 153, 5, 247, 254, 252, 14, 34, 156, 35,
|
||||||
|
0, 25, 18, 147, 9, 147, 6, 146, 11, 224, 191, 122, 123, 122, 189, 6, 27, 4, 45, 67, 29, 122, 251, 2, 27, 67, 29, 123,
|
||||||
|
59, 67, 29, 155, 9, 24, 237, 121, 107, 43, 8, 209, 115, 121, 235, 43, 80, 209, 112, 121, 43, 43, 1, 217, 109, 154, 11,
|
||||||
|
35, 1, 112, 19, 121, 169, 72, 137, 34, 1, 247, 254, 251, 234, 35, 0, 115, 102, 115, 38, 147, 8, 147, 7, 224, 49, 123,
|
||||||
|
170, 123, 235, 6, 18, 4, 27, 67, 19, 124, 42, 2, 18, 67, 19, 124, 106, 67, 19, 154, 8, 24, 155, 120, 218, 42, 2, 209,
|
||||||
|
28, 120, 154, 6, 17, 41, 0, 218, 11, 123, 33, 41, 0, 209, 8, 42, 0, 208, 6, 115, 34, 121, 25, 121, 91, 2, 9, 67, 25,
|
||||||
|
72, 119, 224, 10, 123, 97, 41, 0, 209, 9, 42, 0, 208, 7, 115, 98, 121, 25, 121, 91, 2, 9, 72, 114, 67, 25, 247, 254,
|
||||||
|
251, 184, 155, 7, 154, 8, 51, 1, 50, 7, 147, 7, 146, 8, 121, 43, 154, 7, 66, 154, 211, 201, 123, 33, 41, 0, 208, 93,
|
||||||
|
123, 98, 42, 0, 208, 90, 72, 105, 247, 254, 251, 165, 75, 97, 123, 34, 168, 12, 116, 26, 123, 98, 116, 90, 121, 122,
|
||||||
|
112, 34, 120, 170, 96, 98, 115, 218, 120, 235, 96, 163, 247, 254, 250, 105, 75, 91, 74, 97, 72, 97, 96, 26, 120, 33,
|
||||||
|
104, 162, 247, 254, 251, 142, 28, 35, 51, 144, 70, 105, 104, 24, 49, 71, 247, 254, 254, 140, 40, 0, 218, 89, 224, 85,
|
||||||
|
123, 170, 123, 235, 6, 18, 4, 27, 67, 19, 124, 42, 124, 104, 2, 18, 67, 19, 67, 24, 208, 1, 240, 1, 250, 129, 122, 106,
|
||||||
|
122, 171, 6, 18, 4, 27, 67, 19, 122, 234, 123, 40, 2, 18, 67, 19, 115, 174, 115, 238, 116, 46, 116, 110, 67, 24, 208,
|
||||||
|
1, 240, 1, 250, 112, 121, 107, 114, 110, 114, 174, 114, 238, 115, 46, 43, 9, 209, 4, 74, 72, 75, 63, 168, 12, 96, 26,
|
||||||
|
224, 39, 43, 8, 209, 10, 121, 235, 43, 80, 209, 7, 121, 43, 43, 1, 217, 4, 121, 171, 74, 66, 26, 211, 74, 56, 96, 19,
|
||||||
|
155, 6, 154, 9, 51, 1, 50, 18, 147, 6, 146, 9, 121, 59, 154, 6, 66, 154, 210, 0, 231, 58, 155, 5, 154, 10, 51, 1, 50,
|
||||||
|
13, 147, 5, 146, 10, 173, 12, 124, 107, 154, 5, 66, 154, 210, 0, 231, 27, 72, 53, 247, 254, 251, 51, 28, 40, 247, 254,
|
||||||
|
250, 3, 77, 49, 224, 148, 72, 50, 247, 254, 251, 43, 70, 107, 51, 71, 120, 25, 120, 34, 72, 48, 247, 254, 251, 36, 75,
|
||||||
|
34, 74, 47, 96, 26, 28, 35, 51, 144, 104, 24, 120, 33, 247, 254, 254, 18, 40, 0, 218, 2, 72, 43, 247, 254, 251, 22,
|
||||||
|
74, 42, 75, 27, 121, 225, 96, 26, 28, 35, 51, 144, 104, 24, 122, 226, 247, 254, 253, 245, 40, 0, 218, 2, 72, 37, 247,
|
||||||
|
254, 251, 7, 72, 37, 70, 109, 247, 254, 251, 3, 53, 70, 35, 0, 112, 43, 28, 35, 51, 144, 104, 24, 136, 227, 33, 161,
|
||||||
|
147, 0, 35, 1, 147, 1, 34, 254, 35, 0, 149, 2, 247, 254, 253, 109, 40, 0, 218, 56, 72, 27, 247, 254, 250, 238, 35, 8,
|
||||||
|
115, 163, 224, 58, 70, 192, 19, 112, 96, 64, 44, 13, 224, 1, 19, 112, 101, 86, 19, 112, 107, 56, 19, 112, 107, 36, 19,
|
||||||
|
112, 101, 128, 19, 112, 107, 0, 19, 112, 101, 166, 19, 112, 101, 205, 19, 112, 102, 4, 19, 112, 102, 18, 19, 112, 102,
|
||||||
|
33, 255, 255, 251, 79, 19, 112, 102, 102, 255, 255, 177, 224, 255, 255, 216, 240, 19, 112, 102, 53, 19, 112, 102, 148,
|
||||||
|
19, 112, 102, 189, 255, 255, 251, 78, 19, 112, 102, 222, 255, 255, 251, 77, 19, 112, 102, 252, 19, 112, 103, 43, 19,
|
||||||
|
112, 103, 102, 120, 41, 72, 24, 49, 1, 6, 9, 14, 9, 115, 161, 247, 254, 250, 176, 28, 37, 53, 160, 104, 43, 43, 0, 209,
|
||||||
|
7, 32, 129, 1, 64, 240, 1, 249, 147, 35, 31, 48, 31, 67, 152, 96, 40, 52, 160, 104, 35, 37, 0, 43, 0, 209, 4, 74, 12,
|
||||||
|
75, 13, 37, 4, 96, 26, 66, 109, 74, 12, 75, 12, 96, 26, 45, 0, 208, 5, 75, 8, 72, 11, 104, 25, 247, 254, 250, 143, 224,
|
||||||
|
2, 72, 9, 247, 254, 250, 139, 176, 19, 28, 40, 188, 240, 188, 2, 71, 8, 19, 112, 103, 141, 255, 255, 251, 75, 19, 112,
|
||||||
|
107, 0, 0, 15, 66, 64, 19, 112, 96, 56, 19, 112, 103, 164, 19, 112, 103, 198, 181, 8, 33, 0, 247, 255, 251, 104, 188,
|
||||||
|
8, 188, 2, 71, 8, 0, 0, 181, 240, 176, 139, 171, 8, 34, 18, 112, 26, 1, 74, 112, 90, 34, 0, 112, 154, 112, 218, 113,
|
||||||
|
90, 28, 15, 28, 2, 33, 36, 50, 160, 113, 25, 104, 20, 34, 128, 1, 18, 24, 164, 144, 7, 44, 0, 208, 42, 38, 0, 33, 0,
|
||||||
|
34, 36, 28, 32, 240, 2, 249, 63, 171, 8, 34, 6, 147, 0, 35, 10, 37, 0, 146, 1, 147, 5, 152, 7, 28, 57, 28, 34, 35, 36,
|
||||||
|
149, 2, 149, 3, 149, 4, 247, 255, 251, 233, 40, 0, 219, 7, 120, 35, 34, 31, 64, 19, 43, 5, 208, 6, 43, 7, 209, 8, 224,
|
||||||
|
3, 54, 1, 46, 2, 208, 9, 231, 220, 75, 6, 34, 1, 96, 26, 224, 4, 75, 4, 96, 29, 224, 1, 32, 4, 66, 64, 176, 11, 188,
|
||||||
|
240, 188, 2, 71, 8, 19, 112, 107, 12, 181, 112, 176, 136, 28, 22, 28, 29, 34, 37, 171, 7, 112, 26, 1, 74, 112, 90, 28,
|
||||||
|
2, 50, 160, 104, 20, 34, 128, 1, 18, 24, 164, 44, 0, 208, 42, 147, 0, 35, 2, 147, 1, 35, 0, 147, 2, 147, 3, 147, 4,
|
||||||
|
35, 10, 147, 5, 28, 34, 35, 8, 247, 255, 251, 174, 40, 0, 219, 29, 168, 6, 28, 33, 34, 4, 240, 2, 248, 171, 45, 0, 208,
|
||||||
|
1, 155, 6, 96, 43, 29, 33, 168, 6, 34, 4, 240, 2, 248, 162, 46, 0, 208, 1, 155, 6, 96, 51, 35, 128, 154, 6, 1, 27, 32,
|
||||||
|
0, 66, 154, 209, 5, 75, 4, 34, 1, 96, 26, 224, 1, 32, 4, 66, 64, 176, 8, 188, 112, 188, 2, 71, 8, 19, 112, 107, 12,
|
||||||
|
181, 240, 176, 131, 123, 131, 28, 15, 28, 5, 66, 187, 217, 72, 78, 40, 73, 40, 72, 41, 96, 49, 33, 0, 247, 254, 249,
|
||||||
|
212, 75, 39, 28, 40, 96, 51, 28, 57, 247, 255, 252, 204, 30, 4, 219, 53, 74, 33, 28, 57, 96, 50, 28, 40, 247, 255, 255,
|
||||||
|
86, 28, 4, 28, 33, 72, 32, 247, 254, 249, 193, 44, 0, 219, 40, 28, 43, 51, 160, 104, 26, 35, 128, 1, 27, 92, 211, 33,
|
||||||
|
31, 64, 25, 72, 27, 247, 254, 249, 180, 28, 59, 29, 62, 51, 20, 0, 182, 0, 155, 25, 170, 147, 1, 28, 57, 24, 235, 28,
|
||||||
|
40, 247, 255, 255, 130, 153, 1, 28, 4, 89, 75, 89, 114, 72, 18, 28, 33, 247, 254, 249, 160, 89, 114, 75, 17, 66, 154,
|
||||||
|
217, 3, 154, 1, 89, 83, 43, 9, 216, 1, 36, 33, 66, 100, 74, 6, 75, 5, 96, 26, 224, 1, 36, 3, 66, 100, 176, 3, 28, 32,
|
||||||
|
188, 240, 188, 2, 71, 8, 70, 192, 19, 112, 96, 56, 0, 15, 66, 64, 19, 112, 103, 231, 1, 49, 45, 0, 19, 112, 104, 2,
|
||||||
|
19, 112, 104, 22, 19, 112, 104, 43, 0, 0, 1, 255, 181, 240, 176, 141, 175, 9, 37, 40, 112, 61, 1, 77, 112, 125, 14,
|
||||||
|
21, 112, 189, 70, 110, 12, 21, 36, 0, 112, 253, 113, 122, 10, 21, 54, 47, 10, 26, 112, 52, 113, 61, 113, 188, 113, 250,
|
||||||
|
114, 59, 114, 124, 123, 130, 66, 138, 217, 28, 29, 10, 0, 146, 88, 18, 146, 7, 42, 0, 208, 22, 77, 15, 34, 1, 96, 42,
|
||||||
|
154, 7, 151, 0, 67, 83, 34, 10, 146, 1, 34, 6, 146, 5, 154, 18, 148, 2, 150, 3, 148, 4, 247, 255, 250, 240, 96, 44,
|
||||||
|
40, 0, 221, 7, 120, 51, 43, 0, 209, 3, 224, 3, 32, 3, 66, 64, 224, 0, 72, 3, 176, 13, 188, 240, 188, 2, 71, 8, 70, 192,
|
||||||
|
19, 112, 107, 28, 255, 255, 216, 234, 181, 240, 176, 141, 147, 7, 1, 75, 175, 9, 37, 42, 70, 156, 112, 61, 35, 8, 70,
|
||||||
|
101, 67, 43, 112, 123, 14, 21, 155, 7, 112, 189, 70, 110, 12, 21, 36, 0, 112, 253, 113, 122, 10, 21, 54, 47, 10, 26,
|
||||||
|
112, 52, 113, 61, 113, 188, 113, 250, 114, 59, 114, 124, 123, 130, 66, 138, 217, 32, 29, 10, 0, 146, 88, 18, 70, 148,
|
||||||
|
69, 164, 208, 26, 77, 17, 35, 1, 96, 43, 155, 7, 151, 0, 70, 98, 67, 90, 70, 148, 34, 1, 146, 2, 34, 6, 146, 5, 39,
|
||||||
|
10, 154, 18, 70, 99, 151, 1, 150, 3, 148, 4, 247, 255, 250, 162, 96, 44, 40, 0, 221, 7, 120, 51, 43, 0, 209, 3, 224,
|
||||||
|
3, 32, 3, 66, 64, 224, 0, 72, 3, 176, 13, 188, 240, 188, 2, 71, 8, 70, 192, 19, 112, 107, 28, 255, 255, 216, 234, 181,
|
||||||
|
240, 176, 135, 28, 28, 147, 2, 28, 11, 51, 4, 0, 155, 145, 3, 88, 25, 28, 6, 28, 11, 67, 99, 32, 128, 2, 64, 28, 23,
|
||||||
|
66, 131, 217, 2, 240, 2, 248, 151, 144, 2, 155, 3, 32, 1, 51, 4, 0, 155, 66, 64, 147, 5, 224, 28, 154, 2, 28, 37, 66,
|
||||||
|
148, 217, 0, 28, 21, 4, 43, 12, 27, 147, 4, 155, 12, 28, 48, 147, 0, 153, 3, 28, 58, 155, 4, 247, 255, 255, 67, 40,
|
||||||
|
0, 219, 12, 154, 4, 25, 127, 26, 164, 154, 5, 4, 36, 89, 147, 12, 36, 67, 93, 155, 12, 25, 91, 147, 12, 44, 0, 209,
|
||||||
|
224, 176, 7, 188, 240, 188, 2, 71, 8, 181, 240, 176, 135, 28, 28, 147, 2, 28, 11, 51, 4, 0, 155, 145, 3, 88, 25, 28,
|
||||||
|
6, 28, 11, 67, 99, 32, 128, 2, 64, 28, 23, 66, 131, 217, 2, 240, 2, 248, 89, 144, 2, 155, 3, 32, 1, 51, 4, 0, 155, 66,
|
||||||
|
64, 147, 5, 224, 28, 154, 2, 28, 37, 66, 148, 217, 0, 28, 21, 4, 43, 12, 27, 147, 4, 155, 12, 28, 48, 147, 0, 153, 3,
|
||||||
|
28, 58, 155, 4, 247, 255, 255, 73, 40, 0, 219, 12, 154, 4, 25, 127, 26, 164, 154, 5, 4, 36, 89, 147, 12, 36, 67, 93,
|
||||||
|
155, 12, 25, 91, 147, 12, 44, 0, 209, 224, 176, 7, 188, 240, 188, 2, 71, 8, 181, 240, 176, 139, 74, 135, 35, 0, 128,
|
||||||
|
19, 74, 135, 36, 0, 128, 19, 75, 134, 74, 135, 112, 28, 75, 135, 79, 135, 112, 28, 35, 120, 144, 8, 66, 91, 96, 19,
|
||||||
|
28, 56, 153, 8, 247, 255, 251, 218, 40, 0, 218, 0, 224, 241, 34, 1, 75, 129, 115, 186, 104, 25, 41, 0, 208, 74, 121,
|
||||||
|
91, 43, 0, 209, 3, 75, 126, 120, 27, 66, 26, 208, 29, 76, 122, 35, 0, 115, 163, 77, 124, 75, 124, 38, 1, 96, 43, 28,
|
||||||
|
35, 51, 144, 104, 24, 136, 227, 33, 161, 147, 0, 28, 35, 51, 14, 147, 2, 34, 254, 35, 0, 150, 1, 247, 254, 250, 171,
|
||||||
|
75, 117, 96, 43, 40, 0, 218, 1, 115, 166, 224, 188, 123, 163, 51, 1, 115, 163, 75, 108, 72, 113, 121, 29, 28, 41, 247,
|
||||||
|
254, 248, 34, 78, 104, 28, 41, 28, 48, 247, 255, 254, 59, 28, 4, 28, 33, 72, 108, 247, 254, 248, 24, 28, 163, 43, 1,
|
||||||
|
216, 9, 28, 48, 247, 255, 253, 154, 74, 94, 35, 121, 66, 91, 96, 19, 34, 0, 75, 91, 224, 61, 44, 0, 218, 0, 224, 153,
|
||||||
|
75, 88, 34, 1, 112, 26, 75, 89, 112, 29, 224, 139, 38, 1, 113, 92, 37, 0, 28, 60, 150, 6, 55, 144, 28, 40, 30, 67, 65,
|
||||||
|
152, 144, 9, 40, 0, 209, 5, 75, 84, 120, 27, 7, 217, 213, 1, 46, 0, 209, 41, 72, 87, 28, 41, 247, 253, 255, 236, 6,
|
||||||
|
43, 14, 27, 28, 25, 72, 76, 147, 5, 247, 255, 254, 3, 144, 7, 153, 7, 72, 80, 247, 253, 255, 224, 155, 7, 51, 2, 43,
|
||||||
|
1, 216, 16, 154, 9, 42, 0, 208, 13, 74, 73, 75, 70, 72, 67, 96, 26, 247, 255, 253, 91, 74, 63, 35, 121, 66, 91, 96,
|
||||||
|
19, 75, 60, 34, 0, 112, 26, 224, 105, 155, 7, 43, 0, 218, 59, 46, 0, 208, 52, 78, 61, 75, 62, 73, 66, 96, 51, 136, 227,
|
||||||
|
32, 0, 96, 8, 115, 160, 104, 56, 147, 0, 28, 35, 34, 1, 51, 14, 146, 1, 147, 2, 33, 161, 35, 0, 34, 254, 247, 254, 250,
|
||||||
|
44, 75, 53, 144, 5, 96, 51, 40, 0, 218, 5, 73, 55, 35, 1, 32, 0, 115, 163, 96, 8, 224, 5, 123, 163, 34, 1, 51, 1, 115,
|
||||||
|
163, 75, 42, 113, 90, 75, 40, 72, 49, 123, 155, 153, 5, 28, 26, 147, 6, 247, 253, 255, 153, 75, 38, 38, 0, 120, 27,
|
||||||
|
7, 216, 213, 3, 153, 5, 15, 206, 224, 0, 53, 1, 154, 6, 66, 149, 219, 144, 224, 29, 33, 23, 70, 104, 74, 29, 92, 8,
|
||||||
|
35, 1, 96, 19, 113, 16, 154, 8, 152, 8, 137, 17, 74, 19, 128, 17, 137, 65, 74, 19, 128, 17, 74, 19, 70, 105, 112, 19,
|
||||||
|
34, 23, 75, 19, 92, 81, 112, 25, 74, 23, 75, 21, 32, 0, 96, 26, 75, 14, 34, 0, 96, 26, 224, 14, 74, 12, 35, 122, 66,
|
||||||
|
91, 96, 19, 72, 12, 247, 255, 252, 239, 75, 8, 34, 0, 112, 26, 72, 20, 247, 253, 255, 97, 32, 3, 66, 64, 176, 11, 188,
|
||||||
|
240, 188, 2, 71, 8, 70, 192, 19, 112, 107, 24, 19, 112, 107, 32, 19, 112, 107, 60, 19, 112, 107, 0, 19, 112, 96, 64,
|
||||||
|
19, 114, 197, 128, 19, 112, 107, 36, 19, 112, 1, 14, 19, 112, 96, 56, 0, 152, 150, 128, 0, 15, 66, 64, 19, 112, 104,
|
||||||
|
98, 19, 112, 104, 128, 19, 112, 104, 103, 19, 112, 107, 84, 19, 112, 104, 157, 19, 112, 104, 198, 181, 8, 74, 10, 104,
|
||||||
|
19, 43, 0, 208, 13, 75, 9, 33, 16, 112, 25, 35, 0, 73, 8, 96, 19, 74, 8, 112, 11, 96, 19, 72, 7, 33, 0, 34, 20, 240,
|
||||||
|
1, 254, 17, 188, 8, 188, 1, 71, 0, 19, 112, 107, 56, 19, 112, 96, 64, 19, 112, 107, 60, 19, 112, 107, 84, 19, 112, 107,
|
||||||
|
36, 181, 240, 176, 135, 75, 120, 36, 0, 104, 29, 45, 0, 208, 0, 224, 229, 75, 118, 32, 0, 104, 27, 104, 155, 96, 157,
|
||||||
|
247, 253, 248, 99, 74, 116, 35, 100, 66, 91, 96, 19, 74, 115, 35, 1, 96, 19, 74, 114, 72, 115, 112, 21, 74, 115, 112,
|
||||||
|
19, 247, 253, 254, 251, 75, 114, 120, 27, 43, 1, 208, 4, 43, 2, 208, 6, 34, 0, 146, 4, 224, 6, 35, 1, 147, 4, 36, 1,
|
||||||
|
224, 2, 34, 1, 146, 4, 36, 0, 0, 167, 224, 176, 75, 99, 74, 105, 104, 29, 0, 163, 25, 27, 0, 219, 24, 235, 103, 92,
|
||||||
|
111, 27, 96, 20, 43, 0, 209, 54, 104, 171, 34, 1, 51, 68, 25, 219, 104, 27, 66, 26, 209, 2, 28, 32, 247, 253, 252, 223,
|
||||||
|
78, 88, 34, 1, 104, 51, 104, 155, 51, 68, 25, 219, 104, 27, 66, 26, 208, 35, 28, 32, 247, 254, 251, 253, 35, 140, 0,
|
||||||
|
219, 24, 192, 40, 1, 216, 4, 35, 100, 74, 80, 66, 91, 96, 19, 224, 130, 28, 32, 247, 254, 250, 140, 144, 3, 32, 20,
|
||||||
|
247, 253, 249, 176, 104, 51, 104, 155, 51, 68, 25, 219, 104, 26, 155, 3, 43, 0, 219, 4, 75, 77, 64, 26, 75, 77, 66,
|
||||||
|
154, 208, 2, 28, 32, 247, 254, 251, 220, 0, 160, 25, 0, 0, 192, 24, 43, 111, 27, 43, 0, 208, 100, 75, 64, 34, 1, 48,
|
||||||
|
88, 96, 26, 24, 40, 247, 255, 254, 44, 144, 3, 40, 0, 209, 87, 75, 56, 34, 1, 96, 26, 79, 65, 74, 57, 96, 16, 28, 56,
|
||||||
|
247, 252, 255, 230, 77, 52, 34, 4, 104, 43, 72, 62, 104, 155, 96, 154, 247, 253, 254, 132, 32, 100, 247, 253, 249, 123,
|
||||||
|
32, 128, 1, 0, 240, 0, 253, 105, 78, 57, 75, 57, 34, 1, 96, 51, 75, 57, 144, 4, 112, 26, 104, 43, 154, 3, 104, 155,
|
||||||
|
32, 0, 96, 154, 247, 252, 255, 201, 72, 53, 247, 253, 254, 108, 75, 52, 34, 0, 120, 25, 155, 4, 72, 51, 147, 0, 35,
|
||||||
|
1, 247, 255, 253, 123, 144, 5, 28, 56, 247, 252, 255, 185, 104, 43, 34, 4, 104, 155, 96, 154, 70, 107, 34, 15, 92, 210,
|
||||||
|
75, 40, 152, 4, 112, 26, 75, 43, 96, 51, 240, 0, 253, 91, 155, 5, 43, 0, 218, 7, 72, 40, 247, 253, 254, 75, 28, 32,
|
||||||
|
247, 253, 252, 132, 76, 38, 224, 27, 72, 38, 247, 253, 254, 67, 75, 38, 104, 27, 43, 0, 208, 20, 52, 2, 224, 18, 28,
|
||||||
|
32, 247, 253, 252, 118, 52, 1, 55, 4, 154, 4, 66, 148, 220, 0, 231, 74, 72, 18, 247, 252, 255, 139, 74, 7, 104, 19,
|
||||||
|
34, 4, 104, 155, 96, 154, 75, 5, 104, 28, 176, 7, 28, 32, 188, 240, 188, 2, 71, 8, 70, 192, 19, 112, 107, 56, 19, 112,
|
||||||
|
96, 60, 19, 112, 107, 0, 19, 112, 107, 84, 19, 112, 107, 60, 19, 112, 104, 227, 19, 112, 1, 15, 19, 112, 1, 12, 19,
|
||||||
|
112, 107, 80, 0, 0, 57, 5, 0, 0, 16, 5, 19, 112, 17, 29, 19, 112, 105, 118, 19, 112, 96, 56, 0, 152, 150, 128, 19, 112,
|
||||||
|
106, 248, 19, 112, 105, 167, 19, 112, 96, 64, 19, 114, 197, 128, 0, 15, 66, 64, 19, 112, 105, 140, 255, 255, 251, 162,
|
||||||
|
19, 112, 105, 164, 19, 112, 107, 12, 181, 0, 30, 3, 208, 1, 34, 0, 96, 26, 74, 12, 32, 0, 120, 18, 42, 1, 209, 16, 74,
|
||||||
|
10, 120, 18, 42, 16, 208, 12, 43, 0, 208, 4, 50, 4, 73, 8, 0, 146, 88, 82, 96, 26, 75, 5, 120, 26, 75, 5, 50, 20, 0,
|
||||||
|
146, 88, 208, 188, 2, 71, 8, 70, 192, 19, 112, 107, 60, 19, 112, 96, 64, 19, 114, 197, 128, 181, 240, 176, 139, 75,
|
||||||
|
78, 104, 27, 43, 0, 209, 0, 224, 139, 75, 77, 34, 16, 112, 26, 75, 76, 120, 26, 75, 76, 42, 0, 208, 1, 74, 76, 224,
|
||||||
|
0, 74, 76, 78, 76, 96, 26, 172, 4, 35, 0, 28, 53, 130, 99, 130, 163, 53, 144, 28, 33, 104, 40, 247, 254, 251, 0, 75,
|
||||||
|
71, 121, 34, 121, 153, 66, 145, 209, 23, 121, 217, 121, 98, 66, 145, 209, 19, 137, 25, 137, 34, 66, 145, 209, 15, 137,
|
||||||
|
89, 137, 98, 66, 145, 209, 11, 123, 25, 123, 162, 66, 145, 209, 7, 123, 89, 123, 226, 66, 145, 209, 3, 123, 154, 124,
|
||||||
|
35, 66, 154, 208, 6, 168, 4, 247, 253, 252, 101, 72, 56, 247, 253, 253, 143, 224, 80, 28, 32, 247, 253, 252, 94, 74,
|
||||||
|
54, 75, 47, 104, 40, 96, 26, 120, 49, 247, 254, 248, 123, 40, 0, 219, 70, 104, 178, 42, 0, 208, 7, 6, 18, 104, 40, 121,
|
||||||
|
241, 14, 18, 247, 254, 248, 98, 40, 0, 219, 61, 76, 41, 35, 0, 115, 163, 77, 36, 75, 42, 39, 1, 96, 43, 28, 35, 51,
|
||||||
|
144, 104, 24, 136, 227, 33, 161, 147, 0, 28, 35, 51, 14, 147, 2, 34, 254, 35, 0, 151, 1, 247, 253, 255, 220, 75, 28,
|
||||||
|
96, 43, 40, 0, 218, 6, 115, 167, 28, 32, 33, 0, 247, 254, 254, 77, 72, 30, 224, 34, 123, 163, 78, 25, 51, 1, 115, 163,
|
||||||
|
75, 28, 28, 32, 96, 43, 121, 49, 247, 255, 248, 75, 75, 18, 96, 43, 40, 0, 219, 17, 121, 49, 28, 32, 247, 255, 250,
|
||||||
|
213, 40, 0, 219, 13, 121, 50, 75, 9, 112, 26, 75, 19, 112, 31, 224, 8, 72, 19, 224, 6, 72, 19, 224, 4, 72, 19, 224,
|
||||||
|
2, 72, 19, 224, 0, 72, 19, 176, 11, 188, 240, 188, 2, 71, 8, 19, 112, 107, 56, 19, 112, 96, 64, 19, 112, 1, 15, 19,
|
||||||
|
112, 96, 56, 0, 15, 66, 64, 0, 3, 13, 64, 19, 114, 197, 128, 19, 112, 107, 36, 19, 112, 101, 128, 0, 152, 150, 128,
|
||||||
|
255, 255, 252, 20, 1, 49, 45, 0, 19, 112, 107, 60, 255, 255, 252, 15, 255, 255, 252, 23, 255, 255, 252, 22, 255, 255,
|
||||||
|
252, 19, 255, 255, 252, 18, 181, 240, 176, 131, 75, 57, 76, 58, 120, 26, 38, 1, 30, 83, 65, 154, 75, 56, 96, 34, 104,
|
||||||
|
27, 43, 0, 208, 99, 75, 55, 0, 146, 104, 27, 104, 155, 28, 25, 49, 68, 24, 138, 104, 18, 66, 22, 208, 89, 34, 0, 32,
|
||||||
|
0, 96, 154, 247, 252, 254, 74, 104, 32, 247, 254, 248, 191, 30, 7, 218, 3, 104, 32, 247, 254, 248, 186, 28, 7, 32, 60,
|
||||||
|
247, 252, 255, 222, 77, 41, 72, 42, 104, 43, 28, 57, 104, 154, 75, 37, 50, 68, 104, 27, 38, 1, 0, 155, 24, 211, 104,
|
||||||
|
27, 28, 26, 147, 1, 247, 253, 252, 212, 76, 32, 35, 1, 96, 35, 47, 0, 219, 48, 155, 1, 74, 32, 64, 26, 75, 32, 66, 154,
|
||||||
|
209, 42, 74, 32, 35, 0, 112, 19, 34, 0, 96, 34, 247, 255, 254, 242, 74, 29, 75, 30, 96, 26, 40, 0, 219, 12, 74, 26,
|
||||||
|
35, 0, 112, 22, 96, 35, 72, 27, 247, 252, 254, 16, 104, 43, 34, 4, 104, 155, 38, 0, 96, 154, 224, 17, 28, 57, 72, 23,
|
||||||
|
96, 38, 247, 253, 252, 171, 75, 17, 34, 0, 112, 26, 32, 100, 247, 252, 255, 159, 72, 17, 247, 252, 253, 252, 104, 43,
|
||||||
|
34, 4, 104, 155, 96, 154, 32, 100, 247, 252, 255, 149, 176, 3, 28, 48, 188, 240, 188, 2, 71, 8, 19, 112, 1, 12, 19,
|
||||||
|
112, 107, 80, 19, 112, 107, 84, 19, 112, 96, 60, 19, 112, 105, 185, 0, 0, 49, 5, 0, 0, 16, 5, 19, 112, 107, 60, 0, 15,
|
||||||
|
66, 64, 19, 112, 96, 56, 19, 112, 17, 29, 19, 112, 105, 213, 181, 240, 176, 131, 75, 30, 34, 0, 104, 27, 146, 1, 43,
|
||||||
|
0, 208, 50, 247, 255, 255, 104, 75, 27, 104, 27, 43, 0, 209, 44, 75, 26, 120, 27, 43, 0, 208, 40, 77, 25, 79, 26, 76,
|
||||||
|
26, 78, 27, 96, 47, 121, 49, 28, 32, 247, 255, 249, 243, 40, 0, 219, 29, 96, 47, 121, 49, 28, 32, 28, 11, 29, 10, 51,
|
||||||
|
20, 0, 146, 0, 155, 25, 18, 25, 27, 247, 255, 250, 47, 40, 0, 219, 15, 75, 17, 104, 26, 42, 0, 208, 7, 121, 49, 35,
|
||||||
|
128, 49, 4, 0, 137, 89, 9, 1, 27, 66, 153, 209, 3, 28, 19, 30, 90, 65, 147, 147, 1, 152, 1, 176, 3, 188, 240, 188, 2,
|
||||||
|
71, 8, 19, 112, 107, 56, 19, 112, 107, 84, 19, 112, 107, 60, 19, 112, 96, 56, 0, 15, 66, 64, 19, 114, 197, 128, 19,
|
||||||
|
112, 107, 36, 19, 112, 107, 12, 181, 240, 176, 135, 75, 66, 144, 3, 104, 27, 146, 4, 43, 0, 209, 7, 75, 64, 104, 27,
|
||||||
|
43, 0, 208, 3, 0, 66, 75, 63, 8, 82, 96, 26, 75, 62, 104, 27, 43, 0, 208, 6, 75, 61, 104, 26, 42, 1, 221, 2, 34, 1,
|
||||||
|
96, 26, 224, 101, 4, 9, 12, 9, 79, 56, 38, 4, 36, 0, 145, 5, 247, 255, 254, 255, 30, 67, 65, 152, 104, 59, 66, 64, 64,
|
||||||
|
4, 43, 0, 208, 3, 74, 50, 104, 19, 43, 3, 208, 79, 44, 0, 219, 3, 75, 48, 120, 27, 43, 1, 208, 4, 75, 45, 34, 1, 36,
|
||||||
|
1, 96, 26, 66, 100, 75, 43, 104, 27, 43, 0, 209, 61, 75, 38, 104, 26, 75, 42, 42, 0, 208, 1, 74, 41, 224, 0, 74, 41,
|
||||||
|
96, 26, 28, 99, 208, 24, 32, 0, 247, 252, 253, 61, 77, 39, 34, 0, 104, 43, 72, 38, 104, 155, 96, 154, 154, 4, 75, 37,
|
||||||
|
120, 25, 155, 5, 146, 0, 154, 3, 247, 255, 250, 237, 28, 4, 72, 34, 247, 252, 253, 43, 104, 43, 34, 4, 104, 155, 96,
|
||||||
|
154, 74, 32, 75, 24, 96, 26, 44, 0, 218, 2, 75, 20, 34, 1, 96, 26, 75, 18, 104, 27, 43, 0, 208, 3, 75, 17, 104, 27,
|
||||||
|
43, 0, 209, 15, 75, 15, 104, 27, 43, 0, 209, 5, 75, 14, 120, 27, 43, 1, 209, 1, 44, 0, 218, 7, 62, 1, 46, 0, 209, 162,
|
||||||
|
67, 228, 15, 224, 224, 2, 32, 0, 224, 0, 32, 1, 176, 7, 188, 240, 188, 2, 71, 8, 19, 112, 106, 240, 19, 112, 107, 12,
|
||||||
|
19, 112, 106, 192, 19, 112, 106, 196, 19, 112, 107, 84, 19, 112, 107, 60, 19, 112, 96, 56, 0, 152, 150, 128, 0, 45,
|
||||||
|
198, 192, 19, 112, 96, 60, 19, 114, 197, 128, 19, 112, 96, 64, 19, 112, 17, 29, 0, 15, 66, 64, 181, 240, 176, 133, 75,
|
||||||
|
39, 28, 7, 104, 27, 28, 22, 32, 0, 43, 0, 209, 67, 4, 9, 12, 9, 36, 0, 145, 3, 247, 255, 254, 111, 40, 0, 208, 2, 44,
|
||||||
|
0, 219, 5, 224, 0, 36, 0, 74, 31, 120, 19, 43, 1, 208, 4, 75, 30, 34, 1, 36, 1, 96, 26, 66, 100, 75, 27, 104, 27, 43,
|
||||||
|
0, 209, 234, 73, 26, 74, 27, 96, 17, 28, 98, 208, 22, 77, 26, 32, 0, 104, 42, 104, 146, 96, 147, 247, 252, 252, 182,
|
||||||
|
75, 23, 28, 58, 120, 25, 72, 23, 155, 3, 150, 0, 247, 255, 250, 170, 28, 4, 72, 21, 247, 252, 252, 170, 104, 43, 34,
|
||||||
|
4, 104, 155, 96, 154, 74, 18, 75, 13, 96, 26, 44, 0, 218, 2, 75, 9, 34, 1, 96, 26, 75, 7, 104, 27, 43, 0, 209, 194,
|
||||||
|
44, 0, 219, 192, 32, 1, 176, 5, 188, 240, 188, 2, 71, 8, 70, 192, 19, 112, 107, 12, 19, 112, 107, 60, 19, 112, 107,
|
||||||
|
84, 0, 45, 198, 192, 19, 112, 96, 56, 19, 112, 96, 60, 19, 112, 96, 64, 19, 114, 197, 128, 19, 112, 17, 29, 0, 15, 66,
|
||||||
|
64, 181, 240, 176, 137, 74, 95, 104, 19, 43, 0, 209, 6, 75, 94, 104, 27, 105, 153, 96, 17, 106, 26, 75, 93, 96, 26,
|
||||||
|
75, 92, 77, 90, 104, 28, 38, 0, 28, 55, 104, 43, 55, 8, 0, 191, 80, 252, 28, 32, 33, 0, 34, 96, 240, 1, 249, 245, 104,
|
||||||
|
43, 33, 96, 88, 248, 240, 0, 249, 214, 52, 127, 33, 31, 54, 1, 67, 140, 46, 8, 209, 234, 37, 8, 38, 31, 28, 32, 33,
|
||||||
|
0, 34, 96, 240, 1, 249, 227, 61, 1, 28, 32, 33, 96, 52, 127, 240, 0, 249, 195, 67, 180, 45, 0, 209, 241, 75, 72, 34,
|
||||||
|
255, 96, 28, 75, 68, 39, 128, 104, 29, 35, 255, 2, 18, 4, 27, 76, 69, 38, 0, 5, 255, 146, 2, 147, 3, 33, 0, 96, 37,
|
||||||
|
34, 96, 28, 40, 240, 1, 249, 198, 28, 40, 240, 0, 249, 152, 28, 50, 100, 104, 104, 35, 30, 81, 65, 138, 5, 210, 96,
|
||||||
|
90, 104, 35, 34, 0, 96, 154, 104, 35, 33, 31, 97, 159, 53, 127, 67, 141, 104, 34, 28, 40, 146, 5, 240, 0, 249, 132,
|
||||||
|
144, 6, 28, 40, 240, 0, 249, 128, 144, 1, 28, 40, 240, 0, 249, 124, 144, 7, 28, 40, 240, 0, 249, 120, 35, 255, 2, 27,
|
||||||
|
153, 2, 147, 4, 34, 255, 155, 1, 4, 18, 64, 11, 146, 1, 153, 3, 154, 7, 2, 27, 64, 10, 10, 18, 67, 19, 14, 0, 154, 6,
|
||||||
|
67, 3, 32, 224, 64, 16, 33, 2, 67, 8, 154, 5, 6, 0, 67, 3, 96, 19, 104, 34, 35, 128, 4, 91, 97, 19, 104, 34, 33, 96,
|
||||||
|
97, 83, 204, 1, 54, 1, 240, 0, 249, 100, 46, 6, 209, 175, 76, 22, 77, 26, 104, 32, 105, 110, 240, 0, 249, 75, 144, 2,
|
||||||
|
104, 32, 240, 0, 249, 71, 28, 7, 104, 32, 240, 0, 249, 67, 144, 3, 104, 32, 240, 0, 249, 63, 155, 4, 153, 1, 64, 31,
|
||||||
|
155, 3, 2, 63, 64, 11, 10, 27, 67, 31, 154, 2, 14, 3, 28, 56, 67, 24, 35, 224, 64, 19, 33, 2, 67, 11, 6, 27, 67, 24,
|
||||||
|
96, 48, 105, 104, 33, 96, 240, 0, 249, 57, 176, 9, 188, 240, 188, 1, 71, 0, 70, 192, 19, 112, 107, 76, 19, 112, 96,
|
||||||
|
60, 19, 112, 106, 236, 19, 112, 107, 8, 19, 114, 195, 160, 181, 248, 75, 16, 39, 128, 104, 28, 38, 0, 4, 127, 28, 32,
|
||||||
|
247, 252, 253, 241, 46, 3, 208, 15, 28, 37, 35, 31, 53, 127, 67, 157, 107, 104, 240, 1, 248, 182, 96, 103, 96, 32, 33,
|
||||||
|
96, 28, 32, 240, 0, 249, 18, 54, 1, 28, 44, 231, 234, 28, 32, 33, 96, 240, 0, 249, 11, 188, 248, 188, 1, 71, 0, 19,
|
||||||
|
112, 107, 8, 181, 240, 176, 131, 247, 255, 255, 12, 247, 255, 255, 214, 76, 65, 75, 66, 104, 34, 104, 24, 77, 65, 97,
|
||||||
|
144, 104, 89, 78, 65, 97, 209, 104, 154, 79, 64, 96, 42, 104, 218, 105, 27, 96, 50, 96, 59, 33, 96, 240, 0, 249, 1,
|
||||||
|
104, 35, 33, 0, 105, 154, 100, 211, 105, 154, 100, 145, 105, 155, 28, 24, 147, 1, 240, 0, 248, 209, 155, 1, 104, 34,
|
||||||
|
100, 88, 104, 59, 105, 145, 108, 91, 34, 255, 2, 18, 64, 26, 2, 16, 34, 255, 4, 18, 64, 26, 10, 18, 67, 2, 14, 24, 67,
|
||||||
|
2, 32, 224, 64, 3, 39, 2, 67, 59, 6, 24, 28, 19, 67, 3, 96, 11, 104, 35, 34, 128, 105, 153, 4, 18, 96, 74, 105, 154,
|
||||||
|
33, 0, 96, 145, 105, 153, 34, 128, 5, 210, 97, 138, 105, 153, 34, 128, 4, 82, 97, 10, 105, 153, 97, 74, 105, 152, 33,
|
||||||
|
96, 240, 0, 248, 179, 104, 35, 33, 96, 105, 216, 240, 0, 248, 194, 104, 35, 33, 0, 105, 218, 100, 211, 105, 218, 100,
|
||||||
|
145, 105, 223, 28, 56, 240, 0, 248, 147, 33, 96, 100, 120, 104, 40, 240, 0, 248, 179, 104, 47, 104, 35, 28, 56, 100,
|
||||||
|
251, 35, 0, 100, 187, 240, 0, 248, 134, 33, 96, 100, 120, 104, 40, 240, 0, 248, 146, 104, 48, 33, 96, 240, 0, 248, 162,
|
||||||
|
104, 53, 104, 35, 33, 0, 100, 235, 100, 169, 28, 40, 240, 0, 248, 117, 33, 96, 100, 104, 104, 48, 240, 0, 248, 129,
|
||||||
|
176, 3, 188, 240, 188, 1, 71, 0, 70, 192, 19, 112, 96, 60, 19, 114, 195, 160, 19, 112, 106, 244, 19, 112, 107, 72, 19,
|
||||||
|
112, 107, 68, 181, 248, 76, 35, 75, 35, 96, 35, 240, 0, 248, 74, 40, 0, 219, 58, 240, 0, 249, 117, 74, 32, 104, 131,
|
||||||
|
96, 32, 96, 26, 104, 32, 35, 1, 104, 130, 104, 17, 66, 11, 209, 252, 33, 252, 240, 0, 248, 91, 38, 128, 39, 128, 76,
|
||||||
|
23, 37, 0, 4, 118, 1, 127, 104, 35, 33, 4, 108, 219, 81, 94, 104, 35, 108, 219, 89, 88, 53, 4, 240, 0, 248, 75, 66,
|
||||||
|
189, 209, 243, 247, 255, 255, 65, 104, 35, 34, 2, 51, 84, 112, 26, 247, 252, 255, 185, 104, 35, 32, 0, 104, 154, 105,
|
||||||
|
155, 108, 91, 97, 147, 104, 35, 34, 4, 104, 155, 96, 154, 104, 35, 74, 8, 104, 155, 96, 26, 104, 35, 104, 155, 104,
|
||||||
|
27, 224, 1, 32, 1, 66, 64, 188, 248, 188, 2, 71, 8, 19, 112, 96, 60, 19, 114, 198, 36, 0, 1, 0, 32, 0, 1, 0, 33, 181,
|
||||||
|
8, 33, 224, 72, 4, 2, 9, 240, 1, 249, 66, 75, 3, 96, 24, 23, 192, 188, 8, 188, 2, 71, 8, 19, 112, 163, 128, 19, 112,
|
||||||
|
96, 68, 71, 112, 71, 112, 181, 16, 28, 4, 240, 1, 249, 62, 28, 32, 188, 16, 188, 2, 71, 8, 181, 16, 28, 4, 240, 1, 249,
|
||||||
|
54, 28, 32, 188, 16, 188, 2, 71, 8, 181, 16, 28, 4, 240, 1, 249, 46, 28, 32, 188, 16, 188, 2, 71, 8, 181, 8, 240, 1,
|
||||||
|
249, 71, 188, 8, 188, 1, 71, 0, 181, 8, 240, 1, 249, 65, 188, 8, 188, 1, 71, 0, 181, 8, 240, 1, 249, 59, 188, 8, 188,
|
||||||
|
1, 71, 0, 181, 8, 75, 12, 28, 1, 34, 32, 104, 24, 240, 1, 249, 45, 40, 0, 209, 13, 72, 9, 240, 1, 249, 4, 240, 0, 249,
|
||||||
|
63, 32, 200, 247, 252, 251, 253, 240, 0, 249, 68, 32, 200, 247, 252, 251, 248, 231, 244, 188, 8, 188, 2, 71, 8, 19,
|
||||||
|
112, 96, 68, 19, 112, 105, 237, 181, 8, 75, 4, 28, 1, 104, 24, 240, 1, 248, 216, 188, 8, 188, 1, 71, 0, 70, 192, 19,
|
||||||
|
112, 96, 68, 181, 248, 76, 13, 28, 15, 104, 33, 28, 30, 28, 24, 28, 21, 67, 81, 240, 1, 248, 228, 28, 56, 28, 41, 28,
|
||||||
|
50, 247, 255, 252, 173, 35, 1, 40, 0, 208, 5, 104, 33, 28, 48, 67, 105, 240, 1, 248, 247, 35, 0, 28, 24, 188, 248, 188,
|
||||||
|
2, 71, 8, 19, 114, 199, 32, 181, 16, 76, 11, 104, 32, 40, 0, 208, 3, 240, 0, 252, 39, 35, 0, 96, 35, 76, 8, 104, 35,
|
||||||
|
43, 0, 209, 3, 72, 7, 247, 251, 252, 132, 96, 32, 74, 6, 35, 1, 66, 91, 96, 19, 188, 16, 188, 1, 71, 0, 19, 112, 107,
|
||||||
|
96, 19, 112, 107, 88, 0, 0, 128, 32, 19, 112, 96, 24, 181, 56, 75, 14, 104, 24, 40, 0, 208, 1, 247, 251, 252, 139, 76,
|
||||||
|
12, 75, 10, 104, 32, 37, 0, 96, 29, 40, 0, 208, 2, 240, 0, 251, 254, 96, 37, 75, 8, 104, 24, 40, 0, 208, 1, 240, 0,
|
||||||
|
251, 91, 75, 5, 34, 0, 96, 26, 188, 56, 188, 1, 71, 0, 70, 192, 19, 112, 107, 88, 19, 112, 107, 96, 19, 112, 107, 92,
|
||||||
|
181, 240, 176, 135, 75, 37, 28, 7, 104, 24, 145, 5, 40, 0, 208, 1, 247, 251, 252, 100, 75, 33, 77, 34, 34, 0, 96, 26,
|
||||||
|
104, 43, 43, 0, 209, 23, 247, 255, 249, 93, 78, 31, 36, 0, 28, 48, 247, 255, 250, 124, 75, 29, 96, 24, 40, 0, 208, 43,
|
||||||
|
154, 5, 104, 51, 33, 0, 144, 0, 146, 1, 72, 26, 34, 0, 148, 2, 240, 0, 249, 238, 96, 40, 40, 0, 208, 30, 77, 23, 104,
|
||||||
|
44, 44, 0, 208, 11, 72, 22, 28, 57, 34, 6, 240, 0, 254, 210, 40, 0, 208, 19, 28, 32, 240, 0, 251, 179, 35, 0, 96, 43,
|
||||||
|
75, 11, 28, 57, 104, 24, 240, 0, 251, 54, 75, 12, 28, 4, 96, 24, 40, 0, 208, 4, 72, 11, 28, 57, 34, 6, 240, 0, 254,
|
||||||
|
234, 176, 7, 28, 32, 188, 240, 188, 2, 71, 8, 70, 192, 19, 112, 107, 88, 19, 112, 107, 92, 19, 114, 199, 32, 19, 114,
|
||||||
|
199, 36, 19, 112, 72, 161, 19, 112, 107, 96, 19, 112, 96, 72, 181, 8, 28, 3, 28, 10, 32, 0, 28, 25, 35, 0, 240, 1, 248,
|
||||||
|
56, 188, 8, 188, 1, 71, 0, 181, 8, 32, 1, 33, 0, 34, 0, 35, 0, 240, 1, 248, 46, 188, 8, 188, 2, 71, 8, 181, 8, 32, 17,
|
||||||
|
33, 0, 34, 0, 35, 0, 240, 1, 248, 36, 188, 8, 188, 2, 71, 8, 181, 8, 32, 18, 33, 0, 34, 0, 35, 0, 240, 1, 248, 26, 188,
|
||||||
|
8, 188, 2, 71, 8, 181, 56, 28, 5, 28, 12, 30, 19, 221, 4, 32, 2, 28, 41, 28, 34, 240, 1, 248, 13, 188, 56, 188, 1, 71,
|
||||||
|
0, 181, 56, 28, 5, 28, 12, 30, 19, 221, 4, 32, 9, 28, 41, 28, 34, 240, 1, 248, 0, 188, 56, 188, 1, 71, 0, 181, 8, 28,
|
||||||
|
3, 28, 10, 32, 5, 28, 25, 35, 0, 240, 0, 255, 245, 188, 8, 188, 1, 71, 0, 181, 8, 28, 3, 28, 10, 32, 6, 28, 25, 35,
|
||||||
|
0, 240, 0, 255, 234, 188, 8, 188, 1, 71, 0, 181, 56, 28, 5, 28, 12, 28, 19, 28, 41, 28, 34, 32, 16, 240, 0, 255, 222,
|
||||||
|
188, 56, 188, 2, 71, 8, 181, 8, 32, 128, 33, 0, 34, 0, 35, 0, 240, 0, 255, 212, 188, 8, 188, 1, 71, 0, 181, 8, 32, 129,
|
||||||
|
33, 0, 34, 0, 35, 0, 240, 0, 255, 202, 188, 8, 188, 1, 71, 0, 181, 0, 35, 0, 224, 3, 51, 1, 6, 27, 14, 27, 8, 64, 40,
|
||||||
|
0, 209, 249, 30, 88, 6, 0, 14, 0, 188, 2, 71, 8, 0, 0, 181, 240, 176, 133, 144, 1, 32, 84, 145, 3, 146, 2, 28, 30, 159,
|
||||||
|
11, 247, 251, 251, 98, 28, 4, 30, 48, 209, 1, 32, 128, 0, 128, 247, 251, 251, 91, 28, 5, 32, 128, 2, 0, 97, 32, 247,
|
||||||
|
255, 255, 218, 75, 125, 117, 32, 97, 227, 154, 10, 75, 124, 96, 37, 96, 30, 11, 211, 67, 115, 97, 163, 155, 12, 98,
|
||||||
|
231, 43, 0, 208, 50, 33, 0, 28, 50, 28, 40, 240, 0, 254, 102, 35, 87, 112, 43, 35, 66, 112, 107, 35, 70, 112, 171, 35,
|
||||||
|
83, 112, 235, 28, 48, 247, 255, 255, 188, 114, 40, 159, 10, 73, 111, 14, 59, 113, 43, 12, 59, 113, 107, 10, 59, 113,
|
||||||
|
171, 113, 239, 105, 162, 35, 6, 66, 138, 217, 16, 73, 106, 35, 7, 66, 138, 217, 12, 73, 105, 35, 8, 66, 138, 217, 8,
|
||||||
|
73, 104, 35, 9, 66, 138, 217, 4, 75, 103, 66, 147, 65, 155, 66, 91, 51, 10, 125, 34, 24, 155, 114, 107, 224, 6, 28,
|
||||||
|
57, 152, 2, 34, 1, 28, 43, 159, 1, 240, 0, 248, 207, 120, 43, 120, 106, 6, 27, 4, 18, 67, 26, 120, 171, 2, 27, 67, 26,
|
||||||
|
120, 235, 67, 26, 75, 91, 66, 154, 208, 4, 72, 90, 240, 0, 255, 49, 72, 90, 224, 40, 75, 90, 104, 27, 66, 95, 65, 95,
|
||||||
|
46, 0, 208, 12, 47, 0, 208, 10, 28, 48, 247, 255, 255, 117, 122, 43, 66, 131, 208, 4, 72, 81, 240, 0, 255, 30, 72, 82,
|
||||||
|
224, 21, 154, 10, 42, 0, 208, 31, 47, 0, 208, 29, 121, 42, 121, 107, 6, 18, 4, 27, 67, 19, 121, 170, 159, 10, 2, 18,
|
||||||
|
67, 19, 121, 234, 67, 19, 66, 187, 208, 16, 72, 69, 240, 0, 255, 7, 72, 72, 240, 0, 255, 4, 72, 71, 240, 0, 255, 1,
|
||||||
|
28, 32, 247, 251, 250, 232, 28, 40, 247, 251, 250, 229, 36, 0, 224, 100, 122, 46, 39, 1, 28, 58, 64, 178, 96, 98, 122,
|
||||||
|
43, 28, 22, 147, 0, 114, 35, 121, 42, 121, 107, 6, 18, 4, 27, 67, 19, 121, 170, 121, 232, 2, 18, 67, 19, 67, 24, 105,
|
||||||
|
33, 96, 224, 240, 0, 254, 168, 67, 112, 97, 160, 122, 107, 125, 34, 64, 159, 98, 99, 26, 155, 105, 226, 64, 216, 64,
|
||||||
|
218, 4, 18, 12, 18, 4, 51, 12, 27, 133, 98, 50, 128, 4, 1, 133, 32, 0, 82, 30, 88, 24, 130, 66, 91, 64, 26, 155, 3,
|
||||||
|
28, 37, 53, 72, 99, 99, 12, 201, 155, 0, 98, 39, 128, 42, 26, 127, 154, 1, 64, 223, 99, 34, 100, 39, 154, 2, 159, 12,
|
||||||
|
99, 162, 47, 0, 209, 1, 100, 103, 224, 11, 30, 112, 24, 65, 66, 112, 64, 8, 247, 251, 250, 125, 141, 34, 100, 96, 8,
|
||||||
|
210, 33, 255, 240, 0, 253, 155, 28, 35, 51, 72, 136, 25, 108, 32, 122, 35, 56, 1, 65, 25, 240, 0, 254, 104, 4, 2, 104,
|
||||||
|
96, 12, 18, 28, 3, 59, 12, 135, 162, 66, 154, 217, 0, 135, 163, 247, 251, 250, 99, 35, 0, 100, 224, 101, 35, 176, 5,
|
||||||
|
28, 32, 188, 240, 188, 2, 71, 8, 70, 192, 0, 4, 96, 144, 19, 112, 107, 108, 0, 63, 255, 255, 0, 127, 255, 255, 0, 255,
|
||||||
|
255, 255, 1, 255, 255, 255, 3, 255, 255, 255, 87, 66, 70, 83, 19, 112, 106, 12, 19, 112, 106, 24, 19, 112, 107, 104,
|
||||||
|
19, 112, 106, 34, 19, 112, 106, 63, 19, 112, 105, 116, 71, 56, 70, 192, 181, 240, 176, 165, 144, 9, 28, 24, 146, 10,
|
||||||
|
147, 11, 145, 15, 247, 251, 250, 51, 35, 1, 74, 140, 77, 141, 66, 91, 96, 19, 104, 43, 28, 4, 43, 0, 209, 3, 152, 11,
|
||||||
|
247, 251, 250, 39, 96, 40, 75, 136, 152, 11, 33, 0, 96, 24, 34, 1, 152, 10, 28, 35, 157, 9, 240, 0, 249, 24, 40, 0,
|
||||||
|
208, 0, 224, 246, 35, 255, 0, 91, 92, 227, 43, 85, 209, 28, 51, 171, 51, 255, 92, 227, 43, 170, 209, 23, 28, 224, 73,
|
||||||
|
125, 34, 4, 240, 0, 253, 138, 40, 0, 208, 16, 77, 123, 28, 32, 48, 54, 28, 41, 34, 3, 240, 0, 253, 129, 40, 0, 208,
|
||||||
|
7, 28, 32, 48, 82, 28, 41, 34, 3, 240, 0, 253, 121, 40, 0, 209, 5, 168, 20, 33, 0, 34, 64, 240, 0, 253, 22, 224, 6,
|
||||||
|
28, 33, 49, 191, 49, 255, 168, 20, 34, 64, 240, 0, 252, 204, 175, 32, 151, 5, 32, 228, 39, 1, 66, 127, 0, 64, 38, 0,
|
||||||
|
173, 20, 144, 14, 151, 8, 122, 235, 122, 47, 122, 105, 122, 170, 147, 7, 120, 32, 120, 99, 6, 0, 4, 27, 67, 24, 120,
|
||||||
|
163, 2, 27, 67, 24, 120, 227, 67, 24, 75, 97, 66, 152, 208, 3, 121, 40, 40, 0, 209, 0, 224, 162, 2, 9, 4, 18, 67, 17,
|
||||||
|
67, 57, 159, 7, 6, 59, 67, 25, 145, 7, 121, 43, 43, 15, 209, 101, 33, 227, 32, 0, 0, 73, 159, 8, 144, 12, 35, 0, 145,
|
||||||
|
13, 149, 4, 154, 7, 152, 10, 24, 210, 146, 8, 28, 17, 28, 35, 34, 1, 157, 9, 240, 0, 248, 169, 40, 0, 208, 0, 224, 135,
|
||||||
|
72, 78, 153, 14, 92, 34, 92, 99, 2, 18, 4, 27, 67, 26, 77, 76, 155, 13, 152, 8, 92, 225, 93, 99, 67, 10, 6, 27, 67,
|
||||||
|
19, 24, 192, 35, 235, 144, 8, 0, 91, 92, 227, 152, 10, 147, 16, 75, 69, 153, 8, 92, 227, 34, 1, 147, 17, 35, 236, 0,
|
||||||
|
91, 92, 227, 157, 9, 147, 18, 75, 65, 92, 227, 147, 19, 28, 35, 240, 0, 248, 128, 40, 0, 209, 95, 120, 34, 120, 99,
|
||||||
|
6, 18, 4, 27, 67, 19, 120, 162, 73, 54, 2, 18, 67, 19, 120, 226, 67, 19, 66, 139, 209, 10, 154, 43, 66, 150, 209, 2,
|
||||||
|
144, 0, 155, 8, 224, 48, 152, 8, 66, 184, 208, 1, 54, 1, 28, 7, 153, 17, 157, 18, 2, 11, 4, 42, 152, 16, 153, 19, 67,
|
||||||
|
19, 67, 3, 6, 10, 67, 19, 208, 53, 154, 12, 50, 1, 146, 12, 42, 8, 209, 162, 224, 47, 152, 10, 153, 7, 34, 1, 28, 35,
|
||||||
|
159, 9, 240, 0, 248, 79, 40, 0, 209, 45, 120, 34, 120, 99, 6, 18, 4, 27, 67, 19, 120, 162, 73, 29, 2, 18, 67, 19, 120,
|
||||||
|
226, 67, 19, 66, 139, 209, 27, 154, 43, 66, 150, 209, 15, 155, 7, 144, 0, 157, 44, 147, 1, 152, 9, 153, 15, 154, 10,
|
||||||
|
155, 11, 149, 2, 247, 255, 253, 201, 28, 5, 28, 32, 247, 251, 249, 79, 224, 17, 159, 7, 152, 8, 66, 135, 208, 4, 54,
|
||||||
|
1, 151, 8, 224, 1, 157, 4, 151, 8, 153, 5, 66, 141, 208, 1, 53, 16, 231, 65, 28, 32, 247, 251, 249, 61, 37, 0, 176,
|
||||||
|
37, 28, 40, 188, 240, 188, 2, 71, 8, 70, 192, 19, 112, 96, 80, 19, 112, 107, 100, 19, 112, 107, 108, 19, 112, 106, 91,
|
||||||
|
19, 112, 106, 96, 87, 66, 70, 83, 0, 0, 1, 199, 0, 0, 1, 201, 0, 0, 1, 215, 0, 0, 1, 217, 71, 40, 71, 56, 181, 16, 109,
|
||||||
|
3, 28, 4, 43, 0, 208, 9, 72, 13, 240, 0, 253, 46, 72, 12, 240, 0, 253, 43, 72, 12, 240, 0, 253, 40, 224, 13, 104, 0,
|
||||||
|
247, 251, 249, 14, 108, 224, 247, 251, 249, 11, 108, 96, 40, 0, 208, 1, 247, 251, 249, 6, 28, 32, 247, 251, 249, 3,
|
||||||
|
188, 16, 188, 1, 71, 0, 19, 112, 106, 12, 19, 112, 106, 100, 19, 112, 105, 116, 181, 240, 28, 3, 51, 72, 176, 131, 136,
|
||||||
|
26, 122, 3, 28, 5, 65, 26, 146, 1, 35, 1, 74, 48, 66, 91, 96, 19, 34, 0, 28, 14, 146, 0, 39, 0, 224, 79, 104, 43, 25,
|
||||||
|
219, 123, 27, 43, 0, 208, 68, 106, 233, 155, 0, 49, 1, 24, 201, 34, 1, 107, 168, 108, 235, 107, 44, 240, 0, 248, 83,
|
||||||
|
108, 233, 28, 48, 34, 6, 240, 0, 251, 106, 40, 0, 209, 51, 32, 12, 247, 251, 248, 177, 30, 6, 209, 9, 72, 32, 240, 0,
|
||||||
|
252, 224, 72, 31, 240, 0, 252, 221, 72, 31, 240, 0, 252, 218, 224, 46, 28, 43, 51, 72, 96, 53, 96, 183, 136, 24, 247,
|
||||||
|
251, 248, 158, 28, 3, 96, 112, 40, 0, 209, 12, 72, 21, 240, 0, 252, 203, 72, 21, 240, 0, 252, 200, 72, 20, 240, 0, 252,
|
||||||
|
197, 28, 48, 247, 251, 248, 172, 224, 21, 106, 233, 154, 0, 49, 1, 24, 137, 107, 168, 107, 44, 154, 1, 240, 0, 248,
|
||||||
|
28, 109, 43, 51, 1, 101, 43, 224, 9, 155, 0, 55, 1, 28, 26, 155, 1, 24, 210, 146, 0, 143, 171, 66, 159, 211, 172, 38,
|
||||||
|
0, 176, 3, 28, 48, 188, 240, 188, 2, 71, 8, 70, 192, 19, 112, 96, 80, 19, 112, 106, 12, 19, 112, 106, 144, 19, 112,
|
||||||
|
105, 116, 71, 32, 70, 192, 181, 16, 104, 3, 28, 4, 109, 26, 58, 1, 101, 26, 104, 64, 247, 251, 248, 123, 28, 32, 247,
|
||||||
|
251, 248, 120, 188, 16, 188, 1, 71, 0, 0, 0, 181, 240, 176, 137, 104, 5, 147, 0, 106, 107, 146, 1, 28, 6, 30, 154, 28,
|
||||||
|
8, 64, 208, 4, 2, 12, 18, 104, 104, 146, 4, 70, 132, 152, 4, 104, 116, 48, 128, 0, 64, 90, 32, 122, 47, 106, 42, 144,
|
||||||
|
2, 36, 1, 40, 0, 209, 0, 224, 194, 58, 1, 64, 250, 27, 219, 146, 6, 63, 2, 28, 10, 64, 250, 147, 5, 155, 6, 28, 23,
|
||||||
|
70, 96, 64, 31, 8, 131, 59, 1, 28, 26, 64, 10, 146, 7, 209, 0, 224, 133, 155, 2, 152, 5, 106, 233, 64, 131, 24, 121,
|
||||||
|
147, 3, 24, 201, 75, 87, 104, 26, 108, 235, 66, 138, 209, 5, 74, 85, 28, 24, 104, 17, 74, 85, 104, 18, 224, 18, 107,
|
||||||
|
44, 107, 168, 34, 1, 240, 0, 248, 165, 30, 4, 208, 0, 224, 149, 106, 235, 152, 3, 73, 76, 24, 251, 24, 27, 96, 11, 75,
|
||||||
|
75, 108, 233, 104, 24, 75, 75, 104, 26, 240, 0, 250, 227, 154, 7, 104, 108, 0, 145, 155, 0, 26, 100, 66, 156, 217, 0,
|
||||||
|
28, 28, 108, 235, 152, 1, 24, 89, 28, 34, 240, 0, 250, 213, 152, 0, 153, 1, 27, 0, 25, 9, 144, 0, 145, 1, 55, 1, 40,
|
||||||
|
0, 208, 71, 154, 6, 66, 186, 210, 68, 155, 4, 104, 114, 51, 1, 4, 27, 12, 27, 147, 4, 51, 128, 0, 91, 90, 211, 36, 1,
|
||||||
|
147, 2, 39, 0, 43, 0, 209, 54, 224, 95, 122, 43, 152, 0, 64, 216, 106, 43, 25, 194, 144, 3, 66, 154, 217, 1, 27, 219,
|
||||||
|
147, 3, 154, 5, 106, 233, 155, 2, 24, 121, 64, 147, 24, 201, 107, 168, 107, 44, 154, 3, 155, 1, 240, 0, 248, 86, 40,
|
||||||
|
0, 209, 70, 122, 43, 152, 3, 153, 0, 64, 152, 154, 3, 26, 9, 28, 3, 145, 0, 24, 191, 41, 0, 208, 15, 152, 6, 66, 184,
|
||||||
|
210, 12, 154, 4, 104, 113, 50, 1, 4, 18, 12, 18, 146, 4, 50, 128, 0, 82, 90, 138, 146, 2, 42, 0, 208, 42, 39, 0, 153,
|
||||||
|
1, 24, 201, 145, 1, 104, 107, 154, 0, 66, 154, 210, 197, 36, 0, 42, 0, 208, 34, 155, 5, 158, 2, 106, 233, 64, 158, 24,
|
||||||
|
121, 107, 44, 107, 168, 25, 137, 108, 235, 34, 1, 240, 0, 248, 35, 30, 4, 209, 20, 106, 235, 108, 233, 24, 255, 75,
|
||||||
|
11, 25, 190, 96, 30, 75, 11, 104, 24, 75, 11, 104, 26, 240, 0, 250, 99, 108, 233, 152, 1, 154, 0, 240, 0, 250, 94, 224,
|
||||||
|
2, 36, 1, 224, 0, 28, 4, 176, 9, 28, 32, 188, 240, 188, 2, 71, 8, 70, 192, 19, 112, 96, 80, 19, 112, 107, 100, 19, 112,
|
||||||
|
107, 108, 71, 32, 70, 192, 239, 0, 0, 204, 225, 47, 255, 30, 225, 160, 0, 0, 225, 160, 0, 0, 230, 0, 0, 16, 225, 47,
|
||||||
|
255, 30, 230, 0, 0, 48, 225, 47, 255, 30, 230, 0, 0, 80, 225, 47, 255, 30, 230, 0, 0, 112, 225, 47, 255, 30, 230, 0,
|
||||||
|
0, 144, 225, 47, 255, 30, 230, 0, 0, 176, 225, 47, 255, 30, 230, 0, 0, 208, 225, 47, 255, 30, 230, 0, 0, 240, 225, 47,
|
||||||
|
255, 30, 230, 0, 1, 16, 225, 47, 255, 30, 230, 0, 1, 48, 225, 47, 255, 30, 230, 0, 1, 80, 225, 47, 255, 30, 230, 0,
|
||||||
|
1, 112, 225, 47, 255, 30, 230, 0, 1, 144, 225, 47, 255, 30, 230, 0, 1, 176, 225, 47, 255, 30, 230, 0, 1, 208, 225, 47,
|
||||||
|
255, 30, 230, 0, 1, 240, 225, 47, 255, 30, 230, 0, 2, 16, 225, 47, 255, 30, 230, 0, 2, 48, 225, 47, 255, 30, 230, 0,
|
||||||
|
2, 80, 225, 47, 255, 30, 230, 0, 2, 112, 225, 47, 255, 30, 230, 0, 2, 144, 225, 47, 255, 30, 230, 0, 2, 176, 225, 47,
|
||||||
|
255, 30, 230, 0, 2, 208, 225, 47, 255, 30, 230, 0, 2, 240, 225, 47, 255, 30, 230, 0, 3, 16, 225, 47, 255, 30, 230, 0,
|
||||||
|
3, 48, 225, 47, 255, 30, 230, 0, 3, 80, 225, 47, 255, 30, 230, 0, 3, 112, 225, 47, 255, 30, 230, 0, 3, 144, 225, 47,
|
||||||
|
255, 30, 230, 0, 3, 176, 225, 47, 255, 30, 230, 0, 3, 208, 225, 47, 255, 30, 230, 0, 3, 240, 225, 47, 255, 30, 230,
|
||||||
|
0, 4, 16, 225, 47, 255, 30, 230, 0, 4, 48, 225, 47, 255, 30, 230, 0, 4, 80, 225, 47, 255, 30, 230, 0, 4, 112, 225, 47,
|
||||||
|
255, 30, 230, 0, 4, 144, 225, 47, 255, 30, 230, 0, 4, 176, 225, 47, 255, 30, 230, 0, 4, 208, 225, 47, 255, 30, 230,
|
||||||
|
0, 4, 240, 225, 47, 255, 30, 230, 0, 5, 16, 225, 47, 255, 30, 230, 0, 5, 48, 225, 47, 255, 30, 230, 0, 5, 80, 225, 47,
|
||||||
|
255, 30, 230, 0, 6, 144, 225, 47, 255, 30, 230, 0, 7, 240, 225, 47, 255, 30, 230, 0, 8, 16, 225, 47, 255, 30, 230, 0,
|
||||||
|
10, 16, 225, 47, 255, 30, 226, 144, 16, 0, 227, 176, 0, 4, 239, 0, 0, 171, 225, 47, 255, 30, 225, 160, 0, 0, 225, 160,
|
||||||
|
0, 0, 180, 3, 70, 113, 8, 73, 0, 64, 0, 73, 90, 9, 0, 73, 68, 142, 188, 3, 71, 112, 226, 81, 32, 1, 1, 47, 255, 30,
|
||||||
|
58, 0, 0, 54, 225, 80, 0, 1, 154, 0, 0, 34, 225, 17, 0, 2, 10, 0, 0, 35, 227, 17, 2, 14, 1, 160, 17, 129, 3, 160, 48,
|
||||||
|
8, 19, 160, 48, 1, 227, 81, 2, 1, 49, 81, 0, 0, 49, 160, 18, 1, 49, 160, 50, 3, 58, 255, 255, 250, 227, 81, 1, 2, 49,
|
||||||
|
81, 0, 0, 49, 160, 16, 129, 49, 160, 48, 131, 58, 255, 255, 250, 227, 160, 32, 0, 225, 80, 0, 1, 32, 64, 0, 1, 33, 130,
|
||||||
|
32, 3, 225, 80, 0, 161, 32, 64, 0, 161, 33, 130, 32, 163, 225, 80, 1, 33, 32, 64, 1, 33, 33, 130, 33, 35, 225, 80, 1,
|
||||||
|
161, 32, 64, 1, 161, 33, 130, 33, 163, 227, 80, 0, 0, 17, 176, 50, 35, 17, 160, 18, 33, 26, 255, 255, 239, 225, 160,
|
||||||
|
0, 2, 225, 47, 255, 30, 3, 160, 0, 1, 19, 160, 0, 0, 225, 47, 255, 30, 227, 81, 8, 1, 33, 160, 24, 33, 35, 160, 32,
|
||||||
|
16, 51, 160, 32, 0, 227, 81, 12, 1, 33, 160, 20, 33, 34, 130, 32, 8, 227, 81, 0, 16, 33, 160, 18, 33, 34, 130, 32, 4,
|
||||||
|
227, 81, 0, 4, 130, 130, 32, 3, 144, 130, 32, 161, 225, 160, 2, 48, 225, 47, 255, 30, 225, 47, 255, 31, 225, 160, 0,
|
||||||
|
0, 227, 80, 0, 0, 19, 224, 0, 0, 234, 0, 1, 11, 227, 81, 0, 0, 10, 255, 255, 248, 233, 45, 64, 3, 235, 255, 255, 188,
|
||||||
|
232, 189, 64, 6, 224, 3, 0, 146, 224, 65, 16, 3, 225, 47, 255, 30, 227, 81, 0, 0, 10, 0, 0, 67, 224, 32, 192, 1, 66,
|
||||||
|
97, 16, 0, 226, 81, 32, 1, 10, 0, 0, 39, 225, 176, 48, 0, 66, 96, 48, 0, 225, 83, 0, 1, 154, 0, 0, 38, 225, 17, 0, 2,
|
||||||
|
10, 0, 0, 40, 227, 17, 2, 14, 1, 160, 17, 129, 3, 160, 32, 8, 19, 160, 32, 1, 227, 81, 2, 1, 49, 81, 0, 3, 49, 160,
|
||||||
|
18, 1, 49, 160, 34, 2, 58, 255, 255, 250, 227, 81, 1, 2, 49, 81, 0, 3, 49, 160, 16, 129, 49, 160, 32, 130, 58, 255,
|
||||||
|
255, 250, 227, 160, 0, 0, 225, 83, 0, 1, 32, 67, 48, 1, 33, 128, 0, 2, 225, 83, 0, 161, 32, 67, 48, 161, 33, 128, 0,
|
||||||
|
162, 225, 83, 1, 33, 32, 67, 49, 33, 33, 128, 1, 34, 225, 83, 1, 161, 32, 67, 49, 161, 33, 128, 1, 162, 227, 83, 0,
|
||||||
|
0, 17, 176, 34, 34, 17, 160, 18, 33, 26, 255, 255, 239, 227, 92, 0, 0, 66, 96, 0, 0, 225, 47, 255, 30, 225, 60, 0, 0,
|
||||||
|
66, 96, 0, 0, 225, 47, 255, 30, 51, 160, 0, 0, 1, 160, 15, 204, 3, 128, 0, 1, 225, 47, 255, 30, 227, 81, 8, 1, 33, 160,
|
||||||
|
24, 33, 35, 160, 32, 16, 51, 160, 32, 0, 227, 81, 12, 1, 33, 160, 20, 33, 34, 130, 32, 8, 227, 81, 0, 16, 33, 160, 18,
|
||||||
|
33, 34, 130, 32, 4, 227, 81, 0, 4, 130, 130, 32, 3, 144, 130, 32, 161, 227, 92, 0, 0, 225, 160, 2, 51, 66, 96, 0, 0,
|
||||||
|
225, 47, 255, 30, 225, 47, 255, 31, 225, 160, 0, 0, 227, 80, 0, 0, 195, 224, 1, 2, 179, 160, 1, 2, 234, 0, 0, 183, 227,
|
||||||
|
81, 0, 0, 10, 255, 255, 247, 233, 45, 64, 3, 235, 255, 255, 177, 232, 189, 64, 6, 224, 3, 0, 146, 224, 65, 16, 3, 225,
|
||||||
|
47, 255, 30, 71, 112, 70, 192, 33, 16, 6, 2, 14, 3, 65, 200, 67, 19, 6, 2, 14, 0, 67, 16, 65, 200, 67, 24, 71, 112,
|
||||||
|
70, 192, 181, 112, 28, 4, 28, 13, 42, 3, 217, 33, 28, 11, 67, 3, 7, 158, 208, 18, 120, 32, 120, 41, 66, 136, 209, 29,
|
||||||
|
58, 1, 35, 0, 224, 5, 52, 1, 51, 1, 120, 32, 92, 233, 66, 136, 209, 20, 66, 154, 209, 247, 32, 0, 188, 112, 188, 2,
|
||||||
|
71, 8, 28, 13, 28, 4, 201, 8, 200, 64, 66, 158, 209, 4, 58, 4, 28, 4, 28, 13, 42, 3, 216, 244, 32, 0, 42, 0, 209, 222,
|
||||||
|
231, 237, 26, 64, 231, 235, 70, 192, 181, 240, 28, 5, 28, 14, 28, 20, 42, 15, 217, 3, 28, 11, 67, 3, 7, 159, 208, 10,
|
||||||
|
44, 0, 208, 5, 35, 0, 92, 242, 84, 234, 51, 1, 66, 163, 209, 250, 188, 240, 188, 2, 71, 8, 28, 21, 28, 12, 28, 3, 104,
|
||||||
|
38, 96, 30, 104, 102, 96, 94, 104, 166, 96, 158, 104, 230, 61, 16, 96, 222, 52, 16, 51, 16, 45, 15, 216, 242, 58, 16,
|
||||||
|
9, 23, 28, 126, 1, 63, 1, 54, 27, 215, 25, 133, 28, 60, 25, 142, 47, 3, 217, 217, 28, 52, 28, 59, 28, 42, 204, 2, 59,
|
||||||
|
4, 194, 2, 43, 3, 216, 250, 63, 4, 8, 188, 28, 99, 0, 155, 0, 164, 24, 237, 24, 246, 27, 60, 231, 200, 70, 192, 181,
|
||||||
|
112, 28, 3, 7, 132, 208, 13, 42, 0, 208, 64, 6, 13, 58, 1, 14, 45, 36, 3, 224, 2, 42, 0, 208, 57, 58, 1, 112, 29, 51,
|
||||||
|
1, 66, 35, 209, 248, 42, 3, 217, 41, 37, 255, 64, 13, 2, 44, 67, 37, 4, 44, 28, 30, 67, 37, 42, 15, 217, 18, 28, 28,
|
||||||
|
28, 22, 62, 16, 96, 37, 96, 101, 96, 165, 96, 229, 52, 16, 46, 15, 216, 247, 58, 16, 9, 22, 54, 1, 1, 54, 25, 158, 35,
|
||||||
|
15, 64, 26, 42, 3, 217, 12, 28, 52, 28, 19, 59, 4, 196, 32, 43, 3, 216, 251, 58, 4, 8, 147, 51, 1, 0, 155, 24, 246,
|
||||||
|
35, 3, 64, 26, 28, 51, 42, 0, 208, 6, 6, 9, 14, 12, 33, 0, 84, 92, 49, 1, 66, 138, 209, 251, 188, 112, 188, 2, 71, 8,
|
||||||
|
120, 2, 120, 11, 48, 1, 49, 1, 42, 0, 208, 1, 66, 154, 208, 247, 26, 208, 71, 112, 35, 0, 92, 194, 51, 1, 42, 0, 209,
|
||||||
|
251, 30, 88, 71, 112, 70, 192, 181, 240, 28, 3, 32, 0, 42, 0, 208, 72, 28, 8, 67, 24, 36, 3, 30, 85, 64, 4, 209, 42,
|
||||||
|
28, 30, 28, 13, 42, 3, 217, 67, 104, 31, 104, 8, 66, 135, 209, 63, 58, 4, 28, 32, 42, 0, 208, 54, 72, 34, 24, 61, 67,
|
||||||
|
189, 79, 33, 28, 32, 66, 61, 209, 47, 29, 28, 29, 8, 224, 11, 204, 8, 200, 2, 66, 139, 209, 45, 58, 4, 42, 0, 208, 40,
|
||||||
|
77, 25, 25, 89, 67, 153, 66, 57, 209, 35, 28, 38, 28, 5, 42, 3, 216, 239, 28, 35, 28, 1, 42, 0, 208, 33, 30, 85, 120,
|
||||||
|
28, 120, 8, 66, 132, 209, 18, 32, 0, 45, 0, 208, 16, 44, 0, 208, 14, 61, 1, 34, 0, 224, 4, 66, 170, 208, 12, 50, 1,
|
||||||
|
44, 0, 208, 9, 24, 152, 120, 68, 24, 136, 120, 64, 66, 132, 208, 244, 26, 32, 188, 240, 188, 2, 71, 8, 32, 0, 231, 250,
|
||||||
|
28, 41, 28, 51, 30, 85, 231, 222, 120, 36, 120, 0, 26, 32, 231, 242, 70, 192, 254, 254, 254, 255, 128, 128, 128, 128,
|
||||||
|
0, 0, 0, 0, 71, 120, 70, 192, 234, 255, 254, 125, 71, 120, 70, 192, 234, 255, 254, 137, 71, 120, 70, 192, 234, 255,
|
||||||
|
254, 123, 71, 120, 70, 192, 234, 255, 254, 253, 71, 120, 70, 192, 234, 255, 233, 149, 71, 120, 70, 192, 234, 255, 254,
|
||||||
|
119, 71, 120, 70, 192, 234, 255, 254, 184, 71, 120, 70, 192, 234, 255, 254, 163, 71, 120, 70, 192, 234, 255, 233, 174,
|
||||||
|
229, 159, 192, 0, 225, 47, 255, 28, 19, 112, 87, 81, 71, 120, 70, 192, 234, 255, 254, 124, 71, 120, 70, 192, 234, 255,
|
||||||
|
254, 244, 71, 120, 70, 192, 234, 255, 255, 62, 71, 120, 70, 192, 234, 255, 254, 84, 71, 120, 70, 192, 234, 255, 254,
|
||||||
|
80, 71, 120, 70, 192, 234, 255, 254, 112, 71, 120, 70, 192, 234, 255, 254, 86, 71, 120, 70, 192, 234, 255, 254, 88,
|
||||||
|
71, 120, 70, 192, 234, 255, 233, 162, 71, 120, 70, 192, 234, 255, 254, 96, 71, 120, 70, 192, 234, 255, 254, 144, 71,
|
||||||
|
120, 70, 192, 234, 255, 233, 152, 71, 120, 70, 192, 234, 255, 254, 136, 71, 120, 70, 192, 234, 255, 254, 84, 71, 120,
|
||||||
|
70, 192, 234, 255, 233, 106, 71, 120, 70, 192, 234, 255, 254, 124, 71, 120, 70, 192, 234, 255, 254, 34, 71, 120, 70,
|
||||||
|
192, 234, 255, 254, 66, 71, 120, 70, 192, 234, 255, 233, 94, 71, 120, 70, 192, 234, 255, 254, 82, 71, 120, 70, 192,
|
||||||
|
234, 255, 254, 118, 71, 120, 70, 192, 234, 255, 254, 34, 0, 0, 0, 0, 73, 79, 83, 32, 109, 111, 100, 117, 108, 101, 0,
|
||||||
|
0, 255, 255, 255, 255, 1, 0, 0, 0, 0, 0, 0, 1, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 229, 31,
|
||||||
|
240, 4, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 15, 66, 64, 19, 114, 198, 36, 16,
|
||||||
|
0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 87, 66, 70, 83, 32, 110, 111, 116, 32, 101,
|
||||||
|
110, 111, 117, 103, 104, 32, 109, 101, 109, 111, 114, 121, 33, 10, 0, 47, 100, 101, 118, 47, 117, 115, 98, 49, 50, 51,
|
||||||
|
0, 47, 100, 101, 118, 47, 117, 115, 98, 49, 50, 51, 47, 79, 70, 70, 0, 102, 105, 114, 115, 116, 32, 114, 101, 97, 100,
|
||||||
|
32, 115, 101, 99, 116, 111, 114, 32, 40, 37, 105, 41, 32, 79, 75, 10, 0, 102, 105, 114, 115, 116, 32, 114, 101, 97,
|
||||||
|
100, 32, 115, 101, 99, 116, 111, 114, 32, 40, 37, 105, 41, 32, 69, 82, 82, 79, 82, 10, 0, 101, 104, 99, 105, 95, 105,
|
||||||
|
110, 116, 95, 119, 111, 114, 107, 105, 110, 103, 95, 99, 97, 108, 108, 98, 97, 99, 107, 95, 112, 97, 114, 116, 49, 44,
|
||||||
|
32, 116, 105, 109, 101, 111, 117, 116, 58, 32, 37, 117, 10, 0, 117, 114, 98, 32, 114, 101, 116, 118, 97, 108, 58, 32,
|
||||||
|
37, 105, 10, 0, 117, 110, 97, 98, 108, 101, 32, 116, 111, 32, 103, 101, 116, 32, 100, 101, 118, 105, 99, 101, 32, 100,
|
||||||
|
101, 115, 99, 46, 46, 46, 10, 0, 103, 101, 116, 116, 105, 110, 103, 32, 85, 83, 66, 95, 82, 69, 81, 95, 71, 69, 84,
|
||||||
|
68, 69, 83, 67, 82, 73, 80, 84, 79, 82, 32, 45, 32, 114, 101, 115, 101, 116, 10, 0, 101, 114, 114, 111, 114, 32, 103,
|
||||||
|
101, 116, 116, 105, 110, 103, 32, 85, 83, 66, 95, 82, 69, 81, 95, 71, 69, 84, 68, 69, 83, 67, 82, 73, 80, 84, 79, 82,
|
||||||
|
10, 0, 103, 101, 116, 116, 105, 110, 103, 32, 85, 83, 66, 95, 82, 69, 81, 95, 71, 69, 84, 68, 69, 83, 67, 82, 73, 80,
|
||||||
|
84, 79, 82, 32, 45, 32, 97, 100, 113, 117, 105, 114, 101, 32, 45, 32, 114, 101, 115, 101, 116, 10, 0, 85, 83, 66, 95,
|
||||||
|
82, 69, 81, 95, 71, 69, 84, 68, 69, 83, 67, 82, 73, 80, 84, 79, 82, 32, 111, 107, 10, 0, 116, 114, 121, 105, 110, 103,
|
||||||
|
32, 85, 83, 66, 95, 82, 69, 81, 95, 83, 69, 84, 65, 68, 68, 82, 69, 83, 83, 58, 32, 37, 100, 10, 0, 117, 110, 97, 98,
|
||||||
|
108, 101, 32, 116, 111, 32, 115, 101, 116, 32, 100, 101, 118, 105, 99, 101, 32, 97, 100, 100, 114, 58, 32, 37, 100,
|
||||||
|
10, 0, 85, 83, 66, 95, 82, 69, 81, 95, 83, 69, 84, 65, 68, 68, 82, 69, 83, 83, 32, 111, 107, 58, 32, 37, 100, 10, 0,
|
||||||
|
101, 114, 114, 111, 114, 32, 99, 104, 101, 99, 107, 105, 110, 103, 32, 85, 83, 66, 95, 82, 69, 81, 95, 71, 69, 84, 68,
|
||||||
|
69, 83, 67, 82, 73, 80, 84, 79, 82, 10, 0, 111, 107, 32, 99, 104, 101, 99, 107, 105, 110, 103, 32, 85, 83, 66, 95, 82,
|
||||||
|
69, 81, 95, 71, 69, 84, 68, 69, 83, 67, 82, 73, 80, 84, 79, 82, 10, 0, 105, 110, 105, 116, 32, 111, 107, 10, 0, 98,
|
||||||
|
117, 102, 102, 101, 114, 32, 61, 61, 32, 78, 85, 76, 76, 32, 40, 110, 111, 32, 109, 101, 109, 41, 10, 0, 95, 95, 117,
|
||||||
|
115, 98, 95, 103, 101, 116, 100, 101, 115, 99, 32, 101, 114, 114, 111, 114, 32, 85, 83, 66, 95, 68, 84, 95, 68, 69,
|
||||||
|
86, 73, 67, 69, 58, 32, 114, 101, 116, 114, 121, 10, 0, 95, 95, 117, 115, 98, 95, 103, 101, 116, 100, 101, 115, 99,
|
||||||
|
32, 101, 114, 114, 111, 114, 32, 85, 83, 66, 95, 68, 84, 95, 68, 69, 86, 73, 67, 69, 10, 0, 117, 100, 100, 45, 62, 99,
|
||||||
|
111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 115, 32, 61, 61, 32, 78, 85, 76, 76, 32, 40, 110, 111, 32,
|
||||||
|
109, 101, 109, 41, 10, 0, 95, 95, 117, 115, 98, 95, 103, 101, 116, 100, 101, 115, 99, 32, 101, 114, 114, 111, 114, 32,
|
||||||
|
85, 83, 66, 95, 68, 84, 95, 67, 79, 78, 70, 73, 71, 58, 32, 114, 101, 116, 114, 121, 10, 0, 117, 99, 100, 45, 62, 105,
|
||||||
|
110, 116, 101, 114, 102, 97, 99, 101, 115, 32, 61, 61, 32, 78, 85, 76, 76, 32, 40, 110, 111, 32, 109, 101, 109, 41,
|
||||||
|
10, 0, 117, 105, 100, 45, 62, 101, 110, 100, 112, 111, 105, 110, 116, 115, 32, 61, 61, 32, 78, 85, 76, 76, 32, 40, 110,
|
||||||
|
111, 32, 109, 101, 109, 41, 10, 0, 117, 105, 100, 45, 62, 101, 120, 116, 114, 97, 32, 61, 61, 32, 78, 85, 76, 76, 32,
|
||||||
|
40, 110, 111, 32, 109, 101, 109, 41, 10, 0, 10, 113, 116, 100, 32, 101, 114, 114, 111, 114, 33, 58, 0, 32, 66, 65, 66,
|
||||||
|
66, 76, 69, 0, 32, 32, 109, 105, 115, 115, 101, 100, 32, 109, 105, 99, 114, 111, 32, 102, 114, 97, 109, 101, 0, 32,
|
||||||
|
32, 100, 97, 116, 97, 98, 117, 102, 102, 101, 114, 32, 101, 114, 114, 111, 114, 0, 32, 119, 114, 111, 110, 103, 32,
|
||||||
|
97, 99, 107, 0, 32, 116, 111, 111, 32, 109, 97, 110, 121, 32, 101, 114, 114, 111, 114, 115, 0, 105, 110, 116, 101, 114,
|
||||||
|
114, 117, 112, 116, 95, 99, 97, 108, 108, 98, 97, 99, 107, 95, 104, 97, 110, 100, 32, 83, 84, 83, 95, 73, 78, 84, 10,
|
||||||
|
0, 105, 110, 116, 101, 114, 114, 117, 112, 116, 95, 99, 97, 108, 108, 98, 97, 99, 107, 95, 104, 97, 110, 100, 32, 83,
|
||||||
|
84, 83, 95, 80, 67, 68, 10, 0, 117, 115, 98, 115, 116, 111, 114, 97, 103, 101, 32, 114, 101, 115, 101, 116, 58, 32,
|
||||||
|
66, 85, 76, 75, 32, 82, 69, 83, 69, 84, 32, 37, 105, 10, 0, 117, 115, 98, 115, 116, 111, 114, 97, 103, 101, 32, 114,
|
||||||
|
101, 115, 101, 116, 58, 32, 99, 108, 101, 97, 114, 104, 97, 108, 116, 32, 105, 110, 32, 114, 101, 116, 32, 37, 105,
|
||||||
|
10, 0, 117, 115, 98, 115, 116, 111, 114, 97, 103, 101, 32, 114, 101, 115, 101, 116, 58, 32, 99, 108, 101, 97, 114, 104,
|
||||||
|
97, 108, 116, 32, 111, 117, 116, 32, 114, 101, 116, 32, 37, 105, 10, 0, 117, 115, 98, 115, 116, 111, 114, 97, 103, 101,
|
||||||
|
32, 114, 101, 115, 101, 116, 58, 32, 85, 83, 66, 95, 71, 101, 116, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105,
|
||||||
|
111, 110, 32, 114, 101, 116, 32, 37, 105, 10, 0, 114, 101, 115, 101, 116, 32, 111, 107, 10, 0, 95, 95, 115, 101, 110,
|
||||||
|
100, 95, 99, 98, 119, 32, 114, 101, 116, 32, 37, 105, 10, 0, 95, 95, 85, 83, 66, 95, 66, 108, 107, 77, 115, 103, 84,
|
||||||
|
105, 109, 101, 111, 117, 116, 32, 37, 105, 10, 0, 95, 95, 114, 101, 97, 100, 95, 99, 115, 119, 32, 37, 105, 10, 0, 32,
|
||||||
|
32, 32, 32, 83, 67, 83, 73, 95, 84, 69, 83, 84, 95, 85, 78, 73, 84, 95, 82, 69, 65, 68, 89, 32, 114, 101, 116, 32, 37,
|
||||||
|
105, 10, 0, 32, 32, 32, 32, 83, 67, 83, 73, 95, 82, 69, 81, 85, 69, 83, 84, 95, 83, 69, 78, 83, 69, 32, 114, 101, 116,
|
||||||
|
32, 37, 105, 10, 0, 32, 32, 32, 32, 83, 67, 83, 73, 95, 82, 69, 81, 85, 69, 83, 84, 95, 83, 69, 78, 83, 69, 32, 115,
|
||||||
|
116, 97, 116, 117, 115, 32, 37, 120, 10, 0, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 79, 112, 101, 110, 40,
|
||||||
|
41, 58, 32, 85, 83, 66, 95, 71, 101, 116, 68, 101, 115, 99, 114, 105, 112, 116, 111, 114, 115, 32, 37, 105, 10, 0, 85,
|
||||||
|
83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 79, 112, 101, 110, 40, 41, 58, 32, 100, 101, 118, 105, 99, 101, 32, 99,
|
||||||
|
104, 97, 110, 103, 101, 100, 33, 33, 33, 10, 0, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 79, 112, 101, 110,
|
||||||
|
40, 41, 58, 32, 117, 99, 100, 32, 37, 105, 32, 80, 111, 119, 101, 114, 32, 37, 105, 32, 109, 65, 10, 0, 85, 83, 66,
|
||||||
|
83, 116, 111, 114, 97, 103, 101, 95, 79, 112, 101, 110, 40, 41, 58, 32, 105, 110, 116, 101, 114, 102, 97, 99, 101, 32,
|
||||||
|
115, 117, 98, 99, 108, 97, 115, 115, 32, 37, 105, 32, 97, 116, 97, 95, 112, 114, 111, 116, 32, 37, 105, 32, 10, 0, 73,
|
||||||
|
110, 32, 80, 111, 105, 110, 116, 58, 32, 37, 105, 10, 0, 79, 117, 116, 32, 80, 111, 105, 110, 116, 58, 32, 37, 105,
|
||||||
|
10, 0, 101, 112, 95, 105, 110, 32, 37, 120, 32, 101, 112, 95, 111, 117, 116, 32, 37, 120, 10, 0, 85, 83, 66, 83, 116,
|
||||||
|
111, 114, 97, 103, 101, 95, 79, 112, 101, 110, 40, 41, 58, 32, 99, 97, 110, 110, 111, 116, 32, 102, 105, 110, 100, 32,
|
||||||
|
97, 110, 121, 32, 105, 110, 116, 101, 114, 102, 97, 99, 101, 33, 33, 33, 10, 0, 85, 83, 66, 83, 116, 111, 114, 97, 103,
|
||||||
|
101, 95, 79, 112, 101, 110, 40, 41, 58, 32, 99, 111, 110, 102, 58, 32, 37, 120, 32, 97, 108, 116, 73, 110, 116, 101,
|
||||||
|
114, 102, 97, 99, 101, 58, 32, 37, 120, 10, 0, 85, 83, 66, 95, 71, 101, 116, 67, 111, 110, 102, 105, 103, 117, 114,
|
||||||
|
97, 116, 105, 111, 110, 40, 41, 32, 69, 114, 114, 111, 114, 46, 32, 67, 111, 110, 116, 105, 110, 117, 101, 46, 10, 0,
|
||||||
|
65, 99, 116, 117, 97, 108, 32, 99, 111, 110, 102, 58, 32, 37, 120, 32, 32, 32, 110, 101, 120, 116, 32, 99, 111, 110,
|
||||||
|
102, 58, 32, 37, 120, 10, 0, 85, 83, 66, 95, 83, 101, 116, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111,
|
||||||
|
110, 40, 41, 32, 69, 114, 114, 111, 114, 10, 0, 85, 83, 66, 95, 83, 101, 116, 65, 108, 116, 101, 114, 110, 97, 116,
|
||||||
|
105, 118, 101, 73, 110, 116, 101, 114, 102, 97, 99, 101, 40, 41, 32, 69, 114, 114, 111, 114, 46, 32, 67, 111, 110, 116,
|
||||||
|
105, 110, 117, 101, 10, 0, 85, 83, 66, 95, 83, 101, 116, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110,
|
||||||
|
40, 41, 32, 38, 32, 85, 83, 66, 95, 83, 101, 116, 65, 108, 116, 101, 114, 110, 97, 116, 105, 118, 101, 73, 110, 116,
|
||||||
|
101, 114, 102, 97, 99, 101, 40, 41, 32, 79, 75, 10, 0, 71, 101, 116, 95, 77, 97, 120, 95, 76, 117, 110, 40, 41, 58,
|
||||||
|
32, 101, 114, 114, 44, 32, 100, 101, 102, 97, 117, 108, 116, 32, 109, 97, 120, 95, 108, 117, 110, 61, 56, 10, 0, 71,
|
||||||
|
101, 116, 95, 77, 97, 120, 95, 76, 117, 110, 40, 41, 58, 32, 79, 75, 58, 32, 37, 105, 10, 0, 85, 83, 66, 83, 116, 111,
|
||||||
|
114, 97, 103, 101, 95, 79, 112, 101, 110, 40, 41, 58, 32, 116, 114, 121, 95, 115, 116, 97, 116, 117, 115, 32, 37, 105,
|
||||||
|
10, 0, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 79, 112, 101, 110, 40, 41, 58, 32, 79, 75, 44, 32, 114, 101,
|
||||||
|
116, 117, 114, 110, 32, 48, 10, 0, 32, 32, 32, 32, 115, 116, 97, 114, 116, 95, 115, 116, 111, 112, 32, 99, 109, 100,
|
||||||
|
32, 114, 101, 116, 32, 37, 105, 10, 0, 32, 32, 32, 32, 73, 110, 113, 117, 105, 114, 121, 32, 114, 101, 116, 32, 37,
|
||||||
|
105, 10, 0, 32, 32, 32, 32, 68, 101, 118, 105, 99, 101, 32, 84, 121, 112, 101, 58, 32, 37, 120, 10, 0, 32, 32, 32, 32,
|
||||||
|
82, 101, 97, 100, 67, 97, 112, 97, 99, 105, 116, 121, 32, 114, 101, 116, 32, 37, 105, 32, 32, 115, 101, 99, 116, 111,
|
||||||
|
114, 95, 115, 105, 122, 101, 58, 32, 37, 117, 32, 32, 115, 101, 99, 116, 111, 114, 115, 58, 32, 37, 117, 10, 0, 70,
|
||||||
|
97, 115, 116, 32, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 77, 111, 117, 110, 116, 76, 85, 78, 32, 37, 105,
|
||||||
|
35, 10, 0, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 77, 111, 117, 110, 116, 76, 85, 78, 58, 32, 114, 101, 116,
|
||||||
|
32, 37, 105, 10, 0, 85, 83, 66, 83, 84, 79, 82, 65, 71, 69, 95, 71, 69, 84, 95, 77, 65, 88, 95, 76, 85, 78, 32, 114,
|
||||||
|
101, 116, 32, 37, 105, 32, 109, 97, 120, 108, 117, 110, 32, 37, 105, 10, 0, 85, 83, 66, 83, 116, 111, 114, 97, 103,
|
||||||
|
101, 95, 77, 111, 117, 110, 116, 76, 85, 78, 32, 102, 97, 105, 108, 33, 33, 33, 10, 0, 10, 42, 42, 42, 42, 42, 42, 42,
|
||||||
|
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
|
||||||
|
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 10, 82, 111, 100, 114, 105, 101, 115, 32, 101, 104, 99,
|
||||||
|
109, 111, 100, 117, 108, 101, 32, 49, 46, 48, 10, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 73, 110, 105, 116,
|
||||||
|
40, 41, 10, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
|
||||||
|
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 10, 10, 0, 85, 83,
|
||||||
|
66, 83, 116, 111, 114, 97, 103, 101, 95, 73, 110, 105, 116, 40, 41, 32, 79, 107, 10, 0, 69, 114, 114, 111, 114, 32,
|
||||||
|
82, 101, 97, 100, 105, 110, 103, 32, 115, 101, 99, 116, 111, 114, 32, 48, 10, 0, 79, 75, 32, 82, 101, 97, 100, 105,
|
||||||
|
110, 103, 32, 115, 101, 99, 116, 111, 114, 32, 48, 10, 0, 85, 110, 112, 108, 117, 103, 58, 32, 114, 101, 115, 101, 116,
|
||||||
|
32, 37, 105, 32, 115, 116, 97, 116, 117, 115, 32, 37, 120, 10, 0, 102, 97, 115, 116, 95, 114, 101, 109, 111, 117, 110,
|
||||||
|
116, 32, 75, 79, 32, 114, 101, 116, 32, 37, 105, 10, 0, 85, 83, 66, 32, 65, 108, 108, 111, 99, 58, 32, 110, 111, 116,
|
||||||
|
32, 101, 110, 111, 117, 103, 104, 32, 109, 101, 109, 111, 114, 121, 33, 10, 0, 119, 98, 102, 115, 32, 101, 114, 114,
|
||||||
|
111, 114, 32, 0, 98, 97, 100, 32, 109, 97, 103, 105, 99, 0, 104, 100, 32, 115, 101, 99, 116, 111, 114, 32, 115, 105,
|
||||||
|
122, 101, 32, 100, 111, 101, 115, 110, 39, 116, 32, 109, 97, 116, 99, 104, 0, 104, 100, 32, 110, 117, 109, 32, 115,
|
||||||
|
101, 99, 116, 111, 114, 32, 100, 111, 101, 115, 110, 39, 116, 32, 109, 97, 116, 99, 104, 0, 78, 84, 70, 83, 0, 70, 65,
|
||||||
|
84, 0, 116, 114, 121, 105, 110, 103, 32, 116, 111, 32, 99, 108, 111, 115, 101, 32, 119, 98, 102, 115, 32, 119, 104,
|
||||||
|
105, 108, 101, 32, 100, 105, 115, 99, 115, 32, 115, 116, 105, 108, 108, 32, 111, 112, 101, 110, 0, 97, 108, 108, 111,
|
||||||
|
99, 97, 116, 105, 110, 103, 32, 109, 101, 109, 111, 114, 121, 0
|
||||||
|
};
|
3
bin/ehcmodule_5.h
Normal file
3
bin/ehcmodule_5.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#define size_ehcmodule_5 26234
|
||||||
|
|
||||||
|
extern unsigned char ehcmodule_5[26234];
|
288
cios_installer/add_dip_plugin.c
Normal file
288
cios_installer/add_dip_plugin.c
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
/* Copyright (C) 2008 Mega Man */
|
||||||
|
/* Based on Wii GameCube Homebrew Launcher */
|
||||||
|
/* Copyright (C) 2008 WiiGator */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <ogcsys.h>
|
||||||
|
#include <gccore.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "elf.h"
|
||||||
|
#include "add_dip_plugin.h"
|
||||||
|
#include "debug_printf.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// disabled
|
||||||
|
// XXXXXXXXXXXXXXXXXXXXX
|
||||||
|
|
||||||
|
#include "dip_plugin_bin.h"
|
||||||
|
#define round_up(x,n) (-(-(x) & -(n)))
|
||||||
|
|
||||||
|
/** Binary is loaded to this address. */
|
||||||
|
#if IOS36
|
||||||
|
#define BIN_PATCH_ADDR 0x202080e0
|
||||||
|
#define EXTENDED_AREA_START 0x20200000
|
||||||
|
#define BSS_START 0x2020a000
|
||||||
|
#define BSS_SIZE 0x0002c000
|
||||||
|
#elif IOS38
|
||||||
|
#define BIN_PATCH_ADDR 0x20208200
|
||||||
|
#define EXTENDED_AREA_START 0x20208000
|
||||||
|
#define BSS_START 0x20209000
|
||||||
|
#define BSS_SIZE 0x0002c000
|
||||||
|
#else
|
||||||
|
#ifdef ADD_DIP_PLUGIN
|
||||||
|
|
||||||
|
#error "Hey! i need IOS36 or IOS38 defined!"
|
||||||
|
|
||||||
|
#else
|
||||||
|
// fake data to compile the code
|
||||||
|
#define BIN_PATCH_ADDR 0x202080e0
|
||||||
|
#define EXTENDED_AREA_START 0x20200000
|
||||||
|
#define BSS_START 0x2020a000
|
||||||
|
#define BSS_SIZE 0x0002c000
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
/** Start of ELF area which is extneded. */
|
||||||
|
|
||||||
|
|
||||||
|
/** Header for Wii ARM binaries. */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/** Size of this header. */
|
||||||
|
uint32_t headerSize;
|
||||||
|
/** Offset to ELF file. */
|
||||||
|
uint32_t offset;
|
||||||
|
/** Size of ELF file. */
|
||||||
|
uint32_t size;
|
||||||
|
/** Padded with zeroes. */
|
||||||
|
uint32_t resevered;
|
||||||
|
}
|
||||||
|
|
||||||
|
arm_binary_header_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t cmd;
|
||||||
|
uint32_t function_orig;
|
||||||
|
uint32_t function_patch;
|
||||||
|
}
|
||||||
|
|
||||||
|
jmp_table_patch_entry_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy program sections of ELF file to new ELF file;
|
||||||
|
* @param buffer Pointer to ELF file.
|
||||||
|
*/
|
||||||
|
static int copy_sections(uint8_t *buffer, uint8_t *out)
|
||||||
|
{
|
||||||
|
Elf32_Ehdr_t *file_header;
|
||||||
|
int pos = 0;
|
||||||
|
int i;
|
||||||
|
uint32_t outPos = 0;
|
||||||
|
|
||||||
|
/* 0x1000 should be enough to copy ELF header. */
|
||||||
|
memcpy(out, buffer, 0x1000);
|
||||||
|
|
||||||
|
/* Use output (copied) elf header. */
|
||||||
|
file_header = (Elf32_Ehdr_t *) & out[pos];
|
||||||
|
pos += sizeof(Elf32_Ehdr_t);
|
||||||
|
|
||||||
|
if (file_header->magic != ELFMAGIC)
|
||||||
|
{
|
||||||
|
debug_printf("Magic 0x%08x is wrong.\n", file_header->magic);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
outPos = pos + file_header->phnum * sizeof(Elf32_Phdr_t);
|
||||||
|
//debug_printf("data start = 0x%02x\n", outPos);
|
||||||
|
|
||||||
|
for (i = 0; i < file_header->phnum; i++)
|
||||||
|
{
|
||||||
|
Elf32_Phdr_t *program_header;
|
||||||
|
program_header = (Elf32_Phdr_t *) & out[pos];
|
||||||
|
pos += sizeof(Elf32_Phdr_t);
|
||||||
|
|
||||||
|
if ( (program_header->type == PT_LOAD)
|
||||||
|
&& (program_header->memsz != 0) )
|
||||||
|
{
|
||||||
|
unsigned char *src;
|
||||||
|
unsigned char *dst;
|
||||||
|
|
||||||
|
// Copy to physical address which can be accessed by loader.
|
||||||
|
src = buffer + program_header->offset;
|
||||||
|
|
||||||
|
if (program_header->offset != sizeof(Elf32_Ehdr_t))
|
||||||
|
{
|
||||||
|
program_header->offset = outPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Don't change offset for first section. */
|
||||||
|
outPos = program_header->offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst = out + outPos;
|
||||||
|
|
||||||
|
if (program_header->vaddr == EXTENDED_AREA_START)
|
||||||
|
{
|
||||||
|
uint32_t origFileSize;
|
||||||
|
printf("Extended Area finded!!!!\n");
|
||||||
|
origFileSize = program_header->filesz;
|
||||||
|
program_header->filesz = program_header->memsz = BIN_PATCH_ADDR - EXTENDED_AREA_START + dip_plugin_bin_size;
|
||||||
|
memset(dst, 0, program_header->filesz);
|
||||||
|
|
||||||
|
if (origFileSize != 0)
|
||||||
|
{
|
||||||
|
memcpy(dst, src, origFileSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (program_header->vaddr == BSS_START)
|
||||||
|
{
|
||||||
|
printf("BSS Start finded!!!!\n");
|
||||||
|
//debug_printf("Extending BSS.\n");
|
||||||
|
program_header->memsz += 0x1000; //BSS_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*debug_printf("VAddr: 0x%08x PAddr: 0x%08x Offset 0x%08x File Size 0x%08x Mem Size 0x%08x\n",
|
||||||
|
program_header->vaddr,
|
||||||
|
program_header->paddr,
|
||||||
|
program_header->offset,
|
||||||
|
program_header->filesz,
|
||||||
|
program_header->memsz);
|
||||||
|
*/
|
||||||
|
if (program_header->filesz != 0)
|
||||||
|
{
|
||||||
|
if (program_header->vaddr == EXTENDED_AREA_START)
|
||||||
|
{
|
||||||
|
//debug_printf("Adding dip plugin with binary data in existing ELF section.\n");
|
||||||
|
memcpy(dst + BIN_PATCH_ADDR - EXTENDED_AREA_START, dip_plugin_bin, dip_plugin_bin_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(dst, src, program_header->filesz);
|
||||||
|
}
|
||||||
|
|
||||||
|
outPos += program_header->filesz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate required memory space.
|
||||||
|
* @param buffer Pointer to ELF file.
|
||||||
|
*/
|
||||||
|
static uint32_t calculate_new_size(uint8_t *buffer)
|
||||||
|
{
|
||||||
|
Elf32_Ehdr_t *file_header;
|
||||||
|
int pos = 0;
|
||||||
|
int i;
|
||||||
|
uint32_t maxSize = 0;
|
||||||
|
|
||||||
|
file_header = (Elf32_Ehdr_t *) & buffer[pos];
|
||||||
|
pos += sizeof(Elf32_Ehdr_t);
|
||||||
|
|
||||||
|
if (file_header->magic != ELFMAGIC)
|
||||||
|
{
|
||||||
|
debug_printf("Magic 0x%08x is wrong.\n", file_header->magic);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < file_header->phnum; i++)
|
||||||
|
{
|
||||||
|
Elf32_Phdr_t *program_header;
|
||||||
|
|
||||||
|
program_header = (Elf32_Phdr_t *) & buffer[pos];
|
||||||
|
pos += sizeof(Elf32_Phdr_t);
|
||||||
|
|
||||||
|
if ( (program_header->type == PT_LOAD)
|
||||||
|
&& (program_header->memsz != 0) )
|
||||||
|
{
|
||||||
|
unsigned char *src;
|
||||||
|
|
||||||
|
/*debug_printf("VAddr: 0x%08x PAddr: 0x%08x Offset 0x%08x File Size 0x%08x Mem Size 0x%08x\n",
|
||||||
|
program_header->vaddr,
|
||||||
|
program_header->paddr,
|
||||||
|
program_header->offset,
|
||||||
|
program_header->filesz,
|
||||||
|
program_header->memsz);
|
||||||
|
*/
|
||||||
|
src = buffer + program_header->offset;
|
||||||
|
|
||||||
|
if (program_header->filesz != 0)
|
||||||
|
{
|
||||||
|
uint32_t size;
|
||||||
|
|
||||||
|
size = program_header->offset + program_header->filesz;
|
||||||
|
|
||||||
|
if (size > maxSize)
|
||||||
|
{
|
||||||
|
maxSize = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Real calculation after getting all information .*/
|
||||||
|
return maxSize + BIN_PATCH_ADDR - EXTENDED_AREA_START + dip_plugin_bin_size + sizeof(Elf32_Phdr_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
int add_dip_plugin(uint8_t **buffer)
|
||||||
|
{
|
||||||
|
uint8_t *inElf = NULL;
|
||||||
|
uint8_t *outElf = NULL;
|
||||||
|
uint32_t outElfSize;
|
||||||
|
uint32_t content_size;
|
||||||
|
|
||||||
|
inElf = *buffer;
|
||||||
|
|
||||||
|
debug_printf("Adding DIP plugin\n");
|
||||||
|
|
||||||
|
outElfSize = calculate_new_size(inElf);
|
||||||
|
|
||||||
|
if (outElfSize <= 0)
|
||||||
|
{
|
||||||
|
debug_printf("add dip plugin Patching failed\n");
|
||||||
|
return -32;
|
||||||
|
}
|
||||||
|
|
||||||
|
content_size = round_up(outElfSize, 0x40);
|
||||||
|
outElf = malloc(content_size);
|
||||||
|
|
||||||
|
if (outElf == NULL)
|
||||||
|
{
|
||||||
|
debug_printf("Out of memory\n");
|
||||||
|
return -33;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Set default to 0. */
|
||||||
|
memset(outElf, 0, content_size);
|
||||||
|
|
||||||
|
debug_printf("\n");
|
||||||
|
|
||||||
|
if (copy_sections(inElf, outElf) < 0)
|
||||||
|
{
|
||||||
|
debug_printf("Failed to patch ELF.\n");
|
||||||
|
return -39;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
*buffer = outElf;
|
||||||
|
free(inElf);
|
||||||
|
return outElfSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXXXXXXXXXXXXXXXXXXX
|
||||||
|
#endif
|
8
cios_installer/add_dip_plugin.h
Normal file
8
cios_installer/add_dip_plugin.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef _ADD_KERNEL_CODE_H_
|
||||||
|
#define _ADD_KERNEL_CODE_H_
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
int add_dip_plugin(uint8_t **buffer);
|
||||||
|
|
||||||
|
#endif
|
BIN
cios_installer/data/ticket.raw
Normal file
BIN
cios_installer/data/ticket.raw
Normal file
Binary file not shown.
BIN
cios_installer/data/tmd.raw
Normal file
BIN
cios_installer/data/tmd.raw
Normal file
Binary file not shown.
3
ehcmodule/EHCI.SearchResults
Normal file
3
ehcmodule/EHCI.SearchResults
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
---- port = Matches (2 in 2 files) ----
|
||||||
|
Ehci.c (c:\devkitpro\soft\uloader_v2.6\cios_mload\tinyehci): dev->port = i;
|
||||||
|
Ehci1.c (c:\devkitpro\soft\uloader_v2.6\cios_mload\tinyehci): dev->port = i;
|
BIN
ehcmodule/bin/ehcmodule.elf
Normal file
BIN
ehcmodule/bin/ehcmodule.elf
Normal file
Binary file not shown.
BIN
ehcmodule/bin/ehcmodule.rar
Normal file
BIN
ehcmodule/bin/ehcmodule.rar
Normal file
Binary file not shown.
498
ehcmodule/source/ehc_loop.c.old
Normal file
498
ehcmodule/source/ehc_loop.c.old
Normal file
@ -0,0 +1,498 @@
|
|||||||
|
/*
|
||||||
|
Custom IOS module for Wii.
|
||||||
|
OH0 message loop
|
||||||
|
Copyright (C) 2009 kwiirk.
|
||||||
|
Copyright (C) 2008 neimod.
|
||||||
|
|
||||||
|
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 of the License, 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, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* oh0_loop.c - IOS module main code
|
||||||
|
* even if we are "ehc" driver, we still pretend to be "oh0"
|
||||||
|
* and implement "standard" ios oh0 usb api
|
||||||
|
*
|
||||||
|
*******************************************************************************
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "syscalls.h"
|
||||||
|
#include "ehci_types.h"
|
||||||
|
#include "ehci.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "libwbfs.h"
|
||||||
|
|
||||||
|
void ehci_usleep(int usec);
|
||||||
|
void ehci_msleep(int msec);
|
||||||
|
|
||||||
|
#undef NULL
|
||||||
|
#define NULL ((void *)0)
|
||||||
|
#define IOS_OPEN 0x01
|
||||||
|
#define IOS_CLOSE 0x02
|
||||||
|
#define IOS_IOCTL 0x06
|
||||||
|
#define IOS_IOCTLV 0x07
|
||||||
|
|
||||||
|
#define USB_IOCTL_CTRLMSG 0
|
||||||
|
#define USB_IOCTL_BLKMSG 1
|
||||||
|
#define USB_IOCTL_INTRMSG 2
|
||||||
|
#define USB_IOCTL_SUSPENDDEV 5
|
||||||
|
#define USB_IOCTL_RESUMEDEV 6
|
||||||
|
#define USB_IOCTL_GETDEVLIST 12
|
||||||
|
#define USB_IOCTL_DEVREMOVALHOOK 26
|
||||||
|
#define USB_IOCTL_DEVINSERTHOOK 27
|
||||||
|
|
||||||
|
#define UMS_BASE (('U'<<24)|('M'<<16)|('S'<<8))
|
||||||
|
#define USB_IOCTL_UMS_INIT (UMS_BASE+0x1)
|
||||||
|
#define USB_IOCTL_UMS_GET_CAPACITY (UMS_BASE+0x2)
|
||||||
|
#define USB_IOCTL_UMS_READ_SECTORS (UMS_BASE+0x3)
|
||||||
|
#define USB_IOCTL_UMS_WRITE_SECTORS (UMS_BASE+0x4)
|
||||||
|
|
||||||
|
#define USB_IOCTL_UMS_READ_STRESS (UMS_BASE+0x5)
|
||||||
|
|
||||||
|
#define USB_IOCTL_UMS_SET_VERBOSE (UMS_BASE+0x6)
|
||||||
|
|
||||||
|
#define USB_IOCTL_UMS_UMOUNT (UMS_BASE+0x10)
|
||||||
|
#define USB_IOCTL_UMS_WATCHDOG (UMS_BASE+0x80)
|
||||||
|
|
||||||
|
#define WBFS_BASE (('W'<<24)|('F'<<16)|('S'<<8))
|
||||||
|
#define USB_IOCTL_WBFS_OPEN_DISC (WBFS_BASE+0x1)
|
||||||
|
#define USB_IOCTL_WBFS_READ_DISC (WBFS_BASE+0x2)
|
||||||
|
|
||||||
|
//#define USB_IOCTL_WBFS_SPEED_LIMIT (WBFS_BASE+0x80)
|
||||||
|
|
||||||
|
void USBStorage_Umount(void);
|
||||||
|
|
||||||
|
//#define DEVICE "/dev/usb/ehc"
|
||||||
|
#define DEVICE "/dev/usb2"
|
||||||
|
|
||||||
|
int verbose = 0;
|
||||||
|
#define ioctlv_u8(a) (*((u8*)(a).data))
|
||||||
|
#define ioctlv_u16(a) (*((u16*)(a).data))
|
||||||
|
#define ioctlv_u32(a) (*((u32*)(a).data))
|
||||||
|
#define ioctlv_voidp(a) (a).data
|
||||||
|
|
||||||
|
wbfs_disc_t * wbfs_init_with_partition(u8*discid, int partition);
|
||||||
|
|
||||||
|
|
||||||
|
#define WATCHDOG_TIMER 1000*1000*4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
char *parse_hex(char *base,int *val)
|
||||||
|
{
|
||||||
|
int v = 0,done=0;
|
||||||
|
char *ptr = base,c;
|
||||||
|
while(!done)
|
||||||
|
{
|
||||||
|
c = *ptr++;
|
||||||
|
if(c >= '0' && c <= '9')
|
||||||
|
v = v << 4 | (c-'0');
|
||||||
|
else if(c >= 'a' && c <= 'f')
|
||||||
|
v = v << 4 | (10+c-'a');
|
||||||
|
else if(c >= 'A' && c <= 'F')
|
||||||
|
v = v << 4 | (10+c-'A');
|
||||||
|
else
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
if(ptr==base+1)//only incremented once
|
||||||
|
return 0; //we did not found any hex numbers
|
||||||
|
*val = v;
|
||||||
|
return ptr-1;
|
||||||
|
}
|
||||||
|
int parse_and_open_device(char *devname,int fd)
|
||||||
|
{
|
||||||
|
char *ptr = devname;
|
||||||
|
int vid,pid;
|
||||||
|
if (! (ptr = parse_hex(ptr,&vid)))
|
||||||
|
return -6;
|
||||||
|
if ( *ptr != '/' )
|
||||||
|
return -6;
|
||||||
|
ptr++;// skip /
|
||||||
|
if (! (ptr = parse_hex(ptr,&pid)))
|
||||||
|
return -6;
|
||||||
|
if ( *ptr != '\0' )
|
||||||
|
return -6;
|
||||||
|
return ehci_open_device(vid,pid,fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int DVD_speed_limit=0; // ingame it can fix x6 speed
|
||||||
|
|
||||||
|
int watchdog_enable=1;
|
||||||
|
|
||||||
|
// special ingame
|
||||||
|
int wbfs_disc_read2(wbfs_disc_t*d,u32 offset, u8 *data, u32 len);
|
||||||
|
|
||||||
|
// heap space for WBFS and queue
|
||||||
|
|
||||||
|
extern int heaphandle;
|
||||||
|
|
||||||
|
void msleep(int msec);
|
||||||
|
|
||||||
|
u8 mem_sector[2048] __attribute__ ((aligned (32)));
|
||||||
|
|
||||||
|
void *WBFS_Alloc(int size)
|
||||||
|
{
|
||||||
|
void * ret = 0;
|
||||||
|
ret= os_heap_alloc(heaphandle, size);
|
||||||
|
if(ret==0)
|
||||||
|
{debug_printf("WBFS not enough memory! need %d\n",size);
|
||||||
|
my_sprint("WBFS not enough memory!", NULL);
|
||||||
|
while(1) ehci_msleep(100);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
void WBFS_Free(void *ptr)
|
||||||
|
{
|
||||||
|
return os_heap_free(heaphandle, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void my_sprint(char *cad, char *s)
|
||||||
|
{
|
||||||
|
int n=strlen(cad);
|
||||||
|
int m=0;
|
||||||
|
int fd;
|
||||||
|
os_sync_after_write(cad, n);
|
||||||
|
if(s) {m=strlen(s);os_sync_after_write(s, m);}
|
||||||
|
|
||||||
|
fd=os_open("/dev/fat/log", 1);
|
||||||
|
if(fd<0) return;
|
||||||
|
os_write(fd, cad, n);
|
||||||
|
|
||||||
|
if(s)
|
||||||
|
os_write(fd, s, m);
|
||||||
|
os_close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
char my_log[256];
|
||||||
|
|
||||||
|
void my_dump(char *cad, char *dat, int len)
|
||||||
|
{
|
||||||
|
int n,m;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
|
||||||
|
fd=ios_open("/dev/fat/log", 1);
|
||||||
|
if(fd<0) return;
|
||||||
|
|
||||||
|
n=0;
|
||||||
|
while(*cad) {my_log[n]=*cad++;n++;}
|
||||||
|
my_log[n]='\n';n++;
|
||||||
|
|
||||||
|
for(m=0;m<len;m++)
|
||||||
|
{
|
||||||
|
if(n>=253) {ios_write(fd, my_log, n);n=0;}
|
||||||
|
my_log[n]=((*dat>>8) & 0xf)+48;if(my_log[n]>'9') my_log[n]+=7; n++;
|
||||||
|
my_log[n]=((*dat) & 0xf)+48;if(my_log[n]>'9') my_log[n]+=7; n++;
|
||||||
|
my_log[n]=((m & 15)!=15) ? ' ' : '\n'; n++;
|
||||||
|
dat++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(n>0)
|
||||||
|
{
|
||||||
|
os_sync_after_write((void *) cad, n);
|
||||||
|
os_write(fd, my_log, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
ios_close(fd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern int unplug_device;
|
||||||
|
|
||||||
|
int unplug_procedure(void);
|
||||||
|
|
||||||
|
int ehc_loop(void)
|
||||||
|
{
|
||||||
|
ipcmessage* message;
|
||||||
|
int timer2_id=-1;
|
||||||
|
|
||||||
|
int last_sector=0;
|
||||||
|
|
||||||
|
int must_read_sectors=0;
|
||||||
|
|
||||||
|
|
||||||
|
my_sprint("ehc loop entry", NULL);
|
||||||
|
|
||||||
|
void* queuespace = os_heap_alloc(heaphandle, 0x40);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int queuehandle = os_message_queue_create(queuespace, 16);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
os_device_register(DEVICE, queuehandle);
|
||||||
|
timer2_id=os_create_timer(WATCHDOG_TIMER, WATCHDOG_TIMER, queuehandle, 0x666);
|
||||||
|
|
||||||
|
|
||||||
|
int ums_mode = 0;
|
||||||
|
int already_discovered = 0;
|
||||||
|
wbfs_disc_t *d = 0;
|
||||||
|
|
||||||
|
int usb_lock=0;
|
||||||
|
|
||||||
|
int watch_time_on=1;
|
||||||
|
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
int result = 1;
|
||||||
|
int ack = 1;
|
||||||
|
|
||||||
|
|
||||||
|
// Wait for message to arrive
|
||||||
|
os_message_queue_receive(queuehandle, (void*)&message, 0);
|
||||||
|
|
||||||
|
// timer message WATCHDOG
|
||||||
|
if((int) message==0x555) continue;
|
||||||
|
|
||||||
|
if(watch_time_on)
|
||||||
|
os_stop_timer(timer2_id); // stops watchdog timer
|
||||||
|
watch_time_on=0;
|
||||||
|
|
||||||
|
|
||||||
|
if((int) message==0x666)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(must_read_sectors && watchdog_enable)
|
||||||
|
{
|
||||||
|
int n,m;
|
||||||
|
|
||||||
|
unplug_procedure();
|
||||||
|
if(unplug_device==0 && !usb_lock)
|
||||||
|
{
|
||||||
|
|
||||||
|
n=USBStorage_Get_Capacity((void *) &m);
|
||||||
|
if(m!=0 && m<2048) // only support sector size minor to 2048
|
||||||
|
{
|
||||||
|
|
||||||
|
USBStorage_Read_Sectors(last_sector, 1, mem_sector);
|
||||||
|
last_sector+=0x1000000/m; // steps of 16MB
|
||||||
|
if(last_sector>n) last_sector=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
watch_time_on=1;
|
||||||
|
os_restart_timer(timer2_id, WATCHDOG_TIMER);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//print_hex_dump_bytes("msg",0, message,sizeof(*message));
|
||||||
|
switch( message->command )
|
||||||
|
{
|
||||||
|
case IOS_OPEN:
|
||||||
|
{
|
||||||
|
//debug_printf("%s try open %sfor fd %d\n",DEVICE,message->open.device,message->open.resultfd);
|
||||||
|
// Checking device name
|
||||||
|
if (0 == strcmp(message->open.device, DEVICE))
|
||||||
|
{
|
||||||
|
result = message->open.resultfd;
|
||||||
|
if(!already_discovered)
|
||||||
|
ehci_discover();
|
||||||
|
already_discovered=1;
|
||||||
|
}
|
||||||
|
else if (!ums_mode && 0 == memcmp(message->open.device, DEVICE"/", sizeof(DEVICE)))
|
||||||
|
result = parse_and_open_device(message->open.device+sizeof(DEVICE),message->open.resultfd);
|
||||||
|
else
|
||||||
|
result = -6;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOS_CLOSE:
|
||||||
|
{
|
||||||
|
//debug_printf("close fd %d\n",message->fd);
|
||||||
|
if(ums_mode == message->fd)
|
||||||
|
ums_mode = 0;
|
||||||
|
else
|
||||||
|
ehci_close_device(ehci_fd_to_dev(message->fd));
|
||||||
|
// do nothing
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOS_IOCTL:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IOS_IOCTLV:
|
||||||
|
{
|
||||||
|
ioctlv *vec = message->ioctlv.vector;
|
||||||
|
void *dev =NULL;
|
||||||
|
int i,in = message->ioctlv.num_in,io= message->ioctlv.num_io;
|
||||||
|
if( 0==(message->ioctl.command>>24) && !ums_mode)
|
||||||
|
dev = ehci_fd_to_dev(message->fd);
|
||||||
|
os_sync_before_read( vec, (in+io)*sizeof(ioctlv));
|
||||||
|
for(i=0;i<in+io;i++){
|
||||||
|
os_sync_before_read( vec[i].data, vec[i].len);
|
||||||
|
//print_hex_dump_bytes("vec",0, vec[i].data,vec[i].len);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( message->ioctl.command )
|
||||||
|
{
|
||||||
|
case USB_IOCTL_CTRLMSG:
|
||||||
|
//debug_printf("ctrl message%x\n",dev);
|
||||||
|
if(!dev)result= -6;
|
||||||
|
else
|
||||||
|
result = ehci_control_message(dev,ioctlv_u8(vec[0]),ioctlv_u8(vec[1]),
|
||||||
|
swab16(ioctlv_u16(vec[2])),swab16(ioctlv_u16(vec[3])),
|
||||||
|
swab16(ioctlv_u16(vec[4])),ioctlv_voidp(vec[6]));
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_BLKMSG:
|
||||||
|
//debug_printf("bulk message\n");
|
||||||
|
if(!dev)result= -6;
|
||||||
|
else
|
||||||
|
result = ehci_bulk_message(dev,ioctlv_u8(vec[0]),ioctlv_u16(vec[1]),
|
||||||
|
ioctlv_voidp(vec[2]));
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_INTRMSG:
|
||||||
|
debug_printf("intr message\n");
|
||||||
|
case USB_IOCTL_SUSPENDDEV:
|
||||||
|
case USB_IOCTL_RESUMEDEV:
|
||||||
|
debug_printf("or resume/suspend message\n");
|
||||||
|
result = 0;//-1;// not supported
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_GETDEVLIST:
|
||||||
|
debug_printf("get dev list\n");
|
||||||
|
if(dev)result= -6;
|
||||||
|
else
|
||||||
|
result = ehci_get_device_list(ioctlv_u8(vec[0]),ioctlv_u8(vec[1]),
|
||||||
|
ioctlv_voidp(vec[2]),ioctlv_voidp(vec[3]));
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_DEVREMOVALHOOK:
|
||||||
|
case USB_IOCTL_DEVINSERTHOOK:
|
||||||
|
debug_printf("removal/insert hook\n");
|
||||||
|
ack = 0; // dont reply to those, as we dont detect anything
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_UMS_INIT:
|
||||||
|
must_read_sectors=0;
|
||||||
|
|
||||||
|
result = USBStorage_Init();
|
||||||
|
//result=-os_thread_get_priority();
|
||||||
|
if(result>=0) {must_read_sectors=1;watchdog_enable=1;}
|
||||||
|
ums_mode = message->fd;
|
||||||
|
if(result>=0) my_sprint("UMS Init", NULL); else my_sprint("UMS fail", NULL);
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_UMS_UMOUNT:
|
||||||
|
must_read_sectors=0;
|
||||||
|
watchdog_enable=0;
|
||||||
|
USBStorage_Umount();
|
||||||
|
result =0;
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_UMS_GET_CAPACITY:
|
||||||
|
result = USBStorage_Get_Capacity(ioctlv_voidp(vec[0]));
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_UMS_READ_SECTORS:
|
||||||
|
if (verbose)
|
||||||
|
debug_printf("%p read sector %d %d %p\n",&vec[0],ioctlv_u32(vec[0]),ioctlv_u32(vec[1]), ioctlv_voidp(vec[2]));
|
||||||
|
|
||||||
|
result = USBStorage_Read_Sectors(ioctlv_u32(vec[0]),ioctlv_u32(vec[1]), ioctlv_voidp(vec[2]));
|
||||||
|
|
||||||
|
//udelay(ioctlv_u32(vec[1])*125);
|
||||||
|
if(result) break;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_UMS_WRITE_SECTORS:
|
||||||
|
result = USBStorage_Write_Sectors(ioctlv_u32(vec[0]),ioctlv_u32(vec[1]), ioctlv_voidp(vec[2]));
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_UMS_READ_STRESS:
|
||||||
|
result = USBStorage_Read_Stress(ioctlv_u32(vec[0]),ioctlv_u32(vec[1]), ioctlv_voidp(vec[2]));
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_UMS_SET_VERBOSE:
|
||||||
|
verbose = !verbose;
|
||||||
|
result = 0;
|
||||||
|
break;
|
||||||
|
/*case USB_IOCTL_WBFS_SPEED_LIMIT:
|
||||||
|
DVD_speed_limit=ioctlv_u32(vec[0]);
|
||||||
|
break;*/
|
||||||
|
case USB_IOCTL_UMS_WATCHDOG:
|
||||||
|
watchdog_enable=ioctlv_u32(vec[0]);
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_WBFS_OPEN_DISC:
|
||||||
|
ums_mode = message->fd;
|
||||||
|
|
||||||
|
int partition=0;
|
||||||
|
// if (verbose)
|
||||||
|
debug_printf("ehc:use disc %s\n",ioctlv_voidp(vec[0]));
|
||||||
|
if(vec[1].len==4) memcpy(&partition, ioctlv_voidp(vec[1]), 4);
|
||||||
|
d = wbfs_init_with_partition(ioctlv_voidp(vec[0]), partition);
|
||||||
|
if(!d)
|
||||||
|
result = -1;
|
||||||
|
else
|
||||||
|
{result = 0;watchdog_enable=1;}
|
||||||
|
my_sprint("WBFS Open()", NULL);
|
||||||
|
must_read_sectors=1;
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_WBFS_READ_DISC:
|
||||||
|
if (verbose)
|
||||||
|
debug_printf("r%x %x\n",ioctlv_u32(vec[0]),ioctlv_u32(vec[1]));
|
||||||
|
else
|
||||||
|
debug_printf("r%x %x\r",ioctlv_u32(vec[0]),ioctlv_u32(vec[1]));
|
||||||
|
if(!d || usb_lock)
|
||||||
|
result = -1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usb_lock=1;
|
||||||
|
//os_stop_timer(timer2_id);
|
||||||
|
result = wbfs_disc_read2(d,ioctlv_u32(vec[0]),ioctlv_voidp(vec[2]),ioctlv_u32(vec[1]));
|
||||||
|
usb_lock=0;
|
||||||
|
/* if(result){
|
||||||
|
debug_printf("wbfs failed! %d\n",result);
|
||||||
|
//result = 0x7800; // wii games shows unrecoverable error..
|
||||||
|
result = 0x8000;
|
||||||
|
}*/
|
||||||
|
result=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for(i=in;i<in+io;i++){
|
||||||
|
//print_hex_dump_bytes("iovec",0, vec[i].data,vec[i].len>0x20?0x20:vec[i].len);
|
||||||
|
os_sync_after_write( vec[i].data, vec[i].len);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
result = -1;
|
||||||
|
//ack = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(watchdog_enable)
|
||||||
|
{watch_time_on=1;
|
||||||
|
os_restart_timer(timer2_id, WATCHDOG_TIMER);
|
||||||
|
}
|
||||||
|
//debug_printf("return %d\n",result);
|
||||||
|
// Acknowledge message
|
||||||
|
|
||||||
|
if (ack)
|
||||||
|
os_message_queue_ack( (void*)message, result );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
522
ehcmodule/source/ehc_loop.c.orig
Normal file
522
ehcmodule/source/ehc_loop.c.orig
Normal file
@ -0,0 +1,522 @@
|
|||||||
|
/*
|
||||||
|
Custom IOS module for Wii.
|
||||||
|
OH0 message loop
|
||||||
|
Copyright (C) 2009 kwiirk.
|
||||||
|
Copyright (C) 2008 neimod.
|
||||||
|
|
||||||
|
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 of the License, 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, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* oh0_loop.c - IOS module main code
|
||||||
|
* even if we are "ehc" driver, we still pretend to be "oh0"
|
||||||
|
* and implement "standard" ios oh0 usb api
|
||||||
|
*
|
||||||
|
*******************************************************************************
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "syscalls.h"
|
||||||
|
#include "ehci_types.h"
|
||||||
|
#include "ehci.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "libwbfs.h"
|
||||||
|
|
||||||
|
void ehci_usleep(int usec);
|
||||||
|
void ehci_msleep(int msec);
|
||||||
|
|
||||||
|
#undef NULL
|
||||||
|
#define NULL ((void *)0)
|
||||||
|
#define IOS_OPEN 0x01
|
||||||
|
#define IOS_CLOSE 0x02
|
||||||
|
#define IOS_IOCTL 0x06
|
||||||
|
#define IOS_IOCTLV 0x07
|
||||||
|
|
||||||
|
#define USB_IOCTL_CTRLMSG 0
|
||||||
|
#define USB_IOCTL_BLKMSG 1
|
||||||
|
#define USB_IOCTL_INTRMSG 2
|
||||||
|
#define USB_IOCTL_SUSPENDDEV 5
|
||||||
|
#define USB_IOCTL_RESUMEDEV 6
|
||||||
|
#define USB_IOCTL_GETDEVLIST 12
|
||||||
|
#define USB_IOCTL_DEVREMOVALHOOK 26
|
||||||
|
#define USB_IOCTL_DEVINSERTHOOK 27
|
||||||
|
|
||||||
|
#define UMS_BASE (('U'<<24)|('M'<<16)|('S'<<8))
|
||||||
|
#define USB_IOCTL_UMS_INIT (UMS_BASE+0x1)
|
||||||
|
#define USB_IOCTL_UMS_GET_CAPACITY (UMS_BASE+0x2)
|
||||||
|
#define USB_IOCTL_UMS_READ_SECTORS (UMS_BASE+0x3)
|
||||||
|
#define USB_IOCTL_UMS_WRITE_SECTORS (UMS_BASE+0x4)
|
||||||
|
|
||||||
|
#define USB_IOCTL_UMS_READ_STRESS (UMS_BASE+0x5)
|
||||||
|
|
||||||
|
#define USB_IOCTL_UMS_SET_VERBOSE (UMS_BASE+0x6)
|
||||||
|
#define USB_IOCTL_UMS_IS_INSERTED (UMS_BASE+0x7)
|
||||||
|
|
||||||
|
#define USB_IOCTL_UMS_UMOUNT (UMS_BASE+0x10)
|
||||||
|
#define USB_IOCTL_UMS_START (UMS_BASE+0x11)
|
||||||
|
#define USB_IOCTL_UMS_STOP (UMS_BASE+0x12)
|
||||||
|
#define USB_IOCTL_UMS_WATCHDOG (UMS_BASE+0x80)
|
||||||
|
|
||||||
|
#define WBFS_BASE (('W'<<24)|('F'<<16)|('S'<<8))
|
||||||
|
#define USB_IOCTL_WBFS_OPEN_DISC (WBFS_BASE+0x1)
|
||||||
|
#define USB_IOCTL_WBFS_READ_DISC (WBFS_BASE+0x2)
|
||||||
|
|
||||||
|
|
||||||
|
s32 USBStorage_Umount(void);
|
||||||
|
s32 USBStorage_Start(void);
|
||||||
|
s32 USBStorage_Stop(void);
|
||||||
|
|
||||||
|
|
||||||
|
//#define DEVICE "/dev/usb/ehc"
|
||||||
|
#define DEVICE "/dev/usb2"
|
||||||
|
|
||||||
|
int verbose = 0;
|
||||||
|
#define ioctlv_u8(a) (*((u8*)(a).data))
|
||||||
|
#define ioctlv_u16(a) (*((u16*)(a).data))
|
||||||
|
#define ioctlv_u32(a) (*((u32*)(a).data))
|
||||||
|
#define ioctlv_voidp(a) (a).data
|
||||||
|
|
||||||
|
wbfs_disc_t * wbfs_init_with_partition(u8*discid, int partition);
|
||||||
|
|
||||||
|
|
||||||
|
#define WATCHDOG_TIMER 1000*1000*5
|
||||||
|
|
||||||
|
|
||||||
|
char *parse_hex(char *base,int *val)
|
||||||
|
{
|
||||||
|
int v = 0,done=0;
|
||||||
|
char *ptr = base,c;
|
||||||
|
while(!done)
|
||||||
|
{
|
||||||
|
c = *ptr++;
|
||||||
|
if(c >= '0' && c <= '9')
|
||||||
|
v = v << 4 | (c-'0');
|
||||||
|
else if(c >= 'a' && c <= 'f')
|
||||||
|
v = v << 4 | (10+c-'a');
|
||||||
|
else if(c >= 'A' && c <= 'F')
|
||||||
|
v = v << 4 | (10+c-'A');
|
||||||
|
else
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
if(ptr==base+1)//only incremented once
|
||||||
|
return 0; //we did not found any hex numbers
|
||||||
|
*val = v;
|
||||||
|
return ptr-1;
|
||||||
|
}
|
||||||
|
int parse_and_open_device(char *devname,int fd)
|
||||||
|
{
|
||||||
|
char *ptr = devname;
|
||||||
|
int vid,pid;
|
||||||
|
if (! (ptr = parse_hex(ptr,&vid)))
|
||||||
|
return -6;
|
||||||
|
if ( *ptr != '/' )
|
||||||
|
return -6;
|
||||||
|
ptr++;// skip /
|
||||||
|
if (! (ptr = parse_hex(ptr,&pid)))
|
||||||
|
return -6;
|
||||||
|
if ( *ptr != '\0' )
|
||||||
|
return -6;
|
||||||
|
return ehci_open_device(vid,pid,fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int DVD_speed_limit=0; // ingame it can fix x6 speed
|
||||||
|
|
||||||
|
int watchdog_enable=0;
|
||||||
|
|
||||||
|
// special ingame
|
||||||
|
int wbfs_disc_read2(wbfs_disc_t*d,u32 offset, u8 *data, u32 len);
|
||||||
|
|
||||||
|
// heap space for WBFS and queue
|
||||||
|
|
||||||
|
extern int heaphandle;
|
||||||
|
|
||||||
|
void msleep(int msec);
|
||||||
|
|
||||||
|
u8 mem_sector[2048] __attribute__ ((aligned (32)));
|
||||||
|
|
||||||
|
void *WBFS_Alloc(int size)
|
||||||
|
{
|
||||||
|
void * ret = 0;
|
||||||
|
ret= os_heap_alloc(heaphandle, size);
|
||||||
|
if(ret==0)
|
||||||
|
{debug_printf("WBFS not enough memory! need %d\n",size);
|
||||||
|
my_sprint("WBFS not enough memory!", NULL);
|
||||||
|
while(1) ehci_msleep(100);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
void WBFS_Free(void *ptr)
|
||||||
|
{
|
||||||
|
return os_heap_free(heaphandle, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void my_sprint(char *cad, char *s)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
int n=strlen(cad);
|
||||||
|
int m=0;
|
||||||
|
int fd;
|
||||||
|
os_sync_after_write(cad, n);
|
||||||
|
if(s) {m=strlen(s);os_sync_after_write(s, m);}
|
||||||
|
|
||||||
|
fd=os_open("/dev/fat/log", 1);
|
||||||
|
if(fd<0) return;
|
||||||
|
os_write(fd, cad, n);
|
||||||
|
|
||||||
|
if(s)
|
||||||
|
os_write(fd, s, m);
|
||||||
|
os_close(fd);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
char my_log[256];
|
||||||
|
|
||||||
|
void my_dump(char *cad, char *dat, int len)
|
||||||
|
{
|
||||||
|
int n,m;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
|
||||||
|
fd=ios_open("/dev/fat/log", 1);
|
||||||
|
if(fd<0) return;
|
||||||
|
|
||||||
|
n=0;
|
||||||
|
while(*cad) {my_log[n]=*cad++;n++;}
|
||||||
|
my_log[n]='\n';n++;
|
||||||
|
|
||||||
|
for(m=0;m<len;m++)
|
||||||
|
{
|
||||||
|
if(n>=253) {ios_write(fd, my_log, n);n=0;}
|
||||||
|
my_log[n]=((*dat>>8) & 0xf)+48;if(my_log[n]>'9') my_log[n]+=7; n++;
|
||||||
|
my_log[n]=((*dat) & 0xf)+48;if(my_log[n]>'9') my_log[n]+=7; n++;
|
||||||
|
my_log[n]=((m & 15)!=15) ? ' ' : '\n'; n++;
|
||||||
|
dat++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(n>0)
|
||||||
|
{
|
||||||
|
ios_sync_after_write((void *) cad, n);
|
||||||
|
ios_write(fd, my_log, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
ios_close(fd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
void my_sprint2(char *cad)
|
||||||
|
{
|
||||||
|
int n=strlen(cad);
|
||||||
|
int fd;
|
||||||
|
os_sync_after_write(cad, n);
|
||||||
|
fd=os_open("/dev/fat/log", 1);
|
||||||
|
if(fd<0) return;
|
||||||
|
os_write(fd, cad, n);
|
||||||
|
os_close(fd);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//#ifdef HOMEBREW
|
||||||
|
extern bool first_access;
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
int ehc_loop(void)
|
||||||
|
{
|
||||||
|
ipcmessage* message;
|
||||||
|
int timer2_id=-1;
|
||||||
|
|
||||||
|
//my_sprint2("ehc loop entry");
|
||||||
|
// my_sprint("ehc loop entry", NULL);
|
||||||
|
|
||||||
|
void* queuespace = os_heap_alloc(heaphandle, 0x40);
|
||||||
|
|
||||||
|
int queuehandle = os_message_queue_create(queuespace, 32);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
timer2_id=os_create_timer(WATCHDOG_TIMER, WATCHDOG_TIMER, queuehandle, 0x666);
|
||||||
|
|
||||||
|
int ums_mode = 0;
|
||||||
|
int already_discovered = 0;
|
||||||
|
wbfs_disc_t *d = 0;
|
||||||
|
int usb_lock=0;
|
||||||
|
int cnt_timer=0;
|
||||||
|
|
||||||
|
// wbfs_disc_t *d = 0;
|
||||||
|
|
||||||
|
// int usb_lock=0;
|
||||||
|
|
||||||
|
int watch_time_on=1;
|
||||||
|
os_device_register(DEVICE, queuehandle);
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
int result = 1;
|
||||||
|
int ack = 1;
|
||||||
|
|
||||||
|
// Wait for message to arrive
|
||||||
|
os_message_queue_receive(queuehandle, (void*)&message, 0);
|
||||||
|
|
||||||
|
|
||||||
|
os_stop_timer(timer2_id); // stops watchdog timer
|
||||||
|
|
||||||
|
// timer message WATCHDOG
|
||||||
|
if((int) message==0x555) continue;
|
||||||
|
|
||||||
|
if(watch_time_on)
|
||||||
|
os_stop_timer(timer2_id); // stops watchdog timer
|
||||||
|
watch_time_on=0;
|
||||||
|
|
||||||
|
|
||||||
|
if((int) message==0x666)
|
||||||
|
{
|
||||||
|
cnt_timer++;
|
||||||
|
if(cnt_timer<6) //every 30 secs
|
||||||
|
{
|
||||||
|
watch_time_on=1;
|
||||||
|
os_restart_timer(timer2_id, WATCHDOG_TIMER);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cnt_timer=0;
|
||||||
|
first_access=true;
|
||||||
|
watchdog_enable=0;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//print_hex_dump_bytes("msg",0, message,sizeof(*message));
|
||||||
|
switch( message->command )
|
||||||
|
{
|
||||||
|
case IOS_OPEN:
|
||||||
|
{
|
||||||
|
#ifdef HOMEBREW
|
||||||
|
if (0 == strcmp(message->open.device, DEVICE))
|
||||||
|
result = message->open.resultfd;
|
||||||
|
else
|
||||||
|
result = -6;
|
||||||
|
|
||||||
|
#else
|
||||||
|
// Checking device name
|
||||||
|
if (0 == strcmp(message->open.device, DEVICE))
|
||||||
|
{
|
||||||
|
result = message->open.resultfd;
|
||||||
|
if(!already_discovered)
|
||||||
|
ehci_discover();
|
||||||
|
already_discovered=1;
|
||||||
|
}
|
||||||
|
else if (!ums_mode && 0 == memcmp(message->open.device, DEVICE"/", sizeof(DEVICE)))
|
||||||
|
result = parse_and_open_device(message->open.device+sizeof(DEVICE),message->open.resultfd);
|
||||||
|
else
|
||||||
|
result = -6;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOS_CLOSE:
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifndef HOMEBREW
|
||||||
|
//debug_printf("close fd %d\n",message->fd);
|
||||||
|
if(ums_mode == message->fd)
|
||||||
|
ums_mode = 0;
|
||||||
|
else
|
||||||
|
ehci_close_device(ehci_fd_to_dev(message->fd));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// do nothing
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOS_IOCTL:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IOS_IOCTLV:
|
||||||
|
{
|
||||||
|
ioctlv *vec = message->ioctlv.vector;
|
||||||
|
void *dev =NULL;
|
||||||
|
int i,in = message->ioctlv.num_in,io= message->ioctlv.num_io;
|
||||||
|
#ifdef HOMEBREW
|
||||||
|
if( 0==(message->ioctl.command>>24))
|
||||||
|
dev = ehci_fd_to_dev(message->fd);
|
||||||
|
#else
|
||||||
|
if( 0==(message->ioctl.command>>24) && !ums_mode)
|
||||||
|
dev = ehci_fd_to_dev(message->fd);
|
||||||
|
#endif
|
||||||
|
os_sync_before_read( vec, (in+io)*sizeof(ioctlv));
|
||||||
|
for(i=0;i<in+io;i++){
|
||||||
|
os_sync_before_read( vec[i].data, vec[i].len);
|
||||||
|
//print_hex_dump_bytes("vec",0, vec[i].data,vec[i].len);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( message->ioctl.command )
|
||||||
|
{
|
||||||
|
case USB_IOCTL_CTRLMSG:
|
||||||
|
//debug_printf("ctrl message%x\n",dev);
|
||||||
|
if(!dev)result= -6;
|
||||||
|
else
|
||||||
|
result = ehci_control_message(dev,ioctlv_u8(vec[0]),ioctlv_u8(vec[1]),
|
||||||
|
swab16(ioctlv_u16(vec[2])),swab16(ioctlv_u16(vec[3])),
|
||||||
|
swab16(ioctlv_u16(vec[4])),ioctlv_voidp(vec[6]));
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_BLKMSG:
|
||||||
|
//debug_printf("bulk message\n");
|
||||||
|
if(!dev)result= -6;
|
||||||
|
else
|
||||||
|
result = ehci_bulk_message(dev,ioctlv_u8(vec[0]),ioctlv_u16(vec[1]),
|
||||||
|
ioctlv_voidp(vec[2]));
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_INTRMSG:
|
||||||
|
debug_printf("intr message\n");
|
||||||
|
case USB_IOCTL_SUSPENDDEV:
|
||||||
|
case USB_IOCTL_RESUMEDEV:
|
||||||
|
debug_printf("or resume/suspend message\n");
|
||||||
|
result = 0;//-1;// not supported
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_GETDEVLIST:
|
||||||
|
debug_printf("get dev list\n");
|
||||||
|
if(dev)result= -6;
|
||||||
|
else
|
||||||
|
result = ehci_get_device_list(ioctlv_u8(vec[0]),ioctlv_u8(vec[1]),
|
||||||
|
ioctlv_voidp(vec[2]),ioctlv_voidp(vec[3]));
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_DEVREMOVALHOOK:
|
||||||
|
case USB_IOCTL_DEVINSERTHOOK:
|
||||||
|
debug_printf("removal/insert hook\n");
|
||||||
|
ack = 0; // dont reply to those, as we dont detect anything
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_UMS_INIT:
|
||||||
|
result = USBStorage_Init();
|
||||||
|
if(result>=0) watchdog_enable=1;
|
||||||
|
#ifndef HOMEBREW
|
||||||
|
ums_mode = message->fd;
|
||||||
|
//if(result>=0) my_sprint("UMS Init", NULL); else my_sprint("UMS fail", NULL);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_UMS_UMOUNT:
|
||||||
|
watchdog_enable=0;
|
||||||
|
result = USBStorage_Umount();
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_UMS_START:
|
||||||
|
result = USBStorage_Start();
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_UMS_STOP:
|
||||||
|
result = USBStorage_Stop();
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_UMS_GET_CAPACITY:
|
||||||
|
result = USBStorage_Get_Capacity(ioctlv_voidp(vec[0]));
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_UMS_READ_SECTORS:
|
||||||
|
os_stop_timer(timer2_id);
|
||||||
|
result = USBStorage_Read_Sectors(ioctlv_u32(vec[0]),ioctlv_u32(vec[1]), ioctlv_voidp(vec[2]));
|
||||||
|
cnt_timer=0;
|
||||||
|
watchdog_enable=1;
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_UMS_WRITE_SECTORS:
|
||||||
|
os_stop_timer(timer2_id);
|
||||||
|
result = USBStorage_Write_Sectors(ioctlv_u32(vec[0]),ioctlv_u32(vec[1]), ioctlv_voidp(vec[2]));
|
||||||
|
cnt_timer=0;
|
||||||
|
watchdog_enable=1;
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_UMS_READ_STRESS:
|
||||||
|
result = USBStorage_Read_Stress(ioctlv_u32(vec[0]),ioctlv_u32(vec[1]), ioctlv_voidp(vec[2]));
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_UMS_SET_VERBOSE:
|
||||||
|
verbose = !verbose;
|
||||||
|
result = 0;
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_UMS_IS_INSERTED:
|
||||||
|
result = ehci_is_inserted();
|
||||||
|
break;
|
||||||
|
/*case USB_IOCTL_WBFS_SPEED_LIMIT:
|
||||||
|
DVD_speed_limit=ioctlv_u32(vec[0]);
|
||||||
|
break;*/
|
||||||
|
case USB_IOCTL_UMS_WATCHDOG:
|
||||||
|
watchdog_enable=ioctlv_u32(vec[0]);
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_WBFS_OPEN_DISC:
|
||||||
|
ums_mode = message->fd;
|
||||||
|
|
||||||
|
int partition=0;
|
||||||
|
// if (verbose)
|
||||||
|
debug_printf("ehc:use disc %s\n",ioctlv_voidp(vec[0]));
|
||||||
|
if(vec[1].len==4) memcpy(&partition, ioctlv_voidp(vec[1]), 4);
|
||||||
|
d = wbfs_init_with_partition(ioctlv_voidp(vec[0]), partition);
|
||||||
|
if(!d)
|
||||||
|
result = -1;
|
||||||
|
else
|
||||||
|
{result = 0;watchdog_enable=1;}
|
||||||
|
my_sprint("WBFS Open()", NULL);
|
||||||
|
cnt_timer=0;
|
||||||
|
break;
|
||||||
|
case USB_IOCTL_WBFS_READ_DISC:
|
||||||
|
if(!d || usb_lock)
|
||||||
|
result = -1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usb_lock=1;
|
||||||
|
//os_stop_timer(timer2_id);
|
||||||
|
result = wbfs_disc_read2(d,ioctlv_u32(vec[0]),ioctlv_voidp(vec[2]),ioctlv_u32(vec[1]));
|
||||||
|
usb_lock=0;
|
||||||
|
cnt_timer=0;
|
||||||
|
/* if(result){
|
||||||
|
debug_printf("wbfs failed! %d\n",result);
|
||||||
|
//result = 0x7800; // wii games shows unrecoverable error..
|
||||||
|
result = 0x8000;
|
||||||
|
}*/
|
||||||
|
result=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for(i=in;i<in+io;i++){
|
||||||
|
//print_hex_dump_bytes("iovec",0, vec[i].data,vec[i].len>0x20?0x20:vec[i].len);
|
||||||
|
os_sync_after_write( vec[i].data, vec[i].len);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// os_message_queue_send(queuehandle, (void*)message, 0);
|
||||||
|
result = -1;
|
||||||
|
//ack = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(watchdog_enable)
|
||||||
|
{
|
||||||
|
watch_time_on=1;
|
||||||
|
os_restart_timer(timer2_id, WATCHDOG_TIMER);
|
||||||
|
}
|
||||||
|
//debug_printf("return %d\n",result);
|
||||||
|
// Acknowledge message
|
||||||
|
if (ack)
|
||||||
|
os_message_queue_ack( (void*)message, result );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
90
ehcmodule/source/ums.c
Normal file
90
ehcmodule/source/ums.c
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#ifndef HOMEBREW
|
||||||
|
#include "syscalls.h"
|
||||||
|
#include "ios_usbstorage.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#define UMS_BASE (('U'<<24)|('M'<<16)|('S'<<8))
|
||||||
|
#define USB_IOCTL_UMS_INIT (UMS_BASE+0x1)
|
||||||
|
#define USB_IOCTL_UMS_GET_CAPACITY (UMS_BASE+0x2)
|
||||||
|
#define USB_IOCTL_UMS_READ_SECTORS (UMS_BASE+0x3)
|
||||||
|
#define USB_IOCTL_UMS_WRITE_SECTORS (UMS_BASE+0x4)
|
||||||
|
#define USB_IOCTL_UMS_READ_STRESS (UMS_BASE+0x5)
|
||||||
|
#define USB_IOCTL_UMS_SET_VERBOSE (UMS_BASE+0x6)
|
||||||
|
|
||||||
|
static int fd;
|
||||||
|
static u32 sector_size;
|
||||||
|
static u32 num_sector;
|
||||||
|
static int heap;
|
||||||
|
/* */
|
||||||
|
void ums_init(void)
|
||||||
|
{
|
||||||
|
ioctlv *vec;
|
||||||
|
u32 *p_sector_size;
|
||||||
|
fd = os_open("/dev/usb2", 1);
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
debug_printf("unable to open /dev/usb2 %d\n", fd);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
os_ioctlv(fd, USB_IOCTL_UMS_INIT, 0, 0, 0);
|
||||||
|
|
||||||
|
heap = os_heap_create((void*)0x13898000, 0x8000);
|
||||||
|
vec = os_heap_alloc(heap, sizeof(ioctlv));
|
||||||
|
p_sector_size = os_heap_alloc(heap, sizeof(u32));
|
||||||
|
|
||||||
|
vec[0].data = p_sector_size;
|
||||||
|
vec[0].len = 4;
|
||||||
|
num_sector = os_ioctlv(fd, USB_IOCTL_UMS_GET_CAPACITY, 0, 1, vec);
|
||||||
|
sector_size = *p_sector_size;
|
||||||
|
debug_printf("found device %d %d: %dkB\n", sector_size, num_sector, sector_size*(num_sector / 1024));
|
||||||
|
os_heap_free(heap, vec);
|
||||||
|
os_heap_free(heap, p_sector_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *ums_alloc(int size)
|
||||||
|
{
|
||||||
|
return os_heap_alloc(heap, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ums_free(void *ptr)
|
||||||
|
{
|
||||||
|
os_heap_free(heap, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 ums_read_sectors(u32 sector, u32 numSectors, void *buffer)
|
||||||
|
{
|
||||||
|
ioctlv *vec;
|
||||||
|
u32 *p_sector;
|
||||||
|
u32 *p_nsector;
|
||||||
|
s32 ret;
|
||||||
|
vec = os_heap_alloc(heap, sizeof(ioctlv) * 3);
|
||||||
|
p_sector = os_heap_alloc(heap, sizeof(u32));
|
||||||
|
p_nsector = os_heap_alloc(heap, sizeof(u32));
|
||||||
|
*p_nsector = numSectors;
|
||||||
|
*p_sector = sector;
|
||||||
|
|
||||||
|
vec[0].data = p_sector;
|
||||||
|
vec[0].len = 4;
|
||||||
|
vec[1].data = p_nsector;
|
||||||
|
vec[1].len = 4;
|
||||||
|
vec[2].data = buffer;
|
||||||
|
vec[2].len = sector_size * numSectors;
|
||||||
|
ret = os_ioctlv(fd, USB_IOCTL_UMS_READ_SECTORS, 2, 1, vec);
|
||||||
|
// no need to flush cache, this is done by ehc..
|
||||||
|
os_heap_free(heap, vec);
|
||||||
|
os_heap_free(heap, p_sector);
|
||||||
|
os_heap_free(heap, p_nsector);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ums_close(void)
|
||||||
|
{
|
||||||
|
os_close(fd);
|
||||||
|
os_heap_destroy(heap);
|
||||||
|
fd = -1;
|
||||||
|
heap = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
498
mload/source/main.c.bak
Normal file
498
mload/source/main.c.bak
Normal file
@ -0,0 +1,498 @@
|
|||||||
|
/*
|
||||||
|
dev/mload: Custom IOS module for Wii, to load ios elfs, initialize USB 2.0 and others uses
|
||||||
|
This module is derived from haxx.elf
|
||||||
|
Copyright (C) 2009 Hermes.
|
||||||
|
Copyright (C) 2008 neimod.
|
||||||
|
|
||||||
|
|
||||||
|
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 of the License, 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, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* main.c - IOS module main code
|
||||||
|
*
|
||||||
|
*******************************************************************************
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* v1.0 - 26 July 2008 - initial release by neimod
|
||||||
|
* v1.1 - 5 September 2008 - prepared for public release
|
||||||
|
* v1.2 - march 2008 - added some IOTCL, put it into its own module, by kwiirk
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "syscalls.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define IOS_OPEN 0x01
|
||||||
|
#define IOS_CLOSE 0x02
|
||||||
|
#define IOS_READ 0x03
|
||||||
|
#define IOS_WRITE 0x04
|
||||||
|
#define IOS_SEEK 0x05
|
||||||
|
#define IOS_IOCTL 0x06
|
||||||
|
#define IOS_IOCTLV 0x07
|
||||||
|
|
||||||
|
#define MLOAD_MLOAD_THREAD_ID 0x4D4C4400
|
||||||
|
|
||||||
|
#define MLOAD_LOAD_MODULE 0x4D4C4480
|
||||||
|
#define MLOAD_RUN_MODULE 0x4D4C4481
|
||||||
|
#define MLOAD_RUN_THREAD 0x4D4C4482
|
||||||
|
|
||||||
|
#define MLOAD_STOP_THREAD 0x4D4C4484
|
||||||
|
#define MLOAD_CONTINUE_THREAD 0x4D4C4485
|
||||||
|
|
||||||
|
#define MLOAD_GET_LOAD_BASE 0x4D4C4490
|
||||||
|
#define MLOAD_MEMSET 0x4D4C4491
|
||||||
|
|
||||||
|
#define MLOAD_GET_EHCI_DATA 0x4D4C44A0
|
||||||
|
|
||||||
|
#define MLOAD_SET_ES_IOCTLV 0x4D4C44B0
|
||||||
|
|
||||||
|
#define MLOAD_GETW 0x4D4C44C0
|
||||||
|
#define MLOAD_GETH 0x4D4C44C1
|
||||||
|
#define MLOAD_GETB 0x4D4C44C2
|
||||||
|
#define MLOAD_SETW 0x4D4C44C3
|
||||||
|
#define MLOAD_SETH 0x4D4C44C4
|
||||||
|
#define MLOAD_SETB 0x4D4C44C5
|
||||||
|
|
||||||
|
#define DEVICE "/dev/mload"
|
||||||
|
|
||||||
|
|
||||||
|
extern int ES_ioctlv_ret(void *);
|
||||||
|
|
||||||
|
unsigned ES_ioctlv_vect=((unsigned) ES_ioctlv_ret);
|
||||||
|
|
||||||
|
unsigned int heapspace[0x100/4] __attribute__ ((aligned (32)));
|
||||||
|
|
||||||
|
// from IOS ELF stripper of neimod
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 ident0;
|
||||||
|
u32 ident1;
|
||||||
|
u32 ident2;
|
||||||
|
u32 ident3;
|
||||||
|
u32 machinetype;
|
||||||
|
u32 version;
|
||||||
|
u32 entry;
|
||||||
|
u32 phoff;
|
||||||
|
u32 shoff;
|
||||||
|
u32 flags;
|
||||||
|
u16 ehsize;
|
||||||
|
u16 phentsize;
|
||||||
|
u16 phnum;
|
||||||
|
u16 shentsize;
|
||||||
|
u16 shnum;
|
||||||
|
u16 shtrndx;
|
||||||
|
} elfheader;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 type;
|
||||||
|
u32 offset;
|
||||||
|
u32 vaddr;
|
||||||
|
u32 paddr;
|
||||||
|
u32 filesz;
|
||||||
|
u32 memsz;
|
||||||
|
u32 flags;
|
||||||
|
u32 align;
|
||||||
|
} elfphentry;
|
||||||
|
|
||||||
|
#define ioctlv_u8(a) (*((u8*)(a).data))
|
||||||
|
#define ioctlv_u16(a) (*((u16*)(a).data))
|
||||||
|
#define ioctlv_u32(a) (*((u32*)(a).data))
|
||||||
|
#define ioctlv_voidp(a) (a).data
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern u8 *mem_exe; // size 0x80000 (see crt0.s)
|
||||||
|
|
||||||
|
|
||||||
|
struct _data_elf
|
||||||
|
{
|
||||||
|
void *start;
|
||||||
|
int prio;
|
||||||
|
void *stack;
|
||||||
|
int size_stack;
|
||||||
|
}
|
||||||
|
data_elf;
|
||||||
|
|
||||||
|
#define getbe32(x) ((adr[x]<<24) | (adr[x+1]<<16) | (adr[x+2]<<8) | (adr[x+3]))
|
||||||
|
|
||||||
|
|
||||||
|
int load_elf(u32 elf)
|
||||||
|
{
|
||||||
|
int n,m;
|
||||||
|
int p;
|
||||||
|
u8 *adr;
|
||||||
|
|
||||||
|
elfheader *head=(void *) elf;
|
||||||
|
elfphentry *entries;
|
||||||
|
|
||||||
|
if(head->ident0!=0x7F454C46) return -1;
|
||||||
|
if(head->ident1!=0x01020161) return -1;
|
||||||
|
if(head->ident2!=0x01000000) return -1;
|
||||||
|
|
||||||
|
p=head->phoff;
|
||||||
|
|
||||||
|
data_elf.start=(void *) head->entry;
|
||||||
|
|
||||||
|
for(n=0; n<head->phnum; n++)
|
||||||
|
{
|
||||||
|
entries=(void *) (elf+p);
|
||||||
|
p+=sizeof(elfphentry);
|
||||||
|
|
||||||
|
if(entries->type == 4)
|
||||||
|
{
|
||||||
|
adr=(void *) (elf + entries->offset);
|
||||||
|
|
||||||
|
if(getbe32(0)!=0) return -2; // bad info (sure)
|
||||||
|
|
||||||
|
for(m=4; m < entries->memsz; m+=8)
|
||||||
|
{
|
||||||
|
switch(getbe32(m))
|
||||||
|
{
|
||||||
|
case 0x9:
|
||||||
|
data_elf.start= (void *) getbe32(m+4);
|
||||||
|
break;
|
||||||
|
case 0x7D:
|
||||||
|
data_elf.prio= getbe32(m+4);
|
||||||
|
break;
|
||||||
|
case 0x7E:
|
||||||
|
data_elf.size_stack= getbe32(m+4);
|
||||||
|
break;
|
||||||
|
case 0x7F:
|
||||||
|
data_elf.stack= (void *) (getbe32(m+4));
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(entries->type == 1 && entries->memsz != 0 && entries->vaddr!=0)
|
||||||
|
{
|
||||||
|
|
||||||
|
os_sync_before_read((void *) entries->vaddr, entries->memsz );
|
||||||
|
|
||||||
|
memset((void *) entries->vaddr, 0, entries->memsz);
|
||||||
|
memcpy((void *) entries->vaddr, (void *) (elf + entries->offset), entries->filesz);
|
||||||
|
|
||||||
|
os_sync_after_write((void *) entries->vaddr, entries->memsz );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void *ehci;
|
||||||
|
int tiny_ehci_init(void);
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
ipcmessage* message;
|
||||||
|
unsigned int offset = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mem_exe[0]=0; // don't remove this !!!!!
|
||||||
|
|
||||||
|
|
||||||
|
tiny_ehci_init();
|
||||||
|
|
||||||
|
unsigned int heaphandle = os_heap_create(heapspace, sizeof(heapspace));
|
||||||
|
void* queuespace = os_heap_alloc(heaphandle, 0x20);
|
||||||
|
|
||||||
|
unsigned int queuehandle = os_message_queue_create(queuespace, 8);
|
||||||
|
|
||||||
|
os_device_register(DEVICE, queuehandle);
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
int result = 1;
|
||||||
|
int ack = 1;
|
||||||
|
|
||||||
|
// Wait for message to arrive
|
||||||
|
os_message_queue_receive(queuehandle, (void*)&message, 0);
|
||||||
|
|
||||||
|
switch( message->command )
|
||||||
|
{
|
||||||
|
case IOS_OPEN:
|
||||||
|
{
|
||||||
|
//debug_printf("%s try open %sfor fd %d\n",DEVICE,message->open.device,message->open.resultfd);
|
||||||
|
// Checking device name
|
||||||
|
if (0 == strcmp(message->open.device, DEVICE))
|
||||||
|
{
|
||||||
|
result = message->open.resultfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
result = -6;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOS_CLOSE:
|
||||||
|
{
|
||||||
|
|
||||||
|
// do nothing
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOS_READ:
|
||||||
|
{
|
||||||
|
// Read from Starlet memory
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (message->read.length == 4)
|
||||||
|
{
|
||||||
|
*(volatile unsigned long*)(message->read.data) = *(volatile unsigned long*)offset;
|
||||||
|
}
|
||||||
|
else if (message->read.length == 2)
|
||||||
|
{
|
||||||
|
*(volatile unsigned short*)(message->read.data) = *(volatile unsigned short*)offset;
|
||||||
|
}
|
||||||
|
else if (message->read.length == 1)
|
||||||
|
{
|
||||||
|
*(volatile unsigned char*)(message->read.data) = *(volatile unsigned char*)offset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(message->read.data, (void*)offset, message->read.length);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// NOTE: no aligned is better
|
||||||
|
memcpy(message->read.data, (void*)offset, message->read.length);
|
||||||
|
// Clean cache
|
||||||
|
os_sync_after_write( message->read.data, message->read.length );
|
||||||
|
offset += message->read.length;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOS_WRITE:
|
||||||
|
{
|
||||||
|
// Write to Starlet memory
|
||||||
|
// Invalidate cache
|
||||||
|
os_sync_before_read( message->write.data, message->write.length );
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (message->write.length == 4)
|
||||||
|
{
|
||||||
|
*(volatile unsigned long*)offset = *(volatile unsigned long*)(message->write.data);
|
||||||
|
}
|
||||||
|
else if (message->write.length == 2)
|
||||||
|
{
|
||||||
|
*(volatile unsigned short*)offset = *(volatile unsigned short*)(message->write.data);
|
||||||
|
}
|
||||||
|
else if (message->write.length == 1)
|
||||||
|
{
|
||||||
|
*(volatile unsigned char*)offset = *(volatile unsigned char*)(message->write.data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy((void*)offset, message->write.data, message->write.length);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
memcpy((void*)offset, message->write.data, message->write.length);
|
||||||
|
offset += message->write.length;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IOS_SEEK:
|
||||||
|
{
|
||||||
|
// Change current offset
|
||||||
|
switch(message->seek.origin)
|
||||||
|
{
|
||||||
|
case SEEK_SET:
|
||||||
|
{
|
||||||
|
offset = message->seek.offset;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SEEK_CUR:
|
||||||
|
{
|
||||||
|
offset += message->seek.offset;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SEEK_END:
|
||||||
|
{
|
||||||
|
offset = - message->seek.offset;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result=offset;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case IOS_IOCTL:
|
||||||
|
{
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case IOS_IOCTLV:
|
||||||
|
{
|
||||||
|
ioctlv *vec = message->ioctlv.vector;
|
||||||
|
|
||||||
|
int i,in = message->ioctlv.num_in,io= message->ioctlv.num_io;
|
||||||
|
|
||||||
|
os_sync_before_read( vec, (in+io)*sizeof(ioctlv));
|
||||||
|
|
||||||
|
for(i=0;i<in+io;i++){
|
||||||
|
os_sync_before_read( vec[i].data, vec[i].len);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( message->ioctl.command )
|
||||||
|
{
|
||||||
|
|
||||||
|
case MLOAD_MLOAD_THREAD_ID:
|
||||||
|
|
||||||
|
result=os_get_thread_id();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MLOAD_GET_EHCI_DATA:
|
||||||
|
|
||||||
|
result= (u32) ehci;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MLOAD_GET_LOAD_BASE:
|
||||||
|
|
||||||
|
result=0;
|
||||||
|
ioctlv_u32(vec[0])= 0x13700000;
|
||||||
|
ioctlv_u32(vec[1])= 0x80000;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MLOAD_LOAD_MODULE:
|
||||||
|
|
||||||
|
result = load_elf((u32) ioctlv_voidp(vec[0]));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MLOAD_RUN_MODULE:
|
||||||
|
|
||||||
|
result=os_thread_create( data_elf.start, NULL, data_elf.stack, data_elf.size_stack, data_elf.prio, 0);
|
||||||
|
if(result>=0) os_thread_continue(result);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MLOAD_RUN_THREAD:
|
||||||
|
|
||||||
|
result=os_thread_create((void *) ioctlv_u32(vec[0]), NULL, (void *) ioctlv_u32(vec[1]), ioctlv_u32(vec[2]), ioctlv_u32(vec[3]), 0);
|
||||||
|
if(result>=0) os_thread_continue(result);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MLOAD_STOP_THREAD:
|
||||||
|
|
||||||
|
result=os_thread_stop(ioctlv_u32(vec[0]));
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
case MLOAD_CONTINUE_THREAD:
|
||||||
|
|
||||||
|
result=os_thread_continue(ioctlv_u32(vec[0]));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case MLOAD_MEMSET:
|
||||||
|
result=0;
|
||||||
|
os_sync_before_read((void *) ioctlv_u32(vec[0]), ioctlv_u32(vec[2]));
|
||||||
|
memset((void *) ioctlv_u32(vec[0]), ioctlv_u32(vec[1]), ioctlv_u32(vec[2]));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MLOAD_SET_ES_IOCTLV: // changes the current vector for dev/es ioctl (put 0 to disable it)
|
||||||
|
result=0;
|
||||||
|
ES_ioctlv_vect=ioctlv_u32(vec[0]);
|
||||||
|
os_sync_after_write( &ES_ioctlv_vect, 4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MLOAD_GETW:
|
||||||
|
result=0;
|
||||||
|
ioctlv_u32(vec[1])=*((volatile u32*) ioctlv_u32(vec[0]));
|
||||||
|
break;
|
||||||
|
case MLOAD_GETH:
|
||||||
|
result=0;
|
||||||
|
ioctlv_u16(vec[1])=*((volatile u16*) ioctlv_u16(vec[0]));
|
||||||
|
break;
|
||||||
|
case MLOAD_GETB:
|
||||||
|
result=0;
|
||||||
|
ioctlv_u8(vec[1])=*((volatile u8*) ioctlv_u8(vec[0]));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MLOAD_SETW:
|
||||||
|
result=0;
|
||||||
|
*((volatile u32*) ioctlv_u32(vec[0]))=ioctlv_u32(vec[1]);
|
||||||
|
break;
|
||||||
|
case MLOAD_SETH:
|
||||||
|
result=0;
|
||||||
|
*((volatile u16*) ioctlv_u16(vec[0]))=ioctlv_u16(vec[1]);
|
||||||
|
break;
|
||||||
|
case MLOAD_SETB:
|
||||||
|
result=0;
|
||||||
|
*((volatile u8*) ioctlv_u8(vec[0]))=ioctlv_u8(vec[1]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (message->read.length == 4)
|
||||||
|
{
|
||||||
|
*(volatile unsigned long*)(message->read.data) = *(volatile unsigned long*)offset;
|
||||||
|
}
|
||||||
|
else if (message->read.length == 2)
|
||||||
|
{
|
||||||
|
*(volatile unsigned short*)(message->read.data) = *(volatile unsigned short*)offset;
|
||||||
|
}
|
||||||
|
else if (message->read.length == 1)
|
||||||
|
{
|
||||||
|
*(volatile unsigned char*)(message->read.data) = *(volatile unsigned char*)offset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(message->read.data, (void*)offset, message->read.length);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
for(i=in;i<in+io;i++){
|
||||||
|
os_sync_after_write( vec[i].data, vec[i].len);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
result = -1;
|
||||||
|
//ack = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//debug_printf("return %d\n",result);
|
||||||
|
// Acknowledge message
|
||||||
|
if (ack)
|
||||||
|
os_message_queue_ack( (void*)message, result );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
151
test/Makefile
Normal file
151
test/Makefile
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# Clear the implicit built in rules
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
.SUFFIXES:
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifeq ($(strip $(DEVKITPPC)),)
|
||||||
|
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC)
|
||||||
|
endif
|
||||||
|
|
||||||
|
include $(DEVKITPPC)/wii_rules
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# TARGET is the name of the output
|
||||||
|
# BUILD is the directory where object files & intermediate files will be placed
|
||||||
|
# SOURCES is a list of directories containing source code
|
||||||
|
# INCLUDES is a list of directories containing extra header files
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
TARGET := $(notdir $(CURDIR))
|
||||||
|
BUILD := build
|
||||||
|
SOURCES := source
|
||||||
|
DATA := data
|
||||||
|
INCLUDES :=
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# options for code generation
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CFLAGS = -mrvl -Wall $(MACHDEP) $(INCLUDE)
|
||||||
|
CXXFLAGS = $(CFLAGS)
|
||||||
|
|
||||||
|
LDFLAGS = $(MACHDEP) -mrvl -Wl,-Map,$(notdir $@).map
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# any extra libraries we wish to link with the project
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
#LIBS := -lwiiuse -lbte -ldi -ldb -lfat -logc -lm
|
||||||
|
LIBS := -lwiiuse -lbte -lfat -ldi -logc -lm
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# list of directories containing libraries, this must be the top level containing
|
||||||
|
# include and lib
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
LIBDIRS :=
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# no real need to edit anything past this point unless you need to add additional
|
||||||
|
# rules for different file extensions
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||||
|
|
||||||
|
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||||
|
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||||
|
|
||||||
|
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# automatically build a list of object files for our project
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||||
|
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||||
|
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||||
|
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
|
||||||
|
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# use CXX for linking C++ projects, CC for standard C
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
ifeq ($(strip $(CPPFILES)),)
|
||||||
|
export LD := $(CC)
|
||||||
|
else
|
||||||
|
export LD := $(CXX)
|
||||||
|
endif
|
||||||
|
|
||||||
|
export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||||
|
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
|
||||||
|
$(sFILES:.s=.o) $(SFILES:.S=.o)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# build a list of include paths
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
export INCLUDE := $(foreach dir,$(INCLUDES), -iquote $(CURDIR)/$(dir)) \
|
||||||
|
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||||
|
-I$(CURDIR)/$(BUILD) \
|
||||||
|
-I$(LIBOGC_INC)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# build a list of library paths
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
|
||||||
|
-L$(LIBOGC_LIB)
|
||||||
|
|
||||||
|
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||||
|
.PHONY: $(BUILD) clean
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
$(BUILD):
|
||||||
|
@[ -d $@ ] || mkdir -p $@
|
||||||
|
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
clean:
|
||||||
|
@echo clean ...
|
||||||
|
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
run:
|
||||||
|
wl $(TARGET).dol
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
else
|
||||||
|
|
||||||
|
DEPENDS := $(OFILES:.o=.d)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# main targets
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
$(OUTPUT).dol: $(OUTPUT).elf
|
||||||
|
$(OUTPUT).elf: $(OFILES)
|
||||||
|
|
||||||
|
%.certs.o : %.certs
|
||||||
|
@echo $(notdir $<)
|
||||||
|
$(bin2o)
|
||||||
|
|
||||||
|
%.elf.o : %.elf
|
||||||
|
@echo $(notdir $<)
|
||||||
|
$(bin2o)
|
||||||
|
|
||||||
|
%.bin.o : %.bin
|
||||||
|
@echo $(notdir $<)
|
||||||
|
$(bin2o)
|
||||||
|
%.raw.o : %.raw
|
||||||
|
@echo $(notdir $<)
|
||||||
|
$(bin2o)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# This rule links in binary data with the .jpg extension
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
%.jpg.o : %.jpg
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
@echo $(notdir $<)
|
||||||
|
$(bin2o)
|
||||||
|
|
||||||
|
-include $(DEPENDS)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
endif
|
||||||
|
#---------------------------------------------------------------------------------
|
7
test/c.bat
Normal file
7
test/c.bat
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
rem make clean
|
||||||
|
copy /y C:\devkitPro\msys\home\Julian\cios_mload\ehcmodule\bin\ehcmodule.elf .\data
|
||||||
|
del /q .\build\ehcmodule.elf.o
|
||||||
|
del /q usb.dol
|
||||||
|
del /q usb.elf
|
||||||
|
make
|
||||||
|
copy /y USB.dol H:\apps\usb2\boot.dol
|
BIN
test/data/ehcmodule.elf
Normal file
BIN
test/data/ehcmodule.elf
Normal file
Binary file not shown.
1
test/dbg.bat
Normal file
1
test/dbg.bat
Normal file
@ -0,0 +1 @@
|
|||||||
|
C:\devkitPro\devkitPPC\bin\powerpc-gekko-addr2line -e test.elf %1
|
1
test/l.bat
Normal file
1
test/l.bat
Normal file
@ -0,0 +1 @@
|
|||||||
|
wiiload test.dol
|
7
test/m.bat
Normal file
7
test/m.bat
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
del test.elf
|
||||||
|
del test.dol
|
||||||
|
del .\build\ehcmodule.elf.o
|
||||||
|
del .\data\ehcmodule.elf
|
||||||
|
copy /y ..\ehcmodule\bin\ehcmodule.elf .\data
|
||||||
|
make
|
||||||
|
wiiload test.dol
|
7
test/m2.bat
Normal file
7
test/m2.bat
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
make clean
|
||||||
|
del .\data\ehcmodule.elf
|
||||||
|
copy /y ..\ehcmodule\bin\ehcmodule.elf .\data
|
||||||
|
del test.dol
|
||||||
|
del usb2_test.dol
|
||||||
|
make
|
||||||
|
ren test.dol usb2_test.dol
|
1072
test/source/di2.c
Normal file
1072
test/source/di2.c
Normal file
File diff suppressed because it is too large
Load Diff
98
test/source/di2.h
Normal file
98
test/source/di2.h
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/*-------------------------------------------------------------
|
||||||
|
|
||||||
|
di2.h -- Drive Interface library
|
||||||
|
|
||||||
|
Written by rodries
|
||||||
|
Modified from (and supplemental to) original libdi library:
|
||||||
|
|
||||||
|
Team Twiizers
|
||||||
|
Copyright (C) 2008
|
||||||
|
|
||||||
|
Erant
|
||||||
|
marcan
|
||||||
|
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any
|
||||||
|
damages arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any
|
||||||
|
purpose, including commercial applications, and to alter it and
|
||||||
|
redistribute it freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you
|
||||||
|
must not claim that you wrote the original software. If you use
|
||||||
|
this software in a product, an acknowledgment in the product
|
||||||
|
documentation would be appreciated but is not required.
|
||||||
|
|
||||||
|
2. Altered source versions must be plainly marked as such, and
|
||||||
|
must not be misrepresented as being the original software.
|
||||||
|
|
||||||
|
3. This notice may not be removed or altered from any source
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
-------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
All buffers in this document need to be 32-byte aligned!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DI2_H__
|
||||||
|
#define __DI2_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <ogc/ipc.h>
|
||||||
|
#include <ogc/disc_io.h>
|
||||||
|
#include <di/di.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
FUNCTION PROTOTYPES GO HERE!
|
||||||
|
*/
|
||||||
|
|
||||||
|
int DI2_Init(bool dvdx);
|
||||||
|
void DI2_Mount();
|
||||||
|
void DI2_Close();
|
||||||
|
int DI2_GetStatus();
|
||||||
|
|
||||||
|
int DI2_Identify(DI_DriveID* id);
|
||||||
|
int DI2_ReadDiscID(u64 *id);
|
||||||
|
int DI2_GetError(uint32_t* error);
|
||||||
|
int DI2_GetCoverRegister(uint32_t* status);
|
||||||
|
int DI2_Reset();
|
||||||
|
|
||||||
|
int DI2_StopMotor();
|
||||||
|
int DI2_Eject();
|
||||||
|
int DI2_KillDrive();
|
||||||
|
|
||||||
|
int DI2_ReadDVD(void* buf, uint32_t len, uint32_t lba);
|
||||||
|
int DI2_ReadDVDAsync(void* buf, uint32_t len, uint32_t lba, ipccallback ipc_cb);
|
||||||
|
|
||||||
|
int DI2_Read(void *buf, u32 size, u32 offset);
|
||||||
|
int DI2_UnencryptedRead(void *buf, u32 size, u32 offset);
|
||||||
|
|
||||||
|
int DI2_ReadDVDConfig(uint32_t* val, uint32_t flag);
|
||||||
|
int DI2_ReadDVDCopyright(uint32_t* copyright);
|
||||||
|
int DI2_ReadDVDDiscKey(void* buf);
|
||||||
|
int DI2_ReadDVDPhysical(void* buf);
|
||||||
|
int DI2_ReportKey(int keytype, uint32_t lba, void* buf);
|
||||||
|
|
||||||
|
int DI2_OpenPartition(u32 offset);
|
||||||
|
int DI2_ClosePartition(void);
|
||||||
|
|
||||||
|
void DI2_SetDVDMotorStopSecs(int secs);
|
||||||
|
unsigned int DI2_GetDVDMotorStopSecs(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
1526
test/source/libdvdiso.c
Normal file
1526
test/source/libdvdiso.c
Normal file
File diff suppressed because it is too large
Load Diff
20
test/source/libdvdiso.h
Normal file
20
test/source/libdvdiso.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef _LWISO9660_DEVOPTAB_H
|
||||||
|
#define _LWISO9660_DEVOPTAB_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern int WIIDVD_Init(bool dvdx);
|
||||||
|
extern void WIIDVD_Close(void);
|
||||||
|
extern int WIIDVD_Mount(void);
|
||||||
|
extern void WIIDVD_Unmount(void);
|
||||||
|
extern int WIIDVD_DiscPresent(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
203
test/source/libmload/include/mload.h
Normal file
203
test/source/libmload/include/mload.h
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
/* mload.c (for PPC) (c) 2009, Hermes
|
||||||
|
|
||||||
|
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 of the License, 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, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MLOAD_H__
|
||||||
|
#define __MLOAD_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ogcsys.h>
|
||||||
|
#include <gccore.h>
|
||||||
|
#include "unistd.h"
|
||||||
|
|
||||||
|
#define MLOAD_MLOAD_THREAD_ID 0x4D4C4400
|
||||||
|
#define MLOAD_LOAD_MODULE 0x4D4C4480
|
||||||
|
#define MLOAD_RUN_MODULE 0x4D4C4481
|
||||||
|
#define MLOAD_RUN_THREAD 0x4D4C4482
|
||||||
|
|
||||||
|
#define MLOAD_STOP_THREAD 0x4D4C4484
|
||||||
|
#define MLOAD_CONTINUE_THREAD 0x4D4C4485
|
||||||
|
|
||||||
|
#define MLOAD_GET_LOAD_BASE 0x4D4C4490
|
||||||
|
#define MLOAD_MEMSET 0x4D4C4491
|
||||||
|
|
||||||
|
#define MLOAD_GET_EHCI_DATA 0x4D4C44A0
|
||||||
|
|
||||||
|
#define MLOAD_SET_ES_IOCTLV 0x4D4C44B0
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// from IOS ELF stripper of neimod
|
||||||
|
|
||||||
|
#define getbe32(x) ((adr[x]<<24) | (adr[x+1]<<16) | (adr[x+2]<<8) | (adr[x+3]))
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 ident0;
|
||||||
|
u32 ident1;
|
||||||
|
u32 ident2;
|
||||||
|
u32 ident3;
|
||||||
|
u32 machinetype;
|
||||||
|
u32 version;
|
||||||
|
u32 entry;
|
||||||
|
u32 phoff;
|
||||||
|
u32 shoff;
|
||||||
|
u32 flags;
|
||||||
|
u16 ehsize;
|
||||||
|
u16 phentsize;
|
||||||
|
u16 phnum;
|
||||||
|
u16 shentsize;
|
||||||
|
u16 shnum;
|
||||||
|
u16 shtrndx;
|
||||||
|
}
|
||||||
|
|
||||||
|
elfheader;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 type;
|
||||||
|
u32 offset;
|
||||||
|
u32 vaddr;
|
||||||
|
u32 paddr;
|
||||||
|
u32 filesz;
|
||||||
|
u32 memsz;
|
||||||
|
u32 flags;
|
||||||
|
u32 align;
|
||||||
|
}
|
||||||
|
|
||||||
|
elfphentry;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *start;
|
||||||
|
int prio;
|
||||||
|
void *stack;
|
||||||
|
int size_stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
data_elf;
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// to init/test if the device is running
|
||||||
|
|
||||||
|
int mload_init();
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// to close the device (remember call it when rebooting the IOS!)
|
||||||
|
|
||||||
|
int mload_close();
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// to get the thread id of mload
|
||||||
|
|
||||||
|
int mload_get_thread_id();
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// get the base and the size of the memory readable/writable to load modules
|
||||||
|
|
||||||
|
int mload_get_load_base(u32 *starlet_base, int *size);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// load and run a module from starlet (it need to allocate MEM2 to send the elf file)
|
||||||
|
// the module must be a elf made with stripios
|
||||||
|
|
||||||
|
int mload_module(void *addr, int len);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// load a module from the PPC
|
||||||
|
// the module must be a elf made with stripios
|
||||||
|
|
||||||
|
int mload_elf(void *my_elf, data_elf *data_elf);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// run one thread (you can use to load modules or binary files)
|
||||||
|
|
||||||
|
int mload_run_thread(void *starlet_addr, void *starlet_top_stack, int stack_size, int priority);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// stops one starlet thread
|
||||||
|
|
||||||
|
int mload_stop_thread(int id);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// continue one stopped starlet thread
|
||||||
|
|
||||||
|
int mload_continue_thread(int id);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// fix starlet address to read/write (uses SEEK_SET, etc as mode)
|
||||||
|
|
||||||
|
int mload_seek(int offset, int mode);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// read bytes from starlet (it update the offset)
|
||||||
|
|
||||||
|
int mload_read(void* buf, u32 size);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// write bytes from starlet (it update the offset)
|
||||||
|
|
||||||
|
int mload_write(const void * buf, u32 size);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// fill a block (similar to memset)
|
||||||
|
|
||||||
|
int mload_memset(void *starlet_addr, int set, int len);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// get the ehci datas ( ehcmodule.elf uses this address)
|
||||||
|
|
||||||
|
void * mload_get_ehci_data();
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// set the dev/es ioctlv in routine
|
||||||
|
|
||||||
|
int mload_set_ES_ioctlv_vector(void *starlet_addr);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
410
test/source/libmload/source/mload.c
Normal file
410
test/source/libmload/source/mload.c
Normal file
@ -0,0 +1,410 @@
|
|||||||
|
/* mload.c (for PPC) (c) 2009, Hermes
|
||||||
|
|
||||||
|
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 of the License, 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, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mload.h"
|
||||||
|
|
||||||
|
static const char mload_fs[] ATTRIBUTE_ALIGN(32) = "/dev/mload";
|
||||||
|
|
||||||
|
static s32 mload_fd = -1;
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// to init/test if the device is running
|
||||||
|
|
||||||
|
int mload_init()
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (mload_fd >= 0) return 0;
|
||||||
|
|
||||||
|
for (n = 0;n < 10;n++) // try 2.5 seconds
|
||||||
|
{
|
||||||
|
mload_fd = IOS_Open(mload_fs, 0);
|
||||||
|
|
||||||
|
if (mload_fd >= 0) break;
|
||||||
|
|
||||||
|
usleep(250*1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mload_fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// to close the device (remember call it when rebooting the IOS!)
|
||||||
|
|
||||||
|
int mload_close()
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (mload_fd < 0) return -1;
|
||||||
|
|
||||||
|
ret = IOS_Close(mload_fd);
|
||||||
|
|
||||||
|
mload_fd = -1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// to get the thread id of mload
|
||||||
|
|
||||||
|
int mload_get_thread_id()
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
s32 hid = -1;
|
||||||
|
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
hid = iosCreateHeap(0x800);
|
||||||
|
|
||||||
|
if (hid < 0) return hid;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_MLOAD_THREAD_ID, ":");
|
||||||
|
|
||||||
|
|
||||||
|
iosDestroyHeap(hid);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// get the base and the size of the memory readable/writable to load modules
|
||||||
|
|
||||||
|
int mload_get_load_base(u32 *starlet_base, int *size)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
s32 hid = -1;
|
||||||
|
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
hid = iosCreateHeap(0x800);
|
||||||
|
|
||||||
|
if (hid < 0) return hid;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_LOAD_BASE, ":ii", starlet_base, size);
|
||||||
|
|
||||||
|
|
||||||
|
iosDestroyHeap(hid);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// load and run a module from starlet (it need to allocate MEM2 to send the elf file)
|
||||||
|
// the module must be a elf made with stripios
|
||||||
|
|
||||||
|
int mload_module(void *addr, int len)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
void *buf = NULL;
|
||||||
|
s32 hid = -1;
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
hid = iosCreateHeap(len + 0x800);
|
||||||
|
|
||||||
|
if (hid < 0) return hid;
|
||||||
|
|
||||||
|
buf = iosAlloc(hid, len);
|
||||||
|
|
||||||
|
if (!buf) {ret = -1;goto out;}
|
||||||
|
|
||||||
|
|
||||||
|
memcpy(buf, addr, len);
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_LOAD_MODULE, ":d", buf, len);
|
||||||
|
|
||||||
|
if (ret < 0) goto out;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_RUN_MODULE, ":");
|
||||||
|
|
||||||
|
if (ret < 0) {ret = -666;goto out;}
|
||||||
|
|
||||||
|
out:
|
||||||
|
|
||||||
|
iosDestroyHeap(hid);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// load a module from the PPC
|
||||||
|
// the module must be a elf made with stripios
|
||||||
|
|
||||||
|
int mload_elf(void *my_elf, data_elf *data_elf)
|
||||||
|
{
|
||||||
|
int n, m;
|
||||||
|
int p;
|
||||||
|
u8 *adr;
|
||||||
|
u32 elf = (u32) my_elf;
|
||||||
|
|
||||||
|
if (elf & 3) return -1; // aligned to 4 please!
|
||||||
|
|
||||||
|
elfheader *head = (void *) elf;
|
||||||
|
|
||||||
|
elfphentry *entries;
|
||||||
|
|
||||||
|
if (head->ident0 != 0x7F454C46) return -1;
|
||||||
|
|
||||||
|
if (head->ident1 != 0x01020161) return -1;
|
||||||
|
|
||||||
|
if (head->ident2 != 0x01000000) return -1;
|
||||||
|
|
||||||
|
p = head->phoff;
|
||||||
|
|
||||||
|
data_elf->start = (void *) head->entry;
|
||||||
|
|
||||||
|
for (n = 0; n < head->phnum; n++)
|
||||||
|
{
|
||||||
|
entries = (void *) (elf + p);
|
||||||
|
p += sizeof(elfphentry);
|
||||||
|
|
||||||
|
if (entries->type == 4)
|
||||||
|
{
|
||||||
|
adr = (void *) (elf + entries->offset);
|
||||||
|
|
||||||
|
if (getbe32(0) != 0) return -2; // bad info (sure)
|
||||||
|
|
||||||
|
for (m = 4; m < entries->memsz; m += 8)
|
||||||
|
{
|
||||||
|
switch (getbe32(m))
|
||||||
|
{
|
||||||
|
case 0x9:
|
||||||
|
data_elf->start = (void *) getbe32(m + 4);
|
||||||
|
break;
|
||||||
|
case 0x7D:
|
||||||
|
data_elf->prio = getbe32(m + 4);
|
||||||
|
break;
|
||||||
|
case 0x7E:
|
||||||
|
data_elf->size_stack = getbe32(m + 4);
|
||||||
|
break;
|
||||||
|
case 0x7F:
|
||||||
|
data_elf->stack = (void *) (getbe32(m + 4));
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
if (entries->type == 1 && entries->memsz != 0 && entries->vaddr != 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (mload_memset((void *) entries->vaddr, 0, entries->memsz) < 0) return -1;
|
||||||
|
|
||||||
|
if (mload_seek(entries->vaddr, SEEK_SET) < 0) return -1;
|
||||||
|
|
||||||
|
if (mload_write((void *) (elf + entries->offset), entries->filesz) < 0) return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// run one thread (you can use to load modules or binary files)
|
||||||
|
|
||||||
|
int mload_run_thread(void *starlet_addr, void *starlet_top_stack, int stack_size, int priority)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
s32 hid = -1;
|
||||||
|
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
hid = iosCreateHeap(0x800);
|
||||||
|
|
||||||
|
if (hid < 0) return hid;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_RUN_THREAD, "iiii:", starlet_addr, starlet_top_stack, stack_size, priority);
|
||||||
|
|
||||||
|
|
||||||
|
iosDestroyHeap(hid);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// stops one starlet thread
|
||||||
|
|
||||||
|
int mload_stop_thread(int id)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
s32 hid = -1;
|
||||||
|
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
hid = iosCreateHeap(0x800);
|
||||||
|
|
||||||
|
if (hid < 0) return hid;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_STOP_THREAD, "i:", id);
|
||||||
|
|
||||||
|
|
||||||
|
iosDestroyHeap(hid);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// continue one stopped starlet thread
|
||||||
|
|
||||||
|
int mload_continue_thread(int id)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
s32 hid = -1;
|
||||||
|
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
hid = iosCreateHeap(0x800);
|
||||||
|
|
||||||
|
if (hid < 0) return hid;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_CONTINUE_THREAD, "i:", id);
|
||||||
|
|
||||||
|
|
||||||
|
iosDestroyHeap(hid);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// fix starlet address to read/write (uses SEEK_SET, etc as mode)
|
||||||
|
|
||||||
|
int mload_seek(int offset, int mode)
|
||||||
|
{
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
return IOS_Seek(mload_fd, offset, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// read bytes from starlet (it update the offset)
|
||||||
|
|
||||||
|
int mload_read(void* buf, u32 size)
|
||||||
|
{
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
return IOS_Read(mload_fd, buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// write bytes from starlet (it update the offset)
|
||||||
|
|
||||||
|
int mload_write(const void * buf, u32 size)
|
||||||
|
{
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
return IOS_Write(mload_fd, buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// fill a block (similar to memset)
|
||||||
|
|
||||||
|
int mload_memset(void *starlet_addr, int set, int len)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
s32 hid = -1;
|
||||||
|
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
hid = iosCreateHeap(0x800);
|
||||||
|
|
||||||
|
if (hid < 0) return hid;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_MEMSET, "iii:", starlet_addr, set, len);
|
||||||
|
|
||||||
|
|
||||||
|
iosDestroyHeap(hid);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// get the ehci datas ( ehcmodule.elf uses this address)
|
||||||
|
|
||||||
|
void * mload_get_ehci_data()
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
s32 hid = -1;
|
||||||
|
|
||||||
|
|
||||||
|
if (mload_init() < 0) return NULL;
|
||||||
|
|
||||||
|
hid = iosCreateHeap(0x800);
|
||||||
|
|
||||||
|
if (hid < 0) return NULL;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_EHCI_DATA, ":");
|
||||||
|
|
||||||
|
if (ret < 0) return NULL;
|
||||||
|
|
||||||
|
iosDestroyHeap(hid);
|
||||||
|
|
||||||
|
return (void *) ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// set the dev/es ioctlv in routine
|
||||||
|
|
||||||
|
int mload_set_ES_ioctlv_vector(void *starlet_addr)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
s32 hid = -1;
|
||||||
|
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
hid = iosCreateHeap(0x800);
|
||||||
|
|
||||||
|
if (hid < 0) return hid;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_SET_ES_IOCTLV, "i:", starlet_addr);
|
||||||
|
|
||||||
|
|
||||||
|
iosDestroyHeap(hid);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
441
test/source/main.c
Normal file
441
test/source/main.c
Normal file
@ -0,0 +1,441 @@
|
|||||||
|
/************************************************************/
|
||||||
|
/* USB speed test */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <ogcsys.h>
|
||||||
|
#include <gccore.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <wiiuse/wpad.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <sdcard/gcsd.h>
|
||||||
|
#include <sdcard/wiisd_io.h>
|
||||||
|
#include <sdcard/gcsd.h>
|
||||||
|
#include <ogc/usbstorage.h>
|
||||||
|
|
||||||
|
#include <ogc/lwp_watchdog.h>
|
||||||
|
|
||||||
|
#include "mload.h"
|
||||||
|
#include "../build/ehcmodule_elf.h"
|
||||||
|
//#include "../build/fat_elf.h"
|
||||||
|
data_elf my_data_elf;
|
||||||
|
int my_thread_id = 0;
|
||||||
|
|
||||||
|
|
||||||
|
#include <fat.h>
|
||||||
|
|
||||||
|
#include <sdcard/wiisd_io.h>
|
||||||
|
#include <sdcard/gcsd.h>
|
||||||
|
#include <ogc/usbstorage.h>
|
||||||
|
#include "usb2storage.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const DISC_INTERFACE* sd = &__io_wiisd;
|
||||||
|
const DISC_INTERFACE* usb = &__io_usbstorage;
|
||||||
|
//const DISC_INTERFACE* usb1 = &__io_usb1storage;
|
||||||
|
|
||||||
|
static bool reset_pressed = false;
|
||||||
|
static bool power_pressed = false;
|
||||||
|
|
||||||
|
static void *xfb = NULL;
|
||||||
|
static GXRModeObj *rmode = NULL;
|
||||||
|
static const u32 CACHE_PAGES = 8;
|
||||||
|
|
||||||
|
static u8 memsector[4*1024];
|
||||||
|
|
||||||
|
|
||||||
|
void initialise_video()
|
||||||
|
{
|
||||||
|
VIDEO_Init();
|
||||||
|
rmode = VIDEO_GetPreferredMode(NULL);
|
||||||
|
xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
|
||||||
|
console_init(xfb, 20, 20, rmode->fbWidth, rmode->xfbHeight, rmode->fbWidth * VI_DISPLAY_PIX_SZ);
|
||||||
|
VIDEO_Configure(rmode);
|
||||||
|
VIDEO_SetNextFramebuffer(xfb);
|
||||||
|
VIDEO_SetBlack(FALSE);
|
||||||
|
VIDEO_Flush();
|
||||||
|
VIDEO_WaitVSync();
|
||||||
|
|
||||||
|
if (rmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
|
||||||
|
|
||||||
|
printf("\x1b[2;0H");
|
||||||
|
|
||||||
|
VIDEO_WaitVSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
#include<ogc/lwp_watchdog.h>
|
||||||
|
//#define ticks_to_secs(ticks) ((u32)((u64)(ticks)/(u64)(TB_TIMER_CLOCK*1000)))
|
||||||
|
//#define ticks_to_msecs(ticks) ((u32)((u64)(ticks)/(u64)(TB_TIMER_CLOCK)))
|
||||||
|
|
||||||
|
void showdir(char *path)
|
||||||
|
{
|
||||||
|
char filename[MAXPATHLEN];
|
||||||
|
DIR_ITER *dp;
|
||||||
|
|
||||||
|
struct stat fstat;
|
||||||
|
//chdir("usb:/");
|
||||||
|
dp = diropen(path);
|
||||||
|
|
||||||
|
if (dp == NULL)
|
||||||
|
{
|
||||||
|
printf("Error diropen\n");
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
else printf("Ok diropen\n");
|
||||||
|
|
||||||
|
int cnt = 0;
|
||||||
|
|
||||||
|
while ( dirnext( dp, filename, &fstat ) == 0 )
|
||||||
|
{
|
||||||
|
//if(cnt==20) break;
|
||||||
|
cnt++;
|
||||||
|
|
||||||
|
if ( fstat.st_mode & S_IFDIR ) printf("/");
|
||||||
|
|
||||||
|
printf("%s\n", filename);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
dirclose(dp);
|
||||||
|
printf("\nEnd show dirrectory (%d).\n", cnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void reset_cb (void)
|
||||||
|
{
|
||||||
|
reset_pressed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void power_cb (void)
|
||||||
|
{
|
||||||
|
power_pressed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define VERSION "1.52"
|
||||||
|
|
||||||
|
void save_log() // at now all data is sent to usbgecko, sd log disabled
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
u8 *temp_data = NULL;
|
||||||
|
u32 level, len;
|
||||||
|
|
||||||
|
temp_data = memalign(32, 256 * 1024);
|
||||||
|
|
||||||
|
mload_seek(0x13750000, SEEK_SET);
|
||||||
|
mload_read(temp_data, 128*1024);
|
||||||
|
|
||||||
|
//mload_init();
|
||||||
|
|
||||||
|
//mload_close();
|
||||||
|
|
||||||
|
for (len = 0;len < 4096 && temp_data[len] != 0;len++);
|
||||||
|
|
||||||
|
fatUnmount("sd");
|
||||||
|
|
||||||
|
if (fatMount("sd", sd, 0, 128, 2) )
|
||||||
|
{
|
||||||
|
|
||||||
|
fp = fopen("sd:/log_usb2.txt", "wb");
|
||||||
|
|
||||||
|
if (fp != 0)
|
||||||
|
{
|
||||||
|
fprintf(fp, "USB2 device test program. v%s\n------------------------------\n", VERSION);
|
||||||
|
fwrite(temp_data, 1, len , fp);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usb_isgeckoalive(1))
|
||||||
|
{
|
||||||
|
level = IRQ_Disable();
|
||||||
|
usb_sendbuffer(1, temp_data, len);
|
||||||
|
IRQ_Restore(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("\nlog:\n-------\n%s", temp_data);
|
||||||
|
free(temp_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TryUSBDevice()
|
||||||
|
{
|
||||||
|
printf("Initializing usb device.\n");
|
||||||
|
bool s;
|
||||||
|
|
||||||
|
USB2Enable(true);
|
||||||
|
s = usb->startup();
|
||||||
|
usleep(10000);
|
||||||
|
|
||||||
|
if (s > 0)
|
||||||
|
s = __usb2storage_ReadSectors(0, 1, memsector);
|
||||||
|
|
||||||
|
usleep(10000);
|
||||||
|
|
||||||
|
|
||||||
|
if (s > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
printf("usb device detected, your device is fully compatible with this usb2 driver\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//(s==-1) printf("usb device NOT INSERTED, log file not created\n");
|
||||||
|
//se
|
||||||
|
{
|
||||||
|
printf("usb device NOT detected or not inserted, report 'ubs2 init' value and log file\n");
|
||||||
|
printf("Log saved to sd:/log_usb2.txt file\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
save_log();
|
||||||
|
}
|
||||||
|
|
||||||
|
static s32 initialise_network()
|
||||||
|
{
|
||||||
|
s32 result;
|
||||||
|
|
||||||
|
while ((result = net_init()) == -EAGAIN)
|
||||||
|
{
|
||||||
|
if (reset_pressed) exit(1);
|
||||||
|
|
||||||
|
usleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wait_for_network_initialisation()
|
||||||
|
{
|
||||||
|
printf("Waiting for network to initialise...\n");
|
||||||
|
|
||||||
|
if (initialise_network() >= 0)
|
||||||
|
{
|
||||||
|
char myIP[16];
|
||||||
|
|
||||||
|
if (if_config(myIP, NULL, NULL, true) < 0)
|
||||||
|
{
|
||||||
|
printf("Error reading IP address\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Network initialised. Wii IP address: %s\n", myIP);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Unable to initialise network\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ROUNDDOWN32(v) (((u32)(v)-0x1f)&~0x1f)
|
||||||
|
static bool usblan_detected(void)
|
||||||
|
{
|
||||||
|
u8 *buffer;
|
||||||
|
u8 dummy;
|
||||||
|
u8 i;
|
||||||
|
u16 vid, pid;
|
||||||
|
|
||||||
|
USB_Initialize();
|
||||||
|
|
||||||
|
buffer = (u8*)ROUNDDOWN32(((u32)SYS_GetArena2Hi() - (32 * 1024)));
|
||||||
|
|
||||||
|
memset(buffer, 0, 8 << 3);
|
||||||
|
|
||||||
|
if (USB_GetDeviceList("/dev/usb/oh0", buffer, 8, 0, &dummy) < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
memcpy(&vid, (buffer + (i << 3) + 4), 2);
|
||||||
|
memcpy(&pid, (buffer + (i << 3) + 6), 2);
|
||||||
|
|
||||||
|
if ( (vid == 0x0b95) && (pid == 0x7720))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_mload()
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
ret = mload_init();
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
printf("fail to get dev/mload, mload cios not detected. Quit\n");
|
||||||
|
sleep(3);
|
||||||
|
exit(0);
|
||||||
|
//goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadehcimodule()
|
||||||
|
{
|
||||||
|
u32 addr;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
mload_get_load_base(&addr, &len);
|
||||||
|
|
||||||
|
if (((u32) ehcmodule_elf) & 3) {printf("Unaligned elf!\n"); return ;}
|
||||||
|
|
||||||
|
mload_elf((void *) ehcmodule_elf, &my_data_elf);
|
||||||
|
my_thread_id = mload_run_thread(my_data_elf.start, my_data_elf.stack, my_data_elf.size_stack, /*my_data_elf.prio*/0x47);
|
||||||
|
//my_thread_id=mload_run_thread(my_data_elf.start, my_data_elf.stack, my_data_elf.size_stack, my_data_elf.prio);
|
||||||
|
|
||||||
|
if (my_thread_id < 0)
|
||||||
|
{
|
||||||
|
printf("EHCI module can NOT be loaded (%i).. Quit\n", my_thread_id);
|
||||||
|
sleep(3);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("EHCI module loaded (%i).\n", my_thread_id);
|
||||||
|
VIDEO_WaitVSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
bool usblan;
|
||||||
|
int usblanport;
|
||||||
|
|
||||||
|
initialise_video();
|
||||||
|
CON_EnableGecko(1, 0);
|
||||||
|
|
||||||
|
usblan = usblan_detected();
|
||||||
|
printf("ios 202 reload\n");
|
||||||
|
IOS_ReloadIOS(202);
|
||||||
|
printf("ios 202 reloaded\n");
|
||||||
|
init_mload();
|
||||||
|
mload_reset_log();
|
||||||
|
loadehcimodule();
|
||||||
|
|
||||||
|
if (usblan)
|
||||||
|
{
|
||||||
|
printf("uslan detected\n");
|
||||||
|
usblanport = GetUSB2LanPort();
|
||||||
|
printf("usblanport: %i\n", usblanport);
|
||||||
|
USB2Storage_Close();
|
||||||
|
|
||||||
|
mload_close();
|
||||||
|
IOS_ReloadIOS(202);
|
||||||
|
init_mload();
|
||||||
|
loadehcimodule();
|
||||||
|
printf("SetUSBMode(%i)\n", usblanport);
|
||||||
|
|
||||||
|
if (usblanport == 1)
|
||||||
|
SetUSB2Mode(1);
|
||||||
|
else
|
||||||
|
SetUSB2Mode(2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
printf("usblan NOT found\n");
|
||||||
|
|
||||||
|
SYS_SetResetCallback (reset_cb);
|
||||||
|
|
||||||
|
SYS_SetPowerCallback (power_cb);
|
||||||
|
|
||||||
|
// usleep(10000);
|
||||||
|
//WIIDVD_Init(false);
|
||||||
|
// usleep(10000);
|
||||||
|
|
||||||
|
TryUSBDevice(); // init usb2 device
|
||||||
|
|
||||||
|
// usleep(10000);
|
||||||
|
// save_log();
|
||||||
|
// usleep(10000);
|
||||||
|
/*
|
||||||
|
if(WIIDVD_DiscPresent()) printf("dvd inserted\n");
|
||||||
|
else printf("dvd NOT inserted\n");
|
||||||
|
usleep(10000);
|
||||||
|
save_log();
|
||||||
|
|
||||||
|
if(fatMount("usb",usb,0,3,128))
|
||||||
|
{
|
||||||
|
showdir("usb:/");
|
||||||
|
}
|
||||||
|
else printf("can't mount usb\n");
|
||||||
|
|
||||||
|
sleep(6);
|
||||||
|
return 0;
|
||||||
|
wait_for_network_initialisation(); // check if lan is working
|
||||||
|
sleep(1);
|
||||||
|
*/
|
||||||
|
printf("Press Home or reset to exit. Press A or power to try to detect usb device again.\n");
|
||||||
|
|
||||||
|
VIDEO_WaitVSync();
|
||||||
|
|
||||||
|
VIDEO_WaitVSync();
|
||||||
|
|
||||||
|
while (1) //wait home press to exit
|
||||||
|
{
|
||||||
|
WPAD_ScanPads();
|
||||||
|
|
||||||
|
if (reset_pressed) break;
|
||||||
|
|
||||||
|
u32 pressed = WPAD_ButtonsDown(0);
|
||||||
|
|
||||||
|
if ( pressed & WPAD_BUTTON_HOME )
|
||||||
|
{
|
||||||
|
mload_close();
|
||||||
|
printf ("\n\nExit ...");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (pressed & WPAD_BUTTON_A) || power_pressed)
|
||||||
|
{
|
||||||
|
power_pressed = false;
|
||||||
|
|
||||||
|
TryUSBDevice();
|
||||||
|
//usleep(5000);
|
||||||
|
power_pressed = false;
|
||||||
|
/*
|
||||||
|
if(fatMount("usb",usb,0,3,128))
|
||||||
|
{
|
||||||
|
showdir("usb:/");
|
||||||
|
}
|
||||||
|
else printf("can't mount usb\n");
|
||||||
|
*/
|
||||||
|
//TryUSBDevice();
|
||||||
|
/*
|
||||||
|
printf("deinit (5secs)\n");
|
||||||
|
sleep(1);
|
||||||
|
net_deinit();
|
||||||
|
sleep(4);
|
||||||
|
printf("init\n");
|
||||||
|
wait_for_network_initialisation();
|
||||||
|
*/
|
||||||
|
//power_pressed=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
usleep(5000);
|
||||||
|
VIDEO_WaitVSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
mload_close();
|
||||||
|
printf ("\n\nExit ...");
|
||||||
|
exit(0);
|
||||||
|
}
|
493
test/source/mload.c
Normal file
493
test/source/mload.c
Normal file
@ -0,0 +1,493 @@
|
|||||||
|
/* mload.c (for PPC) (c) 2009, Hermes
|
||||||
|
|
||||||
|
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 of the License, 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, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mload.h"
|
||||||
|
|
||||||
|
static const char mload_fs[] ATTRIBUTE_ALIGN(32) = "/dev/mload";
|
||||||
|
|
||||||
|
static s32 mload_fd = -1;
|
||||||
|
static s32 hid = -1;
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// to init/test if the device is running
|
||||||
|
|
||||||
|
int mload_init()
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (hid < 0) hid = iosCreateHeap(0x800);
|
||||||
|
|
||||||
|
if (hid < 0)
|
||||||
|
{
|
||||||
|
if (mload_fd >= 0)
|
||||||
|
IOS_Close(mload_fd);
|
||||||
|
|
||||||
|
mload_fd = -1;
|
||||||
|
|
||||||
|
return hid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mload_fd >= 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (n = 0;n < 20;n++) // try 5 seconds
|
||||||
|
{
|
||||||
|
mload_fd = IOS_Open(mload_fs, 0);
|
||||||
|
|
||||||
|
if (mload_fd >= 0) break;
|
||||||
|
|
||||||
|
usleep(250*1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mload_fd < 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (hid >= 0)
|
||||||
|
{
|
||||||
|
iosDestroyHeap(hid);
|
||||||
|
hid = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mload_fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// to close the device (remember call it when rebooting the IOS!)
|
||||||
|
|
||||||
|
int mload_close()
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (hid >= 0)
|
||||||
|
{
|
||||||
|
iosDestroyHeap(hid);
|
||||||
|
hid = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mload_fd < 0) return -1;
|
||||||
|
|
||||||
|
ret = IOS_Close(mload_fd);
|
||||||
|
|
||||||
|
mload_fd = -1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// to get the thread id of mload
|
||||||
|
|
||||||
|
int mload_get_thread_id()
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_MLOAD_THREAD_ID, ":");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// get the base and the size of the memory readable/writable to load modules
|
||||||
|
|
||||||
|
int mload_get_load_base(u32 *starlet_base, int *size)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_LOAD_BASE, ":ii", starlet_base, size);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// load and run a module from starlet (it need to allocate MEM2 to send the elf file)
|
||||||
|
// the module must be a elf made with stripios
|
||||||
|
|
||||||
|
int mload_module(void *addr, int len)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
void *buf = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
if (hid >= 0)
|
||||||
|
{
|
||||||
|
iosDestroyHeap(hid);
|
||||||
|
hid = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
hid = iosCreateHeap(len + 0x800);
|
||||||
|
|
||||||
|
if (hid < 0) return hid;
|
||||||
|
|
||||||
|
buf = iosAlloc(hid, len);
|
||||||
|
|
||||||
|
if (!buf) {ret = -1;goto out;}
|
||||||
|
|
||||||
|
|
||||||
|
memcpy(buf, addr, len);
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_LOAD_MODULE, ":d", buf, len);
|
||||||
|
|
||||||
|
if (ret < 0) goto out;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_RUN_MODULE, ":");
|
||||||
|
|
||||||
|
if (ret < 0) {ret = -666;goto out;}
|
||||||
|
|
||||||
|
out:
|
||||||
|
|
||||||
|
if (hid >= 0)
|
||||||
|
{
|
||||||
|
iosDestroyHeap(hid);
|
||||||
|
hid = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// load a module from the PPC
|
||||||
|
// the module must be a elf made with stripios
|
||||||
|
|
||||||
|
int mload_elf(void *my_elf, data_elf *data_elf)
|
||||||
|
{
|
||||||
|
int n, m;
|
||||||
|
int p;
|
||||||
|
u8 *adr;
|
||||||
|
u32 elf = (u32) my_elf;
|
||||||
|
|
||||||
|
if (elf & 3) return -1; // aligned to 4 please!
|
||||||
|
|
||||||
|
elfheader *head = (void *) elf;
|
||||||
|
|
||||||
|
elfphentry *entries;
|
||||||
|
|
||||||
|
if (head->ident0 != 0x7F454C46) return -1;
|
||||||
|
|
||||||
|
if (head->ident1 != 0x01020161) return -1;
|
||||||
|
|
||||||
|
if (head->ident2 != 0x01000000) return -1;
|
||||||
|
|
||||||
|
p = head->phoff;
|
||||||
|
|
||||||
|
data_elf->start = (void *) head->entry;
|
||||||
|
|
||||||
|
for (n = 0; n < head->phnum; n++)
|
||||||
|
{
|
||||||
|
entries = (void *) (elf + p);
|
||||||
|
p += sizeof(elfphentry);
|
||||||
|
|
||||||
|
if (entries->type == 4)
|
||||||
|
{
|
||||||
|
adr = (void *) (elf + entries->offset);
|
||||||
|
|
||||||
|
if (getbe32(0) != 0) return -2; // bad info (sure)
|
||||||
|
|
||||||
|
for (m = 4; m < entries->memsz; m += 8)
|
||||||
|
{
|
||||||
|
switch (getbe32(m))
|
||||||
|
{
|
||||||
|
case 0x9:
|
||||||
|
data_elf->start = (void *) getbe32(m + 4);
|
||||||
|
break;
|
||||||
|
case 0x7D:
|
||||||
|
data_elf->prio = getbe32(m + 4);
|
||||||
|
break;
|
||||||
|
case 0x7E:
|
||||||
|
data_elf->size_stack = getbe32(m + 4);
|
||||||
|
break;
|
||||||
|
case 0x7F:
|
||||||
|
data_elf->stack = (void *) (getbe32(m + 4));
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
if (entries->type == 1 && entries->memsz != 0 && entries->vaddr != 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (mload_memset((void *) entries->vaddr, 0, entries->memsz) < 0) return -1;
|
||||||
|
|
||||||
|
if (mload_seek(entries->vaddr, SEEK_SET) < 0) return -1;
|
||||||
|
|
||||||
|
if (mload_write((void *) (elf + entries->offset), entries->filesz) < 0) return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// run one thread (you can use to load modules or binary files)
|
||||||
|
|
||||||
|
int mload_run_thread(void *starlet_addr, void *starlet_top_stack, int stack_size, int priority)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_RUN_THREAD, "iiii:", starlet_addr, starlet_top_stack, stack_size, priority);
|
||||||
|
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// stops one starlet thread
|
||||||
|
|
||||||
|
int mload_stop_thread(int id)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_STOP_THREAD, "i:", id);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// continue one stopped starlet thread
|
||||||
|
|
||||||
|
int mload_continue_thread(int id)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_CONTINUE_THREAD, "i:", id);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// fix starlet address to read/write (uses SEEK_SET, etc as mode)
|
||||||
|
|
||||||
|
int mload_seek(int offset, int mode)
|
||||||
|
{
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
return IOS_Seek(mload_fd, offset, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// read bytes from starlet (it update the offset)
|
||||||
|
|
||||||
|
int mload_read(void* buf, u32 size)
|
||||||
|
{
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
return IOS_Read(mload_fd, buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// write bytes from starlet (it update the offset)
|
||||||
|
|
||||||
|
int mload_write(const void * buf, u32 size)
|
||||||
|
{
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
return IOS_Write(mload_fd, buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// fill a block (similar to memset)
|
||||||
|
|
||||||
|
int mload_memset(void *starlet_addr, int set, int len)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_MEMSET, "iii:", starlet_addr, set, len);
|
||||||
|
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// get the ehci datas ( ehcmodule.elf uses this address)
|
||||||
|
|
||||||
|
void * mload_get_ehci_data()
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (mload_init() < 0) return NULL;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_EHCI_DATA, ":");
|
||||||
|
|
||||||
|
if (ret < 0) return NULL;
|
||||||
|
|
||||||
|
return (void *) ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// set the dev/es ioctlv in routine
|
||||||
|
|
||||||
|
int mload_set_ES_ioctlv_vector(void *starlet_addr)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_SET_ES_IOCTLV, "i:", starlet_addr);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int mload_getw(const void * addr, u32 *dat)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_GETW, "i:i", addr, dat);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mload_geth(const void * addr, u16 *dat)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_GETH, "i:h", addr, dat);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mload_getb(const void * addr, u8 *dat)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_GETB, "i:b", addr, dat);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mload_setw(const void * addr, u32 dat)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_SETW, "ii:", addr, dat);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mload_seth(const void * addr, u16 dat)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_SETH, "ih:", addr, dat);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mload_setb(const void * addr, u8 dat)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_SETB, "ib:", addr, dat);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// to get log buffer
|
||||||
|
// this function return the size of the log buffer and prepare it to read with mload_read() the datas
|
||||||
|
|
||||||
|
int mload_get_log()
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_LOG, ":");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void mload_reset_log()
|
||||||
|
{
|
||||||
|
if (mload_init() < 0) return ;
|
||||||
|
|
||||||
|
IOS_IoctlvFormat(hid, mload_fd, MLOAD_RESET_LOG, ":");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// to get IOS base for dev/es to create the cIOS
|
||||||
|
|
||||||
|
int mload_get_IOS_base()
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (mload_init() < 0) return -1;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_IOS_BASE, ":");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
240
test/source/mload.h
Normal file
240
test/source/mload.h
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
/* mload.c (for PPC) (c) 2009, Hermes
|
||||||
|
|
||||||
|
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 of the License, 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, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MLOAD_H__
|
||||||
|
#define __MLOAD_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ogcsys.h>
|
||||||
|
#include <gccore.h>
|
||||||
|
#include "unistd.h"
|
||||||
|
|
||||||
|
#define MLOAD_MLOAD_THREAD_ID 0x4D4C4400
|
||||||
|
#define MLOAD_GET_IOS_BASE 0x4D4C4401
|
||||||
|
#define MLOAD_LOAD_MODULE 0x4D4C4480
|
||||||
|
#define MLOAD_RUN_MODULE 0x4D4C4481
|
||||||
|
#define MLOAD_RUN_THREAD 0x4D4C4482
|
||||||
|
|
||||||
|
#define MLOAD_STOP_THREAD 0x4D4C4484
|
||||||
|
#define MLOAD_CONTINUE_THREAD 0x4D4C4485
|
||||||
|
|
||||||
|
#define MLOAD_GET_LOAD_BASE 0x4D4C4490
|
||||||
|
#define MLOAD_MEMSET 0x4D4C4491
|
||||||
|
|
||||||
|
#define MLOAD_GET_EHCI_DATA 0x4D4C44A0
|
||||||
|
#define MLOAD_GET_LOG 0x4D4C44A1
|
||||||
|
#define MLOAD_RESET_LOG 0x4D4C44A2
|
||||||
|
|
||||||
|
#define MLOAD_SET_ES_IOCTLV 0x4D4C44B0
|
||||||
|
|
||||||
|
#define MLOAD_GETW 0x4D4C44C0
|
||||||
|
#define MLOAD_GETH 0x4D4C44C1
|
||||||
|
#define MLOAD_GETB 0x4D4C44C2
|
||||||
|
#define MLOAD_SETW 0x4D4C44C3
|
||||||
|
#define MLOAD_SETH 0x4D4C44C4
|
||||||
|
#define MLOAD_SETB 0x4D4C44C5
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// from IOS ELF stripper of neimod
|
||||||
|
|
||||||
|
#define getbe32(x) ((adr[x]<<24) | (adr[x+1]<<16) | (adr[x+2]<<8) | (adr[x+3]))
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 ident0;
|
||||||
|
u32 ident1;
|
||||||
|
u32 ident2;
|
||||||
|
u32 ident3;
|
||||||
|
u32 machinetype;
|
||||||
|
u32 version;
|
||||||
|
u32 entry;
|
||||||
|
u32 phoff;
|
||||||
|
u32 shoff;
|
||||||
|
u32 flags;
|
||||||
|
u16 ehsize;
|
||||||
|
u16 phentsize;
|
||||||
|
u16 phnum;
|
||||||
|
u16 shentsize;
|
||||||
|
u16 shnum;
|
||||||
|
u16 shtrndx;
|
||||||
|
}
|
||||||
|
|
||||||
|
elfheader;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 type;
|
||||||
|
u32 offset;
|
||||||
|
u32 vaddr;
|
||||||
|
u32 paddr;
|
||||||
|
u32 filesz;
|
||||||
|
u32 memsz;
|
||||||
|
u32 flags;
|
||||||
|
u32 align;
|
||||||
|
}
|
||||||
|
|
||||||
|
elfphentry;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *start;
|
||||||
|
int prio;
|
||||||
|
void *stack;
|
||||||
|
int size_stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
data_elf;
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// to init/test if the device is running
|
||||||
|
|
||||||
|
int mload_init();
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// to close the device (remember call it when rebooting the IOS!)
|
||||||
|
|
||||||
|
int mload_close();
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// to get the thread id of mload
|
||||||
|
|
||||||
|
int mload_get_thread_id();
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// get the base and the size of the memory readable/writable to load modules
|
||||||
|
|
||||||
|
int mload_get_load_base(u32 *starlet_base, int *size);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// load and run a module from starlet (it need to allocate MEM2 to send the elf file)
|
||||||
|
// the module must be a elf made with stripios
|
||||||
|
|
||||||
|
int mload_module(void *addr, int len);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// load a module from the PPC
|
||||||
|
// the module must be a elf made with stripios
|
||||||
|
|
||||||
|
int mload_elf(void *my_elf, data_elf *data_elf);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// run one thread (you can use to load modules or binary files)
|
||||||
|
|
||||||
|
int mload_run_thread(void *starlet_addr, void *starlet_top_stack, int stack_size, int priority);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// stops one starlet thread
|
||||||
|
|
||||||
|
int mload_stop_thread(int id);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// continue one stopped starlet thread
|
||||||
|
|
||||||
|
int mload_continue_thread(int id);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// fix starlet address to read/write (uses SEEK_SET, etc as mode)
|
||||||
|
|
||||||
|
int mload_seek(int offset, int mode);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// read bytes from starlet (it update the offset)
|
||||||
|
|
||||||
|
int mload_read(void* buf, u32 size);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// write bytes from starlet (it update the offset)
|
||||||
|
|
||||||
|
int mload_write(const void * buf, u32 size);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// fill a block (similar to memset)
|
||||||
|
|
||||||
|
int mload_memset(void *starlet_addr, int set, int len);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// get the ehci datas ( ehcmodule.elf uses this address)
|
||||||
|
|
||||||
|
void * mload_get_ehci_data();
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// set the dev/es ioctlv in routine
|
||||||
|
|
||||||
|
int mload_set_ES_ioctlv_vector(void *starlet_addr);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
// to get log buffer
|
||||||
|
// this function return the size of the log buffer and prepare it to read with mload_read() the datas
|
||||||
|
|
||||||
|
int mload_get_log();
|
||||||
|
|
||||||
|
void mload_reset_log();
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
// to get IOS base for dev/es to create the cIOS
|
||||||
|
|
||||||
|
int mload_get_IOS_base();
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
int mload_getw(const void * addr, u32 *dat);
|
||||||
|
|
||||||
|
int mload_geth(const void * addr, u16 *dat);
|
||||||
|
|
||||||
|
int mload_getb(const void * addr, u8 *dat);
|
||||||
|
|
||||||
|
int mload_setw(const void * addr, u32 dat);
|
||||||
|
|
||||||
|
int mload_seth(const void * addr, u16 dat);
|
||||||
|
|
||||||
|
int mload_setb(const void * addr, u8 dat);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
411
test/source/usb2storage.c
Normal file
411
test/source/usb2storage.c
Normal file
@ -0,0 +1,411 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* WiiMC
|
||||||
|
* usb2storage.c -- USB mass storage support, inside starlet
|
||||||
|
* Copyright (C) 2008 Kwiirk
|
||||||
|
* Improved for homebrew by rodries and Tantric
|
||||||
|
*
|
||||||
|
* IOS 202 and the ehcmodule must be loaded before using this!
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any
|
||||||
|
* damages arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any
|
||||||
|
* purpose, including commercial applications, and to alter it and
|
||||||
|
* redistribute it freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you
|
||||||
|
* must not claim that you wrote the original software. If you use
|
||||||
|
* this software in a product, an acknowledgment in the product
|
||||||
|
* documentation would be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and
|
||||||
|
* must not be misrepresented as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <gccore.h>
|
||||||
|
|
||||||
|
#include <ogc/lwp_heap.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <ogc/disc_io.h>
|
||||||
|
#include <ogc/usbstorage.h>
|
||||||
|
#include <ogc/mutex.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <ogc/machine/processor.h>
|
||||||
|
#include <ogc/lwp_watchdog.h>
|
||||||
|
|
||||||
|
|
||||||
|
//#define DEBUG_USB2
|
||||||
|
|
||||||
|
#ifdef DEBUG_USB2
|
||||||
|
#define debug_printf(fmt, args...) \
|
||||||
|
fprintf(stderr, "%s:%d:" fmt, __FUNCTION__, __LINE__, ##args)
|
||||||
|
#else
|
||||||
|
#define debug_printf(fmt, args...)
|
||||||
|
#endif // DEBUG_USB2
|
||||||
|
|
||||||
|
#define UMS_BASE (('U'<<24)|('M'<<16)|('S'<<8))
|
||||||
|
#define USB_IOCTL_UMS_INIT (UMS_BASE+0x1)
|
||||||
|
#define USB_IOCTL_UMS_GET_CAPACITY (UMS_BASE+0x2)
|
||||||
|
#define USB_IOCTL_UMS_READ_SECTORS (UMS_BASE+0x3)
|
||||||
|
#define USB_IOCTL_UMS_WRITE_SECTORS (UMS_BASE+0x4)
|
||||||
|
#define USB_IOCTL_UMS_READ_STRESS (UMS_BASE+0x5)
|
||||||
|
#define USB_IOCTL_UMS_SET_VERBOSE (UMS_BASE+0x6)
|
||||||
|
#define USB_IOCTL_UMS_IS_INSERTED (UMS_BASE+0x7)
|
||||||
|
#define USB_IOCTL_UMS_USB_MODE (UMS_BASE+0x8)
|
||||||
|
#define USB_IOCTL_UMS_GET_USBLAN_PORT (UMS_BASE+0x9)
|
||||||
|
|
||||||
|
#define USB_IOCTL_UMS_UMOUNT (UMS_BASE+0x10)
|
||||||
|
#define USB_IOCTL_UMS_START (UMS_BASE+0x11)
|
||||||
|
#define USB_IOCTL_UMS_STOP (UMS_BASE+0x12)
|
||||||
|
#define USB_IOCTL_UMS_EXIT (UMS_BASE+0x16)
|
||||||
|
|
||||||
|
#define UMS_HEAPSIZE 2*1024
|
||||||
|
#define UMS_MAXPATH 16
|
||||||
|
|
||||||
|
static s32 hId = -1;
|
||||||
|
static s32 __usb2fd = -1;
|
||||||
|
static u32 sector_size;
|
||||||
|
static mutex_t usb2_mutex = LWP_MUTEX_NULL;
|
||||||
|
static u8 *fixed_buffer = NULL;
|
||||||
|
|
||||||
|
#define ROUNDDOWN32(v) (((u32)(v)-0x1f)&~0x1f)
|
||||||
|
#define USB2_BUFFER 128*1024
|
||||||
|
static heap_cntrl usb2_heap;
|
||||||
|
static u8 __usb2_heap_created = 0;
|
||||||
|
|
||||||
|
static DISC_INTERFACE __io_usb1storage;
|
||||||
|
static int usb1disc_inited = 0;
|
||||||
|
extern const DISC_INTERFACE __io_usb2storage;
|
||||||
|
static int currentMode = 2; // 1 = use USB1 interface, 2 = use USB2 interface
|
||||||
|
|
||||||
|
static s32 USB2CreateHeap()
|
||||||
|
{
|
||||||
|
u32 level;
|
||||||
|
void *usb2_heap_ptr;
|
||||||
|
|
||||||
|
if (__usb2_heap_created != 0)
|
||||||
|
return IPC_OK;
|
||||||
|
|
||||||
|
_CPU_ISR_Disable(level);
|
||||||
|
|
||||||
|
usb2_heap_ptr = (void *) ROUNDDOWN32(((u32)SYS_GetArena2Hi() - (USB2_BUFFER + (4 * 1024))));
|
||||||
|
|
||||||
|
if ((u32) usb2_heap_ptr < (u32) SYS_GetArena2Lo())
|
||||||
|
{
|
||||||
|
_CPU_ISR_Restore(level);
|
||||||
|
return IPC_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
SYS_SetArena2Hi(usb2_heap_ptr);
|
||||||
|
__lwp_heap_init(&usb2_heap, usb2_heap_ptr, (USB2_BUFFER + (4 * 1024)), 32);
|
||||||
|
__usb2_heap_created = 1;
|
||||||
|
_CPU_ISR_Restore(level);
|
||||||
|
return IPC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static s32 USB2Storage_Initialize()
|
||||||
|
{
|
||||||
|
char *devicepath = NULL;
|
||||||
|
|
||||||
|
if (usb2_mutex == LWP_MUTEX_NULL)
|
||||||
|
LWP_MutexInit(&usb2_mutex, false);
|
||||||
|
|
||||||
|
if (hId == -1)
|
||||||
|
hId = iosCreateHeap(UMS_HEAPSIZE);
|
||||||
|
|
||||||
|
if (hId < 0)
|
||||||
|
{
|
||||||
|
debug_printf("error IPC_ENOMEM\n");
|
||||||
|
return IPC_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (USB2CreateHeap() != IPC_OK)
|
||||||
|
{
|
||||||
|
debug_printf("error USB2 IPC_ENOMEM\n");
|
||||||
|
return IPC_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fixed_buffer == NULL)
|
||||||
|
fixed_buffer = __lwp_heap_allocate(&usb2_heap, USB2_BUFFER);
|
||||||
|
|
||||||
|
LWP_MutexLock(usb2_mutex);
|
||||||
|
|
||||||
|
if (__usb2fd <= 0)
|
||||||
|
{
|
||||||
|
devicepath = iosAlloc(hId, UMS_MAXPATH);
|
||||||
|
|
||||||
|
if (devicepath == NULL)
|
||||||
|
{
|
||||||
|
LWP_MutexUnlock(usb2_mutex);
|
||||||
|
return IPC_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(devicepath, USB_MAXPATH, "/dev/usb2");
|
||||||
|
__usb2fd = IOS_Open(devicepath, 0);
|
||||||
|
iosFree(hId, devicepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__usb2fd <= 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static s32 USB2Storage_Open()
|
||||||
|
{
|
||||||
|
s32 ret = USB_OK;
|
||||||
|
u32 size = 0;
|
||||||
|
|
||||||
|
if (USB2Storage_Initialize() < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_INIT, ":");
|
||||||
|
|
||||||
|
debug_printf("usb2 init value: %i\n", ret);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
debug_printf("usb2 error init\n");
|
||||||
|
else
|
||||||
|
size = IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_GET_CAPACITY, ":i",
|
||||||
|
§or_size);
|
||||||
|
|
||||||
|
debug_printf("usb2 GET_CAPACITY: %d\n", size);
|
||||||
|
|
||||||
|
if (ret < 0 || size <= 0)
|
||||||
|
ret = -2012;
|
||||||
|
else
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
debug_printf("usb2 USB2Storage_Open ret: %d\n", ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void USB2Storage_Close()
|
||||||
|
{
|
||||||
|
if (__usb2fd <= 0)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
IOS_Close(__usb2fd);
|
||||||
|
|
||||||
|
__usb2fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int is_MEM2_buffer(const void *buffer)
|
||||||
|
{
|
||||||
|
u32 high_addr = ((u32) buffer) >> 24;
|
||||||
|
return (high_addr == 0x90) || (high_addr == 0xD0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void USB2Enable(bool enable)
|
||||||
|
{
|
||||||
|
if (!usb1disc_inited)
|
||||||
|
{
|
||||||
|
usb1disc_inited = 1;
|
||||||
|
memcpy(&__io_usb1storage, &__io_usbstorage, sizeof(DISC_INTERFACE));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!enable)
|
||||||
|
{
|
||||||
|
memcpy(&__io_usbstorage, &__io_usb1storage, sizeof(DISC_INTERFACE));
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
USB2Storage_Initialize();
|
||||||
|
memcpy(&__io_usbstorage, &__io_usb2storage, sizeof(DISC_INTERFACE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool __usb2storage_Startup(void)
|
||||||
|
{
|
||||||
|
s32 ret;
|
||||||
|
|
||||||
|
ret = USB2Storage_Open();
|
||||||
|
|
||||||
|
if (__usb2fd > 0 )
|
||||||
|
{
|
||||||
|
currentMode = 2;
|
||||||
|
return ret > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__io_usb1storage.startup())
|
||||||
|
{
|
||||||
|
currentMode = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool __usb2storage_IsInserted(void)
|
||||||
|
{
|
||||||
|
if (!USB2Storage_Initialize() < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
if (usb2_mutex == LWP_MUTEX_NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (__usb2fd > 0)
|
||||||
|
{
|
||||||
|
LWP_MutexLock(usb2_mutex);
|
||||||
|
int retval = IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_IS_INSERTED, ":");
|
||||||
|
LWP_MutexUnlock(usb2_mutex);
|
||||||
|
debug_printf("isinserted usb2 retval: %d \n", retval);
|
||||||
|
|
||||||
|
if (retval > 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__io_usb1storage.isInserted() > 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool __usb2storage_ReadSectors(u32 sector, u32 numSectors, void *buffer)
|
||||||
|
{
|
||||||
|
s32 ret = 1;
|
||||||
|
u32 sectors = 0;
|
||||||
|
uint8_t *dest = buffer;
|
||||||
|
|
||||||
|
if (currentMode == 1)
|
||||||
|
return __io_usb1storage.readSectors(sector, numSectors, buffer);
|
||||||
|
|
||||||
|
if (__usb2fd < 1 || usb2_mutex == LWP_MUTEX_NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
LWP_MutexLock(usb2_mutex);
|
||||||
|
|
||||||
|
while (numSectors > 0)
|
||||||
|
{
|
||||||
|
if (numSectors * sector_size > USB2_BUFFER)
|
||||||
|
sectors = USB2_BUFFER / sector_size;
|
||||||
|
else
|
||||||
|
sectors = numSectors;
|
||||||
|
|
||||||
|
if (!is_MEM2_buffer(dest)) //libfat is not providing us good buffers :-(
|
||||||
|
{
|
||||||
|
ret = IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_READ_SECTORS, "ii:d",
|
||||||
|
sector, sectors, fixed_buffer, sector_size * sectors);
|
||||||
|
memcpy(dest, fixed_buffer, sector_size * sectors);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_READ_SECTORS, "ii:d",
|
||||||
|
sector, sectors, dest, sector_size * sectors);
|
||||||
|
|
||||||
|
dest += sector_size * sectors;
|
||||||
|
|
||||||
|
if (ret < 1) break;
|
||||||
|
|
||||||
|
sector += sectors;
|
||||||
|
|
||||||
|
numSectors -= sectors;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < 1) USB2Storage_Close();
|
||||||
|
|
||||||
|
LWP_MutexUnlock(usb2_mutex);
|
||||||
|
|
||||||
|
if (ret < 1) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool __usb2storage_WriteSectors(u32 sector, u32 numSectors, const void *buffer)
|
||||||
|
{
|
||||||
|
s32 ret = 1;
|
||||||
|
u32 sectors = 0;
|
||||||
|
uint8_t *dest = (uint8_t *) buffer;
|
||||||
|
|
||||||
|
if (currentMode == 1)
|
||||||
|
return __io_usb1storage.writeSectors(sector, numSectors, buffer);
|
||||||
|
|
||||||
|
if (__usb2fd < 1 || usb2_mutex == LWP_MUTEX_NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
LWP_MutexLock(usb2_mutex);
|
||||||
|
|
||||||
|
while (numSectors > 0 && ret > 0)
|
||||||
|
{
|
||||||
|
if (numSectors * sector_size > USB2_BUFFER)
|
||||||
|
sectors = USB2_BUFFER / sector_size;
|
||||||
|
else
|
||||||
|
sectors = numSectors;
|
||||||
|
|
||||||
|
numSectors -= sectors;
|
||||||
|
|
||||||
|
if (!is_MEM2_buffer(dest)) // libfat is not providing us good buffers :-(
|
||||||
|
{
|
||||||
|
memcpy(fixed_buffer, dest, sector_size * sectors);
|
||||||
|
ret = IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_WRITE_SECTORS,
|
||||||
|
"ii:d", sector, sectors, fixed_buffer, sector_size
|
||||||
|
* sectors);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_WRITE_SECTORS,
|
||||||
|
"ii:d", sector, sectors, dest, sector_size * sectors);
|
||||||
|
|
||||||
|
if (ret < 1)break;
|
||||||
|
|
||||||
|
dest += sector_size * sectors;
|
||||||
|
|
||||||
|
sector += sectors;
|
||||||
|
}
|
||||||
|
|
||||||
|
LWP_MutexUnlock(usb2_mutex);
|
||||||
|
|
||||||
|
if (ret < 1 ) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool __usb2storage_ClearStatus(void)
|
||||||
|
{
|
||||||
|
if (currentMode == 1)
|
||||||
|
return __io_usb1storage.clearStatus();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool __usb2storage_Shutdown(void)
|
||||||
|
{
|
||||||
|
if (currentMode == 1)
|
||||||
|
return __io_usb1storage.shutdown();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetUSB2Mode(int mode)
|
||||||
|
{
|
||||||
|
USB2Storage_Initialize();
|
||||||
|
IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_USB_MODE, "b:", (u8)mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetUSB2LanPort(void)
|
||||||
|
{
|
||||||
|
USB2Storage_Initialize();
|
||||||
|
return IOS_IoctlvFormat(hId, __usb2fd, USB_IOCTL_UMS_GET_USBLAN_PORT, ":");
|
||||||
|
}
|
||||||
|
|
||||||
|
const DISC_INTERFACE __io_usb2storage =
|
||||||
|
{
|
||||||
|
DEVICE_TYPE_WII_USB,
|
||||||
|
FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB,
|
||||||
|
(FN_MEDIUM_STARTUP) & __usb2storage_Startup,
|
||||||
|
(FN_MEDIUM_ISINSERTED) & __usb2storage_IsInserted,
|
||||||
|
(FN_MEDIUM_READSECTORS) & __usb2storage_ReadSectors,
|
||||||
|
(FN_MEDIUM_WRITESECTORS) & __usb2storage_WriteSectors,
|
||||||
|
(FN_MEDIUM_CLEARSTATUS) & __usb2storage_ClearStatus,
|
||||||
|
(FN_MEDIUM_SHUTDOWN) & __usb2storage_Shutdown
|
||||||
|
};
|
33
test/source/usb2storage.h
Normal file
33
test/source/usb2storage.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* WiiMC
|
||||||
|
* usb2storage.h -- USB mass storage support, inside starlet
|
||||||
|
* Copyright (C) 2008 Kwiirk
|
||||||
|
* Improved for homebrew by rodries and Tantric
|
||||||
|
*
|
||||||
|
* IOS 202 and the ehcimodule must be loaded before using this!
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __USB2STORAGE_H__
|
||||||
|
#define __USB2STORAGE_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void USB2Enable(bool e);
|
||||||
|
void USB2Storage_Close();
|
||||||
|
int GetUSB2LanPort(void);
|
||||||
|
void SetUSB2Mode(int mode);
|
||||||
|
//mode 0: port0 disabled & port1 disabled
|
||||||
|
//mode 1: port0 enabled & port1 disabled
|
||||||
|
//mode 2: port0 disabled & port1 enabled
|
||||||
|
//mode 3: port0 enabled & port1 enabled
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
BIN
test/test.rar
Normal file
BIN
test/test.rar
Normal file
Binary file not shown.
980
tinyehci/ehci.c.old
Normal file
980
tinyehci/ehci.c.old
Normal file
@ -0,0 +1,980 @@
|
|||||||
|
/* simplest usb-ehci driver which features:
|
||||||
|
|
||||||
|
control and bulk transfers only
|
||||||
|
only one transfer pending
|
||||||
|
driver is synchronous (waiting for the end of the transfer)
|
||||||
|
endianess independant
|
||||||
|
no uncached memory allocation needed
|
||||||
|
|
||||||
|
this driver is originally based on the GPL linux ehci-hcd driver
|
||||||
|
|
||||||
|
* Original Copyright (c) 2001 by David Brownell
|
||||||
|
*
|
||||||
|
* 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 of the License, 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,
|
||||||
|
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
void my_sprint(char *cad, char *s);
|
||||||
|
|
||||||
|
/* magic numbers that can affect system performance */
|
||||||
|
#define EHCI_TUNE_CERR 0 /* 0-3 qtd retries; 0 == don't stop */ /* by Hermes: i have replaced 3 by 0 and now it don´t hang when i extract the device*/
|
||||||
|
#define EHCI_TUNE_RL_HS 4 /* nak throttle; see 4.9 */
|
||||||
|
#define EHCI_TUNE_RL_TT 0
|
||||||
|
#define EHCI_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */
|
||||||
|
#define EHCI_TUNE_MULT_TT 1
|
||||||
|
#define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */
|
||||||
|
extern int verbose;
|
||||||
|
#ifdef DEBUG
|
||||||
|
static int num_command_before_no_verbose = 100;
|
||||||
|
#endif
|
||||||
|
static void
|
||||||
|
dbg_qtd (const char *label, struct ehci_qtd *qtd)
|
||||||
|
{
|
||||||
|
ehci_dbg( "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
|
||||||
|
hc32_to_cpup( &qtd->hw_next),
|
||||||
|
hc32_to_cpup( &qtd->hw_alt_next),
|
||||||
|
hc32_to_cpup( &qtd->hw_token),
|
||||||
|
hc32_to_cpup( &qtd->hw_buf [0]));
|
||||||
|
if (qtd->hw_buf [1])
|
||||||
|
ehci_dbg( " p1=%08x p2=%08x p3=%08x p4=%08x\n",
|
||||||
|
hc32_to_cpup( &qtd->hw_buf[1]),
|
||||||
|
hc32_to_cpup( &qtd->hw_buf[2]),
|
||||||
|
hc32_to_cpup( &qtd->hw_buf[3]),
|
||||||
|
hc32_to_cpup( &qtd->hw_buf[4]));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dbg_qh (const char *label, struct ehci_qh *qh)
|
||||||
|
{
|
||||||
|
ehci_dbg ( "%s qh %p n%08x info %x %x qtd %x\n", label,
|
||||||
|
qh,
|
||||||
|
hc32_to_cpu(qh->hw_next),
|
||||||
|
hc32_to_cpu(qh->hw_info1),
|
||||||
|
hc32_to_cpu(qh->hw_info2),
|
||||||
|
hc32_to_cpu(qh->hw_current));
|
||||||
|
dbg_qtd ("overlay", (struct ehci_qtd *) &qh->hw_qtd_next);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dbg_command (void)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
u32 command=ehci_readl( &ehci->regs->command);
|
||||||
|
u32 async=ehci_readl( &ehci->regs->async_next);
|
||||||
|
|
||||||
|
ehci_dbg ("async_next: %08x\n",async);
|
||||||
|
ehci_dbg (
|
||||||
|
"command %06x %s=%d ithresh=%d%s%s%s%s %s %s\n",
|
||||||
|
command,
|
||||||
|
(command & CMD_PARK) ? "park" : "(park)",
|
||||||
|
CMD_PARK_CNT (command),
|
||||||
|
(command >> 16) & 0x3f,
|
||||||
|
(command & CMD_LRESET) ? " LReset" : "",
|
||||||
|
(command & CMD_IAAD) ? " IAAD" : "",
|
||||||
|
(command & CMD_ASE) ? " Async" : "",
|
||||||
|
(command & CMD_PSE) ? " Periodic" : "",
|
||||||
|
(command & CMD_RESET) ? " Reset" : "",
|
||||||
|
(command & CMD_RUN) ? "RUN" : "HALT"
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
dbg_status (void)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
u32 status=ehci_readl( &ehci->regs->status);
|
||||||
|
ehci_dbg (
|
||||||
|
"status %04x%s%s%s%s%s%s%s%s%s%s\n",
|
||||||
|
status,
|
||||||
|
(status & STS_ASS) ? " Async" : "",
|
||||||
|
(status & STS_PSS) ? " Periodic" : "",
|
||||||
|
(status & STS_RECL) ? " Recl" : "",
|
||||||
|
(status & STS_HALT) ? " Halt" : "",
|
||||||
|
(status & STS_IAA) ? " IAA" : "",
|
||||||
|
(status & STS_FATAL) ? " FATAL" : "",
|
||||||
|
(status & STS_FLR) ? " FLR" : "",
|
||||||
|
(status & STS_PCD) ? " PCD" : "",
|
||||||
|
(status & STS_ERR) ? " ERR" : "",
|
||||||
|
(status & STS_INT) ? " INT" : ""
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void debug_qtds(void)
|
||||||
|
{
|
||||||
|
struct ehci_qh *qh = ehci->async;
|
||||||
|
struct ehci_qtd *qtd;
|
||||||
|
dbg_qh ("qh",qh);
|
||||||
|
dbg_command ();
|
||||||
|
dbg_status ();
|
||||||
|
for(qtd = qh->qtd_head; qtd; qtd = qtd->next)
|
||||||
|
{
|
||||||
|
ehci_dma_unmap_bidir(qtd->qtd_dma,sizeof(struct ehci_qtd));
|
||||||
|
dbg_qtd("qtd",qtd);
|
||||||
|
ehci_dma_map_bidir(qtd,sizeof(struct ehci_qtd));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
void dump_qh(struct ehci_qh *qh)
|
||||||
|
{
|
||||||
|
struct ehci_qtd *qtd;
|
||||||
|
dbg_command ();
|
||||||
|
dbg_status ();
|
||||||
|
ehci_dma_unmap_bidir(qh->qh_dma,sizeof(struct ehci_qh));
|
||||||
|
dbg_qh("qh",qh);
|
||||||
|
print_hex_dump_bytes("qh:",DUMP_PREFIX_OFFSET,(void*)qh,12*4);
|
||||||
|
for(qtd = qh->qtd_head; qtd; qtd = qtd->next){
|
||||||
|
u32 *buf;
|
||||||
|
ehci_dma_unmap_bidir(qtd->qtd_dma,sizeof(struct ehci_qtd));
|
||||||
|
dbg_qtd("qtd",qtd);
|
||||||
|
print_hex_dump_bytes("qtd:",DUMP_PREFIX_OFFSET,(void*)qtd,8*4);
|
||||||
|
buf = (u32*)hc32_to_cpu(qtd->hw_buf[0]);
|
||||||
|
if(buf)
|
||||||
|
print_hex_dump_bytes("qtd buf:",DUMP_PREFIX_OFFSET,(void*)(buf),8*4);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* handshake - spin reading hc until handshake completes or fails
|
||||||
|
* @ptr: address of hc register to be read
|
||||||
|
* @mask: bits to look at in result of read
|
||||||
|
* @done: value of those bits when handshake succeeds
|
||||||
|
* @usec: timeout in microseconds
|
||||||
|
*
|
||||||
|
* Returns negative errno, or zero on success
|
||||||
|
*
|
||||||
|
* Success happens when the "mask" bits have the specified value (hardware
|
||||||
|
* handshake done). There are two failure modes: "usec" have passed (major
|
||||||
|
* hardware flakeout), or the register reads as all-ones (hardware removed).
|
||||||
|
*
|
||||||
|
* That last failure should_only happen in cases like physical cardbus eject
|
||||||
|
* before driver shutdown. But it also seems to be caused by bugs in cardbus
|
||||||
|
* bridge shutdown: shutting down the bridge before the devices using it.
|
||||||
|
*/
|
||||||
|
int unplug_device=0;
|
||||||
|
|
||||||
|
|
||||||
|
static int handshake (void __iomem *pstatus, void __iomem *ptr,
|
||||||
|
u32 mask, u32 done, int usec)
|
||||||
|
{
|
||||||
|
u32 result,status;
|
||||||
|
|
||||||
|
|
||||||
|
do {
|
||||||
|
status = ehci_readl( pstatus);
|
||||||
|
result = ehci_readl( ptr);
|
||||||
|
if ((result == ~(u32)0) || (PORT_OWNER&status) || !(PORT_CONNECT&status)) /* card removed */
|
||||||
|
{unplug_device=1;
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
result &= mask;
|
||||||
|
|
||||||
|
if (result == done)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
if(num_command_before_no_verbose)
|
||||||
|
{
|
||||||
|
num_command_before_no_verbose--;
|
||||||
|
if(num_command_before_no_verbose==0)
|
||||||
|
verbose=0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
udelay (100); /* Hermes: 100 microseconds is a god time to response and better for multithread (i think).
|
||||||
|
the new timer uses syscalls and queues to release the thread focus */
|
||||||
|
usec-=100;
|
||||||
|
} while (usec > 0);
|
||||||
|
#ifdef DEBUG
|
||||||
|
verbose = 1;
|
||||||
|
num_command_before_no_verbose=100;
|
||||||
|
#endif
|
||||||
|
ehci_dbg("\nhandshake timeout!!\n\n");
|
||||||
|
//dump_qh(ehci->async);
|
||||||
|
//dump_qh(ehci->asyncqh);
|
||||||
|
//BUG();
|
||||||
|
|
||||||
|
unplug_device=1;
|
||||||
|
#ifndef HOMEBREW
|
||||||
|
return -ENODEV; /* Hermes: with ENODEV works the unplugin method receiving datas (fatal error)
|
||||||
|
ENODEV return without retries and unplug_device can works without interferences.
|
||||||
|
i think is no a good idea too much retries when is possible the device needs one drastic action
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "ehci-mem.c"
|
||||||
|
/* one-time init, only for memory state */
|
||||||
|
static int ehci_init(void)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
if ((retval = ehci_mem_init()) < 0)
|
||||||
|
return retval;
|
||||||
|
/*
|
||||||
|
* dedicate a qh for the async ring head, since we couldn't unlink
|
||||||
|
* a 'real' qh without stopping the async schedule [4.8]. use it
|
||||||
|
* as the 'reclamation list head' too.
|
||||||
|
* its dummy is used in hw_alt_next of many tds, to prevent the qh
|
||||||
|
* from automatically advancing to the next td after short reads.
|
||||||
|
*/
|
||||||
|
ehci->async->hw_next = QH_NEXT( ehci->async->qh_dma);
|
||||||
|
ehci->async->hw_info1 = cpu_to_hc32( QH_HEAD);
|
||||||
|
ehci->async->hw_token = cpu_to_hc32( QTD_STS_HALT);
|
||||||
|
ehci->async->hw_qtd_next = EHCI_LIST_END();
|
||||||
|
ehci->async->hw_alt_next = EHCI_LIST_END();//QTD_NEXT( ehci->async->dummy->qtd_dma);
|
||||||
|
ehci->ctrl_buffer = USB_Alloc(sizeof(usbctrlrequest));
|
||||||
|
ehci->command = 0;
|
||||||
|
|
||||||
|
ehci_writel( 0x008000002, &ehci->regs->command);
|
||||||
|
ehci_writel( ehci->periodic_dma, &ehci->regs->frame_list);
|
||||||
|
ehci_writel( ehci->async->qh_dma, &ehci->regs->async_next);
|
||||||
|
ehci_writel( 0x00010009, &ehci->regs->command);
|
||||||
|
ehci_writel( 1, &ehci->regs->configured_flag);
|
||||||
|
ehci_writel( 0x00010029, &ehci->regs->command);
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fill a qtd, returning how much of the buffer we were able to queue up */
|
||||||
|
static int
|
||||||
|
qtd_fill(struct ehci_qtd *qtd, dma_addr_t buf,
|
||||||
|
size_t len, int token, int maxpacket)
|
||||||
|
{
|
||||||
|
int i, count;
|
||||||
|
u64 addr = buf;
|
||||||
|
//ehci_dbg("fill qtd with dma %X len %X\n",buf,len);
|
||||||
|
/* one buffer entry per 4K ... first might be short or unaligned */
|
||||||
|
qtd->hw_buf[0] = cpu_to_hc32( (u32)addr);
|
||||||
|
qtd->hw_buf_hi[0] = 0;
|
||||||
|
count = 0x1000 - (buf & 0x0fff); /* rest of that page */
|
||||||
|
if (likely (len < count)) /* ... iff needed */
|
||||||
|
count = len;
|
||||||
|
else {
|
||||||
|
buf += 0x1000;
|
||||||
|
buf &= ~0x0fff;
|
||||||
|
|
||||||
|
/* per-qtd limit: from 16K to 20K (best alignment) */
|
||||||
|
for (i = 1; count < len && i < 5; i++) {
|
||||||
|
addr = buf;
|
||||||
|
qtd->hw_buf[i] = cpu_to_hc32( (u32)addr);
|
||||||
|
qtd->hw_buf_hi[i] = cpu_to_hc32(
|
||||||
|
(u32)(addr >> 32));
|
||||||
|
buf += 0x1000;
|
||||||
|
if ((count + 0x1000) < len)
|
||||||
|
count += 0x1000;
|
||||||
|
else
|
||||||
|
count = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* short packets may only terminate transfers */
|
||||||
|
if (count != len)
|
||||||
|
count -= (count % maxpacket);
|
||||||
|
}
|
||||||
|
qtd->hw_token = cpu_to_hc32( (count << 16) | token);
|
||||||
|
qtd->length = count;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// high bandwidth multiplier, as encoded in highspeed endpoint descriptors
|
||||||
|
#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
|
||||||
|
// ... and packet size, for any kind of endpoint descriptor
|
||||||
|
#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reverse of qh_urb_transaction: free a list of TDs.
|
||||||
|
* also count the actual transfer length.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void qh_end_transfer (void)
|
||||||
|
{
|
||||||
|
struct ehci_qtd *qtd;
|
||||||
|
struct ehci_qh *qh = ehci->asyncqh;
|
||||||
|
u32 token;
|
||||||
|
int error = 0;
|
||||||
|
for(qtd = qh->qtd_head; qtd; qtd = qtd->next){
|
||||||
|
token = hc32_to_cpu( qtd->hw_token);
|
||||||
|
if (likely (QTD_PID (token) != 2))
|
||||||
|
qtd->urb->actual_length += qtd->length - QTD_LENGTH (token);
|
||||||
|
if (!(qtd->length ==0 && ((token & 0xff)==QTD_STS_HALT)) &&
|
||||||
|
(token & QTD_STS_HALT)) {
|
||||||
|
ehci_dbg("\nqtd error!:");
|
||||||
|
if (token & QTD_STS_BABBLE) {
|
||||||
|
ehci_dbg(" BABBLE");
|
||||||
|
}
|
||||||
|
if (token & QTD_STS_MMF) {
|
||||||
|
/* fs/ls interrupt xfer missed the complete-split */
|
||||||
|
ehci_dbg(" missed micro frame");
|
||||||
|
}
|
||||||
|
if (token & QTD_STS_DBE) {
|
||||||
|
ehci_dbg(" databuffer error");
|
||||||
|
}
|
||||||
|
if (token & QTD_STS_XACT) {
|
||||||
|
ehci_dbg(" wrong ack");
|
||||||
|
}
|
||||||
|
if (QTD_CERR (token)==0)
|
||||||
|
ehci_dbg(" toomany errors");
|
||||||
|
ehci_dbg("\n");
|
||||||
|
error = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(error){
|
||||||
|
#ifdef DEBUG
|
||||||
|
verbose = 1;
|
||||||
|
num_command_before_no_verbose=100;
|
||||||
|
#endif
|
||||||
|
//dump_qh(ehci->asyncqh);
|
||||||
|
qtd->urb->actual_length = error;
|
||||||
|
}
|
||||||
|
ehci->qtd_used = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* create a list of filled qtds for this URB; won't link into qh.
|
||||||
|
*/
|
||||||
|
struct ehci_qtd *qh_urb_transaction (
|
||||||
|
struct ehci_urb *urb
|
||||||
|
) {
|
||||||
|
struct ehci_qtd *qtd, *qtd_prev;
|
||||||
|
struct ehci_qtd *head;
|
||||||
|
dma_addr_t buf;
|
||||||
|
int len, maxpacket;
|
||||||
|
int is_input;
|
||||||
|
u32 token;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* URBs map to sequences of QTDs: one logical transaction
|
||||||
|
*/
|
||||||
|
head = qtd = ehci_qtd_alloc ();
|
||||||
|
qtd->urb = urb;
|
||||||
|
|
||||||
|
urb->actual_length = 0;
|
||||||
|
token = QTD_STS_ACTIVE;
|
||||||
|
token |= (EHCI_TUNE_CERR << 10);
|
||||||
|
/* for split transactions, SplitXState initialized to zero */
|
||||||
|
|
||||||
|
len = urb->transfer_buffer_length;
|
||||||
|
is_input = urb->input;
|
||||||
|
if (urb->ep==0) {/* is control */
|
||||||
|
/* SETUP pid */
|
||||||
|
qtd_fill( qtd, urb->setup_dma,
|
||||||
|
sizeof (usbctrlrequest),
|
||||||
|
token | (2 /* "setup" */ << 8), 8);
|
||||||
|
|
||||||
|
/* ... and always at least one more pid */
|
||||||
|
token ^= QTD_TOGGLE;
|
||||||
|
qtd_prev = qtd;
|
||||||
|
qtd = ehci_qtd_alloc ();
|
||||||
|
qtd->urb = urb;
|
||||||
|
qtd_prev->hw_next = QTD_NEXT( qtd->qtd_dma);
|
||||||
|
qtd_prev->next = qtd;
|
||||||
|
|
||||||
|
/* for zero length DATA stages, STATUS is always IN */
|
||||||
|
if (len == 0)
|
||||||
|
token |= (1 /* "in" */ << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* data transfer stage: buffer setup
|
||||||
|
*/
|
||||||
|
buf = urb->transfer_dma;
|
||||||
|
|
||||||
|
if (is_input)
|
||||||
|
token |= (1 /* "in" */ << 8);
|
||||||
|
/* else it's already initted to "out" pid (0 << 8) */
|
||||||
|
|
||||||
|
maxpacket = max_packet(urb->maxpacket);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* buffer gets wrapped in one or more qtds;
|
||||||
|
* last one may be "short" (including zero len)
|
||||||
|
* and may serve as a control status ack
|
||||||
|
*/
|
||||||
|
for (;;) {
|
||||||
|
int this_qtd_len;
|
||||||
|
|
||||||
|
this_qtd_len = qtd_fill( qtd, buf, len, token, maxpacket);
|
||||||
|
len -= this_qtd_len;
|
||||||
|
buf += this_qtd_len;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* short reads advance to a "magic" dummy instead of the next
|
||||||
|
* qtd ... that forces the queue to stop, for manual cleanup.
|
||||||
|
* (this will usually be overridden later.)
|
||||||
|
*/
|
||||||
|
if (is_input)
|
||||||
|
qtd->hw_alt_next = ehci->asyncqh->hw_alt_next;
|
||||||
|
|
||||||
|
/* qh makes control packets use qtd toggle; maybe switch it */
|
||||||
|
if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0)
|
||||||
|
token ^= QTD_TOGGLE;
|
||||||
|
|
||||||
|
if (likely (len <= 0))
|
||||||
|
break;
|
||||||
|
|
||||||
|
qtd_prev = qtd;
|
||||||
|
qtd = ehci_qtd_alloc ();
|
||||||
|
qtd->urb = urb;
|
||||||
|
qtd_prev->hw_next = QTD_NEXT( qtd->qtd_dma);
|
||||||
|
qtd_prev->next = qtd;
|
||||||
|
}
|
||||||
|
|
||||||
|
qtd->hw_alt_next = EHCI_LIST_END();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* control requests may need a terminating data "status" ack;
|
||||||
|
* bulk ones may need a terminating short packet (zero length).
|
||||||
|
*/
|
||||||
|
if (likely (urb->transfer_buffer_length != 0)) {
|
||||||
|
int one_more = 0;
|
||||||
|
|
||||||
|
if (urb->ep==0) {
|
||||||
|
one_more = 1;
|
||||||
|
token ^= 0x0100; /* "in" <--> "out" */
|
||||||
|
token |= QTD_TOGGLE; /* force DATA1 */
|
||||||
|
} else if(!(urb->transfer_buffer_length % maxpacket)) {
|
||||||
|
//one_more = 1;
|
||||||
|
}
|
||||||
|
if (one_more) {
|
||||||
|
qtd_prev = qtd;
|
||||||
|
qtd = ehci_qtd_alloc ();
|
||||||
|
qtd->urb = urb;
|
||||||
|
qtd_prev->hw_next = QTD_NEXT( qtd->qtd_dma);
|
||||||
|
qtd_prev->next = qtd;
|
||||||
|
|
||||||
|
/* never any data in such packets */
|
||||||
|
qtd_fill( qtd, 0, 0, token, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* by default, enable interrupt on urb completion */
|
||||||
|
qtd->hw_token |= cpu_to_hc32( QTD_IOC);
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
//u32 usb_timeout=2000*1000;
|
||||||
|
u32 usb_timeout=200*1000;
|
||||||
|
|
||||||
|
int ehci_do_urb (
|
||||||
|
struct ehci_device *dev,
|
||||||
|
struct ehci_urb *urb)
|
||||||
|
{
|
||||||
|
struct ehci_qh *qh;
|
||||||
|
struct ehci_qtd *qtd;
|
||||||
|
u32 info1 = 0, info2 = 0;
|
||||||
|
int is_input;
|
||||||
|
int maxp = 0;
|
||||||
|
int retval=0;
|
||||||
|
|
||||||
|
//ehci_dbg ("do urb %X %X ep %X\n",urb->setup_buffer,urb->transfer_buffer,urb->ep);
|
||||||
|
if(urb->ep==0) //control message
|
||||||
|
urb->setup_dma = ehci_dma_map_to(urb->setup_buffer,sizeof (usbctrlrequest));
|
||||||
|
|
||||||
|
if(urb->transfer_buffer_length){
|
||||||
|
if(urb->input)
|
||||||
|
urb->transfer_dma = ehci_dma_map_to(urb->transfer_buffer,urb->transfer_buffer_length);
|
||||||
|
else
|
||||||
|
urb->transfer_dma = ehci_dma_map_from(urb->transfer_buffer,urb->transfer_buffer_length);
|
||||||
|
}
|
||||||
|
qh = ehci->asyncqh;
|
||||||
|
memset(qh,0,12*4);
|
||||||
|
qtd = qh_urb_transaction ( urb);
|
||||||
|
qh ->qtd_head = qtd;
|
||||||
|
|
||||||
|
|
||||||
|
info1 |= ((urb->ep)&0xf)<<8;
|
||||||
|
info1 |= dev->id;
|
||||||
|
is_input = urb->input;
|
||||||
|
maxp = urb->maxpacket;
|
||||||
|
|
||||||
|
info1 |= (2 << 12); /* EPS "high" */
|
||||||
|
if(urb->ep==0)// control
|
||||||
|
{
|
||||||
|
info1 |= (EHCI_TUNE_RL_HS << 28);
|
||||||
|
info1 |= 64 << 16; /* usb2 fixed maxpacket */
|
||||||
|
info1 |= 1 << 14; /* toggle from qtd */
|
||||||
|
info2 |= (EHCI_TUNE_MULT_HS << 30);
|
||||||
|
}else//bulk
|
||||||
|
{
|
||||||
|
info1 |= (EHCI_TUNE_RL_HS << 28);
|
||||||
|
/* The USB spec says that high speed bulk endpoints
|
||||||
|
* always use 512 byte maxpacket. But some device
|
||||||
|
* vendors decided to ignore that, and MSFT is happy
|
||||||
|
* to help them do so. So now people expect to use
|
||||||
|
* such nonconformant devices with Linux too; sigh.
|
||||||
|
*/
|
||||||
|
info1 |= max_packet(maxp) << 16;
|
||||||
|
info2 |= (EHCI_TUNE_MULT_HS << 30);
|
||||||
|
|
||||||
|
}
|
||||||
|
//ehci_dbg("HW info: %08X\n",info1);
|
||||||
|
qh->hw_info1 = cpu_to_hc32( info1);
|
||||||
|
qh->hw_info2 = cpu_to_hc32( info2);
|
||||||
|
|
||||||
|
qh->hw_next = QH_NEXT(qh->qh_dma);
|
||||||
|
qh->hw_qtd_next = QTD_NEXT( qtd->qtd_dma);
|
||||||
|
qh->hw_alt_next = EHCI_LIST_END();
|
||||||
|
|
||||||
|
if(urb->ep!=0){
|
||||||
|
if(get_toggle(dev,urb->ep))
|
||||||
|
qh->hw_token |= cpu_to_hc32(QTD_TOGGLE);
|
||||||
|
else
|
||||||
|
qh->hw_token &= ~cpu_to_hc32( QTD_TOGGLE);
|
||||||
|
//ehci_dbg("toggle for ep %x: %d %x\n",urb->ep,get_toggle(dev,urb->ep),qh->hw_token);
|
||||||
|
}
|
||||||
|
|
||||||
|
qh->hw_token &= cpu_to_hc32( QTD_TOGGLE | QTD_STS_PING);
|
||||||
|
|
||||||
|
qh->hw_next = QH_NEXT(ehci->async->qh_dma);
|
||||||
|
|
||||||
|
|
||||||
|
ehci_dma_map_bidir(qh,sizeof(struct ehci_qh));
|
||||||
|
for(qtd = qh->qtd_head; qtd; qtd = qtd->next)
|
||||||
|
ehci_dma_map_bidir(qtd,sizeof(struct ehci_qtd));
|
||||||
|
#if 0
|
||||||
|
if(urb->ep!=0){
|
||||||
|
dump_qh(ehci->async);
|
||||||
|
dump_qh(ehci->asyncqh);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// start (link qh)
|
||||||
|
ehci->async->hw_next = QH_NEXT(qh->qh_dma);
|
||||||
|
ehci_dma_map_bidir(ehci->async,sizeof(struct ehci_qh));
|
||||||
|
|
||||||
|
retval = handshake(&ehci->regs->port_status[dev->port],&ehci->regs->status,STS_INT,STS_INT,usb_timeout);
|
||||||
|
|
||||||
|
//print_hex_dump_bytes ("qh mem",0,(void*)qh,17*4);
|
||||||
|
//retval = poll_transfer_end(1000*1000);
|
||||||
|
ehci_dma_unmap_bidir(ehci->async->qh_dma,sizeof(struct ehci_qh));
|
||||||
|
ehci_dma_unmap_bidir(qh->qh_dma,sizeof(struct ehci_qh));
|
||||||
|
for(qtd = qh->qtd_head; qtd; qtd = qtd->next)
|
||||||
|
ehci_dma_unmap_bidir(qtd->qtd_dma,sizeof(struct ehci_qtd));
|
||||||
|
|
||||||
|
// stop (unlink qh)
|
||||||
|
ehci->async->hw_next = QH_NEXT(ehci->async->qh_dma);
|
||||||
|
ehci_dma_map_bidir(ehci->async,sizeof(struct ehci_qh));
|
||||||
|
ehci_dma_unmap_bidir(ehci->async->qh_dma,sizeof(struct ehci_qh));
|
||||||
|
|
||||||
|
// ack
|
||||||
|
ehci_writel( STS_RECL|STS_IAA|STS_INT, &ehci->regs->status);
|
||||||
|
|
||||||
|
if(urb->ep!=0){
|
||||||
|
set_toggle(dev,urb->ep,(qh->hw_token & cpu_to_hc32(QTD_TOGGLE))?1:0);
|
||||||
|
//ehci_dbg("toggle for ep %x: %d %d %x %X\n",urb->ep,get_toggle(dev,urb->ep),(qh->hw_token & cpu_to_hc32(QTD_TOGGLE)),qh->hw_token,dev->toggles);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(retval>=0)
|
||||||
|
// wait hc really stopped
|
||||||
|
retval = handshake(&ehci->regs->port_status[dev->port],&ehci->regs->async_next,~0,ehci->async->qh_dma,60*1000);
|
||||||
|
//release memory, and actualise urb->actual_length
|
||||||
|
qh_end_transfer();
|
||||||
|
|
||||||
|
|
||||||
|
if(urb->transfer_buffer_length){
|
||||||
|
if(urb->input)
|
||||||
|
ehci_dma_unmap_to(urb->transfer_dma,urb->transfer_buffer_length);
|
||||||
|
else
|
||||||
|
ehci_dma_unmap_from(urb->transfer_dma,urb->transfer_buffer_length);
|
||||||
|
}
|
||||||
|
if(urb->ep==0) //control message
|
||||||
|
ehci_dma_unmap_to(urb->setup_dma,sizeof (usbctrlrequest));
|
||||||
|
if(retval==0){
|
||||||
|
|
||||||
|
return urb->actual_length;
|
||||||
|
|
||||||
|
ehci_dbg ( "un successfull urb %d!!\n", retval);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 ehci_control_message(struct ehci_device *dev,u8 bmRequestType,u8 bmRequest,u16 wValue,u16 wIndex,u32 wLength,void *buf)
|
||||||
|
{
|
||||||
|
struct ehci_urb urb;
|
||||||
|
usbctrlrequest *req = ehci->ctrl_buffer;
|
||||||
|
if(verbose)
|
||||||
|
ehci_dbg ( "control msg: rt%02X r%02X v%04X i%04X s%04x %p\n", bmRequestType, bmRequest, wValue, wIndex,wLength,buf);
|
||||||
|
req->bRequestType = bmRequestType;
|
||||||
|
req->bRequest = bmRequest;
|
||||||
|
req->wValue = swab16(wValue);
|
||||||
|
req->wIndex = swab16(wIndex);
|
||||||
|
req->wLength = swab16(wLength);
|
||||||
|
urb.setup_buffer = req;
|
||||||
|
urb.ep = 0;
|
||||||
|
urb.input = (bmRequestType&USB_CTRLTYPE_DIR_DEVICE2HOST)!=0;
|
||||||
|
urb.maxpacket = 64;
|
||||||
|
|
||||||
|
|
||||||
|
urb.transfer_buffer_length = wLength;
|
||||||
|
|
||||||
|
if (((u32)buf) > 0x13880000){// HW cannot access this buffer, we allow this for convenience
|
||||||
|
int ret;
|
||||||
|
urb.transfer_buffer = USB_Alloc(wLength);
|
||||||
|
if(urb.transfer_buffer==NULL)
|
||||||
|
{
|
||||||
|
//my_sprint("USB Alloc: not enough memory! transfer_buffer", NULL);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
if (verbose)
|
||||||
|
ehci_dbg("alloc another buffer %p %p\n",buf,urb.transfer_buffer);
|
||||||
|
memcpy(urb.transfer_buffer,buf,wLength);
|
||||||
|
ret = ehci_do_urb(dev,&urb);
|
||||||
|
memcpy(buf,urb.transfer_buffer,wLength);
|
||||||
|
USB_Free(urb.transfer_buffer);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
|
||||||
|
{
|
||||||
|
urb.transfer_buffer = buf;
|
||||||
|
return ehci_do_urb(dev,&urb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s32 ehci_bulk_message(struct ehci_device *dev,u8 bEndpoint,u32 wLength,void *rpData)
|
||||||
|
{
|
||||||
|
struct ehci_urb urb;
|
||||||
|
s32 ret;
|
||||||
|
urb.setup_buffer = NULL;
|
||||||
|
urb.ep = bEndpoint;
|
||||||
|
urb.input = (bEndpoint&0x80)!=0;
|
||||||
|
urb.maxpacket = 512;
|
||||||
|
urb.transfer_buffer_length = wLength;
|
||||||
|
urb.transfer_buffer = rpData;
|
||||||
|
if(verbose)
|
||||||
|
ehci_dbg ( "bulk msg: ep:%02X size:%02X addr:%04X", bEndpoint, wLength, rpData);
|
||||||
|
|
||||||
|
ret= ehci_do_urb(dev,&urb);
|
||||||
|
/*
|
||||||
|
int i;
|
||||||
|
for(i=0;i<1;i++)
|
||||||
|
{
|
||||||
|
ret= ehci_do_urb(dev,&urb);
|
||||||
|
//if(ret<0) msleep(500);
|
||||||
|
//else break;
|
||||||
|
}
|
||||||
|
//if(ret<0)my_sprint("urb error",NULL);
|
||||||
|
*/
|
||||||
|
if(verbose)
|
||||||
|
ehci_dbg ( "==>%d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ehci_reset_port(int port)
|
||||||
|
{
|
||||||
|
u32 __iomem *status_reg = &ehci->regs->port_status[port];
|
||||||
|
|
||||||
|
struct ehci_device *dev = &ehci->devices[port];
|
||||||
|
u32 status = ehci_readl(status_reg);
|
||||||
|
|
||||||
|
int retval = 0;
|
||||||
|
dev->id = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if ((PORT_OWNER&status) || !(PORT_CONNECT&status))
|
||||||
|
{
|
||||||
|
ehci_writel( PORT_OWNER,status_reg);
|
||||||
|
ehci_dbg ( "port %d had no usb2 device connected at startup %X \n", port,ehci_readl(status_reg));
|
||||||
|
return -ENODEV;// no USB2 device connected
|
||||||
|
}
|
||||||
|
ehci_dbg ( "port %d has usb2 device connected! reset it...\n", port);
|
||||||
|
|
||||||
|
char log[2048];
|
||||||
|
char cad[200];
|
||||||
|
|
||||||
|
log[0]='\0';
|
||||||
|
status = ehci_readl(status_reg);
|
||||||
|
debug_sprintf(cad,"status 1: %04x\n",status);
|
||||||
|
strcat(log,cad);
|
||||||
|
//ehci_writel( portsc,status_reg);
|
||||||
|
msleep(5);
|
||||||
|
status &= ~PORT_PE;
|
||||||
|
status |= PORT_RESET;
|
||||||
|
debug_sprintf(cad,"ehci_writel 1: %04x\n",status);
|
||||||
|
strcat(log,cad);
|
||||||
|
ehci_writel( status,status_reg);
|
||||||
|
|
||||||
|
//ehci_writel( 0x1803,status_reg);
|
||||||
|
|
||||||
|
//msleep(50);
|
||||||
|
//ehci_writel( 0x1903,status_reg);
|
||||||
|
//ehci_writel( PORT_OWNER|PORT_POWER|PORT_RESET,status_reg);
|
||||||
|
#ifdef HOMEBREW
|
||||||
|
msleep(20);
|
||||||
|
#else
|
||||||
|
msleep(500); // wait 500ms for the reset sequence
|
||||||
|
#endif
|
||||||
|
status = ehci_readl(status_reg);
|
||||||
|
debug_sprintf(cad,"status 2: %04x\n",status);
|
||||||
|
strcat(log,cad);
|
||||||
|
status &= ~PORT_RESET;
|
||||||
|
debug_sprintf(cad,"ehci_writel 2: %04x\n",status);strcat(log,cad);
|
||||||
|
ehci_writel( status,status_reg);
|
||||||
|
|
||||||
|
|
||||||
|
//ehci_writel( ehci_readl(status_reg)& (~PORT_RESET),status_reg);
|
||||||
|
|
||||||
|
|
||||||
|
retval = handshake(status_reg, status_reg,
|
||||||
|
PORT_RESET, 0, 750*2);
|
||||||
|
|
||||||
|
if (retval != 0) {
|
||||||
|
debug_sprintf(cad,"port reset error status: %04x\n",ehci_readl(status_reg));
|
||||||
|
strcat(log,cad);
|
||||||
|
my_sprint(log,NULL);
|
||||||
|
ehci_dbg ( "port %d reset error %d\n",
|
||||||
|
port, retval);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
ehci_dbg ( "port %d reseted status:%04x...\n", port,ehci_readl(status_reg));
|
||||||
|
status = ehci_readl(status_reg);
|
||||||
|
|
||||||
|
|
||||||
|
if (!(status & PORT_PE)) {
|
||||||
|
// that means is low speed device so release
|
||||||
|
status |= PORT_OWNER;
|
||||||
|
status &= ~PORT_RWC_BITS;
|
||||||
|
ehci_writel( status, status_reg);
|
||||||
|
msleep(10);
|
||||||
|
status = ehci_readl(status_reg);
|
||||||
|
debug_sprintf(cad,"PORT_PE status: %04x\n",status);
|
||||||
|
strcat(log,cad);
|
||||||
|
my_sprint(log,NULL);
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
}
|
||||||
|
//my_sprint(log,NULL);
|
||||||
|
debug_sprintf(cad,"port status2: %04x\n",status);
|
||||||
|
strcat(log,cad);
|
||||||
|
|
||||||
|
//portsc = ehci_readl(status_reg);
|
||||||
|
if (status & PORT_RESUME)
|
||||||
|
{
|
||||||
|
ehci_writel(status & ~(PORT_RWC_BITS | PORT_RESUME),status_reg);
|
||||||
|
(void) ehci_readl(&ehci->regs->command);
|
||||||
|
status = ehci_readl(status_reg);
|
||||||
|
ehci_writel(status & ~PORT_RESET,status_reg);
|
||||||
|
status = ehci_readl(status_reg);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
portsc &= ~(PORT_RWC_BITS | PORT_RESUME|(3<<10)) ;
|
||||||
|
ehci_writel( portsc,status_reg);
|
||||||
|
msleep(50);
|
||||||
|
debug_sprintf(cad,"%d - %08x ",ehci_readl(status_reg),ehci_readl(status_reg));
|
||||||
|
my_sprint("port resume status: ",cad);
|
||||||
|
*/
|
||||||
|
debug_sprintf(cad,"port reseted status: %04x\n",status);
|
||||||
|
strcat(log,cad);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HOMEBREW
|
||||||
|
msleep(400);
|
||||||
|
#else
|
||||||
|
msleep(1000);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ehci_control_message(dev,USB_CTRLTYPE_DIR_HOST2DEVICE | USB_CTRLTYPE_TYPE_CLASS | USB_CTRLTYPE_REC_INTERFACE,
|
||||||
|
// 0xFF,0,0,0,0);
|
||||||
|
/*
|
||||||
|
ehci_control_message(dev, (USB_CTRLTYPE_DIR_HOST2DEVICE | USB_CTRLTYPE_TYPE_CLASS | USB_CTRLTYPE_REC_INTERFACE), 0xFF, 0, dev->interface, 0, NULL);
|
||||||
|
USBStorage_Inquiry(dev, 0);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// now the device has the default device id
|
||||||
|
// retval = ehci_control_message(dev,USB_CTRLTYPE_DIR_HOST2DEVICE,
|
||||||
|
// USB_REQ_GETDESCRIPTOR,USB_DT_DEVICE<<8,0,sizeof(dev->desc),&dev->desc);
|
||||||
|
// retval = ehci_control_message(dev,0x80,
|
||||||
|
// USB_REQ_GETDESCRIPTOR,USB_DT_DEVICE<<8,0,sizeof(dev->desc),&dev->desc);
|
||||||
|
|
||||||
|
//void *buf;
|
||||||
|
//buf = USB_Alloc(0x20);
|
||||||
|
|
||||||
|
// retval = ehci_control_message(dev,0x80,
|
||||||
|
// 0x6,0x100,0,0x12,&dev->desc);
|
||||||
|
/*
|
||||||
|
retval = ehci_control_message(dev,0x80,
|
||||||
|
0x6,0x200,0,0x9,buf);
|
||||||
|
retval = ehci_control_message(dev,0x80,
|
||||||
|
0x6,0x200,0,0x20,buf);
|
||||||
|
retval = ehci_control_message(dev,0x80,
|
||||||
|
0x6,0x300,0,0x2,buf);
|
||||||
|
retval = ehci_control_message(dev,0x80,
|
||||||
|
0x6,0x300,0,0x4,buf);
|
||||||
|
|
||||||
|
retval = ehci_control_message(dev,0x80,
|
||||||
|
USB_REQ_SETCONFIG,1,0,0,0);
|
||||||
|
retval = ehci_control_message(dev,0x80,
|
||||||
|
USB_REQ_SETINTERFACE,0,0,0,0);
|
||||||
|
*/
|
||||||
|
//USB_Free(buf);
|
||||||
|
/*
|
||||||
|
if (retval < 0) {
|
||||||
|
debug_sprintf(cad,"unable to get device desc: %04x %04x\n",status,USB_DT_DEVICE<<8);strcat(log,cad);
|
||||||
|
my_sprint(log,NULL);
|
||||||
|
ehci_dbg ( "unable to get device desc...\n");
|
||||||
|
return retval;
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
debug_sprintf(cad," device desc ok\n");strcat(log,cad);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// retval = ehci_control_message(dev,USB_CTRLTYPE_DIR_HOST2DEVICE,
|
||||||
|
// USB_REQ_SETADDRESS,port+1,0,0,0);
|
||||||
|
retval = ehci_control_message(dev,0x80,
|
||||||
|
USB_REQ_SETADDRESS,port+1,0,0,0);
|
||||||
|
if (retval < 0) {
|
||||||
|
//my_sprint("unable to set device addr",NULL);
|
||||||
|
debug_sprintf(cad,"unable to set device addr\n");strcat(log,cad);
|
||||||
|
ehci_dbg ( "unable to set device addr...\n");
|
||||||
|
//return retval;
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
debug_sprintf(cad," set device addr ok\n");strcat(log,cad);
|
||||||
|
}
|
||||||
|
// retval = ehci_control_message(dev,USB_CTRLTYPE_DIR_DEVICE2HOST,
|
||||||
|
// USB_REQ_GETDESCRIPTOR,USB_DT_DEVICE<<8,0,sizeof(dev->desc),&dev->desc);
|
||||||
|
|
||||||
|
|
||||||
|
dev->toggles = 0;
|
||||||
|
|
||||||
|
dev->id = port+1;
|
||||||
|
|
||||||
|
|
||||||
|
debug_sprintf(cad,"device %d: %X %X...\n", dev->id,le16_to_cpu(dev->desc.idVendor),le16_to_cpu(dev->desc.idProduct));
|
||||||
|
strcat(log,cad);
|
||||||
|
debug_sprintf(cad,"device reset ok\n");
|
||||||
|
strcat(log,cad);
|
||||||
|
my_sprint(log,NULL);
|
||||||
|
|
||||||
|
ehci_dbg ( "device %d: %X %X...\n", dev->id,le16_to_cpu(dev->desc.idVendor),le16_to_cpu(dev->desc.idProduct));
|
||||||
|
|
||||||
|
/*
|
||||||
|
result = usb_stor_control_msg(us, us->send_ctrl_pipe,
|
||||||
|
USB_REQ_SET_FEATURE,
|
||||||
|
USB_TYPE_STANDARD | USB_RECIP_DEVICE,
|
||||||
|
0x01, 0x0, NULL, 0x0, 1000);
|
||||||
|
*/
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ehci_reset_port2(int port)
|
||||||
|
{
|
||||||
|
u32 __iomem *status_reg = &ehci->regs->port_status[port];
|
||||||
|
int ret=ehci_reset_port(port);
|
||||||
|
//if(ret==-ENODEV)
|
||||||
|
{
|
||||||
|
//msleep(1000); // power off 1 second
|
||||||
|
msleep(10); // power off 1 second
|
||||||
|
ehci_writel( 0x1001 ,status_reg); // power on
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ehci_reset_device(struct ehci_device *dev)
|
||||||
|
{
|
||||||
|
return ehci_reset_port(dev->port);
|
||||||
|
}
|
||||||
|
#include "usbstorage.h"
|
||||||
|
int ehci_discover(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
// precondition: the ehci should be halted
|
||||||
|
for(i = 0;i<ehci->num_port; i++){
|
||||||
|
struct ehci_device *dev = &ehci->devices[i];
|
||||||
|
dev->port = i;
|
||||||
|
ehci_reset_port(i);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* wii: quickly release non ehci or not connected ports,
|
||||||
|
as we can't kick OHCI drivers laters if we discover a device for them.
|
||||||
|
*/
|
||||||
|
int ehci_release_ports(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
u32 __iomem *status_reg = &ehci->regs->port_status[2];
|
||||||
|
while(ehci_readl(&ehci->regs->port_status[2]) == 0x1000) udelay(100);// wait port 2 to init
|
||||||
|
msleep(100);// wait another msec..
|
||||||
|
for(i = 0;i<ehci->num_port; i++){
|
||||||
|
status_reg = &ehci->regs->port_status[i];
|
||||||
|
u32 status = ehci_readl(status_reg);
|
||||||
|
if (i==2 || !(PORT_CONNECT&status) || PORT_USB11(status))
|
||||||
|
ehci_writel( PORT_OWNER,status_reg); // release port.
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ehci_open_device(int vid,int pid,int fd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=0;i<ehci->num_port;i++)
|
||||||
|
{
|
||||||
|
//ehci_dbg("try device: %d\n",i);
|
||||||
|
if(ehci->devices[i].fd == 0 &&
|
||||||
|
le16_to_cpu(ehci->devices[i].desc.idVendor) == vid &&
|
||||||
|
le16_to_cpu(ehci->devices[i].desc.idProduct) == pid)
|
||||||
|
{
|
||||||
|
//ehci_dbg("found device: %x %x\n",vid,pid);
|
||||||
|
ehci->devices[i].fd = fd;
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -6;
|
||||||
|
}
|
||||||
|
int ehci_close_device(struct ehci_device *dev)
|
||||||
|
{
|
||||||
|
if (dev)
|
||||||
|
dev->fd = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
void * ehci_fd_to_dev(int fd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=0;i<ehci->num_port;i++)
|
||||||
|
{
|
||||||
|
struct ehci_device *dev = &ehci->devices[i];
|
||||||
|
//ehci_dbg ( "device %d:fd:%d %X %X...\n", dev->id,dev->fd,le16_to_cpu(dev->desc.idVendor),le16_to_cpu(dev->desc.idProduct));
|
||||||
|
if(dev->fd == fd){
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ehci_dbg("unkown fd! %d\n",fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#define g_ehci #error
|
||||||
|
int ehci_get_device_list(u8 maxdev,u8 b0,u8*num,u16*buf)
|
||||||
|
{
|
||||||
|
int i,j = 0;
|
||||||
|
for(i=0;i<ehci->num_port && j<maxdev ;i++)
|
||||||
|
{
|
||||||
|
struct ehci_device *dev = &ehci->devices[i];
|
||||||
|
if(dev->id != 0){
|
||||||
|
//ehci_dbg ( "device %d: %X %X...\n", dev->id,le16_to_cpu(dev->desc.idVendor),le16_to_cpu(dev->desc.idProduct));
|
||||||
|
buf[j*4] = 0;
|
||||||
|
buf[j*4+1] = 0;
|
||||||
|
buf[j*4+2] = le16_to_cpu(dev->desc.idVendor);
|
||||||
|
buf[j*4+3] = le16_to_cpu(dev->desc.idProduct);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//ehci_dbg("found %d devices\n",j);
|
||||||
|
*num = j;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#include "usb.c"
|
||||||
|
#include "usbstorage.c"
|
862
tinyehci/ehci.c.old2
Normal file
862
tinyehci/ehci.c.old2
Normal file
@ -0,0 +1,862 @@
|
|||||||
|
void my_sprint(char *cad, char *s);
|
||||||
|
/* simplest usb-ehci driver which features:
|
||||||
|
|
||||||
|
control and bulk transfers only
|
||||||
|
only one transfer pending
|
||||||
|
driver is synchronous (waiting for the end of the transfer)
|
||||||
|
endianess independant
|
||||||
|
no uncached memory allocation needed
|
||||||
|
|
||||||
|
this driver is originally based on the GPL linux ehci-hcd driver
|
||||||
|
|
||||||
|
* Original Copyright (c) 2001 by David Brownell
|
||||||
|
*
|
||||||
|
* 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 of the License, 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,
|
||||||
|
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* magic numbers that can affect system performance */
|
||||||
|
#define EHCI_TUNE_CERR 0 /* 0-3 qtd retries; 0 == don't stop */ /* by Hermes: i have replaced 3 by 0 and now it don´t hang when i extract the device*/
|
||||||
|
#define EHCI_TUNE_RL_HS 4 /* nak throttle; see 4.9 */
|
||||||
|
#define EHCI_TUNE_RL_TT 0
|
||||||
|
#define EHCI_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */
|
||||||
|
#define EHCI_TUNE_MULT_TT 1
|
||||||
|
#define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */
|
||||||
|
extern int verbose;
|
||||||
|
#ifdef DEBUG
|
||||||
|
static int num_command_before_no_verbose = 100;
|
||||||
|
#endif
|
||||||
|
static void
|
||||||
|
dbg_qtd (const char *label, struct ehci_qtd *qtd)
|
||||||
|
{
|
||||||
|
ehci_dbg( "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
|
||||||
|
hc32_to_cpup( &qtd->hw_next),
|
||||||
|
hc32_to_cpup( &qtd->hw_alt_next),
|
||||||
|
hc32_to_cpup( &qtd->hw_token),
|
||||||
|
hc32_to_cpup( &qtd->hw_buf [0]));
|
||||||
|
if (qtd->hw_buf [1])
|
||||||
|
ehci_dbg( " p1=%08x p2=%08x p3=%08x p4=%08x\n",
|
||||||
|
hc32_to_cpup( &qtd->hw_buf[1]),
|
||||||
|
hc32_to_cpup( &qtd->hw_buf[2]),
|
||||||
|
hc32_to_cpup( &qtd->hw_buf[3]),
|
||||||
|
hc32_to_cpup( &qtd->hw_buf[4]));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dbg_qh (const char *label, struct ehci_qh *qh)
|
||||||
|
{
|
||||||
|
ehci_dbg ( "%s qh %p n%08x info %x %x qtd %x\n", label,
|
||||||
|
qh,
|
||||||
|
hc32_to_cpu(qh->hw_next),
|
||||||
|
hc32_to_cpu(qh->hw_info1),
|
||||||
|
hc32_to_cpu(qh->hw_info2),
|
||||||
|
hc32_to_cpu(qh->hw_current));
|
||||||
|
dbg_qtd ("overlay", (struct ehci_qtd *) &qh->hw_qtd_next);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dbg_command (void)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
u32 command=ehci_readl( &ehci->regs->command);
|
||||||
|
u32 async=ehci_readl( &ehci->regs->async_next);
|
||||||
|
|
||||||
|
ehci_dbg ("async_next: %08x\n",async);
|
||||||
|
ehci_dbg (
|
||||||
|
"command %06x %s=%d ithresh=%d%s%s%s%s %s %s\n",
|
||||||
|
command,
|
||||||
|
(command & CMD_PARK) ? "park" : "(park)",
|
||||||
|
CMD_PARK_CNT (command),
|
||||||
|
(command >> 16) & 0x3f,
|
||||||
|
(command & CMD_LRESET) ? " LReset" : "",
|
||||||
|
(command & CMD_IAAD) ? " IAAD" : "",
|
||||||
|
(command & CMD_ASE) ? " Async" : "",
|
||||||
|
(command & CMD_PSE) ? " Periodic" : "",
|
||||||
|
(command & CMD_RESET) ? " Reset" : "",
|
||||||
|
(command & CMD_RUN) ? "RUN" : "HALT"
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
dbg_status (void)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
u32 status=ehci_readl( &ehci->regs->status);
|
||||||
|
ehci_dbg (
|
||||||
|
"status %04x%s%s%s%s%s%s%s%s%s%s\n",
|
||||||
|
status,
|
||||||
|
(status & STS_ASS) ? " Async" : "",
|
||||||
|
(status & STS_PSS) ? " Periodic" : "",
|
||||||
|
(status & STS_RECL) ? " Recl" : "",
|
||||||
|
(status & STS_HALT) ? " Halt" : "",
|
||||||
|
(status & STS_IAA) ? " IAA" : "",
|
||||||
|
(status & STS_FATAL) ? " FATAL" : "",
|
||||||
|
(status & STS_FLR) ? " FLR" : "",
|
||||||
|
(status & STS_PCD) ? " PCD" : "",
|
||||||
|
(status & STS_ERR) ? " ERR" : "",
|
||||||
|
(status & STS_INT) ? " INT" : ""
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void debug_qtds(void)
|
||||||
|
{
|
||||||
|
struct ehci_qh *qh = ehci->async;
|
||||||
|
struct ehci_qtd *qtd;
|
||||||
|
dbg_qh ("qh",qh);
|
||||||
|
dbg_command ();
|
||||||
|
dbg_status ();
|
||||||
|
for(qtd = qh->qtd_head; qtd; qtd = qtd->next)
|
||||||
|
{
|
||||||
|
ehci_dma_unmap_bidir(qtd->qtd_dma,sizeof(struct ehci_qtd));
|
||||||
|
dbg_qtd("qtd",qtd);
|
||||||
|
ehci_dma_map_bidir(qtd,sizeof(struct ehci_qtd));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
void dump_qh(struct ehci_qh *qh)
|
||||||
|
{
|
||||||
|
struct ehci_qtd *qtd;
|
||||||
|
dbg_command ();
|
||||||
|
dbg_status ();
|
||||||
|
ehci_dma_unmap_bidir(qh->qh_dma,sizeof(struct ehci_qh));
|
||||||
|
dbg_qh("qh",qh);
|
||||||
|
print_hex_dump_bytes("qh:",DUMP_PREFIX_OFFSET,(void*)qh,12*4);
|
||||||
|
for(qtd = qh->qtd_head; qtd; qtd = qtd->next){
|
||||||
|
u32 *buf;
|
||||||
|
ehci_dma_unmap_bidir(qtd->qtd_dma,sizeof(struct ehci_qtd));
|
||||||
|
dbg_qtd("qtd",qtd);
|
||||||
|
print_hex_dump_bytes("qtd:",DUMP_PREFIX_OFFSET,(void*)qtd,8*4);
|
||||||
|
buf = (u32*)hc32_to_cpu(qtd->hw_buf[0]);
|
||||||
|
if(buf)
|
||||||
|
print_hex_dump_bytes("qtd buf:",DUMP_PREFIX_OFFSET,(void*)(buf),8*4);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* handshake - spin reading hc until handshake completes or fails
|
||||||
|
* @ptr: address of hc register to be read
|
||||||
|
* @mask: bits to look at in result of read
|
||||||
|
* @done: value of those bits when handshake succeeds
|
||||||
|
* @usec: timeout in microseconds
|
||||||
|
*
|
||||||
|
* Returns negative errno, or zero on success
|
||||||
|
*
|
||||||
|
* Success happens when the "mask" bits have the specified value (hardware
|
||||||
|
* handshake done). There are two failure modes: "usec" have passed (major
|
||||||
|
* hardware flakeout), or the register reads as all-ones (hardware removed).
|
||||||
|
*
|
||||||
|
* That last failure should_only happen in cases like physical cardbus eject
|
||||||
|
* before driver shutdown. But it also seems to be caused by bugs in cardbus
|
||||||
|
* bridge shutdown: shutting down the bridge before the devices using it.
|
||||||
|
*/
|
||||||
|
int unplug_device=0;
|
||||||
|
|
||||||
|
|
||||||
|
static int handshake (void __iomem *pstatus, void __iomem *ptr,
|
||||||
|
u32 mask, u32 done, int usec)
|
||||||
|
{
|
||||||
|
u32 result,status;
|
||||||
|
|
||||||
|
|
||||||
|
do {
|
||||||
|
status = ehci_readl( pstatus);
|
||||||
|
result = ehci_readl( ptr);
|
||||||
|
if ((result == ~(u32)0) || (PORT_OWNER&status) || !(PORT_CONNECT&status)) /* card removed */
|
||||||
|
{unplug_device=1;
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
result &= mask;
|
||||||
|
|
||||||
|
if (result == done)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
if(num_command_before_no_verbose)
|
||||||
|
{
|
||||||
|
num_command_before_no_verbose--;
|
||||||
|
if(num_command_before_no_verbose==0)
|
||||||
|
verbose=0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
udelay (100); /* Hermes: 100 microseconds is a god time to response and better for multithread (i think).
|
||||||
|
the new timer uses syscalls and queues to release the thread focus */
|
||||||
|
usec-=100;
|
||||||
|
} while (usec > 0);
|
||||||
|
#ifdef DEBUG
|
||||||
|
verbose = 1;
|
||||||
|
num_command_before_no_verbose=100;
|
||||||
|
#endif
|
||||||
|
ehci_dbg("\nhandshake timeout!!\n\n");
|
||||||
|
//dump_qh(ehci->async);
|
||||||
|
//dump_qh(ehci->asyncqh);
|
||||||
|
//BUG();
|
||||||
|
|
||||||
|
unplug_device=1;
|
||||||
|
#ifndef HOMEBREW
|
||||||
|
return -ENODEV; /* Hermes: with ENODEV works the unplugin method receiving datas (fatal error)
|
||||||
|
ENODEV return without retries and unplug_device can works without interferences.
|
||||||
|
i think is no a good idea too much retries when is possible the device needs one drastic action
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "ehci-mem.c"
|
||||||
|
/* one-time init, only for memory state */
|
||||||
|
static int ehci_init(void)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
if ((retval = ehci_mem_init()) < 0)
|
||||||
|
return retval;
|
||||||
|
/*
|
||||||
|
* dedicate a qh for the async ring head, since we couldn't unlink
|
||||||
|
* a 'real' qh without stopping the async schedule [4.8]. use it
|
||||||
|
* as the 'reclamation list head' too.
|
||||||
|
* its dummy is used in hw_alt_next of many tds, to prevent the qh
|
||||||
|
* from automatically advancing to the next td after short reads.
|
||||||
|
*/
|
||||||
|
ehci->async->hw_next = QH_NEXT( ehci->async->qh_dma);
|
||||||
|
ehci->async->hw_info1 = cpu_to_hc32( QH_HEAD);
|
||||||
|
ehci->async->hw_token = cpu_to_hc32( QTD_STS_HALT);
|
||||||
|
ehci->async->hw_qtd_next = EHCI_LIST_END();
|
||||||
|
ehci->async->hw_alt_next = EHCI_LIST_END();//QTD_NEXT( ehci->async->dummy->qtd_dma);
|
||||||
|
ehci->ctrl_buffer = USB_Alloc(sizeof(usbctrlrequest));
|
||||||
|
ehci->command = 0;
|
||||||
|
|
||||||
|
ehci_writel( 0x008000002, &ehci->regs->command);
|
||||||
|
ehci_writel( ehci->periodic_dma, &ehci->regs->frame_list);
|
||||||
|
ehci_writel( ehci->async->qh_dma, &ehci->regs->async_next);
|
||||||
|
ehci_writel( 0x00010009, &ehci->regs->command);
|
||||||
|
ehci_writel( 1, &ehci->regs->configured_flag);
|
||||||
|
ehci_writel( 0x00010029, &ehci->regs->command);
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fill a qtd, returning how much of the buffer we were able to queue up */
|
||||||
|
static int
|
||||||
|
qtd_fill(struct ehci_qtd *qtd, dma_addr_t buf,
|
||||||
|
size_t len, int token, int maxpacket)
|
||||||
|
{
|
||||||
|
int i, count;
|
||||||
|
u64 addr = buf;
|
||||||
|
//ehci_dbg("fill qtd with dma %X len %X\n",buf,len);
|
||||||
|
/* one buffer entry per 4K ... first might be short or unaligned */
|
||||||
|
qtd->hw_buf[0] = cpu_to_hc32( (u32)addr);
|
||||||
|
qtd->hw_buf_hi[0] = 0;
|
||||||
|
count = 0x1000 - (buf & 0x0fff); /* rest of that page */
|
||||||
|
if (likely (len < count)) /* ... iff needed */
|
||||||
|
count = len;
|
||||||
|
else {
|
||||||
|
buf += 0x1000;
|
||||||
|
buf &= ~0x0fff;
|
||||||
|
|
||||||
|
/* per-qtd limit: from 16K to 20K (best alignment) */
|
||||||
|
for (i = 1; count < len && i < 5; i++) {
|
||||||
|
addr = buf;
|
||||||
|
qtd->hw_buf[i] = cpu_to_hc32( (u32)addr);
|
||||||
|
qtd->hw_buf_hi[i] = cpu_to_hc32(
|
||||||
|
(u32)(addr >> 32));
|
||||||
|
buf += 0x1000;
|
||||||
|
if ((count + 0x1000) < len)
|
||||||
|
count += 0x1000;
|
||||||
|
else
|
||||||
|
count = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* short packets may only terminate transfers */
|
||||||
|
if (count != len)
|
||||||
|
count -= (count % maxpacket);
|
||||||
|
}
|
||||||
|
qtd->hw_token = cpu_to_hc32( (count << 16) | token);
|
||||||
|
qtd->length = count;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// high bandwidth multiplier, as encoded in highspeed endpoint descriptors
|
||||||
|
#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
|
||||||
|
// ... and packet size, for any kind of endpoint descriptor
|
||||||
|
#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reverse of qh_urb_transaction: free a list of TDs.
|
||||||
|
* also count the actual transfer length.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void qh_end_transfer (void)
|
||||||
|
{
|
||||||
|
struct ehci_qtd *qtd;
|
||||||
|
struct ehci_qh *qh = ehci->asyncqh;
|
||||||
|
u32 token;
|
||||||
|
int error = 0;
|
||||||
|
for(qtd = qh->qtd_head; qtd; qtd = qtd->next){
|
||||||
|
token = hc32_to_cpu( qtd->hw_token);
|
||||||
|
if (likely (QTD_PID (token) != 2))
|
||||||
|
qtd->urb->actual_length += qtd->length - QTD_LENGTH (token);
|
||||||
|
if (!(qtd->length ==0 && ((token & 0xff)==QTD_STS_HALT)) &&
|
||||||
|
(token & QTD_STS_HALT)) {
|
||||||
|
ehci_dbg("\nqtd error!:");
|
||||||
|
if (token & QTD_STS_BABBLE) {
|
||||||
|
ehci_dbg(" BABBLE");
|
||||||
|
}
|
||||||
|
if (token & QTD_STS_MMF) {
|
||||||
|
/* fs/ls interrupt xfer missed the complete-split */
|
||||||
|
ehci_dbg(" missed micro frame");
|
||||||
|
}
|
||||||
|
if (token & QTD_STS_DBE) {
|
||||||
|
ehci_dbg(" databuffer error");
|
||||||
|
}
|
||||||
|
if (token & QTD_STS_XACT) {
|
||||||
|
ehci_dbg(" wrong ack");
|
||||||
|
}
|
||||||
|
if (QTD_CERR (token)==0)
|
||||||
|
ehci_dbg(" toomany errors");
|
||||||
|
ehci_dbg("\n");
|
||||||
|
error = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(error){
|
||||||
|
#ifdef DEBUG
|
||||||
|
verbose = 1;
|
||||||
|
num_command_before_no_verbose=100;
|
||||||
|
#endif
|
||||||
|
//dump_qh(ehci->asyncqh);
|
||||||
|
qtd->urb->actual_length = error;
|
||||||
|
}
|
||||||
|
ehci->qtd_used = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* create a list of filled qtds for this URB; won't link into qh.
|
||||||
|
*/
|
||||||
|
struct ehci_qtd *qh_urb_transaction (
|
||||||
|
struct ehci_urb *urb
|
||||||
|
) {
|
||||||
|
struct ehci_qtd *qtd, *qtd_prev;
|
||||||
|
struct ehci_qtd *head;
|
||||||
|
dma_addr_t buf;
|
||||||
|
int len, maxpacket;
|
||||||
|
int is_input;
|
||||||
|
u32 token;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* URBs map to sequences of QTDs: one logical transaction
|
||||||
|
*/
|
||||||
|
head = qtd = ehci_qtd_alloc ();
|
||||||
|
qtd->urb = urb;
|
||||||
|
|
||||||
|
urb->actual_length = 0;
|
||||||
|
token = QTD_STS_ACTIVE;
|
||||||
|
token |= (EHCI_TUNE_CERR << 10);
|
||||||
|
/* for split transactions, SplitXState initialized to zero */
|
||||||
|
|
||||||
|
len = urb->transfer_buffer_length;
|
||||||
|
is_input = urb->input;
|
||||||
|
if (urb->ep==0) {/* is control */
|
||||||
|
/* SETUP pid */
|
||||||
|
qtd_fill( qtd, urb->setup_dma,
|
||||||
|
sizeof (usbctrlrequest),
|
||||||
|
token | (2 /* "setup" */ << 8), 8);
|
||||||
|
|
||||||
|
/* ... and always at least one more pid */
|
||||||
|
token ^= QTD_TOGGLE;
|
||||||
|
qtd_prev = qtd;
|
||||||
|
qtd = ehci_qtd_alloc ();
|
||||||
|
qtd->urb = urb;
|
||||||
|
qtd_prev->hw_next = QTD_NEXT( qtd->qtd_dma);
|
||||||
|
qtd_prev->next = qtd;
|
||||||
|
|
||||||
|
/* for zero length DATA stages, STATUS is always IN */
|
||||||
|
if (len == 0)
|
||||||
|
token |= (1 /* "in" */ << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* data transfer stage: buffer setup
|
||||||
|
*/
|
||||||
|
buf = urb->transfer_dma;
|
||||||
|
|
||||||
|
if (is_input)
|
||||||
|
token |= (1 /* "in" */ << 8);
|
||||||
|
/* else it's already initted to "out" pid (0 << 8) */
|
||||||
|
|
||||||
|
maxpacket = max_packet(urb->maxpacket);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* buffer gets wrapped in one or more qtds;
|
||||||
|
* last one may be "short" (including zero len)
|
||||||
|
* and may serve as a control status ack
|
||||||
|
*/
|
||||||
|
for (;;) {
|
||||||
|
int this_qtd_len;
|
||||||
|
|
||||||
|
this_qtd_len = qtd_fill( qtd, buf, len, token, maxpacket);
|
||||||
|
len -= this_qtd_len;
|
||||||
|
buf += this_qtd_len;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* short reads advance to a "magic" dummy instead of the next
|
||||||
|
* qtd ... that forces the queue to stop, for manual cleanup.
|
||||||
|
* (this will usually be overridden later.)
|
||||||
|
*/
|
||||||
|
if (is_input)
|
||||||
|
qtd->hw_alt_next = ehci->asyncqh->hw_alt_next;
|
||||||
|
|
||||||
|
/* qh makes control packets use qtd toggle; maybe switch it */
|
||||||
|
if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0)
|
||||||
|
token ^= QTD_TOGGLE;
|
||||||
|
|
||||||
|
if (likely (len <= 0))
|
||||||
|
break;
|
||||||
|
|
||||||
|
qtd_prev = qtd;
|
||||||
|
qtd = ehci_qtd_alloc ();
|
||||||
|
qtd->urb = urb;
|
||||||
|
qtd_prev->hw_next = QTD_NEXT( qtd->qtd_dma);
|
||||||
|
qtd_prev->next = qtd;
|
||||||
|
}
|
||||||
|
|
||||||
|
qtd->hw_alt_next = EHCI_LIST_END();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* control requests may need a terminating data "status" ack;
|
||||||
|
* bulk ones may need a terminating short packet (zero length).
|
||||||
|
*/
|
||||||
|
if (likely (urb->transfer_buffer_length != 0)) {
|
||||||
|
int one_more = 0;
|
||||||
|
|
||||||
|
if (urb->ep==0) {
|
||||||
|
one_more = 1;
|
||||||
|
token ^= 0x0100; /* "in" <--> "out" */
|
||||||
|
token |= QTD_TOGGLE; /* force DATA1 */
|
||||||
|
} else if(!(urb->transfer_buffer_length % maxpacket)) {
|
||||||
|
//one_more = 1;
|
||||||
|
}
|
||||||
|
if (one_more) {
|
||||||
|
qtd_prev = qtd;
|
||||||
|
qtd = ehci_qtd_alloc ();
|
||||||
|
qtd->urb = urb;
|
||||||
|
qtd_prev->hw_next = QTD_NEXT( qtd->qtd_dma);
|
||||||
|
qtd_prev->next = qtd;
|
||||||
|
|
||||||
|
/* never any data in such packets */
|
||||||
|
qtd_fill( qtd, 0, 0, token, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* by default, enable interrupt on urb completion */
|
||||||
|
qtd->hw_token |= cpu_to_hc32( QTD_IOC);
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 usb_timeout=2000*1000;
|
||||||
|
int ehci_do_urb (
|
||||||
|
struct ehci_device *dev,
|
||||||
|
struct ehci_urb *urb)
|
||||||
|
{
|
||||||
|
struct ehci_qh *qh;
|
||||||
|
struct ehci_qtd *qtd;
|
||||||
|
u32 info1 = 0, info2 = 0;
|
||||||
|
int is_input;
|
||||||
|
int maxp = 0;
|
||||||
|
int retval=0;
|
||||||
|
|
||||||
|
//ehci_dbg ("do urb %X %X ep %X\n",urb->setup_buffer,urb->transfer_buffer,urb->ep);
|
||||||
|
if(urb->ep==0) //control message
|
||||||
|
urb->setup_dma = ehci_dma_map_to(urb->setup_buffer,sizeof (usbctrlrequest));
|
||||||
|
|
||||||
|
if(urb->transfer_buffer_length){
|
||||||
|
if(urb->input)
|
||||||
|
urb->transfer_dma = ehci_dma_map_to(urb->transfer_buffer,urb->transfer_buffer_length);
|
||||||
|
else
|
||||||
|
urb->transfer_dma = ehci_dma_map_from(urb->transfer_buffer,urb->transfer_buffer_length);
|
||||||
|
}
|
||||||
|
qh = ehci->asyncqh;
|
||||||
|
memset(qh,0,12*4);
|
||||||
|
qtd = qh_urb_transaction ( urb);
|
||||||
|
qh ->qtd_head = qtd;
|
||||||
|
|
||||||
|
|
||||||
|
info1 |= ((urb->ep)&0xf)<<8;
|
||||||
|
info1 |= dev->id;
|
||||||
|
is_input = urb->input;
|
||||||
|
maxp = urb->maxpacket;
|
||||||
|
|
||||||
|
info1 |= (2 << 12); /* EPS "high" */
|
||||||
|
if(urb->ep==0)// control
|
||||||
|
{
|
||||||
|
info1 |= (EHCI_TUNE_RL_HS << 28);
|
||||||
|
info1 |= 64 << 16; /* usb2 fixed maxpacket */
|
||||||
|
info1 |= 1 << 14; /* toggle from qtd */
|
||||||
|
info2 |= (EHCI_TUNE_MULT_HS << 30);
|
||||||
|
}else//bulk
|
||||||
|
{
|
||||||
|
info1 |= (EHCI_TUNE_RL_HS << 28);
|
||||||
|
/* The USB spec says that high speed bulk endpoints
|
||||||
|
* always use 512 byte maxpacket. But some device
|
||||||
|
* vendors decided to ignore that, and MSFT is happy
|
||||||
|
* to help them do so. So now people expect to use
|
||||||
|
* such nonconformant devices with Linux too; sigh.
|
||||||
|
*/
|
||||||
|
info1 |= max_packet(maxp) << 16;
|
||||||
|
info2 |= (EHCI_TUNE_MULT_HS << 30);
|
||||||
|
|
||||||
|
}
|
||||||
|
//ehci_dbg("HW info: %08X\n",info1);
|
||||||
|
qh->hw_info1 = cpu_to_hc32( info1);
|
||||||
|
qh->hw_info2 = cpu_to_hc32( info2);
|
||||||
|
|
||||||
|
qh->hw_next = QH_NEXT(qh->qh_dma);
|
||||||
|
qh->hw_qtd_next = QTD_NEXT( qtd->qtd_dma);
|
||||||
|
qh->hw_alt_next = EHCI_LIST_END();
|
||||||
|
|
||||||
|
if(urb->ep!=0){
|
||||||
|
if(get_toggle(dev,urb->ep))
|
||||||
|
qh->hw_token |= cpu_to_hc32(QTD_TOGGLE);
|
||||||
|
else
|
||||||
|
qh->hw_token &= ~cpu_to_hc32( QTD_TOGGLE);
|
||||||
|
//ehci_dbg("toggle for ep %x: %d %x\n",urb->ep,get_toggle(dev,urb->ep),qh->hw_token);
|
||||||
|
}
|
||||||
|
|
||||||
|
qh->hw_token &= cpu_to_hc32( QTD_TOGGLE | QTD_STS_PING);
|
||||||
|
|
||||||
|
qh->hw_next = QH_NEXT(ehci->async->qh_dma);
|
||||||
|
|
||||||
|
|
||||||
|
ehci_dma_map_bidir(qh,sizeof(struct ehci_qh));
|
||||||
|
for(qtd = qh->qtd_head; qtd; qtd = qtd->next)
|
||||||
|
ehci_dma_map_bidir(qtd,sizeof(struct ehci_qtd));
|
||||||
|
#if 0
|
||||||
|
if(urb->ep!=0){
|
||||||
|
dump_qh(ehci->async);
|
||||||
|
dump_qh(ehci->asyncqh);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// start (link qh)
|
||||||
|
ehci->async->hw_next = QH_NEXT(qh->qh_dma);
|
||||||
|
ehci_dma_map_bidir(ehci->async,sizeof(struct ehci_qh));
|
||||||
|
|
||||||
|
retval = handshake(&ehci->regs->port_status[dev->port],&ehci->regs->status,STS_INT,STS_INT,usb_timeout);
|
||||||
|
|
||||||
|
//print_hex_dump_bytes ("qh mem",0,(void*)qh,17*4);
|
||||||
|
//retval = poll_transfer_end(1000*1000);
|
||||||
|
ehci_dma_unmap_bidir(ehci->async->qh_dma,sizeof(struct ehci_qh));
|
||||||
|
ehci_dma_unmap_bidir(qh->qh_dma,sizeof(struct ehci_qh));
|
||||||
|
for(qtd = qh->qtd_head; qtd; qtd = qtd->next)
|
||||||
|
ehci_dma_unmap_bidir(qtd->qtd_dma,sizeof(struct ehci_qtd));
|
||||||
|
|
||||||
|
// stop (unlink qh)
|
||||||
|
ehci->async->hw_next = QH_NEXT(ehci->async->qh_dma);
|
||||||
|
ehci_dma_map_bidir(ehci->async,sizeof(struct ehci_qh));
|
||||||
|
ehci_dma_unmap_bidir(ehci->async->qh_dma,sizeof(struct ehci_qh));
|
||||||
|
|
||||||
|
// ack
|
||||||
|
ehci_writel( STS_RECL|STS_IAA|STS_INT, &ehci->regs->status);
|
||||||
|
|
||||||
|
if(urb->ep!=0){
|
||||||
|
set_toggle(dev,urb->ep,(qh->hw_token & cpu_to_hc32(QTD_TOGGLE))?1:0);
|
||||||
|
//ehci_dbg("toggle for ep %x: %d %d %x %X\n",urb->ep,get_toggle(dev,urb->ep),(qh->hw_token & cpu_to_hc32(QTD_TOGGLE)),qh->hw_token,dev->toggles);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(retval>=0)
|
||||||
|
// wait hc really stopped
|
||||||
|
retval = handshake(&ehci->regs->port_status[dev->port],&ehci->regs->async_next,~0,ehci->async->qh_dma,20*1000);
|
||||||
|
//release memory, and actualise urb->actual_length
|
||||||
|
qh_end_transfer();
|
||||||
|
|
||||||
|
|
||||||
|
if(urb->transfer_buffer_length){
|
||||||
|
if(urb->input)
|
||||||
|
ehci_dma_unmap_to(urb->transfer_dma,urb->transfer_buffer_length);
|
||||||
|
else
|
||||||
|
ehci_dma_unmap_from(urb->transfer_dma,urb->transfer_buffer_length);
|
||||||
|
}
|
||||||
|
if(urb->ep==0) //control message
|
||||||
|
ehci_dma_unmap_to(urb->setup_dma,sizeof (usbctrlrequest));
|
||||||
|
if(retval==0){
|
||||||
|
|
||||||
|
return urb->actual_length;
|
||||||
|
|
||||||
|
ehci_dbg ( "un successfull urb %d!!\n", retval);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 ehci_control_message(struct ehci_device *dev,u8 bmRequestType,u8 bmRequest,u16 wValue,u16 wIndex,u32 wLength,void *buf)
|
||||||
|
{
|
||||||
|
struct ehci_urb urb;
|
||||||
|
usbctrlrequest *req = ehci->ctrl_buffer;
|
||||||
|
if(verbose)
|
||||||
|
ehci_dbg ( "control msg: rt%02X r%02X v%04X i%04X s%04x %p\n", bmRequestType, bmRequest, wValue, wIndex,wLength,buf);
|
||||||
|
req->bRequestType = bmRequestType;
|
||||||
|
req->bRequest = bmRequest;
|
||||||
|
req->wValue = swab16(wValue);
|
||||||
|
req->wIndex = swab16(wIndex);
|
||||||
|
req->wLength = swab16(wLength);
|
||||||
|
urb.setup_buffer = req;
|
||||||
|
urb.ep = 0;
|
||||||
|
urb.input = (bmRequestType&USB_CTRLTYPE_DIR_DEVICE2HOST)!=0;
|
||||||
|
urb.maxpacket = 64;
|
||||||
|
urb.transfer_buffer_length = wLength;
|
||||||
|
if (((u32)buf) > 0x13880000){// HW cannot access this buffer, we allow this for convenience
|
||||||
|
int ret;
|
||||||
|
urb.transfer_buffer = USB_Alloc(wLength);
|
||||||
|
if (verbose)
|
||||||
|
ehci_dbg("alloc another buffer %p %p\n",buf,urb.transfer_buffer);
|
||||||
|
memcpy(urb.transfer_buffer,buf,wLength);
|
||||||
|
ret = ehci_do_urb(dev,&urb);
|
||||||
|
memcpy(buf,urb.transfer_buffer,wLength);
|
||||||
|
USB_Free(urb.transfer_buffer);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
urb.transfer_buffer = buf;
|
||||||
|
return ehci_do_urb(dev,&urb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s32 ehci_bulk_message(struct ehci_device *dev,u8 bEndpoint,u32 wLength,void *rpData)
|
||||||
|
{
|
||||||
|
struct ehci_urb urb;
|
||||||
|
s32 ret;
|
||||||
|
urb.setup_buffer = NULL;
|
||||||
|
urb.ep = bEndpoint;
|
||||||
|
urb.input = (bEndpoint&0x80)!=0;
|
||||||
|
urb.maxpacket = 512;
|
||||||
|
urb.maxpacket = 64;
|
||||||
|
urb.transfer_buffer_length = wLength;
|
||||||
|
urb.transfer_buffer = rpData;
|
||||||
|
if(verbose)
|
||||||
|
ehci_dbg ( "bulk msg: ep:%02X size:%02X addr:%04X", bEndpoint, wLength, rpData);
|
||||||
|
ret= ehci_do_urb(dev,&urb);
|
||||||
|
if(verbose)
|
||||||
|
ehci_dbg ( "==>%d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ehci_reset_port(int port)
|
||||||
|
{
|
||||||
|
u32 __iomem *status_reg = &ehci->regs->port_status[port];
|
||||||
|
struct ehci_device *dev = &ehci->devices[port];
|
||||||
|
u32 status = ehci_readl(status_reg);
|
||||||
|
int retval = 0;
|
||||||
|
dev->id = 0;
|
||||||
|
if ((PORT_OWNER&status) || !(PORT_CONNECT&status))
|
||||||
|
{
|
||||||
|
ehci_writel( PORT_OWNER,status_reg);
|
||||||
|
ehci_dbg ( "port %d had no usb2 device connected at startup %X \n", port,ehci_readl(status_reg));
|
||||||
|
return -ENODEV;// no USB2 device connected
|
||||||
|
}
|
||||||
|
char cad[128];
|
||||||
|
char log[1024];
|
||||||
|
ehci_dbg ( "port %d has usb2 device connected! reset it...\n", port);
|
||||||
|
debug_sprintf(cad," status1: %04X\n",status);strcat(log,cad);
|
||||||
|
status &= ~PORT_PE;
|
||||||
|
status |= PORT_RESET;
|
||||||
|
ehci_writel( status,status_reg);
|
||||||
|
msleep(50);// wait 50ms for the reset sequence
|
||||||
|
status=ehci_readl(status_reg);
|
||||||
|
debug_sprintf(cad," status2: %04X\n",status);strcat(log,cad);
|
||||||
|
status &= ~PORT_RESET;
|
||||||
|
ehci_writel( status,status_reg);
|
||||||
|
debug_sprintf(cad," status3: %04X\n",ehci_readl(status_reg));strcat(log,cad);
|
||||||
|
//ehci_writel( ehci_readl(status_reg)& (~PORT_RESET),status_reg);
|
||||||
|
retval = handshake(status_reg, status_reg,
|
||||||
|
PORT_RESET, 0, 750);
|
||||||
|
if (retval != 0) {
|
||||||
|
ehci_dbg ( "port %d reset error %d\n",
|
||||||
|
port, retval);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
status=ehci_readl(status_reg);
|
||||||
|
ehci_dbg ( "port %d reseted status:%04x...\n", port,status);
|
||||||
|
|
||||||
|
debug_sprintf(cad," port reseted status: %04x\n",status);strcat(log,cad);
|
||||||
|
|
||||||
|
if (!(status & PORT_PE)) {
|
||||||
|
// that means is low speed device so release
|
||||||
|
status |= PORT_OWNER;
|
||||||
|
status &= ~PORT_RWC_BITS;
|
||||||
|
ehci_writel( status, status_reg);
|
||||||
|
msleep(10);
|
||||||
|
status = ehci_readl(status_reg);
|
||||||
|
debug_sprintf(cad,"PORT_PE, release USB11 status: %04x\n",status); strcat(log,cad);
|
||||||
|
my_sprint(log,NULL);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
my_sprint(log,NULL);
|
||||||
|
|
||||||
|
msleep(500);
|
||||||
|
// now the device has the default device id
|
||||||
|
retval = ehci_control_message(dev,USB_CTRLTYPE_DIR_DEVICE2HOST,
|
||||||
|
USB_REQ_GETDESCRIPTOR,USB_DT_DEVICE<<8,0,sizeof(dev->desc),&dev->desc);
|
||||||
|
|
||||||
|
if (retval < 0) {
|
||||||
|
ehci_dbg ( "unable to get device desc...\n");
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = ehci_control_message(dev,USB_CTRLTYPE_DIR_HOST2DEVICE,
|
||||||
|
USB_REQ_SETADDRESS,port+1,0,0,0);
|
||||||
|
if (retval < 0) {
|
||||||
|
ehci_dbg ( "unable to set device addr...\n");
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
dev->toggles = 0;
|
||||||
|
|
||||||
|
dev->id = port+1;
|
||||||
|
ehci_dbg ( "device %d: %X %X...\n", dev->id,le16_to_cpu(dev->desc.idVendor),le16_to_cpu(dev->desc.idProduct));
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
int init_port(int port)
|
||||||
|
{
|
||||||
|
int retval=0;
|
||||||
|
struct ehci_device *dev = &ehci->devices[port];
|
||||||
|
dev->id = 0;
|
||||||
|
|
||||||
|
// now the device has the default device id
|
||||||
|
retval = ehci_control_message(dev,USB_CTRLTYPE_DIR_DEVICE2HOST,
|
||||||
|
USB_REQ_GETDESCRIPTOR,USB_DT_DEVICE<<8,0,sizeof(dev->desc),&dev->desc);
|
||||||
|
|
||||||
|
if (retval < 0) {
|
||||||
|
ehci_dbg ( "unable to get device desc...\n");
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = ehci_control_message(dev,USB_CTRLTYPE_DIR_HOST2DEVICE,
|
||||||
|
USB_REQ_SETADDRESS,port+1,0,0,0);
|
||||||
|
if (retval < 0) {
|
||||||
|
ehci_dbg ( "unable to set device addr...\n");
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
dev->toggles = 0;
|
||||||
|
|
||||||
|
dev->id = port+1;
|
||||||
|
ehci_dbg ( "device %d: %X %X...\n", dev->id,le16_to_cpu(dev->desc.idVendor),le16_to_cpu(dev->desc.idProduct));
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
int ehci_reset_port2(int port)
|
||||||
|
{
|
||||||
|
u32 __iomem *status_reg = &ehci->regs->port_status[port];
|
||||||
|
int ret=ehci_reset_port(port);
|
||||||
|
if(ret==-ENODEV)
|
||||||
|
{
|
||||||
|
msleep(2000); // power off 2 second
|
||||||
|
ehci_writel( 0x1001 ,status_reg); // power on
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ehci_reset_device(struct ehci_device *dev)
|
||||||
|
{
|
||||||
|
return ehci_reset_port(dev->port);
|
||||||
|
}
|
||||||
|
#include "usbstorage.h"
|
||||||
|
int ehci_discover(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
// precondition: the ehci should be halted
|
||||||
|
for(i = 0;i<ehci->num_port; i++){
|
||||||
|
struct ehci_device *dev = &ehci->devices[i];
|
||||||
|
dev->port = i;
|
||||||
|
ehci_reset_port(i);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* wii: quickly release non ehci or not connected ports,
|
||||||
|
as we can't kick OHCI drivers laters if we discover a device for them.
|
||||||
|
*/
|
||||||
|
int ehci_release_ports(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
u32 __iomem *status_reg = &ehci->regs->port_status[2];
|
||||||
|
while(ehci_readl(&ehci->regs->port_status[2]) == 0x1000) udelay(100);// wait port 2 to init
|
||||||
|
msleep(100);// wait another msec..
|
||||||
|
for(i = 0;i<ehci->num_port; i++){
|
||||||
|
status_reg = &ehci->regs->port_status[i];
|
||||||
|
u32 status = ehci_readl(status_reg);
|
||||||
|
if (i==2 || !(PORT_CONNECT&status) || PORT_USB11(status))
|
||||||
|
ehci_writel( PORT_OWNER,status_reg); // release port.
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ehci_open_device(int vid,int pid,int fd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=0;i<ehci->num_port;i++)
|
||||||
|
{
|
||||||
|
//ehci_dbg("try device: %d\n",i);
|
||||||
|
if(ehci->devices[i].fd == 0 &&
|
||||||
|
le16_to_cpu(ehci->devices[i].desc.idVendor) == vid &&
|
||||||
|
le16_to_cpu(ehci->devices[i].desc.idProduct) == pid)
|
||||||
|
{
|
||||||
|
//ehci_dbg("found device: %x %x\n",vid,pid);
|
||||||
|
ehci->devices[i].fd = fd;
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -6;
|
||||||
|
}
|
||||||
|
int ehci_close_device(struct ehci_device *dev)
|
||||||
|
{
|
||||||
|
if (dev)
|
||||||
|
dev->fd = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
void * ehci_fd_to_dev(int fd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=0;i<ehci->num_port;i++)
|
||||||
|
{
|
||||||
|
struct ehci_device *dev = &ehci->devices[i];
|
||||||
|
//ehci_dbg ( "device %d:fd:%d %X %X...\n", dev->id,dev->fd,le16_to_cpu(dev->desc.idVendor),le16_to_cpu(dev->desc.idProduct));
|
||||||
|
if(dev->fd == fd){
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ehci_dbg("unkown fd! %d\n",fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#define g_ehci #error
|
||||||
|
int ehci_get_device_list(u8 maxdev,u8 b0,u8*num,u16*buf)
|
||||||
|
{
|
||||||
|
int i,j = 0;
|
||||||
|
for(i=0;i<ehci->num_port && j<maxdev ;i++)
|
||||||
|
{
|
||||||
|
struct ehci_device *dev = &ehci->devices[i];
|
||||||
|
if(dev->id != 0){
|
||||||
|
//ehci_dbg ( "device %d: %X %X...\n", dev->id,le16_to_cpu(dev->desc.idVendor),le16_to_cpu(dev->desc.idProduct));
|
||||||
|
buf[j*4] = 0;
|
||||||
|
buf[j*4+1] = 0;
|
||||||
|
buf[j*4+2] = le16_to_cpu(dev->desc.idVendor);
|
||||||
|
buf[j*4+3] = le16_to_cpu(dev->desc.idProduct);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//ehci_dbg("found %d devices\n",j);
|
||||||
|
*num = j;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#include "usb.c"
|
||||||
|
#include "usbstorage.c"
|
1538
tinyehci/ehci1.c
Normal file
1538
tinyehci/ehci1.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -40,13 +40,41 @@ s32 USB_GetDescriptors(struct ehci_device * fd, usb_devdesc *udd)
|
|||||||
buffer = USB_Alloc(sizeof(*udd));
|
buffer = USB_Alloc(sizeof(*udd));
|
||||||
if(buffer == NULL)
|
if(buffer == NULL)
|
||||||
{
|
{
|
||||||
|
s_printf("buffer == NULL (no mem)\n");
|
||||||
retval = -ENOMEM;
|
retval = -ENOMEM;
|
||||||
goto free_and_error;
|
goto free_and_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ehci_msleep(10);
|
||||||
|
|
||||||
retval = __usb_getdesc(fd, buffer, USB_DT_DEVICE, 0, USB_DT_DEVICE_SIZE);
|
retval = __usb_getdesc(fd, buffer, USB_DT_DEVICE, 0, USB_DT_DEVICE_SIZE);
|
||||||
if(retval < 0)
|
if(retval < 0)
|
||||||
|
{
|
||||||
|
u32 status;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
s_printf("__usb_getdesc error USB_DT_DEVICE: retry\n");
|
||||||
|
|
||||||
|
|
||||||
|
ret=ehci_reset_port(current_port);
|
||||||
|
ehci_msleep(20);
|
||||||
|
status=ehci_readl(&ehci->regs->port_status[current_port]);
|
||||||
|
|
||||||
|
if(ret<0 || (status & 0x3105)!=0x1005)
|
||||||
|
{
|
||||||
|
ret=ehci_reset_port2(current_port);
|
||||||
|
ehci_msleep(20);
|
||||||
|
ehci_readl(&ehci->regs->port_status[current_port]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ehci_msleep(30);
|
||||||
|
retval = __usb_getdesc(fd, buffer, USB_DT_DEVICE, 0, USB_DT_DEVICE_SIZE);
|
||||||
|
if(retval < 0)
|
||||||
|
{
|
||||||
|
s_printf("__usb_getdesc error USB_DT_DEVICE\n");
|
||||||
goto free_and_error;
|
goto free_and_error;
|
||||||
|
}
|
||||||
|
}
|
||||||
memcpy(udd, buffer, USB_DT_DEVICE_SIZE);
|
memcpy(udd, buffer, USB_DT_DEVICE_SIZE);
|
||||||
USB_Free(buffer);
|
USB_Free(buffer);
|
||||||
|
|
||||||
@ -58,6 +86,7 @@ s32 USB_GetDescriptors(struct ehci_device * fd, usb_devdesc *udd)
|
|||||||
udd->configurations = USB_Alloc(udd->bNumConfigurations* sizeof(*udd->configurations));
|
udd->configurations = USB_Alloc(udd->bNumConfigurations* sizeof(*udd->configurations));
|
||||||
if(udd->configurations == NULL)
|
if(udd->configurations == NULL)
|
||||||
{
|
{
|
||||||
|
s_printf("udd->configurations == NULL (no mem)\n");
|
||||||
retval = -ENOMEM;
|
retval = -ENOMEM;
|
||||||
goto free_and_error;
|
goto free_and_error;
|
||||||
}
|
}
|
||||||
@ -67,6 +96,7 @@ s32 USB_GetDescriptors(struct ehci_device * fd, usb_devdesc *udd)
|
|||||||
buffer = USB_Alloc( USB_DT_CONFIG_SIZE);
|
buffer = USB_Alloc( USB_DT_CONFIG_SIZE);
|
||||||
if(buffer == NULL)
|
if(buffer == NULL)
|
||||||
{
|
{
|
||||||
|
s_printf("buffer == NULL (no mem)\n");
|
||||||
retval = -ENOMEM;
|
retval = -ENOMEM;
|
||||||
goto free_and_error;
|
goto free_and_error;
|
||||||
}
|
}
|
||||||
@ -81,13 +111,17 @@ s32 USB_GetDescriptors(struct ehci_device * fd, usb_devdesc *udd)
|
|||||||
buffer = USB_Alloc( ucd->wTotalLength);
|
buffer = USB_Alloc( ucd->wTotalLength);
|
||||||
if(buffer == NULL)
|
if(buffer == NULL)
|
||||||
{
|
{
|
||||||
|
s_printf("buffer == NULL (no mem)\n");
|
||||||
retval = -ENOMEM;
|
retval = -ENOMEM;
|
||||||
goto free_and_error;
|
goto free_and_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = __usb_getdesc(fd, buffer, USB_DT_CONFIG, iConf, ucd->wTotalLength);
|
retval = __usb_getdesc(fd, buffer, USB_DT_CONFIG, iConf, ucd->wTotalLength);
|
||||||
if(retval < 0)
|
if(retval < 0)
|
||||||
|
{
|
||||||
|
s_printf("__usb_getdesc error USB_DT_CONFIG: retry\n");
|
||||||
goto free_and_error;
|
goto free_and_error;
|
||||||
|
}
|
||||||
|
|
||||||
ptr = buffer;
|
ptr = buffer;
|
||||||
ptr += ucd->bLength;
|
ptr += ucd->bLength;
|
||||||
@ -96,7 +130,10 @@ s32 USB_GetDescriptors(struct ehci_device * fd, usb_devdesc *udd)
|
|||||||
retval = -ENOMEM;
|
retval = -ENOMEM;
|
||||||
ucd->interfaces = USB_Alloc(ucd->bNumInterfaces* sizeof(*ucd->interfaces));
|
ucd->interfaces = USB_Alloc(ucd->bNumInterfaces* sizeof(*ucd->interfaces));
|
||||||
if(ucd->interfaces == NULL)
|
if(ucd->interfaces == NULL)
|
||||||
|
{
|
||||||
|
s_printf("ucd->interfaces == NULL (no mem)\n");
|
||||||
goto free_and_error;
|
goto free_and_error;
|
||||||
|
}
|
||||||
memset(ucd->interfaces,0,ucd->bNumInterfaces* sizeof(*ucd->interfaces));
|
memset(ucd->interfaces,0,ucd->bNumInterfaces* sizeof(*ucd->interfaces));
|
||||||
for(iInterface = 0; iInterface < ucd->bNumInterfaces; iInterface++)
|
for(iInterface = 0; iInterface < ucd->bNumInterfaces; iInterface++)
|
||||||
{
|
{
|
||||||
@ -107,7 +144,10 @@ s32 USB_GetDescriptors(struct ehci_device * fd, usb_devdesc *udd)
|
|||||||
|
|
||||||
uid->endpoints = USB_Alloc(uid->bNumEndpoints* sizeof(*uid->endpoints));
|
uid->endpoints = USB_Alloc(uid->bNumEndpoints* sizeof(*uid->endpoints));
|
||||||
if(uid->endpoints == NULL)
|
if(uid->endpoints == NULL)
|
||||||
|
{
|
||||||
|
s_printf("uid->endpoints == NULL (no mem)\n");
|
||||||
goto free_and_error;
|
goto free_and_error;
|
||||||
|
}
|
||||||
memset(uid->endpoints,0,uid->bNumEndpoints* sizeof(*uid->endpoints));
|
memset(uid->endpoints,0,uid->bNumEndpoints* sizeof(*uid->endpoints));
|
||||||
|
|
||||||
// This skips vendor and class specific descriptors
|
// This skips vendor and class specific descriptors
|
||||||
@ -117,7 +157,10 @@ s32 USB_GetDescriptors(struct ehci_device * fd, usb_devdesc *udd)
|
|||||||
{
|
{
|
||||||
uid->extra = USB_Alloc(i);
|
uid->extra = USB_Alloc(i);
|
||||||
if(uid->extra == NULL)
|
if(uid->extra == NULL)
|
||||||
|
{
|
||||||
|
s_printf("uid->extra == NULL (no mem)\n");
|
||||||
goto free_and_error;
|
goto free_and_error;
|
||||||
|
}
|
||||||
memcpy(uid->extra, ptr, i);
|
memcpy(uid->extra, ptr, i);
|
||||||
ptr += i;
|
ptr += i;
|
||||||
size -= i;
|
size -= i;
|
||||||
|
@ -672,7 +672,8 @@ static s32 __usbstorage_clearerrors(usbstorage_handle *dev, u8 lun)
|
|||||||
//retval = __cycle(dev, lun, NULL, 0, cmd, 1, 1, &status, NULL, USBSTORAGE_CYCLE_RETRIES);
|
//retval = __cycle(dev, lun, NULL, 0, cmd, 1, 1, &status, NULL, USBSTORAGE_CYCLE_RETRIES);
|
||||||
|
|
||||||
|
|
||||||
if(retval<0) s_printf(" SCSI_TEST_UNIT_READY ret %i\n", retval);
|
//if(retval<0)
|
||||||
|
s_printf(" SCSI_TEST_UNIT_READY ret %i\n", retval);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1041,8 +1042,8 @@ found:
|
|||||||
|
|
||||||
if(USB_GetConfiguration(dev->usb_fd, &conf) < 0)
|
if(USB_GetConfiguration(dev->usb_fd, &conf) < 0)
|
||||||
{
|
{
|
||||||
s_printf("USB_GetConfiguration() Error\n");
|
s_printf("USB_GetConfiguration() Error. Continue.\n");
|
||||||
goto free_and_return;
|
//goto free_and_return;
|
||||||
}
|
}
|
||||||
s_printf("Actual conf: %x next conf: %x\n",conf, dev->configuration);
|
s_printf("Actual conf: %x next conf: %x\n",conf, dev->configuration);
|
||||||
try_status=-1202;
|
try_status=-1202;
|
||||||
@ -1610,7 +1611,7 @@ s32 USBStorage_Init(void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
try_status=-1;
|
try_status=-100;
|
||||||
unplug_device=1;
|
unplug_device=1;
|
||||||
__mounted=0;
|
__mounted=0;
|
||||||
use_alternative_timeout=1;
|
use_alternative_timeout=1;
|
||||||
@ -1664,6 +1665,7 @@ s_printf("\n***************************************************\nRodries ehcmodu
|
|||||||
if(ret==-1119 || ret==-1120)
|
if(ret==-1119 || ret==-1120)
|
||||||
{
|
{
|
||||||
try_status=ret;
|
try_status=ret;
|
||||||
|
try_status=-100;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ret=ehci_reset_port2(i);
|
ret=ehci_reset_port2(i);
|
||||||
|
Loading…
Reference in New Issue
Block a user