Bug 9

Summary: EHCI not properly shut down on reboot, kills usb keyboard in bios/bootloader
Product: Drivers Reporter: Nicolas Mailhot (Nicolas.Mailhot)
Component: USBAssignee: David Brownell (dbrownell)
Status: CLOSED CODE_FIX    
Severity: normal    
Priority: P2    
Hardware: IA-32   
OS: Linux   
Kernel Version: Subsystem:
Regression: --- Bisected commit-id:

Description Nicolas Mailhot 2002-11-14 08:51:04 UTC
Exact Kernel version: 2.5.46-bk2 (and other from 2.5.44 to 2.5.47, don't
remember all the verions tested)

Distribution: Red Hat Rawhide

Hardware Environment: Gigabyte GA -7VAX, latest bios, keyboard + mouse on
external usb2 nec hub

Problem Description: 

When I enable ehci, boot into  2.5 then reboot I loose the usb input. Since my
input is 100% usb, this is real anoying in the bootloader and bios settings
(i.e. I need usb input that can be handled by the bios)

uhci works in 2.4 and 2.5
ehci works in w2k

The workaround is to manually turn off the psu to reset the system
Comment 1 Greg Kroah-Hartman 2002-11-14 09:58:53 UTC
What do you mean, "The workaround is to manually turn off the psu to reset the
system"?  What does this entail?
Comment 2 Nicolas Mailhot 2002-11-14 10:30:19 UTC
If I ever boot in 2.5, and wish to switch to another kernel/another os, I can't
just reboot. I have to press the psu switch (off then on) at post time  or the
bios is not able to initialise usb input (I think if the default bootloader
entry is a working kernel it won't be able to initialise it either).

Bios is an ami bios, fastest boot time I've ever seen, so I wouldn't be
surprised it cut all non-mandatory ops at reboot to speed it up)

Merely pressing the case power switch is not sufficient, I have to use the psu one
Comment 3 Nicolas Mailhot 2002-11-14 10:37:59 UTC
The result is I can't just do /sbin/init 6 (local or via ssh) and hope it will
work alone. It won't. Plus I'm pretty sure playing with the psu is very bad for
the hardware.
Comment 4 David Brownell 2002-11-14 11:19:54 UTC
Hmm, Nicolas the last time I remember seeing you post info on 
this bug you _only_ had the EHCI driver loaded, which would 
prevent keyboard from working.  With NEC ECHI you also need 
the OHCI driver loaded ... unless you're only working with 
USB 2.0 devices (connecting all USB 1.1 devices to a USB 2.0 
hub, and thence to an EHCI root hub). 
 
What happens when you turn normal boot checks back on?  If 
the BIOS isn't even trying to get the keyboard back, because 
you enabled fast boot and it only tries the keyboard stuff 
from a cold boot, there's not going to be anything Linux can 
ever do. 
 
Comment 5 Nicolas Mailhot 2002-11-14 11:31:36 UTC
Hi David, good to see you on bugzilla.

I do only have ehci loaded. The hardware is still :

via kt400 mobo -- external usb2 nec hub -- usb1 mouse + keyboard + combo
smartmedia/compactflash reader

So all usb1 devices are filtered by the external usb2 hub, and I only need ehci
loaded (anyway also loading uhci changes zip)

I've enabled all checks I could in the bios, but it's still damn fast.

And since it works on 2.5/2.4 uhci and w2k ehci, I do suppose the bios tries to
initialise things back, only after a 2.5 ehci boot it somehow can not:(

Comment 6 Greg Kroah-Hartman 2002-11-14 11:47:15 UTC
I'm glad to see Dave here too :)
I've given him this bug, let me know if that's a problem.
Comment 7 Nicolas Mailhot 2002-11-14 11:59:23 UTC
No problem at all, I switched to bugzilla because it's better at handling bugs
and  I asked for it, not because I was uhappy of david's handling.

(just reproduced this one on 2.5.43-ac3 btw)

Anyway since I seem to be unable to describe the device topology in good
english, I'll let lsusb speak :

Bus 001 Device 005: ID 046a:0001 Cherry Mikroschalter GmbH My3000 Keyboard
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.00
  bDeviceClass            0 Interface
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0         8
  idVendor           0x046a Cherry Mikroschalter GmbH
  idProduct          0x0001 My3000 Keyboard
  bcdDevice            9.08
  iManufacturer           0
  iProduct                0
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           34
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0xa0
      Remote Wakeup
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Devices
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      1 Keyboard
      iInterface              0
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.00
          bCountryCode            0
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      63
cannot get report descriptor
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               none
        wMaxPacketSize          8
        bInterval              12
  Language IDs: (length=4)
     0009 English(English)

Bus 001 Device 004: ID 046d:c001 Logitech Inc. N48/M-BB48 [FirstMouse Plus]
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 Interface
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0         8
  idVendor           0x046d Logitech Inc.
  idProduct          0xc001 N48/M-BB48 [FirstMouse Plus]
  bcdDevice            4.10
  iManufacturer           1 Logitech
  iProduct                2 USB Mouse
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           34
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0xa0
      Remote Wakeup
    MaxPower               50mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Devices
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      2 Mouse
      iInterface              0
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode            0
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      68
cannot get report descriptor
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               none
        wMaxPacketSize          4
        bInterval              10
  Language IDs: (length=4)
     0409 English(US)

Bus 001 Device 003: ID 04e6:0005 Shuttle Technology Inc.
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 Interface
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        16
  idVendor           0x04e6 Shuttle Technology Inc.
  idProduct          0x0005
  bcdDevice            2.08
  iManufacturer           1 SCM Microsystems Inc.
  iProduct                2 eUSB SmartMedia / CompactFlash Adapter
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           39
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          3
    bmAttributes         0x80
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           3
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      1
      bInterfaceProtocol      1
      iInterface              4 CBC Interface
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               none
        wMaxPacketSize         64
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               none
        wMaxPacketSize         64
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               none
        wMaxPacketSize          2
        bInterval              32
  Language IDs: (length=4)
     0409 English(US)

Bus 001 Device 002: ID 0409:0058 NEC Systems
cannot get string descriptor 1, error = Broken pipe(32)
cannot get string descriptor 2, error = Broken pipe(32)
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            9 Hub
  bDeviceSubClass         0
  bDeviceProtocol         1
  bMaxPacketSize0        64
  idVendor           0x0409 NEC Systems
  idProduct          0x0058
  bcdDevice            1.00
  iManufacturer           1
  iProduct                2
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           25
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0xe0
      Self Powered
      Remote Wakeup
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         9 Hub
      bInterfaceSubClass      0
      bInterfaceProtocol      0
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               none
        wMaxPacketSize          1
        bInterval              12
  Language IDs: (length=4)
     0409 English(US)

Bus 001 Device 001: ID 0000:0000 Virtual Hub
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            9 Hub
  bDeviceSubClass         0
  bDeviceProtocol         1
  bMaxPacketSize0         8
  idVendor           0x0000 Virtual
  idProduct          0x0000 Hub
  bcdDevice            2.05
  iManufacturer           3 Linux 2.5.47-ac3-rous1 ehci-hcd
  iProduct                2 VIA Technologies, Inc. USB 2.0
  iSerial                 1 00:10.3
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           25
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x40
      Self Powered
    MaxPower                0mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         9 Hub
      bInterfaceSubClass      0
      bInterfaceProtocol      0
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               none
        wMaxPacketSize          2
        bInterval              12
  Language IDs: (length=4)
     0409 English(US)
Comment 8 Nicolas Mailhot 2003-01-15 02:12:02 UTC
2.5.58-ehci1231 is now able to recover usb after reboot.

USB keyboard is still dead in bios and bootloader after booting out of 2.5.

This appears to be due to the ehci unloading code not being called in a
monolithic kernel at shutdown time.

(and a lsusb killed the box yesterday in 2.5, didn't dare replicating it yet)
Comment 9 Nicolas Mailhot 2003-02-16 04:02:54 UTC
And ehci-0215.patch makes usb shut down cleanly at reboot time.
So with of them we've got a complete fix.
Comment 10 David Brownell 2003-02-19 19:12:08 UTC
The fix was to just give up on the PCI device getting shut down,  and provide a reboot notifier.  It just disables EHCI; maybe a  BIOS that understands EHCI will want more than that, but I don't  have any to test with.  Patch provided, and is in Linus' 2.5.62+ BK tree.  
Comment 11 Alejandro Colomar 2021-01-09 21:20:40 UTC
A more detailed notice is on realloc(3p).

......

$ man 3p realloc \
  |sed -n \
     -e '/APPLICATION USAGE/,/^$/p' \
     -e '/FUTURE DIRECTIONS/,/^$/p';
APPLICATION USAGE
       The description of realloc() has been modified from  pre‐
       vious  versions  of  this  standard  to  align  with  the
       ISO/IEC 9899:1999 standard. Previous versions  explicitly
       permitted  a  call  to  realloc(p,  0)  to free the space
       pointed to by p and return a null pointer. While this be‐
       havior  could be interpreted as permitted by this version
       of the standard, the C language committee have  indicated
       that   this  interpretation  is  incorrect.  Applications
       should assume that if realloc() returns a  null  pointer,
       the  space pointed to by p has not been freed. Since this
       could lead to double-frees, implementations  should  also
       set errno if a null pointer actually indicates a failure,
       and applications should only free the space if errno  was
       changed.

FUTURE DIRECTIONS
       This  standard  defers  to the ISO C standard. While that
       standard currently has language that might  permit  real‐
       loc(p, 0), where p is not a null pointer, to free p while
       still returning a null pointer, the committee responsible
       for  that standard is considering clarifying the language
       to explicitly prohibit that alternative.

Bug: 211039 <https://bugzilla.kernel.org/show_bug.cgi?id=211039>
Reported-by: Johannes Pfister <johannes.pfister@josttech.ch>
Cc: libc-alpha@sourceware.org
Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
---

Hi Johannes, Michael,

Thanks for the report, Johannes!
Please review that your name is correct (I guessed it from the email).

Michael, please review the wording.

Thanks,

Alex

 man3/malloc.3 | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/man3/malloc.3 b/man3/malloc.3
index d8b4da62f..467e2438a 100644
--- a/man3/malloc.3
+++ b/man3/malloc.3
@@ -149,7 +149,8 @@ is equal to zero,
 and
 .I ptr
 is not NULL, then the call is equivalent to
-.IR free(ptr) .
+.I free(ptr)
+(this behavior is nonportable; see NOTES).
 Unless
 .I ptr
 is NULL, it must have been returned by an earlier call to
@@ -375,6 +376,21 @@ The
 implementation is tunable via environment variables; see
 .BR mallopt (3)
 for details.
+.SS Nonportable behavior
+The behavior of
+.BR realloc ()
+when
+.I size
+is equal to zero,
+and
+.I ptr
+is not NULL,
+is glibc specific;
+other implementations may return NULL, and set
+.IR errno .
+Portable POSIX programs should avoid it.
+See
+.BR realloc (3p).
 .SH SEE ALSO
 .\" http://g.oswego.edu/dl/html/malloc.html
 .\" A Memory Allocator - by Doug Lea
Comment 12 Michael Kerrisk 2021-01-10 08:19:19 UTC
Hi ALex,

On 1/9/21 10:15 PM, Alejandro Colomar wrote:
> A more detailed notice is on realloc(3p).
> 
> ......
> 
> $ man 3p realloc \
>   |sed -n \
>      -e '/APPLICATION USAGE/,/^$/p' \
>      -e '/FUTURE DIRECTIONS/,/^$/p';
> APPLICATION USAGE
>        The description of realloc() has been modified from  pre‐
>        vious  versions  of  this  standard  to  align  with  the
>        ISO/IEC 9899:1999 standard. Previous versions  explicitly
>        permitted  a  call  to  realloc(p,  0)  to free the space
>        pointed to by p and return a null pointer. While this be‐
>        havior  could be interpreted as permitted by this version
>        of the standard, the C language committee have  indicated
>        that   this  interpretation  is  incorrect.  Applications
>        should assume that if realloc() returns a  null  pointer,
>        the  space pointed to by p has not been freed. Since this
>        could lead to double-frees, implementations  should  also
>        set errno if a null pointer actually indicates a failure,
>        and applications should only free the space if errno  was
>        changed.
> 
> FUTURE DIRECTIONS
>        This  standard  defers  to the ISO C standard. While that
>        standard currently has language that might  permit  real‐
>        loc(p, 0), where p is not a null pointer, to free p while
>        still returning a null pointer, the committee responsible
>        for  that standard is considering clarifying the language
>        to explicitly prohibit that alternative.
> 
> Bug: 211039 <https://bugzilla.kernel.org/show_bug.cgi?id=211039>
> Reported-by: Johannes Pfister <johannes.pfister@josttech.ch>
> Cc: libc-alpha@sourceware.org
> Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>

Thanks. Patch applied.

Cheers,

Michael

> ---
> 
> Hi Johannes, Michael,
> 
> Thanks for the report, Johannes!
> Please review that your name is correct (I guessed it from the email).
> 
> Michael, please review the wording.
> 
> Thanks,
> 
> Alex
> 
>  man3/malloc.3 | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/man3/malloc.3 b/man3/malloc.3
> index d8b4da62f..467e2438a 100644
> --- a/man3/malloc.3
> +++ b/man3/malloc.3
> @@ -149,7 +149,8 @@ is equal to zero,
>  and
>  .I ptr
>  is not NULL, then the call is equivalent to
> -.IR free(ptr) .
> +.I free(ptr)
> +(this behavior is nonportable; see NOTES).
>  Unless
>  .I ptr
>  is NULL, it must have been returned by an earlier call to
> @@ -375,6 +376,21 @@ The
>  implementation is tunable via environment variables; see
>  .BR mallopt (3)
>  for details.
> +.SS Nonportable behavior
> +The behavior of
> +.BR realloc ()
> +when
> +.I size
> +is equal to zero,
> +and
> +.I ptr
> +is not NULL,
> +is glibc specific;
> +other implementations may return NULL, and set
> +.IR errno .
> +Portable POSIX programs should avoid it.
> +See
> +.BR realloc (3p).
>  .SH SEE ALSO
>  .\" http://g.oswego.edu/dl/html/malloc.html
>  .\" A Memory Allocator - by Doug Lea
>
Comment 13 johannes.pfister 2021-01-11 10:13:19 UTC
> A more detailed notice is on realloc(3p).

Yes. But i think it will lead to bugs when there is a documentation
that describes the behavior of realloc(), says realloc(ptr,0) will do
free(ptr), says realloc() is conforming to POSIX.1-2001, POSIX.1-2008,
C89, C99.
But does not mention that the realloc(ptr,0) is not specified in this
standards (except C89).

And there are some distributions that do not include the realloc(3p)
man page. On my Debian Buster (10) there is no realloc(3p) man page
and man realloc goes to the malloc man page of the Linux Programmer's
Manual.
But maybe this is a problem of the distributions/Debian?

> Thanks for the report, Johannes!
> Please review that your name is correct (I guessed it from the email).
Yes it is. Should i configure my name somewhere?


Kind Regards
Johannes


Am Sa., 9. Jan. 2021 um 21:20 Uhr schrieb Alejandro Colomar
<alx.manpages@gmail.com>:
>
> A more detailed notice is on realloc(3p).
>
> ......
>
> $ man 3p realloc \
>   |sed -n \
>      -e '/APPLICATION USAGE/,/^$/p' \
>      -e '/FUTURE DIRECTIONS/,/^$/p';
> APPLICATION USAGE
>        The description of realloc() has been modified from  pre‐
>        vious  versions  of  this  standard  to  align  with  the
>        ISO/IEC 9899:1999 standard. Previous versions  explicitly
>        permitted  a  call  to  realloc(p,  0)  to free the space
>        pointed to by p and return a null pointer. While this be‐
>        havior  could be interpreted as permitted by this version
>        of the standard, the C language committee have  indicated
>        that   this  interpretation  is  incorrect.  Applications
>        should assume that if realloc() returns a  null  pointer,
>        the  space pointed to by p has not been freed. Since this
>        could lead to double-frees, implementations  should  also
>        set errno if a null pointer actually indicates a failure,
>        and applications should only free the space if errno  was
>        changed.
>
> FUTURE DIRECTIONS
>        This  standard  defers  to the ISO C standard. While that
>        standard currently has language that might  permit  real‐
>        loc(p, 0), where p is not a null pointer, to free p while
>        still returning a null pointer, the committee responsible
>        for  that standard is considering clarifying the language
>        to explicitly prohibit that alternative.
>
> Bug: 211039 <https://bugzilla.kernel.org/show_bug.cgi?id=211039>
> Reported-by: Johannes Pfister <johannes.pfister@josttech.ch>
> Cc: libc-alpha@sourceware.org
> Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
> ---
>
> Hi Johannes, Michael,
>
> Thanks for the report, Johannes!
> Please review that your name is correct (I guessed it from the email).
>
> Michael, please review the wording.
>
> Thanks,
>
> Alex
>
>  man3/malloc.3 | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/man3/malloc.3 b/man3/malloc.3
> index d8b4da62f..467e2438a 100644
> --- a/man3/malloc.3
> +++ b/man3/malloc.3
> @@ -149,7 +149,8 @@ is equal to zero,
>  and
>  .I ptr
>  is not NULL, then the call is equivalent to
> -.IR free(ptr) .
> +.I free(ptr)
> +(this behavior is nonportable; see NOTES).
>  Unless
>  .I ptr
>  is NULL, it must have been returned by an earlier call to
> @@ -375,6 +376,21 @@ The
>  implementation is tunable via environment variables; see
>  .BR mallopt (3)
>  for details.
> +.SS Nonportable behavior
> +The behavior of
> +.BR realloc ()
> +when
> +.I size
> +is equal to zero,
> +and
> +.I ptr
> +is not NULL,
> +is glibc specific;
> +other implementations may return NULL, and set
> +.IR errno .
> +Portable POSIX programs should avoid it.
> +See
> +.BR realloc (3p).
>  .SH SEE ALSO
>  .\" http://g.oswego.edu/dl/html/malloc.html
>  .\" A Memory Allocator - by Doug Lea
> --
> 2.30.0
>
Comment 14 Alejandro Colomar 2021-01-11 14:38:13 UTC
On 1/11/21 11:13 AM, Johannes Pfister wrote:
>> A more detailed notice is on realloc(3p).
> 
> Yes. But i think it will lead to bugs when there is a documentation
> that describes the behavior of realloc(), says realloc(ptr,0) will do
> free(ptr), says realloc() is conforming to POSIX.1-2001, POSIX.1-2008,
> C89, C99.
> But does not mention that the realloc(ptr,0) is not specified in this
> standards (except C89).
> 
> And there are some distributions that do not include the realloc(3p)
> man page. On my Debian Buster (10) there is no realloc(3p) man page
> and man realloc goes to the malloc man page of the Linux Programmer's
> Manual.
> But maybe this is a problem of the distributions/Debian?

Hi Johannes,

That was the message for the commit.
See commit: da116d481b79892026029b442fb381713a09f123
<https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/commit/?id=da116d481b79892026029b442fb381713a09f123>

> 
>> Thanks for the report, Johannes!
>> Please review that your name is correct (I guessed it from the email).
> Yes it is. Should i configure my name somewhere?

No, don't worry.  It was only for the "Reported-by" line in the patch.

Regards,

Alex