Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 415403
Collapse All | Expand All

(-)qemu-kvm-1.0/default-configs/pci.mak (+1 lines)
Lines 1-5 Link Here
1
CONFIG_PCI=y
1
CONFIG_PCI=y
2
CONFIG_VIRTIO_PCI=y
2
CONFIG_VIRTIO_PCI=y
3
CONFIG_VIRTIO_SCSI=y
3
CONFIG_VIRTIO=y
4
CONFIG_VIRTIO=y
4
CONFIG_USB_UHCI=y
5
CONFIG_USB_UHCI=y
5
CONFIG_USB_OHCI=y
6
CONFIG_USB_OHCI=y
(-)qemu-kvm-1.0/default-configs/s390x-softmmu.mak (+1 lines)
Line 1 Link Here
1
CONFIG_VIRTIO=y
1
CONFIG_VIRTIO=y
2
CONFIG_VIRTIO_SCSI=y
(-)qemu-kvm-1.0/dma.h (-7 / +13 lines)
Lines 17-22 Link Here
17
17
18
typedef struct ScatterGatherEntry ScatterGatherEntry;
18
typedef struct ScatterGatherEntry ScatterGatherEntry;
19
19
20
struct QEMUSGList {
21
    ScatterGatherEntry *sg;
22
    int nsg;
23
    int nalloc;
24
    size_t size;
25
};
26
20
#if defined(TARGET_PHYS_ADDR_BITS)
27
#if defined(TARGET_PHYS_ADDR_BITS)
21
typedef target_phys_addr_t dma_addr_t;
28
typedef target_phys_addr_t dma_addr_t;
22
29
Lines 32-44 struct ScatterGatherEntry { Link Here
32
    dma_addr_t len;
39
    dma_addr_t len;
33
};
40
};
34
41
35
struct QEMUSGList {
36
    ScatterGatherEntry *sg;
37
    int nsg;
38
    int nalloc;
39
    dma_addr_t size;
40
};
41
42
void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint);
42
void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint);
43
void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len);
43
void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len);
44
void qemu_sglist_destroy(QEMUSGList *qsg);
44
void qemu_sglist_destroy(QEMUSGList *qsg);
Lines 58-61 BlockDriverAIOCB *dma_bdrv_read(BlockDri Link Here
58
BlockDriverAIOCB *dma_bdrv_write(BlockDriverState *bs,
58
BlockDriverAIOCB *dma_bdrv_write(BlockDriverState *bs,
59
                                 QEMUSGList *sg, uint64_t sector,
59
                                 QEMUSGList *sg, uint64_t sector,
60
                                 BlockDriverCompletionFunc *cb, void *opaque);
60
                                 BlockDriverCompletionFunc *cb, void *opaque);
61
uint64_t dma_buf_read(uint8_t *ptr, int32_t len, QEMUSGList *sg);
62
uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg);
63
64
void dma_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie,
65
                    QEMUSGList *sg, enum BlockAcctType type);
66
61
#endif
67
#endif
(-)qemu-kvm-1.0/dma-helpers.c (+36 lines)
Lines 196-198 BlockDriverAIOCB *dma_bdrv_write(BlockDr Link Here
196
{
196
{
197
    return dma_bdrv_io(bs, sg, sector, bdrv_aio_writev, cb, opaque, true);
197
    return dma_bdrv_io(bs, sg, sector, bdrv_aio_writev, cb, opaque, true);
198
}
198
}
199
200
201
static uint64_t dma_buf_rw(uint8_t *ptr, int32_t len, QEMUSGList *sg, bool to_dev)
202
{
203
    uint64_t resid;
204
    int sg_cur_index;
205
206
    resid = sg->size;
207
    sg_cur_index = 0;
208
    len = MIN(len, resid);
209
    while (len > 0) {
210
        ScatterGatherEntry entry = sg->sg[sg_cur_index++];
211
        cpu_physical_memory_rw(entry.base, ptr, MIN(len, entry.len), !to_dev);
212
        ptr += entry.len;
213
        len -= entry.len;
214
        resid -= entry.len;
215
    }
216
217
    return resid;
218
}
219
220
uint64_t dma_buf_read(uint8_t *ptr, int32_t len, QEMUSGList *sg)
221
{
222
    return dma_buf_rw(ptr, len, sg, 0);
223
}
224
225
uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg)
226
{
227
    return dma_buf_rw(ptr, len, sg, 1);
228
}
229
230
void dma_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie,
231
                    QEMUSGList *sg, enum BlockAcctType type)
232
{
233
    bdrv_acct_start(bs, cookie, sg->size, type);
234
}
(-)qemu-kvm-1.0/hw/esp.c (-1 / +2 lines)
Lines 389-395 static void esp_do_dma(ESPState *s) Link Here
389
    esp_dma_done(s);
389
    esp_dma_done(s);
390
}
390
}
391
391
392
static void esp_command_complete(SCSIRequest *req, uint32_t status)
392
static void esp_command_complete(SCSIRequest *req, uint32_t status,
393
                                 int32_t resid)
393
{
394
{
394
    ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent);
395
    ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent);
395
396
(-)qemu-kvm-1.0/hw/ide/ahci.c (-69 / +13 lines)
Lines 425-479 static void ahci_reg_init(AHCIState *s) Link Here
425
    }
425
    }
426
}
426
}
427
427
428
static uint32_t read_from_sglist(uint8_t *buffer, uint32_t len,
429
                                 QEMUSGList *sglist)
430
{
431
    uint32_t i = 0;
432
    uint32_t total = 0, once;
433
    ScatterGatherEntry *cur_prd;
434
    uint32_t sgcount;
435
436
    cur_prd = sglist->sg;
437
    sgcount = sglist->nsg;
438
    for (i = 0; len && sgcount; i++) {
439
        once = MIN(cur_prd->len, len);
440
        cpu_physical_memory_read(cur_prd->base, buffer, once);
441
        cur_prd++;
442
        sgcount--;
443
        len -= once;
444
        buffer += once;
445
        total += once;
446
    }
447
448
    return total;
449
}
450
451
static uint32_t write_to_sglist(uint8_t *buffer, uint32_t len,
452
                                QEMUSGList *sglist)
453
{
454
    uint32_t i = 0;
455
    uint32_t total = 0, once;
456
    ScatterGatherEntry *cur_prd;
457
    uint32_t sgcount;
458
459
    DPRINTF(-1, "total: 0x%x bytes\n", len);
460
461
    cur_prd = sglist->sg;
462
    sgcount = sglist->nsg;
463
    for (i = 0; len && sgcount; i++) {
464
        once = MIN(cur_prd->len, len);
465
        DPRINTF(-1, "write 0x%x bytes to 0x%lx\n", once, (long)cur_prd->base);
466
        cpu_physical_memory_write(cur_prd->base, buffer, once);
467
        cur_prd++;
468
        sgcount--;
469
        len -= once;
470
        buffer += once;
471
        total += once;
472
    }
473
474
    return total;
475
}
476
477
static void check_cmd(AHCIState *s, int port)
428
static void check_cmd(AHCIState *s, int port)
478
{
429
{
479
    AHCIPortRegs *pr = &s->dev[port].port_regs;
430
    AHCIPortRegs *pr = &s->dev[port].port_regs;
Lines 794-802 static void process_ncq_command(AHCIStat Link Here
794
            DPRINTF(port, "tag %d aio read %"PRId64"\n",
745
            DPRINTF(port, "tag %d aio read %"PRId64"\n",
795
                    ncq_tfs->tag, ncq_tfs->lba);
746
                    ncq_tfs->tag, ncq_tfs->lba);
796
747
797
            bdrv_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
748
            dma_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
798
                            (ncq_tfs->sector_count-1) * BDRV_SECTOR_SIZE,
749
                           &ncq_tfs->sglist, BDRV_ACCT_READ);
799
                            BDRV_ACCT_READ);
800
            ncq_tfs->aiocb = dma_bdrv_read(ncq_tfs->drive->port.ifs[0].bs,
750
            ncq_tfs->aiocb = dma_bdrv_read(ncq_tfs->drive->port.ifs[0].bs,
801
                                           &ncq_tfs->sglist, ncq_tfs->lba,
751
                                           &ncq_tfs->sglist, ncq_tfs->lba,
802
                                           ncq_cb, ncq_tfs);
752
                                           ncq_cb, ncq_tfs);
Lines 808-816 static void process_ncq_command(AHCIStat Link Here
808
            DPRINTF(port, "tag %d aio write %"PRId64"\n",
758
            DPRINTF(port, "tag %d aio write %"PRId64"\n",
809
                    ncq_tfs->tag, ncq_tfs->lba);
759
                    ncq_tfs->tag, ncq_tfs->lba);
810
760
811
            bdrv_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
761
            dma_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
812
                            (ncq_tfs->sector_count-1) * BDRV_SECTOR_SIZE,
762
                           &ncq_tfs->sglist, BDRV_ACCT_WRITE);
813
                            BDRV_ACCT_WRITE);
814
            ncq_tfs->aiocb = dma_bdrv_write(ncq_tfs->drive->port.ifs[0].bs,
763
            ncq_tfs->aiocb = dma_bdrv_write(ncq_tfs->drive->port.ifs[0].bs,
815
                                            &ncq_tfs->sglist, ncq_tfs->lba,
764
                                            &ncq_tfs->sglist, ncq_tfs->lba,
816
                                            ncq_cb, ncq_tfs);
765
                                            ncq_cb, ncq_tfs);
Lines 1015-1026 static int ahci_start_transfer(IDEDMA *d Link Here
1015
            is_write ? "writ" : "read", size, is_atapi ? "atapi" : "ata",
964
            is_write ? "writ" : "read", size, is_atapi ? "atapi" : "ata",
1016
            has_sglist ? "" : "o");
965
            has_sglist ? "" : "o");
1017
966
1018
    if (is_write && has_sglist && (s->data_ptr < s->data_end)) {
967
    if (has_sglist && size) {
1019
        read_from_sglist(s->data_ptr, size, &s->sg);
968
        if (is_write) {
1020
    }
969
            dma_buf_write(s->data_ptr, size, &s->sg);
1021
970
        } else {
1022
    if (!is_write && has_sglist && (s->data_ptr < s->data_end)) {
971
            dma_buf_read(s->data_ptr, size, &s->sg);
1023
        write_to_sglist(s->data_ptr, size, &s->sg);
972
        }
1024
    }
973
    }
1025
974
1026
    /* update number of transferred bytes */
975
    /* update number of transferred bytes */
Lines 1059-1072 static int ahci_dma_prepare_buf(IDEDMA * Link Here
1059
{
1008
{
1060
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
1009
    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
1061
    IDEState *s = &ad->port.ifs[0];
1010
    IDEState *s = &ad->port.ifs[0];
1062
    int i;
1063
1011
1064
    ahci_populate_sglist(ad, &s->sg);
1012
    ahci_populate_sglist(ad, &s->sg);
1065
1013
    s->io_buffer_size = s->sg.size;
1066
    s->io_buffer_size = 0;
1067
    for (i = 0; i < s->sg.nsg; i++) {
1068
        s->io_buffer_size += s->sg.sg[i].len;
1069
    }
1070
1014
1071
    DPRINTF(ad->port_no, "len=%#x\n", s->io_buffer_size);
1015
    DPRINTF(ad->port_no, "len=%#x\n", s->io_buffer_size);
1072
    return s->io_buffer_size != 0;
1016
    return s->io_buffer_size != 0;
Lines 1084-1092 static int ahci_dma_rw_buf(IDEDMA *dma, Link Here
1084
    }
1028
    }
1085
1029
1086
    if (is_write) {
1030
    if (is_write) {
1087
        write_to_sglist(p, l, &s->sg);
1031
        dma_buf_read(p, l, &s->sg);
1088
    } else {
1032
    } else {
1089
        read_from_sglist(p, l, &s->sg);
1033
        dma_buf_write(p, l, &s->sg);
1090
    }
1034
    }
1091
1035
1092
    /* update number of transferred bytes */
1036
    /* update number of transferred bytes */
(-)qemu-kvm-1.0/hw/lsi53c895a.c (-1 / +1 lines)
Lines 699-705 static int lsi_queue_req(LSIState *s, SC Link Here
699
}
699
}
700
700
701
 /* Callback to indicate that the SCSI layer has completed a command.  */
701
 /* Callback to indicate that the SCSI layer has completed a command.  */
702
static void lsi_command_complete(SCSIRequest *req, uint32_t status)
702
static void lsi_command_complete(SCSIRequest *req, uint32_t status, int32_t resid)
703
{
703
{
704
    LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
704
    LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
705
    int out;
705
    int out;
(-)qemu-kvm-1.0/hw/pci.h (+1 lines)
Lines 76-81 Link Here
76
#define PCI_DEVICE_ID_VIRTIO_BLOCK       0x1001
76
#define PCI_DEVICE_ID_VIRTIO_BLOCK       0x1001
77
#define PCI_DEVICE_ID_VIRTIO_BALLOON     0x1002
77
#define PCI_DEVICE_ID_VIRTIO_BALLOON     0x1002
78
#define PCI_DEVICE_ID_VIRTIO_CONSOLE     0x1003
78
#define PCI_DEVICE_ID_VIRTIO_CONSOLE     0x1003
79
#define PCI_DEVICE_ID_VIRTIO_SCSI        0x1004
79
80
80
#define FMT_PCIBUS                      PRIx64
81
#define FMT_PCIBUS                      PRIx64
81
82
(-)qemu-kvm-1.0/hw/s390-virtio-bus.c (+24 lines)
Lines 158-163 static int s390_virtio_serial_init(VirtI Link Here
158
    return r;
158
    return r;
159
}
159
}
160
160
161
static int s390_virtio_scsi_init(VirtIOS390Device *dev)
162
{
163
    VirtIODevice *vdev;
164
165
    vdev = virtio_scsi_init((DeviceState *)dev, &dev->scsi);
166
    if (!vdev) {
167
        return -1;
168
    }
169
170
    return s390_virtio_device_init(dev, vdev);
171
}
172
161
static uint64_t s390_virtio_device_vq_token(VirtIOS390Device *dev, int vq)
173
static uint64_t s390_virtio_device_vq_token(VirtIOS390Device *dev, int vq)
162
{
174
{
163
    ram_addr_t token_off;
175
    ram_addr_t token_off;
Lines 370-375 static VirtIOS390DeviceInfo s390_virtio_ Link Here
370
    },
382
    },
371
};
383
};
372
384
385
static VirtIOS390DeviceInfo s390_virtio_scsi = {
386
    .init = s390_virtio_scsi_init,
387
    .qdev.name = "virtio-scsi-s390",
388
    .qdev.alias = "virtio-scsi",
389
    .qdev.size = sizeof(VirtIOS390Device),
390
    .qdev.props = (Property[]) {
391
        DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOS390Device, host_features, scsi),
392
        DEFINE_PROP_END_OF_LIST(),
393
    },
394
};
395
373
static int s390_virtio_busdev_init(DeviceState *dev, DeviceInfo *info)
396
static int s390_virtio_busdev_init(DeviceState *dev, DeviceInfo *info)
374
{
397
{
375
    VirtIOS390DeviceInfo *_info = (VirtIOS390DeviceInfo *)info;
398
    VirtIOS390DeviceInfo *_info = (VirtIOS390DeviceInfo *)info;
Lines 392-397 static void s390_virtio_register(void) Link Here
392
    s390_virtio_bus_register_withprop(&s390_virtio_serial);
415
    s390_virtio_bus_register_withprop(&s390_virtio_serial);
393
    s390_virtio_bus_register_withprop(&s390_virtio_blk);
416
    s390_virtio_bus_register_withprop(&s390_virtio_blk);
394
    s390_virtio_bus_register_withprop(&s390_virtio_net);
417
    s390_virtio_bus_register_withprop(&s390_virtio_net);
418
    s390_virtio_bus_register_withprop(&s390_virtio_scsi);
395
}
419
}
396
device_init(s390_virtio_register);
420
device_init(s390_virtio_register);
397
421
(-)qemu-kvm-1.0/hw/s390-virtio-bus.h (+2 lines)
Lines 19-24 Link Here
19
19
20
#include "virtio-net.h"
20
#include "virtio-net.h"
21
#include "virtio-serial.h"
21
#include "virtio-serial.h"
22
#include "virtio-scsi.h"
22
23
23
#define VIRTIO_DEV_OFFS_TYPE		0	/* 8 bits */
24
#define VIRTIO_DEV_OFFS_TYPE		0	/* 8 bits */
24
#define VIRTIO_DEV_OFFS_NUM_VQ		1	/* 8 bits */
25
#define VIRTIO_DEV_OFFS_NUM_VQ		1	/* 8 bits */
Lines 47-52 typedef struct VirtIOS390Device { Link Here
47
    uint32_t host_features;
48
    uint32_t host_features;
48
    virtio_serial_conf serial;
49
    virtio_serial_conf serial;
49
    virtio_net_conf net;
50
    virtio_net_conf net;
51
    VirtIOSCSIConf scsi;
50
} VirtIOS390Device;
52
} VirtIOS390Device;
51
53
52
typedef struct VirtIOS390Bus {
54
typedef struct VirtIOS390Bus {
(-)qemu-kvm-1.0/hw/scsi-bus.c (-6 / +137 lines)
Lines 5-10 Link Here
5
#include "qdev.h"
5
#include "qdev.h"
6
#include "blockdev.h"
6
#include "blockdev.h"
7
#include "trace.h"
7
#include "trace.h"
8
#include "dma.h"
8
9
9
static char *scsibus_get_fw_dev_path(DeviceState *dev);
10
static char *scsibus_get_fw_dev_path(DeviceState *dev);
10
static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf);
11
static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf);
Lines 50-55 static void scsi_dma_restart_bh(void *op Link Here
50
                scsi_req_continue(req);
51
                scsi_req_continue(req);
51
                break;
52
                break;
52
            case SCSI_XFER_NONE:
53
            case SCSI_XFER_NONE:
54
                assert(!req->sg);
53
                scsi_req_dequeue(req);
55
                scsi_req_dequeue(req);
54
                scsi_req_enqueue(req);
56
                scsi_req_enqueue(req);
55
                break;
57
                break;
Lines 512-517 SCSIRequest *scsi_req_new(SCSIDevice *d, Link Here
512
    }
514
    }
513
515
514
    req->cmd = cmd;
516
    req->cmd = cmd;
517
    req->resid = req->cmd.xfer;
