From patchwork Wed Dec 12 14:38:11 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guennadi Liakhovetski X-Patchwork-Id: 1867381 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 4DE2B40079 for ; Wed, 12 Dec 2012 14:38:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754586Ab2LLOih (ORCPT ); Wed, 12 Dec 2012 09:38:37 -0500 Received: from moutng.kundenserver.de ([212.227.126.186]:58448 "EHLO moutng.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754464Ab2LLOi0 (ORCPT ); Wed, 12 Dec 2012 09:38:26 -0500 Received: from axis700.grange (dslb-146-060-250-080.pools.arcor-ip.net [146.60.250.80]) by mrelayeu.kundenserver.de (node=mrbap3) with ESMTP (Nemesis) id 0MSa4i-1TbCCR07YC-00S821; Wed, 12 Dec 2012 15:38:23 +0100 Received: from 6a.grange (6a.grange [192.168.1.11]) by axis700.grange (Postfix) with ESMTPS id 91142105EA; Wed, 12 Dec 2012 15:38:21 +0100 (CET) Received: from lyakh by 6a.grange with local (Exim 4.72) (envelope-from ) id 1TinRy-0004iG-SK; Wed, 12 Dec 2012 15:38:18 +0100 From: Guennadi Liakhovetski To: linux-mmc@vger.kernel.org Cc: linux-sh@vger.kernel.org, Magnus Damm , Chris Ball Subject: [PATCH 07/14] mmc: sh-mmcif: fix missing and consolidate IO completion timeouts Date: Wed, 12 Dec 2012 15:38:11 +0100 Message-Id: <1355323098-18061-8-git-send-email-g.liakhovetski@gmx.de> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1355323098-18061-1-git-send-email-g.liakhovetski@gmx.de> References: <1355323098-18061-1-git-send-email-g.liakhovetski@gmx.de> X-Provags-ID: V02:K0:b0iserQ5HSwc+zVfZ6Y+nvhNKY3fdU687eM2buqp76O INVUURNuOyhKOosMrRM7FQQ2SIC82unjijLa4mCbwGhtDxTtax FqHILYPgoAeILiy5XtLO2g2XsJvGQsOlaTX9vXFUrm3LlVL+MX +FUudhaol7K4zwRZT54hcO1LlfjAeyEwIa2XX3I4YomEtb3666 BA1loPKv93AOBRQVdXDlIRjau79qLVWhHZCrzAloDtv1Sw407R ua8PKK9TAHrYHJpMmVkUWHkP1lUR6B69GsFAuFlLgYzDYwQlbU 0u4QsbdJUAmm0wdNwP4OarTmWeSC5PZz4TC5M6GWHXSgSXX9HI vCL8UjqS3CipVJVkEl10kWbRiFMr6NFZ5dblKUzGEHi//ZKXu5 8g2e3lVOBsdFQ== Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Read block and write block operations are currently missing completion timeouts. Add missing timeouts and consolidate them at one location. Signed-off-by: Guennadi Liakhovetski --- drivers/mmc/host/sh_mmcif.c | 45 +++++++++++++++++++++---------------------- 1 files changed, 22 insertions(+), 23 deletions(-) diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index 092c415..ac4c3c3 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c @@ -564,7 +564,6 @@ static void sh_mmcif_single_read(struct sh_mmcif_host *host, BLOCK_SIZE_MASK) + 3; host->wait_for = MMCIF_WAIT_FOR_READ; - schedule_delayed_work(&host->timeout_work, host->timeout); /* buf read enable */ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); @@ -606,7 +605,7 @@ static void sh_mmcif_multi_read(struct sh_mmcif_host *host, host->sg_idx = 0; host->sg_blkidx = 0; host->pio_ptr = sg_virt(data->sg); - schedule_delayed_work(&host->timeout_work, host->timeout); + sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); } @@ -629,7 +628,6 @@ static bool sh_mmcif_mread_block(struct sh_mmcif_host *host) if (!sh_mmcif_next_block(host, p)) return false; - schedule_delayed_work(&host->timeout_work, host->timeout); sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); return true; @@ -642,7 +640,6 @@ static void sh_mmcif_single_write(struct sh_mmcif_host *host, BLOCK_SIZE_MASK) + 3; host->wait_for = MMCIF_WAIT_FOR_WRITE; - schedule_delayed_work(&host->timeout_work, host->timeout); /* buf write enable */ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); @@ -684,7 +681,7 @@ static void sh_mmcif_multi_write(struct sh_mmcif_host *host, host->sg_idx = 0; host->sg_blkidx = 0; host->pio_ptr = sg_virt(data->sg); - schedule_delayed_work(&host->timeout_work, host->timeout); + sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); } @@ -707,7 +704,6 @@ static bool sh_mmcif_mwrite_block(struct sh_mmcif_host *host) if (!sh_mmcif_next_block(host, p)) return false; - schedule_delayed_work(&host->timeout_work, host->timeout); sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); return true; @@ -900,7 +896,6 @@ static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host, } host->wait_for = MMCIF_WAIT_FOR_STOP; - schedule_delayed_work(&host->timeout_work, host->timeout); } static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq) @@ -1121,6 +1116,7 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id) { struct sh_mmcif_host *host = dev_id; struct mmc_request *mrq = host->mrq; + bool wait = false; cancel_delayed_work_sync(&host->timeout_work); @@ -1133,29 +1129,24 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id) /* We're too late, the timeout has already kicked in */ return IRQ_HANDLED; case MMCIF_WAIT_FOR_CMD: - if (sh_mmcif_end_cmd(host)) - /* Wait for data */ - return IRQ_HANDLED; + /* Wait for data? */ + wait = sh_mmcif_end_cmd(host); break; case MMCIF_WAIT_FOR_MREAD: - if (sh_mmcif_mread_block(host)) - /* Wait for more data */ - return IRQ_HANDLED; + /* Wait for more data? */ + wait = sh_mmcif_mread_block(host); break; case MMCIF_WAIT_FOR_READ: - if (sh_mmcif_read_block(host)) - /* Wait for data end */ - return IRQ_HANDLED; + /* Wait for data end? */ + wait = sh_mmcif_read_block(host); break; case MMCIF_WAIT_FOR_MWRITE: - if (sh_mmcif_mwrite_block(host)) - /* Wait data to write */ - return IRQ_HANDLED; + /* Wait data to write? */ + wait = sh_mmcif_mwrite_block(host); break; case MMCIF_WAIT_FOR_WRITE: - if (sh_mmcif_write_block(host)) - /* Wait for data end */ - return IRQ_HANDLED; + /* Wait for data end? */ + wait = sh_mmcif_write_block(host); break; case MMCIF_WAIT_FOR_STOP: if (host->sd_error) { @@ -1174,6 +1165,12 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id) BUG(); } + if (wait) { + schedule_delayed_work(&host->timeout_work, host->timeout); + /* Wait for more data */ + return IRQ_HANDLED; + } + if (host->wait_for != MMCIF_WAIT_FOR_STOP) { struct mmc_data *data = mrq->data; if (!mrq->cmd->error && data && !data->error) @@ -1182,8 +1179,10 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id) if (mrq->stop && !mrq->cmd->error && (!data || !data->error)) { sh_mmcif_stop_cmd(host, mrq); - if (!mrq->stop->error) + if (!mrq->stop->error) { + schedule_delayed_work(&host->timeout_work, host->timeout); return IRQ_HANDLED; + } } }