Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (17.8 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.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-defs.h"
38

    
39
#define SCSI_SENSE_BUF_SIZE 96
40

    
41
#define SG_ERR_DRIVER_TIMEOUT 0x06
42
#define SG_ERR_DRIVER_SENSE 0x08
43

    
44
#ifndef MAX_UINT
45
#define MAX_UINT ((unsigned int)-1)
46
#endif
47

    
48
typedef struct SCSIGenericState SCSIGenericState;
49

    
50
typedef struct SCSIGenericReq {
51
    SCSIRequest req;
52
    uint8_t *buf;
53
    int buflen;
54
    int len;
55
    sg_io_hdr_t io_header;
56
} SCSIGenericReq;
57

    
58
struct SCSIGenericState
59
{
60
    SCSIDevice qdev;
61
    DriveInfo *dinfo;
62
    int type;
63
    int lun;
64
    int driver_status;
65
    uint8_t sensebuf[SCSI_SENSE_BUF_SIZE];
66
    uint8_t senselen;
67
};
68

    
69
static SCSIGenericReq *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
70
{
71
    SCSIRequest *req;
72

    
73
    req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun);
74
    return DO_UPCAST(SCSIGenericReq, req, req);
75
}
76

    
77
static void scsi_remove_request(SCSIGenericReq *r)
78
{
79
    qemu_free(r->buf);
80
    scsi_req_free(&r->req);
81
}
82

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

    
88
/* Helper function for command completion.  */
89
static void scsi_command_complete(void *opaque, int ret)
90
{
91
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
92
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
93
    uint32_t tag;
94
    int status;
95

    
96
    s->driver_status = r->io_header.driver_status;
97
    if (s->driver_status & SG_ERR_DRIVER_SENSE)
98
        s->senselen = r->io_header.sb_len_wr;
99

    
100
    if (ret != 0)
101
        status = BUSY << 1;
102
    else {
103
        if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
104
            status = BUSY << 1;
105
            BADF("Driver Timeout\n");
106
        } else if (r->io_header.status)
107
            status = r->io_header.status;
108
        else if (s->driver_status & SG_ERR_DRIVER_SENSE)
109
            status = CHECK_CONDITION << 1;
110
        else
111
            status = GOOD << 1;
112
    }
113
    DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
114
            r, r->req.tag, status);
115
    tag = r->req.tag;
116
    r->req.bus->complete(r->req.bus, SCSI_REASON_DONE, tag, status);
117
    scsi_remove_request(r);
118
}
119

    
120
/* Cancel a pending data transfer.  */
121
static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
122
{
123
    DPRINTF("scsi_cancel_io 0x%x\n", tag);
124
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
125
    SCSIGenericReq *r;
126
    DPRINTF("Cancel tag=0x%x\n", tag);
127
    r = scsi_find_request(s, tag);
128
    if (r) {
129
        if (r->req.aiocb)
130
            bdrv_aio_cancel(r->req.aiocb);
131
        r->req.aiocb = NULL;
132
        scsi_remove_request(r);
133
    }
134
}
135

    
136
static int execute_command(BlockDriverState *bdrv,
137
                           SCSIGenericReq *r, int direction,
138
                           BlockDriverCompletionFunc *complete)
139
{
140
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
141

    
142
    r->io_header.interface_id = 'S';
143
    r->io_header.dxfer_direction = direction;
144
    r->io_header.dxferp = r->buf;
145
    r->io_header.dxfer_len = r->buflen;
146
    r->io_header.cmdp = r->req.cmd.buf;
147
    r->io_header.cmd_len = r->req.cmd.len;
148
    r->io_header.mx_sb_len = sizeof(s->sensebuf);
149
    r->io_header.sbp = s->sensebuf;
150
    r->io_header.timeout = MAX_UINT;
151
    r->io_header.usr_ptr = r;
152
    r->io_header.flags |= SG_FLAG_DIRECT_IO;
153

    
154
    r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
155
    if (r->req.aiocb == NULL) {
156
        BADF("execute_command: read failed !\n");
157
        return -1;
158
    }
159

    
160
    return 0;
161
}
162

    
163
static void scsi_read_complete(void * opaque, int ret)
164
{
165
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
166
    int len;
167

    
168
    if (ret) {
169
        DPRINTF("IO error\n");
170
        scsi_command_complete(r, ret);
171
        return;
172
    }
173
    len = r->io_header.dxfer_len - r->io_header.resid;
174
    DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
175

    
176
    r->len = -1;
177
    r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, len);
178
    if (len == 0)
179
        scsi_command_complete(r, 0);
180
}
181

    
182
/* Read more data from scsi device into buffer.  */
183
static void scsi_read_data(SCSIDevice *d, uint32_t tag)
184
{
185
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
186
    SCSIGenericReq *r;
187
    int ret;
188

    
189
    DPRINTF("scsi_read_data 0x%x\n", tag);
190
    r = scsi_find_request(s, tag);
191
    if (!r) {
192
        BADF("Bad read tag 0x%x\n", tag);
193
        /* ??? This is the wrong error.  */
194
        scsi_command_complete(r, -EINVAL);
195
        return;
196
    }
197

    
198
    if (r->len == -1) {
199
        scsi_command_complete(r, 0);
200
        return;
201
    }
202

    
203
    if (r->req.cmd.buf[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
204
    {
205
        s->senselen = MIN(r->len, s->senselen);
206
        memcpy(r->buf, s->sensebuf, s->senselen);
207
        r->io_header.driver_status = 0;
208
        r->io_header.status = 0;
209
        r->io_header.dxfer_len  = s->senselen;
210
        r->len = -1;
211
        DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, s->senselen);
212
        DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
213
                r->buf[0], r->buf[1], r->buf[2], r->buf[3],
214
                r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
215
        r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, s->senselen);
216
        return;
217
    }
218

    
219
    ret = execute_command(s->dinfo->bdrv, r, SG_DXFER_FROM_DEV, scsi_read_complete);
220
    if (ret == -1) {
221
        scsi_command_complete(r, -EINVAL);
222
        return;
223
    }
224
}
225

    
226
static void scsi_write_complete(void * opaque, int ret)
227
{
228
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
229
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
230

    
231
    DPRINTF("scsi_write_complete() ret = %d\n", ret);
232
    if (ret) {
233
        DPRINTF("IO error\n");
234
        scsi_command_complete(r, ret);
235
        return;
236
    }
237

    
238
    if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
239
        s->type == TYPE_TAPE) {
240
        s->qdev.blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
241
        DPRINTF("block size %d\n", s->blocksize);
242
    }
243

    
244
    scsi_command_complete(r, ret);
245
}
246

    
247
/* Write data to a scsi device.  Returns nonzero on failure.
248
   The transfer may complete asynchronously.  */
249
static int scsi_write_data(SCSIDevice *d, uint32_t tag)
250
{
251
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
252
    SCSIGenericReq *r;
253
    int ret;
254

    
255
    DPRINTF("scsi_write_data 0x%x\n", tag);
256
    r = scsi_find_request(s, tag);
257
    if (!r) {
258
        BADF("Bad write tag 0x%x\n", tag);
259
        /* ??? This is the wrong error.  */
260
        scsi_command_complete(r, -EINVAL);
261
        return 0;
262
    }
263

    
264
    if (r->len == 0) {
265
        r->len = r->buflen;
266
        r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, r->len);
267
        return 0;
268
    }
269

    
270
    ret = execute_command(s->dinfo->bdrv, r, SG_DXFER_TO_DEV, scsi_write_complete);
271
    if (ret == -1) {
272
        scsi_command_complete(r, -EINVAL);
273
        return 1;
274
    }
275

    
276
    return 0;
277
}
278

    
279
/* Return a pointer to the data buffer.  */
280
static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
281
{
282
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
283
    SCSIGenericReq *r;
284
    r = scsi_find_request(s, tag);
285
    if (!r) {
286
        BADF("Bad buffer tag 0x%x\n", tag);
287
        return NULL;
288
    }
289
    return r->buf;
290
}
291

    
292
static int scsi_length(uint8_t *cmd, int blocksize, int *cmdlen, uint32_t *len)
293
{
294
    switch (cmd[0] >> 5) {
295
    case 0:
296
        *len = cmd[4];
297
        *cmdlen = 6;
298
        /* length 0 means 256 blocks */
299
        if (*len == 0)
300
            *len = 256;
301
        break;
302
    case 1:
303
    case 2:
304
        *len = cmd[8] | (cmd[7] << 8);
305
        *cmdlen = 10;
306
        break;
307
    case 4:
308
        *len = cmd[13] | (cmd[12] << 8) | (cmd[11] << 16) | (cmd[10] << 24);
309
        *cmdlen = 16;
310
        break;
311
    case 5:
312
        *len = cmd[9] | (cmd[8] << 8) | (cmd[7] << 16) | (cmd[6] << 24);
313
        *cmdlen = 12;
314
        break;
315
    default:
316
        return -1;
317
    }
318

    
319
    switch(cmd[0]) {
320
    case TEST_UNIT_READY:
321
    case REZERO_UNIT:
322
    case START_STOP:
323
    case SEEK_6:
324
    case WRITE_FILEMARKS:
325
    case SPACE:
326
    case ERASE:
327
    case ALLOW_MEDIUM_REMOVAL:
328
    case VERIFY:
329
    case SEEK_10:
330
    case SYNCHRONIZE_CACHE:
331
    case LOCK_UNLOCK_CACHE:
332
    case LOAD_UNLOAD:
333
    case SET_CD_SPEED:
334
    case SET_LIMITS:
335
    case WRITE_LONG:
336
    case MOVE_MEDIUM:
337
    case UPDATE_BLOCK:
338
        *len = 0;
339
        break;
340
    case MODE_SENSE:
341
        break;
342
    case WRITE_SAME:
343
        *len = 1;
344
        break;
345
    case READ_CAPACITY:
346
        *len = 8;
347
        break;
348
    case READ_BLOCK_LIMITS:
349
        *len = 6;
350
        break;
351
    case READ_POSITION:
352
        *len = 20;
353
        break;
354
    case SEND_VOLUME_TAG:
355
        *len *= 40;
356
        break;
357
    case MEDIUM_SCAN:
358
        *len *= 8;
359
        break;
360
    case WRITE_10:
361
        cmd[1] &= ~0x08;        /* disable FUA */
362
    case WRITE_VERIFY:
363
    case WRITE_6:
364
    case WRITE_12:
365
    case WRITE_VERIFY_12:
366
        *len *= blocksize;
367
        break;
368
    case READ_10:
369
        cmd[1] &= ~0x08;        /* disable FUA */
370
    case READ_6:
371
    case READ_REVERSE:
372
    case RECOVER_BUFFERED_DATA:
373
    case READ_12:
374
        *len *= blocksize;
375
        break;
376
    case INQUIRY:
377
        *len = cmd[4] | (cmd[3] << 8);
378
        break;
379
    }
380
    return 0;
381
}
382

    
383
static int scsi_stream_length(uint8_t *cmd, int blocksize, int *cmdlen, uint32_t *len)
384
{
385
    switch(cmd[0]) {
386
    /* stream commands */
387
    case READ_6:
388
    case READ_REVERSE:
389
    case RECOVER_BUFFERED_DATA:
390
    case WRITE_6:
391
        *cmdlen = 6;
392
        *len = cmd[4] | (cmd[3] << 8) | (cmd[2] << 16);
393
        if (cmd[1] & 0x01) /* fixed */
394
            *len *= blocksize;
395
        break;
396
    case REWIND:
397
    case START_STOP:
398
        *cmdlen = 6;
399
        *len = 0;
400
        cmd[1] = 0x01;        /* force IMMED, otherwise qemu waits end of command */
401
        break;
402
    /* generic commands */
403
    default:
404
        return scsi_length(cmd, blocksize, cmdlen, len);
405
    }
406
    return 0;
407
}
408

    
409
static int is_write(int command)
410
{
411
    switch (command) {
412
    case COPY:
413
    case COPY_VERIFY:
414
    case COMPARE:
415
    case CHANGE_DEFINITION:
416
    case LOG_SELECT:
417
    case MODE_SELECT:
418
    case MODE_SELECT_10:
419
    case SEND_DIAGNOSTIC:
420
    case WRITE_BUFFER:
421
    case FORMAT_UNIT:
422
    case REASSIGN_BLOCKS:
423
    case RESERVE:
424
    case SEARCH_EQUAL:
425
    case SEARCH_HIGH:
426
    case SEARCH_LOW:
427
    case WRITE_6:
428
    case WRITE_10:
429
    case WRITE_VERIFY:
430
    case UPDATE_BLOCK:
431
    case WRITE_LONG:
432
    case WRITE_SAME:
433
    case SEARCH_HIGH_12:
434
    case SEARCH_EQUAL_12:
435
    case SEARCH_LOW_12:
436
    case WRITE_12:
437
    case WRITE_VERIFY_12:
438
    case SET_WINDOW:
439
    case MEDIUM_SCAN:
440
    case SEND_VOLUME_TAG:
441
    case WRITE_LONG_2:
442
        return 1;
443
    }
444
    return 0;
445
}
446

    
447
/* Execute a scsi command.  Returns the length of the data expected by the
448
   command.  This will be Positive for data transfers from the device
449
   (eg. disk reads), negative for transfers to the device (eg. disk writes),
450
   and zero if the command does not transfer any data.  */
451

    
452
static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
453
                                 uint8_t *cmd, int lun)
