static void usb_host_auto_check(void *unused);
static int usb_host_read_file(char *line, size_t line_size,
const char *device_file, const char *device_name);
-static int usb_linux_update_endp_table(USBHostDevice *s);
+static void usb_linux_update_endp_table(USBHostDevice *s);
static int usb_host_usbfs_type(USBHostDevice *s, USBPacket *p)
{
}
if (aurb->urb.type == USBDEVFS_URB_TYPE_CONTROL) {
- trace_usb_host_req_complete(s->bus_num, s->addr, p, p->status);
+ trace_usb_host_req_complete(s->bus_num, s->addr, p,
+ p->status, aurb->urb.actual_length);
usb_generic_async_ctrl_complete(&s->dev, p);
} else if (!aurb->more) {
- trace_usb_host_req_complete(s->bus_num, s->addr, p, p->status);
+ trace_usb_host_req_complete(s->bus_num, s->addr, p,
+ p->status, aurb->urb.actual_length);
usb_packet_complete(&s->dev, p);
}
}
p->ep->nr, p->iov.size);
if (!is_valid(s, p->pid, p->ep->nr)) {
- trace_usb_host_req_complete(s->bus_num, s->addr, p, USB_RET_NAK);
p->status = USB_RET_NAK;
+ trace_usb_host_req_complete(s->bus_num, s->addr, p,
+ p->status, p->actual_length);
return;
}
ret = ioctl(s->fd, USBDEVFS_CLEAR_HALT, &arg);
if (ret < 0) {
perror("USBDEVFS_CLEAR_HALT");
- trace_usb_host_req_complete(s->bus_num, s->addr, p, USB_RET_NAK);
p->status = USB_RET_NAK;
+ trace_usb_host_req_complete(s->bus_num, s->addr, p,
+ p->status, p->actual_length);
return;
}
clear_halt(s, p->pid, p->ep->nr);
switch(errno) {
case ETIMEDOUT:
- trace_usb_host_req_complete(s->bus_num, s->addr, p,
- USB_RET_NAK);
p->status = USB_RET_NAK;
+ trace_usb_host_req_complete(s->bus_num, s->addr, p,
+ p->status, p->actual_length);
break;
case EPIPE:
default:
- trace_usb_host_req_complete(s->bus_num, s->addr, p,
- USB_RET_STALL);
p->status = USB_RET_STALL;
+ trace_usb_host_req_complete(s->bus_num, s->addr, p,
+ p->status, p->actual_length);
}
return;
}
p->status = USB_RET_ASYNC;
}
-/* returns 1 on problem encountered or 0 for success */
-static int usb_linux_update_endp_table(USBHostDevice *s)
+static void usb_linux_update_endp_table(USBHostDevice *s)
{
static const char *tname[] = {
[USB_ENDPOINT_XFER_CONTROL] = "control",
if (d->bLength < 2) {
trace_usb_host_parse_error(s->bus_num, s->addr,
"descriptor too short");
- goto error;
+ return;
}
if (i + d->bLength > s->descr_len) {
trace_usb_host_parse_error(s->bus_num, s->addr,
"descriptor too long");
- goto error;
+ return;
}
switch (d->bDescriptorType) {
case 0:
trace_usb_host_parse_error(s->bus_num, s->addr,
"invalid descriptor type");
- goto error;
+ return;
case USB_DT_DEVICE:
if (d->bLength < 0x12) {
trace_usb_host_parse_error(s->bus_num, s->addr,
"device descriptor too short");
- goto error;
+ return;
}
v = (d->u.device.idVendor_hi << 8) | d->u.device.idVendor_lo;
p = (d->u.device.idProduct_hi << 8) | d->u.device.idProduct_lo;
if (d->bLength < 0x09) {
trace_usb_host_parse_error(s->bus_num, s->addr,
"config descriptor too short");
- goto error;
+ return;
}
configuration = d->u.config.bConfigurationValue;
active = (configuration == s->dev.configuration);
if (d->bLength < 0x09) {
trace_usb_host_parse_error(s->bus_num, s->addr,
"interface descriptor too short");
- goto error;
+ return;
}
interface = d->u.interface.bInterfaceNumber;
altsetting = d->u.interface.bAlternateSetting;
if (d->bLength < 0x07) {
trace_usb_host_parse_error(s->bus_num, s->addr,
"endpoint descriptor too short");
- goto error;
+ return;
}
devep = d->u.endpoint.bEndpointAddress;
pid = (devep & USB_DIR_IN) ? USB_TOKEN_IN : USB_TOKEN_OUT;
if (ep == 0) {
trace_usb_host_parse_error(s->bus_num, s->addr,
"invalid endpoint address");
- goto error;
+ return;
}
type = d->u.endpoint.bmAttributes & 0x3;
break;
}
}
- return 0;
-
-error:
- usb_ep_reset(&s->dev);
- return 1;
}
/*
}
usb_ep_init(&dev->dev);
- ret = usb_linux_update_endp_table(dev);
- if (ret) {
- goto fail;
- }
+ usb_linux_update_endp_table(dev);
if (speed == -1) {
struct usbdevfs_connectinfo ci;
}
static QEMUTimer *usb_auto_timer;
+static VMChangeStateEntry *usb_vmstate;
static int usb_host_auto_scan(void *opaque, int bus_num,
int addr, const char *port,
return 0;
}
+static void usb_host_vm_state(void *unused, int running, RunState state)
+{
+ if (running) {
+ usb_host_auto_check(unused);
+ }
+}
+
static void usb_host_auto_check(void *unused)
{
struct USBHostDevice *s;
}
}
+ if (!usb_vmstate) {
+ usb_vmstate = qemu_add_vm_change_state_handler(usb_host_vm_state, NULL);
+ }
if (!usb_auto_timer) {
usb_auto_timer = qemu_new_timer_ms(rt_clock, usb_host_auto_check, NULL);
if (!usb_auto_timer) {