diff options
author | Avi Kivity <avi@redhat.com> | 2010-05-09 14:05:19 +0300 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-05-09 14:05:19 +0300 |
commit | 4b1b0617b6f454b368a7f04786c0bc842253f849 (patch) | |
tree | 46842c3026a59c6431e9c236734666b5d7286836 /hw | |
parent | pci passthrough: zap option rom scanning. (diff) | |
parent | Update for 0.12.4 release (diff) | |
download | qemu-kvm-4b1b0617b6f454b368a7f04786c0bc842253f849.tar.gz qemu-kvm-4b1b0617b6f454b368a7f04786c0bc842253f849.tar.bz2 qemu-kvm-4b1b0617b6f454b368a7f04786c0bc842253f849.zip |
Merge commit 'v0.12.4' into stable-0.12qemu-kvm-0.12.4
* commit 'v0.12.4': (49 commits)
Update for 0.12.4 release
Workaround for broken OSS_GETVERSION on FreeBSD, part two
oss: fix fragment setting
oss: issue OSS_GETVERSION ioctl only when needed
oss: refactor code around policy setting
oss: workaround for cases when OSS_GETVERSION is not defined
block: Free iovec arrays allocated by multiwrite_merge()
lsi: fix segfault in lsi_command_complete
lsi: pass lsi_request to lsi_reselect
lsi: move dma_len+dma_buf into lsi_request
lsi: move current_dev into lsi_request
lsi: have lsi_request for the whole life time of the request.
lsi: use QTAILQ for lsi_queue
tcp/mips: Change TCG_AREG0 (fp -> s0)
sh_pci: fix memory and I/O access
Fix incoming migration with iothread
Fix SIGFPE for vnc display of width/height = 1
net: remove broken net_set_boot_mask() boot device validation
qcow2: Remove request from in-flight list after error
qcow2: Don't ignore immediate read/write failures
...
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/fdc.c | 20 | ||||
-rw-r--r-- | hw/fw_cfg.c | 2 | ||||
-rw-r--r-- | hw/ide/cmd646.c | 7 | ||||
-rw-r--r-- | hw/ide/internal.h | 1 | ||||
-rw-r--r-- | hw/ide/piix.c | 1 | ||||
-rw-r--r-- | hw/lsi53c895a.c | 176 | ||||
-rw-r--r-- | hw/scsi-disk.c | 4 | ||||
-rw-r--r-- | hw/sh7750.c | 7 | ||||
-rw-r--r-- | hw/sh_pci.c | 111 | ||||
-rw-r--r-- | hw/usb-uhci.c | 7 |
10 files changed, 131 insertions, 205 deletions
@@ -1860,8 +1860,12 @@ fdctrl_t *fdctrl_init_isa(DriveInfo **fds) ISADevice *dev; dev = isa_create("isa-fdc"); - qdev_prop_set_drive(&dev->qdev, "driveA", fds[0]); - qdev_prop_set_drive(&dev->qdev, "driveB", fds[1]); + if (fds[0]) { + qdev_prop_set_drive(&dev->qdev, "driveA", fds[0]); + } + if (fds[1]) { + qdev_prop_set_drive(&dev->qdev, "driveB", fds[1]); + } if (qdev_init(&dev->qdev) < 0) return NULL; return &(DO_UPCAST(fdctrl_isabus_t, busdev, dev)->state); @@ -1879,8 +1883,12 @@ fdctrl_t *fdctrl_init_sysbus(qemu_irq irq, int dma_chann, sys = DO_UPCAST(fdctrl_sysbus_t, busdev.qdev, dev); fdctrl = &sys->state; fdctrl->dma_chann = dma_chann; /* FIXME */ - qdev_prop_set_drive(dev, "driveA", fds[0]); - qdev_prop_set_drive(dev, "driveB", fds[1]); + if (fds[0]) { + qdev_prop_set_drive(dev, "driveA", fds[0]); + } + if (fds[1]) { + qdev_prop_set_drive(dev, "driveB", fds[1]); + } qdev_init_nofail(dev); sysbus_connect_irq(&sys->busdev, 0, irq); sysbus_mmio_map(&sys->busdev, 0, mmio_base); @@ -1896,7 +1904,9 @@ fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base, fdctrl_t *fdctrl; dev = qdev_create(NULL, "SUNW,fdtwo"); - qdev_prop_set_drive(dev, "drive", fds[0]); + if (fds[0]) { + qdev_prop_set_drive(dev, "drive", fds[0]); + } qdev_init_nofail(dev); sys = DO_UPCAST(fdctrl_sysbus_t, busdev.qdev, dev); fdctrl = &sys->state; diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c index ea120ba55..c62bf522d 100644 --- a/hw/fw_cfg.c +++ b/hw/fw_cfg.c @@ -179,7 +179,7 @@ static int get_uint32_as_uint16(QEMUFile *f, void *pv, size_t size) static void put_unused(QEMUFile *f, void *pv, size_t size) { - fprintf(stderr, "uint32_as_uint16 is only used for backward compatibilty.\n"); + fprintf(stderr, "uint32_as_uint16 is only used for backward compatibility.\n"); fprintf(stderr, "This functions shouldn't be called.\n"); } diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index e1e626e2a..835c98d72 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -70,11 +70,7 @@ static void ide_map(PCIDevice *pci_dev, int region_num, static PCIIDEState *pci_from_bm(BMDMAState *bm) { - if (bm->unit == 0) { - return container_of(bm, PCIIDEState, bmdma[0]); - } else { - return container_of(bm, PCIIDEState, bmdma[1]); - } + return bm->pci_dev; } static uint32_t bmdma_readb(void *opaque, uint32_t addr) @@ -145,6 +141,7 @@ static void bmdma_map(PCIDevice *pci_dev, int region_num, BMDMAState *bm = &d->bmdma[i]; d->bus[i].bmdma = bm; bm->bus = d->bus+i; + bm->pci_dev = d; qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm); register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm); diff --git a/hw/ide/internal.h b/hw/ide/internal.h index 8869a0834..8615d1a1f 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -481,6 +481,7 @@ struct BMDMAState { uint8_t status; uint32_t addr; + struct PCIIDEState *pci_dev; IDEBus *bus; /* current transfer state */ uint32_t cur_addr; diff --git a/hw/ide/piix.c b/hw/ide/piix.c index de3648023..2776ac365 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -78,6 +78,7 @@ static void bmdma_map(PCIDevice *pci_dev, int region_num, BMDMAState *bm = &d->bmdma[i]; d->bus[i].bmdma = bm; bm->bus = d->bus+i; + bm->pci_dev = d; qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm); register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm); diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index 014c85dbd..e0ade1e54 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -173,11 +173,15 @@ do { fprintf(stderr, "lsi_scsi: error: " fmt , ## __VA_ARGS__);} while (0) /* Flag set if this is a tagged command. */ #define LSI_TAG_VALID (1 << 16) -typedef struct { +typedef struct lsi_request { uint32_t tag; + SCSIDevice *dev; + uint32_t dma_len; + uint8_t *dma_buf; uint32_t pending; int out; -} lsi_queue; + QTAILQ_ENTRY(lsi_request) next; +} lsi_request; typedef struct { PCIDevice dev; @@ -198,16 +202,13 @@ typedef struct { * 3 if a DMA operation is in progress. */ int waiting; SCSIBus bus; - SCSIDevice *current_dev; + SCSIDevice *select_dev; int current_lun; /* The tag is a combination of the device ID and the SCSI tag. */ - uint32_t current_tag; - uint32_t current_dma_len; + uint32_t select_tag; int command_complete; - uint8_t *dma_buf; - lsi_queue *queue; - int queue_len; - int active_commands; + QTAILQ_HEAD(, lsi_request) queue; + lsi_request *current; uint32_t dsa; uint32_t temp; @@ -370,7 +371,7 @@ static int lsi_dma_64bit(LSIState *s) static uint8_t lsi_reg_readb(LSIState *s, int offset); static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val); static void lsi_execute_script(LSIState *s); -static void lsi_reselect(LSIState *s, uint32_t tag); +static void lsi_reselect(LSIState *s, lsi_request *p); static inline uint32_t read_dword(LSIState *s, uint32_t addr) { @@ -391,9 +392,9 @@ static void lsi_stop_script(LSIState *s) static void lsi_update_irq(LSIState *s) { - int i; int level; static int last_level; + lsi_request *p; /* It's unclear whether the DIP/SIP bits should be cleared when the Interrupt Status Registers are cleared or when istat0 is read. @@ -427,9 +428,9 @@ static void lsi_update_irq(LSIState *s) if (!level && lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON)) { DPRINTF("Handled IRQs & disconnected, looking for pending " "processes\n"); - for (i = 0; i < s->active_commands; i++) { - if (s->queue[i].pending) { - lsi_reselect(s, s->queue[i].tag); + QTAILQ_FOREACH(p, &s->queue, next) { + if (p->pending) { + lsi_reselect(s, p); break; } } @@ -508,15 +509,16 @@ static void lsi_do_dma(LSIState *s, int out) uint32_t count; target_phys_addr_t addr; - if (!s->current_dma_len) { + assert(s->current); + if (!s->current->dma_len) { /* Wait until data is available. */ DPRINTF("DMA no data available\n"); return; } count = s->dbc; - if (count > s->current_dma_len) - count = s->current_dma_len; + if (count > s->current->dma_len) + count = s->current->dma_len; addr = s->dnad; /* both 40 and Table Indirect 64-bit DMAs store upper bits in dnad64 */ @@ -532,29 +534,29 @@ static void lsi_do_dma(LSIState *s, int out) s->dnad += count; s->dbc -= count; - if (s->dma_buf == NULL) { - s->dma_buf = s->current_dev->info->get_buf(s->current_dev, - s->current_tag); + if (s->current->dma_buf == NULL) { + s->current->dma_buf = s->current->dev->info->get_buf(s->current->dev, + s->current->tag); } /* ??? Set SFBR to first data byte. */ if (out) { - cpu_physical_memory_read(addr, s->dma_buf, count); + cpu_physical_memory_read(addr, s->current->dma_buf, count); } else { - cpu_physical_memory_write(addr, s->dma_buf, count); + cpu_physical_memory_write(addr, s->current->dma_buf, count); } - s->current_dma_len -= count; - if (s->current_dma_len == 0) { - s->dma_buf = NULL; + s->current->dma_len -= count; + if (s->current->dma_len == 0) { + s->current->dma_buf = NULL; if (out) { /* Write the data. */ - s->current_dev->info->write_data(s->current_dev, s->current_tag); + s->current->dev->info->write_data(s->current->dev, s->current->tag); } else { /* Request any remaining data. */ - s->current_dev->info->read_data(s->current_dev, s->current_tag); + s->current->dev->info->read_data(s->current->dev, s->current->tag); } } else { - s->dma_buf += count; + s->current->dma_buf += count; lsi_resume_script(s); } } @@ -563,15 +565,14 @@ static void lsi_do_dma(LSIState *s, int out) /* Add a command to the queue. */ static void lsi_queue_command(LSIState *s) { - lsi_queue *p; + lsi_request *p = s->current; DPRINTF("Queueing tag=0x%x\n", s->current_tag); - if (s->queue_len == s->active_commands) { - s->queue_len++; - s->queue = qemu_realloc(s->queue, s->queue_len * sizeof(lsi_queue)); - } - p = &s->queue[s->active_commands++]; - p->tag = s->current_tag; + assert(s->current != NULL); + assert(s->current->dma_len == 0); + QTAILQ_INSERT_TAIL(&s->queue, s->current, next); + s->current = NULL; + p->pending = 0; p->out = (s->sstat1 & PHASE_MASK) == PHASE_DO; } @@ -588,45 +589,29 @@ static void lsi_add_msg_byte(LSIState *s, uint8_t data) } /* Perform reselection to continue a command. */ -static void lsi_reselect(LSIState *s, uint32_t tag) +static void lsi_reselect(LSIState *s, lsi_request *p) { - lsi_queue *p; - int n; int id; - p = NULL; - for (n = 0; n < s->active_commands; n++) { - p = &s->queue[n]; - if (p->tag == tag) - break; - } - if (n == s->active_commands) { - BADF("Reselected non-existant command tag=0x%x\n", tag); - return; - } - id = (tag >> 8) & 0xf; + assert(s->current == NULL); + QTAILQ_REMOVE(&s->queue, p, next); + s->current = p; + + id = (p->tag >> 8) & 0xf; s->ssid = id | 0x80; /* LSI53C700 Family Compatibility, see LSI53C895A 4-73 */ if (!s->dcntl & LSI_DCNTL_COM) { s->sfbr = 1 << (id & 0x7); } DPRINTF("Reselected target %d\n", id); - s->current_dev = s->bus.devs[id]; - s->current_tag = tag; s->scntl1 |= LSI_SCNTL1_CON; lsi_set_phase(s, PHASE_MI); s->msg_action = p->out ? 2 : 3; - s->current_dma_len = p->pending; - s->dma_buf = NULL; + s->current->dma_len = p->pending; lsi_add_msg_byte(s, 0x80); - if (s->current_tag & LSI_TAG_VALID) { + if (s->current->tag & LSI_TAG_VALID) { lsi_add_msg_byte(s, 0x20); - lsi_add_msg_byte(s, tag & 0xff); - } - - s->active_commands--; - if (n != s->active_commands) { - s->queue[n] = s->queue[s->active_commands]; + lsi_add_msg_byte(s, p->tag & 0xff); } if (lsi_irq_on_rsl(s)) { @@ -638,10 +623,9 @@ static void lsi_reselect(LSIState *s, uint32_t tag) the device was reselected, nonzero if the IO is deferred. */ static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg) { - lsi_queue *p; - int i; - for (i = 0; i < s->active_commands; i++) { - p = &s->queue[i]; + lsi_request *p; + + QTAILQ_FOREACH(p, &s->queue, next) { if (p->tag == tag) { if (p->pending) { BADF("Multiple IO pending for tag %d\n", tag); @@ -656,10 +640,10 @@ static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg) (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON) && !(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP)))) { /* Reselect device. */ - lsi_reselect(s, tag); + lsi_reselect(s, p); return 0; } else { - DPRINTF("Queueing IO tag=0x%x\n", tag); + DPRINTF("Queueing IO tag=0x%x\n", tag); p->pending = arg; return 1; } @@ -687,11 +671,15 @@ static void lsi_command_complete(SCSIBus *bus, int reason, uint32_t tag, } else { lsi_set_phase(s, PHASE_ST); } + + qemu_free(s->current); + s->current = NULL; + lsi_resume_script(s); return; } - if (s->waiting == 1 || tag != s->current_tag || + if (s->waiting == 1 || !s->current || tag != s->current->tag || (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON))) { if (lsi_queue_tag(s, tag, arg)) return; @@ -699,7 +687,7 @@ static void lsi_command_complete(SCSIBus *bus, int reason, uint32_t tag, /* host adapter (re)connected */ DPRINTF("Data ready tag=0x%x len=%d\n", tag, arg); - s->current_dma_len = arg; + s->current->dma_len = arg; s->command_complete = 1; if (!s->waiting) return; @@ -721,14 +709,20 @@ static void lsi_do_command(LSIState *s) cpu_physical_memory_read(s->dnad, buf, s->dbc); s->sfbr = buf[0]; s->command_complete = 0; - n = s->current_dev->info->send_command(s->current_dev, s->current_tag, buf, - s->current_lun); + + assert(s->current == NULL); + s->current = qemu_mallocz(sizeof(lsi_request)); + s->current->tag = s->select_tag; + s->current->dev = s->select_dev; + + n = s->current->dev->info->send_command(s->current->dev, s->current->tag, buf, + s->current_lun); if (n > 0) { lsi_set_phase(s, PHASE_DI); - s->current_dev->info->read_data(s->current_dev, s->current_tag); + s->current->dev->info->read_data(s->current->dev, s->current->tag); } else if (n < 0) { lsi_set_phase(s, PHASE_DO); - s->current_dev->info->write_data(s->current_dev, s->current_tag); + s->current->dev->info->write_data(s->current->dev, s->current->tag); } if (!s->command_complete) { @@ -851,16 +845,16 @@ static void lsi_do_msgout(LSIState *s) } break; case 0x20: /* SIMPLE queue */ - s->current_tag |= lsi_get_msgbyte(s) | LSI_TAG_VALID; + s->select_tag |= lsi_get_msgbyte(s) | LSI_TAG_VALID; DPRINTF("SIMPLE queue tag=0x%x\n", s->current_tag & 0xff); break; case 0x21: /* HEAD of queue */ BADF("HEAD queue not implemented\n"); - s->current_tag |= lsi_get_msgbyte(s) | LSI_TAG_VALID; + s->select_tag |= lsi_get_msgbyte(s) | LSI_TAG_VALID; break; case 0x22: /* ORDERED queue */ BADF("ORDERED queue not implemented\n"); - s->current_tag |= lsi_get_msgbyte(s) | LSI_TAG_VALID; + s->select_tag |= lsi_get_msgbyte(s) | LSI_TAG_VALID; break; default: if ((msg & 0x80) == 0) { @@ -905,17 +899,17 @@ static void lsi_memcpy(LSIState *s, uint32_t dest, uint32_t src, int count) static void lsi_wait_reselect(LSIState *s) { - int i; + lsi_request *p; + DPRINTF("Wait Reselect\n"); - if (s->current_dma_len) - BADF("Reselect with pending DMA\n"); - for (i = 0; i < s->active_commands; i++) { - if (s->queue[i].pending) { - lsi_reselect(s, s->queue[i].tag); + + QTAILQ_FOREACH(p, &s->queue, next) { + if (p->pending) { + lsi_reselect(s, p); break; } } - if (s->current_dma_len == 0) { + if (s->current == NULL) { s->waiting = 1; } } @@ -1093,8 +1087,8 @@ again: /* ??? Linux drivers compain when this is set. Maybe it only applies in low-level mode (unimplemented). lsi_script_scsi_interrupt(s, LSI_SIST0_CMP, 0); */ - s->current_dev = s->bus.devs[id]; - s->current_tag = id << 8; + s->select_dev = s->bus.devs[id]; + s->select_tag = id << 8; s->scntl1 |= LSI_SCNTL1_CON; if (insn & (1 << 3)) { s->socl |= LSI_SOCL_ATN; @@ -2006,9 +2000,11 @@ static void lsi_pre_save(void *opaque) { LSIState *s = opaque; - assert(s->dma_buf == NULL); - assert(s->current_dma_len == 0); - assert(s->active_commands == 0); + if (s->current) { + assert(s->current->dma_buf == NULL); + assert(s->current->dma_len == 0); + } + assert(QTAILQ_EMPTY(&s->queue)); } static const VMStateDescription vmstate_lsi_scsi = { @@ -2101,8 +2097,6 @@ static int lsi_scsi_uninit(PCIDevice *d) cpu_unregister_io_memory(s->mmio_io_addr); cpu_unregister_io_memory(s->ram_io_addr); - qemu_free(s->queue); - return 0; } @@ -2138,9 +2132,7 @@ static int lsi_scsi_init(PCIDevice *dev) PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_mmio_mapfunc); pci_register_bar((struct PCIDevice *)s, 2, 0x2000, PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_ram_mapfunc); - s->queue = qemu_malloc(sizeof(lsi_queue)); - s->queue_len = 1; - s->active_commands = 0; + QTAILQ_INIT(&s->queue); lsi_soft_reset(s); diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index b34fbaa67..a79201213 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -434,7 +434,9 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) memcpy(&outbuf[16], "QEMU HARDDISK ", 16); } memcpy(&outbuf[8], "QEMU ", 8); - memcpy(&outbuf[32], s->version ? s->version : QEMU_VERSION, 4); + memset(&outbuf[32], 0, 4); + memcpy(&outbuf[32], s->version ? s->version : QEMU_VERSION, + MIN(4, strlen(s->version ? s->version : QEMU_VERSION))); /* Identify device as SCSI-3 rev 1. Some later commands are also implemented. */ outbuf[2] = 3; diff --git a/hw/sh7750.c b/hw/sh7750.c index 933bbc0c7..9c39f4b68 100644 --- a/hw/sh7750.c +++ b/hw/sh7750.c @@ -396,8 +396,11 @@ static void sh7750_mem_writel(void *opaque, target_phys_addr_t addr, portb_changed(s, temp); return; case SH7750_MMUCR_A7: - s->cpu->mmucr = mem_value; - return; + if (mem_value & MMUCR_TI) { + cpu_sh4_invalidate_tlb(s->cpu); + } + s->cpu->mmucr = mem_value & ~MMUCR_TI; + return; case SH7750_PTEH_A7: /* If asid changes, clear all registered tlb entries. */ if ((s->cpu->pteh & 0xff) != (mem_value & 0xff)) diff --git a/hw/sh_pci.c b/hw/sh_pci.c index abe4c7568..441879a9d 100644 --- a/hw/sh_pci.c +++ b/hw/sh_pci.c @@ -47,10 +47,15 @@ static void sh_pci_reg_write (void *p, target_phys_addr_t addr, uint32_t val) pcic->par = val; break; case 0x1c4: - pcic->mbr = val; + pcic->mbr = val & 0xff000001; break; case 0x1c8: - pcic->iobr = val; + if ((val & 0xfffc0000) != (pcic->iobr & 0xfffc0000)) { + cpu_register_physical_memory(pcic->iobr & 0xfffc0000, 0x40000, + IO_MEM_UNASSIGNED); + pcic->iobr = val & 0xfffc0001; + isa_mmio_init(pcic->iobr & 0xfffc0000, 0x40000); + } break; case 0x220: pci_data_write(pcic->bus, pcic->par, val, 4); @@ -66,89 +71,16 @@ static uint32_t sh_pci_reg_read (void *p, target_phys_addr_t addr) return le32_to_cpup((uint32_t*)(pcic->dev->config + addr)); case 0x1c0: return pcic->par; + case 0x1c4: + return pcic->mbr; + case 0x1c8: + return pcic->iobr; case 0x220: return pci_data_read(pcic->bus, pcic->par, 4); } return 0; } -static void sh_pci_data_write (SHPCIC *pcic, target_phys_addr_t addr, - uint32_t val, int size) -{ - pci_data_write(pcic->bus, addr + pcic->mbr, val, size); -} - -static uint32_t sh_pci_mem_read (SHPCIC *pcic, target_phys_addr_t addr, - int size) -{ - return pci_data_read(pcic->bus, addr + pcic->mbr, size); -} - -static void sh_pci_writeb (void *p, target_phys_addr_t addr, uint32_t val) -{ - sh_pci_data_write(p, addr, val, 1); -} - -static void sh_pci_writew (void *p, target_phys_addr_t addr, uint32_t val) -{ - sh_pci_data_write(p, addr, val, 2); -} - -static void sh_pci_writel (void *p, target_phys_addr_t addr, uint32_t val) -{ - sh_pci_data_write(p, addr, val, 4); -} - -static uint32_t sh_pci_readb (void *p, target_phys_addr_t addr) -{ - return sh_pci_mem_read(p, addr, 1); -} - -static uint32_t sh_pci_readw (void *p, target_phys_addr_t addr) -{ - return sh_pci_mem_read(p, addr, 2); -} - -static uint32_t sh_pci_readl (void *p, target_phys_addr_t addr) -{ - return sh_pci_mem_read(p, addr, 4); -} - -static int sh_pci_addr2port(SHPCIC *pcic, target_phys_addr_t addr) -{ - return addr + pcic->iobr; -} - -static void sh_pci_outb (void *p, target_phys_addr_t addr, uint32_t val) -{ - cpu_outb(sh_pci_addr2port(p, addr), val); -} - -static void sh_pci_outw (void *p, target_phys_addr_t addr, uint32_t val) -{ - cpu_outw(sh_pci_addr2port(p, addr), val); -} - -static void sh_pci_outl (void *p, target_phys_addr_t addr, uint32_t val) -{ - cpu_outl(sh_pci_addr2port(p, addr), val); -} - -static uint32_t sh_pci_inb (void *p, target_phys_addr_t addr) -{ - return cpu_inb(sh_pci_addr2port(p, addr)); -} - -static uint32_t sh_pci_inw (void *p, target_phys_addr_t addr) -{ - return cpu_inw(sh_pci_addr2port(p, addr)); -} - -static uint32_t sh_pci_inl (void *p, target_phys_addr_t addr) -{ - return cpu_inl(sh_pci_addr2port(p, addr)); -} - typedef struct { CPUReadMemoryFunc * const r[3]; CPUWriteMemoryFunc * const w[3]; @@ -159,21 +91,11 @@ static MemOp sh_pci_reg = { { NULL, NULL, sh_pci_reg_write }, }; -static MemOp sh_pci_mem = { - { sh_pci_readb, sh_pci_readw, sh_pci_readl }, - { sh_pci_writeb, sh_pci_writew, sh_pci_writel }, -}; - -static MemOp sh_pci_iop = { - { sh_pci_inb, sh_pci_inw, sh_pci_inl }, - { sh_pci_outb, sh_pci_outw, sh_pci_outl }, -}; - PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, void *opaque, int devfn_min, int nirq) { SHPCIC *p; - int mem, reg, iop; + int reg; p = qemu_mallocz(sizeof(SHPCIC)); p->bus = pci_register_bus(NULL, "pci", @@ -182,14 +104,11 @@ PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, p->dev = pci_register_device(p->bus, "SH PCIC", sizeof(PCIDevice), -1, NULL, NULL); reg = cpu_register_io_memory(sh_pci_reg.r, sh_pci_reg.w, p); - iop = cpu_register_io_memory(sh_pci_iop.r, sh_pci_iop.w, p); - mem = cpu_register_io_memory(sh_pci_mem.r, sh_pci_mem.w, p); cpu_register_physical_memory(0x1e200000, 0x224, reg); - cpu_register_physical_memory(0x1e240000, 0x40000, iop); - cpu_register_physical_memory(0x1d000000, 0x1000000, mem); cpu_register_physical_memory(0xfe200000, 0x224, reg); - cpu_register_physical_memory(0xfe240000, 0x40000, iop); - cpu_register_physical_memory(0xfd000000, 0x1000000, mem); + + p->iobr = 0xfe240000; + isa_mmio_init(p->iobr, 0x40000); pci_config_set_vendor_id(p->dev->config, PCI_VENDOR_ID_HITACHI); pci_config_set_device_id(p->dev->config, PCI_DEVICE_ID_HITACHI_SH7751R); diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c index dc52737ae..cfd77ebed 100644 --- a/hw/usb-uhci.c +++ b/hw/usb-uhci.c @@ -677,9 +677,6 @@ static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_ ret = async->packet.len; - if (td->ctrl & TD_CTRL_IOC) - *int_mask |= 0x01; - if (td->ctrl & TD_CTRL_IOS) td->ctrl &= ~TD_CTRL_ACTIVE; @@ -693,6 +690,8 @@ static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_ here. The docs are somewhat unclear, but win2k relies on this behavior. */ td->ctrl &= ~(TD_CTRL_ACTIVE | TD_CTRL_NAK); + if (td->ctrl & TD_CTRL_IOC) + *int_mask |= 0x01; if (pid == USB_TOKEN_IN) { if (len > max_len) { @@ -750,6 +749,8 @@ out: if (err == 0) { td->ctrl &= ~TD_CTRL_ACTIVE; s->status |= UHCI_STS_USBERR; + if (td->ctrl & TD_CTRL_IOC) + *int_mask |= 0x01; uhci_update_irq(s); } } |