Statistics
| Branch: | Revision:

root / hw / scsi-generic.c @ 6521dc62

History | View | Annotate | Download (18.7 kB)

1
/*
2
 * Generic SCSI Device support
3
 *
4
 * Copyright (c) 2007 Bull S.A.S.
5
 * Based on code by Paul Brook
6
 * Based on code by Fabrice Bellard
7
 *
8
 * Written by Laurent Vivier <Laurent.Vivier@bull.net>
9
 *
10
 * This code is licenced under the LGPL.
11
 *
12
 */
13

    
14
#include "qemu-common.h"
15
#include "block.h"
16
#include "scsi-disk.h"
17

    
18
#ifdef __linux__
19

    
20
//#define DEBUG_SCSI
21

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

    
29
#define BADF(fmt, ...) \
30
do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
31

    
32
#include <stdio.h>
33
#include <sys/types.h>
34
#include <sys/stat.h>
35
#include <unistd.h>
36
#include <scsi/sg.h>
37
#include <scsi/scsi.h>
38

    
39
#define REWIND 0x01
40
#define REPORT_DENSITY_SUPPORT 0x44
41
#define LOAD_UNLOAD 0xa6
42
#define SET_CD_SPEED 0xbb
43
#define BLANK 0xa1
44

    
45
#define SCSI_CMD_BUF_SIZE     16
46
#define SCSI_SENSE_BUF_SIZE 96
47

    
48
#define SG_ERR_DRIVER_TIMEOUT 0x06
49
#define SG_ERR_DRIVER_SENSE 0x08
50

    
51
#ifndef MAX_UINT
52
#define MAX_UINT ((unsigned int)-1)
53
#endif
54

    
55
typedef struct SCSIGenericState SCSIGenericState;
56

    
57
typedef struct SCSIRequest {
58
    BlockDriverAIOCB *aiocb;
59
    struct SCSIRequest *next;
60
    SCSIBus *bus;
61
    SCSIGenericState *dev;
62
    uint32_t tag;
63
    uint8_t cmd[SCSI_CMD_BUF_SIZE];
64
    int cmdlen;
65
    uint8_t *buf;
66
    int buflen;
67
    int len;
68
    sg_io_hdr_t io_header;
69
} SCSIRequest;
70

    
71
struct SCSIGenericState
72
{
73
    SCSIDevice qdev;
74
    SCSIRequest *requests;
75
    DriveInfo *dinfo;
76
    int type;
77
    int blocksize;
78
    int lun;
79
    int driver_status;
80
    uint8_t sensebuf[SCSI_SENSE_BUF_SIZE];
81
    uint8_t senselen;
82
};
83

    
84
/* Global pool of SCSIRequest structures.  */
85
static SCSIRequest *free_requests = NULL;
86

    
87
static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag)
88
{
89
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
90
    SCSIRequest *r;
91

    
92
    if (free_requests) {
93
        r = free_requests;
94
        free_requests = r->next;
95
    } else {
96
        r = qemu_malloc(sizeof(SCSIRequest));
97
        r->buf = NULL;
98
        r->buflen = 0;
99
    }
100
    r->bus = scsi_bus_from_device(d);
101
    r->dev = s;
102
    r->tag = tag;
103
    memset(r->cmd, 0, sizeof(r->cmd));
104
    memset(&r->io_header, 0, sizeof(r->io_header));
105
    r->cmdlen = 0;
106
    r->len = 0;
107
    r->aiocb = NULL;
108

    
109
    /* link */
110

    
111
    r->next = s->requests;
112
    s->requests = r;
113
    return r;
114
}
115

    
116
static void scsi_remove_request(SCSIRequest *r)
117
{
118
    SCSIRequest *last;
119
    SCSIGenericState *s = r->dev;
120

    
121
    if (s->requests == r) {
122
        s->requests = r->next;
123
    } else {
124
        last = s->requests;
125
        while (last && last->next != r)
126
            last = last->next;
127
        if (last) {
128
            last->next = r->next;
129
        } else {
130
            BADF("Orphaned request\n");
131
        }
132
    }
133
    r->next = free_requests;
134
    free_requests = r;
135
}
136

    
137
static SCSIRequest *scsi_find_request(SCSIGenericState *s, uint32_t tag)
138
{
139
    SCSIRequest *r;
140

    
141
    r = s->requests;
142
    while (r && r->tag != tag)
143
        r = r->next;
144

    
145
    return r;
146
}
147

    
148
/* Helper function for command completion.  */
149
static void scsi_command_complete(void *opaque, int ret)
150
{
151
    SCSIRequest *r = (SCSIRequest *)opaque;
152
    SCSIGenericState *s = r->dev;
153
    uint32_t tag;
154
    int status;
155

    
156
    s->driver_status = r->io_header.driver_status;
157
    if (s->driver_status & SG_ERR_DRIVER_SENSE)
158
        s->senselen = r->io_header.sb_len_wr;
159

    
160
    if (ret != 0)
161
        status = BUSY << 1;
162
    else {
163
        if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
164
            status = BUSY << 1;
165
            BADF("Driver Timeout\n");
166
        } else if (r->io_header.status)
167
            status = r->io_header.status;
168
        else if (s->driver_status & SG_ERR_DRIVER_SENSE)
169
            status = CHECK_CONDITION << 1;
170
        else
171
            status = GOOD << 1;
172
    }
