From owner-freebsd-bugs@FreeBSD.ORG Fri Sep 26 10:10:23 2003 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5E0A216A4B3 for ; Fri, 26 Sep 2003 10:10:23 -0700 (PDT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 989D044025 for ; Fri, 26 Sep 2003 10:10:14 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.9/8.12.9) with ESMTP id h8QHAEFY042197 for ; Fri, 26 Sep 2003 10:10:14 -0700 (PDT) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.9/8.12.9/Submit) id h8QHAEeW042196; Fri, 26 Sep 2003 10:10:14 -0700 (PDT) (envelope-from gnats) Resent-Date: Fri, 26 Sep 2003 10:10:14 -0700 (PDT) Resent-Message-Id: <200309261710.h8QHAEeW042196@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, walter@pelissero.de Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7001A16A4B3 for ; Fri, 26 Sep 2003 10:01:24 -0700 (PDT) Received: from webmail.tiscali.de (relay1.tiscali.de [62.26.116.129]) by mx1.FreeBSD.org (Postfix) with ESMTP id DA79143FDF for ; Fri, 26 Sep 2003 10:01:22 -0700 (PDT) (envelope-from walter@pelissero.de) Received: from daemon.home.loc (62.246.12.103) by webmail.tiscali.de (6.7.019) id 3F59F9DF007B92C3 for FreeBSD-gnats-submit@freebsd.org; Fri, 26 Sep 2003 19:01:22 +0200 Received: from hyde.home.loc (hyde.home.loc [10.0.0.2]) by daemon.home.loc (8.12.9/8.12.8) with ESMTP id h8QGlWP5000391 for ; Fri, 26 Sep 2003 18:47:32 +0200 (CEST) (envelope-from wcp@hyde.home.loc) Received: from hyde.home.loc (localhost [127.0.0.1]) by hyde.home.loc (8.12.9/8.12.8) with ESMTP id h8QGlU0o075830 for ; Fri, 26 Sep 2003 18:47:30 +0200 (CEST) (envelope-from wcp@hyde.home.loc) Received: (from wcp@localhost) by hyde.home.loc (8.12.9/8.12.6/Submit) id h8QGlU7E075829; Fri, 26 Sep 2003 18:47:30 +0200 (CEST) (envelope-from wcp) Message-Id: <200309261647.h8QGlU7E075829@hyde.home.loc> Date: Fri, 26 Sep 2003 18:47:30 +0200 (CEST) From: "Walter C. Pelissero" To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: bin/57255: usbd and multi-function devices X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: walter@pelissero.de List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 26 Sep 2003 17:10:23 -0000 >Number: 57255 >Category: bin >Synopsis: usbd and multi-function devices >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Fri Sep 26 10:10:14 PDT 2003 >Closed-Date: >Last-Modified: >Originator: Walter C. Pelissero >Release: FreeBSD 4.9-PRERELEASE i386 >Organization: >Environment: System: FreeBSD hyde.home.loc 4.9-PRERELEASE FreeBSD 4.9-PRERELEASE #3: Sun Sep 21 21:01:59 CEST 2003 root@hyde.home.loc:/.amd_mnt/daemon/host/usr/warehouse/src/sys/compile/PCG-XG9 i386 >Description: Usbd, as it is, lacks proper support for USB devices implementing multiple functionalities (docking stations and such). If the usbd behaviour was amended to execute all the entries in usbd.conf that match a certain device it would simplify things a bit. An example. If an USB device provides keyboard and mouse interface, you are now required to write a specific entry in usbd.conf so that on matching of that particular manufacturer and product id, usbd should execute two actions to enable keyboard and mouse. If usbd was made able to execute for all the device types implemented the corresponding entry in usbd.conf, nothing would need to be added to usbd.conf (provided actions matching ukbd and ums are already there). This approach has also the advantage of making the name of the device available to the actions, which is not possible in the case of a single entry serving multiple devices. That is, if you match manufacturer and product id, what is the name of the mouse device to use in the action? >How-To-Repeat: >Fix: The following patch will change the behaviour of usbd so that if an entry matching manufacture/product is not available, all the entries matching the implemented devices will be executed. The old behaviour is retained with the command line -s flag. --- usbd.c.orig Sun Aug 31 17:24:14 2003 +++ usbd.c Sun Aug 31 17:08:19 2003 @@ -102,6 +102,7 @@ int lineno; int verbose = 0; /* print message on what it is doing */ +int single_action = 0; typedef struct event_name_s { int type; /* event number (from usb.h) */ @@ -204,8 +205,7 @@ void print_event __P((struct usb_event *event)); void print_action __P((action_t *action, int i)); void print_actions __P((void)); -int find_action __P((struct usb_device_info *devinfo, - action_match_t *action_match)); +void execute_command __P((char *cmd)); void @@ -674,37 +674,19 @@ int -match_devname(action_t *action, struct usb_device_info *devinfo) +match_devname(regex_t *regex, char *name) { - int i; - regmatch_t match; - int error; - - for (i = 0; i < USB_MAX_DEVNAMES; i++) { - if (devinfo->udi_devnames[i][0] == '\0') - break; - - error = regexec(&action->devname_regex, devinfo->udi_devnames[i], - 1, &match, 0); - if (error == 0) { - if (verbose >= 2) - printf("%s: %s matches %s\n", __progname, - devinfo->udi_devnames[i], action->devname); - return(i); - } - } - - return(-1); + return regexec(regex, name, 0, 0, 0) == 0; } - -int -find_action(struct usb_device_info *devinfo, action_match_t *action_match) +void +execute_actions (struct usb_device_info *devinfo, int event_type) { action_t *action; char *devname = NULL; - int match = -1; + int i; + for (i = 0; i < USB_MAX_DEVNAMES && devinfo->udi_devnames[i][0] != '\0'; i++) { STAILQ_FOREACH(action, &actions, next) { if ((action->vendor == WILDCARD_INT || action->vendor == devinfo->udi_vendorNo) && @@ -719,15 +701,15 @@ (action->protocol == WILDCARD_INT || action->protocol == devinfo->udi_protocol) && (action->devname == WILDCARD_STRING || - (match = match_devname(action, devinfo)) != -1)) { - /* found match !*/ - + match_devname(&action->devname_regex, devinfo->udi_devnames[i]))) { + if (verbose >= 2) + print_action(action, 0); /* Find a devname for pretty printing. Either * the matched one or otherwise, if there is only * one devname for that device, use that. */ - if (match >= 0) - devname = devinfo->udi_devnames[match]; + if (action->devname != WILDCARD_STRING) + devname = devinfo->udi_devnames[i]; else if (devinfo->udi_devnames[0][0] != '\0' && devinfo->udi_devnames[1][0] == '\0') /* if we have exactly 1 device name */ @@ -742,16 +724,37 @@ printf("\n"); } - action_match->action = action; - action_match->devname = devname; + if (devname) { + int error; + if (verbose >= 2) + printf("%s: Setting DEVNAME='%s'\n", + __progname, devname); + error = setenv("DEVNAME", devname, 1); + if (error) + fprintf(stderr, "%s: setenv(\"DEVNAME\", + \"%s\",1) failed, %s\n", + __progname, devname, strerror(errno)); + } - return(1); + if (USB_EVENT_IS_ATTACH(event_type) && action->attach) + execute_command(action->attach); + if (USB_EVENT_IS_DETACH(event_type) && action->detach) + execute_command(action->detach); + /* We are done if either we are + * running in single action mode or we + * didn't match the device name, that + * is, we have a catch-all entry for + * the particular USB device. */ + if (single_action || action->devname == WILDCARD_STRING) + return; + /* get on to the next device name */ + break; + } } } - - return(0); } + void execute_command(char *cmd) { @@ -881,30 +884,7 @@ break; case USB_EVENT_DEVICE_ATTACH: case USB_EVENT_DEVICE_DETACH: - if (find_action(&event.u.ue_device, &action_match) == 0) - /* nothing found */ - break; - - if (verbose >= 2) - print_action(action_match.action, 0); - - if (action_match.devname) { - if (verbose >= 2) - printf("%s: Setting DEVNAME='%s'\n", - __progname, action_match.devname); - - error = setenv("DEVNAME", action_match.devname, 1); - if (error) - fprintf(stderr, "%s: setenv(\"DEVNAME\", \"%s\",1) failed, %s\n", - __progname, action_match.devname, strerror(errno)); - } - - if (USB_EVENT_IS_ATTACH(event.ue_type) && - action_match.action->attach) - execute_command(action_match.action->attach); - if (USB_EVENT_IS_DETACH(event.ue_type) && - action_match.action->detach) - execute_command(action_match.action->detach); + execute_actions(&event.u.ue_device, event.ue_type); break; case USB_EVENT_DRIVER_ATTACH: if (verbose) @@ -944,7 +924,7 @@ } } - while ((ch = getopt(argc, argv, "c:def:nt:v")) != -1) { + while ((ch = getopt(argc, argv, "c:def:nst:v")) != -1) { switch(ch) { case 'c': configfile = strdup(optarg); @@ -965,6 +945,9 @@ break; case 'n': handle_events = 0; + break; + case 's': + single_action = 1; break; case 't': itimeout = atoi(optarg); >Release-Note: >Audit-Trail: >Unformatted: