Statistics
| Branch: | Revision:

root / hw / scsi-generic.c @ 5ee8ad71

History | View | Annotate | Download (15.6 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 "qemu-error.h"
16
#include "scsi.h"
17
#include "blockdev.h"
18

    
19
#ifdef __linux__
20

    
21
//#define DEBUG_SCSI
22

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

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

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

    
40
#define SCSI_SENSE_BUF_SIZE 96
41

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

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

    
49
typedef struct SCSIGenericState SCSIGenericState;
50

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

    
59
struct SCSIGenericState
60
{
61
    SCSIDevice qdev;
62
    BlockDriverState *bs;
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

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

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

    
114
    scsi_req_complete(&r->req);
115
    scsi_remove_request(r);
116
}
117

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

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

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

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

    
158
    return 0;
159
}
160

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

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

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

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

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

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

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

    
217
    ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
218
    if (ret == -1) {
219
        scsi_command_complete(r, -EINVAL);
220
        return;
221
    }
222
}
223

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

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

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

    
242
    scsi_command_complete(r, ret);
243
}
244

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

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

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

    
268
    ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
269
    if (ret == -1) {
270
        scsi_command_complete(r, -EINVAL);
271
        return 1;
272
    }
273

    
274
    return 0;
275
}
276

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

    
290
static void scsi_req_fixup(SCSIRequest *req)
291
{
292
    switch(req->cmd.buf[0]) {
293
    case WRITE_10:
294
        req->cmd.buf[1] &= ~0x08;        /* disable FUA */
295
        break;
296
    case READ_10:
297
        req->cmd.buf[1] &= ~0x08;        /* disable FUA */
298
        break;
299
    case REWIND:
300
    case START_STOP:
301
        if (req->dev->type == TYPE_TAPE) {
302
            /* force IMMED, otherwise qemu waits end of command */
303
            req->cmd.buf[1] = 0x01;
304
        }
305
        break;
306
    }
307
}
308

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

    
314
static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
315
                                 uint8_t *cmd, int lun)
316
{
317
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
318
    SCSIGenericReq *r;
319
    SCSIBus *bus;
320
    int ret;
321

    
322
    if (cmd[0] != REQUEST_SENSE &&
323
        (lun != s->lun || (cmd[1] >> 5) != s->lun)) {
324
        DPRINTF("Unimplemented LUN %d\n", lun ? lun : cmd[1] >> 5);
325

    
326
        s->sensebuf[0] = 0x70;
327
        s->sensebuf[1] = 0x00;
328
        s->sensebuf[2] = ILLEGAL_REQUEST;
329
        s->sensebuf[3] = 0x00;
330
        s->sensebuf[4] = 0x00;
331
        s->sensebuf[5] = 0x00;
332
        s->sensebuf[6] = 0x00;
333
        s->senselen = 7;
334
        s->driver_status = SG_ERR_DRIVER_SENSE;
335
        bus = scsi_bus_from_device(d);
336
        bus->complete(bus, SCSI_REASON_DONE, tag, CHECK_CONDITION);
337
        return 0;
338
    }
339

    
340
    r = scsi_find_request(s, tag);
341
    if (r) {
342
        BADF("Tag 0x%x already in use %p\n", tag, r);
343
        scsi_cancel_io(d, tag);
344
    }
345
    r = scsi_new_request(d, tag, lun);
346

    
347
    if (-1 == scsi_req_parse(&r->req, cmd)) {
348
        BADF("Unsupported command length, command %x\n", cmd[0]);
349
        scsi_remove_request(r);
350
        return 0;
351
    }
352
    scsi_req_fixup(&r->req);
353

    
354
    DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,
355
            r->req.cmd.xfer, cmd[0]);
356

    
357
#ifdef DEBUG_SCSI
358
    {
359
        int i;
360
        for (i = 1; i < r->req.cmd.len; i++) {
361
            printf(" 0x%02x", cmd[i]);
362
        }
363
        printf("\n");
364
    }
365
#endif
366

    
367
    if (r->req.cmd.xfer == 0) {
368
        if (r->buf != NULL)
369
            qemu_free(r->buf);
370
        r->buflen = 0;
371
        r->buf = NULL;
372
        ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
373
        if (ret == -1) {
374
            scsi_command_complete(r, -EINVAL);
375
            return 0;
376
        }
377
        return 0;
378
    }
379

    
380
    if (r->buflen != r->req.cmd.xfer) {
381
        if (r->buf != NULL)
382
            qemu_free(r->buf);
383
        r->buf = qemu_malloc(r->req.cmd.xfer);
384
        r->buflen = r->req.cmd.xfer;
385
    }
386

    
387
    memset(r->buf, 0, r->buflen);
388
    r->len = r->req.cmd.xfer;
389
    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
390
        r->len = 0;
391
        return -r->req.cmd.xfer;
392
    }
393

    
394
    return r->req.cmd.xfer;
