Statistics
| Branch: | Revision:

root / hw / scsi-generic.c @ b45ef674

History | View | Annotate | Download (14.3 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 licensed 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
};
65

    
66
static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
67
                                     void *hba_private)
68
{
69
    SCSIRequest *req;
70

    
71
    req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun, hba_private);
72
    return req;
73
}
74

    
75
static void scsi_free_request(SCSIRequest *req)
76
{
77
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
78

    
79
    qemu_free(r->buf);
80
}
81

    
82
/* Helper function for command completion.  */
83
static void scsi_command_complete(void *opaque, int ret)
84
{
85
    int status;
86
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
87

    
88
    r->req.aiocb = NULL;
89
    if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE)
90
        r->req.sense_len = r->io_header.sb_len_wr;
91

    
92
    if (ret != 0) {
93
        switch (ret) {
94
        case -EDOM:
95
            status = TASK_SET_FULL;
96
            break;
97
        case -EINVAL:
98
            status = CHECK_CONDITION;
99
            scsi_req_build_sense(&r->req, SENSE_CODE(INVALID_FIELD));
100
            break;
101
        case -ENOMEM:
102
            status = CHECK_CONDITION;
103
            scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));
104
            break;
105
        default:
106
            status = CHECK_CONDITION;
107
            scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR));
108
            break;
109
        }
110
    } else {
111
        if (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT) {
112
            status = BUSY;
113
            BADF("Driver Timeout\n");
114
        } else if (r->io_header.status) {
115
            status = r->io_header.status;
116
        } else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
117
            status = CHECK_CONDITION;
118
        } else {
119
            status = GOOD;
120
        }
121
    }
122
    DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
123
            r, r->req.tag, status);
124

    
125
    scsi_req_complete(&r->req, status);
126
}
127

    
128
/* Cancel a pending data transfer.  */
129
static void scsi_cancel_io(SCSIRequest *req)
130
{
131
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
132

    
133
    DPRINTF("Cancel tag=0x%x\n", req->tag);
134
    if (r->req.aiocb) {
135
        bdrv_aio_cancel(r->req.aiocb);
136
    }
137
    r->req.aiocb = NULL;
138
}
139

    
140
static int execute_command(BlockDriverState *bdrv,
141
                           SCSIGenericReq *r, int direction,
142
                           BlockDriverCompletionFunc *complete)
143
{
144
    r->io_header.interface_id = 'S';
145
    r->io_header.dxfer_direction = direction;
146
    r->io_header.dxferp = r->buf;
147
    r->io_header.dxfer_len = r->buflen;
148
    r->io_header.cmdp = r->req.cmd.buf;
149
    r->io_header.cmd_len = r->req.cmd.len;
150
    r->io_header.mx_sb_len = sizeof(r->req.sense);
151
    r->io_header.sbp = r->req.sense;
152
    r->io_header.timeout = MAX_UINT;
153
    r->io_header.usr_ptr = r;
154
    r->io_header.flags |= SG_FLAG_DIRECT_IO;
155

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

    
162
    return 0;
163
}
164

    
165
static void scsi_read_complete(void * opaque, int ret)
166
{
167
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
168
    int len;
169

    
170
    r->req.aiocb = NULL;
171
    if (ret) {
172
        DPRINTF("IO error ret %d\n", ret);
173
        scsi_command_complete(r, ret);
174
        return;
175
    }
176
    len = r->io_header.dxfer_len - r->io_header.resid;
177
    DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
178

    
179
    r->len = -1;
180
    if (len == 0) {
181
        scsi_command_complete(r, 0);
182
    } else {
183
        scsi_req_data(&r->req, len);
184
    }
185
}
186

    
187
/* Read more data from scsi device into buffer.  */
188
static void scsi_read_data(SCSIRequest *req)
189
{
190
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
191
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
192
    int ret;
193

    
194
    DPRINTF("scsi_read_data 0x%x\n", req->tag);
195
    if (r->len == -1) {
196
        scsi_command_complete(r, 0);
197
        return;
198
    }
199

    
200
    if (r->req.cmd.buf[0] == REQUEST_SENSE) {
201
        r->io_header.driver_status = 0;
202
        r->io_header.status = 0;
203
        r->io_header.dxfer_len =
204
            scsi_device_get_sense(&s->qdev, r->buf, r->req.cmd.xfer,
205
                                  (r->req.cmd.buf[1] & 1) == 0);
206
        r->len = -1;
207
        DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, r->io_header.dxfer_len);
208
        DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
209
                r->buf[0], r->buf[1], r->buf[2], r->buf[3],
210
                r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
211
        scsi_req_data(&r->req, r->io_header.dxfer_len);
212
        /* The sense buffer is cleared when we return GOOD */
213
        return;
214
    }
215

    
216
    ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
217
    if (ret < 0) {
218
        scsi_command_complete(r, ret);
219
        return;
220
    }
