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>
