From walter@pelissero.de  Fri Sep 26 10:01:24 2003
Return-Path: <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 <FreeBSD-gnats-submit@freebsd.org>; 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 <FreeBSD-gnats-submit@freebsd.org>; 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 <FreeBSD-gnats-submit@freebsd.org>; 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 <FreeBSD-gnats-submit@freebsd.org>; 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" <walter@pelissero.de>
Reply-To: walter@pelissero.de
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: usbd and multi-function devices
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         57255
>Category:       bin
>Synopsis:       [patch] usbd(8) and multi-function devices
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-usb
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Sep 26 10:10:14 PDT 2003
>Closed-Date:    Fri Nov 02 13:42:37 UTC 2012
>Last-Modified:  Fri Nov 02 13:42:37 UTC 2012
>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:
Responsible-Changed-From-To: freebsd-bugs->joe 
Responsible-Changed-By: kris 
Responsible-Changed-When: Wed Oct 8 15:11:17 PDT 2003 
Responsible-Changed-Why:  
Assign to USB maintainer 

http://www.freebsd.org/cgi/query-pr.cgi?pr=57255 
Responsible-Changed-From-To: joe->freebsd-usb 
Responsible-Changed-By: joe 
Responsible-Changed-When: Wed Nov 10 11:01:46 GMT 2004 
Responsible-Changed-Why:  
Hand this over to the usb mailling list. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=57255 
State-Changed-From-To: open->suspended 
State-Changed-By: linimon 
State-Changed-When: Thu Nov 13 18:30:17 UTC 2008 
State-Changed-Why:  
These days, the recommended approach is to use devd, so mark this 
suspended unless someone takes an interest in usbd. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=57255 
State-Changed-From-To: suspended->closed 
State-Changed-By: eadler 
State-Changed-When: Fri Nov 2 13:42:36 UTC 2012 
State-Changed-Why:  
usbd.c seems to be non-existent now 

http://www.freebsd.org/cgi/query-pr.cgi?pr=57255 
>Unformatted:
