Statistics
| Branch: | Revision:

root / hw / scsi-generic.c @ a1f0cce2

History | View | Annotate | Download (14.9 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 SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
83
{
84
    SCSIRequest *req;
85

    
86
    req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun);
87
    return req;
88
}
89

    
90
static void scsi_free_request(SCSIRequest *req)
91
{
92
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
93

    
94
    qemu_free(r->buf);
95
}
96

    
97
/* Helper function for command completion.  */
98
static void scsi_command_complete(void *opaque, int ret)
99
{
100
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
101
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
102

    
103
    r->req.aiocb = NULL;
104
    s->driver_status = r->io_header.driver_status;
105
    if (s->driver_status & SG_ERR_DRIVER_SENSE)
106
        s->senselen = r->io_header.sb_len_wr;
107

    
108
    if (ret != 0) {
109
        switch (ret) {
110
        case -EINVAL:
111
            r->req.status = CHECK_CONDITION;
112
            scsi_set_sense(s, SENSE_CODE(INVALID_FIELD));
113
            break;
114
        case -ENOMEM:
115
            r->req.status = CHECK_CONDITION;
116
            scsi_set_sense(s, SENSE_CODE(TARGET_FAILURE));
117
            break;
118
        default:
119
            r->req.status = CHECK_CONDITION;
120
            scsi_set_sense(s, SENSE_CODE(IO_ERROR));
121
            break;
122
        }
123
    } else {
124
        if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
125
            r->req.status = BUSY;
126
            BADF("Driver Timeout\n");
127
        } else if (r->io_header.status)
128
            r->req.status = r->io_header.status;
129
        else if (s->driver_status & SG_ERR_DRIVER_SENSE)
130
            r->req.status = CHECK_CONDITION;
131
        else
132
            r->req.status = GOOD;
133
    }
134
    DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
135
            r, r->req.tag, r->req.status);
136

    
137
    scsi_req_complete(&r->req);
138
}
139

    
140
/* Cancel a pending data transfer.  */
141
static void scsi_cancel_io(SCSIRequest *req)
142
{
143
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
144

    
145
    DPRINTF("Cancel tag=0x%x\n", req->tag);
146
    if (r->req.aiocb) {
147
        bdrv_aio_cancel(r->req.aiocb);
148
    }
149
    r->req.aiocb = NULL;
150
}
151

    
152
static int execute_command(BlockDriverState *bdrv,
153
                           SCSIGenericReq *r, int direction,
154
                           BlockDriverCompletionFunc *complete)
155
{
156
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
157

    
158
    r->io_header.interface_id = 'S';
159
    r->io_header.dxfer_direction = direction;
160
    r->io_header.dxferp = r->buf;
161
    r->io_header.dxfer_len = r->buflen;
162
    r->io_header.cmdp = r->req.cmd.buf;
163
    r->io_header.cmd_len = r->req.cmd.len;
164
    r->io_header.mx_sb_len = sizeof(s->sensebuf);
165
    r->io_header.sbp = s->sensebuf;
166
    r->io_header.timeout = MAX_UINT;
167
    r->io_header.usr_ptr = r;
168
    r->io_header.flags |= SG_FLAG_DIRECT_IO;
169

    
170
    r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
171
    if (r->req.aiocb == NULL) {
172
        BADF("execute_command: read failed !\n");
173
        return -ENOMEM;
174
    }
175

    
176
    return 0;
177
}
178

    
179
static void scsi_read_complete(void * opaque, int ret)
180
{
181
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
182
    int len;
183

    
184
    r->req.aiocb = NULL;
185
    if (ret) {
186
        DPRINTF("IO error ret %d\n", ret);
187
        scsi_command_complete(r, ret);
188
        return;
189
    }
190
    len = r->io_header.dxfer_len - r->io_header.resid;
191
    DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
192

    
193
    r->len = -1;
194
    if (len == 0) {
195
        scsi_command_complete(r, 0);
196
    } else {
197
        scsi_req_data(&r->req, len);
198
    }
199
}
200

    
201
/* Read more data from scsi device into buffer.  */
202
static void scsi_read_data(SCSIRequest *req)
203
{
204
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
205
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
206
    int ret;
207

    
208
    DPRINTF("scsi_read_data 0x%x\n", req->tag);
209
    if (r->len == -1) {
210
        scsi_command_complete(r, 0);
211
        return;
212
    }
213

    
214
    if (r->req.cmd.buf[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
215
    {
216
        s->senselen = MIN(r->len, s->senselen);
217
        memcpy(r->buf, s->sensebuf, s->senselen);
218
        r->io_header.driver_status = 0;
219
        r->io_header.status = 0;
220
        r->io_header.dxfer_len  = s->senselen;
221
        r->len = -1;
222
        DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, s->senselen);
223
        DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
224
                r->buf[0], r->buf[1], r->buf[2], r->buf[3],
225
                r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
226
        scsi_req_data(&r->req, s->senselen);
227
        /* Clear sensebuf after REQUEST_SENSE */
228
        scsi_clear_sense(s);
229
        return;
230
    }
231

    
232
    ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
233
    if (ret < 0) {
234
        scsi_command_complete(r, ret);
235
        return;
236
    }
237
}
238

    
239
static void scsi_write_complete(void * opaque, int ret)
240
{
241
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
242
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
243

    
244
    DPRINTF("scsi_write_complete() ret = %d\n", ret);
245
    r->req.aiocb = NULL;
246
    if (ret) {
247
        DPRINTF("IO error\n");
248
        scsi_command_complete(r, ret);
249
        return;
250
    }
251

    
252
    if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
253
        s->qdev.type == TYPE_TAPE) {
254
        s->qdev.blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
255
        DPRINTF("block size %d\n", s->qdev.blocksize);
256
    }
257

    
258
    scsi_command_complete(r, ret);
259
}
260

    
261
/* Write data to a scsi device.  Returns nonzero on failure.
262
   The transfer may complete asynchronously.  */