454
{
455
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
456
    uint32_t len=0;
457
    int cmdlen=0;
458
    SCSIGenericReq *r;
459
    SCSIBus *bus;
460
    int ret;
461

    
462
    if (s->type == TYPE_TAPE) {
463
        if (scsi_stream_length(cmd, s->qdev.blocksize, &cmdlen, &len) == -1) {
464
            BADF("Unsupported command length, command %x\n", cmd[0]);
465
            return 0;
466
        }
467
     } else {
468
        if (scsi_length(cmd, s->qdev.blocksize, &cmdlen, &len) == -1) {
469
            BADF("Unsupported command length, command %x\n", cmd[0]);
470
            return 0;
471
        }
472
    }
473

    
474
    DPRINTF("Command: lun=%d tag=0x%x data=0x%02x len %d\n", lun, tag,
475
            cmd[0], len);
476

    
477
    if (cmd[0] != REQUEST_SENSE &&
478
        (lun != s->lun || (cmd[1] >> 5) != s->lun)) {
479
        DPRINTF("Unimplemented LUN %d\n", lun ? lun : cmd[1] >> 5);
480

    
481
        s->sensebuf[0] = 0x70;
482
        s->sensebuf[1] = 0x00;
483
        s->sensebuf[2] = ILLEGAL_REQUEST;
484
        s->sensebuf[3] = 0x00;
485
        s->sensebuf[4] = 0x00;
486
        s->sensebuf[5] = 0x00;
487
        s->sensebuf[6] = 0x00;
488
        s->senselen = 7;
489
        s->driver_status = SG_ERR_DRIVER_SENSE;
490
        bus = scsi_bus_from_device(d);
491
        bus->complete(bus, SCSI_REASON_DONE, tag, CHECK_CONDITION << 1);
492
        return 0;
493
    }
494

    
495
    r = scsi_find_request(s, tag);
496
    if (r) {
497
        BADF("Tag 0x%x already in use %p\n", tag, r);
498
        scsi_cancel_io(d, tag);
499
    }
500
    r = scsi_new_request(d, tag, lun);
501

    
502
    memcpy(r->req.cmd.buf, cmd, cmdlen);
503
    r->req.cmd.len = cmdlen;
504

    
505
    if (len == 0) {
506
        if (r->buf != NULL)
507
            qemu_free(r->buf);
508
        r->buflen = 0;
509
        r->buf = NULL;
510
        ret = execute_command(s->dinfo->bdrv, r, SG_DXFER_NONE, scsi_command_complete);
511
        if (ret == -1) {
512
            scsi_command_complete(r, -EINVAL);
513
            return 0;
514
        }
515
        return 0;
516
    }
517

    
518
    if (r->buflen != len) {
519
        if (r->buf != NULL)
520
            qemu_free(r->buf);
521
        r->buf = qemu_malloc(len);
522
        r->buflen = len;
523
    }
524

    
525
    memset(r->buf, 0, r->buflen);
526
    r->len = len;
527
    if (is_write(cmd[0])) {
528
        r->len = 0;
529
        return -len;
530
    }
531

    
532
    return len;
533
}
534

    
535
static int get_blocksize(BlockDriverState *bdrv)
536
{
537
    uint8_t cmd[10];
538
    uint8_t buf[8];
539
    uint8_t sensebuf[8];
540
    sg_io_hdr_t io_header;
541
    int ret;
542

    
543
    memset(cmd, 0, sizeof(cmd));
544
    memset(buf, 0, sizeof(buf));
545
    cmd[0] = READ_CAPACITY;
546

    
547
    memset(&io_header, 0, sizeof(io_header));
548
    io_header.interface_id = 'S';
549
    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
550
    io_header.dxfer_len = sizeof(buf);
551
    io_header.dxferp = buf;
552
    io_header.cmdp = cmd;
553
    io_header.cmd_len = sizeof(cmd);
554
    io_header.mx_sb_len = sizeof(sensebuf);
555
    io_header.sbp = sensebuf;
556
    io_header.timeout = 6000; /* XXX */
557

    
558
    ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
559
    if (ret < 0)
560
        return -1;
561

    
562
    return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
563
}
564

    
565
static int get_stream_blocksize(BlockDriverState *bdrv)
566
{
567
    uint8_t cmd[6];
568
    uint8_t buf[12];
569
    uint8_t sensebuf[8];
570
    sg_io_hdr_t io_header;
571
    int ret;
572

    
573
    memset(cmd, 0, sizeof(cmd));
574
    memset(buf, 0, sizeof(buf));
575
    cmd[0] = MODE_SENSE;
576
    cmd[4] = sizeof(buf);
577

    
578
    memset(&io_header, 0, sizeof(io_header));
579
    io_header.interface_id = 'S';
580
    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
581
    io_header.dxfer_len = sizeof(buf);
582
    io_header.dxferp = buf;
583
    io_header.cmdp = cmd;
584
    io_header.cmd_len = sizeof(cmd);
585
    io_header.mx_sb_len = sizeof(sensebuf);
586
    io_header.sbp = sensebuf;
587
    io_header.timeout = 6000; /* XXX */
588

    
589
    ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
590
    if (ret < 0)
591
        return -1;
592

    
593
    return (buf[9] << 16) | (buf[10] << 8) | buf[11];
594
}
595

    
596
static void scsi_destroy(SCSIDevice *d)
597
{
598
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
599
    SCSIGenericReq *r;
600

    
601
    while (!QTAILQ_EMPTY(&s->qdev.requests)) {
602
        r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&s->qdev.requests));