173
    DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
174
            r, r->tag, status);
175
    tag = r->tag;
176
    scsi_remove_request(r);
177
    r->bus->complete(r->bus, SCSI_REASON_DONE, tag, status);
178
}
179

    
180
/* Cancel a pending data transfer.  */
181
static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
182
{
183
    DPRINTF("scsi_cancel_io 0x%x\n", tag);
184
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
185
    SCSIRequest *r;
186
    DPRINTF("Cancel tag=0x%x\n", tag);
187
    r = scsi_find_request(s, tag);
188
    if (r) {
189
        if (r->aiocb)
190
            bdrv_aio_cancel(r->aiocb);
191
        r->aiocb = NULL;
192
        scsi_remove_request(r);
193
    }
194
}
195

    
196
static int execute_command(BlockDriverState *bdrv,
197
                           SCSIRequest *r, int direction,
198
                           BlockDriverCompletionFunc *complete)
199
{
200
    r->io_header.interface_id = 'S';
201
    r->io_header.dxfer_direction = direction;
202
    r->io_header.dxferp = r->buf;
203
    r->io_header.dxfer_len = r->buflen;
204
    r->io_header.cmdp = r->cmd;
205
    r->io_header.cmd_len = r->cmdlen;
206
    r->io_header.mx_sb_len = sizeof(r->dev->sensebuf);
207
    r->io_header.sbp = r->dev->sensebuf;
208
    r->io_header.timeout = MAX_UINT;
209
    r->io_header.usr_ptr = r;
210
    r->io_header.flags |= SG_FLAG_DIRECT_IO;
211

    
212
    r->aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
213
    if (r->aiocb == NULL) {
214
        BADF("execute_command: read failed !\n");
215
        return -1;
216
    }
217

    
218
    return 0;
219
}
220

    
221
static void scsi_read_complete(void * opaque, int ret)
222
{
223
    SCSIRequest *r = (SCSIRequest *)opaque;
224
    int len;
225

    
226
    if (ret) {
227
        DPRINTF("IO error\n");
228
        scsi_command_complete(r, ret);
229
        return;
230
    }
231
    len = r->io_header.dxfer_len - r->io_header.resid;
232
    DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, len);
233

    
234
    r->len = -1;
235
    r->bus->complete(r->bus, SCSI_REASON_DATA, r->tag, len);
236
    if (len == 0)
237
        scsi_command_complete(r, 0);
238
}
239

    
240
/* Read more data from scsi device into buffer.  */
241
static void scsi_read_data(SCSIDevice *d, uint32_t tag)
242
{
243
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
244
    SCSIRequest *r;
245
    int ret;
246

    
247
    DPRINTF("scsi_read_data 0x%x\n", tag);
248
    r = scsi_find_request(s, tag);
249
    if (!r) {
250
        BADF("Bad read tag 0x%x\n", tag);
251
        /* ??? This is the wrong error.  */
252
        scsi_command_complete(r, -EINVAL);
253
        return;
254
    }
255

    
256
    if (r->len == -1) {
257
        scsi_command_complete(r, 0);
258
        return;
259
    }
260

    
261
    if (r->cmd[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
262
    {
263
        s->senselen = MIN(r->len, s->senselen);
264
        memcpy(r->buf, s->sensebuf, s->senselen);
265
        r->io_header.driver_status = 0;
266
        r->io_header.status = 0;
267
        r->io_header.dxfer_len  = s->senselen;
268
        r->len = -1;
269
        DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, s->senselen);
270
        DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
271
                r->buf[0], r->buf[1], r->buf[2], r->buf[3],
272
                r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
273
        r->bus->complete(r->bus, SCSI_REASON_DATA, r->tag, s->senselen);
274
        return;
275
    }
276

    
277
    ret = execute_command(s->dinfo->bdrv, r, SG_DXFER_FROM_DEV, scsi_read_complete);
278
    if (ret == -1) {
279
        scsi_command_complete(r, -EINVAL);
280
        return;
281
    }
282
}
283

    
284
static void scsi_write_complete(void * opaque, int ret)
285
{
286
    SCSIRequest *r = (SCSIRequest *)opaque;
287

    
288
    DPRINTF("scsi_write_complete() ret = %d\n", ret);
289
    if (ret) {
290
        DPRINTF("IO error\n");
291
        scsi_command_complete(r, ret);
292
        return;
293
    }
294

    
295
    if (r->cmd[0] == MODE_SELECT && r->cmd[4] == 12 &&
296
        r->dev->type == TYPE_TAPE) {
297
        r->dev->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
298
        DPRINTF("block size %d\n", r->dev->blocksize);
299
    }
300

    
301
    scsi_command_complete(r, ret);
302
}
303

    
304
/* Write data to a scsi device.  Returns nonzero on failure.
305
   The transfer may complete asynchronously.  */
306
static int scsi_write_data(SCSIDevice *d, uint32_t tag)
307
{
308
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
309
    SCSIRequest *r;
310
    int ret;
311

    
312
    DPRINTF("scsi_write_data 0x%x\n", tag);
313
    r = scsi_find_request(s, tag);
314
    if (!r) {
315
        BADF("Bad write tag 0x%x\n", tag);
316
        /* ??? This is the wrong error.  */
317
        scsi_command_complete(r, -EINVAL);
318
        return 0;
319
    }
320

    
321
    if (r->len == 0) {
322
        r->len = r->buflen;
323
        r->bus->complete(r->bus, SCSI_REASON_DATA, r->tag, r->len);
324
        return 0;
325
    }
326

    
327
    ret = execute_command(s->dinfo->bdrv, r, SG_DXFER_TO_DEV, scsi_write_complete);
328
    if (ret == -1) {
329
        scsi_command_complete(r, -EINVAL);
330
        return 1;
331
    }
332

    
333
    return 0;
334
}
335

    
336
/* Return a pointer to the data buffer.  */
337
static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
338
{
339
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
340
    SCSIRequest *r;
341
    r = scsi_find_request(s, tag);
342
    if (!r) {
343
        BADF("Bad buffer tag 0x%x\n", tag);
344
        return NULL;
345
    }
346
    return r->buf;
347
}
348

    
349
static int scsi_length(uint8_t *cmd, int blocksize, int *cmdlen, uint32_t *len)
350
{
351
    switch (cmd[0] >> 5) {
352
    case 0:
353
        *len = cmd[4];
354
        *cmdlen = 6;
355
        /* length 0 means 256 blocks */
356
        if (*len == 0)
357
            *len = 256;
358
        break;
359
    case 1:
360
    case 2:
361
        *len = cmd[8] | (cmd[7] << 8);
362
        *cmdlen = 10;
363
        break;
364
    case 4:
365
        *len = cmd[13] | (cmd[12] << 8) | (cmd[11] << 16) | (cmd[10] << 24);
366
        *cmdlen = 16;
367
        break;
368
    case 5:
369
        *len = cmd[9] | (cmd[8] << 8) | (cmd[7] << 16) | (cmd[6] << 24);
370
        *cmdlen = 12;
371
        break;
372
    default:
373
        return -1;
374
    }
375

    
376
    switch(cmd[0]) {
377
    case TEST_UNIT_READY:
378
    case REZERO_UNIT:
379
    case START_STOP:
380
    case SEEK_6:
381
    case WRITE_FILEMARKS:
382
    case SPACE:
383
    case ERASE:
384
    case ALLOW_MEDIUM_REMOVAL:
385
    case VERIFY:
386
    case SEEK_10:
387
    case SYNCHRONIZE_CACHE:
388
    case LOCK_UNLOCK_CACHE:
389
    case LOAD_UNLOAD:
390
    case SET_CD_SPEED:
391
    case SET_LIMITS:
392
    case WRITE_LONG:
393
    case MOVE_MEDIUM:
394
    case UPDATE_BLOCK:
395
        *len = 0;
396
        break;
397
    case MODE_SENSE:
398
        break;
399
    case WRITE_SAME:
400
        *len = 1;
401
        break;
402
    case READ_CAPACITY:
403
        *len = 8;
404
        break;
405
    case READ_BLOCK_LIMITS:
406
        *len = 6;
407
        break;
408
    case READ_POSITION:
409
        *len = 20;
410
        break;
411
    case SEND_VOLUME_TAG:
412
        *len *= 40;
413
        break;
414
    case MEDIUM_SCAN:
415
        *len *= 8;
416
        break;
417
    case WRITE_10:
418
        cmd[1] &= ~0x08;        /* disable FUA */
419
    case WRITE_VERIFY:
420
    case WRITE_6:
421
    case WRITE_12:
422
    case WRITE_VERIFY_12:
423
        *len *= blocksize;
424
        break;
425
    case READ_10:
426
        cmd[1] &= ~0x08;        /* disable FUA */
427
    case READ_6:
428
    case READ_REVERSE:
429
    case RECOVER_BUFFERED_DATA:
430
    case READ_12:
431
        *len *= blocksize;
432
        break;
433
    case INQUIRY:
434
        *len = cmd[4] | (cmd[3] << 8);
435
        break;
436
    }
437
    return 0;
438
}
439

    
440
static int scsi_stream_length(uint8_t *cmd, int blocksize, int *cmdlen, uint32_t *len)
441
{
442
    switch(cmd[0]) {
443
    /* stream commands */
444
    case READ_6:
445
    case READ_REVERSE:
446
    case RECOVER_BUFFERED_DATA:
447
    case WRITE_6:
448
        *cmdlen = 6;
449
        *len = cmd[4] | (cmd[3] << 8) | (cmd[2] << 16);
450
        if (cmd[1] & 0x01) /* fixed */
451
            *len *= blocksize;
452
        break;
453
    case REWIND:
454
    case START_STOP:
455
        *cmdlen = 6;
456
        *len = 0;
457
        cmd[1] = 0x01;        /* force IMMED, otherwise qemu waits end of command */
458
        break;
459
    /* generic commands */
460
    default:
461
        return scsi_length(cmd, blocksize, cmdlen, len);
462
    }
463
    return 0;
464
}
465

    
466
static int is_write(int command)
467
{
468
    switch (command) {
469
    case COPY:
470
    case COPY_VERIFY:
471
    case COMPARE:
472
    case CHANGE_DEFINITION:
473
    case LOG_SELECT:
474
    case MODE_SELECT:
475
    case MODE_SELECT_10:
476
    case SEND_DIAGNOSTIC:
477
    case WRITE_BUFFER:
478
    case FORMAT_UNIT:
479
    case REASSIGN_BLOCKS:
480
    case RESERVE:
481
    case SEARCH_EQUAL:
482
    case SEARCH_HIGH:
483
    case SEARCH_LOW:
484
    case WRITE_6:
485
    case WRITE_10:
486
    case WRITE_VERIFY:
487
    case UPDATE_BLOCK:
488
    case WRITE_LONG:
489
    case WRITE_SAME:
490
    case SEARCH_HIGH_12:
491
    case SEARCH_EQUAL_12:
492
    case SEARCH_LOW_12:
493
    case WRITE_12:
494
    case WRITE_VERIFY_12:
495
    case SET_WINDOW:
496
    case MEDIUM_SCAN:
497
    case SEND_VOLUME_TAG:
498
    case WRITE_LONG_2:
499
        return 1;
500
    }
501
    return 0;
502
}
503

    
504
/* Execute a scsi command.  Returns the length of the data expected by the
505
   command.  This will be Positive for data transfers from the device
506
   (eg. disk reads), negative for transfers to the device (eg. disk writes),
507
   and zero if the command does not transfer any data.  */
508

    
509
static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
510
                                 uint8_t *cmd, int lun)
