Subversion Repositories freemyipod

Rev

Rev 918 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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