NetBSD Problem Report #48358

From gson@gson.org  Fri Nov  1 12:18:34 2013
Return-Path: <gson@gson.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
	(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
	(Client CN "mail.NetBSD.org", Issuer "Postmaster NetBSD.org" (verified OK))
	by mollari.NetBSD.org (Postfix) with ESMTPS id E4156A5B40
	for <gnats-bugs@gnats.NetBSD.org>; Fri,  1 Nov 2013 12:18:34 +0000 (UTC)
Message-Id: <20131101121831.1143C75E2D@guava.gson.org>
Date: Fri,  1 Nov 2013 14:18:31 +0200 (EET)
From: gson@gson.org (Andreas Gustafsson)
Reply-To: gson@gson.org (Andreas Gustafsson)
To: gnats-bugs@gnats.NetBSD.org
Subject: Repeated low-speed USB control transfers returning short data fail on EHCI
X-Send-Pr-Version: 3.95

>Number:         48358
>Category:       kern
>Synopsis:       Repeated low-speed USB control transfers returning short data fail on EHCI
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Nov 01 12:20:00 +0000 2013
>Closed-Date:    Sat Dec 14 19:43:22 +0000 2013
>Last-Modified:  Sat Dec 14 19:43:22 +0000 2013
>Originator:     Andreas Gustafsson
>Release:        NetBSD 6.0
>Organization:
>Environment:
System: NetBSD guido.araneus.fi
Architecture: x86_64
Machine: amd64
>Description:

Trying to track down the cause of PR 46696 as well as some other USB
communication problems, I constructed the attached test case.  It
reads the device descriptor of a USB device repeatedly in a tight
loop, asking for 64 bytes, which will result in a "short read" since
the actual descriptor size is smaller.  The short read is to mimic
the behavior of kernel versions afflicted by 46696.

When I run the test against a low-speed USB device attached to an EHCI
controller, it fails.  I have tried three different EHCI controllers:
the on-board Intel one, a VIA-based PCI card, and an ALI-based PCI
card, and it fails with all of them (in the case of the PCI cards, an
external high-speed hub must be used to reproduce the failure, because
otherwise the device attaches to the OHCI/UHCI companion controller).

If the device is attached to an OHCI or UHCI rather than an EHCI,
the test passes.

If I use a full-speed device rather than a low-speed one, the test
passes.

If I reduce TRANSFER_SIZE from 64 bytes to the actual size of the
descriptor or smaller, the test passes.

If I introduce a 10 ms delay between the calls to usb_control_msg(),
the test passes.

This may or may not actually be the cause of PR 46696, and may the
cause of problems other than 46696, so I'm making this a separate
PR rather than adding to 46696.

Other PRs applying to the same machine are 38970, 46596, 46696, 47153,
and 48211.

>How-To-Repeat:

How to run the test:

0. Extract the Makefile and test.c included below.

1. Find a low-speed USB device.  I used a USB-to-PS/2 adapter dongle
(with no PS/2 keyboard or mouse connected), but a keyboard or mouse
should work, too.

2. Run "usbdevs -v" to find its vendor and product IDs.  Mine says:

  port 4 addr 4: low speed, power 400 mA, config 1, PS2toUSB Adapter(0x0020), GASIA(0x0e8f), rev 2.80

Note that the product ID is listed first and the vendor ID second,
which is the opposite order from the kernel configuration file and
test program below.

3. Create a kernel configuration file which will attach the device
using the generic USB driver "ugen" instead of the uhid driver.
Assuming the above product and vendor IDs, the kernel configuration
file should look like

  include "arch/amd64/conf/GENERIC"
  ugen* at uhub? vendor 0x0e8f product 0x0020 flags 1

4. Build, install, and boot the new kernel.

5. Install the devel/libusb package if you don't already have it.

6. Edit the VENDOR and PRODUCT definitions in test.c to
match your device.

7. Build the test program by running "make".

8. Attach the device and inspect the console messages to verify that
it attached as ugen rather than uhid, and that it attached to an 
EHCI controller (via a hub).

9. Run the test program as root:

  sudo ./test

The output is self-explanatory.


Contents of the Makefile:

test: test.c
	cc -I/usr/pkg/include -L/usr/pkg/lib test.c -R/usr/pkg/lib -lusb -o test


Contents of test.c:

/*
 * Test repeated short transfers on USB endpoint 0.
 * Rembember to update the VENDOR and PRODUCT
 * definitions to match your device.
 */

#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>

#include <usb.h>

#define VENDOR 0x0e8f
#define PRODUCT 0x0020

#define TRANSFER_SIZE 64

/* Timeout in milliseconds */
#define TIMEOUT 5000

static void
fatal(const char *format, ...) {
    va_list args;
    va_start(args, format);
    vfprintf(stderr, format, args);
    va_end(args);
    fprintf(stderr, "\n");
    exit(1);
}

int
main(int argc, char *argv[]) {
    struct usb_bus *bus;
    struct usb_device *dev;
    struct usb_dev_handle *handle;
    int r, n;
    unsigned char buffer[TRANSFER_SIZE];

    usb_init();
    usb_find_busses();
    usb_find_devices();

    for (bus = usb_busses; bus != NULL; bus = bus->next) {
	for (dev = bus->devices; dev != NULL; dev = dev->next) {
	    if (dev->descriptor.idVendor == VENDOR &&
		dev->descriptor.idProduct == PRODUCT)
		goto found;
	}
    }
    fatal("device not found");

 found:
    handle = usb_open(dev);

    for (n = 0; n < 1000; n++) {
	memset(buffer, 0, sizeof buffer);
	r = usb_control_msg(handle,
			    /* bmRequestType */
			    USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
			    /* bRequest */
			    USB_REQ_GET_DESCRIPTOR,
			    /* wValue: top byte is 1 = device descriptor */
			    1 << 8,
			    /* wIndex */
			    0,
			    buffer, TRANSFER_SIZE, TIMEOUT);
	if (r < 0)
	    fatal("FAILED: usb_control_msg() failed on iteration %d, return value = %d", n, r);
    }
    printf("PASSED\n");

    usb_release_interface(handle, 0);
    usb_close(handle);
    return 0;
}

>Fix:

>Release-Note:

>Audit-Trail:
From: "Nick Hudson" <skrll@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/48358 CVS commit: src/sys/dev/usb
Date: Sun, 1 Dec 2013 07:34:16 +0000

 Module Name:	src
 Committed By:	skrll
 Date:		Sun Dec  1 07:34:16 UTC 2013

 Modified Files:
 	src/sys/dev/usb: ehci.c

 Log Message:
 In ehci_check_qh_intr don't treat a short control transfer as done if the
 status phase is still inflight.  Let the hardware complete it.

 PR/48358: Repeated low-speed USB control transfers returning short data
 	  fail on EHCI

 PR/46696: uhub disables port where USB keyboard attached


 To generate a diff of this commit:
 cvs rdiff -u -r1.220 -r1.221 src/sys/dev/usb/ehci.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: open->feedback
State-Changed-By: skrll@NetBSD.org
State-Changed-When: Sun, 01 Dec 2013 07:40:14 +0000
State-Changed-Why:
I assume you'd like a pullups request for this?


From: Andreas Gustafsson <gson@gson.org>
To: gnats-bugs@NetBSD.org
Cc: kern-bug-people@netbsd.org,
    netbsd-bugs@netbsd.org,
    gnats-admin@netbsd.org,
    skrll@NetBSD.org
Subject: Re: kern/48358 (Repeated low-speed USB control transfers returning short data fail on EHCI)
Date: Sun, 1 Dec 2013 12:36:33 +0200

 skrll@NetBSD.org wrote:
 > I assume you'd like a pullups request for this?

 Yes, please.
 -- 
 Andreas Gustafsson, gson@gson.org

State-Changed-From-To: feedback->pending-pullups
State-Changed-By: skrll@NetBSD.org
State-Changed-When: Sun, 01 Dec 2013 14:18:29 +0000
State-Changed-Why:
pullup-6 #990


From: "Manuel Bouyer" <bouyer@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/48358 CVS commit: [netbsd-6] src/sys/dev/usb
Date: Sat, 14 Dec 2013 19:26:39 +0000

 Module Name:	src
 Committed By:	bouyer
 Date:		Sat Dec 14 19:26:39 UTC 2013

 Modified Files:
 	src/sys/dev/usb [netbsd-6]: ehci.c

 Log Message:
 Pull up following revision(s) (requested by skrll in ticket #990):
 	sys/dev/usb/ehci.c: revision 1.221
 In ehci_check_qh_intr don't treat a short control transfer as done if the
 status phase is still inflight.  Let the hardware complete it.
 PR/48358: Repeated low-speed USB control transfers returning short data
 	  fail on EHCI
 PR/46696: uhub disables port where USB keyboard attached


 To generate a diff of this commit:
 cvs rdiff -u -r1.183.2.1 -r1.183.2.2 src/sys/dev/usb/ehci.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: pending-pullups->closed
State-Changed-By: bouyer@NetBSD.org
State-Changed-When: Sat, 14 Dec 2013 19:43:22 +0000
State-Changed-Why:
pullup processed


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.