Subversion Repositories freemyipod

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
770 user890104 1
//
2
//
3
//    Copyright 2011 user890104
4
//
5
//
6
//    This file is part of emCORE.
7
//
8
//    emCORE is free software: you can redistribute it and/or
9
//    modify it under the terms of the GNU General Public License as
10
//    published by the Free Software Foundation, either version 2 of the
11
//    License, or (at your option) any later version.
12
//
13
//    emCORE is distributed in the hope that it will be useful,
14
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
//    See the GNU General Public License for more details.
17
//
18
//    You should have received a copy of the GNU General Public License along
19
//    with emCORE.  If not, see <http://www.gnu.org/licenses/>.
20
//
21
//
22
 
23
 
24
#include "global.h"
25
 
26
#include "emcore.h"
27
#include "util.h"
28
#include "usb.h"
29
 
30
 
31
struct emcore_usb_endpoints_addr emcore_usb_eps_addr;
32
struct emcore_usb_endpoints_max_packet_size emcore_usb_eps_mps;
33
 
34
int emcore_cout(const void* data, const uint32_t length)
35
{
36
    return usb_bulk_transfer(emcore_usb_eps_addr.cout, (void*)data, length);
37
}
38
 
39
int emcore_cin(void* data, const uint32_t length)
40
{
41
    return usb_bulk_transfer(emcore_usb_eps_addr.cin, data, length);
42
}
43
 
44
int emcore_dout(const void* data, const uint32_t length)
45
{
46
    return usb_bulk_transfer(emcore_usb_eps_addr.dout, (void*)data, length);
47
}
48
 
49
int emcore_din(void* data, const uint32_t length)
50
{
51
    return usb_bulk_transfer(emcore_usb_eps_addr.din, data, length);
52
}
53
 
54
int emcore_monitor_command(const void* out, void* in,
55
    const uint32_t send_length, const uint32_t receive_length)
56
{
57
    int res;
58
    uint32_t status;
59
 
60
#ifdef DEBUG_USB_PACKETS
61
    fprintf(stderr, "--------------------------------------------\n");
62
    fprintf(stderr, "Sending %d bytes...\n", send_length);
63
 
64
    dump_packet(out, send_length);
65
 
66
#endif
67
    res = emcore_cout(out, send_length);
68
 
69
    if (LIBUSB_SUCCESS != res)
70
    {
71
        return res;
72
    }
73
 
74
    if (in && receive_length)
75
    {
76
#ifdef DEBUG_USB_PACKETS
77
        fprintf(stderr, "Receiving %d bytes...\n", receive_length);
78
 
79
#endif
80
        res = emcore_cin(in, receive_length);
81
 
82
        if (LIBUSB_SUCCESS != res)
83
        {
84
            return res;
85
        }
86
 
87
#ifdef DEBUG_USB_PACKETS
88
        dump_packet(in, receive_length);
89
 
90
#endif
91
        status = *((int *)(in));
92
    }
93
    else
94
    {
95
        status = EMCORE_SUCCESS;
96
    }
97
 
98
#ifdef DEBUG_USB_PACKETS
99
    fprintf(stderr, "--------------------------------------------\n");
100
 
101
#endif
102
    switch (status)
103
    {
104
        case 0:
105
            return EMCORE_ERROR_INVALID;
106
        break;
107
        case 1:
108
            return EMCORE_SUCCESS;
109
        break;
110
        case 2:
111
            return EMCORE_ERROR_NOT_SUPPORTED;
112
        break;
113
        case 3:
114
            return EMCORE_ERROR_BUSY;
115
        break;
116
        default:
117
            return EMCORE_ERROR_INVALID;
118
        break;
119
    }
120
}
121
 
122
int emcore_get_version(struct emcore_dev_info* dev_info)
123
{
124
    int res;
125
    uint32_t out[4] = { 1, 0, 0, 0 }, in[4];
126
 
127
    res = emcore_monitor_command(out, in, 16, 16);
128
 
129
    if (EMCORE_SUCCESS != res)
130
    {
131
        return res;
132
    }
133
 
134
    memcpy(dev_info, &in[1], sizeof(*dev_info));
135
 
136
    return EMCORE_SUCCESS;
137
}
138
 
139
int emcore_get_packet_info(struct emcore_usb_endpoints_max_packet_size* max_packet_size)
140
{
141
    int res;
142
    uint32_t out[4] = { 1, 1, 0, 0 }, in[4];
143
 
144
    res = emcore_monitor_command(out, in, 16, 16);
145
 
146
    if (EMCORE_SUCCESS != res)
147
    {
148
        return res;
149
    }
150
 
151
    memcpy(max_packet_size, &in[1], sizeof(*max_packet_size));
152
 
153
    return EMCORE_SUCCESS;
154
}
155
 
156
int emcore_get_user_mem_range(struct emcore_user_mem_range* mem_range)
157
{
158
    int res;
159
    uint32_t out[4] = { 1, 2, 0, 0 }, in[4];
160
 
161
    res = emcore_monitor_command(out, in, 16, 16);
162
 
163
    if (EMCORE_SUCCESS != res)
164
    {
165
        return res;
166
    }
167
 
168
    memcpy(mem_range, &in[1], sizeof(*mem_range));
169
 
170
    return EMCORE_SUCCESS;
171
}
172
 
