Subversion Repositories freemyipod

Rev

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

Rev Author Line No. Line
881 theseven 1
#include "global.h"
2
#include "app/umsboot/ums.h"
3
#include "app/umsboot/main.h"
4
#include "protocol/usb/usb.h"
5
#include "sys/util.h"
6
 
7
 
8
#define SCSI_TEST_UNIT_READY        0x00
9
#define SCSI_INQUIRY                0x12
10
#define SCSI_MODE_SENSE_6           0x1a
11
#define SCSI_MODE_SENSE_10          0x5a
12
#define SCSI_REQUEST_SENSE          0x03
13
#define SCSI_ALLOW_MEDIUM_REMOVAL   0x1e
14
#define SCSI_READ_CAPACITY          0x25
15
#define SCSI_READ_FORMAT_CAPACITY   0x23
16
#define SCSI_READ_10                0x28
17
#define SCSI_WRITE_10               0x2a
18
#define SCSI_START_STOP_UNIT        0x1b
19
#define SCSI_REPORT_LUNS            0xa0
20
#define SCSI_WRITE_BUFFER           0x3b
21
 
22
#define SENSE_NOT_READY             0x02
23
#define SENSE_MEDIUM_ERROR          0x03
24
#define SENSE_ILLEGAL_REQUEST       0x05
25
#define SENSE_UNIT_ATTENTION        0x06
26
 
27
#define ASC_MEDIUM_NOT_PRESENT      0x3a
28
#define ASC_INVALID_FIELD_IN_CBD    0x24
29
#define ASC_LBA_OUT_OF_RANGE        0x21
30
#define ASC_WRITE_ERROR             0x0C
31
#define ASC_READ_ERROR              0x11
32
#define ASC_NOT_READY               0x04
33
#define ASC_INVALID_COMMAND         0x20
34
 
35
#define ASCQ_BECOMING_READY         0x01
36
 
37
#define DIRECT_ACCESS_DEVICE        0x00
38
#define DEVICE_REMOVABLE            0x80
39
 
40
#define SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA 0x02000000
41
 
42
 
43
struct command_block_wrapper
44
{
45
    unsigned int signature;
46
    unsigned int tag;
47
    unsigned int data_transfer_length;
48
    unsigned char flags;
49
    unsigned char lun;
50
    unsigned char command_length;
51
    unsigned char command_block[16];
52
} __attribute__((packed));
53
 
54
struct command_status_wrapper
55
{
56
    unsigned int signature;
57
    unsigned int tag;
58
    unsigned int data_residue;
59
    unsigned char status;
60
} __attribute__((packed));
61
 
62
struct inquiry_data
63
{
64
    unsigned char DeviceType;
65
    unsigned char DeviceTypeModifier;
66
    unsigned char Versions;
67
    unsigned char Format;
68
    unsigned char AdditionalLength;
69
    unsigned char Reserved[2];
70
    unsigned char Capability;
71
    char VendorId[8];
72
    char ProductId[16];
73
    char ProductRevisionLevel[4];
74
} __attribute__((packed));
75
 
76
struct report_lun_data
77
{
78
    unsigned int lun_list_length;
79
    unsigned int reserved1;
80
    unsigned char luns[1][8];
81
} __attribute__((packed));
82
 
83
struct sense_data
84
{
85
    unsigned char ResponseCode;
86
    unsigned char Obsolete;
87
    unsigned char fei_sensekey;
88
    unsigned int Information;
89
    unsigned char AdditionalSenseLength;
90
    unsigned int  CommandSpecificInformation;
91
    unsigned char AdditionalSenseCode;
92
    unsigned char AdditionalSenseCodeQualifier;
93
    unsigned char FieldReplaceableUnitCode;
94
    unsigned char SKSV;
95
    unsigned short SenseKeySpecific;
96
} __attribute__((packed));
97
 
