From patchwork Fri Aug 18 02:35:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shawn Lin X-Patchwork-Id: 9907457 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 93AB36024A for ; Fri, 18 Aug 2017 02:36:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 77E6528B98 for ; Fri, 18 Aug 2017 02:36:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6C42828BD5; Fri, 18 Aug 2017 02:36:36 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9A6D428B98 for ; Fri, 18 Aug 2017 02:36:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753775AbdHRCge (ORCPT ); Thu, 17 Aug 2017 22:36:34 -0400 Received: from lucky1.263xmail.com ([211.157.147.135]:43734 "EHLO lucky1.263xmail.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753345AbdHRCgd (ORCPT ); Thu, 17 Aug 2017 22:36:33 -0400 Received: from shawn.lin?rock-chips.com (unknown [192.168.167.154]) by lucky1.263xmail.com (Postfix) with ESMTP id 9075C8A3; Fri, 18 Aug 2017 10:36:28 +0800 (CST) X-263anti-spam: KSV:0; X-MAIL-GRAY: 1 X-MAIL-DELIVERY: 0 X-KSVirus-check: 0 X-ABS-CHECKED: 4 Received: from localhost.localdomain (localhost [127.0.0.1]) by smtp.263.net (Postfix) with ESMTPA id 9D4F1393; Fri, 18 Aug 2017 10:36:24 +0800 (CST) X-RL-SENDER: shawn.lin@rock-chips.com X-FST-TO: ulf.hansson@linaro.org X-SENDER-IP: 58.22.7.114 X-LOGIN-NAME: shawn.lin@rock-chips.com X-UNIQUE-TAG: <30c6903eed76175b3e134fcf8baf5eef> X-ATTACHMENT-NUM: 0 X-SENDER: lintao@rock-chips.com X-DNS-TYPE: 0 Received: from localhost.localdomain (unknown [58.22.7.114]) by smtp.263.net (Postfix) whith ESMTP id 10291X5T6OM; Fri, 18 Aug 2017 10:36:25 +0800 (CST) From: Shawn Lin To: Ulf Hansson Cc: linux-mmc@vger.kernel.org, Shawn Lin Subject: [PATCH] mmc: sdio: fix bug for IO transfer due to incorrect size check Date: Fri, 18 Aug 2017 10:35:29 +0800 Message-Id: <1503023729-243359-1-git-send-email-shawn.lin@rock-chips.com> X-Mailer: git-send-email 1.9.1 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP I got some reports that some sdio-WiFis weren't able to finish data transfer randomly in there stress test but hard to reproduce it. However after analysing the code, I find a long standing bug which seems could explain how that happened. If the function drivers call sdio_memcpy_{fromio, toio}, it may set the count to 512 Bytes. If the multiple_block in CCCR shows it does support that, we now need to do the checking of 'size > sdio_max_byte_size(func)'. If func->max_blksize, func->cur_blksize, and func->max_blksize are 512, and func->card->host->max_blk_size is larger than 512, thus we will expect sdio_max_byte_size return 512 in gerenal. Then it will fail the checking, and falls into using byte mode for transferring 512 Bytes. Note that we use mmc_io_rw_extended for that with zero blocks and 512 size as arguments. So cmd.arg is zero instead of 512 that the wifi can't get this and abort the data transfer. To fix it, we should allow size to be equal as func's sdio_max_byte_size. That works fine and sloves the problems I got by testing. Signed-off-by: Shawn Lin --- Hi Ulf, Not sure whether should we add a fix tag and CC stable as it seems it has been there since 2007. drivers/mmc/core/sdio_io.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c index d40744b..42c3424 100644 --- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c @@ -313,7 +313,8 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write, return -EINVAL; /* Do the bulk of the transfer using block mode (if supported). */ - if (func->card->cccr.multi_block && (size > sdio_max_byte_size(func))) { + if (func->card->cccr.multi_block && + size >= sdio_max_byte_size(func)) { /* Blocks per command is limited by host count, host transfer * size and the maximum for IO_RW_EXTENDED of 511 blocks. */ max_blocks = min(func->card->host->max_blk_count, 511u);