From owner-freebsd-usb@FreeBSD.ORG Mon Feb 2 07:51:58 2015 Return-Path: Delivered-To: freebsd-usb@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 5E435D4B; Mon, 2 Feb 2015 07:51:58 +0000 (UTC) Received: from mail.turbocat.net (mail.turbocat.net [IPv6:2a01:4f8:d16:4514::2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E0AB7C2C; Mon, 2 Feb 2015 07:51:57 +0000 (UTC) Received: from laptop015.home.selasky.org (cm-176.74.213.204.customer.telag.net [176.74.213.204]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.turbocat.net (Postfix) with ESMTPSA id DCDE11FE023; Mon, 2 Feb 2015 08:51:54 +0100 (CET) Message-ID: <54CF2CCE.9090101@selasky.org> Date: Mon, 02 Feb 2015 08:52:46 +0100 From: Hans Petter Selasky User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:31.0) Gecko/20100101 Thunderbird/31.3.0 MIME-Version: 1.0 To: Kohji Okuno Subject: Re: [Bug?] Control Transfers in xHCI References: <54CA4BE3.2090706@selasky.org> <20150129195714.GA3683@dchagin.static.corbina.net> <54CA9144.4030601@selasky.org> <20150202.100611.2049338919815112954.okuno.kohji@jp.panasonic.com> In-Reply-To: <20150202.100611.2049338919815112954.okuno.kohji@jp.panasonic.com> Content-Type: multipart/mixed; boundary="------------000306000605080001060004" Cc: freebsd-usb@freebsd.org X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 02 Feb 2015 07:51:58 -0000 This is a multi-part message in MIME format. --------------000306000605080001060004 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Hi, Please find updated patch. The control_rem is pre-decremented and not post-decremented. --HPS --------------000306000605080001060004 Content-Type: text/x-patch; name="xhci.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="xhci.patch" Index: sys/dev/usb/controller/xhci.c =================================================================== --- sys/dev/usb/controller/xhci.c (revision 277724) +++ sys/dev/usb/controller/xhci.c (working copy) @@ -1866,6 +1866,15 @@ XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_DATA_STAGE); if (temp->direction == UE_DIR_IN) dword |= XHCI_TRB_3_DIR_IN | XHCI_TRB_3_ISP_BIT; + /* + * Section 3.2.9 in the XHCI + * specification about control + * transfers says that we should use a + * normal-TRB if there are more TRBs + * extending the data-stage + * TRB. Update the "trb_type". + */ + temp->trb_type = XHCI_TRB_TYPE_NORMAL; break; case XHCI_TRB_TYPE_STATUS_STAGE: dword = XHCI_TRB_3_CHAIN_BIT | XHCI_TRB_3_CYCLE_BIT | @@ -2106,7 +2115,8 @@ mult = 1; temp.isoc_delta = 0; temp.isoc_frame = 0; - temp.trb_type = XHCI_TRB_TYPE_DATA_STAGE; + temp.trb_type = xfer->flags_int.control_did_data ? + XHCI_TRB_TYPE_NORMAL : XHCI_TRB_TYPE_DATA_STAGE; } else { x = 0; mult = 1; Index: sys/dev/usb/usb_core.h =================================================================== --- sys/dev/usb/usb_core.h (revision 277724) +++ sys/dev/usb/usb_core.h (working copy) @@ -101,6 +101,7 @@ * sent */ uint8_t control_act:1; /* set if control transfer is active */ uint8_t control_stall:1; /* set if control transfer should be stalled */ + uint8_t control_did_data:1; /* set if control data has been sent */ uint8_t short_frames_ok:1; /* filtered version */ uint8_t short_xfer_ok:1; /* filtered version */ Index: sys/dev/usb/usb_transfer.c =================================================================== --- sys/dev/usb/usb_transfer.c (revision 277724) +++ sys/dev/usb/usb_transfer.c (working copy) @@ -1409,6 +1409,28 @@ } /*------------------------------------------------------------------------* + * usbd_control_transfer_did_data + * + * This function returns non-zero if a control endpoint has done the + * first DATA packet after the SETUP packet. Else it returns zero. + *------------------------------------------------------------------------*/ +static uint8_t +usbd_control_transfer_did_data(struct usb_xfer *xfer) +{ + struct usb_device_request req; + + /* SETUP packet is not yet sent */ + if (xfer->flags_int.control_hdr != 0) + return (0); + + /* copy out the USB request header */ + usbd_copy_out(xfer->frbuffers, 0, &req, sizeof(req)); + + /* compare remainder to the initial value */ + return (xfer->flags_int.control_rem != UGETW(req.wLength)); +} + +/*------------------------------------------------------------------------* * usbd_setup_ctrl_transfer * * This function handles initialisation of control transfers. Control @@ -1513,6 +1535,11 @@ len = (xfer->sumlen - sizeof(struct usb_device_request)); } + /* update did data flag */ + + xfer->flags_int.control_did_data = + usbd_control_transfer_did_data(xfer); + /* check if there is a length mismatch */ if (len > xfer->flags_int.control_rem) { --------------000306000605080001060004--