98
struct mode_sense_bdesc_longlba
99
{
100
    unsigned char num_blocks[8];
101
    unsigned char reserved[4];
102
    unsigned char block_size[4];
103
} __attribute__((packed));
104
 
105
struct mode_sense_bdesc_shortlba
106
{
107
    unsigned char density_code;
108
    unsigned char num_blocks[3];
109
    unsigned char reserved;
110
    unsigned char block_size[3];
111
} __attribute__((packed));
112
 
113
struct mode_sense_data_10
114
{
115
    unsigned short mode_data_length;
116
    unsigned char medium_type;
117
    unsigned char device_specific;
118
    unsigned char longlba;
119
    unsigned char reserved;
120
    unsigned short block_descriptor_length;
121
    struct mode_sense_bdesc_longlba block_descriptor;
122
} __attribute__((packed));
123
 
124
struct mode_sense_data_6
125
{
126
    unsigned char mode_data_length;
127
    unsigned char medium_type;
128
    unsigned char device_specific;
129
    unsigned char block_descriptor_length;
130
    struct mode_sense_bdesc_shortlba block_descriptor;
131
} __attribute__((packed));
132
 
133
struct capacity
134
{
135
    unsigned int block_count;
136
    unsigned int block_size;
137
} __attribute__((packed));
138
 
139
struct format_capacity
140
{
141
    unsigned int following_length;
142
    unsigned int block_count;
143
    unsigned int block_size;
144
} __attribute__((packed));
145
 
146
static union {
147
    struct inquiry_data inquiry;
148
    struct capacity capacity_data;
149
    struct format_capacity format_capacity_data;
150
    struct sense_data sense_data;
151
    struct mode_sense_data_6 ms_data_6;
152
    struct mode_sense_data_10 ms_data_10;
153
    struct report_lun_data lun_data;
154
    struct command_status_wrapper csw;
155
} tb __attribute__((section(".dmabss.tb"),aligned(CACHEALIGN_SIZE)));
156
 
157
static enum
158
{
159
    WAITING_FOR_COMMAND,
160
    SENDING_BLOCKS,
161
    SENDING_RESULT,
162
    SENDING_FAILED_RESULT,
163
    RECEIVING_BLOCKS,
164
    WAITING_FOR_CSW_COMPLETION
165
} state = WAITING_FOR_COMMAND;
166
 
167
static struct
168
{
169
    unsigned int sector;
170
    unsigned int count;
171
    unsigned int orig_count;
172
    unsigned int cur_cmd;
173
    unsigned int tag;
174
    unsigned int lun;
175
    unsigned int last_result;
176
} cur_cmd;
177
 
178
static struct
179
{
180
    unsigned char sense_key;
181
    unsigned char information;
182
    unsigned char asc;
183
    unsigned char ascq;
184
} cur_sense_data;
185
 
186
static const union usb_endpoint_number outep = { .number = UMSBOOT_ENDPOINT_OUT, .direction = USB_ENDPOINT_DIRECTION_OUT };
187
static const union usb_endpoint_number inep = { .number = UMSBOOT_ENDPOINT_IN, .direction = USB_ENDPOINT_DIRECTION_IN };
188
 
189
static struct command_block_wrapper cbw __attribute__((section(".dmabss.cbw"),aligned(CACHEALIGN_SIZE)));
190
static int maxpacket = 512;
191
static int maxlen;
192
static int length;
193
static bool locked;
194
static const struct usb_instance* usb;
195
volatile bool ums_ejected = false;
196
 
197
 
198
static void ums_listen()
199
{
200
    usb_start_rx(usb, outep, &cbw, sizeof(cbw));
201
}
202
 
