Statistics
| Branch: | Revision:

root / hw / scsi-generic.c @ 37e828b4

History | View | Annotate | Download (15.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 licenced under the LGPL.
11
 *
12
 */
13

    
14
#include "qemu-common.h"
15
#include "block.h"
16
#include "scsi-disk.h"
17

    
18
#ifndef __linux__
19

    
20
SCSIDevice *scsi_generic_init(BlockDriverState *bdrv, int tcq,
21
                              scsi_completionfn completion, void *opaque)
22
{
23
    return NULL;
24
}
25

    
26
#else /* __linux__ */
27

    
28
//#define DEBUG_SCSI
29

    
30
#ifdef DEBUG_SCSI
31
#define DPRINTF(fmt, args...) \
32
do { printf("scsi-generic: " fmt , ##args); } while (0)
33
#else
34
#define DPRINTF(fmt, args...) do {} while(0)
35
#endif
36

    
37
#define BADF(fmt, args...) \
38
do { fprintf(stderr, "scsi-generic: " fmt , ##args); } while (0)
39

    
40
#include <stdio.h>
41
#include <sys/types.h>
42
#include <sys/stat.h>
43
#include <unistd.h>
44
#include <scsi/sg.h>
45
#include <scsi/scsi.h>
46

    
47
#define LOAD_UNLOAD 0xa6
48
#define SET_CD_SPEED 0xbb
49
#define BLANK 0xa1
50

    
51
#define SCSI_CMD_BUF_SIZE     16
52
#define SCSI_SENSE_BUF_SIZE 32
53

    
54
#define SG_ERR_DRIVER_TIMEOUT 0x06
55
#define SG_ERR_DRIVER_SENSE 0x08
56

    
57
#ifndef MAX_UINT
58
#define MAX_UINT ((unsigned int)-1)
59
#endif
60

    
61
typedef struct SCSIRequest {
62
    BlockDriverAIOCB *aiocb;
63
    struct SCSIRequest *next;
64
    SCSIDeviceState *dev;
65
    uint32_t tag;
66
    uint8_t cmd[SCSI_CMD_BUF_SIZE];
67
    int cmdlen;
68
    uint8_t *buf;
69
    int buflen;
70
    int len;
71
    sg_io_hdr_t io_header;
72
} SCSIRequest;
73

    
74
struct SCSIDeviceState
75
{
76
    SCSIRequest *requests;
77
    BlockDriverState *bdrv;
78
    int blocksize;
79
    int lun;
80
    scsi_completionfn completion;
81
    void *opaque;
82
    int driver_status;
83
    uint8_t sensebuf[SCSI_SENSE_BUF_SIZE];
84
};
85

    
86
/* Global pool of SCSIRequest structures.  */
87
static SCSIRequest *free_requests = NULL;
88

    
89
static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag)
90
{
91
    SCSIRequest *r;
92

    
93
    if (free_requests) {
94
        r = free_requests;
95
        free_requests = r->next;
96
    } else {
97
        r = qemu_malloc(sizeof(SCSIRequest));
98
        r->buf = NULL;
99
        r->buflen = 0;
100
    }
101
    r->dev = s;
102
    r->tag = tag;
103
    memset(r->cmd, 0, sizeof(r->cmd));
104
    memset(&r->io_header, 0, sizeof(r->io_header));
105
    r->cmdlen = 0;
106
    r->len = 0;
107
    r->aiocb = NULL;
108

    
109
    /* link */
110

    
111
    r->next = s->requests;
112
    s->requests = r;
113
    return r;
114
}
115

    
116
static void scsi_remove_request(SCSIRequest *r)
117
{
118
    SCSIRequest *last;
119
    SCSIDeviceState *s = r->dev;
120

    
121
    if (s->requests == r) {
122
        s->requests = r->next;
123
    } else {
124
        last = s->requests;
125
        while (last && last->next != r)
126
            last = last->next;
127
        if (last) {
128
            last->next = r->next;
129
        } else {
130
            BADF("Orphaned request\n");
131
        }
132
    }
133
    r->next = free_requests;
134
    free_requests = r;
135
}
136

    
137
static SCSIRequest *scsi_find_request(SCSIDeviceState *s, uint32_t tag)
138
{
139
    SCSIRequest *r;
140

    
141
    r = s->requests;
142
    while (r && r->tag != tag)
143
        r = r->next;
144

    
145
    return r;
146
}
147

    
148
/* Helper function for command completion.  */
149
static void scsi_command_complete(void *opaque, int ret)
150
{
151
    SCSIRequest *r = (SCSIRequest *)opaque;
152
    SCSIDeviceState *s = r->dev;
153
    uint32_t tag;
154
    int sense;
155

    
156
    s->driver_status = r->io_header.driver_status;
157
    if (ret != 0)
158
        sense = HARDWARE_ERROR;
159
    else {
160
        if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
161
            sense = HARDWARE_ERROR;
162
            BADF("Driver Timeout\n");
163
        } else if ((s->driver_status & SG_ERR_DRIVER_SENSE) == 0)
164
            sense = NO_SENSE;
165
        else
166
            sense = s->sensebuf[2] & 0x0f;
167
    }
168

    
169
    DPRINTF("Command complete 0x%p tag=0x%x sense=%d\n", r, r->tag, sense);
170
    tag = r->tag;
171
    scsi_remove_request(r);
172
    s->completion(s->opaque, SCSI_REASON_DONE, tag, sense);
173
}
174

    
175
/* Cancel a pending data transfer.  */
176
static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
177
{
178
    DPRINTF("scsi_cancel_io 0x%x\n", tag);
179
    SCSIDeviceState *s = d->state;
180
    SCSIRequest *r;
181
    DPRINTF("Cancel tag=0x%x\n", tag);
182
    r = scsi_find_request(s, tag);
183
    if (r) {
184
        if (r->aiocb)
185
            bdrv_aio_cancel(r->aiocb);
186
        r->aiocb = NULL;
187
        scsi_remove_request(r);
188
    }
189
}
190

    
191
static int execute_command(BlockDriverState *bdrv,
192
                           SCSIRequest *r, int direction,
193
                           BlockDriverCompletionFunc *complete)
194
{
195

    
196
    r->io_header.interface_id = 'S';
197
    r->io_header.dxfer_direction = direction;
198
    r->io_header.dxferp = r->buf;
199
    r->io_header.dxfer_len = r->buflen;
200
    r->io_header.cmdp = r->cmd;
201
    r->io_header.cmd_len = r->cmdlen;
202
    r->io_header.mx_sb_len = sizeof(r->dev->sensebuf);
203
    r->io_header.sbp = r->dev->sensebuf;
204
    r->io_header.timeout = MAX_UINT;
205
    r->io_header.usr_ptr = r;
206
    r->io_header.flags |= SG_FLAG_DIRECT_IO;
207

    
208
    if (bdrv_pwrite(bdrv, -1, &r->io_header, sizeof(r->io_header)) == -1) {
209
        BADF("execute_command: write failed ! (%d)\n", errno);
210
        return -1;
211
    }
212
    if (complete == NULL) {
213
        int ret;
214
        r->aiocb = NULL;
215
        while ((ret = bdrv_pread(bdrv, -1, &r->io_header,
216
                                           sizeof(r->io_header))) == -1 &&
217
                      errno == EINTR);
218
        if (ret == -1) {
219
            BADF("execute_command: read failed !\n");
220
            return -1;
221
        }
222
        return 0;
223
    }
224

    
225
    r->aiocb = bdrv_aio_read(bdrv, 0, (uint8_t*)&r->io_header,
226
                          -(int64_t)sizeof(r->io_header), complete, r);
227
    if (r->aiocb == NULL) {
228
        BADF("execute_command: read failed !\n");
229
        return -1;
230
    }
231

    
232
    return 0;
233
}
234

    
235
static void scsi_read_complete(void * opaque, int ret)
236
{
237
    SCSIRequest *r = (SCSIRequest *)opaque;
238
    SCSIDeviceState *s = r->dev;
239
    int len;
240

    
241
    if (ret) {
242
        DPRINTF("IO error\n");
243
        scsi_command_complete(r, ret);
244
        return;
245
    }
246
    len = r->io_header.dxfer_len - r->io_header.resid;
247
    DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, len);
248

    
249
    r->len = -1;
250
    s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len);
251
}
252

    
253
/* Read more data from scsi device into buffer.  */
254
static void scsi_read_data(SCSIDevice *d, uint32_t tag)
255
{
256
    SCSIDeviceState *s = d->state;
257
    SCSIRequest *r;
258
    int ret;
259

    
260
    DPRINTF("scsi_read_data 0x%x\n", tag);
261
    r = scsi_find_request(s, tag);
262
    if (!r) {
263
        BADF("Bad read tag 0x%x\n", tag);
264
        /* ??? This is the wrong error.  */
265
        scsi_command_complete(r, -EINVAL);
266
        return;
267
    }
268

    
269
    if (r->len == -1) {
270
        scsi_command_complete(r, 0);
271
        return;
272
    }
273

    
274
    if (r->cmd[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
275
    {
276
        memcpy(r->buf, s->sensebuf, 16);
277
        r->io_header.driver_status = 0;
278
        r->len = -1;
279
        s->completion(s->opaque, SCSI_REASON_DATA, r->tag, 16);
280
        return;
281
    }
282

    
283
    ret = execute_command(s->bdrv, r, SG_DXFER_FROM_DEV, scsi_read_complete);
284
    if (ret == -1) {
285
        scsi_command_complete(r, -EINVAL);
286
        return;
287
    }
288
}
289

    
290
static void scsi_write_complete(void * opaque, int ret)
291
{
292
    SCSIRequest *r = (SCSIRequest *)opaque;
293

    
294
    DPRINTF("scsi_write_complete() ret = %d\n", ret);
295
    if (ret) {
296
        DPRINTF("IO error\n");
297
        scsi_command_complete(r, ret);
298
        return;
299
    }
300

    
301
    scsi_command_complete(r, ret);
302
}
303

    
304
/* Write data to a scsi device.  Returns nonzero on failure.
305
   The transfer may complete asynchronously.  */
306
static int scsi_write_data(SCSIDevice *d, uint32_t tag)
307
{
308
    SCSIDeviceState *s = d->state;
309
    SCSIRequest *r;
310
    int ret;
311

    
312
    DPRINTF("scsi_write_data 0x%x\n", tag);
313
    r = scsi_find_request(s, tag);
314
    if (!r) {
315
        BADF("Bad write tag 0x%x\n", tag);
316
        /* ??? This is the wrong error.  */
317
        scsi_command_complete(r, -EINVAL);
318
        return 0;
319
    }
320

    
321
    if (r->len == 0) {
322
        r->len = r->buflen;
323
        s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->len);
324
        return 0;
325
    }
326

    
327
    ret = execute_command(s->bdrv, r, SG_DXFER_TO_DEV, scsi_write_complete);
328
    if (ret == -1) {
329
        scsi_command_complete(r, -EINVAL);
330
        return 1;
331
    }
332

    
333
    return 0;
334
}
335

    
336
/* Return a pointer to the data buffer.  */
337
static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
338
{
339
    SCSIDeviceState *s = d->state;
340
    SCSIRequest *r;
341
    r = scsi_find_request(s, tag);
342
    if (!r) {
343
        BADF("Bad buffer tag 0x%x\n", tag);
344
        return NULL;
345
    }
346
    return r->buf;
347
}
348

    
349
static int scsi_length(uint8_t *cmd, int blocksize, int *cmdlen, uint32_t *len)
350
{
351
    switch (cmd[0] >> 5) {
352
    case 0:
353
        *len = cmd[4];
354
        *cmdlen = 6;
355
        break;
356
    case 1:
357
    case 2:
358
        *len = cmd[8] | (cmd[7] << 8);
359
        *cmdlen = 10;
360
        break;
361
    case 4:
362
        *len = cmd[13] | (cmd[12] << 8) | (cmd[11] << 16) | (cmd[10] << 24);
363
        *cmdlen = 16;
364
        break;
365
    case 5:
366
        *len = cmd[9] | (cmd[8] << 8) | (cmd[7] << 16) | (cmd[6] << 24);
367
        *cmdlen = 12;
368
        break;
369
    default:
370
        return -1;
371
    }
372

    
373
    switch(cmd[0]) {
374
    case TEST_UNIT_READY:
375
    case REZERO_UNIT:
376
    case START_STOP:
377
    case SEEK_6:
378
    case WRITE_FILEMARKS:
379
    case SPACE:
380
    case ERASE:
381
    case ALLOW_MEDIUM_REMOVAL:
382
    case VERIFY:
383
    case SEEK_10:
384
    case SYNCHRONIZE_CACHE:
385
    case LOCK_UNLOCK_CACHE:
386
    case LOAD_UNLOAD:
387
    case SET_CD_SPEED:
388
    case SET_LIMITS:
389
    case WRITE_LONG:
390
    case MOVE_MEDIUM:
391
    case UPDATE_BLOCK:
392
        *len = 0;
393
        break;
394
    case MODE_SENSE:
395
        break;
396
    case WRITE_SAME:
397
        *len = 1;
398
        break;
399
    case READ_CAPACITY:
400
        *len = 8;
401
        break;
402
    case READ_BLOCK_LIMITS:
403
        *len = 6;
404
        break;
405
    case READ_POSITION:
406
        *len = 20;
407
        break;
408
    case SEND_VOLUME_TAG:
409
        *len *= 40;
410
        break;
411
    case MEDIUM_SCAN:
412
        *len *= 8;
413
        break;
414
    case WRITE_10:
415
        cmd[1] &= ~0x08;        /* disable FUA */
416
    case WRITE_VERIFY:
417
    case WRITE_6:
418
    case WRITE_12:
419
    case WRITE_VERIFY_12:
420
        *len *= blocksize;
421
        break;
422
    case READ_10:
423
        cmd[1] &= ~0x08;        /* disable FUA */
424
    case READ_6:
425
    case READ_REVERSE:
426
    case RECOVER_BUFFERED_DATA:
427
    case READ_12:
428
        *len *= blocksize;
429
        break;
430
    }
431
    return 0;
432
}
433

    
434
static int is_write(int command)
435
{
436
    switch (command) {
437
    case COPY:
438
    case COPY_VERIFY:
439
    case COMPARE:
440
    case CHANGE_DEFINITION:
441
    case LOG_SELECT:
442
    case MODE_SELECT:
443
    case MODE_SELECT_10:
444
    case SEND_DIAGNOSTIC:
445
    case WRITE_BUFFER:
446
    case FORMAT_UNIT:
447
    case REASSIGN_BLOCKS:
448
    case RESERVE:
449
    case SEARCH_EQUAL:
450
    case SEARCH_HIGH:
451
    case SEARCH_LOW:
452
    case WRITE_6:
453
    case WRITE_10:
454
    case WRITE_VERIFY:
455
    case UPDATE_BLOCK:
456
    case WRITE_LONG:
457
    case WRITE_SAME:
458
    case SEARCH_HIGH_12:
459
    case SEARCH_EQUAL_12:
460
    case SEARCH_LOW_12:
461
    case WRITE_12:
462
    case WRITE_VERIFY_12:
463
    case SET_WINDOW:
464
    case MEDIUM_SCAN:
465
    case SEND_VOLUME_TAG:
466
    case WRITE_LONG_2:
467
        return 1;
468
    }
469
    return 0;
470
}
471

    
472
/* Execute a scsi command.  Returns the length of the data expected by the
473
   command.  This will be Positive for data transfers from the device
474
   (eg. disk reads), negative for transfers to the device (eg. disk writes),
475
   and zero if the command does not transfer any data.  */
476

    
477
static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
478
                                 uint8_t *cmd, int lun)
479
{
480
    SCSIDeviceState *s = d->state;
481
    uint32_t len=0;
482
    int cmdlen=0;
483
    SCSIRequest *r;
484
    int ret;
485

    
486
    /* ??? Tags are not unique for different luns.  We only implement a
487
       single lun, so this should not matter.  */
488

    
489
    if (lun != s->lun || (cmd[1] >> 5) != s->lun) {
490
        DPRINTF("Unimplemented LUN %d\n", lun ? lun : cmd[1] >> 5);
491
        s->completion(s->opaque, SCSI_REASON_DONE, tag, ILLEGAL_REQUEST);
492
        return 0;
493
    }
494

    
495
    if (scsi_length(cmd, s->blocksize, &cmdlen, &len) == -1) {
496
        BADF("Unsupported command length, command %x\n", cmd[0]);
497
        return 0;
498
    }
499

    
500
    DPRINTF("Command: lun=%d tag=0x%x data=0x%02x len %d\n", lun, tag,
501
            cmd[0], len);
502

    
503
    r = scsi_find_request(s, tag);
504
    if (r) {
505
        BADF("Tag 0x%x already in use %p\n", tag, r);
506
        scsi_cancel_io(d, tag);
507
    }
508
    r = scsi_new_request(s, tag);
509

    
510
    memcpy(r->cmd, cmd, cmdlen);
511
    r->cmdlen = cmdlen;
512

    
513
    if (len == 0) {
514
        if (r->buf != NULL)
515
            free(r->buf);
516
        r->buflen = 0;
517
        r->buf = NULL;
518
        ret = execute_command(s->bdrv, r, SG_DXFER_NONE, scsi_command_complete);
519
        if (ret == -1) {
520
            scsi_command_complete(r, -EINVAL);
521
            return 0;
522
        }
523
        return 0;
524
    }
525

    
526
    if (r->buflen != len) {
527
        if (r->buf != NULL)
528
            free(r->buf);
529
        r->buf = qemu_malloc(len);
530
        r->buflen = len;
531
    }
532

    
533
    memset(r->buf, 0, r->buflen);
534
    r->len = len;
535
    if (is_write(cmd[0])) {
536
        r->len = 0;
537
        return -len;
538
    }
539

    
540
    return len;
541
}
542

    
543
static int get_blocksize(BlockDriverState *bdrv)
544
{
545
    uint8_t cmd[10];
546
    uint8_t buf[8];
547
    uint8_t sensebuf[8];
548
    sg_io_hdr_t io_header;
549
    int ret;
550

    
551
    memset(cmd, sizeof(cmd), 0);
552
    memset(buf, sizeof(buf), 0);
553
    cmd[0] = READ_CAPACITY;
554

    
555
    memset(&io_header, 0, sizeof(io_header));
556
    io_header.interface_id = 'S';
557
    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
558
    io_header.dxfer_len = sizeof(buf);
559
    io_header.dxferp = buf;
560
    io_header.cmdp = cmd;
561
    io_header.cmd_len = sizeof(cmd);
562
    io_header.mx_sb_len = sizeof(sensebuf);
563
    io_header.sbp = sensebuf;
564
    io_header.timeout = 6000; /* XXX */
565

    
566
    ret = bdrv_pwrite(bdrv, -1, &io_header, sizeof(io_header));
567
    if (ret == -1)
568
        return -1;
569

    
570
    while ((ret = bdrv_pread(bdrv, -1, &io_header, sizeof(io_header))) == -1 &&
571
           errno == EINTR);
572

    
573
    if (ret == -1)
574
        return -1;
575

    
576
    return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
577
}
578

    
579
static void scsi_destroy(SCSIDevice *d)
580
{
581
    SCSIRequest *r, *n;
582

    
583
    r = d->state->requests;
584
    while (r) {
585
        n = r->next;
586
        qemu_free(r);
587
        r = n;
588
    }
589

    
590
    r = free_requests;
591
    while (r) {
592
        n = r->next;
593
        qemu_free(r);
594
        r = n;
595
    }
596

    
597
    qemu_free(d->state);
598
    qemu_free(d);
599
}
600

    
601
SCSIDevice *scsi_generic_init(BlockDriverState *bdrv, int tcq,
602
                              scsi_completionfn completion, void *opaque)
603
{
604
    int sg_version;
605
    SCSIDevice *d;
606
    SCSIDeviceState *s;
607
    struct sg_scsi_id scsiid;
608

    
609
    /* check we are really using a /dev/sg* file */
610

    
611
    if (!bdrv_is_sg(bdrv))
612
        return NULL;
613

    
614
    /* check we are using a driver managing SG_IO (version 3 and after */
615

    
616
    if (bdrv_ioctl(bdrv, SG_GET_VERSION_NUM, &sg_version) < 0 ||
617
        sg_version < 30000)
618
        return NULL;
619

    
620
    /* get LUN of the /dev/sg? */
621

    
622
    if (bdrv_ioctl(bdrv, SG_GET_SCSI_ID, &scsiid))
623
        return NULL;
624

    
625
    /* define device state */
626

    
627
    s = (SCSIDeviceState *)qemu_mallocz(sizeof(SCSIDeviceState));
628
    s->bdrv = bdrv;
629
    s->requests = NULL;
630
    s->completion = completion;
631
    s->opaque = opaque;
632
    s->lun = scsiid.lun;
633
    s->blocksize = get_blocksize(s->bdrv);
634
    s->driver_status = 0;
635
    memset(s->sensebuf, 0, sizeof(s->sensebuf));
636
    /* removable media returns 0 if not present */
637
    if (s->blocksize <= 0)
638
        s->blocksize = 2048;
639

    
640
    /* define function to manage device */
641

    
642
    d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
643
    d->state = s;
644
    d->destroy = scsi_destroy;
645
    d->send_command = scsi_send_command;
646
    d->read_data = scsi_read_data;
647
    d->write_data = scsi_write_data;
648
    d->cancel_io = scsi_cancel_io;
649
    d->get_buf = scsi_get_buf;
650

    
651
    return d;
652
}
653
#endif /* __linux__ */