* [Qemu-devel] Large USB patch
@ 2006-04-20 19:59 nix.wie.weg
2006-04-21 2:23 ` Lonnie Mendez
` (4 more replies)
0 siblings, 5 replies; 31+ messages in thread
From: nix.wie.weg @ 2006-04-20 19:59 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 3276 bytes --]
Hello everybody,
I have extended the USB support for Qemu. The patch is included and
compiles just fine against todays cvs repository. As explained below,
this patch touches 15 different files, which makes it not so easy to
keep it applying on that very fast developing project. Thats why I would
ask you to test it quickly and apply it to cvs as soon as possible.
With this patch applied I could detect a USB Epson Scanner and a USB
Epson Printer from Windows 98 + XP and I could even print pages with
the printer (see known problems below).
reasons for this patch:
I was looking for a way to address my USB printer with windows while
working on linux. As I started the work I had to recognize that my
printer was not even detected under qemu. So I started to work on it.
changes I made:
First I eliminated all potential error sources, which could be avoided.
One of these sources where the
1. usb-hub - which I transfered to an extra file usb-hub.c, then I
added the usb-libusb.c devices directly to the UHCI controller this
introduced the changes of 2)
2. I enhanced the usb add device potentialities so that you should be
able to add a device to the UHCI controller. This device can be a usb
hub or a usb device. Behind this device you can add another hub or
device ... (remember this feature is now theoretically possible but not
tested yet), this let to a new usb syntax:
#$ qemu -usb controller=uhci,busnum=001 device=host:2:3,addto=001:001
(the short form is:
#$ qemu -usb controller=uhci -usb device=host:2:3)
so you can build up a complete usb tree.
3. I changed the usb_generic_handle_packet() function and implemented a
state machine, which is able to handle the usb packets correct.
4. I changed the linux standard usb-host library to libusb. I personally
will always prefer a portable solution if possible.
5. I changed large parts of usb-libusb.c. Some changes were made because
I found the source very awkward, some others because I fixed errors and
some because I changed the general usb api (see item 2).
6. I tried to join as many usb functions as possible to the usb related
files. So that hopefully nobody has to change 15 files again.
7. I made minor changes to usb-uhci - mainly I applied the new api and
changed the handling of special messages like usb_reset or usb_attach
8. I made the necessary changes to usb-hid.c and usb-hub.c
9. I wrote a lot of source comments
this patch breaks some things:
Sorry guys but I could not fix all of it, so I need your help, I didn't
want to destroy anybodys work, but the new api makes it necessary to
change some files:
1. usb-linux.c and usb-bsd.c will not work without adoption of the new api
2. I did not test usb-hid and usb-hub
known problems:
1. under linux the uhci controller reports an error if no usb device is
connected
2. the printer and the scanner are recognized under Windows 98/XP and
Linux, but the scanner goes into STALL state as soon as a packet in
usb_write_bulk() or usb_read_bulk()
3. the libusb usb_host_reset() function does not work as expected and I
don't know why (i have commented out this part of the source)
4. the printer stops printing on large images and is then in a state,
where it will not resume his work (probably a timing issue)
With kind regards,
Tino H. Seifert
[-- Attachment #2: usb-2006-04-20.patch.gz --]
[-- Type: application/x-gunzip, Size: 32699 bytes --]
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-20 19:59 [Qemu-devel] Large USB patch nix.wie.weg
@ 2006-04-21 2:23 ` Lonnie Mendez
2006-04-21 5:59 ` nix.wie.weg
2006-04-21 14:53 ` Lonnie Mendez
` (3 subsequent siblings)
4 siblings, 1 reply; 31+ messages in thread
From: Lonnie Mendez @ 2006-04-21 2:23 UTC (permalink / raw)
To: qemu-devel
nix.wie.weg@gmx.de wrote:
>With this patch applied I could detect a USB Epson Scanner and a USB
>Epson Printer from Windows 98 + XP and I could even print pages with
>the printer (see known problems below).
>
>reasons for this patch:
>I was looking for a way to address my USB printer with windows while
>working on linux. As I started the work I had to recognize that my
>printer was not even detected under qemu. So I started to work on it.
>
>
Are you sure such vast changes are necessary? What was it exactly
that happened when you attached the printer/scanner? I'd be interested
in seeing a packet log without all the changes that seem to "break stuff."
>changes I made:
>First I eliminated all potential error sources, which could be avoided.
>One of these sources where the
>
>1. usb-hub - which I transfered to an extra file usb-hub.c, then I
>added the usb-libusb.c devices directly to the UHCI controller this
>introduced the changes of 2)
>2. I enhanced the usb add device potentialities so that you should be
>able to add a device to the UHCI controller. This device can be a usb
>hub or a usb device. Behind this device you can add another hub or
>device ... (remember this feature is now theoretically possible but not
>tested yet), this let to a new usb syntax:
>#$ qemu -usb controller=uhci,busnum=001 device=host:2:3,addto=001:001
>(the short form is:
>#$ qemu -usb controller=uhci -usb device=host:2:3)
>so you can build up a complete usb tree.
>3. I changed the usb_generic_handle_packet() function and implemented a
>state machine, which is able to handle the usb packets correct.
>4. I changed the linux standard usb-host library to libusb. I personally
>will always prefer a portable solution if possible.
>5. I changed large parts of usb-libusb.c. Some changes were made because
>I found the source very awkward, some others because I fixed errors and
>some because I changed the general usb api (see item 2).
>6. I tried to join as many usb functions as possible to the usb related
>files. So that hopefully nobody has to change 15 files again.
>7. I made minor changes to usb-uhci - mainly I applied the new api and
>changed the handling of special messages like usb_reset or usb_attach
>8. I made the necessary changes to usb-hid.c and usb-hub.c
>9. I wrote a lot of source comments
>
>
I'm in favor of a new api but with only one controller there is
almost no point in doing this yet. It may make more sense to either be
able to specify either grabbing all or a few interfaces to proxy to the
guest. Also, libusb is ok for a generic handler, but there is no way
you'll get someone to jump through all the hoops necessary to get usb
working under windows with libusb-win32 or even mac os x. On win32 host
you have to manually create an inf file with the PID/VID and then
install that for every device you try to use. It's not a good idea to
use the filter driver unless the corresponding host driver is unbinded
(especially for mass storage). On mac os x you would supposedly creates
codeless kernel extensions with the PID/VID to unbind the device. That
could be done through scripts, but none exist.
Also keep in mind the people here probably don't know about the
all-in-one patch on my webserver. I've never posted about it here
except for on the user forums.
>this patch breaks some things:
>Sorry guys but I could not fix all of it, so I need your help, I didn't
>want to destroy anybodys work, but the new api makes it necessary to
>change some files:
>1. usb-linux.c and usb-bsd.c will not work without adoption of the new api
>2. I did not test usb-hid and usb-hub
>
>
I'll try to look at the patch this weekend.
>known problems:
>1. under linux the uhci controller reports an error if no usb device is
>connected
>2. the printer and the scanner are recognized under Windows 98/XP and
>Linux, but the scanner goes into STALL state as soon as a packet in
>usb_write_bulk() or usb_read_bulk()
>3. the libusb usb_host_reset() function does not work as expected and I
>don't know why (i have commented out this part of the source)
>
>
The reset function in libusb causes the device to have a new address
when it reconnects therefore forcing you to rescan and open the device
again. Perhaps this is the problem.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-21 2:23 ` Lonnie Mendez
@ 2006-04-21 5:59 ` nix.wie.weg
2006-04-21 7:04 ` Lonnie Mendez
0 siblings, 1 reply; 31+ messages in thread
From: nix.wie.weg @ 2006-04-21 5:59 UTC (permalink / raw)
To: qemu-devel
Hello Lonnie,
First, thank you for the answer.
Lonnie Mendez wrote:
> nix.wie.weg@gmx.de wrote:
>
>> printer was not even detected under qemu. So I started to work on it.
>>
> Are you sure such vast changes are necessary? What was it exactly
> that happened when you attached the printer/scanner? I'd be
> interested in seeing a packet log without all the changes that seem to
> "break stuff."
Yes I am absolutly sure we need this changes. The usb protocoll is a
very sophisticated work. There is an exactly defined sequence in which
packets are send. (I have made some small documentation about this:
http://217.20.126.200/tino/usb-order-of-events.pdf
http://217.20.126.200/tino/usb-order-of-events.odg)
If you do not keep track of this, you will never be able to get most
devices running. The qemu-specialcase-1.patch is the result of ignoring
these sequence. At the moment I'm not even sure, if we have to implement
the states in which a device is in (I mean default state, adress state
... USB Spec. 1.1 chapter 9).
>
>> changed the handling of special messages like usb_reset or usb_attach
>> 8. I made the necessary changes to usb-hid.c and usb-hub.c
>> 9. I wrote a lot of source comments
>>
>>
> I'm in favor of a new api but with only one controller there is
> almost no point in doing this yet.
Sorry I can't agree on that point with you. We will get more
controller/devices if we can provide an easy api for implementing them.
I would really be interrested to see an EHCI Controller - maybe I will
even implement it by myself.
> It may make more sense to either be able to specify either grabbing
> all or a few interfaces to proxy to the guest. Also, libusb is ok for
> a generic handler, but there is no way you'll get someone to jump
> through all the hoops necessary to get usb working under windows with
> libusb-win32 or even mac os x. On win32 host you have to manually
> create an inf file with the PID/VID and then install that for every
> device you try to use. It's not a good idea to use the filter driver
> unless the corresponding host driver is unbinded (especially for mass
> storage). On mac os x you would supposedly creates codeless kernel
> extensions with the PID/VID to unbind the device. That could be done
> through scripts, but none exist.
>
On that point you have probably misunderstood me. I dont want to
liquidate any native usb-host files. On the contrary, with that patch it
is easier to get more such native interfaces running. We could even
implement on some platforms more than one interface. I for instance
would like it, if I could have libusb and linux native support enabled
at the same time so I could make such things like:
$ qemu -usb controller=uhci -usb device=libusb:002:003,addto=001:001
-usb device=linux:001:002,addto=001:002
and it should now not be so difficult to implement.
> Also keep in mind the people here probably don't know about the
> all-in-one patch on my webserver. I've never posted about it here
> except for on the user forums.
>> this patch breaks some things:
>>
> I'll try to look at the patch this weekend.
Thanks
>> known problems:
> The reset function in libusb causes the device to have a new address
> when it reconnects therefore forcing you to rescan and open the device
> again. Perhaps this is the problem.
Yes I know this and I implemented it. But it does still not work. We get
a STALL on the devices when the code is enabled.
With kind regards
Tino H. Seifert
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-21 5:59 ` nix.wie.weg
@ 2006-04-21 7:04 ` Lonnie Mendez
0 siblings, 0 replies; 31+ messages in thread
From: Lonnie Mendez @ 2006-04-21 7:04 UTC (permalink / raw)
To: qemu-devel
nix.wie.weg@gmx.de wrote:
lo
>Yes I am absolutly sure we need this changes. The usb protocoll is a
>very sophisticated work. There is an exactly defined sequence in which
>packets are send. (I have made some small documentation about this:
>http://217.20.126.200/tino/usb-order-of-events.pdf
>http://217.20.126.200/tino/usb-order-of-events.odg)
>If you do not keep track of this, you will never be able to get most
>devices running. The qemu-specialcase-1.patch is the result of ignoring
>these sequence. At the moment I'm not even sure, if we have to implement
>the states in which a device is in (I mean default state, adress state
>... USB Spec. 1.1 chapter 9).
>
>
Well I'm glad someone took a deeper look at it. I never addressed it
as a correct solution to the problem. And indeed with the patch applied
the transaction log is clean.
>>>changed the handling of special messages like usb_reset or usb_attach
>>>8. I made the necessary changes to usb-hid.c and usb-hub.c
>>>9. I wrote a lot of source comments
>>>
>>>
>>>
>>>
>> I'm in favor of a new api but with only one controller there is
>>almost no point in doing this yet.
>>
>>
>Sorry I can't agree on that point with you. We will get more
>controller/devices if we can provide an easy api for implementing them.
>I would really be interrested to see an EHCI Controller - maybe I will
>even implement it by myself.
>
>
Sounds good. Not sure what I was going on about there.
>>It may make more sense to either be able to specify either grabbing
>>all or a few interfaces to proxy to the guest. Also, libusb is ok for
>>a generic handler, but there is no way you'll get someone to jump
>>through all the hoops necessary to get usb working under windows with
>>libusb-win32 or even mac os x. On win32 host you have to manually
>>create an inf file with the PID/VID and then install that for every
>>device you try to use. It's not a good idea to use the filter driver
>>unless the corresponding host driver is unbinded (especially for mass
>>storage). On mac os x you would supposedly creates codeless kernel
>>extensions with the PID/VID to unbind the device. That could be done
>>through scripts, but none exist.
>>
>>
>>
>On that point you have probably misunderstood me. I dont want to
>liquidate any native usb-host files. On the contrary, with that patch it
>is easier to get more such native interfaces running. We could even
>implement on some platforms more than one interface. I for instance
>would like it, if I could have libusb and linux native support enabled
>at the same time so I could make such things like:
>$ qemu -usb controller=uhci -usb device=libusb:002:003,addto=001:001
>-usb device=linux:001:002,addto=001:002
>and it should now not be so difficult to implement.
>
>
Yes, I have misunderstood you. It sounds like a good plan. I'll
ready the bsd redirector around the api tomorrow if possible. From some
limited testing it fails rather early on a linux guest so it shouldn't
be too hard to fix on that. There is quite a bit here and the person
that would merge this into CVS is Fabrice Bellard. He would have to
review all this before it ever touches CVS.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-20 19:59 [Qemu-devel] Large USB patch nix.wie.weg
2006-04-21 2:23 ` Lonnie Mendez
@ 2006-04-21 14:53 ` Lonnie Mendez
2006-04-21 15:00 ` Lonnie Mendez
2006-04-21 15:50 ` Lonnie Mendez
2006-04-22 14:15 ` nix.wie.weg
` (2 subsequent siblings)
4 siblings, 2 replies; 31+ messages in thread
From: Lonnie Mendez @ 2006-04-21 14:53 UTC (permalink / raw)
To: qemu-devel
nix.wie.weg@gmx.de wrote:
>this patch breaks some things:
>Sorry guys but I could not fix all of it, so I need your help, I didn't
>want to destroy anybodys work, but the new api makes it necessary to
>change some files:
>1. usb-linux.c and usb-bsd.c will not work without adoption of the new api
>
>
Looking at that now.
>2. I did not test usb-hid and usb-hub
>
>
There was a usb tablet device added recently. You may want to cvs up
to account for that.
>known problems:
>1. under linux the uhci controller reports an error if no usb device is
>connected
>
>
The port registers on the uhci controller shows no appropriate
response to an HCHALT command that is issued and so the hcd puts the
controller into global suspend.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-21 14:53 ` Lonnie Mendez
@ 2006-04-21 15:00 ` Lonnie Mendez
2006-04-21 15:50 ` Lonnie Mendez
1 sibling, 0 replies; 31+ messages in thread
From: Lonnie Mendez @ 2006-04-21 15:00 UTC (permalink / raw)
To: qemu-devel
Lonnie Mendez wrote:
>> 2. I did not test usb-hid and usb-hub
>>
>
> There was a usb tablet device added recently. You may want to cvs
> up to account for that.
>
Disregard that. Just saw it ;p
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-21 14:53 ` Lonnie Mendez
2006-04-21 15:00 ` Lonnie Mendez
@ 2006-04-21 15:50 ` Lonnie Mendez
2006-04-21 16:19 ` Lonnie Mendez
2006-04-21 16:26 ` nix.wie.weg
1 sibling, 2 replies; 31+ messages in thread
From: Lonnie Mendez @ 2006-04-21 15:50 UTC (permalink / raw)
To: qemu-devel
Lonnie Mendez wrote:
>> known problems:
>> 1. under linux the uhci controller reports an error if no usb device is
>> connected
>>
>
> The port registers on the uhci controller shows no appropriate
> response to an HCHALT command that is issued and so the hcd puts the
> controller into global suspend.
The problem is more likely that the controller is being suspended but
there is currently nothing being done to signal it to wake up on
appropriate events. If the error/warning message you got was something
like "controller still running" then changing uhci writew to always set
UHCI_STS_HCHALTED on writing 0 to bit 0 of cmd register seems to clear
the message. That means having the bit set in the frame is a bit
redundant and also makes the bit a less accurate indicator of hchalt.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-21 15:50 ` Lonnie Mendez
@ 2006-04-21 16:19 ` Lonnie Mendez
2006-04-21 16:29 ` nix.wie.weg
2006-04-21 16:26 ` nix.wie.weg
1 sibling, 1 reply; 31+ messages in thread
From: Lonnie Mendez @ 2006-04-21 16:19 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 107 bytes --]
lo. The attached patch applied on top of your patchset seems to work
as far as signaling resume goes.
[-- Attachment #2: qemu-usb-resume.diff --]
[-- Type: text/plain, Size: 1782 bytes --]
--- a/qemu/hw/usb-uhci.c 2006-04-21 11:15:40.000000000 -0500
+++ b/qemu/hw/usb-uhci.c 2006-04-21 11:17:08.000000000 -0500
@@ -32,6 +32,8 @@
// #define DEBUG
// #define DEBUG_PACKET
+#define UHCI_CMD_FGR (1 << 4)
+#define UHCI_CMD_EGSM (1 << 3)
#define UHCI_CMD_GRESET (1 << 2)
#define UHCI_CMD_HCRESET (1 << 1)
#define UHCI_CMD_RS (1 << 0)
@@ -109,7 +111,8 @@
((s->status & UHCI_STS_USBERR) && (s->intr & (1 << 0))) ||
((s->status & UHCI_STS_RD) && (s->intr & (1 << 1))) ||
(s->status & UHCI_STS_HSERR) ||
- (s->status & UHCI_STS_HCPERR)) {
+ (s->status & UHCI_STS_HCPERR) ||
+ ((s->status & UHCI_STS_RD) && (s->intr & (1 << 1)))) {
level = 1;
} else {
level = 0;
@@ -188,7 +191,7 @@
/* start frame processing */
qemu_mod_timer(s->frame_timer, qemu_get_clock(vm_clock));
s->status &= ~UHCI_STS_HCHALTED;
- } else if (!(val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
+ } else if (!(val & UHCI_CMD_RS)) {
s->status |= UHCI_STS_HCHALTED;
}
if (val & UHCI_CMD_GRESET) {
@@ -335,6 +338,14 @@
UHCIState *s = hub->opaque;
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
@@ -575,8 +586,6 @@
if (!(s->cmd & UHCI_CMD_RS)) {
qemu_del_timer(s->frame_timer);
- /* set hchalted bit in status - UHCI11D 2.1.2 */
- s->status |= UHCI_STS_HCHALTED;
return;
}
frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2);
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-21 15:50 ` Lonnie Mendez
2006-04-21 16:19 ` Lonnie Mendez
@ 2006-04-21 16:26 ` nix.wie.weg
1 sibling, 0 replies; 31+ messages in thread
From: nix.wie.weg @ 2006-04-21 16:26 UTC (permalink / raw)
To: qemu-devel
Hello,
Lonnie Mendez wrote:
> Lonnie Mendez wrote:
>
>>
>> The port registers on the uhci controller shows no appropriate
>> response to an HCHALT command that is issued and so the hcd puts the
>> controller into global suspend.
>
> The problem is more likely that the controller is being suspended
> but there is currently nothing being done to signal it to wake up on
> appropriate events. If the error/warning message you got was
> something like "controller still running" then changing uhci writew to
> always set UHCI_STS_HCHALTED on writing 0 to bit 0 of cmd register
> seems to clear the message. That means having the bit set in the
> frame is a bit redundant and also makes the bit a less accurate
> indicator of hchalt.
Yes this seems to be the case. I will take a look at it. Maybe I can get
the signaling correct. I will read the specification, what the correct
handling should be.
I must tell you: very impressive and fast error detection. I take my hat :)
With kind regards
Tino H. Seifert
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-21 16:19 ` Lonnie Mendez
@ 2006-04-21 16:29 ` nix.wie.weg
2006-04-21 17:28 ` Lonnie Mendez
0 siblings, 1 reply; 31+ messages in thread
From: nix.wie.weg @ 2006-04-21 16:29 UTC (permalink / raw)
To: qemu-devel
you are too fast for me :)
Lonnie Mendez wrote:
> lo. The attached patch applied on top of your patchset seems to
> work as far as signaling resume goes.
> ------------------------------------------------------------------------
>
>
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-21 16:29 ` nix.wie.weg
@ 2006-04-21 17:28 ` Lonnie Mendez
2006-04-21 18:06 ` Lonnie Mendez
0 siblings, 1 reply; 31+ messages in thread
From: Lonnie Mendez @ 2006-04-21 17:28 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 294 bytes --]
nix.wie.weg@gmx.de wrote:
>you are too fast for me :)
>
Had to rediff it. Fabrice already put the necessary bits in
uhci_update_irq. Right in front of my eyes too.
There is some funkiness going on with removing the device in the
linux guest once attached. Not sure what it is yet.
[-- Attachment #2: qemu-usb-resume.diff --]
[-- Type: text/plain, Size: 1387 bytes --]
--- a/qemu/hw/usb-uhci.c 2006-04-21 11:15:40.000000000 -0500
+++ b/qemu/hw/usb-uhci.c 2006-04-21 11:17:08.000000000 -0500
@@ -32,6 +32,8 @@
// #define DEBUG
// #define DEBUG_PACKET
+#define UHCI_CMD_FGR (1 << 4)
+#define UHCI_CMD_EGSM (1 << 3)
#define UHCI_CMD_GRESET (1 << 2)
#define UHCI_CMD_HCRESET (1 << 1)
#define UHCI_CMD_RS (1 << 0)
@@ -188,7 +191,7 @@
/* start frame processing */
qemu_mod_timer(s->frame_timer, qemu_get_clock(vm_clock));
s->status &= ~UHCI_STS_HCHALTED;
- } else if (!(val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
+ } else if (!(val & UHCI_CMD_RS)) {
s->status |= UHCI_STS_HCHALTED;
}
if (val & UHCI_CMD_GRESET) {
@@ -335,6 +338,14 @@
UHCIState *s = hub->opaque;
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
@@ -575,8 +586,6 @@
if (!(s->cmd & UHCI_CMD_RS)) {
qemu_del_timer(s->frame_timer);
- /* set hchalted bit in status - UHCI11D 2.1.2 */
- s->status |= UHCI_STS_HCHALTED;
return;
}
frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2);
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-21 17:28 ` Lonnie Mendez
@ 2006-04-21 18:06 ` Lonnie Mendez
2006-04-21 18:38 ` Lonnie Mendez
0 siblings, 1 reply; 31+ messages in thread
From: Lonnie Mendez @ 2006-04-21 18:06 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 200 bytes --]
Lonnie Mendez wrote:
> There is some funkiness going on with removing the device in the
> linux guest once attached. Not sure what it is yet.
This problem is addressed in the attached patch.
[-- Attachment #2: qemu-uhci-portdisc.diff --]
[-- Type: text/plain, Size: 539 bytes --]
--- a/qemu/hw/usb-uhci.c 2006-04-21 11:15:40.000000000 -0500
+++ b/qemu/hw/usb-uhci.c 2006-04-21 12:57:04.000000000 -0500
@@ -382,8 +392,9 @@
} else {
port = &s->ports[portnum];
/* set connect status */
- if (!(port->ctrl & UHCI_PORT_CCS)) {
- port->ctrl |= UHCI_PORT_CCS | UHCI_PORT_CSC;
+ if (port->ctrl & UHCI_PORT_CCS) {
+ port->ctrl &= ~UHCI_PORT_CCS;
+ port->ctrl |= UHCI_PORT_CSC;
}
/* disable port */
if (port->ctrl & UHCI_PORT_EN) {
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-21 18:06 ` Lonnie Mendez
@ 2006-04-21 18:38 ` Lonnie Mendez
2006-04-21 20:50 ` Lonnie Mendez
0 siblings, 1 reply; 31+ messages in thread
From: Lonnie Mendez @ 2006-04-21 18:38 UTC (permalink / raw)
To: qemu-devel
lo. A few more things to note in the current problems category:
-emulated devices don't seem to be interacting:
frame 36: pid=SETUP addr=0x00 ep=0 len=8
data_out= 80 06 00 01 00 00 40 00
frame 37: pid=SETUP addr=0x00 ep=0 len=8
data_out= 80 06 00 01 00 00 40 00
frame 38: pid=SETUP addr=0x00 ep=0 len=8
data_out= 80 06 00 01 00 00 40 00
-qemu segfaults after giving invalid string for device removal:
usb_add tablet
usb_del tablet
usb_del 001:001
This only happens with the emulated devices.
-performing usb_del on a valid string handle gives error message:
(qemu) usb_add host:001:021
(qemu) info usb
Controller 001: uhci
001:001 = host:001:021
Summary: 1 USB Controller, 1 USB Devices
(qemu) usb_del 001:001
Could not remove USB device '001:001'
(qemu) info usb
Controller 001: uhci
Summary: 1 USB Controller, 0 USB Devices
(qemu)
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-21 18:38 ` Lonnie Mendez
@ 2006-04-21 20:50 ` Lonnie Mendez
2006-04-22 9:33 ` nix.wie.weg
0 siblings, 1 reply; 31+ messages in thread
From: Lonnie Mendez @ 2006-04-21 20:50 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 457 bytes --]
Another patch. This one does a few things:
-fixes minor output bugs and some various OBO bugs
-adds some improvements to the emulated hub
-sets up the emulated devices to use the generic message handler (they
now work again)
-makes tablet device visible to usb_add
There are of course more bugs I've found. Namely being able to
usb_add any particular string with that string showing up as a new
device even though no valid entry for it exists.
[-- Attachment #2: lusb-upd1.diff --]
[-- Type: text/plain, Size: 6133 bytes --]
--- a/qemu/hw/usb.c 2006-04-21 11:15:40.000000000 -0500
+++ b/qemu/hw/usb.c 2006-04-21 15:27:19.000000000 -0500
@@ -455,6 +455,10 @@
/* we found a guest usb mouse */
tree->dev= usb_mouse_init ();
return add_usb_device (tree);
+ } else if (strcmp (tree->name,"tablet") == 0) {
+ /* we found a guest usb tablet */
+ tree->dev = usb_tablet_init ();
+ return add_usb_device (tree);
}
return 1;
}
@@ -491,6 +495,7 @@
usb_host_info();
usb_hub_info();
usb_mouse_info();
+ usb_tablet_info();
}
void usb_print_childs (USBTree *tree, int layer) {
--- a/qemu/hw/usb.h 2006-04-21 11:15:40.000000000 -0500
+++ b/qemu/hw/usb.h 2006-04-21 15:27:58.000000000 -0500
@@ -242,7 +242,9 @@
void usb_hub_info (void);
/* usb-hid.c */
USBDevice* usb_mouse_init (void);
+USBDevice* usb_tablet_init (void);
void usb_mouse_info (void);
+void usb_tablet_info (void);
/* The usb dummy device functions, they exist only to make it easier to
--- a/qemu/hw/usb-hub.c 2006-04-21 11:15:40.000000000 -0500
+++ b/qemu/hw/usb-hub.c 2006-04-21 15:23:05.000000000 -0500
@@ -165,9 +165,9 @@
0x0a, /* u16 wHubCharacteristics; */
0x00, /* (per-port OC, no power switching) */
0x01, /* u8 bPwrOn2pwrGood; 2ms */
- 0x00, /* u8 bHubContrCurrent; 0 mA */
- 0x00, /* u8 DeviceRemovable; *** 7 Ports max *** */
- 0xff /* u8 PortPwrCtrlMask; *** 7 ports max *** */
+ 0x00 /* u8 bHubContrCurrent; 0 mA */
+
+ /* DeviceRemovable and PortPwrCtrlMask patched in later */
};
static int usb_hub_attach (USBDevice *hub, USBDevice *dev, int portnum)
@@ -260,6 +260,12 @@
}
ret = 0;
break;
+ case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
+ if (value == 0 && index != 0x81) { /* clear ep halt */
+ goto fail;
+ }
+ ret = 0;
+ break;
case DeviceOutRequest | USB_REQ_SET_FEATURE:
if (value == USB_DEVICE_REMOTE_WAKEUP) {
dev->remote_wakeup = 1;
@@ -282,6 +288,11 @@
case USB_DT_CONFIG:
memcpy(data, qemu_hub_config_descriptor,
sizeof(qemu_hub_config_descriptor));
+
+ /* status change endpoint size based on number
+ * of ports */
+ data[22] = (s->nb_ports + 1 + 7) / 8;
+
ret = sizeof(qemu_hub_config_descriptor);
break;
case USB_DT_STRING:
@@ -427,11 +438,29 @@
}
break;
case GetHubDescriptor:
- memcpy(data, qemu_hub_hub_descriptor,
- sizeof(qemu_hub_hub_descriptor));
- data[2] = s->nb_ports;
- ret = sizeof(qemu_hub_hub_descriptor);
- break;
+ {
+ unsigned int n, limit, var_hub_size = 0;
+ memcpy(data, qemu_hub_hub_descriptor,
+ sizeof(qemu_hub_hub_descriptor));
+ data[2] = s->nb_ports;
+
+ /* fill DeviceRemovable bits */
+ limit = ((s->nb_ports + 1 + 7) / 8) + 7;
+ for (n = 7; n < limit; n++) {
+ data[n] = 0x00;
+ var_hub_size++;
+ }
+
+ /* fill PortPwrCtrlMask bits */
+ limit = limit + ((s->nb_ports + 7) / 8);
+ for (;n < limit; n++) {
+ data[n] = 0xff;
+ var_hub_size++;
+ }
+
+ ret = sizeof(qemu_hub_hub_descriptor) + var_hub_size;
+ break;
+ }
default:
fail:
ret = USB_RET_STALL;
@@ -453,8 +482,11 @@
unsigned int status;
int i, n;
n = (s->nb_ports + 1 + 7) / 8;
- if (n > len)
+ if (len == 1) { /* FreeBSD uhub workaround */
+ n = 1;
+ } else if (n > len) {
return USB_RET_BABBLE;
+ }
status = 0;
for(i = 0; i < s->nb_ports; i++) {
port = &s->ports[i];
@@ -467,7 +499,7 @@
}
ret = n;
} else {
- ret = 0;
+ ret = USB_RET_NAK; /* usb_20 11.12.1 */
}
} else {
goto fail;
@@ -541,6 +573,7 @@
return NULL;
dev->opaque= s;
dev->speed= USB_SPEED_FULL;
+ dev->handle_msg= usb_generic_handle_msg;
dev->handle_packet= usb_hub_handle_packet;
dev->handle_attach= usb_hub_attach;
dev->handle_reset= usb_hub_handle_reset;
@@ -558,5 +591,5 @@
void usb_hub_info(void) {
term_printf(" Device usbhub, Manufacturer QEMU, Product QEMU USB Hub\n" );
- term_printf (" VendorID:ProductID 0000:0000, USB-Standard: 01.01\n");
+ term_printf (" VendorID:ProductID 0000:0000, USB-Standard: 01.10\n");
}
--- a/qemu/hw/usb-hid.c 2006-04-21 11:15:40.000000000 -0500
+++ b/qemu/hw/usb-hid.c 2006-04-21 15:31:55.000000000 -0500
@@ -515,6 +515,7 @@
return NULL;
dev->opaque= s;
dev->speed= USB_SPEED_FULL;
+ dev->handle_msg= usb_generic_handle_msg;
dev->handle_packet= usb_generic_handle_packet;
dev->handle_reset= usb_mouse_handle_reset;
@@ -536,6 +539,7 @@
return NULL;
dev->opaque= s;
dev->speed= USB_SPEED_FULL;
+ dev->handle_msg= usb_generic_handle_msg;
dev->handle_packet= usb_generic_handle_packet;
dev->handle_reset= usb_mouse_handle_reset;
@@ -549,5 +553,10 @@
void usb_mouse_info() {
term_printf(" Device mouse, Manufacturer QEMU, Product QEMU USB Mouse\n" );
- term_printf (" VendorID:ProductID 2706:0001, USB-Standard: 01.00\n");
+ term_printf (" VendorID:ProductID 0627:0001, USB-Standard: 01.00\n");
+}
+
+void usb_tablet_info() {
+ term_printf(" Device tablet, Manufacturer QEMU, Product QEMU USB Tablet\n");
+ term_printf (" VendorID:ProductID 0627:0001, USB-Standard: 01.00\n");
}
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-21 20:50 ` Lonnie Mendez
@ 2006-04-22 9:33 ` nix.wie.weg
2006-04-22 14:36 ` Lonnie Mendez
0 siblings, 1 reply; 31+ messages in thread
From: nix.wie.weg @ 2006-04-22 9:33 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 455 bytes --]
Hello,
Lonnie Mendez wrote:
>
> There are of course more bugs I've found. Namely being able to
> usb_add any particular string with that string showing up as a new
> device even though no valid entry for it exists.
I have fixed this issue, also I have found the segfault on usb_del.
Patch is attached.
Next problem:
Linux does not recognize it, if I add a "tablet" while linux is allready
running. The attach is not delivered to the operating system.
[-- Attachment #2: lusb-upd2.diff --]
[-- Type: text/plain, Size: 4297 bytes --]
diff -Nur qemu-last-snapshot/hw/usb-hid.c qemu/hw/usb-hid.c
--- qemu-last-snapshot/hw/usb-hid.c 2006-04-22 10:23:40.000000000 +0200
+++ qemu/hw/usb-hid.c 2006-04-22 11:13:31.000000000 +0200
@@ -339,6 +339,13 @@
return 1;
}
+static int usb_mouse_handle_close(USBDevice *dev)
+{
+ USBMouseState *s = (USBMouseState *)dev->opaque;
+ qemu_free (s);
+ return 1;
+}
+
static int usb_mouse_handle_control(USBDevice *dev, int request, int value,
int index, int length, uint8_t *data)
{
@@ -541,6 +548,7 @@
dev->handle_packet= usb_generic_handle_packet;
dev->handle_reset= usb_mouse_handle_reset;
+ dev->handle_close= usb_mouse_handle_close;
dev->handle_control= usb_mouse_handle_control;
dev->handle_data= usb_mouse_handle_data;
s->kind= USB_MOUSE;
diff -Nur qemu-last-snapshot/hw/usb.c qemu/hw/usb.c
--- qemu-last-snapshot/hw/usb.c 2006-04-22 10:23:40.000000000 +0200
+++ qemu/hw/usb.c 2006-04-22 11:15:46.000000000 +0200
@@ -372,19 +372,27 @@
return 1;
USBDevice *dev= (*tree)->dev;
for (;tmp != NULL; tmp= tmp->next) {
- if( tmp == *tree ) {
+ if (tmp == *tree) {
+ if (dev != NULL){
+ if( dev->father != NULL &&
+ dev->father->handle_attach
+ (dev->father, NULL, dev->father_port) < 0) {
+#ifdef DEBUG
+ printf ("Could not dettach from father\n");
+#endif
+ return -1;
+ }
+ if (dev->handle_close(dev) < 0) {
+#ifdef DEBUG
+ printf ("Could not close device\n");
+#endif
+ return -2;
+ }
+ }
if( last != NULL ) {
last->next= (*tree)->next;
}
- if( dev != NULL && dev->father != NULL &&
- !dev->father->handle_attach
- (dev->father, NULL, dev->father_port)) {
- return -1;
- } else {
- if( dev != NULL && !dev->handle_close(dev) )
- return -2;
- }
- free (*tree);
+ qemu_free (*tree);
*tree= last;
return 1;
}
@@ -441,8 +449,11 @@
if( tree->dev == NULL ) {
usb_remove_device(&tree);
return -1;
+ } else {
+ return 0;
}
}
+ return -1;
} else if (strstr (tree->name, "host:") == tree->name) {
/* we found a host device */
tree->dev= usb_host_init (tree->name);
@@ -459,8 +470,10 @@
/* we found a guest usb tablet */
tree->dev = usb_tablet_init ();
return add_usb_device (tree);
- }
- return 1;
+ } else {
+ usb_remove_device(&tree);
+ return -1;
+ }
}
/* this function connects or removes devices according to usb_tree */
@@ -555,10 +568,11 @@
dev->setup_index= 0;
dev->handle_packet= &usb_dummy_handle_packet;
dev->handle_reset= &usb_dummy_handle_reset;
+ dev->handle_close= &usb_dummy_handle_close;
dev->handle_control= &usb_dummy_handle_control;
dev->handle_msg= &usb_dummy_handle_msg;
dev->handle_data= &usb_dummy_handle_data;
- dev->handle_attach= &usb_dummy_handle_attach;
+ dev->handle_attach= &usb_dummy_handle_attach;
}
return dev;
}
diff -Nur qemu-last-snapshot/vl.c qemu/vl.c
--- qemu-last-snapshot/vl.c 2006-04-22 10:23:40.000000000 +0200
+++ qemu/vl.c 2006-04-22 10:57:09.000000000 +0200
@@ -3274,6 +3274,7 @@
usb_tree= tmp;
tmp->next= NULL;
}
+ tmp->dev= NULL;
memcpy (tmp->name, devname, nameend-devname);
tmp->name[nameend-devname+1]= '\0';
memcpy (tmp->path, bus, 4);
@@ -3334,6 +3335,7 @@
last->next= qemu_malloc (sizeof (USBTree));
tree= last->next;
tree->next= NULL;
+ tree->dev= NULL;
strcpy (tree->name, name);
strcpy( tree->path, treepath );
tree->device_status= USB_ADD_DEVICE;
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-20 19:59 [Qemu-devel] Large USB patch nix.wie.weg
2006-04-21 2:23 ` Lonnie Mendez
2006-04-21 14:53 ` Lonnie Mendez
@ 2006-04-22 14:15 ` nix.wie.weg
2006-04-23 15:02 ` Fabrice Bellard
2006-04-24 23:50 ` [Qemu-devel] Update for cvs 2006-04-24 nix.wie.weg
4 siblings, 0 replies; 31+ messages in thread
From: nix.wie.weg @ 2006-04-22 14:15 UTC (permalink / raw)
To: qemu-devel
Hello,
I have made a new patch which includes all changes from yesterday,
because there were already inconsistencies Also attached is the log of
my USB scanner (The last lines are repeated for ever). It is recognized
but when the first bulk packet is send to it, I get a ETIMEDOUT Error
and I don't know why. I have already tried to give back a STALL and I
have also tried to clear the stall first ... .
With kind regards
Tino H. Seifert
patch:
http://217.20.126.200/tino/usb-2006-04-22.patch
scanner.log
http://217.20.126.200/tino/usb-scanner.log
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-22 9:33 ` nix.wie.weg
@ 2006-04-22 14:36 ` Lonnie Mendez
2006-04-22 15:36 ` nix.wie.weg
2006-04-22 16:00 ` nix.wie.weg
0 siblings, 2 replies; 31+ messages in thread
From: Lonnie Mendez @ 2006-04-22 14:36 UTC (permalink / raw)
To: qemu-devel
nix.wie.weg@gmx.de wrote:
>I have fixed this issue, also I have found the segfault on usb_del.
>Patch is attached.
>Next problem:
>Linux does not recognize it, if I add a "tablet" while linux is allready
>running. The attach is not delivered to the operating system.
>
>
Hm. There also seems to be some unchecked bounds when adding devices:
(qemu) usb_add host:001:021
Could not add USB Device 'host:001:021'
(qemu) info usb
Controller 001: uhci
001:001 = mouse
001:002 = tablet
001:001 = host:001:021
Summary: 1 USB Controller, 3 USB Devices
(qemu)
Also I've a question on where the emulated hub comes into play.
Specifically how do you currently add new devices to it? The ,addto
syntax doesn't seem to apply to the emulated hub as it takes a bus
address (the controller) and an address on the root hub. But the hub
itself would be centrally connected to a bus number identifying a
controller and not have its own. It seems we've presently traded a hub
with dynamic ports for 2 static ones. I'm glad there is a lot more
internal tracking here as with the previous system you could usb_add the
same host device several times and it wouldn't care. This should also
make it easier to reconnect the ps2 mouse when the hid mouse is dettached.
Adding a device by Vendor id and Product id doesn't seem to work. If
this is intentional then perhaps the functionality should be restored.
qemu users will find this convenient as it is a fixed/static
identification for a single usb device which is most likely going to be
the common usage.
In regards to the linux guest problem I'm not seeing it. On an older
debian SID install which is currently using linux kernel 2.6.14 all
seems well. The code here is merely the first patch combined with CVS
along with the already submitted patches. I'll try to find some
variation to test with. In which distro is this happening?
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-22 14:36 ` Lonnie Mendez
@ 2006-04-22 15:36 ` nix.wie.weg
2006-04-22 15:38 ` nix.wie.weg
2006-04-22 16:00 ` nix.wie.weg
1 sibling, 1 reply; 31+ messages in thread
From: nix.wie.weg @ 2006-04-22 15:36 UTC (permalink / raw)
To: qemu-devel
Hello Lonnie,
Lonnie Mendez wrote:
> nix.wie.weg@gmx.de wrote:
>
>> Next problem:
>> Linux does not recognize it, if I add a "tablet" while linux is allready
>> running. The attach is not delivered to the operating system.
I have solved the problem, it was located in a rejected diff. (it was
the reason I made the new patch earlier)
> (qemu) usb_add host:001:021
> Could not add USB Device 'host:001:021'
> (qemu) info usb
> Controller 001: uhci
> 001:001 = mouse
> 001:002 = tablet
> 001:001 = host:001:021
> Summary: 1 USB Controller, 3 USB Devices
> (qemu)
>
solved see attached patch.
> Also I've a question on where the emulated hub comes into play.
> Specifically how do you currently add new devices to it? The ,addto
> syntax doesn't seem to apply to the emulated hub as it takes a bus
> address (the controller) and an address on the root hub. But the hub
> itself would be centrally connected to a bus number identifying a
> controller and not have its own. It seems we've presently traded a
> hub with dynamic ports for 2 static ones. I'm glad there is a lot
> more internal tracking here as with the previous system you could
> usb_add the same host device several times and it wouldn't care. This
> should also make it easier to reconnect the ps2 mouse when the hid
> mouse is dettached.
>
Let me explain it on an example, lets assume you add
usb_add usbhub to 001:001
then you should be able (in fact it is absolutly untested)
usb_add host:2:3 to 001:001:001
it should even work something like:
usb_add usbhub to 001:001:002
usb_add host:2:2 to 001:001:002:001
you see, you build up a path. Maximum depth at the moment ist 8.
> Adding a device by Vendor id and Product id doesn't seem to work.
> If this is intentional then perhaps the functionality should be
> restored. qemu users will find this convenient as it is a
> fixed/static identification for a single usb device which is most
> likely going to be the common usage.
I aggree with that, and normaly it should work. The complete name
"host:AAAxBBB" is delivered to usb_host_init(), I will look at it.
> In regards to the linux guest problem I'm not seeing it. On an
> older debian SID install which is currently using linux kernel 2.6.14
> all seems well. The code here is merely the first patch combined with
> CVS along with the already submitted patches. I'll try to find some
> variation to test with. In which distro is this happening?
With kind regards,
Tino H. Seifert
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-22 15:36 ` nix.wie.weg
@ 2006-04-22 15:38 ` nix.wie.weg
0 siblings, 0 replies; 31+ messages in thread
From: nix.wie.weg @ 2006-04-22 15:38 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 39 bytes --]
Sorry have forgotten the patch.
>
[-- Attachment #2: multiple-portadds.patch --]
[-- Type: text/x-patch, Size: 4223 bytes --]
--- qemu-2006-04-22/hw/usb.c 2006-04-22 14:44:21.000000000 +0200
+++ qemu/hw/usb.c 2006-04-22 17:24:06.000000000 +0200
@@ -403,73 +403,74 @@
/* this function adds a newly created device and cares for the attach and
handles all errors */
-int add_usb_device (USBTree *tree)
+int add_usb_device (USBTree **tree)
{
char father[USB_PATH_MAX_LENGTH];
char child[USB_PATH_MAX_LENGTH];
int port;
USBDevice *fatherdev;
- if (tree->dev == NULL) {
- usb_remove_device(&tree);
+ if ((*tree)->dev == NULL) {
+ usb_remove_device(tree);
return -1;
}
- usb_str_father_and_child (tree->path, father, child);
+ usb_str_father_and_child ((*tree)->path, father, child);
fatherdev= usb_find_device (father);
if (!fatherdev ) {
#ifdef DEBUG
- printf ( "Could not find father father USB for %s.\n", tree->name);
+ printf ( "Could not find father father USB for %s.\n", (*tree)->name);
#endif
- usb_remove_device(&tree);
+ usb_remove_device(tree);
return -1;
}
- tree->dev->father= fatherdev;
port= atoi (child)-1;
- port= fatherdev->handle_attach(fatherdev, tree->dev, port);
+ port= fatherdev->handle_attach(fatherdev, (*tree)->dev, port);
if( port < 0 ) {
#ifdef DEBUG
- printf ( "Could not attach USB host device %s.\n", tree->name);
-#endif
+ printf ( "Could not attach USB host device %s.\n", (*tree)->name);
+#endif
+ usb_remove_device(tree);
return -1;
}
- tree->dev->father_port= port;
- snprintf( tree->path, USB_PATH_MAX_LENGTH,"%s:%03i", father, port+1);
+ (*tree)->dev->father= fatherdev;
+ (*tree)->dev->father_port= port;
+ snprintf( (*tree)->path, USB_PATH_MAX_LENGTH,"%s:%03i", father, port+1);
return 0;
}
/* this function does decide which device should be added, if you write a new
device driver than you must add it here */
-int usb_add_device( PCIBus *pci_bus, USBTree *tree )
+int usb_add_device (PCIBus *pci_bus, USBTree **tree)
{
- if (strcmp(tree->name, "uhci") == 0) {
+ if (strcmp((*tree)->name, "uhci") == 0) {
/* uhci controller found */
/* controller are allways root devices, so no add is tried */
if (pci_bus != NULL) {
- tree->dev= usb_uhci_init (pci_bus);
- if( tree->dev != NULL ) {
+ (*tree)->dev= usb_uhci_init (pci_bus);
+ if( (*tree)->dev != NULL ) {
return 0;
}
}
- usb_remove_device(&tree);
+ usb_remove_device(tree);
return -1;
- } else if (strstr (tree->name, "host:") == tree->name) {
+ } else if (strstr ((*tree)->name, "host:") == (*tree)->name) {
/* we found a host device */
- tree->dev= usb_host_init (tree->name);
+ (*tree)->dev= usb_host_init ((*tree)->name);
return add_usb_device (tree);
- } else if (strcmp (tree->name,"usbhub") == 0) {
+ } else if (strcmp ((*tree)->name,"usbhub") == 0) {
/* we found a guest usb hub */
- tree->dev= usb_hub_init (4);
+ (*tree)->dev= usb_hub_init (4);
return add_usb_device (tree);
- } else if (strcmp (tree->name,"mouse") == 0) {
+ } else if (strcmp ((*tree)->name,"mouse") == 0) {
/* we found a guest usb mouse */
- tree->dev= usb_mouse_init ();
+ (*tree)->dev= usb_mouse_init ();
return add_usb_device (tree);
- } else if (strcmp (tree->name,"tablet") == 0) {
+ } else if (strcmp ((*tree)->name,"tablet") == 0) {
/* we found a guest usb tablet */
- tree->dev = usb_tablet_init ();
+ (*tree)->dev = usb_tablet_init ();
return add_usb_device (tree);
} else {
- usb_remove_device(&tree);
+ usb_remove_device(tree);
return -1;
}
}
@@ -482,7 +483,7 @@
for (;tmp != NULL; tmp= tmp->next) {
switch (tmp->device_status) {
case USB_ADD_DEVICE:
- if (usb_add_device (pci_bus, tmp) < 0)
+ if (usb_add_device (pci_bus, &tmp) < 0)
ret= -1;
else
tmp->device_status= USB_STANDARD_DEVICE;
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-22 14:36 ` Lonnie Mendez
2006-04-22 15:36 ` nix.wie.weg
@ 2006-04-22 16:00 ` nix.wie.weg
2006-04-22 16:19 ` Lonnie Mendez
1 sibling, 1 reply; 31+ messages in thread
From: nix.wie.weg @ 2006-04-22 16:00 UTC (permalink / raw)
To: qemu-devel
>
> Adding a device by Vendor id and Product id doesn't seem to work.
> If this is intentional then perhaps the functionality should be
> restored. qemu users will find this convenient as it is a
> fixed/static identification for a single usb device which is most
> likely going to be the common usage.
>
In which case did it not work, when I test it, it is functioning (only
with libusb)
usb_add host:04b6x0005
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-22 16:00 ` nix.wie.weg
@ 2006-04-22 16:19 ` Lonnie Mendez
2006-04-22 16:35 ` nix.wie.weg
0 siblings, 1 reply; 31+ messages in thread
From: Lonnie Mendez @ 2006-04-22 16:19 UTC (permalink / raw)
To: qemu-devel
nix.wie.weg@gmx.de wrote:
>In which case did it not work, when I test it, it is functioning (only
>with libusb)
>usb_add host:04b6x0005
>
Sorry about that. I was used to the previous syntax:
usb_add host:04b6:0005
My guess is that the new syntax is to distinguish it from the
busaddr:addr syntax? It would seem checking for length would
differentiate the two in that case.
For the linux guest problem which distro is being used?
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-22 16:19 ` Lonnie Mendez
@ 2006-04-22 16:35 ` nix.wie.weg
2006-04-23 3:38 ` Lonnie Mendez
0 siblings, 1 reply; 31+ messages in thread
From: nix.wie.weg @ 2006-04-22 16:35 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 788 bytes --]
Lonnie Mendez wrote:
> nix.wie.weg@gmx.de wrote:
>
> Sorry about that. I was used to the previous syntax:
> usb_add host:04b6:0005
>
> My guess is that the new syntax is to distinguish it from the
> busaddr:addr syntax? It would seem checking for length would
> differentiate the two in that case.
Yes maybe, but not a real good solution, especially if you know that
with the solution we have now, you can omit leading zeros.
>
> For the linux guest problem which distro is being used?
I don't have this problem any more. It was an incomplete merged patch.
I have attached a small patch, with which you can really add a device to
a hub, if this is then working is another question, but it should only
depend on the implementation of usb-hub.c
With kind regards,
Tino H. Seifert
[-- Attachment #2: lusb-upd3.diff --]
[-- Type: text/plain, Size: 2825 bytes --]
diff -Nur qemu-last-snapshot/hw/usb-hub.c qemu/hw/usb-hub.c
--- qemu-last-snapshot/hw/usb-hub.c 2006-04-22 17:53:27.000000000 +0200
+++ qemu/hw/usb-hub.c 2006-04-22 18:24:11.000000000 +0200
@@ -172,18 +172,16 @@
static int usb_hub_attach (USBDevice *hub, USBDevice *dev, int portnum)
{
- USBHubState *s = (USBHubState *)(dev->father->opaque);
+ USBHubState *s = (USBHubState *)(hub->opaque);
USBHubPort *port;
int i;
if (dev) {
- if( portnum >= MAX_PORTS ) {
+ if (portnum >= MAX_PORTS || portnum < 0) {
#ifdef DEBUG
- printf( "Not so many ports available on USB hub \n" );
+ printf( "This usb hub port does not exist.\n" );
#endif
portnum= 0;
- } else if( portnum < 0 ){
- portnum= 0;
}
if (s->ports[portnum].dev != NULL) {
#ifdef DEBUG
@@ -201,7 +199,7 @@
}
if( portnum < 0 ) {
#ifdef DEBUG
- printf( "Could not find a Hub Port to connect to!" );
+ printf( "Could not find a Hub Port to connect to! \n" );
#endif
return 0;
}
@@ -215,7 +213,8 @@
else
port->wPortStatus &= ~PORT_STAT_LOW_SPEED;
port->dev = dev;
- return 1;
+ port->dev->handle_msg (port->dev, USB_MSG_ATTACH);
+ return portnum;
} else {
port = &s->ports[portnum];
dev = port->dev;
@@ -226,11 +225,13 @@
port->wPortStatus &= ~PORT_STAT_ENABLE;
port->wPortChange |= PORT_STAT_C_ENABLE;
}
+ port->dev->handle_msg(port->dev, USB_MSG_DETACH);
port->dev = NULL;
- return 1;
+ return portnum;
+ } else {
+ return -1;
}
}
- return -1;
}
int usb_hub_handle_reset(USBDevice *dev)
diff -Nur qemu-last-snapshot/usb-libusb.c qemu/usb-libusb.c
--- qemu-last-snapshot/usb-libusb.c 2006-04-22 17:53:29.000000000 +0200
+++ qemu/usb-libusb.c 2006-04-22 18:03:47.000000000 +0200
@@ -230,8 +230,8 @@
}
/* the syntax is :
- 'bus.addr' (decimal numbers) or
- 'vendor_id:product_id' (hexa numbers) */
+ 'bus:addr' (decimal numbers) or
+ 'vendor_idxproduct_id' (hexa numbers) */
void usb_host_find_device(const char *devname, struct usb_device **device)
{
*device= NULL;
@@ -399,7 +399,7 @@
usbVersion[1]= (bcd >> 8) & 7;
usbVersion[2]= (bcd >> 4) & 7;
usbVersion[3]= bcd & 7;
- term_printf(" VendorID:ProductID %04x:%04x, USB-Standard: %i%i.%i%i\n",
+ term_printf(" VendorID:ProductID %04xx%04x, USB-Standard: %i%i.%i%i\n",
dev->descriptor.idVendor, dev->descriptor.idProduct,
usbVersion[0], usbVersion[1], usbVersion[2], usbVersion[3] );
}
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-22 16:35 ` nix.wie.weg
@ 2006-04-23 3:38 ` Lonnie Mendez
2006-04-23 21:54 ` nix.wie.weg
2006-04-29 1:03 ` Lonnie Mendez
0 siblings, 2 replies; 31+ messages in thread
From: Lonnie Mendez @ 2006-04-23 3:38 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 2442 bytes --]
nix.wie.weg@gmx.de wrote:
>Lonnie Mendez wrote:
>
>
>>nix.wie.weg@gmx.de wrote:
>>
>>Sorry about that. I was used to the previous syntax:
>>usb_add host:04b6:0005
>>
>> My guess is that the new syntax is to distinguish it from the
>>busaddr:addr syntax? It would seem checking for length would
>>differentiate the two in that case.
>>
>>
>Yes maybe, but not a real good solution, especially if you know that
>with the solution we have now, you can omit leading zeros.
>
>
Aye.
>
>I have attached a small patch, with which you can really add a device to
>a hub, if this is then working is another question, but it should only
>depend on the implementation of usb-hub.c
>
>
That works but not in the literal means of the attached device
actually functioning (see below). Here is something interesting:
(qemu) usb_add mouse
Controller 001: uhci
001:001 = mouse
Summary: 1 USB Controller, 1 USB Devices
(qemu) usb_add tablet,addto 001:001:001
(qemu) info usb
Controller 001: uhci
001:001 = mouse
001:001:001 = tablet
Summary: 1 USB Controller, 2 USB Devices
(qemu)
The device attached on the hub doesn't seem to be receiving
transactions (like before with the emulated devices):
frame 1227: pid=SETUP addr=0x00 ep=0 len=8
data_out= 80 06 00 01 00 00 40 00
uhci readw port=0x0002 val=0x0001
uhci writew port=0x0002 val=0x0001
uhci readw port=0x0006 val=0x04cc
frame 1228: pid=SETUP addr=0x00 ep=0 len=8
data_out= 80 06 00 01 00 00 40 00
frame 1229: pid=SETUP addr=0x00 ep=0 len=8
data_out= 80 06 00 01 00 00 40 00
uhci readw port=0x0002 val=0x0002
uhci writew port=0x0002 val=0x0002
There are some problems with the port status request traffic from the
hub as well:
frame 1174: pid=SETUP addr=0x03 ep=0 len=8
data_out= 23 03 04 00 01 00 00 00
error usb_generic_handle_packet: unknown USB-Token - 258
ret=0
The interface is also giving incorrect errors at certain times:
(qemu) usb_add usbhub
usb_add: extraneous characters at the end of line
(qemu)
Attached is a patch to get the linux redirector working with the
changes. It has a few other modifications as well but nothing radical.
The default redirector for linux host was changed to the linux
redirector as well (just a heads up). I'm still using the libusb
redirector for testing here but it's good to restore the linux
redirector as default on linux host.
[-- Attachment #2: lusb-upd4.diff --]
[-- Type: text/plain, Size: 13121 bytes --]
--- a/qemu/configure 2006-04-22 21:58:54.000000000 -0500
+++ b/qemu/configure 2006-04-22 22:00:43.000000000 -0500
@@ -105,7 +105,7 @@
;;
MINGW32*)
mingw32="yes"
-usb="linux"
+usb="generic"
;;
FreeBSD)
bsd="yes"
@@ -130,7 +130,7 @@
oss="yes"
linux="yes"
user="yes"
-usb="generic"
+usb="linux"
if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
kqemu="yes"
fi
--- a/qemu/usb-linux.c 2006-04-22 21:58:54.000000000 -0500
+++ b/qemu/usb-linux.c 2006-04-22 22:02:10.000000000 -0500
@@ -42,11 +42,14 @@
void *data;
};
-typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id,
+typedef int USBScanFunc(void *opaque, int bus_num, int addr,
int vendor_id, int product_id,
- const char *product_name, int speed);
+ const char *spec_version,
+ const char *manf_string,
+ const char *prod_string);
static int usb_host_find_device(int *pbus_num, int *paddr,
const char *devname);
+int usb_host_handle_close(USBDevice *opaque);
//#define DEBUG
@@ -63,32 +66,19 @@
"error code: %i\n", ret );
# endif
switch(ret) {
- case -ETIMEDOUT:
+ case ETIMEDOUT:
# ifdef DEBUG
printf( "USB_ERROR: ETIMEDOUT\n" );
#endif
return USB_RET_NAK;
break;
- case -EIO:
-# ifdef DEBUG
- printf( "USB_ERROR: EIO\n" );
-#endif
- /* stall condition on win32 */
- /* XXX: clear stall */
- return USB_RET_STALL;
- break;
- case -EBUSY:
- /* stall on linux */
- /* XXX: clear stall */
- return USB_RET_STALL;
- break;
- case -EPIPE:
+ case EPIPE:
default:
return USB_RET_STALL;
}
}
-static void usb_host_handle_reset(USBDevice *dev)
+static int usb_host_handle_reset(USBDevice *dev)
{
#if 0
USBHostDevice *s = (USBHostDevice *)dev;
@@ -96,6 +86,7 @@
done by the host OS */
ioctl(s->fd, USBDEVFS_RESET);
#endif
+ return USB_RET_ACK;
}
static int usb_host_handle_control(USBDevice *dev,
@@ -118,7 +109,7 @@
ct.data = data;
ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
if (ret < 0) {
- usb_host_handle_error( ret );
+ return usb_host_handle_error( errno );
} else {
return ret;
}
@@ -142,14 +133,14 @@
bt.data = data;
ret = ioctl(s->fd, USBDEVFS_BULK, &bt);
if (ret < 0) {
- usb_host_handle_error( ret );
+ return usb_host_handle_error( errno );
} else {
return ret;
}
}
/* XXX: exclude high speed devices or implement EHCI */
-USBDevice *usb_host_device_open(const char *devname)
+USBDevice *usb_host_init(const char *devname)
{
int fd, interface, ret, i;
USBHostDevice *hostdev;
@@ -162,7 +153,7 @@
if (usb_host_find_device(&bus_num, &addr, devname) < 0)
return NULL;
-
+
snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d",
bus_num, addr);
fd = open(buf, O_RDWR);
@@ -272,12 +263,16 @@
return q - buf;
}
-void usb_host_device_close(USBDevice *opaque)
+int usb_host_handle_close(USBDevice *opaque)
{
USBHostDevice *s = (USBHostDevice *)opaque;
- if (s->fd >= 0)
+ if (s->fd >= 0) {
close(s->fd);
+ return 1;
+ }
+
+ return -1;
}
static int usb_host_scan(void *opaque, USBScanFunc *func)
@@ -285,9 +280,11 @@
FILE *f;
char line[1024];
char buf[1024];
- int bus_num, addr, speed, device_count, class_id, product_id, vendor_id;
+ int bus_num, addr, device_count, product_id, vendor_id;
int ret;
- char product_name[512];
+ char manf_name[512];
+ char prod_name[512];
+ char spec_version[6];
f = fopen(USBDEVFS_PATH "/devices", "r");
if (!f) {
@@ -295,7 +292,7 @@
return 0;
}
device_count = 0;
- bus_num = addr = speed = class_id = product_id = vendor_id = 0;
+ bus_num = addr = product_id = vendor_id = 0;
ret = 0;
for(;;) {
if (fgets(line, sizeof(line), f) == NULL)
@@ -305,8 +302,8 @@
if (line[0] == 'T' && line[1] == ':') {
if (device_count && (vendor_id || product_id)) {
/* New device. Add the previously discovered device. */
- ret = func(opaque, bus_num, addr, class_id, vendor_id,
- product_id, product_name, speed);
+ ret = func(opaque, bus_num, addr, vendor_id, product_id,
+ spec_version, manf_name, prod_name);
if (ret)
goto the_end;
}
@@ -316,19 +313,17 @@
if (get_tag_value(buf, sizeof(buf), line, "Dev#=", " ") < 0)
goto fail;
addr = atoi(buf);
- if (get_tag_value(buf, sizeof(buf), line, "Spd=", " ") < 0)
- goto fail;
- if (!strcmp(buf, "480"))
- speed = USB_SPEED_HIGH;
- else if (!strcmp(buf, "1.5"))
- speed = USB_SPEED_LOW;
- else
- speed = USB_SPEED_FULL;
- product_name[0] = '\0';
- class_id = 0xff;
+ strcpy(spec_version, "01.10");
+ strcpy(manf_name, "unknown");
+ strcpy(prod_name, "unknown");
device_count++;
product_id = 0;
vendor_id = 0;
+ } else if (line[0] == 'D' && line[1] == ':') {
+ if (get_tag_value(&buf[1], sizeof(buf) - 1, line, "Ver=", " ") < 0)
+ goto fail;
+ buf[0] = '0';
+ pstrcpy(spec_version, sizeof(spec_version), buf);
} else if (line[0] == 'P' && line[1] == ':') {
if (get_tag_value(buf, sizeof(buf), line, "Vendor=", " ") < 0)
goto fail;
@@ -337,20 +332,22 @@
goto fail;
product_id = strtoul(buf, NULL, 16);
} else if (line[0] == 'S' && line[1] == ':') {
- if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0)
- goto fail;
- pstrcpy(product_name, sizeof(product_name), buf);
- } else if (line[0] == 'D' && line[1] == ':') {
- if (get_tag_value(buf, sizeof(buf), line, "Cls=", " (") < 0)
- goto fail;
- class_id = strtoul(buf, NULL, 16);
+ if (get_tag_value(buf, sizeof(buf), line, "Manufacturer=", "") < 0) {
+ if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0) {
+ goto fail;
+ } else {
+ pstrcpy(prod_name, sizeof(prod_name), buf);
+ }
+ } else {
+ pstrcpy(manf_name, sizeof(manf_name), buf);
+ }
}
fail: ;
}
if (device_count && (vendor_id || product_id)) {
/* Add the last device. */
- ret = func(opaque, bus_num, addr, class_id, vendor_id,
- product_id, product_name, speed);
+ ret = func(opaque, bus_num, addr, vendor_id, product_id, spec_version,
+ manf_name, prod_name);
}
the_end:
fclose(f);
@@ -364,10 +361,11 @@
int addr;
} FindDeviceState;
-static int usb_host_find_device_scan(void *opaque, int bus_num, int addr,
- int class_id,
- int vendor_id, int product_id,
- const char *product_name, int speed)
+static int usb_host_find_device_scan(void *opaque, int bus_num, int addr,
+ int vendor_id, int product_id,
+ const char *spec_version,
+ const char *manf_string,
+ const char *prod_string)
{
FindDeviceState *s = opaque;
if (vendor_id == s->vendor_id &&
@@ -386,108 +384,38 @@
static int usb_host_find_device(int *pbus_num, int *paddr,
const char *devname)
{
- const char *p;
- int ret;
FindDeviceState fs;
- p = strchr(devname, '.');
- if (p) {
- *pbus_num = strtoul(devname, NULL, 0);
- *paddr = strtoul(p + 1, NULL, 0);
- return 0;
- }
- p = strchr(devname, ':');
- if (p) {
- fs.vendor_id = strtoul(devname, NULL, 16);
- fs.product_id = strtoul(p + 1, NULL, 16);
- ret = usb_host_scan(&fs, usb_host_find_device_scan);
- if (ret) {
- *pbus_num = fs.bus_num;
- *paddr = fs.addr;
- return 0;
+ if (sscanf(devname, "host:%03d:%03d", pbus_num, paddr) != 2) {
+ if (sscanf(devname, "host:%04xx%04x", &fs.vendor_id, &fs.product_id) == 2) {
+ if (usb_host_scan(&fs, usb_host_find_device_scan)) {
+ *pbus_num = fs.bus_num;
+ *paddr = fs.addr;
+ return 0;
+ } else {
+ return -1;
+ }
+ } else {
+ return -1;
}
+ } else {
+ return 0;
}
- return -1;
}
/**********************/
/* USB host device info */
-struct usb_class_info {
- int class;
- const char *class_name;
-};
-
-static const struct usb_class_info usb_class_info[] = {
- { USB_CLASS_AUDIO, "Audio"},
- { USB_CLASS_COMM, "Communication"},
- { USB_CLASS_HID, "HID"},
- { USB_CLASS_HUB, "Hub" },
- { USB_CLASS_PHYSICAL, "Physical" },
- { USB_CLASS_PRINTER, "Printer" },
- { USB_CLASS_MASS_STORAGE, "Storage" },
- { USB_CLASS_CDC_DATA, "Data" },
- { USB_CLASS_APP_SPEC, "Application Specific" },
- { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
- { USB_CLASS_STILL_IMAGE, "Still Image" },
- { USB_CLASS_CSCID, "Smart Card" },
- { USB_CLASS_CONTENT_SEC, "Content Security" },
- { -1, NULL }
-};
-
-static const char *usb_class_str(uint8_t class)
-{
- const struct usb_class_info *p;
- for(p = usb_class_info; p->class != -1; p++) {
- if (p->class == class)
- break;
- }
- return p->class_name;
-}
-
-void usb_info_device(int bus_num, int addr, int class_id,
- int vendor_id, int product_id,
- const char *product_name,
- int speed)
-{
- const char *class_str, *speed_str;
-
- switch(speed) {
- case USB_SPEED_LOW:
- speed_str = "1.5";
- break;
- case USB_SPEED_FULL:
- speed_str = "12";
- break;
- case USB_SPEED_HIGH:
- speed_str = "480";
- break;
- default:
- speed_str = "?";
- break;
- }
-
- term_printf(" Device %d.%d, speed %s Mb/s\n",
- bus_num, addr, speed_str);
- class_str = usb_class_str(class_id);
- if (class_str)
- term_printf(" %s:", class_str);
- else
- term_printf(" Class %02x:", class_id);
- term_printf(" USB device %04x:%04x", vendor_id, product_id);
- if (product_name[0] != '\0')
- term_printf(", %s", product_name);
- term_printf("\n");
-}
-
static int usb_host_info_device(void *opaque, int bus_num, int addr,
- int class_id,
- int vendor_id, int product_id,
- const char *product_name,
- int speed)
-{
- usb_info_device(bus_num, addr, class_id, vendor_id, product_id,
- product_name, speed);
+ int vendor_id, int product_id,
+ const char *spec_ver,
+ const char *manf_string,
+ const char *prod_string)
+{
+ term_printf(" Device host:%03d:%03d, Manufacturer %s, Product %s\n",
+ bus_num, addr, manf_string, prod_string );
+ term_printf(" VendorID:ProductID %04xx%04x, USB-Standard: %s\n",
+ vendor_id, product_id, spec_ver );
return 0;
}
--- a/qemu/usb-libusb.c 2006-04-22 21:59:14.000000000 -0500
+++ b/qemu/usb-libusb.c 2006-04-22 22:03:02.000000000 -0500
@@ -368,12 +368,7 @@
/**********************/
/* USB host device info */
-struct usb_class_info {
- int class;
- const char *class_name;
-};
-
void usb_host_info_device( struct usb_bus *bus, struct usb_device *dev, struct usb_dev_handle *handle )
{
char str1[256], str2[256];
--- a/qemu/hw/usb-hub.c 2006-04-22 21:59:14.000000000 -0500
+++ b/qemu/hw/usb-hub.c 2006-04-22 13:51:23.000000000 -0500
@@ -177,7 +177,7 @@
int i;
if (dev) {
- if (portnum >= MAX_PORTS || portnum < 0) {
+ if (portnum >= s->nb_ports || portnum < 0) {
#ifdef DEBUG
printf( "This usb hub port does not exist.\n" );
#endif
@@ -188,7 +188,7 @@
printf( "Hub Port %i is allready occupied! \n", portnum );
#endif
portnum= -1;
- for (i= 0; i < MAX_PORTS; i++) {
+ for (i= 0; i < s->nb_ports; i++) {
if (s->ports[i].dev == NULL) {
#ifdef DEBUG
printf( "Will use Hub Port %i instead! \n", i );
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-20 19:59 [Qemu-devel] Large USB patch nix.wie.weg
` (2 preceding siblings ...)
2006-04-22 14:15 ` nix.wie.weg
@ 2006-04-23 15:02 ` Fabrice Bellard
2006-04-23 16:11 ` nix.wie.weg
2006-04-24 23:50 ` [Qemu-devel] Update for cvs 2006-04-24 nix.wie.weg
4 siblings, 1 reply; 31+ messages in thread
From: Fabrice Bellard @ 2006-04-23 15:02 UTC (permalink / raw)
To: qemu-devel
Hi,
Could you make a small patch containing just the bug fixes of the state
machine ?
Concerning your API changes, I am relunctant to include them now, but my
mind can evolve. An API change that I would consider as very useful
could be to be able to make asynchronous USB I/Os to avoid blocking QEMU
while doing host USB I/Os.
Regards,
Fabrice.
nix.wie.weg@gmx.de wrote:
> Hello everybody,
>
> I have extended the USB support for Qemu. The patch is included and
> compiles just fine against todays cvs repository. As explained below,
> this patch touches 15 different files, which makes it not so easy to
> keep it applying on that very fast developing project. Thats why I would
> ask you to test it quickly and apply it to cvs as soon as possible.
>
> With this patch applied I could detect a USB Epson Scanner and a USB
> Epson Printer from Windows 98 + XP and I could even print pages with
> the printer (see known problems below).
>
> reasons for this patch:
> I was looking for a way to address my USB printer with windows while
> working on linux. As I started the work I had to recognize that my
> printer was not even detected under qemu. So I started to work on it.
>
> changes I made:
> First I eliminated all potential error sources, which could be avoided.
> One of these sources where the
>
> 1. usb-hub - which I transfered to an extra file usb-hub.c, then I
> added the usb-libusb.c devices directly to the UHCI controller this
> introduced the changes of 2)
> 2. I enhanced the usb add device potentialities so that you should be
> able to add a device to the UHCI controller. This device can be a usb
> hub or a usb device. Behind this device you can add another hub or
> device ... (remember this feature is now theoretically possible but not
> tested yet), this let to a new usb syntax:
> #$ qemu -usb controller=uhci,busnum=001 device=host:2:3,addto=001:001
> (the short form is:
> #$ qemu -usb controller=uhci -usb device=host:2:3)
> so you can build up a complete usb tree.
> 3. I changed the usb_generic_handle_packet() function and implemented a
> state machine, which is able to handle the usb packets correct.
> 4. I changed the linux standard usb-host library to libusb. I personally
> will always prefer a portable solution if possible.
> 5. I changed large parts of usb-libusb.c. Some changes were made because
> I found the source very awkward, some others because I fixed errors and
> some because I changed the general usb api (see item 2).
> 6. I tried to join as many usb functions as possible to the usb related
> files. So that hopefully nobody has to change 15 files again.
> 7. I made minor changes to usb-uhci - mainly I applied the new api and
> changed the handling of special messages like usb_reset or usb_attach
> 8. I made the necessary changes to usb-hid.c and usb-hub.c
> 9. I wrote a lot of source comments
>
> this patch breaks some things:
> Sorry guys but I could not fix all of it, so I need your help, I didn't
> want to destroy anybodys work, but the new api makes it necessary to
> change some files:
> 1. usb-linux.c and usb-bsd.c will not work without adoption of the new api
> 2. I did not test usb-hid and usb-hub
>
> known problems:
> 1. under linux the uhci controller reports an error if no usb device is
> connected
> 2. the printer and the scanner are recognized under Windows 98/XP and
> Linux, but the scanner goes into STALL state as soon as a packet in
> usb_write_bulk() or usb_read_bulk()
> 3. the libusb usb_host_reset() function does not work as expected and I
> don't know why (i have commented out this part of the source)
> 4. the printer stops printing on large images and is then in a state,
> where it will not resume his work (probably a timing issue)
>
> With kind regards,
> Tino H. Seifert
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Qemu-devel mailing list
> Qemu-devel@nongnu.org
> http://lists.nongnu.org/mailman/listinfo/qemu-devel
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-23 15:02 ` Fabrice Bellard
@ 2006-04-23 16:11 ` nix.wie.weg
0 siblings, 0 replies; 31+ messages in thread
From: nix.wie.weg @ 2006-04-23 16:11 UTC (permalink / raw)
To: qemu-devel
Hello Fabrice,
I can understand, that you are not so happy with such an huge patch. But
sorry it can't be done with just patching the state machine. The main
problem is, that the cvs source needs the usbhub. But this hub is not
operational at its current state. So in fact whenever we try to find a
usb problem, we have to look in at least 4 completly different USB
components (uhci controller, usb state machine, usb hub, usb device). It
is a great help to reduce these components by one. Now if you go so far,
you have to touch all these 15 files and then it makes no sence not to
implement a better, and more flexible api. I have done this work and I
was successful, as in the last days we (Lonnie Mendez and I) have found
a lot of bugs. Some bugs were surely introduced by the new api, but we
have also fixed bugs which were simply not detected earlier because the
USB system was never bevor working so good. Today I have even detected
why my usb scanner was not recognised. I will add the patch later on.
So for the foregoing reasons, I will clearly reject to produce a patch
which will only cover the state machine. I have worked very hard on that
patch and some times you have to take what you get :)
But as I said before I can understand, that it is a problem to add such
a huge patch. So I want to submit the following offer: I and maybe also
Lonnie Mendez (hey Lonnie this is a request for some more of your
wonderful help :) ) will test the patch one week longer and get it a
little more stable. On saturday I will make another comprehensive patch
and you will please add it to cvs. Is that an offer?
Thanks for your time and your work so far,
Tino H. Seifert
PS: Your feature request is noted and I will look into it after we have
successfully dealt with the issues above. At the moment I'm not sure if
it is possible at all.
Fabrice Bellard wrote:
> Hi,
>
> Could you make a small patch containing just the bug fixes of the
> state machine ?
>
> Concerning your API changes, I am relunctant to include them now, but
> my mind can evolve. An API change that I would consider as very useful
> could be to be able to make asynchronous USB I/Os to avoid blocking
> QEMU while doing host USB I/Os.
>
> Regards,
>
> Fabrice.
>
>
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-23 3:38 ` Lonnie Mendez
@ 2006-04-23 21:54 ` nix.wie.weg
2006-04-29 1:03 ` Lonnie Mendez
1 sibling, 0 replies; 31+ messages in thread
From: nix.wie.weg @ 2006-04-23 21:54 UTC (permalink / raw)
To: qemu-devel
Hello,
Lonnie Mendez wrote:
>
> That works but not in the literal means of the attached device
> actually functioning (see below). Here is something interesting:
>
> (qemu) usb_add mouse
> Controller 001: uhci
> 001:001 = mouse
> Summary: 1 USB Controller, 1 USB Devices
> (qemu) usb_add tablet,addto 001:001:001
> (qemu) info usb
> Controller 001: uhci
> 001:001 = mouse
> 001:001:001 = tablet
> Summary: 1 USB Controller, 2 USB Devices
> (qemu)
I have changed that, the usb_dummy_ funtions did return 0, but must
return -1
> The device attached on the hub doesn't seem to be receiving
> transactions (like before with the emulated devices):
>
> frame 1227: pid=SETUP addr=0x00 ep=0 len=8
> data_out= 80 06 00 01 00 00 40 00
> uhci readw port=0x0002 val=0x0001
> uhci writew port=0x0002 val=0x0001
> uhci readw port=0x0006 val=0x04cc
> frame 1228: pid=SETUP addr=0x00 ep=0 len=8
> data_out= 80 06 00 01 00 00 40 00
> frame 1229: pid=SETUP addr=0x00 ep=0 len=8
> data_out= 80 06 00 01 00 00 40 00
> uhci readw port=0x0002 val=0x0002
> uhci writew port=0x0002 val=0x0002
>
> There are some problems with the port status request traffic from
> the hub as well:
>
> frame 1174: pid=SETUP addr=0x03 ep=0 len=8
> data_out= 23 03 04 00 01 00 00 00
> error usb_generic_handle_packet: unknown USB-Token - 258
> ret=0
Yes this is clear, the usbhub does not work at all. If I find the time I
will look at it, this week.
>
> The interface is also giving incorrect errors at certain times:
>
> (qemu) usb_add usbhub
> usb_add: extraneous characters at the end of line
> (qemu)
Yes I also noticed this. It's very strange. If you add the same line
again, it will work in most cases. I don't know why it happens. It is a
bug which is located in monitor.c.
>
> Attached is a patch to get the linux redirector working with the
> changes. It has a few other modifications as well but nothing
> radical. The default redirector for linux host was changed to the
> linux redirector as well (just a heads up). I'm still using the
> libusb redirector for testing here but it's good to restore the linux
> redirector as default on linux host.
Thanks works very well.
I have found today an error in the state machine and fixed it. You will
find the fix in the patch:
http://217.20.126.200/tino/usb-2006-04-23.patch
which includes all of our patches until today.
With kind regards,
Tino H. Seifert
^ permalink raw reply [flat|nested] 31+ messages in thread
* [Qemu-devel] Update for cvs 2006-04-24
2006-04-20 19:59 [Qemu-devel] Large USB patch nix.wie.weg
` (3 preceding siblings ...)
2006-04-23 15:02 ` Fabrice Bellard
@ 2006-04-24 23:50 ` nix.wie.weg
4 siblings, 0 replies; 31+ messages in thread
From: nix.wie.weg @ 2006-04-24 23:50 UTC (permalink / raw)
To: qemu-devel
Hello everybody,
As Fabrice is already adding some changes to cvs. The patch is getting
smaller (by fivehundert lines today). If we keep this speed the patch
will be gone in only 9 more days.
Here is the patch - as allways applying cleanly to todays cvs:
http://217.20.126.200/tino/usb-2006-04-24.patch
With kind regards,
Tino H. Seifert
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-23 3:38 ` Lonnie Mendez
2006-04-23 21:54 ` nix.wie.weg
@ 2006-04-29 1:03 ` Lonnie Mendez
2006-04-29 3:29 ` Lonnie Mendez
1 sibling, 1 reply; 31+ messages in thread
From: Lonnie Mendez @ 2006-04-29 1:03 UTC (permalink / raw)
To: qemu-devel
lo. The bug with the usb hub is a simple fix. We're simply using
handle_packet to pass USB_MSG_RESET when this should be passed to
handle_msg:
hw/usb-hub.c - line 388:
case PORT_RESET:
if (dev) {
dev->handle_packet(dev,
USB_MSG_RESET, 0, 0, NULL, 0);
port->wPortChange |= PORT_STAT_C_RESET;
The simple fix is to change the function call to dev->handle_msg(dev,
USB_MSG_RESET) so that the state machine is correctly set up.
I'm going to go over the port status bits with a fine comb to make
sure everything is looking good.
It also looks like we'll need to be able to propogate resume signal
from usb_hub_attach to the uhci controller. This means putting the
resume code in uhci_attach:
// 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);
}
into a static function inside usb-uhci.c and then setting up a way of
calling this when the controller needs to be resumed. If a device is
set for remote_wakeup then it can call this function to resume the bus
if necessary.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-29 1:03 ` Lonnie Mendez
@ 2006-04-29 3:29 ` Lonnie Mendez
2006-04-30 0:46 ` Lonnie Mendez
0 siblings, 1 reply; 31+ messages in thread
From: Lonnie Mendez @ 2006-04-29 3:29 UTC (permalink / raw)
To: qemu-devel
Ran into this as well when testing a gps device. Looking at hw/usb.c
and usb_20 8.5.3 now.
frame 1346: pid=OUT addr=0x03 ep=2 len=1
data_out= 30
usb_generic_handle_data(): handle setup
usb.c: usb_generic_handle_data, send more than oneconfig paket out not
implemented yet - FIXME
frame 1346: pid=SETUP addr=0x03 ep=0 len=8
data_out= 21 09 00 03 00 00 08 00
usb_generic_handle_setup(): New setup Token
ret=8
uhci readw port=0x0002 val=0x0001
uhci writew port=0x0002 val=0x0001
uhci readw port=0x0006 val=0x0543
frame 1347: pid=OUT addr=0x03 ep=2 len=1
data_out= 30
usb_generic_handle_data(): handle setup
usb.c: usb_generic_handle_data, send more than oneconfig paket out not
implemented yet - FIXME
Is it intentional that once the hub is added it can't be removed?
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-29 3:29 ` Lonnie Mendez
@ 2006-04-30 0:46 ` Lonnie Mendez
2006-04-30 20:56 ` Lonnie Mendez
0 siblings, 1 reply; 31+ messages in thread
From: Lonnie Mendez @ 2006-04-30 0:46 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 211 bytes --]
lo. The attached patch addresses the problem with removing the
usbhub/tablet devices and switches the handle_packet call in the port
reset call to handle_msg which just happens to make the hub functional.
[-- Attachment #2: lusb-upd5.diff --]
[-- Type: text/plain, Size: 1678 bytes --]
--- a/qemu/hw/usb-hub.c 2006-04-28 19:44:18.000000000 -0500
+++ b/qemu/hw/usb-hub.c 2006-04-29 18:55:46.000000000 -0500
@@ -240,6 +240,13 @@
return 1;
}
+int usb_hub_handle_close(USBDevice *dev)
+{
+ USBHubState *s = (USBHubState *)(dev->opaque);
+ qemu_free(s);
+ return 1;
+}
+
int usb_hub_handle_control(USBDevice *dev, int request, int value,
int index, int length, uint8_t *data)
{
@@ -385,8 +392,7 @@
break;
case PORT_RESET:
if (dev) {
- dev->handle_packet(dev,
- USB_MSG_RESET, 0, 0, NULL, 0);
+ dev->handle_msg(dev, USB_MSG_RESET);
port->wPortChange |= PORT_STAT_C_RESET;
/* set enable bit */
// port->wPortChange |= PORT_STAT_C_ENABLE;
@@ -578,6 +584,7 @@
dev->handle_packet= usb_hub_handle_packet;
dev->handle_attach= usb_hub_attach;
dev->handle_reset= usb_hub_handle_reset;
+ dev->handle_close= usb_hub_handle_close;
dev->handle_control= usb_hub_handle_control;
dev->handle_data= usb_hub_handle_data;
--- a/qemu/hw/usb-hid.c 2006-04-28 19:44:18.000000000 -0500
+++ b/qemu/hw/usb-hid.c 2006-04-29 18:56:15.000000000 -0500
@@ -526,6 +526,7 @@
dev->handle_packet= usb_generic_handle_packet;
dev->handle_reset= usb_mouse_handle_reset;
+ dev->handle_close= usb_mouse_handle_close;
dev->handle_control= usb_mouse_handle_control;
dev->handle_data= usb_mouse_handle_data;
s->kind= USB_TABLET;
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] Large USB patch
2006-04-30 0:46 ` Lonnie Mendez
@ 2006-04-30 20:56 ` Lonnie Mendez
0 siblings, 0 replies; 31+ messages in thread
From: Lonnie Mendez @ 2006-04-30 20:56 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 447 bytes --]
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.
[-- Attachment #2: lusb-upd6.diff --]
[-- Type: text/plain, Size: 4837 bytes --]
--- 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;
^ permalink raw reply [flat|nested] 31+ messages in thread
end of thread, other threads:[~2006-04-30 20:57 UTC | newest]
Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-04-20 19:59 [Qemu-devel] Large USB patch nix.wie.weg
2006-04-21 2:23 ` Lonnie Mendez
2006-04-21 5:59 ` nix.wie.weg
2006-04-21 7:04 ` Lonnie Mendez
2006-04-21 14:53 ` Lonnie Mendez
2006-04-21 15:00 ` Lonnie Mendez
2006-04-21 15:50 ` Lonnie Mendez
2006-04-21 16:19 ` Lonnie Mendez
2006-04-21 16:29 ` nix.wie.weg
2006-04-21 17:28 ` Lonnie Mendez
2006-04-21 18:06 ` Lonnie Mendez
2006-04-21 18:38 ` Lonnie Mendez
2006-04-21 20:50 ` Lonnie Mendez
2006-04-22 9:33 ` nix.wie.weg
2006-04-22 14:36 ` Lonnie Mendez
2006-04-22 15:36 ` nix.wie.weg
2006-04-22 15:38 ` nix.wie.weg
2006-04-22 16:00 ` nix.wie.weg
2006-04-22 16:19 ` Lonnie Mendez
2006-04-22 16:35 ` nix.wie.weg
2006-04-23 3:38 ` Lonnie Mendez
2006-04-23 21:54 ` nix.wie.weg
2006-04-29 1:03 ` Lonnie Mendez
2006-04-29 3:29 ` Lonnie Mendez
2006-04-30 0:46 ` Lonnie Mendez
2006-04-30 20:56 ` Lonnie Mendez
2006-04-21 16:26 ` nix.wie.weg
2006-04-22 14:15 ` nix.wie.weg
2006-04-23 15:02 ` Fabrice Bellard
2006-04-23 16:11 ` nix.wie.weg
2006-04-24 23:50 ` [Qemu-devel] Update for cvs 2006-04-24 nix.wie.weg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).