From owner-freebsd-usb@FreeBSD.ORG Mon Mar 26 14:20:04 2007 Return-Path: X-Original-To: freebsd-usb@hub.freebsd.org Delivered-To: freebsd-usb@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id DF54D16A405 for ; Mon, 26 Mar 2007 14:20:04 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [69.147.83.40]) by mx1.freebsd.org (Postfix) with ESMTP id BFEDA13C480 for ; Mon, 26 Mar 2007 14:20:04 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id l2QEK4vT080693 for ; Mon, 26 Mar 2007 14:20:04 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id l2QEK4no080692; Mon, 26 Mar 2007 14:20:04 GMT (envelope-from gnats) Resent-Date: Mon, 26 Mar 2007 14:20:04 GMT Resent-Message-Id: <200703261420.l2QEK4no080692@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-usb@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Markus Henschel Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 9305A16A401 for ; Mon, 26 Mar 2007 14:18:33 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [69.147.83.33]) by mx1.freebsd.org (Postfix) with ESMTP id 6A71B13C45D for ; Mon, 26 Mar 2007 14:18:33 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.13.1/8.13.1) with ESMTP id l2QEIW4Q073986 for ; Mon, 26 Mar 2007 14:18:33 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.13.1/8.13.1/Submit) id l2QEDUNQ060832; Mon, 26 Mar 2007 14:13:30 GMT (envelope-from nobody) Message-Id: <200703261413.l2QEDUNQ060832@www.freebsd.org> Date: Mon, 26 Mar 2007 14:13:30 GMT From: Markus Henschel To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.0 Cc: Subject: usb/110855: ugen: interrupt in msgs are truncated when buffer is full X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 26 Mar 2007 14:20:05 -0000 >Number: 110855 >Category: usb >Synopsis: ugen: interrupt in msgs are truncated when buffer is full >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-usb >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Mon Mar 26 14:20:04 GMT 2007 >Closed-Date: >Last-Modified: >Originator: Markus Henschel >Release: 6.2 custom kernel >Organization: Bally Wulff Automaten GmbH >Environment: FreeBSD freebsd-1.bally.de 6.2-RELEASE FreeBSD 6.2-RELEASE #11: Fri Mar 23 21:28:38 CET 2007 prog@freebsd-1.bally.de:/usr/obj/usr/src/sys/BALLYWULFF i386 >Description: We use ugen for some user space drivers. When an interrupt in endpoint is used ugen creates a queue that is filled by the kernel. The user space driver is responsible for reading data from the device file. If this happens too slow the queue is full and new msgs arriving from the usb device are lost. This behavior is OK. The problem is that the queue is not a multiple of the interrupt in endpoints msgs size. So it is possible that the last msg in the queue is truncated. This is very hard to detect for a user space driver. The data stream seen by the user space driver will contain an incomplete msgs directly followed by the next message without knowing truncation happened (except when using some data corruption detection mechanism). It would be much better if ugen would fill the queues of interrupt in endpoints until there is no more space for a complete msg. This way the user space driver will not loose sync with the incoming msgs. >How-To-Repeat: 1. Attach a device served by the ugen driver 2. Open an interrupt in endpoint 3. read data in chunk equivalent to the endpoints msg size 4. pause the reading to fill the ugen kernel msg queue 5. resume reading chunks, the last chunk that comes from the queue will probably be truncated directly followed by the next new chunk (tested with a msgs size of the interrupt in endpoint of 16) >Fix: I use the attached patch in our company and it works as expected. Patch attached with submission follows: --- /usr/src/sys/dev/usb/ugen.c.old Mon Mar 26 15:56:18 2007 +++ /usr/src/sys/dev/usb/ugen.c Fri Mar 23 21:27:13 2007 @@ -1081,6 +1081,7 @@ /*struct ugen_softc *sc = sce->sc;*/ u_int32_t count; u_char *ibuf; + int iSize; if (status == USBD_CANCELLED) return; @@ -1100,6 +1101,10 @@ DPRINTFN(5, (" data = %02x %02x %02x\n", ibuf[0], ibuf[1], ibuf[2])); + // begin changes MH@BW + iSize = UGETW(sce->edesc->wMaxPacketSize); + if (count <= ( (UGEN_IBSIZE/iSize)*iSize - sce->q.c_cc)) + // end changes MH@BW (void)b_to_q(ibuf, count, &sce->q); if (sce->state & UGEN_ASLP) { >Release-Note: >Audit-Trail: >Unformatted: