Kernel Driver Hack: Add Blacklist for some printers to usblp

Since most modern Linux distributions (included Debian Wheezy/Sid) are already blacklist the "usblp" kernel driver as it disturbs the CUPS (Common UNIX Printing System) which now talks to USB printers directly.
Despite, there are some drivers still require to talk to the USB printers through the usblp, such as Canon CAPT Driver which the installation instructions could be found at https://help.ubuntu.com/community/CanonCaptDrv190.

For the situation that only one printer requires the usblp, therefore, just remove the usblp from kernel modules blacklist may enough but in the more complicated situations that you need to setup more than one printer and you should disable the registration of usblp for those printers to work properly or even those printers have to pass to the KVM guest with the USB Passthrough, it's a nightmare as the usblp will register every USB printers automatically and no solution to disable (blacklist) some printers yet.

Hence, I have reviewed the usblp code and found that it's not much complicate to understand and I think it not suffers me if I try to hack. Let's start.

I have prepared the patch which could apply to the Linux 2.6.32, since it's the current stable kernel for Debian Squeeze that I use as the Internet and printer server. I think it could be refreshed if needs to apply to the newer kernel.

Install linux source and headers

# apt-get install linux-source-2.6.32 linux-headers-2.6.32-5-amd64

Extract source

$ mkdir ~/linux-build
$ cd ~/linux-build
$ tar xvjf /usr/src/linux-source-2.6.32.tar.bz2

Get driver patch and patch to the source tree

$ wget http://www.neutron.in.th/sites/neutron.in.th/files/usblp-blacklist.patch
$ cd linux-source-2.6.32
$ patch -p0 < ~/linux-build/usblp-blacklist.patch
patching file drivers/usb/class/usblp.c

Create custom makefile ~/linux-build/linux-source-2.6.32/drivers/usb/class/Makefile.custom

KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

defult:
	$(MAKE) -C$(KDIR) SUBDIRS=$(PWD) modules
clean:
	$(MAKE) -C$(KDIR) SUBDIRS=$(PWD) clean

Make the module and install

$ cd drivers/usb/class
$ make -f Makefile.custom clean
$ make -f Makefile.custom
$ sudo cp usblp.ko /lib/modules/`uname -r`/kernel/drivers/usb/class/

It's time to test

# modprobe usblp blacklist="0x04f9,0x003f;0x04b8"
# dmesg | grep usblp
[642291.856603] usblp: Add to blacklist - vid: 0x04F9 pid 0x003F
[642291.856605] usblp: Add to blacklist - vid: 0x04B8 pid 0x0000
[642291.856711] usblp: vid: 0x04F9 pid: 0x003F is in blacklist
[642291.858408] usblp1: USB Bidirectional printer dev 95 if 0 alt 0 proto 2 vid 0x04A9 pid 0x26DA
[642291.858418] usbcore: registered new interface driver usblp
[642809.214397] usb 1-1.2.2: usbfs: interface 0 claimed by usblp while 'usb' sets config #1
[648634.230517] usblp: vid: 0x04B8 pid: 0x001B is in blacklist

As we can see now, the blacklist printers would not be registered with usblp at all. Only those not in blacklist registered properly with usblp as usblp1.

*** Note: If the usblp is in the module blacklist (Debian Wheezy/Sid), should be removed from blacklist first

$ sed -i "s/^blacklist/#blacklist/g" /etc/modprobe.d/blacklist-cups-usblp.conf

Finally, we could add the blacklist options permanently

# echo 'options usblp blacklist="0x04f9,0x003f;0x04b8"' > /etc/modprobe.d/usblp-blacklist.conf
# modprobe -r usblp
# modprobe usblp

That's it.
Happy Hacking :P