From e9e835c93f5343b3808af8e4a8c47c13aaf47315 Mon Sep 17 00:00:00 2001 From: Kai Wang Date: Mon, 22 Oct 2012 17:52:21 +0000 Subject: [PATCH] Add command line option "-U" and config file option "forced_attach". If "-U" or "forced_attach" is set, the uhidd daemon will force attaching the interface even if a kernel driver is actively attached or uhidd fails to detach the kernel driver. --- uhidd/lex.l | 1 + uhidd/parser.y | 25 +++++++++++++++++++++++++ uhidd/uhidd.c | 17 +++++++++++++++-- uhidd/uhidd.h | 2 ++ 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/uhidd/lex.l b/uhidd/lex.l index 22e8286..d1a5dc6 100644 --- a/uhidd/lex.l +++ b/uhidd/lex.l @@ -56,6 +56,7 @@ cc_attach { return (T_CC_ATTACH); } cc_keymap { return (T_CC_KEYMAP); } hidaction { return (T_HIDACTION); } detach_kernel_driver { return (T_DETACHKERNELDRIVER); } +forced_attach { return (T_FORCED_ATTACH); } 0x[0-9a-fA-F]+ { yylval.val = strtoul(yytext, NULL, 16); diff --git a/uhidd/parser.y b/uhidd/parser.y index 4762434..efc9fa4 100644 --- a/uhidd/parser.y +++ b/uhidd/parser.y @@ -66,6 +66,7 @@ static struct device_config dconfig, *dconfig_p; %token T_CC_KEYMAP %token T_HIDACTION %token T_DETACHKERNELDRIVER +%token T_FORCED_ATTACH %token T_NUM %token T_HEX %token T_USAGE @@ -149,6 +150,7 @@ conf_entry | vhid_devname | hidaction | detach_kernel_driver + | forced_attach ; mouse_attach @@ -229,6 +231,15 @@ detach_kernel_driver dconfig.detach_kernel_driver = -1; } +forced_attach + : T_FORCED_ATTACH "=" T_YES { + dconfig.forced_attach = 1; + } + | T_FORCED_ATTACH "=" T_NO { + dconfig.forced_attach = -1; + } + + hidaction : T_HIDACTION "=" "{" hidaction_entry_list "}" ; @@ -447,3 +458,17 @@ config_detach_kernel_driver(struct hid_interface *hi) return (uconfig.gconfig.detach_kernel_driver); } + +int +config_forced_attach(struct hid_interface *hi) +{ + struct device_config *dc; + + dc = config_find_device(hi->vendor_id, hi->product_id, hi->ndx); + if (dc != NULL && dc->forced_attach) + return (dc->forced_attach); + if (clconfig.forced_attach) + return (clconfig.forced_attach); + + return (uconfig.gconfig.forced_attach); +} diff --git a/uhidd/uhidd.c b/uhidd/uhidd.c index 2516a4b..d5d7034 100644 --- a/uhidd/uhidd.c +++ b/uhidd/uhidd.c @@ -83,7 +83,7 @@ main(int argc, char **argv) eval = 0; - while ((opt = getopt(argc, argv, "c:dDhH:kmosuVv")) != -1) { + while ((opt = getopt(argc, argv, "c:dDhH:kmosuUvV")) != -1) { switch(opt) { case 'c': config_file = optarg; @@ -116,6 +116,9 @@ main(int argc, char **argv) case 'u': clconfig.detach_kernel_driver = 1; break; + case 'U': + clconfig.forced_attach = 1; + break; case 'v': detach = 0; verbose++; @@ -524,13 +527,23 @@ hid_handle_kernel_driver(struct hid_parser *hp) PRINT1("Unable to detach kernel driver: " "libusb20_dev_detach_kernel_driver " "failed\n"); + if (config_forced_attach(hi) > 0) { + PRINT1("Continue anyway\n"); + return (0); + } return (-1); } else PRINT1("kernel driver detached!\n"); } else { + if (config_forced_attach(hi) > 0) { + PRINT1("Continue anyway\n"); + return (0); + } PRINT1("Abort attach since kernel driver is active\n"); PRINT1("Please try running uhidd with option '-u' to " "detach the kernel drivers\n"); + PRINT1("or specify option '-U' to force attaching the" + " interface\n") return (-1); } } @@ -759,7 +772,7 @@ usage(void) { fprintf(stderr, "usage: uhidd [-c config_file] [-H devname] " - "[-dhkmosuvV] /dev/ugen%%u.%%u\n"); + "[-dDhkmosuUvV] /dev/ugen%%u.%%u\n"); exit(1); } diff --git a/uhidd/uhidd.h b/uhidd/uhidd.h index 87d2d3d..1fd03d0 100644 --- a/uhidd/uhidd.h +++ b/uhidd/uhidd.h @@ -182,6 +182,7 @@ struct device_config { int detach_kernel_driver; int vhid_strip_id; char *vhid_devname; + int forced_attach; STAILQ_HEAD(, hidaction_config) haclist; STAILQ_ENTRY(device_config) next; }; @@ -319,6 +320,7 @@ int config_read_file(void); int config_vhid_strip_id(struct hid_interface *); char *config_vhid_devname(struct hid_interface *); int config_detach_kernel_driver(struct hid_interface *); +int config_forced_attach(struct hid_interface *); void find_hidaction(struct hid_appcol *); void run_hidaction(struct hid_appcol *, struct hid_report *); int ucuse_init(void);