# USB HotSync Patch for SONY Clie / Kernel 2.6.24/25

## Guenther Brunthaler

Hi all,

There is a problem in visor.ko kernel module of the 2.6.24 and 2.6.25 kernels.

This results in USB HotSync not working for certain PDA devices with those kernels, such as with SONY Clie PDAs.

In order to fix the problem, please apply the attached patch to the kernel and recompile. The new visor.ko module which will then work with your PDA again.

Here is the patch - please save the text as visor-bug215679-2.6.24.patch

```
This patch fixes LKML issue 10118 for 2.6.24 and 2.6.25 kernels

http://www.spinics.net/lists/linux-usb/msg03120.html

From: Brad Sawatzky <brad+debian@xxxxxxxxxxx>

Fixes a bug/inconsistency revealed by the additional sanity checking in

   commit 063a2da8f01806906f7d7b1a1424b9afddebc443

introduced in the original 2.6.24 branch.

The Handspring Visor / PalmOS 4 device structure defines .num_bulk_out=2

but the usb-serial probe returns num_bulk_out=3, triggering the check in

the above commit and forcing a bail out when the device (a Garmin iQue in

my case) attempts to connect.  The patch bumps the expected number of

endpoints to 3.

I suppose it's possible that the kernel is identifying 3 bulk endpoints

when there should only be 2 and there is some issue with the lower level

endpoint probe?

FWIW, this patch will probably solve the following kernel bug report for

Treo users (identical symptoms, different model PalmOS units):

  <http://bugzilla.kernel.org/show_bug.cgi?id=10118>

Signed-off-by: Brad Sawatzky <brad+kernel@xxxxxxxxxxx>

Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>

Index: linux-2.6.24-gentoo-r4/drivers/usb/serial/visor.c

===================================================================

--- linux-2.6.24-gentoo-r4.orig/drivers/usb/serial/visor.c

+++ linux-2.6.24-gentoo-r4/drivers/usb/serial/visor.c

@@ -191,7 +191,7 @@ static struct usb_serial_driver handspri

 (TAB).id_table =(TAB)(TAB)id_table,

 (TAB).num_interrupt_in =(TAB)NUM_DONT_CARE,

 (TAB).num_bulk_in =(TAB)(TAB)2,

-(TAB).num_bulk_out =(TAB)(TAB)2,

+(TAB).num_bulk_out =(TAB)(TAB)3,

 (TAB).num_ports =(TAB)(TAB)2,

 (TAB).open =(TAB)(TAB)(TAB)visor_open,

 (TAB).close =(TAB)(TAB)visor_close,

```

and apply it as

```
# sed -i -e 's,(TAB),\t,g' path/to/visor-bug215679-2.6.24.patch

# cd /usr/src/linux

# patch -p1 < path/to/visor-bug215679-2.6.24.patch
```

Last edited by Guenther Brunthaler on Thu Apr 10, 2008 2:22 pm; edited 2 times in total

----------

## m_gustafsson

Hi,

and thanks for the patch!

I have seen some problems with syncing my Palm T5 and now tried your patch.

Unfortunately I run into some problems that you maybe can help me with...

First I tried to apply the patch:

```
# patch -p1 < visor-bug215679-2.6.24.patch 

patching file drivers/usb/serial/visor.c

Hunk #1 FAILED at 191.

1 out of 1 hunk FAILED -- saving rejects to file drivers/usb/serial/visor.c.rej
```

The rejects file:

```
$ cat /usr/src/linux/drivers/usb/serial/visor.c.rej 

***************

*** 191,197 ****

     .id_table =      id_table,

     .num_interrupt_in =   NUM_DONT_CARE,

     .num_bulk_in =   2,

-    .num_bulk_out =    2,

     .num_ports =      2,

     .open =        visor_open,

     .close =         visor_close,

--- 191,197 ----

     .id_table =      id_table,

     .num_interrupt_in =   NUM_DONT_CARE,

     .num_bulk_in =   2,

+    .num_bulk_out =     3,

     .num_ports =      2,

     .open =        visor_open,

     .close =         visor_close,
```

