Statistics
| Branch: | Revision:

root / hw / scsi-disk.c @ 6ae81775

History | View | Annotate | Download (16.9 kB)

1
/*
2
 * SCSI Device emulation
3
 *
4
 * Copyright (c) 2006 CodeSourcery.
5
 * Based on code by Fabrice Bellard
6
 *
7
 * Written by Paul Brook
8
 *
9
 * This code is licenced under the LGPL.
10
 *
11
 * Note that this file only handles the SCSI architecture model and device
12
 * commands.  Emultion of interface/link layer protocols is handled by
13
 * the host adapter emulation.
14
 */
15

    
16
//#define DEBUG_SCSI
17

    
18
#ifdef DEBUG_SCSI
19
#define DPRINTF(fmt, args...) \
20
do { printf("scsi-disk: " fmt , ##args); } while (0)
21
#else
22
#define DPRINTF(fmt, args...) do {} while(0)
23
#endif
24

    
25
#define BADF(fmt, args...) \
26
do { fprintf(stderr, "scsi-disk: " fmt , ##args); } while (0)
27

    
28
#include "vl.h"
29

    
30
#define SENSE_NO_SENSE        0
31
#define SENSE_NOT_READY       2
32
#define SENSE_HARDWARE_ERROR  4
33
#define SENSE_ILLEGAL_REQUEST 5
34

    
35
#define SCSI_DMA_BUF_SIZE    65536
36

    
37
typedef struct SCSIRequest {
38
    SCSIDevice *dev;
39
    uint32_t tag;
40
    /* ??? We should probably keep track of whether the data trasfer is
41
       a read or a write.  Currently we rely on the host getting it right.  */
42
    /* Both sector and sector_count are in terms of qemu 512 byte blocks.  */
43
    int sector;
44
    int sector_count;
45
    /* The amounnt of data in the buffer.  */
46
    int buf_len;
47
    uint8_t dma_buf[SCSI_DMA_BUF_SIZE];
48
    BlockDriverAIOCB *aiocb;
49
    struct SCSIRequest *next;
50
} SCSIRequest;
51

    
52
struct SCSIDevice
53
{
54
    BlockDriverState *bdrv;
55
    SCSIRequest *requests;
56
    /* The qemu block layer uses a fixed 512 byte sector size.
57
       This is the number of 512 byte blocks in a single scsi sector.  */
58
    int cluster_size;
59
    int sense;
60
    int tcq;
61
    /* Completion functions may be called from either scsi_{read,write}_data
62
       or from the AIO completion routines.  */
63
    scsi_completionfn completion;
64
    void *opaque;
65
};
66

    
67
/* Global pool of SCSIRequest structures.  */
68
static SCSIRequest *free_requests = NULL;
69

    
70
static SCSIRequest *scsi_new_request(SCSIDevice *s, uint32_t tag)
71
{
72
    SCSIRequest *r;
73

    
74
    if (free_requests) {
75
        r = free_requests;
76
        free_requests = r->next;
77
    } else {
78
        r = qemu_malloc(sizeof(SCSIRequest));
79
    }
80
    r->dev = s;
81
    r->tag = tag;
82
    r->sector_count = 0;
83
    r->buf_len = 0;
84
    r->aiocb = NULL;
85

    
86
    r->next = s->requests;
87
    s->requests = r;
88
    return r;
89
}
90

    
91
static void scsi_remove_request(SCSIRequest *r)
92
{
93
    SCSIRequest *last;
94
    SCSIDevice *s = r->dev;
95

    
96
    if (s->requests == r) {
97
        s->requests = r->next;
98
    } else {
99
        last = s->requests;
100
        while (last && last->next != r)
101
            last = last->next;
102
        if (last) {
103
            last->next = r->next;
104
        } else {
105
            BADF("Orphaned request\n");
106
        }
107
    }
108
    r->next = free_requests;
109
    free_requests = r;
110
}
111

    
112
static SCSIRequest *scsi_find_request(SCSIDevice *s, uint32_t tag)
113
{
114
    SCSIRequest *r;
115

    
116
    r = s->requests;
117
    while (r && r->tag != tag)
118
        r = r->next;
119

    
120
    return r;
121
}
122

    
123
/* Helper function for command completion.  */
124
static void scsi_command_complete(SCSIRequest *r, int sense)
125
{
126
    SCSIDevice *s = r->dev;
127
    uint32_t tag;
128
    DPRINTF("Command complete tag=0x%x sense=%d\n", r->tag, sense);
129
    s->sense = sense;
130
    tag = r->tag;
131
    scsi_remove_request(r);
132
    s->completion(s->opaque, SCSI_REASON_DONE, tag, sense);
133
}
134

    
135
/* Cancel a pending data transfer.  */
136
void scsi_cancel_io(SCSIDevice *s, uint32_t tag)
137
{
138
    SCSIRequest *r;
139
    DPRINTF("Cancel tag=0x%x\n", tag);
140
    r = scsi_find_request(s, tag);
141
    if (r) {
142
        if (r->aiocb)
143
            bdrv_aio_cancel(r->aiocb);
144
        r->aiocb = NULL;
145
        scsi_remove_request(r);
146
    }
147
}
148

    
149
static void scsi_read_complete(void * opaque, int ret)
150
{
151
    SCSIRequest *r = (SCSIRequest *)opaque;
152
    SCSIDevice *s = r->dev;
153

    
154
    if (ret) {
155
        DPRINTF("IO error\n");
156
        scsi_command_complete(r, SENSE_HARDWARE_ERROR);
157
        return;
158
    }
159
    DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, r->buf_len);
160

    
161
    s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
162
}
163

    
164
/* Read more data from scsi device into buffer.  */
165
void scsi_read_data(SCSIDevice *s, uint32_t tag)
166
{
167
    SCSIRequest *r;
168
    uint32_t n;
169

    
170
    r = scsi_find_request(s, tag);
171
    if (!r) {
172
        BADF("Bad read tag 0x%x\n", tag);
173
        /* ??? This is the wrong error.  */
174
        scsi_command_complete(r, SENSE_HARDWARE_ERROR);
175
        return;
176
    }
177
    if (r->sector_count == (uint32_t)-1) {
178
        DPRINTF("Read buf_len=%d\n", r->buf_len);
179
        r->sector_count = 0;
180
        s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
181
        return;
182
    }
183
    DPRINTF("Read sector_count=%d\n", r->sector_count);
184
    if (r->sector_count == 0) {
185
        scsi_command_complete(r, SENSE_NO_SENSE);
186
        return;
187
    }
188

    
189
    n = r->sector_count;
190
    if (n > SCSI_DMA_BUF_SIZE / 512)
191
        n = SCSI_DMA_BUF_SIZE / 512;
192

    
193
    r->buf_len = n * 512;
194
    r->aiocb = bdrv_aio_read(s->bdrv, r->sector, r->dma_buf, n,
195
                             scsi_read_complete, r);
196
    if (r->aiocb == NULL)
197
        scsi_command_complete(r, SENSE_HARDWARE_ERROR);
198
    r->sector += n;
199
    r->sector_count -= n;
200
}
201

    
202
static void scsi_write_complete(void * opaque, int ret)
203
{
204
    SCSIRequest *r = (SCSIRequest *)opaque;
205
    SCSIDevice *s = r->dev;
206
    uint32_t len;
207

    
208
    if (ret) {
209
        fprintf(stderr, "scsi-disc: IO write error\n");
210
        exit(1);
211
    }
212

    
213
    r->aiocb = NULL;
214
    if (r->sector_count == 0) {
215
        scsi_command_complete(r, SENSE_NO_SENSE);
216
    } else {
217
        len = r->sector_count * 512;
218
        if (len > SCSI_DMA_BUF_SIZE) {
219
            len = SCSI_DMA_BUF_SIZE;
220
        }
221
        r->buf_len = len;
222
        DPRINTF("Write complete tag=0x%x more=%d\n", r->tag, len);
223
        s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len);
224
    }
225
}
226

    
227
/* Write data to a scsi device.  Returns nonzero on failure.
228
   The transfer may complete asynchronously.  */
229
int scsi_write_data(SCSIDevice *s, uint32_t tag)
230
{
231
    SCSIRequest *r;
232
    uint32_t n;
233

    
234
    DPRINTF("Write data tag=0x%x\n", tag);
235
    r = scsi_find_request(s, tag);
236
    if (!r) {
237
        BADF("Bad write tag 0x%x\n", tag);
238
        scsi_command_complete(r, SENSE_HARDWARE_ERROR);
239
        return 1;
240
    }
241
    if (r->aiocb)
242
        BADF("Data transfer already in progress\n");
243
    n = r->buf_len / 512;
244
    if (n) {
245
        r->aiocb = bdrv_aio_write(s->bdrv, r->sector, r->dma_buf, n,
246
                                  scsi_write_complete, r);
247
        if (r->aiocb == NULL)
248
            scsi_command_complete(r, SENSE_HARDWARE_ERROR);
249
        r->sector += n;
250
        r->sector_count -= n;
251
    } else {
252
        /* Invoke completion routine to fetch data from host.  */
253
        scsi_write_complete(r, 0);
254
    }
255

    
256
    return 0;
257
}
258

    
259
/* Return a pointer to the data buffer.  */
260
uint8_t *scsi_get_buf(SCSIDevice *s, uint32_t tag)
261
{
262
    SCSIRequest *r;
263

    
264
    r = scsi_find_request(s, tag);
265
    if (!r) {
266
        BADF("Bad buffer tag 0x%x\n", tag);
267
        return NULL;
268
    }
269
    return r->dma_buf;
270
}
271

    
272
/* Execute a scsi command.  Returns the length of the data expected by the
273
   command.  This will be Positive for data transfers from the device
274
   (eg. disk reads), negative for transfers to the device (eg. disk writes),
275
   and zero if the command does not transfer any data.  */
276

    
277
int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun)
278
{
279
    int64_t nb_sectors;
280
    uint32_t lba;
281
    uint32_t len;
282
    int cmdlen;
283
    int is_write;
284
    uint8_t command;
285
    uint8_t *outbuf;
286
    SCSIRequest *r;
287

    
288
    command = buf[0];
289
    r = scsi_find_request(s, tag);
290
    if (r) {
291
        BADF("Tag 0x%x already in use\n", tag);
292
        scsi_cancel_io(s, tag);
293
    }
294
    /* ??? Tags are not unique for different luns.  We only implement a
295
       single lun, so this should not matter.  */
296
    r = scsi_new_request(s, tag);
297
    outbuf = r->dma_buf;
298
    is_write = 0;
299
    DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
300
    switch (command >> 5) {
301
    case 0:
302
        lba = buf[3] | (buf[2] << 8) | ((buf[1] & 0x1f) << 16);
303
        len = buf[4];
304
        cmdlen = 6;
305
        break;
306
    case 1:
307
    case 2:
308
        lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
309
        len = buf[8] | (buf[7] << 8);
310
        cmdlen = 10;
311
        break;
312
    case 4:
313
        lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
314
        len = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);
315
        cmdlen = 16;
316
        break;
317
    case 5:
318
        lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
319
        len = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
320
        cmdlen = 12;
321
        break;
322
    default:
323
        BADF("Unsupported command length, command %x\n", command);
324
        goto fail;
325
    }
326
#ifdef DEBUG_SCSI
327
    {
328
        int i;
329
        for (i = 1; i < cmdlen; i++) {
330
            printf(" 0x%02x", buf[i]);
331
        }
332
        printf("\n");
333
    }
334
#endif
335
    if (lun || buf[1] >> 5) {
336
        /* Only LUN 0 supported.  */
337
        DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
338
        goto fail;
339
    }
340
    switch (command) {
341
    case 0x0:
342
        DPRINTF("Test Unit Ready\n");
343
        break;
344
    case 0x03:
345
        DPRINTF("Request Sense (len %d)\n", len);
346
        if (len < 4)
347
            goto fail;
348
        memset(buf, 0, 4);
349
        outbuf[0] = 0xf0;
350
        outbuf[1] = 0;
351
        outbuf[2] = s->sense;
352
        r->buf_len = 4;
353
        break;
354
    case 0x12:
355
        DPRINTF("Inquiry (len %d)\n", len);
356
        if (len < 36) {
357
            BADF("Inquiry buffer too small (%d)\n", len);
358
        }
359
        memset(outbuf, 0, 36);
360
        if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
361
            outbuf[0] = 5;
362
            outbuf[1] = 0x80;
363
            memcpy(&outbuf[16], "QEMU CD-ROM    ", 16);
364
        } else {
365
            outbuf[0] = 0;
366
            memcpy(&outbuf[16], "QEMU HARDDISK  ", 16);
367
        }
368
        memcpy(&outbuf[8], "QEMU   ", 8);
369
        memcpy(&outbuf[32], QEMU_VERSION, 4);
370
        /* Identify device as SCSI-3 rev 1.
371
           Some later commands are also implemented. */
372
        outbuf[2] = 3;
373
        outbuf[3] = 2; /* Format 2 */
374
        outbuf[4] = 32;
375
        /* Sync data transfer and TCQ.  */
376
        outbuf[7] = 0x10 | (s->tcq ? 0x02 : 0);
377
        r->buf_len = 36;
378
        break;
379
    case 0x16:
380
        DPRINTF("Reserve(6)\n");
381
        if (buf[1] & 1)
382
            goto fail;
383
        break;
384
    case 0x17:
385
        DPRINTF("Release(6)\n");
386
        if (buf[1] & 1)
387
            goto fail;
388
        break;
389
    case 0x1a:
390
    case 0x5a:
391
        {
392
            uint8_t *p;
393
            int page;
394

    
395
            page = buf[2] & 0x3f;
396
            DPRINTF("Mode Sense (page %d, len %d)\n", page, len);
397
            p = outbuf;
398
            memset(p, 0, 4);
399
            outbuf[1] = 0; /* Default media type.  */
400
            outbuf[3] = 0; /* Block descriptor length.  */
401
            if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
402
                outbuf[2] = 0x80; /* Readonly.  */
403
            }
404
            p += 4;
405
            if ((page == 8 || page == 0x3f)) {
406
                /* Caching page.  */
407
                p[0] = 8;
408
                p[1] = 0x12;
409
                p[2] = 4; /* WCE */
410
                p += 19;
411
            }
412
            if ((page == 0x3f || page == 0x2a)
413
                    && (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM)) {
414
                /* CD Capabilities and Mechanical Status page. */
415
                p[0] = 0x2a;
416
                p[1] = 0x14;
417
                p[2] = 3; // CD-R & CD-RW read
418
                p[3] = 0; // Writing not supported
419
                p[4] = 0x7f; /* Audio, composite, digital out,
420
                                         mode 2 form 1&2, multi session */
421
                p[5] = 0xff; /* CD DA, DA accurate, RW supported,
422
                                         RW corrected, C2 errors, ISRC,
423
                                         UPC, Bar code */
424
                p[6] = 0x2d | (bdrv_is_locked(s->bdrv)? 2 : 0);
425
                /* Locking supported, jumper present, eject, tray */
426
                p[7] = 0; /* no volume & mute control, no
427
                                      changer */
428
                p[8] = (50 * 176) >> 8; // 50x read speed
429
                p[9] = (50 * 176) & 0xff;
430
                p[10] = 0 >> 8; // No volume
431
                p[11] = 0 & 0xff;
432
                p[12] = 2048 >> 8; // 2M buffer
433
                p[13] = 2048 & 0xff;
434
                p[14] = (16 * 176) >> 8; // 16x read speed current
435
                p[15] = (16 * 176) & 0xff;
436
                p[18] = (16 * 176) >> 8; // 16x write speed
437
                p[19] = (16 * 176) & 0xff;
438
                p[20] = (16 * 176) >> 8; // 16x write speed current
439
                p[21] = (16 * 176) & 0xff;
440
                p += 21;
441
            }
442
            r->buf_len = p - outbuf;
443
            outbuf[0] = r->buf_len - 4;
444
            if (r->buf_len > len)
445
                r->buf_len = len;
446
        }
447
        break;
448
    case 0x1b:
449
        DPRINTF("Start Stop Unit\n");
450
        break;
451
    case 0x1e:
452
        DPRINTF("Prevent Allow Medium Removal (prevent = %d)\n", buf[4] & 3);
453
        bdrv_set_locked(s->bdrv, buf[4] & 1);
454
        break;
455
    case 0x25:
456
        DPRINTF("Read Capacity\n");
457
        /* The normal LEN field for this command is zero.  */
458
        memset(outbuf, 0, 8);
459
        bdrv_get_geometry(s->bdrv, &nb_sectors);
460
        /* Returned value is the address of the last sector.  */
461
        if (nb_sectors) {
462
            nb_sectors--;
463
            outbuf[0] = (nb_sectors >> 24) & 0xff;
464
            outbuf[1] = (nb_sectors >> 16) & 0xff;
465
            outbuf[2] = (nb_sectors >> 8) & 0xff;
466
            outbuf[3] = nb_sectors & 0xff;
467
            outbuf[4] = 0;
468
            outbuf[5] = 0;
469
            outbuf[6] = s->cluster_size * 2;
470
            outbuf[7] = 0;
471
            r->buf_len = 8;
472
        } else {
473
            scsi_command_complete(r, SENSE_NOT_READY);
474
            return 0;
475
        }
476
        break;
477
    case 0x08:
478
    case 0x28:
479
        DPRINTF("Read (sector %d, count %d)\n", lba, len);
480
        r->sector = lba * s->cluster_size;
481
        r->sector_count = len * s->cluster_size;
482
        break;
483
    case 0x0a:
484
    case 0x2a:
485
        DPRINTF("Write (sector %d, count %d)\n", lba, len);
486
        r->sector = lba * s->cluster_size;
487
        r->sector_count = len * s->cluster_size;
488
        is_write = 1;
489
        break;
490
    case 0x35:
491
        DPRINTF("Syncronise cache (sector %d, count %d)\n", lba, len);
492
        bdrv_flush(s->bdrv);
493
        break;
494
    case 0x43:
495
        {
496
            int start_track, format, msf, toclen;
497

    
498
            msf = buf[1] & 2;
499
            format = buf[2] & 0xf;
500
            start_track = buf[6];
501
            bdrv_get_geometry(s->bdrv, &nb_sectors);
502
            DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
503
            switch(format) {
504
            case 0:
505
                toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
506
                break;
507
            case 1:
508
                /* multi session : only a single session defined */
509
                toclen = 12;
510
                memset(outbuf, 0, 12);
511
                outbuf[1] = 0x0a;
512
                outbuf[2] = 0x01;
513
                outbuf[3] = 0x01;
514
                break;
515
            case 2:
516
                toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
517
                break;
518
            default:
519
                goto error_cmd;
520
            }
521
            if (toclen > 0) {
522
                if (len > toclen)
523
                  len = toclen;
524
                r->buf_len = len;
525
                break;
526
            }
527
        error_cmd:
528
            DPRINTF("Read TOC error\n");
529
            goto fail;
530
        }
531
    case 0x46:
532
        DPRINTF("Get Configuration (rt %d, maxlen %d)\n", buf[1] & 3, len);
533
        memset(outbuf, 0, 8);
534
        /* ??? This shoud probably return much more information.  For now
535
           just return the basic header indicating the CD-ROM profile.  */
536
        outbuf[7] = 8; // CD-ROM
537
        r->buf_len = 8;
538
        break;
539
    case 0x56:
540
        DPRINTF("Reserve(10)\n");
541
        if (buf[1] & 3)
542
            goto fail;
543
        break;
544
    case 0x57:
545
        DPRINTF("Release(10)\n");
546
        if (buf[1] & 3)
547
            goto fail;
548
        break;
549
    case 0xa0:
550
        DPRINTF("Report LUNs (len %d)\n", len);
551
        if (len < 16)
552
            goto fail;
553
        memset(outbuf, 0, 16);
554
        outbuf[3] = 8;
555
        r->buf_len = 16;
556
        break;
557
    default:
558
        DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
559
    fail:
560
        scsi_command_complete(r, SENSE_ILLEGAL_REQUEST);
561
        return 0;
562
    }
563
    if (r->sector_count == 0 && r->buf_len == 0) {
564
        scsi_command_complete(r, SENSE_NO_SENSE);
565
    }
566
    len = r->sector_count * 512 + r->buf_len;
567
    if (is_write) {
568
        return -len;
569
    } else {
570
        if (!r->sector_count)
571
            r->sector_count = -1;
572
        return len;
573
    }
574
}
575

    
576
void scsi_disk_destroy(SCSIDevice *s)
577
{
578
    qemu_free(s);
579
}
580

    
581
SCSIDevice *scsi_disk_init(BlockDriverState *bdrv,
582
                           int tcq,
583
                           scsi_completionfn completion,
584
                           void *opaque)
585
{
586
    SCSIDevice *s;
587

    
588
    s = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
589
    s->bdrv = bdrv;
590
    s->tcq = tcq;
591
    s->completion = completion;
592
    s->opaque = opaque;
593
    if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
594
        s->cluster_size = 4;
595
    } else {
596
        s->cluster_size = 1;
597
    }
598

    
599
    return s;
600
}
601