Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 12 Oct 2002 19:59:41 -0700 (PDT)
From:      Naoyuki Tai <ntai@smartfruit.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   bin/43993: /usr/sbin/usbd does not handle an usb event with multiple devices
Message-ID:  <200210130259.g9D2xfLk002432@www.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         43993
>Category:       bin
>Synopsis:       /usr/sbin/usbd does not handle an usb event with multiple devices
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Oct 12 20:00:09 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Naoyuki Tai
>Release:        4.6 STABLE
>Organization:
N/A
>Environment:
FreeBSD nile.camelsoft.com 4.6-STABLE FreeBSD 4.6-STABLE #4: Fri Jul 12 15:20:13 EDT 2002     ntai@nile.camelsoft.com:/usr/obj/usr/src/sys/NILE  i386
>Description:
When there is a usb event that consists of multiple devices, the usbd only  handles the first device and ignores the rest.
So, if you connect a USB hub or USB KVM with multiple devices already attached to the hub, to the host, usbd handles only one device and drops the rest.
For example, if a hub is connected to a usb keyboard and mouse, and the hub is then connected to the machine, usbd handles the keyboard or the mouse but not both.

>How-To-Repeat:
Connect multiple USB devices to a hub. Disconnect and reconnect the hub. If the hub is capable of sending an usb event with multiple devices, the problem appears.

>Fix:
Following patch to /usr/src/usr.sbin/usbd/usbd.c fixed the problem for me. But, I'm not sure that the patch is neat.

*** usbd.c.orig	Sun Feb 24 09:23:13 2002
--- usbd.c	Sat Oct 12 22:43:14 2002
***************
*** 826,831 ****
--- 826,835 ----
  	int error;
  	int len;
  	action_match_t action_match;
+ 	int i;
+ 	struct usb_event one_event;
+ 	struct usb_device_info *one_devinfo;
+ 	struct usb_device_info *devinfo;
  
  	for (;;) {
  		len = read(fd, &event, sizeof(event));
***************
*** 851,888 ****
  		if (verbose)
  			print_event(&event);
  
! 		/* handle the event appropriately */
! 		switch (event.ue_type) {
! 		case USB_EVENT_ATTACH:
! 		case USB_EVENT_DETACH:
! 			if (find_action(&event.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 (event.ue_type == USB_EVENT_ATTACH && action_match.action->attach)
- 				execute_command(action_match.action->attach);
- 			if (event.ue_type == USB_EVENT_DETACH && action_match.action->detach)
- 				execute_command(action_match.action->detach);
- 
- 			break;
- 		default:
- 			printf("Unknown USB event %d\n", event.ue_type);
  		}
! 	}	
  }
  
  
--- 855,903 ----
  		if (verbose)
  			print_event(&event);
  
! 		devinfo = &event.ue_device;
! 
! 		for (i = 0; i < MAXDEVNAMES; i++) {
! 			if (devinfo->udi_devnames[i][0] == '\0')
  				break;
  
! 			memcpy(&one_event, &event, sizeof(one_event));
! 			one_devinfo = &one_event.ue_device;
! 			memcpy(&one_devinfo->udi_devnames[0], &devinfo->udi_devnames[i], sizeof(one_devinfo->udi_devnames[0]));
! 			one_devinfo->udi_devnames[1][0] = '\0';
! 
! 			/* handle the event appropriately */
! 			switch (one_event.ue_type) {
! 			case USB_EVENT_ATTACH:
! 			case USB_EVENT_DETACH:
! 				if (find_action(&one_event.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 (one_event.ue_type == USB_EVENT_ATTACH && action_match.action->attach)
! 					execute_command(action_match.action->attach);
! 				if (one_event.ue_type == USB_EVENT_DETACH && action_match.action->detach)
! 					execute_command(action_match.action->detach);
! 				break;
! 			default:
! 				printf("Unknown USB event %d\n", one_event.ue_type);
  			}
  		}
! 	}
  }
  
  

>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200210130259.g9D2xfLk002432>