Subversion Repositories freemyipod

Rev

Go to most recent revision | Details | 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"
29
 
30
 
31
#define UMS_BUFSIZE 65536
32
 
33
 
34
static struct
35
{
36
    unsigned int sector;
37
    unsigned int count;
38
    unsigned int orig_count;
39
    unsigned int cur_cmd;
40
    unsigned int tag;
41
    unsigned int lun;
42
    unsigned int last_result;
43
} cur_cmd;
44
 
45
 
46
static struct
47
{
48
    unsigned char sense_key;
49
    unsigned char information;
50
    unsigned char asc;
51
    unsigned char ascq;
52
} cur_sense_data;
53
 
54
 
55
struct __attribute__((packed,aligned(32))) command_block_wrapper
56
{
57
    unsigned int signature;
58
    unsigned int tag;
59
    unsigned int data_transfer_length;
60
    unsigned char flags;
61
    unsigned char lun;
62
    unsigned char command_length;
63
    unsigned char command_block[16];
64
};
65
 
66
 
67
struct __attribute__((packed)) command_status_wrapper
68
{
69
    unsigned int signature;
70
    unsigned int tag;
71
    unsigned int data_residue;
72
    unsigned char status;
73
};
74
 
75
 
76
union __attribute__((aligned(32)))
77
{
78
    struct inquiry_data inquiry;
79
    struct capacity capacity_data;
80
    struct format_capacity format_capacity_data;
81
    struct sense_data sense_data;
82
    struct mode_sense_data_6 ms_data_6;
83
    struct mode_sense_data_10 ms_data_10;
84
    struct report_lun_data lun_data;
85
    struct command_status_wrapper csw;
86
} tb;
87
 
88
 
89
static enum
90
{
91
    WAITING_FOR_COMMAND,
92
    SENDING_BLOCKS,
93
    SENDING_RESULT,
94
    SENDING_FAILED_RESULT,
95
    RECEIVING_BLOCKS,
96
    WAITING_FOR_CSW_COMPLETION
97
} state = WAITING_FOR_COMMAND;
98
 
99
static uint32_t length;
100
static struct storage_info storage_info;
101
static uint8_t __attribute__((aligned(32))) umsbuf[2][2][UMS_BUFSIZE];
102
static union __attribute__((packed,aligned(32)))
103
{
104
    struct command_block_wrapper cbw;
105
    uint8_t dummy;
106
} cmdbuf;
107
static uint8_t readbuf_current;
108
static uint32_t readbuf_sector[2] = {0, 0};
109
static int8_t readbuf_count[2] = {0, 0};
110
static uint8_t read_blocked = false;
111
static uint8_t writebuf_current;
112
static uint32_t writebuf_sector;
113
static uint8_t writebuf_count;
114
static uint8_t writebuf_busy = false;
115
static uint8_t writebuf_overrun = false;
116
static uint32_t write_rc = 0;
117
static bool locked = false;
118
 
119
 
120
bool ums_ejected = false;
121
 
122
 
123
static void listen()
124
{
125
    usb_receive(&cmdbuf.cbw, sizeof(cmdbuf.cbw));
126
}
127
 
128
 
129
void ums_listen()
130
{
131
    state = WAITING_FOR_COMMAND;
132
    listen();
133
}
134
 
135
 
136
static void send_csw(int status)
137
{
138
    tb.csw.signature = 0x53425355;
139
    tb.csw.tag = cur_cmd.tag;
140
    tb.csw.data_residue = 0;
141
    tb.csw.status = status;
142
 
143
    state = WAITING_FOR_CSW_COMPLETION;
144
    usb_transmit(&tb.csw, sizeof(tb.csw));
145
 
146
    if (!status)
147
    {
148
        cur_sense_data.sense_key = 0;
149
        cur_sense_data.information = 0;
150
        cur_sense_data.asc = 0;
151
        cur_sense_data.ascq = 0;
152
    }
153
}
154
 
155
 
156
static void receive_block_data(void* data, int size)
157
{
158
    length = size;
159
    usb_receive(data, size);
160
    state = RECEIVING_BLOCKS;
161
}
162
 
163
 
164
static void send_block_data(void* data, int size)
165
{
166
    length = size;
167
    usb_transmit(data, size);
168
    state = SENDING_BLOCKS;
169
}
170
 
171
 
172
static void send_command_result(void* data, int size)
173
{
174
    length = size;
175
    usb_transmit(data, size);
176
    state = SENDING_RESULT;
177
}
178
 
179
 
180
static void send_command_failed_result()
181
{
182
    usb_transmit(NULL, 0);
183
    state = SENDING_FAILED_RESULT;
184
}
185
 
186
 
187
static void send_and_read_next()
188
{
189
    int bufsize = UMS_BUFSIZE / storage_info.sector_size;
190
    int i;
191
    for (i = 0; i < 2; i++)
192
    {
193
        if (readbuf_sector[i] <= cur_cmd.sector && readbuf_sector[i] + bufsize > cur_cmd.sector)
194
        {
195
            if (readbuf_sector[i] + readbuf_count[i] <= cur_cmd.sector)
196
            {
197
                readbuf_current = i;
198
                read_blocked = true;
199
                enqueue_async();
200
                return;
201
            }
202
            int overlap = MIN(readbuf_sector[i] + readbuf_count[i] - cur_cmd.sector, cur_cmd.count);
203
            if (i == readbuf_current && readbuf_sector[i] + readbuf_count[i] < storage_info.num_sectors)
204
            {
205
                readbuf_current = !i;
206
                readbuf_sector[!i] = MAX(readbuf_sector[i] + readbuf_count[i], cur_cmd.sector + overlap);
207
                readbuf_count[!i] = 0;
208
                enqueue_async();
209
            }
210
            int offset = (cur_cmd.sector - readbuf_sector[i]) * storage_info.sector_size;
211
            send_block_data(umsbuf[0][i] + offset, overlap * storage_info.sector_size);
212
            cur_cmd.sector += overlap;
213
            cur_cmd.count -= overlap;
214
            return;
215
        }
216
    }
217
    readbuf_current ^= 1;
218
    readbuf_sector[readbuf_current] = cur_cmd.sector;
219
    readbuf_count[readbuf_current] = 0;
220
    read_blocked = true;
221
    enqueue_async();
222
}
223
 
224
 
225
static void copy_padded(char* dest, char* src, int len)
226
{
227
   int i = 0;
228
   while (src[i] && i < len)
229
   {
230
      dest[i] = src[i];
231
      i++;
232
   }
233
   while(i < len) dest[i++] = ' ';
234
}
235
 
236
 
237
static void fill_inquiry()
238
{
239
    memset(&tb.inquiry, 0, sizeof(tb.inquiry));
240
    copy_padded(tb.inquiry.VendorId, storage_info.vendor, sizeof(tb.inquiry.VendorId));
241
    copy_padded(tb.inquiry.ProductId, storage_info.product, sizeof(tb.inquiry.ProductId));
242
    copy_padded(tb.inquiry.ProductRevisionLevel, storage_info.revision, sizeof(tb.inquiry.ProductRevisionLevel));
243
 
244
    tb.inquiry.DeviceType = DIRECT_ACCESS_DEVICE;
245
    tb.inquiry.AdditionalLength = 0x1f;
246
    tb.inquiry.Versions = 4;  // SPC-2
247
    tb.inquiry.Format = 2;  // SPC-2/3 inquiry format
248
    tb.inquiry.DeviceTypeModifier = DEVICE_REMOVABLE;
249
}
250
 
251
 
252
static void handle_scsi(struct command_block_wrapper* cbw)
253
{
254
    unsigned int length = cbw->data_transfer_length;
255
 
256
    if (cbw->signature != 0x43425355)
257
    {
258
        usb_stall();
259
        return;
260
    }
261
    cur_cmd.tag = cbw->tag;
262
    cur_cmd.lun = cbw->lun;
263
    cur_cmd.cur_cmd = cbw->command_block[0];
264
 
265
    switch (cbw->command_block[0])
266
    {
267
        case SCSI_TEST_UNIT_READY:
268
            if (!ums_ejected) send_csw(0);
269
            else
270
            {
271
                send_csw(1);
272
                cur_sense_data.sense_key = SENSE_NOT_READY;
273
                cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
274
                cur_sense_data.ascq = 0;
275
            }
276
            break;
277
 
278
        case SCSI_REPORT_LUNS:
279
        {
280
            memset(&tb.lun_data, 0, sizeof(struct report_lun_data));
281
            tb.lun_data.lun_list_length = 0x08000000;
282
            send_command_result(&tb.lun_data, MIN(16, length));
283
            break;
284
        }
285
 
286
        case SCSI_INQUIRY:
287
            fill_inquiry();
288
            length = MIN(length, cbw->command_block[4]);
289
            send_command_result(&tb.inquiry, MIN(sizeof(tb.inquiry), length));
290
            break;
291
 
292
        case SCSI_REQUEST_SENSE:
293
        {
294
            tb.sense_data.ResponseCode = 0x70;
295
            tb.sense_data.Obsolete = 0;
296
            tb.sense_data.fei_sensekey = cur_sense_data.sense_key & 0x0f;
297
            tb.sense_data.Information = cur_sense_data.information;
298
            tb.sense_data.AdditionalSenseLength = 10;
299
            tb.sense_data.CommandSpecificInformation = 0;
300
            tb.sense_data.AdditionalSenseCode = cur_sense_data.asc;
301
            tb.sense_data.AdditionalSenseCodeQualifier = cur_sense_data.ascq;
302
            tb.sense_data.FieldReplaceableUnitCode = 0;
303
            tb.sense_data.SKSV = 0;
304
            tb.sense_data.SenseKeySpecific = 0;
305
            send_command_result(&tb.sense_data, MIN(sizeof(tb.sense_data), length));
306
            break;
307
        }
308
 
309
        case SCSI_MODE_SENSE_10:
310
        {
311
            if (ums_ejected)
312
            {
313
                send_command_failed_result();
314
                cur_sense_data.sense_key = SENSE_NOT_READY;
315
                cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
316
                cur_sense_data.ascq = 0;
317
                break;
318
            }
319
            unsigned char page_code = cbw->command_block[2] & 0x3f;
320
            switch (page_code)
321
            {
322
                case 0x3f:
323
                    tb.ms_data_10.mode_data_length = htobe16(sizeof(tb.ms_data_10) - 2);
324
                    tb.ms_data_10.medium_type = 0;
325
                    tb.ms_data_10.device_specific = 0;
326
                    tb.ms_data_10.reserved = 0;
327
                    tb.ms_data_10.longlba = 1;
328
                    tb.ms_data_10.block_descriptor_length = htobe16(sizeof(tb.ms_data_10.block_descriptor));
329
 
330
                    memset(tb.ms_data_10.block_descriptor.reserved, 0, 4);
331
                    memset(tb.ms_data_10.block_descriptor.num_blocks, 0, 8);
332
 
333
                    tb.ms_data_10.block_descriptor.num_blocks[4] = (storage_info.num_sectors & 0xff000000) >> 24;
334
                    tb.ms_data_10.block_descriptor.num_blocks[5] = (storage_info.num_sectors & 0x00ff0000) >> 16;
335
                    tb.ms_data_10.block_descriptor.num_blocks[6] = (storage_info.num_sectors & 0x0000ff00) >> 8;
336
                    tb.ms_data_10.block_descriptor.num_blocks[7] = (storage_info.num_sectors & 0x000000ff);
337
 
338
                    tb.ms_data_10.block_descriptor.block_size[0] = (storage_info.sector_size & 0xff000000) >> 24;
339
                    tb.ms_data_10.block_descriptor.block_size[1] = (storage_info.sector_size & 0x00ff0000) >> 16;
340
                    tb.ms_data_10.block_descriptor.block_size[2] = (storage_info.sector_size & 0x0000ff00) >> 8;
341
                    tb.ms_data_10.block_descriptor.block_size[3] = (storage_info.sector_size & 0x000000ff);
342
                    send_command_result(&tb.ms_data_10, MIN(sizeof(tb.ms_data_10), length));
343
                    break;
344
                default:
345
                    send_command_failed_result();
346
                    cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
347
                    cur_sense_data.asc = ASC_INVALID_FIELD_IN_CBD;
348
                    cur_sense_data.ascq = 0;
349
                    break;
350
            }
351
            break;
352
        }
353
 
354
        case SCSI_MODE_SENSE_6:
355
        {
356
            if (ums_ejected)
357
            {
358
                send_command_failed_result();
359
                cur_sense_data.sense_key = SENSE_NOT_READY;
360
                cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
361
                cur_sense_data.ascq = 0;
362
                break;
363
            }
364
            unsigned char page_code = cbw->command_block[2] & 0x3f;
365
            switch (page_code)
366
            {
367
                case 0x3f:
368
                    tb.ms_data_6.mode_data_length = sizeof(tb.ms_data_6) - 1;
369
                    tb.ms_data_6.medium_type = 0;
370
                    tb.ms_data_6.device_specific = 0;
371
                    tb.ms_data_6.block_descriptor_length = sizeof(tb.ms_data_6.block_descriptor);
372
                    tb.ms_data_6.block_descriptor.density_code = 0;
373
                    tb.ms_data_6.block_descriptor.reserved = 0;
374
                    if (storage_info.num_sectors > 0xffffff)
375
                    {
376
                        tb.ms_data_6.block_descriptor.num_blocks[0] = 0xff;
377
                        tb.ms_data_6.block_descriptor.num_blocks[1] = 0xff;
378
                        tb.ms_data_6.block_descriptor.num_blocks[2] = 0xff;
379
                    }
380
                    else
381
                    {
382
                        tb.ms_data_6.block_descriptor.num_blocks[0] = (storage_info.num_sectors & 0xff0000) >> 16;
383
                        tb.ms_data_6.block_descriptor.num_blocks[1] = (storage_info.num_sectors & 0x00ff00) >> 8;
384
                        tb.ms_data_6.block_descriptor.num_blocks[2] = (storage_info.num_sectors & 0x0000ff);
385
                    }
386
                    tb.ms_data_6.block_descriptor.block_size[0] = (storage_info.sector_size & 0xff0000) >> 16;
387
                    tb.ms_data_6.block_descriptor.block_size[1] = (storage_info.sector_size & 0x00ff00) >> 8;
388
                    tb.ms_data_6.block_descriptor.block_size[2] = (storage_info.sector_size & 0x0000ff);
389
                    send_command_result(&tb.ms_data_6, MIN(sizeof(tb.ms_data_6), length));
390
                    break;
391
                default:
392
                    send_command_failed_result();
393
                    cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
394
                    cur_sense_data.asc = ASC_INVALID_FIELD_IN_CBD;
395
                    cur_sense_data.ascq = 0;
396
                    break;
397
            }
398
            break;
399
        }
400
 
401
        case SCSI_START_STOP_UNIT:
402
            if ((cbw->command_block[4] & 0xf3) == 2) ums_ejected = true;
403
            send_csw(0);
404
            break;
405
 
406
        case SCSI_ALLOW_MEDIUM_REMOVAL:
407
            if ((cbw->command_block[4] & 0x03) == 0) locked = false;
408
            else locked = true;
409
            send_csw(0);
410
            break;
411
 
412
        case SCSI_READ_FORMAT_CAPACITY:
413
        {
414
            if (!ums_ejected)
415
            {
416
                tb.format_capacity_data.following_length = 0x08000000;
417
                tb.format_capacity_data.block_count = swap32(storage_info.num_sectors - 1);
418
                tb.format_capacity_data.block_size = swap32(storage_info.sector_size);
419
                tb.format_capacity_data.block_size |= swap32(SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA);
420
                send_command_result(&tb.format_capacity_data, MIN(sizeof(tb.format_capacity_data), length));
421
           }
422
           else
423
           {
424
               send_command_failed_result();
425
               cur_sense_data.sense_key = SENSE_NOT_READY;
426
               cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
427
               cur_sense_data.ascq = 0;
428
           }
429
           break;
430
        }
431
 
432
        case SCSI_READ_CAPACITY:
433
        {
434
            if (!ums_ejected)
435
            {
436
                tb.capacity_data.block_count = swap32(storage_info.num_sectors - 1);
437
                tb.capacity_data.block_size = swap32(storage_info.sector_size);
438
                send_command_result(&tb.capacity_data, MIN(sizeof(tb.capacity_data), length));
439
            }
440
            else
441
            {
442
                send_command_failed_result();
443
                cur_sense_data.sense_key = SENSE_NOT_READY;
444
                cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
445
                cur_sense_data.ascq = 0;
446
            }
447
            break;
448
        }
449
 
450
        case SCSI_READ_10:
451
            if (ums_ejected)
452
            {
453
                send_command_failed_result();
454
                cur_sense_data.sense_key = SENSE_NOT_READY;
455
                cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
456
                cur_sense_data.ascq = 0;
457
                break;
458
            }
459
            cur_cmd.sector = (cbw->command_block[2] << 24 | cbw->command_block[3] << 16
460
                            | cbw->command_block[4] << 8 | cbw->command_block[5]);
461
            cur_cmd.count = (cbw->command_block[7] << 8 | cbw->command_block[8]);
462
            cur_cmd.orig_count = cur_cmd.count;
463
 
464
            if ((cur_cmd.sector + cur_cmd.count) > storage_info.num_sectors)
465
            {
466
                send_csw(1);
467
                cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
468
                cur_sense_data.asc = ASC_LBA_OUT_OF_RANGE;
469
                cur_sense_data.ascq = 0;
470
            }
471
            else if (!cur_cmd.count) send_csw(0);
472
            else send_and_read_next();
473
            break;
474
 
475
        case SCSI_WRITE_10:
476
            if (ums_ejected)
477
            {
478
                send_command_failed_result();
479
                cur_sense_data.sense_key = SENSE_NOT_READY;
480
                cur_sense_data.asc = ASC_MEDIUM_NOT_PRESENT;
481
                cur_sense_data.ascq = 0;
482
                break;
483
            }
484
            cur_cmd.sector = (cbw->command_block[2] << 24 | cbw->command_block[3] << 16
485
                            | cbw->command_block[4] << 8 | cbw->command_block[5]);
486
            cur_cmd.count = (cbw->command_block[7] << 8 | cbw->command_block[8]);
487
            cur_cmd.orig_count = cur_cmd.count;
488
 
489
            if ((cur_cmd.sector + cur_cmd.count) > storage_info.num_sectors)
490
            {
491
                send_csw(1);
492
                cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
493
                cur_sense_data.asc = ASC_LBA_OUT_OF_RANGE;
494
                cur_sense_data.ascq = 0;
495
            }
496
            else if (!cur_cmd.count) send_csw(0);
497
            else
498
                receive_block_data(umsbuf[1][!writebuf_current],
499
                                   MIN(UMS_BUFSIZE, cur_cmd.count * storage_info.sector_size));
500
            break;
501
 
502
        case SCSI_WRITE_BUFFER:
503
            break;
504
 
505
        default:
506
            send_csw(1);
507
            cur_sense_data.sense_key = SENSE_ILLEGAL_REQUEST;
508
            cur_sense_data.asc = ASC_INVALID_COMMAND;
509
            cur_sense_data.ascq = 0;
510
            break;
511
    }
512
}
513
 
