Statistics
| Branch: | Revision:

root / hw / scsi-disk.c @ 33f00271

History | View | Annotate | Download (17.5 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 "qemu-common.h"
29
#include "block.h"
30
#include "scsi-disk.h"
31

    
32
#define SENSE_NO_SENSE        0
33
#define SENSE_NOT_READY       2
34
#define SENSE_HARDWARE_ERROR  4
35
#define SENSE_ILLEGAL_REQUEST 5
36

    
37
#define SCSI_DMA_BUF_SIZE    65536
38

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

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

    
69
/* Global pool of SCSIRequest structures.  */
70
static SCSIRequest *free_requests = NULL;
71

    
72
static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag)
73
{
74
    SCSIRequest *r;
75

    
76
    if (free_requests) {
77
        r = free_requests;
78
        free_requests = r->next;
79
    } else {
80
        r = qemu_malloc(sizeof(SCSIRequest));
81
        r->dma_buf = qemu_memalign(512, SCSI_DMA_BUF_SIZE);
82
    }
83
    r->dev = s;
84
    r->tag = tag;
85
    r->sector_count = 0;
86
    r->buf_len = 0;
87
    r->aiocb = NULL;
88

    
89
    r->next = s->requests;
90
    s->requests = r;
91
    return r;
92
}
93

    
94
static void scsi_remove_request(SCSIRequest *r)
95
{
96
    SCSIRequest *last;
97
    SCSIDeviceState *s = r->dev;
98

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

    
115
static SCSIRequest *scsi_find_request(SCSIDeviceState *s, uint32_t tag)
116
{
117
    SCSIRequest *r;
118

    
119
    r = s->requests;
120
    while (r && r->tag != tag)
121
        r = r->next;
122

    
123
    return r;
124
}
125

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

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

    
153
static void scsi_read_complete(void * opaque, int ret)
154
{
155
    SCSIRequest *r = (SCSIRequest *)opaque;
156
    SCSIDeviceState *s = r->dev;
157

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

    
165
    s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
166
}
167

    
168
/* Read more data from scsi device into buffer.  */
169
static void scsi_read_data(SCSIDevice *d, uint32_t tag)
170
{
171
    SCSIDeviceState *s = d->state;
172
    SCSIRequest *r;
173
    uint32_t n;
174

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

    
194
    n = r->sector_count;
195
    if (n > SCSI_DMA_BUF_SIZE / 512)
196
        n = SCSI_DMA_BUF_SIZE / 512;
197

    
198
    r->buf_len = n * 512;
199
    r->aiocb = bdrv_aio_read(s->bdrv, r->sector, r->dma_buf, n,
200
                             scsi_read_complete, r);
201
    if (r->aiocb == NULL)
202
        scsi_command_complete(r, SENSE_HARDWARE_ERROR);
203
    r->sector += n;
204
    r->sector_count -= n;
205
}
206

    
207
static void scsi_write_complete(void * opaque, int ret)
208
{
209
    SCSIRequest *r = (SCSIRequest *)opaque;
210
    SCSIDeviceState *s = r->dev;
211
    uint32_t len;
212

    
213
    if (ret) {
214
        fprintf(stderr, "scsi-disc: IO write error\n");
215
        exit(1);
216
    }
217

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

    
232
/* Write data to a scsi device.  Returns nonzero on failure.
233
   The transfer may complete asynchronously.  */
234
static int scsi_write_data(SCSIDevice *d, uint32_t tag)
235
{
236
    SCSIDeviceState *s = d->state;
237
    SCSIRequest *r;
238
    uint32_t n;
239

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

    
262
    return 0;
263
}
264

    
265
/* Return a pointer to the data buffer.  */
266
static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
267
{
268
    SCSIDeviceState *s = d->state;
269
    SCSIRequest *r;
270

    
271
    r = scsi_find_request(s, tag);
272
    if (!r) {
273
        BADF("Bad buffer tag 0x%x\n", tag);
274
        return NULL;
275
    }
276
    return r->dma_buf;
277
}
278

    
279
/* Execute a scsi command.  Returns the length of the data expected by the
280
   command.  This will be Positive for data transfers from the device
281
   (eg. disk reads), negative for transfers to the device (eg. disk writes),
282
   and zero if the command does not transfer any data.  */
283

    
284
static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
285
                                 uint8_t *buf, int lun)
286
{
287
    SCSIDeviceState *s = d->state;
288
    uint64_t nb_sectors;
289
    uint32_t lba;
290
    uint32_t len;
291
    int cmdlen;
292
    int is_write;
293
    uint8_t command;
294
    uint8_t *outbuf;
295
    SCSIRequest *r;
296

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

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

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

    
586
static void scsi_destroy(SCSIDevice *d)
587
{
588
    qemu_free(d->state);
589
    qemu_free(d);
590
}
591

    
592
SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq,
593
                           scsi_completionfn completion, void *opaque)
594
{
595
    SCSIDevice *d;
596
    SCSIDeviceState *s;
597

    
598
    s = (SCSIDeviceState *)qemu_mallocz(sizeof(SCSIDeviceState));
599
    s->bdrv = bdrv;
600
    s->tcq = tcq;
601
    s->completion = completion;
602
    s->opaque = opaque;
603
    if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
604
        s->cluster_size = 4;
605
    } else {
606
        s->cluster_size = 1;
607
    }
608

    
609
    d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
610
    d->state = s;
611
    d->destroy = scsi_destroy;
612
    d->send_command = scsi_send_command;
613
    d->read_data = scsi_read_data;
614
    d->write_data = scsi_write_data;
615
    d->cancel_io = scsi_cancel_io;
616
    d->get_buf = scsi_get_buf;
617

    
618
    return d;
619
}