518
515
    switch (buf[0]) {
519
    switch (buf[0]) {
516
    case INQUIRY:
520
    case INQUIRY:
517
        trace_scsi_inquiry(d->id, lun, tag, cmd.buf[1], cmd.buf[2]);
521
        trace_scsi_inquiry(d->id, lun, tag, cmd.buf[1], cmd.buf[2]);
Lines 624-638 void scsi_req_build_sense(SCSIRequest *r Link Here
624
    req->sense_len = 18;
628
    req->sense_len = 18;
625
}
629
}
626
630
627
int32_t scsi_req_enqueue(SCSIRequest *req)
631
static void scsi_req_enqueue_internal(SCSIRequest *req)
628
{
632
{
629
    int32_t rc;
630
631
    assert(!req->enqueued);
633
    assert(!req->enqueued);
632
    scsi_req_ref(req);
634
    scsi_req_ref(req);
635
    if (req->bus->info->get_sg_list) {
636
        req->sg = req->bus->info->get_sg_list(req);
637
    } else {
638
        req->sg = NULL;
639
    }
633
    req->enqueued = true;
640
    req->enqueued = true;
634
    QTAILQ_INSERT_TAIL(&req->dev->requests, req, next);
641
    QTAILQ_INSERT_TAIL(&req->dev->requests, req, next);
642
}
643
644
int32_t scsi_req_enqueue(SCSIRequest *req)
645
{
646
    int32_t rc;
635
647
648
    assert (!req->retry);
649
    scsi_req_enqueue_internal(req);
636
    scsi_req_ref(req);
650
    scsi_req_ref(req);
637
    rc = req->ops->send_command(req, req->cmd.buf);
651
    rc = req->ops->send_command(req, req->cmd.buf);
638
    scsi_req_unref(req);
652
    scsi_req_unref(req);
Lines 1254-1265 void scsi_req_continue(SCSIRequest *req) Link Here
1254
   Once it completes, calling scsi_req_continue will restart I/O.  */
1268
   Once it completes, calling scsi_req_continue will restart I/O.  */
1255
void scsi_req_data(SCSIRequest *req, int len)
1269
void scsi_req_data(SCSIRequest *req, int len)
1256
{
1270
{
1271
    uint8_t *buf;
1257
    if (req->io_canceled) {
1272
    if (req->io_canceled) {
1258
        trace_scsi_req_data_canceled(req->dev->id, req->lun, req->tag, len);
1273
        trace_scsi_req_data_canceled(req->dev->id, req->lun, req->tag, len);
1259
    } else {
1274
        return;
1260
        trace_scsi_req_data(req->dev->id, req->lun, req->tag, len);
1275
    }
1276
    trace_scsi_req_data(req->dev->id, req->lun, req->tag, len);
1277
    assert(req->cmd.mode != SCSI_XFER_NONE);
1278
    if (!req->sg) {
1279
        req->resid -= len;
1261
        req->bus->info->transfer_data(req, len);
1280
        req->bus->info->transfer_data(req, len);
1281
        return;
1282
    }
1283
1284
    /* If the device calls scsi_req_data and the HBA specified a
1285
     * scatter/gather list, the transfer has to happen in a single
1286
     * step.  */
1287
    assert(!req->dma_started);
1288
    req->dma_started = true;
1289
1290
    buf = scsi_req_get_buf(req);
1291
    if (req->cmd.mode == SCSI_XFER_FROM_DEV) {
1292
        req->resid = dma_buf_read(buf, len, req->sg);
1293
    } else {
1294
        req->resid = dma_buf_write(buf, len, req->sg);
1262
    }
1295
    }
1296
    scsi_req_continue(req);
1263
}
1297
}
1264
1298
1265
void scsi_req_print(SCSIRequest *req)
1299
void scsi_req_print(SCSIRequest *req)
Lines 1318-1324 void scsi_req_complete(SCSIRequest *req, Link Here
1318
1352
1319
    scsi_req_ref(req);
1353
    scsi_req_ref(req);
1320
    scsi_req_dequeue(req);
1354
    scsi_req_dequeue(req);
1321
    req->bus->info->complete(req, req->status);
1355
    req->bus->info->complete(req, req->status, req->resid);
1322
    scsi_req_unref(req);
1356
    scsi_req_unref(req);
1323
}
1357
}
1324
1358
Lines 1393-1395 SCSIDevice *scsi_device_find(SCSIBus *bu Link Here
1393
    }
1427
    }
1394
    return target_dev;
1428
    return target_dev;
1395
}
1429
}
1430
1431
1432
/* SCSI request list.  For simplicity, pv points to the whole device */
1433
1434
static void put_scsi_requests(QEMUFile *f, void *pv, size_t size)
1435
{
1436
    SCSIDevice *s = pv;
1437
    SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, s->qdev.parent_bus);
1438
    SCSIRequest *req;
1439
1440
    QTAILQ_FOREACH(req, &s->requests, next) {
1441
        assert(!req->io_canceled);
1442
        assert(req->status == -1);
1443
        assert(req->retry);
1444
        assert(req->enqueued);
1445
1446
        qemu_put_sbyte(f, 1);
1447
        qemu_put_buffer(f, req->cmd.buf, sizeof(req->cmd.buf));
1448
        qemu_put_be32s(f, &req->tag);
1449
        qemu_put_be32s(f, &req->lun);
1450
        if (bus->info->save_request) {
1451
            bus->info->save_request(f, req);
1452
        }
1453
        if (req->ops->save_request) {
1454
            req->ops->save_request(f, req);
1455
        }
1456
    }
1457
    qemu_put_sbyte(f, 0);
1458
}
1459
1460
static int get_scsi_requests(QEMUFile *f, void *pv, size_t size)
1461
{
1462
    SCSIDevice *s = pv;
1463
    SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, s->qdev.parent_bus);
1464
1465
    while (qemu_get_sbyte(f)) {
1466
        uint8_t buf[SCSI_CMD_BUF_SIZE];
1467
        uint32_t tag;
1468
        uint32_t lun;
1469
        SCSIRequest *req;
1470
1471
        qemu_get_buffer(f, buf, sizeof(buf));
1472
        qemu_get_be32s(f, &tag);
1473
        qemu_get_be32s(f, &lun);
1474
        req = scsi_req_new(s, tag, lun, buf, NULL);
1475
        if (bus->info->load_request) {
1476
            req->hba_private = bus->info->load_request(f, req);
1477
        }
1478
        if (req->ops->load_request) {
1479
            req->ops->load_request(f, req);
1480
        }
1481
1482
        /* Just restart it later.  */
1483
        req->retry = true;
1484
        scsi_req_enqueue_internal(req);
1485
1486
        /* At this point, the request will be kept alive by the reference
1487
         * added by scsi_req_enqueue_internal, so we can release our reference.
1488
         * The HBA of course will add its own reference in the load_request
1489
         * callback if it needs to hold on the SCSIRequest.
1490
         */
1491
        scsi_req_unref(req);
1492
    }
1493
1494
    return 0;
1495
}
1496
1497
const VMStateInfo vmstate_info_scsi_requests = {
1498
    .name = "scsi-requests",
1499
    .get  = get_scsi_requests,
1500
    .put  = put_scsi_requests,
1501
};
1502
1503
const VMStateDescription vmstate_scsi_device = {
1504
    .name = "SCSIDevice",
1505
    .version_id = 1,
1506
    .minimum_version_id = 1,
1507
    .minimum_version_id_old = 1,
1508
    .fields = (VMStateField[]) {
1509
        VMSTATE_UINT8(unit_attention.key, SCSIDevice),
1510
        VMSTATE_UINT8(unit_attention.asc, SCSIDevice),
1511
        VMSTATE_UINT8(unit_attention.ascq, SCSIDevice),
1512
        VMSTATE_BOOL(sense_is_ua, SCSIDevice),
1513
        VMSTATE_UINT8_ARRAY(sense, SCSIDevice, SCSI_SENSE_BUF_SIZE),
1514
        VMSTATE_UINT32(sense_len, SCSIDevice),
1515
        {
1516
            .name         = "requests",
1517
            .version_id   = 0,
1518
            .field_exists = NULL,
1519
            .size         = 0,   /* ouch */
1520
            .info         = &vmstate_info_scsi_requests,
1521
            .flags        = VMS_SINGLE,
1522
            .offset       = 0,
1523
        },
1524
        VMSTATE_END_OF_LIST()
1525
    }
1526
};
(-)qemu-kvm-1.0/hw/scsi-disk.c (-19 / +107 lines)
Lines 38-43 do { fprintf(stderr, "scsi-disk: " fmt , Link Here
38
#include "sysemu.h"
38
#include "sysemu.h"
39
#include "blockdev.h"
39
#include "blockdev.h"
40
#include "block_int.h"
40
#include "block_int.h"
41
#include "dma.h"
41
42
42
#ifdef __linux
43
#ifdef __linux
43
#include <scsi/sg.h>
44
#include <scsi/sg.h>
Lines 110-121 static void scsi_cancel_io(SCSIRequest * Link Here
110
    r->req.aiocb = NULL;
111
    r->req.aiocb = NULL;
111
}
112
}
112
113
113
static uint32_t scsi_init_iovec(SCSIDiskReq *r)
114
static uint32_t scsi_init_iovec(SCSIDiskReq *r, size_t size)
114
{
115
{
115
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
116
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
116
117
117
    if (!r->iov.iov_base) {
118
    if (!r->iov.iov_base) {
118
        r->buflen = SCSI_DMA_BUF_SIZE;
119
        r->buflen = size;
119
        r->iov.iov_base = qemu_blockalign(s->qdev.conf.bs, r->buflen);
120
        r->iov.iov_base = qemu_blockalign(s->qdev.conf.bs, r->buflen);
120
    }
121
    }
121
    r->iov.iov_len = MIN(r->sector_count * 512, r->buflen);
122
    r->iov.iov_len = MIN(r->sector_count * 512, r->buflen);
Lines 123-128 static uint32_t scsi_init_iovec(SCSIDisk Link Here
123
    return r->qiov.size / 512;
124
    return r->qiov.size / 512;
124
}
125
}
125
126
127
static void scsi_disk_save_request(QEMUFile *f, SCSIRequest *req)
128
{
129
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
130
131
    qemu_put_be64s(f, &r->sector);
132
    qemu_put_be32s(f, &r->sector_count);
133
    qemu_put_be32s(f, &r->buflen);
134
    if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
135
        qemu_put_buffer(f, r->iov.iov_base, r->iov.iov_len);
136
    }
137
}
138
139
static void scsi_disk_load_request(QEMUFile *f, SCSIRequest *req)
140
{
141
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
142
143
    qemu_get_be64s(f, &r->sector);
144
    qemu_get_be32s(f, &r->sector_count);
145
    qemu_get_be32s(f, &r->buflen);
146
    if (r->buflen) {
147
        scsi_init_iovec(r, r->buflen);
148
        if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
149
            qemu_get_buffer(f, r->iov.iov_base, r->iov.iov_len);
150
        }
151
    }
152
153
    qemu_iovec_init_external(&r->qiov, &r->iov, 1);
154
}
155
156
static void scsi_dma_complete(void * opaque, int ret)
157
{
158
    SCSIDiskReq *r = (SCSIDiskReq *)opaque;
159
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
160
161
    bdrv_acct_done(s->qdev.conf.bs, &r->acct);
162
163
    if (ret) {
164
        if (scsi_handle_rw_error(r, -ret)) {
165
            goto done;
166
        }
167
    }
168
169
    r->sector += r->sector_count;
170
    r->sector_count = 0;
171
    scsi_req_complete(&r->req, GOOD);
172
173
done:
174
    scsi_req_unref(&r->req);
175
}
176
126
static void scsi_read_complete(void * opaque, int ret)
177
static void scsi_read_complete(void * opaque, int ret)
127
{
178
{
128
    SCSIDiskReq *r = (SCSIDiskReq *)opaque;
179
    SCSIDiskReq *r = (SCSIDiskReq *)opaque;
Lines 213-222 static void scsi_read_data(SCSIRequest * Link Here
213
        return;
264
        return;
214
    }
265
    }
215
266
216
    n = scsi_init_iovec(r);
267
    if (r->req.sg) {
217
    bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
268
        dma_acct_start(s->qdev.conf.bs, &r->acct, r->req.sg, BDRV_ACCT_READ);
218
    r->req.aiocb = bdrv_aio_readv(s->qdev.conf.bs, r->sector, &r->qiov, n,
269
	r->req.resid -= r->req.sg->size;
219
                              scsi_read_complete, r);
270
        r->req.aiocb = dma_bdrv_read(s->qdev.conf.bs, r->req.sg, r->sector,
271
                                     scsi_dma_complete, r);
272
    } else {
273
        n = scsi_init_iovec(r, SCSI_DMA_BUF_SIZE);
274
        bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
275
        r->req.aiocb = bdrv_aio_readv(s->qdev.conf.bs, r->sector, &r->qiov, n,
276
                                      scsi_read_complete, r);
277
    }
220
    if (r->req.aiocb == NULL) {
278
    if (r->req.aiocb == NULL) {
221
        scsi_read_complete(r, -EIO);
279
        scsi_read_complete(r, -EIO);
222
    }
280
    }
Lines 290-296 static void scsi_write_complete(void * o Link Here
290
    if (r->sector_count == 0) {
348
    if (r->sector_count == 0) {
291
        scsi_req_complete(&r->req, GOOD);
349
        scsi_req_complete(&r->req, GOOD);
292
    } else {
350
    } else {
293
        scsi_init_iovec(r);
351
        scsi_init_iovec(r, SCSI_DMA_BUF_SIZE);
294
        DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, r->qiov.size);
352
        DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, r->qiov.size);
295
        scsi_req_data(&r->req, r->qiov.size);
353
        scsi_req_data(&r->req, r->qiov.size);
296
    }
354
    }
Lines 318-338 static void scsi_write_data(SCSIRequest Link Here
318
        return;
376
        return;
319
    }
377
    }
320
378
321
    n = r->qiov.size / 512;
379
    if (!r->req.sg && !r->qiov.size) {
322
    if (n) {
380
        /* Called for the first time.  Ask the driver to send us more data.  */
323
        if (s->tray_open) {
381
        scsi_write_complete(r, 0);
324
            scsi_write_complete(r, -ENOMEDIUM);
382
        return;
325
            return;
383
    }
326
        }
384
    if (s->tray_open) {
385
        scsi_write_complete(r, -ENOMEDIUM);
386
        return;
387
    }
388
389
    if (r->req.sg) {
390
        dma_acct_start(s->qdev.conf.bs, &r->acct, r->req.sg, BDRV_ACCT_WRITE);
391
	r->req.resid -= r->req.sg->size;
392
        r->req.aiocb = dma_bdrv_write(s->qdev.conf.bs, r->req.sg, r->sector,
393
                                      scsi_dma_complete, r);
394
    } else {
395
        n = r->qiov.size / 512;
327
        bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE);
396
        bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE);
328
        r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, r->sector, &r->qiov, n,
397
        r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, r->sector, &r->qiov, n,
329
                                       scsi_write_complete, r);
398
                                       scsi_write_complete, r);
330
        if (r->req.aiocb == NULL) {
399
    }
331
            scsi_write_complete(r, -ENOMEM);
400
    if (r->req.aiocb == NULL) {
332
        }
401
        scsi_write_complete(r, -ENOMEM);
333
    } else {
334
        /* Called for the first time.  Ask the driver to send us more data.  */
335
        scsi_write_complete(r, 0);
336
    }
402
    }
337
}
403
}
338
404
Lines 1601-1606 static const SCSIReqOps scsi_disk_reqops Link Here
1601
    .write_data   = scsi_write_data,
1667
    .write_data   = scsi_write_data,
1602
    .cancel_io    = scsi_cancel_io,
1668
    .cancel_io    = scsi_cancel_io,
1603
    .get_buf      = scsi_get_buf,
1669
    .get_buf      = scsi_get_buf,
1670
    .load_request = scsi_disk_load_request,
1671
    .save_request = scsi_disk_save_request,
1604
};
1672
};
1605
1673
1606
static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
1674
static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
Lines 1729-1734 static SCSIRequest *scsi_block_new_reque Link Here
1729
    DEFINE_PROP_STRING("ver",  SCSIDiskState, version),         \
1797
    DEFINE_PROP_STRING("ver",  SCSIDiskState, version),         \
1730
    DEFINE_PROP_STRING("serial",  SCSIDiskState, serial)
1798
    DEFINE_PROP_STRING("serial",  SCSIDiskState, serial)
1731
1799
1800
static const VMStateDescription vmstate_scsi_disk_state = {
1801
    .name = "scsi-disk",
1802
    .version_id = 1,
1803
    .minimum_version_id = 1,
1804
    .minimum_version_id_old = 1,
1805
    .fields = (VMStateField[]) {
1806
        VMSTATE_SCSI_DEVICE(qdev, SCSIDiskState),
1807
        VMSTATE_BOOL(media_changed, SCSIDiskState),
1808
        VMSTATE_BOOL(media_event, SCSIDiskState),
1809
        VMSTATE_BOOL(eject_request, SCSIDiskState),
1810
        VMSTATE_BOOL(tray_open, SCSIDiskState),
1811
        VMSTATE_BOOL(tray_locked, SCSIDiskState),
1812
        VMSTATE_END_OF_LIST()
1813
    }
1814
};
1815
1732
static SCSIDeviceInfo scsi_disk_info[] = {
1816
static SCSIDeviceInfo scsi_disk_info[] = {
1733
    {
1817
    {
1734
        .qdev.name    = "scsi-hd",
1818
        .qdev.name    = "scsi-hd",
Lines 1736-1741 static SCSIDeviceInfo scsi_disk_info[] = Link Here
1736
        .qdev.desc    = "virtual SCSI disk",
1820
        .qdev.desc    = "virtual SCSI disk",
1737
        .qdev.size    = sizeof(SCSIDiskState),
1821
        .qdev.size    = sizeof(SCSIDiskState),
1738
        .qdev.reset   = scsi_disk_reset,
1822
        .qdev.reset   = scsi_disk_reset,
1823
        .qdev.vmsd    = &vmstate_scsi_disk_state,
1739
        .init         = scsi_hd_initfn,
1824
        .init         = scsi_hd_initfn,
1740
        .destroy      = scsi_destroy,
1825
        .destroy      = scsi_destroy,
1741
        .alloc_req    = scsi_new_request,
1826
        .alloc_req    = scsi_new_request,
Lines 1751-1756 static SCSIDeviceInfo scsi_disk_info[] = Link Here
1751
        .qdev.desc    = "virtual SCSI CD-ROM",
1836
        .qdev.desc    = "virtual SCSI CD-ROM",
1752
        .qdev.size    = sizeof(SCSIDiskState),
1837
        .qdev.size    = sizeof(SCSIDiskState),
1753
        .qdev.reset   = scsi_disk_reset,
1838
        .qdev.reset   = scsi_disk_reset,
1839
        .qdev.vmsd    = &vmstate_scsi_disk_state,
1754
        .init         = scsi_cd_initfn,
1840
        .init         = scsi_cd_initfn,
1755
        .destroy      = scsi_destroy,
1841
        .destroy      = scsi_destroy,
1756
        .alloc_req    = scsi_new_request,
1842
        .alloc_req    = scsi_new_request,
Lines 1766-1771 static SCSIDeviceInfo scsi_disk_info[] = Link Here
1766
        .qdev.desc    = "SCSI block device passthrough",
1852
        .qdev.desc    = "SCSI block device passthrough",
1767
        .qdev.size    = sizeof(SCSIDiskState),
1853
        .qdev.size    = sizeof(SCSIDiskState),
1768
        .qdev.reset   = scsi_disk_reset,
1854
        .qdev.reset   = scsi_disk_reset,
1855
        .qdev.vmsd    = &vmstate_scsi_disk_state,
1769
        .init         = scsi_block_initfn,
1856
        .init         = scsi_block_initfn,
1770
        .destroy      = scsi_destroy,
1857
        .destroy      = scsi_destroy,
1771
        .alloc_req    = scsi_block_new_request,
1858
        .alloc_req    = scsi_block_new_request,
Lines 1780-1785 static SCSIDeviceInfo scsi_disk_info[] = Link Here
1780
        .qdev.desc    = "virtual SCSI disk or CD-ROM (legacy)",
1867
        .qdev.desc    = "virtual SCSI disk or CD-ROM (legacy)",
1781
        .qdev.size    = sizeof(SCSIDiskState),
1868
        .qdev.size    = sizeof(SCSIDiskState),
1782
        .qdev.reset   = scsi_disk_reset,
1869
        .qdev.reset   = scsi_disk_reset,
1870
        .qdev.vmsd    = &vmstate_scsi_disk_state,
1783
        .init         = scsi_disk_initfn,
1871
        .init         = scsi_disk_initfn,
1784
        .destroy      = scsi_destroy,
1872
        .destroy      = scsi_destroy,
1785
        .alloc_req    = scsi_new_request,
1873
        .alloc_req    = scsi_new_request,
(-)qemu-kvm-1.0/hw/scsi-generic.c (+25 lines)
Lines 59-64 typedef struct SCSIGenericReq { Link Here
59
    sg_io_hdr_t io_header;
59
    sg_io_hdr_t io_header;
60
} SCSIGenericReq;
60
} SCSIGenericReq;
61
61
62
static void scsi_generic_save_request(QEMUFile *f, SCSIRequest *req)
63
{
64
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
65
66
    qemu_put_sbe32s(f, &r->buflen);
67
    if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
68
        assert(!r->req.sg);
69
        qemu_put_buffer(f, r->buf, r->req.cmd.xfer);
70
    }
71
}
72
73
static void scsi_generic_load_request(QEMUFile *f, SCSIRequest *req)
74
{
75
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
76
77
    qemu_get_sbe32s(f, &r->buflen);
78
    if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
79
        assert(!r->req.sg);
80
        qemu_get_buffer(f, r->buf, r->req.cmd.xfer);
81
    }
82
}
83
62
static void scsi_free_request(SCSIRequest *req)
84
static void scsi_free_request(SCSIRequest *req)
63
{
85
{
64
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
86
    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
Lines 450-455 const SCSIReqOps scsi_generic_req_ops = Link Here
450
    .write_data   = scsi_write_data,
472
    .write_data   = scsi_write_data,
451
    .cancel_io    = scsi_cancel_io,
473
    .cancel_io    = scsi_cancel_io,
452
    .get_buf      = scsi_get_buf,
474
    .get_buf      = scsi_get_buf,
475
    .load_request = scsi_generic_load_request,
476
    .save_request = scsi_generic_save_request,
453
};
477
};
454
478
455
static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
479
static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
Lines 467-472 static SCSIDeviceInfo scsi_generic_info Link Here
467
    .qdev.desc    = "pass through generic scsi device (/dev/sg*)",
491
    .qdev.desc    = "pass through generic scsi device (/dev/sg*)",
468
    .qdev.size    = sizeof(SCSIDevice),
492
    .qdev.size    = sizeof(SCSIDevice),
469
    .qdev.reset   = scsi_generic_reset,
493
    .qdev.reset   = scsi_generic_reset,
494
    .qdev.vmsd    = &vmstate_scsi_device,
470
    .init         = scsi_generic_initfn,
495
    .init         = scsi_generic_initfn,
471
    .destroy      = scsi_destroy,
496
    .destroy      = scsi_destroy,
472
    .alloc_req    = scsi_new_request,
497
    .alloc_req    = scsi_new_request,
(-)qemu-kvm-1.0/hw/scsi.h (-1 / +21 lines)
Lines 47-54 struct SCSIRequest { Link Here
47
    uint32_t          tag;
47
    uint32_t          tag;
48
    uint32_t          lun;
48
    uint32_t          lun;
49
    uint32_t          status;
49
    uint32_t          status;
50
    size_t            resid;
50
    SCSICommand       cmd;
51
    SCSICommand       cmd;
51
    BlockDriverAIOCB  *aiocb;
52
    BlockDriverAIOCB  *aiocb;
53
    QEMUSGList        *sg;
54
    bool              dma_started;
52
    uint8_t sense[SCSI_SENSE_BUF_SIZE];
55
    uint8_t sense[SCSI_SENSE_BUF_SIZE];
53
    uint32_t sense_len;
56
    uint32_t sense_len;
54
    bool enqueued;
57
    bool enqueued;
Lines 78-83 struct SCSIDevice Link Here
78
    uint64_t max_lba;
81
    uint64_t max_lba;
79
};
82
};
80
83
84
extern const VMStateDescription vmstate_scsi_device;
85
86
#define VMSTATE_SCSI_DEVICE(_field, _state) {                        \
87
    .name       = (stringify(_field)),                               \
