mirror of https://github.com/xemu-project/xemu.git
Merge remote-tracking branch 'kraxel/usb.32' into staging
This commit is contained in:
commit
f04303743a
|
@ -528,6 +528,9 @@ USBDevice *usb_bt_init(HCIInfo *hci)
|
|||
if (!hci)
|
||||
return NULL;
|
||||
dev = usb_create_simple(NULL /* FIXME */, "usb-bt-dongle");
|
||||
if (!dev) {
|
||||
return NULL;
|
||||
}
|
||||
s = DO_UPCAST(struct USBBtState, dev, dev);
|
||||
s->dev.opaque = s;
|
||||
|
||||
|
|
29
hw/usb-bus.c
29
hw/usb-bus.c
|
@ -9,6 +9,7 @@ static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
|
|||
|
||||
static char *usb_get_dev_path(DeviceState *dev);
|
||||
static char *usb_get_fw_dev_path(DeviceState *qdev);
|
||||
static int usb_qdev_exit(DeviceState *qdev);
|
||||
|
||||
static struct BusInfo usb_bus_info = {
|
||||
.name = "USB",
|
||||
|
@ -75,12 +76,23 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
|
|||
dev->auto_attach = 1;
|
||||
QLIST_INIT(&dev->strings);
|
||||
rc = usb_claim_port(dev);
|
||||
if (rc == 0) {
|
||||
rc = dev->info->init(dev);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
if (rc == 0 && dev->auto_attach) {
|
||||
rc = dev->info->init(dev);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
if (dev->auto_attach) {
|
||||
rc = usb_device_attach(dev);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
err:
|
||||
usb_qdev_exit(qdev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -139,10 +151,17 @@ USBDevice *usb_create(USBBus *bus, const char *name)
|
|||
USBDevice *usb_create_simple(USBBus *bus, const char *name)
|
||||
{
|
||||
USBDevice *dev = usb_create(bus, name);
|
||||
int rc;
|
||||
|
||||
if (!dev) {
|
||||
hw_error("Failed to create USB device '%s'\n", name);
|
||||
error_report("Failed to create USB device '%s'\n", name);
|
||||
return NULL;
|
||||
}
|
||||
rc = qdev_init(&dev->qdev);
|
||||
if (rc < 0) {
|
||||
error_report("Failed to initialize USB device '%s'\n", name);
|
||||
return NULL;
|
||||
}
|
||||
qdev_init_nofail(&dev->qdev);
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
|
|
@ -437,37 +437,39 @@ struct EHCIState {
|
|||
} while(0)
|
||||
|
||||
static const char *ehci_state_names[] = {
|
||||
[ EST_INACTIVE ] = "INACTIVE",
|
||||
[ EST_ACTIVE ] = "ACTIVE",
|
||||
[ EST_EXECUTING ] = "EXECUTING",
|
||||
[ EST_SLEEPING ] = "SLEEPING",
|
||||
[ EST_WAITLISTHEAD ] = "WAITLISTHEAD",
|
||||
[ EST_FETCHENTRY ] = "FETCH ENTRY",
|
||||
[ EST_FETCHQH ] = "FETCH QH",
|
||||
[ EST_FETCHITD ] = "FETCH ITD",
|
||||
[ EST_ADVANCEQUEUE ] = "ADVANCEQUEUE",
|
||||
[ EST_FETCHQTD ] = "FETCH QTD",
|
||||
[ EST_EXECUTE ] = "EXECUTE",
|
||||
[ EST_WRITEBACK ] = "WRITEBACK",
|
||||
[ EST_HORIZONTALQH ] = "HORIZONTALQH",
|
||||
[EST_INACTIVE] = "INACTIVE",
|
||||
[EST_ACTIVE] = "ACTIVE",
|
||||
[EST_EXECUTING] = "EXECUTING",
|
||||
[EST_SLEEPING] = "SLEEPING",
|
||||
[EST_WAITLISTHEAD] = "WAITLISTHEAD",
|
||||
[EST_FETCHENTRY] = "FETCH ENTRY",
|
||||
[EST_FETCHQH] = "FETCH QH",
|
||||
[EST_FETCHITD] = "FETCH ITD",
|
||||
[EST_ADVANCEQUEUE] = "ADVANCEQUEUE",
|
||||
[EST_FETCHQTD] = "FETCH QTD",
|
||||
[EST_EXECUTE] = "EXECUTE",
|
||||
[EST_WRITEBACK] = "WRITEBACK",
|
||||
[EST_HORIZONTALQH] = "HORIZONTALQH",
|
||||
};
|
||||
|
||||
static const char *ehci_mmio_names[] = {
|
||||
[ CAPLENGTH ] = "CAPLENGTH",
|
||||
[ HCIVERSION ] = "HCIVERSION",
|
||||
[ HCSPARAMS ] = "HCSPARAMS",
|
||||
[ HCCPARAMS ] = "HCCPARAMS",
|
||||
[ USBCMD ] = "USBCMD",
|
||||
[ USBSTS ] = "USBSTS",
|
||||
[ USBINTR ] = "USBINTR",
|
||||
[ FRINDEX ] = "FRINDEX",
|
||||
[ PERIODICLISTBASE ] = "P-LIST BASE",
|
||||
[ ASYNCLISTADDR ] = "A-LIST ADDR",
|
||||
[ PORTSC_BEGIN ] = "PORTSC #0",
|
||||
[ PORTSC_BEGIN + 4] = "PORTSC #1",
|
||||
[ PORTSC_BEGIN + 8] = "PORTSC #2",
|
||||
[ PORTSC_BEGIN + 12] = "PORTSC #3",
|
||||
[ CONFIGFLAG ] = "CONFIGFLAG",
|
||||
[CAPLENGTH] = "CAPLENGTH",
|
||||
[HCIVERSION] = "HCIVERSION",
|
||||
[HCSPARAMS] = "HCSPARAMS",
|
||||
[HCCPARAMS] = "HCCPARAMS",
|
||||
[USBCMD] = "USBCMD",
|
||||
[USBSTS] = "USBSTS",
|
||||
[USBINTR] = "USBINTR",
|
||||
[FRINDEX] = "FRINDEX",
|
||||
[PERIODICLISTBASE] = "P-LIST BASE",
|
||||
[ASYNCLISTADDR] = "A-LIST ADDR",
|
||||
[PORTSC_BEGIN] = "PORTSC #0",
|
||||
[PORTSC_BEGIN + 4] = "PORTSC #1",
|
||||
[PORTSC_BEGIN + 8] = "PORTSC #2",
|
||||
[PORTSC_BEGIN + 12] = "PORTSC #3",
|
||||
[PORTSC_BEGIN + 16] = "PORTSC #4",
|
||||
[PORTSC_BEGIN + 20] = "PORTSC #5",
|
||||
[CONFIGFLAG] = "CONFIGFLAG",
|
||||
};
|
||||
|
||||
static const char *nr2str(const char **n, size_t len, uint32_t nr)
|
||||
|
|
22
hw/usb-hub.c
22
hw/usb-hub.c
|
@ -171,6 +171,8 @@ static void usb_hub_detach(USBPort *port1)
|
|||
USBHubState *s = port1->opaque;
|
||||
USBHubPort *port = &s->ports[port1->index];
|
||||
|
||||
usb_wakeup(&s->dev);
|
||||
|
||||
/* Let upstream know the device on this port is gone */
|
||||
s->dev.port->ops->child_detach(s->dev.port, port1->dev);
|
||||
|
||||
|
@ -220,7 +222,22 @@ static void usb_hub_complete(USBPort *port, USBPacket *packet)
|
|||
|
||||
static void usb_hub_handle_reset(USBDevice *dev)
|
||||
{
|
||||
/* XXX: do it */
|
||||
USBHubState *s = DO_UPCAST(USBHubState, dev, dev);
|
||||
USBHubPort *port;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_PORTS; i++) {
|
||||
port = s->ports + i;
|
||||
port->wPortStatus = PORT_STAT_POWER;
|
||||
port->wPortChange = 0;
|
||||
if (port->port.dev && port->port.dev->attached) {
|
||||
port->wPortStatus |= PORT_STAT_CONNECTION;
|
||||
port->wPortChange |= PORT_STAT_C_CONNECTION;
|
||||
if (port->port.dev->speed == USB_SPEED_LOW) {
|
||||
port->wPortStatus |= PORT_STAT_LOW_SPEED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int usb_hub_handle_control(USBDevice *dev, USBPacket *p,
|
||||
|
@ -495,9 +512,8 @@ static int usb_hub_initfn(USBDevice *dev)
|
|||
&port->port, s, i, &usb_hub_port_ops,
|
||||
USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
|
||||
usb_port_location(&port->port, dev->port, i+1);
|
||||
port->wPortStatus = PORT_STAT_POWER;
|
||||
port->wPortChange = 0;
|
||||
}
|
||||
usb_hub_handle_reset(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
25
usb-linux.c
25
usb-linux.c
|
@ -148,6 +148,25 @@ 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 int usb_host_do_reset(USBHostDevice *dev)
|
||||
{
|
||||
struct timeval s, e;
|
||||
uint32_t usecs;
|
||||
int ret;
|
||||
|
||||
gettimeofday(&s, NULL);
|
||||
ret = ioctl(dev->fd, USBDEVFS_RESET);
|
||||
gettimeofday(&e, NULL);
|
||||
usecs = (e.tv_sec - s.tv_sec) * 1000000;
|
||||
usecs += e.tv_usec - s.tv_usec;
|
||||
if (usecs > 1000000) {
|
||||
/* more than a second, something is fishy, broken usb device? */
|
||||
fprintf(stderr, "husb: device %d:%d reset took %d.%06d seconds\n",
|
||||
dev->bus_num, dev->addr, usecs / 1000000, usecs % 1000000);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct endp_data *get_endp(USBHostDevice *s, int pid, int ep)
|
||||
{
|
||||
struct endp_data *eps = pid == USB_TOKEN_IN ? s->ep_in : s->ep_out;
|
||||
|
@ -606,7 +625,7 @@ static void usb_host_handle_reset(USBDevice *dev)
|
|||
|
||||
trace_usb_host_reset(s->bus_num, s->addr);
|
||||
|
||||
ioctl(s->fd, USBDEVFS_RESET);
|
||||
usb_host_do_reset(s);;
|
||||
|
||||
usb_host_claim_interfaces(s, 0);
|
||||
usb_linux_update_endp_table(s);
|
||||
|
@ -1370,7 +1389,7 @@ static int usb_host_close(USBHostDevice *dev)
|
|||
if (dev->dev.attached) {
|
||||
usb_device_detach(&dev->dev);
|
||||
}
|
||||
ioctl(dev->fd, USBDEVFS_RESET);
|
||||
usb_host_do_reset(dev);
|
||||
close(dev->fd);
|
||||
dev->fd = -1;
|
||||
return 0;
|
||||
|
@ -1381,7 +1400,7 @@ static void usb_host_exit_notifier(struct Notifier *n, void *data)
|
|||
USBHostDevice *s = container_of(n, USBHostDevice, exit);
|
||||
|
||||
if (s->fd != -1) {
|
||||
ioctl(s->fd, USBDEVFS_RESET);
|
||||
usb_host_do_reset(s);;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue