From patchwork Sat Jan 23 00:42:25 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Stefan_Br=C3=BCns?= X-Patchwork-Id: 572032 X-Patchwork-Delegate: marek.vasut@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 4F35D14031E for ; Sat, 23 Jan 2016 11:42:39 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 417BEA7535; Sat, 23 Jan 2016 01:42:36 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6O8ic5r9BsHS; Sat, 23 Jan 2016 01:42:36 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id BA601A74D0; Sat, 23 Jan 2016 01:42:35 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 56A1AA74D0 for ; Sat, 23 Jan 2016 01:42:32 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id nBzOel0GJuXM for ; Sat, 23 Jan 2016 01:42:32 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mx-out-2.rwth-aachen.de (mx-out-2.rwth-aachen.de [134.130.5.187]) by theia.denx.de (Postfix) with ESMTPS id 17A84A749F for ; Sat, 23 Jan 2016 01:42:28 +0100 (CET) X-IronPort-AV: E=Sophos;i="5.22,333,1449529200"; d="scan'208";a="421889726" Received: from rwthex-w2-a.rwth-ad.de ([134.130.26.158]) by mx-2.rz.rwth-aachen.de with ESMTP; 23 Jan 2016 01:42:29 +0100 Received: from pebbles.fritz.box (78.49.3.231) by rwthex-w2-a.rwth-ad.de (2002:8682:1a9e::8682:1a9e) with Microsoft SMTP Server (TLS) id 15.0.1130.7; Sat, 23 Jan 2016 01:42:27 +0100 From: =?UTF-8?q?Stefan=20Br=C3=BCns?= To: Date: Sat, 23 Jan 2016 01:42:25 +0100 Message-ID: <1453509745-16518-1-git-send-email-stefan.bruens@rwth-aachen.de> X-Mailer: git-send-email 2.1.4 MIME-Version: 1.0 X-ClientProxiedBy: rwthex-s1-a.rwth-ad.de (2002:8682:1a98::8682:1a98) To rwthex-w2-a.rwth-ad.de (2002:8682:1a9e::8682:1a9e) Cc: Marek Vasut Subject: [U-Boot] [PATCH v2] usb: dwc2: Do not mix data toggle for IN and OUT endpoints, check bounds X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" USB protocol allows for 16 IN and 16 OUT endpoints (USB 2.0 Spec, 8.3.2.2 Endpoint Field). A function may have an EP 1 for both IN and OUT, so these two should be kept separate. As EPs are either BULK or INTERRUPT (or ISO), it is fine to have one array per direction for all transfer types (also see e236519b7365ef75c5da6a5623f0b03d9c00cfae). USB device address is 7 bits, so a bus may have more than 16 devices. Check the device number, as the DWC2 driver only supports BULK/ISO for the first 16 devices. Signed-off-by: Stefan BrĂ¼ns --- drivers/usb/host/dwc2.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) v2: replace uint8_t with u8 diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c index 291e4a5..b272c57 100644 --- a/drivers/usb/host/dwc2.c +++ b/drivers/usb/host/dwc2.c @@ -34,7 +34,8 @@ struct dwc2_priv { uint8_t *aligned_buffer; uint8_t *status_buffer; #endif - int bulk_data_toggle[MAX_DEVICE][MAX_ENDPOINT]; + u8 in_data_toggle[MAX_DEVICE][MAX_ENDPOINT]; + u8 out_data_toggle[MAX_DEVICE][MAX_ENDPOINT]; struct dwc2_core_regs *regs; int root_hub_devnum; }; @@ -739,7 +740,7 @@ static int dwc_otg_submit_rh_msg(struct dwc2_priv *priv, struct usb_device *dev, return stat; } -int wait_for_chhltd(struct dwc2_hc_regs *hc_regs, uint32_t *sub, int *toggle) +int wait_for_chhltd(struct dwc2_hc_regs *hc_regs, uint32_t *sub, u8 *toggle) { int ret; uint32_t hcint, hctsiz; @@ -775,7 +776,7 @@ static int dwc2_eptype[] = { }; static int transfer_chunk(struct dwc2_hc_regs *hc_regs, void *aligned_buffer, - int *pid, int in, void *buffer, int num_packets, + u8 *pid, int in, void *buffer, int num_packets, int xfer_len, int *actual_len, int odd_frame) { int ret = 0; @@ -829,7 +830,7 @@ static int transfer_chunk(struct dwc2_hc_regs *hc_regs, void *aligned_buffer, } int chunk_msg(struct dwc2_priv *priv, struct usb_device *dev, - unsigned long pipe, int *pid, int in, void *buffer, int len) + unsigned long pipe, u8 *pid, int in, void *buffer, int len) { struct dwc2_core_regs *regs = priv->regs; struct dwc2_hc_regs *hc_regs = ®s->hc_regs[DWC2_HC_CHANNEL]; @@ -960,14 +961,19 @@ int _submit_bulk_msg(struct dwc2_priv *priv, struct usb_device *dev, { int devnum = usb_pipedevice(pipe); int ep = usb_pipeendpoint(pipe); + u8* pid; - if (devnum == priv->root_hub_devnum) { + if ((devnum >= MAX_DEVICE) || (devnum == priv->root_hub_devnum)) { dev->status = 0; return -EINVAL; } - return chunk_msg(priv, dev, pipe, &priv->bulk_data_toggle[devnum][ep], - usb_pipein(pipe), buffer, len); + if (usb_pipein(pipe)) + pid = &priv->in_data_toggle[devnum][ep]; + else + pid = &priv->out_data_toggle[devnum][ep]; + + return chunk_msg(priv, dev, pipe, pid, usb_pipein(pipe), buffer, len); } static int _submit_control_msg(struct dwc2_priv *priv, struct usb_device *dev, @@ -975,7 +981,8 @@ static int _submit_control_msg(struct dwc2_priv *priv, struct usb_device *dev, struct devrequest *setup) { int devnum = usb_pipedevice(pipe); - int pid, ret, act_len; + int ret, act_len; + u8 pid; /* For CONTROL endpoint pid should start with DATA1 */ int status_direction; @@ -1075,8 +1082,10 @@ static int dwc2_init_common(struct dwc2_priv *priv) DWC2_HPRT0_PRTRST); for (i = 0; i < MAX_DEVICE; i++) { - for (j = 0; j < MAX_ENDPOINT; j++) - priv->bulk_data_toggle[i][j] = DWC2_HC_PID_DATA0; + for (j = 0; j < MAX_ENDPOINT; j++) { + priv->in_data_toggle[i][j] = DWC2_HC_PID_DATA0; + priv->out_data_toggle[i][j] = DWC2_HC_PID_DATA0; + } } return 0;