~dannf/qemu-linaro/qemu-highbank-ppa

« back to all changes in this revision

Viewing changes to hw/scsi-disk.c

  • Committer: Steve Langasek
  • Date: 2012-03-15 21:13:19 UTC
  • mfrom: (0.1.15)
  • Revision ID: steve.langasek@canonical.com-20120315211319-f1j3ot1ihx30b2s9
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
#include "sysemu.h"
39
39
#include "blockdev.h"
40
40
#include "block_int.h"
 
41
#include "dma.h"
41
42
 
42
43
#ifdef __linux
43
44
#include <scsi/sg.h>
110
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
116
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
116
117
 
117
118
    if (!r->iov.iov_base) {
118
 
        r->buflen = SCSI_DMA_BUF_SIZE;
 
119
        r->buflen = size;
119
120
        r->iov.iov_base = qemu_blockalign(s->qdev.conf.bs, r->buflen);
120
121
    }
121
122
    r->iov.iov_len = MIN(r->sector_count * 512, r->buflen);
123
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
177
static void scsi_read_complete(void * opaque, int ret)
127
178
{
128
179
    SCSIDiskReq *r = (SCSIDiskReq *)opaque;
213
264
        return;
214
265
    }
215
266
 
216
 
    n = scsi_init_iovec(r);
217
 
    bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
218
 
    r->req.aiocb = bdrv_aio_readv(s->qdev.conf.bs, r->sector, &r->qiov, n,
219
 
                              scsi_read_complete, r);
 
267
    if (r->req.sg) {
 
268
        dma_acct_start(s->qdev.conf.bs, &r->acct, r->req.sg, BDRV_ACCT_READ);
 
269
        r->req.resid -= r->req.sg->size;
 
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
278
}
221
279
 
222
280
/*
233
291
    BlockErrorAction action = bdrv_get_on_error(s->qdev.conf.bs, is_read);
234
292
 
235
293
    if (action == BLOCK_ERR_IGNORE) {
236
 
        bdrv_mon_event(s->qdev.conf.bs, BDRV_ACTION_IGNORE, is_read);
 
294
        bdrv_emit_qmp_error_event(s->qdev.conf.bs, BDRV_ACTION_IGNORE, is_read);
237
295
        return 0;
238
296
    }
239
297
 
240
298
    if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
241
299
            || action == BLOCK_ERR_STOP_ANY) {
242
300
 
243
 
        bdrv_mon_event(s->qdev.conf.bs, BDRV_ACTION_STOP, is_read);
 
301
        bdrv_emit_qmp_error_event(s->qdev.conf.bs, BDRV_ACTION_STOP, is_read);
244
302
        vm_stop(RUN_STATE_IO_ERROR);
245
303
        bdrv_iostatus_set_err(s->qdev.conf.bs, error);
246
304
        scsi_req_retry(&r->req);
259
317
            scsi_check_condition(r, SENSE_CODE(IO_ERROR));
260
318
            break;
261
319
        }
262
 
        bdrv_mon_event(s->qdev.conf.bs, BDRV_ACTION_REPORT, is_read);
 
320
        bdrv_emit_qmp_error_event(s->qdev.conf.bs, BDRV_ACTION_REPORT, is_read);
263
321
    }
264
322
    return 1;
265
323
}
287
345
    if (r->sector_count == 0) {
288
346
        scsi_req_complete(&r->req, GOOD);
289
347
    } else {
290
 
        scsi_init_iovec(r);
 
348
        scsi_init_iovec(r, SCSI_DMA_BUF_SIZE);
291
349
        DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, r->qiov.size);
292
350
        scsi_req_data(&r->req, r->qiov.size);
293
351
    }
315
373
        return;
316
374
    }
317
375
 
318
 
    n = r->qiov.size / 512;
319
 
    if (n) {
320
 
        if (s->tray_open) {
321
 
            scsi_write_complete(r, -ENOMEDIUM);
322
 
            return;
323
 
        }
 
376
    if (!r->req.sg && !r->qiov.size) {
 
377
        /* Called for the first time.  Ask the driver to send us more data.  */
 
378
        scsi_write_complete(r, 0);
 
379
        return;
 
380
    }
 
381
    if (s->tray_open) {
 
382
        scsi_write_complete(r, -ENOMEDIUM);
 
383
        return;
 
384
    }
 
385
 
 
386
    if (r->req.sg) {
 
387
        dma_acct_start(s->qdev.conf.bs, &r->acct, r->req.sg, BDRV_ACCT_WRITE);
 
388
        r->req.resid -= r->req.sg->size;
 
389
        r->req.aiocb = dma_bdrv_write(s->qdev.conf.bs, r->req.sg, r->sector,
 
390
                                      scsi_dma_complete, r);
 
391
    } else {
 
392
        n = r->qiov.size / 512;
324
393
        bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE);
325
394
        r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, r->sector, &r->qiov, n,
326
395
                                       scsi_write_complete, r);
327
 
    } else {
328
 
        /* Called for the first time.  Ask the driver to send us more data.  */
329
 
        scsi_write_complete(r, 0);
330
396
    }
331
397
}
332
398
 
1050
1116
                                 : SENSE_CODE(NOT_READY_REMOVAL_PREVENTED));
1051
1117
            return -1;
1052
1118
        }
1053
 
        bdrv_eject(s->qdev.conf.bs, !start);
1054
 
        s->tray_open = !start;
 
1119
 
 
1120
        if (s->tray_open != !start) {
 
1121
            bdrv_eject(s->qdev.conf.bs, !start);
 
1122
            s->tray_open = !start;
 
1123
        }
1055
1124
    }
1056
1125
    return 0;
1057
1126
}
1584
1653
    .write_data   = scsi_write_data,
1585
1654
    .cancel_io    = scsi_cancel_io,
1586
1655
    .get_buf      = scsi_get_buf,
 
1656
    .load_request = scsi_disk_load_request,
 
1657
    .save_request = scsi_disk_save_request,
1587
1658
};
1588
1659
 
1589
1660
static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
1686
1757
    case WRITE_VERIFY_10:
1687
1758
    case WRITE_VERIFY_12:
1688
1759
    case WRITE_VERIFY_16:
 
1760
        /* If we are not using O_DIRECT, we might read stale data from the
 
1761
         * host cache if writes were made using other commands than these
 
1762
         * ones (such as WRITE SAME or EXTENDED COPY, etc.).  So, without
 
1763
         * O_DIRECT everything must go through SG_IO.
 
1764
         */
 
1765
        if (!(s->qdev.conf.bs->open_flags & BDRV_O_NOCACHE)) {
 
1766
            break;
 
1767
        }
 
1768
 
1689
1769
        /* MMC writing cannot be done via pread/pwrite, because it sometimes
1690
1770
         * involves writing beyond the maximum LBA or to negative LBA (lead-in).
1691
1771
         * And once you do these writes, reading from the block device is
1696
1776
         * seen, but performance usually isn't paramount on optical media.  So,
1697
1777
         * just make scsi-block operate the same as scsi-generic for them.
1698
1778
         */
1699
 
        if (s->qdev.type != TYPE_ROM) {
1700
 
            return scsi_req_alloc(&scsi_disk_reqops, &s->qdev, tag, lun,
1701
 
                                  hba_private);
1702
 
        }
 
1779
        if (s->qdev.type == TYPE_ROM) {
 
1780
            break;
 
1781
        }
 
1782
        return scsi_req_alloc(&scsi_disk_reqops, &s->qdev, tag, lun,
 
1783
                              hba_private);
1703
1784
    }
1704
1785
 
1705
1786
    return scsi_req_alloc(&scsi_generic_req_ops, &s->qdev, tag, lun,
1712
1793
    DEFINE_PROP_STRING("ver",  SCSIDiskState, version),         \
1713
1794
    DEFINE_PROP_STRING("serial",  SCSIDiskState, serial)
1714
1795
 
 
1796
static Property scsi_hd_properties[] = {
 
1797
    DEFINE_SCSI_DISK_PROPERTIES(),
 
1798
    DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
 
1799
    DEFINE_PROP_END_OF_LIST(),
 
1800
};
 
1801
 
 
1802
static const VMStateDescription vmstate_scsi_disk_state = {
 
1803
    .name = "scsi-disk",
 
1804
    .version_id = 1,
 
1805
    .minimum_version_id = 1,
 
1806
    .minimum_version_id_old = 1,
 
1807
    .fields = (VMStateField[]) {
 
1808
        VMSTATE_SCSI_DEVICE(qdev, SCSIDiskState),
 
1809
        VMSTATE_BOOL(media_changed, SCSIDiskState),
 
1810
        VMSTATE_BOOL(media_event, SCSIDiskState),
 
1811
        VMSTATE_BOOL(eject_request, SCSIDiskState),
 
1812
        VMSTATE_BOOL(tray_open, SCSIDiskState),
 
1813
        VMSTATE_BOOL(tray_locked, SCSIDiskState),
 
1814
        VMSTATE_END_OF_LIST()
 
1815
    }
 
1816
};
 
1817
 
1715
1818
static void scsi_hd_class_initfn(ObjectClass *klass, void *data)
1716
1819
{
 
1820
    DeviceClass *dc = DEVICE_CLASS(klass);
1717
1821
    SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
1718
1822
 
1719
1823
    sc->init         = scsi_hd_initfn;
1720
1824
    sc->destroy      = scsi_destroy;
1721
1825
    sc->alloc_req    = scsi_new_request;
1722
1826
    sc->unit_attention_reported = scsi_disk_unit_attention_reported;
 
1827
    dc->fw_name = "disk";
 
1828
    dc->desc = "virtual SCSI disk";
 
1829
    dc->reset = scsi_disk_reset;
 
1830
    dc->props = scsi_hd_properties;
 
1831
    dc->vmsd  = &vmstate_scsi_disk_state;
1723
1832
}
1724
1833
 
1725
 
static DeviceInfo scsi_hd_info = {
1726
 
    .name    = "scsi-hd",
1727
 
    .fw_name = "disk",
1728
 
    .desc    = "virtual SCSI disk",
1729
 
    .size    = sizeof(SCSIDiskState),
1730
 
    .reset   = scsi_disk_reset,
1731
 
    .class_init = scsi_hd_class_initfn,
1732
 
    .props   = (Property[]) {
1733
 
        DEFINE_SCSI_DISK_PROPERTIES(),
1734
 
        DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
1735
 
        DEFINE_PROP_END_OF_LIST(),
1736
 
    },
 
1834
static TypeInfo scsi_hd_info = {
 
1835
    .name          = "scsi-hd",
 
1836
    .parent        = TYPE_SCSI_DEVICE,
 
1837
    .instance_size = sizeof(SCSIDiskState),
 
1838
    .class_init    = scsi_hd_class_initfn,
 
1839
};
 
1840
 
 
1841
static Property scsi_cd_properties[] = {
 
1842
    DEFINE_SCSI_DISK_PROPERTIES(),
 
1843
    DEFINE_PROP_END_OF_LIST(),
1737
1844
};
1738
1845
 
1739
1846
static void scsi_cd_class_initfn(ObjectClass *klass, void *data)
1740
1847
{
 
1848
    DeviceClass *dc = DEVICE_CLASS(klass);
1741
1849
    SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
1742
1850
 
1743
1851
    sc->init         = scsi_cd_initfn;
1744
1852
    sc->destroy      = scsi_destroy;
1745
1853
    sc->alloc_req    = scsi_new_request;
1746
1854
    sc->unit_attention_reported = scsi_disk_unit_attention_reported;
 
1855
    dc->fw_name = "disk";
 
1856
    dc->desc = "virtual SCSI CD-ROM";
 
1857
    dc->reset = scsi_disk_reset;
 
1858
    dc->props = scsi_cd_properties;
 
1859
    dc->vmsd  = &vmstate_scsi_disk_state;
1747
1860
}
1748
1861
 
1749
 
static DeviceInfo scsi_cd_info = {
1750
 
    .name    = "scsi-cd",
1751
 
    .fw_name = "disk",
1752
 
    .desc    = "virtual SCSI CD-ROM",
1753
 
    .size    = sizeof(SCSIDiskState),
1754
 
    .reset   = scsi_disk_reset,
1755
 
    .class_init = scsi_cd_class_initfn,
1756
 
    .props   = (Property[]) {
1757
 
        DEFINE_SCSI_DISK_PROPERTIES(),
1758
 
        DEFINE_PROP_END_OF_LIST(),
1759
 
    },
 
1862
static TypeInfo scsi_cd_info = {
 
1863
    .name          = "scsi-cd",
 
1864
    .parent        = TYPE_SCSI_DEVICE,
 
1865
    .instance_size = sizeof(SCSIDiskState),
 
1866
    .class_init    = scsi_cd_class_initfn,
1760
1867
};
1761
1868
 
1762
1869
#ifdef __linux__
 
1870
static Property scsi_block_properties[] = {
 
1871
    DEFINE_SCSI_DISK_PROPERTIES(),
 
1872
    DEFINE_PROP_END_OF_LIST(),
 
1873
};
 
1874
 
1763
1875
static void scsi_block_class_initfn(ObjectClass *klass, void *data)
1764
1876
{
 
1877
    DeviceClass *dc = DEVICE_CLASS(klass);
1765
1878
    SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
1766
1879
 
1767
1880
    sc->init         = scsi_block_initfn;
1768
1881
    sc->destroy      = scsi_destroy;
1769
1882
    sc->alloc_req    = scsi_block_new_request;
 
1883
    dc->fw_name = "disk";
 
1884
    dc->desc = "SCSI block device passthrough";
 
1885
    dc->reset = scsi_disk_reset;
 
1886
    dc->props = scsi_block_properties;
 
1887
    dc->vmsd  = &vmstate_scsi_disk_state;
1770
1888
}
1771
1889
 
1772
 
static DeviceInfo scsi_block_info = {
1773
 
    .name    = "scsi-block",
1774
 
    .fw_name = "disk",
1775
 
    .desc    = "SCSI block device passthrough",
1776
 
    .size    = sizeof(SCSIDiskState),
1777
 
    .reset   = scsi_disk_reset,
1778
 
    .class_init = scsi_block_class_initfn,
1779
 
    .props   = (Property[]) {
1780
 
        DEFINE_SCSI_DISK_PROPERTIES(),
1781
 
        DEFINE_PROP_END_OF_LIST(),
1782
 
    },
 
1890
static TypeInfo scsi_block_info = {
 
1891
    .name          = "scsi-block",
 
1892
    .parent        = TYPE_SCSI_DEVICE,
 
1893
    .instance_size = sizeof(SCSIDiskState),
 
1894
    .class_init    = scsi_block_class_initfn,
1783
1895
};
1784
1896
#endif
1785
1897
 
 
1898
static Property scsi_disk_properties[] = {
 
1899
    DEFINE_SCSI_DISK_PROPERTIES(),
 
1900
    DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
 
1901
    DEFINE_PROP_END_OF_LIST(),
 
1902
};
 
1903
 
1786
1904
static void scsi_disk_class_initfn(ObjectClass *klass, void *data)
1787
1905
{
 
1906
    DeviceClass *dc = DEVICE_CLASS(klass);
1788
1907
    SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
1789
1908
 
1790
1909
    sc->init         = scsi_disk_initfn;
1791
1910
    sc->destroy      = scsi_destroy;
1792
1911
    sc->alloc_req    = scsi_new_request;
1793
1912
    sc->unit_attention_reported = scsi_disk_unit_attention_reported;
 
1913
    dc->fw_name = "disk";
 
1914
    dc->desc = "virtual SCSI disk or CD-ROM (legacy)";
 
1915
    dc->reset = scsi_disk_reset;
 
1916
    dc->props = scsi_disk_properties;
 
1917
    dc->vmsd  = &vmstate_scsi_disk_state;
1794
1918
}
1795
1919
 
1796
 
static DeviceInfo scsi_disk_info = {
1797
 
    .name    = "scsi-disk", /* legacy -device scsi-disk */
1798
 
    .fw_name = "disk",
1799
 
    .desc    = "virtual SCSI disk or CD-ROM (legacy)",
1800
 
    .size    = sizeof(SCSIDiskState),
1801
 
    .reset   = scsi_disk_reset,
1802
 
    .class_init = scsi_disk_class_initfn,
1803
 
    .props   = (Property[]) {
1804
 
        DEFINE_SCSI_DISK_PROPERTIES(),
1805
 
        DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
1806
 
        DEFINE_PROP_END_OF_LIST(),
1807
 
    }
 
1920
static TypeInfo scsi_disk_info = {
 
1921
    .name          = "scsi-disk",
 
1922
    .parent        = TYPE_SCSI_DEVICE,
 
1923
    .instance_size = sizeof(SCSIDiskState),
 
1924
    .class_init    = scsi_disk_class_initfn,
1808
1925
};
1809
1926
 
1810
 
static void scsi_disk_register_devices(void)
 
1927
static void scsi_disk_register_types(void)
1811
1928
{
1812
 
    scsi_qdev_register(&scsi_hd_info);
1813
 
    scsi_qdev_register(&scsi_cd_info);
 
1929
    type_register_static(&scsi_hd_info);
 
1930
    type_register_static(&scsi_cd_info);
1814
1931
#ifdef __linux__
1815
 
    scsi_qdev_register(&scsi_block_info);
 
1932
    type_register_static(&scsi_block_info);
1816
1933
#endif
1817
 
    scsi_qdev_register(&scsi_disk_info);
 
1934
    type_register_static(&scsi_disk_info);
1818
1935
}
1819
 
device_init(scsi_disk_register_devices)
 
1936
 
 
1937
type_init(scsi_disk_register_types)