Subversion Repositories freemyipod

Rev

Rev 913 | Rev 918 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 913 Rev 914
Line 1... Line 1...
1
//
1
//
2
//
2
//
3
//    Copyright 2013 TheSeven
3
//    Copyright 2013 TheSeven
-
 
4
//    Copyright 2014 user890104
4
//
5
//
5
//
6
//
6
//    This file is part of emCORE.
7
//    This file is part of emCORE.
7
//
8
//
8
//    emCORE is free software: you can redistribute it and/or
9
//    emCORE is free software: you can redistribute it and/or
Line 60... Line 61...
60
#define DEVICE_REMOVABLE            0x80
61
#define DEVICE_REMOVABLE            0x80
61
 
62
 
62
#define SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA 0x02000000
63
#define SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA 0x02000000
63
 
64
 
64
 
65
 
65
#define RAMDISK_SECTORSIZE 512
66
struct storage_info storage_info;
66
#define RAMDISK_SECTORS 2048
-
 
67
 
67
 
-
 
68
enum storage_operation {
-
 
69
    OP_READ,
-
 
70
    OP_WRITE
-
 
71
} pending_op;
-
 
72
 
-
 
73
unsigned long pending_op_start;
-
 
74
int pending_op_count;
-
 
75
 
-
 
76
struct wakeup pending_op_wakeup;
68
 
77
 
69
static const struct usb_devicedescriptor usb_devicedescriptor =
78
static const struct usb_devicedescriptor usb_devicedescriptor =
70
{
79
{
71
    .bLength = sizeof(struct usb_devicedescriptor),
80
    .bLength = sizeof(struct usb_devicedescriptor),
72
    .bDescriptorType = USB_DESCRIPTOR_TYPE_DEVICE,
81
    .bDescriptorType = USB_DESCRIPTOR_TYPE_DEVICE,
Line 149... Line 158...
149
    .wString = { 'f', 'r', 'e', 'e', 'm', 'y', 'i', 'p', 'o', 'd', '.', 'o', 'r', 'g' },
158
    .wString = { 'f', 'r', 'e', 'e', 'm', 'y', 'i', 'p', 'o', 'd', '.', 'o', 'r', 'g' },
150
};
159
};
151
 
160
 
152
static const struct usb_stringdescriptor usb_string_product =
161
static const struct usb_stringdescriptor usb_string_product =
153
{
162
{
154
    .bLength = sizeof(usb_string_product) + sizeof(*usb_string_product.wString) * 28,
163
    .bLength = sizeof(usb_string_product) + sizeof(*usb_string_product.wString) * 16,
155
    .bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
164
    .bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
156
    .wString = { 'e', 'm', 'C', 'O', 'R', 'E', ' ', 'U', 'S', 'B', ' ', 'm', 'a', 's', 's', ' ', 's', 't', 'o', 'r', 'a', 'g', 'e', ' ', 't', 'e', 's', 't' },
165
    .wString = { 'e', 'm', 'C', 'O', 'R', 'E', ' ', 'D', 'i', 's', 'k', ' ', 'm', 'o', 'd', 'e' },
157
};
166
};
158
 
167
 
159
static const struct usb_stringdescriptor* usb_stringdescriptors[] =
168
static const struct usb_stringdescriptor* usb_stringdescriptors[] =
160
{
169
{
161
    &usb_string_language,
170
    &usb_string_language,
Line 315... Line 324...
315
static int maxlen;
324
static int maxlen;
316
static int length;
325
static int length;
317
static bool locked;
326
static bool locked;
318
static const struct usb_instance* usb;
327
static const struct usb_instance* usb;
319
static volatile bool ejected = false;
328
static volatile bool ejected = false;
320
static uint8_t __attribute__((aligned(32))) ramdisk[RAMDISK_SECTORS][RAMDISK_SECTORSIZE];
329
static uint8_t __attribute__((aligned(32))) storage_buffer[0x10000];
321
 
330
 
322
static void listen()
331
static void listen()
323
{
332
{
324
    usb_start_rx(usb, outep, &cbw, sizeof(cbw));
333
    usb_start_rx(usb, outep, &cbw, sizeof(cbw));
325
}
334
}
Line 378... Line 387...
378
        cur_sense_data.sense_key = SENSE_MEDIUM_ERROR;
387
        cur_sense_data.sense_key = SENSE_MEDIUM_ERROR;
379
        cur_sense_data.asc = ASC_READ_ERROR;
388
        cur_sense_data.asc = ASC_READ_ERROR;
380
        cur_sense_data.ascq = 0;
389
        cur_sense_data.ascq = 0;
381
        return;
390
        return;
382
    }
391
    }
