diff options
author | Avi Kivity <avi@redhat.com> | 2009-12-03 14:30:07 +0200 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-12-03 14:30:07 +0200 |
commit | 60b28da0dbc522aa0e892fd02e9af425d0713d4f (patch) | |
tree | 0c760fff969c2d4ae462d40569068321b1fc5d06 | |
parent | fafd46eff229834a15496051acb8880848fcd8eb (diff) | |
parent | 35bfc7324e2e6946c4113ada5db30553a1a7c40b (diff) |
Merge commit 'v0.11.1' into stable-0.11qemu-kvm-0.11.1stable-0.11
* commit 'v0.11.1':
Update version and changelog for 0.11.1 release
fix I2C slave addressing
Revert "vga: do not resize the screen on hw_invalidate"
slirp: fix use-after-free
Fix sparc.ld
ELF codedump build failures
kvm: Move KVM mp_state accessors to i386-specific code
this patch fixes a typo where armv4l was incorrectly spelled arm4l,
net: disable draining tap queue in one go
pcnet: Restart poll timer on pcnet_start
Sparc32: Fix lance
mac99: fix segmentation fault on startup
usb-linux.c: fix buffer overflow
ARM host: fix generated blocks linking
qemu serial: lost tx irqs (affecting FreeBSD's new uart(4) driver)
exec-all.h: increase MAX_OP_PER_INSTR to 96 from 64
Conflicts:
net.c
Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r-- | Changelog | 17 | ||||
-rw-r--r-- | VERSION | 2 | ||||
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | exec-all.h | 6 | ||||
-rw-r--r-- | hw/i2c.c | 6 | ||||
-rw-r--r-- | hw/pcnet.c | 1 | ||||
-rw-r--r-- | hw/serial.c | 10 | ||||
-rw-r--r-- | hw/sun4m.c | 1 | ||||
-rw-r--r-- | hw/unin_pci.c | 2 | ||||
-rw-r--r-- | hw/vga.c | 6 | ||||
-rw-r--r-- | hw/vga_int.h | 1 | ||||
-rw-r--r-- | kvm-all.c | 20 | ||||
-rw-r--r-- | kvm.h | 3 | ||||
-rw-r--r-- | linux-user/elfload.c | 59 | ||||
-rw-r--r-- | net.c | 29 | ||||
-rw-r--r-- | slirp/mbuf.c | 2 | ||||
-rw-r--r-- | sparc.ld | 20 | ||||
-rw-r--r-- | target-i386/kvm.c | 20 | ||||
-rw-r--r-- | usb-linux.c | 12 |
19 files changed, 131 insertions, 88 deletions
@@ -1,3 +1,20 @@ +Version 0.11.1 + - fix I2C slave addressing (Juha Riihimäki) + - Revert "vga: do not resize the screen on hw_invalidate" (Aurelien Jarno) + - slirp: fix use-after-free (Mark McLoughlin) + - Fix sparc.ld (Blue Swirl) + - ELF codedump build failures (Laurent Desnogues) + - kvm: Move KVM mp_state accessors to i386-specific code (Hollis Blanchard) + - fix configure script with armv4l cpu (Laurent Desnogues) + - net: disable draining tap queue in one go (Mark McLoughlin) + - pcnet: Restart poll timer on pcnet_start (Jan Kiszka) + - Sparc32: Fix lance (Blue Swirl) + - mac99: fix segmentation fault on startup (Aurelien Jarno) + - usb-linux.c: fix buffer overflow (Jim Paris) + - ARM host: fix generated blocks linking (Laurent Desnogues) + - qemu serial: lost tx irqs (affecting FreeBSD's new uart(4) driver (Juergen Lock) + - exec-all.h: increase MAX_OP_PER_INSTR to 96 from 64 (Aurelien Jarno) + version 0.11.0 - fix rtc polling mode (Bernhard Kauer) - qcow2: order concurrent aio requests (Kevin Wolf) @@ -1 +1 @@ -0.11.0 +0.11.1 @@ -1638,7 +1638,7 @@ case "$cpu" in i386|x86_64|alpha|cris|hppa|ia64|m68k|microbaze|mips|mips64|ppc|ppc64|s390|sparc|sparc64) ARCH=$cpu ;; - armv4b|arm4l) + armv4b|armv4l) ARCH=arm ;; *) diff --git a/exec-all.h b/exec-all.h index 31ab7ad93..6439e3cc7 100644 --- a/exec-all.h +++ b/exec-all.h @@ -34,7 +34,7 @@ typedef struct TranslationBlock TranslationBlock; /* XXX: make safe guess about sizes */ -#define MAX_OP_PER_INSTR 64 +#define MAX_OP_PER_INSTR 96 /* A Call op needs up to 6 + 2N parameters (N = number of arguments). */ #define MAX_OPC_PARAM 10 #define OPC_BUF_SIZE 512 @@ -211,7 +211,9 @@ static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr #endif /* we could use a ldr pc, [pc, #-4] kind of branch and avoid the flush */ - *(uint32_t *)jmp_addr |= ((addr - (jmp_addr + 8)) >> 2) & 0xffffff; + *(uint32_t *)jmp_addr = + (*(uint32_t *)jmp_addr & ~0xffffff) + | (((addr - (jmp_addr + 8)) >> 2) & 0xffffff); #if QEMU_GNUC_PREREQ(4, 1) __clear_cache((char *) jmp_addr, (char *) jmp_addr + 4); @@ -81,9 +81,11 @@ int i2c_start_transfer(i2c_bus *bus, int address, int recv) i2c_slave *slave = NULL; LIST_FOREACH(qdev, &bus->qbus.children, sibling) { - slave = I2C_SLAVE_FROM_QDEV(qdev); - if (slave->address == address) + i2c_slave *candidate = I2C_SLAVE_FROM_QDEV(qdev); + if (candidate->address == address) { + slave = candidate; break; + } } if (!slave) diff --git a/hw/pcnet.c b/hw/pcnet.c index 22ab6beaf..008b71a53 100644 --- a/hw/pcnet.c +++ b/hw/pcnet.c @@ -936,6 +936,7 @@ static void pcnet_start(PCNetState *s) s->csr[0] &= ~0x0004; /* clear STOP bit */ s->csr[0] |= 0x0002; + pcnet_poll_timer(s); } static void pcnet_stop(PCNetState *s) diff --git a/hw/serial.c b/hw/serial.c index d70504bb0..498f4a0a1 100644 --- a/hw/serial.c +++ b/hw/serial.c @@ -195,12 +195,10 @@ static void serial_update_irq(SerialState *s) * this is not in the specification but is observed on existing * hardware. */ tmp_iir = UART_IIR_CTI; - } else if ((s->ier & UART_IER_RDI) && (s->lsr & UART_LSR_DR)) { - if (!(s->fcr & UART_FCR_FE)) { - tmp_iir = UART_IIR_RDI; - } else if (s->recv_fifo.count >= s->recv_fifo.itl) { - tmp_iir = UART_IIR_RDI; - } + } else if ((s->ier & UART_IER_RDI) && (s->lsr & UART_LSR_DR) && + (!(s->fcr & UART_FCR_FE) || + s->recv_fifo.count >= s->recv_fifo.itl)) { + tmp_iir = UART_IIR_RDI; } else if ((s->ier & UART_IER_THRI) && s->thr_ipending) { tmp_iir = UART_IIR_THRI; } else if ((s->ier & UART_IER_MSI) && (s->msr & UART_MSR_ANY_DELTA)) { diff --git a/hw/sun4m.c b/hw/sun4m.c index c810b3598..f39059588 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -374,6 +374,7 @@ static void lance_init(NICInfo *nd, target_phys_addr_t leaddr, dev = qdev_create(NULL, "lance"); dev->nd = nd; + qdev_prop_set_ptr(dev, "dma", dma_opaque); qdev_init(dev); s = sysbus_from_qdev(dev); sysbus_mmio_map(s, 0, leaddr); diff --git a/hw/unin_pci.c b/hw/unin_pci.c index 0ad0cd391..ca8d9a5c0 100644 --- a/hw/unin_pci.c +++ b/hw/unin_pci.c @@ -234,7 +234,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic) cpu_register_physical_memory(0xf0c00000, 0x1000, pci_mem_data); d = pci_register_device(s->bus, "Uni-north AGP", sizeof(PCIDevice), - 11 << 3, NULL, NULL); + 12 << 3, NULL, NULL); pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE); pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_UNI_N_AGP); d->config[0x08] = 0x00; // revision @@ -1844,8 +1844,7 @@ static void vga_update_display(void *opaque) if (ds_get_bits_per_pixel(s->ds) == 0) { /* nothing to do */ } else { - full_update = s->full_update; - s->full_update = 0; + full_update = 0; if (!(s->ar_index & 0x20)) { graphic_mode = GMODE_BLANK; } else { @@ -1878,7 +1877,8 @@ static void vga_invalidate_display(void *opaque) { VGAState *s = (VGAState *)opaque; - s->full_update = 1; + s->last_width = -1; + s->last_height = -1; } void vga_reset(void *opaque) diff --git a/hw/vga_int.h b/hw/vga_int.h index be174f3f3..1aaf5c547 100644 --- a/hw/vga_int.h +++ b/hw/vga_int.h @@ -158,7 +158,6 @@ typedef struct VGACommonState { uint32_t last_width, last_height; /* in chars or pixels */ uint32_t last_scr_width, last_scr_height; /* in pixels */ uint32_t last_depth; /* in bits */ - uint8_t full_update; uint8_t cursor_start, cursor_end; uint32_t cursor_offset; unsigned int (*rgb_to_pixel)(unsigned int r, @@ -194,26 +194,6 @@ err: return ret; } -int kvm_put_mp_state(CPUState *env) -{ - struct kvm_mp_state mp_state = { .mp_state = env->mp_state }; - - return kvm_vcpu_ioctl(env, KVM_SET_MP_STATE, &mp_state); -} - -int kvm_get_mp_state(CPUState *env) -{ - struct kvm_mp_state mp_state; - int ret; - - ret = kvm_vcpu_ioctl(env, KVM_GET_MP_STATE, &mp_state); - if (ret < 0) { - return ret; - } - env->mp_state = mp_state.mp_state; - return 0; -} - /* * dirty pages logging control */ @@ -74,9 +74,6 @@ int kvm_vm_ioctl(KVMState *s, int type, ...); int kvm_vcpu_ioctl(CPUState *env, int type, ...); -int kvm_get_mp_state(CPUState *env); -int kvm_put_mp_state(CPUState *env); - /* Arch specific hooks */ int kvm_arch_post_run(CPUState *env, struct kvm_run *run); diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 3a8268b78..dbadc51ec 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -134,13 +134,13 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i regs->rip = infop->entry; } -typedef target_ulong elf_greg_t; +typedef target_ulong target_elf_greg_t; typedef uint32_t target_uid_t; typedef uint32_t target_gid_t; typedef int32_t target_pid_t; #define ELF_NREG 27 -typedef elf_greg_t elf_gregset_t[ELF_NREG]; +typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG]; /* * Note that ELF_NREG should be 29 as there should be place for @@ -149,7 +149,7 @@ typedef elf_greg_t elf_gregset_t[ELF_NREG]; * * See linux kernel: arch/x86/include/asm/elf.h */ -static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env) +static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env) { (*regs)[0] = env->regs[15]; (*regs)[1] = env->regs[14]; @@ -211,13 +211,13 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i regs->edx = 0; } -typedef target_ulong elf_greg_t; +typedef target_ulong target_elf_greg_t; typedef uint16_t target_uid_t; typedef uint16_t target_gid_t; typedef int32_t target_pid_t; #define ELF_NREG 17 -typedef elf_greg_t elf_gregset_t[ELF_NREG]; +typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG]; /* * Note that ELF_NREG should be 19 as there should be place for @@ -226,7 +226,7 @@ typedef elf_greg_t elf_gregset_t[ELF_NREG]; * * See linux kernel: arch/x86/include/asm/elf.h */ -static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env) +static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env) { (*regs)[0] = env->regs[R_EBX]; (*regs)[1] = env->regs[R_ECX]; @@ -286,15 +286,15 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i regs->ARM_r10 = infop->start_data; } -typedef uint32_t elf_greg_t; +typedef uint32_t target_elf_greg_t; typedef uint16_t target_uid_t; typedef uint16_t target_gid_t; typedef int32_t target_pid_t; #define ELF_NREG 18 -typedef elf_greg_t elf_gregset_t[ELF_NREG]; +typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG]; -static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env) +static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env) { (*regs)[0] = env->regs[0]; (*regs)[1] = env->regs[1]; @@ -1725,7 +1725,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, /* * Definitions to generate Intel SVR4-like core files. - * These mostly have the same names as the SVR4 types with "elf_" + * These mostly have the same names as the SVR4 types with "target_elf_" * tacked on the front to prevent clashes with linux definitions, * and the typedef forms have been avoided. This is mostly like * the SVR4 structure, but more Linuxy, with things that Linux does @@ -1745,9 +1745,9 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, * Next you define type of register set used for dumping. ELF specification * says that it needs to be array of elf_greg_t that has size of ELF_NREG. * - * typedef <target_regtype> elf_greg_t; + * typedef <target_regtype> target_elf_greg_t; * #define ELF_NREG <number of registers> - * typedef elf_greg_t elf_gregset_t[ELF_NREG]; + * typedef taret_elf_greg_t target_elf_gregset_t[ELF_NREG]; * * Then define following types to match target types. Actual types can * be found from linux kernel (arch/<ARCH>/include/asm/posix_types.h): @@ -1759,7 +1759,8 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, * Last step is to implement target specific function that copies registers * from given cpu into just specified register set. Prototype is: * - * static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env); + * static void elf_core_copy_regs(taret_elf_gregset_t *regs, + * const CPUState *env); * * Parameters: * regs - copy register values into here (allocated and zeroed by caller) @@ -1779,14 +1780,14 @@ struct memelfnote { size_t notesz; }; -struct elf_siginfo { +struct target_elf_siginfo { int si_signo; /* signal number */ int si_code; /* extra code */ int si_errno; /* errno */ }; -struct elf_prstatus { - struct elf_siginfo pr_info; /* Info associated with signal */ +struct target_elf_prstatus { + struct target_elf_siginfo pr_info; /* Info associated with signal */ short pr_cursig; /* Current signal */ target_ulong pr_sigpend; /* XXX */ target_ulong pr_sighold; /* XXX */ @@ -1798,13 +1799,13 @@ struct elf_prstatus { struct target_timeval pr_stime; /* XXX System time */ struct target_timeval pr_cutime; /* XXX Cumulative user time */ struct target_timeval pr_cstime; /* XXX Cumulative system time */ - elf_gregset_t pr_reg; /* GP registers */ + target_elf_gregset_t pr_reg; /* GP registers */ int pr_fpvalid; /* XXX */ }; #define ELF_PRARGSZ (80) /* Number of chars for args */ -struct elf_prpsinfo { +struct target_elf_prpsinfo { char pr_state; /* numeric process state */ char pr_sname; /* char for pr_state */ char pr_zomb; /* zombie */ @@ -1821,7 +1822,7 @@ struct elf_prpsinfo { /* Here is the structure in which status of each thread is captured. */ struct elf_thread_status { TAILQ_ENTRY(elf_thread_status) ets_link; - struct elf_prstatus prstatus; /* NT_PRSTATUS */ + struct target_elf_prstatus prstatus; /* NT_PRSTATUS */ #if 0 elf_fpregset_t fpu; /* NT_PRFPREG */ struct task_struct *thread; @@ -1833,8 +1834,8 @@ struct elf_thread_status { struct elf_note_info { struct memelfnote *notes; - struct elf_prstatus *prstatus; /* NT_PRSTATUS */ - struct elf_prpsinfo *psinfo; /* NT_PRPSINFO */ + struct target_elf_prstatus *prstatus; /* NT_PRSTATUS */ + struct target_elf_prpsinfo *psinfo; /* NT_PRPSINFO */ TAILQ_HEAD(thread_list_head, elf_thread_status) thread_list; #if 0 @@ -1876,8 +1877,8 @@ static int vma_walker(void *priv, unsigned long start, unsigned long end, static void fill_elf_header(struct elfhdr *, int, uint16_t, uint32_t); static void fill_note(struct memelfnote *, const char *, int, unsigned int, void *); -static void fill_prstatus(struct elf_prstatus *, const TaskState *, int); -static int fill_psinfo(struct elf_prpsinfo *, const TaskState *); +static void fill_prstatus(struct target_elf_prstatus *, const TaskState *, int); +static int fill_psinfo(struct target_elf_prpsinfo *, const TaskState *); static void fill_auxv_note(struct memelfnote *, const TaskState *); static void fill_elf_note_phdr(struct elf_phdr *, int, off_t); static size_t note_size(const struct memelfnote *); @@ -1891,10 +1892,10 @@ static int write_note(struct memelfnote *, int); static int write_note_info(struct elf_note_info *, int); #ifdef BSWAP_NEEDED -static void bswap_prstatus(struct elf_prstatus *); -static void bswap_psinfo(struct elf_prpsinfo *); +static void bswap_prstatus(struct target_elf_prstatus *); +static void bswap_psinfo(struct target_elf_prpsinfo *); -static void bswap_prstatus(struct elf_prstatus *prstatus) +static void bswap_prstatus(struct target_elf_prstatus *prstatus) { prstatus->pr_info.si_signo = tswapl(prstatus->pr_info.si_signo); prstatus->pr_info.si_code = tswapl(prstatus->pr_info.si_code); @@ -1911,7 +1912,7 @@ static void bswap_prstatus(struct elf_prstatus *prstatus) prstatus->pr_fpvalid = tswap32(prstatus->pr_fpvalid); } -static void bswap_psinfo(struct elf_prpsinfo *psinfo) +static void bswap_psinfo(struct target_elf_prpsinfo *psinfo) { psinfo->pr_flag = tswapl(psinfo->pr_flag); psinfo->pr_uid = tswap16(psinfo->pr_uid); @@ -2105,7 +2106,7 @@ static size_t note_size(const struct memelfnote *note) return (note->notesz); } -static void fill_prstatus(struct elf_prstatus *prstatus, +static void fill_prstatus(struct target_elf_prstatus *prstatus, const TaskState *ts, int signr) { (void) memset(prstatus, 0, sizeof (*prstatus)); @@ -2120,7 +2121,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus, #endif } -static int fill_psinfo(struct elf_prpsinfo *psinfo, const TaskState *ts) +static int fill_psinfo(struct target_elf_prpsinfo *psinfo, const TaskState *ts) { char *filename, *base_filename; unsigned int i, len; @@ -1453,27 +1453,24 @@ static void tap_send(void *opaque) { TAPState *s = opaque; int size; + uint8_t *buf = s->buf; - do { - uint8_t *buf = s->buf; - - size = tap_read_packet(s->fd, s->buf, sizeof(s->buf)); - if (size <= 0) { - break; - } + size = tap_read_packet(s->fd, s->buf, sizeof(s->buf)); + if (size <= 0) { + return; + } #ifdef IFF_VNET_HDR - if (s->has_vnet_hdr && !s->using_vnet_hdr) { - buf += sizeof(struct virtio_net_hdr); - size -= sizeof(struct virtio_net_hdr); - } + if (s->has_vnet_hdr && !s->using_vnet_hdr) { + buf += sizeof(struct virtio_net_hdr); + size -= sizeof(struct virtio_net_hdr); + } #endif - size = qemu_send_packet_async(s->vc, buf, size, tap_send_completed); - if (size == 0) { - tap_read_poll(s, 0); - } - } while (size > 0); + size = qemu_send_packet_async(s->vc, buf, size, tap_send_completed); + if (size == 0) { + tap_read_poll(s, 0); + } } #ifdef TUNSETSNDBUF diff --git a/slirp/mbuf.c b/slirp/mbuf.c index 7652fea19..87508ba01 100644 --- a/slirp/mbuf.c +++ b/slirp/mbuf.c @@ -95,8 +95,8 @@ m_free(struct mbuf *m) * Either free() it or put it on the free list */ if (m->m_flags & M_DOFREE) { - free(m); m->slirp->mbuf_alloced--; + free(m); } else if ((m->m_flags & M_FREELIST) == 0) { insque(m,&m->slirp->m_freelist); m->m_flags = M_FREELIST; /* Clobber other flags */ @@ -66,6 +66,26 @@ SECTIONS .data1 : { *(.data1) } .tdata : { *(.tdata) } .tbss : { *(.tbss) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__fini_array_end = .); + } .ctors : { *(.ctors) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index cfa5b80d5..6037b20f3 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -665,6 +665,26 @@ static int kvm_get_msrs(CPUState *env) return 0; } +static int kvm_put_mp_state(CPUState *env) +{ + struct kvm_mp_state mp_state = { .mp_state = env->mp_state }; + + return kvm_vcpu_ioctl(env, KVM_SET_MP_STATE, &mp_state); +} + +static int kvm_get_mp_state(CPUState *env) +{ + struct kvm_mp_state mp_state; + int ret; + + ret = kvm_vcpu_ioctl(env, KVM_GET_MP_STATE, &mp_state); + if (ret < 0) { + return ret; + } + env->mp_state = mp_state.mp_state; + return 0; +} + int kvm_arch_put_registers(CPUState *env) { int ret; diff --git a/usb-linux.c b/usb-linux.c index 043f6b6ba..eb1c5f071 100644 --- a/usb-linux.c +++ b/usb-linux.c @@ -115,7 +115,7 @@ struct ctrl_struct { uint16_t offset; uint8_t state; struct usb_ctrlrequest req; - uint8_t buffer[1024]; + uint8_t buffer[2048]; }; typedef struct USBHostDevice { @@ -552,6 +552,7 @@ static int usb_host_handle_control(USBHostDevice *s, USBPacket *p) struct usbdevfs_urb *urb; AsyncURB *aurb; int ret, value, index; + int buffer_len; /* * Process certain standard device requests. @@ -580,6 +581,13 @@ static int usb_host_handle_control(USBHostDevice *s, USBPacket *p) /* The rest are asynchronous */ + buffer_len = 8 + s->ctrl.len; + if (buffer_len > sizeof(s->ctrl.buffer)) { + fprintf(stderr, "husb: ctrl buffer too small (%u > %lu)\n", + buffer_len, sizeof(s->ctrl.buffer)); + return USB_RET_STALL; + } + aurb = async_alloc(); aurb->hdev = s; aurb->packet = p; @@ -596,7 +604,7 @@ static int usb_host_handle_control(USBHostDevice *s, USBPacket *p) urb->endpoint = p->devep; urb->buffer = &s->ctrl.req; - urb->buffer_length = 8 + s->ctrl.len; + urb->buffer_length = buffer_len; urb->usercontext = s; |