[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] Large USB patch
From: |
Lonnie Mendez |
Subject: |
Re: [Qemu-devel] Large USB patch |
Date: |
Sun, 30 Apr 2006 15:56:52 -0500 |
User-agent: |
Mozilla Thunderbird 1.0.7 (X11/20050923) |
Attached is another patch to implement the said resume code. With
this patch, devices attached to windows xp guest are able to resume the
controller when necessary. Before, if a device was attached to the
usbhub and windows had the root hub set for power savings then the bus
would stay suspended.
It implements the function usb_wakeup_controller which can be called
with a USBDevice handle for the device that is causing the event.
--- a/qemu/hw/usb-uhci.c 2006-04-30 14:32:43.000000000 -0500
+++ b/qemu/hw/usb-uhci.c 2006-04-30 15:03:46.000000000 -0500
@@ -102,6 +102,7 @@
} UHCI_QH;
static int uhci_attach (USBDevice *hub, USBDevice *dev, int portnum);
+static void uhci_resume (void *opaque);
static void uhci_update_irq (UHCIState *s)
{
@@ -338,13 +339,6 @@
UHCIPort *port;
int i;
- // wakeup the controller if suspended
- if (s->cmd & UHCI_CMD_EGSM) {
- s->cmd |= UHCI_CMD_FGR;
- s->status |= UHCI_STS_RD;
- uhci_update_irq(s);
- }
-
if (dev) {
if( portnum >= NB_PORTS ) {
#ifdef DEBUG
@@ -385,6 +379,9 @@
port->ctrl |= UHCI_PORT_LSDA;
else
port->ctrl &= ~UHCI_PORT_LSDA;
+
+ uhci_resume(s);
+
/* send the attach message */
port->dev= dev;
port->dev->handle_msg (port->dev, USB_MSG_ATTACH);
@@ -401,6 +398,9 @@
port->ctrl &= ~UHCI_PORT_EN;
port->ctrl |= UHCI_PORT_ENC;
}
+
+ uhci_resume(s);
+
if (port->dev) {
/* send the detach message */
port->dev->handle_msg(port->dev, USB_MSG_DETACH);
@@ -412,6 +412,21 @@
}
}
+/* signal resume if controller suspended */
+static void uhci_resume (void *opaque)
+{
+ UHCIState *s = (UHCIState *)opaque;
+
+ if (!s)
+ return;
+
+ if (s->cmd & UHCI_CMD_EGSM) {
+ s->cmd |= UHCI_CMD_FGR;
+ s->status |= UHCI_STS_RD;
+ uhci_update_irq(s);
+ }
+}
+
static int uhci_broadcast_packet(UHCIState *s, uint8_t pid,
uint8_t devaddr, uint8_t devep,
uint8_t *data, int len)
@@ -732,6 +738,7 @@
dev->speed= USB_SPEED_FULL;
dev->state= USB_STATE_ATTACHED;
dev->handle_attach= &uhci_attach;
+ dev->handle_resume= &uhci_resume;
for(i = 0; i < NB_PORTS; i++) {
s->ports[i].dev= NULL;
}
--- a/qemu/hw/usb.h 2006-04-30 14:32:43.000000000 -0500
+++ b/qemu/hw/usb.h 2006-04-30 15:14:23.000000000 -0500
@@ -187,6 +187,7 @@
int (*handle_data) (USBDevice *dev, int pid, uint8_t devep,
uint8_t *data, int len);
int (*handle_attach) (USBDevice *hub, USBDevice *dev, int
portnum);
+ void (*handle_resume) (void *opaque);
};
/* Maximum of simultaneous USB Devices including all USB Controllers */
@@ -212,6 +213,9 @@
USBDevice* usb_find_device (char *path);
char* usb_find_name (USBDevice *device);
+/* resumes a suspended controller that given device is attached to */
+void usb_wakeup_controller(USBDevice *dev);
+
/* function which adds or removes the usb devices according to usb_tree */
int usb_update_devices (PCIBus *pci_bus);
/* functions which show info on the available usb devices - used by monitor.c*/
--- a/qemu/hw/usb.c 2006-04-30 14:32:43.000000000 -0500
+++ b/qemu/hw/usb.c 2006-04-30 15:14:35.000000000 -0500
@@ -401,6 +408,27 @@
}
}
+/* communicate resume to host controller */
+void usb_wakeup_controller(USBDevice *dev)
+{
+ USBTree *tree = usb_tree;
+ USBDevice *controller = NULL;
+ char bus_path[5];
+
+ if (dev == NULL)
+ return;
+
+ for (; tree != NULL; tree= tree->next) {
+ if (tree->dev == dev) { // have match - next find root controller
+ strncpy(bus_path, tree->path, 3);
+ controller = usb_find_device(bus_path);
+ if (controller && controller->handle_resume) // send resume if
implemented
+ controller->handle_resume(controller->opaque);
+ break;
+ }
+ }
+}
+
/* remove a usb device, the following steps are taken:
1. find the device
2. let his father know
@@ -608,6 +636,7 @@
dev->handle_msg= &usb_dummy_handle_msg;
dev->handle_data= &usb_dummy_handle_data;
dev->handle_attach= &usb_dummy_handle_attach;
+ dev->handle_resume= NULL;
}
return dev;
}
--- a/qemu/hw/usb-hub.c 2006-04-30 14:33:29.000000000 -0500
+++ b/qemu/hw/usb-hub.c 2006-04-30 15:13:22.000000000 -0500
@@ -212,12 +212,20 @@
port->wPortStatus |= PORT_STAT_LOW_SPEED;
else
port->wPortStatus &= ~PORT_STAT_LOW_SPEED;
+
+ if (hub->remote_wakeup)
+ usb_wakeup_controller(dev);
+
port->dev = dev;
port->dev->handle_msg (port->dev, USB_MSG_ATTACH);
return portnum;
} else {
port = &s->ports[portnum];
dev = port->dev;
+
+ if (hub->remote_wakeup)
+ usb_wakeup_controller(dev);
+
if (dev) {
port->wPortStatus &= ~PORT_STAT_CONNECTION;
port->wPortChange |= PORT_STAT_C_CONNECTION;
- Re: [Qemu-devel] Large USB patch, (continued)
- Re: [Qemu-devel] Large USB patch, nix . wie . weg, 2006/04/22
- Re: [Qemu-devel] Large USB patch, Lonnie Mendez, 2006/04/22
- Re: [Qemu-devel] Large USB patch, nix . wie . weg, 2006/04/22
- Re: [Qemu-devel] Large USB patch, Lonnie Mendez, 2006/04/22
- Re: [Qemu-devel] Large USB patch, nix . wie . weg, 2006/04/23
- Re: [Qemu-devel] Large USB patch, Lonnie Mendez, 2006/04/28
- Re: [Qemu-devel] Large USB patch, Lonnie Mendez, 2006/04/28
- Re: [Qemu-devel] Large USB patch, Lonnie Mendez, 2006/04/29
- Re: [Qemu-devel] Large USB patch,
Lonnie Mendez <=
- Re: [Qemu-devel] Large USB patch, nix . wie . weg, 2006/04/21
Re: [Qemu-devel] Large USB patch, nix . wie . weg, 2006/04/22
Re: [Qemu-devel] Large USB patch, Fabrice Bellard, 2006/04/23
[Qemu-devel] Update for cvs 2006-04-24, nix . wie . weg, 2006/04/24