Statistics
| Branch: | Revision:

root / hw / scsi-disk.c @ 0d65e1f8

History | View | Annotate | Download (32 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.  Emulation of interface/link layer protocols is handled by
13
 * the host adapter emulator.
14
 */
15

    
16
#include <qemu-common.h>
17
#include <sysemu.h>
18
//#define DEBUG_SCSI
19

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

    
27
#define BADF(fmt, ...) \
28
do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
29

    
30
#include "qemu-common.h"
31
#include "block.h"
32
#include "scsi.h"
33
#include "scsi-defs.h"
34

    
35
#define SCSI_DMA_BUF_SIZE    131072
36
#define SCSI_MAX_INQUIRY_LEN 256
37

    
38
#define SCSI_REQ_STATUS_RETRY 0x01
39

    
40
typedef struct SCSIDiskState SCSIDiskState;
41

    
42
typedef struct SCSIDiskReq {
43
    SCSIRequest req;
44
    /* ??? We should probably keep track of whether the data transfer is
45
       a read or a write.  Currently we rely on the host getting it right.  */
46
    /* Both sector and sector_count are in terms of qemu 512 byte blocks.  */
47
    uint64_t sector;
48
    uint32_t sector_count;
49
    struct iovec iov;
50
    QEMUIOVector qiov;
51
    uint32_t status;
52
} SCSIDiskReq;
53

    
54
struct SCSIDiskState
55
{
56
    SCSIDevice qdev;
57
    DriveInfo *dinfo;
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
    uint64_t max_lba;
62
    int sense;
63
    char drive_serial_str[21];
64
    QEMUBH *bh;
65
};
66

    
67
static SCSIDiskReq *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
68
{
69
    SCSIRequest *req;
70
    SCSIDiskReq *r;
71

    
72
    req = scsi_req_alloc(sizeof(SCSIDiskReq), d, tag, lun);
73
    r = DO_UPCAST(SCSIDiskReq, req, req);
74
    r->iov.iov_base = qemu_memalign(512, SCSI_DMA_BUF_SIZE);
75
    return r;
76
}
77

    
78
static void scsi_remove_request(SCSIDiskReq *r)
79
{
80
    qemu_free(r->iov.iov_base);
81
    scsi_req_free(&r->req);
82
}
83

    
84
static SCSIDiskReq *scsi_find_request(SCSIDiskState *s, uint32_t tag)
85
{
86
    return DO_UPCAST(SCSIDiskReq, req, scsi_req_find(&s->qdev, tag));
87
}
88

    
89
/* Helper function for command completion.  */
90
static void scsi_command_complete(SCSIDiskReq *r, int status, int sense)
91
{
92
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
93
    uint32_t tag;
94
    DPRINTF("Command complete tag=0x%x status=%d sense=%d\n",
95
            r->req.tag, status, sense);
96
    s->sense = sense;
97
    tag = r->req.tag;
98
    r->req.bus->complete(r->req.bus, SCSI_REASON_DONE, tag, status);
99
    scsi_remove_request(r);
100
}
101

    
102
/* Cancel a pending data transfer.  */
103
static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
104
{
105
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
106
    SCSIDiskReq *r;
107
    DPRINTF("Cancel tag=0x%x\n", tag);
108
    r = scsi_find_request(s, tag);
109
    if (r) {
110
        if (r->req.aiocb)
111
            bdrv_aio_cancel(r->req.aiocb);
112
        r->req.aiocb = NULL;
113
        scsi_remove_request(r);
114
    }
115
}
116

    
117
static void scsi_read_complete(void * opaque, int ret)
118
{
119
    SCSIDiskReq *r = (SCSIDiskReq *)opaque;
120

    
121
    if (ret) {
122
        DPRINTF("IO error\n");
123
        r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, 0);
124
        scsi_command_complete(r, CHECK_CONDITION, NO_SENSE);
125
        return;
126
    }
127
    DPRINTF("Data ready tag=0x%x len=%" PRId64 "\n", r->req.tag, r->iov.iov_len);
128

    
129
    r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, r->iov.iov_len);
130
}
131

    
132
/* Read more data from scsi device into buffer.  */
133
static void scsi_read_data(SCSIDevice *d, uint32_t tag)
134
{
135
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
136
    SCSIDiskReq *r;
137
    uint32_t n;
138

    
139
    r = scsi_find_request(s, tag);
140
    if (!r) {
141
        BADF("Bad read tag 0x%x\n", tag);
142
        /* ??? This is the wrong error.  */
143
        scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
144
        return;
145
    }
146
    if (r->sector_count == (uint32_t)-1) {
147
        DPRINTF("Read buf_len=%" PRId64 "\n", r->iov.iov_len);
148
        r->sector_count = 0;
149
        r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, r->iov.iov_len);
150
        return;
151
    }
152
    DPRINTF("Read sector_count=%d\n", r->sector_count);
153
    if (r->sector_count == 0) {
154
        scsi_command_complete(r, GOOD, NO_SENSE);
155
        return;
156
    }
157

    
158
    n = r->sector_count;
159
    if (n > SCSI_DMA_BUF_SIZE / 512)
160
        n = SCSI_DMA_BUF_SIZE / 512;
161

    
162
    r->iov.iov_len = n * 512;
163
    qemu_iovec_init_external(&r->qiov, &r->iov, 1);
164
    r->req.aiocb = bdrv_aio_readv(s->dinfo->bdrv, r->sector, &r->qiov, n,
165
                              scsi_read_complete, r);
166
    if (r->req.aiocb == NULL)
167
        scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
168
    r->sector += n;
169
    r->sector_count -= n;
170
}
171

    
172
static int scsi_handle_write_error(SCSIDiskReq *r, int error)
173
{
174
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
175
    BlockInterfaceErrorAction action = drive_get_onerror(s->dinfo->bdrv);
176

    
177
    if (action == BLOCK_ERR_IGNORE)
178
        return 0;
179

    
180
    if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
181
            || action == BLOCK_ERR_STOP_ANY) {
182
        r->status |= SCSI_REQ_STATUS_RETRY;
183
        vm_stop(0);
184
    } else {
185
        scsi_command_complete(r, CHECK_CONDITION,
186
                HARDWARE_ERROR);
187
    }
188

    
189
    return 1;
190
}
191

    
192
static void scsi_write_complete(void * opaque, int ret)
193
{
194
    SCSIDiskReq *r = (SCSIDiskReq *)opaque;
195
    uint32_t len;
196
    uint32_t n;
197

    
198
    r->req.aiocb = NULL;
199

    
200
    if (ret) {
201
        if (scsi_handle_write_error(r, -ret))
202
            return;
203
    }
204

    
205
    n = r->iov.iov_len / 512;
206
    r->sector += n;
207
    r->sector_count -= n;
208
    if (r->sector_count == 0) {
209
        scsi_command_complete(r, GOOD, NO_SENSE);
210
    } else {
211
        len = r->sector_count * 512;
212
        if (len > SCSI_DMA_BUF_SIZE) {
213
            len = SCSI_DMA_BUF_SIZE;
214
        }
215
        r->iov.iov_len = len;
216
        DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, len);
217
        r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, len);
218
    }
219
}
220

    
221
static void scsi_write_request(SCSIDiskReq *r)
222
{
223
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
224
    uint32_t n;
225

    
226
    n = r->iov.iov_len / 512;
227
    if (n) {
228
        qemu_iovec_init_external(&r->qiov, &r->iov, 1);
229
        r->req.aiocb = bdrv_aio_writev(s->dinfo->bdrv, r->sector, &r->qiov, n,
230
                                   scsi_write_complete, r);
231
        if (r->req.aiocb == NULL)
232
            scsi_command_complete(r, CHECK_CONDITION,
233
                                  HARDWARE_ERROR);
234
    } else {
235
        /* Invoke completion routine to fetch data from host.  */
236
        scsi_write_complete(r, 0);
237
    }
238
}
239

    
240
/* Write data to a scsi device.  Returns nonzero on failure.
241
   The transfer may complete asynchronously.  */
242
static int scsi_write_data(SCSIDevice *d, uint32_t tag)
243
{
244
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
245
    SCSIDiskReq *r;
246

    
247
    DPRINTF("Write data tag=0x%x\n", tag);
248
    r = scsi_find_request(s, tag);
249
    if (!r) {
250
        BADF("Bad write tag 0x%x\n", tag);
251
        scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
252
        return 1;
253
    }
254

    
255
    if (r->req.aiocb)
256
        BADF("Data transfer already in progress\n");
257

    
258
    scsi_write_request(r);
259

    
260
    return 0;
261
}
262

    
263
static void scsi_dma_restart_bh(void *opaque)
264
{
265
    SCSIDiskState *s = opaque;
266
    SCSIRequest *req;
267
    SCSIDiskReq *r;
268

    
269
    qemu_bh_delete(s->bh);
270
    s->bh = NULL;
271

    
272
    QTAILQ_FOREACH(req, &s->qdev.requests, next) {
273
        r = DO_UPCAST(SCSIDiskReq, req, req);
274
        if (r->status & SCSI_REQ_STATUS_RETRY) {
275
            r->status &= ~SCSI_REQ_STATUS_RETRY;
276
            scsi_write_request(r); 
277
        }
278
    }
279
}
280

    
281
static void scsi_dma_restart_cb(void *opaque, int running, int reason)
282
{
283
    SCSIDiskState *s = opaque;
284

    
285
    if (!running)
286
        return;
287

    
288
    if (!s->bh) {
289
        s->bh = qemu_bh_new(scsi_dma_restart_bh, s);
290
        qemu_bh_schedule(s->bh);
291
    }
292
}
293

    
294
/* Return a pointer to the data buffer.  */
295
static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
296
{
297
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
298
    SCSIDiskReq *r;
299

    
300
    r = scsi_find_request(s, tag);
301
    if (!r) {
302
        BADF("Bad buffer tag 0x%x\n", tag);
303
        return NULL;
304
    }
305
    return (uint8_t *)r->iov.iov_base;
306
}
307

    
308
/* Execute a scsi command.  Returns the length of the data expected by the
309
   command.  This will be Positive for data transfers from the device
310
   (eg. disk reads), negative for transfers to the device (eg. disk writes),
311
   and zero if the command does not transfer any data.  */
312

    
313
static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
314
                                 uint8_t *buf, int lun)
315
{
316
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
317
    uint64_t nb_sectors;
318
    uint64_t lba;
319
    uint32_t len;
320
    int cmdlen;
321
    int is_write;
322
    uint8_t command;
323
    uint8_t *outbuf;
324
    SCSIDiskReq *r;
325

    
326
    command = buf[0];
327
    r = scsi_find_request(s, tag);
328
    if (r) {
329
        BADF("Tag 0x%x already in use\n", tag);
330
        scsi_cancel_io(d, tag);
331
    }
332
    /* ??? Tags are not unique for different luns.  We only implement a
333
       single lun, so this should not matter.  */
334
    r = scsi_new_request(d, tag, lun);
335
    outbuf = (uint8_t *)r->iov.iov_base;
336
    is_write = 0;
337
    DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
338
    switch (command >> 5) {
339
    case 0:
340
        lba = (uint64_t) buf[3] | ((uint64_t) buf[2] << 8) |
341
              (((uint64_t) buf[1] & 0x1f) << 16);
342
        len = buf[4];
343
        cmdlen = 6;
344
        break;
345
    case 1:
346
    case 2:
347
        lba = (uint64_t) buf[5] | ((uint64_t) buf[4] << 8) |
348
              ((uint64_t) buf[3] << 16) | ((uint64_t) buf[2] << 24);
349
        len = buf[8] | (buf[7] << 8);
350
        cmdlen = 10;
351
        break;
352
    case 4:
353
        lba = (uint64_t) buf[9] | ((uint64_t) buf[8] << 8) |
354
              ((uint64_t) buf[7] << 16) | ((uint64_t) buf[6] << 24) |
355
              ((uint64_t) buf[5] << 32) | ((uint64_t) buf[4] << 40) |
356
              ((uint64_t) buf[3] << 48) | ((uint64_t) buf[2] << 56);
357
        len = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);
358
        cmdlen = 16;
359
        break;
360
    case 5:
361
        lba = (uint64_t) buf[5] | ((uint64_t) buf[4] << 8) |
362
              ((uint64_t) buf[3] << 16) | ((uint64_t) buf[2] << 24);
363
        len = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
364
        cmdlen = 12;
365
        break;
366
    default:
367
        BADF("Unsupported command length, command %x\n", command);
368
        goto fail;
369
    }
370
#ifdef DEBUG_SCSI
371
    {
372
        int i;
373
        for (i = 1; i < cmdlen; i++) {
374
            printf(" 0x%02x", buf[i]);
375
        }
376
        printf("\n");
377
    }
378
#endif
379
    if (lun || buf[1] >> 5) {
380
        /* Only LUN 0 supported.  */
381
        DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
382
        if (command != 0x03 && command != 0x12) /* REQUEST SENSE and INQUIRY */
383
            goto fail;
384
    }
385
    switch (command) {
386
    case 0x0:
387
        DPRINTF("Test Unit Ready\n");
388
        if (!bdrv_is_inserted(s->dinfo->bdrv))
389
            goto notready;
390
        break;
391
    case 0x03:
392
        DPRINTF("Request Sense (len %d)\n", len);
393
        if (len < 4)
394
            goto fail;
395
        memset(outbuf, 0, 4);
396
        r->iov.iov_len = 4;
397
        if (s->sense == NOT_READY && len >= 18) {
398
            memset(outbuf, 0, 18);
399
            r->iov.iov_len = 18;
400
            outbuf[7] = 10;
401
            /* asc 0x3a, ascq 0: Medium not present */
402
            outbuf[12] = 0x3a;
403
            outbuf[13] = 0;
404
        }
405
        outbuf[0] = 0xf0;
406
        outbuf[1] = 0;
407
        outbuf[2] = s->sense;
408
        break;
409
    case 0x12:
410
        DPRINTF("Inquiry (len %d)\n", len);
411
        if (buf[1] & 0x2) {
412
            /* Command support data - optional, not implemented */
413
            BADF("optional INQUIRY command support request not implemented\n");
414
            goto fail;
415
        }
416
        else if (buf[1] & 0x1) {
417
            /* Vital product data */
418
            uint8_t page_code = buf[2];
419
            if (len < 4) {
420
                BADF("Error: Inquiry (EVPD[%02X]) buffer size %d is "
421
                     "less than 4\n", page_code, len);
422
                goto fail;
423
            }
424

    
425
            switch (page_code) {
426
                case 0x00:
427
                    {
428
                        /* Supported page codes, mandatory */
429
                        DPRINTF("Inquiry EVPD[Supported pages] "
430
                                "buffer size %d\n", len);
431

    
432
                        r->iov.iov_len = 0;
433

    
434
                        if (bdrv_get_type_hint(s->dinfo->bdrv) == BDRV_TYPE_CDROM) {
435
                            outbuf[r->iov.iov_len++] = 5;
436
                        } else {
437
                            outbuf[r->iov.iov_len++] = 0;
438
                        }
439

    
440
                        outbuf[r->iov.iov_len++] = 0x00; // this page
441
                        outbuf[r->iov.iov_len++] = 0x00;
442
                        outbuf[r->iov.iov_len++] = 3;    // number of pages
443
                        outbuf[r->iov.iov_len++] = 0x00; // list of supported pages (this page)
444
                        outbuf[r->iov.iov_len++] = 0x80; // unit serial number
445
                        outbuf[r->iov.iov_len++] = 0x83; // device identification
446
                    }
447
                    break;
448
                case 0x80:
449
                    {
450
                        int l;
451

    
452
                        /* Device serial number, optional */
453
                        if (len < 4) {
454
                            BADF("Error: EVPD[Serial number] Inquiry buffer "
455
                                 "size %d too small, %d needed\n", len, 4);
456
                            goto fail;
457
                        }
458

    
459
                        DPRINTF("Inquiry EVPD[Serial number] buffer size %d\n", len);
460
                        l = MIN(len, strlen(s->drive_serial_str));
461

    
462
                        r->iov.iov_len = 0;
463

    
464
                        /* Supported page codes */
465
                        if (bdrv_get_type_hint(s->dinfo->bdrv) == BDRV_TYPE_CDROM) {
466
                            outbuf[r->iov.iov_len++] = 5;
467
                        } else {
468
                            outbuf[r->iov.iov_len++] = 0;
469
                        }
470

    
471
                        outbuf[r->iov.iov_len++] = 0x80; // this page
472
                        outbuf[r->iov.iov_len++] = 0x00;
473
                        outbuf[r->iov.iov_len++] = l;
474
                        memcpy(&outbuf[r->iov.iov_len], s->drive_serial_str, l);
475
                        r->iov.iov_len += l;
476
                    }
477

    
478
                    break;
479
                case 0x83:
480
                    {
481
                        /* Device identification page, mandatory */
482
                        int max_len = 255 - 8;
483
                        int id_len = strlen(bdrv_get_device_name(s->dinfo->bdrv));
484
                        if (id_len > max_len)
485
                            id_len = max_len;
486

    
487
                        DPRINTF("Inquiry EVPD[Device identification] "
488
                                "buffer size %d\n", len);
489
                        r->iov.iov_len = 0;
490
                        if (bdrv_get_type_hint(s->dinfo->bdrv) == BDRV_TYPE_CDROM) {
491
                            outbuf[r->iov.iov_len++] = 5;
492
                        } else {
493
                            outbuf[r->iov.iov_len++] = 0;
494
                        }
495

    
496
                        outbuf[r->iov.iov_len++] = 0x83; // this page
497
                        outbuf[r->iov.iov_len++] = 0x00;
498
                        outbuf[r->iov.iov_len++] = 3 + id_len;
499

    
500
                        outbuf[r->iov.iov_len++] = 0x2; // ASCII
501
                        outbuf[r->iov.iov_len++] = 0;   // not officially assigned
502
                        outbuf[r->iov.iov_len++] = 0;   // reserved
503
                        outbuf[r->iov.iov_len++] = id_len; // length of data following
504

    
505
                        memcpy(&outbuf[r->iov.iov_len],
506
                               bdrv_get_device_name(s->dinfo->bdrv), id_len);
507
                        r->iov.iov_len += id_len;
508
                    }
509
                    break;
510
                default:
511
                    BADF("Error: unsupported Inquiry (EVPD[%02X]) "
512
                         "buffer size %d\n", page_code, len);
513
                    goto fail;
514
            }
515
            /* done with EVPD */
516
            break;
517
        }
518
        else {
519
            /* Standard INQUIRY data */
520
            if (buf[2] != 0) {
521
                BADF("Error: Inquiry (STANDARD) page or code "
522
                     "is non-zero [%02X]\n", buf[2]);
523
                goto fail;
524
            }
525

    
526
            /* PAGE CODE == 0 */
527
            if (len < 5) {
528
                BADF("Error: Inquiry (STANDARD) buffer size %d "
529
                     "is less than 5\n", len);
530
                goto fail;
531
            }
532

    
533
            if (len < 36) {
534
                BADF("Error: Inquiry (STANDARD) buffer size %d "
535
                     "is less than 36 (TODO: only 5 required)\n", len);
536
            }
537
        }
538

    
539
        if(len > SCSI_MAX_INQUIRY_LEN)
540
            len = SCSI_MAX_INQUIRY_LEN;
541

    
542
        memset(outbuf, 0, len);
543

    
544
        if (lun || buf[1] >> 5) {
545
            outbuf[0] = 0x7f;        /* LUN not supported */
546
        } else if (bdrv_get_type_hint(s->dinfo->bdrv) == BDRV_TYPE_CDROM) {
547
            outbuf[0] = 5;
548
            outbuf[1] = 0x80;
549
            memcpy(&outbuf[16], "QEMU CD-ROM    ", 16);
550
        } else {
551
            outbuf[0] = 0;
552
            memcpy(&outbuf[16], "QEMU HARDDISK  ", 16);
553
        }
554
        memcpy(&outbuf[8], "QEMU   ", 8);
555
        memcpy(&outbuf[32], QEMU_VERSION, 4);
556
        /* Identify device as SCSI-3 rev 1.
557
           Some later commands are also implemented. */
558
        outbuf[2] = 3;
559
        outbuf[3] = 2; /* Format 2 */
560
        outbuf[4] = len - 5; /* Additional Length = (Len - 1) - 4 */
561
        /* Sync data transfer and TCQ.  */
562
        outbuf[7] = 0x10 | (r->req.bus->tcq ? 0x02 : 0);
563
        r->iov.iov_len = len;
564
        break;
565
    case 0x16:
566
        DPRINTF("Reserve(6)\n");
567
        if (buf[1] & 1)
568
            goto fail;
569
        break;
570
    case 0x17:
571
        DPRINTF("Release(6)\n");
572
        if (buf[1] & 1)
573
            goto fail;
574
        break;
575
    case 0x1a:
576
    case 0x5a:
577
        {
578
            uint8_t *p;
579
            int page;
580
            int dbd;
581
            
582
            dbd = buf[1]  & 0x8;
583
            page = buf[2] & 0x3f;
584
            DPRINTF("Mode Sense (page %d, len %d)\n", page, len);
585
            p = outbuf;
586
            memset(p, 0, 4);
587
            outbuf[1] = 0; /* Default media type.  */
588
            outbuf[3] = 0; /* Block descriptor length.  */
589
            if (bdrv_get_type_hint(s->dinfo->bdrv) == BDRV_TYPE_CDROM ||
590
                bdrv_is_read_only(s->dinfo->bdrv)) {
591
                outbuf[2] = 0x80; /* Readonly.  */
592
            }
593
            p += 4;
594
            bdrv_get_geometry(s->dinfo->bdrv, &nb_sectors);
595
            if ((~dbd) & nb_sectors) {
596
                nb_sectors /= s->cluster_size;
597
                nb_sectors--;
598
                if (nb_sectors > 0xffffff)
599
                    nb_sectors = 0xffffff;
600
                outbuf[3] = 8; /* Block descriptor length  */
601
                p[0] = 0; /* media density code */
602
                p[1] = (nb_sectors >> 16) & 0xff;
603
                p[2] = (nb_sectors >> 8) & 0xff;
604
                p[3] = nb_sectors & 0xff;
605
                p[4] = 0; /* reserved */
606
                p[5] = 0; /* bytes 5-7 are the sector size in bytes */
607
                p[6] = s->cluster_size * 2;
608
                p[7] = 0;
609
                p += 8;
610
            }
611

    
612
            if (page == 4) {
613
                int cylinders, heads, secs;
614

    
615
                /* Rigid disk device geometry page. */
616
                p[0] = 4;
617
                p[1] = 0x16;
618
                /* if a geometry hint is available, use it */
619
                bdrv_get_geometry_hint(s->dinfo->bdrv, &cylinders, &heads, &secs);
620
                p[2] = (cylinders >> 16) & 0xff;
621
                p[3] = (cylinders >> 8) & 0xff;
622
                p[4] = cylinders & 0xff;
623
                p[5] = heads & 0xff;
624
                /* Write precomp start cylinder, disabled */
625
                p[6] = (cylinders >> 16) & 0xff;
626
                p[7] = (cylinders >> 8) & 0xff;
627
                p[8] = cylinders & 0xff;
628
                /* Reduced current start cylinder, disabled */
629
                p[9] = (cylinders >> 16) & 0xff;
630
                p[10] = (cylinders >> 8) & 0xff;
631
                p[11] = cylinders & 0xff;
632
                /* Device step rate [ns], 200ns */
633
                p[12] = 0;
634
                p[13] = 200;
635
                /* Landing zone cylinder */
636
                p[14] = 0xff;
637
                p[15] =  0xff;
638
                p[16] = 0xff;
639
                /* Medium rotation rate [rpm], 5400 rpm */
640
                p[20] = (5400 >> 8) & 0xff;
641
                p[21] = 5400 & 0xff;
642
                p += 0x16;
643
            } else if (page == 5) {
644
                int cylinders, heads, secs;
645

    
646
                /* Flexible disk device geometry page. */
647
                p[0] = 5;
648
                p[1] = 0x1e;
649
                /* Transfer rate [kbit/s], 5Mbit/s */
650
                p[2] = 5000 >> 8;
651
                p[3] = 5000 & 0xff;
652
                /* if a geometry hint is available, use it */
653
                bdrv_get_geometry_hint(s->dinfo->bdrv, &cylinders, &heads, &secs);
654
                p[4] = heads & 0xff;
655
                p[5] = secs & 0xff;
656
                p[6] = s->cluster_size * 2;
657
                p[8] = (cylinders >> 8) & 0xff;
658
                p[9] = cylinders & 0xff;
659
                /* Write precomp start cylinder, disabled */
660
                p[10] = (cylinders >> 8) & 0xff;
661
                p[11] = cylinders & 0xff;
662
                /* Reduced current start cylinder, disabled */
663
                p[12] = (cylinders >> 8) & 0xff;
664
                p[13] = cylinders & 0xff;
665
                /* Device step rate [100us], 100us */
666
                p[14] = 0;
667
                p[15] = 1;
668
                /* Device step pulse width [us], 1us */
669
                p[16] = 1;
670
                /* Device head settle delay [100us], 100us */
671
                p[17] = 0;
672
                p[18] = 1;
673
                /* Motor on delay [0.1s], 0.1s */
674
                p[19] = 1;
675
                /* Motor off delay [0.1s], 0.1s */
676
                p[20] = 1;
677
                /* Medium rotation rate [rpm], 5400 rpm */
678
                p[28] = (5400 >> 8) & 0xff;
679
                p[29] = 5400 & 0xff;
680
                p += 0x1e;
681
            } else if ((page == 8 || page == 0x3f)) {
682
                /* Caching page.  */
683
                memset(p,0,20);
684
                p[0] = 8;
685
                p[1] = 0x12;
686
                if (bdrv_enable_write_cache(s->dinfo->bdrv)) {
687
                     p[2] = 4; /* WCE */
688
                }
689
                p += 20;
690
            }
691
            if ((page == 0x3f || page == 0x2a)
692
                    && (bdrv_get_type_hint(s->dinfo->bdrv) == BDRV_TYPE_CDROM)) {
693
                /* CD Capabilities and Mechanical Status page. */
694
                p[0] = 0x2a;
695
                p[1] = 0x14;
696
                p[2] = 3; // CD-R & CD-RW read
697
                p[3] = 0; // Writing not supported
698
                p[4] = 0x7f; /* Audio, composite, digital out,
699
                                         mode 2 form 1&2, multi session */
700
                p[5] = 0xff; /* CD DA, DA accurate, RW supported,
701
                                         RW corrected, C2 errors, ISRC,
702
                                         UPC, Bar code */
703
                p[6] = 0x2d | (bdrv_is_locked(s->dinfo->bdrv)? 2 : 0);
704
                /* Locking supported, jumper present, eject, tray */
705
                p[7] = 0; /* no volume & mute control, no
706
                                      changer */
707
                p[8] = (50 * 176) >> 8; // 50x read speed
708
                p[9] = (50 * 176) & 0xff;
709
                p[10] = 0 >> 8; // No volume
710
                p[11] = 0 & 0xff;
711
                p[12] = 2048 >> 8; // 2M buffer
712
                p[13] = 2048 & 0xff;
713
                p[14] = (16 * 176) >> 8; // 16x read speed current
714
                p[15] = (16 * 176) & 0xff;
715
                p[18] = (16 * 176) >> 8; // 16x write speed
716
                p[19] = (16 * 176) & 0xff;
717
                p[20] = (16 * 176) >> 8; // 16x write speed current
718
                p[21] = (16 * 176) & 0xff;
719
                p += 22;
720
            }
721
            r->iov.iov_len = p - outbuf;
722
            outbuf[0] = r->iov.iov_len - 4;
723
            if (r->iov.iov_len > len)
724
                r->iov.iov_len = len;
725
        }
726
        break;
727
    case 0x1b:
728
        DPRINTF("Start Stop Unit\n");
729
        if (bdrv_get_type_hint(s->dinfo->bdrv) == BDRV_TYPE_CDROM &&
730
            (buf[4] & 2))
731
            /* load/eject medium */
732
            bdrv_eject(s->dinfo->bdrv, !(buf[4] & 1));
733
        break;
734
    case 0x1e:
735
        DPRINTF("Prevent Allow Medium Removal (prevent = %d)\n", buf[4] & 3);
736
        bdrv_set_locked(s->dinfo->bdrv, buf[4] & 1);
737
        break;
738
    case 0x25:
739
        DPRINTF("Read Capacity\n");
740
        /* The normal LEN field for this command is zero.  */
741
        memset(outbuf, 0, 8);
742
        bdrv_get_geometry(s->dinfo->bdrv, &nb_sectors);
743
        nb_sectors /= s->cluster_size;
744
        /* Returned value is the address of the last sector.  */
745
        if (nb_sectors) {
746
            nb_sectors--;
747
            /* Remember the new size for read/write sanity checking. */
748
            s->max_lba = nb_sectors;
749
            /* Clip to 2TB, instead of returning capacity modulo 2TB. */
750
            if (nb_sectors > UINT32_MAX)
751
                nb_sectors = UINT32_MAX;
752
            outbuf[0] = (nb_sectors >> 24) & 0xff;
753
            outbuf[1] = (nb_sectors >> 16) & 0xff;
754
            outbuf[2] = (nb_sectors >> 8) & 0xff;
755
            outbuf[3] = nb_sectors & 0xff;
756
            outbuf[4] = 0;
757
            outbuf[5] = 0;
758
            outbuf[6] = s->cluster_size * 2;
759
            outbuf[7] = 0;
760
            r->iov.iov_len = 8;
761
        } else {
762
        notready:
763
            scsi_command_complete(r, CHECK_CONDITION, NOT_READY);
764
            return 0;
765
        }
766
        break;
767
    case 0x08:
768
    case 0x28:
769
    case 0x88:
770
        DPRINTF("Read (sector %" PRId64 ", count %d)\n", lba, len);
771
        if (lba > s->max_lba)
772
            goto illegal_lba;
773
        r->sector = lba * s->cluster_size;
774
        r->sector_count = len * s->cluster_size;
775
        break;
776
    case 0x0a:
777
    case 0x2a:
778
    case 0x8a:
779
        DPRINTF("Write (sector %" PRId64 ", count %d)\n", lba, len);
780
        if (lba > s->max_lba)
781
            goto illegal_lba;
782
        r->sector = lba * s->cluster_size;
783
        r->sector_count = len * s->cluster_size;
784
        is_write = 1;
785
        break;
786
    case 0x35:
787
        DPRINTF("Synchronise cache (sector %" PRId64 ", count %d)\n", lba, len);
788
        bdrv_flush(s->dinfo->bdrv);
789
        break;
790
    case 0x43:
791
        {
792
            int start_track, format, msf, toclen;
793

    
794
            msf = buf[1] & 2;
795
            format = buf[2] & 0xf;
796
            start_track = buf[6];
797
            bdrv_get_geometry(s->dinfo->bdrv, &nb_sectors);
798
            DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
799
            nb_sectors /= s->cluster_size;
800
            switch(format) {
801
            case 0:
802
                toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
803
                break;
804
            case 1:
805
                /* multi session : only a single session defined */
806
                toclen = 12;
807
                memset(outbuf, 0, 12);
808
                outbuf[1] = 0x0a;
809
                outbuf[2] = 0x01;
810
                outbuf[3] = 0x01;
811
                break;
812
            case 2:
813
                toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
814
                break;
815
            default:
816
                goto error_cmd;
817
            }
818
            if (toclen > 0) {
819
                if (len > toclen)
820
                  len = toclen;
821
                r->iov.iov_len = len;
822
                break;
823
            }
824
        error_cmd:
825
            DPRINTF("Read TOC error\n");
826
            goto fail;
827
        }
828
    case 0x46:
829
        DPRINTF("Get Configuration (rt %d, maxlen %d)\n", buf[1] & 3, len);
830
        memset(outbuf, 0, 8);
831
        /* ??? This should probably return much more information.  For now
832
           just return the basic header indicating the CD-ROM profile.  */
833
        outbuf[7] = 8; // CD-ROM
834
        r->iov.iov_len = 8;
835
        break;
836
    case 0x56:
837
        DPRINTF("Reserve(10)\n");
838
        if (buf[1] & 3)
839
            goto fail;
840
        break;
841
    case 0x57:
842
        DPRINTF("Release(10)\n");
843
        if (buf[1] & 3)
844
            goto fail;
845
        break;
846
    case 0x9e:
847
        /* Service Action In subcommands. */
848
        if ((buf[1] & 31) == 0x10) {
849
            DPRINTF("SAI READ CAPACITY(16)\n");
850
            memset(outbuf, 0, len);
851
            bdrv_get_geometry(s->dinfo->bdrv, &nb_sectors);
852
            nb_sectors /= s->cluster_size;
853
            /* Returned value is the address of the last sector.  */
854
            if (nb_sectors) {
855
                nb_sectors--;
856
                /* Remember the new size for read/write sanity checking. */
857
                s->max_lba = nb_sectors;
858
                outbuf[0] = (nb_sectors >> 56) & 0xff;
859
                outbuf[1] = (nb_sectors >> 48) & 0xff;
860
                outbuf[2] = (nb_sectors >> 40) & 0xff;
861
                outbuf[3] = (nb_sectors >> 32) & 0xff;
862
                outbuf[4] = (nb_sectors >> 24) & 0xff;
863
                outbuf[5] = (nb_sectors >> 16) & 0xff;
864
                outbuf[6] = (nb_sectors >> 8) & 0xff;
865
                outbuf[7] = nb_sectors & 0xff;
866
                outbuf[8] = 0;
867
                outbuf[9] = 0;
868
                outbuf[10] = s->cluster_size * 2;
869
                outbuf[11] = 0;
870
                /* Protection, exponent and lowest lba field left blank. */
871
                r->iov.iov_len = len;
872
            } else {
873
                scsi_command_complete(r, CHECK_CONDITION, NOT_READY);
874
                return 0;
875
            }
876
            break;
877
        }
878
        DPRINTF("Unsupported Service Action In\n");
879
        goto fail;
880
    case 0xa0:
881
        DPRINTF("Report LUNs (len %d)\n", len);
882
        if (len < 16)
883
            goto fail;
884
        memset(outbuf, 0, 16);
885
        outbuf[3] = 8;
886
        r->iov.iov_len = 16;
887
        break;
888
    case 0x2f:
889
        DPRINTF("Verify (sector %" PRId64 ", count %d)\n", lba, len);
890
        break;
891
    default:
892
        DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
893
    fail:
894
        scsi_command_complete(r, CHECK_CONDITION, ILLEGAL_REQUEST);
895
        return 0;
896
    illegal_lba:
897
        scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
898
        return 0;
899
    }
