Subversion Repositories freemyipod

Rev

Rev 913 | Rev 918 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
893 theseven 1
//
2
//
3
//    Copyright 2013 TheSeven
914 user890104 4
//    Copyright 2014 user890104
893 theseven 5
//
6
//
7
//    This file is part of emCORE.
8
//
9
//    emCORE is free software: you can redistribute it and/or
10
//    modify it under the terms of the GNU General Public License as
11
//    published by the Free Software Foundation, either version 2 of the
12
//    License, or (at your option) any later version.
13
//
14
//    emCORE is distributed in the hope that it will be useful,
15
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
16
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
//    See the GNU General Public License for more details.
18
//
19
//    You should have received a copy of the GNU General Public License along
20
//    with emCORE.  If not, see <http://www.gnu.org/licenses/>.
21
//
22
//
23
 
24
 
25
#define LITTLE_ENDIAN
26
 
27
 
28
#include "emcoreapp.h"
29
 
30
 
31
#define SCSI_TEST_UNIT_READY        0x00
32
#define SCSI_INQUIRY                0x12
33
#define SCSI_MODE_SENSE_6           0x1a
34
#define SCSI_MODE_SENSE_10          0x5a
35
#define SCSI_REQUEST_SENSE          0x03
36
#define SCSI_ALLOW_MEDIUM_REMOVAL   0x1e
37
#define SCSI_READ_CAPACITY          0x25
38
#define SCSI_READ_FORMAT_CAPACITY   0x23
39
#define SCSI_READ_10                0x28
40
#define SCSI_WRITE_10               0x2a
41
#define SCSI_START_STOP_UNIT        0x1b
42
#define SCSI_REPORT_LUNS            0xa0
43
#define SCSI_WRITE_BUFFER           0x3b
44
 
45
#define SENSE_NOT_READY             0x02
46
#define SENSE_MEDIUM_ERROR          0x03
47
#define SENSE_ILLEGAL_REQUEST       0x05
48
#define SENSE_UNIT_ATTENTION        0x06
49
 
50
#define ASC_MEDIUM_NOT_PRESENT      0x3a
51
#define ASC_INVALID_FIELD_IN_CBD    0x24
52
#define ASC_LBA_OUT_OF_RANGE        0x21
53
#define ASC_WRITE_ERROR             0x0C
54
#define ASC_READ_ERROR              0x11
55
#define ASC_NOT_READY               0x04
56
#define ASC_INVALID_COMMAND         0x20
57
 
58
#define ASCQ_BECOMING_READY         0x01
59
 
60
#define DIRECT_ACCESS_DEVICE        0x00
61
#define DEVICE_REMOVABLE            0x80
62
 
63
#define SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA 0x02000000
64
 
65
 
914 user890104 66
struct storage_info storage_info;
893 theseven 67
 
914 user890104 68
enum storage_operation {
69
    OP_READ,
70
    OP_WRITE
71
} pending_op;
893 theseven 72
 
914 user890104 73
unsigned long pending_op_start;
74
int pending_op_count;
75
 
76
struct wakeup pending_op_wakeup;
77
 
893 theseven 78
static const struct usb_devicedescriptor usb_devicedescriptor =
79
{
80
    .bLength = sizeof(struct usb_devicedescriptor),
81
    .bDescriptorType = USB_DESCRIPTOR_TYPE_DEVICE,
82
    .bcdUSB = 0x0200,
83
    .bDeviceClass = 0,
84
    .bDeviceSubClass = 0,
85
    .bDeviceProtocol = 0,
86
    .bMaxPacketSize0 = 64,
87
    .idVendor = 0xffff,
913 user890104 88
    .idProduct = 0xe001,
893 theseven 89
    .bcdDevice = 2,
90
    .iManufacturer = 1,
91
    .iProduct = 2,
92
    .iSerialNumber = 0,
93
    .bNumConfigurations = 1,
94
};
95
 
96
static struct __attribute__((packed)) _usb_config1_descriptors
97
{
98
    struct usb_configurationdescriptor c1;
99
    struct usb_interfacedescriptor c1_i0_a0;
100
    struct usb_endpointdescriptor c1_i0_a0_e1out;
101
    struct usb_endpointdescriptor c1_i0_a0_e1in;
102
} usb_config1_descriptors =
103
{
104
    .c1 =
105
    {
106
        .bLength = sizeof(struct usb_configurationdescriptor),
107
        .bDescriptorType = USB_DESCRIPTOR_TYPE_CONFIGURATION,
108
        .wTotalLength = sizeof(struct _usb_config1_descriptors),
109
        .bNumInterfaces = 1,
110
        .bConfigurationValue = 1,
111
        .iConfiguration = 0,
112
        .bmAttributes = { .buspowered = 1, .selfpowered = 1 },
113
        .bMaxPower = 100 / 2,
114
    },
115
    .c1_i0_a0 =
116
    {
117
        .bLength = sizeof(struct usb_interfacedescriptor),
118
        .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE,
119
        .bInterfaceNumber = 0,
120
        .bAlternateSetting = 0,
121
        .bNumEndpoints = 2,
122
        .bInterfaceClass = 0x08,
123
        .bInterfaceSubClass = 0x06,
124
        .bInterfaceProtocol = 0x50,
125
        .iInterface = 0,
126
    },
127
    .c1_i0_a0_e1out =
128
    {
129
        .bLength = sizeof(struct usb_endpointdescriptor),
130
        .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
131
        .bEndpointAddress = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_OUT },
132
        .bmAttributes = { .type = USB_ENDPOINT_ATTRIBUTE_TYPE_BULK },
133
        .wMaxPacketSize = 512,
134
        .bInterval = 1,
135
    },
136
    .c1_i0_a0_e1in =
137
    {
138
        .bLength = sizeof(struct usb_endpointdescriptor),
139
        .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
140
        .bEndpointAddress = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_IN },
141
        .bmAttributes = { .type = USB_ENDPOINT_ATTRIBUTE_TYPE_BULK },
142
        .wMaxPacketSize = 512,
143
        .bInterval = 1,
144
    },
145
};
146
 
147
static const struct usb_stringdescriptor usb_string_language =
148
{
149
    .bLength = sizeof(usb_string_language) + sizeof(*usb_string_language.wString),
150
    .bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
151
    .wString = { 0x0409 },
152
};
153
 
154
static const struct usb_stringdescriptor usb_string_vendor =
155
{
156
    .bLength = sizeof(usb_string_vendor) + sizeof(*usb_string_vendor.wString) * 14,
157
    .bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
158
    .wString = { 'f', 'r', 'e', 'e', 'm', 'y', 'i', 'p', 'o', 'd', '.', 'o', 'r', 'g' },
159
};
160
 
161
static const struct usb_stringdescriptor usb_string_product =
162
{
914 user890104 163
    .bLength = sizeof(usb_string_product) + sizeof(*usb_string_product.wString) * 16,
893 theseven 164
    .bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
914 user890104 165
    .wString = { 'e', 'm', 'C', 'O', 'R', 'E', ' ', 'D', 'i', 's', 'k', ' ', 'm', 'o', 'd', 'e' },
893 theseven 166
};
167
 
168
static const struct usb_stringdescriptor* usb_stringdescriptors[] =
169
{
170
    &usb_string_language,
171
    &usb_string_vendor,
172
    &usb_string_product,
173
};
174
 
175
struct __attribute__((packed,aligned(32))) command_block_wrapper
176
{
177
    unsigned int signature;
178
    unsigned int tag;
179
    unsigned int data_transfer_length;
180
    unsigned char flags;
181
    unsigned char lun;
182
    unsigned char command_length;
183
    unsigned char command_block[16];
184
};
185
 
186
struct __attribute__((packed)) command_status_wrapper
187
{
188
    unsigned int signature;
189
    unsigned int tag;
190
    unsigned int data_residue;
191
    unsigned char status;
192
};
193
 
194
struct __attribute__((packed)) inquiry_data
195
{
196
    unsigned char DeviceType;
197
    unsigned char DeviceTypeModifier;
198
    unsigned char Versions;
199
    unsigned char Format;
200
    unsigned char AdditionalLength;
201
    unsigned char Reserved[2];
202
    unsigned char Capability;
203
    char VendorId[8];
204
    char ProductId[16];
205
    char ProductRevisionLevel[4];
206
};
207
 
208
struct __attribute__((packed)) report_lun_data
209
{
210
    unsigned int lun_list_length;
211
    unsigned int reserved1;
212
    unsigned char luns[1][8];
213
};
214
 
215
struct __attribute__((packed)) sense_data
216
{
217
    unsigned char ResponseCode;
218
    unsigned char Obsolete;
219
    unsigned char fei_sensekey;
220
    unsigned int Information;
221
    unsigned char AdditionalSenseLength;
222
    unsigned int  CommandSpecificInformation;
223
    unsigned char AdditionalSenseCode;
224
    unsigned char AdditionalSenseCodeQualifier;
225
    unsigned char FieldReplaceableUnitCode;
226
    unsigned char SKSV;
227
    unsigned short SenseKeySpecific;
228
};
229
 