514
 
515
void ums_init()
516
{
517
    storage_get_info(0, &storage_info);
518
    if (!storage_info.sector_size) panicf(PANIC_KILLTHREAD, "Sector size is zero!\n");
519
    if (!storage_info.num_sectors) panicf(PANIC_KILLTHREAD, "Number of sectors is zero!\n");
520
}
521
 
522
 
523
void update_readcache()
524
{
525
    int count = length / storage_info.sector_size;
526
    int i;
527
    for (i = 0; i < 2; i++)
528
        if ((readbuf_sector[i] <= cur_cmd.sector && readbuf_sector[i] + readbuf_count[i] > cur_cmd.sector)
529
         || (readbuf_sector[i] <= cur_cmd.sector + count
530
          && readbuf_sector[i] + readbuf_count[i] > cur_cmd.sector + count))
531
        {
532
            int roffset = MAX(0, (int)(cur_cmd.sector - readbuf_sector[i]));
533
            int woffset = MAX(0, (int)(readbuf_sector[i] - cur_cmd.sector));
534
            int len = MIN(readbuf_count[i] - roffset, count - woffset);
535
            roffset *= storage_info.sector_size;
536
            woffset *= storage_info.sector_size;
537
            len *= storage_info.sector_size;
538
            memcpy(umsbuf[0][i] + roffset, umsbuf[1][writebuf_current] + woffset, len);
539
        }
540
}
541
 
