Subversion Repositories freemyipod

Rev

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

Rev Author Line No. Line
924 theseven 1
//
2
//
3
//    Copyright 2013 TheSeven
4
//    Copyright 2014 user890104
5
//
6
//
7
//    This file is part of emCORE.
8
//
9
//    emCORE is free software: you can redistribute it and/or
10
//    modify it under the terms of the GNU General Public License as
11
//    published by the Free Software Foundation, either version 2 of the
12
//    License, or (at your option) any later version.
13
//
14
//    emCORE is distributed in the hope that it will be useful,
15
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
16
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
//    See the GNU General Public License for more details.
18
//
19
//    You should have received a copy of the GNU General Public License along
20
//    with emCORE.  If not, see <http://www.gnu.org/licenses/>.
21
//
22
//
23
 
24
 
25
#include "emcoreapp.h"
26
#include "ums.h"
27
#include "scsi.h"
28
#include "usb.h"
967 theseven 29
#include "../../emcore/trunk/target/ipodclassic/storage_ata-target.h"
924 theseven 30
 
31
 
32
#define UMS_BUFSIZE 65536
33
 
34
 
35
static struct
36
{
37
    unsigned int sector;
38
    unsigned int count;
39
    unsigned int orig_count;
40
    unsigned int cur_cmd;
41
    unsigned int tag;
42
    unsigned int lun;
43
    unsigned int last_result;
967 theseven 44
    unsigned int bytes_pending;
45
    bool data_direction;
924 theseven 46
} cur_cmd;
47
 
48
 
49
static struct
50
{
51
    unsigned char sense_key;
52
    unsigned char information;
53
    unsigned char asc;
54
    unsigned char ascq;
55
} cur_sense_data;
56
 
57
 
967 theseven 58
static enum
924 theseven 59
{
967 theseven 60
    SAT_PENDING_NONE = 0,
61
    SAT_PENDING_SRST,
62
    SAT_PENDING_HRST,
63
    SAT_PENDING_CMD,
64
    SAT_PENDING_READ_CDB,
65
} sat_pending = SAT_PENDING_NONE;
66
static struct ata_raw_cmd_t sat_command;
67
static struct __attribute__((packed)) sat_response_information
68
{
69
    uint8_t descriptor_code;
70
    uint8_t additional_length;
71
    uint8_t extend;
72
    uint8_t error;
73
    uint8_t sector_count_h;
74
    uint8_t sector_count_l;
75
    uint8_t lba_low_h;
76
    uint8_t lba_low_l;
77
    uint8_t lba_mid_h;
78
    uint8_t lba_mid_l;
79
    uint8_t lba_high_h;
80
    uint8_t lba_high_l;
81
    uint8_t device;
82
    uint8_t status;
83
} sat_response_information;
84
static bool have_sat_response_information = false;
85
static bool sat_check;
86
 
87
 
88
struct __attribute__((packed)) command_block_wrapper
89
{
924 theseven 90
    unsigned int signature;
91
    unsigned int tag;
92
    unsigned int data_transfer_length;
93
    unsigned char flags;
94
    unsigned char lun;
95
    unsigned char command_length;
96
    unsigned char command_block[16];
97
};
98
 
99
 
100
struct __attribute__((packed)) command_status_wrapper
101
{
102
    unsigned int signature;
103
    unsigned int tag;
104
    unsigned int data_residue;
105
    unsigned char status;
106
};
107
 
108
 
109
union __attribute__((aligned(32)))
110
{
111
    struct inquiry_data inquiry;
112
    struct capacity capacity_data;
113
    struct format_capacity format_capacity_data;
967 theseven 114
    struct sense_data_fixed sense_data_fixed;
115
    struct
116
    {
117
        struct sense_data_descr header;
118
        union
119
        {
120
            struct sat_response_information sat_response;
121
        } info;
122
    } sense_data_descr;
924 theseven 123
    struct mode_sense_data_6 ms_data_6;
124
    struct mode_sense_data_10 ms_data_10;
125
    struct report_lun_data lun_data;
126
    struct command_status_wrapper csw;
127
} tb;
128
 
129
 
130
static enum
131
{
132
    WAITING_FOR_COMMAND,
133
    SENDING_BLOCKS,
134
    SENDING_RESULT,
135
    RECEIVING_BLOCKS,
967 theseven 136
    WAITING_FOR_CSW_COMPLETION,
137
    RECEIVING_SAT_WRITE,
138
    PROCESSING,
924 theseven 139
} state = WAITING_FOR_COMMAND;
140
 
141
static uint32_t length;
142
static struct storage_info storage_info;
143
static uint8_t __attribute__((aligned(32))) umsbuf[2][2][UMS_BUFSIZE];
144
static union __attribute__((packed,aligned(32)))
145
{
146
    struct command_block_wrapper cbw;
147
    uint8_t dummy;
148
} cmdbuf;
149
static uint8_t readbuf_current;
150
static uint32_t readbuf_sector[2] = {0, 0};
151
static int8_t readbuf_count[2] = {0, 0};
152
static uint8_t read_blocked = false;
153
static uint8_t writebuf_current;
154
static uint32_t writebuf_sector;
155
static uint8_t writebuf_count;
156
static uint8_t writebuf_busy = false;
157
static uint8_t writebuf_overrun = false;
158
static uint32_t write_rc = 0;
159
static bool locked = false;
160
 
