Thursday 23 January 2014

Getting a Prolific PL-2501 based USB-to-USB link cable working with Debian and a Raspberry Pi

A while ago I had an idea to use a Raspberry Pi as a recovery interface to my bigger home server.  My home server acts as my fileserver, network router, dns server and provides the web interface for my home automation and is always on.  I wanted a way of being able to access it over the network even if it's own network interface is down for some reason (usually because I've been experimenting with something and made a mistake).

I looked into the options and decided the simplest way of making this work would be to get a USB-to-USB link cable.  These aren't simple USB cables, there is some electronics in the middle that makes it work.  They are fairly common though and there are quite a few different manufacturers, most of which seem to be based on a few chipsets.

The one I got was made by "Sandberg" and came from ebay for about £5.  Unfortunately, I was unlucky and it turned out to be based on a chipset that's not currently supported by the plusb kernel module for Prolific USB network interfaces.

The module description says:

"Prolific PL-2301/2302/25A1 USB Host to Host Link Driver"

The cable I got has a PL-2501 chipset.  It was being recognised by the USB system OK but the module simply doesn't know about this chipset:
Bus 001 Device 004: ID 067b:2501 Prolific Technology, Inc. PL2501 USB-USB Bridge (USB 2.0)
There is a patch you can find on the Internet to make this work.  It involves installing the kernel source, patching the module, compiling the module and then copying it over the original module in the kernel driver folder.

In hindsight I'd have been much better off either:
  • using the Raspberry Pi UART and a spare internal serial port in my home server along with a 3.3v-5v level converter to create a serial link
  • installing a 2nd network card into my home server, linking this to the Raspberry Pi's NIC and then using a USB-to-Ethernet dongle in the Raspberry Pi so it has 2 interfaces.
Since I already had my USB link cable I was determined to make it work.

Here is what I did to get it to work.  You will need to compile the module twice, once on the Linux server and once on the Raspberry Pi since they are different architectures.  A module compiled on x86 wont work on the ARM based Pi.

---

Standard Debian system howto

This was what I did to get the cable working on my Linux server, it's x86 architecture but this will work OK for anything using a standard Debian system (i.e. no custom kernel).

1) Install the kernel headers and kernel source packages for your current kernel:
apt-get install linux-headers-`uname -r` linux-source
Note the use of backticks - ` these are not apostrophes, on a UK keyboard the key is next to the number one key.

Then extract the source:
cd /usr/src
tar xjf linux-source-3.2.tar.gz
Note - at the time of writing the source was for kernel 3.2, might have changed when you read this!

2) Copy your running kernel config into the source folder so any compiled modules are use the correct settings:
cd /usr/src/linux-source-3.2
cp /boot/config-`uname -r` .config
cp /usr/src/linux-headers-`uname -r`/Module.symvers ./
3) Patch the plusb module to work with our PL-2501.  I found a patch someone had made and downloaded it.  However it failed to patch against my source code.   The patch was very simple though so I manually patched my file and created a new patch file that can be downloaded here:
plusb.patch
Then apply the patch:
cd /usr/src/linux-source-3.2/drivers/net/usb/
patch < plusb.patch 
4) build your module:
cd /usr/src/linux-source-3.2
 make prepare
 make scripts
 make SUBDIRS=drivers/net/usb modules
 Note - this actually builds all the modules in the net/usb folder but there's not many and it doesn't take long.

5) Replace the old module with your new one:
rmmod -f plusb
mv drivers/net/usb/plusb.ko /lib/modules/`uname -r`/kernel/drivers/net/usb/
6) Load the module and make sure it's worked:
modprobe plusb
ifconfig -a
And you should see the usb0 interface listed that you can now use like any other network interface.

Raspberry Pi howto 

The process is very similar on the R-Pi.  To keep things as simple as possible I used the kernel maintained by the Raspbian people.  If you are using a non-standard kernel or the latest kernel from the Raspberry Pi foundation it'll be a lot more involved as they don't provide header packages.

You will need quite a lot of free space on your Pi's filesystem for this, I'd estimate at least 1GB.  It depends what you already have installed.

1) Install the latest Raspbian kernel and the source package:
apt-get install linux-image-rpi-rpfv
Note - I'm not sure if this is normal (I had been messing about with kernels a fair bit) but after installing this I had to copy the new kernel over the old one before rebooting would get it to load:
cp /boot/vmlinuz-3.10-3-rpi /boot/kernel.img
Or you could add a "kernel=vmlinuz-3.10-3-rpi" line to the config.txt file.

3) Get the kernel headers and source:
apt-get install linux-headers-rpi-rpfv linux-source-3.10
Note - make sure you have the deb-src repo in your sources.list.  http://www.raspbian.org/RaspbianRepository

4) Extract the source:
cd /usr/src
tar xJf linux-source-3.10.tar.xz
Everything else is the same as the instructions for standard Debian, step 2 onwards.  Just replace "linux-source-3.2" with "linux-source-3.10" anywhere.

After that, you'll have a usb0 interface on the Raspberry Pi too.  Once you've assigned IP addresses to this interface on both systems you can access one via the other simply using ssh.

You'll definitely want the device to come up at boot time.  So create a udev rule (create a file called something like /etc/udev/rules.d/99-plusb.rules) and put this in it:
SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="067b", ATTR{idProduct}=="2501", RUN+="/sbin/modprobe plusb"
Do this on both systems.

In case these are of any use, here are my finished working modules for both the Raspberry Pi and x86 (Intel Atom) server:

plusb-3.2.0.4-686-pae.tar

plusb-3.10-3-rpi.tar

2 comments:

  1. Your plusb.patch link just leads to the precompiled Raspberry Pi module. Do you still have the patch? I'm wanting to use this between two regular computers.

    ReplyDelete
  2. Can't seem to find it but a quick google search found this which I'm fairly sure is the same thing I used:

    https://lkml.org/lkml/2012/7/22/89

    It's just a case of changing the USB ID.

    ReplyDelete