511
{
512
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
513
    uint32_t len=0;
514
    int cmdlen=0;
515
    SCSIRequest *r;
516
    SCSIBus *bus;
517
    int ret;
518

    
519
    if (s->type == TYPE_TAPE) {
520
        if (scsi_stream_length(cmd, s->blocksize, &cmdlen, &len) == -1) {
521
            BADF("Unsupported command length, command %x\n", cmd[0]);
522
            return 0;
523
        }
524
     } else {
525
        if (scsi_length(cmd, s->blocksize, &cmdlen, &len) == -1) {
526
            BADF("Unsupported command length, command %x\n", cmd[0]);
527
            return 0;
528
        }
529
    }
530

    
531
    DPRINTF("Command: lun=%d tag=0x%x data=0x%02x len %d\n", lun, tag,
532
            cmd[0], len);
533

    
534
    if (cmd[0] != REQUEST_SENSE &&
535
        (lun != s->lun || (cmd[1] >> 5) != s->lun)) {
536
        DPRINTF("Unimplemented LUN %d\n", lun ? lun : cmd[1] >> 5);
537

    
538
        s->sensebuf[0] = 0x70;
539
        s->sensebuf[1] = 0x00;
540
        s->sensebuf[2] = ILLEGAL_REQUEST;
541
        s->sensebuf[3] = 0x00;
542
        s->sensebuf[4] = 0x00;
543
        s->sensebuf[5] = 0x00;
544
        s->sensebuf[6] = 0x00;
545
        s->senselen = 7;
546
        s->driver_status = SG_ERR_DRIVER_SENSE;
547
        bus = scsi_bus_from_device(d);
548
        bus->complete(bus, SCSI_REASON_DONE, tag, CHECK_CONDITION << 1);
549
        return 0;
550
    }
551

    
552
    r = scsi_find_request(s, tag);
553
    if (r) {
554
        BADF("Tag 0x%x already in use %p\n", tag, r);
555
        scsi_cancel_io(d, tag);
556
    }
557
    r = scsi_new_request(d, tag);
558

    
559
    memcpy(r->cmd, cmd, cmdlen);
560
    r->cmdlen = cmdlen;
561

    
562
    if (len == 0) {
563
        if (r->buf != NULL)
564
            free(r->buf);
565
        r->buflen = 0;
566
        r->buf = NULL;
567
        ret = execute_command(s->dinfo->bdrv, r, SG_DXFER_NONE, scsi_command_complete);
568
        if (ret == -1) {
569
            scsi_command_complete(r, -EINVAL);
570
            return 0;
571
        }
572
        return 0;
573
    }
574

    
575
    if (r->buflen != len) {
576
        if (r->buf != NULL)
577
            free(r->buf);
578
        r->buf = qemu_malloc(len);
579
        r->buflen = len;
580
    }
581

    
582
    memset(r->buf, 0, r->buflen);
583
    r->len = len;
584
    if (is_write(cmd[0])) {
585
        r->len = 0;
586
        return -len;
587
    }
588

    
589
    return len;
590
}
591

    
592
static int get_blocksize(BlockDriverState *bdrv)
593
{
594
    uint8_t cmd[10];
595
    uint8_t buf[8];
596
    uint8_t sensebuf[8];
597
    sg_io_hdr_t io_header;
598
    int ret;
599

    
600
    memset(cmd, 0, sizeof(cmd));
601
    memset(buf, 0, sizeof(buf));
602
    cmd[0] = READ_CAPACITY;
603

    
604
    memset(&io_header, 0, sizeof(io_header));
605
    io_header.interface_id = 'S';
606
    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
607
    io_header.dxfer_len = sizeof(buf);
608
    io_header.dxferp = buf;
609
    io_header.cmdp = cmd;
610
    io_header.cmd_len = sizeof(cmd);
611
    io_header.mx_sb_len = sizeof(sensebuf);
612
    io_header.sbp = sensebuf;
613
    io_header.timeout = 6000; /* XXX */
614

    
615
    ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
616
    if (ret < 0)
617
        return -1;
618

    
619
    return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
620
}
621

    
622
static int get_stream_blocksize(BlockDriverState *bdrv)
623
{
624
    uint8_t cmd[6];
625
    uint8_t buf[12];
626
    uint8_t sensebuf[8];
627
    sg_io_hdr_t io_header;
628
    int ret;
629

    
630
    memset(cmd, 0, sizeof(cmd));
631
    memset(buf, 0, sizeof(buf));
632
    cmd[0] = MODE_SENSE;
633
    cmd[4] = sizeof(buf);
634

    
635
    memset(&io_header, 0, sizeof(io_header));
636
    io_header.interface_id = 'S';
637
    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
638
    io_header.dxfer_len = sizeof(buf);
639
    io_header.dxferp = buf;
640
    io_header.cmdp = cmd;
641
    io_header.cmd_len = sizeof(cmd);
642
    io_header.mx_sb_len = sizeof(sensebuf);
643
    io_header.sbp = sensebuf;
644
    io_header.timeout = 6000; /* XXX */
645

    
646
    ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
647
    if (ret < 0)
648
        return -1;
649

    
650
    return (buf[9] << 16) | (buf[10] << 8) | buf[11];
651
}
652

    
653
static void scsi_destroy(SCSIDevice *d)
654
{
655
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
656
    SCSIRequest *r, *n;
657

    
658
    r = s->requests;
659
    while (r) {
660
        n = r->next;
661
        qemu_free(r);
662
        r = n;
663
    }
664

    
665
    r = free_requests;
666
    while (r) {
667
        n = r->next;
668
        qemu_free(r);
669
        r = n;
670
    }
671

    
672
    drive_uninit(s->dinfo);
673
}
674

    
675
static int scsi_generic_initfn(SCSIDevice *dev)
676
{
677
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
678
    int sg_version;
679
    struct sg_scsi_id scsiid;
680

    
681
    if (!s->dinfo || !s->dinfo->bdrv) {
682
        qemu_error("scsi-generic: drive property not set\n");
683
        return -1;
684
    }
685

    
686
    /* check we are really using a /dev/sg* file */
687
    if (!bdrv_is_sg(s->dinfo->bdrv)) {
688
        qemu_error("scsi-generic: not /dev/sg*\n");
689
        return -1;
690
    }
691

    
692
    /* check we are using a driver managing SG_IO (version 3 and after */
693
    if (bdrv_ioctl(s->dinfo->bdrv, SG_GET_VERSION_NUM, &sg_version) < 0 ||
694
        sg_version < 30000) {
695
        qemu_error("scsi-generic: scsi generic interface too old\n");
696
        return -1;
697
    }
698

    
699
    /* get LUN of the /dev/sg? */
700
    if (bdrv_ioctl(s->dinfo->bdrv, SG_GET_SCSI_ID, &scsiid)) {
701
        qemu_error("scsi-generic: SG_GET_SCSI_ID ioctl failed\n");
702
        return -1;
703
    }
704

    
705
    /* define device state */
706
    s->lun = scsiid.lun;
707
    DPRINTF("LUN %d\n", s->lun);
708
    s->type = scsiid.scsi_type;
709
    DPRINTF("device type %d\n", s->type);
710
    if (s->type == TYPE_TAPE) {
711
        s->blocksize = get_stream_blocksize(s->dinfo->bdrv);
712
        if (s->blocksize == -1)
713
            s->blocksize = 0;
714
    } else {
715
        s->blocksize = get_blocksize(s->dinfo->bdrv);
716
        /* removable media returns 0 if not present */
717
        if (s->blocksize <= 0) {
718
            if (s->type == TYPE_ROM || s->type  == TYPE_WORM)
719
                s->blocksize = 2048;
720
            else
721
                s->blocksize = 512;
722
        }
723
    }
724
    DPRINTF("block size %d\n", s->blocksize);
725
    s->driver_status = 0;
726
    memset(s->sensebuf, 0, sizeof(s->sensebuf));
727
    return 0;
728
}
729

    
730
static SCSIDeviceInfo scsi_generic_info = {
731
    .qdev.name    = "scsi-generic",
732
    .qdev.desc    = "pass through generic scsi device (/dev/sg*)",
733
    .qdev.size    = sizeof(SCSIGenericState),
734
    .init         = scsi_generic_initfn,
735
    .destroy      = scsi_destroy,
736
    .send_command = scsi_send_command,
737
    .read_data    = scsi_read_data,
738
    .write_data   = scsi_write_data,
739
    .cancel_io    = scsi_cancel_io,
740
    .get_buf      = scsi_get_buf,
741
    .qdev.props   = (Property[]) {
742
        DEFINE_PROP_DRIVE("drive", SCSIGenericState, dinfo),
743
        DEFINE_PROP_END_OF_LIST(),
744
    },
745
};
746

    
747
static void scsi_generic_register_devices(void)
748
{
749
    scsi_qdev_register(&scsi_generic_info);
750
}
751
device_init(scsi_generic_register_devices)
752

    
753
#endif /* __linux__ */