221
}
222

    
223
static void scsi_write_complete(void * opaque, int ret)
224
{
225
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
226
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
227

    
228
    DPRINTF("scsi_write_complete() ret = %d\n", ret);
229
    r->req.aiocb = NULL;
230
    if (ret) {
231
        DPRINTF("IO error\n");
232
        scsi_command_complete(r, ret);
233
        return;
234
    }
235

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

    
242
    scsi_command_complete(r, ret);
243
}
244

    
245
/* Write data to a scsi device.  Returns nonzero on failure.
246
   The transfer may complete asynchronously.  */
247
static void scsi_write_data(SCSIRequest *req)
248
{
249
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
250
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
251
    int ret;
252

    
253
    DPRINTF("scsi_write_data 0x%x\n", req->tag);
254
    if (r->len == 0) {
255
        r->len = r->buflen;
256
        scsi_req_data(&r->req, r->len);
257
        return;
258
    }
259

    
260
    ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
261
    if (ret < 0) {
262
        scsi_command_complete(r, ret);
263
    }
264
}
265

    
266
/* Return a pointer to the data buffer.  */
267
static uint8_t *scsi_get_buf(SCSIRequest *req)
268
{
269
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
270

    
271
    return r->buf;
272
}
273

    
274
static void scsi_req_fixup(SCSIRequest *req)
275
{
276
    switch(req->cmd.buf[0]) {
277
    case WRITE_10:
278
        req->cmd.buf[1] &= ~0x08;        /* disable FUA */
279
        break;
280
    case READ_10:
281
        req->cmd.buf[1] &= ~0x08;        /* disable FUA */
282
        break;
283
    case REWIND:
284
    case START_STOP:
285
        if (req->dev->type == TYPE_TAPE) {
286
            /* force IMMED, otherwise qemu waits end of command */
287
            req->cmd.buf[1] = 0x01;
288
        }
289
        break;
290
    }
291
}
292

    
293
/* Execute a scsi command.  Returns the length of the data expected by the
294
   command.  This will be Positive for data transfers from the device
295
   (eg. disk reads), negative for transfers to the device (eg. disk writes),
296
   and zero if the command does not transfer any data.  */
297

    
298
static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
299
{
300
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
301
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
302
    int ret;
303

    
304
    if (cmd[0] != REQUEST_SENSE && req->lun != s->lun) {
305
        DPRINTF("Unimplemented LUN %d\n", req->lun);
306
        scsi_req_build_sense(&r->req, SENSE_CODE(LUN_NOT_SUPPORTED));
307
        scsi_req_complete(&r->req, CHECK_CONDITION);
308
        return 0;
309
    }
310

    
311
    if (-1 == scsi_req_parse(&r->req, cmd)) {
312
        BADF("Unsupported command length, command %x\n", cmd[0]);
313
        scsi_command_complete(r, -EINVAL);
314
        return 0;
315
    }
316
    scsi_req_fixup(&r->req);
317

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

    
321
#ifdef DEBUG_SCSI
322
    {
323
        int i;
324
        for (i = 1; i < r->req.cmd.len; i++) {
325
            printf(" 0x%02x", cmd[i]);
326
        }
327
        printf("\n");
328
    }
329
#endif
330

    
331
    if (r->req.cmd.xfer == 0) {
332
        if (r->buf != NULL)
333
            qemu_free(r->buf);
334
        r->buflen = 0;
335
        r->buf = NULL;
336
        ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
337
        if (ret < 0) {
338
            scsi_command_complete(r, ret);
339
            return 0;
340
        }
341
        return 0;
342
    }
343

    
344
    if (r->buflen != r->req.cmd.xfer) {
345
        if (r->buf != NULL)
346
            qemu_free(r->buf);
347
        r->buf = qemu_malloc(r->req.cmd.xfer);
348
        r->buflen = r->req.cmd.xfer;
349
    }
350

    
351
    memset(r->buf, 0, r->buflen);
352
    r->len = r->req.cmd.xfer;
353
    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
354
        r->len = 0;
355
        return -r->req.cmd.xfer;
356
    } else {
357
        return r->req.cmd.xfer;
358
    }