603
        scsi_remove_request(r);
604
    }
605
    drive_uninit(s->dinfo);
606
}
607

    
608
static int scsi_generic_initfn(SCSIDevice *dev)
609
{
610
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
611
    int sg_version;
612
    struct sg_scsi_id scsiid;
613

    
614
    if (!s->dinfo || !s->dinfo->bdrv) {
615
        qemu_error("scsi-generic: drive property not set\n");
616
        return -1;
617
    }
618

    
619
    /* check we are really using a /dev/sg* file */
620
    if (!bdrv_is_sg(s->dinfo->bdrv)) {
621
        qemu_error("scsi-generic: not /dev/sg*\n");
622
        return -1;
623
    }
624

    
625
    /* check we are using a driver managing SG_IO (version 3 and after */
626
    if (bdrv_ioctl(s->dinfo->bdrv, SG_GET_VERSION_NUM, &sg_version) < 0 ||
627
        sg_version < 30000) {
628
        qemu_error("scsi-generic: scsi generic interface too old\n");
629
        return -1;
630
    }
631

    
632
    /* get LUN of the /dev/sg? */
633
    if (bdrv_ioctl(s->dinfo->bdrv, SG_GET_SCSI_ID, &scsiid)) {
634
        qemu_error("scsi-generic: SG_GET_SCSI_ID ioctl failed\n");
635
        return -1;
636
    }
637

    
638
    /* define device state */
639
    s->lun = scsiid.lun;
640
    DPRINTF("LUN %d\n", s->lun);
641
    s->type = scsiid.scsi_type;
642
    DPRINTF("device type %d\n", s->type);
643
    if (s->type == TYPE_TAPE) {
644
        s->qdev.blocksize = get_stream_blocksize(s->dinfo->bdrv);
645
        if (s->qdev.blocksize == -1)
646
            s->qdev.blocksize = 0;
647
    } else {
648
        s->qdev.blocksize = get_blocksize(s->dinfo->bdrv);
649
        /* removable media returns 0 if not present */
650
        if (s->qdev.blocksize <= 0) {
651
            if (s->type == TYPE_ROM || s->type  == TYPE_WORM)
652
                s->qdev.blocksize = 2048;
653
            else
654
                s->qdev.blocksize = 512;
655
        }
656
    }
657
    DPRINTF("block size %d\n", s->qdev.blocksize);
658
    s->driver_status = 0;
659
    memset(s->sensebuf, 0, sizeof(s->sensebuf));
660
    return 0;
661
}
662

    
663
static SCSIDeviceInfo scsi_generic_info = {
664
    .qdev.name    = "scsi-generic",
665
    .qdev.desc    = "pass through generic scsi device (/dev/sg*)",
666
    .qdev.size    = sizeof(SCSIGenericState),
667
    .init         = scsi_generic_initfn,
668
    .destroy      = scsi_destroy,
669
    .send_command = scsi_send_command,
670
    .read_data    = scsi_read_data,
671
    .write_data   = scsi_write_data,
672
    .cancel_io    = scsi_cancel_io,
673
    .get_buf      = scsi_get_buf,
674
    .qdev.props   = (Property[]) {
675
        DEFINE_PROP_DRIVE("drive", SCSIGenericState, dinfo),
676
        DEFINE_PROP_END_OF_LIST(),
677
    },
678
};
679

    
680
static void scsi_generic_register_devices(void)
681
{
682
    scsi_qdev_register(&scsi_generic_info);
683
}
684
device_init(scsi_generic_register_devices)
685

    
686
#endif /* __linux__ */