kopia lustrzana https://gitlab.com/sane-project/backends
Add a new :scsi keyword for SCSI devices, add support for SCSI devices
in the udev and HAL FDI outputs.merge-requests/1/head
rodzic
e91b604df7
commit
acc2b0fccf
|
@ -2,7 +2,9 @@
|
|||
* tools/sane-desc.c: replace opencoded device permissions and
|
||||
ownership by proper definitions. Group USB devices by vendor in
|
||||
the HAL FDI output. Replace obsolete SYSFS{} key by the newer
|
||||
ATTR{} key in the udev output.
|
||||
ATTR{} key in the udev output. Add a new :scsi keyword for SCSI
|
||||
devices, add support for SCSI devices in the udev and HAL FDI
|
||||
outputs.
|
||||
All of the above based on a patch contributed by Dieter Jurzitza.
|
||||
|
||||
2009-01-10 m. allan noah <kitno455 a t gmail d o t com>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
Copyright (C) 2002-2006 Henning Meier-Geinitz <henning@meier-geinitz.de>
|
||||
Copyright (C) 2004 Jose Gato <jgato@gsyc.escet.urjc.es> (XML output)
|
||||
Copyright (C) 2006 Mattias Ellert <mattias.ellert@tsl.uu.se> (plist output)
|
||||
Copyright (C) 2009 Dr. Ing. Dieter Jurzitza <dieter.jurzitza@t-online.de>
|
||||
|
||||
This file is part of the SANE package.
|
||||
|
||||
|
@ -23,18 +24,6 @@
|
|||
MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#define SANE_DESC_VERSION "3.3"
|
||||
|
||||
#define MAN_PAGE_LINK "http://www.sane-project.org/man/%s.5.html"
|
||||
#define COLOR_MINIMAL "\"#B00000\""
|
||||
#define COLOR_BASIC "\"#FF9000\""
|
||||
#define COLOR_GOOD "\"#90B000\""
|
||||
#define COLOR_COMPLETE "\"#007000\""
|
||||
#define COLOR_UNTESTED "\"#0000B0\""
|
||||
#define COLOR_UNSUPPORTED "\"#F00000\""
|
||||
#define COLOR_NEW "\"#F00000\""
|
||||
#define COLOR_UNKNOWN "\"#000000\""
|
||||
|
||||
#include <../include/sane/config.h>
|
||||
|
||||
#include <getopt.h>
|
||||
|
@ -55,8 +44,20 @@
|
|||
#include "../include/sane/sanei.h"
|
||||
#include "../include/sane/sanei_config.h"
|
||||
|
||||
#define DEVMODE "0664"
|
||||
#define DEVOWNER "root"
|
||||
#define SANE_DESC_VERSION "3.5"
|
||||
|
||||
#define MAN_PAGE_LINK "http://www.sane-project.org/man/%s.5.html"
|
||||
#define COLOR_MINIMAL "\"#B00000\""
|
||||
#define COLOR_BASIC "\"#FF9000\""
|
||||
#define COLOR_GOOD "\"#90B000\""
|
||||
#define COLOR_COMPLETE "\"#007000\""
|
||||
#define COLOR_UNTESTED "\"#0000B0\""
|
||||
#define COLOR_UNSUPPORTED "\"#F00000\""
|
||||
#define COLOR_NEW "\"#F00000\""
|
||||
#define COLOR_UNKNOWN "\"#000000\""
|
||||
|
||||
#define DEVMODE "0664"
|
||||
#define DEVOWNER "root"
|
||||
#define DEVGROUP "scanner"
|
||||
|
||||
#ifndef PATH_MAX
|
||||
|
@ -68,7 +69,6 @@
|
|||
#define DBG_INFO current_debug_level = 2; debug_call
|
||||
#define DBG_DBG current_debug_level = 3; debug_call
|
||||
|
||||
|
||||
typedef enum output_mode
|
||||
{
|
||||
output_mode_ascii = 0,
|
||||
|
@ -90,7 +90,8 @@ typedef enum parameter_type
|
|||
{
|
||||
param_none = 0,
|
||||
param_string,
|
||||
param_two_strings
|
||||
param_two_strings,
|
||||
param_three_strings
|
||||
}
|
||||
parameter_type;
|
||||
|
||||
|
@ -144,6 +145,9 @@ typedef struct model_entry
|
|||
char *usb_vendor_id;
|
||||
char *usb_product_id;
|
||||
SANE_Bool ignore_usb_id;
|
||||
char *scsi_vendor_id;
|
||||
char *scsi_product_id;
|
||||
SANE_Bool scsi_is_processor;
|
||||
}
|
||||
model_entry;
|
||||
|
||||
|
@ -198,6 +202,9 @@ typedef struct model_record_entry
|
|||
enum status_entry status;
|
||||
char *usb_vendor_id;
|
||||
char *usb_product_id;
|
||||
char *scsi_vendor_id;
|
||||
char *scsi_product_id;
|
||||
SANE_Bool scsi_is_processor;
|
||||
struct backend_entry *be;
|
||||
}
|
||||
model_record_entry;
|
||||
|
@ -231,6 +238,16 @@ typedef struct usbid_type
|
|||
}
|
||||
usbid_type;
|
||||
|
||||
typedef struct scsiid_type
|
||||
{
|
||||
struct scsiid_type * next;
|
||||
char *scsi_vendor_id;
|
||||
char *scsi_product_id;
|
||||
SANE_Bool is_processor;
|
||||
struct manufacturer_model_type *name;
|
||||
}
|
||||
scsiid_type;
|
||||
|
||||
static char *program_name;
|
||||
static int debug = 0;
|
||||
static int current_debug_level = 0;
|
||||
|
@ -253,6 +270,7 @@ static const char *status_color[] =
|
|||
{COLOR_UNKNOWN, COLOR_UNSUPPORTED, COLOR_UNTESTED, COLOR_MINIMAL,
|
||||
COLOR_BASIC, COLOR_GOOD, COLOR_COMPLETE};
|
||||
|
||||
|
||||
static void
|
||||
debug_call (const char *fmt, ...)
|
||||
{
|
||||
|
@ -654,6 +672,56 @@ read_keyword (SANE_String line, SANE_String keyword_token,
|
|||
* (SANE_String **) argument = strings;
|
||||
break;
|
||||
}
|
||||
case param_three_strings:
|
||||
{
|
||||
char *pos;
|
||||
char **strings = malloc (3 * sizeof (SANE_String));
|
||||
|
||||
cp = get_token (cp, &word);
|
||||
if (!word)
|
||||
{
|
||||
DBG_ERR ("read_keyword: missing quotation mark: %s\n", line);
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
/* remove escaped quotations */
|
||||
while ((pos = strstr (word, "\\\"")) != 0)
|
||||
*pos = ' ';
|
||||
DBG_INFO ("read_keyword: set first entry of `%s' to `%s'\n", keyword_token,
|
||||
word);
|
||||
strings[0] = strdup (word);
|
||||
if (word)
|
||||
free (word);
|
||||
|
||||
cp = get_token (cp, &word);
|
||||
if (!word)
|
||||
{
|
||||
DBG_ERR ("read_keyword: missing quotation mark: %s\n", line);
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
/* remove escaped quotations */
|
||||
while ((pos = strstr (word, "\\\"")) != 0)
|
||||
*pos = ' ';
|
||||
DBG_INFO ("read_keyword: set second entry of `%s' to `%s'\n", keyword_token,
|
||||
word);
|
||||
strings[1] = strdup (word);
|
||||
if (word)
|
||||
free (word);
|
||||
|
||||
cp = get_token (cp, &word);
|
||||
if (!word)
|
||||
{
|
||||
DBG_ERR ("read_keyword: missing quotation mark: %s\n", line);
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
/* remove escaped quotations */
|
||||
while ((pos = strstr (word, "\\\"")) != 0)
|
||||
*pos = ' ';
|
||||
DBG_INFO ("read_keyword: set third entry of `%s' to `%s'\n", keyword_token,
|
||||
word);
|
||||
strings[2] = strdup (word);
|
||||
* (SANE_String **) argument = strings;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
DBG_ERR ("read_keyword: unknown param_type %d\n", p_type);
|
||||
return SANE_STATUS_INVAL;
|
||||
|
@ -825,6 +893,7 @@ read_files (void)
|
|||
{
|
||||
char *string_entry = 0;
|
||||
char **two_string_entry;
|
||||
char **three_string_entry;
|
||||
word = 0;
|
||||
|
||||
cp = get_token (line, &word);
|
||||
|
@ -1279,6 +1348,39 @@ read_files (void)
|
|||
current_model->interface = string_entry;
|
||||
continue;
|
||||
}
|
||||
if (read_keyword
|
||||
(line, ":scsi", param_three_strings,
|
||||
&three_string_entry) == SANE_STATUS_GOOD)
|
||||
{
|
||||
if (!current_model)
|
||||
{
|
||||
DBG_WARN
|
||||
("ignored `%s' :scsi, only allowed for "
|
||||
"hardware devices\n", current_backend->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
DBG_INFO ("setting scsi vendor and product ids of model `%s' to `%s/%s'\n",
|
||||
current_model->name, three_string_entry[0], three_string_entry[1]);
|
||||
if (strcasecmp (three_string_entry[0], "ignore") == 0)
|
||||
{
|
||||
DBG_INFO ("Ignoring `%s's scsi-entries of `%s'\n",
|
||||
current_backend->name,
|
||||
current_model->name);
|
||||
continue;
|
||||
}
|
||||
if (strcasecmp (three_string_entry[2], "processor") == 0){
|
||||
current_model->scsi_is_processor = SANE_TRUE;
|
||||
current_model->scsi_vendor_id = three_string_entry[0];
|
||||
current_model->scsi_product_id = three_string_entry[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG_INFO ("scsi-format info in %s is invalid -> break\n", current_backend->name);
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (read_keyword
|
||||
(line, ":usbid", param_two_strings,
|
||||
&two_string_entry) == SANE_STATUS_GOOD)
|
||||
|
@ -1455,6 +1557,9 @@ create_model_record (model_entry * model)
|
|||
model_record->comment = model->comment;
|
||||
model_record->usb_vendor_id = model->usb_vendor_id;
|
||||
model_record->usb_product_id = model->usb_product_id;
|
||||
model_record->scsi_vendor_id = model->scsi_vendor_id;
|
||||
model_record->scsi_product_id = model->scsi_product_id;
|
||||
model_record->scsi_is_processor = model->scsi_is_processor;
|
||||
return model_record;
|
||||
}
|
||||
|
||||
|
@ -2939,6 +3044,25 @@ create_usbid (char *manufacturer, char *model,
|
|||
return usbid;
|
||||
}
|
||||
|
||||
static scsiid_type *
|
||||
create_scsiid (char *manufacturer, char *model,
|
||||
char *scsi_vendor_id, char *scsi_product_id, SANE_Bool is_processor)
|
||||
{
|
||||
scsiid_type * scsiid = calloc (1, sizeof (scsiid_type));
|
||||
|
||||
scsiid->scsi_vendor_id = strdup (scsi_vendor_id);
|
||||
scsiid->scsi_product_id = strdup (scsi_product_id);
|
||||
scsiid->is_processor = is_processor;
|
||||
scsiid->name = calloc (1, sizeof (manufacturer_model_type));
|
||||
scsiid->name->name = calloc (1, strlen (manufacturer) + strlen (model) + 3);
|
||||
sprintf (scsiid->name->name, "%s %s", manufacturer, model);
|
||||
scsiid->name->next = 0;
|
||||
scsiid->next = 0;
|
||||
DBG_DBG ("New SCSI ids: %s/%s (%s %s)\n", scsi_vendor_id, scsi_product_id,
|
||||
manufacturer, model);
|
||||
return scsiid;
|
||||
}
|
||||
|
||||
static usbid_type *
|
||||
add_usbid (usbid_type *first_usbid, char *manufacturer, char *model,
|
||||
char *usb_vendor_id, char *usb_product_id)
|
||||
|
@ -2992,6 +3116,59 @@ add_usbid (usbid_type *first_usbid, char *manufacturer, char *model,
|
|||
return first_usbid;
|
||||
}
|
||||
|
||||
static scsiid_type *
|
||||
add_scsiid (scsiid_type *first_scsiid, char *manufacturer, char *model,
|
||||
char *scsi_vendor_id, char *scsi_product_id, SANE_Bool is_processor)
|
||||
{
|
||||
scsiid_type *scsiid = first_scsiid;
|
||||
scsiid_type *prev_scsiid = 0, *tmp_scsiid = 0;
|
||||
|
||||
if (!first_scsiid)
|
||||
first_scsiid = create_scsiid (manufacturer, model, scsi_vendor_id, scsi_product_id, is_processor);
|
||||
else
|
||||
{
|
||||
while (scsiid)
|
||||
{
|
||||
if (strcmp (scsi_vendor_id, scsiid->scsi_vendor_id) == 0 &&
|
||||
strcmp (scsi_product_id, scsiid->scsi_product_id) == 0)
|
||||
{
|
||||
manufacturer_model_type *man_mod = scsiid->name;
|
||||
|
||||
while (man_mod->next)
|
||||
man_mod = man_mod->next;
|
||||
man_mod->next = malloc (sizeof (manufacturer_model_type));
|
||||
man_mod->next->name = malloc (strlen (manufacturer) + strlen (model) + 3);
|
||||
sprintf (man_mod->next->name, "%s %s", manufacturer, model);
|
||||
man_mod->next->next = 0;
|
||||
DBG_DBG ("Added manufacturer/model %s %s to SCSI ids %s/%s\n", manufacturer, model,
|
||||
scsi_vendor_id, scsi_product_id);
|
||||
break;
|
||||
}
|
||||
if (strcmp (scsi_vendor_id, scsiid->scsi_vendor_id) < 0 ||
|
||||
(strcmp (scsi_vendor_id, scsiid->scsi_vendor_id) == 0 &&
|
||||
strcmp (scsi_product_id, scsiid->scsi_product_id) < 0))
|
||||
{
|
||||
|
||||
tmp_scsiid = create_scsiid (manufacturer, model, scsi_vendor_id, scsi_product_id, is_processor);
|
||||
tmp_scsiid->next = scsiid;
|
||||
if (prev_scsiid)
|
||||
prev_scsiid->next = tmp_scsiid;
|
||||
else
|
||||
first_scsiid = tmp_scsiid;
|
||||
break;
|
||||
}
|
||||
prev_scsiid = scsiid;
|
||||
scsiid = scsiid->next;
|
||||
}
|
||||
if (!scsiid)
|
||||
{
|
||||
prev_scsiid->next = create_scsiid (manufacturer, model, scsi_vendor_id, scsi_product_id, is_processor);
|
||||
scsiid = prev_scsiid->next;
|
||||
}
|
||||
}
|
||||
return first_scsiid;
|
||||
}
|
||||
|
||||
static usbid_type *
|
||||
create_usbids_table (void)
|
||||
{
|
||||
|
@ -3040,6 +3217,55 @@ create_usbids_table (void)
|
|||
return first_usbid;
|
||||
}
|
||||
|
||||
static scsiid_type *
|
||||
create_scsiids_table (void)
|
||||
{
|
||||
backend_entry *be = first_backend;
|
||||
scsiid_type *first_scsiid = 0;
|
||||
|
||||
while (be)
|
||||
{
|
||||
type_entry *type = be->type;
|
||||
|
||||
while (type)
|
||||
{
|
||||
mfg_entry *mfg = type->mfg;
|
||||
model_entry *model;
|
||||
|
||||
if (!mfg)
|
||||
{
|
||||
type = type->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
mfg = type->mfg;
|
||||
while (mfg)
|
||||
{
|
||||
model = mfg->model;
|
||||
if (model)
|
||||
{
|
||||
while (model)
|
||||
{
|
||||
if (model->scsi_vendor_id && model->scsi_product_id)
|
||||
{
|
||||
first_scsiid = add_scsiid (first_scsiid, mfg->name,
|
||||
model->name,
|
||||
model->scsi_vendor_id,
|
||||
model->scsi_product_id,
|
||||
model->scsi_is_processor);
|
||||
}
|
||||
model = model->next;
|
||||
} /* while (model) */
|
||||
} /* if (model) */
|
||||
mfg = mfg->next;
|
||||
} /* while (mfg) */
|
||||
type = type->next;
|
||||
} /* while (type) */
|
||||
be = be->next;
|
||||
} /* while (be) */
|
||||
return first_scsiid;
|
||||
}
|
||||
|
||||
/* print USB usermap file to be used by the hotplug tools */
|
||||
static void
|
||||
print_usermap_header (void)
|
||||
|
@ -3167,10 +3393,16 @@ print_udev_header (void)
|
|||
|
||||
printf
|
||||
("#\n"
|
||||
"# udev rules file for supported USB devices\n"
|
||||
"# udev rules file for supported USB and SCSI devices\n"
|
||||
"#\n"
|
||||
"# To add a USB device, add a rule to the list below between the\n"
|
||||
"# LABEL=\"libsane_rules_begin\" and LABEL=\"libsane_rules_end\" lines.\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
|
||||
("# To add a USB device, add a rule to the list below between the\n"
|
||||
"# LABEL=\"libsane_usb_rules_begin\" and LABEL=\"libsane_usb_rules_end\" lines.\n"
|
||||
"#\n"
|
||||
"# To run a script when your device is plugged in, add RUN+=\"/path/to/script\"\n"
|
||||
"# to the appropriate rule.\n");
|
||||
|
@ -3186,13 +3418,15 @@ static void
|
|||
print_udev (void)
|
||||
{
|
||||
usbid_type *usbid = create_usbids_table ();
|
||||
scsiid_type *scsiid = create_scsiids_table ();
|
||||
int i;
|
||||
|
||||
print_udev_header ();
|
||||
printf("ACTION!=\"add\", GOTO=\"libsane_rules_end\"\n"
|
||||
"ENV{DEVTYPE}==\"usb_device\", GOTO=\"libsane_create_usb_dev\"\n"
|
||||
"SUBSYSTEM==\"usb_device\", GOTO=\"libsane_rules_begin\"\n"
|
||||
"SUBSYSTEM!=\"usb_device\", GOTO=\"libsane_rules_end\"\n"
|
||||
"SUBSYSTEMS==\"scsi\", GOTO=\"libsane_scsi_rules_begin\"\n"
|
||||
"SUBSYSTEM==\"usb_device\", GOTO=\"libsane_usb_rules_begin\"\n"
|
||||
"SUBSYSTEM!=\"usb_device\", GOTO=\"libsane_usb_rules_end\"\n"
|
||||
"\n");
|
||||
|
||||
printf("# Kernel >= 2.6.22 jumps here\n"
|
||||
|
@ -3206,7 +3440,7 @@ print_udev (void)
|
|||
"\n");
|
||||
|
||||
printf("# Kernel < 2.6.22 jumps here\n"
|
||||
"LABEL=\"libsane_rules_begin\"\n"
|
||||
"LABEL=\"libsane_usb_rules_begin\"\n"
|
||||
"\n");
|
||||
|
||||
while (usbid)
|
||||
|
@ -3244,7 +3478,51 @@ print_udev (void)
|
|||
printf("\n# The following rule will disable USB autosuspend for the device\n");
|
||||
printf("ENV{libsane_matched}==\"yes\", RUN+=\"/bin/sh -c 'test -e /sys/$env{DEVPATH}/power/level && echo on > /sys/$env{DEVPATH}/power/level'\"\n");
|
||||
|
||||
printf ("\nLABEL=\"libsane_rules_end\"\n");
|
||||
printf ("\nLABEL=\"libsane_usb_rules_end\"\n\n");
|
||||
|
||||
printf ("SUBSYSTEMS!=\"scsi\", GOTO=\"libsane_scsi_rules_end\"\n\n");
|
||||
printf ("LABEL=\"libsane_scsi_rules_begin\"\n");
|
||||
printf ("# Generic: SCSI device type 6 indicates a scanner\n");
|
||||
printf ("KERNEL==\"sg[0-9]*\", NAME=\"%%k\", ATTRS{type}==\"6\", MODE=\"%s\", GROUP=\"%s\"\n", DEVMODE, DEVGROUP);
|
||||
printf ("# Some scanners advertise themselves as SCSI device type 3\n");
|
||||
|
||||
while (scsiid)
|
||||
{
|
||||
manufacturer_model_type * name = scsiid->name;
|
||||
|
||||
if (!scsiid->is_processor)
|
||||
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 ("KERNEL==\"sg[0-9]*\", NAME=\"%%k\", ATTRS{type}==\"3\", ATTRS{vendor}==\"%s\", ATTRS{model}==\"%s\", MODE=\"%s\", GROUP=\"%s\"\n",
|
||||
scsiid->scsi_vendor_id, scsiid->scsi_product_id, DEVMODE, DEVGROUP);
|
||||
scsiid = scsiid->next;
|
||||
}
|
||||
printf ("LABEL=\"libsane_scsi_rules_end\"\n\n");
|
||||
|
||||
printf ("LABEL=\"libsane_rules_end\"\n");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -3287,11 +3565,61 @@ print_hal (int new)
|
|||
int i;
|
||||
SANE_Bool in_match;
|
||||
char *last_vendor;
|
||||
scsiid_type *scsiid = create_scsiids_table ();
|
||||
usbid_type *usbid = create_usbids_table ();
|
||||
|
||||
printf ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
|
||||
printf ("<deviceinfo version=\"0.2\">\n");
|
||||
printf (" <device>\n");
|
||||
printf (" <!-- SCSI-SUBSYSTEM -->\n");
|
||||
printf (" <match key=\"info.category\" string=\"scsi_generic\">\n");
|
||||
printf (" <!-- Some SCSI Scanners announce themselves \"processor\" -->\n");
|
||||
printf (" <match key=\"@info.parent:scsi.type\" string=\"processor\">\n");
|
||||
|
||||
last_vendor = "";
|
||||
in_match = SANE_FALSE;
|
||||
while (scsiid)
|
||||
{
|
||||
manufacturer_model_type * name = scsiid->name;
|
||||
|
||||
if (!scsiid->is_processor)
|
||||
{
|
||||
scsiid = scsiid->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(last_vendor, scsiid->scsi_vendor_id) != 0)
|
||||
{
|
||||
if (in_match)
|
||||
printf (" </match>\n");
|
||||
|
||||
printf (" <match key=\"@info.parent:scsi.vendor\" string=\"%s\">\n", scsiid->scsi_vendor_id);
|
||||
last_vendor = scsiid->scsi_vendor_id;
|
||||
in_match = SANE_TRUE;
|
||||
}
|
||||
|
||||
printf (" <!-- SCSI Scanner ");
|
||||
while (name)
|
||||
{
|
||||
if (name != scsiid->name)
|
||||
printf (" | ");
|
||||
printf ("\"%s\"", name->name);
|
||||
name = name->next;
|
||||
}
|
||||
printf (" -->\n");
|
||||
printf (" <match key=\"@info.parent:scsi.model\" string=\"%s\">\n", scsiid->scsi_product_id);
|
||||
printf (" <append key=\"info.capabilities\" type=\"strlist\">scanner</append>\n");
|
||||
printf (" </match>\n");
|
||||
|
||||
scsiid = scsiid->next;
|
||||
}
|
||||
|
||||
if (in_match)
|
||||
printf (" </match>\n");
|
||||
|
||||
printf (" </match>\n");
|
||||
printf (" </match>\n");
|
||||
printf (" <!-- USB-SUBSYSTEM -->\n");
|
||||
|
||||
if (new)
|
||||
printf (" <match key=\"info.subsystem\" string=\"usb\">\n");
|
||||
|
|
Ładowanie…
Reference in New Issue