161
 
162
bool ums_ejected = false;
163
 
164
 
165
static void listen()
166
{
167
    usb_receive(&cmdbuf.cbw, sizeof(cmdbuf.cbw));
168
}
169
 
170
 
171
void ums_listen()
172
{
173
    state = WAITING_FOR_COMMAND;
174
    listen();
175
}
176
 
177
 
178
static void send_csw(int status)
179
{
967 theseven 180
    if (cur_cmd.bytes_pending)
181
    {
182
        if (cur_cmd.data_direction) usb_stall_in();
183
        else usb_stall_out();
184
    }
185
 
924 theseven 186
    tb.csw.signature = 0x53425355;
187
    tb.csw.tag = cur_cmd.tag;
967 theseven 188
    tb.csw.data_residue = cur_cmd.bytes_pending;
924 theseven 189
    tb.csw.status = status;
190
 
191
    state = WAITING_FOR_CSW_COMPLETION;
192
    usb_transmit(&tb.csw, sizeof(tb.csw));
193
 
194
    if (!status)
195
    {
196
        cur_sense_data.sense_key = 0;
197
        cur_sense_data.information = 0;
198
        cur_sense_data.asc = 0;
199
        cur_sense_data.ascq = 0;
200
    }
201
}
202
 
203
 
204
static void receive_block_data(void* data, int size)
205
{
967 theseven 206
    if (cur_cmd.data_direction) fail("diskmode: Attempting to receive data for IN command!");
207
    else if (size > cur_cmd.bytes_pending) fail("diskmode: Receive overrun!");
208
    else
209
    {
210
        cur_cmd.bytes_pending -= size;
211
        length = size;
212
        usb_receive(data, size);
213
        state = RECEIVING_BLOCKS;
214
    }
924 theseven 215
}
216
 
217
 
967 theseven 218
static void receive_sat_write(void* data, int size)
219
{
220
    if (cur_cmd.data_direction) fail("diskmode: Attempting to receive data for SAT IN command!");
221
    else if (size > cur_cmd.bytes_pending) fail("diskmode: Receive SAT overrun!");
222
    else
223
    {
224
        cur_cmd.bytes_pending -= size;
225
        length = size;
226
        usb_receive(data, size);
227
        state = RECEIVING_SAT_WRITE;
228
    }
229
}
230
 
231
 
924 theseven 232
static void send_block_data(void* data, int size)
233
{
967 theseven 234
    if (!cur_cmd.data_direction) fail("diskmode: Attempting to send data for OUT command!");
235
    else if (size > cur_cmd.bytes_pending) fail("diskmode: Send block overrun!");
236
    else
237
    {
238
        cur_cmd.bytes_pending -= size;
239
        length = size;
240
        usb_transmit(data, size);
241
        state = SENDING_BLOCKS;
242
    }
924 theseven 243
}
244
 
245
 
246
static void send_command_result(void* data, int size)
247
{
967 theseven 248
    if (!cur_cmd.data_direction) fail("diskmode: Attempting to send result for OUT command!");
249
    else if (size > cur_cmd.bytes_pending) fail("diskmode: Send result overrun!");
250
    else
251
    {
252
        cur_cmd.bytes_pending -= size;
253
        length = size;
254
        usb_transmit(data, size);
255
        state = SENDING_RESULT;
256
    }
924 theseven 257
}
258
 
259
 
967 theseven 260
static void send_command_failed_result(unsigned char key, unsigned char asc, unsigned char ascq)
924 theseven 261
{
967 theseven 262
    send_csw(1);
263
    cur_sense_data.sense_key = key;
264
    cur_sense_data.asc = asc;
265
    cur_sense_data.ascq = ascq;
924 theseven 266
}
267
 
268
 
269
static void send_and_read_next()
270
{
271
    int bufsize = UMS_BUFSIZE / storage_info.sector_size;
272
    int i;
273
    for (i = 0; i < 2; i++)
274
    {
275
        if (readbuf_sector[i] <= cur_cmd.sector && readbuf_sector[i] + bufsize > cur_cmd.sector)
276
        {
277
            if (readbuf_sector[i] + readbuf_count[i] <= cur_cmd.sector)
278
            {
279
                readbuf_current = i;
280
                read_blocked = true;
281
                enqueue_async();
282
                return;
283
            }
284
            int overlap = MIN(readbuf_sector[i] + readbuf_count[i] - cur_cmd.sector, cur_cmd.count);
285
            if (i == readbuf_current && readbuf_sector[i] + readbuf_count[i] < storage_info.num_sectors)
286
            {
287
                readbuf_current = !i;
288
                readbuf_sector[!i] = MAX(readbuf_sector[i] + readbuf_count[i], cur_cmd.sector + overlap);
289
                readbuf_count[!i] = 0;
290
                enqueue_async();
291
            }
292
            int offset = (cur_cmd.sector - readbuf_sector[i]) * storage_info.sector_size;
293
            send_block_data(umsbuf[0][i] + offset, overlap * storage_info.sector_size);
294
            cur_cmd.sector += overlap;
295
            cur_cmd.count -= overlap;
296
            return;
297
        }
298
    }
299
    readbuf_current ^= 1;
300
    readbuf_sector[readbuf_current] = cur_cmd.sector;
301
    readbuf_count[readbuf_current] = 0;
302
    read_blocked = true;
303
    enqueue_async();
304
}
305
 
306
 
307
static void copy_padded(char* dest, char* src, int len)
308
{
309
   int i = 0;
310
   while (src[i] && i < len)
311
   {
312
      dest[i] = src[i];
313
      i++;
314
   }
315
   while(i < len) dest[i++] = ' ';
316
}
317
 
318
 
319
static void fill_inquiry()
320
{
321
    memset(&tb.inquiry, 0, sizeof(tb.inquiry));
322
    copy_padded(tb.inquiry.VendorId, storage_info.vendor, sizeof(tb.inquiry.VendorId));
323
    copy_padded(tb.inquiry.ProductId, storage_info.product, sizeof(tb.inquiry.ProductId));
324
    copy_padded(tb.inquiry.ProductRevisionLevel, storage_info.revision, sizeof(tb.inquiry.ProductRevisionLevel));
325
 
326
    tb.inquiry.DeviceType = DIRECT_ACCESS_DEVICE;
327
    tb.inquiry.AdditionalLength = 0x1f;
328
    tb.inquiry.Versions = 4;  // SPC-2
329
    tb.inquiry.Format = 2;  // SPC-2/3 inquiry format
330
    tb.inquiry.DeviceTypeModifier = DEVICE_REMOVABLE;
331
}
332
 
333
 
334
static void handle_scsi(struct command_block_wrapper* cbw)
335
{
336
    unsigned int length = cbw->data_transfer_length;
337
 
338
    if (cbw->signature != 0x43425355)
339
    {
967 theseven 340
        usb_stall_in();
341
        usb_stall_out();
924 theseven 342
        return;
343
    }
344
    cur_cmd.tag = cbw->tag;
345
    cur_cmd.lun = cbw->lun;
346
    cur_cmd.cur_cmd = cbw->command_block[0];
967 theseven 347
    cur_cmd.bytes_pending = cbw->data_transfer_length;
348
    if (cbw->flags & 0x80) cur_cmd.data_direction = 1;
349
    else cur_cmd.data_direction = 0;
924 theseven 350
 
351
    switch (cbw->command_block[0])
352
    {
353
        case SCSI_TEST_UNIT_READY:
354
            if (!ums_ejected) send_csw(0);
967 theseven 355
            else send_command_failed_result(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0);
924 theseven 356
            break;
357
 
358
        case SCSI_REPORT_LUNS:
359
        {
360
            memset(&tb.lun_data, 0, sizeof(struct report_lun_data));
361
            tb.lun_data.lun_list_length = 0x08000000;
362
            send_command_result(&tb.lun_data, MIN(16, length));
363
            break;
364
        }
365
 
366
        case SCSI_INQUIRY:
367
            fill_inquiry();
368
            length = MIN(length, cbw->command_block[4]);
369
            send_command_result(&tb.inquiry, MIN(sizeof(tb.inquiry), length));
370
            break;
371
 
372
        case SCSI_REQUEST_SENSE:
373
        {
967 theseven 374
            if (have_sat_response_information)
375
            {
376
                memset(&tb.sense_data_descr.header, 0, sizeof(tb.sense_data_descr.header));
377
                tb.sense_data_descr.header.ResponseCode = 0x72;
378
                tb.sense_data_descr.header.fei_sensekey = cur_sense_data.sense_key & 0x0f;
379
                tb.sense_data_descr.header.AdditionalSenseCode = cur_sense_data.asc;
380
                tb.sense_data_descr.header.AdditionalSenseCodeQualifier = cur_sense_data.ascq;
381
                tb.sense_data_descr.header.AdditionalSenseLength = sizeof(sat_response_information);
382
                memcpy(&tb.sense_data_descr.info.sat_response, &sat_response_information, sizeof(sat_response_information));
383
                send_command_result(&tb.sense_data_descr, MIN(sizeof(tb.sense_data_descr.header) + sizeof(sat_response_information), length));
384
            }
385
            else
386
            {
387
                tb.sense_data_fixed.ResponseCode = 0x70;
388
                tb.sense_data_fixed.Obsolete = 0;
389
                tb.sense_data_fixed.fei_sensekey = cur_sense_data.sense_key & 0x0f;
390
                tb.sense_data_fixed.Information = cur_sense_data.information;
391
                tb.sense_data_fixed.AdditionalSenseLength = 10;
392
                tb.sense_data_fixed.CommandSpecificInformation = 0;
393
                tb.sense_data_fixed.AdditionalSenseCode = cur_sense_data.asc;
394
                tb.sense_data_fixed.AdditionalSenseCodeQualifier = cur_sense_data.ascq;
395
                tb.sense_data_fixed.FieldReplaceableUnitCode = 0;
396
                tb.sense_data_fixed.SKSV = 0;
397
                tb.sense_data_fixed.SenseKeySpecific = 0;
398
                send_command_result(&tb.sense_data_fixed, MIN(sizeof(tb.sense_data_fixed), length));
399
            }
924 theseven 400
            break;
401
        }
402
 
403
        case SCSI_MODE_SENSE_10:
404
        {
967 theseven 405
            if (ums_ejected) 
924 theseven 406
            {
967 theseven 407
                send_command_failed_result(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0);
924 theseven 408
                break;
409
            }
410
            unsigned char page_code = cbw->command_block[2] & 0x3f;
411
            switch (page_code)
412
            {
413
                case 0x3f:
414
                    tb.ms_data_10.mode_data_length = htobe16(sizeof(tb.ms_data_10) - 2);
415
                    tb.ms_data_10.medium_type = 0;
416
                    tb.ms_data_10.device_specific = 0;
417
                    tb.ms_data_10.reserved = 0;
418
                    tb.ms_data_10.longlba = 1;
419
                    tb.ms_data_10.block_descriptor_length = htobe16(sizeof(tb.ms_data_10.block_descriptor));
420
 
421
                    memset(tb.ms_data_10.block_descriptor.reserved, 0, 4);
422
                    memset(tb.ms_data_10.block_descriptor.num_blocks, 0, 8);
423
 
424
                    tb.ms_data_10.block_descriptor.num_blocks[4] = (storage_info.num_sectors & 0xff000000) >> 24;
425
                    tb.ms_data_10.block_descriptor.num_blocks[5] = (storage_info.num_sectors & 0x00ff0000) >> 16;
426
                    tb.ms_data_10.block_descriptor.num_blocks[6] = (storage_info.num_sectors & 0x0000ff00) >> 8;
427
                    tb.ms_data_10.block_descriptor.num_blocks[7] = (storage_info.num_sectors & 0x000000ff);
428
 
429
                    tb.ms_data_10.block_descriptor.block_size[0] = (storage_info.sector_size & 0xff000000) >> 24;
430
                    tb.ms_data_10.block_descriptor.block_size[1] = (storage_info.sector_size & 0x00ff0000) >> 16;
431
                    tb.ms_data_10.block_descriptor.block_size[2] = (storage_info.sector_size & 0x0000ff00) >> 8;
432
                    tb.ms_data_10.block_descriptor.block_size[3] = (storage_info.sector_size & 0x000000ff);
433
                    send_command_result(&tb.ms_data_10, MIN(sizeof(tb.ms_data_10), length));
434
                    break;
435
                default:
967 theseven 436
                    send_command_failed_result(SENSE_ILLEGAL_REQUEST, ASC_INVALID_FIELD_IN_CBD, 0);
924 theseven 437
                    break;
438
            }
439
            break;
440
        }
441
 
442
        case SCSI_MODE_SENSE_6:
443
        {
444
            if (ums_ejected)
445
            {
967 theseven 446
                send_command_failed_result(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0);
924 theseven 447
                break;
448
            }
449
            unsigned char page_code = cbw->command_block[2] & 0x3f;
450
            switch (page_code)
451
            {
452
                case 0x3f:
453
                    tb.ms_data_6.mode_data_length = sizeof(tb.ms_data_6) - 1;
454
                    tb.ms_data_6.medium_type = 0;
455
                    tb.ms_data_6.device_specific = 0;
456
                    tb.ms_data_6.block_descriptor_length = sizeof(tb.ms_data_6.block_descriptor);
457
                    tb.ms_data_6.block_descriptor.density_code = 0;
458
                    tb.ms_data_6.block_descriptor.reserved = 0;
459
                    if (storage_info.num_sectors > 0xffffff)
460
                    {
461
                        tb.ms_data_6.block_descriptor.num_blocks[0] = 0xff;
462
                        tb.ms_data_6.block_descriptor.num_blocks[1] = 0xff;
463
                        tb.ms_data_6.block_descriptor.num_blocks[2] = 0xff;
464
                    }
465
                    else
466
                    {
467
                        tb.ms_data_6.block_descriptor.num_blocks[0] = (storage_info.num_sectors & 0xff0000) >> 16;
468
                        tb.ms_data_6.block_descriptor.num_blocks[1] = (storage_info.num_sectors & 0x00ff00) >> 8;
469
                        tb.ms_data_6.block_descriptor.num_blocks[2] = (storage_info.num_sectors & 0x0000ff);
470
                    }
471
                    tb.ms_data_6.block_descriptor.block_size[0] = (storage_info.sector_size & 0xff0000) >> 16;
472
                    tb.ms_data_6.block_descriptor.block_size[1] = (storage_info.sector_size & 0x00ff00) >> 8;
473
                    tb.ms_data_6.block_descriptor.block_size[2] = (storage_info.sector_size & 0x0000ff);
474
                    send_command_result(&tb.ms_data_6, MIN(sizeof(tb.ms_data_6), length));
475
                    break;
476
                default:
967 theseven 477
                    send_command_failed_result(SENSE_ILLEGAL_REQUEST, ASC_INVALID_FIELD_IN_CBD, 0);
924 theseven 478
                    break;
479
            }
480
            break;
481
        }
482
 
483
        case SCSI_START_STOP_UNIT:
484
            if ((cbw->command_block[4] & 0xf3) == 2) ums_ejected = true;
485
            send_csw(0);
486
            break;
487
 
488
        case SCSI_ALLOW_MEDIUM_REMOVAL:
489
            if ((cbw->command_block[4] & 0x03) == 0) locked = false;
490
            else locked = true;
491
            send_csw(0);
492
            break;
493
 
494
        case SCSI_READ_FORMAT_CAPACITY:
495
        {
496
            if (!ums_ejected)
497
            {
498
                tb.format_capacity_data.following_length = 0x08000000;
499
                tb.format_capacity_data.block_count = swap32(storage_info.num_sectors - 1);
500
                tb.format_capacity_data.block_size = swap32(storage_info.sector_size);
501
                tb.format_capacity_data.block_size |= swap32(SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA);
502
                send_command_result(&tb.format_capacity_data, MIN(sizeof(tb.format_capacity_data), length));
503
           }
967 theseven 504
           else send_command_failed_result(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0);
924 theseven 505
           break;
506
        }
507
 
508
        case SCSI_READ_CAPACITY:
509
        {
510
            if (!ums_ejected)
511
            {
512
                tb.capacity_data.block_count = swap32(storage_info.num_sectors - 1);
513
                tb.capacity_data.block_size = swap32(storage_info.sector_size);
514
                send_command_result(&tb.capacity_data, MIN(sizeof(tb.capacity_data), length));
515
            }
967 theseven 516
            else send_command_failed_result(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0);
924 theseven 517
            break;
518
        }
519
 
520
        case SCSI_READ_10:
521
            if (ums_ejected)
522
            {
967 theseven 523
                send_command_failed_result(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0);
924 theseven 524
                break;
525
            }
526
            cur_cmd.sector = (cbw->command_block[2] << 24 | cbw->command_block[3] << 16
527
                            | cbw->command_block[4] << 8 | cbw->command_block[5]);
528
            cur_cmd.count = (cbw->command_block[7] << 8 | cbw->command_block[8]);
529
            cur_cmd.orig_count = cur_cmd.count;
530
 
531
            if ((cur_cmd.sector + cur_cmd.count) > storage_info.num_sectors)
967 theseven 532
                send_command_failed_result(SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0);
924 theseven 533
            else if (!cur_cmd.count) send_csw(0);
534
            else send_and_read_next();
535
            break;
536
 
537
        case SCSI_WRITE_10:
538
            if (ums_ejected)
539
            {
967 theseven 540
                send_command_failed_result(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0);
924 theseven 541
                break;
542
            }
543
            cur_cmd.sector = (cbw->command_block[2] << 24 | cbw->command_block[3] << 16
544
                            | cbw->command_block[4] << 8 | cbw->command_block[5]);
545
            cur_cmd.count = (cbw->command_block[7] << 8 | cbw->command_block[8]);
546
            cur_cmd.orig_count = cur_cmd.count;
547
 
548
            if ((cur_cmd.sector + cur_cmd.count) > storage_info.num_sectors)
967 theseven 549
                send_command_failed_result(SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0);
924 theseven 550
            else if (!cur_cmd.count) send_csw(0);
551
            else
552
                receive_block_data(umsbuf[1][!writebuf_current],
553
                                   MIN(UMS_BUFSIZE, cur_cmd.count * storage_info.sector_size));
554
            break;
555
 
556
        case SCSI_WRITE_BUFFER:
557
            break;
967 theseven 558
 
559
        case SCSI_ATA_PASSTHROUGH_12:
560
        case SCSI_ATA_PASSTHROUGH_16:
561
        {
562
            if (!storage_info.driverinfo || get_platform_id() != 0x4c435049)
563
            {
564
                send_command_failed_result(SENSE_ILLEGAL_REQUEST, ASC_INVALID_COMMAND, 0);
565
                break;
566
            }
567
            int cmd = cbw->command_block[0];
568
            int multi = cbw->command_block[1] >> 5;
569
            int protocol = (cbw->command_block[1] >> 1) & 0xf;
570
            int extend = 0;
571
            int offline = cbw->command_block[2] >> 6;
572
            int check = (cbw->command_block[2] >> 5) & 1;
573
            int type = (cbw->command_block[2] >> 4) & 1;
574
            int dir = (cbw->command_block[2] >> 3) & 1;
575
            int block = (cbw->command_block[2] >> 2) & 1;
576
            int len = cbw->command_block[2] & 3;
577
            int features = cbw->command_block[3];
578
            int count = cbw->command_block[4];
579
            int lbal = cbw->command_block[5];
580
            int lbam = cbw->command_block[6];
581
            int lbah = cbw->command_block[7];
582
            int device = cbw->command_block[8] & ~0x10;
583
            int command = cbw->command_block[9];
584
            int control = cbw->command_block[11];
585
            if (cmd == SCSI_ATA_PASSTHROUGH_16)
586
            {
587
                extend = cbw->command_block[1] & 1;
588
                features = (extend ? (cbw->command_block[3] << 8) : 0) | cbw->command_block[4];
589
                count = (extend ? (cbw->command_block[5] << 8) : 0) | cbw->command_block[6];
590
                lbal = (extend ? (cbw->command_block[7] << 8) : 0) | cbw->command_block[8];
591
                lbam = (extend ? (cbw->command_block[9] << 8) : 0) | cbw->command_block[10];
592
                lbah = (extend ? (cbw->command_block[11] << 8) : 0) | cbw->command_block[12];
593
                device = cbw->command_block[13] & ~0x10;
594
                command = cbw->command_block[14];
595
                control = cbw->command_block[15];
596
            }
597
            sat_command.lba48 = extend;
598
            sat_check = check;
599
            int delay = (2 << offline) - 2;
600
            int bytes = 0;
601
            switch (len)
602
            {
603
                case 1: bytes = features; break;
604
                case 2: bytes = count; break;
605
                case 3: bytes = length; break;
606
            }
607
            int blocks = 1;
608
            if (block)
609
            {
610
                blocks = bytes;
611
                bytes = type ? storage_info.sector_size : 512;
612
            }
613
            int invalid = blocks * bytes > UMS_BUFSIZE;
614
            int dma = 0;
615
            switch (protocol)
616
            {
617
                case SAT_HARD_RESET:
618
                    sat_pending = SAT_PENDING_HRST;
619
                    enqueue_async();
620
                    return;
621
                case SAT_SOFT_RESET:
622
                    sat_pending = SAT_PENDING_SRST;
623
                    enqueue_async();
624
                    return;
625
                case SAT_NON_DATA:
626
                    if (len) invalid = 1;
627
                    break;
628
                case SAT_PIO_DATA_IN:
629
                    if (!len || !dir) invalid = 1;
630
                    break;
631
                case SAT_PIO_DATA_OUT:
632
                    if (!len || dir) invalid = 1;
633
                    break;
634
                case SAT_UDMA_DATA_IN:
635
                    if (!len || !dir) invalid = 1;
636
                    dma = 1;
637
                    break;
638
                case SAT_UDMA_DATA_OUT:
639
                    if (!len || dir) invalid = 1;
640
                    dma = 1;
641
                    break;
642
                case SAT_RETURN_RESPONSE:
643
                    sat_pending = SAT_PENDING_READ_CDB;
644
                    enqueue_async();
645
                    return;
646
                //case SAT_NON_DATA_RESET:
647
                //case SAT_DMA:
648
                //case SAT_DMA_QUEUED:
649
                //case SAT_FPDMA:
650
                //case SAT_DIAGNOSTIC:
651
                default:
652
                    invalid = 1;
653
                    break;
654
            }
655
            if (invalid)
656
            {
657
                send_command_failed_result(SENSE_ILLEGAL_REQUEST, ASC_INVALID_FIELD_IN_CBD, 0);
658
                return;
659
            }
660
            readbuf_count[!readbuf_current] = 0;
661
            void* buffer = umsbuf[0][!readbuf_current];
662
            sat_command.transfer = !!len;
663
            sat_command.send = !dir;
664
            sat_command.dma = dma;
665
            sat_command.delay = delay * 1000000;
666
            sat_command.buffer = buffer;
667
            sat_command.size = blocks;
668
            sat_command.blksize = bytes;
669
            sat_command.feature = features;
670
            sat_command.count = count;
671
            sat_command.lba_low = lbal;
672
            sat_command.lba_mid = lbam;
673
            sat_command.lba_high = lbah;
674
            sat_command.device = device;
675
            sat_command.command = command;
676
            if (len && !dir) receive_sat_write(buffer, bytes * blocks);
677
            else
678
            {
679
                sat_pending = SAT_PENDING_CMD;
680
                enqueue_async();
681
            }
682
            break;
683
        }
684
 
924 theseven 685
        default:
967 theseven 686
            send_command_failed_result(SENSE_ILLEGAL_REQUEST, ASC_INVALID_COMMAND, 0);
924 theseven 687
            break;
688
    }
967 theseven 689
    have_sat_response_information = false;
924 theseven 690
}
691
 
692
 
693
void ums_init()
694
{
695
    storage_get_info(0, &storage_info);
696
    if (!storage_info.sector_size) panicf(PANIC_KILLTHREAD, "Sector size is zero!\n");
697
    if (!storage_info.num_sectors) panicf(PANIC_KILLTHREAD, "Number of sectors is zero!\n");
698
}
699
 
700
 
701
void update_readcache()
702
{
703
    int count = length / storage_info.sector_size;
704
    int i;
705
    for (i = 0; i < 2; i++)
706
        if ((readbuf_sector[i] <= cur_cmd.sector && readbuf_sector[i] + readbuf_count[i] > cur_cmd.sector)
707
         || (readbuf_sector[i] <= cur_cmd.sector + count
708
          && readbuf_sector[i] + readbuf_count[i] > cur_cmd.sector + count))
709
        {
710
            int roffset = MAX(0, (int)(cur_cmd.sector - readbuf_sector[i]));
711
            int woffset = MAX(0, (int)(readbuf_sector[i] - cur_cmd.sector));
712
            int len = MIN(readbuf_count[i] - roffset, count - woffset);
713
            roffset *= storage_info.sector_size;
714
            woffset *= storage_info.sector_size;
715
            len *= storage_info.sector_size;
716
            memcpy(umsbuf[0][i] + roffset, umsbuf[1][writebuf_current] + woffset, len);
717
        }
718
}
719
 
