Subversion Repositories freemyipod

Rev

Rev 893 | Details | Compare with Previous | Last modification | View Log | RSS feed

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