203
static void send_csw(int status)
204
{
205
    tb.csw.signature = 0x53425355;
206
    tb.csw.tag = cur_cmd.tag;
207
    tb.csw.data_residue = 0;
208
    tb.csw.status = status;
209
 
210
    state = WAITING_FOR_CSW_COMPLETION;
211
    usb_start_tx(usb, inep, &tb.csw, sizeof(tb.csw));
212
 
213
    if (!status)
214
    {
215
        cur_sense_data.sense_key = 0;
216
        cur_sense_data.information = 0;
217
        cur_sense_data.asc = 0;
218
        cur_sense_data.ascq = 0;
219
    }
220
}
221
 
222
static void receive_block_data(void* data, int size)
223
{
224
    length = size;
225
    usb_start_rx(usb, outep, data, size);
226
    state = RECEIVING_BLOCKS;
227
}
228
 
229
static void send_block_data(void* data, int size)
230
{
231
    length = size;
232
    usb_start_tx(usb, inep, data, size);
233
    state = SENDING_BLOCKS;
234
}
235
 
236
static void send_command_result(void* data, int size)
237
{
238
    length = size;
239
    usb_start_tx(usb, inep, data, size);
240
    state = SENDING_RESULT;
241
}
242
 
243
static void send_command_failed_result()
244
{
245
    usb_start_tx(usb, inep, NULL, 0);
246
    state = SENDING_FAILED_RESULT;
247
}
248
 
249
static void send_and_read_next()
250
{
251
    if (cur_cmd.last_result)
252
    {
253
        send_csw(1);
254
        cur_sense_data.sense_key = SENSE_MEDIUM_ERROR;
255
        cur_sense_data.asc = ASC_READ_ERROR;
256
        cur_sense_data.ascq = 0;
257
        return;
258
    }
259
    send_block_data(RAMDISK[cur_cmd.sector], MIN(maxlen, cur_cmd.count * RAMDISK_SECTORSIZE));
260
 
261
    cur_cmd.sector += maxlen / RAMDISK_SECTORSIZE;
262
    cur_cmd.count -= MIN(cur_cmd.count, maxlen / RAMDISK_SECTORSIZE);
263
}
264
 
265
static void copy_padded(char* dest, char* src, int len)
266
{
267
   int i = 0;
268
   while (src[i] && i < len)
269
   {
270
      dest[i] = src[i];
271
      i++;
272
   }
273
   while(i < len) dest[i++] = ' ';
274
}
275
 
276
static void fill_inquiry()
277
{
278
    memset(&tb.inquiry, 0, sizeof(tb.inquiry));
279
    copy_padded(tb.inquiry.VendorId, "UMSboot", sizeof(tb.inquiry.VendorId));
280
    copy_padded(tb.inquiry.ProductId, "RAMDISK", sizeof(tb.inquiry.ProductId));
281
    copy_padded(tb.inquiry.ProductRevisionLevel, "0.2", sizeof(tb.inquiry.ProductRevisionLevel));
282
 
283
    tb.inquiry.DeviceType = DIRECT_ACCESS_DEVICE;
284
    tb.inquiry.AdditionalLength = 0x1f;
285
    tb.inquiry.Versions = 4;  // SPC-2
286
    tb.inquiry.Format = 2;  // SPC-2/3 inquiry format
287
    tb.inquiry.DeviceTypeModifier = DEVICE_REMOVABLE;
288
}
289
 
290
static void handle_scsi(struct command_block_wrapper* cbw)
291
{
292
    unsigned int length = cbw->data_transfer_length;
293
 
294
    if (cbw->signature != 0x43425355)
295
    {
296
        usb_set_stall(usb, outep, true);
297
        usb_set_stall(usb, inep, true);
298
        return;
299
    }
300
    cur_cmd.tag = cbw->tag;
301
    cur_cmd.lun = cbw->lun;
302
    cur_cmd.cur_cmd = cbw->command_block[0];
303
 
304
    switch (cbw->command_block[0])
305
    {
306
        case SCSI_TEST_UNIT_READY:
307
            if (!ums_ejected) send_csw(0);
308
            else
309
            {
310
                send_csw(1);
311
                cur_sense_data.sense_key = SENSE_NOT_READY;
312
                cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
313
                cur_sense_data.ascq = 0;
314
            }
315
            break;
316
 
317
        case SCSI_REPORT_LUNS:
318
        {
319
            memset(&tb.lun_data, 0, sizeof(struct report_lun_data));
320
            tb.lun_data.lun_list_length = 0x08000000;
321
            send_command_result(&tb.lun_data, MIN(16, length));
322
            break;
323
        }
324
 
325
        case SCSI_INQUIRY:
326
            fill_inquiry();
327
            length = MIN(length, cbw->command_block[4]);
328
            send_command_result(&tb.inquiry, MIN(sizeof(tb.inquiry), length));
329
            break;
330
 
331
        case SCSI_REQUEST_SENSE:
332
        {
333
            tb.sense_data.ResponseCode = 0x70;
334
            tb.sense_data.Obsolete = 0;
335
            tb.sense_data.fei_sensekey = cur_sense_data.sense_key & 0x0f;
336
            tb.sense_data.Information = cur_sense_data.information;
337
            tb.sense_data.AdditionalSenseLength = 10;
338
            tb.sense_data.CommandSpecificInformation = 0;
339
            tb.sense_data.AdditionalSenseCode = cur_sense_data.asc;
340
            tb.sense_data.AdditionalSenseCodeQualifier = cur_sense_data.ascq;
341
            tb.sense_data.FieldReplaceableUnitCode = 0;
342
            tb.sense_data.SKSV = 0;
343
            tb.sense_data.SenseKeySpecific = 0;
344
            send_command_result(&tb.sense_data, MIN(sizeof(tb.sense_data), length));
345
            break;
346
        }
347
 
348
        case SCSI_MODE_SENSE_10:
349
        {
350
            if (ums_ejected)
351
            {
352
                send_command_failed_result();
353
                cur_sense_data.sense_key = SENSE_NOT_READY;
354
                cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
355
                cur_sense_data.ascq = 0;
356
                break;
357
            }
358
            unsigned char page_code = cbw->command_block[2] & 0x3f;
359
            switch (page_code)
360
            {
361
                case 0x3f:
362
                    tb.ms_data_10.mode_data_length = htobe16(sizeof(tb.ms_data_10) - 2);
363
                    tb.ms_data_10.medium_type = 0;
364
                    tb.ms_data_10.device_specific = 0;
365
                    tb.ms_data_10.reserved = 0;
366
                    tb.ms_data_10.longlba = 1;
367
                    tb.ms_data_10.block_descriptor_length = htobe16(sizeof(tb.ms_data_10.block_descriptor));
368
 
369
                    memset(tb.ms_data_10.block_descriptor.reserved, 0, 4);
370
                    memset(tb.ms_data_10.block_descriptor.num_blocks, 0, 8);
371
 
372
                    tb.ms_data_10.block_descriptor.num_blocks[4] = (RAMDISK_SECTORS & 0xff000000) >> 24;
373
                    tb.ms_data_10.block_descriptor.num_blocks[5] = (RAMDISK_SECTORS & 0x00ff0000) >> 16;
374
                    tb.ms_data_10.block_descriptor.num_blocks[6] = (RAMDISK_SECTORS & 0x0000ff00) >> 8;
375
                    tb.ms_data_10.block_descriptor.num_blocks[7] = (RAMDISK_SECTORS & 0x000000ff);
376
 
377
                    tb.ms_data_10.block_descriptor.block_size[0] = (RAMDISK_SECTORSIZE & 0xff000000) >> 24;
378
                    tb.ms_data_10.block_descriptor.block_size[1] = (RAMDISK_SECTORSIZE & 0x00ff0000) >> 16;
379
                    tb.ms_data_10.block_descriptor.block_size[2] = (RAMDISK_SECTORSIZE & 0x0000ff00) >> 8;
380
                    tb.ms_data_10.block_descriptor.block_size[3] = (RAMDISK_SECTORSIZE & 0x000000ff);
381
                    send_command_result(&tb.ms_data_10, MIN(sizeof(tb.ms_data_10), length));
382
                    break;
383
                default:
384
                    send_command_failed_result();
385
                    cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
386
                    cur_sense_data.asc = ASC_INVALID_FIELD_IN_CBD;
387
                    cur_sense_data.ascq = 0;
388
                    break;
389
            }
390
            break;
391
        }
392
 
393
        case SCSI_MODE_SENSE_6:
394
        {
395
            if (ums_ejected)
396
            {
397
                send_command_failed_result();
398
                cur_sense_data.sense_key = SENSE_NOT_READY;
399
                cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
400
                cur_sense_data.ascq = 0;
401
                break;
402
            }
403
            unsigned char page_code = cbw->command_block[2] & 0x3f;
404
            switch (page_code)
405
            {
406
                case 0x3f:
407
                    tb.ms_data_6.mode_data_length = sizeof(tb.ms_data_6) - 1;
408
                    tb.ms_data_6.medium_type = 0;
409
                    tb.ms_data_6.device_specific = 0;
410
                    tb.ms_data_6.block_descriptor_length = sizeof(tb.ms_data_6.block_descriptor);
411
                    tb.ms_data_6.block_descriptor.density_code = 0;
412
                    tb.ms_data_6.block_descriptor.reserved = 0;
413
                    if (RAMDISK_SECTORS > 0xffffff)
414
                    {
415
                        tb.ms_data_6.block_descriptor.num_blocks[0] = 0xff;
416
                        tb.ms_data_6.block_descriptor.num_blocks[1] = 0xff;
417
                        tb.ms_data_6.block_descriptor.num_blocks[2] = 0xff;
418
                    }
419
                    else
420
                    {
421
                        tb.ms_data_6.block_descriptor.num_blocks[0] = (RAMDISK_SECTORS & 0xff0000) >> 16;
422
                        tb.ms_data_6.block_descriptor.num_blocks[1] = (RAMDISK_SECTORS & 0x00ff00) >> 8;
423
                        tb.ms_data_6.block_descriptor.num_blocks[2] = (RAMDISK_SECTORS & 0x0000ff);
424
                    }
425
                    tb.ms_data_6.block_descriptor.block_size[0] = (RAMDISK_SECTORSIZE & 0xff0000) >> 16;
426
                    tb.ms_data_6.block_descriptor.block_size[1] = (RAMDISK_SECTORSIZE & 0x00ff00) >> 8;
427
                    tb.ms_data_6.block_descriptor.block_size[2] = (RAMDISK_SECTORSIZE & 0x0000ff);
428
                    send_command_result(&tb.ms_data_6, MIN(sizeof(tb.ms_data_6), length));
429
                    break;
430
                default:
431
                    send_command_failed_result();
432
                    cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
433
                    cur_sense_data.asc = ASC_INVALID_FIELD_IN_CBD;
434
                    cur_sense_data.ascq = 0;
435
                    break;
436
            }
437
            break;
438
        }
439
 
440
        case SCSI_START_STOP_UNIT:
441
            if ((cbw->command_block[4] & 0xf3) == 2) ums_ejected = true;
442
            send_csw(0);
443
            break;
444
 
445
        case SCSI_ALLOW_MEDIUM_REMOVAL:
446
            if ((cbw->command_block[4] & 0x03) == 0) locked = false;
447
            else locked = true;
448
            send_csw(0);
449
            break;
450
 
451
        case SCSI_READ_FORMAT_CAPACITY:
452
        {
453
            if (!ums_ejected)
454
            {
455
                tb.format_capacity_data.following_length = 0x08000000;
456
                tb.format_capacity_data.block_count = htobe32(RAMDISK_SECTORS - 1);
457
                tb.format_capacity_data.block_size = htobe32(RAMDISK_SECTORSIZE);
458
                tb.format_capacity_data.block_size |= htobe32(SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA);
459
                send_command_result(&tb.format_capacity_data, MIN(sizeof(tb.format_capacity_data), length));
460
           }
461
           else
462
           {
463
               send_command_failed_result();
464
               cur_sense_data.sense_key = SENSE_NOT_READY;
465
               cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
466
               cur_sense_data.ascq = 0;
467
           }
468
           break;
469
        }
470
 
471
        case SCSI_READ_CAPACITY:
472
        {
473
            if (!ums_ejected)
474
            {
475
                tb.capacity_data.block_count = htobe32(RAMDISK_SECTORS - 1);
476
                tb.capacity_data.block_size = htobe32(RAMDISK_SECTORSIZE);
477
                send_command_result(&tb.capacity_data, MIN(sizeof(tb.capacity_data), length));
478
            }
479
            else
480
            {
481
                send_command_failed_result();
482
                cur_sense_data.sense_key = SENSE_NOT_READY;
483
                cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
484
                cur_sense_data.ascq = 0;
485
            }
486
            break;
487
        }
488
 
489
        case SCSI_READ_10:
490
            if (ums_ejected)
491
            {
492
                send_command_failed_result();
493
                cur_sense_data.sense_key = SENSE_NOT_READY;
494
                cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
495
                cur_sense_data.ascq = 0;
496
                break;
497
            }
498
            cur_cmd.sector = (cbw->command_block[2] << 24 | cbw->command_block[3] << 16
499
                            | cbw->command_block[4] << 8 | cbw->command_block[5]);
500
            cur_cmd.count = (cbw->command_block[7] << 8 | cbw->command_block[8]);
501
            cur_cmd.orig_count = cur_cmd.count;
502
 
503
            if ((cur_cmd.sector + cur_cmd.count) > RAMDISK_SECTORS)
504
            {
505
                send_csw(1);
506
                cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
507
                cur_sense_data.asc = ASC_LBA_OUT_OF_RANGE;
508
                cur_sense_data.ascq = 0;
509
            }
510
            else send_and_read_next();
511
            break;
512
 
513
        case SCSI_WRITE_10:
514
            if (ums_ejected)
515
            {
516
                send_command_failed_result();
517
                cur_sense_data.sense_key = SENSE_NOT_READY;
518
                cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
519
                cur_sense_data.ascq = 0;
520
                break;
521
            }
522
            cur_cmd.sector = (cbw->command_block[2] << 24 | cbw->command_block[3] << 16
523
                            | cbw->command_block[4] << 8 | cbw->command_block[5]);
524
            cur_cmd.count = (cbw->command_block[7] << 8 | cbw->command_block[8]);
525
            cur_cmd.orig_count = cur_cmd.count;
526
 
527
            if ((cur_cmd.sector + cur_cmd.count) > RAMDISK_SECTORS)
528
            {
529
                send_csw(1);
530
                cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
531
                cur_sense_data.asc = ASC_LBA_OUT_OF_RANGE;
532
                cur_sense_data.ascq = 0;
533
            }
534
            else
535
                receive_block_data(RAMDISK[cur_cmd.sector],
536
                                   MIN(maxlen, cur_cmd.count * RAMDISK_SECTORSIZE));
537
            break;
538
 
539
        case SCSI_WRITE_BUFFER:
540
            break;
541
 
542
        default:
543
            send_csw(1);
544
            cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
545
            cur_sense_data.asc = ASC_INVALID_COMMAND;
546
            cur_sense_data.ascq = 0;
547
            break;
548
    }
549
}
550
 
