Statistics
| Branch: | Revision:

root / hw / scsi-generic.c @ baaa86d9

History | View | Annotate | Download (13.1 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
};
64

    
65
static void scsi_free_request(SCSIRequest *req)
66
{
67
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
68

    
69
    g_free(r->buf);
70
}
71

    
72
/* Helper function for command completion.  */
73
static void scsi_command_complete(void *opaque, int ret)
74
{
75
    int status;
76
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
77

    
78
    r->req.aiocb = NULL;
79
    if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE)
80
        r->req.sense_len = r->io_header.sb_len_wr;
81

    
82
    if (ret != 0) {
83
        switch (ret) {
84
        case -EDOM:
85
            status = TASK_SET_FULL;
86
            break;
87
        case -ENOMEM:
88
            status = CHECK_CONDITION;
89
            scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));
90
            break;
91
        default:
92
            status = CHECK_CONDITION;
93
            scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR));
94
            break;
95
        }
96
    } else {
97
        if (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT) {
98
            status = BUSY;
99
            BADF("Driver Timeout\n");
100
        } else if (r->io_header.status) {
101
            status = r->io_header.status;
102
        } else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
103
            status = CHECK_CONDITION;
104
        } else {
105
            status = GOOD;
106
        }
107
    }
108
    DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
109
            r, r->req.tag, status);
110

    
111
    scsi_req_complete(&r->req, status);
112
}
113

    
114
/* Cancel a pending data transfer.  */
115
static void scsi_cancel_io(SCSIRequest *req)
116
{
117
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
118

    
119
    DPRINTF("Cancel tag=0x%x\n", req->tag);
120
    if (r->req.aiocb) {
121
        bdrv_aio_cancel(r->req.aiocb);
122
    }
123
    r->req.aiocb = NULL;
124
}
125

    
126
static int execute_command(BlockDriverState *bdrv,
127
                           SCSIGenericReq *r, int direction,
128
                           BlockDriverCompletionFunc *complete)
129
{
130
    r->io_header.interface_id = 'S';
131
    r->io_header.dxfer_direction = direction;
132
    r->io_header.dxferp = r->buf;
133
    r->io_header.dxfer_len = r->buflen;
134
    r->io_header.cmdp = r->req.cmd.buf;
135
    r->io_header.cmd_len = r->req.cmd.len;
136
    r->io_header.mx_sb_len = sizeof(r->req.sense);
137
    r->io_header.sbp = r->req.sense;
138
    r->io_header.timeout = MAX_UINT;
139
    r->io_header.usr_ptr = r;
140
    r->io_header.flags |= SG_FLAG_DIRECT_IO;
141

    
142
    r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
143
    if (r->req.aiocb == NULL) {
144
        BADF("execute_command: read failed !\n");
145
        return -ENOMEM;
146
    }
147

    
148
    return 0;
149
}
150

    
151
static void scsi_read_complete(void * opaque, int ret)
152
{
153
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
154
    int len;
155

    
156
    r->req.aiocb = NULL;
157
    if (ret) {
158
        DPRINTF("IO error ret %d\n", ret);
159
        scsi_command_complete(r, ret);
160
        return;
161
    }
162
    len = r->io_header.dxfer_len - r->io_header.resid;
163
    DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
164

    
165
    r->len = -1;
166
    if (len == 0) {
167
        scsi_command_complete(r, 0);
168
    } else {
169
        scsi_req_data(&r->req, len);
170
    }
171
}
172

    
173
/* Read more data from scsi device into buffer.  */
174
static void scsi_read_data(SCSIRequest *req)
175
{
176
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
177
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
178
    int ret;
179

    
180
    DPRINTF("scsi_read_data 0x%x\n", req->tag);
181
    if (r->len == -1) {
182
        scsi_command_complete(r, 0);
183
        return;
184
    }
185

    
186
    ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
187
    if (ret < 0) {
188
        scsi_command_complete(r, ret);
189
        return;
190
    }
191
}
192

    
193
static void scsi_write_complete(void * opaque, int ret)
194
{
195
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
196
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
197

    
198
    DPRINTF("scsi_write_complete() ret = %d\n", ret);
199
    r->req.aiocb = NULL;
200
    if (ret) {
201
        DPRINTF("IO error\n");
202
        scsi_command_complete(r, ret);
203
        return;
204
    }
205

    
206
    if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
207
        s->qdev.type == TYPE_TAPE) {
208
        s->qdev.blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
209
        DPRINTF("block size %d\n", s->qdev.blocksize);
210
    }
211

    
212
    scsi_command_complete(r, ret);
