diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2014-09-08 13:14:41 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-09-08 13:14:41 +0100 |
commit | 1bc0e405816c9c6bde5695af20b07a1491ce1f9f (patch) | |
tree | 616f83e0841e34ae48e2312c28d8165f40a23cb9 /hw | |
parent | 2d6838e86ce942f886401818b48d77e575a5f7de (diff) | |
parent | 01ce352e62c3f86df6f4ad32c3ab9353e55af799 (diff) |
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
Block pull request
# gpg: Signature made Mon 08 Sep 2014 11:49:31 BST using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>"
* remotes/stefanha/tags/block-pull-request: (24 commits)
ide: Add resize callback to ide/core
IDE: Fill the IDENTIFY request consistently
vmdk: fix buf leak in vmdk_parse_extents()
vmdk: fix vmdk_parse_extents() extent_file leaks
ide: Add wwn support to IDE-ATAPI drive
qtest/ide: Uninitialize PC allocator
libqos: add a simple first-fit memory allocator
MAINTAINERS: update sheepdog maintainer
qemu-nbd: fix indentation and coding style
qemu-nbd: add option to set detect-zeroes mode
rename parse_enum_option to qapi_enum_parse and make it public
block/archipelago: Use QEMU atomic builtins
qemu-img: fix rebase src_cache option documentation
qemu-img: clarify src_cache option documentation
libqos: Added EVENT_IDX support
libqos: Added MSI-X support
libqos: Added test case for configuration changes in virtio-blk test
libqos: Added indirect descriptor support to virtio implementation
libqos: Added basic virtqueue support to virtio implementation
tests: Add virtio device initialization
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/block/pflash_cfi01.c | 18 | ||||
-rw-r--r-- | hw/ide/core.c | 111 |
2 files changed, 104 insertions, 25 deletions
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index 2238f39579..593fbc5525 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -94,10 +94,13 @@ struct pflash_t { void *storage; }; +static int pflash_post_load(void *opaque, int version_id); + static const VMStateDescription vmstate_pflash = { .name = "pflash_cfi01", .version_id = 1, .minimum_version_id = 1, + .post_load = pflash_post_load, .fields = (VMStateField[]) { VMSTATE_UINT8(wcycle, pflash_t), VMSTATE_UINT8(cmd, pflash_t), @@ -209,11 +212,11 @@ static uint32_t pflash_devid_query(pflash_t *pfl, hwaddr offset) switch (boff & 0xFF) { case 0: resp = pfl->ident0; - DPRINTF("%s: Manufacturer Code %04x\n", __func__, ret); + DPRINTF("%s: Manufacturer Code %04x\n", __func__, resp); break; case 1: resp = pfl->ident1; - DPRINTF("%s: Device ID Code %04x\n", __func__, ret); + DPRINTF("%s: Device ID Code %04x\n", __func__, resp); break; default: DPRINTF("%s: Read Device Information offset=%x\n", __func__, @@ -982,3 +985,14 @@ MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl) { return &fl->mem; } + +static int pflash_post_load(void *opaque, int version_id) +{ + pflash_t *pfl = opaque; + + if (!pfl->ro) { + DPRINTF("%s: updating bdrv for %s\n", __func__, pfl->name); + pflash_update(pfl, 0, pfl->sector_len * pfl->nb_blocs); + } + return 0; +} diff --git a/hw/ide/core.c b/hw/ide/core.c index b48127f921..191f89321e 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -75,19 +75,29 @@ static void put_le16(uint16_t *p, unsigned int v) *p = cpu_to_le16(v); } +static void ide_identify_size(IDEState *s) +{ + uint16_t *p = (uint16_t *)s->identify_data; + put_le16(p + 60, s->nb_sectors); + put_le16(p + 61, s->nb_sectors >> 16); + put_le16(p + 100, s->nb_sectors); + put_le16(p + 101, s->nb_sectors >> 16); + put_le16(p + 102, s->nb_sectors >> 32); + put_le16(p + 103, s->nb_sectors >> 48); +} + static void ide_identify(IDEState *s) { uint16_t *p; unsigned int oldsize; IDEDevice *dev = s->unit ? s->bus->slave : s->bus->master; + p = (uint16_t *)s->identify_data; if (s->identify_set) { - memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data)); - return; + goto fill_buffer; } + memset(p, 0, sizeof(s->identify_data)); - memset(s->io_buffer, 0, 512); - p = (uint16_t *)s->io_buffer; put_le16(p + 0, 0x0040); put_le16(p + 1, s->cylinders); put_le16(p + 3, s->heads); @@ -116,8 +126,8 @@ static void ide_identify(IDEState *s) put_le16(p + 58, oldsize >> 16); if (s->mult_sectors) put_le16(p + 59, 0x100 | s->mult_sectors); - put_le16(p + 60, s->nb_sectors); - put_le16(p + 61, s->nb_sectors >> 16); + /* *(p + 60) := nb_sectors -- see ide_identify_size */ + /* *(p + 61) := nb_sectors >> 16 -- see ide_identify_size */ put_le16(p + 62, 0x07); /* single word dma0-2 supported */ put_le16(p + 63, 0x07); /* mdma0-2 supported */ put_le16(p + 64, 0x03); /* pio3-4 supported */ @@ -162,10 +172,10 @@ static void ide_identify(IDEState *s) } put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */ put_le16(p + 93, 1 | (1 << 14) | 0x2000); - put_le16(p + 100, s->nb_sectors); - put_le16(p + 101, s->nb_sectors >> 16); - put_le16(p + 102, s->nb_sectors >> 32); - put_le16(p + 103, s->nb_sectors >> 48); + /* *(p + 100) := nb_sectors -- see ide_identify_size */ + /* *(p + 101) := nb_sectors >> 16 -- see ide_identify_size */ + /* *(p + 102) := nb_sectors >> 32 -- see ide_identify_size */ + /* *(p + 103) := nb_sectors >> 48 -- see ide_identify_size */ if (dev && dev->conf.physical_block_size) put_le16(p + 106, 0x6000 | get_physical_block_exp(&dev->conf)); @@ -180,21 +190,23 @@ static void ide_identify(IDEState *s) put_le16(p + 169, 1); /* TRIM support */ } - memcpy(s->identify_data, p, sizeof(s->identify_data)); + ide_identify_size(s); s->identify_set = 1; + +fill_buffer: + memcpy(s->io_buffer, p, sizeof(s->identify_data)); } static void ide_atapi_identify(IDEState *s) { uint16_t *p; + p = (uint16_t *)s->identify_data; if (s->identify_set) { - memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data)); - return; + goto fill_buffer; } + memset(p, 0, sizeof(s->identify_data)); - memset(s->io_buffer, 0, 512); - p = (uint16_t *)s->io_buffer; /* Removable CDROM, 50us response, 12 byte packets */ put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0)); padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */ @@ -230,11 +242,36 @@ static void ide_atapi_identify(IDEState *s) } put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */ + if (s->wwn) { + put_le16(p + 84, (1 << 8)); /* supports WWN for words 108-111 */ + put_le16(p + 87, (1 << 8)); /* WWN enabled */ + } + #ifdef USE_DMA_CDROM put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */ #endif - memcpy(s->identify_data, p, sizeof(s->identify_data)); + + if (s->wwn) { + /* LE 16-bit words 111-108 contain 64-bit World Wide Name */ + put_le16(p + 108, s->wwn >> 48); + put_le16(p + 109, s->wwn >> 32); + put_le16(p + 110, s->wwn >> 16); + put_le16(p + 111, s->wwn); + } + s->identify_set = 1; + +fill_buffer: + memcpy(s->io_buffer, p, sizeof(s->identify_data)); +} + +static void ide_cfata_identify_size(IDEState *s) +{ + uint16_t *p = (uint16_t *)s->identify_data; + put_le16(p + 7, s->nb_sectors >> 16); /* Sectors per card */ + put_le16(p + 8, s->nb_sectors); /* Sectors per card */ + put_le16(p + 60, s->nb_sectors); /* Total LBA sectors */ + put_le16(p + 61, s->nb_sectors >> 16); /* Total LBA sectors */ } static void ide_cfata_identify(IDEState *s) @@ -242,10 +279,10 @@ static void ide_cfata_identify(IDEState *s) uint16_t *p; uint32_t cur_sec; - p = (uint16_t *) s->identify_data; - if (s->identify_set) + p = (uint16_t *)s->identify_data; + if (s->identify_set) { goto fill_buffer; - + } memset(p, 0, sizeof(s->identify_data)); cur_sec = s->cylinders * s->heads * s->sectors; @@ -254,8 +291,8 @@ static void ide_cfata_identify(IDEState *s) put_le16(p + 1, s->cylinders); /* Default cylinders */ put_le16(p + 3, s->heads); /* Default heads */ put_le16(p + 6, s->sectors); /* Default sectors per track */ - put_le16(p + 7, s->nb_sectors >> 16); /* Sectors per card */ - put_le16(p + 8, s->nb_sectors); /* Sectors per card */ + /* *(p + 7) := nb_sectors >> 16 -- see ide_cfata_identify_size */ + /* *(p + 8) := nb_sectors -- see ide_cfata_identify_size */ padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */ put_le16(p + 22, 0x0004); /* ECC bytes */ padstr((char *) (p + 23), s->version, 8); /* Firmware Revision */ @@ -276,8 +313,8 @@ static void ide_cfata_identify(IDEState *s) put_le16(p + 58, cur_sec >> 16); /* Current capacity */ if (s->mult_sectors) /* Multiple sector setting */ put_le16(p + 59, 0x100 | s->mult_sectors); - put_le16(p + 60, s->nb_sectors); /* Total LBA sectors */ - put_le16(p + 61, s->nb_sectors >> 16); /* Total LBA sectors */ + /* *(p + 60) := nb_sectors -- see ide_cfata_identify_size */ + /* *(p + 61) := nb_sectors >> 16 -- see ide_cfata_identify_size */ put_le16(p + 63, 0x0203); /* Multiword DMA capability */ put_le16(p + 64, 0x0001); /* Flow Control PIO support */ put_le16(p + 65, 0x0096); /* Min. Multiword DMA cycle */ @@ -297,6 +334,7 @@ static void ide_cfata_identify(IDEState *s) put_le16(p + 160, 0x8100); /* Power requirement */ put_le16(p + 161, 0x8001); /* CF command set */ + ide_cfata_identify_size(s); s->identify_set = 1; fill_buffer: @@ -2115,6 +2153,28 @@ static bool ide_cd_is_medium_locked(void *opaque) return ((IDEState *)opaque)->tray_locked; } +static void ide_resize_cb(void *opaque) +{ + IDEState *s = opaque; + uint64_t nb_sectors; + + if (!s->identify_set) { + return; + } + + bdrv_get_geometry(s->bs, &nb_sectors); + s->nb_sectors = nb_sectors; + + /* Update the identify data buffer. */ + if (s->drive_kind == IDE_CFATA) { + ide_cfata_identify_size(s); + } else { + /* IDE_CD uses a different set of callbacks entirely. */ + assert(s->drive_kind != IDE_CD); + ide_identify_size(s); + } +} + static const BlockDevOps ide_cd_block_ops = { .change_media_cb = ide_cd_change_cb, .eject_request_cb = ide_cd_eject_request_cb, @@ -2122,6 +2182,10 @@ static const BlockDevOps ide_cd_block_ops = { .is_medium_locked = ide_cd_is_medium_locked, }; +static const BlockDevOps ide_hd_block_ops = { + .resize_cb = ide_resize_cb, +}; + int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind, const char *version, const char *serial, const char *model, uint64_t wwn, @@ -2158,6 +2222,7 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind, error_report("Can't use a read-only drive"); return -1; } + bdrv_set_dev_ops(bs, &ide_hd_block_ops, s); } if (serial) { pstrcpy(s->drive_serial_str, sizeof(s->drive_serial_str), serial); |