Jump to content


Building a kernel where USB_PERSIST actually works


51 replies to this topic

#1 timauton

    Advanced Member

  • Members
  • PipPipPip
  • 89 posts
  • LocationSheffield, UK

Posted 03 April 2008 - 04:32 PM

After a lot of fun trying to build a kernel where USB_PERSIST actually worked, I finally managed it. I thought I'd share the secret. Simply enabling it on vanilla or Debian-patched 2.6.24 kernel (and enabling it in /sys/bus/usb... for the relevant device) didn't work for me.

I found a patch from Greg Kroah-Hartman (a kernel dev) which, with a minor tweak, fixed my problem. Apparently without the fix persist only works when a hub is powered down during suspend - this doesn't happen on the eee when it's plugged in. The patch fixes that. My tweak was just moving a function so the compiler didn't bitch about it being implicitly declared - I presume the original patch was against some development tree, not the released 2.6.24 kernel.

You can download a copy of the patch here (right-click and save-as). Then you want to..

cd /i/build/my/kernels/here/linux-2.6.24
patch -p1 </i/downloaded/the/patch/to/here/usb-make-usb-persist-work-after-every-system-sleep.tsa.patch
edit: If you get an error saying that Hunk #4 FAILED your sources probably already have that part of the patch. Assuming that hunk is the only one which failed then the other three parts have been applied. You don't need to do anything else, just ignore the error and get on with building your kernel.

edit: You need to enable USB_PERSIST when you run eg. make menuconfig. Tick "USB device persistence during system suspend" which is under Device Drivers > USB support.

Just enabling USB_PERSIST for the kernel isn't enough - you also need to enable it at runtime for the device(s) you want to persist. You do this by echoing 1 to /sys/bus/usb.../power/persist for the relevant device. That path is liable to change every boot, which is annoying, so I wrote a little script which enables/disables persist by the vendor and product IDs of the USB device, which is a little friendlier. You can find that here (right click and save-as, put it some where in your path, chmod +x). Unsurprisingly, you need to run it as root (eg. sudo it). You can get the vendor and product IDs from lsusb. For example, lsusb gives me this:

debeee:/home/tim# lsusb
Bus 005 Device 019: ID 0951:1606 Kingston Technology 
Bus 005 Device 004: ID 1b1c:1a90  
Bus 005 Device 001: ID 0000:0000  
Bus 004 Device 001: ID 0000:0000  
Bus 003 Device 001: ID 0000:0000  
Bus 002 Device 001: ID 0000:0000  
Bus 001 Device 013: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
Bus 001 Device 001: ID 0000:0000
The card reader is the one labelled "Kingston Technology". The vendor and product IDs are the two groups of hex digits either side of the colon. To enable persist for the card reader:

set_usb_persist.sh 0951 1606 on
You'll want to add a line like that (but with the full path to the script) to, say, /etc/rc.local to enable persist for that device on every boot.

edit: fixed link

edit2: info on failed hunk, enabling persist in kernel config

Edited by timauton, 12 May 2008 - 11:20 PM.


#2 randomT

    Advanced Member

  • Members
  • PipPipPip
  • 55 posts

Posted 11 April 2008 - 03:42 PM

Hi Tim,

thanks for the howto, unfortunately the link is broken (one space to many).

However, I downloaded the patch as well but I couldn't apply it.

Only get an error message which tells me to look at hub.c.rej
However, I have no clue what the content of this file is supposed to tell me...
***************
*** 2946,2952 ****
                if (len < le16_to_cpu(udev->config[index].desc.wTotalLength))
                        len = le16_to_cpu(udev->config[index].desc.wTotalLength);
        }
-       buf = kmalloc (len, GFP_KERNEL);
        if (buf == NULL) {
                dev_err(&udev->dev, "no mem to re-read configs after reset\n");
                /* assume the worst */
--- 2993,2999 ----
                if (len < le16_to_cpu(udev->config[index].desc.wTotalLength))
                        len = le16_to_cpu(udev->config[index].desc.wTotalLength);
        }
