All of lore.kernel.org
 help / color / mirror / Atom feed
* Plans on 1.99 release
@ 2010-08-25 13:26 Vladimir 'φ-coder/phcoder' Serbinenko
  2010-08-26 23:05 ` Carles Pina i Estany
  0 siblings, 1 reply; 23+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2010-08-25 13:26 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 922 bytes --]

Hello, all. 1.98 was released about half a year ago and it means time is
to release 1.99 soon. There are few patches around which would be pity
if they aren't included in 1.99. Like:
1) RAID-related developpement
2) Legacy menu.lst parser
3) Keyboard layouts and related USB improvements
4) Dynamic menu generation facilities.
5) XZ parts
6) Minix parts
7) NetBSD subpartuition parts
8) Probably few more that I forgot about right now.

My last exam is on 1st of September after which I'll be able to go
through the mail backlog and review the patches.
So the freeze will be on 20th September after which there will be
extensive testing period and 1.99 will be release once we're
sufficiently confident that it contains no major bugs.
The freeze date may be changed to an earlier point in the time if
patches are accepted faster than expected

-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Plans on 1.99 release
  2010-08-25 13:26 Plans on 1.99 release Vladimir 'φ-coder/phcoder' Serbinenko
@ 2010-08-26 23:05 ` Carles Pina i Estany
  2010-08-26 23:15   ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 1 reply; 23+ messages in thread
From: Carles Pina i Estany @ 2010-08-26 23:05 UTC (permalink / raw)
  To: The development of GNU GRUB


Hello,

On Aug/25/2010, Vladimir '??-coder/phcoder' Serbinenko wrote:
> Hello, all. 1.98 was released about half a year ago and it means time is
> to release 1.99 soon. There are few patches around which would be pity
> if they aren't included in 1.99. Like:

> 3) Keyboard layouts and related USB improvements

Maybe I've missed something. When I did it some months ago was working
fine, but we had some design issue (I think that Vladimir wanted to
change something, I don't remember if I changed or I didn't).

In any case: if nobody has done anything after that, I'll try to catchup
and make the required changes.

Probably more news soon.

-- 
Carles Pina i Estany
	http://pinux.info


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Plans on 1.99 release
  2010-08-26 23:05 ` Carles Pina i Estany
@ 2010-08-26 23:15   ` Vladimir 'φ-coder/phcoder' Serbinenko
  2010-08-28 11:31     ` Aleš Nesrsta
  0 siblings, 1 reply; 23+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2010-08-26 23:15 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 834 bytes --]

On 08/27/2010 01:05 AM, Carles Pina i Estany wrote:
> > 3) Keyboard layouts and related USB improvements
>   
> Maybe I've missed something. When I did it some months ago was working
> fine, but we had some design issue (I think that Vladimir wanted to
> change something, I don't remember if I changed or I didn't).
>
> In any case: if nobody has done anything after that, I'll try to catchup
> and make the required changes.
>
>   
It's sitting in
sftp://bzr.savannah.gnu.org/srv/bzr/grub/branches/kbdlayouts/. I already
did most of the necessary changes. There are still issues with
grub-kbcomp, some USB issues (hub code, I have solution but it needs
more testing) and some AT issues (have solution, needs testing)
> Probably more news soon.
>
>   


-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Plans on 1.99 release
  2010-08-26 23:15   ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2010-08-28 11:31     ` Aleš Nesrsta
  2010-08-29 23:52       ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 1 reply; 23+ messages in thread
From: Aleš Nesrsta @ 2010-08-28 11:31 UTC (permalink / raw)
  To: The development of GNU GRUB

Vladimir 'φ-coder/phcoder' Serbinenko wrote:
> On 08/27/2010 01:05 AM, Carles Pina i Estany wrote:
> > > 3) Keyboard layouts and related USB improvements
> >   
> > Maybe I've missed something. When I did it some months ago was working
> > fine, but we had some design issue (I think that Vladimir wanted to
> > change something, I don't remember if I changed or I didn't).
> >
> > In any case: if nobody has done anything after that, I'll try to catchup
> > and make the required changes.
> >
> >   
> It's sitting in
> sftp://bzr.savannah.gnu.org/srv/bzr/grub/branches/kbdlayouts/. I already
> did most of the necessary changes. There are still issues with
> grub-kbcomp, some USB issues (hub code,

Hi Vladimir,
what is the issue(s) with USB (hub code) ?
Could I help You with it - at least with testing ?
Regards
Ales

>  I have solution but it needs
> more testing) and some AT issues (have solution, needs testing)
> > Probably more news soon.
> >
> >   
> 
> 
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Plans on 1.99 release
  2010-08-28 11:31     ` Aleš Nesrsta
@ 2010-08-29 23:52       ` Vladimir 'φ-coder/phcoder' Serbinenko
  2010-08-30  0:14         ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 1 reply; 23+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2010-08-29 23:52 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 2506 bytes --]

On 08/28/2010 01:31 PM, Aleš Nesrsta wrote:
> Vladimir 'φ-coder/phcoder' Serbinenko wrote:
>   
>> On 08/27/2010 01:05 AM, Carles Pina i Estany wrote:
>>     
>>>> 3) Keyboard layouts and related USB improvements
>>>>         
>>>   
>>> Maybe I've missed something. When I did it some months ago was working
>>> fine, but we had some design issue (I think that Vladimir wanted to
>>> change something, I don't remember if I changed or I didn't).
>>>
>>> In any case: if nobody has done anything after that, I'll try to catchup
>>> and make the required changes.
>>>
>>>   
>>>       
>> It's sitting in
>> sftp://bzr.savannah.gnu.org/srv/bzr/grub/branches/kbdlayouts/. I already
>> did most of the necessary changes. There are still issues with
>> grub-kbcomp, some USB issues (hub code,
>>     
> Hi Vladimir,
> what is the issue(s) with USB (hub code) ?
>   
The issue was that we were using getStatus every time we polled for new
devices which suposedly (I fixed few other bugs in the code I used at
the time so, I'm not sure) drove hub in my USB keyboard crazy. The
correct way is to poll interrupt pipe.
Another thing I added is the ability to do background transfers. It is
important for USB keyboard support because otherwise we lose messages on
keyboard interrupt pipe. It triggered a bug in uhci module. Now there
are 2 issues:
1) code is new or modified. Needs testing.
2) On yeeloong the data read from mass storage is sometimes corrupted.
Happens in mainline, not sure about other branches. It seems that it
wasn't the case before. It's either a regression (perhaps from my code
for partial transfers) or cache issues (some cache isn't correctly flushed)
> Could I help You with it - at least with testing ?
>   
Yes, a test run of keylayouts branch on your hardware would be helpful.
Especially I'm interested if USB data corruption happens in your case too.
> Regards
> Ales
>
>   
>>  I have solution but it needs
>> more testing) and some AT issues (have solution, needs testing)
>>     
>>> Probably more news soon.
>>>
>>>   
>>>       
>>
>> _______________________________________________
>> Grub-devel mailing list
>> Grub-devel@gnu.org
>> http://lists.gnu.org/mailman/listinfo/grub-devel
>>     
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
>   


-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Plans on 1.99 release
  2010-08-29 23:52       ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2010-08-30  0:14         ` Vladimir 'φ-coder/phcoder' Serbinenko
  2010-09-03 22:02           ` Plans on 1.99 release - USB issues Aleš Nesrsta
  0 siblings, 1 reply; 23+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2010-08-30  0:14 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 2953 bytes --]

On 08/30/2010 01:52 AM, Vladimir 'φ-coder/phcoder' Serbinenko wrote:
> On 08/28/2010 01:31 PM, Aleš Nesrsta wrote:
>   
>> Vladimir 'φ-coder/phcoder' Serbinenko wrote:
>>   
>>     
>>> On 08/27/2010 01:05 AM, Carles Pina i Estany wrote:
>>>     
>>>       
>>>>> 3) Keyboard layouts and related USB improvements
>>>>>         
>>>>>           
>>>>   
>>>> Maybe I've missed something. When I did it some months ago was working
>>>> fine, but we had some design issue (I think that Vladimir wanted to
>>>> change something, I don't remember if I changed or I didn't).
>>>>
>>>> In any case: if nobody has done anything after that, I'll try to catchup
>>>> and make the required changes.
>>>>
>>>>   
>>>>       
>>>>         
>>> It's sitting in
>>> sftp://bzr.savannah.gnu.org/srv/bzr/grub/branches/kbdlayouts/. I already
>>> did most of the necessary changes. There are still issues with
>>> grub-kbcomp, some USB issues (hub code,
>>>     
>>>       
>> Hi Vladimir,
>> what is the issue(s) with USB (hub code) ?
>>   
>>     
> The issue was that we were using getStatus every time we polled for new
> devices which suposedly (I fixed few other bugs in the code I used at
> the time so, I'm not sure) drove hub in my USB keyboard crazy. The
> correct way is to poll interrupt pipe.
>   
Just to be clear: polling interrupt pipe on hub is what I have
implemented in keylayouts, just so you don't implement it again
> Another thing I added is the ability to do background transfers. It is
> important for USB keyboard support because otherwise we lose messages on
> keyboard interrupt pipe. It triggered a bug in uhci module. Now there
> are 2 issues:
> 1) code is new or modified. Needs testing.
> 2) On yeeloong the data read from mass storage is sometimes corrupted.
> Happens in mainline, not sure about other branches. It seems that it
> wasn't the case before. It's either a regression (perhaps from my code
> for partial transfers) or cache issues (some cache isn't correctly flushed)
>   
>> Could I help You with it - at least with testing ?
>>   
>>     
> Yes, a test run of keylayouts branch on your hardware would be helpful.
> Especially I'm interested if USB data corruption happens in your case too.
>   
>> Regards
>> Ales
>>
>>   
>>     
>>>  I have solution but it needs
>>> more testing) and some AT issues (have solution, needs testing)
>>>     
>>>       
>>>> Probably more news soon.
>>>>
>>>>   
>>>>       
>>>>         
>>> _______________________________________________
>>> Grub-devel mailing list
>>> Grub-devel@gnu.org
>>> http://lists.gnu.org/mailman/listinfo/grub-devel
>>>     
>>>       
>> _______________________________________________
>> Grub-devel mailing list
>> Grub-devel@gnu.org
>> http://lists.gnu.org/mailman/listinfo/grub-devel
>>
>>   
>>     
>
>   


-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Plans on 1.99 release - USB issues
  2010-08-30  0:14         ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2010-09-03 22:02           ` Aleš Nesrsta
  2010-09-04 17:34             ` Aleš Nesrsta
  2010-09-18 10:08             ` Plans on 1.99 release - USB issues Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 2 replies; 23+ messages in thread
From: Aleš Nesrsta @ 2010-09-03 22:02 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 3885 bytes --]

Vladimir 'φ-coder/phcoder' Serbinenko wrote:
> > The issue was that we were using getStatus every time we polled for new
> > devices which suposedly (I fixed few other bugs in the code I used at
> > the time so, I'm not sure) drove hub in my USB keyboard crazy. The
> > correct way is to poll interrupt pipe.
> >   
> Just to be clear: polling interrupt pipe on hub is what I have
> implemented in keylayouts, just so you don't implement it again
> > Another thing I added is the ability to do background transfers. It is
> > important for USB keyboard support because otherwise we lose messages on
> > keyboard interrupt pipe. It triggered a bug in uhci module. Now there
> > are 2 issues:
> > 1) code is new or modified. Needs testing.
> > 2) On yeeloong the data read from mass storage is sometimes corrupted.
> > Happens in mainline, not sure about other branches. It seems that it
> > wasn't the case before. It's either a regression (perhaps from my code
> > for partial transfers) or cache issues (some cache isn't correctly flushed)
> >   
> >> Could I help You with it - at least with testing ?
> >>   
> >>     
> > Yes, a test run of keylayouts branch on your hardware would be helpful.
> > Especially I'm interested if USB data corruption happens in your case too.

Hi Vladimir,

I made some tests on machine with UHCI with kbdlayouts branch (rev.
2424).
I did not notice any evident data corruption. But there were some
another odd results:

1.
My USB keyboard is low speed device (Genius KB-06XE, model no. K639).
Low speed device transfer was not properly handled - I made some simple
patch - see attachment, I did not commit it into repository.
Control type transfer with keyboard is working with this patch, but bulk
(interrupt) transfer returns always err=7 and in UHCI TD status&control
are set bits "CRC/Time Out Error" (bit 18) and "Stalled" (bit 22). It is
the same behavior as some normal full speed mass-storage devices do also
(I reported it in some previous e-mails). I have some idea right now -
probably there is bad handling of UHCI transfer status in uhci.c when
more than one bit is set - GRUB_USB_ERR_TIMEOUT is returned instead of
GRUB_USB_ERR_STALL. I will try to play with this part during weekend and
I will report to You if some success happens...

2.
Next bad thing is some problem with device attachment detection or
handling of newly attached device on non-root hubs. Behavior of this
problem looks little bit randomly and probably depends also on used port
of hub - some ports are often working, some not (but all hub ports are
working normally in Linux/Windows). I did not find reason yet.

3.
Sometimes partitions of USB mass storage devices were not properly
detected - maybe disk cache problem again?
Maybe it is data corruption which is reported by you - but I never
detected data corruption when I read data from files.

---
I am not sure if interrupt transfers can be handled via bulk queue on
OHCI - according specification, it should be handled via interrupt
pointers table which is currently not implemented in ohci.c. Did you
test background polling of interrupt pipe on some PC with OHCI?

---
At the end some maybe bad idea - if I am not wrong, two simultaneous
transfers can happen (be active in UHCI/OHCI) with current background
bulk/interrupt transfer. There is question if are all related functions
fully reentrant ? I.e., is correct handling of some shared data ?
For the first look I don't see such problem - with one exception:
donehead interrupt can be probably incorrectly handled in ohci.c - it
can be detected and misinterpreted by wrong call of
grub_ohci_check_transfer. The first aid in this case can be forcing of
OHCI driver into "bad OHCI" mode, i.e. donehead interrupt ignoring - in
this mode it should work properly.

Regards
Ales


[-- Attachment #2: usb_low_speed_100903_0 --]
[-- Type: text/x-patch, Size: 1124 bytes --]

--- kbdlayouts/grub-core/bus/usb/uhci.c	2010-09-03 22:13:28.000000000 +0200
+++ kbdlayouts_changed/grub-core/bus/usb/uhci.c	2010-09-01 21:10:24.000000000 +0200
@@ -414,7 +414,7 @@
 grub_uhci_transaction (struct grub_uhci *u, unsigned int endp,
 		       grub_transfer_type_t type, unsigned int addr,
 		       unsigned int toggle, grub_size_t size,
-		       grub_uint32_t data)
+		       grub_uint32_t data, grub_usb_speed_t speed)
 {
   grub_uhci_td_t td;
   static const unsigned int tf[] = { 0x69, 0xE1, 0x2D };
@@ -439,7 +439,8 @@
   td->linkptr = 1;
 
   /* Active!  Only retry a transfer 3 times.  */
-  td->ctrl_status = (1 << 23) | (3 << 27);
+  td->ctrl_status = (1 << 23) | (3 << 27) |
+                    ((speed == GRUB_USB_SPEED_LOW) ? (1 << 26) : 0);
 
   /* If zero bytes are transmitted, size is 0x7FF.  Otherwise size is
      size-1.  */
@@ -495,7 +496,8 @@
 
       td = grub_uhci_transaction (u, transfer->endpoint & 15, tr->pid,
 				  transfer->devaddr, tr->toggle,
-				  tr->size, tr->data);
+				  tr->size, tr->data,
+				  transfer->dev->speed);
       if (! td)
 	{
 	  grub_size_t actual = 0;

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Plans on 1.99 release - USB issues
  2010-09-03 22:02           ` Plans on 1.99 release - USB issues Aleš Nesrsta
@ 2010-09-04 17:34             ` Aleš Nesrsta
  2010-09-12 17:28               ` [PATCH] USB issues - kbdlayouts branch Aleš Nesrsta
  2010-09-18 10:08             ` Plans on 1.99 release - USB issues Vladimir 'φ-coder/phcoder' Serbinenko
  1 sibling, 1 reply; 23+ messages in thread
From: Aleš Nesrsta @ 2010-09-04 17:34 UTC (permalink / raw)
  To: The development of GNU GRUB

Hi Vladimir,

in fact nothing important changed from my previous e-mail, I have only
few information what I did.

I still have no progress with low-speed keyboard problem as I wrote in
last e-mail. Control transfers are working fine but interrupt transfer
fails even if I tried to send Clear Halt on interrupt pipe - it is not
possible, Clear Feature Halt returns STALL, i.e. Request Error as
described in USB specification.

USB specification says that low speed devices can communicate only via
control and interrupt pipes.
UHCI specification does not specify any difference between bulk and
interrupt TD - with one exception: "The software must schedule low speed
control transfers such that they are guaranteed to complete within the
current frame.". And, additionally, QH with interrupt transfers should
be placed in schedule as the first immediately after isochronous
transfer TDs.
But even I tried to place low speed interrupt transfer to QH with index
0, which is surely executed as the first QH in schedule, I had no
success.
I don't understand why it is not working, there must be something what I
am missing...


There is only one small positive information - probably thanks to your
changes it is now working one of USB mass storage devices which was not
working on UHCI root hub port (but worked on OHCI or non-root hub
connected to UHCI).


Unfortunately I have to cancel testing now because I must go out of home
for approx. two next weeks.

Regards
Ales

> Vladimir 'φ-coder/phcoder' Serbinenko wrote:
> > > The issue was that we were using getStatus every time we polled for new
> > > devices which suposedly (I fixed few other bugs in the code I used at
> > > the time so, I'm not sure) drove hub in my USB keyboard crazy. The
> > > correct way is to poll interrupt pipe.
> > >   
> > Just to be clear: polling interrupt pipe on hub is what I have
> > implemented in keylayouts, just so you don't implement it again
> > > Another thing I added is the ability to do background transfers. It is
> > > important for USB keyboard support because otherwise we lose messages on
> > > keyboard interrupt pipe. It triggered a bug in uhci module. Now there
> > > are 2 issues:
> > > 1) code is new or modified. Needs testing.
> > > 2) On yeeloong the data read from mass storage is sometimes corrupted.
> > > Happens in mainline, not sure about other branches. It seems that it
> > > wasn't the case before. It's either a regression (perhaps from my code
> > > for partial transfers) or cache issues (some cache isn't correctly flushed)
> > >   
> > >> Could I help You with it - at least with testing ?
> > >>   
> > >>     
> > > Yes, a test run of keylayouts branch on your hardware would be helpful.
> > > Especially I'm interested if USB data corruption happens in your case too.
> 
> Hi Vladimir,
> 
> I made some tests on machine with UHCI with kbdlayouts branch (rev.
> 2424).
> I did not notice any evident data corruption. But there were some
> another odd results:
> 
> 1.
> My USB keyboard is low speed device (Genius KB-06XE, model no. K639).
> Low speed device transfer was not properly handled - I made some simple
> patch - see attachment, I did not commit it into repository.
> Control type transfer with keyboard is working with this patch, but bulk
> (interrupt) transfer returns always err=7 and in UHCI TD status&control
> are set bits "CRC/Time Out Error" (bit 18) and "Stalled" (bit 22). It is
> the same behavior as some normal full speed mass-storage devices do also
> (I reported it in some previous e-mails). I have some idea right now -
> probably there is bad handling of UHCI transfer status in uhci.c when
> more than one bit is set - GRUB_USB_ERR_TIMEOUT is returned instead of
> GRUB_USB_ERR_STALL. I will try to play with this part during weekend and
> I will report to You if some success happens...
> 
> 2.
> Next bad thing is some problem with device attachment detection or
> handling of newly attached device on non-root hubs. Behavior of this
> problem looks little bit randomly and probably depends also on used port
> of hub - some ports are often working, some not (but all hub ports are
> working normally in Linux/Windows). I did not find reason yet.
> 
> 3.
> Sometimes partitions of USB mass storage devices were not properly
> detected - maybe disk cache problem again?
> Maybe it is data corruption which is reported by you - but I never
> detected data corruption when I read data from files.
> 
> ---
> I am not sure if interrupt transfers can be handled via bulk queue on
> OHCI - according specification, it should be handled via interrupt
> pointers table which is currently not implemented in ohci.c. Did you
> test background polling of interrupt pipe on some PC with OHCI?
> 
> ---
> At the end some maybe bad idea - if I am not wrong, two simultaneous
> transfers can happen (be active in UHCI/OHCI) with current background
> bulk/interrupt transfer. There is question if are all related functions
> fully reentrant ? I.e., is correct handling of some shared data ?
> For the first look I don't see such problem - with one exception:
> donehead interrupt can be probably incorrectly handled in ohci.c - it
> can be detected and misinterpreted by wrong call of
> grub_ohci_check_transfer. The first aid in this case can be forcing of
> OHCI driver into "bad OHCI" mode, i.e. donehead interrupt ignoring - in
> this mode it should work properly.
> 
> Regards
> Ales
> 
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel



^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH] USB issues - kbdlayouts branch
  2010-09-04 17:34             ` Aleš Nesrsta
@ 2010-09-12 17:28               ` Aleš Nesrsta
  2010-09-13 10:43                 ` [PATCH] usb_keyboard.c problems (USB issues - kbdlayouts branch) Aleš Nesrsta
  2010-09-13 11:47                 ` [PATCH] USB issues - kbdlayouts branch Aleš Nesrsta
  0 siblings, 2 replies; 23+ messages in thread
From: Aleš Nesrsta @ 2010-09-12 17:28 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 4313 bytes --]

Hi Vladimir (and, of course, possibly others...),

there is patch which (perhaps) solves some bugs I found in kbdlayouts
branch.

It includes:
0. Previously sent patch for UHCI low speed problem.
1. UHCI transfer error evaluation
2. OHCI cdata de-allocation
3. OHCI proper previous TD unchaining
4. OHCI EDs quantity
5. "Simplified" OHCI driver
6. Non-root hub "multiple reset"
7. OHCI/UHCI port reset handling

Patch is done against kbdlayouts branch version 2424.
I did not commit changes into branch repository.

Please test it on Yeelong and possible other machines, it contains
significant changes (mainly points 5,6,7).


Details about points:

ad 0.
Unfortunately, I still don't have progress with low-speed keyboard -
interrupt (bulk) transfer is not working on UHCI nor OHCI. This patch
solves control transfer only and I still don't know why.

ad 1.
More than one bit can be set in register at the end of transfer and old
evaluation of error code was wrong. Now it is better but probably still
not totally exact - but GRUB does not have so much different USB error
codes currently, so it probably makes not sense.

ad 2.
I did not find de-allocation of cdata in OHCI, so I added it into
finish_transfer.

ad 3.
I found some small mistake in OHCI TD unchaining of last (not processed)
TD which sometimes resulted in bad toggle value.

ad 4.
Increased possible number of connected devices or unplug/plug cycles for
OHCI driver - I wrote approx. two/three months ago about such expected
simple change.

ad 5.
I removed interrupt-like processing of transfers from OHCI driver. I
decided it is unnecessarily complex to implement proper handling of
donehead when "non-single thread execution" of transfer is used
(different cdata).
Only "bad OHCI" code is now in driver (in fact it is your old original
idea/algorithm with some hazards removed and little bit improved).
It should work - I tested it on my OHCI machine and it works well.

ad 6.
There was one big trouble - if I connected into PC hub with two or more
devices connected, usually none was working.
It was caused by "multiple reset" - all devices connected on hub were
reset in the same time, i.e. all devices become into default state with
address 0 - USB specification does not allow such situation, only one
device on one controller can have address 0 at the same time.
I made some relative simple workaround via special flag in controller
structure - it looks working.

ad 7.
I had problems with some devices to be evaluated - hotplugging changed
timing of device detection and evaluation process, so I tried to change
it into more proper way, according USB1.x/2.0, OHCI and UHCI
specifications.
There are three main things which are important:
a. Wait for stable power and insertion procedure completion before issue
reset - at least 100ms, I found more safe it is 250ms
b. Port reset and enable procedure and its timing (50ms reset signal and
after very small delay enable request)
c. Reset recovery delay 10ms

Point a. is little bit complicated by possible not stable "connected"
signal - this problem I detected on my older computer with worse
contacts and also on some very small (usually cheap) devices.

Point b. is relative easy on OHCI and non-root hubs, because OHCI or hub
handles reset procedure timing by itself and port is automatically
enabled after reset. But control of such procedure was not good on OHCI,
I changed it to respect automatic functions of OHCI.
On UHCI reset procedure is handled only via SW and we did not it
properly - it was reason, why some my devices were working on non-root
hub port and not on UHCI root port. I changed more things there, I was
inspired by USB specification and uhci-hub.c from Linux (but code is
different, I did not copy it). I am not sure what was more important -
if timing or bit masking... But result is - now are working all my
devices also on UHCI root port! Of course, I am not sure if it is fully
compatible...

Point c. is easy and it was included in portstatus before.

The last thing is - I deleted disabling of port before resetting and
enabling it - USB specification does not say it is necessary. But if
there is really some reason to use it, why not - but in this case maybe
some delay should be inserted between disable and enable, I not tested
it yet.

Regards
Ales


[-- Attachment #2: usb_patch_USB_issues_100912_0 --]
[-- Type: text/x-patch, Size: 25736 bytes --]

diff -urB ./kbdlayouts/grub-core/bus/usb/ohci.c ./kbdlayouts_changed/grub-core/bus/usb/ohci.c
--- ./kbdlayouts/grub-core/bus/usb/ohci.c	2010-09-03 22:13:28.000000000 +0200
+++ ./kbdlayouts_changed/grub-core/bus/usb/ohci.c	2010-09-12 16:39:39.000000000 +0200
@@ -98,7 +98,6 @@
   struct grub_pci_dma_chunk *td_chunk;
   struct grub_ohci *next;
   grub_ohci_td_t td_free; /* Pointer to first free TD */
-  int bad_OHCI;
 };
 
 static struct grub_ohci *ohci;
@@ -149,8 +148,8 @@
 #define GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE (1 << 4)
 
 #define GRUB_OHCI_RESET_CONNECT_CHANGE (1 << 16)
-#define GRUB_OHCI_CTRL_EDS 16
-#define GRUB_OHCI_BULK_EDS 16
+#define GRUB_OHCI_CTRL_EDS 256
+#define GRUB_OHCI_BULK_EDS 510
 #define GRUB_OHCI_TDS 256
 
 #define GRUB_OHCI_ED_ADDR_MASK 0x7ff
@@ -442,8 +441,10 @@
                        (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA)
                         & ~GRUB_OHCI_RHUB_PORT_POWER_MASK)
                        | GRUB_OHCI_RHUB_PORT_ALL_POWERED);
+#if 0 /* We don't need it at all, handled via hotplugging */
   /* Now we have hot-plugging, we need to wait for stable power only */
   grub_millisleep (100);
+#endif
 
   /* Link to ohci now that initialisation is successful.  */
   o->next = ohci;
@@ -623,7 +624,8 @@
       break;
     }
 
-  /* Set the token (Always generate interrupt - bits 21-23 = 0).  */
+  /* Set the token */
+  token |= ( 7 << 21); /* Never generate interrupt */
   token |= toggle << 24;
   token |= 1 << 25;
 
@@ -659,7 +661,6 @@
   grub_ohci_ed_t ed_virt;
   grub_ohci_td_t td_current_virt;
   grub_ohci_td_t td_head_virt;
-  grub_uint64_t bad_OHCI_delay;
 };
 
 static grub_usb_err_t
@@ -756,10 +757,6 @@
 
       /* Set index of TD in transfer */
       cdata->td_current_virt->tr_index = (grub_uint32_t) i;
-
-      /* No IRQ request in TD if bad_OHCI set */
-      if (o->bad_OHCI)
-        cdata->td_current_virt->token |= grub_cpu_to_le32 ( 7 << 21);
       
       /* Remember last used (processed) TD phys. addr. */
       cdata->td_last_phys = grub_ohci_td_virt2phys (o, cdata->td_current_virt);
@@ -891,8 +888,8 @@
   /* Now print debug values - to have full info what happened */
   grub_dprintf ("ohci", "loop finished: control=0x%02x status=0x%02x\n",
 		control, status);
-  grub_dprintf ("ohci", "intstatus=0x%02x \n\t\t tderr_phys=0x%02x, td_last_phys=0x%02x\n",
-		intstatus, cdata->tderr_phys, cdata->td_last_phys);
+  grub_dprintf ("ohci", "intstatus=0x%02x, td_last_phys=0x%02x\n",
+		intstatus, cdata->td_last_phys);
   grub_dprintf ("ohci", "TARGET=0x%02x, HEAD=0x%02x, TAIL=0x%02x\n",
                 target,
                 grub_le_to_cpu32 (cdata->ed_virt->td_head),
@@ -915,12 +912,6 @@
    *    i.e. it is safe to free all TDs except last not processed
    * ED HEAD == TAIL == phys. addr. of td_current_virt */
 
-  /* Reset DoneHead - sanity cleanup */
-  o->hcca->donehead = 0;
-  grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1));
-  /* Read back of register should ensure it is really written */
-  grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
-
   /* Un-chainig of last TD */
   if (cdata->td_current_virt->prev_td_phys)
     {
@@ -929,10 +920,13 @@
       
       if (cdata->td_current_virt == (grub_ohci_td_t) td_prev_virt->link_td)
         td_prev_virt->link_td = 0;
+
+      cdata->td_current_virt->prev_td_phys = 0;
     }
 
   grub_dprintf ("ohci", "OHCI finished, freeing\n");
   grub_ohci_free_tds (o, cdata->td_head_virt);
+  grub_free (cdata);
 }
 
 static grub_usb_err_t
@@ -951,28 +945,10 @@
   pre_finish_transfer (dev, transfer);
 
   /* First we must get proper tderr_phys value */
-  if (o->bad_OHCI) /* In case of bad_OHCI tderr_phys can be wrong */
-    {
-      if (cdata->tderr_phys) /* check if tderr_phys points to TD with error */
-	errcode = grub_le_to_cpu32 (grub_ohci_td_phys2virt (o,
-							    cdata->tderr_phys)->token)
-	  >> 28;
-      if ( !cdata->tderr_phys || !errcode ) /* tderr_phys not valid or points to wrong TD */
-	{ /* Retired TD with error should be previous TD to ED->td_head */
-	  cdata->tderr_phys = grub_ohci_td_phys2virt (o,
-						      grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf )
-	    ->prev_td_phys;
-	}
-    }
-  /* Even if we have "good" OHCI, in some cases
-   * tderr_phys can be zero, check it */
-  else if (!cdata->tderr_phys)
-    /* Retired TD with error should be previous TD to ED->td_head */
-    cdata->tderr_phys 
-      = grub_ohci_td_phys2virt (o,
-				grub_le_to_cpu32 (cdata->ed_virt->td_head)
-				& ~0xf)->prev_td_phys;
-    
+  /* Retired TD with error should be previous TD to ED->td_head */
+  cdata->tderr_phys = grub_ohci_td_phys2virt (o,
+                                                grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf )
+	              ->prev_td_phys;
 
   /* Prepare pointer to last processed TD and get error code */
   tderr_virt = grub_ohci_td_phys2virt (o, cdata->tderr_phys);
@@ -1090,16 +1067,12 @@
 
   pre_finish_transfer (dev, transfer);
 
-  /* Simple workaround if donehead is not working */
-  if (o->bad_OHCI &&
-      (!cdata->tderr_phys || (cdata->tderr_phys != cdata->td_last_phys)))
-    {
-      grub_dprintf ("ohci", "normal finish, but tderr_phys corrected\n");
-      cdata->tderr_phys = cdata->td_last_phys;
-      /* I hope we can do it as transfer (most probably) finished OK */
-    }
+  /* I hope we can do it as transfer (most probably) finished OK */
+  cdata->tderr_phys = cdata->td_last_phys;
+
   /* Prepare pointer to last processed TD */
   tderr_virt = grub_ohci_td_phys2virt (o, cdata->tderr_phys);
+  
   /* Set index of last processed TD */
   if (tderr_virt)
     transfer->last_trans = tderr_virt->tr_index;
@@ -1168,25 +1141,6 @@
 
   /* Check transfer status */
   intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
-  if (!o->bad_OHCI && (intstatus & 0x2) != 0)
-    {
-      /* Remember last successful TD */
-      cdata->tderr_phys = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf;
-      /* Reset DoneHead */
-      o->hcca->donehead = 0;
-      grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1));
-      /* Read back of register should ensure it is really written */
-      grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
-      /* if TD is last, finish */
-      if (cdata->tderr_phys == cdata->td_last_phys)
-	{
-	  if (grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1)
-	    return parse_halt (dev, transfer, actual);
-	  else
-	    return parse_success (dev, transfer, actual);
-	}
-      return GRUB_USB_ERR_WAIT;
-    }
 
   if ((intstatus & 0x10) != 0)
     /* Unrecoverable error - only reset can help...! */
@@ -1194,54 +1148,20 @@
 
   /* Detected a HALT.  */
   if ((grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1))
-    {
-      /* ED is halted, but donehead event can happened in the meantime */
-      intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
-      if (!o->bad_OHCI && (intstatus & 0x2) != 0)
-	{
-	  /* Remember last successful TD */
-	  cdata->tderr_phys = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf;
-	  /* Reset DoneHead */
-	  o->hcca->donehead = 0;
-	  grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1));
-	  /* Read back of register should ensure it is really written */
-	  grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
-	  /* if TD is last, finish */
-	}
-      return parse_halt (dev, transfer, actual);
-    }
+    return parse_halt (dev, transfer, actual);
 
-  /* bad OHCI handling */
+  /* Finished ED detection */
   if ( (grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf) ==
        (grub_le_to_cpu32 (cdata->ed_virt->td_tail) & ~0xf) ) /* Empty ED */
     {
-      if (o->bad_OHCI) /* Bad OHCI detected previously */
-	{
-	  /* Try get last successful TD. */
-	  cdata->tderr_phys = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf;
-	  if (cdata->tderr_phys)/* Reset DoneHead if we were successful */
-	    {
-	      o->hcca->donehead = 0;
-	      grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1));
-	      /* Read back of register should ensure it is really written */
-	      grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
-	    }
-	  /* Check the HALT bit */
-	  if (grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1)
-	    return parse_halt (dev, transfer, actual);
-	  else
-	    return parse_success (dev, transfer, actual);
-	}
-      else /* Detection of bad OHCI */
-	/* We should wait short time (~2ms) before we say that
-	 * it is bad OHCI to prevent some hazard -
-	 * donehead can react in the meantime. This waiting is done
-	 * only once per OHCI driver "live cycle". */
-	if (!cdata->bad_OHCI_delay) /* Set delay time */
-	  cdata->bad_OHCI_delay = grub_get_time_ms () + 2;
-	else if (grub_get_time_ms () >= cdata->bad_OHCI_delay)
-	  o->bad_OHCI = 1;
-      return GRUB_USB_ERR_WAIT;
+      /* Check the HALT bit */
+      /* It looks like nonsense - it was tested previously...
+       * but it can change because OHCI is working
+       * simultaneously via DMA... */
+      if (grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1)
+	return parse_halt (dev, transfer, actual);
+      else
+        return parse_success (dev, transfer, actual);
     }
 
   return GRUB_USB_ERR_WAIT;
@@ -1266,14 +1186,16 @@
   /* Wait for new SOF */
   while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0);
 
-  /* Now we must find last processed TD if bad_OHCI == TRUE */
-  if (o->bad_OHCI)
-    /* Retired TD with error should be previous TD to ED->td_head */
-    cdata->tderr_phys
-      = grub_ohci_td_phys2virt (o, grub_le_to_cpu32 (cdata->ed_virt->td_head)
-				& ~0xf)->prev_td_phys;
+  /* Possible retired TD with error should be previous TD to ED->td_head */
+  cdata->tderr_phys
+    = grub_ohci_td_phys2virt (o, grub_le_to_cpu32 (cdata->ed_virt->td_head)
+                              & ~0xf)->prev_td_phys;
     
   tderr_virt = grub_ohci_td_phys2virt (o,cdata-> tderr_phys);
+
+  grub_dprintf ("ohci", "Cancel: tderr_phys=0x%08x, tderr_virt=0x%08x\n",
+                cdata->tderr_phys, (unsigned int)tderr_virt);
+
   if (tderr_virt)
     transfer->last_trans = tderr_virt->tr_index;
   else
@@ -1310,27 +1232,39 @@
        return GRUB_ERR_NONE;
      }
      
-   /* Reset the port */
+   /* Reset the port - timing of reset is done by OHCI */
    grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
 			 GRUB_OHCI_SET_PORT_RESET);
-   grub_millisleep (50); /* For root hub should be nominaly 50ms */
- 
-    /* End the reset signaling.  */
-   grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
-			 GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE);
-   grub_millisleep (10);
 
-   /* Enable the port and wait for it. */
-   grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
-                         GRUB_OHCI_SET_PORT_ENABLE);
+   /* Wait for reset completion */
    endtime = grub_get_time_ms () + 1000;
    while (! (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)
-           & (1 << 1)))
+           & GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE))
      if (grub_get_time_ms () > endtime)
-       return grub_error (GRUB_ERR_IO, "OHCI Timed out - enable");
+       return grub_error (GRUB_ERR_IO, "OHCI Timed out - reset");
 
-   grub_millisleep (10);
+   /* End the reset signaling - reset the reset status change  */
+   grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
+			 GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE);
+
+   /* According to USB and OHCI specification, port should be enabled
+    * automaticaly now - but... */
+   if (! (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)
+           & (1 << 1)))
+     {
+       /* Enable the port and wait for it. */
+       grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
+                             GRUB_OHCI_SET_PORT_ENABLE);
+       endtime = grub_get_time_ms () + 1000;
+       while (! (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)
+               & (1 << 1)))
+         if (grub_get_time_ms () > endtime)
+           return grub_error (GRUB_ERR_IO, "OHCI Timed out - enable");
+     }
 
+   /* "Reset recovery time" (USB spec.) */
+   grub_millisleep (10);
+   
    /* Reset bit Connect Status Change */
    grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
                          GRUB_OHCI_RESET_CONNECT_CHANGE);
diff -urB ./kbdlayouts/grub-core/bus/usb/uhci.c ./kbdlayouts_changed/grub-core/bus/usb/uhci.c
--- ./kbdlayouts/grub-core/bus/usb/uhci.c	2010-09-03 22:13:28.000000000 +0200
+++ ./kbdlayouts_changed/grub-core/bus/usb/uhci.c	2010-09-12 15:56:42.000000000 +0200
@@ -53,6 +53,8 @@
     | GRUB_UHCI_REG_PORTSC_SUSPEND
   };
 
+/* These bits should not be written as 1 unless we really need it */
+#define GRUB_UHCI_PORTSC_ZERO ((1<<1) | (1<<3) | (1<<11) | (3<<13))
 
 /* UHCI Queue Head.  */
 struct grub_uhci_qh
@@ -414,7 +416,7 @@
 grub_uhci_transaction (struct grub_uhci *u, unsigned int endp,
 		       grub_transfer_type_t type, unsigned int addr,
 		       unsigned int toggle, grub_size_t size,
-		       grub_uint32_t data)
+		       grub_uint32_t data, grub_usb_speed_t speed)
 {
   grub_uhci_td_t td;
   static const unsigned int tf[] = { 0x69, 0xE1, 0x2D };
@@ -439,7 +441,8 @@
   td->linkptr = 1;
 
   /* Active!  Only retry a transfer 3 times.  */
-  td->ctrl_status = (1 << 23) | (3 << 27);
+  td->ctrl_status = (1 << 23) | (3 << 27) |
+                    ((speed == GRUB_USB_SPEED_LOW) ? (1 << 26) : 0);
 
   /* If zero bytes are transmitted, size is 0x7FF.  Otherwise size is
      size-1.  */
@@ -495,7 +498,8 @@
 
       td = grub_uhci_transaction (u, transfer->endpoint & 15, tr->pid,
 				  transfer->devaddr, tr->toggle,
-				  tr->size, tr->data);
+				  tr->size, tr->data,
+				  transfer->dev->speed);
       if (! td)
 	{
 	  grub_size_t actual = 0;
@@ -576,23 +580,23 @@
 	err = GRUB_USB_ERR_STALL;
       
       /* Check if an error related to the data buffer occurred.  */
-      if (errtd->ctrl_status & (1 << 21))
+      else if (errtd->ctrl_status & (1 << 21))
 	err = GRUB_USB_ERR_DATA;
       
       /* Check if a babble error occurred.  */
-      if (errtd->ctrl_status & (1 << 20))
+      else if (errtd->ctrl_status & (1 << 20))
 	err = GRUB_USB_ERR_BABBLE;
       
       /* Check if a NAK occurred.  */
-      if (errtd->ctrl_status & (1 << 19))
+      else if (errtd->ctrl_status & (1 << 19))
 	err = GRUB_USB_ERR_NAK;
       
       /* Check if a timeout occurred.  */
-      if (errtd->ctrl_status & (1 << 18))
+      else if (errtd->ctrl_status & (1 << 18))
 	err = GRUB_USB_ERR_TIMEOUT;
       
       /* Check if a bitstuff error occurred.  */
-      if (errtd->ctrl_status & (1 << 17))
+      else if (errtd->ctrl_status & (1 << 17))
 	err = GRUB_USB_ERR_BITSTUFF;
       
       if (err)
@@ -683,7 +687,7 @@
       endtime = grub_get_time_ms () + 1000;
       while ((grub_uhci_readreg16 (u, reg) & (1 << 2)))
         if (grub_get_time_ms () > endtime)
-          return grub_error (GRUB_ERR_IO, "UHCI Timed out");
+          return grub_error (GRUB_ERR_IO, "UHCI Timed out - disable");
 
       status = grub_uhci_readreg16 (u, reg);
       grub_dprintf ("uhci", ">3detect=0x%02x\n", status);
@@ -691,28 +695,37 @@
     }
     
   /* Reset the port.  */
-  grub_uhci_writereg16 (u, reg, 1 << 9);
+  status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_ZERO;
+  grub_uhci_writereg16 (u, reg, status | (1 << 9));
+  grub_uhci_readreg16 (u, reg); /* Ensure it is writen... */
 
   /* Wait for the reset to complete.  XXX: How long exactly?  */
   grub_millisleep (50); /* For root hub should be nominaly 50ms */
-  status = grub_uhci_readreg16 (u, reg);
+  status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_ZERO;
   grub_uhci_writereg16 (u, reg, status & ~(1 << 9));
+  grub_uhci_readreg16 (u, reg); /* Ensure it is writen... */
   grub_dprintf ("uhci", "reset completed\n");
-  grub_millisleep (10);
+  grub_millisleep (1); /* Probably not needed at all or only few microsecs. */
+
+  /* Reset bits Connect & Enable Status Change */
+  status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_ZERO;
+  grub_uhci_writereg16 (u, reg, status | (1 << 3) | GRUB_UHCI_REG_PORTSC_CONNECT_CHANGED);
+  grub_uhci_readreg16 (u, reg); /* Ensure it is writen... */
 
   /* Enable the port.  */
-  grub_uhci_writereg16 (u, reg, 1 << 2);
-  grub_millisleep (10);
+  status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_ZERO;
+  grub_uhci_writereg16 (u, reg, status | (1 << 2));
+  grub_uhci_readreg16 (u, reg); /* Ensure it is writen... */
 
   grub_dprintf ("uhci", "waiting for the port to be enabled\n");
 
   endtime = grub_get_time_ms () + 1000;
   while (! ((status = grub_uhci_readreg16 (u, reg)) & (1 << 2)))
     if (grub_get_time_ms () > endtime)
-      return grub_error (GRUB_ERR_IO, "UHCI Timed out");
+      return grub_error (GRUB_ERR_IO, "UHCI Timed out - enable");
 
-  /* Reset bit Connect Status Change */
-  grub_uhci_writereg16 (u, reg, status | GRUB_UHCI_REG_PORTSC_CONNECT_CHANGED);
+  /* Reset recovery time */
+  grub_millisleep (10);
 
   /* Read final port status */
   status = grub_uhci_readreg16 (u, reg);
diff -urB ./kbdlayouts/grub-core/bus/usb/usb.c ./kbdlayouts_changed/grub-core/bus/usb/usb.c
--- ./kbdlayouts/grub-core/bus/usb/usb.c	2010-09-03 22:13:28.000000000 +0200
+++ ./kbdlayouts_changed/grub-core/bus/usb/usb.c	2010-09-12 16:40:41.000000000 +0200
@@ -262,7 +262,7 @@
 
       if (dev->config[0].interf[i].attached)
 	continue;
-
+	
       for (desc = attach_hooks; desc; desc = desc->next)
 	if (interf->class == desc->class && desc->hook (dev, 0, i))
 	  dev->config[0].interf[i].attached = 1;
diff -urB ./kbdlayouts/grub-core/bus/usb/usbhub.c ./kbdlayouts_changed/grub-core/bus/usb/usbhub.c
--- ./kbdlayouts/grub-core/bus/usb/usbhub.c	2010-09-03 22:13:28.000000000 +0200
+++ ./kbdlayouts_changed/grub-core/bus/usb/usbhub.c	2010-09-12 11:35:17.000000000 +0200
@@ -179,19 +179,45 @@
 {
   grub_usb_device_t dev;
   grub_err_t err;
+  int total, i;
+  grub_usb_speed_t current_speed = GRUB_USB_SPEED_NONE;
+  int changed=0;
 
+#if 0
+/* Specification does not say about disabling of port when device
+ * connected. If disabling is really necessary for some devices,
+ * delete this #if 0 and related #endif */
   /* Disable the port. XXX: Why? */
   err = hub->controller->dev->portstatus (hub->controller, portno, 0);
   if (err)
     return;
+#endif
+  /* Wait for completion of insertion and stable power (USB spec.)
+   * Should be at least 100ms, some devices requires more...
+   * There is also another thing - some devices have worse contacts
+   * and connected signal is unstable for some time - we should handle
+   * it - but prevent deadlock in case when device is too faulty... */
+  for (total = i = 0; (i < 250) && (total < 2000); i++, total++)
+    {
+      grub_millisleep (1);
+      current_speed = hub->controller->dev->detect_dev
+                        (hub->controller, portno, &changed);
+      if (current_speed == GRUB_USB_SPEED_NONE)
+        i = 0;
+    }
+  grub_dprintf ("usb", "total=%d\n", total);
+  if (total >= 2000)
+    return;
 
   /* Enable the port.  */
   err = hub->controller->dev->portstatus (hub->controller, portno, 1);
   if (err)
     return;
+  hub->controller->dev->pending_reset = grub_get_time_ms () + 5000;
 
   /* Enable the port and create a device.  */
   dev = grub_usb_hub_add_dev (hub->controller, speed);
+  hub->controller->dev->pending_reset = 0;
   if (! dev)
     return;
 
@@ -238,11 +264,14 @@
   for (i = 0; i < hub->nports; i++)
     {
       grub_usb_speed_t speed;
-      speed = controller->dev->detect_dev (hub->controller, i,
-					   &changed);
-
-      if (speed != GRUB_USB_SPEED_NONE)
-	attach_root_port (hub, i, speed);
+      if (!controller->dev->pending_reset)
+        {
+          speed = controller->dev->detect_dev (hub->controller, i,
+					       &changed);
+
+          if (speed != GRUB_USB_SPEED_NONE)
+	    attach_root_port (hub, i, speed);
+        }
     }
 
   return GRUB_USB_ERR_NONE;
@@ -284,6 +313,7 @@
   unsigned i;
   grub_uint8_t changed;
   grub_size_t actual;
+  int j, total;
 
   if (!dev->hub_transfer)
     return;
@@ -308,6 +338,7 @@
   for (i = 1; i <= dev->nports; i++)
     {
       grub_uint32_t status;
+      grub_uint32_t current_status = 0;
 
       if (!(changed & (1 << i)))
 	continue;
@@ -319,7 +350,8 @@
 				  GRUB_USB_REQ_GET_STATUS,
 				  0, i, sizeof (status), (char *) &status);
 
-      grub_printf ("i = %d, status = %08x\n", i, status);
+      grub_printf ("dev = 0x%0x, i = %d, status = %08x\n",
+                   (unsigned int) dev, i, status);
 
       if (err)
 	continue;
@@ -346,7 +378,8 @@
 			      GRUB_USB_REQ_CLEAR_FEATURE,
 			      GRUB_USB_HUB_FEATURE_C_PORT_OVERCURRENT, i, 0, 0);
 
-      if (status & GRUB_USB_HUB_STATUS_C_PORT_CONNECTED)
+      if (!dev->controller.dev->pending_reset &&
+          (status & GRUB_USB_HUB_STATUS_C_PORT_CONNECTED))
 	{
 	  grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
 				      | GRUB_USB_REQTYPE_CLASS
@@ -360,8 +393,36 @@
 	  /* Connected and status of connection changed ? */
 	  if (status & GRUB_USB_HUB_STATUS_PORT_CONNECTED)
 	    {
-	      /* A device is actually connected to this port.
-	       * Now do reset of port. */
+	      /* A device is actually connected to this port. */
+  /* Wait for completion of insertion and stable power (USB spec.)
+   * Should be at least 100ms, some devices requires more...
+   * There is also another thing - some devices have worse contacts
+   * and connected signal is unstable for some time - we should handle
+   * it - but prevent deadlock in case when device is too faulty... */
+              for (total = j = 0; (j < 250) && (total < 2000); j++, total++)
+                {
+                  grub_millisleep (1);
+                  /* Get the port status.  */
+                  err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
+					       | GRUB_USB_REQTYPE_CLASS
+					       | GRUB_USB_REQTYPE_TARGET_OTHER),
+				              GRUB_USB_REQ_GET_STATUS,
+				              0, i,
+				              sizeof (current_status),
+				              (char *) &current_status);
+                  if (err)
+                    {
+                      total = 2000;
+	              break;
+                    }
+                  if (!(current_status & GRUB_USB_HUB_STATUS_PORT_CONNECTED))
+                    j = 0;
+                }
+              grub_dprintf ("usb", "(non-root) total=%d\n", total);
+              if (total >= 2000)
+                continue;
+
+              /* Now do reset of port. */
 	      grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
 					  | GRUB_USB_REQTYPE_CLASS
 					  | GRUB_USB_REQTYPE_TARGET_OTHER),
@@ -369,6 +430,15 @@
 				    GRUB_USB_HUB_FEATURE_PORT_RESET,
 				    i, 0, 0);
 	      rescan = 1;
+	      /* We cannot reset more than one device at the same time !
+	       * Resetting more devices together results in very bad
+	       * situation: more than one device has default address 0
+	       * at the same time !!!
+	       * Additionaly, we cannot perform another reset
+	       * anywhere on the same OHCI controller until
+	       * we will finish addressing of reseted device ! */
+              dev->controller.dev->pending_reset = grub_get_time_ms () + 5000;
+              return;
 	    }
 	}
 
@@ -401,6 +471,7 @@
 
 	      /* Add the device and assign a device address to it.  */
 	      next_dev = grub_usb_hub_add_dev (&dev->controller, speed);
+	      dev->controller.dev->pending_reset = 0;
 	      if (! next_dev)
 		continue;
 
@@ -426,12 +497,21 @@
       /* No, it should be never changed, it should be constant. */
       for (i = 0; i < hub->nports; i++)
 	{
-	  grub_usb_speed_t speed;
+	  grub_usb_speed_t speed = GRUB_USB_SPEED_NONE;
 	  int changed = 0;
 
-	  speed = hub->controller->dev->detect_dev (hub->controller, i,
-	                                            &changed);
-
+          if (!hub->controller->dev->pending_reset)
+            {
+              /* Check for possible timeout */
+              if (grub_get_time_ms () > hub->controller->dev->pending_reset)
+                {
+                  /* Something went wrong, reset device was not
+                   * addressed properly, timeout happened */
+	          hub->controller->dev->pending_reset = 0;
+	          speed = hub->controller->dev->detect_dev (hub->controller,
+                                                            i, &changed);
+                }
+            }
 	  if (changed)
 	    {
 	      detach_device (hub->devices[i]);
diff -urB ./kbdlayouts/grub-core/bus/usb/usbtrans.c ./kbdlayouts_changed/grub-core/bus/usb/usbtrans.c
--- ./kbdlayouts/grub-core/bus/usb/usbtrans.c	2010-09-03 22:13:28.000000000 +0200
+++ ./kbdlayouts_changed/grub-core/bus/usb/usbtrans.c	2010-09-10 23:10:27.000000000 +0200
@@ -33,10 +33,12 @@
   grub_usb_err_t err;
   grub_uint64_t endtime;
 
-  endtime = grub_get_time_ms () + timeout;
   err = dev->controller.dev->setup_transfer (&dev->controller, transfer);
   if (err)
     return err;
+  /* endtime moved behind setup transfer to prevent false timeouts
+   * while debugging... */
+  endtime = grub_get_time_ms () + timeout;
   while (1)
     {
       err = dev->controller.dev->check_transfer (&dev->controller, transfer,
diff -urB ./kbdlayouts/include/grub/usb.h ./kbdlayouts_changed/include/grub/usb.h
--- ./kbdlayouts/include/grub/usb.h	2010-09-03 22:13:28.000000000 +0200
+++ ./kbdlayouts_changed/include/grub/usb.h	2010-09-12 16:30:41.000000000 +0200
@@ -116,6 +116,9 @@
 
   grub_usb_speed_t (*detect_dev) (grub_usb_controller_t dev, int port, int *changed);
 
+  /* Per controller flag - port reset pending, don't do another reset */
+  grub_uint64_t pending_reset;
+  
   /* The next host controller.  */
   struct grub_usb_controller_dev *next;
 };

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH] usb_keyboard.c problems (USB issues - kbdlayouts branch)
  2010-09-12 17:28               ` [PATCH] USB issues - kbdlayouts branch Aleš Nesrsta
@ 2010-09-13 10:43                 ` Aleš Nesrsta
  2010-09-13 11:47                 ` [PATCH] USB issues - kbdlayouts branch Aleš Nesrsta
  1 sibling, 0 replies; 23+ messages in thread
From: Aleš Nesrsta @ 2010-09-13 10:43 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 447 bytes --]

Hi,

I found two problems in usb_keyboard, included patch should solve them
(I hope...):

1.
Configuration of USB device was misssing.
(Additionally, for low speed devices on UHCI should be applied patch
which I sent at Sat, 04 Sep 2010 00:02:28, subject: "Re: Plans on 1.99
release - USB issues").

2.
Received report was wrongly interpreted. It caused wrong repeating of
keys, for example when more than one key were pressed etc.

Regards
Ales


[-- Attachment #2: usb_keyboard_patch_100913_0 --]
[-- Type: text/x-patch, Size: 5544 bytes --]

diff -urB ./kbdlayouts/grub-core/term/usb_keyboard.c ./kbdlayouts_changed/grub-core/term/usb_keyboard.c
--- ./kbdlayouts/grub-core/term/usb_keyboard.c	2010-09-03 22:13:28.000000000 +0200
+++ ./kbdlayouts_changed/grub-core/term/usb_keyboard.c	2010-09-13 12:21:50.000000000 +0200
@@ -75,6 +75,10 @@
   int dead;
   int last_key;
   grub_uint64_t repeat_time;
+  grub_uint8_t current_report[8];
+  grub_uint8_t last_report[8];
+  int index;
+  int max_index;
 };
 
 static int grub_usb_keyboard_getkey (struct grub_term_input *term);
@@ -192,6 +196,9 @@
   data->interfno = interfno;
   data->endp = endp;
 
+  /* Configure device */
+  grub_usb_set_configuration (usbdev, configno + 1);
+  
   /* Place the device in boot mode.  */
   grub_usb_control_msg (usbdev, GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT,
   			USB_HID_SET_PROTOCOL, 0, interfno, 0, 0);
@@ -271,16 +278,95 @@
 }
 
 static int
+parse_keycode (struct grub_usb_keyboard_data *termdata)
+{
+  int index = termdata->index;
+  int i, keycode;
+
+  /* Sanity check */
+  if (index < 2)
+    index = 2;
+
+  for ( ; index < termdata->max_index; index++)
+    {
+      keycode = termdata->current_report[index];
+      
+      if (keycode == KEY_NO_KEY
+          || keycode == KEY_ERR_BUFFER
+          || keycode == KEY_ERR_POST
+          || keycode == KEY_ERR_UNDEF)
+        {
+          /* Don't parse (rest of) this report */
+          termdata->index = 0;
+          if (keycode != KEY_NO_KEY)
+          /* Don't replace last report with current faulty report
+           * in future ! */
+            grub_memcpy (termdata->current_report,
+                         termdata->last_report,
+                         sizeof (termdata->report));
+          return GRUB_TERM_NO_KEY;
+        }
+
+      /* Try to find current keycode in last report. */
+      for (i = 2; i < 8; i++)
+        if (keycode == termdata->last_report[i])
+          break;
+      if (i < 8)
+        /* Keycode is in last report, it means it was not released,
+         * ignore it. */
+        continue;
+        
+      if (keycode == KEY_CAPS_LOCK)
+        {
+          termdata->mods ^= GRUB_TERM_STATUS_CAPS;
+          send_leds (termdata);
+          continue;
+        }
+
+      if (keycode == KEY_NUM_LOCK)
+        {
+          termdata->mods ^= GRUB_TERM_STATUS_NUM;
+          send_leds (termdata);
+          continue;
+        }
+
+      termdata->last_key = grub_term_map_key (keycode,
+                                              interpret_status (termdata->current_report[0])
+					        | termdata->mods);
+      termdata->repeat_time = grub_get_time_ms () + GRUB_TERM_REPEAT_PRE_INTERVAL;
+
+      grub_errno = GRUB_ERR_NONE;
+
+      index++;
+      if (index >= termdata->max_index)
+        termdata->index = 0;
+      else
+        termdata->index = index;
+
+      return termdata->last_key;
+    }
+
+  /* All keycodes parsed */
+  termdata->index = 0;
+  return GRUB_TERM_NO_KEY;
+}
+
+static int
 grub_usb_keyboard_getkey (struct grub_term_input *term)
 {
   grub_usb_err_t err;
   struct grub_usb_keyboard_data *termdata = term->data;
-  grub_uint8_t data[sizeof (termdata->report)];
   grub_size_t actual;
+  int keycode = GRUB_TERM_NO_KEY;
 
   if (termdata->dead)
     return GRUB_TERM_NO_KEY;
 
+  if (termdata->index)
+    keycode = parse_keycode (termdata);
+  if (keycode != GRUB_TERM_NO_KEY)
+    return keycode;
+    
   /* Poll interrupt pipe.  */
   err = grub_usb_check_transfer (termdata->transfer, &actual);
 
@@ -296,7 +382,14 @@
       return GRUB_TERM_NO_KEY;
     }
 
-  grub_memcpy (data, termdata->report, sizeof (data));
+  if (!err && (actual >= 3))
+    grub_memcpy (termdata->last_report,
+                 termdata->current_report,
+                 sizeof (termdata->report));
+                 
+  grub_memcpy (termdata->current_report,
+               termdata->report,
+               sizeof (termdata->report));
 
   termdata->transfer = grub_usb_bulk_read_background (termdata->usbdev,
 						      termdata->endp->endp_addr,
@@ -314,42 +407,23 @@
 		"err = %d, actual = %d report: 0x%02x 0x%02x 0x%02x 0x%02x"
 		" 0x%02x 0x%02x 0x%02x 0x%02x\n",
 		err, actual,
-		data[0], data[1], data[2], data[3],
-		data[4], data[5], data[6], data[7]);
+		termdata->current_report[0], termdata->current_report[1],
+		termdata->current_report[2], termdata->current_report[3],
+		termdata->current_report[4], termdata->current_report[5],
+		termdata->current_report[6], termdata->current_report[7]);
 
   if (err || actual < 1)
     return GRUB_TERM_NO_KEY;
 
-  termdata->status = data[0];
+  termdata->status = termdata->current_report[0];
 
   if (actual < 3)
     return GRUB_TERM_NO_KEY;
 
-  if (data[2] == KEY_NO_KEY || data[2] == KEY_ERR_BUFFER
-      || data[2] == KEY_ERR_POST || data[2] == KEY_ERR_UNDEF)
-    return GRUB_TERM_NO_KEY;
-
-  if (data[2] == KEY_CAPS_LOCK)
-    {
-      termdata->mods ^= GRUB_TERM_STATUS_CAPS;
-      send_leds (termdata);
-      return GRUB_TERM_NO_KEY;
-    }
-
-  if (data[2] == KEY_NUM_LOCK)
-    {
-      termdata->mods ^= GRUB_TERM_STATUS_NUM;
-      send_leds (termdata);
-      return GRUB_TERM_NO_KEY;
-    }
-
-  termdata->last_key = grub_term_map_key (data[2], interpret_status (data[0])
-					  | termdata->mods);
-  termdata->repeat_time = grub_get_time_ms () + GRUB_TERM_REPEAT_PRE_INTERVAL;
-
-  grub_errno = GRUB_ERR_NONE;
-
-  return termdata->last_key;
+  termdata->index = 2; /* New data received. */
+  termdata->max_index = actual;
+  
+  return parse_keycode (termdata);
 }
 
 static int

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] USB issues - kbdlayouts branch
  2010-09-12 17:28               ` [PATCH] USB issues - kbdlayouts branch Aleš Nesrsta
  2010-09-13 10:43                 ` [PATCH] usb_keyboard.c problems (USB issues - kbdlayouts branch) Aleš Nesrsta
@ 2010-09-13 11:47                 ` Aleš Nesrsta
  2010-09-13 18:13                   ` Aleš Nesrsta
  1 sibling, 1 reply; 23+ messages in thread
From: Aleš Nesrsta @ 2010-09-13 11:47 UTC (permalink / raw)
  To: The development of GNU GRUB

Hi,

today I discovered some small problem related to my last patch described
in e-mail below, point 7. The problem is:

The first (and only first) connection of USB device to root hub port is
not properly recognized or handled, any other subsequent connection is
OK.
It looks like it is the same on OHCI and UHCI, so maybe it is related to
common part (usbhub.c) or device initialization.
I am now investigating what is wrong...

Regards
Ales

Aleš Nesrsta wrote:
> Hi Vladimir (and, of course, possibly others...),
> 
> there is patch which (perhaps) solves some bugs I found in kbdlayouts
> branch.
> 
> It includes:
> 0. Previously sent patch for UHCI low speed problem.
> 1. UHCI transfer error evaluation
> 2. OHCI cdata de-allocation
> 3. OHCI proper previous TD unchaining
> 4. OHCI EDs quantity
> 5. "Simplified" OHCI driver
> 6. Non-root hub "multiple reset"
> 7. OHCI/UHCI port reset handling
> 
> Patch is done against kbdlayouts branch version 2424.
> I did not commit changes into branch repository.
> 
> Please test it on Yeelong and possible other machines, it contains
> significant changes (mainly points 5,6,7).
> 
> 
> Details about points:
> 
> ad 0.
> Unfortunately, I still don't have progress with low-speed keyboard -
> interrupt (bulk) transfer is not working on UHCI nor OHCI. This patch
> solves control transfer only and I still don't know why.
> 
> ad 1.
> More than one bit can be set in register at the end of transfer and old
> evaluation of error code was wrong. Now it is better but probably still
> not totally exact - but GRUB does not have so much different USB error
> codes currently, so it probably makes not sense.
> 
> ad 2.
> I did not find de-allocation of cdata in OHCI, so I added it into
> finish_transfer.
> 
> ad 3.
> I found some small mistake in OHCI TD unchaining of last (not processed)
> TD which sometimes resulted in bad toggle value.
> 
> ad 4.
> Increased possible number of connected devices or unplug/plug cycles for
> OHCI driver - I wrote approx. two/three months ago about such expected
> simple change.
> 
> ad 5.
> I removed interrupt-like processing of transfers from OHCI driver. I
> decided it is unnecessarily complex to implement proper handling of
> donehead when "non-single thread execution" of transfer is used
> (different cdata).
> Only "bad OHCI" code is now in driver (in fact it is your old original
> idea/algorithm with some hazards removed and little bit improved).
> It should work - I tested it on my OHCI machine and it works well.
> 
> ad 6.
> There was one big trouble - if I connected into PC hub with two or more
> devices connected, usually none was working.
> It was caused by "multiple reset" - all devices connected on hub were
> reset in the same time, i.e. all devices become into default state with
> address 0 - USB specification does not allow such situation, only one
> device on one controller can have address 0 at the same time.
> I made some relative simple workaround via special flag in controller
> structure - it looks working.
> 
> ad 7.
> I had problems with some devices to be evaluated - hotplugging changed
> timing of device detection and evaluation process, so I tried to change
> it into more proper way, according USB1.x/2.0, OHCI and UHCI
> specifications.
> There are three main things which are important:
> a. Wait for stable power and insertion procedure completion before issue
> reset - at least 100ms, I found more safe it is 250ms
> b. Port reset and enable procedure and its timing (50ms reset signal and
> after very small delay enable request)
> c. Reset recovery delay 10ms
> 
> Point a. is little bit complicated by possible not stable "connected"
> signal - this problem I detected on my older computer with worse
> contacts and also on some very small (usually cheap) devices.
> 
> Point b. is relative easy on OHCI and non-root hubs, because OHCI or hub
> handles reset procedure timing by itself and port is automatically
> enabled after reset. But control of such procedure was not good on OHCI,
> I changed it to respect automatic functions of OHCI.
> On UHCI reset procedure is handled only via SW and we did not it
> properly - it was reason, why some my devices were working on non-root
> hub port and not on UHCI root port. I changed more things there, I was
> inspired by USB specification and uhci-hub.c from Linux (but code is
> different, I did not copy it). I am not sure what was more important -
> if timing or bit masking... But result is - now are working all my
> devices also on UHCI root port! Of course, I am not sure if it is fully
> compatible...
> 
> Point c. is easy and it was included in portstatus before.
> 
> The last thing is - I deleted disabling of port before resetting and
> enabling it - USB specification does not say it is necessary. But if
> there is really some reason to use it, why not - but in this case maybe
> some delay should be inserted between disable and enable, I not tested
> it yet.
> 
> Regards
> Ales
> 
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] USB issues - kbdlayouts branch
  2010-09-13 11:47                 ` [PATCH] USB issues - kbdlayouts branch Aleš Nesrsta
@ 2010-09-13 18:13                   ` Aleš Nesrsta
  2010-09-15  5:58                     ` [PATCH] USB serial - missing configuration Aleš Nesrsta
  2010-09-15  5:58                     ` Question: USB serial - device driver debugging Aleš Nesrsta
  0 siblings, 2 replies; 23+ messages in thread
From: Aleš Nesrsta @ 2010-09-13 18:13 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 5860 bytes --]

Hi,

there is little bit modified patch, it should work better...
For details see description in original e-mail included below.

Regards
Ales

Aleš Nesrsta wrote:
> Hi,
> 
> today I discovered some small problem related to my last patch described
> in e-mail below, point 7. The problem is:
> 
> The first (and only first) connection of USB device to root hub port is
> not properly recognized or handled, any other subsequent connection is
> OK.
> It looks like it is the same on OHCI and UHCI, so maybe it is related to
> common part (usbhub.c) or device initialization.
> I am now investigating what is wrong...
> 
> Regards
> Ales
> 
> Aleš Nesrsta wrote:
> > Hi Vladimir (and, of course, possibly others...),
> > 
> > there is patch which (perhaps) solves some bugs I found in kbdlayouts
> > branch.
> > 
> > It includes:
> > 0. Previously sent patch for UHCI low speed problem.
> > 1. UHCI transfer error evaluation
> > 2. OHCI cdata de-allocation
> > 3. OHCI proper previous TD unchaining
> > 4. OHCI EDs quantity
> > 5. "Simplified" OHCI driver
> > 6. Non-root hub "multiple reset"
> > 7. OHCI/UHCI port reset handling
> > 
> > Patch is done against kbdlayouts branch version 2424.
> > I did not commit changes into branch repository.
> > 
> > Please test it on Yeelong and possible other machines, it contains
> > significant changes (mainly points 5,6,7).
> > 
> > 
> > Details about points:
> > 
> > ad 0.
> > Unfortunately, I still don't have progress with low-speed keyboard -
> > interrupt (bulk) transfer is not working on UHCI nor OHCI. This patch
> > solves control transfer only and I still don't know why.
> > 
> > ad 1.
> > More than one bit can be set in register at the end of transfer and old
> > evaluation of error code was wrong. Now it is better but probably still
> > not totally exact - but GRUB does not have so much different USB error
> > codes currently, so it probably makes not sense.
> > 
> > ad 2.
> > I did not find de-allocation of cdata in OHCI, so I added it into
> > finish_transfer.
> > 
> > ad 3.
> > I found some small mistake in OHCI TD unchaining of last (not processed)
> > TD which sometimes resulted in bad toggle value.
> > 
> > ad 4.
> > Increased possible number of connected devices or unplug/plug cycles for
> > OHCI driver - I wrote approx. two/three months ago about such expected
> > simple change.
> > 
> > ad 5.
> > I removed interrupt-like processing of transfers from OHCI driver. I
> > decided it is unnecessarily complex to implement proper handling of
> > donehead when "non-single thread execution" of transfer is used
> > (different cdata).
> > Only "bad OHCI" code is now in driver (in fact it is your old original
> > idea/algorithm with some hazards removed and little bit improved).
> > It should work - I tested it on my OHCI machine and it works well.
> > 
> > ad 6.
> > There was one big trouble - if I connected into PC hub with two or more
> > devices connected, usually none was working.
> > It was caused by "multiple reset" - all devices connected on hub were
> > reset in the same time, i.e. all devices become into default state with
> > address 0 - USB specification does not allow such situation, only one
> > device on one controller can have address 0 at the same time.
> > I made some relative simple workaround via special flag in controller
> > structure - it looks working.
> > 
> > ad 7.
> > I had problems with some devices to be evaluated - hotplugging changed
> > timing of device detection and evaluation process, so I tried to change
> > it into more proper way, according USB1.x/2.0, OHCI and UHCI
> > specifications.
> > There are three main things which are important:
> > a. Wait for stable power and insertion procedure completion before issue
> > reset - at least 100ms, I found more safe it is 250ms
> > b. Port reset and enable procedure and its timing (50ms reset signal and
> > after very small delay enable request)
> > c. Reset recovery delay 10ms
> > 
> > Point a. is little bit complicated by possible not stable "connected"
> > signal - this problem I detected on my older computer with worse
> > contacts and also on some very small (usually cheap) devices.
> > 
> > Point b. is relative easy on OHCI and non-root hubs, because OHCI or hub
> > handles reset procedure timing by itself and port is automatically
> > enabled after reset. But control of such procedure was not good on OHCI,
> > I changed it to respect automatic functions of OHCI.
> > On UHCI reset procedure is handled only via SW and we did not it
> > properly - it was reason, why some my devices were working on non-root
> > hub port and not on UHCI root port. I changed more things there, I was
> > inspired by USB specification and uhci-hub.c from Linux (but code is
> > different, I did not copy it). I am not sure what was more important -
> > if timing or bit masking... But result is - now are working all my
> > devices also on UHCI root port! Of course, I am not sure if it is fully
> > compatible...
> > 
> > Point c. is easy and it was included in portstatus before.
> > 
> > The last thing is - I deleted disabling of port before resetting and
> > enabling it - USB specification does not say it is necessary. But if
> > there is really some reason to use it, why not - but in this case maybe
> > some delay should be inserted between disable and enable, I not tested
> > it yet.
> > 
> > Regards
> > Ales
> > 
> > _______________________________________________
> > Grub-devel mailing list
> > Grub-devel@gnu.org
> > http://lists.gnu.org/mailman/listinfo/grub-devel
> 
> 
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
> 

[-- Attachment #2: usb_patch_USB_issues_100913_0 --]
[-- Type: text/x-patch, Size: 26284 bytes --]

diff -urB ./kbdlayouts/grub-core/bus/usb/ohci.c ./kbdlayouts_changed/grub-core/bus/usb/ohci.c
--- ./kbdlayouts/grub-core/bus/usb/ohci.c	2010-09-03 22:13:28.000000000 +0200
+++ ./kbdlayouts_changed/grub-core/bus/usb/ohci.c	2010-09-13 18:27:43.000000000 +0200
@@ -98,7 +98,6 @@
   struct grub_pci_dma_chunk *td_chunk;
   struct grub_ohci *next;
   grub_ohci_td_t td_free; /* Pointer to first free TD */
-  int bad_OHCI;
 };
 
 static struct grub_ohci *ohci;
@@ -149,8 +148,8 @@
 #define GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE (1 << 4)
 
 #define GRUB_OHCI_RESET_CONNECT_CHANGE (1 << 16)
-#define GRUB_OHCI_CTRL_EDS 16
-#define GRUB_OHCI_BULK_EDS 16
+#define GRUB_OHCI_CTRL_EDS 256
+#define GRUB_OHCI_BULK_EDS 510
 #define GRUB_OHCI_TDS 256
 
 #define GRUB_OHCI_ED_ADDR_MASK 0x7ff
@@ -442,8 +441,10 @@
                        (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA)
                         & ~GRUB_OHCI_RHUB_PORT_POWER_MASK)
                        | GRUB_OHCI_RHUB_PORT_ALL_POWERED);
+#if 0 /* We don't need it at all, handled via hotplugging */
   /* Now we have hot-plugging, we need to wait for stable power only */
   grub_millisleep (100);
+#endif
 
   /* Link to ohci now that initialisation is successful.  */
   o->next = ohci;
@@ -623,7 +624,8 @@
       break;
     }
 
-  /* Set the token (Always generate interrupt - bits 21-23 = 0).  */
+  /* Set the token */
+  token |= ( 7 << 21); /* Never generate interrupt */
   token |= toggle << 24;
   token |= 1 << 25;
 
@@ -659,7 +661,6 @@
   grub_ohci_ed_t ed_virt;
   grub_ohci_td_t td_current_virt;
   grub_ohci_td_t td_head_virt;
-  grub_uint64_t bad_OHCI_delay;
 };
 
 static grub_usb_err_t
@@ -756,10 +757,6 @@
 
       /* Set index of TD in transfer */
       cdata->td_current_virt->tr_index = (grub_uint32_t) i;
-
-      /* No IRQ request in TD if bad_OHCI set */
-      if (o->bad_OHCI)
-        cdata->td_current_virt->token |= grub_cpu_to_le32 ( 7 << 21);
       
       /* Remember last used (processed) TD phys. addr. */
       cdata->td_last_phys = grub_ohci_td_virt2phys (o, cdata->td_current_virt);
@@ -891,8 +888,8 @@
   /* Now print debug values - to have full info what happened */
   grub_dprintf ("ohci", "loop finished: control=0x%02x status=0x%02x\n",
 		control, status);
-  grub_dprintf ("ohci", "intstatus=0x%02x \n\t\t tderr_phys=0x%02x, td_last_phys=0x%02x\n",
-		intstatus, cdata->tderr_phys, cdata->td_last_phys);
+  grub_dprintf ("ohci", "intstatus=0x%02x, td_last_phys=0x%02x\n",
+		intstatus, cdata->td_last_phys);
   grub_dprintf ("ohci", "TARGET=0x%02x, HEAD=0x%02x, TAIL=0x%02x\n",
                 target,
                 grub_le_to_cpu32 (cdata->ed_virt->td_head),
@@ -915,12 +912,6 @@
    *    i.e. it is safe to free all TDs except last not processed
    * ED HEAD == TAIL == phys. addr. of td_current_virt */
 
-  /* Reset DoneHead - sanity cleanup */
-  o->hcca->donehead = 0;
-  grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1));
-  /* Read back of register should ensure it is really written */
-  grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
-
   /* Un-chainig of last TD */
   if (cdata->td_current_virt->prev_td_phys)
     {
@@ -929,10 +920,13 @@
       
       if (cdata->td_current_virt == (grub_ohci_td_t) td_prev_virt->link_td)
         td_prev_virt->link_td = 0;
+
+      cdata->td_current_virt->prev_td_phys = 0;
     }
 
   grub_dprintf ("ohci", "OHCI finished, freeing\n");
   grub_ohci_free_tds (o, cdata->td_head_virt);
+  grub_free (cdata);
 }
 
 static grub_usb_err_t
@@ -951,28 +945,10 @@
   pre_finish_transfer (dev, transfer);
 
   /* First we must get proper tderr_phys value */