359
}
360

    
361
static int get_blocksize(BlockDriverState *bdrv)
362
{
363
    uint8_t cmd[10];
364
    uint8_t buf[8];
365
    uint8_t sensebuf[8];
366
    sg_io_hdr_t io_header;
367
    int ret;
368

    
369
    memset(cmd, 0, sizeof(cmd));
370
    memset(buf, 0, sizeof(buf));
371
    cmd[0] = READ_CAPACITY_10;
372

    
373
    memset(&io_header, 0, sizeof(io_header));
374
    io_header.interface_id = 'S';
375
    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
376
    io_header.dxfer_len = sizeof(buf);
377
    io_header.dxferp = buf;
378
    io_header.cmdp = cmd;
379
    io_header.cmd_len = sizeof(cmd);
380
    io_header.mx_sb_len = sizeof(sensebuf);
381
    io_header.sbp = sensebuf;
382
    io_header.timeout = 6000; /* XXX */
383

    
384
    ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
385
    if (ret < 0)
386
        return -1;
387

    
388
    return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
389
}
390

    
391
static int get_stream_blocksize(BlockDriverState *bdrv)
392
{
393
    uint8_t cmd[6];
394
    uint8_t buf[12];
395
    uint8_t sensebuf[8];
396
    sg_io_hdr_t io_header;
397
    int ret;
398

    
399
    memset(cmd, 0, sizeof(cmd));
400
    memset(buf, 0, sizeof(buf));
401
    cmd[0] = MODE_SENSE;
402
    cmd[4] = sizeof(buf);
403

    
404
    memset(&io_header, 0, sizeof(io_header));
405
    io_header.interface_id = 'S';
406
    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
407
    io_header.dxfer_len = sizeof(buf);
408
    io_header.dxferp = buf;
409
    io_header.cmdp = cmd;
410
    io_header.cmd_len = sizeof(cmd);
411
    io_header.mx_sb_len = sizeof(sensebuf);
412
    io_header.sbp = sensebuf;
413
    io_header.timeout = 6000; /* XXX */
414

    
415
    ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
416
    if (ret < 0)
417
        return -1;
418

    
419
    return (buf[9] << 16) | (buf[10] << 8) | buf[11];
420
}
421

    
422
static void scsi_generic_reset(DeviceState *dev)
423
{
424
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev);
425

    
426
    scsi_device_purge_requests(&s->qdev);
427
}
428

    
429
static void scsi_destroy(SCSIDevice *d)
430
{
431
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
432

    
433
    scsi_device_purge_requests(&s->qdev);
434
    blockdev_mark_auto_del(s->qdev.conf.bs);
435
}
436

    
437
static int scsi_generic_initfn(SCSIDevice *dev)
438
{
439
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
440
    int sg_version;
441
    struct sg_scsi_id scsiid;
442

    
443
    if (!s->qdev.conf.bs) {
444
        error_report("scsi-generic: drive property not set");
445
        return -1;
446
    }
447
    s->bs = s->qdev.conf.bs;
448

    
449
    /* check we are really using a /dev/sg* file */
450
    if (!bdrv_is_sg(s->bs)) {
451
        error_report("scsi-generic: not /dev/sg*");
452
        return -1;
453
    }
454

    
455
    if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
456
        error_report("Device doesn't support drive option werror");
457
        return -1;
458
    }
459
    if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
460
        error_report("Device doesn't support drive option rerror");
461
        return -1;
462
    }
463

    
464
    /* check we are using a driver managing SG_IO (version 3 and after */
465
    if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
466
        sg_version < 30000) {
467
        error_report("scsi-generic: scsi generic interface too old");
468
        return -1;
469
    }
470

    
471
    /* get LUN of the /dev/sg? */
472
    if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
473
        error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
474
        return -1;
475
    }
476

    
477
    /* define device state */
478
    s->lun = scsiid.lun;
479
    DPRINTF("LUN %d\n", s->lun);
480
    s->qdev.type = scsiid.scsi_type;
481
    DPRINTF("device type %d\n", s->qdev.type);
482
    if (s->qdev.type == TYPE_TAPE) {
483
        s->qdev.blocksize = get_stream_blocksize(s->bs);
484
        if (s->qdev.blocksize == -1)
485
            s->qdev.blocksize = 0;
486
    } else {
487
        s->qdev.blocksize = get_blocksize(s->bs);
488
        /* removable media returns 0 if not present */
489
        if (s->qdev.blocksize <= 0) {
490
            if (s->qdev.type == TYPE_ROM || s->qdev.type  == TYPE_WORM)
491
                s->qdev.blocksize = 2048;
492
            else
493
                s->qdev.blocksize = 512;
494
        }
495
    }
496
    DPRINTF("block size %d\n", s->qdev.blocksize);
497
    bdrv_set_removable(s->bs, 0);
498
    return 0;
499
}
500

    
501
static SCSIDeviceInfo scsi_generic_info = {
502
    .qdev.name    = "scsi-generic",
503
    .qdev.desc    = "pass through generic scsi device (/dev/sg*)",
504
    .qdev.size    = sizeof(SCSIGenericState),
505
    .qdev.reset   = scsi_generic_reset,
506
    .init         = scsi_generic_initfn,
507
    .destroy      = scsi_destroy,
508
    .alloc_req    = scsi_new_request,
509
    .free_req     = scsi_free_request,
510
    .send_command = scsi_send_command,
511
    .read_data    = scsi_read_data,
512
    .write_data   = scsi_write_data,
513
    .cancel_io    = scsi_cancel_io,
514
    .get_buf      = scsi_get_buf,
515
    .qdev.props   = (Property[]) {
516
        DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
517
        DEFINE_PROP_END_OF_LIST(),
518
    },
519
};
520

    
521
static void scsi_generic_register_devices(void)
522
{
523
    scsi_qdev_register(&scsi_generic_info);
524
}
525
device_init(scsi_generic_register_devices)
526

    
527
#endif /* __linux__ */