88
    .size       = sizeof(SCSIDevice),                                \
89
    .vmsd       = &vmstate_scsi_device,                              \
90
    .flags      = VMS_STRUCT,                                        \
91
    .offset     = vmstate_offset_value(_state, _field, SCSIDevice),  \
92
}
93
81
/* cdrom.c */
94
/* cdrom.c */
82
int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
95
int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
83
int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num);
96
int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num);
Lines 91-96 struct SCSIReqOps { Link Here
91
    void (*write_data)(SCSIRequest *req);
104
    void (*write_data)(SCSIRequest *req);
92
    void (*cancel_io)(SCSIRequest *req);
105
    void (*cancel_io)(SCSIRequest *req);
93
    uint8_t *(*get_buf)(SCSIRequest *req);
106
    uint8_t *(*get_buf)(SCSIRequest *req);
107
108
    void (*save_request)(QEMUFile *f, SCSIRequest *req);
109
    void (*load_request)(QEMUFile *f, SCSIRequest *req);
94
};
110
};
95
111
96
typedef int (*scsi_qdev_initfn)(SCSIDevice *dev);
112
typedef int (*scsi_qdev_initfn)(SCSIDevice *dev);
Lines 107-114 struct SCSIBusInfo { Link Here
107
    int tcq;
123
    int tcq;
108
    int max_channel, max_target, max_lun;
124
    int max_channel, max_target, max_lun;
109
    void (*transfer_data)(SCSIRequest *req, uint32_t arg);
125
    void (*transfer_data)(SCSIRequest *req, uint32_t arg);
110
    void (*complete)(SCSIRequest *req, uint32_t arg);
126
    void (*complete)(SCSIRequest *req, uint32_t arg, int32_t len);
111
    void (*cancel)(SCSIRequest *req);
127
    void (*cancel)(SCSIRequest *req);
128
    QEMUSGList *(*get_sg_list)(SCSIRequest *req);
129
130
    void (*save_request)(QEMUFile *f, SCSIRequest *req);
131
    void *(*load_request)(QEMUFile *f, SCSIRequest *req);
112
};
132
};
113
133
114
struct SCSIBus {
134
struct SCSIBus {
(-)qemu-kvm-1.0/hw/spapr_vscsi.c (-1 / +1 lines)
Lines 494-500 static void vscsi_transfer_data(SCSIRequ Link Here
494
}
494
}
495
495
496
/* Callback to indicate that the SCSI layer has completed a transfer.  */
496
/* Callback to indicate that the SCSI layer has completed a transfer.  */
497
static void vscsi_command_complete(SCSIRequest *sreq, uint32_t status)
497
static void vscsi_command_complete(SCSIRequest *sreq, uint32_t status, int32_t resid)
498
{
498
{
499
    VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent);
499
    VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent);
500
    vscsi_req *req = sreq->hba_private;
500
    vscsi_req *req = sreq->hba_private;
(-)qemu-kvm-1.0/hw/usb-msd.c (-1 / +1 lines)
Lines 223-229 static void usb_msd_transfer_data(SCSIRe Link Here
223
    }
223
    }
224
}
224
}
225
225
226
static void usb_msd_command_complete(SCSIRequest *req, uint32_t status)
226
static void usb_msd_command_complete(SCSIRequest *req, uint32_t status, int32_t resid)
227
{
227
{
228
    MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
228
    MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
229
    USBPacket *p = s->packet;
229
    USBPacket *p = s->packet;
(-)qemu-kvm-1.0/hw/virtio.h (+3 lines)
Lines 199-204 VirtIODevice *virtio_net_init(DeviceStat Link Here
199
typedef struct virtio_serial_conf virtio_serial_conf;
199
typedef struct virtio_serial_conf virtio_serial_conf;
200
VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *serial);
200
VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *serial);
201
VirtIODevice *virtio_balloon_init(DeviceState *dev);
201
VirtIODevice *virtio_balloon_init(DeviceState *dev);
202
typedef struct VirtIOSCSIConf VirtIOSCSIConf;
203
VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *conf);
202
#ifdef CONFIG_LINUX
204
#ifdef CONFIG_LINUX
203
VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf);
205
VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf);
204
#endif
206
#endif
Lines 208-213 void virtio_net_exit(VirtIODevice *vdev) Link Here
208
void virtio_blk_exit(VirtIODevice *vdev);
210
void virtio_blk_exit(VirtIODevice *vdev);
209
void virtio_serial_exit(VirtIODevice *vdev);
211
void virtio_serial_exit(VirtIODevice *vdev);
210
void virtio_balloon_exit(VirtIODevice *vdev);
212
void virtio_balloon_exit(VirtIODevice *vdev);
213
void virtio_scsi_exit(VirtIODevice *vdev);
211
214
212
#define DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) \
215
#define DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) \
213
	DEFINE_PROP_BIT("indirect_desc", _state, _field, \
216
	DEFINE_PROP_BIT("indirect_desc", _state, _field, \
(-)qemu-kvm-1.0/hw/virtio-pci.c (+42 lines)
Lines 19-24 Link Here
19
#include "virtio-blk.h"
19
#include "virtio-blk.h"
20
#include "virtio-net.h"
20
#include "virtio-net.h"
21
#include "virtio-serial.h"
21
#include "virtio-serial.h"
22
#include "virtio-scsi.h"
22
#include "pci.h"
23
#include "pci.h"
23
#include "qemu-error.h"
24
#include "qemu-error.h"
24
#include "msix.h"
25
#include "msix.h"
Lines 855-860 static int virtio_balloon_exit_pci(PCIDe Link Here
855
    return virtio_exit_pci(pci_dev);
856
    return virtio_exit_pci(pci_dev);
856
}
857
}
857
858
859
static int virtio_scsi_init_pci(PCIDevice *pci_dev)
860
{
861
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
862
    VirtIODevice *vdev;
863
864
    vdev = virtio_scsi_init(&pci_dev->qdev, &proxy->scsi);
865
    if (!vdev) {
866
        return -EINVAL;
867
    }
868
869
    vdev->nvectors = proxy->nvectors;
870
    virtio_init_pci(proxy, vdev);
871
872
    /* make the actual value visible */
873
    proxy->nvectors = vdev->nvectors;
874
    return 0;
875
}
876
877
static int virtio_scsi_exit_pci(PCIDevice *pci_dev)
878
{
879
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
880
881
    virtio_scsi_exit(proxy->vdev);
882
    return virtio_exit_pci(pci_dev);
883
}
884
858
static PCIDeviceInfo virtio_info[] = {
885
static PCIDeviceInfo virtio_info[] = {
859
    {
886
    {
860
        .qdev.name = "virtio-blk-pci",
887
        .qdev.name = "virtio-blk-pci",
Lines 940-945 static PCIDeviceInfo virtio_info[] = { Link Here
940
        },
967
        },
941
        .qdev.reset = virtio_pci_reset,
968
        .qdev.reset = virtio_pci_reset,
942
    },{
969
    },{
970
        .qdev.name = "virtio-scsi-pci",
971
        .qdev.alias = "virtio-scsi",
972
        .qdev.size = sizeof(VirtIOPCIProxy),
973
        .init      = virtio_scsi_init_pci,
974
        .exit      = virtio_scsi_exit_pci,
975
        .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
976
        .device_id = PCI_DEVICE_ID_VIRTIO_SCSI,
977
        .class_id  = PCI_CLASS_STORAGE_SCSI,
978
        .revision  = 0x00,
979
        .qdev.props = (Property[]) {
980
            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
981
            DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOPCIProxy, host_features, scsi),
982
            DEFINE_PROP_END_OF_LIST(),
983
        },
984
    }, {
943
        /* end of list */
985
        /* end of list */
944
    }
986
    }
945
};
987
};
(-)qemu-kvm-1.0/hw/virtio-pci.h (+2 lines)
Lines 17-22 Link Here
17
17
18
#include "virtio-net.h"
18
#include "virtio-net.h"
19
#include "virtio-serial.h"
19
#include "virtio-serial.h"
20
#include "virtio-scsi.h"
20
21
21
/* Performance improves when virtqueue kick processing is decoupled from the
22
/* Performance improves when virtqueue kick processing is decoupled from the
22
 * vcpu thread using ioeventfd for some devices. */
23
 * vcpu thread using ioeventfd for some devices. */
Lines 40-45 typedef struct { Link Here
40
#endif
41
#endif
41
    virtio_serial_conf serial;
42
    virtio_serial_conf serial;
42
    virtio_net_conf net;
43
    virtio_net_conf net;
44
    VirtIOSCSIConf scsi;
43
    bool ioeventfd_disabled;
45
    bool ioeventfd_disabled;
44
    bool ioeventfd_started;
46
    bool ioeventfd_started;
45
} VirtIOPCIProxy;
47
} VirtIOPCIProxy;
(-)qemu-kvm-1.0/hw/virtio-scsi.c (+607 lines)
Line 0 Link Here
1
/*
2
 * Virtio SCSI HBA
3
 *
4
 * Copyright IBM, Corp. 2010
5
 * Copyright Red Hat, Inc. 2011
6
 *
7
 * Authors:
8
 *   Stefan Hajnoczi    <stefanha@linux.vnet.ibm.com>
9
 *   Paolo Bonzini      <pbonzini@redhat.com>
10
 *
11
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
12
 * See the COPYING file in the top-level directory.
13
 *
14
 */
15
16
#include "virtio-scsi.h"
17
#include <hw/scsi.h>
18
#include <hw/scsi-defs.h>
19
20
#define VIRTIO_SCSI_VQ_SIZE     128
21
#define VIRTIO_SCSI_CDB_SIZE    32
22
#define VIRTIO_SCSI_SENSE_SIZE  96
23
#define VIRTIO_SCSI_MAX_CHANNEL	0
24
#define VIRTIO_SCSI_MAX_TARGET  255
25
#define VIRTIO_SCSI_MAX_LUN     16383
26
27
/* Response codes */
28
#define VIRTIO_SCSI_S_OK                       0
29
#define VIRTIO_SCSI_S_OVERRUN                  1
30
#define VIRTIO_SCSI_S_ABORTED                  2
31
#define VIRTIO_SCSI_S_BAD_TARGET               3
32
#define VIRTIO_SCSI_S_RESET                    4
33
#define VIRTIO_SCSI_S_BUSY                     5
34
#define VIRTIO_SCSI_S_TRANSPORT_FAILURE        6
35
#define VIRTIO_SCSI_S_TARGET_FAILURE           7
36
#define VIRTIO_SCSI_S_NEXUS_FAILURE            8
37
#define VIRTIO_SCSI_S_FAILURE                  9
38
#define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED       10
39
#define VIRTIO_SCSI_S_FUNCTION_REJECTED        11
40
#define VIRTIO_SCSI_S_INCORRECT_LUN            12
41
42
/* Controlq type codes.  */
43
#define VIRTIO_SCSI_T_TMF                      0
44
#define VIRTIO_SCSI_T_AN_QUERY                 1
45
#define VIRTIO_SCSI_T_AN_SUBSCRIBE             2
46
47
/* Valid TMF subtypes.  */
48
#define VIRTIO_SCSI_T_TMF_ABORT_TASK           0
49
#define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET       1
50
#define VIRTIO_SCSI_T_TMF_CLEAR_ACA            2
51
#define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET       3
52
#define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET      4
53
#define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET   5
54
#define VIRTIO_SCSI_T_TMF_QUERY_TASK           6
55
#define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET       7
56
57
/* Events.  */
58
#define VIRTIO_SCSI_T_EVENTS_MISSED            0x80000000
59
#define VIRTIO_SCSI_T_NO_EVENT                 0
60
#define VIRTIO_SCSI_T_TRANSPORT_RESET          1
61
#define VIRTIO_SCSI_T_ASYNC_NOTIFY             2
62
63
/* SCSI command request, followed by data-out */
64
typedef struct {
65
    uint8_t lun[8];              /* Logical Unit Number */
66
    uint64_t tag;                /* Command identifier */
67
    uint8_t task_attr;           /* Task attribute */
68
    uint8_t prio;
69
    uint8_t crn;
70
    uint8_t cdb[];
71
} QEMU_PACKED VirtIOSCSICmdReq;
72
73
/* Response, followed by sense data and data-in */
74
typedef struct {
75
    uint32_t sense_len;          /* Sense data length */
76
    uint32_t resid;              /* Residual bytes in data buffer */
77
    uint16_t status_qualifier;   /* Status qualifier */
78
    uint8_t status;              /* Command completion status */
79
    uint8_t response;            /* Response values */
80
    uint8_t sense[];
81
} QEMU_PACKED VirtIOSCSICmdResp;
82
83
/* Task Management Request */
84
typedef struct {
85
    uint32_t type;
86
    uint32_t subtype;
87
    uint8_t lun[8];
88
    uint64_t tag;
89
} QEMU_PACKED VirtIOSCSICtrlTMFReq;
90
91
typedef struct {
92
    uint8_t response;
93
} QEMU_PACKED VirtIOSCSICtrlTMFResp;
94
95
/* Asynchronous notification query/subscription */
96
typedef struct {
97
    uint32_t type;
98
    uint8_t lun[8];
99
    uint32_t event_requested;
100
} QEMU_PACKED VirtIOSCSICtrlANReq;
101
102
typedef struct {
103
    uint32_t event_actual;
104
    uint8_t response;
105
} QEMU_PACKED VirtIOSCSICtrlANResp;
106
107
typedef struct {
108
    uint32_t event;
109
    uint8_t lun[8];
110
    uint32_t reason;
111
} QEMU_PACKED VirtIOSCSIEvent;
112
113
typedef struct {
114
    uint32_t num_queues;
115
    uint32_t seg_max;
116
    uint32_t max_sectors;
117
    uint32_t cmd_per_lun;
118
    uint32_t event_info_size;
119
    uint32_t sense_size;
120
    uint32_t cdb_size;
121
    uint16_t max_channel;
122
    uint16_t max_target;
123
    uint32_t max_lun;
124
} QEMU_PACKED VirtIOSCSIConfig;
125
126
typedef struct {
127
    VirtIODevice vdev;
128
    DeviceState *qdev;
129
    VirtIOSCSIConf *conf;
130
131
    SCSIBus bus;
132
    VirtQueue *ctrl_vq;
133
    VirtQueue *event_vq;
134
    VirtQueue *cmd_vq;
135
    uint32_t sense_size;
136
    uint32_t cdb_size;
137
    bool resetting;
138
} VirtIOSCSI;
139
140
typedef struct VirtIOSCSIReq {
141
    VirtIOSCSI *dev;
142
    VirtQueue *vq;
143
    VirtQueueElement elem;
144
    QEMUSGList qsgl;
145
    SCSIRequest *sreq;
146
    union {
147
        char                  *buf;
148
        VirtIOSCSICmdReq      *cmd;
149
        VirtIOSCSICtrlTMFReq  *tmf;
150
        VirtIOSCSICtrlANReq   *an;
151
    } req;
152
    union {
153
        char                  *buf;
154
        VirtIOSCSICmdResp     *cmd;
155
        VirtIOSCSICtrlTMFResp *tmf;
156
        VirtIOSCSICtrlANResp  *an;
157
        VirtIOSCSIEvent       *event;
158
    } resp;
159
} VirtIOSCSIReq;
160
161
static inline int virtio_scsi_get_lun(uint8_t *lun)
162
{
163
    return ((lun[2] << 8) | lun[3]) & 0x3FFF;
164
}
165
166
static inline SCSIDevice *virtio_scsi_device_find(VirtIOSCSI *s, uint8_t *lun)
167
{
168
    if (lun[0] != 1) {
169
        return NULL;
170
    }
171
    if (lun[2] != 0 && !(lun[2] >= 0x40 && lun[2] < 0x80)) {
172
        return NULL;
173
    }
174
    return scsi_device_find(&s->bus, 0, lun[1], virtio_scsi_get_lun(lun));
175
}
176
177
static void virtio_scsi_complete_req(VirtIOSCSIReq *req)
178
{
179
    VirtIOSCSI *s = req->dev;
180
    VirtQueue *vq = req->vq;
181
    virtqueue_push(vq, &req->elem, req->qsgl.size + req->elem.in_sg[0].iov_len);
182
    qemu_sglist_destroy(&req->qsgl);
183
    if (req->sreq) {
184
        req->sreq->hba_private = NULL;
185
        scsi_req_unref(req->sreq);
186
    }
187
    g_free(req);
188
    virtio_notify(&s->vdev, vq);
189
}
190
191
static void virtio_scsi_bad_req(void)
192
{
193
    error_report("wrong size for virtio-scsi headers");
194
    exit(1);
195
}
196
197
static void qemu_sgl_init_external(QEMUSGList *qsgl, struct iovec *sg,
198
                                   target_phys_addr_t *addr, int num)