-  if (o->bad_OHCI) /* In case of bad_OHCI tderr_phys can be wrong */
-    {
-      if (cdata->tderr_phys) /* check if tderr_phys points to TD with error */
-	errcode = grub_le_to_cpu32 (grub_ohci_td_phys2virt (o,
-							    cdata->tderr_phys)->token)
-	  >> 28;
-      if ( !cdata->tderr_phys || !errcode ) /* tderr_phys not valid or points to wrong TD */
-	{ /* Retired TD with error should be previous TD to ED->td_head */
-	  cdata->tderr_phys = grub_ohci_td_phys2virt (o,
-						      grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf )
-	    ->prev_td_phys;
-	}
-    }
-  /* Even if we have "good" OHCI, in some cases
-   * tderr_phys can be zero, check it */
-  else if (!cdata->tderr_phys)
-    /* Retired TD with error should be previous TD to ED->td_head */
-    cdata->tderr_phys 
-      = grub_ohci_td_phys2virt (o,
-				grub_le_to_cpu32 (cdata->ed_virt->td_head)
-				& ~0xf)->prev_td_phys;
-    
+  /* Retired TD with error should be previous TD to ED->td_head */
+  cdata->tderr_phys = grub_ohci_td_phys2virt (o,
+                                                grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf )
+	              ->prev_td_phys;
 
   /* Prepare pointer to last processed TD and get error code */
   tderr_virt = grub_ohci_td_phys2virt (o, cdata->tderr_phys);
@@ -1090,16 +1067,12 @@
 
   pre_finish_transfer (dev, transfer);
 
-  /* Simple workaround if donehead is not working */
-  if (o->bad_OHCI &&
-      (!cdata->tderr_phys || (cdata->tderr_phys != cdata->td_last_phys)))
-    {
-      grub_dprintf ("ohci", "normal finish, but tderr_phys corrected\n");
-      cdata->tderr_phys = cdata->td_last_phys;
-      /* I hope we can do it as transfer (most probably) finished OK */
-    }
+  /* I hope we can do it as transfer (most probably) finished OK */
+  cdata->tderr_phys = cdata->td_last_phys;
+
   /* Prepare pointer to last processed TD */
   tderr_virt = grub_ohci_td_phys2virt (o, cdata->tderr_phys);
+  
   /* Set index of last processed TD */
   if (tderr_virt)
     transfer->last_trans = tderr_virt->tr_index;
@@ -1168,25 +1141,6 @@
 
   /* Check transfer status */
   intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
-  if (!o->bad_OHCI && (intstatus & 0x2) != 0)
-    {
-      /* Remember last successful TD */
-      cdata->tderr_phys = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf;
-      /* Reset DoneHead */
-      o->hcca->donehead = 0;
-      grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1));
-      /* Read back of register should ensure it is really written */
-      grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
-      /* if TD is last, finish */
-      if (cdata->tderr_phys == cdata->td_last_phys)
-	{
-	  if (grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1)
-	    return parse_halt (dev, transfer, actual);
-	  else
-	    return parse_success (dev, transfer, actual);
-	}
-      return GRUB_USB_ERR_WAIT;
-    }
 
   if ((intstatus & 0x10) != 0)
     /* Unrecoverable error - only reset can help...! */
@@ -1194,54 +1148,20 @@
 
   /* Detected a HALT.  */
   if ((grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1))
-    {
-      /* ED is halted, but donehead event can happened in the meantime */
-      intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
-      if (!o->bad_OHCI && (intstatus & 0x2) != 0)
-	{
-	  /* Remember last successful TD */
-	  cdata->tderr_phys = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf;
-	  /* Reset DoneHead */
-	  o->hcca->donehead = 0;
-	  grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1));
-	  /* Read back of register should ensure it is really written */
-	  grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
-	  /* if TD is last, finish */
-	}
-      return parse_halt (dev, transfer, actual);
-    }
+    return parse_halt (dev, transfer, actual);
 
-  /* bad OHCI handling */
+  /* Finished ED detection */
   if ( (grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf) ==
        (grub_le_to_cpu32 (cdata->ed_virt->td_tail) & ~0xf) ) /* Empty ED */
     {
-      if (o->bad_OHCI) /* Bad OHCI detected previously */
-	{
-	  /* Try get last successful TD. */
-	  cdata->tderr_phys = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf;
-	  if (cdata->tderr_phys)/* Reset DoneHead if we were successful */
-	    {
-	      o->hcca->donehead = 0;
-	      grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1));
-	      /* Read back of register should ensure it is really written */
-	      grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
-	    }
-	  /* Check the HALT bit */
-	  if (grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1)
-	    return parse_halt (dev, transfer, actual);
-	  else
-	    return parse_success (dev, transfer, actual);
-	}
-      else /* Detection of bad OHCI */
-	/* We should wait short time (~2ms) before we say that
-	 * it is bad OHCI to prevent some hazard -
-	 * donehead can react in the meantime. This waiting is done
-	 * only once per OHCI driver "live cycle". */
-	if (!cdata->bad_OHCI_delay) /* Set delay time */
-	  cdata->bad_OHCI_delay = grub_get_time_ms () + 2;
-	else if (grub_get_time_ms () >= cdata->bad_OHCI_delay)
-	  o->bad_OHCI = 1;
-      return GRUB_USB_ERR_WAIT;
+      /* Check the HALT bit */
+      /* It looks like nonsense - it was tested previously...
+       * but it can change because OHCI is working
+       * simultaneously via DMA... */
+      if (grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1)
+	return parse_halt (dev, transfer, actual);
+      else
+        return parse_success (dev, transfer, actual);
     }
 
   return GRUB_USB_ERR_WAIT;
@@ -1266,14 +1186,16 @@
   /* Wait for new SOF */
   while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0);
 
-  /* Now we must find last processed TD if bad_OHCI == TRUE */
-  if (o->bad_OHCI)
-    /* Retired TD with error should be previous TD to ED->td_head */
-    cdata->tderr_phys
-      = grub_ohci_td_phys2virt (o, grub_le_to_cpu32 (cdata->ed_virt->td_head)
-				& ~0xf)->prev_td_phys;
+  /* Possible retired TD with error should be previous TD to ED->td_head */
+  cdata->tderr_phys
+    = grub_ohci_td_phys2virt (o, grub_le_to_cpu32 (cdata->ed_virt->td_head)
+                              & ~0xf)->prev_td_phys;
     
   tderr_virt = grub_ohci_td_phys2virt (o,cdata-> tderr_phys);
+
+  grub_dprintf ("ohci", "Cancel: tderr_phys=0x%08x, tderr_virt=0x%08x\n",
+                cdata->tderr_phys, (unsigned int)tderr_virt);
+
   if (tderr_virt)
     transfer->last_trans = tderr_virt->tr_index;
   else
@@ -1290,6 +1212,7 @@
 {
    struct grub_ohci *o = (struct grub_ohci *) dev->data;
    grub_uint64_t endtime;
+   int i;
 
    grub_dprintf ("ohci", "begin of portstatus=0x%02x\n",
                  grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port));
@@ -1310,31 +1233,47 @@
        return GRUB_ERR_NONE;
      }
      
-   /* Reset the port */
-   grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
-			 GRUB_OHCI_SET_PORT_RESET);
-   grub_millisleep (50); /* For root hub should be nominaly 50ms */
- 
-    /* End the reset signaling.  */
-   grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
-			 GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE);
-   grub_millisleep (10);
+   /* OHCI does one reset signal 10ms long but USB spec.
+    * requests 50ms for root hub (no need to be continuous).
+    * So, we do reset 5 times... */
+   for (i = 0; i < 5; i++)
+     {
+       /* Reset the port - timing of reset is done by OHCI */
+       grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
+                             GRUB_OHCI_SET_PORT_RESET);
+
+       /* Wait for reset completion */
+       endtime = grub_get_time_ms () + 1000;
+       while (! (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)
+               & GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE))
+         if (grub_get_time_ms () > endtime)
+           return grub_error (GRUB_ERR_IO, "OHCI Timed out - reset");
 
-   /* Enable the port and wait for it. */
+       /* End the reset signaling - reset the reset status change */
+       grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
+			     GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE);
+       grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
+     }
+
+   /* Enable port */
    grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
                          GRUB_OHCI_SET_PORT_ENABLE);
+   grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
+   
+   /* Wait for signal enabled */
    endtime = grub_get_time_ms () + 1000;
    while (! (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)
            & (1 << 1)))
      if (grub_get_time_ms () > endtime)
        return grub_error (GRUB_ERR_IO, "OHCI Timed out - enable");
 
-   grub_millisleep (10);
-
    /* Reset bit Connect Status Change */
    grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
                          GRUB_OHCI_RESET_CONNECT_CHANGE);
 
+   /* "Reset recovery time" (USB spec.) */
+   grub_millisleep (10);
+   
    grub_dprintf ("ohci", "end of portstatus=0x%02x\n",
 		 grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port));
  
diff -urB ./kbdlayouts/grub-core/bus/usb/uhci.c ./kbdlayouts_changed/grub-core/bus/usb/uhci.c
--- ./kbdlayouts/grub-core/bus/usb/uhci.c	2010-09-03 22:13:28.000000000 +0200
+++ ./kbdlayouts_changed/grub-core/bus/usb/uhci.c	2010-09-13 18:53:48.000000000 +0200
@@ -53,6 +53,8 @@
     | GRUB_UHCI_REG_PORTSC_SUSPEND
   };
 
+/* These bits should not be written as 1 unless we really need it */
+#define GRUB_UHCI_PORTSC_ZERO ((1<<1) | (1<<3) | (1<<11) | (3<<13))
 
 /* UHCI Queue Head.  */
 struct grub_uhci_qh
@@ -414,7 +416,7 @@
 grub_uhci_transaction (struct grub_uhci *u, unsigned int endp,
 		       grub_transfer_type_t type, unsigned int addr,
 		       unsigned int toggle, grub_size_t size,
-		       grub_uint32_t data)
+		       grub_uint32_t data, grub_usb_speed_t speed)
 {
   grub_uhci_td_t td;
   static const unsigned int tf[] = { 0x69, 0xE1, 0x2D };
@@ -439,7 +441,8 @@
   td->linkptr = 1;
 
   /* Active!  Only retry a transfer 3 times.  */
-  td->ctrl_status = (1 << 23) | (3 << 27);
+  td->ctrl_status = (1 << 23) | (3 << 27) |
+                    ((speed == GRUB_USB_SPEED_LOW) ? (1 << 26) : 0);
 
   /* If zero bytes are transmitted, size is 0x7FF.  Otherwise size is
      size-1.  */
@@ -495,7 +498,8 @@
 
       td = grub_uhci_transaction (u, transfer->endpoint & 15, tr->pid,
 				  transfer->devaddr, tr->toggle,
-				  tr->size, tr->data);
+				  tr->size, tr->data,
+				  transfer->dev->speed);
       if (! td)
 	{
 	  grub_size_t actual = 0;
@@ -576,23 +580,23 @@
 	err = GRUB_USB_ERR_STALL;
       
       /* Check if an error related to the data buffer occurred.  */
-      if (errtd->ctrl_status & (1 << 21))
+      else if (errtd->ctrl_status & (1 << 21))
 	err = GRUB_USB_ERR_DATA;
       
       /* Check if a babble error occurred.  */
-      if (errtd->ctrl_status & (1 << 20))
+      else if (errtd->ctrl_status & (1 << 20))
 	err = GRUB_USB_ERR_BABBLE;
       
       /* Check if a NAK occurred.  */
-      if (errtd->ctrl_status & (1 << 19))
+      else if (errtd->ctrl_status & (1 << 19))
 	err = GRUB_USB_ERR_NAK;
       
       /* Check if a timeout occurred.  */
-      if (errtd->ctrl_status & (1 << 18))
+      else if (errtd->ctrl_status & (1 << 18))
 	err = GRUB_USB_ERR_TIMEOUT;
       
       /* Check if a bitstuff error occurred.  */
-      if (errtd->ctrl_status & (1 << 17))
+      else if (errtd->ctrl_status & (1 << 17))
 	err = GRUB_USB_ERR_BITSTUFF;
       
       if (err)
@@ -683,7 +687,7 @@
       endtime = grub_get_time_ms () + 1000;
       while ((grub_uhci_readreg16 (u, reg) & (1 << 2)))
         if (grub_get_time_ms () > endtime)
-          return grub_error (GRUB_ERR_IO, "UHCI Timed out");
+          return grub_error (GRUB_ERR_IO, "UHCI Timed out - disable");
 
       status = grub_uhci_readreg16 (u, reg);
       grub_dprintf ("uhci", ">3detect=0x%02x\n", status);
@@ -691,28 +695,37 @@
     }
     
   /* Reset the port.  */
-  grub_uhci_writereg16 (u, reg, 1 << 9);
+  status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_ZERO;
+  grub_uhci_writereg16 (u, reg, status | (1 << 9));
+  grub_uhci_readreg16 (u, reg); /* Ensure it is writen... */
 
   /* Wait for the reset to complete.  XXX: How long exactly?  */
   grub_millisleep (50); /* For root hub should be nominaly 50ms */
-  status = grub_uhci_readreg16 (u, reg);
+  status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_ZERO;
   grub_uhci_writereg16 (u, reg, status & ~(1 << 9));
-  grub_dprintf ("uhci", "reset completed\n");
-  grub_millisleep (10);
+  grub_uhci_readreg16 (u, reg); /* Ensure it is writen... */
 
-  /* Enable the port.  */
-  grub_uhci_writereg16 (u, reg, 1 << 2);
-  grub_millisleep (10);
+  /* Note: some debug prints were removed because they affected reset/enable timing. */
+
+  grub_millisleep (1); /* Probably not needed at all or only few microsecs. */
 
-  grub_dprintf ("uhci", "waiting for the port to be enabled\n");
+  /* Reset bits Connect & Enable Status Change */
+  status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_ZERO;
+  grub_uhci_writereg16 (u, reg, status | (1 << 3) | GRUB_UHCI_REG_PORTSC_CONNECT_CHANGED);
+  grub_uhci_readreg16 (u, reg); /* Ensure it is writen... */
+
+  /* Enable the port.  */
+  status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_ZERO;
+  grub_uhci_writereg16 (u, reg, status | (1 << 2));
+  grub_uhci_readreg16 (u, reg); /* Ensure it is writen... */
 
   endtime = grub_get_time_ms () + 1000;
   while (! ((status = grub_uhci_readreg16 (u, reg)) & (1 << 2)))
     if (grub_get_time_ms () > endtime)
-      return grub_error (GRUB_ERR_IO, "UHCI Timed out");
+      return grub_error (GRUB_ERR_IO, "UHCI Timed out - enable");
 
-  /* Reset bit Connect Status Change */
-  grub_uhci_writereg16 (u, reg, status | GRUB_UHCI_REG_PORTSC_CONNECT_CHANGED);
+  /* Reset recovery time */
+  grub_millisleep (10);
 
   /* Read final port status */
   status = grub_uhci_readreg16 (u, reg);
diff -urB ./kbdlayouts/grub-core/bus/usb/usb.c ./kbdlayouts_changed/grub-core/bus/usb/usb.c
--- ./kbdlayouts/grub-core/bus/usb/usb.c	2010-09-03 22:13:28.000000000 +0200
+++ ./kbdlayouts_changed/grub-core/bus/usb/usb.c	2010-09-12 16:40:41.000000000 +0200
@@ -262,7 +262,7 @@
 
       if (dev->config[0].interf[i].attached)
 	continue;
-
+	
       for (desc = attach_hooks; desc; desc = desc->next)
 	if (interf->class == desc->class && desc->hook (dev, 0, i))
 	  dev->config[0].interf[i].attached = 1;