263
static int scsi_write_data(SCSIRequest *req)
264
{
265
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
266
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
267
    int ret;
268

    
269
    DPRINTF("scsi_write_data 0x%x\n", req->tag);
270
    if (r->len == 0) {
271
        r->len = r->buflen;
272
        scsi_req_data(&r->req, r->len);
273
        return 0;
274
    }
275

    
276
    ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
277
    if (ret < 0) {
278
        scsi_command_complete(r, ret);
279
        return 1;
280
    }
281

    
282
    return 0;
283
}
284

    
285
/* Return a pointer to the data buffer.  */
286
static uint8_t *scsi_get_buf(SCSIRequest *req)
287
{
288
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
289

    
290
    return r->buf;
291
}
292

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

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

    
317
static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
318
{
319
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
320
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
321
    int ret;
322

    
323
    scsi_req_enqueue(req);
324
    if (cmd[0] != REQUEST_SENSE &&
325
        (req->lun != s->lun || (cmd[1] >> 5) != s->lun)) {
326
        DPRINTF("Unimplemented LUN %d\n", req->lun ? req->lun : cmd[1] >> 5);
327
        scsi_set_sense(s, SENSE_CODE(LUN_NOT_SUPPORTED));
328
        r->req.status = CHECK_CONDITION;
329
        scsi_req_complete(&r->req);
330
        return 0;
331
    }
332

    
333
    if (-1 == scsi_req_parse(&r->req, cmd)) {
334
        BADF("Unsupported command length, command %x\n", cmd[0]);
335
        scsi_command_complete(r, -EINVAL);
336
        return 0;
337
    }
338
    scsi_req_fixup(&r->req);
339

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

    
343
#ifdef DEBUG_SCSI
344
    {
345
        int i;
346
        for (i = 1; i < r->req.cmd.len; i++) {
347
            printf(" 0x%02x", cmd[i]);
348
        }
349
        printf("\n");
350
    }
351
#endif
352

    
353
    if (r->req.cmd.xfer == 0) {
354
        if (r->buf != NULL)
355
            qemu_free(r->buf);
356
        r->buflen = 0;
357
        r->buf = NULL;
358
        ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
359
        if (ret < 0) {
360
            scsi_command_complete(r, ret);
361
            return 0;
362
        }
363
        return 0;
364
    }
365

    
366
    if (r->buflen != r->req.cmd.xfer) {
367
        if (r->buf != NULL)
368
            qemu_free(r->buf);
369
        r->buf = qemu_malloc(r->req.cmd.xfer);
370
        r->buflen = r->req.cmd.xfer;
371
    }
372

    
373
    memset(r->buf, 0, r->buflen);
374
    r->len = r->req.cmd.xfer;
375
    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
376
        r->len = 0;
377
        return -r->req.cmd.xfer;
378
    } else {
379
        return r->req.cmd.xfer;
380
    }