230
struct __attribute__((packed)) mode_sense_bdesc_longlba
231
{
232
    unsigned char num_blocks[8];
233
    unsigned char reserved[4];
234
    unsigned char block_size[4];
235
};
236
 
237
struct __attribute__((packed)) mode_sense_bdesc_shortlba
238
{
239
    unsigned char density_code;
240
    unsigned char num_blocks[3];
241
    unsigned char reserved;
242
    unsigned char block_size[3];
243
};
244
 
245
struct __attribute__((packed)) mode_sense_data_10
246
{
247
    unsigned short mode_data_length;
248
    unsigned char medium_type;
249
    unsigned char device_specific;
250
    unsigned char longlba;
251
    unsigned char reserved;
252
    unsigned short block_descriptor_length;
253
    struct mode_sense_bdesc_longlba block_descriptor;
254
};
255
 
256
struct __attribute__((packed)) mode_sense_data_6
257
{
258
    unsigned char mode_data_length;
259
    unsigned char medium_type;
260
    unsigned char device_specific;
261
    unsigned char block_descriptor_length;
262
    struct mode_sense_bdesc_shortlba block_descriptor;
263
};
264
 
265
struct __attribute__((packed)) capacity
266
{
267
    unsigned int block_count;
268
    unsigned int block_size;
269
};
270
 
271
struct __attribute__((packed)) format_capacity
272
{
273
    unsigned int following_length;
274
    unsigned int block_count;
275
    unsigned int block_size;
276
};
277
 
278
union __attribute__((aligned(32)))
279
{
280
    struct inquiry_data inquiry;
281
    struct capacity capacity_data;
282
    struct format_capacity format_capacity_data;
283
    struct sense_data sense_data;
284
    struct mode_sense_data_6 ms_data_6;
285
    struct mode_sense_data_10 ms_data_10;
286
    struct report_lun_data lun_data;
287
    struct command_status_wrapper csw;
288
} tb;
289
 
290
static enum
291
{
292
    WAITING_FOR_COMMAND,
293
    SENDING_BLOCKS,
294
    SENDING_RESULT,
295
    SENDING_FAILED_RESULT,
296
    RECEIVING_BLOCKS,
297
    WAITING_FOR_CSW_COMPLETION
298
} state = WAITING_FOR_COMMAND;
299
 
300
static struct
301
{
302
    unsigned int sector;
303
    unsigned int count;
304
    unsigned int orig_count;
305
    unsigned int cur_cmd;
306
    unsigned int tag;
307
    unsigned int lun;
308
    unsigned int last_result;
309
} cur_cmd;
310
 
311
static struct
312
{
313
    unsigned char sense_key;
314
    unsigned char information;
315
    unsigned char asc;
316
    unsigned char ascq;
317
} cur_sense_data;
318
 
319
static union usb_endpoint_number outep = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_OUT };
320
static union usb_endpoint_number inep = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_IN };
321
 
322
static struct command_block_wrapper cbw;
323
static int maxpacket = 512;
324
static int maxlen;
325
static int length;
326
static bool locked;
327
static const struct usb_instance* usb;
328
static volatile bool ejected = false;
914 user890104 329
static uint8_t __attribute__((aligned(32))) storage_buffer[0x10000];
893 theseven 330
 
331
static void listen()
332
{
333
    usb_start_rx(usb, outep, &cbw, sizeof(cbw));
334
}
335
 
336
static void send_csw(int status)
337
{
338
    tb.csw.signature = 0x53425355;
339
    tb.csw.tag = cur_cmd.tag;
340
    tb.csw.data_residue = 0;
341
    tb.csw.status = status;
342
 
343
    state = WAITING_FOR_CSW_COMPLETION;
344
    usb_start_tx(usb, inep, &tb.csw, sizeof(tb.csw));
345
 
346
    if (!status)
347
    {
348
        cur_sense_data.sense_key = 0;
349
        cur_sense_data.information = 0;
350
        cur_sense_data.asc = 0;
351
        cur_sense_data.ascq = 0;
352
    }
353
}
354
 
355
static void receive_block_data(void* data, int size)
356
{
357
    length = size;
358
    usb_start_rx(usb, outep, data, size);
359
    state = RECEIVING_BLOCKS;
360
}
361
 
362
static void send_block_data(void* data, int size)
363
{
364
    length = size;
365
    usb_start_tx(usb, inep, data, size);
366
    state = SENDING_BLOCKS;
367
}
368
 
369
static void send_command_result(void* data, int size)
370
{
371
    length = size;
372
    usb_start_tx(usb, inep, data, size);
373
    state = SENDING_RESULT;
374
}
375
 
376
static void send_command_failed_result()
377
{
378
    usb_start_tx(usb, inep, NULL, 0);
379
    state = SENDING_FAILED_RESULT;
380
}
381
 
382
static void send_and_read_next()
383
{
384
    if (cur_cmd.last_result)
385
    {
386
        send_csw(1);
387
        cur_sense_data.sense_key = SENSE_MEDIUM_ERROR;
388
        cur_sense_data.asc = ASC_READ_ERROR;
389
        cur_sense_data.ascq = 0;
390
        return;
391
    }
914 user890104 392
 
393
    pending_op_start = cur_cmd.sector;
394
    pending_op_count = cur_cmd.count;
395
    pending_op = OP_READ;
396
    wakeup_signal(&pending_op_wakeup);
893 theseven 397
}
398
 
399
static void copy_padded(char* dest, char* src, int len)
400
{
401
   int i = 0;
402
   while (src[i] && i < len)
403
   {
404
      dest[i] = src[i];
405
      i++;
406
   }
407
   while(i < len) dest[i++] = ' ';
408
}
409
 
410
static void fill_inquiry()
411
{
412
    memset(&tb.inquiry, 0, sizeof(tb.inquiry));
914 user890104 413
    copy_padded(tb.inquiry.VendorId, storage_info.vendor, sizeof(tb.inquiry.VendorId));
414
    copy_padded(tb.inquiry.ProductId, storage_info.product, sizeof(tb.inquiry.ProductId));
415
    copy_padded(tb.inquiry.ProductRevisionLevel, storage_info.revision, sizeof(tb.inquiry.ProductRevisionLevel));
893 theseven 416
 
417
    tb.inquiry.DeviceType = DIRECT_ACCESS_DEVICE;
418
    tb.inquiry.AdditionalLength = 0x1f;
419
    tb.inquiry.Versions = 4;  // SPC-2
420
    tb.inquiry.Format = 2;  // SPC-2/3 inquiry format
421
    tb.inquiry.DeviceTypeModifier = DEVICE_REMOVABLE;
422
}
423
 