+       buf = kmalloc(len, GFP_NOIO);
        if (buf == NULL) {
                dev_err(&udev->dev, "no mem to re-read configs after reset\n");
                /* assume the worst */
~


#3 timauton

    Advanced Member

  • Members
  • PipPipPip
  • 89 posts
  • LocationSheffield, UK

Posted 11 April 2008 - 05:48 PM

Sorry about the link, fixed now.

I'm guessing you have a different set of kernel sources to me, the patch I posted works against a vanilla 2.6.24 (and the Debian patched version I use, but that file is identical in both). The reject file is just telling you which part of the patch didn't apply - the last one-line change in the patch. The other parts of the patch will have been applied (assuming that's the whole contents of hub.c.rej).

As it's a simple one-line change you can do it by hand. It's just changing the line from the reject file starting with a - to the one starting with a +. The other lines are context so patch knows it's looking in the right place - there are probably other lines like that in the file, so a simple search and replace won't do, you have to do it in the right place. Search for "assume the worst" in your text editor to find the right bit of the file. It's possible your kernel source already has that change, if it does you don't need to do anything.

#4 randomT

    Advanced Member

  • Members
  • PipPipPip
  • 55 posts

Posted 11 April 2008 - 06:51 PM

Thanks for the quick reply!
You were right, the patch was already included in my sources, I used the latest gentoo sources.

#5 lyso

    Member

  • Members
  • 21 posts

Posted 23 April 2008 - 07:46 PM

Just wanted to say thanks for this info - attempting a build now.

#6 dvm

    Senior Member

  • Members
  • 124 posts

Posted 30 April 2008 - 11:29 AM

Hi,

I built a new kernel with this patch. Building and installation went fine. My 701 can boot with this kernel too.

But I got stuck with an error when executing the set_usb_persist.sh script:
 /usr/bin/set_usb_persist.sh 0951 1606 on
Found ENE UB6225.
Unable to write to /sys/devices/pci0000:00/0000:00:1d.7/usb5/5-5/power/persist, aborting.
What to do? Thanks in advance! :)

#7 timauton

    Advanced Member

  • Members
  • PipPipPip
  • 89 posts
  • LocationSheffield, UK

Posted 30 April 2008 - 04:48 PM

You need to run the script as root (in a root terminal) or with sudo (sudo set_usb_persist.sh ...), if you don't you would get that error.

#8 dvm

    Senior Member

  • Members
  • 124 posts

Posted 30 April 2008 - 07:45 PM

Thanks for the reply. I am already running as root. But still getting the same error.

#9 timauton

    Advanced Member

  • Members
  • PipPipPip
  • 89 posts
  • LocationSheffield, UK

Posted 02 May 2008 - 09:19 PM

Curious. Does just "echo 1 > /sys/.../power/persist" work OK? Can you post the output of "ls -l /sys/.../power/persist"? (you can get the proper path from the script's error message).

#10 dvm

    Senior Member

  • Members
  • 124 posts

Posted 08 May 2008 - 04:21 PM

Quote

Curious. Does just "echo 1 > /sys/.../power/persist" work OK? Can you post the output of "ls -l /sys/.../power/persist"? (you can get the proper path from the script's error message).
Running both says "No such file or directory"... strange... :/

#11 timauton

    Advanced Member

  • Members
  • PipPipPip
  • 89 posts
  • LocationSheffield, UK

Posted 11 May 2008 - 01:37 AM

Sorry, missed my email about your reply. That is odd, it looks like the persist file doesn't exist, which suggests the kernel you're running doesn't support it. If you compiled a new kernel with persist enabled, are you sure it's the new one that's actually running? Which kernel sources are you using?

#12 dvm

    Senior Member

  • Members
  • 124 posts

Posted 12 May 2008 - 09:41 AM

Thanks again. I was using the debian kernel source. I also found the last change in the patch not working because the source already has it, so I manually removed that part from the patch and then built the kernel. Probably some setting got messed up during building...
Just wonder if you could upload the kernel .deb so that I can test?

#13 br00tal

    Advanced Member

  • Members
  • PipPipPip
  • 41 posts

Posted 12 May 2008 - 05:33 PM

I'm trying to find/create a version of this patch that works on a vanilla 2.6.24.3 from kernel.org. The patch fails instantly currently. Anyone have any ideas?

#14 timauton

    Advanced Member

  • Members
  • PipPipPip
  • 89 posts
  • LocationSheffield, UK

Posted 12 May 2008 - 11:07 PM

dvm, Just a thought, did you tick the box for USB_PERSIST when configuring your kernel? The patch doesn't enable it in the kernel config, you need to do that manually when you do eg. make menuconfig. It's not enabled by default. Anyway, I've uploaded my kernel .deb. You might want the matching wifi drivers too. A tarball of the sources it was built from is here. Ethernet drivers come with the kernel. Sorry there's no kernel headers package, for some reason I couldn't build one which actually worked, I don't think the Debian kernel packaging tools were working properly with 2.6.24 then (I don't know if that's been fixed yet). The kernel was targeted only at me and my eee, so it may be missing stuff that's important to you.

br00ta, do all four hunks fail? If it's just hunk #4 then that change has probably already made it into 2.6.24.3. I think that last hunk may have been a different fix which "leaked" into that patch by mistake. It doesn't appear directly related to the other changes to me, but I'm no Linux kernel hacker. If it just says hunk #4 failed then the rest applied OK and you can just get on with building your kernel.

Just for reference, the original patch (against 2.6.25) can be found here.

I'll update my first post with the info from this post.

#15 br00tal

    Advanced Member

  • Members
  • PipPipPip
  • 41 posts

Posted 13 May 2008 - 04:50 AM

Actually, the first three succeeded, just the fourth failed. The kernel compiles and runs, but the SD card still has I/O errors upon wakeup. It seems as though they've fixed this in 2.6.25, correct? Can anyone verify? Also, is that's the case, has anyone built a small 2.6.25 kernel for the Eee yet? I tried to, but the API has changed so much in that kernel that I had a hard time getting it configure.

#16 br00tal

    Advanced Member

  • Members
  • PipPipPip
  • 41 posts

Posted 13 May 2008 - 10:27 PM

Alright, I built a 2.6.25.3 kernel, and USB_PERSIST still doesn't work. I've applied the usb-make-usb-persist-work-after-every-system-sleep.patch and the usb-reorganize-code-in-hub.c.patch (the latter because the first breaks the compilation process in hub.c), and nothing seems to change. Does anyone know of a good fix for this? Also, it appears that ath5k, the new Atheros module, does not work with the Eee's wireless card. I had my hopes, though.

Any developments would be wonderful.

#17 timauton

    Advanced Member

  • Members
  • PipPipPip
  • 89 posts
  • LocationSheffield, UK

Posted 13 May 2008 - 11:27 PM

I'll build and test a new kernel (actually two, one Debian and one vanilla) when I find some time and post my findings here.

For now, the kernel sources and kernel .deb I posted work, are only a couple of months old and do produce a kernel where USB_PERSIST works. The sources are Debian-patched, but AFAIK they'll still build in the normal way and the resulting kernel will work with other distributions.

It'd be worth checking manually that persist really is on for the device in question and for the hub it's attached to - it's always on for all hubs in the kernel I used so my script doesn't bother to set it; this could have changed. You can do this manually by trawling through the entries in /sys/bus/usb/devices and checking that, eg. /sys/bus/devices/usb5/power/persist is set to 1 (use cat to read it). The ones with names like "usb5" are hubs, ones with names like "5-6" are devices, ones with names like "5-6:1.0" are endpoints. You care about hubs and devices. Read the contents of eg. /sys/bus/devices/usb5/product for a human-readable name for the device. (In case you notice the discrepancy, set_usb_persist.sh doesn't use those exact paths - the entries in /sys/bus/usb/devices are symlinks, the script uses the real paths, which are rather unfriendly).

#18 br00tal

    Advanced Member

  • Members
  • PipPipPip
  • 41 posts

Posted 14 May 2008 - 05:27 AM

Actually, I lied. It does work, I just have to use your script. I'm trying to figure out how to get this to patch into 2.6.25.3. Supposedly it enables persist be default, but the patch fails for me. I looked through it, and added what I thought was the added code (it's a small patch), and the kernel built, but still no persist. Getting closer, but no cigar so far.

EDIT:

I got it working with 2.6.25.3. See this page for the quirks.c file necessary to have persistence enabled by default. This way, it works like it used to in 2.6.21. There's no need for an echo 1 > /sys/bah/blah, or a script to do it for you. Took quite a while to track that down.

Edited by br00tal, 14 May 2008 - 06:42 AM.


#19 dvm

    Senior Member

  • Members
  • 124 posts

Posted 15 May 2008 - 01:13 PM

Thank you timauton for the .deb and the tip. Will try that if my next build fails. :)
br00tal, do we still need the patch on top of this quicks.c? Any special setting to build?

#20 br00tal

    Advanced Member

  • Members
  • PipPipPip
  • 41 posts

Posted 15 May 2008 - 09:45 PM

No, nothing special at all. Actually, the patch tries to change quirks.c to the one in the link, it just fails to do so.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users