395
}
396

    
397
static int get_blocksize(BlockDriverState *bdrv)
398
{
399
    uint8_t cmd[10];
400
    uint8_t buf[8];
401
    uint8_t sensebuf[8];
402
    sg_io_hdr_t io_header;
403
    int ret;
404

    
405
    memset(cmd, 0, sizeof(cmd));
406
    memset(buf, 0, sizeof(buf));
407
    cmd[0] = READ_CAPACITY;
408

    
409
    memset(&io_header, 0, sizeof(io_header));
410
    io_header.interface_id = 'S';
411
    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
412
    io_header.dxfer_len = sizeof(buf);
413
    io_header.dxferp = buf;
414
    io_header.cmdp = cmd;
415
    io_header.cmd_len = sizeof(cmd);
416
    io_header.mx_sb_len = sizeof(sensebuf);
417
    io_header.sbp = sensebuf;
418
    io_header.timeout = 6000; /* XXX */
419

    
420
    ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
421
    if (ret < 0)
422
        return -1;
423

    
424
    return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
425
}
426

    
427
static int get_stream_blocksize(BlockDriverState *bdrv)
428
{
429
    uint8_t cmd[6];
430
    uint8_t buf[12];
431
    uint8_t sensebuf[8];
432
    sg_io_hdr_t io_header;
433
    int ret;
434

    
435
    memset(cmd, 0, sizeof(cmd));
436
    memset(buf, 0, sizeof(buf));
437
    cmd[0] = MODE_SENSE;
438
    cmd[4] = sizeof(buf);
439

    
440
    memset(&io_header, 0, sizeof(io_header));
441
    io_header.interface_id = 'S';
442
    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
443
    io_header.dxfer_len = sizeof(buf);
444
    io_header.dxferp = buf;
445
    io_header.cmdp = cmd;
446
    io_header.cmd_len = sizeof(cmd);
447
    io_header.mx_sb_len = sizeof(sensebuf);
448
    io_header.sbp = sensebuf;
449
    io_header.timeout = 6000; /* XXX */
450

    
451
    ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
452
    if (ret < 0)
453
        return -1;
454

    
455
    return (buf[9] << 16) | (buf[10] << 8) | buf[11];
456
}
457

    
458
static void scsi_generic_purge_requests(SCSIGenericState *s)
459
{
460
    SCSIGenericReq *r;
461

    
462
    while (!QTAILQ_EMPTY(&s->qdev.requests)) {
463
        r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&s->qdev.requests));
464
        if (r->req.aiocb) {
465
            bdrv_aio_cancel(r->req.aiocb);
466
        }
467
        scsi_remove_request(r);
468
    }
469
}
470

    
471
static void scsi_generic_reset(DeviceState *dev)
472
{
473
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev);
474

    
475
    scsi_generic_purge_requests(s);
476
}
477

    
478
static void scsi_destroy(SCSIDevice *d)
479
{
480
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
481

    
482
    scsi_generic_purge_requests(s);
483
    blockdev_mark_auto_del(s->qdev.conf.bs);
484
}
485

    
486
static int scsi_generic_initfn(SCSIDevice *dev)
487
{
488
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
489
    int sg_version;
490
    struct sg_scsi_id scsiid;
491

    
492
    if (!s->qdev.conf.bs) {
493
        error_report("scsi-generic: drive property not set");
494
        return -1;
495
    }
496
    s->bs = s->qdev.conf.bs;
497

    
498
    /* check we are really using a /dev/sg* file */
499
    if (!bdrv_is_sg(s->bs)) {
500
        error_report("scsi-generic: not /dev/sg*");
501
        return -1;
502
    }
503

    
504
    if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
505
        error_report("Device doesn't support drive option werror");
506
        return -1;
507
    }
508
    if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
509
        error_report("Device doesn't support drive option rerror");
510
        return -1;
511
    }
512

    
513
    /* check we are using a driver managing SG_IO (version 3 and after */
514
    if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
515
        sg_version < 30000) {
516
        error_report("scsi-generic: scsi generic interface too old");
517
        return -1;
518
    }
519

    
520
    /* get LUN of the /dev/sg? */
521
    if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
522
        error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
523
        return -1;
524
    }
525

    
526
    /* define device state */
527
    s->lun = scsiid.lun;
528
    DPRINTF("LUN %d\n", s->lun);
529
    s->qdev.type = scsiid.scsi_type;
530
    DPRINTF("device type %d\n", s->qdev.type);
531
    if (s->qdev.type == TYPE_TAPE) {
532
        s->qdev.blocksize = get_stream_blocksize(s->bs);
533
        if (s->qdev.blocksize == -1)
534
            s->qdev.blocksize = 0;
535
    } else {
536
        s->qdev.blocksize = get_blocksize(s->bs);
537
        /* removable media returns 0 if not present */
538
        if (s->qdev.blocksize <= 0) {
539
            if (s->qdev.type == TYPE_ROM || s->qdev.type  == TYPE_WORM)
540
                s->qdev.blocksize = 2048;
541
            else
542
                s->qdev.blocksize = 512;
543
        }
544
    }
545
    DPRINTF("block size %d\n", s->qdev.blocksize);
546
    s->driver_status = 0;
547
    memset(s->sensebuf, 0, sizeof(s->sensebuf));
548
    bdrv_set_removable(s->bs, 0);
549
    return 0;
550
}
551

    
552
static SCSIDeviceInfo scsi_generic_info = {
553
    .qdev.name    = "scsi-generic",
554
    .qdev.desc    = "pass through generic scsi device (/dev/sg*)",
555
    .qdev.size    = sizeof(SCSIGenericState),
556
    .qdev.reset   = scsi_generic_reset,
557
    .init         = scsi_generic_initfn,
558
    .destroy      = scsi_destroy,
559
    .send_command = scsi_send_command,
560
    .read_data    = scsi_read_data,
561
    .write_data   = scsi_write_data,
562
    .cancel_io    = scsi_cancel_io,
563
    .get_buf      = scsi_get_buf,
564
    .qdev.props   = (Property[]) {
565
        DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
566
        DEFINE_PROP_END_OF_LIST(),
567
    },
568
};
569

    
570
static void scsi_generic_register_devices(void)
571
{
572
    scsi_qdev_register(&scsi_generic_info);
573
}
574
device_init(scsi_generic_register_devices)
575

    
576
#endif /* __linux__ */