Message ID | 20230516110038.2413224-36-schnelle@linux.ibm.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp366855vqo; Tue, 16 May 2023 04:58:13 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7Yze55/fo9Jf9BOq7VWjNOE+ZY0Zh6T2jF7hfic/mwIv+MzRzrtrcZ2y98GHvAyxAIYQlj X-Received: by 2002:a17:902:9f87:b0:1a9:b0a3:f03a with SMTP id g7-20020a1709029f8700b001a9b0a3f03amr37450695plq.9.1684238293632; Tue, 16 May 2023 04:58:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1684238293; cv=none; d=google.com; s=arc-20160816; b=WUl3SKzckJiSZSguPlTDzcMHSWFb1yaINHrHxNBFz/3XrvRXPVIWoSmWPK/kHfwxw/ mMLguniYIOfm6BhX2oZnVke6Ex5vDBgCywGk2JTE089T4Udr7I+V1VuTm19jnGfROb2N dPArFx7uBgn2s4y10d+FQwZaI4/lZu99TRX8R9fLMwZkOfDqBtEusNop5WleqqPPeEu0 zaum52XZVAZbS9Bu+Mn8xQmnvKHAD/X4OgtFHU0r0BGuVgAGgLJ27INsudfLaTt9GPKB m/5cEbz/RDpV/pOZIeHRgznLWFwXhzRcsPCz+p7uYoebmBNoD7qbGpTCWYuZngjS6fkj Ichg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=k1lr2gkx2EG7llhCOzfRkPYbbk1LM9LiZTc9+G/8hFg=; b=CG0ktF0K4ihCCOoodKDIAAnAfkCvjDXpSDHEk987uT+GYUQ8UpHJxYSCTkqwzl3deP sJmrRQOXl07ae33S/PdANN5kjnqd7KlYyCLdVTQ7QKlaFbl/We1+4tQ2ViLm/BFS0vfQ yXhDLlFEt6wP6RWP0NOqJGjgFtacX+m1K6CBUQ8EhYgpCl9Esh/ykDAxrOwNj8IK7Yrv FtWvWpmp/6IaYmDB2kfUXg97IRl3yy5KmpYEfusMh4Vnjb9YlwiERwRV5Wyw0S7ArxLN +hv4rFKkazlRuNg2/qkO+8qChIZHvZul69fbjee+meTxRmO7WwEZfZMQhKlYqklAtx1a M8OA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ibm.com header.s=pp1 header.b="Gx0h2vG/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=NONE dis=NONE) header.from=ibm.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id h8-20020a170902f54800b001aaf607910fsi19918025plf.376.2023.05.16.04.58.01; Tue, 16 May 2023 04:58:13 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@ibm.com header.s=pp1 header.b="Gx0h2vG/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=NONE dis=NONE) header.from=ibm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232738AbjEPLXI (ORCPT <rfc822;peekingduck44@gmail.com> + 99 others); Tue, 16 May 2023 07:23:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52770 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232797AbjEPLXE (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Tue, 16 May 2023 07:23:04 -0400 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 540C6A9; Tue, 16 May 2023 04:22:48 -0700 (PDT) Received: from pps.filterd (m0356517.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 34GB4U9k030858; Tue, 16 May 2023 11:05:43 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=k1lr2gkx2EG7llhCOzfRkPYbbk1LM9LiZTc9+G/8hFg=; b=Gx0h2vG/4jUKpz7lJWROJQ2moEwGeFSPj/HZk0w0SLLRknImLl0ynhFGX4uDQafoehl6 M0mKp5WfSwb7Nn5zD9RQg1sQnmpvUOBVk+7RLL8ohEzycUHCgkTIx7CUHs2yguW9x4K8 jHKQUfEaC/7spLYmUf3zyclLlu+Pj7fTn8Y3mcMgnHA31wTtEPHNQrDuQLrPO6jxJagw at2xnIhBw8YlIPlArbTCRsjL0JkgJq+/C9tN4hB2I9le2YhP11j9dKc9VNZO37Qw9bzP pfBuVni9bBDzrF6g5uq0brfDxK3gVtSjMnhMw9LDpQShwMQxZg1kloj3D1QXFFRP4Kk+ gA== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3qm82f0t88-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 16 May 2023 11:05:42 +0000 Received: from m0356517.ppops.net (m0356517.ppops.net [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 34GB4xdW002085; Tue, 16 May 2023 11:05:07 GMT Received: from ppma03ams.nl.ibm.com (62.31.33a9.ip4.static.sl-reverse.com [169.51.49.98]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3qm82f0pt9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 16 May 2023 11:05:06 +0000 Received: from pps.filterd (ppma03ams.nl.ibm.com [127.0.0.1]) by ppma03ams.nl.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 34G36MH5019561; Tue, 16 May 2023 11:01:13 GMT Received: from smtprelay07.fra02v.mail.ibm.com ([9.218.2.229]) by ppma03ams.nl.ibm.com (PPS) with ESMTPS id 3qj264sjvn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 16 May 2023 11:01:13 +0000 Received: from smtpav04.fra02v.mail.ibm.com (smtpav04.fra02v.mail.ibm.com [10.20.54.103]) by smtprelay07.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 34GB1BjH30146816 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 16 May 2023 11:01:11 GMT Received: from smtpav04.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3FBA32004E; Tue, 16 May 2023 11:01:11 +0000 (GMT) Received: from smtpav04.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E332B2004D; Tue, 16 May 2023 11:01:10 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.152.85.9]) by smtpav04.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 16 May 2023 11:01:10 +0000 (GMT) From: Niklas Schnelle <schnelle@linux.ibm.com> To: Arnd Bergmann <arnd@arndb.de>, Alan Stern <stern@rowland.harvard.edu>, Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Bjorn Helgaas <bhelgaas@google.com>, =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>, Mauro Carvalho Chehab <mchehab@kernel.org>, "Rafael J. Wysocki" <rafael@kernel.org>, Geert Uytterhoeven <geert@linux-m68k.org>, Paul Walmsley <paul.walmsley@sifive.com>, Palmer Dabbelt <palmer@dabbelt.com>, Albert Ou <aou@eecs.berkeley.edu>, linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, linux-pci@vger.kernel.org, Arnd Bergmann <arnd@kernel.org>, linux-usb@vger.kernel.org Subject: [PATCH v4 35/41] usb: uhci: handle HAS_IOPORT dependencies Date: Tue, 16 May 2023 13:00:31 +0200 Message-Id: <20230516110038.2413224-36-schnelle@linux.ibm.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230516110038.2413224-1-schnelle@linux.ibm.com> References: <20230516110038.2413224-1-schnelle@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-TM-AS-GCONF: 00 X-Proofpoint-GUID: WJu3W9w7VBhxXeFU00kPI5t0x556P1nr X-Proofpoint-ORIG-GUID: DNZTFNG-K6-B0c13-rs-mTZTz4QU1LYq X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.957,Hydra:6.0.573,FMLib:17.11.170.22 definitions=2023-05-16_04,2023-05-16_01,2023-02-09_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 bulkscore=0 spamscore=0 suspectscore=0 mlxlogscore=610 impostorscore=0 malwarescore=0 adultscore=0 phishscore=0 priorityscore=1501 clxscore=1011 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2304280000 definitions=main-2305160094 X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_EF,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1766051853173432263?= X-GMAIL-MSGID: =?utf-8?q?1766051853173432263?= |
Series |
treewide: Remove I/O port accessors for HAS_IOPORT=n
|
|
Commit Message
Niklas Schnelle
May 16, 2023, 11 a.m. UTC
In a future patch HAS_IOPORT=n will result in inb()/outb() and friends not being declared. We thus need to guard sections of code calling them as alternative access methods with CONFIG_HAS_IOPORT checks. For uhci-hcd there are a lot of I/O port uses that do have MMIO alternatives all selected by uhci_has_pci_registers() so this can be handled by UHCI_IN/OUT macros and making uhci_has_pci_registers() constant 0 if CONFIG_HAS_IOPORT is unset. Co-developed-by: Arnd Bergmann <arnd@kernel.org> Signed-off-by: Arnd Bergmann <arnd@kernel.org> Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com> --- Note: The HAS_IOPORT Kconfig option was added in v6.4-rc1 so per-subsystem patches may be applied independently drivers/usb/host/uhci-hcd.c | 2 +- drivers/usb/host/uhci-hcd.h | 36 +++++++++++++++++++++++------------- 2 files changed, 24 insertions(+), 14 deletions(-)
Comments
On Tue, May 16, 2023 at 01:00:31PM +0200, Niklas Schnelle wrote: > In a future patch HAS_IOPORT=n will result in inb()/outb() and friends > not being declared. We thus need to guard sections of code calling them > as alternative access methods with CONFIG_HAS_IOPORT checks. For > uhci-hcd there are a lot of I/O port uses that do have MMIO alternatives > all selected by uhci_has_pci_registers() so this can be handled by > UHCI_IN/OUT macros and making uhci_has_pci_registers() constant 0 if > CONFIG_HAS_IOPORT is unset. > > Co-developed-by: Arnd Bergmann <arnd@kernel.org> > Signed-off-by: Arnd Bergmann <arnd@kernel.org> > Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com> > --- > Note: The HAS_IOPORT Kconfig option was added in v6.4-rc1 so > per-subsystem patches may be applied independently > > drivers/usb/host/uhci-hcd.c | 2 +- > drivers/usb/host/uhci-hcd.h | 36 +++++++++++++++++++++++------------- > 2 files changed, 24 insertions(+), 14 deletions(-) > > diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c > index 7cdc2fa7c28f..fd2408b553cf 100644 > --- a/drivers/usb/host/uhci-hcd.c > +++ b/drivers/usb/host/uhci-hcd.c > @@ -841,7 +841,7 @@ static int uhci_count_ports(struct usb_hcd *hcd) > > static const char hcd_name[] = "uhci_hcd"; > > -#ifdef CONFIG_USB_PCI > +#if defined(CONFIG_USB_PCI) && defined(CONFIG_HAS_IOPORT) > #include "uhci-pci.c" > #define PCI_DRIVER uhci_pci_driver > #endif > diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h > index 0688c3e5bfe2..c77705d03ed0 100644 > --- a/drivers/usb/host/uhci-hcd.h > +++ b/drivers/usb/host/uhci-hcd.h > @@ -505,41 +505,49 @@ static inline bool uhci_is_aspeed(const struct uhci_hcd *uhci) > * we use memory mapped registers. > */ > > +#ifdef CONFIG_HAS_IOPORT > +#define UHCI_IN(x) x > +#define UHCI_OUT(x) x > +#else > +#define UHCI_IN(x) 0 > +#define UHCI_OUT(x) > +#endif > + > #ifndef CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC > /* Support PCI only */ > static inline u32 uhci_readl(const struct uhci_hcd *uhci, int reg) > { > - return inl(uhci->io_addr + reg); > + return UHCI_IN(inl(uhci->io_addr + reg)); > } > > static inline void uhci_writel(const struct uhci_hcd *uhci, u32 val, int reg) > { > - outl(val, uhci->io_addr + reg); > + UHCI_OUT(outl(val, uhci->io_addr + reg)); I'm confused now. So if CONFIG_HAS_IOPORT is enabled, wonderful, all is good. But if it isn't, then these are just no-ops that do nothing? So then the driver will fail to work? Why have these stubs at all? Why not just not build the driver at all if this option is not enabled? thanks, greg k-h
On Tue, May 16, 2023, at 18:29, Greg Kroah-Hartman wrote: > On Tue, May 16, 2023 at 01:00:31PM +0200, Niklas Schnelle wrote: >> #ifndef CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC >> /* Support PCI only */ >> static inline u32 uhci_readl(const struct uhci_hcd *uhci, int reg) >> { >> - return inl(uhci->io_addr + reg); >> + return UHCI_IN(inl(uhci->io_addr + reg)); >> } >> >> static inline void uhci_writel(const struct uhci_hcd *uhci, u32 val, int reg) >> { >> - outl(val, uhci->io_addr + reg); >> + UHCI_OUT(outl(val, uhci->io_addr + reg)); > > I'm confused now. > > So if CONFIG_HAS_IOPORT is enabled, wonderful, all is good. > > But if it isn't, then these are just no-ops that do nothing? So then > the driver will fail to work? Why have these stubs at all? > > Why not just not build the driver at all if this option is not enabled? If I remember correctly, the problem here is the lack of abstractions in the uhci driver, it instead supports all combinations of on-chip non-PCI devices using readb()/writeb() and PCI devices using inb()/outb() in a shared codebase. A particularly tricky combination is a kernel that supports on-chip UHCI as well as CONFIG_USB_PCI (for EHCI/XHCI) but does not support I/O ports because of platform limitations. The trick is to come up with a set of changes that doesn't have to rewrite the entire logic but also doesn't add an obscene number of #ifdef checks. That said, there is a minor problem with the empty definition +#define UHCI_OUT(x) I think this should be "do { } while (0)" to avoid warnings about empty if/else blocks. Arnd
On Tue, May 16, 2023 at 06:44:34PM +0200, Arnd Bergmann wrote: > On Tue, May 16, 2023, at 18:29, Greg Kroah-Hartman wrote: > > On Tue, May 16, 2023 at 01:00:31PM +0200, Niklas Schnelle wrote: > > >> #ifndef CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC > >> /* Support PCI only */ > >> static inline u32 uhci_readl(const struct uhci_hcd *uhci, int reg) > >> { > >> - return inl(uhci->io_addr + reg); > >> + return UHCI_IN(inl(uhci->io_addr + reg)); > >> } > >> > >> static inline void uhci_writel(const struct uhci_hcd *uhci, u32 val, int reg) > >> { > >> - outl(val, uhci->io_addr + reg); > >> + UHCI_OUT(outl(val, uhci->io_addr + reg)); > > > > I'm confused now. > > > > So if CONFIG_HAS_IOPORT is enabled, wonderful, all is good. > > > > But if it isn't, then these are just no-ops that do nothing? So then > > the driver will fail to work? Why have these stubs at all? > > > > Why not just not build the driver at all if this option is not enabled? > > If I remember correctly, the problem here is the lack of > abstractions in the uhci driver, it instead supports all > combinations of on-chip non-PCI devices using readb()/writeb() > and PCI devices using inb()/outb() in a shared codebase. Isn't that an abstraction? A single set of operations (uhci_readl(), uhci_writel(), etc.) that always does the right sort of I/O even when talking to different buses? So I'm not sure what you mean by "the lack of abstractions". > A particularly tricky combination is a kernel that supports on-chip > UHCI as well as CONFIG_USB_PCI (for EHCI/XHCI) but does not support > I/O ports because of platform limitations. The trick is to come up > with a set of changes that doesn't have to rewrite the entire logic > but also doesn't add an obscene number of #ifdef checks. Indeed, in a kernel supporting that tricky combination the no-op code would be generated. But it would never execute at runtime because the uhci_has_pci_registers(uhci) test would always return 0, and so the driver wouldn't fail. > That said, there is a minor problem with the empty definition > > +#define UHCI_OUT(x) > > I think this should be "do { } while (0)" to avoid warnings > about empty if/else blocks. I'm sure Niklas wouldn't mind making such a change. But do we really get such warnings? Does the compiler really think that this kind of (macro-expanded) code: if (uhci_has_pci_registers(uhci)) ; else if (uhci_is_aspeed(uhci)) writel(val, uhci->regs + uhci_aspeed_reg(reg)); deserves a warning? I write stuff like that fairly often; it's a good way to showcase a high-probability do-nothing pathway at the start of a series of conditional cases. And I haven't noticed any complaints from the compiler. Alan Stern
On Tue, May 16, 2023 at 06:29:56PM +0200, Greg Kroah-Hartman wrote: > On Tue, May 16, 2023 at 01:00:31PM +0200, Niklas Schnelle wrote: > > In a future patch HAS_IOPORT=n will result in inb()/outb() and friends > > not being declared. We thus need to guard sections of code calling them > > as alternative access methods with CONFIG_HAS_IOPORT checks. For > > uhci-hcd there are a lot of I/O port uses that do have MMIO alternatives > > all selected by uhci_has_pci_registers() so this can be handled by > > UHCI_IN/OUT macros and making uhci_has_pci_registers() constant 0 if > > CONFIG_HAS_IOPORT is unset. > > > > Co-developed-by: Arnd Bergmann <arnd@kernel.org> > > Signed-off-by: Arnd Bergmann <arnd@kernel.org> > > Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com> > > --- > > Note: The HAS_IOPORT Kconfig option was added in v6.4-rc1 so > > per-subsystem patches may be applied independently > > > > drivers/usb/host/uhci-hcd.c | 2 +- > > drivers/usb/host/uhci-hcd.h | 36 +++++++++++++++++++++++------------- > > 2 files changed, 24 insertions(+), 14 deletions(-) > > > > diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c > > index 7cdc2fa7c28f..fd2408b553cf 100644 > > --- a/drivers/usb/host/uhci-hcd.c > > +++ b/drivers/usb/host/uhci-hcd.c > > @@ -841,7 +841,7 @@ static int uhci_count_ports(struct usb_hcd *hcd) > > > > static const char hcd_name[] = "uhci_hcd"; > > > > -#ifdef CONFIG_USB_PCI > > +#if defined(CONFIG_USB_PCI) && defined(CONFIG_HAS_IOPORT) > > #include "uhci-pci.c" > > #define PCI_DRIVER uhci_pci_driver > > #endif > > diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h > > index 0688c3e5bfe2..c77705d03ed0 100644 > > --- a/drivers/usb/host/uhci-hcd.h > > +++ b/drivers/usb/host/uhci-hcd.h > > @@ -505,41 +505,49 @@ static inline bool uhci_is_aspeed(const struct uhci_hcd *uhci) > > * we use memory mapped registers. > > */ > > > > +#ifdef CONFIG_HAS_IOPORT > > +#define UHCI_IN(x) x > > +#define UHCI_OUT(x) x > > +#else > > +#define UHCI_IN(x) 0 > > +#define UHCI_OUT(x) > > +#endif > > + > > #ifndef CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC > > /* Support PCI only */ > > static inline u32 uhci_readl(const struct uhci_hcd *uhci, int reg) > > { > > - return inl(uhci->io_addr + reg); > > + return UHCI_IN(inl(uhci->io_addr + reg)); > > } > > > > static inline void uhci_writel(const struct uhci_hcd *uhci, u32 val, int reg) > > { > > - outl(val, uhci->io_addr + reg); > > + UHCI_OUT(outl(val, uhci->io_addr + reg)); > > I'm confused now. > > So if CONFIG_HAS_IOPORT is enabled, wonderful, all is good. > > But if it isn't, then these are just no-ops that do nothing? So then > the driver will fail to work? Why have these stubs at all? > > Why not just not build the driver at all if this option is not enabled? I should add something to my previous email. This particular section of code is protected by: #ifndef CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC /* Support PCI only */ So it gets used only in cases where the driver supports just a PCI bus -- no other sorts of non-PCI on-chip devices. But the preceding patch in this series changes the Kconfig file to say: config USB_UHCI_HCD tristate "UHCI HCD (most Intel and VIA) support" depends on (USB_PCI && HAS_IOPORT) || USB_UHCI_SUPPORT_NON_PCI_HC As a result, when the configuration includes support only for PCI controllers the driver won't get built unless HAS_IOPORT is set. Thus the no-op case (in this part of the code) can't arise. Which is a long-winded way of saying that you're right; the UHCI_IN() and UHCI_OUT() wrappers aren't needed in this part of the driver. I guess Niklas put them in either for consistency with the rest of the code or because it didn't occur to him that they could be omitted. (And I didn't spot it either.) Alan Stern
On Tue, 2023-05-16 at 15:51 -0400, Alan Stern wrote: > On Tue, May 16, 2023 at 06:44:34PM +0200, Arnd Bergmann wrote: > > On Tue, May 16, 2023, at 18:29, Greg Kroah-Hartman wrote: > > > On Tue, May 16, 2023 at 01:00:31PM +0200, Niklas Schnelle wrote: > > > > > > #ifndef CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC > > > > /* Support PCI only */ > > > > static inline u32 uhci_readl(const struct uhci_hcd *uhci, int reg) > > > > { > > > > - return inl(uhci->io_addr + reg); > > > > + return UHCI_IN(inl(uhci->io_addr + reg)); > > > > } > > > > > > > > static inline void uhci_writel(const struct uhci_hcd *uhci, u32 val, int reg) > > > > { > > > > - outl(val, uhci->io_addr + reg); > > > > + UHCI_OUT(outl(val, uhci->io_addr + reg)); > > > > > > I'm confused now. > > > > > > So if CONFIG_HAS_IOPORT is enabled, wonderful, all is good. > > > > > > But if it isn't, then these are just no-ops that do nothing? So then > > > the driver will fail to work? Why have these stubs at all? > > > > > > Why not just not build the driver at all if this option is not enabled? The driver supports multiple access methods in several functions similar to the following: static inline void uhci_writel(const struct uhci_hcd *uhci, u32 val, int reg) { if (uhci_has_pci_registers(uhci)) UHCI_OUT(outl(val, uhci->io_addr + reg)); else if (uhci_is_aspeed(uhci)) writel(val, uhci->regs + uhci_aspeed_reg(reg)); #ifdef CONFIG_USB_UHCI_BIG_ENDIAN_MMIO else if (uhci_big_endian_mmio(uhci)) writel_be(val, uhci->regs + reg); #endif else writel(val, uhci->regs + reg); } Instead of adding more #ifdefs Alan Stern suggested to just stub out both uhci_has_pci_registers() and the access itself. So with a half way optimizing compiler this shouldn't even leave no-ops in the binary. > > > That said, there is a minor problem with the empty definition > > > > +#define UHCI_OUT(x) > > > > I think this should be "do { } while (0)" to avoid warnings > > about empty if/else blocks. > > I'm sure Niklas wouldn't mind making such a change. But do we really > get such warnings? Does the compiler really think that this kind of > (macro-expanded) code: > > if (uhci_has_pci_registers(uhci)) > ; > else if (uhci_is_aspeed(uhci)) > writel(val, uhci->regs + uhci_aspeed_reg(reg)); > > deserves a warning? I write stuff like that fairly often; it's a good > way to showcase a high-probability do-nothing pathway at the start of a > series of conditional cases. And I haven't noticed any complaints from > the compiler. > > Alan Stern I changed it to "do {} while (0)" for v5 but agree I haven't seen warnings for this either. Still doesn't hurt. Thanks, Niklas
On Tue, May 16, 2023, at 22:17, Alan Stern wrote: > On Tue, May 16, 2023 at 06:29:56PM +0200, Greg Kroah-Hartman wrote: >> On Tue, May 16, 2023 at 01:00:31PM +0200, Niklas Schnelle wrote: > >> I'm confused now. >> >> So if CONFIG_HAS_IOPORT is enabled, wonderful, all is good. >> >> But if it isn't, then these are just no-ops that do nothing? So then >> the driver will fail to work? Why have these stubs at all? >> >> Why not just not build the driver at all if this option is not enabled? > > I should add something to my previous email. This particular section of > code is protected by: > > #ifndef CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC > /* Support PCI only */ > > So it gets used only in cases where the driver supports just a PCI bus > -- no other sorts of non-PCI on-chip devices. But the preceding patch > in this series changes the Kconfig file to say: > > config USB_UHCI_HCD > tristate "UHCI HCD (most Intel and VIA) support" > depends on (USB_PCI && HAS_IOPORT) || USB_UHCI_SUPPORT_NON_PCI_HC > > As a result, when the configuration includes support only for PCI > controllers the driver won't get built unless HAS_IOPORT is set. Thus > the no-op case (in this part of the code) can't arise. Indeed, that makes sense. > Which is a long-winded way of saying that you're right; the UHCI_IN() > and UHCI_OUT() wrappers aren't needed in this part of the driver. I > guess Niklas put them in either for consistency with the rest of the > code or because it didn't occur to him that they could be omitted. (And > I didn't spot it either.) It's probably less confusing to leave out the PCI-only part of the patch then and only modify the generic portion. Arnd
On Wed, 2023-05-17 at 14:17 +0200, Arnd Bergmann wrote: > On Tue, May 16, 2023, at 22:17, Alan Stern wrote: > > On Tue, May 16, 2023 at 06:29:56PM +0200, Greg Kroah-Hartman wrote: > > > On Tue, May 16, 2023 at 01:00:31PM +0200, Niklas Schnelle wrote: > > > > > I'm confused now. > > > > > > So if CONFIG_HAS_IOPORT is enabled, wonderful, all is good. > > > > > > But if it isn't, then these are just no-ops that do nothing? So then > > > the driver will fail to work? Why have these stubs at all? > > > > > > Why not just not build the driver at all if this option is not enabled? > > > > I should add something to my previous email. This particular section of > > code is protected by: > > > > #ifndef CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC > > /* Support PCI only */ > > > > So it gets used only in cases where the driver supports just a PCI bus > > -- no other sorts of non-PCI on-chip devices. But the preceding patch > > in this series changes the Kconfig file to say: > > > > config USB_UHCI_HCD > > tristate "UHCI HCD (most Intel and VIA) support" > > depends on (USB_PCI && HAS_IOPORT) || USB_UHCI_SUPPORT_NON_PCI_HC > > > > As a result, when the configuration includes support only for PCI > > controllers the driver won't get built unless HAS_IOPORT is set. Thus > > the no-op case (in this part of the code) can't arise. > > Indeed, that makes sense. > > > Which is a long-winded way of saying that you're right; the UHCI_IN() > > and UHCI_OUT() wrappers aren't needed in this part of the driver. I > > guess Niklas put them in either for consistency with the rest of the > > code or because it didn't occur to him that they could be omitted. (And > > I didn't spot it either.) > > It's probably less confusing to leave out the PCI-only part of > the patch then and only modify the generic portion. > > Arnd Yes I agree that way the UHCI_IN/OUT() macro is also only used directly in combination with uhci_has_pci_registers(). I've done this for v5. Thanks, Niklas
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 7cdc2fa7c28f..fd2408b553cf 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -841,7 +841,7 @@ static int uhci_count_ports(struct usb_hcd *hcd) static const char hcd_name[] = "uhci_hcd"; -#ifdef CONFIG_USB_PCI +#if defined(CONFIG_USB_PCI) && defined(CONFIG_HAS_IOPORT) #include "uhci-pci.c" #define PCI_DRIVER uhci_pci_driver #endif diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 0688c3e5bfe2..c77705d03ed0 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h @@ -505,41 +505,49 @@ static inline bool uhci_is_aspeed(const struct uhci_hcd *uhci) * we use memory mapped registers. */ +#ifdef CONFIG_HAS_IOPORT +#define UHCI_IN(x) x +#define UHCI_OUT(x) x +#else +#define UHCI_IN(x) 0 +#define UHCI_OUT(x) +#endif + #ifndef CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC /* Support PCI only */ static inline u32 uhci_readl(const struct uhci_hcd *uhci, int reg) { - return inl(uhci->io_addr + reg); + return UHCI_IN(inl(uhci->io_addr + reg)); } static inline void uhci_writel(const struct uhci_hcd *uhci, u32 val, int reg) { - outl(val, uhci->io_addr + reg); + UHCI_OUT(outl(val, uhci->io_addr + reg)); } static inline u16 uhci_readw(const struct uhci_hcd *uhci, int reg) { - return inw(uhci->io_addr + reg); + return UHCI_IN(inw(uhci->io_addr + reg)); } static inline void uhci_writew(const struct uhci_hcd *uhci, u16 val, int reg) { - outw(val, uhci->io_addr + reg); + UHCI_OUT(outw(val, uhci->io_addr + reg)); } static inline u8 uhci_readb(const struct uhci_hcd *uhci, int reg) { - return inb(uhci->io_addr + reg); + return UHCI_IN(inb(uhci->io_addr + reg)); } static inline void uhci_writeb(const struct uhci_hcd *uhci, u8 val, int reg) { - outb(val, uhci->io_addr + reg); + UHCI_OUT(outb(val, uhci->io_addr + reg)); } #else /* Support non-PCI host controllers */ -#ifdef CONFIG_USB_PCI +#if defined(CONFIG_USB_PCI) && defined(HAS_IOPORT) /* Support PCI and non-PCI host controllers */ #define uhci_has_pci_registers(u) ((u)->io_addr != 0) #else @@ -587,7 +595,7 @@ static inline int uhci_aspeed_reg(unsigned int reg) static inline u32 uhci_readl(const struct uhci_hcd *uhci, int reg) { if (uhci_has_pci_registers(uhci)) - return inl(uhci->io_addr + reg); + return UHCI_IN(inl(uhci->io_addr + reg)); else if (uhci_is_aspeed(uhci)) return readl(uhci->regs + uhci_aspeed_reg(reg)); #ifdef CONFIG_USB_UHCI_BIG_ENDIAN_MMIO @@ -601,7 +609,7 @@ static inline u32 uhci_readl(const struct uhci_hcd *uhci, int reg) static inline void uhci_writel(const struct uhci_hcd *uhci, u32 val, int reg) { if (uhci_has_pci_registers(uhci)) - outl(val, uhci->io_addr + reg); + UHCI_OUT(outl(val, uhci->io_addr + reg)); else if (uhci_is_aspeed(uhci)) writel(val, uhci->regs + uhci_aspeed_reg(reg)); #ifdef CONFIG_USB_UHCI_BIG_ENDIAN_MMIO @@ -615,7 +623,7 @@ static inline void uhci_writel(const struct uhci_hcd *uhci, u32 val, int reg) static inline u16 uhci_readw(const struct uhci_hcd *uhci, int reg) { if (uhci_has_pci_registers(uhci)) - return inw(uhci->io_addr + reg); + return UHCI_IN(inw(uhci->io_addr + reg)); else if (uhci_is_aspeed(uhci)) return readl(uhci->regs + uhci_aspeed_reg(reg)); #ifdef CONFIG_USB_UHCI_BIG_ENDIAN_MMIO @@ -629,7 +637,7 @@ static inline u16 uhci_readw(const struct uhci_hcd *uhci, int reg) static inline void uhci_writew(const struct uhci_hcd *uhci, u16 val, int reg) { if (uhci_has_pci_registers(uhci)) - outw(val, uhci->io_addr + reg); + UHCI_OUT(outw(val, uhci->io_addr + reg)); else if (uhci_is_aspeed(uhci)) writel(val, uhci->regs + uhci_aspeed_reg(reg)); #ifdef CONFIG_USB_UHCI_BIG_ENDIAN_MMIO @@ -643,7 +651,7 @@ static inline void uhci_writew(const struct uhci_hcd *uhci, u16 val, int reg) static inline u8 uhci_readb(const struct uhci_hcd *uhci, int reg) { if (uhci_has_pci_registers(uhci)) - return inb(uhci->io_addr + reg); + return UHCI_IN(inb(uhci->io_addr + reg)); else if (uhci_is_aspeed(uhci)) return readl(uhci->regs + uhci_aspeed_reg(reg)); #ifdef CONFIG_USB_UHCI_BIG_ENDIAN_MMIO @@ -657,7 +665,7 @@ static inline u8 uhci_readb(const struct uhci_hcd *uhci, int reg) static inline void uhci_writeb(const struct uhci_hcd *uhci, u8 val, int reg) { if (uhci_has_pci_registers(uhci)) - outb(val, uhci->io_addr + reg); + UHCI_OUT(outb(val, uhci->io_addr + reg)); else if (uhci_is_aspeed(uhci)) writel(val, uhci->regs + uhci_aspeed_reg(reg)); #ifdef CONFIG_USB_UHCI_BIG_ENDIAN_MMIO @@ -668,6 +676,8 @@ static inline void uhci_writeb(const struct uhci_hcd *uhci, u8 val, int reg) writeb(val, uhci->regs + reg); } #endif /* CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC */ +#undef UHCI_IN +#undef UHCI_OUT /* * The GRLIB GRUSBHC controller can use big endian format for its descriptors.