diff -urB ./kbdlayouts/grub-core/bus/usb/usbhub.c ./kbdlayouts_changed/grub-core/bus/usb/usbhub.c
--- ./kbdlayouts/grub-core/bus/usb/usbhub.c	2010-09-03 22:13:28.000000000 +0200
+++ ./kbdlayouts_changed/grub-core/bus/usb/usbhub.c	2010-09-12 11:35:17.000000000 +0200
@@ -179,19 +179,45 @@
 {
   grub_usb_device_t dev;
   grub_err_t err;
+  int total, i;
+  grub_usb_speed_t current_speed = GRUB_USB_SPEED_NONE;
+  int changed=0;
 
+#if 0
+/* Specification does not say about disabling of port when device
+ * connected. If disabling is really necessary for some devices,
+ * delete this #if 0 and related #endif */
   /* Disable the port. XXX: Why? */
   err = hub->controller->dev->portstatus (hub->controller, portno, 0);
   if (err)
     return;
+#endif
+  /* Wait for completion of insertion and stable power (USB spec.)
+   * Should be at least 100ms, some devices requires more...
+   * There is also another thing - some devices have worse contacts
+   * and connected signal is unstable for some time - we should handle
+   * it - but prevent deadlock in case when device is too faulty... */
+  for (total = i = 0; (i < 250) && (total < 2000); i++, total++)
+    {
+      grub_millisleep (1);
+      current_speed = hub->controller->dev->detect_dev
+                        (hub->controller, portno, &changed);
+      if (current_speed == GRUB_USB_SPEED_NONE)
+        i = 0;
+    }
+  grub_dprintf ("usb", "total=%d\n", total);
+  if (total >= 2000)
+    return;
 
   /* Enable the port.  */
   err = hub->controller->dev->portstatus (hub->controller, portno, 1);
   if (err)
     return;
+  hub->controller->dev->pending_reset = grub_get_time_ms () + 5000;
 
   /* Enable the port and create a device.  */
   dev = grub_usb_hub_add_dev (hub->controller, speed);
+  hub->controller->dev->pending_reset = 0;
   if (! dev)
     return;
 
@@ -238,11 +264,14 @@
   for (i = 0; i < hub->nports; i++)
     {
       grub_usb_speed_t speed;
-      speed = controller->dev->detect_dev (hub->controller, i,
-					   &changed);
-
-      if (speed != GRUB_USB_SPEED_NONE)
-	attach_root_port (hub, i, speed);
+      if (!controller->dev->pending_reset)
+        {
+          speed = controller->dev->detect_dev (hub->controller, i,
+					       &changed);
+
+          if (speed != GRUB_USB_SPEED_NONE)
+	    attach_root_port (hub, i, speed);
+        }
     }
 
   return GRUB_USB_ERR_NONE;
@@ -284,6 +313,7 @@
   unsigned i;
   grub_uint8_t changed;
   grub_size_t actual;
+  int j, total;
 
   if (!dev->hub_transfer)
     return;
@@ -308,6 +338,7 @@
   for (i = 1; i <= dev->nports; i++)
     {
       grub_uint32_t status;
+      grub_uint32_t current_status = 0;
 
       if (!(changed & (1 << i)))
 	continue;
@@ -319,7 +350,8 @@
 				  GRUB_USB_REQ_GET_STATUS,
 				  0, i, sizeof (status), (char *) &status);
 
-      grub_printf ("i = %d, status = %08x\n", i, status);
+      grub_printf ("dev = 0x%0x, i = %d, status = %08x\n",
+                   (unsigned int) dev, i, status);
 
       if (err)
 	continue;
@@ -346,7 +378,8 @@
 			      GRUB_USB_REQ_CLEAR_FEATURE,
 			      GRUB_USB_HUB_FEATURE_C_PORT_OVERCURRENT, i, 0, 0);
 
-      if (status & GRUB_USB_HUB_STATUS_C_PORT_CONNECTED)
+      if (!dev->controller.dev->pending_reset &&
+          (status & GRUB_USB_HUB_STATUS_C_PORT_CONNECTED))
 	{
 	  grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
 				      | GRUB_USB_REQTYPE_CLASS
@@ -360,8 +393,36 @@
 	  /* Connected and status of connection changed ? */
 	  if (status & GRUB_USB_HUB_STATUS_PORT_CONNECTED)
 	    {
-	      /* A device is actually connected to this port.
-	       * Now do reset of port. */
+	      /* A device is actually connected to this port. */
+  /* Wait for completion of insertion and stable power (USB spec.)
+   * Should be at least 100ms, some devices requires more...
+   * There is also another thing - some devices have worse contacts
+   * and connected signal is unstable for some time - we should handle
+   * it - but prevent deadlock in case when device is too faulty... */
+              for (total = j = 0; (j < 250) && (total < 2000); j++, total++)
+                {
+                  grub_millisleep (1);
+                  /* Get the port status.  */
+                  err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
+					       | GRUB_USB_REQTYPE_CLASS
+					       | GRUB_USB_REQTYPE_TARGET_OTHER),
+				              GRUB_USB_REQ_GET_STATUS,
+				              0, i,
+				              sizeof (current_status),
+				              (char *) &current_status);
+                  if (err)
+                    {
+                      total = 2000;
+	              break;
+                    }
+                  if (!(current_status & GRUB_USB_HUB_STATUS_PORT_CONNECTED))
+                    j = 0;
+                }
+              grub_dprintf ("usb", "(non-root) total=%d\n", total);
+              if (total >= 2000)
+                continue;
+
+              /* Now do reset of port. */
 	      grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
 					  | GRUB_USB_REQTYPE_CLASS
 					  | GRUB_USB_REQTYPE_TARGET_OTHER),
@@ -369,6 +430,15 @@
 				    GRUB_USB_HUB_FEATURE_PORT_RESET,
 				    i, 0, 0);
 	      rescan = 1;
+	      /* We cannot reset more than one device at the same time !
+	       * Resetting more devices together results in very bad
+	       * situation: more than one device has default address 0
+	       * at the same time !!!
+	       * Additionaly, we cannot perform another reset
+	       * anywhere on the same OHCI controller until
+	       * we will finish addressing of reseted device ! */
+              dev->controller.dev->pending_reset = grub_get_time_ms () + 5000;
+              return;
 	    }
 	}
 
@@ -401,6 +471,7 @@
 
 	      /* Add the device and assign a device address to it.  */
 	      next_dev = grub_usb_hub_add_dev (&dev->controller, speed);
+	      dev->controller.dev->pending_reset = 0;
 	      if (! next_dev)
 		continue;
 
@@ -426,12 +497,21 @@
       /* No, it should be never changed, it should be constant. */
       for (i = 0; i < hub->nports; i++)
 	{
-	  grub_usb_speed_t speed;
+	  grub_usb_speed_t speed = GRUB_USB_SPEED_NONE;
 	  int changed = 0;
 
-	  speed = hub->controller->dev->detect_dev (hub->controller, i,
-	                                            &changed);
-
+          if (!hub->controller->dev->pending_reset)
+            {
+              /* Check for possible timeout */
+              if (grub_get_time_ms () > hub->controller->dev->pending_reset)
+                {
+                  /* Something went wrong, reset device was not
+                   * addressed properly, timeout happened */
+	          hub->controller->dev->pending_reset = 0;
+	          speed = hub->controller->dev->detect_dev (hub->controller,
+                                                            i, &changed);
+                }
+            }
 	  if (changed)
 	    {
 	      detach_device (hub->devices[i]);
diff -urB ./kbdlayouts/grub-core/bus/usb/usbtrans.c ./kbdlayouts_changed/grub-core/bus/usb/usbtrans.c
--- ./kbdlayouts/grub-core/bus/usb/usbtrans.c	2010-09-03 22:13:28.000000000 +0200
+++ ./kbdlayouts_changed/grub-core/bus/usb/usbtrans.c	2010-09-10 23:10:27.000000000 +0200
@@ -33,10 +33,12 @@
   grub_usb_err_t err;
   grub_uint64_t endtime;
 
-  endtime = grub_get_time_ms () + timeout;
   err = dev->controller.dev->setup_transfer (&dev->controller, transfer);
   if (err)
     return err;
+  /* endtime moved behind setup transfer to prevent false timeouts
+   * while debugging... */
+  endtime = grub_get_time_ms () + timeout;
   while (1)
     {
       err = dev->controller.dev->check_transfer (&dev->controller, transfer,
diff -urB ./kbdlayouts/include/grub/usb.h ./kbdlayouts_changed/include/grub/usb.h
--- ./kbdlayouts/include/grub/usb.h	2010-09-03 22:13:28.000000000 +0200
+++ ./kbdlayouts_changed/include/grub/usb.h	2010-09-12 16:30:41.000000000 +0200
@@ -116,6 +116,9 @@
 
   grub_usb_speed_t (*detect_dev) (grub_usb_controller_t dev, int port, int *changed);
 
+  /* Per controller flag - port reset pending, don't do another reset */
+  grub_uint64_t pending_reset;
+  
   /* The next host controller.  */
   struct grub_usb_controller_dev *next;
 };

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH] USB serial - missing configuration
  2010-09-13 18:13                   ` Aleš Nesrsta
@ 2010-09-15  5:58                     ` Aleš Nesrsta
  2010-09-19 11:46                       ` Vladimir 'φ-coder/phcoder' Serbinenko
  2010-09-15  5:58                     ` Question: USB serial - device driver debugging Aleš Nesrsta
  1 sibling, 1 reply; 23+ messages in thread
From: Aleš Nesrsta @ 2010-09-15  5:58 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 98 bytes --]

Hi,

I did not find configuration of USB serial device, so I made this small
patch.

Regards
Ales

[-- Attachment #2: usb_serial_100915_0 --]
[-- Type: text/x-patch, Size: 846 bytes --]

diff -urB ./kbdlayouts/grub-core/bus/usb/serial/common.c ./kbdlayouts_changed/grub-core/bus/usb/serial/common.c
--- ./kbdlayouts/grub-core/bus/usb/serial/common.c	2010-09-03 22:13:28.000000000 +0200
+++ ./kbdlayouts_changed/grub-core/bus/usb/serial/common.c	2010-09-14 17:09:30.000000000 +0200
@@ -44,6 +44,7 @@
   struct grub_serial_port *port;
   int j;
   struct grub_usb_desc_if *interf;
+  grub_usb_err_t err = GRUB_USB_ERR_NONE;
 
   interf = usbdev->config[configno].interf[interfno].descif;
 
@@ -80,7 +81,12 @@
 	  port->out_endp = endp;
 	}
     }
-  if (!port->out_endp || !port->in_endp)
+
+  /* Configure device */
+  if (port->out_endp && port->in_endp)
+    err = grub_usb_set_configuration (usbdev, configno + 1);
+  
+  if (!port->out_endp || !port->in_endp || err)
     {
       grub_free (port->name);
       grub_free (port);

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Question: USB serial - device driver debugging
  2010-09-13 18:13                   ` Aleš Nesrsta
  2010-09-15  5:58                     ` [PATCH] USB serial - missing configuration Aleš Nesrsta
@ 2010-09-15  5:58                     ` Aleš Nesrsta
  2010-09-30 17:53                       ` [RFC - Vladimir ?] USB/RS232 converter PL2303 small problem Aleš Nesrsta
  1 sibling, 1 reply; 23+ messages in thread
From: Aleš Nesrsta @ 2010-09-15  5:58 UTC (permalink / raw)
  To: The development of GNU GRUB

Hi,

it seems there are some problems in USB serial driver PL2303 and I want
to debug it.

I need to send and receive some data to see what happened, i.e. I need
to enable remote debug via classic serial interface by e.g.
"serial;terminal_output console serial;debug=xxx" and then do something
like "cat some_file > serial_usb0" and "cat serial_usb0 > some file" to
send and receive some data. But redirection is not supported in GRUB...

I cannot use additional terminal redirection like "terminal_output
console serial serial_usb0" to send something into serial_usb0 - it
makes recursive hang/crash when debug output is enabled.

Is there some way how to send/receive data to/from such device from GRUB
command line?
Or do I need to prepare my own testing program as command module?

Regards
Ales




^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Plans on 1.99 release - USB issues
  2010-09-03 22:02           ` Plans on 1.99 release - USB issues Aleš Nesrsta
  2010-09-04 17:34             ` Aleš Nesrsta
@ 2010-09-18 10:08             ` Vladimir 'φ-coder/phcoder' Serbinenko
  1 sibling, 0 replies; 23+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2010-09-18 10:08 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 4579 bytes --]

On 09/04/2010 12:02 AM, Aleš Nesrsta wrote:
> Vladimir 'φ-coder/phcoder' Serbinenko wrote:
>   
>>> The issue was that we were using getStatus every time we polled for new
>>> devices which suposedly (I fixed few other bugs in the code I used at
>>> the time so, I'm not sure) drove hub in my USB keyboard crazy. The
>>> correct way is to poll interrupt pipe.
>>>   
>>>       
>> Just to be clear: polling interrupt pipe on hub is what I have
>> implemented in keylayouts, just so you don't implement it again
>>     
>>> Another thing I added is the ability to do background transfers. It is
>>> important for USB keyboard support because otherwise we lose messages on
>>> keyboard interrupt pipe. It triggered a bug in uhci module. Now there
>>> are 2 issues:
>>> 1) code is new or modified. Needs testing.
>>> 2) On yeeloong the data read from mass storage is sometimes corrupted.
>>> Happens in mainline, not sure about other branches. It seems that it
>>> wasn't the case before. It's either a regression (perhaps from my code
>>> for partial transfers) or cache issues (some cache isn't correctly flushed)
>>>   
>>>       
>>>> Could I help You with it - at least with testing ?
>>>>   
>>>>     
>>>>         
>>> Yes, a test run of keylayouts branch on your hardware would be helpful.
>>> Especially I'm interested if USB data corruption happens in your case too.
>>>       
> Hi Vladimir,
>
> I made some tests on machine with UHCI with kbdlayouts branch (rev.
> 2424).
> I did not notice any evident data corruption. But there were some
> another odd results:
>
> 1.
> My USB keyboard is low speed device (Genius KB-06XE, model no. K639).
> Low speed device transfer was not properly handled - I made some simple
> patch - see attachment, I did not commit it into repository.
> Control type transfer with keyboard is working with this patch, but bulk
> (interrupt) transfer returns always err=7 and in UHCI TD status&control
> are set bits "CRC/Time Out Error" (bit 18) and "Stalled" (bit 22). It is
> the same behavior as some normal full speed mass-storage devices do also
> (I reported it in some previous e-mails). I have some idea right now -
> probably there is bad handling of UHCI transfer status in uhci.c when
> more than one bit is set - GRUB_USB_ERR_TIMEOUT is returned instead of
> GRUB_USB_ERR_STALL. I will try to play with this part during weekend and
> I will report to You if some success happens...
>
> 2.
> Next bad thing is some problem with device attachment detection or
> handling of newly attached device on non-root hubs. Behavior of this
> problem looks little bit randomly and probably depends also on used port
> of hub - some ports are often working, some not (but all hub ports are
> working normally in Linux/Windows). I did not find reason yet.
>
>   
Perhaps has something to do with port number. Or perhaps unlike mine
your router doesn't send initial device status change.
> 3.
> Sometimes partitions of USB mass storage devices were not properly
> detected - maybe disk cache problem again?
> Maybe it is data corruption which is reported by you - but I never
> detected data corruption when I read data from files.
>
> ---
> I am not sure if interrupt transfers can be handled via bulk queue on
> OHCI - according specification, it should be handled via interrupt
> pointers table which is currently not implemented in ohci.c. Did you
> test background polling of interrupt pipe on some PC with OHCI?
>   
I could use USB keyboard just fine on Yeeloong.
> ---
> At the end some maybe bad idea - if I am not wrong, two simultaneous
> transfers can happen (be active in UHCI/OHCI) with current background
> bulk/interrupt transfer. There is question if are all related functions
> fully reentrant ? I.e., is correct handling of some shared data ?
> For the first look I don't see such problem - with one exception:
> donehead interrupt can be probably incorrectly handled in ohci.c - it
> can be detected and misinterpreted by wrong call of
> grub_ohci_check_transfer. The first aid in this case can be forcing of
> OHCI driver into "bad OHCI" mode, i.e. donehead interrupt ignoring - in
> this mode it should work properly.
>   
It might have been the reason of yeeloong data corruption
> Regards
> Ales
>
>   
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>   


-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] USB serial - missing configuration
  2010-09-15  5:58                     ` [PATCH] USB serial - missing configuration Aleš Nesrsta
@ 2010-09-19 11:46                       ` Vladimir 'φ-coder/phcoder' Serbinenko
  2010-09-21 20:18                         ` Aleš Nesrsta
  0 siblings, 1 reply; 23+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2010-09-19 11:46 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 421 bytes --]

