The problem of scanning using USB multi-function printers in Linux (success at last)
July 29, 2015 1 Comment
After my investigations described in a couple of earlier posts ([1], [2]), I finally got Gentoo Linux to scan reliably via the USB connection to my Canon MP560 MFP (multi-function peripheral), a single USB device with three interfaces: scanner (Interface 0); printer (Interface 1); mass storage (Interface 2). Well, ninety-nine per cent reliably, if that isn’t a contradiction in terms. The formula for success? I had to do all the following:
- Stop the kernel from binding the
usb-storage
driver to the device. - Create a UDEV rule to modify the ACL (access control list) of the device to give both the ‘
lp
‘ and ‘scanner
‘ groups Read-Write access to the device. - Create a UDEV rule to: a) change the owner of the device from ‘
root
‘ to my user account (fitzcarraldo
); b) change the device’s group to ‘scanner
‘ instead of ‘lp
‘; c) give all users Read-Write access to the device (see my note about this at the end of this post). - Disable the SANE backend from accessing the MP560 via the network.
Let’s look in more detail at each of these …
Stop the kernel from binding the usb-storage
driver to the device
Originally I had built the usb-storage
driver into the kernel (CONFIG_USB_STORAGE=y
). During the course of my investigations into this problem I rebuilt the kernel with CONFIG_USB_STORAGE=m
, i.e. I rebuilt the driver as an external module, although it should not matter either way.
The vendor ID (04a9) and product ID (173e) of the MP560 can be found using the lsusb
command:
# lsusb | grep -i canon
Bus 001 Device 007: ID 04a9:173e Canon, Inc. MP560
If the usb-storage
driver is built as an external module, the kernel configuration file will include the following:
# grep CONFIG_USB_STORAGE= /usr/src/linux/.config
CONFIG_USB_STORAGE=m
In this case, it is possible to stop the driver binding to the USB storage interface in the MP560 by creating a ‘quirk’ in the file /etc/modprobe.d/usb-storage.conf
as shown below:
# cat /etc/modprobe.d/usb-storage.conf
options usb-storage quirks=04a9:173e:i
If the usb-storage
driver is built into the kernel, the kernel configuration file will include the following:
# grep CONFIG_USB_STORAGE= /usr/src/linux/.config
CONFIG_USB_STORAGE=y
In this case, it is possible to stop the driver binding to the USB storage interface in the MP560 by adding a ‘quirk’ (usb-storage.quirks=::i
) to the kernel boot line as shown below (ignore the rest of the parameters shown below, as yours are likely to be different):
# grep usb-storage /boot/grub/grub.cfg
linux /vmlinuz-3.18.11-gentoo root=/dev/sda5 ro drm_kms_helper.edid_firmware=edid/1920x1080_Clevo_W230SS.bin i915.modeset=1 rcutree.rcu_idle_gp_delay=1 usb-storage.quirks=04a9:173e:i
If you edit the file /boot/grub/grub.cfg
directly, the change will be lost if you rebuild or upgrade in future. The ‘proper’ way to add the quirk would be to add it to the list of kernel boot parameters in GRUB_CMDLINE_LINUX_DEFAULT
in the file /etc/default/grub
and regenerate grub.cfg
using the command ‘grub2-mkconfig -o /boot/grub/grub.cfg
‘.
Create a UDEV rules file to modify the device’s ACL
I created a UDEV rules file /etc/udev/rules.d/99-canon-mp560.rules
containing the following:
# ACL settings for Canon PIXMA MP560 printer MFP ATTR{idVendor}=="04a9", ATTR{idProduct}=="173e", GOTO="canon" GOTO="canon_end" LABEL="canon" RUN+="/bin/setfacl -m g:scanner:rw -m g:lp:rw $env{DEVNAME}" TEST=="/var/run/ConsoleKit/database", \ RUN+="udev-acl --action=$env{ACTION} --device=$env{DEVNAME}" LABEL="canon_end"
Create a UDEV rules file to change the owner, group and permissions of the device
The file 41-libsane.rules
in my installation is the only UDEV rules file in the directory /lib/udev/rules.d/
that explicitly mentions the MP560:
# grep 173e /lib/udev/rules.d/*
/lib/udev/rules.d/41-libsane.rules:ATTRS{idVendor}=="04a9", ATTRS{idProduct}=="173e", MODE="0664", GROUP="scanner", ENV{libsane_matched}="yes"
As the USB device was always in the ‘lp
‘ group (see the output of the ‘ls -la
‘ command [1]), the above UDEV rule was clearly being overridden by another rule, but which one in the long list of rules files created automatically when I installed the OS and various packages (see below)?
# ls -F1 /lib/udev/rules.d/
10-ft-rockey.rules
10-virtualbox.rules
40-gentoo.rules
40-usb-media-players.rules
41-libsane.rules
42-usb-hid-pm.rules
50-udev-default.rules
56-hpmud.rules
60-block.rules
60-cdrom_id.rules
60-drm.rules
60-evdev.rules
60-persistent-alsa.rules
60-persistent-input.rules
60-persistent-storage-tape.rules
60-persistent-storage.rules
60-persistent-v4l.rules
60-serial.rules
61-accelerometer.rules
64-btrfs.rules
69-cd-sensors.rules
70-libgphoto2.rules
70-mouse.rules
70-printers.rules
70-touchpad.rules
70-udev-acl.rules
75-net-description.rules
75-probe_mtd.rules
77-mm-cinterion-port-types.rules
77-mm-ericsson-mbm.rules
77-mm-huawei-net-port-types.rules
77-mm-longcheer-port-types.rules
77-mm-mtk-port-types.rules
77-mm-nokia-port-types.rules
77-mm-pcmcia-device-blacklist.rules
77-mm-platform-serial-whitelist.rules
77-mm-simtech-port-types.rules
77-mm-telit-port-types.rules
77-mm-usb-device-blacklist.rules
77-mm-usb-serial-adapters-greylist.rules
77-mm-x22x-port-types.rules
77-mm-zte-port-types.rules
77-nm-olpc-mesh.rules
78-sound-card.rules
80-drivers.rules
80-mm-candidate.rules
80-net-name-slot.rules
80-udisks2.rules
85-regulatory.rules
90-alsa-restore.rules
90-libgpod.rules
90-network.rules
90-pulseaudio.rules
95-cd-devices.rules
95-upower-battery-recall-dell.rules
95-upower-battery-recall-fujitsu.rules
95-upower-battery-recall-gateway.rules
95-upower-battery-recall-ibm.rules
95-upower-battery-recall-lenovo.rules
95-upower-battery-recall-toshiba.rules
95-upower-csr.rules
95-upower-hid.rules
95-upower-wup.rules
97-hid2hci.rules
99-fuse.rules
99-ntfs3g.rules
99-nvidia.rules
Anyway, I created a UDEV rules file /etc/udev/rules.d/95-libsane.rules
to change the owner of the MP560 USB device from ‘root
‘ to me (i.e. user name ‘fitzcarraldo
‘), to put the device in the ‘scanner
‘ group instead of the ‘lp
‘ group, and to give all users Read-Write permission for the device:
ATTRS{idVendor}=="04a9", ATTRS{idProduct}=="173e", MODE="0666", OWNER="fitzcarraldo", GROUP="scanner", ENV{libsane_matched}="yes"
So I now have two user-created UDEV rules files:
# ls /etc/udev/rules.d/
95-libsane.rules 99-canon-mp560.rules
Note that user-created UDEV rules files should be put in the directory /etc/udev/rules.d/
, not the directory /lib/udev/rules.d/
which is reserved for UDEV rules installed when you install the OS and by packages you install later. Unfortunately, there is no consistency in UDEV rules file names and their contents between Linux distributions, which makes debugging UDEV rules even more difficult. Higher numbered rules files override lower-numbered rules files.
I then switched off the MP560 and switched it on again. The two UDEV rules files I created had worked as intended. The ownership and group of the device had changed, and so had the permissions and ACL:
# ls -la /dev/bus/usb/001
total 0
drwxr-xr-x 2 root root 200 Jul 29 10:10 .
drwxr-xr-x 4 root root 80 Jul 29 09:56 ..
crw-rw-r-- 1 root usb 189, 0 Jul 29 11:25 001
crw-rw-r-- 1 root usb 189, 1 Jul 29 09:56 002
crw-rw-r-- 1 root usb 189, 2 Jul 29 11:25 003
crw-rw-r-- 1 root usb 189, 3 Jul 29 09:56 004
crw-rw-r-- 1 root usb 189, 4 Jul 29 11:25 005
crw-rw-r-- 1 root usb 189, 5 Jul 29 11:25 006
crw-rw-r-- 1 root usb 189, 7 Jul 29 11:25 008
crw-rw-rw-+ 1 fitzcarraldo scanner 189, 8 Jul 29 11:27 009
# getfacl /dev/bus/usb/001/009
getfacl: Removing leading '/' from absolute path names
# file: dev/bus/usb/001/009
# owner: fitzcarraldo
# group: scanner
user::rw-
user:fitzcarraldo:rw-
group::rw-
group:lp:rw-
group:scanner:rw-
mask::rw-
other::rw-
Disable the SANE backend from accessing the MP560 via the network
Although scanning via the USB connection sometimes still works if I have also specified a network connection in the file /etc/sane.d/pixma.conf
, apparently the two interfaces should not normally be enabled simultaneously. See the post [sane-devel] Pixma 530 series – tested and not working by SANE developer Rolf Bensch:
Please disconnect the scanner from network and try again. The backend
has problems if both network and USB are connected at once.
Therefore, to try using SANE to access the MP560 via USB, I disabled network access to the MP560 by commenting out the URI in the relevant SANE backend configuration file, which in the case of the MP560 is the file /etc/sane.d/pixma.conf
. I commented out the line ‘bjnp://192.168.1.78
‘ which I had previously inserted to enable me to scan via my home network because the USB connection was unreliable.
Trying to scan
I then checked if the USB-connected scanner is detected by SANE when running as root
user and when running under my user account:
# scanimage -L
device `pixma:04A9173E_1653C4' is a CANON Canon PIXMA MP560 multi-function peripheral
# sane-find-scanner -q
found USB scanner (vendor=0x04a9 [Canon], product=0x173e [MP560 series]) at libusb:001:010
# exit
exit
$ scanimage -L
device `pixma:04A9173E_1653C4' is a CANON Canon PIXMA MP560 multi-function peripheral
$ sane-find-scanner -q
found USB scanner (vendor=0x04a9 [Canon], product=0x173e [MP560 series]) at libusb:001:010
The test using the scanimage
command worked:
$ scanimage -d pixma:04A9173E_1653C4 -T
scanimage: scanning image of size 638x877 pixels at 24 bits/pixel
scanimage: acquiring RGB frame, 8 bits/sample
scanimage: reading one scanline, 1914 bytes... PASS
scanimage: reading one byte... PASS
scanimage: stepped read, 2 bytes... PASS
scanimage: stepped read, 4 bytes... PASS
scanimage: stepped read, 8 bytes... PASS
scanimage: stepped read, 16 bytes... PASS
scanimage: stepped read, 32 bytes... PASS
scanimage: stepped read, 64 bytes... PASS
scanimage: stepped read, 128 bytes... PASS
scanimage: stepped read, 256 bytes... PASS
scanimage: stepped read, 512 bytes... PASS
scanimage: stepped read, 1024 bytes... PASS
scanimage: stepped read, 2048 bytes... PASS
scanimage: stepped read, 2047 bytes... PASS
scanimage: stepped read, 1023 bytes... PASS
scanimage: stepped read, 511 bytes... PASS
scanimage: stepped read, 255 bytes... PASS
scanimage: stepped read, 127 bytes... PASS
scanimage: stepped read, 63 bytes... PASS
scanimage: stepped read, 31 bytes... PASS
scanimage: stepped read, 15 bytes... PASS
scanimage: stepped read, 7 bytes... PASS
scanimage: stepped read, 3 bytes... PASS
So I tried to scan an A4 page from the command line:
$ scanimage -d pixma:04A9173E_1653C4 -l 0 -t 0 -x 215 -y 297 --resolution 150 --mode Color | convert - scanned-page.png
That worked, so I launched XSane, one of the GUI scanner applications:
$ xsane
That also worked.
Sometimes either scanimage
or a GUI scanner application (XSane, gscan2pdf, Simple Scan or whatever) hangs, but, more often than not, scanning now works via the USB connection. However, if either scanimage
or a GUI scanner application hangs, I kill them, run them again and then they usually work.
Importantly, printing still works, even though I have changed the USB device group from ‘lp
‘ to ‘scanner
‘.
So I have satisfied my curiosity and managed to get the MP560 to scan when connected to my laptop via USB, even though it already worked fine when using a network connection instead.
A note on the version of SANE
For information, I currently have Version 1.0.25_pre20150725 (daily snapshot from 25 July 2015) of the package sane-backends
installed:
$ eix -I sane-backends
[I] media-gfx/sane-backends
Available versions: 1.0.24-r5 (~)1.0.25_pre20150628 (~)1.0.25_pre20150725[1] {avahi doc gphoto2 ipv6 snmp systemd threads usb v4l xinetd ABI_MIPS="n32 n64 o32" ABI_PPC="32 64" ABI_S390="32 64" ABI_X86="32 64 x32" SANE_BACKENDS="+abaton +agfafocus +apple +artec +artec_eplus48u +as6e +avision +bh +canon +canon630u +canon_dr -canon_pp +cardscan +coolscan +coolscan2 +coolscan3 +dc210 +dc240 +dc25 +dell1600n_net +dmc +epjitsu +epson +epson2 +fujitsu +genesys +gt68xx +hp +hp3500 +hp3900 +hp4200 +hp5400 +hp5590 +hpljm1005 -hpsj5s +hs2p +ibm +kodak +kodakaio +kvs1025 +kvs20xx kvs40xx +leo +lexmark +ma1509 +magicolor +matsushita +microtek +microtek2 +mustek -mustek_pp +mustek_usb mustek_usb2 +nec +net +niash +p5 +pie +pixma +plustek +plustek_pp -pnm +qcam +ricoh +rts8891 +s9036 +sceptre +sharp +sm3600 +sm3840 +snapscan +sp15c +st400 +stv680 +tamarack +teco1 +teco2 +teco3 +test +u12 +umax +umax1220u +umax_pp +xerox_mfp"}
Installed versions: 1.0.25_pre20150725[1](01:39:24 25/07/15)(avahi gphoto2 ipv6 usb v4l -doc -snmp -systemd -threads -xinetd ABI_MIPS="-n32 -n64 -o32" ABI_PPC="-32 -64" ABI_S390="-32 -64" ABI_X86="32 64 -x32" SANE_BACKENDS="abaton agfafocus apple artec artec_eplus48u as6e avision bh canon canon630u canon_dr cardscan coolscan coolscan2 coolscan3 dc210 dc240 dc25 dell1600n_net dmc epjitsu epson epson2 fujitsu genesys gt68xx hp hp3500 hp3900 hp4200 hp5400 hp5590 hpljm1005 hs2p ibm kodak kodakaio kvs1025 kvs20xx leo lexmark ma1509 magicolor matsushita microtek microtek2 mustek mustek_usb nec net niash p5 pie pixma plustek plustek_pp qcam ricoh rts8891 s9036 sceptre sharp sm3600 sm3840 snapscan sp15c st400 stv680 tamarack teco1 teco2 teco3 test u12 umax umax1220u umax_pp xerox_mfp -canon_pp -hpsj5s -kvs40xx -mustek_pp -mustek_usb2 -pnm")
Homepage: http://www.sane-project.org/
Description: Scanner Access Now Easy - Backends
[1] "local_overlay" /usr/local/portage
However, the same symptoms occurred with versions 1.0.24-r5, 1.0.25_pre20150628 and 1.0.25_pre20150725 of the sane-backends
package, so I believe the problem was not version-specific.
A note about scanning in Linux
An early developer’s Web site for the SANE pixma
backend has the following warning:
If you grant a group a full permission to access the scanner (by using udev, hotplug, resmgr etc.), every members in the group will have full access rights not only for the scanner part but also for the other parts of the device i.e. printer, memory-card reader and fax. These users can bypass your system’s security policy and do everything with the device intentionally and unintentionally.
It is all very well to say that, but it is the only way I could get the backend to work reliably (almost). And, judging by the number of people who posted on the Web that they had to do the same with other Linux distributions, other manufacturers and models of MFPs, this is a common requirement in order to get Linux to work with MFP scanners. It’s not impressive when people have to resort to this to get something to work.
Note that the success of the approach described in this post is dependent on the contents and order of all the UDEV rules files. Just because the rules files I have posted above work in my case does not guarantee they will work in your case too. It depends what rules files your installation already has, what are their precise contents and in what order they are. In my opinion this is not a good concept.
I stand by my comments in the Conclusion of my first post regarding this problem. To have to jump through so many hoops to be able to scan using Linux on a computer connected to a MFP via USB is ridiculous in my opinion. The fact that it works reliably via a network connection does not alter that. I have been ‘scratching an itch’ as I enjoy tinkering, but I feel sorry for users who just need something that works without having to mess around for hours or days.
Background
- The problem of scanning using USB multi-function printers in Linux
- The problem of scanning using USB multi-function printers in Linux (continued)
Addendum (7 October 2019): I have deleted the file /etc/udev/rules.d/99-canon-mp560.rules
I created in 2015, as both the printer and scanner in my Canon PIXMA MP560 can now function without it. Firstly, that rule required ConsoleKit, which I am no longer using. Secondly, apparently the Linux system software has changed since I made my blog post in 2015 and I think eudev and/or elogind, which I am currently using in Gentoo Linux, are managing ACLs now (see Tomasz Torcz’s 2012 blog post Linux automatic user ACL management), which I assume was not the case when I wrote this blog post in 2015. Although I do not use systemd (which incorporates udev and logind) in Gentoo Linux, I believe it manages ACLs as discussed in the aforementioned blog post by Tomasz Torcz.
Addendum (7 October 2019): If you use Gentoo Linux and are having trouble getting SANE to work with one of the Canon models listed below, you might find that Canon’s ScanGear MP driver and GUI work. The package is media-gfx/scangearmp2. For details see Gentoo Bugzilla Bug Report No. 663176 and Gentoo Forums – Canon G3110 Multifunction Printer Scanner Does Not Work.
E3100 series Product_ID 0x1828
E460 series Product_ID 0x1788
E470 series Product_ID 0x180C
E480 series Product_ID 0x1789
G3000 series Product_ID 0x1794
G3010 series Product_ID 0x183B
G4000 series Product_ID 0x181D
G4010 series Product_ID 0x183D
MB2000 series Product_ID 0x1778
MB2100 series Product_ID 0x1793
MB2300 series Product_ID 0x1779
MB2700 series Product_ID 0x1792
MB5000 series Product_ID 0x1776
MB5100 series Product_ID 0x1790
MB5300 series Product_ID 0x1777
MB5400 series Product_ID 0x178F
MG2900 series Product_ID 0x1780
MG3000 series Product_ID 0x180B
MG3600 series Product_ID 0x178A
MG5600 series Product_ID 0x177F
MG5700 series Product_ID 0x178E
MG6600 series Product_ID 0x177E
MG6800 series Product_ID 0x178D
MG6900 series Product_ID 0x178C
MG7500 series Product_ID 0x177C
MG7700 series Product_ID 0x178B
MX490 series Product_ID 0x1787
TR7500 series Product_ID 0x1824
TR7530 series Product_ID 0x1845
TR8500 series Product_ID 0x1823
TR8530 series Product_ID 0x1844
TR8580 series Product_ID 0x1841
TS3100 series Product_ID 0x1827
TS5000 series Product_ID 0x1802
TS5100 series Product_ID 0x1825
TS6000 series Product_ID 0x1801
TS6100 series Product_ID 0x1822
TS6130 series Product_ID 0x1843
TS6180 series Product_ID 0x1840
TS8000 series Product_ID 0x1800
TS8100 series Product_ID 0x1821
TS8130 series Product_ID 0x1842
TS8180 series Product_ID 0x183F
TS9000 series Product_ID 0x179F
TS9100 series Product_ID 0x1820
TS9180 series Product_ID 0x183E
XK50 series Product_ID 0x1846
XK70 series Product_ID 0x1847