900
    if (r->sector_count == 0 && r->iov.iov_len == 0) {
901
        scsi_command_complete(r, GOOD, NO_SENSE);
902
    }
903
    len = r->sector_count * 512 + r->iov.iov_len;
904
    if (is_write) {
905
        return -len;
906
    } else {
907
        if (!r->sector_count)
908
            r->sector_count = -1;
909
        return len;
910
    }
911
}
912

    
913
static void scsi_destroy(SCSIDevice *dev)
914
{
915
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
916
    SCSIDiskReq *r;
917

    
918
    while (!QTAILQ_EMPTY(&s->qdev.requests)) {
919
        r = DO_UPCAST(SCSIDiskReq, req, QTAILQ_FIRST(&s->qdev.requests));
920
        scsi_remove_request(r);
921
    }
922
    drive_uninit(s->dinfo);
923
}
924

    
925
static int scsi_disk_initfn(SCSIDevice *dev)
926
{
927
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
928
    uint64_t nb_sectors;
929

    
930
    if (!s->dinfo || !s->dinfo->bdrv) {
931
        qemu_error("scsi-disk: drive property not set\n");
932
        return -1;
933
    }
934

    
935
    if (bdrv_get_type_hint(s->dinfo->bdrv) == BDRV_TYPE_CDROM) {
936
        s->cluster_size = 4;
937
    } else {
938
        s->cluster_size = 1;
939
    }
940
    s->qdev.blocksize = 512 * s->cluster_size;
941
    bdrv_get_geometry(s->dinfo->bdrv, &nb_sectors);
942
    nb_sectors /= s->cluster_size;
943
    if (nb_sectors)
944
        nb_sectors--;
945
    s->max_lba = nb_sectors;
946
    strncpy(s->drive_serial_str, drive_get_serial(s->dinfo->bdrv),
947
            sizeof(s->drive_serial_str));
948
    if (strlen(s->drive_serial_str) == 0)
949
        pstrcpy(s->drive_serial_str, sizeof(s->drive_serial_str), "0");
950
    qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s);
951
    return 0;
952
}
953

    
954
static SCSIDeviceInfo scsi_disk_info = {
955
    .qdev.name    = "scsi-disk",
956
    .qdev.desc    = "virtual scsi disk or cdrom",
957
    .qdev.size    = sizeof(SCSIDiskState),
958
    .init         = scsi_disk_initfn,
959
    .destroy      = scsi_destroy,
960
    .send_command = scsi_send_command,
961
    .read_data    = scsi_read_data,
962
    .write_data   = scsi_write_data,
963
    .cancel_io    = scsi_cancel_io,
964
    .get_buf      = scsi_get_buf,
965
    .qdev.props   = (Property[]) {
966
        DEFINE_PROP_DRIVE("drive", SCSIDiskState, dinfo),
967
        DEFINE_PROP_END_OF_LIST(),
968
    },
969
};
970

    
971
static void scsi_disk_register_devices(void)
972
{
973
    scsi_qdev_register(&scsi_disk_info);
974
}
975
device_init(scsi_disk_register_devices)