720
 
721
static void writebuf_push()
722
{
723
    int count = length / storage_info.sector_size;
724
    writebuf_current ^= 1;
725
    writebuf_sector = cur_cmd.sector;
726
    cur_cmd.sector += count;
727
    writebuf_count = count;
728
    cur_cmd.count -= count;
729
    writebuf_busy = true;
730
    int remaining = cur_cmd.count * storage_info.sector_size;
731
    if (!cur_cmd.count)
732
    {
733
        if (IS_ERR(write_rc))
734
        {
967 theseven 735
            send_command_failed_result(SENSE_MEDIUM_ERROR, ASC_WRITE_ERROR, 0);
736
            return;
924 theseven 737
        }
738
        send_csw(0);
739
        write_rc = 0;
740
    }
741
    else receive_block_data(umsbuf[1][!writebuf_current], MIN(UMS_BUFSIZE, remaining));
742
}
743
 
744
 
745
void ums_xfer_complete(bool in, int bytesleft)
746
{
747
    length -= bytesleft;
967 theseven 748
    if (in)
749
        switch (state)
750
        {
751
            case WAITING_FOR_CSW_COMPLETION:
752
                state = WAITING_FOR_COMMAND;
753
                listen();
754
                break;
755
            case SENDING_RESULT:
756
                send_csw(0);
757
                break;
758
            case SENDING_BLOCKS:
759
                if (!cur_cmd.count) send_csw(0);
760
                else send_and_read_next();
761
                break;
762
            default:
763
                fail("diskmode: Got IN completion in invalid state!");
764
        }
765
    else
766
        switch (state)
767
        {
768
            case RECEIVING_BLOCKS:
769
                if (length != storage_info.sector_size * cur_cmd.count && length != UMS_BUFSIZE) break;
770
                update_readcache();
771
                if (!writebuf_busy) writebuf_push();
772
                else writebuf_overrun = true;
773
                enqueue_async();
774
                break;
775
            case WAITING_FOR_COMMAND:
776
                state = PROCESSING;
777
                invalidate_dcache(&cmdbuf, sizeof(cmdbuf));  // Who pulls this into a cache line!?
778
                handle_scsi(&cmdbuf.cbw);
779
                break;
780
            case RECEIVING_SAT_WRITE:
781
                state = PROCESSING;
782
                sat_pending = SAT_PENDING_CMD;
783
                enqueue_async();
784
                break;
785
            default:
786
                fail("diskmode: Got OUT completion in invalid state!");
787
        }
924 theseven 788
}
789
 
