From patchwork Fri Jun 23 16:37:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Scheller X-Patchwork-Id: 9806943 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 58ECF60349 for ; Fri, 23 Jun 2017 16:37:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4823328740 for ; Fri, 23 Jun 2017 16:37:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3C92C28792; Fri, 23 Jun 2017 16:37:47 +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=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, 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 6D75E28740 for ; Fri, 23 Jun 2017 16:37:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754011AbdFWQhp (ORCPT ); Fri, 23 Jun 2017 12:37:45 -0400 Received: from mail-wr0-f194.google.com ([209.85.128.194]:34374 "EHLO mail-wr0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753926AbdFWQho (ORCPT ); Fri, 23 Jun 2017 12:37:44 -0400 Received: by mail-wr0-f194.google.com with SMTP id k67so13724906wrc.1 for ; Fri, 23 Jun 2017 09:37:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id; bh=48qX8OmdD29ZTRKCH4Id085ZuKY/ZPIbMpaEBwq2KDE=; b=O1hzrG2epa6kBpD0XDVvu0YZ7SPHl84EH+WKL5D/XC9PaIVhYAi4gK8x33ptoXuLPY d7ufNJa5Z5oDJGFoDQNhA3jjucqbd/nrpv0ao34fpOOz4+/D5rWQDpzNwEC2Gr8s1A+U 7oh7NIP1QAgqhcpNAXdAiyo3BtWc7fwg/L0VuozvgXnlhylAQfwselU7pkLKJoO91L53 K5YexN9drVrYJUrX4QBNu34vug4C/pQBuJJ4sf84khfKWLDF6UB8YBiCUYfm1dccxXkf FZo/wDJvaZfqGA9YC71CFjMuWd9P6ubL+6d8NXDcKsuYeygb6CSfMCFsO5hEde3eV2Yv dwUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=48qX8OmdD29ZTRKCH4Id085ZuKY/ZPIbMpaEBwq2KDE=; b=kRwbopvD2PyHyJx88XOtTc3JS2K9Zxe9lgIcTyrhsYBD6fQKL6sjOEAimVeDL5zqFp oVW05j/Drccm50ORomyENIQFpkh+2V/P+SVkTdk8Dy6Sr/2VNAnRAJOdGZVVNlQaGZcz v9ynvzicOuHVvpzf8rMlOQnvOEMLHHqF6RfgjDLQ30pCS1Yd7nBKejaDyEm4SWmXNEtI EnFqVv088q3t72iFInNNBKPJo1Lwirx0d0Q+9cFz++fLnktRiXetfvo6olUvNak0a9wn S1a3+thFtrBapL0sNHorZH78KoxJBTAZituGYORZtmqmRvOrykcVftthHrm/TqmrDF0G MoCA== X-Gm-Message-State: AKS2vOxbYpEojDm/tK1bmi+b+u9a95KeMgozlCeXhxdH1exXojHFqNLB vR3OgooH8fu48o2i X-Received: by 10.223.131.66 with SMTP id 60mr6842195wrd.54.1498235862763; Fri, 23 Jun 2017 09:37:42 -0700 (PDT) Received: from dvbdev.wuest.de (ip-37-24-178-151.hsi14.unitymediagroup.de. [37.24.178.151]) by smtp.gmail.com with ESMTPSA id q70sm5859604wrb.3.2017.06.23.09.37.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 23 Jun 2017 09:37:42 -0700 (PDT) From: Daniel Scheller To: linux-media@vger.kernel.org, mchehab@kernel.org, mchehab@s-opensource.com Subject: [PATCH] [media] ddbridge: make (ddb)readl in while-loops fail-safe Date: Fri, 23 Jun 2017 18:37:40 +0200 Message-Id: <20170623163740.21250-1-d.scheller.oss@gmail.com> X-Mailer: git-send-email 2.13.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Daniel Scheller Reported by smatch: drivers/media/pci/ddbridge/ddbridge-core.c:1246 input_tasklet() warn: this loop depends on readl() succeeding drivers/media/pci/ddbridge/ddbridge-core.c:1768 flashio() warn: this loop depends on readl() succeeding drivers/media/pci/ddbridge/ddbridge-core.c:1788 flashio() warn: this loop depends on readl() succeeding Fix this by introducing safe_ddbreadl() which will wrap ddbreadl and checks for all bits set in the return which indicates failure, and return 0 in that case. Usable as drop-in-replacement in all affected while loops w/o having to change the logic. Signed-off-by: Daniel Scheller --- drivers/media/pci/ddbridge/ddbridge-core.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) TODO: fix up the printk if https://patchwork.linuxtv.org/patch/42034/ eventually gets merged. Assuming that (uint)-1 is really a reserved return value in iomem (as mentioned, I'm not that much into kernel and io related things) and it isn't possible to expect 0xffffffff by definition, this should be good. Quickly tested with four tuners and four streams running in parallel without issues. diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 9420479bee9a..cf7a6b0532dc 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -114,6 +114,19 @@ static int i2c_write_reg(struct i2c_adapter *adap, u8 adr, return i2c_write(adap, adr, msg, 2); } +static inline u32 safe_ddbreadl(struct ddb *dev, u32 adr) +{ + u32 val = ddbreadl(adr); + + /* (ddb)readl returns (uint)-1 (all bits set) on failure, catch that */ + if (val == ~0) { + printk(KERN_ERR "ddbreadl failure, adr=%08x\n", adr); + return 0; + } + + return val; +} + static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd) { struct ddb *dev = i2c->dev; @@ -1243,7 +1256,7 @@ static void input_tasklet(unsigned long data) if (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr))) printk(KERN_ERR "Overflow input %d\n", input->nr); while (input->cbuf != ((input->stat >> 11) & 0x1f) - || (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr)))) { + || (4 & safe_ddbreadl(dev, DMA_BUFFER_CONTROL(input->nr)))) { dvb_dmx_swfilter_packets(&input->demux, input->vbuf[input->cbuf], input->dma_buf_size / 188); @@ -1765,7 +1778,7 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) wbuf += 4; wlen -= 4; ddbwritel(data, SPI_DATA); - while (ddbreadl(SPI_CONTROL) & 0x0004) + while (safe_ddbreadl(dev, SPI_CONTROL) & 0x0004) ; } @@ -1785,7 +1798,7 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) if (shift) data <<= shift; ddbwritel(data, SPI_DATA); - while (ddbreadl(SPI_CONTROL) & 0x0004) + while (safe_ddbreadl(dev, SPI_CONTROL) & 0x0004) ; if (!rlen) { @@ -1797,7 +1810,7 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) while (rlen > 4) { ddbwritel(0xffffffff, SPI_DATA); - while (ddbreadl(SPI_CONTROL) & 0x0004) + while (safe_ddbreadl(dev, SPI_CONTROL) & 0x0004) ; data = ddbreadl(SPI_DATA); *(u32 *) rbuf = swab32(data); @@ -1806,7 +1819,7 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) } ddbwritel(0x0003 | ((rlen << (8 + 3)) & 0x1F00), SPI_CONTROL); ddbwritel(0xffffffff, SPI_DATA); - while (ddbreadl(SPI_CONTROL) & 0x0004) + while (safe_ddbreadl(dev, SPI_CONTROL) & 0x0004) ; data = ddbreadl(SPI_DATA);