381
}
382

    
383
static int get_blocksize(BlockDriverState *bdrv)
384
{
385
    uint8_t cmd[10];
386
    uint8_t buf[8];
387
    uint8_t sensebuf[8];
388
    sg_io_hdr_t io_header;
389
    int ret;
390

    
391
    memset(cmd, 0, sizeof(cmd));
392
    memset(buf, 0, sizeof(buf));
393
    cmd[0] = READ_CAPACITY;
394

    
395
    memset(&io_header, 0, sizeof(io_header));
396
    io_header.interface_id = 'S';
397
    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
398
    io_header.dxfer_len = sizeof(buf);
399
    io_header.dxferp = buf;
400
    io_header.cmdp = cmd;
401
    io_header.cmd_len = sizeof(cmd);
402
    io_header.mx_sb_len = sizeof(sensebuf);
403
    io_header.sbp = sensebuf;
404
    io_header.timeout = 6000; /* XXX */
405

    
406
    ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
407
    if (ret < 0)
408
        return -1;
409

    
410
    return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
411
}
412

    
413
static int get_stream_blocksize(BlockDriverState *bdrv)
414
{
415
    uint8_t cmd[6];
416
    uint8_t buf[12];
417
    uint8_t sensebuf[8];
418
    sg_io_hdr_t io_header;
419
    int ret;
420

    
421
    memset(cmd, 0, sizeof(cmd));
422
    memset(buf, 0, sizeof(buf));
423
    cmd[0] = MODE_SENSE;
424
    cmd[4] = sizeof(buf);
425

    
426
    memset(&io_header, 0, sizeof(io_header));
427
    io_header.interface_id = 'S';
428
    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
429
    io_header.dxfer_len = sizeof(buf);
430
    io_header.dxferp = buf;
431
    io_header.cmdp = cmd;
432
    io_header.cmd_len = sizeof(cmd);
433
    io_header.mx_sb_len = sizeof(sensebuf);
434
    io_header.sbp = sensebuf;
435
    io_header.timeout = 6000; /* XXX */
436

    
437
    ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
438
    if (ret < 0)
439
        return -1;
440

    
441
    return (buf[9] << 16) | (buf[10] << 8) | buf[11];
442
}
443

    
444
static void scsi_generic_reset(DeviceState *dev)
445
{
446
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev);
447

    
448
    scsi_device_purge_requests(&s->qdev);
449
}
450

    
451
static void scsi_destroy(SCSIDevice *d)
452
{
453
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
454

    
455
    scsi_device_purge_requests(&s->qdev);
456
    blockdev_mark_auto_del(s->qdev.conf.bs);
457
}
458

    
459
static int scsi_generic_initfn(SCSIDevice *dev)
460
{
461
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
462
    int sg_version;
463
    struct sg_scsi_id scsiid;
464

    
465
    if (!s->qdev.conf.bs) {
466
        error_report("scsi-generic: drive property not set");
467
        return -1;
468
    }
469
    s->bs = s->qdev.conf.bs;
470

    
471
    /* check we are really using a /dev/sg* file */
472
    if (!bdrv_is_sg(s->bs)) {
473
        error_report("scsi-generic: not /dev/sg*");
474
        return -1;
475
    }
476

    
477
    if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
478
        error_report("Device doesn't support drive option werror");
479
        return -1;
480
    }
481
    if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
482
        error_report("Device doesn't support drive option rerror");
483
        return -1;
484
    }
485

    
486
    /* check we are using a driver managing SG_IO (version 3 and after */
487
    if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
488
        sg_version < 30000) {
489
        error_report("scsi-generic: scsi generic interface too old");
490
        return -1;
491
    }
492

    
493
    /* get LUN of the /dev/sg? */
494
    if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
495
        error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
496
        return -1;
497
    }
498

    
499
    /* define device state */
500
    s->lun = scsiid.lun;
501
    DPRINTF("LUN %d\n", s->lun);
502
    s->qdev.type = scsiid.scsi_type;
503
    DPRINTF("device type %d\n", s->qdev.type);
504
    if (s->qdev.type == TYPE_TAPE) {
505
        s->qdev.blocksize = get_stream_blocksize(s->bs);
506
        if (s->qdev.blocksize == -1)
507
            s->qdev.blocksize = 0;
508
    } else {
509
        s->qdev.blocksize = get_blocksize(s->bs);
510
        /* removable media returns 0 if not present */
511
        if (s->qdev.blocksize <= 0) {
512
            if (s->qdev.type == TYPE_ROM || s->qdev.type  == TYPE_WORM)
513
                s->qdev.blocksize = 2048;
514
            else
515
                s->qdev.blocksize = 512;
516
        }
517
    }
518
    DPRINTF("block size %d\n", s->qdev.blocksize);
519
    s->driver_status = 0;
520
    memset(s->sensebuf, 0, sizeof(s->sensebuf));
521
    bdrv_set_removable(s->bs, 0);
522
    return 0;
523
}
524

    
525
static SCSIDeviceInfo scsi_generic_info = {
526
    .qdev.name    = "scsi-generic",
527
    .qdev.desc    = "pass through generic scsi device (/dev/sg*)",
528
    .qdev.size    = sizeof(SCSIGenericState),
529
    .qdev.reset   = scsi_generic_reset,
530
    .init         = scsi_generic_initfn,
531
    .destroy      = scsi_destroy,
532
    .alloc_req    = scsi_new_request,
533
    .free_req     = scsi_free_request,
534
    .send_command = scsi_send_command,
535
    .read_data    = scsi_read_data,
536
    .write_data   = scsi_write_data,
537
    .cancel_io    = scsi_cancel_io,
538
    .get_buf      = scsi_get_buf,
539
    .qdev.props   = (Property[]) {
540
        DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
541
        DEFINE_PROP_END_OF_LIST(),
542
    },
543
};
544

    
545
static void scsi_generic_register_devices(void)
546
{
547
    scsi_qdev_register(&scsi_generic_info);
548
}
549
device_init(scsi_generic_register_devices)
550

    
551
#endif /* __linux__ */