Statistics
| Branch: | Revision:

root / hw / scsi-generic.c @ c5bf71a9

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
                                     void *hba_private)
101
{
102
    SCSIRequest *req;
103

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

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

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

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

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

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

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

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

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

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

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

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

    
197
    return 0;
198
}
199

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

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

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

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

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

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

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

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

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

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

    
279
    scsi_command_complete(r, ret);
280
}
281

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

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

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

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

    
308
    return r->buf;
309
}
310

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

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

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

    
341
    if (cmd[0] != REQUEST_SENSE && req->lun != s->lun) {
342
        DPRINTF("Unimplemented LUN %d\n", req->lun);
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__ */