From nobody@FreeBSD.org Sat Oct 12 19:59:42 2002 Return-Path: Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 038D337B401 for ; Sat, 12 Oct 2002 19:59:42 -0700 (PDT) Received: from www.freebsd.org (www.freebsd.org [216.136.204.117]) by mx1.FreeBSD.org (Postfix) with ESMTP id A25FE43E91 for ; Sat, 12 Oct 2002 19:59:41 -0700 (PDT) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.12.6/8.12.6) with ESMTP id g9D2xf7R002433 for ; Sat, 12 Oct 2002 19:59:41 -0700 (PDT) (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.12.6/8.12.6/Submit) id g9D2xfLk002432; Sat, 12 Oct 2002 19:59:41 -0700 (PDT) Message-Id: <200210130259.g9D2xfLk002432@www.freebsd.org> Date: Sat, 12 Oct 2002 19:59:41 -0700 (PDT) From: Naoyuki Tai To: freebsd-gnats-submit@FreeBSD.org Subject: /usr/sbin/usbd does not handle an usb event with multiple devices X-Send-Pr-Version: www-1.0 >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-usb >State: closed >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Oct 12 20:00:09 PDT 2002 >Closed-Date: Tue Jan 04 06:46:51 GMT 2005 >Last-Modified: Tue Jan 04 06:46:51 GMT 2005 >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: Responsible-Changed-From-To: freebsd-bugs->joe Responsible-Changed-By: kris Responsible-Changed-When: Thu Jul 17 17:31:33 PDT 2003 Responsible-Changed-Why: Assign to USB maintainer http://www.freebsd.org/cgi/query-pr.cgi?pr=43993 From: Naoyuki Tai To: freebsd-gnats-submit@FreeBSD.org Cc: Subject: Re: bin/43993: [PATCH] /usr/sbin/usbd does not handle an usb event with multiple devices Date: Wed, 29 Sep 2004 02:10:45 -0400 This is a multi-part message in MIME format. --------------050805000001070108080206 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Based on FreeBSD 4.10's usbd.c --------------050805000001070108080206 Content-Type: text/plain; name="usbd.c.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="usbd.c.patch" *** usbd.c.orig Tue Nov 25 16:13:37 2003 --- usbd.c Wed Jun 2 02:07:53 2004 *************** *** 840,865 **** void process_event_queue(int fd) { ! struct usb_event event; int error; int len; action_match_t action_match; for (;;) { ! len = read(fd, &event, sizeof(event)); if (len == -1) { if (errno == EWOULDBLOCK) { /* no more events */ break; } else { fprintf(stderr,"%s: Could not read event, %s\n", ! __progname, strerror(errno)); exit(1); } } if (len == 0) break; ! if (len != sizeof(event)) { fprintf(stderr, "partial read on %s\n", USBDEV); exit(1); } --- 840,869 ---- void process_event_queue(int fd) { ! struct usb_event events; int error; int len; action_match_t action_match; + int i; + struct usb_event the_event; + struct usb_device_info* devinfo; + struct usb_device_info* the_devinfo; for (;;) { ! len = read(fd, &events, sizeof(events)); if (len == -1) { if (errno == EWOULDBLOCK) { /* no more events */ break; } else { fprintf(stderr,"%s: Could not read event, %s\n", ! __progname, strerror(errno)); exit(1); } } if (len == 0) break; ! if (len != sizeof(events)) { fprintf(stderr, "partial read on %s\n", USBDEV); exit(1); } *************** *** 867,923 **** /* we seem to have gotten a valid event */ if (verbose) ! print_event(&event); ! /* handle the event appropriately */ ! switch (event.ue_type) { ! case USB_EVENT_CTRLR_ATTACH: ! if (verbose) ! printf("USB_EVENT_CTRLR_ATTACH\n"); ! break; ! case USB_EVENT_CTRLR_DETACH: ! if (verbose) ! printf("USB_EVENT_CTRLR_DETACH\n"); ! 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); - break; - case USB_EVENT_DRIVER_ATTACH: - if (verbose) - printf("USB_EVENT_DRIVER_ATTACH\n"); - break; - case USB_EVENT_DRIVER_DETACH: - if (verbose) - printf("USB_EVENT_DRIVER_DETACH\n"); - break; - default: - printf("Unknown USB event %d\n", event.ue_type); } ! } } --- 871,943 ---- /* we seem to have gotten a valid event */ if (verbose) ! print_event(&events); ! devinfo = &events.u.ue_device; ! for (i = 0; i < USB_MAX_DEVNAMES; i++) { ! if (devinfo->udi_devnames[i][0] == '\0') break; ! memcpy(&the_event, &events, sizeof(the_event)); ! the_devinfo = &the_event.u.ue_device; ! if (i > 0) ! memcpy(the_devinfo->udi_devnames[0], the_devinfo->udi_devnames[i], USB_MAX_DEVNAMELEN); ! the_devinfo->udi_devnames[1][0] = '\0'; ! ! if (verbose >=2) { ! printf(" === match attempt: %s\n", the_devinfo->udi_devnames[0]); ! } ! ! /* handle the event appropriately */ ! switch (the_event.ue_type) { ! case USB_EVENT_CTRLR_ATTACH: ! if (verbose) ! printf("USB_EVENT_CTRLR_ATTACH\n"); ! break; ! case USB_EVENT_CTRLR_DETACH: ! if (verbose) ! printf("USB_EVENT_CTRLR_DETACH\n"); ! break; ! case USB_EVENT_DEVICE_ATTACH: ! case USB_EVENT_DEVICE_DETACH: ! if (find_action(&the_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(the_event.ue_type) && ! action_match.action->attach) ! execute_command(action_match.action->attach); ! if (USB_EVENT_IS_DETACH(the_event.ue_type) && ! action_match.action->detach) ! execute_command(action_match.action->detach); ! break; ! case USB_EVENT_DRIVER_ATTACH: ! if (verbose) ! printf("USB_EVENT_DRIVER_ATTACH\n"); ! break; ! case USB_EVENT_DRIVER_DETACH: ! if (verbose) ! printf("USB_EVENT_DRIVER_DETACH\n"); ! break; ! default: ! printf("Unknown USB event %d\n", the_event.ue_type); } } ! } } --------------050805000001070108080206-- Responsible-Changed-From-To: joe->freebsd-usb Responsible-Changed-By: joe Responsible-Changed-When: Wed Nov 10 10:58:30 GMT 2004 Responsible-Changed-Why: Hand this over to the usb mailling list. http://www.freebsd.org/cgi/query-pr.cgi?pr=43993 State-Changed-From-To: open->closed State-Changed-By: julian State-Changed-When: Tue Jan 4 06:46:16 GMT 2005 State-Changed-Why: Apply the supplied patch. http://www.freebsd.org/cgi/query-pr.cgi?pr=43993 >Unformatted: