sane-desc: add support for udev's hwdb

udev now comes with a hardware database (hwdb) which is meant to replace large
rule files as the one typically shipped with sane. This should significantly
speed up the processing of usb add events.

Add the required output format and add a special udev output mode which is
produces the udev file to be used with hwdb.

Sample hwdb file: <https://dev.archlinux.org/~tomegun/20-sane.hwdb>.
Sample udev+hwdb rules file:
                       <https://dev.archlinux.org/~tomegun/53-sane.rules>.

Similar support was recently added to gphoto2:
                            <http://sourceforge.net/p/gphoto/code/14490/>.

The new udev rules file does not support old udev/kernels as these anyway
don't support hwdb.

Moreover, it does not come with GROUP=/MODE= or ACL support as this can easily
be done externally by hooking into the libsane_matched envvar. In particular
systemd-logind uses this to do its own ACL handling.
merge-requests/1/head
Tom Gundersen 2013-07-18 01:27:33 +02:00 zatwierdzone przez Stphane Voltz
rodzic 234d6f1320
commit 3087a5efb5
5 zmienionych plików z 3025 dodań i 3 usunięć

Wyświetl plik

@ -24,7 +24,7 @@ check: check.local
check.local:
@echo "**** Testing $(SANEDESC) with $(TESTFILE)"
@for mode in ascii html-backends-split html-mfgs xml statistics usermap db udev udev+acl plist hal hal-new; \
@for mode in ascii html-backends-split html-mfgs xml statistics usermap db udev udev+acl udev+hwdb hwdb plist hal hal-new; \
do \
echo "PASS: sane-desc -m $$mode"; \
$(SANEDESC) -m $$mode -s data >$$mode.res ;\

Wyświetl plik

@ -422,7 +422,7 @@ check: check.local
check.local:
@echo "**** Testing $(SANEDESC) with $(TESTFILE)"
@for mode in ascii html-backends-split html-mfgs xml statistics usermap db udev udev+acl plist hal hal-new; \
@for mode in ascii html-backends-split html-mfgs xml statistics usermap db udev udev+acl udev+hwdb hwdb plist hal hal-new; \
do \
echo "PASS: $(SANEDESC) -m $$mode"; \
$(SANEDESC) -m $$mode -s data >$$mode.res ;\

Plik diff jest za duży Load Diff

Wyświetl plik

@ -0,0 +1,76 @@
# This file was automatically created based on description files (*.desc)
# by sane-desc 3.5 from sane-backends 1.0.24git on Thu Aug 1 18:50:15 2013
#
# udev rules file for supported USB and SCSI devices
#
# For the list of supported USB devices see /usr/lib/udev/hwdb.d/20-sane.hwdb
#
# The SCSI device support is very basic and includes only
# scanners that mark themselves as type "scanner" or
# SCSI-scanners from HP and other vendors that are entitled "processor"
# but are treated accordingly.
#
# If your SCSI scanner isn't listed below, you can add it to a new rules
# file under /etc/udev/rules.d/.
#
# If your scanner is supported by some external backend (brother, epkowa,
# hpaio, etc) please ask the author of the backend to provide proper
# device detection support for your OS
#
# If the scanner is supported by sane-backends, please mail the entry to
# the sane-devel mailing list (sane-devel@lists.alioth.debian.org).
#
ACTION!="add", GOTO="libsane_rules_end"
# The following rule will disable USB autosuspend for the device
ENV{DEVTYPE}=="usb_device", ENV{libsane_matched}=="yes", TEST=="power/control", ATTR{power/control}="on"
SUBSYSTEMS!="scsi", GOTO="libsane_rules_end"
KERNEL!="sg[0-9]*", GOTO="libsane_rules_end"
# Generic: SCSI device type 6 indicates a scanner
ATTRS{type}=="6", ENV{libsane_matched}="yes"
# Some scanners advertise themselves as SCSI device type 3
# Wildcard: for some Epson SCSI scanners
ATTRS{type}=="3", ATTRS{vendor}=="EPSON", ATTRS{model}=="SCANNER*", ENV{libsane_matched}="yes"
# Epson Perfection 2450 | Epson Perfection 2450 PHOTO
ATTRS{type}=="3", ATTRS{vendor}=="EPSON", ATTRS{model}=="GT-9700", ENV{libsane_matched}="yes"
# Epson Perfection 3200 | Epson Perfection 3200 PHOTO
ATTRS{type}=="3", ATTRS{vendor}=="EPSON", ATTRS{model}=="GT-9800", ENV{libsane_matched}="yes"
# Epson Perfection 636S | Epson Perfection 1200S
ATTRS{type}=="3", ATTRS{vendor}=="EPSON", ATTRS{model}=="Perfection1200", ENV{libsane_matched}="yes"
# Epson Perfection 636
ATTRS{type}=="3", ATTRS{vendor}=="EPSON", ATTRS{model}=="Perfection636", ENV{libsane_matched}="yes"
# Hewlett-Packard ScanJet 4p
ATTRS{type}=="3", ATTRS{vendor}=="HP", ATTRS{model}=="C1130A", ENV{libsane_matched}="yes"
# Hewlett-Packard ScanJet IIc
ATTRS{type}=="3", ATTRS{vendor}=="HP", ATTRS{model}=="C1750A", ENV{libsane_matched}="yes"
# Hewlett-Packard ScanJet IIp
ATTRS{type}=="3", ATTRS{vendor}=="HP", ATTRS{model}=="C1790A", ENV{libsane_matched}="yes"
# Hewlett-Packard ScanJet IIcx
ATTRS{type}=="3", ATTRS{vendor}=="HP", ATTRS{model}=="C2500A", ENV{libsane_matched}="yes"
# Hewlett-Packard ScanJet 4c
ATTRS{type}=="3", ATTRS{vendor}=="HP", ATTRS{model}=="C2520A", ENV{libsane_matched}="yes"
# Hewlett-Packard ScanJet 5p
ATTRS{type}=="3", ATTRS{vendor}=="HP", ATTRS{model}=="C5110A", ENV{libsane_matched}="yes"
# Hewlett-Packard ScanJet 6200C
ATTRS{type}=="3", ATTRS{vendor}=="HP", ATTRS{model}=="C6270A", ENV{libsane_matched}="yes"
# Hewlett-Packard ScanJet 6300C
ATTRS{type}=="3", ATTRS{vendor}=="HP", ATTRS{model}=="C7670A", ENV{libsane_matched}="yes"
LABEL="libsane_rules_end"

Wyświetl plik

@ -81,6 +81,8 @@ typedef enum output_mode
output_mode_db,
output_mode_udev,
output_mode_udevacl,
output_mode_udevhwdb,
output_mode_hwdb,
output_mode_plist,
output_mode_hal,
output_mode_halnew
@ -317,7 +319,7 @@ print_usage (char *program_name)
"(multiple directories can be concatenated by \":\")\n");
printf (" -m|--mode mode "
"Output mode (ascii, html-backends-split, html-mfgs,\n"
" xml, statistics, usermap, db, udev, udev+acl, plist, hal, hal-new)\n");
" xml, statistics, usermap, db, udev, udev+acl, udev+hwdb, hwdb, plist, hal, hal-new)\n");
printf (" -t|--title \"title\" The title used for HTML pages\n");
printf (" -i|--intro \"intro\" A short description of the "
"contents of the page\n");
@ -419,6 +421,16 @@ get_options (int argc, char **argv)
DBG_INFO ("Output mode: %s\n", optarg);
mode = output_mode_udevacl;
}
else if (strcmp (optarg, "udev+hwdb") == 0)
{
DBG_INFO ("Output mode: %s\n", optarg);
mode = output_mode_udevhwdb;
}
else if (strcmp (optarg, "hwdb") == 0)
{
DBG_INFO ("Output mode: %s\n", optarg);
mode = output_mode_hwdb;
}
else if (strcmp (optarg, "plist") == 0)
{
DBG_INFO ("Output mode: %s\n", optarg);
@ -3635,6 +3647,198 @@ print_udev (void)
printf ("\nLABEL=\"libsane_rules_end\"\n");
}
/* print libsane.rules for Linux udev */
static void
print_udevhwdb_header (void)
{
time_t current_time = time (0);
printf ("# This file was automatically created based on description files (*.desc)\n"
"# by sane-desc %s from %s on %s",
SANE_DESC_VERSION, PACKAGE_STRING, asctime (localtime (&current_time)));
printf
("#\n"
"# udev rules file for supported USB and SCSI devices\n"
"#\n"
"# For the list of supported USB devices see /usr/lib/udev/hwdb.d/20-sane.hwdb\n"
"# \n"
"# The SCSI device support is very basic and includes only\n"
"# scanners that mark themselves as type \"scanner\" or\n"
"# SCSI-scanners from HP and other vendors that are entitled \"processor\"\n"
"# but are treated accordingly.\n"
"#\n");
printf
("# If your SCSI scanner isn't listed below, you can add it to a new rules\n"
"# file under /etc/udev/rules.d/.\n"
"#\n"
"# If your scanner is supported by some external backend (brother, epkowa,\n"
"# hpaio, etc) please ask the author of the backend to provide proper\n"
"# device detection support for your OS\n"
"#\n"
"# If the scanner is supported by sane-backends, please mail the entry to\n"
"# the sane-devel mailing list (sane-devel@lists.alioth.debian.org).\n"
"#\n"
);
}
static void
print_udevhwdb (void)
{
scsiid_type *scsiid = create_scsiids_table ();
int i;
print_udevhwdb_header ();
printf("ACTION!=\"add\", GOTO=\"libsane_rules_end\"\n\n");
printf("# The following rule will disable USB autosuspend for the device\n");
printf("ENV{DEVTYPE}==\"usb_device\", ENV{libsane_matched}==\"yes\", TEST==\"power/control\", ATTR{power/control}=\"on\"\n\n");
printf ("SUBSYSTEMS!=\"scsi\", GOTO=\"libsane_rules_end\"\n");
printf ("KERNEL!=\"sg[0-9]*\", GOTO=\"libsane_rules_end\"\n\n");
printf ("# Generic: SCSI device type 6 indicates a scanner\n");
printf ("ATTRS{type}==\"6\", ENV{libsane_matched}=\"yes\"\n\n");
printf ("# Some scanners advertise themselves as SCSI device type 3\n\n");
printf ("# Wildcard: for some Epson SCSI scanners\n");
printf ("ATTRS{type}==\"3\", ATTRS{vendor}==\"EPSON\", ATTRS{model}==\"SCANNER*\", ENV{libsane_matched}=\"yes\"\n\n");
while (scsiid)
{
manufacturer_model_type * name = scsiid->name;
if (!scsiid->is_processor)
{
scsiid = scsiid->next;
continue;
}
/* Wildcard for Epson scanners: vendor = EPSON, product = SCANNER* */
if ((strcmp(scsiid->scsi_vendor_id, "EPSON") == 0)
&& (strncmp(scsiid->scsi_product_id, "SCANNER", 7) == 0))
{
scsiid = scsiid->next;
continue;
}
i = 0;
printf ("# ");
while (name)
{
if ((name != scsiid->name) && (i > 0))
printf (" | ");
printf ("%s", name->name);
name = name->next;
i++;
/*
* Limit the number of model names on the same line to 3,
* as udev cannot handle very long lines and prints a warning
* message while loading the rules files.
*/
if ((i == 3) && (name != NULL))
{
printf("\n# ");
i = 0;
}
}
printf ("\n");
printf ("ATTRS{type}==\"3\", ATTRS{vendor}==\"%s\", ATTRS{model}==\"%s\", ENV{libsane_matched}=\"yes\"\n\n",
scsiid->scsi_vendor_id, scsiid->scsi_product_id);
scsiid = scsiid->next;
}
printf ("\nLABEL=\"libsane_rules_end\"\n");
}
/* print /usr/lib/udev/hwdb.d/20-sane.conf for Linux hwdb */
static void
print_hwdb_header (void)
{
time_t current_time = time (0);
printf ("# This file was automatically created based on description files (*.desc)\n"
"# by sane-desc %s from %s on %s",
SANE_DESC_VERSION, PACKAGE_STRING, asctime (localtime (&current_time)));
printf
("#\n"
"# hwdb file for supported USB devices\n"
"#\n");
printf
("# If your scanner isn't listed below, you can add it to a new hwdb file\n"
"# under /etc/udev/hwdb.d/.\n"
"#\n"
"# If your scanner is supported by some external backend (brother, epkowa,\n"
"# hpaio, etc) please ask the author of the backend to provide proper\n"
"# device detection support for your OS\n"
"#\n"
"# If the scanner is supported by sane-backends, please mail the entry to\n"
"# the sane-devel mailing list (sane-devel@lists.alioth.debian.org).\n"
"#\n"
);
}
static void
print_hwdb (void)
{
usbid_type *usbid = create_usbids_table ();
char *vendor_id;
char *product_id;
int i,j;
print_hwdb_header ();
while (usbid)
{
manufacturer_model_type * name = usbid->name;
i = 0;
printf ("# ");
while (name)
{
if ((name != usbid->name) && (i > 0))
printf (" | ");
printf ("%s", name->name);
name = name->next;
i++;
/*
* Limit the number of model names on the same line to 3,
* as udev cannot handle very long lines and prints a warning
* message while loading the rules files.
*/
if ((i == 3) && (name != NULL))
{
printf("\n# ");
i = 0;
}
}
printf ("\n");
vendor_id = strdup(usbid->usb_vendor_id + 2);
product_id = strdup(usbid->usb_product_id + 2);
for(j = 0; j < 4; j++) {
vendor_id[j] = toupper(vendor_id[j]);
product_id[j] = toupper(vendor_id[j]);
}
printf ("usb:v%sp%s*\n libsane_matched=yes\n\n",
vendor_id, product_id);
free(vendor_id);
free(product_id);
usbid = usbid->next;
}
}
static void
print_plist (void)
{
@ -3827,6 +4031,12 @@ main (int argc, char **argv)
case output_mode_udevacl:
print_udev ();
break;
case output_mode_udevhwdb:
print_udevhwdb ();
break;
case output_mode_hwdb:
print_hwdb ();
break;
case output_mode_plist:
print_plist ();
break;