I don't know much about patches, but I did try to apply it by hand.

So, what I did was to change the line .num_bulk_out = 2 to .num_bul_out = 3 around line 194 in visor.c.

I saved the change and did:

```
# make && make modules_install
```

After a reboot I tried my Palm sync once more and then got the error:

```
# dmesg

usb 1-6.1: new full speed USB device using ehci_hcd and address 8

usb 1-6.1: configuration #1 chosen from 1 choice

usbcore: registered new interface driver usbserial

drivers/usb/serial/usb-serial.c: USB Serial support registered for generic

usbcore: registered new interface driver usbserial_generic

drivers/usb/serial/usb-serial.c: USB Serial Driver core

drivers/usb/serial/usb-serial.c: USB Serial support registered for Handspring Visor / Palm OS

drivers/usb/serial/usb-serial.c: USB Serial support registered for Sony Clie 3.5

drivers/usb/serial/usb-serial.c: USB Serial support registered for Sony Clie 5.0

visor: probe of 1-6.1:1.0 failed with error -5

usbcore: registered new interface driver visor

drivers/usb/serial/visor.c: USB HandSpring Visor / Palm OS driver
```

As I have a T5 I also tried to apply the change in visor.c to the section in the code following the one with the original patch, i.e. the section on Palm 5.0 (I removed the old patch at the same time).

When I now run I see the same problem as before any patching, i.e. I can sync one or two times but the I get the following:

```
usb 1-6.1: new full speed USB device using ehci_hcd and address 12

usb 1-6.1: configuration #1 chosen from 1 choice

visor 1-6.1:1.0: Handspring Visor / Palm OS converter detected

usb 1-6.1: Handspring Visor / Palm OS converter now attached to ttyUSB0

usb 1-6.1: Handspring Visor / Palm OS converter now attached to ttyUSB1

usb 1-6.1: USB disconnect, address 12

visor ttyUSB0: Handspring Visor / Palm OS converter now disconnected from ttyUSB0

visor ttyUSB1: Handspring Visor / Palm OS converter now disconnected from ttyUSB1

visor 1-6.1:1.0: device disconnected

usb 1-6.1: new full speed USB device using ehci_hcd and address 13

usb 1-6.1: configuration #1 chosen from 1 choice

visor 1-6.1:1.0: Handspring Visor / Palm OS converter detected

usb 1-6.1: Handspring Visor / Palm OS converter now attached to ttyUSB0

usb 1-6.1: Handspring Visor / Palm OS converter now attached to ttyUSB1

usb 1-6.1: USB disconnect, address 13

visor ttyUSB0: Handspring Visor / Palm OS converter now disconnected from ttyUSB0

visor ttyUSB1: Handspring Visor / Palm OS converter now disconnected from ttyUSB1

visor 1-6.1:1.0: device disconnected

usb 1-6.1: new full speed USB device using ehci_hcd and address 14

usb 1-6.1: new full speed USB device using ehci_hcd and address 15

usb 1-6.1: device descriptor read/64, error -110
```

Is this the same type of error that your patch is fixing?

As I in my dmesg output I can see this line:

```
usbcore: registered new interface driver visor
```

I would guess that the second patch I did is not relevant, because then it should say something about using driver clie_5 I would guess?

Many thanks for your time.

/Mats

----------

## Guenther Brunthaler

Hi Mats,

 *m_gustafsson wrote:*   

> Hunk #1 FAILED at 191.

 

Sorry, it seems the horizontal tabulator characters in the patch have been lost when I pasted it into my article.

I have edited and updated the article accordingly; the patch should apply cleanly now.

 *m_gustafsson wrote:*   

> So, what I did was to change the line .num_bulk_out = 2 to .num_bul_out = 3 around line 194 in visor.c

 

You have done well; that's all the patch does!

 *m_gustafsson wrote:*   

> After a reboot I tried my Palm sync once more and

 

Actually it's not even necessary to reboot: In changes only affecting single kernel modules, such as for this one, it suffices to remove the old module from the running kernel and re-insert the new one.

That is, just make the patch/make/make modules_install as usual. This will overwrite the on-disk visor.ko module with the new one.

But then, instead of rebooting, just unplug your Palm device which keeps the visor.ko module loaded but unused.

Then do a "rmmod visor" in order to remove the old module from memory.

When you re-connect your Palm, the UDEV hotplug daemon should load and use the new visor module automatically.

 *m_gustafsson wrote:*   

> visor: probe of 1-6.1:1.0 failed with error -5

 

That error -5 is exactly the same I got before patching.

 *m_gustafsson wrote:*   

> As I have a T5 I also

 

That might be a problem: I noticed that while my SONY Clie required the patch in order to work, a different Palm (Z22) only worked *without* that patch!

It's really a mess...  :Sad: 

I think the problem with the code is that the device/model identifiers in the tables are not accurate enough for precise detection, which leads to mismatching device models and access configuration.

Unfortunately, I do not really understand what the code actually compares against what, and thus have no idea how to fix the code myself.

The best advice I can think of is that: Make different versions of the kernel module for different Palm models.

That is, first make/make modules_install a visor.ko version with the patch applied. (Make a backup of the original visor.c source file first).

Then 'cd' to /lib/modules/`uname -r`/kernel/drivers/usb/serial

and rename the patched module

```
# mv visor.ko visor-patched.ko
```

Then go back to the kernel directory, restore the original visor.c from the backup copy, and make/make modules_install again.

After that, you will have two versions of the module:

```
# rmmod visor; modprobe visor
```

will load the original, unmodified module, working with some Palm Models, and

```
# rmmod visor; modprobe -o visor visor-patched
```

will load the patched module, working with some other Palm models.

Note the "-o" switch, it will rename the visor-patched.ko file after it has been loaded into memory, so the system will treat it exactly as if it was the original visor.ko module.

 *m_gustafsson wrote:*   

> Is this the same type of error that your patch is fixing?

 

No, the patch only fixed the "-5" error.

But then, maybe that second error is only a follow-up error of the -5 error. I don't know.

Regards,

Guenther

----------

## m_gustafsson

Hi Guenther!

I followed your idea about that an incorrect Palm product might be picked by the visor program.

Looked into visor.h and it actually looks like the product  id of my Palm T5 which is 0061 is associated with a Treo 650 in the visor.h file.

I changed that and tried again (re-compiled etc), but unfortunately I see the same problem even after the change   :Sad: 

Will dig into this more later, but now I have to do some work   :Sad: 

I was thinking about another thing...

The error you saw was:

 *Quote:*   

> visor: probe of 1-6.1:1.0 failed with error -5

 

which seems like it comes from a module called visor, right?

The error I see says:

 *Quote:*   

> usb 1-6.1: device descriptor read/64, error -110

 

which indicates that it comes from a module called usb 1-6.1.

Could it be like that? In that case my problem is maybe not with the visor module?

Do you know of any good way to track error meassages, i.e. to find the source for a message like the one I see?

/Mats

----------

## Guenther Brunthaler

Hi Mats,

 *m_gustafsson wrote:*   

> Could it be like that? In that case my problem is maybe not with the visor module

 

I would say, yes. But that does not necessarily mean the problem is originating in the usb module - perhaps it has just been detected there.

Let's not forget visor.ko is a USB serial converter helper module; the data arrives at the usb subsystem and is then relayed to the visor.ko module.

So the usb and visor modules certainly have to co-operate internally.

 *m_gustafsson wrote:*   

> Do you know of any good way to track error meassages, i.e. to find the source for a message like the one I see?

 

Well, I'm not a kernel developer. There may be several ways to indicate an error. But a typical way to indicate failure seems to be code like

