From patchwork Fri Jul 14 02:31:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 107716 Delivered-To: patch@linaro.org Received: by 10.140.101.44 with SMTP id t41csp304343qge; Thu, 13 Jul 2017 19:32:25 -0700 (PDT) X-Received: by 10.80.216.195 with SMTP id y3mr4918493edj.165.1499999545066; Thu, 13 Jul 2017 19:32:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1499999545; cv=none; d=google.com; s=arc-20160816; b=hgZYbyL0EBMTxhus+7Qd4Y0RSTXAfRZ0fro1Usjko0sy2KU1x52kqbbuIoOOk3bah0 ZyssHL1L0/PXMEpLXFemJ6i4H3KSz80p65qVsIajdoCPY1GbbsVqx8Iw4W/ptYhF1T9D vyyNuyps+ucDijmZ3NlqOpP4fIH13VvkSdz7nva61XrhKQlUmGAV8rKzABx56tcwhdBQ Y968qvHw0MG7bFz81NTays+sQCZdBissBsYuQfvIFpOj2qJuDvoM0SH+0d8cOz0KPyne 7YdNI6wJRdWkSMjisoRJrsDrl3ykiuHKv5VVQMzDmIYDqpxmh6wJRc0w8T1J8ZKCM+NE tmVg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:cc:message-id:date:to:from :dkim-signature:dkim-filter:arc-authentication-results; bh=nEQX0IyjjgDDWsP3UkxTBQSs/LFSqLENYcjtQmQNrtM=; b=h6HLd44EzEzq/yUTt4hO28KXaR9e8PL9jsx0YQyHgtZ9v4GyvYTXH/j01UlGADkJUK H9P3R/l4CwwG0+opitetZiYDBPE519k4xOm5wcmVplgm0x7GRMPt57Lh74UT53j6slOv LlMWrCafVAEB/tfU4m7J2Meo8eHOU5EwTZWH++plaGrIWTy+ekawmpSsd4lwbNNft752 181HyobreHwqjlHbwkwXYzQyaYGz2qNGhK3jjspyoQuGG0Q9MxuYWOJ0ZYvq1vsTs/vp zk8tCSpCuQW7jRuLRH0qDarGC6lB8PQDipWHG8GwLBnzcBf+aMBKCAFqjrtKkOu/db3u jjNQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@nifty.com header.b=HdmAZgCD; spf=pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de Return-Path: Received: from lists.denx.de (dione.denx.de. [81.169.180.215]) by mx.google.com with ESMTP id k35si5186199ede.23.2017.07.13.19.32.24; Thu, 13 Jul 2017 19:32:25 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) client-ip=81.169.180.215; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@nifty.com header.b=HdmAZgCD; spf=pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by lists.denx.de (Postfix, from userid 105) id 595FCC21E16; Fri, 14 Jul 2017 02:32:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 2F374C21E16; Fri, 14 Jul 2017 02:32:19 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id D3D43C21C3D; Fri, 14 Jul 2017 02:32:17 +0000 (UTC) Received: from conuserg-09.nifty.com (conuserg-09.nifty.com [210.131.2.76]) by lists.denx.de (Postfix) with ESMTPS id 8A8FEC21C3D for ; Fri, 14 Jul 2017 02:32:16 +0000 (UTC) Received: from pug.e01.socionext.com (p14092-ipngnfx01kyoto.kyoto.ocn.ne.jp [153.142.97.92]) (authenticated) by conuserg-09.nifty.com with ESMTP id v6E2VE9Z020877; Fri, 14 Jul 2017 11:31:15 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-09.nifty.com v6E2VE9Z020877 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1499999475; bh=2FjVM7e18t4hiD6LOENT4VBZFLrSeUxjkITD8NtXhbA=; h=From:To:Cc:Subject:Date:From; b=HdmAZgCDEF1zUIyjqdVVPDHwgBwONO0lTi15vgLVXy6cx4UqczP+bmvwiCUsBAAPm O7UdZjAMTjVCdqHFDWTZ+kBDONG3dmDOt1cEyceLjvn5JW3Z/TR1naGUS+2td5NoJC yPQCRTngp+DIa5DcKIcIUJ1QAjU3z0rlu14Ct5mTO41Lyg8ZWAvcTjPaDQXXeZPWhM V4Z7twnAv0KI3133aGsP2mzsW9QNMEOtEaSehyCD8zGA0DlwXo9tbwcR7zaHSRmZqj CMBl/lu2bIYnUpPYMomQJSTA+QYKlKf8tGMLvf4HyDAp40UiGfpn+3G9B5Usr6PWKq NEsk1FiLvuY9w== X-Nifty-SrcIP: [153.142.97.92] From: Masahiro Yamada To: u-boot@lists.denx.de Date: Fri, 14 Jul 2017 11:31:09 +0900 Message-Id: <1499999469-9861-1-git-send-email-yamada.masahiro@socionext.com> X-Mailer: git-send-email 2.7.4 Cc: Marek Vasut , Hans de Goede , Vagrant Cascadian , Andre Przywara , Michal Simek Subject: [U-Boot] [PATCH v2] usb: fix usb_stor_read/write on DM X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Prior to DM, we could not enable different types of USB controllers at the same time. DM was supposed to loosen the limitation. It is true that we can compile drivers, but they do not work. For example, if EHCI is enabled, xHCI fails as follows: => usb read 82000000 0 2000 USB read: device 0 block # 0, count 8192 ... WARN halted endpoint, queueing URB anyway. Unexpected XHCI event TRB, skipping... (3fb54010 00000001 13000000 01008401) BUG: failure at drivers/usb/host/xhci-ring.c:489/abort_td()! BUG! ### ERROR ### Please RESET the board ### The cause of the error seems the following code: #ifdef CONFIG_USB_EHCI_HCD /* * The U-Boot EHCI driver can handle any transfer length as long as there is * enough free heap space left, but the SCSI READ(10) and WRITE(10) commands are * limited to 65535 blocks. */ #define USB_MAX_XFER_BLK 65535 #else #define USB_MAX_XFER_BLK 20 #endif To fix the problem, choose the chunk size at run-time for CONFIG_BLK. Signed-off-by: Masahiro Yamada --- Changes in v2: - Run-time detection of host if common/usb_storage.c | 30 ++++++++++++++++++++---------- drivers/usb/host/ehci-hcd.c | 1 + drivers/usb/host/ohci-hcd.c | 1 + drivers/usb/host/xhci.c | 1 + include/usb.h | 9 +++++++++ 5 files changed, 32 insertions(+), 10 deletions(-) diff --git a/common/usb_storage.c b/common/usb_storage.c index df0b05730879..d17b12639cad 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -1109,7 +1109,7 @@ static unsigned long usb_stor_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt, void *buffer) #endif { - lbaint_t start, blks; + lbaint_t start, blks, max_xfer_blk; uintptr_t buf_addr; unsigned short smallblks; struct usb_device *udev; @@ -1118,6 +1118,7 @@ static unsigned long usb_stor_read(struct blk_desc *block_dev, lbaint_t blknr, struct scsi_cmd *srb = &usb_ccb; #ifdef CONFIG_BLK struct blk_desc *block_dev; + struct usb_bus_priv *bus_priv; #endif if (blkcnt == 0) @@ -1127,6 +1128,9 @@ static unsigned long usb_stor_read(struct blk_desc *block_dev, lbaint_t blknr, block_dev = dev_get_uclass_platdata(dev); udev = dev_get_parent_priv(dev_get_parent(dev)); debug("\nusb_read: udev %d\n", block_dev->devnum); + + bus_priv = dev_get_uclass_priv(dev_get_parent(dev_get_parent(dev_get_parent(dev)))); + max_xfer_blk = bus_priv->host_if == USB_HOST_EHCI ? 65535 : 20; #else debug("\nusb_read: udev %d\n", block_dev->devnum); udev = usb_dev_desc[block_dev->devnum].priv; @@ -1134,6 +1138,7 @@ static unsigned long usb_stor_read(struct blk_desc *block_dev, lbaint_t blknr, debug("%s: No device\n", __func__); return 0; } + max_xfer_blk = USB_MAX_XFER_BLK; #endif ss = (struct us_data *)udev->privptr; @@ -1150,12 +1155,12 @@ static unsigned long usb_stor_read(struct blk_desc *block_dev, lbaint_t blknr, /* XXX need some comment here */ retry = 2; srb->pdata = (unsigned char *)buf_addr; - if (blks > USB_MAX_XFER_BLK) - smallblks = USB_MAX_XFER_BLK; + if (blks > max_xfer_blk) + smallblks = max_xfer_blk; else smallblks = (unsigned short) blks; retry_it: - if (smallblks == USB_MAX_XFER_BLK) + if (smallblks == max_xfer_blk) usb_show_progress(); srb->datalen = block_dev->blksz * smallblks; srb->pdata = (unsigned char *)buf_addr; @@ -1178,7 +1183,7 @@ retry_it: start, smallblks, buf_addr); usb_disable_asynch(0); /* asynch transfer allowed */ - if (blkcnt >= USB_MAX_XFER_BLK) + if (blkcnt >= max_xfer_blk) debug("\n"); return blkcnt; } @@ -1191,7 +1196,7 @@ static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt, const void *buffer) #endif { - lbaint_t start, blks; + lbaint_t start, blks, max_xfer_blk; uintptr_t buf_addr; unsigned short smallblks; struct usb_device *udev; @@ -1200,6 +1205,7 @@ static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr, struct scsi_cmd *srb = &usb_ccb; #ifdef CONFIG_BLK struct blk_desc *block_dev; + struct usb_bus_priv *bus_priv; #endif if (blkcnt == 0) @@ -1210,6 +1216,9 @@ static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr, block_dev = dev_get_uclass_platdata(dev); udev = dev_get_parent_priv(dev_get_parent(dev)); debug("\nusb_read: udev %d\n", block_dev->devnum); + + bus_priv = dev_get_uclass_priv(dev_get_parent(dev_get_parent(dev_get_parent(dev)))); + max_xfer_blk = bus_priv->host_if == USB_HOST_EHCI ? 65535 : 20; #else debug("\nusb_read: udev %d\n", block_dev->devnum); udev = usb_dev_desc[block_dev->devnum].priv; @@ -1217,6 +1226,7 @@ static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr, debug("%s: No device\n", __func__); return 0; } + max_xfer_blk = USB_MAX_XFER_BLK; #endif ss = (struct us_data *)udev->privptr; @@ -1236,12 +1246,12 @@ static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr, */ retry = 2; srb->pdata = (unsigned char *)buf_addr; - if (blks > USB_MAX_XFER_BLK) - smallblks = USB_MAX_XFER_BLK; + if (blks > max_xfer_blk) + smallblks = max_xfer_blk; else smallblks = (unsigned short) blks; retry_it: - if (smallblks == USB_MAX_XFER_BLK) + if (smallblks == max_xfer_blk) usb_show_progress(); srb->datalen = block_dev->blksz * smallblks; srb->pdata = (unsigned char *)buf_addr; @@ -1263,7 +1273,7 @@ retry_it: PRIxPTR "\n", start, smallblks, buf_addr); usb_disable_asynch(0); /* asynch transfer allowed */ - if (blkcnt >= USB_MAX_XFER_BLK) + if (blkcnt >= max_xfer_blk) debug("\n"); return blkcnt; diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index f08709d0212d..b55961954a33 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1604,6 +1604,7 @@ int ehci_register(struct udevice *dev, struct ehci_hccr *hccr, dev->name, ctrl, hccr, hcor, init); priv->desc_before_addr = true; + priv->host_if = USB_HOST_EHCI; ehci_setup_ops(ctrl, ops); ctrl->hccr = hccr; diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index fdfc870efa3e..d877f2bb0bbf 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -2193,6 +2193,7 @@ int ohci_register(struct udevice *dev, struct ohci_regs *regs) u32 reg; priv->desc_before_addr = true; + priv->host_if = USB_HOST_OHCI; ohci->regs = regs; ohci->hcca = memalign(256, sizeof(struct ohci_hcca)); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index bd8f4c43b4b2..2df78f29cd78 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1207,6 +1207,7 @@ int xhci_register(struct udevice *dev, struct xhci_hccr *hccr, * of that is done for XHCI unlike EHCI. */ priv->desc_before_addr = false; + priv->host_if = USB_HOST_XHCI; ret = xhci_reset(hcor); if (ret) diff --git a/include/usb.h b/include/usb.h index 62f051fe535c..675761edfc08 100644 --- a/include/usb.h +++ b/include/usb.h @@ -604,6 +604,14 @@ struct usb_dev_platdata { int configno; }; +enum usb_host_if { + USB_HOST_UNKNOWN, + USB_HOST_OHCI, + USB_HOST_UHCI, + USB_HOST_EHCI, + USB_HOST_XHCI, +}; + /** * struct usb_bus_priv - information about the USB controller * @@ -623,6 +631,7 @@ struct usb_bus_priv { int next_addr; bool desc_before_addr; bool companion; + enum usb_host_if host_if; }; /**