Statistics
| Branch: | Revision:

root / hw / scsi-generic.c @ 2e7cc4d6

History | View | Annotate | Download (15.4 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 void scsi_set_sense(SCSIGenericState *s, SCSISense sense)
70
{
71
    s->senselen = scsi_build_sense(sense, s->sensebuf, SCSI_SENSE_BUF_SIZE, 0);
72
    s->driver_status = SG_ERR_DRIVER_SENSE;
73
}
74

    
75
static void scsi_clear_sense(SCSIGenericState *s)
76
{
77
    memset(s->sensebuf, 0, SCSI_SENSE_BUF_SIZE);
78
    s->senselen = 0;
79
    s->driver_status = 0;
80
}
81

    
82
static int scsi_get_sense(SCSIRequest *req, uint8_t *outbuf, int len)
83
{
84
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
85
    int size = SCSI_SENSE_BUF_SIZE;
86

    
87
    if (!(s->driver_status & SG_ERR_DRIVER_SENSE)) {
88
        size = scsi_build_sense(SENSE_CODE(NO_SENSE), s->sensebuf,
89
                                SCSI_SENSE_BUF_SIZE, 0);
90
    }
91
    if (size > len) {
92
        size = len;
93
    }
94
    memcpy(outbuf, s->sensebuf, size);
95

    
96
    return size;
97
}
98

    
99
static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
100
{
101
    SCSIRequest *req;
102

    
103
    req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun);
104
    return req;
105
}
106

    
107
static void scsi_free_request(SCSIRequest *req)
108
{
109
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
110

    
111
    qemu_free(r->buf);
112
}
113

    
114
/* Helper function for command completion.  */
115
static void scsi_command_complete(void *opaque, int ret)
116
{
117
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
118
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
119

    
120
    r->req.aiocb = NULL;
121
    s->driver_status = r->io_header.driver_status;
122
    if (s->driver_status & SG_ERR_DRIVER_SENSE)
123
        s->senselen = r->io_header.sb_len_wr;
124

    
125
    if (ret != 0) {
126
        switch (ret) {
127
        case -EDOM:
128
            r->req.status = TASK_SET_FULL;
129
            break;
130
        case -EINVAL:
131
            r->req.status = CHECK_CONDITION;
132
            scsi_set_sense(s, SENSE_CODE(INVALID_FIELD));
133
            break;
134
        case -ENOMEM:
135
            r->req.status = CHECK_CONDITION;
136
            scsi_set_sense(s, SENSE_CODE(TARGET_FAILURE));
137
            break;
138
        default:
139
            r->req.status = CHECK_CONDITION;
140
            scsi_set_sense(s, SENSE_CODE(IO_ERROR));
141
            break;
142
        }
143
    } else {
144
        if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
145
            r->req.status = BUSY;
146
            BADF("Driver Timeout\n");
147
        } else if (r->io_header.status)
148
            r->req.status = r->io_header.status;
149
        else if (s->driver_status & SG_ERR_DRIVER_SENSE)
150
            r->req.status = CHECK_CONDITION;
151
        else
152
            r->req.status = GOOD;
153
    }
154
    DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
155
            r, r->req.tag, r->req.status);
156

    
157
    scsi_req_complete(&r->req);
158
}
159

    
160
/* Cancel a pending data transfer.  */
161
static void scsi_cancel_io(SCSIRequest *req)
162
{
163
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
164

    
165
    DPRINTF("Cancel tag=0x%x\n", req->tag);
166
    if (r->req.aiocb) {
167
        bdrv_aio_cancel(r->req.aiocb);
168
    }
169
    r->req.aiocb = NULL;
170
}
171

    
172
static int execute_command(BlockDriverState *bdrv,
173
                           SCSIGenericReq *r, int direction,
174
                           BlockDriverCompletionFunc *complete)