542
 
543
static void writebuf_push()
544
{
545
    int count = length / storage_info.sector_size;
546
    writebuf_current ^= 1;
547
    writebuf_sector = cur_cmd.sector;
548
    cur_cmd.sector += count;
549
    writebuf_count = count;
550
    cur_cmd.count -= count;
551
    writebuf_busy = true;
552
    int remaining = cur_cmd.count * storage_info.sector_size;
553
    if (!cur_cmd.count)
554
    {
555
        if (IS_ERR(write_rc))
556
        {
557
            send_csw(1);
558
            cur_sense_data.sense_key = SENSE_MEDIUM_ERROR;
559
            cur_sense_data.asc = ASC_WRITE_ERROR;
560
            cur_sense_data.ascq = 0;
561
        }
562
        send_csw(0);
563
        write_rc = 0;
564
    }
565
    else receive_block_data(umsbuf[1][!writebuf_current], MIN(UMS_BUFSIZE, remaining));
566
}
567
 
568
 
569
void ums_xfer_complete(bool in, int bytesleft)
570
{
571
    length -= bytesleft;
572
    switch (state)
573
    {
574
        case RECEIVING_BLOCKS:
575
            if (length != storage_info.sector_size * cur_cmd.count && length != UMS_BUFSIZE) break;
576
            update_readcache();
577
            if (!writebuf_busy) writebuf_push();
578
            else writebuf_overrun = true;
579
            enqueue_async();
580
            break;
581
        case WAITING_FOR_CSW_COMPLETION:
582
            state = WAITING_FOR_COMMAND;
583
            listen();
584
            break;
585
        case WAITING_FOR_COMMAND:
586
            invalidate_dcache(&cmdbuf, sizeof(cmdbuf));  // Who pulls this into a cache line!?
587
            handle_scsi(&cmdbuf.cbw);
588
            break;
589
        case SENDING_RESULT:
590
            send_csw(0);
591
            break;
592
        case SENDING_FAILED_RESULT:
593
            send_csw(1);
594
            break;
595
        case SENDING_BLOCKS:
596
            if (!cur_cmd.count) send_csw(0);
597
            else send_and_read_next();
598
            break;
599
    }
600
}
601
 
602
void ums_handle_async()
603
{
604
    if (writebuf_overrun)
605
    {
606
        writebuf_overrun = false;
607
        writebuf_push();
608
    }
609
    if (writebuf_busy)
610
    {
611
        write_rc |= storage_write_sectors_md(0, writebuf_sector, writebuf_count, umsbuf[1][writebuf_current]);
612
        writebuf_busy = false;
613
    }
614
 
615
    int c = readbuf_current;        
616
    if (!readbuf_count[c])
617
    {
618
        int sector = readbuf_sector[c];
619
        int count = MIN(UMS_BUFSIZE / storage_info.sector_size, storage_info.num_sectors - sector);
620
        if (IS_ERR(storage_read_sectors_md(0, sector, count, umsbuf[0][c]))) count = -1;
621
        if (sector == readbuf_sector[c]) readbuf_count[c] = count;
622
        if (sector != readbuf_sector[c]) readbuf_count[c] = 0;  // Extremely ugly hack to neutralize race condition
623
    }
624
    if (read_blocked)
625
    {
626
        read_blocked = false;
627
        if (readbuf_count[readbuf_current] < 0)
628
        {
629
            send_csw(1);
630
            cur_sense_data.sense_key = SENSE_MEDIUM_ERROR;
631
            cur_sense_data.asc = ASC_READ_ERROR;
632
            cur_sense_data.ascq = 0;
633
        }
634
        else send_and_read_next();
635
    }
636
}
637