~ubuntu-branches/ubuntu/hardy/kvm/hardy-backports

« back to all changes in this revision

Viewing changes to qemu/hw/scsi-generic.c

  • Committer: Bazaar Package Importer
  • Author(s): Soren Hansen
  • Date: 2008-01-03 10:39:25 UTC
  • mfrom: (1.1.16 upstream)
  • Revision ID: james.westby@ubuntu.com-20080103103925-8480u7sq2646hvbh
Tags: 1:59+dfsg-0ubuntu1
* New upstream release
* Build with alsa support (cherry pick from 57+dfsg-2)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#ifndef __linux__
 
19
 
 
20
SCSIDevice *scsi_generic_init(BlockDriverState *bdrv, int tcq,
 
21
                              scsi_completionfn completion, void *opaque)
 
22
{
 
23
    return NULL;
 
24
}
 
25
 
 
26
#else /* __linux__ */
 
27
 
 
28
//#define DEBUG_SCSI
 
29
 
 
30
#ifdef DEBUG_SCSI
 
31
#define DPRINTF(fmt, args...) \
 
32
do { printf("scsi-generic: " fmt , ##args); } while (0)
 
33
#else
 
34
#define DPRINTF(fmt, args...) do {} while(0)
 
35
#endif
 
36
 
 
37
#define BADF(fmt, args...) \
 
38
do { fprintf(stderr, "scsi-generic: " fmt , ##args); } while (0)
 
39
 
 
40
#include <stdio.h>
 
41
#include <sys/types.h>
 
42
#include <sys/stat.h>
 
43
#include <unistd.h>
 
44
#include <scsi/sg.h>
 
45
#include <scsi/scsi.h>
 
46
 
 
47
#define LOAD_UNLOAD 0xa6
 
48
#define SET_CD_SPEED 0xbb
 
49
#define BLANK 0xa1
 
50
 
 
51
#define SCSI_CMD_BUF_SIZE     16
 
52
#define SCSI_SENSE_BUF_SIZE 32
 
53
 
 
54
#define SG_ERR_DRIVER_TIMEOUT 0x06
 
55
#define SG_ERR_DRIVER_SENSE 0x08
 
56
 
 
57
#ifndef MAX_UINT
 
58
#define MAX_UINT ((unsigned int)-1)
 
59
#endif
 
60
 
 
61
typedef struct SCSIRequest {
 
62
    BlockDriverAIOCB *aiocb;
 
63
    struct SCSIRequest *next;
 
64
    SCSIDeviceState *dev;
 
65
    uint32_t tag;
 
66
    uint8_t cmd[SCSI_CMD_BUF_SIZE];
 
67
    int cmdlen;
 
68
    uint8_t *buf;
 
69
    int buflen;
 
70
    int len;
 
71
    sg_io_hdr_t io_header;
 
72
} SCSIRequest;
 
73
 
 
74
struct SCSIDeviceState
 
75
{
 
76
    SCSIRequest *requests;
 
77
    BlockDriverState *bdrv;
 
78
    int blocksize;
 
79
    int lun;
 
80
    scsi_completionfn completion;
 
81
    void *opaque;
 
82
    int driver_status;
 
83
    uint8_t sensebuf[SCSI_SENSE_BUF_SIZE];
 
84
};
 
85
 
 
86
/* Global pool of SCSIRequest structures.  */
 
87
static SCSIRequest *free_requests = NULL;
 
88
 
 
89
static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag)
 
90
{
 
91
    SCSIRequest *r;
 
92
 
 
93
    if (free_requests) {
 
94
        r = free_requests;
 
95
        free_requests = r->next;
 
96
    } else {
 
97
        r = qemu_malloc(sizeof(SCSIRequest));
 
98
        r->buf = NULL;
 
99
        r->buflen = 0;
 
100
    }
 
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
    SCSIDeviceState *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(SCSIDeviceState *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
    SCSIDeviceState *s = r->dev;
 
153
    uint32_t tag;
 
154
    int sense;
 
155
 
 
156
    s->driver_status = r->io_header.driver_status;
 
157
    if (ret != 0)
 
158
        sense = HARDWARE_ERROR;
 
159
    else {
 
160
        if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
 
161
            sense = HARDWARE_ERROR;
 
162
            BADF("Driver Timeout\n");
 
163
        } else if ((s->driver_status & SG_ERR_DRIVER_SENSE) == 0)
 
164
            sense = NO_SENSE;
 
165
        else
 
166
            sense = s->sensebuf[2] & 0x0f;
 
167
    }
 
168
 
 
169
    DPRINTF("Command complete 0x%p tag=0x%x sense=%d\n", r, r->tag, sense);
 
170
    tag = r->tag;
 
171
    scsi_remove_request(r);
 
172
    s->completion(s->opaque, SCSI_REASON_DONE, tag, sense);
 
173
}
 
174
 
 
175
/* Cancel a pending data transfer.  */
 
176
static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
 
177
{
 
178
    DPRINTF("scsi_cancel_io 0x%x\n", tag);
 
179
    SCSIDeviceState *s = d->state;
 
180
    SCSIRequest *r;
 
181
    DPRINTF("Cancel tag=0x%x\n", tag);
 
182
    r = scsi_find_request(s, tag);
 
183
    if (r) {
 
184
        if (r->aiocb)
 
185
            bdrv_aio_cancel(r->aiocb);
 
186
        r->aiocb = NULL;
 
187
        scsi_remove_request(r);
 
188
    }
 
189
}
 
190
 
 
191
static int execute_command(BlockDriverState *bdrv,
 
192
                           SCSIRequest *r, int direction,
 
193
                           BlockDriverCompletionFunc *complete)
 
194
{
 
195
 
 
196
    r->io_header.interface_id = 'S';
 
197
    r->io_header.dxfer_direction = direction;
 
198
    r->io_header.dxferp = r->buf;
 
199
    r->io_header.dxfer_len = r->buflen;
 
200
    r->io_header.cmdp = r->cmd;
 
201
    r->io_header.cmd_len = r->cmdlen;
 
202
    r->io_header.mx_sb_len = sizeof(r->dev->sensebuf);
 
203
    r->io_header.sbp = r->dev->sensebuf;
 
204
    r->io_header.timeout = MAX_UINT;
 
205
    r->io_header.usr_ptr = r;
 
206
    r->io_header.flags |= SG_FLAG_DIRECT_IO;
 
207
 
 
208
    if (bdrv_pwrite(bdrv, -1, &r->io_header, sizeof(r->io_header)) == -1) {
 
209
        BADF("execute_command: write failed ! (%d)\n", errno);
 
210
        return -1;
 
211
    }
 
212
    if (complete == NULL) {
 
213
        int ret;
 
214
        r->aiocb = NULL;
 
215
        while ((ret = bdrv_pread(bdrv, -1, &r->io_header,
 
216
                                           sizeof(r->io_header))) == -1 &&
 
217
                      errno == EINTR);
 
218
        if (ret == -1) {
 
219
            BADF("execute_command: read failed !\n");
 
220
            return -1;
 
221
        }
 
222
        return 0;
 
223
    }
 
224
 
 
225
    r->aiocb = bdrv_aio_read(bdrv, 0, (uint8_t*)&r->io_header,
 
226
                          -(int64_t)sizeof(r->io_header), complete, r);
 
227
    if (r->aiocb == NULL) {
 
228
        BADF("execute_command: read failed !\n");
 
229
        return -1;
 
230
    }
 
231
 
 
232
    return 0;
 
233
}
 
234
 
 
235
static void scsi_read_complete(void * opaque, int ret)
 
236
{
 
237
    SCSIRequest *r = (SCSIRequest *)opaque;
 
238
    SCSIDeviceState *s = r->dev;
 
239
    int len;
 
240
 
 
241
    if (ret) {
 
242
        DPRINTF("IO error\n");
 
243
        scsi_command_complete(r, ret);
 
244
        return;
 
245
    }
 
246
    len = r->io_header.dxfer_len - r->io_header.resid;
 
247
    DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, len);
 
248
 
 
249
    r->len = -1;
 
250
    s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len);
 
251
}
 
252
 
 
253
/* Read more data from scsi device into buffer.  */
 
254
static void scsi_read_data(SCSIDevice *d, uint32_t tag)
 
255
{
 
256
    SCSIDeviceState *s = d->state;
 
257
    SCSIRequest *r;
 
258
    int ret;
 
259
 
 
260
    DPRINTF("scsi_read_data 0x%x\n", tag);
 
261
    r = scsi_find_request(s, tag);
 
262
    if (!r) {
 
263
        BADF("Bad read tag 0x%x\n", tag);
 
264
        /* ??? This is the wrong error.  */
 
265
        scsi_command_complete(r, -EINVAL);
 
266
        return;
 
267
    }
 
268
 
 
269
    if (r->len == -1) {
 
270
        scsi_command_complete(r, 0);
 
271
        return;
 
272
    }
 
273
 
 
274
    if (r->cmd[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
 
275
    {
 
276
        memcpy(r->buf, s->sensebuf, 16);
 
277
        r->io_header.driver_status = 0;
 
278
        r->len = -1;
 
279
        s->completion(s->opaque, SCSI_REASON_DATA, r->tag, 16);
 
280
        return;
 
281
    }
 
282
 
 
283
    ret = execute_command(s->bdrv, r, SG_DXFER_FROM_DEV, scsi_read_complete);
 
284
    if (ret == -1) {
 
285
        scsi_command_complete(r, -EINVAL);
 
286
        return;
 
287
    }
 
288
}
 
289
 
 
290
static void scsi_write_complete(void * opaque, int ret)
 
291
{
 
292
    SCSIRequest *r = (SCSIRequest *)opaque;
 
293
 
 
294
    DPRINTF("scsi_write_complete() ret = %d\n", ret);
 
295
    if (ret) {
 
296
        DPRINTF("IO error\n");
 
297
        scsi_command_complete(r, ret);
 
298
        return;
 
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
    SCSIDeviceState *s = d->state;
 
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
        s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->len);
 
324
        return 0;
 
325
    }
 
326
 
 
327
    ret = execute_command(s->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
    SCSIDeviceState *s = d->state;
 
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
        break;
 
356
    case 1:
 
357
    case 2:
 
358
        *len = cmd[8] | (cmd[7] << 8);
 
359
        *cmdlen = 10;
 
360
        break;
 
361
    case 4:
 
362
        *len = cmd[13] | (cmd[12] << 8) | (cmd[11] << 16) | (cmd[10] << 24);
 
363
        *cmdlen = 16;
 
364
        break;
 
365
    case 5:
 
366
        *len = cmd[9] | (cmd[8] << 8) | (cmd[7] << 16) | (cmd[6] << 24);
 
367
        *cmdlen = 12;
 
368
        break;
 
369
    default:
 
370
        return -1;
 
371
    }
 
372
 
 
373
    switch(cmd[0]) {
 
374
    case TEST_UNIT_READY:
 
375
    case REZERO_UNIT:
 
376
    case START_STOP:
 
377
    case SEEK_6:
 
378
    case WRITE_FILEMARKS:
 
379
    case SPACE:
 
380
    case ERASE:
 
381
    case ALLOW_MEDIUM_REMOVAL:
 
382
    case VERIFY:
 
383
    case SEEK_10:
 
384
    case SYNCHRONIZE_CACHE:
 
385
    case LOCK_UNLOCK_CACHE:
 
386
    case LOAD_UNLOAD:
 
387
    case SET_CD_SPEED:
 
388
    case SET_LIMITS:
 
389
    case WRITE_LONG:
 
390
    case MOVE_MEDIUM:
 
391
    case UPDATE_BLOCK:
 
392
        *len = 0;
 
393
        break;
 
394
    case MODE_SENSE:
 
395
        break;
 
396
    case WRITE_SAME:
 
397
        *len = 1;
 
398
        break;
 
399
    case READ_CAPACITY:
 
400
        *len = 8;
 
401
        break;
 
402
    case READ_BLOCK_LIMITS:
 
403
        *len = 6;
 
404
        break;
 
405
    case READ_POSITION:
 
406
        *len = 20;
 
407
        break;
 
408
    case SEND_VOLUME_TAG:
 
409
        *len *= 40;
 
410
        break;
 
411
    case MEDIUM_SCAN:
 
412
        *len *= 8;
 
413
        break;
 
414
    case WRITE_10:
 
415
        cmd[1] &= ~0x08;        /* disable FUA */
 
416
    case WRITE_VERIFY:
 
417
    case WRITE_6:
 
418
    case WRITE_12:
 
419
    case WRITE_VERIFY_12:
 
420
        *len *= blocksize;
 
421
        break;
 
422
    case READ_10:
 
423
        cmd[1] &= ~0x08;        /* disable FUA */
 
424
    case READ_6:
 
425
    case READ_REVERSE:
 
426
    case RECOVER_BUFFERED_DATA:
 
427
    case READ_12:
 
428
        *len *= blocksize;
 
429
        break;
 
430
    }
 
431
    return 0;
 
432
}
 
433
 
 
434
static int is_write(int command)
 
435
{
 
436
    switch (command) {
 
437
    case COPY:
 
438
    case COPY_VERIFY:
 
439
    case COMPARE:
 
440
    case CHANGE_DEFINITION:
 
441
    case LOG_SELECT:
 
442
    case MODE_SELECT:
 
443
    case MODE_SELECT_10:
 
444
    case SEND_DIAGNOSTIC:
 
445
    case WRITE_BUFFER:
 
446
    case FORMAT_UNIT:
 
447
    case REASSIGN_BLOCKS:
 
448
    case RESERVE:
 
449
    case SEARCH_EQUAL:
 
450
    case SEARCH_HIGH:
 
451
    case SEARCH_LOW:
 
452
    case WRITE_6:
 
453
    case WRITE_10:
 
454
    case WRITE_VERIFY:
 
455
    case UPDATE_BLOCK:
 
456
    case WRITE_LONG:
 
457
    case WRITE_SAME:
 
458
    case SEARCH_HIGH_12:
 
459
    case SEARCH_EQUAL_12:
 
460
    case SEARCH_LOW_12:
 
461
    case WRITE_12:
 
462
    case WRITE_VERIFY_12:
 
463
    case SET_WINDOW:
 
464
    case MEDIUM_SCAN:
 
465
    case SEND_VOLUME_TAG:
 
466
    case WRITE_LONG_2:
 
467
        return 1;
 
468
    }
 
469
    return 0;
 
470
}
 
471
 
 
472
/* Execute a scsi command.  Returns the length of the data expected by the
 
473
   command.  This will be Positive for data transfers from the device
 
474
   (eg. disk reads), negative for transfers to the device (eg. disk writes),
 
475
   and zero if the command does not transfer any data.  */
 
476
 
 
477
static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
 
478
                                 uint8_t *cmd, int lun)
 
479
{
 
480
    SCSIDeviceState *s = d->state;
 
481
    uint32_t len;
 
482
    int cmdlen;
 
483
    SCSIRequest *r;
 
484
    int ret;
 
485
 
 
486
    /* ??? Tags are not unique for different luns.  We only implement a
 
487
       single lun, so this should not matter.  */
 
488
 
 
489
    if (lun != s->lun || (cmd[1] >> 5) != s->lun) {
 
490
        DPRINTF("Unimplemented LUN %d\n", lun ? lun : cmd[1] >> 5);
 
491
        s->completion(s->opaque, SCSI_REASON_DONE, tag, ILLEGAL_REQUEST);
 
492
        return 0;
 
493
    }
 
494
 
 
495
    if (scsi_length(cmd, s->blocksize, &cmdlen, &len) == -1) {
 
496
        BADF("Unsupported command length, command %x\n", cmd[0]);
 
497
        return 0;
 
498
    }
 
499
 
 
500
    DPRINTF("Command: lun=%d tag=0x%x data=0x%02x len %d\n", lun, tag,
 
501
            cmd[0], len);
 
502
 
 
503
    r = scsi_find_request(s, tag);
 
504
    if (r) {
 
505
        BADF("Tag 0x%x already in use %p\n", tag, r);
 
506
        scsi_cancel_io(d, tag);
 
507
    }
 
508
    r = scsi_new_request(s, tag);
 
509
 
 
510
    memcpy(r->cmd, cmd, cmdlen);
 
511
    r->cmdlen = cmdlen;
 
512
 
 
513
    if (len == 0) {
 
514
        if (r->buf != NULL)
 
515
            free(r->buf);
 
516
        r->buflen = 0;
 
517
        r->buf = NULL;
 
518
        ret = execute_command(s->bdrv, r, SG_DXFER_NONE, scsi_command_complete);
 
519
        if (ret == -1) {
 
520
            scsi_command_complete(r, -EINVAL);
 
521
            return 0;
 
522
        }
 
523
        return 0;
 
524
    }
 
525
 
 
526
    if (r->buflen != len) {
 
527
        if (r->buf != NULL)
 
528
            free(r->buf);
 
529
        r->buf = qemu_malloc(len);
 
530
        r->buflen = len;
 
531
    }
 
532
 
 
533
    memset(r->buf, 0, r->buflen);
 
534
    r->len = len;
 
535
    if (is_write(cmd[0])) {
 
536
        r->len = 0;
 
537
        return -len;
 
538
    }
 
539
 
 
540
    return len;
 
541
}
 
542
 
 
543
static int get_blocksize(BlockDriverState *bdrv)
 
544
{
 
545
    uint8_t cmd[10];
 
546
    uint8_t buf[8];
 
547
    uint8_t sensebuf[8];
 
548
    sg_io_hdr_t io_header;
 
549
    int ret;
 
550
 
 
551
    memset(cmd, sizeof(cmd), 0);
 
552
    memset(buf, sizeof(buf), 0);
 
553
    cmd[0] = READ_CAPACITY;
 
554
 
 
555
    memset(&io_header, 0, sizeof(io_header));
 
556
    io_header.interface_id = 'S';
 
557
    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
 
558
    io_header.dxfer_len = sizeof(buf);
 
559
    io_header.dxferp = buf;
 
560
    io_header.cmdp = cmd;
 
561
    io_header.cmd_len = sizeof(cmd);
 
562
    io_header.mx_sb_len = sizeof(sensebuf);
 
563
    io_header.sbp = sensebuf;
 
564
    io_header.timeout = 6000; /* XXX */
 
565
 
 
566
    ret = bdrv_pwrite(bdrv, -1, &io_header, sizeof(io_header));
 
567
    if (ret == -1)
 
568
        return -1;
 
569
 
 
570
    while ((ret = bdrv_pread(bdrv, -1, &io_header, sizeof(io_header))) == -1 &&
 
571
           errno == EINTR);
 
572
 
 
573
    if (ret == -1)
 
574
        return -1;
 
575
 
 
576
    return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
 
577
}
 
578
 
 
579
static void scsi_destroy(SCSIDevice *d)
 
580
{
 
581
    SCSIRequest *r, *n;
 
582
 
 
583
    r = d->state->requests;
 
584
    while (r) {
 
585
        n = r->next;
 
586
        qemu_free(r);
 
587
        r = n;
 
588
    }
 
589
 
 
590
    r = free_requests;
 
591
    while (r) {
 
592
        n = r->next;
 
593
        qemu_free(r);
 
594
        r = n;
 
595
    }
 
596
 
 
597
    qemu_free(d->state);
 
598
    qemu_free(d);
 
599
}
 
600
 
 
601
SCSIDevice *scsi_generic_init(BlockDriverState *bdrv, int tcq,
 
602
                              scsi_completionfn completion, void *opaque)
 
603
{
 
604
    int sg_version;
 
605
    SCSIDevice *d;
 
606
    SCSIDeviceState *s;
 
607
    struct sg_scsi_id scsiid;
 
608
 
 
609
    /* check we are really using a /dev/sg* file */
 
610
 
 
611
    if (!bdrv_is_sg(bdrv))
 
612
        return NULL;
 
613
 
 
614
    /* check we are using a driver managing SG_IO (version 3 and after */
 
615
 
 
616
    if (bdrv_ioctl(bdrv, SG_GET_VERSION_NUM, &sg_version) < 0 ||
 
617
        sg_version < 30000)
 
618
        return NULL;
 
619
 
 
620
    /* get LUN of the /dev/sg? */
 
621
 
 
622
    if (bdrv_ioctl(bdrv, SG_GET_SCSI_ID, &scsiid))
 
623
        return NULL;
 
624
 
 
625
    /* define device state */
 
626
 
 
627
    s = (SCSIDeviceState *)qemu_mallocz(sizeof(SCSIDeviceState));
 
628
    s->bdrv = bdrv;
 
629
    s->requests = NULL;
 
630
    s->completion = completion;
 
631
    s->opaque = opaque;
 
632
    s->lun = scsiid.lun;
 
633
    s->blocksize = get_blocksize(s->bdrv);
 
634
    s->driver_status = 0;
 
635
    memset(s->sensebuf, 0, sizeof(s->sensebuf));
 
636
    /* removable media returns 0 if not present */
 
637
    if (s->blocksize <= 0)
 
638
        s->blocksize = 2048;
 
639
 
 
640
    /* define function to manage device */
 
641
 
 
642
    d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
 
643
    d->state = s;
 
644
    d->destroy = scsi_destroy;
 
645
    d->send_command = scsi_send_command;
 
646
    d->read_data = scsi_read_data;
 
647
    d->write_data = scsi_write_data;
 
648
    d->cancel_io = scsi_cancel_io;
 
649
    d->get_buf = scsi_get_buf;
 
650
 
 
651
    return d;
 
652
}
 
653
#endif /* __linux__ */