213
}
214

    
215
/* Write data to a scsi device.  Returns nonzero on failure.
216
   The transfer may complete asynchronously.  */
217
static void scsi_write_data(SCSIRequest *req)
218
{
219
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
220
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
221
    int ret;
222

    
223
    DPRINTF("scsi_write_data 0x%x\n", req->tag);
224
    if (r->len == 0) {
225
        r->len = r->buflen;
226
        scsi_req_data(&r->req, r->len);
227
        return;
228
    }
229

    
230
    ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
231
    if (ret < 0) {
232
        scsi_command_complete(r, ret);
233
    }
234
}
235

    
236
/* Return a pointer to the data buffer.  */
237
static uint8_t *scsi_get_buf(SCSIRequest *req)
238
{
239
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
240

    
241
    return r->buf;
242
}
243

    
244
static void scsi_req_fixup(SCSIRequest *req)
245
{
246
    switch(req->cmd.buf[0]) {
247
    case WRITE_10:
248
        req->cmd.buf[1] &= ~0x08;        /* disable FUA */
249
        break;
250
    case READ_10:
251
        req->cmd.buf[1] &= ~0x08;        /* disable FUA */
252
        break;
253
    case REWIND:
254
    case START_STOP:
255
        if (req->dev->type == TYPE_TAPE) {
256
            /* force IMMED, otherwise qemu waits end of command */
257
            req->cmd.buf[1] = 0x01;
258
        }
259
        break;
260
    }
261
}
262

    
263
/* Execute a scsi command.  Returns the length of the data expected by the
264
   command.  This will be Positive for data transfers from the device
265
   (eg. disk reads), negative for transfers to the device (eg. disk writes),
266
   and zero if the command does not transfer any data.  */
267

    
268
static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
269
{
270
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
271
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
272
    int ret;
273

    
274
    scsi_req_fixup(&r->req);
275

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

    
279
#ifdef DEBUG_SCSI
280
    {
281
        int i;
282
        for (i = 1; i < r->req.cmd.len; i++) {
283
            printf(" 0x%02x", cmd[i]);
284
        }
285
        printf("\n");
286
    }
287
#endif
288

    
289
    if (r->req.cmd.xfer == 0) {
290
        if (r->buf != NULL)
291
            g_free(r->buf);
292
        r->buflen = 0;
293
        r->buf = NULL;
294
        ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
295
        if (ret < 0) {
296
            scsi_command_complete(r, ret);
297
            return 0;
298
        }
299
        return 0;
300
    }
301

    
302
    if (r->buflen != r->req.cmd.xfer) {
303
        if (r->buf != NULL)
304
            g_free(r->buf);
305
        r->buf = g_malloc(r->req.cmd.xfer);
306
        r->buflen = r->req.cmd.xfer;
307
    }
308

    
309
    memset(r->buf, 0, r->buflen);
310
    r->len = r->req.cmd.xfer;
311
    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
312
        r->len = 0;
313
        return -r->req.cmd.xfer;
314
    } else {
315
        return r->req.cmd.xfer;
316
    }
317
}
318

    
319
static int get_blocksize(BlockDriverState *bdrv)
320
{
321
    uint8_t cmd[10];
322
    uint8_t buf[8];
323
    uint8_t sensebuf[8];
324
    sg_io_hdr_t io_header;
325
    int ret;
326

    
327
    memset(cmd, 0, sizeof(cmd));
328
    memset(buf, 0, sizeof(buf));
329
    cmd[0] = READ_CAPACITY_10;
330

    
331
    memset(&io_header, 0, sizeof(io_header));
332
    io_header.interface_id = 'S';
333
    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
334
    io_header.dxfer_len = sizeof(buf);
335
    io_header.dxferp = buf;
336
    io_header.cmdp = cmd;
337
    io_header.cmd_len = sizeof(cmd);
338
    io_header.mx_sb_len = sizeof(sensebuf);
339
    io_header.sbp = sensebuf;
340
    io_header.timeout = 6000; /* XXX */
341

    
342
    ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
343
    if (ret < 0)
344
        return -1;
345

    
346
    return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
347
}
348

    
349
static int get_stream_blocksize(BlockDriverState *bdrv)
350
{
351
    uint8_t cmd[6];
352
    uint8_t buf[12];
353
    uint8_t sensebuf[8];
354
    sg_io_hdr_t io_header;
355
    int ret;
356

    
357
    memset(cmd, 0, sizeof(cmd));
358
    memset(buf, 0, sizeof(buf));
359
    cmd[0] = MODE_SENSE;
360
    cmd[4] = sizeof(buf);
361

    
362
    memset(&io_header, 0, sizeof(io_header));
363
    io_header.interface_id = 'S';
364
    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
365
    io_header.dxfer_len = sizeof(buf);
366
    io_header.dxferp = buf;
367
    io_header.cmdp = cmd;
368
    io_header.cmd_len = sizeof(cmd);
369
    io_header.mx_sb_len = sizeof(sensebuf);
370
    io_header.sbp = sensebuf;
371
    io_header.timeout = 6000; /* XXX */
372

    
373
    ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
374
    if (ret < 0)
375
        return -1;
376

    
377
    return (buf[9] << 16) | (buf[10] << 8) | buf[11];
378
}
379

    
380
static void scsi_generic_reset(DeviceState *dev)
381
{
382
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev);
383

    
384
    scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET));