173
int emcore_reset(const uint8_t graceful)
174
{
175
    int res;
176
    uint32_t out[4] = { 2, 0xdeadbeef, 0, 0 }, in[4];
177
 
178
    out[1] = graceful;
179
 
180
    res = emcore_monitor_command(out, in, 16, graceful ? 16 : 0);
181
 
182
    if (EMCORE_SUCCESS != res)
183
    {
184
        return res;
185
    }
186
 
187
    return EMCORE_SUCCESS;
188
}
189
 
190
int emcore_poweroff(const uint8_t graceful)
191
{
192
    int res;
193
    uint32_t out[4] = { 3, 0xdeadbeef, 0, 0 }, in[4];
194
 
195
    out[1] = graceful;
196
 
197
    res = emcore_monitor_command(out, in, 16, graceful ? 16 : 0);
198
 
199
    if (EMCORE_SUCCESS != res)
200
    {
201
        return res;
202
    }
203
 
204
    return EMCORE_SUCCESS;
205
}
206
 
207
int emcore_readmem(void* data, const uint32_t addr, const uint32_t size)
208
{
209
    int res;
210
    uint32_t data_length, out[4] = { 4, 0xdeadbeef, 0xdeadbeef, 0 };
211
    void* in;
212
 
213
    out[1] = addr;
214
    out[2] = size;
215
 
216
    if (size + EMCORE_HEADER_SIZE > emcore_usb_eps_mps.cin)
217
    {
218
        return EMCORE_ERROR_OVERFLOW;
219
    }
220
 
221
    data_length = size + EMCORE_HEADER_SIZE;
222
    in = malloc(data_length);
223
 
224
    res = emcore_monitor_command(out, in, 16, data_length);
225
 
226
    if (EMCORE_SUCCESS != res)
227
    {
228
        return res;
229
    }
230
 
231
    memcpy(data, in + EMCORE_HEADER_SIZE, size);
232
 
233
    return EMCORE_SUCCESS;
234
}
235
 
236
int emcore_writemem(const void* data, const uint32_t addr, const uint32_t size)
237
{
238
    int res;
239
    uint32_t data_length, in[4], *out;
240
 
241
    if (size + EMCORE_HEADER_SIZE > emcore_usb_eps_mps.cout)
242
    {
243
        return EMCORE_ERROR_OVERFLOW;
244
    }
245
 
246
    data_length = size + EMCORE_HEADER_SIZE;
247
    out = malloc(data_length);
248
 
249
    *(out) = 5;
250
    *(out + 1) = addr;
251
    *(out + 2) = size;
252
    *(out + 3) = 0;
253
    memcpy(out + 4, data, size);
254
 
255
    res = emcore_monitor_command(out, in, data_length, 16);
256
 
257
    if (EMCORE_SUCCESS != res)
258
    {
259
        return res;
260
    }
261
 
262
    return EMCORE_SUCCESS;
263
}
264
 