On 09/15/2010 07:58 AM, Aleš Nesrsta wrote:
> Hi,
>
> I did not find configuration of USB serial device, so I made this small
> patch.
>
>   
Go ahead for trunk
> Regards
> Ales
>   
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>   


-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] USB serial - missing configuration
  2010-09-19 11:46                       ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2010-09-21 20:18                         ` Aleš Nesrsta
  2010-09-23 21:13                           ` Trunk: boot problem - unaligned pointer 0x Aleš Nesrsta
  0 siblings, 1 reply; 23+ messages in thread
From: Aleš Nesrsta @ 2010-09-21 20:18 UTC (permalink / raw)
  To: The development of GNU GRUB

Vladimir 'φ-coder/phcoder' Serbinenko wrote:
> On 09/15/2010 07:58 AM, Aleš Nesrsta wrote:
> > Hi,
> >
> > I did not find configuration of USB serial device, so I made this small
> > patch.
> >
> >   
> Go ahead for trunk

Done (trunk revision 2843).

(I had to do it two times - unfortunately there was some error during
committing into trunk and it makes revision 2842 which is "empty", i.e.
without changes. I don't know how to rollback such change on remote
repository and I do not want to do some more damage in repository..., so
I kept it here - I am sorry...)

Regards
Ales

> > Regards
> > Ales
> >   
> >
> >
> > _______________________________________________
> > Grub-devel mailing list
> > Grub-devel@gnu.org
> > http://lists.gnu.org/mailman/listinfo/grub-devel
> >   
> 
> 
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Trunk: boot problem - unaligned pointer 0x...
  2010-09-21 20:18                         ` Aleš Nesrsta
@ 2010-09-23 21:13                           ` Aleš Nesrsta
  2010-09-26  9:58                             ` Aleš Nesrsta
  2010-09-30 19:37                             ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 2 replies; 23+ messages in thread
From: Aleš Nesrsta @ 2010-09-23 21:13 UTC (permalink / raw)
  To: The development of GNU GRUB

Hi,

there is some bug in trunk last versions:

I am not able to boot with normal configuration stored in grub.cfg - if
I select any item from menu (or wait for timeout for default item),
booting is aborted with messages:


"
Booting 'xyz...'

unaligned pointer 0x...
Aborted. Press any key to exit.
"

If I edit menu item, delete "search" command and specify Linux root
device directly ("linux ... root=/dev/sdb1..."), Linux is booted
normally.


Some initial information:

GRUB was autoconfigured for compilation in this way:
*******************************************************
GRUB2 will be compiled with following components:
Platform: i386-pc
With devmapper support: No (need devmapper library)
With memory debugging: No
efiemu runtime: Yes
grub-mkfont: Yes
*******************************************************

Menuentry looks for example like that:
        set root=(hd0,1)
        search --fs-uuid --set 02ba8dca-885d-4acd-9730-eee482f3305b
        linux   /boot/vmlinuz-2.6.32-bpo.5-686
root=UUID=02ba8dca-885d-4acd-9730-eee482f3305b ro  
        initrd  /boot/initrd.img-2.6.32-bpo.5-686


Unfortunately, I cannot simply debug this problem, because when I set
for example "all" into debug variable, problem does not happen and boot
is processed normally... :-(

Regards
Ales



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Trunk: boot problem - unaligned pointer 0x...
  2010-09-23 21:13                           ` Trunk: boot problem - unaligned pointer 0x Aleš Nesrsta
@ 2010-09-26  9:58                             ` Aleš Nesrsta
  2010-09-30 19:37                             ` Vladimir 'φ-coder/phcoder' Serbinenko
  1 sibling, 0 replies; 23+ messages in thread
From: Aleš Nesrsta @ 2010-09-26  9:58 UTC (permalink / raw)
  To: The development of GNU GRUB

Hi,

I discovered something.
It looks like problem is caused by empty line in booting command list:

...
script/lexer.c:305: token 290 text [Debian GNU/Linux, linux
2.6.32-bpo.5-686
/dev/sdb1]
script/script.c:50: malloc 0x3ffac100
script/script.c:50: malloc 0x3feddab0
script/lexer.c:305: token 290 text []
script/script.c:50: malloc 0x3ff11360
script/script.c:50: malloc 0x3ff14ee0
script/script.c:163: arglist
script/script.c:50: malloc 0x3ff1e4a0
script/lexer.c:305: token 259 text [
]
script/script.c:50: malloc 0x3ff24e90
script/script.c:50: malloc 0x3ff25010
script/script.c:198: cmdline
script/script.c:50: malloc 0x3ff2d2c0
script/lexer.c:305: token 0 text []
script/script.c:50: malloc 0x3fee1d10
script/script.c:50: malloc 0x3ff11340
script/script.c:294: append command
script/script.c:50: malloc 0x3ff1b130
unaligned pointer 0x692a6373

But I don't know where the empty line is generated - it is not in
grub.cfg

Regards
Ales


Aleš Nesrsta wrote:
> Hi,
> 
> there is some bug in trunk last versions:
> 
> I am not able to boot with normal configuration stored in grub.cfg - if
> I select any item from menu (or wait for timeout for default item),
> booting is aborted with messages:
> 
> 
> "
> Booting 'xyz...'
> 
> unaligned pointer 0x...
> Aborted. Press any key to exit.
> "
> 
> If I edit menu item, delete "search" command and specify Linux root
> device directly ("linux ... root=/dev/sdb1..."), Linux is booted
> normally.
> 
> 
> Some initial information:
> 
> GRUB was autoconfigured for compilation in this way:
> *******************************************************
> GRUB2 will be compiled with following components:
> Platform: i386-pc
> With devmapper support: No (need devmapper library)
> With memory debugging: No
> efiemu runtime: Yes
> grub-mkfont: Yes
> *******************************************************
> 
> Menuentry looks for example like that:
>         set root=(hd0,1)
>         search --fs-uuid --set 02ba8dca-885d-4acd-9730-eee482f3305b
>         linux   /boot/vmlinuz-2.6.32-bpo.5-686
> root=UUID=02ba8dca-885d-4acd-9730-eee482f3305b ro  
>         initrd  /boot/initrd.img-2.6.32-bpo.5-686
> 
> 
> Unfortunately, I cannot simply debug this problem, because when I set
> for example "all" into debug variable, problem does not happen and boot
> is processed normally... :-(
> 
> Regards
> Ales
> 
> 
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
> 



^ permalink raw reply	[flat|nested] 23+ messages in thread

* [RFC - Vladimir ?] USB/RS232 converter PL2303 small problem
  2010-09-15  5:58                     ` Question: USB serial - device driver debugging Aleš Nesrsta
@ 2010-09-30 17:53                       ` Aleš Nesrsta
  2010-10-17 11:54                         ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 1 reply; 23+ messages in thread
From: Aleš Nesrsta @ 2010-09-30 17:53 UTC (permalink / raw)
  To: The development of GNU GRUB

Hi,

I don't know who is developer/maintainer of USB serial drivers - I
expect it is Vladimir, so this e-mail is addressed mainly to him.

As I wrote in my older e-mail (Question: USB serial - device driver
debugging), there is some problem with PL2303. Not with driver but with
device itself (probably).

What is the problem:

If I put some stream of characters into PL2303, device stops accepting
data and answers NAK indefinitely after some time / some amounts of
character sent (256 exactly).

It happens only if PL2303 is connected to another computer. If only
null-modem cable is connected, it does not happen. (If no cable is
connected, it happens also but in this case it is caused by missing
handshaking signals which prevent sending -> output buffer overloading
happens, i.e. it is in fact correct situation.)

I discovered the reason - I forgot switch off "echo" on ttyS0 of PC
where was cable connected. I.e. every character sent by GRUB was
returned from connected PC back to input of PL2303 and input buffer was
overloaded.

But what is surprising for me - why stops PL2303 SENDING when INPUT
buffer is full ???
("Normal" serial port does not such thing in GRUB, it looks like it is
PL2303 device speciality. I did not test FTDI, I don't have it.)

Maybe such behavior can be prevented by some another pre-setting of
PL2303 device - but there is no detailed documentation about PL2303
device USB interface.

I thought also about some workaround - continuously check amount of
characters in input buffer in device but there is problem how to do it -
at least there is no related documentation of PL2303 as I mentioned
above.

Another possibility is periodical fetching characters from PL2303 but it
should be disabled when PL2303 is used as input for terminal etc. - it
looks too difficult to implement (and non-standard...).

I.e. there is probably no simple way how to prevent this problem but
such unexpected behavior of device should be known and probably
documented somewhere - where ?
Is there some place in source where to store HowTos, FAQs and some other
more or less important notes ? Or should I write this information into
driver source code ?

Regards
Ales





^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Trunk: boot problem - unaligned pointer 0x...
  2010-09-23 21:13                           ` Trunk: boot problem - unaligned pointer 0x Aleš Nesrsta
  2010-09-26  9:58                             ` Aleš Nesrsta
@ 2010-09-30 19:37                             ` Vladimir 'φ-coder/phcoder' Serbinenko
  2010-09-30 20:45                               ` Aleš Nesrsta
  1 sibling, 1 reply; 23+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2010-09-30 19:37 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 542 bytes --]


> Unfortunately, I cannot simply debug this problem, because when I set
> for example "all" into debug variable, problem does not happen and boot
> is processed normally... :-(
>
>   
It's a typical syndrom of memory corruption. I fixed few memory misusage
in trunk. Could you retest?
> Regards
> Ales
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
>   


-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Trunk: boot problem - unaligned pointer 0x...
  2010-09-30 19:37                             ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2010-09-30 20:45                               ` Aleš Nesrsta
  0 siblings, 0 replies; 23+ messages in thread
From: Aleš Nesrsta @ 2010-09-30 20:45 UTC (permalink / raw)
  To: The development of GNU GRUB

Vladimir 'φ-coder/phcoder' Serbinenko wrote:
> > Unfortunately, I cannot simply debug this problem, because when I set
> > for example "all" into debug variable, problem does not happen and boot
> > is processed normally... :-(
> >
> >   
> It's a typical syndrom of memory corruption. I fixed few memory misusage
> in trunk. Could you retest?

Done. Your corrections were successful, GRUB boots OK on my machines
now.

Regards
Ales




^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [RFC - Vladimir ?] USB/RS232 converter PL2303 small problem
  2010-09-30 17:53                       ` [RFC - Vladimir ?] USB/RS232 converter PL2303 small problem Aleš Nesrsta
@ 2010-10-17 11:54                         ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 0 replies; 23+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2010-10-17 11:54 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 3248 bytes --]

On 09/30/2010 07:53 PM, Aleš Nesrsta wrote:
> Hi,
>
> I don't know who is developer/maintainer of USB serial drivers - I
> expect it is Vladimir, so this e-mail is addressed mainly to him.
>
> As I wrote in my older e-mail (Question: USB serial - device driver
> debugging), there is some problem with PL2303. Not with driver but with
> device itself (probably).
>
> What is the problem:
>
> If I put some stream of characters into PL2303, device stops accepting
> data and answers NAK indefinitely after some time / some amounts of
> character sent (256 exactly).
>
> It happens only if PL2303 is connected to another computer. If only
> null-modem cable is connected, it does not happen. (If no cable is
> connected, it happens also but in this case it is caused by missing
> handshaking signals which prevent sending -> output buffer overloading
> happens, i.e. it is in fact correct situation.)
>
> I discovered the reason - I forgot switch off "echo" on ttyS0 of PC
> where was cable connected. I.e. every character sent by GRUB was
> returned from connected PC back to input of PL2303 and input buffer was
> overloaded.
>
> But what is surprising for me - why stops PL2303 SENDING when INPUT
> buffer is full ???
> ("Normal" serial port does not such thing in GRUB, it looks like it is
> PL2303 device speciality. I did not test FTDI, I don't have it.)
>
> Maybe such behavior can be prevented by some another pre-setting of
> PL2303 device - but there is no detailed documentation about PL2303
> device USB interface.
>
>   
I doubt it's the case or that it's at least known. I expect it's
something Linux would want to enable and the driver is based on USB
capture from Linux operation.
> I thought also about some workaround - continuously check amount of
> characters in input buffer in device but there is problem how to do it -
> at least there is no related documentation of PL2303 as I mentioned
> above.
>
>   
Yes, we need a workaround. The sanest and simplest would be to receive
input before sending anything. The input will be saved in a buffer of
fixed size and in case of overflow just discarded (it's to prevent
memory overusage by input noone cares about, not very clean but...)
This logic can be put in common usbserial part. This workaround is
harmless and enabling it on all devices will save the time of figuring
out which ones exhibit such behaviour
> Another possibility is periodical fetching characters from PL2303 but it
> should be disabled when PL2303 is used as input for terminal etc. - it
> looks too difficult to implement (and non-standard...).
>
> I.e. there is probably no simple way how to prevent this problem but
> such unexpected behavior of device should be known and probably
> documented somewhere - where ?
> Is there some place in source where to store HowTos, FAQs and some other
> more or less important notes ? Or should I write this information into
> driver source code ?
>
> Regards
> Ales
>
>
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
>   


-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2010-10-17 11:54 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-25 13:26 Plans on 1.99 release Vladimir 'φ-coder/phcoder' Serbinenko
2010-08-26 23:05 ` Carles Pina i Estany
2010-08-26 23:15   ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-08-28 11:31     ` Aleš Nesrsta
2010-08-29 23:52       ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-08-30  0:14         ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-09-03 22:02           ` Plans on 1.99 release - USB issues Aleš Nesrsta
2010-09-04 17:34             ` Aleš Nesrsta
2010-09-12 17:28               ` [PATCH] USB issues - kbdlayouts branch Aleš Nesrsta
2010-09-13 10:43                 ` [PATCH] usb_keyboard.c problems (USB issues - kbdlayouts branch) Aleš Nesrsta
2010-09-13 11:47                 ` [PATCH] USB issues - kbdlayouts branch Aleš Nesrsta
2010-09-13 18:13                   ` Aleš Nesrsta
2010-09-15  5:58                     ` [PATCH] USB serial - missing configuration Aleš Nesrsta
2010-09-19 11:46                       ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-09-21 20:18                         ` Aleš Nesrsta
2010-09-23 21:13                           ` Trunk: boot problem - unaligned pointer 0x Aleš Nesrsta
2010-09-26  9:58                             ` Aleš Nesrsta
2010-09-30 19:37                             ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-09-30 20:45                               ` Aleš Nesrsta
2010-09-15  5:58                     ` Question: USB serial - device driver debugging Aleš Nesrsta
2010-09-30 17:53                       ` [RFC - Vladimir ?] USB/RS232 converter PL2303 small problem Aleš Nesrsta
2010-10-17 11:54                         ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-09-18 10:08             ` Plans on 1.99 release - USB issues Vladimir 'φ-coder/phcoder' Serbinenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.