424
static void handle_scsi(struct command_block_wrapper* cbw)
425
{
426
    unsigned int length = cbw->data_transfer_length;
427
 
428
    if (cbw->signature != 0x43425355)
429
    {
430
        usb_set_stall(usb, outep, true);
431
        usb_set_stall(usb, inep, true);
432
        return;
433
    }
434
    cur_cmd.tag = cbw->tag;
435
    cur_cmd.lun = cbw->lun;
436
    cur_cmd.cur_cmd = cbw->command_block[0];
437
 
438
    switch (cbw->command_block[0])
439
    {
440
        case SCSI_TEST_UNIT_READY:
441
            if (!ejected) send_csw(0);
442
            else
443
            {
444
                send_csw(1);
445
                cur_sense_data.sense_key = SENSE_NOT_READY;
446
                cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
447
                cur_sense_data.ascq = 0;
448
            }
449
            break;
450
 
451
        case SCSI_REPORT_LUNS:
452
        {
453
            memset(&tb.lun_data, 0, sizeof(struct report_lun_data));
454
            tb.lun_data.lun_list_length = 0x08000000;
455
            send_command_result(&tb.lun_data, MIN(16, length));
456
            break;
457
        }
458
 
459
        case SCSI_INQUIRY:
460
            fill_inquiry();
461
            length = MIN(length, cbw->command_block[4]);
462
            send_command_result(&tb.inquiry, MIN(sizeof(tb.inquiry), length));
463
            break;
464
 
465
        case SCSI_REQUEST_SENSE:
466
        {
467
            tb.sense_data.ResponseCode = 0x70;
468
            tb.sense_data.Obsolete = 0;
469
            tb.sense_data.fei_sensekey = cur_sense_data.sense_key & 0x0f;
470
            tb.sense_data.Information = cur_sense_data.information;
471
            tb.sense_data.AdditionalSenseLength = 10;
472
            tb.sense_data.CommandSpecificInformation = 0;
473
            tb.sense_data.AdditionalSenseCode = cur_sense_data.asc;
474
            tb.sense_data.AdditionalSenseCodeQualifier = cur_sense_data.ascq;
475
            tb.sense_data.FieldReplaceableUnitCode = 0;
476
            tb.sense_data.SKSV = 0;
477
            tb.sense_data.SenseKeySpecific = 0;
478
            send_command_result(&tb.sense_data, MIN(sizeof(tb.sense_data), length));
479
            break;
480
        }
481
 
482
        case SCSI_MODE_SENSE_10:
483
        {
484
            if (ejected)
485
            {
486
                send_command_failed_result();
487
                cur_sense_data.sense_key = SENSE_NOT_READY;
488
                cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
489
                cur_sense_data.ascq = 0;
490
                break;
491
            }
492
            unsigned char page_code = cbw->command_block[2] & 0x3f;
493
            switch (page_code)
494
            {
495
                case 0x3f:
496
                    tb.ms_data_10.mode_data_length = htobe16(sizeof(tb.ms_data_10) - 2);
497
                    tb.ms_data_10.medium_type = 0;
498
                    tb.ms_data_10.device_specific = 0;
499
                    tb.ms_data_10.reserved = 0;
500
                    tb.ms_data_10.longlba = 1;
501
                    tb.ms_data_10.block_descriptor_length = htobe16(sizeof(tb.ms_data_10.block_descriptor));
502
 
503
                    memset(tb.ms_data_10.block_descriptor.reserved, 0, 4);
504
                    memset(tb.ms_data_10.block_descriptor.num_blocks, 0, 8);
505
 
914 user890104 506
                    tb.ms_data_10.block_descriptor.num_blocks[4] = (storage_info.num_sectors & 0xff000000) >> 24;
507
                    tb.ms_data_10.block_descriptor.num_blocks[5] = (storage_info.num_sectors & 0x00ff0000) >> 16;
508
                    tb.ms_data_10.block_descriptor.num_blocks[6] = (storage_info.num_sectors & 0x0000ff00) >> 8;
509
                    tb.ms_data_10.block_descriptor.num_blocks[7] = (storage_info.num_sectors & 0x000000ff);
893 theseven 510
 
914 user890104 511
                    tb.ms_data_10.block_descriptor.block_size[0] = (storage_info.sector_size & 0xff000000) >> 24;
512
                    tb.ms_data_10.block_descriptor.block_size[1] = (storage_info.sector_size & 0x00ff0000) >> 16;
513
                    tb.ms_data_10.block_descriptor.block_size[2] = (storage_info.sector_size & 0x0000ff00) >> 8;
514
                    tb.ms_data_10.block_descriptor.block_size[3] = (storage_info.sector_size & 0x000000ff);
893 theseven 515
                    send_command_result(&tb.ms_data_10, MIN(sizeof(tb.ms_data_10), length));
516
                    break;
517
                default:
518
                    send_command_failed_result();
519
                    cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
520
                    cur_sense_data.asc = ASC_INVALID_FIELD_IN_CBD;
521
                    cur_sense_data.ascq = 0;
522
                    break;
523
            }
524
            break;
525
        }
526
 
527
        case SCSI_MODE_SENSE_6:
528
        {
529
            if (ejected)
530
            {
531
                send_command_failed_result();
532
                cur_sense_data.sense_key = SENSE_NOT_READY;
533
                cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
534
                cur_sense_data.ascq = 0;
535
                break;
536
            }
537
            unsigned char page_code = cbw->command_block[2] & 0x3f;
538
            switch (page_code)
539
            {
540
                case 0x3f:
541
                    tb.ms_data_6.mode_data_length = sizeof(tb.ms_data_6) - 1;
542
                    tb.ms_data_6.medium_type = 0;
543
                    tb.ms_data_6.device_specific = 0;
544
                    tb.ms_data_6.block_descriptor_length = sizeof(tb.ms_data_6.block_descriptor);
545
                    tb.ms_data_6.block_descriptor.density_code = 0;
546
                    tb.ms_data_6.block_descriptor.reserved = 0;
914 user890104 547
                    if (storage_info.num_sectors > 0xffffff)
893 theseven 548
                    {
549
                        tb.ms_data_6.block_descriptor.num_blocks[0] = 0xff;
550
                        tb.ms_data_6.block_descriptor.num_blocks[1] = 0xff;
551
                        tb.ms_data_6.block_descriptor.num_blocks[2] = 0xff;
552
                    }
553
                    else
554
                    {
914 user890104 555
                        tb.ms_data_6.block_descriptor.num_blocks[0] = (storage_info.num_sectors & 0xff0000) >> 16;
556
                        tb.ms_data_6.block_descriptor.num_blocks[1] = (storage_info.num_sectors & 0x00ff00) >> 8;
557
                        tb.ms_data_6.block_descriptor.num_blocks[2] = (storage_info.num_sectors & 0x0000ff);
893 theseven 558
                    }
914 user890104 559
                    tb.ms_data_6.block_descriptor.block_size[0] = (storage_info.sector_size & 0xff0000) >> 16;
560
                    tb.ms_data_6.block_descriptor.block_size[1] = (storage_info.sector_size & 0x00ff00) >> 8;
561
                    tb.ms_data_6.block_descriptor.block_size[2] = (storage_info.sector_size & 0x0000ff);
893 theseven 562
                    send_command_result(&tb.ms_data_6, MIN(sizeof(tb.ms_data_6), length));
563
                    break;
564
                default:
565
                    send_command_failed_result();
566
                    cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
567
                    cur_sense_data.asc = ASC_INVALID_FIELD_IN_CBD;
568
                    cur_sense_data.ascq = 0;
569
                    break;
570
            }
571
            break;
572
        }
573
 
574
        case SCSI_START_STOP_UNIT:
575
            if ((cbw->command_block[4] & 0xf3) == 2) ejected = true;
576
            send_csw(0);
577
            break;
578
 
579
        case SCSI_ALLOW_MEDIUM_REMOVAL:
580
            if ((cbw->command_block[4] & 0x03) == 0) locked = false;
581
            else locked = true;
582
            send_csw(0);
583
            break;
584
 
585
        case SCSI_READ_FORMAT_CAPACITY:
586
        {
587
            if (!ejected)
588
            {
589
                tb.format_capacity_data.following_length = 0x08000000;
914 user890104 590
                tb.format_capacity_data.block_count = htobe32(storage_info.num_sectors - 1);
591
                tb.format_capacity_data.block_size = htobe32(storage_info.sector_size);
893 theseven 592
                tb.format_capacity_data.block_size |= htobe32(SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA);
593
                send_command_result(&tb.format_capacity_data, MIN(sizeof(tb.format_capacity_data), length));
594
           }
595
           else
596
           {
597
               send_command_failed_result();
598
               cur_sense_data.sense_key = SENSE_NOT_READY;
599
               cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
600
               cur_sense_data.ascq = 0;
601
           }
602
           break;
603
        }
604
 
605
        case SCSI_READ_CAPACITY:
606
        {
607
            if (!ejected)
608
            {
914 user890104 609
                tb.capacity_data.block_count = htobe32(storage_info.num_sectors - 1);
610
                tb.capacity_data.block_size = htobe32(storage_info.sector_size);
893 theseven 611
                send_command_result(&tb.capacity_data, MIN(sizeof(tb.capacity_data), length));
612
            }
613
            else
614
            {
615
                send_command_failed_result();
616
                cur_sense_data.sense_key = SENSE_NOT_READY;
617
                cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
618
                cur_sense_data.ascq = 0;
619
            }
620
            break;
621
        }
622
 
623
        case SCSI_READ_10:
624
            if (ejected)
625
            {
626
                send_command_failed_result();
627
                cur_sense_data.sense_key = SENSE_NOT_READY;
628
                cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
629
                cur_sense_data.ascq = 0;
630
                break;
631
            }
632
            cur_cmd.sector = (cbw->command_block[2] << 24 | cbw->command_block[3] << 16
633
                            | cbw->command_block[4] << 8 | cbw->command_block[5]);
634
            cur_cmd.count = (cbw->command_block[7] << 8 | cbw->command_block[8]);
635
            cur_cmd.orig_count = cur_cmd.count;
636
 
914 user890104 637
            if ((cur_cmd.sector + cur_cmd.count) > storage_info.num_sectors)
893 theseven 638
            {
639
                send_csw(1);
640
                cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
641
                cur_sense_data.asc = ASC_LBA_OUT_OF_RANGE;
642
                cur_sense_data.ascq = 0;
643
            }
644
            else send_and_read_next();
645
            break;
646
 
647
        case SCSI_WRITE_10:
648
            if (ejected)
649
            {
650
                send_command_failed_result();
651
                cur_sense_data.sense_key = SENSE_NOT_READY;
652
                cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
653
                cur_sense_data.ascq = 0;
654
                break;
655
            }
656
            cur_cmd.sector = (cbw->command_block[2] << 24 | cbw->command_block[3] << 16
657
                            | cbw->command_block[4] << 8 | cbw->command_block[5]);
658
            cur_cmd.count = (cbw->command_block[7] << 8 | cbw->command_block[8]);
659
            cur_cmd.orig_count = cur_cmd.count;
660
 
914 user890104 661
            if ((cur_cmd.sector + cur_cmd.count) > storage_info.num_sectors)
893 theseven 662
            {
663
                send_csw(1);
664
                cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
665
                cur_sense_data.asc = ASC_LBA_OUT_OF_RANGE;
666
                cur_sense_data.ascq = 0;
667
            }
914 user890104 668
            else {
669
                receive_block_data(storage_buffer, MIN(maxlen, cur_cmd.count * storage_info.sector_size));
670
            }
893 theseven 671
            break;
672
 
673
        case SCSI_WRITE_BUFFER:
674
            break;
675
 
676
        default:
677
            send_csw(1);
678
            cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
679
            cur_sense_data.asc = ASC_INVALID_COMMAND;
680
            cur_sense_data.ascq = 0;
681
            break;
682
    }
683
}
684
 
685
int handle_ctrl_request(const struct usb_instance* data, int interface, union usb_ep0_buffer* request, const void** response)
686
{
687
    int size = -1;
688
    switch (request->setup.bmRequestType.type)
689
    {
690
    case USB_SETUP_BMREQUESTTYPE_TYPE_CLASS:
691
        switch (request->setup.bRequest.raw)
692
        {
693
        case 0xfe:  // GET_MAX_LUN
694
            data->buffer->raw[0] = 0;
695
            size = 1;
696
            break;
697
        case 0xff:  // STORAGE_RESET
698
            size = 0;
699
            break;
700
        default: break;
701
        }
702
        break;
703
        default: break;
704
    }
705
    return size;
706
}
707
 
708
void handle_set_altsetting(const struct usb_instance* data, int interface, int altsetting)
709
{
710
    usb = data;
711
    state = WAITING_FOR_COMMAND;
712
    maxlen = maxpacket * MIN(usb_get_max_transfer_size(usb, outep), usb_get_max_transfer_size(usb, inep));
713
    usb_configure_ep(usb, outep, USB_ENDPOINT_TYPE_BULK, maxpacket);
714
    usb_configure_ep(usb, inep, USB_ENDPOINT_TYPE_BULK, maxpacket);
715
    listen();
716
}
717
 
