From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A525CC4332F for ; Fri, 11 Nov 2022 13:56:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233969AbiKKN4R (ORCPT ); Fri, 11 Nov 2022 08:56:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59582 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233801AbiKKNzl (ORCPT ); Fri, 11 Nov 2022 08:55:41 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1BF8778312; Fri, 11 Nov 2022 05:54:45 -0800 (PST) Message-ID: <20221111122014.640052354@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1668174884; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=kRlEyVKKnxgc8wl62QvRU5nn9b1AZrPtWorLrgk375w=; b=ryg7ebz1ONkJp0BcF1tctqW/uo0TmYwk0M6DtUb4Qn1AD8mgQ8aFowTJsj/fYjtGqjKQ6Y 8pJ7TqZ5qm8LAYIPzt4XY2dea7aga7xIjPc/Gsr9KpqpHe2CjrS/7+ERr3KWCSzV/0A3+o cMavcFEzD5YtUPC6WgiK3TmqbNwhS4cWxO6S/w4fRL3w3GUHOtsmWyaoCGfI2kGsoW6Ebj f1zDZpAisWpCM5Vsxq+vr8maslsCRDHK1+2+7nG6eVFf93aDVuyNHvIdE5TNkzxEDun/Cc mU4CkGo/PQPzwlKHrGs9gY1ar04p8XRxdmoxmwkgEiyPWZeJekQ36NPz6A/4ug== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1668174884; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=kRlEyVKKnxgc8wl62QvRU5nn9b1AZrPtWorLrgk375w=; b=ofJHjiRin0h7f5PMtU9l0xr54GINmGaThK/QZV+71VLlJINnxO9w97aT1aoGQ5bQKcTog+ aFDIPBRjC7itWZBw== From: Thomas Gleixner To: LKML Cc: x86@kernel.org, Joerg Roedel , Will Deacon , linux-pci@vger.kernel.org, Bjorn Helgaas , Lorenzo Pieralisi , Marc Zyngier , Greg Kroah-Hartman , Jason Gunthorpe , Dave Jiang , Alex Williamson , Kevin Tian , Dan Williams , Logan Gunthorpe , Ashok Raj , Jon Mason , Allen Hubbe , "Ahmed S. Darwish" , Reinette Chatre , Michael Ellerman , Christophe Leroy , linuxppc-dev@lists.ozlabs.org Subject: [patch 18/39] PCI/MSI: Move mask and unmask helpers to msi.h References: <20221111120501.026511281@linutronix.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Date: Fri, 11 Nov 2022 14:54:43 +0100 (CET) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Ahmed S. Darwish The upcoming support for per device MSI interrupt domains needs to share some of the inline helpers with the MSI implementation. Move them to the header file. Signed-off-by: Ahmed S. Darwish Signed-off-by: Thomas Gleixner --- drivers/pci/msi/msi.c | 61 +-------------------------------------- drivers/pci/msi/msi.h | 83 +++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 74 insertions(+), 70 deletions(-) --- diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c index 160af9f01669..5c310df55d0d 100644 --- a/drivers/pci/msi/msi.c +++ b/drivers/pci/msi/msi.c @@ -16,7 +16,7 @@ static int pci_msi_enable = 1; int pci_msi_ignore_mask; -static noinline void pci_msi_update_mask(struct msi_desc *desc, u32 clear, u32 set) +void pci_msi_update_mask(struct msi_desc *desc, u32 clear, u32 set) { raw_spinlock_t *lock = &to_pci_dev(desc->dev)->msi_lock; unsigned long flags; @@ -32,65 +32,6 @@ static noinline void pci_msi_update_mask(struct msi_desc *desc, u32 clear, u32 s raw_spin_unlock_irqrestore(lock, flags); } -static inline void pci_msi_mask(struct msi_desc *desc, u32 mask) -{ - pci_msi_update_mask(desc, 0, mask); -} - -static inline void pci_msi_unmask(struct msi_desc *desc, u32 mask) -{ - pci_msi_update_mask(desc, mask, 0); -} - -static inline void __iomem *pci_msix_desc_addr(struct msi_desc *desc) -{ - return desc->pci.mask_base + desc->msi_index * PCI_MSIX_ENTRY_SIZE; -} - -/* - * This internal function does not flush PCI writes to the device. All - * users must ensure that they read from the device before either assuming - * that the device state is up to date, or returning out of this file. - * It does not affect the msi_desc::msix_ctrl cache either. Use with care! - */ -static void pci_msix_write_vector_ctrl(struct msi_desc *desc, u32 ctrl) -{ - void __iomem *desc_addr = pci_msix_desc_addr(desc); - - if (desc->pci.msi_attrib.can_mask) - writel(ctrl, desc_addr + PCI_MSIX_ENTRY_VECTOR_CTRL); -} - -static inline void pci_msix_mask(struct msi_desc *desc) -{ - desc->pci.msix_ctrl |= PCI_MSIX_ENTRY_CTRL_MASKBIT; - pci_msix_write_vector_ctrl(desc, desc->pci.msix_ctrl); - /* Flush write to device */ - readl(desc->pci.mask_base); -} - -static inline void pci_msix_unmask(struct msi_desc *desc) -{ - desc->pci.msix_ctrl &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; - pci_msix_write_vector_ctrl(desc, desc->pci.msix_ctrl); -} - -static void __pci_msi_mask_desc(struct msi_desc *desc, u32 mask) -{ - if (desc->pci.msi_attrib.is_msix) - pci_msix_mask(desc); - else - pci_msi_mask(desc, mask); -} - -static void __pci_msi_unmask_desc(struct msi_desc *desc, u32 mask) -{ - if (desc->pci.msi_attrib.is_msix) - pci_msix_unmask(desc); - else - pci_msi_unmask(desc, mask); -} - /** * pci_msi_mask_irq - Generic IRQ chip callback to mask PCI/MSI interrupts * @data: pointer to irqdata associated to that interrupt diff --git a/drivers/pci/msi/msi.h b/drivers/pci/msi/msi.h index fc92603b33e1..d8f62d911f08 100644 --- a/drivers/pci/msi/msi.h +++ b/drivers/pci/msi/msi.h @@ -8,21 +8,67 @@ int pci_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); void pci_msi_teardown_msi_irqs(struct pci_dev *dev); -#ifdef CONFIG_PCI_MSI_ARCH_FALLBACKS -int pci_msi_legacy_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); -void pci_msi_legacy_teardown_msi_irqs(struct pci_dev *dev); -#else -static inline int pci_msi_legacy_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) +/* Mask/unmask helpers */ +void pci_msi_update_mask(struct msi_desc *desc, u32 clear, u32 set); + +static inline void pci_msi_mask(struct msi_desc *desc, u32 mask) { - WARN_ON_ONCE(1); - return -ENODEV; + pci_msi_update_mask(desc, 0, mask); } -static inline void pci_msi_legacy_teardown_msi_irqs(struct pci_dev *dev) +static inline void pci_msi_unmask(struct msi_desc *desc, u32 mask) { - WARN_ON_ONCE(1); + pci_msi_update_mask(desc, mask, 0); +} + +static inline void __iomem *pci_msix_desc_addr(struct msi_desc *desc) +{ + return desc->pci.mask_base + desc->msi_index * PCI_MSIX_ENTRY_SIZE; +} + +/* + * This internal function does not flush PCI writes to the device. All + * users must ensure that they read from the device before either assuming + * that the device state is up to date, or returning out of this file. + * It does not affect the msi_desc::msix_ctrl cache either. Use with care! + */ +static inline void pci_msix_write_vector_ctrl(struct msi_desc *desc, u32 ctrl) +{ + void __iomem *desc_addr = pci_msix_desc_addr(desc); + + if (desc->pci.msi_attrib.can_mask) + writel(ctrl, desc_addr + PCI_MSIX_ENTRY_VECTOR_CTRL); +} + +static inline void pci_msix_mask(struct msi_desc *desc) +{ + desc->pci.msix_ctrl |= PCI_MSIX_ENTRY_CTRL_MASKBIT; + pci_msix_write_vector_ctrl(desc, desc->pci.msix_ctrl); + /* Flush write to device */ + readl(desc->pci.mask_base); +} + +static inline void pci_msix_unmask(struct msi_desc *desc) +{ + desc->pci.msix_ctrl &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; + pci_msix_write_vector_ctrl(desc, desc->pci.msix_ctrl); +} + +static inline void __pci_msi_mask_desc(struct msi_desc *desc, u32 mask) +{ + if (desc->pci.msi_attrib.is_msix) + pci_msix_mask(desc); + else + pci_msi_mask(desc, mask); +} + +static inline void __pci_msi_unmask_desc(struct msi_desc *desc, u32 mask) +{ + if (desc->pci.msi_attrib.is_msix) + pci_msix_unmask(desc); + else + pci_msi_unmask(desc, mask); } -#endif /* * PCI 2.3 does not specify mask bits for each MSI interrupt. Attempting to @@ -37,3 +83,20 @@ static inline __attribute_const__ u32 msi_multi_mask(struct msi_desc *desc) return 0xffffffff; return (1 << (1 << desc->pci.msi_attrib.multi_cap)) - 1; } + +/* Legacy (!IRQDOMAIN) fallbacks */ +#ifdef CONFIG_PCI_MSI_ARCH_FALLBACKS +int pci_msi_legacy_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); +void pci_msi_legacy_teardown_msi_irqs(struct pci_dev *dev); +#else +static inline int pci_msi_legacy_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) +{ + WARN_ON_ONCE(1); + return -ENODEV; +} + +static inline void pci_msi_legacy_teardown_msi_irqs(struct pci_dev *dev) +{ + WARN_ON_ONCE(1); +} +#endif From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.ozlabs.org (lists.ozlabs.org [112.213.38.117]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id ACD96C4332F for ; Fri, 11 Nov 2022 14:29:24 +0000 (UTC) Received: from boromir.ozlabs.org (localhost [IPv6:::1]) by lists.ozlabs.org (Postfix) with ESMTP id 4N81LC2GWxz3fBL for ; Sat, 12 Nov 2022 01:29:23 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=linutronix.de header.i=@linutronix.de header.a=rsa-sha256 header.s=2020 header.b=ryg7ebz1; dkim=fail reason="signature verification failed" header.d=linutronix.de header.i=@linutronix.de header.a=ed25519-sha256 header.s=2020e header.b=ofJHjiRi; dkim-atps=neutral Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=linutronix.de (client-ip=193.142.43.55; helo=galois.linutronix.de; envelope-from=tglx@linutronix.de; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=linutronix.de header.i=@linutronix.de header.a=rsa-sha256 header.s=2020 header.b=ryg7ebz1; dkim=pass header.d=linutronix.de header.i=@linutronix.de header.a=ed25519-sha256 header.s=2020e header.b=ofJHjiRi; dkim-atps=neutral Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4N80pD26Z4z3fKW for ; Sat, 12 Nov 2022 01:05:08 +1100 (AEDT) Message-ID: <20221111122014.640052354@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1668174884; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=kRlEyVKKnxgc8wl62QvRU5nn9b1AZrPtWorLrgk375w=; b=ryg7ebz1ONkJp0BcF1tctqW/uo0TmYwk0M6DtUb4Qn1AD8mgQ8aFowTJsj/fYjtGqjKQ6Y 8pJ7TqZ5qm8LAYIPzt4XY2dea7aga7xIjPc/Gsr9KpqpHe2CjrS/7+ERr3KWCSzV/0A3+o cMavcFEzD5YtUPC6WgiK3TmqbNwhS4cWxO6S/w4fRL3w3GUHOtsmWyaoCGfI2kGsoW6Ebj f1zDZpAisWpCM5Vsxq+vr8maslsCRDHK1+2+7nG6eVFf93aDVuyNHvIdE5TNkzxEDun/Cc mU4CkGo/PQPzwlKHrGs9gY1ar04p8XRxdmoxmwkgEiyPWZeJekQ36NPz6A/4ug== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1668174884; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=kRlEyVKKnxgc8wl62QvRU5nn9b1AZrPtWorLrgk375w=; b=ofJHjiRin0h7f5PMtU9l0xr54GINmGaThK/QZV+71VLlJINnxO9w97aT1aoGQ5bQKcTog+ aFDIPBRjC7itWZBw== From: Thomas Gleixner To: LKML Subject: [patch 18/39] PCI/MSI: Move mask and unmask helpers to msi.h References: <20221111120501.026511281@linutronix.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Date: Fri, 11 Nov 2022 14:54:43 +0100 (CET) X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-pci@vger.kernel.org, Will Deacon , Lorenzo Pieralisi , Dave Jiang , Ashok Raj , Joerg Roedel , x86@kernel.org, Jason Gunthorpe , Allen Hubbe , Kevin Tian , "Ahmed S. Darwish" , Jon Mason , linuxppc-dev@lists.ozlabs.org, Alex Williamson , Bjorn Helgaas , Dan Williams , Reinette Chatre , Greg Kroah-Hartman , Marc Zyngier , Logan Gunthorpe Errors-To: linuxppc-dev-bounces+linuxppc-dev=archiver.kernel.org@lists.ozlabs.org Sender: "Linuxppc-dev" From: Ahmed S. Darwish The upcoming support for per device MSI interrupt domains needs to share some of the inline helpers with the MSI implementation. Move them to the header file. Signed-off-by: Ahmed S. Darwish Signed-off-by: Thomas Gleixner --- drivers/pci/msi/msi.c | 61 +-------------------------------------- drivers/pci/msi/msi.h | 83 +++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 74 insertions(+), 70 deletions(-) --- diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c index 160af9f01669..5c310df55d0d 100644 --- a/drivers/pci/msi/msi.c +++ b/drivers/pci/msi/msi.c @@ -16,7 +16,7 @@ static int pci_msi_enable = 1; int pci_msi_ignore_mask; -static noinline void pci_msi_update_mask(struct msi_desc *desc, u32 clear, u32 set) +void pci_msi_update_mask(struct msi_desc *desc, u32 clear, u32 set) { raw_spinlock_t *lock = &to_pci_dev(desc->dev)->msi_lock; unsigned long flags; @@ -32,65 +32,6 @@ static noinline void pci_msi_update_mask(struct msi_desc *desc, u32 clear, u32 s raw_spin_unlock_irqrestore(lock, flags); } -static inline void pci_msi_mask(struct msi_desc *desc, u32 mask) -{ - pci_msi_update_mask(desc, 0, mask); -} - -static inline void pci_msi_unmask(struct msi_desc *desc, u32 mask) -{ - pci_msi_update_mask(desc, mask, 0); -} - -static inline void __iomem *pci_msix_desc_addr(struct msi_desc *desc) -{ - return desc->pci.mask_base + desc->msi_index * PCI_MSIX_ENTRY_SIZE; -} - -/* - * This internal function does not flush PCI writes to the device. All - * users must ensure that they read from the device before either assuming - * that the device state is up to date, or returning out of this file. - * It does not affect the msi_desc::msix_ctrl cache either. Use with care! - */ -static void pci_msix_write_vector_ctrl(struct msi_desc *desc, u32 ctrl) -{ - void __iomem *desc_addr = pci_msix_desc_addr(desc); - - if (desc->pci.msi_attrib.can_mask) - writel(ctrl, desc_addr + PCI_MSIX_ENTRY_VECTOR_CTRL); -} - -static inline void pci_msix_mask(struct msi_desc *desc) -{ - desc->pci.msix_ctrl |= PCI_MSIX_ENTRY_CTRL_MASKBIT; - pci_msix_write_vector_ctrl(desc, desc->pci.msix_ctrl); - /* Flush write to device */ - readl(desc->pci.mask_base); -} - -static inline void pci_msix_unmask(struct msi_desc *desc) -{ - desc->pci.msix_ctrl &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; - pci_msix_write_vector_ctrl(desc, desc->pci.msix_ctrl); -} - -static void __pci_msi_mask_desc(struct msi_desc *desc, u32 mask) -{ - if (desc->pci.msi_attrib.is_msix) - pci_msix_mask(desc); - else - pci_msi_mask(desc, mask); -} - -static void __pci_msi_unmask_desc(struct msi_desc *desc, u32 mask) -{ - if (desc->pci.msi_attrib.is_msix) - pci_msix_unmask(desc); - else - pci_msi_unmask(desc, mask); -} - /** * pci_msi_mask_irq - Generic IRQ chip callback to mask PCI/MSI interrupts * @data: pointer to irqdata associated to that interrupt diff --git a/drivers/pci/msi/msi.h b/drivers/pci/msi/msi.h index fc92603b33e1..d8f62d911f08 100644 --- a/drivers/pci/msi/msi.h +++ b/drivers/pci/msi/msi.h @@ -8,21 +8,67 @@ int pci_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); void pci_msi_teardown_msi_irqs(struct pci_dev *dev); -#ifdef CONFIG_PCI_MSI_ARCH_FALLBACKS -int pci_msi_legacy_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); -void pci_msi_legacy_teardown_msi_irqs(struct pci_dev *dev); -#else -static inline int pci_msi_legacy_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) +/* Mask/unmask helpers */ +void pci_msi_update_mask(struct msi_desc *desc, u32 clear, u32 set); + +static inline void pci_msi_mask(struct msi_desc *desc, u32 mask) { - WARN_ON_ONCE(1); - return -ENODEV; + pci_msi_update_mask(desc, 0, mask); } -static inline void pci_msi_legacy_teardown_msi_irqs(struct pci_dev *dev) +static inline void pci_msi_unmask(struct msi_desc *desc, u32 mask) { - WARN_ON_ONCE(1); + pci_msi_update_mask(desc, mask, 0); +} + +static inline void __iomem *pci_msix_desc_addr(struct msi_desc *desc) +{ + return desc->pci.mask_base + desc->msi_index * PCI_MSIX_ENTRY_SIZE; +} + +/* + * This internal function does not flush PCI writes to the device. All + * users must ensure that they read from the device before either assuming + * that the device state is up to date, or returning out of this file. + * It does not affect the msi_desc::msix_ctrl cache either. Use with care! + */ +static inline void pci_msix_write_vector_ctrl(struct msi_desc *desc, u32 ctrl) +{ + void __iomem *desc_addr = pci_msix_desc_addr(desc); + + if (desc->pci.msi_attrib.can_mask) + writel(ctrl, desc_addr + PCI_MSIX_ENTRY_VECTOR_CTRL); +} + +static inline void pci_msix_mask(struct msi_desc *desc) +{ + desc->pci.msix_ctrl |= PCI_MSIX_ENTRY_CTRL_MASKBIT; + pci_msix_write_vector_ctrl(desc, desc->pci.msix_ctrl); + /* Flush write to device */ + readl(desc->pci.mask_base); +} + +static inline void pci_msix_unmask(struct msi_desc *desc) +{ + desc->pci.msix_ctrl &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; + pci_msix_write_vector_ctrl(desc, desc->pci.msix_ctrl); +} + +static inline void __pci_msi_mask_desc(struct msi_desc *desc, u32 mask) +{ + if (desc->pci.msi_attrib.is_msix) + pci_msix_mask(desc); + else + pci_msi_mask(desc, mask); +} + +static inline void __pci_msi_unmask_desc(struct msi_desc *desc, u32 mask) +{ + if (desc->pci.msi_attrib.is_msix) + pci_msix_unmask(desc); + else + pci_msi_unmask(desc, mask); } -#endif /* * PCI 2.3 does not specify mask bits for each MSI interrupt. Attempting to @@ -37,3 +83,20 @@ static inline __attribute_const__ u32 msi_multi_mask(struct msi_desc *desc) return 0xffffffff; return (1 << (1 << desc->pci.msi_attrib.multi_cap)) - 1; } + +/* Legacy (!IRQDOMAIN) fallbacks */ +#ifdef CONFIG_PCI_MSI_ARCH_FALLBACKS +int pci_msi_legacy_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); +void pci_msi_legacy_teardown_msi_irqs(struct pci_dev *dev); +#else +static inline int pci_msi_legacy_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) +{ + WARN_ON_ONCE(1); + return -ENODEV; +} + +static inline void pci_msi_legacy_teardown_msi_irqs(struct pci_dev *dev) +{ + WARN_ON_ONCE(1); +} +#endif