175
{
176
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
177

    
178
    r->io_header.interface_id = 'S';
179
    r->io_header.dxfer_direction = direction;
180
    r->io_header.dxferp = r->buf;
181
    r->io_header.dxfer_len = r->buflen;
182
    r->io_header.cmdp = r->req.cmd.buf;
183
    r->io_header.cmd_len = r->req.cmd.len;
184
    r->io_header.mx_sb_len = sizeof(s->sensebuf);
185
    r->io_header.sbp = s->sensebuf;
186
    r->io_header.timeout = MAX_UINT;
187
    r->io_header.usr_ptr = r;
188
    r->io_header.flags |= SG_FLAG_DIRECT_IO;
189

    
190
    r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
191
    if (r->req.aiocb == NULL) {
192
        BADF("execute_command: read failed !\n");
193
        return -ENOMEM;
194
    }
195

    
196
    return 0;
197
}
198

    
199
static void scsi_read_complete(void * opaque, int ret)
200
{
201
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
202
    int len;
203

    
204
    r->req.aiocb = NULL;
205
    if (ret) {
206
        DPRINTF("IO error ret %d\n", ret);
207
        scsi_command_complete(r, ret);
208
        return;
209
    }
210
    len = r->io_header.dxfer_len - r->io_header.resid;
211
    DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
212

    
213
    r->len = -1;
214
    if (len == 0) {
215
        scsi_command_complete(r, 0);
216
    } else {
217
        scsi_req_data(&r->req, len);
218
    }
219
}
220

    
221
/* Read more data from scsi device into buffer.  */
222
static void scsi_read_data(SCSIRequest *req)
223
{
224
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
225
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
226
    int ret;
227

    
228
    DPRINTF("scsi_read_data 0x%x\n", req->tag);
229
    if (r->len == -1) {
230
        scsi_command_complete(r, 0);
231
        return;
232
    }
233

    
234
    if (r->req.cmd.buf[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
235
    {
236
        s->senselen = MIN(r->len, s->senselen);
237
        memcpy(r->buf, s->sensebuf, s->senselen);
238
        r->io_header.driver_status = 0;
239
        r->io_header.status = 0;
240
        r->io_header.dxfer_len  = s->senselen;
241
        r->len = -1;
242
        DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, s->senselen);
243
        DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
244
                r->buf[0], r->buf[1], r->buf[2], r->buf[3],
245
                r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
246
        scsi_req_data(&r->req, s->senselen);
247
        /* Clear sensebuf after REQUEST_SENSE */
248
        scsi_clear_sense(s);
249
        return;
250
    }
251

    
252
    ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
253
    if (ret < 0) {
254
        scsi_command_complete(r, ret);
255
        return;
256
    }
257
}
258

    
259
static void scsi_write_complete(void * opaque, int ret)
260
{
261
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
262
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
263

    
264
    DPRINTF("scsi_write_complete() ret = %d\n", ret);
265
    r->req.aiocb = NULL;
266
    if (ret) {
267
        DPRINTF("IO error\n");
268
        scsi_command_complete(r, ret);
269
        return;
270
    }
271

    
272
    if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
273
        s->qdev.type == TYPE_TAPE) {
274
        s->qdev.blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
275
        DPRINTF("block size %d\n", s->qdev.blocksize);
276
    }
277

    
278
    scsi_command_complete(r, ret);
279
}
280

    
281
/* Write data to a scsi device.  Returns nonzero on failure.
282
   The transfer may complete asynchronously.  */
283
static void scsi_write_data(SCSIRequest *req)
284
{
285
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
286
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
287
    int ret;
288

    
289
    DPRINTF("scsi_write_data 0x%x\n", req->tag);
290
    if (r->len == 0) {
291
        r->len = r->buflen;
292
        scsi_req_data(&r->req, r->len);
293
        return;
294
    }
295

    
296
    ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
297
    if (ret < 0) {
298
        scsi_command_complete(r, ret);
299
    }
300
}
301

    
302
/* Return a pointer to the data buffer.  */
303
static uint8_t *scsi_get_buf(SCSIRequest *req)
304
{
305
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
306

    
307
    return r->buf;
308
}
309

    
310
static void scsi_req_fixup(SCSIRequest *req)
311
{
312
    switch(req->cmd.buf[0]) {
313
    case WRITE_10:
314
        req->cmd.buf[1] &= ~0x08;        /* disable FUA */
315
        break;
316
    case READ_10:
317
        req->cmd.buf[1] &= ~0x08;        /* disable FUA */
318
        break;
319
    case REWIND:
320
    case START_STOP:
321
        if (req->dev->type == TYPE_TAPE) {
322
            /* force IMMED, otherwise qemu waits end of command */
323
            req->cmd.buf[1] = 0x01;
324
        }
325
        break;
326
    }
327
}
328

    
329
/* Execute a scsi command.  Returns the length of the data expected by the
330
   command.  This will be Positive for data transfers from the device
331
   (eg. disk reads), negative for transfers to the device (eg. disk writes),
332
   and zero if the command does not transfer any data.  */