790
void ums_handle_async()
791
{
792
    if (writebuf_overrun)
793
    {
794
        writebuf_overrun = false;
795
        writebuf_push();
796
    }
797
    if (writebuf_busy)
798
    {
799
        write_rc |= storage_write_sectors_md(0, writebuf_sector, writebuf_count, umsbuf[1][writebuf_current]);
800
        writebuf_busy = false;
801
    }
802
 
803
    int c = readbuf_current;        
804
    if (!readbuf_count[c])
805
    {
806
        int sector = readbuf_sector[c];
807
        int count = MIN(UMS_BUFSIZE / storage_info.sector_size, storage_info.num_sectors - sector);
808
        if (IS_ERR(storage_read_sectors_md(0, sector, count, umsbuf[0][c]))) count = -1;
809
        if (sector == readbuf_sector[c]) readbuf_count[c] = count;
810
        if (sector != readbuf_sector[c]) readbuf_count[c] = 0;  // Extremely ugly hack to neutralize race condition
811
    }
812
    if (read_blocked)
813
    {
814
        read_blocked = false;
815
        if (readbuf_count[readbuf_current] < 0)
967 theseven 816
            send_command_failed_result(SENSE_MEDIUM_ERROR, ASC_READ_ERROR, 0);
817
        else send_and_read_next();
818
    }
819
 
820
    struct ata_target_driverinfo* drv = storage_info.driverinfo;
821
    switch (sat_pending)
822
    {
823
        case SAT_PENDING_SRST:
924 theseven 824
        {
967 theseven 825
            sat_pending = SAT_PENDING_NONE;
826
            if (IS_ERR(drv->soft_reset()))
827
                send_command_failed_result(SENSE_HARDWARE_ERROR, ASC_UNSUCCESSFUL_SOFT_RESET, 0);
828
            else send_csw(0);
829
            break;
924 theseven 830
        }
967 theseven 831
        case SAT_PENDING_HRST:
832
        {
833
            sat_pending = SAT_PENDING_NONE;
834
            if (IS_ERR(drv->hard_reset()))
835
                send_command_failed_result(SENSE_HARDWARE_ERROR, ASC_UNSUCCESSFUL_SOFT_RESET, 0);
836
            else send_csw(0);
837
            break;
838
        }
839
        case SAT_PENDING_CMD:
840
        {
841
int cmd = sat_command.command;
842
            int datasize = sat_command.size * sat_command.blksize;
843
            void* buffer = sat_command.buffer;
844
            int rc = drv->raw_cmd(&sat_command);
845
            sat_response_information.descriptor_code = 9;
846
            sat_response_information.additional_length = 12;
847
            sat_response_information.extend = sat_command.lba48;
848
            sat_response_information.error = sat_command.feature;
849
            sat_response_information.sector_count_h = sat_command.count >> 8;
850
            sat_response_information.sector_count_l = sat_command.count & 0xff;
851
            sat_response_information.lba_low_h = sat_command.lba_low >> 8;
852
            sat_response_information.lba_low_l = sat_command.lba_low & 0xff;
853
            sat_response_information.lba_mid_h = sat_command.lba_mid >> 8;
854
            sat_response_information.lba_mid_l = sat_command.lba_mid & 0xff;
855
            sat_response_information.lba_high_h = sat_command.lba_high >> 8;
856
            sat_response_information.lba_high_l = sat_command.lba_high & 0xff;
857
            sat_response_information.device = sat_command.device;
858
            sat_response_information.status = sat_command.command;
859
            have_sat_response_information = true;
860
            sat_pending = SAT_PENDING_NONE;
861
            if (IS_ERR(rc) || (sat_command.command & 0x21))
862
            {
863
                if (sat_command.command & 0x20)
864
                    send_command_failed_result(SENSE_HARDWARE_ERROR, ASC_INTERNAL_TARGET_FAILURE, 0);
865
                else if ((sat_command.command & 0x01) && (sat_command.feature & 0x01))
866
                    send_command_failed_result(SENSE_MEDIUM_ERROR, ASC_ADDRESS_MARK_NOT_FOUND, 0);
867
                else if ((sat_command.command & 0x01) && (sat_command.feature & 0x02))
868
                    send_command_failed_result(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0);
869
                else if ((sat_command.command & 0x01) && (sat_command.feature & 0x08))
870
                    send_command_failed_result(SENSE_UNIT_ATTENTION, ASC_OPERATOR_REQUEST, ASCQ_MEDIUM_REMOVAL_REQUEST);
871
                else if ((sat_command.command & 0x01) && (sat_command.feature & 0x10))
872
                    send_command_failed_result(SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0);
873
                else if ((sat_command.command & 0x01) && (sat_command.feature & 0x20))
874
                    send_command_failed_result(SENSE_UNIT_ATTENTION, ASC_MEDIUM_MAY_HAVE_CHANGED, 0);
875
                else if ((sat_command.command & 0x01) && (sat_command.feature & 0x40) && datasize && !sat_command.send)
876
                    send_command_failed_result(SENSE_MEDIUM_ERROR, ASC_READ_ERROR, 0);
877
                else if ((sat_command.command & 0x01) && (sat_command.feature & 0x40))
878
                    send_command_failed_result(SENSE_DATA_PROTECT, ASC_WRITE_PROTECTED, 0);
879
                else if ((sat_command.command & 0x01) && (sat_command.feature & 0x80))
880
                    send_command_failed_result(SENSE_ABORTED_COMMAND, ASC_SCSI_PARITY_ERROR, ASCQ_UICRC_ERROR_DETECTED);
881
                else if ((sat_command.command & 0x01) && (sat_command.feature & 0x04))
882
                    send_command_failed_result(SENSE_ABORTED_COMMAND, 0, 0);
883
                else send_command_failed_result(SENSE_HARDWARE_ERROR, ASC_INTERNAL_TARGET_FAILURE, 0);
884
            }
885
            else if (sat_check)
886
                send_command_failed_result(SENSE_SOFT_ERROR, ASC_RECOVERED_ERROR, ASCQ_SAT_INFO_AVAILABLE);
887
            else if (datasize) send_command_result(buffer, datasize);
888
            else send_csw(0);
889
            break;
890
        }
891
        case SAT_PENDING_READ_CDB:
892
        {
893
            int rc = drv->read_taskfile(&sat_command);
894
            sat_response_information.descriptor_code = 9;
895
            sat_response_information.additional_length = 12;
896
            sat_response_information.extend = sat_command.lba48;
897
            sat_response_information.error = sat_command.feature;
898
            sat_response_information.sector_count_h = sat_command.count >> 8;
899
            sat_response_information.sector_count_l = sat_command.count & 0xff;
900
            sat_response_information.lba_low_h = sat_command.lba_low >> 8;
901
            sat_response_information.lba_low_l = sat_command.lba_low & 0xff;
902
            sat_response_information.lba_mid_h = sat_command.lba_mid >> 8;
903
            sat_response_information.lba_mid_l = sat_command.lba_mid & 0xff;
904
            sat_response_information.lba_high_h = sat_command.lba_high >> 8;
905
            sat_response_information.lba_high_l = sat_command.lba_high & 0xff;
906
            sat_response_information.device = sat_command.device;
907
            sat_response_information.status = sat_command.command;
908
            sat_pending = SAT_PENDING_NONE;
909
            if (IS_ERR(rc)) send_command_failed_result(SENSE_HARDWARE_ERROR, ASC_INTERNAL_TARGET_FAILURE, 0);
910
            else send_command_result(&sat_response_information, sizeof(sat_response_information));
911
            break;
912
        }
924 theseven 913
    }
914
}
915