Hacking the PL2303 driver
-------------------------

These are the simple steps to hack the pl2303 Linux driver to support
the SonyEricsson DCU-11 USB-to-Serial cable. In kernel 2.4.21, the pl2303
driver is updated to support many more pl2303 based cables, including
the SE DCU-11 cable, so no changes are needed there.

The cable is made by a company called Susteen, but is based on the pl2303
chip.

First of all, get the source to your kernel. You only need three files, but
you must extract them from the kernel source. Also, you need the kernel source,
or at least the header files, to be able to compile the module.

Make a directory somewhere and copy these three files:

linux-2.4.xx/drivers/usb/serial/usb-serial.h
linux-2.4.xx/drivers/usb/serial/pl2303.c
linux-2.4.xx/drivers/usb/serial/pl2303.h

In the file pl2303.h, add the following two lines

#define SUSTEEN_VENDOR_ID       0x0731
#define SUSTEEN_DCU11_PRODUCT_ID        0x0528

Then, in the file pl2303.c, there is a struct that looks like this:

static struct usb_device_id id_table [] = {
        { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) },
        { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) },
        { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
        { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
        { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) },
        { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) },
        { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) },
        { }                                     /* Terminating entry */
};

Add an entry for the DCU-11 cable, so the sctruct looks like this,
notice the new line, third from the end. Make sure you have the syntax
correct.

static struct usb_device_id id_table [] = {
        { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) },
        { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) },
        { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
        { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
        { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) },
        { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) },
        { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) },
        { USB_DEVICE(SUSTEEN_VENDOR_ID, SUSTEEN_DCU11_PRODUCT_ID) },
        { }                                     /* Terminating entry */
};

Now compile it. Here is a line that I copied from a kernel compilation.
It works on my machine.

gcc -Wstrict-prototypes -Wno-trigraphs -fomit-frame-pointer -fno-strict-aliasing \
-fno-common -D__KERNEL__ -DMODULE -DNOKERNEL -I/lib/modules/`uname -r`/build/include \
-O2  -Wall -Wstrict-prototypes -fomit-frame-pointer -pipe -DMODULE -D__KERNEL__ \
-DEXPORT_SYMTAB -DMODVERSIONS -c pl2303.c

You should now have a file in your current directory called pl2303.o.
Replace the old pl2303.o file somewhere in the /lib/modules/2.4.xx/ tree.
You should find it as
/lib/modules/2.4.xx/kernel/drivers/usb/serial/pl2303.o .

Finally, do a /sbin/depmod -a . Plug the cable into any usb port and watch
your syslog logfile for any messages. You should be able to access the
cable as /dev/ttyUSB0 (unless you already had devices that manifested itself
as /dev/ttyUSB -devices, in which case the cable will have another number.)

-Fredrik Srensson