333

    
334
static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
335
{
336
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
337
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
338
    int ret;
339

    
340
    if (cmd[0] != REQUEST_SENSE &&
341
        (req->lun != s->lun || (cmd[1] >> 5) != s->lun)) {
342
        DPRINTF("Unimplemented LUN %d\n", req->lun ? req->lun : cmd[1] >> 5);
343
        scsi_set_sense(s, SENSE_CODE(LUN_NOT_SUPPORTED));
344
        r->req.status = CHECK_CONDITION;
345
        scsi_req_complete(&r->req);
346
        return 0;
347
    }
348

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

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

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

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

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

    
389
    memset(r->buf, 0, r->buflen);
390
    r->len = r->req.cmd.xfer;
391
    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
392
        r->len = 0;
393
        return -r->req.cmd.xfer;
394
    } else {
395
        return r->req.cmd.xfer;
396
    }
397
}
398

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

    
407
    memset(cmd, 0, sizeof(cmd));
408
    memset(buf, 0, sizeof(buf));
409
    cmd[0] = READ_CAPACITY;
410

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

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

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

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

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

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

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

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

    
460
static void scsi_generic_reset(DeviceState *dev)
461
{
462
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev);
463

    
464
    scsi_device_purge_requests(&s->qdev);
465
}
466

    
467
static void scsi_destroy(SCSIDevice *d)
468
{
469
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
470

    
471
    scsi_device_purge_requests(&s->qdev);
472
    blockdev_mark_auto_del(s->qdev.conf.bs);
473
}
474

    
475
static int scsi_generic_initfn(SCSIDevice *dev)
476
{
477
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
478
    int sg_version;
479
    struct sg_scsi_id scsiid;
480

    
481
    if (!s->qdev.conf.bs) {
482
        error_report("scsi-generic: drive property not set");
483
        return -1;
484
    }
485
    s->bs = s->qdev.conf.bs;
486

    
487
    /* check we are really using a /dev/sg* file */
488
    if (!bdrv_is_sg(s->bs)) {
489
        error_report("scsi-generic: not /dev/sg*");
490
        return -1;
491
    }
492

    
493
    if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
494
        error_report("Device doesn't support drive option werror");
495
        return -1;
496
    }
497
    if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
498
        error_report("Device doesn't support drive option rerror");
499
        return -1;
500
    }
501

    
502
    /* check we are using a driver managing SG_IO (version 3 and after */
503
    if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
504
        sg_version < 30000) {
505
        error_report("scsi-generic: scsi generic interface too old");
506
        return -1;
507
    }
508

    
509
    /* get LUN of the /dev/sg? */
510
    if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
511
        error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
512
        return -1;
513
    }
514

    
515
    /* define device state */
516
    s->lun = scsiid.lun;
517
    DPRINTF("LUN %d\n", s->lun);
518
    s->qdev.type = scsiid.scsi_type;
519
    DPRINTF("device type %d\n", s->qdev.type);
520
    if (s->qdev.type == TYPE_TAPE) {
521
        s->qdev.blocksize = get_stream_blocksize(s->bs);
522
        if (s->qdev.blocksize == -1)
523
            s->qdev.blocksize = 0;
524
    } else {
525
        s->qdev.blocksize = get_blocksize(s->bs);
526
        /* removable media returns 0 if not present */
527
        if (s->qdev.blocksize <= 0) {
528
            if (s->qdev.type == TYPE_ROM || s->qdev.type  == TYPE_WORM)
529
                s->qdev.blocksize = 2048;
530
            else
531
                s->qdev.blocksize = 512;
532
        }
533
    }
534
    DPRINTF("block size %d\n", s->qdev.blocksize);
535
    s->driver_status = 0;
536
    memset(s->sensebuf, 0, sizeof(s->sensebuf));
537
    bdrv_set_removable(s->bs, 0);
538
    return 0;
539
}
540

    
541
static SCSIDeviceInfo scsi_generic_info = {
542
    .qdev.name    = "scsi-generic",
543
    .qdev.desc    = "pass through generic scsi device (/dev/sg*)",
544
    .qdev.size    = sizeof(SCSIGenericState),
545
    .qdev.reset   = scsi_generic_reset,
546
    .init         = scsi_generic_initfn,
547
    .destroy      = scsi_destroy,
548
    .alloc_req    = scsi_new_request,
549
    .free_req     = scsi_free_request,
550
    .send_command = scsi_send_command,
551
    .read_data    = scsi_read_data,
552
    .write_data   = scsi_write_data,
553
    .cancel_io    = scsi_cancel_io,
554
    .get_buf      = scsi_get_buf,
555
    .get_sense    = scsi_get_sense,
556
    .qdev.props   = (Property[]) {
557
        DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
558
        DEFINE_PROP_END_OF_LIST(),
559
    },
560
};
561

    
562
static void scsi_generic_register_devices(void)
563
{
564
    scsi_qdev_register(&scsi_generic_info);
565
}
566
device_init(scsi_generic_register_devices)
567

    
568
#endif /* __linux__ */