551
void ums_bus_reset(const struct usb_instance* data, int configuration, int interface, int highspeed)
552
{
553
    maxpacket = highspeed ? 512 : 64;
554
}
555
 
556
int ums_ctrl_request(const struct usb_instance* data, int interface, union usb_ep0_buffer* request, const void** response)
557
{
558
    int size = -1;
559
    switch (request->setup.bmRequestType.type)
560
    {
561
    case USB_SETUP_BMREQUESTTYPE_TYPE_CLASS:
562
        switch (request->setup.bRequest.raw)
563
        {
564
        case 0xfe:  // GET_MAX_LUN
565
            request->raw[0] = 0;
566
            *response = request;
567
            size = 1;
568
            break;
569
        case 0xff:  // STORAGE_RESET
570
            size = 0;
571
            break;
572
        default: break;
573
        }
574
        break;
575
        default: break;
576
    }
577
    return size;
578
}
579
 
580
void ums_set_altsetting(const struct usb_instance* data, int interface, int altsetting)
581
{
582
    usb = data;
583
    state = WAITING_FOR_COMMAND;
584
    maxlen = maxpacket * MIN(usb_get_max_transfer_size(usb, outep), usb_get_max_transfer_size(usb, inep));
585
    usb_configure_ep(usb, outep, USB_ENDPOINT_TYPE_BULK, maxpacket);
586
    usb_configure_ep(usb, inep, USB_ENDPOINT_TYPE_BULK, maxpacket);
587
    ums_listen();
588
}
589
 