199
{
200
    memset(qsgl, 0, sizeof(*qsgl));
201
    while (num--) {
202
        qemu_sglist_add(qsgl, *(addr++), (sg++)->iov_len);
203
    }
204
}
205
206
static void virtio_scsi_parse_req(VirtIOSCSI *s, VirtQueue *vq,
207
                                  VirtIOSCSIReq *req)
208
{
209
    assert(req->elem.out_num && req->elem.in_num);
210
    req->vq = vq;
211
    req->dev = s;
212
    req->sreq = NULL;
213
    req->req.buf = req->elem.out_sg[0].iov_base;
214
    req->resp.buf = req->elem.in_sg[0].iov_base;
215
216
    if (req->elem.out_num > 1) {
217
        qemu_sgl_init_external(&req->qsgl, &req->elem.out_sg[1],
218
                               &req->elem.out_addr[1],
219
                               req->elem.out_num - 1);
220
    } else {
221
        qemu_sgl_init_external(&req->qsgl, &req->elem.in_sg[1],
222
                               &req->elem.in_addr[1],
223
                               req->elem.in_num - 1);
224
    }
225
}
226
227
static VirtIOSCSIReq *virtio_scsi_pop_req(VirtIOSCSI *s, VirtQueue *vq)
228
{
229
    VirtIOSCSIReq *req;
230
    req = g_malloc(sizeof(*req));
231
    if (!virtqueue_pop(vq, &req->elem)) {
232
        g_free(req);
233
        return NULL;
234
    }
235
236
    virtio_scsi_parse_req(s, vq, req);
237
    return req;
238
}
239
240
static void virtio_scsi_save_request(QEMUFile *f, SCSIRequest *sreq)
241
{
242
    VirtIOSCSIReq *req = sreq->hba_private;
243
244
    qemu_put_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem));
245
}
246
247
static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq)
248
{
249
    SCSIBus *bus = sreq->bus;
250
    VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
251
    VirtIOSCSIReq *req;
252
253
    req = g_malloc(sizeof(*req));
254
    qemu_get_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem));
255
    virtio_scsi_parse_req(s, s->cmd_vq, req);
256
257
    scsi_req_ref(sreq);
258
    req->sreq = sreq;
259
    if (req->sreq->cmd.mode != SCSI_XFER_NONE) {
260
        int req_mode =
261
            (req->elem.in_num > 1 ? SCSI_XFER_FROM_DEV : SCSI_XFER_TO_DEV);
262
263
	assert (req->sreq->cmd.mode == req_mode);
264
    }
265
    return req;
266
}
267
268
static void virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
269
{
270
    SCSIDevice *d = virtio_scsi_device_find(s, req->req.cmd->lun);
271
    SCSIRequest *r, *next;
272
    DeviceState *qdev;
273
    int target;
274
275
    switch (req->req.tmf->subtype) {
276
    case VIRTIO_SCSI_T_TMF_ABORT_TASK:
277
    case VIRTIO_SCSI_T_TMF_QUERY_TASK:
278
        d = virtio_scsi_device_find(s, req->req.cmd->lun);
279
        if (!d) {
280
            goto fail;
281
        }
282
        if (d->lun != virtio_scsi_get_lun(req->req.cmd->lun)) {
283
            req->resp.tmf->response = VIRTIO_SCSI_S_INCORRECT_LUN;
284
            break;
285
        }
286
        QTAILQ_FOREACH_SAFE(r, &d->requests, next, next) {
287
            if (r->tag == req->req.cmd->tag) {
288
                break;
289
            }
290
        }
291
        if (r && r->hba_private) {
292
            if (req->req.tmf->subtype == VIRTIO_SCSI_T_TMF_ABORT_TASK) {
293
                scsi_req_cancel(r);
294
            }
295
            req->resp.tmf->response = VIRTIO_SCSI_S_FUNCTION_SUCCEEDED;
296
        } else {
297
            req->resp.tmf->response = VIRTIO_SCSI_S_OK;
298
        }
299
        break;
300
301
    case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET:
302
        d = virtio_scsi_device_find(s, req->req.cmd->lun);
303
        if (!d) {
304
            goto fail;
305
        }
306
        if (d->lun == virtio_scsi_get_lun(req->req.cmd->lun)) {
307
            s->resetting++;
308
            qdev_reset_all(&d->qdev);
309
            s->resetting--;
310
        }
311
        break;
312
313
    case VIRTIO_SCSI_T_TMF_ABORT_TASK_SET:
314
    case VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET:
315
    case VIRTIO_SCSI_T_TMF_QUERY_TASK_SET:
316
        d = virtio_scsi_device_find(s, req->req.cmd->lun);
317
        if (!d) {
318
            goto fail;
319
        }
320
        if (d->lun != virtio_scsi_get_lun(req->req.cmd->lun)) {
321
            req->resp.tmf->response = VIRTIO_SCSI_S_INCORRECT_LUN;
322
            break;
323
        }
324
        req->resp.tmf->response = VIRTIO_SCSI_S_OK;
325
        QTAILQ_FOREACH_SAFE(r, &d->requests, next, next) {
326
            if (r->hba_private) {
327
                if (req->req.tmf->subtype != VIRTIO_SCSI_T_TMF_QUERY_TASK) {
328
                    scsi_req_cancel(r);
329
                }
330
                req->resp.tmf->response = VIRTIO_SCSI_S_FUNCTION_SUCCEEDED;
331
            }
332
        }
333
        break;
334
335
    case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET:
336
        target = req->req.cmd->lun[1];
337
        s->resetting++;
338
        QTAILQ_FOREACH(qdev, &s->bus.qbus.children, sibling) {
339
             d = DO_UPCAST(SCSIDevice, qdev, qdev);
340
             if (d->channel == 0 && d->id == target) {
341
                qdev_reset_all(&d->qdev);
342
             }
343
        }
344
        s->resetting--;
345
        break;
346
347
    case VIRTIO_SCSI_T_TMF_CLEAR_ACA:
348
    default:
349
        req->resp.tmf->response = VIRTIO_SCSI_S_FUNCTION_REJECTED;
350
        break;
351
    }
352
353
    return;
354
355
fail:
356
    req->resp.tmf->response = VIRTIO_SCSI_S_BAD_TARGET;
357
}
358
359
static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
360
{
361
    VirtIOSCSI *s = (VirtIOSCSI *)vdev;
362
    VirtIOSCSIReq *req;
363
364
    while ((req = virtio_scsi_pop_req(s, vq))) {
365
        int out_size, in_size;
366
        if (req->elem.out_num < 1 || req->elem.in_num < 1) {
367
            virtio_scsi_bad_req();
368
            continue;
369
        }
370
371
        out_size = req->elem.out_sg[0].iov_len;
372
        in_size = req->elem.in_sg[0].iov_len;
373
        if (req->req.tmf->type == VIRTIO_SCSI_T_TMF) {
374
            if (out_size < sizeof(VirtIOSCSICtrlTMFReq) ||
375
                in_size < sizeof(VirtIOSCSICtrlTMFResp)) {
376
                virtio_scsi_bad_req();
377
            }
378
            virtio_scsi_do_tmf(s, req);
379
380
        } else if (req->req.tmf->type == VIRTIO_SCSI_T_AN_QUERY ||
381
                   req->req.tmf->type == VIRTIO_SCSI_T_AN_SUBSCRIBE) {
382
            if (out_size < sizeof(VirtIOSCSICtrlANReq) ||
383
                in_size < sizeof(VirtIOSCSICtrlANResp)) {
384
                virtio_scsi_bad_req();
385
            }
386
            req->resp.an->event_actual = 0;
387
            req->resp.an->response = VIRTIO_SCSI_S_OK;
388
        }
389
        virtio_scsi_complete_req(req);
390
    }
391
}
392
393
static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status,
394
                                         int32_t resid)