385
}
386

    
387
static void scsi_destroy(SCSIDevice *d)
388
{
389
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
390

    
391
    scsi_device_purge_requests(&s->qdev, SENSE_CODE(NO_SENSE));
392
    blockdev_mark_auto_del(s->qdev.conf.bs);
393
}
394

    
395
static int scsi_generic_initfn(SCSIDevice *dev)
396
{
397
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
398
    int sg_version;
399
    struct sg_scsi_id scsiid;
400

    
401
    if (!s->qdev.conf.bs) {
402
        error_report("scsi-generic: drive property not set");
403
        return -1;
404
    }
405
    s->bs = s->qdev.conf.bs;
406

    
407
    /* check we are really using a /dev/sg* file */
408
    if (!bdrv_is_sg(s->bs)) {
409
        error_report("scsi-generic: not /dev/sg*");
410
        return -1;
411
    }
412

    
413
    if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
414
        error_report("Device doesn't support drive option werror");
415
        return -1;
416
    }
417
    if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
418
        error_report("Device doesn't support drive option rerror");
419
        return -1;
420
    }
421

    
422
    /* check we are using a driver managing SG_IO (version 3 and after */
423
    if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
424
        sg_version < 30000) {
425
        error_report("scsi-generic: scsi generic interface too old");
426
        return -1;
427
    }
428

    
429
    /* get LUN of the /dev/sg? */
430
    if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
431
        error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
432
        return -1;
433
    }
434

    
435
    /* define device state */
436
    s->qdev.type = scsiid.scsi_type;
437
    DPRINTF("device type %d\n", s->qdev.type);
438
    if (s->qdev.type == TYPE_TAPE) {
439
        s->qdev.blocksize = get_stream_blocksize(s->bs);
440
        if (s->qdev.blocksize == -1)
441
            s->qdev.blocksize = 0;
442
    } else {
443
        s->qdev.blocksize = get_blocksize(s->bs);
444
        /* removable media returns 0 if not present */
445
        if (s->qdev.blocksize <= 0) {
446
            if (s->qdev.type == TYPE_ROM || s->qdev.type  == TYPE_WORM)
447
                s->qdev.blocksize = 2048;
448
            else
449
                s->qdev.blocksize = 512;
450
        }
451
    }
452
    DPRINTF("block size %d\n", s->qdev.blocksize);
453
    bdrv_set_removable(s->bs, 0);
454
    return 0;
455
}
456

    
457
static SCSIReqOps scsi_generic_req_ops = {
458
    .size         = sizeof(SCSIGenericReq),
459
    .free_req     = scsi_free_request,
460
    .send_command = scsi_send_command,
461
    .read_data    = scsi_read_data,
462
    .write_data   = scsi_write_data,
463
    .cancel_io    = scsi_cancel_io,
464
    .get_buf      = scsi_get_buf,
465
};
466

    
467
static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
468
                                     void *hba_private)
469
{
470
    SCSIRequest *req;
471

    
472
    req = scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
473
    return req;
474
}
475

    
476
static SCSIDeviceInfo scsi_generic_info = {
477
    .qdev.name    = "scsi-generic",
478
    .qdev.desc    = "pass through generic scsi device (/dev/sg*)",
479
    .qdev.size    = sizeof(SCSIGenericState),
480
    .qdev.reset   = scsi_generic_reset,
481
    .init         = scsi_generic_initfn,
482
    .destroy      = scsi_destroy,
483
    .alloc_req    = scsi_new_request,
484
    .qdev.props   = (Property[]) {
485
        DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
486
        DEFINE_PROP_END_OF_LIST(),
487
    },
488
};
489

    
490
static void scsi_generic_register_devices(void)
491
{
492
    scsi_qdev_register(&scsi_generic_info);
493
}
494
device_init(scsi_generic_register_devices)
495

    
496
#endif /* __linux__ */