From owner-svn-src-stable-10@FreeBSD.ORG Tue Feb 10 13:16:55 2015 Return-Path: Delivered-To: svn-src-stable-10@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 EFF354CA; Tue, 10 Feb 2015 13:16:54 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (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 D9BF1C22; Tue, 10 Feb 2015 13:16:54 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t1ADGsRa095293; Tue, 10 Feb 2015 13:16:54 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t1ADGsGH095290; Tue, 10 Feb 2015 13:16:54 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <201502101316.t1ADGsGH095290@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Tue, 10 Feb 2015 13:16:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r278507 - in stable/10/sys/dev/usb: . controller X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 10 Feb 2015 13:16:55 -0000 Author: hselasky Date: Tue Feb 10 13:16:53 2015 New Revision: 278507 URL: https://svnweb.freebsd.org/changeset/base/278507 Log: MFC r278071: 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. Add a dedicated state bit to the internal USB transfer flags to handle this case. Modified: stable/10/sys/dev/usb/controller/xhci.c stable/10/sys/dev/usb/usb_core.h stable/10/sys/dev/usb/usb_transfer.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/usb/controller/xhci.c ============================================================================== --- stable/10/sys/dev/usb/controller/xhci.c Tue Feb 10 13:07:08 2015 (r278506) +++ stable/10/sys/dev/usb/controller/xhci.c Tue Feb 10 13:16:53 2015 (r278507) @@ -1870,6 +1870,15 @@ restart: 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 | @@ -2110,7 +2119,8 @@ xhci_setup_generic_chain(struct usb_xfer 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; Modified: stable/10/sys/dev/usb/usb_core.h ============================================================================== --- stable/10/sys/dev/usb/usb_core.h Tue Feb 10 13:07:08 2015 (r278506) +++ stable/10/sys/dev/usb/usb_core.h Tue Feb 10 13:16:53 2015 (r278507) @@ -101,6 +101,7 @@ struct usb_xfer_flags_int { * 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 transferred */ uint8_t short_frames_ok:1; /* filtered version */ uint8_t short_xfer_ok:1; /* filtered version */ Modified: stable/10/sys/dev/usb/usb_transfer.c ============================================================================== --- stable/10/sys/dev/usb/usb_transfer.c Tue Feb 10 13:07:08 2015 (r278506) +++ stable/10/sys/dev/usb/usb_transfer.c Tue Feb 10 13:16:53 2015 (r278507) @@ -1409,6 +1409,29 @@ usbd_control_transfer_init(struct usb_xf } /*------------------------------------------------------------------------* + * usbd_control_transfer_did_data + * + * This function returns non-zero if a control endpoint has + * transferred 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 +1536,11 @@ usbd_setup_ctrl_transfer(struct usb_xfer 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) {