395
{
396
    VirtIOSCSIReq *req = r->hba_private;
397
398
    req->resp.cmd->response = VIRTIO_SCSI_S_OK;
399
    req->resp.cmd->status = status;
400
    if (req->resp.cmd->status == GOOD) {
401
        req->resp.cmd->resid = resid;
402
    } else {
403
       req->resp.cmd->resid = 0;
404
       scsi_req_get_sense(r, req->resp.cmd->sense, VIRTIO_SCSI_SENSE_SIZE);
405
    }
406
    virtio_scsi_complete_req(req);
407
}
408
409
static QEMUSGList *virtio_scsi_get_sg_list(SCSIRequest *r)
410
{
411
    VirtIOSCSIReq *req = r->hba_private;
412
413
    return &req->qsgl;
414
}
415
416
static void virtio_scsi_request_cancelled(SCSIRequest *r)
417
{
418
    VirtIOSCSIReq *req = r->hba_private;
419
420
    if (!req) {
421
        return;
422
    }
423
    if (req->dev->resetting) {
424
        req->resp.cmd->response = VIRTIO_SCSI_S_RESET;
425
    } else {
426
        req->resp.cmd->response = VIRTIO_SCSI_S_ABORTED;
427
    }
428
    virtio_scsi_complete_req(req);
429
}
430
431
static void virtio_scsi_fail_cmd_req(VirtIOSCSIReq *req)
432
{
433
    req->resp.cmd->response = VIRTIO_SCSI_S_FAILURE;
434
    virtio_scsi_complete_req(req);
435
}
436
437
static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
438
{
439
    VirtIOSCSI *s = (VirtIOSCSI *)vdev;
440
    VirtIOSCSIReq *req;
441
    int n;
442
443
    while ((req = virtio_scsi_pop_req(s, vq))) {
444
        SCSIDevice *d;
445
        int out_size, in_size;
446
        if (req->elem.out_num < 1 || req->elem.in_num < 1) {
447
            virtio_scsi_bad_req();
448
        }
449
450
        out_size = req->elem.out_sg[0].iov_len;
451
        in_size = req->elem.in_sg[0].iov_len;
452
        if (out_size < sizeof(VirtIOSCSICmdReq) + s->cdb_size ||
453
            in_size < sizeof(VirtIOSCSICmdResp) + s->sense_size) {
454
            virtio_scsi_bad_req();
455
        }
456
457
        if (req->elem.out_num > 1 && req->elem.in_num > 1) {
458
            virtio_scsi_fail_cmd_req(req);
459
            continue;
460
        }
461
462
        d = virtio_scsi_device_find(s, req->req.cmd->lun);
463
        if (!d) {
464
            req->resp.cmd->response = VIRTIO_SCSI_S_BAD_TARGET;
465
            virtio_scsi_complete_req(req);
466
            continue;
467
        }
468
        req->sreq = scsi_req_new(d, req->req.cmd->tag,
469
                                 virtio_scsi_get_lun(req->req.cmd->lun),
470
                                 req->req.cmd->cdb, req);
471
472
        if (req->sreq->cmd.mode != SCSI_XFER_NONE) {
473
            int req_mode =
474
                (req->elem.in_num > 1 ? SCSI_XFER_FROM_DEV : SCSI_XFER_TO_DEV);
475
476
            if (req->sreq->cmd.mode != req_mode ||
477
                req->sreq->cmd.xfer > req->qsgl.size) {
478
                req->resp.cmd->response = VIRTIO_SCSI_S_OVERRUN;
479
                virtio_scsi_complete_req(req);
480
                continue;
481
            }
482
        }
483
484
        n = scsi_req_enqueue(req->sreq);
485
        if (n) {
486
            scsi_req_continue(req->sreq);
487
        }
488
    }
489
}
490
491
static void virtio_scsi_get_config(VirtIODevice *vdev,
492
                                   uint8_t *config)
493
{
494
    VirtIOSCSIConfig *scsiconf = (VirtIOSCSIConfig *)config;
495
    VirtIOSCSI *s = (VirtIOSCSI *)vdev;
496
497
    stl_raw(&scsiconf->num_queues, s->conf->num_queues);
498
    stl_raw(&scsiconf->seg_max, 128 - 2);
499
    stl_raw(&scsiconf->max_sectors, s->conf->max_sectors);
500
    stl_raw(&scsiconf->cmd_per_lun, s->conf->cmd_per_lun);
501
    stl_raw(&scsiconf->event_info_size, sizeof(VirtIOSCSIEvent));
502
    stl_raw(&scsiconf->sense_size, s->sense_size);
503
    stl_raw(&scsiconf->cdb_size, s->cdb_size);
504
    stl_raw(&scsiconf->max_channel, VIRTIO_SCSI_MAX_CHANNEL);
505
    stl_raw(&scsiconf->max_target, VIRTIO_SCSI_MAX_TARGET);
506
    stl_raw(&scsiconf->max_lun, VIRTIO_SCSI_MAX_LUN);
507
}
508
509
static void virtio_scsi_set_config(VirtIODevice *vdev,
510
                                   const uint8_t *config)
511
{
512
    VirtIOSCSIConfig *scsiconf = (VirtIOSCSIConfig *)config;
513
    VirtIOSCSI *s = (VirtIOSCSI *)vdev;
514
515
    if ((uint32_t) ldl_raw(&scsiconf->sense_size) >= 65536 ||
516
        (uint32_t) ldl_raw(&scsiconf->cdb_size) >= 256) {
517
        error_report("bad data written to virtio-scsi configuration space");
518
        exit(1);
519
    }
520
521
    s->sense_size = ldl_raw(&scsiconf->sense_size);
522
    s->cdb_size = ldl_raw(&scsiconf->cdb_size);
523
}
524
525
static uint32_t virtio_scsi_get_features(VirtIODevice *vdev,
526
                                         uint32_t requested_features)
527
{
528
    return requested_features;
529
}
530
531
static void virtio_scsi_reset(VirtIODevice *vdev)
532
{
533
    VirtIOSCSI *s = (VirtIOSCSI *)vdev;
534
535
    s->sense_size = VIRTIO_SCSI_SENSE_SIZE;
536
    s->cdb_size = VIRTIO_SCSI_CDB_SIZE;
537
}
538
539
/* The device does not have anything to save beyond the virtio data.
540
 * Request data is saved with callbacks from SCSI devices.
541
 */
542
static void virtio_scsi_save(QEMUFile *f, void *opaque)
543
{
544
    VirtIOSCSI *s = opaque;
545
    virtio_save(&s->vdev, f);
546
}
547
548
static int virtio_scsi_load(QEMUFile *f, void *opaque, int version_id)
549
{
550
    VirtIOSCSI *s = opaque;
551
    virtio_load(&s->vdev, f);
552
    return 0;
553
}
554
555
static struct SCSIBusInfo virtio_scsi_scsi_info = {
556
    .tcq = true,
557
    .max_channel = VIRTIO_SCSI_MAX_CHANNEL,
558
    .max_target = VIRTIO_SCSI_MAX_TARGET,
559
    .max_lun = VIRTIO_SCSI_MAX_LUN,
560
561
    .complete = virtio_scsi_command_complete,
562
    .cancel = virtio_scsi_request_cancelled,
563
    .get_sg_list = virtio_scsi_get_sg_list,
564
    .save_request = virtio_scsi_save_request,
565
    .load_request = virtio_scsi_load_request,
566
};
567
568
VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf)
569
{
570
    VirtIOSCSI *s;
571
    static int virtio_scsi_id;
572
573
    s = (VirtIOSCSI *)virtio_common_init("virtio-scsi", VIRTIO_ID_SCSI,
574
                                         sizeof(VirtIOSCSIConfig),
575
                                         sizeof(VirtIOSCSI));
576
577
    s->qdev = dev;
578
    s->conf = proxyconf;
579
580
    /* TODO set up vdev function pointers */
581
    s->vdev.get_config = virtio_scsi_get_config;
582
    s->vdev.set_config = virtio_scsi_set_config;
583
    s->vdev.get_features = virtio_scsi_get_features;
584
    s->vdev.reset = virtio_scsi_reset;
585
586
    s->ctrl_vq = virtio_add_queue(&s->vdev, VIRTIO_SCSI_VQ_SIZE,
587
                                   virtio_scsi_handle_ctrl);
588
    s->event_vq = virtio_add_queue(&s->vdev, VIRTIO_SCSI_VQ_SIZE,
589
                                   NULL);
590
    s->cmd_vq = virtio_add_queue(&s->vdev, VIRTIO_SCSI_VQ_SIZE,
591
                                   virtio_scsi_handle_cmd);
592
593
    scsi_bus_new(&s->bus, dev, &virtio_scsi_scsi_info);
594
    if (!dev->hotplugged) {
595
        scsi_bus_legacy_handle_cmdline(&s->bus);
596
    }
597
598
    register_savevm(dev, "virtio-scsi", virtio_scsi_id++, 1,
599
                    virtio_scsi_save, virtio_scsi_load, s);
600
601
    return &s->vdev;
602
}
603
604
void virtio_scsi_exit(VirtIODevice *vdev)
605
{
606
    virtio_cleanup(vdev);
607
}
(-)qemu-kvm-1.0/hw/virtio-scsi.h (+36 lines)
Line 0 Link Here
1
/*
2
 * Virtio SCSI HBA
3
 *
4
 * Copyright IBM, Corp. 2010
5
 *
6
 * Authors:
7
 *  Stefan Hajnoczi    <stefanha@linux.vnet.ibm.com>
8
 *
9
 * This work is licensed under the terms of the GNU GPL, version 2.  See
10
 * the COPYING file in the top-level directory.
11
 *
12
 */
13
14
#ifndef _QEMU_VIRTIO_SCSI_H
15
#define _QEMU_VIRTIO_SCSI_H
16
17
#include "virtio.h"
18
#include "net.h"
19
#include "pci.h"
20
21
/* The ID for virtio_scsi */
22
#define VIRTIO_ID_SCSI  8
23
24
struct VirtIOSCSIConf {
25
    uint32_t num_queues;
26
    uint32_t max_sectors;
27
    uint32_t cmd_per_lun;
28
};
29
30
#define DEFINE_VIRTIO_SCSI_PROPERTIES(_state, _features_field, _conf_field) \
31
    DEFINE_VIRTIO_COMMON_FEATURES(_state, _features_field), \
32
    DEFINE_PROP_UINT32("num_queues", _state, _conf_field.num_queues, 1), \
33
    DEFINE_PROP_UINT32("max_sectors", _state, _conf_field.max_sectors, 0xFFFF), \
34
    DEFINE_PROP_UINT32("cmd_per_lun", _state, _conf_field.cmd_per_lun, 128)
35
36
#endif /* _QEMU_VIRTIO_SCSI_H */
(-)qemu-kvm-1.0/Makefile.target (+1 lines)
Lines 205-210 obj-y = arch_init.o cpus.o monitor.o mac Link Here
205
obj-$(CONFIG_NO_PCI) += pci-stub.o
205
obj-$(CONFIG_NO_PCI) += pci-stub.o
206
obj-$(CONFIG_PCI) += pci.o
206
obj-$(CONFIG_PCI) += pci.o
207
obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
207
obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
208
obj-$(CONFIG_VIRTIO_SCSI) += virtio-scsi.o
208
obj-y += vhost_net.o
209
obj-y += vhost_net.o
209
obj-$(CONFIG_VHOST_NET) += vhost.o
210
obj-$(CONFIG_VHOST_NET) += vhost.o
210
obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o
211
obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o

Return to bug 415403