383
    send_block_data(ramdisk[cur_cmd.sector], MIN(maxlen, cur_cmd.count * RAMDISK_SECTORSIZE));
-
 
384
 
392
    
385
    cur_cmd.sector += maxlen / RAMDISK_SECTORSIZE;
393
    pending_op_start = cur_cmd.sector;
386
    cur_cmd.count -= MIN(cur_cmd.count, maxlen / RAMDISK_SECTORSIZE);
394
    pending_op_count = cur_cmd.count;
-
 
395
    pending_op = OP_READ;
-
 
396
    wakeup_signal(&pending_op_wakeup);
387
}
397
}
388
 
398
 
389
static void copy_padded(char* dest, char* src, int len)
399
static void copy_padded(char* dest, char* src, int len)
390
{
400
{
391
   int i = 0;
401
   int i = 0;
Line 398... Line 408...
398
}
408
}
399
 
409
 
400
static void fill_inquiry()
410
static void fill_inquiry()
401
{
411
{
402
    memset(&tb.inquiry, 0, sizeof(tb.inquiry));
412
    memset(&tb.inquiry, 0, sizeof(tb.inquiry));
403
    copy_padded(tb.inquiry.VendorId, "emCORE", sizeof(tb.inquiry.VendorId));
413
    copy_padded(tb.inquiry.VendorId, storage_info.vendor, sizeof(tb.inquiry.VendorId));
404
    copy_padded(tb.inquiry.ProductId, "UMS Test", sizeof(tb.inquiry.ProductId));
414
    copy_padded(tb.inquiry.ProductId, storage_info.product, sizeof(tb.inquiry.ProductId));
405
    copy_padded(tb.inquiry.ProductRevisionLevel, "0.1", sizeof(tb.inquiry.ProductRevisionLevel));
415
    copy_padded(tb.inquiry.ProductRevisionLevel, storage_info.revision, sizeof(tb.inquiry.ProductRevisionLevel));
406
 
416
 
407
    tb.inquiry.DeviceType = DIRECT_ACCESS_DEVICE;
417
    tb.inquiry.DeviceType = DIRECT_ACCESS_DEVICE;
408
    tb.inquiry.AdditionalLength = 0x1f;
418
    tb.inquiry.AdditionalLength = 0x1f;
409
    tb.inquiry.Versions = 4;  // SPC-2
419
    tb.inquiry.Versions = 4;  // SPC-2
410
    tb.inquiry.Format = 2;  // SPC-2/3 inquiry format
420
    tb.inquiry.Format = 2;  // SPC-2/3 inquiry format
Line 491... Line 501...
491
                    tb.ms_data_10.block_descriptor_length = htobe16(sizeof(tb.ms_data_10.block_descriptor));
501
                    tb.ms_data_10.block_descriptor_length = htobe16(sizeof(tb.ms_data_10.block_descriptor));
492
 
502
 
493
                    memset(tb.ms_data_10.block_descriptor.reserved, 0, 4);
503
                    memset(tb.ms_data_10.block_descriptor.reserved, 0, 4);
494
                    memset(tb.ms_data_10.block_descriptor.num_blocks, 0, 8);
504
                    memset(tb.ms_data_10.block_descriptor.num_blocks, 0, 8);
495
 
505
 
496
                    tb.ms_data_10.block_descriptor.num_blocks[4] = (RAMDISK_SECTORS & 0xff000000) >> 24;
506
                    tb.ms_data_10.block_descriptor.num_blocks[4] = (storage_info.num_sectors & 0xff000000) >> 24;
497
                    tb.ms_data_10.block_descriptor.num_blocks[5] = (RAMDISK_SECTORS & 0x00ff0000) >> 16;
507
                    tb.ms_data_10.block_descriptor.num_blocks[5] = (storage_info.num_sectors & 0x00ff0000) >> 16;
498
                    tb.ms_data_10.block_descriptor.num_blocks[6] = (RAMDISK_SECTORS & 0x0000ff00) >> 8;
508
                    tb.ms_data_10.block_descriptor.num_blocks[6] = (storage_info.num_sectors & 0x0000ff00) >> 8;
499
                    tb.ms_data_10.block_descriptor.num_blocks[7] = (RAMDISK_SECTORS & 0x000000ff);
509
                    tb.ms_data_10.block_descriptor.num_blocks[7] = (storage_info.num_sectors & 0x000000ff);
500
 
510
 
501
                    tb.ms_data_10.block_descriptor.block_size[0] = (RAMDISK_SECTORSIZE & 0xff000000) >> 24;
511
                    tb.ms_data_10.block_descriptor.block_size[0] = (storage_info.sector_size & 0xff000000) >> 24;
502
                    tb.ms_data_10.block_descriptor.block_size[1] = (RAMDISK_SECTORSIZE & 0x00ff0000) >> 16;
512
                    tb.ms_data_10.block_descriptor.block_size[1] = (storage_info.sector_size & 0x00ff0000) >> 16;
503
                    tb.ms_data_10.block_descriptor.block_size[2] = (RAMDISK_SECTORSIZE & 0x0000ff00) >> 8;
513
                    tb.ms_data_10.block_descriptor.block_size[2] = (storage_info.sector_size & 0x0000ff00) >> 8;
504
                    tb.ms_data_10.block_descriptor.block_size[3] = (RAMDISK_SECTORSIZE & 0x000000ff);
514
                    tb.ms_data_10.block_descriptor.block_size[3] = (storage_info.sector_size & 0x000000ff);
505
                    send_command_result(&tb.ms_data_10, MIN(sizeof(tb.ms_data_10), length));
515
                    send_command_result(&tb.ms_data_10, MIN(sizeof(tb.ms_data_10), length));
506
                    break;
516
                    break;
507
                default:
517
                default:
508
                    send_command_failed_result();
518
                    send_command_failed_result();
509
                    cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
519
                    cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
Line 532... Line 542...
532
                    tb.ms_data_6.medium_type = 0;
542
                    tb.ms_data_6.medium_type = 0;
533
                    tb.ms_data_6.device_specific = 0;
543
                    tb.ms_data_6.device_specific = 0;
534
                    tb.ms_data_6.block_descriptor_length = sizeof(tb.ms_data_6.block_descriptor);
544
                    tb.ms_data_6.block_descriptor_length = sizeof(tb.ms_data_6.block_descriptor);
535
                    tb.ms_data_6.block_descriptor.density_code = 0;
545
                    tb.ms_data_6.block_descriptor.density_code = 0;
536
                    tb.ms_data_6.block_descriptor.reserved = 0;
546
                    tb.ms_data_6.block_descriptor.reserved = 0;
537
                    if (RAMDISK_SECTORS > 0xffffff)
547
                    if (storage_info.num_sectors > 0xffffff)
538
                    {
548
                    {
539
                        tb.ms_data_6.block_descriptor.num_blocks[0] = 0xff;
549
                        tb.ms_data_6.block_descriptor.num_blocks[0] = 0xff;
540
                        tb.ms_data_6.block_descriptor.num_blocks[1] = 0xff;
550
                        tb.ms_data_6.block_descriptor.num_blocks[1] = 0xff;
541
                        tb.ms_data_6.block_descriptor.num_blocks[2] = 0xff;
551
                        tb.ms_data_6.block_descriptor.num_blocks[2] = 0xff;
542
                    }
552
                    }
543
                    else
553
                    else
544
                    {
554
                    {
545
                        tb.ms_data_6.block_descriptor.num_blocks[0] = (RAMDISK_SECTORS & 0xff0000) >> 16;
555
                        tb.ms_data_6.block_descriptor.num_blocks[0] = (storage_info.num_sectors & 0xff0000) >> 16;
546
                        tb.ms_data_6.block_descriptor.num_blocks[1] = (RAMDISK_SECTORS & 0x00ff00) >> 8;
556
                        tb.ms_data_6.block_descriptor.num_blocks[1] = (storage_info.num_sectors & 0x00ff00) >> 8;
547
                        tb.ms_data_6.block_descriptor.num_blocks[2] = (RAMDISK_SECTORS & 0x0000ff);
557
                        tb.ms_data_6.block_descriptor.num_blocks[2] = (storage_info.num_sectors & 0x0000ff);
548
                    }
558
                    }
549
                    tb.ms_data_6.block_descriptor.block_size[0] = (RAMDISK_SECTORSIZE & 0xff0000) >> 16;
559
                    tb.ms_data_6.block_descriptor.block_size[0] = (storage_info.sector_size & 0xff0000) >> 16;
550
                    tb.ms_data_6.block_descriptor.block_size[1] = (RAMDISK_SECTORSIZE & 0x00ff00) >> 8;
560
                    tb.ms_data_6.block_descriptor.block_size[1] = (storage_info.sector_size & 0x00ff00) >> 8;
551
                    tb.ms_data_6.block_descriptor.block_size[2] = (RAMDISK_SECTORSIZE & 0x0000ff);
561
                    tb.ms_data_6.block_descriptor.block_size[2] = (storage_info.sector_size & 0x0000ff);
552
                    send_command_result(&tb.ms_data_6, MIN(sizeof(tb.ms_data_6), length));
562
                    send_command_result(&tb.ms_data_6, MIN(sizeof(tb.ms_data_6), length));
553
                    break;
563
                    break;
554
                default:
564
                default:
555
                    send_command_failed_result();
565
                    send_command_failed_result();
556
                    cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
566
                    cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
Line 575... Line 585...
575
        case SCSI_READ_FORMAT_CAPACITY:
585
        case SCSI_READ_FORMAT_CAPACITY:
576
        {
586
        {
577
            if (!ejected)
587
            if (!ejected)
578
            {
588
            {
579
                tb.format_capacity_data.following_length = 0x08000000;
589
                tb.format_capacity_data.following_length = 0x08000000;
580
                tb.format_capacity_data.block_count = htobe32(RAMDISK_SECTORS - 1);
590
                tb.format_capacity_data.block_count = htobe32(storage_info.num_sectors - 1);
581
                tb.format_capacity_data.block_size = htobe32(RAMDISK_SECTORSIZE);
591
                tb.format_capacity_data.block_size = htobe32(storage_info.sector_size);
582
                tb.format_capacity_data.block_size |= htobe32(SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA);
592
                tb.format_capacity_data.block_size |= htobe32(SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA);
583
                send_command_result(&tb.format_capacity_data, MIN(sizeof(tb.format_capacity_data), length));
593
                send_command_result(&tb.format_capacity_data, MIN(sizeof(tb.format_capacity_data), length));
584
           }
594
           }
585
           else
595
           else
586
           {
596
           {
Line 594... Line 604...
594
 
604
 
595
        case SCSI_READ_CAPACITY:
605
        case SCSI_READ_CAPACITY:
596
        {
606
        {
597
            if (!ejected)
607
            if (!ejected)
598
            {
608
            {
599
                tb.capacity_data.block_count = htobe32(RAMDISK_SECTORS - 1);
609
                tb.capacity_data.block_count = htobe32(storage_info.num_sectors - 1);
600
                tb.capacity_data.block_size = htobe32(RAMDISK_SECTORSIZE);
610
                tb.capacity_data.block_size = htobe32(storage_info.sector_size);
601
                send_command_result(&tb.capacity_data, MIN(sizeof(tb.capacity_data), length));
611
                send_command_result(&tb.capacity_data, MIN(sizeof(tb.capacity_data), length));
602
            }
612
            }
603
            else
613
            else
604
            {
614
            {
605
                send_command_failed_result();
615
                send_command_failed_result();
Line 622... Line 632...
622
            cur_cmd.sector = (cbw->command_block[2] << 24 | cbw->command_block[3] << 16
632
            cur_cmd.sector = (cbw->command_block[2] << 24 | cbw->command_block[3] << 16
623
                            | cbw->command_block[4] << 8 | cbw->command_block[5]);
633
                            | cbw->command_block[4] << 8 | cbw->command_block[5]);
624
            cur_cmd.count = (cbw->command_block[7] << 8 | cbw->command_block[8]);
634
            cur_cmd.count = (cbw->command_block[7] << 8 | cbw->command_block[8]);
625
            cur_cmd.orig_count = cur_cmd.count;
635
            cur_cmd.orig_count = cur_cmd.count;
626
 
636
 
627
            if ((cur_cmd.sector + cur_cmd.count) > RAMDISK_SECTORS)
637
            if ((cur_cmd.sector + cur_cmd.count) > storage_info.num_sectors)
628
            {
638
            {
629
                send_csw(1);
639
                send_csw(1);
630
                cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
640
                cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
631
                cur_sense_data.asc = ASC_LBA_OUT_OF_RANGE;
641
                cur_sense_data.asc = ASC_LBA_OUT_OF_RANGE;
632
                cur_sense_data.ascq = 0;
642
                cur_sense_data.ascq = 0;
Line 646... Line 656...
646
            cur_cmd.sector = (cbw->command_block[2] << 24 | cbw->command_block[3] << 16
656
            cur_cmd.sector = (cbw->command_block[2] << 24 | cbw->command_block[3] << 16
647
                            | cbw->command_block[4] << 8 | cbw->command_block[5]);
657
                            | cbw->command_block[4] << 8 | cbw->command_block[5]);
648
            cur_cmd.count = (cbw->command_block[7] << 8 | cbw->command_block[8]);
658
            cur_cmd.count = (cbw->command_block[7] << 8 | cbw->command_block[8]);
649
            cur_cmd.orig_count = cur_cmd.count;
659
            cur_cmd.orig_count = cur_cmd.count;
650
 
660
 
651
            if ((cur_cmd.sector + cur_cmd.count) > RAMDISK_SECTORS)
661
            if ((cur_cmd.sector + cur_cmd.count) > storage_info.num_sectors)
652
            {
662
            {
653
                send_csw(1);
663
                send_csw(1);
654
                cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
664
                cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
655
                cur_sense_data.asc = ASC_LBA_OUT_OF_RANGE;
665
                cur_sense_data.asc = ASC_LBA_OUT_OF_RANGE;
656
                cur_sense_data.ascq = 0;
666
                cur_sense_data.ascq = 0;
657
            }
667
            }
658
            else
668
            else {
659
                receive_block_data(ramdisk[cur_cmd.sector], MIN(maxlen, cur_cmd.count * RAMDISK_SECTORSIZE));
669
                receive_block_data(storage_buffer, MIN(maxlen, cur_cmd.count * storage_info.sector_size));
-
 
670
            }
660
            break;
671
            break;
661
 
672
 
662
        case SCSI_WRITE_BUFFER:
673
        case SCSI_WRITE_BUFFER:
663
            break;
674
            break;
664
 
675
 
Line 734... Line 745...
734
{
745
{
735
    length -= bytesleft;
746
    length -= bytesleft;
736
    switch (state)
747
    switch (state)
737
    {
748
    {
738
        case RECEIVING_BLOCKS:
749
        case RECEIVING_BLOCKS:
739
            if (length != RAMDISK_SECTORSIZE * cur_cmd.count && length != maxlen) break;
750
            if (length != storage_info.sector_size * cur_cmd.count && length != maxlen) break;
740
 
-
 
741
            cur_cmd.sector += (maxlen / RAMDISK_SECTORSIZE);
-
 
742
            cur_cmd.count -= MIN(cur_cmd.count, maxlen / RAMDISK_SECTORSIZE);
-
 
743
 
751
 
744
            if (cur_cmd.count)
752
            pending_op_start = cur_cmd.sector;
745
                receive_block_data(ramdisk[cur_cmd.sector], MIN(maxlen, cur_cmd.count * RAMDISK_SECTORSIZE));
753
            pending_op_count = cur_cmd.count;
746
            else send_csw(0);
754
            pending_op = OP_WRITE;
-
 
755
            wakeup_signal(&pending_op_wakeup);
747
            break;
756
            break;
748
        case WAITING_FOR_CSW_COMPLETION:
757
        case WAITING_FOR_CSW_COMPLETION:
749
            state = WAITING_FOR_COMMAND;
758
            state = WAITING_FOR_COMMAND;
750
            listen();
759
            listen();
751
            break;
760
            break;
Line 833... Line 842...
833
    &usb_c1,
842
    &usb_c1,
834
};
843
};
835
 
844
 
836
static void main(int argc, const char** argv)
845
static void main(int argc, const char** argv)
837
{
846
{
-
 
847
    storage_get_info(0, &storage_info);
-
 
848
    
-
 
849
    if (!storage_info.sector_size) panicf(PANIC_KILLTHREAD, "Sector size is zero!\n");
-
 
850
    if (!storage_info.num_sectors) panicf(PANIC_KILLTHREAD, "Number of sectors is zero!\n");
-
 
851
 
-
 
852
    disk_unmount(0);
-
 
853
 
838
    int i;
854
    int i;
839
    uint32_t eps = usbmanager_get_available_endpoints();
855
    uint32_t eps = usbmanager_get_available_endpoints();
840
    int ep_out = 0;
856
    int ep_out = 0;
841
    int ep_in = 0;
857
    int ep_in = 0;
842
    for (i = 1; i < 16; i++)
858
    for (i = 1; i < 16; i++)
Line 858... Line 874...
858
    usb_c1_i0_a0_ep1in.number.number = ep_in;
874
    usb_c1_i0_a0_ep1in.number.number = ep_in;
859
    outep.number = ep_out;
875
    outep.number = ep_out;
860
    inep.number = ep_in;
876
    inep.number = ep_in;
861
    int rc = usbmanager_install_custom(&usb_devicedescriptor, ARRAYLEN(usb_configurations), usb_configurations,
877
    int rc = usbmanager_install_custom(&usb_devicedescriptor, ARRAYLEN(usb_configurations), usb_configurations,
862
                                       ARRAYLEN(usb_stringdescriptors), usb_stringdescriptors, true);
878
                                       ARRAYLEN(usb_stringdescriptors), usb_stringdescriptors, true);
-
 
879
    if (IS_ERR(rc)) {
-
 
880
        disk_mount(0);
863
    if (IS_ERR(rc)) panicf(PANIC_KILLTHREAD, "Failed to register USB handler: %08X\n", rc);
881
        panicf(PANIC_KILLTHREAD, "Failed to register USB handler: %08X\n", rc);
-
 
882
    }
-
 
883
    
-
 
884
    wakeup_init(&pending_op_wakeup);
-
 
885
    
864
    while (!ejected && usbmanager_get_connected()) sleep(200000);
886
    while (!ejected && usbmanager_get_connected()) {
-
 
887
        if (wakeup_wait(&pending_op_wakeup, 200000) == THREAD_OK) {
-
 
888
            if (pending_op == OP_READ) {
-
 
889
                //cprintf(3, "R(%u, %u)\n", pending_op_start, pending_op_count);
-
 
890
                storage_read_sectors_md(0, pending_op_start, pending_op_count, storage_buffer);
-
 
891
 
-
 
892
                send_block_data(storage_buffer, MIN(maxlen, cur_cmd.count * storage_info.sector_size));
-
 
893
            }
-
 
894
            
-
 
895
            if (pending_op == OP_WRITE) {
-
 
896
                //cprintf(3, "W(%u, %u)\n", pending_op_start, pending_op_count);
-
 
897
                storage_write_sectors_md(0, pending_op_start, pending_op_count, storage_buffer);
-
 
898
            }
-
 
899
                
-
 
900
            cur_cmd.sector += maxlen / storage_info.sector_size;
-
 
901
            cur_cmd.count -= MIN(cur_cmd.count, maxlen / storage_info.sector_size);
-
 
902
            
-
 
903
            if (pending_op == OP_WRITE) {
-
 
904
                if (cur_cmd.count) {
-
 
905
                    receive_block_data(storage_buffer, MIN(maxlen, cur_cmd.count * storage_info.sector_size));
-
 
906
                }
-
 
907
                else send_csw(0);
-
 
908
            }
-
 
909
        }
-
 
910
    }
-
 
911
    
865
    usbmanager_uninstall_custom();
912
    usbmanager_uninstall_custom();
-
 
913
    
-
 
914
    disk_mount(0);
866
}
915
}
867
 
916
 
868
 
917
 
869
EMCORE_APP_HEADER("USB mass storage test", main, 127)
918
EMCORE_APP_HEADER("Disk mode", main, 127)
870
 
-