265
int emcore_readdma(void* data, const uint32_t addr, const uint32_t size)
266
{
267
    int res;
268
    uint32_t out[4] = { 6, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
269
 
270
    out[1] = addr;
271
    out[2] = size;
272
 
273
    if (size > emcore_usb_eps_mps.din)
274
    {
275
        return EMCORE_ERROR_OVERFLOW;
276
    }
277
 
278
    res = emcore_monitor_command(out, in, 16, 16);
279
 
280
    if (EMCORE_SUCCESS != res)
281
    {
282
        return res;
283
    }
284
 
285
    res = emcore_din(data, size);
286
 
287
    return EMCORE_SUCCESS;
288
}
289
 
290
int emcore_writedma(const void* data, const uint32_t addr, const uint32_t size)
291
{
292
    int res;
293
    uint32_t out[4] = { 7, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
294
 
295
    out[1] = addr;
296
    out[2] = size;
297
 
298
    if (size > emcore_usb_eps_mps.dout)
299
    {
300
        return EMCORE_ERROR_OVERFLOW;
301
    }
302
 
303
    res = emcore_monitor_command(out, in, 16, 16);
304
 
305
    if (EMCORE_SUCCESS != res)
306
    {
307
        return res;
308
    }
309
 
310
    res = emcore_dout(data, size);
311
 
312
    return EMCORE_SUCCESS;
313
}
314
 
315
int emcore_readi2c(void* data, const uint8_t bus, const uint8_t slave, const uint8_t addr, const uint8_t size)
316
{
317
    int res;
318
    uint32_t data_length, out[4] = { 8, 0xdeadbeef, 0, 0 };
319
    void* in;
320
 
321
    out[1] = bus | (slave << 8) | (addr << 16) | (size << 24);
322
 
323
    if (size + EMCORE_HEADER_SIZE > emcore_usb_eps_mps.cin)
324
    {
325
        return EMCORE_ERROR_OVERFLOW;
326
    }
327
 
328
    data_length = 16 + size;
329
    in = malloc(data_length);
330
 
331
    res = emcore_monitor_command(out, in, 16, data_length);
332
 
333
    if (EMCORE_SUCCESS != res)
334
    {
335
        return res;
336
    }
337
 
338
    memcpy(data, in + 16, size);
339
 
340
    return EMCORE_SUCCESS;
341
}
342
 
343
int emcore_writei2c(const void* data, const uint8_t bus, const uint8_t slave, const uint8_t addr, const uint8_t size)
344
{
345
    int res;
346
    uint32_t data_length, in[4], *out;
347
 
348
    if (size + EMCORE_HEADER_SIZE > emcore_usb_eps_mps.cout)
349
    {
350
        return EMCORE_ERROR_OVERFLOW;
351
    }
352
 
353
    data_length = 16 + size;
354
    out = calloc(data_length, 1);
355
 
356
    *(out) = 9; // bytes 0-3
357
    *(out + 4) = bus;
358
    *(out + 5) = slave;
359
    *(out + 6) = addr;
360
    *(out + 7) = size;
361
 
362
    memcpy(out + 16, data, size); // bytes 16+
363
 
364
    res = emcore_monitor_command(out, in, data_length, 16);
365
 
366
    if (EMCORE_SUCCESS != res)
367
    {
368
        return res;
369
    }
370
 
371
    return EMCORE_SUCCESS;
372
}
373
 
374
int emcore_file_open(uint32_t* handle, const char* path, const int flags)
375
{
376
    int res;
377
    uint32_t str_length, data_length, in[4], *out;
378
 
379
    *handle = 0;
380
 
381
    str_length = strlen(path);
382
    data_length = str_length + 1 + EMCORE_HEADER_SIZE;
383
 
384
    if (data_length > emcore_usb_eps_mps.cout)
385
    {
386
        return EMCORE_ERROR_OVERFLOW;
387
    }
388
 
389
    out = calloc(sizeof(char), data_length);
390
 
391
    *(out) = 30;
392
    *(out + 1) = flags;
393
 
394
    strncpy(((char*)(out + 4)), path, str_length);
395
 
396
    res = emcore_monitor_command(out, in, data_length, 16);
397
 
398
    if (EMCORE_SUCCESS != res)
399
    {
400
        return res;
401
    }
402
 
403
    if (in[1] > 0x80000000)
404
    {
405
        return EMCORE_ERROR_IO;
406
    }
407
 
408
    *handle = in[1];
409
 
410
    return EMCORE_SUCCESS;
411
}
412
 
413
int emcore_file_size(uint32_t* size, const uint32_t handle)
414
{
415
    int res;
416
    uint32_t out[4] = { 31, 0xdeadbeef, 0, 0 }, in[4];
417
 
418
    out[1] = handle;
419
 
420
    res = emcore_monitor_command(out, in, 16, 16);
421
 
422
    if (EMCORE_SUCCESS != res)
423
    {
424
        return res;
425
    }
426
 
427
    if (in[1] > 0x80000000)
428
    {
429
        return EMCORE_ERROR_IO;
430
    }
431
 
432
    *size = in[1];
433
 
434
    return EMCORE_SUCCESS;
435
}
436
 
437
int emcore_file_read(uint32_t* nread, const uint32_t handle, const uint32_t addr, const uint32_t size)
438
{
439
    int res;
440
    uint32_t out[4] = { 32, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }, in[4];
441
 
442
    out[1] = handle;
443
    out[2] = addr;
444
    out[3] = size;
445
 
446
    res = emcore_monitor_command(out, in, 16, 16);
447
 
448
    if (EMCORE_SUCCESS != res)
449
    {
450
        return res;
451
    }
452
 
453
    if (in[1] > 0x80000000)
454
    {
455
        return EMCORE_ERROR_IO;
456
    }
457
 
458
    *nread = in[1];
459
 
460
    return EMCORE_SUCCESS;
461
}
462
 
463
int emcore_file_write(const uint32_t handle, const uint32_t addr, const uint32_t size)
464
{
465
    int res;
466
    uint32_t out[4] = { 33, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }, in[4];
467
 
468
    out[1] = handle;
469
    out[2] = addr;
470
    out[3] = size;
471
 
472
    res = emcore_monitor_command(out, in, 16, 16);
473
 
474
    if (EMCORE_SUCCESS != res)
475
    {
476
        return res;
477
    }
478
 
479
    if (in[1] > 0x80000000)
480
    {
481
        return EMCORE_ERROR_IO;
482
    }
483
 
484
    return EMCORE_SUCCESS;
485
}
486
 
487
int emcore_file_seek(const uint32_t handle, const uint32_t offset, const uint32_t whence)
488
{
489
    int res;
490
    uint32_t out[4] = { 34, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }, in[4];
491
 
492
    out[1] = handle;
493
    out[2] = offset;
494
    out[3] = whence;
495
 
496
    res = emcore_monitor_command(out, in, 16, 16);
497
 
498
    if (EMCORE_SUCCESS != res)
499
    {
500
        return res;
501
    }
502
 
503
    if (in[1] > 0x80000000)
504
    {
505
        return EMCORE_ERROR_IO;
506
    }
507
 
508
    return EMCORE_SUCCESS;
509
}
510
 
511
int emcore_file_truncate(const uint32_t handle, const uint32_t length)
512
{
513
    int res;
514
    uint32_t out[4] = { 35, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
515
 
516
    out[1] = handle;
517
    out[2] = length;
518
 
519
    res = emcore_monitor_command(out, in, 16, 16);
520
 
521
    if (EMCORE_SUCCESS != res)
522
    {
523
        return res;
524
    }
525
 
526
    if (in[1] > 0x80000000)
527
    {
528
        return EMCORE_ERROR_IO;
529
    }
530
 
531
    return EMCORE_SUCCESS;
532
}
533
 
534
int emcore_file_sync(const uint32_t handle)
535
{
536
    int res;
537
    uint32_t out[4] = { 36, 0xdeadbeef, 0, 0 }, in[4];
538
 
539
    out[1] = handle;
540
 
541
    res = emcore_monitor_command(out, in, 16, 16);
542
 
543
    if (EMCORE_SUCCESS != res)
544
    {
545
        return res;
546
    }
547
 
548
    if (in[1] > 0x80000000)
549
    {
550
        return EMCORE_ERROR_IO;
551
    }
552
 
553
    return EMCORE_SUCCESS;
554
}
555
 
556
int emcore_file_close(const uint32_t handle)
557
{
558
    int res;
559
    uint32_t out[4] = { 37, 0xdeadbeef, 0, 0 }, in[4];
560
 
561
    out[1] = handle;
562
 
563
    res = emcore_monitor_command(out, in, 16, 16);
564
 
565
    if (EMCORE_SUCCESS != res)
566
    {
567
        return res;
568
    }
569
 
570
    if (in[1] > 0x80000000)
571
    {
572
        return EMCORE_ERROR_IO;
573
    }
574
 
575
    return EMCORE_SUCCESS;
576
}
577
 
578
int emcore_file_close_all(uint32_t* count)
579
{
580
    int res;
581
    uint32_t out[4] = { 38, 0, 0, 0 }, in[4];
582
 
583
    res = emcore_monitor_command(out, in, 16, 16);
584
 
585
    if (EMCORE_SUCCESS != res)
586
    {
587
        return res;
588
    }
589
 
590
    if (in[1] > 0x80000000)
591
    {
592
        return EMCORE_ERROR_IO;
593
    }
594
 
595
    *count = in[1];
596
 
597
    return EMCORE_SUCCESS;
598
}
599
 
600
int emcore_file_kill_all(const uint32_t volume)
601
{
602
    int res;
603
    uint32_t out[4] = { 39, 0xdeadbeef, 0, 0 }, in[4];
604
 
605
    out[1] = volume;
606
 
607
    res = emcore_monitor_command(out, in, 16, 16);
608
 
609
    if (EMCORE_SUCCESS != res)
610
    {
611
        return res;
612
    }
613
 
614
    if (in[1] > 0x80000000)
615
    {
616
        return EMCORE_ERROR_IO;
617
    }
618
 
619
    return EMCORE_SUCCESS;
620
}
621
 
622
int emcore_file_unlink(const char* name)
623
{
624
    int res;
625
    uint32_t str_length, data_length, in[4], *out;
626
 
627
    str_length = strlen(name);
628
    data_length = str_length + 1 + EMCORE_HEADER_SIZE;
629
 
630
    if (data_length > emcore_usb_eps_mps.cout)
631
    {
632
        return EMCORE_ERROR_OVERFLOW;
633
    }
634
 
635
    out = calloc(sizeof(char), data_length);
636
 
637
    *(out) = 40;
638
 
639
    strncpy(((char*)(out + 4)), name, str_length);
640
 
641
    res = emcore_monitor_command(out, in, data_length, 16);
642
 
643
    if (EMCORE_SUCCESS != res)
644
    {
645
        return res;
646
    }
647
 
648
    if (in[1] > 0x80000000)
649
    {
650
        return EMCORE_ERROR_IO;
651
    }
652
 
653
    return EMCORE_SUCCESS;
654
}
655
 
656
int emcore_file_rename(const char* path, const char* newpath)
657
{
658
    int res;
659
    uint32_t str_length, data_length, in[4], *out;
660
 
661
    if (strlen(path) > 247)
662
    {
663
        return EMCORE_ERROR_OVERFLOW;
664
    }
665
 
666
    str_length = MIN(247, strlen(newpath));
667
    data_length = str_length + 1 + 248 + EMCORE_HEADER_SIZE;
668
 
669
    if (data_length > emcore_usb_eps_mps.cout)
670
    {
671
        return EMCORE_ERROR_OVERFLOW;
672
    }
673
 
674
    out = calloc(sizeof(char), data_length);
675
 
676
    *(out) = 41;
677
 
678
    strncpy(((char*)(out + 4)), path, strlen(path));
679
    strncpy(((char*)(out) + 248), newpath, str_length);
680
 
681
    res = emcore_monitor_command(out, in, data_length, 16);
682
 
683
    if (EMCORE_SUCCESS != res)
684
    {
685
        return res;
686
    }
687
 
688
    if (in[1] > 0x80000000)
689
    {
690
        return EMCORE_ERROR_IO;
691
    }
692
 
693
    return EMCORE_SUCCESS;
694
}
695
 
696
int emcore_dir_open(uint32_t* handle, const char* name)
697
{
698
    int res;
699
    size_t name_length;
700
    uint32_t data_length, in[4], *out;
701
 
702
    name_length = strlen(name);
703
    data_length = name_length + 1 + EMCORE_HEADER_SIZE;
704
    out = calloc(data_length, 1);
705
 
706
    *out = 42;
707
    strncpy(((char*)(out + 4)), name, name_length + 1);
708
 
709
    res = emcore_monitor_command(out, in, data_length, 16);
710
 
711
    if (EMCORE_SUCCESS != res)
712
    {
713
        return res;
714
    }
715
 
716
    *handle = in[1];
717
 
718
    return EMCORE_SUCCESS;
719
}
720
 
721
int emcore_dir_read(struct emcore_dir_entry* entry, const uint32_t handle)
722
{
723
    int res;
724
    uint32_t maxpath, ptr, dirent_size, emcore_errno_value, filename_buf_len,
725
        out[4] = { 43, 0xdeadbeef, 0, 0 }, in[4];
726
    void *buf;
727
 
728
    memset(entry, 0, sizeof(*entry));
729
 
730
    out[1] = handle;
731
 
732
    res = emcore_monitor_command(out, in, 16, 16);
733
 
734
    if (EMCORE_SUCCESS != res)
735
    {
736
        return res;
737
    }
738
 
739
    ptr = in[3];
740
 
741
    if (0 == ptr)
742
    {
743
        res = emcore_errno(&emcore_errno_value);
744
 
745
        if (EMCORE_SUCCESS != res)
746
        {
747
            return res;
748
        }
749
 
750
        if (EMCORE_SUCCESS != emcore_errno_value)
751
        {
752
            return EMCORE_ERROR_IO;
753
        }
754
 
755
        return EMCORE_ERROR_NO_MORE_ENTRIES;
756
    }
757
 
758
    if (1 != in[1]) // version
759
    {
760
        return EMCORE_ERROR_NOT_IMPLEMENTED;
761
    }
762
 
763
    maxpath = in[2];
764
 
765
    dirent_size = maxpath + 16;
766
 
767
    buf = malloc(dirent_size);
768
 
769
    res = emcore_read(buf, ptr, dirent_size);
770
 
771
    if (EMCORE_SUCCESS != res)
772
    {
773
        return res;
774
    }
775
 
776
    filename_buf_len = strlen((char*)buf) + 1;
777
 
778
    entry->name = malloc(filename_buf_len);
779
    strncpy(entry->name, buf, filename_buf_len);
780
    memcpy(&entry->attributes, buf + maxpath, 16);
781
 
782
#ifdef DEBUG_DIR_ENTRIES
783
    fprintf(stderr, "Read directory entry: %s\n", entry->name);
784
    fprintf(stderr, "Attributes: 0x%08x\n", entry->attributes);
785
    fprintf(stderr, "Size: %d\n", entry->size);
786
    fprintf(stderr, "Start cluster: %d\n", entry->startcluster);
787
    fprintf(stderr, "Last written date: 0x%04x\n", entry->wrtdate);
788
    fprintf(stderr, "Last written time: 0x%04x\n", entry->wrttime);
789
    fprintf(stderr, "Last written TS: %lu\n",
790
        (unsigned long) fat_time_to_unix_ts(entry->wrttime, entry->wrtdate));
791
#endif
792
    return EMCORE_SUCCESS;
793
}
794
 
795
int emcore_dir_close(const uint32_t handle)
796
{
797
    int res;
798
    uint32_t out[4] = { 44, 0xdeadbeef, 0, 0 }, in[4];
799
 
800
    out[1] = handle;
801
 
802
    res = emcore_monitor_command(out, in, 16, 16);
803
 
804
    if (EMCORE_SUCCESS != res)
805
    {
806
        return res;
807
    }
808
 
809
    if (in[1] > 0x80000000)
810
    {
811
        return EMCORE_ERROR_IO;
812
    }
813
 
814
    return EMCORE_SUCCESS;
815
}
816
 
817
int emcore_dir_close_all(uint32_t* count)
818
{
819
    int res;
820
    uint32_t out[4] = { 45, 0, 0, 0 }, in[4];
821
 
822
    res = emcore_monitor_command(out, in, 16, 16);
823
 
824
    if (EMCORE_SUCCESS != res)
825
    {
826
        return res;
827
    }
828
 
829
    if (in[1] > 0x80000000)
830
    {
831
        return EMCORE_ERROR_IO;
832
    }
833
 
834
    *count = in[1];
835
 
836
    return EMCORE_SUCCESS;
837
}
838
 
839
int emcore_errno(uint32_t* emcore_errno_value)
840
{
841
    int res;
842
    uint32_t out[4] = { 49, 0, 0, 0 }, in[4];
843
 
844
    res = emcore_monitor_command(out, in, 16, 16);
845
 
846
    if (EMCORE_SUCCESS != res)
847
    {
848
        return res;
849
    }
850
 
851
    *emcore_errno_value = in[1];
852
 
853
    return EMCORE_SUCCESS;
854
}
855
 
856
int emcore_malloc(uint32_t* ptr, const uint32_t size)
857
{
858
    int res;
859
    uint32_t out[4] = { 52, 0xdeadbeef, 0, 0 }, in[4];
860
 
861
    out[1] = size;
862
 
863
    res = emcore_monitor_command(out, in, 16, 16);
864
 
865
    if (EMCORE_SUCCESS != res)
866
    {
867
        return res;
868
    }
869
 
870
    *ptr = in[1];
871
 
872
    return EMCORE_SUCCESS;
873
}
874
 
875
int emcore_memalign(uint32_t* ptr, const uint32_t align, const uint32_t size)
876
{
877
    int res;
878
    uint32_t out[4] = { 53, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
879
 
880
    out[1] = align;
881
    out[2] = size;
882
 
883
    res = emcore_monitor_command(out, in, 16, 16);
884
 
885
    if (EMCORE_SUCCESS != res)
886
    {
887
        return res;
888
    }
889
 
890
    *ptr = in[1];
891
 
892
    return EMCORE_SUCCESS;
893
}
894
 
895
int emcore_realloc(uint32_t* new_ptr, const uint32_t ptr, const uint32_t size)
896
{
897
    int res;
898
    uint32_t out[4] = { 54, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
899
 
900
    out[1] = ptr;
901
    out[2] = size;
902
 
903
    res = emcore_monitor_command(out, in, 16, 16);
904
 
905
    if (EMCORE_SUCCESS != res)
906
    {
907
        return res;
908
    }
909
 
910
    *new_ptr = in[1];
911
 
912
    return EMCORE_SUCCESS;
913
}
914
 
915
int emcore_reownalloc(const uint32_t ptr, const uint32_t owner)
916
{
917
    uint32_t out[4] = { 55, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
918
 
919
    out[1] = ptr;
920
    out[2] = owner;
921
 
922
    return emcore_monitor_command(out, in, 16, 16);
923
}
924
 
925
int emcore_free(const uint32_t ptr)
926
{
927
    uint32_t out[4] = { 56, 0xdeadbeef, 0, 0 }, in[4];
928
 
929
    out[1] = ptr;
930
 
931
    return emcore_monitor_command(out, in, 16, 16);
932
}
933
 
934
int emcore_free_all(void)
935
{
936
    uint32_t out[4] = { 57, 0, 0, 0 }, in[4];
937
 
938
    return emcore_monitor_command(out, in, 16, 16);
939
}
940
 
941
int emcore_read(void* data, const uint32_t addr, const uint32_t size)
942
{
943
    int res;
944
    struct alignsizes* sizes;
945
    uint32_t cin_maxsize, readsize, curraddr;
946
 
947
    cin_maxsize = emcore_usb_eps_mps.cin - EMCORE_HEADER_SIZE;
948
    sizes = malloc(sizeof(*sizes));
949
 
950
    alignsplit(sizes, addr, size, cin_maxsize, 16);
951
#ifdef DEBUG_ALIGN_SPLIT
952
    fprintf(stderr, "Downloading %d bytes from 0x%08x, split as (%d/%d/%d)\n",
953
        size, addr, sizes->head, sizes->body, sizes->tail);
954
 
955
#endif
956
    curraddr = addr;
957
 
958
    if (sizes->head > 0)
959
    {
960
        res = emcore_readmem(data, curraddr, sizes->head);
961
 
962
        if (EMCORE_SUCCESS != res)
963
        {
964
            return res;
965
        }
966
 
967
        data += sizes->head;
968
        curraddr += sizes->head;
969
    }
970
 
971
    while (sizes->body > 0)
972
    {
973
        if (sizes->body >= cin_maxsize * 2)
974
        {
975
            readsize = MIN(sizes->body, emcore_usb_eps_mps.din);
976
            res = emcore_readdma(data, curraddr, readsize);
977
        }
978
        else
979
        {
980
            readsize = MIN(sizes->body, cin_maxsize);
981
            res = emcore_readmem(data, curraddr, readsize);
982
        }
983
 
984
        if (EMCORE_SUCCESS != res)
985
        {
986
            return res;
987
        }
988
 
989
        data += readsize;
990
        curraddr += readsize;
991
        sizes->body -= readsize;
992
    }
993
 
994
    if (sizes->tail > 0)
995
    {
996
        res = emcore_readmem(data, curraddr, sizes->tail);
997
 
998
        if (EMCORE_SUCCESS != res)
999
        {
1000
            return res;
1001
        }
1002
 
1003
        data += sizes->tail;
1004
    }
1005
 
1006
    return EMCORE_SUCCESS;
1007
}
1008
 
1009
int emcore_write(const void* data, const uint32_t addr, const uint32_t size)
1010
{
1011
    int res;
1012
    struct alignsizes* sizes;
1013
    uint32_t cout_maxsize, writesize, curraddr;
1014
 
1015
    cout_maxsize = emcore_usb_eps_mps.cout - 16;
1016
    sizes = malloc(sizeof(*sizes));
1017
 
1018
    alignsplit(sizes, addr, size, cout_maxsize, 16);
1019
#ifdef DEBUG_ALIGN_SPLIT
1020
    fprintf(stderr, "Uploading %d bytes from 0x%08x, split as (%d/%d/%d)\n",
1021
        size, addr, sizes->head, sizes->body, sizes->tail);
1022
 
1023
#endif
1024
    curraddr = addr;
1025
 
1026
    if (sizes->head > 0)
1027
    {
1028
        res = emcore_writemem(data, curraddr, sizes->head);
1029
 
1030
        if (EMCORE_SUCCESS != res)
1031
        {
1032
            return res;
1033
        }
1034
 
1035
        data += sizes->head;
1036
        curraddr += sizes->head;
1037
    }
1038
 
1039
    while (sizes->body > 0)
1040
    {
1041
        if (sizes->body >= 2 * cout_maxsize)
1042
        {
1043
            writesize = MIN(sizes->body, emcore_usb_eps_mps.dout);
1044
            res = emcore_writedma(data, curraddr, writesize);
1045
        }
1046
        else
1047
        {
1048
            writesize = MIN(sizes->body, cout_maxsize);
1049
            res = emcore_writemem(data, curraddr, writesize);
1050
        }
1051
 
1052
        if (EMCORE_SUCCESS != res)
1053
        {
1054
            return res;
1055
        }
1056
 
1057
        data += writesize;
1058
        curraddr += writesize;
1059
        sizes->body -= writesize;
1060
    }
1061
 
1062
    if (sizes->tail > 0)
1063
    {
1064
        res = emcore_writemem(data, curraddr, sizes->tail);
1065
 
1066
        if (EMCORE_SUCCESS != res)
1067
        {
1068
            return res;
1069
        }
1070
 
1071
        data += sizes->tail;
1072
    }
1073
 
1074
    return EMCORE_SUCCESS;
1075
}
1076
 
1077
int emcore_ls(const uint32_t handle)
1078
{
1079
    int res = 0;
1080
    struct emcore_dir_entry entry;
1081
 
1082
    while (1)
1083
    {
1084
        res = emcore_dir_read(&entry, handle);
1085
 
1086
        if (EMCORE_ERROR_NO_MORE_ENTRIES == res)
1087
        {
1088
            res = EMCORE_SUCCESS;
1089
            break;
1090
        }
1091
 
1092
        if (EMCORE_SUCCESS != res)
1093
        {
1094
            return res;
1095
        }
1096
 
1097
#ifdef DEBUG_DIR_ENTRIES
1098
        fprintf(stderr, "Read directory entry:\n");
1099
        fprintf(stderr, "Name: %s\n", entry.name);
1100
        fprintf(stderr, "Attributes: 0x%08x\n", entry.attributes);
1101
        fprintf(stderr, "Size: %d\n", entry.size);
1102
        fprintf(stderr, "Start cluster: %d\n", entry.startcluster);
1103
        fprintf(stderr, "Last written date: 0x%04x\n", entry.wrtdate);
1104
        fprintf(stderr, "Last written time: 0x%04x\n", entry.wrttime);
1105
        fprintf(stderr, "Last written TS: %lu\n",
1106
            (unsigned long) fat_time_to_unix_ts(entry.wrttime, entry.wrtdate));
1107
#endif
1108
        if (entry.attributes & 0x10)
1109
        {
1110
            printf("     [DIR]");
1111
        }
1112
        else
1113
        {
1114
            printf("%10d", entry.size);
1115
        }
1116
 
1117
        printf(" %s\n", entry.name);
1118
    }
1119
 
1120
    return res;
1121
}
1122
 
1123
int emcore_test(void)
1124
{
1125
    int res;
1126
 
1127
    /* emcore_get_version */
1128
    struct emcore_dev_info dev_info;
1129
    char *hw_type;
1130
 
1131
    /* emcore_get_packet_info */
1132
    struct emcore_usb_endpoints_max_packet_size max_packet_size;
1133
 
1134
    /* emcore_get_user_mem_range */
1135
    struct emcore_user_mem_range mem_range;
1136
 
1137
    /* emcore_readmem */
1138
    void* buf;
1139
    uint16_t buf_size;
1140
    uint32_t read_addr;
1141
 
1142
    /* emcore_readi2c */
1143
    /* uint8_t i2cdata; */
1144
 
1145
    /* emcore_dir_open */
1146
    uint32_t dir_handle;
1147
 
1148
    /* emcore_dir_close_all */
1149
    uint32_t count;
1150
 
1151
    res = emcore_get_version(&dev_info);
1152
 
1153
    if (EMCORE_SUCCESS != res)
1154
    {
1155
        return res;
1156
    }
1157
 
1158
    hw_type = malloc(5);
1159
 
1160
    strncpy(hw_type, ((char*)&dev_info.hw_type), 4);
1161
 
1162
    printf("Connected to %4s running %s v%d.%d.%d r%d\n",
1163
        hw_type, (1 == dev_info.sw_type ? "emBIOS" : (2 == dev_info.sw_type ? "emCORE" : "UNKNOWN")),
1164
        dev_info.major, dev_info.minor, dev_info.patch, dev_info.svn_revision
1165
    );
1166
 
1167
    free(hw_type);
1168
 
1169
    res = emcore_get_packet_info(&max_packet_size);
1170
 
1171
    if (EMCORE_SUCCESS != res)
1172
    {
1173
        return res;
1174
    }
1175
 
1176
    printf("COUT max pckt: %d, CIN max pckt: %d, DOUT max pckt: %d, DIN max pckt: %d\n",
1177
        max_packet_size.cout, max_packet_size.cin, max_packet_size.dout, max_packet_size.din
1178
    );
1179
 
1180
    res = emcore_get_user_mem_range(&mem_range);
1181
 
1182
    if (EMCORE_SUCCESS != res)
1183
    {
1184
        return res;
1185
    }
1186
 
1187
    printf("User mem range: 0x%08x - 0x%08x\n", mem_range.lower, mem_range.upper);
1188
 
1189
    read_addr = 0x09000000;
1190
    buf_size = 0x1000;
1191
    buf = malloc(buf_size);
1192
 
1193
    printf("Reading 0x%08x bytes from 0x%08x\n", buf_size, read_addr);
1194
 
1195
    res = emcore_read(buf, read_addr, buf_size);
1196
 
1197
    if (EMCORE_SUCCESS != res)
1198
    {
1199
        return res;
1200
    }
1201
 
1202
#ifdef DEBUG
1203
    dump_packet(buf, buf_size);
1204
 
1205
#endif
1206
    printf("Writing 0x%08x bytes to 0x%08x\n", buf_size, read_addr);
1207
 
1208
    res = emcore_write(buf, read_addr, buf_size);
1209
 
1210
    if (EMCORE_SUCCESS != res)
1211
    {
1212
        return res;
1213
    }
1214
 
1215
    free(buf);
1216
 
1217
    /*
1218
    printf("Reading 1 byte from I2C\n");
1219
 
1220
    res = emcore_readi2c(&i2cdata, 0, 0xe6, 0x29, 1);
1221
 
1222
    if (EMCORE_SUCCESS != res)
1223
    {
1224
        return res;
1225
    }
1226
 
1227
#ifdef DEBUG
1228
    dump_packet(&i2cdata, 1);
1229
 
1230
#endif
1231
    */
1232
    /* nano2g - turns on/off the backlight */
1233
    /*
1234
    i2cdata = 1;
1235
 
1236
    printf("Writing 1 byte to I2C\n");
1237
 
1238
    res = emcore_writei2c(&i2cdata, 0, 0xe6, 0x29, 1);
1239
 
1240
    if (EMCORE_SUCCESS != res)
1241
    {
1242
        return res;
1243
    }
1244
 
1245
    sleep(1);
1246
 
1247
    i2cdata = 0;
1248
 
1249
    printf("Writing 1 byte to I2C\n");
1250
 
1251
    res = emcore_writei2c(&i2cdata, 0, 0xe6, 0x29, 1);
1252
 
1253
    if (EMCORE_SUCCESS != res)
1254
    {
1255
        return res;
1256
    }
1257
    */
1258
    res = emcore_dir_open(&dir_handle, "/");
1259
 
1260
    if (EMCORE_SUCCESS != res)
1261
    {
1262
        return res;
1263
    }
1264
 
1265
    printf("Opened dir handle: 0x%08x\n", dir_handle);
1266
 
1267
    res = emcore_ls(dir_handle);
1268
 
1269
    if (EMCORE_SUCCESS != res)
1270
    {
1271
        return res;
1272
    }
1273
 
1274
    printf("Listed dir handle: 0x%08x\n", dir_handle);
1275
 
1276
    res = emcore_dir_close(dir_handle);
1277
 
1278
    if (EMCORE_SUCCESS != res)
1279
    {
1280
        return res;
1281
    }
1282
 
1283
    printf("Closed dir handle 0x%08x\n", dir_handle);
1284
 
1285
    res = emcore_dir_close_all(&count);
1286
 
1287
    if (EMCORE_SUCCESS != res)
1288
    {
1289
        return res;
1290
    }
1291
 
1292
    printf("Closed %d dir handles\n", count);
1293
    /* powers off the device - graceful
1294
    res = emcore_poweroff(1);
1295
 
1296
    if (EMCORE_SUCCESS != res)
1297
    {
1298
        return res;
1299
    }
1300
 
1301
    printf("Device powered off successfully!\n");
1302
    */
1303
    return EMCORE_SUCCESS;
1304
}