```
dev_err(dev, "%s - kmalloc(%Zd) failed.\n", __FUNCTION__, sizeof(*connection_info));

return -ENOMEM;

```

That is, first some function is called for logging the error to the kernel message ring buffer (which can be read by dmesg).

And then the function returns some negative number as an error code, where the corresponding positive number is a #define in some header file.

It should therefore be possible to locate the error message (or at least parts of it if it is constructed as in the above example) by grepping the source files.

Or the #define name associated with the error code could be located by grepping the kernel header files, and then grepping the kernel source files for the #define identifier found in the previous step.

For instance,

```
# find -name "*".h | while read F; do grep -HP 'define\s+\S+\s+110\D' "$F"; done
```

should find all macro definitions evaluating to the value 110. (If that does not find anything, the hexadecimal equivalent of 110 should also be searched for.)

I had multiple hits when searching for 110 that way, but I think that

```
#define ETIMEDOUT       110     /* Connection timed out */
```

seems to be the right one.

Next I searched for return -ETIMEDOUT:

```
# cd /usr/src/linux/drivers/usb

# find -name "*".c | while read F; do grep -HP 'return\s+-ETIMEDOUT' "$F"; done
```

which returned the following source files I consider a potential hit:

```
./core/hub.c:           return -ETIMEDOUT;

./host/ehci-hcd.c:      return -ETIMEDOUT;

./host/uhci-hub.c:              return -ETIMEDOUT;

```

 *m_gustafsson wrote:*   

> usb 1-6.1: device descriptor read/64, error -110

 

Finally I searched the hits from above for the error message text:

```
# grep "device descriptor" core/hub.c host/ehci-hcd.c host/uhci-hub.c
```

This yielded several hits in core/hub.c, but only the following section starting in line 2388 matches the error message fully:

```
        retval = usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);

        if (retval < (signed)sizeof(udev->descriptor)) {

                dev_err(&udev->dev, "device descriptor read/%s, error %d\n",

                        "all", retval);

                if (retval >= 0)

                        retval = -ENOMSG;

                goto fail;

        }

```

I therefore assume the "110" error message originates from there.

Oh, and just for the record: I am using sys-kernel/gentoo-sources-2.6.24-r4 at the time of this writing.

----------

## m_gustafsson

Many thanks!

I have been away during the weekend, but I will dig into this later today   :Very Happy: 

----------

## m_gustafsson

Hi Guenther,

took a look at this now and I am now sure that it is row 2329 in hub.c that reports the error:

```
   if (r) {

            dev_err(&udev->dev, "device descriptor "

                  "read/%s, error %d\n",

                  "64", r);

            retval = -EMSGSIZE;

            continue;
```

I changed the error message, recompiled and saw my own text being printed out in the terminal.

Now I just got to find out the reason for the error   :Smile: 

/Mats

----------

## m_gustafsson

For me the problem was in the file hub.c.

After changing initialization scheme so that only the old way is used it seems to be running ok.

Many thanks for your help!

----------

## Guenther Brunthaler

Hi Mats,

 *m_gustafsson wrote:*   

> For me the problem was in the file hub.c.

 

It seems the problem has finally been fixed with gentoo-sources-2.6.24-r8.

At least both my SONY GPS Receiver as well as my SONY Clié TJ 35 work again now without the patch!  :Smile: 

BTW, I noticed they did not change the number of endpoints (which the temporary patch had modified).

Instead, they changed the line

```
.id_table =      id_table,
```

into

```
.id_table =      clie_id_5_table,
```

which makes the whole issue look as simple as an inappropriately referenced table entry...   :Confused:  But then, of course everyone is smarter after fixing the bug.    :Embarassed: 

----------

## m_gustafsson

Thanks for the update  :Smile: 

In the end I think that I had more problems, see my other topic:

https://forums.gentoo.org/viewtopic-t-682352-highlight-.html

I have not changed to the new kernel yet, but when I do I will see if it changes the behavior for me.

Best regards, Mats

----------