718
void handle_unset_altsetting(const struct usb_instance* data, int interface, int altsetting)
719
{
720
    usb_unconfigure_ep(usb, outep);
721
    usb_unconfigure_ep(usb, inep);
722
}
723
 
724
int handle_ep_ctrl_request(const struct usb_instance* data, int interface, int endpoint, union usb_ep0_buffer* request, const void** response)
725
{
726
    int size = -1;
727
    switch (request->setup.bmRequestType.type)
728
    {
729
    case USB_SETUP_BMREQUESTTYPE_TYPE_STANDARD:
730
        switch (request->setup.bRequest.req)
731
        {
732
        case USB_SETUP_BREQUEST_CLEAR_FEATURE:
733
            if (request->setup.wLength || request->setup.wValue) break;
734
            listen();
735
            break;
736
        default: break;
737
        }
738
        break;
739
        default: break;
740
    }
741
    return size;
742
}
743
 
744
void handle_xfer_complete(const struct usb_instance* data, int ifnum, int epnum, int bytesleft)
745
{
746
    length -= bytesleft;
747
    switch (state)
748
    {
749
        case RECEIVING_BLOCKS:
914 user890104 750
            if (length != storage_info.sector_size * cur_cmd.count && length != maxlen) break;
893 theseven 751
 
914 user890104 752
            pending_op_start = cur_cmd.sector;
753
            pending_op_count = cur_cmd.count;
754
            pending_op = OP_WRITE;
755
            wakeup_signal(&pending_op_wakeup);
893 theseven 756
            break;
757
        case WAITING_FOR_CSW_COMPLETION:
758
            state = WAITING_FOR_COMMAND;
759
            listen();
760
            break;
761
        case WAITING_FOR_COMMAND:
762
            handle_scsi(&cbw);
763
            break;
764
        case SENDING_RESULT:
765
            send_csw(0);
766
            break;
767
        case SENDING_FAILED_RESULT:
768
            send_csw(1);
769
            break;
770
        case SENDING_BLOCKS:
771
            if (!cur_cmd.count) send_csw(0);
772
            else send_and_read_next();
773
            break;
774
    }
775
}
776
 
777
void handle_timeout(const struct usb_instance* data, int interface, int endpoint, int bytesleft)
778
{
779
    usb_set_stall(usb, outep, true);
780
    usb_set_stall(usb, inep, true);
781
}
782
 
783
static void handle_bus_reset(const struct usb_instance* data, int configuration, int interface, int highspeed)
784
{
785
    maxpacket = highspeed ? 512 : 64;
786
    usb_config1_descriptors.c1_i0_a0_e1out.wMaxPacketSize = maxpacket;
787
    usb_config1_descriptors.c1_i0_a0_e1in.wMaxPacketSize = maxpacket;
788
}
789
 
790
static struct usb_endpoint usb_c1_i0_a0_ep1out =
791
{
792
    .number = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_OUT },
793
    .ctrl_request = handle_ep_ctrl_request,
794
    .xfer_complete = handle_xfer_complete,
795
};
796
 
797
static struct usb_endpoint usb_c1_i0_a0_ep1in =
798
{
799
    .number = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_IN },
800
    .ctrl_request = handle_ep_ctrl_request,
801
    .xfer_complete = handle_xfer_complete,
802
    .timeout = handle_timeout,
803
};
804
 
805
static const struct usb_altsetting usb_c1_i0_a0 =
806
{
807
    .set_altsetting = handle_set_altsetting,
808
    .unset_altsetting = handle_unset_altsetting,
809
    .endpoint_count = 2,
810
    .endpoints =
811
    {
812
        &usb_c1_i0_a0_ep1out,
813
        &usb_c1_i0_a0_ep1in,
814
    },
815
};
816
 
817
static const struct usb_interface usb_c1_i0 =
818
{
819
    .bus_reset = handle_bus_reset,
820
    .ctrl_request = handle_ctrl_request,
821
    .altsetting_count = 1,
822
    .altsettings =
823
    {
824
        &usb_c1_i0_a0,
825
    },
826
};
827
 
828
static const struct usb_configuration usb_c1 =
829
{
830
    .descriptor = &usb_config1_descriptors.c1,
831
    .set_configuration = NULL,
832
    .unset_configuration = NULL,
833
    .interface_count = 1,
834
    .interfaces =
835
    {
836
        &usb_c1_i0,
837
    },
838
};
839
 
840
static const struct usb_configuration* usb_configurations[] =
841
{
842
    &usb_c1,
843
};
844
 
845
static void main(int argc, const char** argv)
846
{
914 user890104 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
 
893 theseven 854
    int i;
855
    uint32_t eps = usbmanager_get_available_endpoints();
856
    int ep_out = 0;
857
    int ep_in = 0;
858
    for (i = 1; i < 16; i++)
859
        if (eps & (1 << i))
860
        {
861
            ep_out = i;
862
            break;
863
        }
864
    for (i = 1; i < 16; i++)
865
        if (eps & (1 << (16 + i)))
866
        {
867
            ep_in = i;
868
            break;
869
        }
870
    if (!ep_out || !ep_in) panicf(PANIC_KILLTHREAD, "Not enough USB endpoints available!\n");
871
    usb_config1_descriptors.c1_i0_a0_e1out.bEndpointAddress.number = ep_out;
872
    usb_config1_descriptors.c1_i0_a0_e1in.bEndpointAddress.number = ep_in;
873
    usb_c1_i0_a0_ep1out.number.number = ep_out;
874
    usb_c1_i0_a0_ep1in.number.number = ep_in;
875
    outep.number = ep_out;
876
    inep.number = ep_in;
877
    int rc = usbmanager_install_custom(&usb_devicedescriptor, ARRAYLEN(usb_configurations), usb_configurations,
878
                                       ARRAYLEN(usb_stringdescriptors), usb_stringdescriptors, true);
914 user890104 879
    if (IS_ERR(rc)) {
880
        disk_mount(0);
881
        panicf(PANIC_KILLTHREAD, "Failed to register USB handler: %08X\n", rc);
882
    }
883
 
884
    wakeup_init(&pending_op_wakeup);
885
 
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
 
893 theseven 912
    usbmanager_uninstall_custom();
914 user890104 913
 
914
    disk_mount(0);
893 theseven 915
}
916
 
917
 
914 user890104 918
EMCORE_APP_HEADER("Disk mode", main, 127)