Statistics
| Branch: | Revision:

root / hw / scsi-generic.c @ ad2d30f7

History | View | Annotate | Download (15.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 "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_free_request(SCSIRequest *req)
78
{
79
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
80

    
81
    qemu_free(r->buf);
82
}
83

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

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

    
95
    r->req.aiocb = NULL;
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
        r->req.status = BUSY;
102
    else {
103
        if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
104
            r->req.status = BUSY;
105
            BADF("Driver Timeout\n");
106
        } else if (r->io_header.status)
107
            r->req.status = r->io_header.status;
108
        else if (s->driver_status & SG_ERR_DRIVER_SENSE)
109
            r->req.status = CHECK_CONDITION;
110
        else
111
            r->req.status = GOOD;
112
    }
113
    DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
114
            r, r->req.tag, r->req.status);
115

    
116
    scsi_req_complete(&r->req);
117
}
118

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

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

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

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

    
159
    return 0;
160
}
161

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

    
167
    r->req.aiocb = NULL;
168
    if (ret) {
169
        DPRINTF("IO error ret %d\n", ret);
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
    if (len == 0) {
178
        scsi_command_complete(r, 0);
179
    } else {
180
        scsi_req_data(&r->req, len);
181
    }
182
}
183

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

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

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

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

    
221
    ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
222
    if (ret == -1) {
223
        scsi_command_complete(r, -EINVAL);
224
        return;
225
    }
226
}
227

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

    
233
    DPRINTF("scsi_write_complete() ret = %d\n", ret);
234
    r->req.aiocb = NULL;
235
    if (ret) {
236
        DPRINTF("IO error\n");
237
        scsi_command_complete(r, ret);
238
        return;
239
    }
240

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

    
247
    scsi_command_complete(r, ret);
248
}
249

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

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

    
267
    if (r->len == 0) {
268
        r->len = r->buflen;
269
        scsi_req_data(&r->req, r->len);
270
        return 0;
271
    }
272

    
273
    ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
274
    if (ret == -1) {
275
        scsi_command_complete(r, -EINVAL);
276
        return 1;
277
    }
278

    
279
    return 0;
280
}
281

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

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

    
314
/* Execute a scsi command.  Returns the length of the data expected by the
315
   command.  This will be Positive for data transfers from the device
316
   (eg. disk reads), negative for transfers to the device (eg. disk writes),
317
   and zero if the command does not transfer any data.  */
318

    
319
static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
320
                                 uint8_t *cmd, int lun)
321
{
322
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
323
    SCSIGenericReq *r;
324
    SCSIBus *bus;
325
    int ret;
326
    int32_t len;
327

    
328
    if (cmd[0] != REQUEST_SENSE &&
329
        (lun != s->lun || (cmd[1] >> 5) != s->lun)) {
330
        DPRINTF("Unimplemented LUN %d\n", lun ? lun : cmd[1] >> 5);
331

    
332
        s->sensebuf[0] = 0x70;
333
        s->sensebuf[1] = 0x00;
334
        s->sensebuf[2] = ILLEGAL_REQUEST;
335
        s->sensebuf[3] = 0x00;
336
        s->sensebuf[4] = 0x00;
337
        s->sensebuf[5] = 0x00;
338
        s->sensebuf[6] = 0x00;
339
        s->senselen = 7;
340
        s->driver_status = SG_ERR_DRIVER_SENSE;
341
        bus = scsi_bus_from_device(d);
342
        bus->ops->complete(bus, SCSI_REASON_DONE, tag, CHECK_CONDITION);
343
        return 0;
344
    }
345

    
346
    r = scsi_find_request(s, tag);
347
    if (r) {
348
        BADF("Tag 0x%x already in use %p\n", tag, r);
349
        scsi_cancel_io(d, tag);
350
    }
351
    r = scsi_new_request(d, tag, lun);
352

    
353
    if (-1 == scsi_req_parse(&r->req, cmd)) {
354
        BADF("Unsupported command length, command %x\n", cmd[0]);
355
        scsi_req_dequeue(&r->req);
356
        scsi_req_unref(&r->req);
357
        return 0;
358
    }
359
    scsi_req_fixup(&r->req);
360

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

    
364
#ifdef DEBUG_SCSI
365
    {
366
        int i;
367
        for (i = 1; i < r->req.cmd.len; i++) {
368
            printf(" 0x%02x", cmd[i]);
369
        }
370
        printf("\n");
371
    }
372
#endif
373

    
374
    if (r->req.cmd.xfer == 0) {
375
        if (r->buf != NULL)
376
            qemu_free(r->buf);
377
        r->buflen = 0;
378
        r->buf = NULL;
379
        ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
380
        if (ret == -1) {
381
            scsi_command_complete(r, -EINVAL);
382
            scsi_req_unref(&r->req);
383
            return 0;
384
        }
385
        scsi_req_unref(&r->req);
386
        return 0;
387
    }
388

    
389
    if (r->buflen != r->req.cmd.xfer) {
390
        if (r->buf != NULL)
391
            qemu_free(r->buf);
392
        r->buf = qemu_malloc(r->req.cmd.xfer);
393
        r->buflen = r->req.cmd.xfer;
394
    }
395

    
396
    memset(r->buf, 0, r->buflen);
397
    r->len = r->req.cmd.xfer;
398
    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
399
        r->len = 0;
400
        len = -r->req.cmd.xfer;
401
    } else {
402
        len = r->req.cmd.xfer;
403
    }
404

    
405
    scsi_req_unref(&r->req);
406
    return len;
407
}
408

    
409
static int get_blocksize(BlockDriverState *bdrv)
410
{
411
    uint8_t cmd[10];
412
    uint8_t buf[8];
413
    uint8_t sensebuf[8];
414
    sg_io_hdr_t io_header;
415
    int ret;
416

    
417
    memset(cmd, 0, sizeof(cmd));
418
    memset(buf, 0, sizeof(buf));
419
    cmd[0] = READ_CAPACITY;
420

    
421
    memset(&io_header, 0, sizeof(io_header));
422
    io_header.interface_id = 'S';
423
    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
424
    io_header.dxfer_len = sizeof(buf);
425
    io_header.dxferp = buf;
426
    io_header.cmdp = cmd;
427
    io_header.cmd_len = sizeof(cmd);
428
    io_header.mx_sb_len = sizeof(sensebuf);
429
    io_header.sbp = sensebuf;
430
    io_header.timeout = 6000; /* XXX */
431

    
432
    ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
433
    if (ret < 0)
434
        return -1;
435

    
436
    return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
437
}
438

    
439
static int get_stream_blocksize(BlockDriverState *bdrv)
440
{
441
    uint8_t cmd[6];
442
    uint8_t buf[12];
443
    uint8_t sensebuf[8];
444
    sg_io_hdr_t io_header;
445
    int ret;
446

    
447
    memset(cmd, 0, sizeof(cmd));
448
    memset(buf, 0, sizeof(buf));
449
    cmd[0] = MODE_SENSE;
450
    cmd[4] = sizeof(buf);
451

    
452
    memset(&io_header, 0, sizeof(io_header));
453
    io_header.interface_id = 'S';
454
    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
455
    io_header.dxfer_len = sizeof(buf);
456
    io_header.dxferp = buf;
457
    io_header.cmdp = cmd;
458
    io_header.cmd_len = sizeof(cmd);
459
    io_header.mx_sb_len = sizeof(sensebuf);
460
    io_header.sbp = sensebuf;
461
    io_header.timeout = 6000; /* XXX */
462

    
463
    ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
464
    if (ret < 0)
465
        return -1;
466

    
467
    return (buf[9] << 16) | (buf[10] << 8) | buf[11];
468
}
469

    
470
static void scsi_generic_purge_requests(SCSIGenericState *s)
471
{
472
    SCSIGenericReq *r;
473

    
474
    while (!QTAILQ_EMPTY(&s->qdev.requests)) {
475
        r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&s->qdev.requests));
476
        if (r->req.aiocb) {
477
            bdrv_aio_cancel(r->req.aiocb);
478
        }
479
        scsi_req_dequeue(&r->req);
480
    }
481
}
482

    
483
static void scsi_generic_reset(DeviceState *dev)
484
{
485
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev);
486

    
487
    scsi_generic_purge_requests(s);
488
}
489

    
490
static void scsi_destroy(SCSIDevice *d)
491
{
492
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
493

    
494
    scsi_generic_purge_requests(s);
495
    blockdev_mark_auto_del(s->qdev.conf.bs);
496
}
497

    
498
static int scsi_generic_initfn(SCSIDevice *dev)
499
{
500
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
501
    int sg_version;
502
    struct sg_scsi_id scsiid;
503

    
504
    if (!s->qdev.conf.bs) {
505
        error_report("scsi-generic: drive property not set");
506
        return -1;
507
    }
508
    s->bs = s->qdev.conf.bs;
509

    
510
    /* check we are really using a /dev/sg* file */
511
    if (!bdrv_is_sg(s->bs)) {
512
        error_report("scsi-generic: not /dev/sg*");
513
        return -1;
514
    }
515

    
516
    if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
517
        error_report("Device doesn't support drive option werror");
518
        return -1;
519
    }
520
    if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
521
        error_report("Device doesn't support drive option rerror");
522
        return -1;
523
    }
524

    
525
    /* check we are using a driver managing SG_IO (version 3 and after */
526
    if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
527
        sg_version < 30000) {
528
        error_report("scsi-generic: scsi generic interface too old");
529
        return -1;
530
    }
531

    
532
    /* get LUN of the /dev/sg? */
533
    if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
534
        error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
535
        return -1;
536
    }
537

    
538
    /* define device state */
539
    s->lun = scsiid.lun;
540
    DPRINTF("LUN %d\n", s->lun);
541
    s->qdev.type = scsiid.scsi_type;
542
    DPRINTF("device type %d\n", s->qdev.type);
543
    if (s->qdev.type == TYPE_TAPE) {
544
        s->qdev.blocksize = get_stream_blocksize(s->bs);
545
        if (s->qdev.blocksize == -1)
546
            s->qdev.blocksize = 0;
547
    } else {
548
        s->qdev.blocksize = get_blocksize(s->bs);
549
        /* removable media returns 0 if not present */
550
        if (s->qdev.blocksize <= 0) {
551
            if (s->qdev.type == TYPE_ROM || s->qdev.type  == TYPE_WORM)
552
                s->qdev.blocksize = 2048;
553
            else
554
                s->qdev.blocksize = 512;
555
        }
556
    }
557
    DPRINTF("block size %d\n", s->qdev.blocksize);
558
    s->driver_status = 0;
559
    memset(s->sensebuf, 0, sizeof(s->sensebuf));
560
    bdrv_set_removable(s->bs, 0);
561
    return 0;
562
}
563

    
564
static SCSIDeviceInfo scsi_generic_info = {
565
    .qdev.name    = "scsi-generic",
566
    .qdev.desc    = "pass through generic scsi device (/dev/sg*)",
567
    .qdev.size    = sizeof(SCSIGenericState),
568
    .qdev.reset   = scsi_generic_reset,
569
    .init         = scsi_generic_initfn,
570
    .destroy      = scsi_destroy,
571
    .free_req     = scsi_free_request,
572
    .send_command = scsi_send_command,
573
    .read_data    = scsi_read_data,
574
    .write_data   = scsi_write_data,
575
    .cancel_io    = scsi_cancel_io,
576
    .get_buf      = scsi_get_buf,
577
    .qdev.props   = (Property[]) {
578
        DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
579
        DEFINE_PROP_END_OF_LIST(),
580
    },
581
};
582

    
583
static void scsi_generic_register_devices(void)
584
{
585
    scsi_qdev_register(&scsi_generic_info);
586
}
587
device_init(scsi_generic_register_devices)
588

    
589
#endif /* __linux__ */