summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2010-08-01 17:29:21 +0300
committerAvi Kivity <avi@redhat.com>2010-08-01 17:29:21 +0300
commitab8c54b5a08ed8ad3d7bb930c306785b471b2d7e (patch)
tree7adefa1a3150575571da77f6e382aa8a2a6bdd3b /hw
parentf229c5df0796c02fc39279db24b114cc04757c4a (diff)
parentfd2f659ee3f6f991f4f194f3fde5c9f957fd663d (diff)
Merge commit 'fd2f659ee3f6f991f4f194f3fde5c9f957fd663d' into upstream-merge
* commit 'fd2f659ee3f6f991f4f194f3fde5c9f957fd663d': (58 commits) Update version for 0.13.0-rc0 vnc: better default values for VNC options vnc: tight: split send_sub_rect vnc: tight: fix rgb_prepare_row vnc: add missing lock for vnc_cursor_define() vnc: threaded VNC server qemu-thread: add qemu_mutex/cond_destroy and qemu_mutex_exit vnc: fix tight png memory leak vnc: encapsulate encoding members vnc: tight: stop using qdict for palette stuff vnc: tight: specific zlib level and filters for each compression level vnc: tight add PNG encoding vnc: tight: remove a memleak in send_jpeg_rect() vnc: tight: don't forget do at the last color vnc: rename vnc-encoding-* vnc-enc-* ui: move all ui components in ui/ vnc: add lossy option vnc: JPEG should be disabled if the client don't set tight quality vnc: tight: add JPEG and gradient subencoding with smooth image detection Initial documentation for migration ... Merge 0.13 branch point. Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/e1000.c29
-rw-r--r--hw/etraxfs_eth.c1
-rw-r--r--hw/hw.h6
-rw-r--r--hw/ide/core.c72
-rw-r--r--hw/ide/pci.c38
-rw-r--r--hw/mips_int.c32
-rw-r--r--hw/pc_piix.c6
-rw-r--r--hw/ppc440_bamboo.c2
-rw-r--r--hw/scsi-bus.c12
-rw-r--r--hw/scsi.h1
-rw-r--r--hw/vhost.c21
11 files changed, 150 insertions, 70 deletions
diff --git a/hw/e1000.c b/hw/e1000.c
index 0da65f9a3..80b78bc61 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -262,21 +262,20 @@ set_eecd(E1000State *s, int index, uint32_t val)
s->eecd_state.old_eecd = val & (E1000_EECD_SK | E1000_EECD_CS |
E1000_EECD_DI|E1000_EECD_FWE_MASK|E1000_EECD_REQ);
+ if (!(E1000_EECD_CS & val)) // CS inactive; nothing to do
+ return;
+ if (E1000_EECD_CS & (val ^ oldval)) { // CS rise edge; reset state
+ s->eecd_state.val_in = 0;
+ s->eecd_state.bitnum_in = 0;
+ s->eecd_state.bitnum_out = 0;
+ s->eecd_state.reading = 0;
+ }
if (!(E1000_EECD_SK & (val ^ oldval))) // no clock edge
return;
if (!(E1000_EECD_SK & val)) { // falling edge
s->eecd_state.bitnum_out++;
return;
}
- if (!(val & E1000_EECD_CS)) { // rising, no CS (EEPROM reset)
- memset(&s->eecd_state, 0, sizeof s->eecd_state);
- /*
- * restore old_eecd's E1000_EECD_SK (known to be on)
- * to avoid false detection of a clock edge
- */
- s->eecd_state.old_eecd = E1000_EECD_SK;
- return;
- }
s->eecd_state.val_in <<= 1;
if (val & E1000_EECD_DI)
s->eecd_state.val_in |= 1;
@@ -344,6 +343,15 @@ is_vlan_txd(uint32_t txd_lower)
return ((txd_lower & E1000_TXD_CMD_VLE) != 0);
}
+/* FCS aka Ethernet CRC-32. We don't get it from backends and can't
+ * fill it in, just pad descriptor length by 4 bytes unless guest
+ * told us to trip it off the packet. */
+static inline int
+fcs_len(E1000State *s)
+{
+ return (s->mac_reg[RCTL] & E1000_RCTL_SECRC) ? 0 : 4;
+}
+
static void
xmit_seg(E1000State *s)
{
@@ -649,7 +657,6 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
}
rdh_start = s->mac_reg[RDH];
- size += 4; // for the header
do {
if (s->mac_reg[RDH] == s->mac_reg[RDT] && s->check_rxov) {
set_ics(s, 0, E1000_ICS_RXO);
@@ -663,7 +670,7 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
if (desc.buffer_addr) {
cpu_physical_memory_write(le64_to_cpu(desc.buffer_addr),
(void *)(buf + vlan_offset), size);
- desc.length = cpu_to_le16(size);
+ desc.length = cpu_to_le16(size + fcs_len(s));
desc.status |= E1000_RXD_STAT_EOP|E1000_RXD_STAT_IXSM;
} else // as per intel docs; skip descriptors with null buf addr
DBGOUT(RX, "Null RX descriptor!!\n");
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index 187ece19e..b897c9c16 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -437,6 +437,7 @@ eth_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
eth_validate_duplex(eth);
}
eth->mdio_bus.mdc = !!(value & 4);
+ eth->regs[addr] = value;
break;
case RW_REC_CTRL:
diff --git a/hw/hw.h b/hw/hw.h
index cb553a6e8..ec6985d3b 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -313,6 +313,11 @@ typedef struct {
bool (*field_exists)(void *opaque, int version_id);
} VMStateField;
+typedef struct VMStateSubsection {
+ const VMStateDescription *vmsd;
+ bool (*needed)(void *opaque);
+} VMStateSubsection;
+
struct VMStateDescription {
const char *name;
int version_id;
@@ -323,6 +328,7 @@ struct VMStateDescription {
int (*post_load)(void *opaque, int version_id);
void (*pre_save)(void *opaque);
VMStateField *fields;
+ const VMStateSubsection *subsections;
};
extern const VMStateInfo vmstate_info_int8;
diff --git a/hw/ide/core.c b/hw/ide/core.c
index e20f2e7cb..db000831e 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2733,6 +2733,7 @@ static EndTransferFunc* transfer_end_table[] = {
ide_transfer_stop,
ide_atapi_cmd_reply_end,
ide_atapi_cmd,
+ ide_dummy_transfer_stop,
};
static int transfer_end_table_idx(EndTransferFunc *fn)
@@ -2756,26 +2757,29 @@ static int ide_drive_post_load(void *opaque, int version_id)
s->cdrom_changed = 1;
}
}
+ return 0;
+}
- if (s->cur_io_buffer_len) {
- s->end_transfer_func = transfer_end_table[s->end_transfer_fn_idx];
- s->data_ptr = s->io_buffer + s->cur_io_buffer_offset;
- s->data_end = s->data_ptr + s->cur_io_buffer_len;
+static int ide_drive_pio_post_load(void *opaque, int version_id)
+{
+ IDEState *s = opaque;
+
+ if (s->end_transfer_fn_idx < 0 ||
+ s->end_transfer_fn_idx > ARRAY_SIZE(transfer_end_table)) {
+ return -EINVAL;
}
-
+ s->end_transfer_func = transfer_end_table[s->end_transfer_fn_idx];
+ s->data_ptr = s->io_buffer + s->cur_io_buffer_offset;
+ s->data_end = s->data_ptr + s->cur_io_buffer_len;
+
return 0;
}
-static void ide_drive_pre_save(void *opaque)
+static void ide_drive_pio_pre_save(void *opaque)
{
IDEState *s = opaque;
int idx;
- s->cur_io_buffer_len = 0;
-
- if (!(s->status & DRQ_STAT))
- return;
-
s->cur_io_buffer_offset = s->data_ptr - s->io_buffer;
s->cur_io_buffer_len = s->data_end - s->data_ptr;
@@ -2789,12 +2793,38 @@ static void ide_drive_pre_save(void *opaque)
}
}
+static bool ide_drive_pio_state_needed(void *opaque)
+{
+ IDEState *s = opaque;
+
+ return (s->status & DRQ_STAT) != 0;
+}
+
+const VMStateDescription vmstate_ide_drive_pio_state = {
+ .name = "ide_drive/pio_state",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .pre_save = ide_drive_pio_pre_save,
+ .post_load = ide_drive_pio_post_load,
+ .fields = (VMStateField []) {
+ VMSTATE_INT32(req_nb_sectors, IDEState),
+ VMSTATE_VARRAY_INT32(io_buffer, IDEState, io_buffer_total_len, 1,
+ vmstate_info_uint8, uint8_t),
+ VMSTATE_INT32(cur_io_buffer_offset, IDEState),
+ VMSTATE_INT32(cur_io_buffer_len, IDEState),
+ VMSTATE_UINT8(end_transfer_fn_idx, IDEState),
+ VMSTATE_INT32(elementary_transfer_size, IDEState),
+ VMSTATE_INT32(packet_transfer_size, IDEState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
const VMStateDescription vmstate_ide_drive = {
.name = "ide_drive",
- .version_id = 4,
+ .version_id = 3,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
- .pre_save = ide_drive_pre_save,
.post_load = ide_drive_post_load,
.fields = (VMStateField []) {
VMSTATE_INT32(mult_sectors, IDEState),
@@ -2817,15 +2847,15 @@ const VMStateDescription vmstate_ide_drive = {
VMSTATE_UINT8(sense_key, IDEState),
VMSTATE_UINT8(asc, IDEState),
VMSTATE_UINT8_V(cdrom_changed, IDEState, 3),
- VMSTATE_INT32_V(req_nb_sectors, IDEState, 4),
- VMSTATE_VARRAY_INT32(io_buffer, IDEState, io_buffer_total_len, 4,
- vmstate_info_uint8, uint8_t),
- VMSTATE_INT32_V(cur_io_buffer_offset, IDEState, 4),
- VMSTATE_INT32_V(cur_io_buffer_len, IDEState, 4),
- VMSTATE_UINT8_V(end_transfer_fn_idx, IDEState, 4),
- VMSTATE_INT32_V(elementary_transfer_size, IDEState, 4),
- VMSTATE_INT32_V(packet_transfer_size, IDEState, 4),
VMSTATE_END_OF_LIST()
+ },
+ .subsections = (VMStateSubsection []) {
+ {
+ .vmsd = &vmstate_ide_drive_pio_state,
+ .needed = ide_drive_pio_state_needed,
+ }, {
+ /* empty */
+ }
}
};
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 4d95cc5e2..4331d7723 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -121,9 +121,31 @@ void bmdma_addr_writel(void *opaque, uint32_t addr, uint32_t val)
bm->cur_addr = bm->addr;
}
+static bool ide_bmdma_current_needed(void *opaque)
+{
+ BMDMAState *bm = opaque;
+
+ return (bm->cur_prd_len != 0);
+}
+
+static const VMStateDescription vmstate_bmdma_current = {
+ .name = "ide bmdma_current",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField []) {
+ VMSTATE_UINT32(cur_addr, BMDMAState),
+ VMSTATE_UINT32(cur_prd_last, BMDMAState),
+ VMSTATE_UINT32(cur_prd_addr, BMDMAState),
+ VMSTATE_UINT32(cur_prd_len, BMDMAState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+
static const VMStateDescription vmstate_bmdma = {
.name = "ide bmdma",
- .version_id = 4,
+ .version_id = 3,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.fields = (VMStateField []) {
@@ -133,11 +155,15 @@ static const VMStateDescription vmstate_bmdma = {
VMSTATE_INT64(sector_num, BMDMAState),
VMSTATE_UINT32(nsector, BMDMAState),
VMSTATE_UINT8(unit, BMDMAState),
- VMSTATE_UINT32_V(cur_addr, BMDMAState, 4),
- VMSTATE_UINT32_V(cur_prd_last, BMDMAState, 4),
- VMSTATE_UINT32_V(cur_prd_addr, BMDMAState, 4),
- VMSTATE_UINT32_V(cur_prd_len, BMDMAState, 4),
VMSTATE_END_OF_LIST()
+ },
+ .subsections = (VMStateSubsection []) {
+ {
+ .vmsd = &vmstate_bmdma_current,
+ .needed = ide_bmdma_current_needed,
+ }, {
+ /* empty */
+ }
}
};
@@ -156,7 +182,7 @@ static int ide_pci_post_load(void *opaque, int version_id)
const VMStateDescription vmstate_ide_pci = {
.name = "ide",
- .version_id = 4,
+ .version_id = 3,
.minimum_version_id = 0,
.minimum_version_id_old = 0,
.post_load = ide_pci_post_load,
diff --git a/hw/mips_int.c b/hw/mips_int.c
index c30954caa..477f6abf9 100644
--- a/hw/mips_int.c
+++ b/hw/mips_int.c
@@ -24,22 +24,6 @@
#include "mips_cpudevs.h"
#include "cpu.h"
-/* Raise IRQ to CPU if necessary. It must be called every time the active
- IRQ may change */
-void cpu_mips_update_irq(CPUState *env)
-{
- if ((env->CP0_Status & (1 << CP0St_IE)) &&
- !(env->CP0_Status & (1 << CP0St_EXL)) &&
- !(env->CP0_Status & (1 << CP0St_ERL)) &&
- !(env->hflags & MIPS_HFLAG_DM)) {
- if ((env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) &&
- !(env->interrupt_request & CPU_INTERRUPT_HARD)) {
- cpu_interrupt(env, CPU_INTERRUPT_HARD);
- }
- } else
- cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
-}
-
static void cpu_mips_irq_request(void *opaque, int irq, int level)
{
CPUState *env = (CPUState *)opaque;
@@ -52,7 +36,12 @@ static void cpu_mips_irq_request(void *opaque, int irq, int level)
} else {
env->CP0_Cause &= ~(1 << (irq + CP0Ca_IP));
}
- cpu_mips_update_irq(env);
+
+ if (env->CP0_Cause & CP0Ca_IP_mask) {
+ cpu_interrupt(env, CPU_INTERRUPT_HARD);
+ } else {
+ cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
+ }
}
void cpu_mips_irq_init_cpu(CPUState *env)
@@ -65,3 +54,12 @@ void cpu_mips_irq_init_cpu(CPUState *env)
env->irq[i] = qi[i];
}
}
+
+void cpu_mips_soft_irq(CPUState *env, int irq, int level)
+{
+ if (irq < 0 || irq > 2) {
+ return;
+ }
+
+ qemu_set_irq(env->irq[irq], level);
+}
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 3a1c67023..9e4bac867 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -245,7 +245,7 @@ static QEMUMachine pc_machine_v0_12 = {
.compat_props = (GlobalProperty[]) {
{
.driver = "virtio-serial-pci",
- .property = "max_nr_ports",
+ .property = "max_ports",
.value = stringify(1),
},{
.driver = "virtio-serial-pci",
@@ -268,7 +268,7 @@ static QEMUMachine pc_machine_v0_11 = {
.value = stringify(0),
},{
.driver = "virtio-serial-pci",
- .property = "max_nr_ports",
+ .property = "max_ports",
.value = stringify(1),
},{
.driver = "virtio-serial-pci",
@@ -307,7 +307,7 @@ static QEMUMachine pc_machine_v0_10 = {
.value = stringify(PCI_CLASS_DISPLAY_OTHER),
},{
.driver = "virtio-serial-pci",
- .property = "max_nr_ports",
+ .property = "max_ports",
.value = stringify(1),
},{
.driver = "virtio-serial-pci",
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index 79eb0b357..74cc56a34 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -187,7 +187,7 @@ static QEMUMachine bamboo_machine_v0_12 = {
.compat_props = (GlobalProperty[]) {
{
.driver = "virtio-serial-pci",
- .property = "max_nr_ports",
+ .property = "max_ports",
.value = stringify(1),
},{
.driver = "virtio-serial-pci",
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index d69c74c4e..b860a09ed 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -142,6 +142,7 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t l
req->tag = tag;
req->lun = lun;
req->status = -1;
+ req->enqueued = true;
QTAILQ_INSERT_TAIL(&d->requests, req, next);
return req;
}
@@ -158,9 +159,17 @@ SCSIRequest *scsi_req_find(SCSIDevice *d, uint32_t tag)
return NULL;
}
+static void scsi_req_dequeue(SCSIRequest *req)
+{
+ if (req->enqueued) {
+ QTAILQ_REMOVE(&req->dev->requests, req, next);
+ req->enqueued = false;
+ }
+}
+
void scsi_req_free(SCSIRequest *req)
{
- QTAILQ_REMOVE(&req->dev->requests, req, next);
+ scsi_req_dequeue(req);
qemu_free(req);
}
@@ -512,6 +521,7 @@ void scsi_req_print(SCSIRequest *req)
void scsi_req_complete(SCSIRequest *req)
{
assert(req->status != -1);
+ scsi_req_dequeue(req);
req->bus->complete(req->bus, SCSI_REASON_DONE,
req->tag,
req->status);
diff --git a/hw/scsi.h b/hw/scsi.h
index 4fbf1d5df..cb06d6d82 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -43,6 +43,7 @@ typedef struct SCSIRequest {
enum SCSIXferMode mode;
} cmd;
BlockDriverAIOCB *aiocb;
+ bool enqueued;
QTAILQ_ENTRY(SCSIRequest) next;
} SCSIRequest;
diff --git a/hw/vhost.c b/hw/vhost.c
index d37a66e0e..65709d005 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -659,6 +659,16 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
r = -errno;
goto fail;
}
+ for (i = 0; i < hdev->nvqs; ++i) {
+ r = vhost_virtqueue_init(hdev,
+ vdev,
+ hdev->vqs + i,
+ i);
+ if (r < 0) {
+ goto fail_vq;
+ }
+ }
+
if (hdev->log_enabled) {
hdev->log_size = vhost_get_log_size(hdev);
hdev->log = hdev->log_size ?
@@ -667,19 +677,10 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
(uint64_t)(unsigned long)hdev->log);
if (r < 0) {
r = -errno;
- goto fail;
- }
- }
-
- for (i = 0; i < hdev->nvqs; ++i) {
- r = vhost_virtqueue_init(hdev,
- vdev,
- hdev->vqs + i,
- i);
- if (r < 0) {
goto fail_vq;
}
}
+
hdev->started = true;
return 0;