590
void ums_unset_altsetting(const struct usb_instance* data, int interface, int altsetting)
591
{
592
    usb_unconfigure_ep(usb, outep);
593
    usb_unconfigure_ep(usb, inep);
594
}
595
 
596
int ums_ep_ctrl_request(const struct usb_instance* data, int interface, int endpoint, union usb_ep0_buffer* request, const void** response)
597
{
598
    int size = -1;
599
    switch (request->setup.bmRequestType.type)
600
    {
601
    case USB_SETUP_BMREQUESTTYPE_TYPE_STANDARD:
602
        switch (request->setup.bRequest.req)
603
        {
604
        case USB_SETUP_BREQUEST_CLEAR_FEATURE:
605
            if (request->setup.wLength || request->setup.wValue) break;
606
            ums_listen();
607
            break;
608
        default: break;
609
        }
610
        break;
611
        default: break;
612
    }
613
    return size;
614
}
615
 
616
void ums_xfer_complete(const struct usb_instance* data, int ifnum, int epnum, int bytesleft)
617
{
618
    length -= bytesleft;
619
    switch (state)
620
    {
621
        case RECEIVING_BLOCKS:
622
            if (length != RAMDISK_SECTORSIZE * cur_cmd.count && length != maxlen) break;
623
 
624
            cur_cmd.sector += (maxlen / RAMDISK_SECTORSIZE);
625
            cur_cmd.count -= MIN(cur_cmd.count, maxlen / RAMDISK_SECTORSIZE);
626
 
627
            if (cur_cmd.count)
628
                receive_block_data(RAMDISK[cur_cmd.sector],
629
                                   MIN(maxlen, cur_cmd.count * RAMDISK_SECTORSIZE));
630
            else send_csw(0);
631
            break;
632
        case WAITING_FOR_CSW_COMPLETION:
633
            state = WAITING_FOR_COMMAND;
634
            ums_listen();
635
            break;
636
        case WAITING_FOR_COMMAND:
637
            handle_scsi(&cbw);
638
            break;
639
        case SENDING_RESULT:
640
            send_csw(0);
641
            break;
642
        case SENDING_FAILED_RESULT:
643
            send_csw(1);
644
            break;
645
        case SENDING_BLOCKS:
646
            if (!cur_cmd.count) send_csw(0);
647
            else send_and_read_next();
648
            break;
649
    }
650
}
651
 
652
void ums_timeout(const struct usb_instance* data, int interface, int endpoint, int bytesleft)
653
{
654
    usb_set_stall(usb, outep, true);
655
    usb_set_stall(usb, inep, true);
656
}