Statistics
| Branch: | Revision:

root / hw / scsi-generic.c @ fc4f0754

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
550
#endif /* __linux__ */