{"id":2234826,"url":"http://patchwork.ozlabs.org/api/1.2/patches/2234826/?format=json","web_url":"http://patchwork.ozlabs.org/project/linuxppc-dev/patch/20260508043543.217179-23-kwilczynski@kernel.org/","project":{"id":2,"url":"http://patchwork.ozlabs.org/api/1.2/projects/2/?format=json","name":"Linux PPC development","link_name":"linuxppc-dev","list_id":"linuxppc-dev.lists.ozlabs.org","list_email":"linuxppc-dev@lists.ozlabs.org","web_url":"https://github.com/linuxppc/wiki/wiki","scm_url":"https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git","webscm_url":"https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/","list_archive_url":"https://lore.kernel.org/linuxppc-dev/","list_archive_url_format":"https://lore.kernel.org/linuxppc-dev/{}/","commit_url_format":"https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/commit/?id={}"},"msgid":"<20260508043543.217179-23-kwilczynski@kernel.org>","list_archive_url":"https://lore.kernel.org/linuxppc-dev/20260508043543.217179-23-kwilczynski@kernel.org/","date":"2026-05-08T04:35:41","name":"[v7,22/24] PCI/sysfs: Convert legacy I/O and memory attributes to static definitions","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"b184893c15ae67c364e8c52cb8c7dc75417a7bb5","submitter":{"id":86709,"url":"http://patchwork.ozlabs.org/api/1.2/people/86709/?format=json","name":"Krzysztof Wilczyński","email":"kwilczynski@kernel.org"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linuxppc-dev/patch/20260508043543.217179-23-kwilczynski@kernel.org/mbox/","series":[{"id":503322,"url":"http://patchwork.ozlabs.org/api/1.2/series/503322/?format=json","web_url":"http://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=503322","date":"2026-05-08T04:35:20","name":"PCI: Convert all dynamic sysfs attributes to static","version":7,"mbox":"http://patchwork.ozlabs.org/series/503322/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2234826/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2234826/checks/","tags":{},"related":[],"headers":{"Return-Path":"\n <linuxppc-dev+bounces-20606-incoming=patchwork.ozlabs.org@lists.ozlabs.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linuxppc-dev@lists.ozlabs.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=RaqT9k45;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org\n (client-ip=2404:9400:21b9:f100::1; helo=lists.ozlabs.org;\n envelope-from=linuxppc-dev+bounces-20606-incoming=patchwork.ozlabs.org@lists.ozlabs.org;\n receiver=patchwork.ozlabs.org)","lists.ozlabs.org;\n arc=none smtp.remote-ip=\"2600:3c0a:e001:78e:0:1991:8:25\"","lists.ozlabs.org;\n dmarc=pass (p=quarantine dis=none) header.from=kernel.org","lists.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=RaqT9k45;\n\tdkim-atps=neutral","lists.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=kernel.org\n (client-ip=2600:3c0a:e001:78e:0:1991:8:25; helo=sea.source.kernel.org;\n envelope-from=kwilczynski@kernel.org; receiver=lists.ozlabs.org)"],"Received":["from lists.ozlabs.org (lists.ozlabs.org\n [IPv6:2404:9400:21b9:f100::1])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4gBbwh2mncz1yJq\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 08 May 2026 14:38:44 +1000 (AEST)","from boromir.ozlabs.org (localhost [127.0.0.1])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 4gBbtw1LShz3cPK;\n\tFri, 08 May 2026 14:37:12 +1000 (AEST)","from sea.source.kernel.org (sea.source.kernel.org\n [IPv6:2600:3c0a:e001:78e:0:1991:8:25])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby lists.ozlabs.org (Postfix) with ESMTPS id 4gBbtv0H74z2xPb\n\tfor <linuxppc-dev@lists.ozlabs.org>; Fri, 08 May 2026 14:37:11 +1000 (AEST)","from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58])\n\tby sea.source.kernel.org (Postfix) with ESMTP id 0309F44049;\n\tFri,  8 May 2026 04:37:09 +0000 (UTC)","by smtp.kernel.org (Postfix) with ESMTPSA id 95A86C2BCB4;\n\tFri,  8 May 2026 04:37:05 +0000 (UTC)"],"ARC-Seal":"i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707; t=1778215032;\n\tcv=none;\n b=dMCLOVlmpIGy3t435q6kifbYATorY/h27I9GPtkjYALtV8AvyPZ/3hmyOqUW+Y6S29ocuzJp1q8uycBUUrU0KODyaBZMxsqlE5SNJYjhWy2qaoTH9GpBNvU9CpG8aPjMBeFhN/QGHgqRMV4YxRaerbBDsns7E0su3R59mYZdApXmWhekC4AQW1/sVRkfsy5DT9dSH3Rp1LzxLU8+OGHU0OUIGQds05i3YJb6jcsP3o3evuJ1bVuQB/GKgoFePbft731J0X1bKhKVremF35K8BuhCKWF28vofOERiXj05hWblY9KubT63/yItHSwPPgt8u2X35FG21wqDb4wli70HZw==","ARC-Message-Signature":"i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707;\n\tt=1778215032; c=relaxed/relaxed;\n\tbh=Tqz3/W1Ur8IQ6oLkqp1jj/dVz1s+mpHUaVgZMEzMUSo=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version:Content-Type;\n b=ayxbeGf0BxZpD33wikQaFTZYZHZdcraYeEfEjWIpEFjVWgoljI1BqaP/9xOMsa16cojZYWd3+4R6ISmZ0mEv+iKdEW12O3Hy1O/xYFDZcSTZAypakHQo+4gow0bJ1dyQhyHQ9prWAzo7Tth1lBTKcAKCwhDSXlgFTC1ze2ZJWAenqKXK0KiQp2CR5JsYXS9wIqpyP0UpZa8sUuMAbMmEVyTusEjIQBRlXSw3/kir3Cy0wtSssEsb4+yW0RjTD32HFqp4KdNFK0qKSUAARAg3qKsckQJc04Cl06omeHqhYbaY3EUqb0E/MasGMKFbx4EgrdxIOHui8UVnyS00rhiRLw==","ARC-Authentication-Results":"i=1; lists.ozlabs.org;\n dmarc=pass (p=quarantine dis=none) header.from=kernel.org;\n dkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=RaqT9k45; dkim-atps=neutral;\n spf=pass (client-ip=2600:3c0a:e001:78e:0:1991:8:25;\n helo=sea.source.kernel.org; envelope-from=kwilczynski@kernel.org;\n receiver=lists.ozlabs.org) smtp.mailfrom=kernel.org","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org;\n\ts=k20201202; t=1778215028;\n\tbh=G6UD1aaMiOXRzm8kwnIOIyTXuf7I20BRIy7t3eDKGHk=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=RaqT9k45tf2HKbqNoc6L4sev712QYa636E35uPMtdW+AOElCTeTp53DZv3gyynVA+\n\t LnHzueyh9HEaw2ks+9cMV4Adt1/zNfcn5uQ+qE05p04MLdrmTBqhdb30xHcBeoaWqJ\n\t Jzzk6d+QnTkAv3ZSB1AkB534VkWcKyEP7xeCkW5JtKz0AAUGfMksvb5qG+rbzJ39X8\n\t Rq75iVzbnWL8t5TybhoBhFH0iFCev6lefEKwMnazBMzSZgt2SselEotQB9K8R5rWwz\n\t XZRW/v77zRUc+wqwFZ7p/1E7a0lpl6ASGrFBhpSn0RLItNAy0ptC7tYRwRNR/iw9Ba\n\t ilwnlYdJFzBMw==","From":"=?utf-8?q?Krzysztof_Wilczy=C5=84ski?= <kwilczynski@kernel.org>","To":"Bjorn Helgaas <bhelgaas@google.com>","Cc":"Bjorn Helgaas <helgaas@kernel.org>,\n Manivannan Sadhasivam <mani@kernel.org>,\n Lorenzo Pieralisi <lpieralisi@kernel.org>,\n Alex Williamson <alex@shazbot.org>, Magnus Lindholm <linmag7@gmail.com>,\n Matt Turner <mattst88@gmail.com>,\n Richard Henderson <richard.henderson@linaro.org>,\n Christophe Leroy <chleroy@kernel.org>,\n Madhavan Srinivasan <maddy@linux.ibm.com>,\n Michael Ellerman <mpe@ellerman.id.au>, Nicholas Piggin <npiggin@gmail.com>,\n Dexuan Cui <decui@microsoft.com>,\n =?utf-8?q?Krzysztof_Ha=C5=82asa?= <khalasa@piap.pl>,\n Lukas Wunner <lukas@wunner.de>, \"Oliver O'Halloran\" <oohall@gmail.com>,\n Saurabh Singh Sengar <ssengar@microsoft.com>,\n Shuan He <heshuan@bytedance.com>, Srivatsa Bhat <srivatsabhat@microsoft.com>,\n\t=?utf-8?q?Ilpo_J=C3=A4rvinen?= <ilpo.jarvinen@linux.intel.com>,\n linux-pci@vger.kernel.org, linux-alpha@vger.kernel.org,\n linuxppc-dev@lists.ozlabs.org","Subject":"[PATCH v7 22/24] PCI/sysfs: Convert legacy I/O and memory attributes\n to static definitions","Date":"Fri,  8 May 2026 04:35:41 +0000","Message-ID":"<20260508043543.217179-23-kwilczynski@kernel.org>","X-Mailer":"git-send-email 2.54.0","In-Reply-To":"<20260508043543.217179-1-kwilczynski@kernel.org>","References":"<20260508043543.217179-1-kwilczynski@kernel.org>","X-Mailing-List":"linuxppc-dev@lists.ozlabs.org","List-Id":"<linuxppc-dev.lists.ozlabs.org>","List-Help":"<mailto:linuxppc-dev+help@lists.ozlabs.org>","List-Owner":"<mailto:linuxppc-dev+owner@lists.ozlabs.org>","List-Post":"<mailto:linuxppc-dev@lists.ozlabs.org>","List-Archive":"<https://lore.kernel.org/linuxppc-dev/>,\n  <https://lists.ozlabs.org/pipermail/linuxppc-dev/>","List-Subscribe":"<mailto:linuxppc-dev+subscribe@lists.ozlabs.org>,\n  <mailto:linuxppc-dev+subscribe-digest@lists.ozlabs.org>,\n  <mailto:linuxppc-dev+subscribe-nomail@lists.ozlabs.org>","List-Unsubscribe":"<mailto:linuxppc-dev+unsubscribe@lists.ozlabs.org>","Precedence":"list","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","X-Spam-Status":"No, score=-0.6 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED,\n\tDKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS\n\tautolearn=disabled version=4.0.1 OzLabs 8","X-Spam-Checker-Version":"SpamAssassin 4.0.1 (2024-03-25) on lists.ozlabs.org"},"content":"Currently, legacy_io and legacy_mem are dynamically allocated and\ncreated by pci_create_legacy_files(), with pci_adjust_legacy_attr()\nupdating the attributes at runtime on Alpha to rename them and shift\nthe size for sparse addressing.\n\nConvert to four static const attributes (legacy_io, legacy_io_sparse,\nlegacy_mem, legacy_mem_sparse) with is_bin_visible() callbacks that\nuse pci_legacy_has_sparse() to select the appropriate variant per bus.\nThe sizes are compile-time constants and .size is set directly on\neach attribute.\n\nRegister the groups in pcibus_groups[] under a HAVE_PCI_LEGACY guard\nso the driver model handles creation and removal automatically.\n\nStub out pci_create_legacy_files() and pci_remove_legacy_files() as\nthe dynamic creation is no longer needed.  Remove the __weak\npci_adjust_legacy_attr(), Alpha's override, and its declaration from\nboth Alpha and PowerPC asm/pci.h headers.\n\nTested-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>\nSigned-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>\n---\n arch/alpha/include/asm/pci.h   |   2 -\n arch/alpha/kernel/pci-sysfs.c  |  38 ++----\n arch/powerpc/include/asm/pci.h |   2 -\n drivers/pci/pci-sysfs.c        | 221 +++++++++++++++++++--------------\n 4 files changed, 135 insertions(+), 128 deletions(-)","diff":"diff --git a/arch/alpha/include/asm/pci.h b/arch/alpha/include/asm/pci.h\nindex 95de7ffd59e8..ad5d1391e1fa 100644\n--- a/arch/alpha/include/asm/pci.h\n+++ b/arch/alpha/include/asm/pci.h\n@@ -84,8 +84,6 @@ extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val,\n extern int pci_mmap_legacy_page_range(struct pci_bus *bus,\n \t\t\t\t      struct vm_area_struct *vma,\n \t\t\t\t      enum pci_mmap_state mmap_state);\n-extern void pci_adjust_legacy_attr(struct pci_bus *bus,\n-\t\t\t\t   enum pci_mmap_state mmap_type);\n extern bool pci_legacy_has_sparse(struct pci_bus *bus,\n \t\t\t\t  enum pci_mmap_state type);\n #define HAVE_PCI_LEGACY\t1\ndiff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c\nindex 2d46502ba09b..7dae4999c5e3 100644\n--- a/arch/alpha/kernel/pci-sysfs.c\n+++ b/arch/alpha/kernel/pci-sysfs.c\n@@ -192,30 +192,6 @@ bool pci_legacy_has_sparse(struct pci_bus *bus, enum pci_mmap_state type)\n \treturn has_sparse(hose, type);\n }\n \n-/**\n- * pci_adjust_legacy_attr - adjustment of legacy file attributes\n- * @bus: bus to create files under\n- * @mmap_type: I/O port or memory\n- *\n- * Adjust file name and size for sparse mappings.\n- */\n-void pci_adjust_legacy_attr(struct pci_bus *bus, enum pci_mmap_state mmap_type)\n-{\n-\tstruct pci_controller *hose = bus->sysdata;\n-\n-\tif (!has_sparse(hose, mmap_type))\n-\t\treturn;\n-\n-\tif (mmap_type == pci_mmap_mem) {\n-\t\tbus->legacy_mem->attr.name = \"legacy_mem_sparse\";\n-\t\tbus->legacy_mem->size <<= 5;\n-\t} else {\n-\t\tbus->legacy_io->attr.name = \"legacy_io_sparse\";\n-\t\tbus->legacy_io->size <<= 5;\n-\t}\n-\treturn;\n-}\n-\n /* Legacy I/O bus read/write functions */\n int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, size_t size)\n {\n@@ -292,9 +268,9 @@ static inline enum pci_mmap_state pci_bar_mmap_type(struct pci_dev *pdev,\n \treturn pci_resource_is_mem(pdev, bar) ? pci_mmap_mem : pci_mmap_io;\n }\n \n-static inline umode_t __pci_dev_resource_is_visible(struct kobject *kobj,\n-\t\t\t\t\t\t    const struct bin_attribute *a,\n-\t\t\t\t\t\t    int bar)\n+static inline umode_t __pci_resource_attr_is_visible(struct kobject *kobj,\n+\t\t\t\t\t\t     const struct bin_attribute *a,\n+\t\t\t\t\t\t     int bar)\n {\n \tstruct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));\n \n@@ -314,7 +290,7 @@ static umode_t pci_dev_resource_is_visible(struct kobject *kobj,\n \tif (has_sparse(hose, pci_bar_mmap_type(pdev, bar)))\n \t\treturn 0;\n \n-\treturn __pci_dev_resource_is_visible(kobj, a, bar);\n+\treturn __pci_resource_attr_is_visible(kobj, a, bar);\n }\n \n static umode_t pci_dev_resource_sparse_is_visible(struct kobject *kobj,\n@@ -331,7 +307,7 @@ static umode_t pci_dev_resource_sparse_is_visible(struct kobject *kobj,\n \tif (type == pci_mmap_mem && !sparse_mem_mmap_fits(pdev, bar))\n \t\treturn 0;\n \n-\treturn __pci_dev_resource_is_visible(kobj, a, bar);\n+\treturn __pci_resource_attr_is_visible(kobj, a, bar);\n }\n \n static umode_t pci_dev_resource_dense_is_visible(struct kobject *kobj,\n@@ -347,14 +323,14 @@ static umode_t pci_dev_resource_dense_is_visible(struct kobject *kobj,\n \t\treturn 0;\n \n \tif (type == pci_mmap_mem && !sparse_mem_mmap_fits(pdev, bar))\n-\t\treturn __pci_dev_resource_is_visible(kobj, a, bar);\n+\t\treturn __pci_resource_attr_is_visible(kobj, a, bar);\n \n \tdense_base = (type == pci_mmap_mem) ? hose->dense_mem_base :\n \t\t\t\t\t      hose->dense_io_base;\n \tif (!dense_base)\n \t\treturn 0;\n \n-\treturn __pci_dev_resource_is_visible(kobj, a, bar);\n+\treturn __pci_resource_attr_is_visible(kobj, a, bar);\n }\n \n static inline size_t __pci_dev_resource_bin_size(struct kobject *kobj,\ndiff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h\nindex 46a9c4491ed0..72f286e74786 100644\n--- a/arch/powerpc/include/asm/pci.h\n+++ b/arch/powerpc/include/asm/pci.h\n@@ -82,8 +82,6 @@ extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val,\n extern int pci_mmap_legacy_page_range(struct pci_bus *bus,\n \t\t\t\t      struct vm_area_struct *vma,\n \t\t\t\t      enum pci_mmap_state mmap_state);\n-extern void pci_adjust_legacy_attr(struct pci_bus *bus,\n-\t\t\t\t   enum pci_mmap_state mmap_type);\n #define HAVE_PCI_LEGACY\t1\n \n extern void pcibios_claim_one_bus(struct pci_bus *b);\ndiff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c\nindex 1e6786463e4e..868b42420358 100644\n--- a/drivers/pci/pci-sysfs.c\n+++ b/drivers/pci/pci-sysfs.c\n@@ -676,11 +676,6 @@ static const struct attribute_group pcibus_group = {\n \t.attrs = pcibus_attrs,\n };\n \n-const struct attribute_group *pcibus_groups[] = {\n-\t&pcibus_group,\n-\tNULL,\n-};\n-\n static ssize_t boot_vga_show(struct device *dev, struct device_attribute *attr,\n \t\t\t     char *buf)\n {\n@@ -879,19 +874,6 @@ static const struct attribute_group pci_dev_config_attr_group = {\n \t.bin_size = pci_dev_config_attr_bin_size,\n };\n \n-/*\n- * llseek operation for mmappable PCI resources.\n- * May be left unused if the arch doesn't provide them.\n- */\n-static __maybe_unused loff_t\n-pci_llseek_resource_legacy(struct file *filep,\n-\t\t\t   struct kobject *kobj __always_unused,\n-\t\t\t   const struct bin_attribute *attr,\n-\t\t\t   loff_t offset, int whence)\n-{\n-\treturn fixed_size_llseek(filep, offset, whence, attr->size);\n-}\n-\n #ifdef HAVE_PCI_LEGACY\n /**\n  * pci_read_legacy_io - read byte(s) from legacy I/O port space\n@@ -989,91 +971,144 @@ bool __weak pci_legacy_has_sparse(struct pci_bus *bus,\n \treturn false;\n }\n \n-/**\n- * pci_adjust_legacy_attr - adjustment of legacy file attributes\n- * @b: bus to create files under\n- * @mmap_type: I/O port or memory\n- *\n- * Stub implementation. Can be overridden by arch if necessary.\n- */\n-void __weak pci_adjust_legacy_attr(struct pci_bus *b,\n-\t\t\t\t   enum pci_mmap_state mmap_type)\n+static inline umode_t __pci_legacy_is_visible(struct kobject *kobj,\n+\t\t\t\t\t      const struct bin_attribute *a,\n+\t\t\t\t\t      enum pci_mmap_state type,\n+\t\t\t\t\t      bool sparse)\n {\n+\tstruct pci_bus *bus = to_pci_bus(kobj_to_dev(kobj));\n+\n+\tif (pci_legacy_has_sparse(bus, type) != sparse)\n+\t\treturn 0;\n+\n+\treturn a->attr.mode;\n }\n \n-/**\n- * pci_create_legacy_files - create legacy I/O port and memory files\n- * @b: bus to create files under\n- *\n- * Some platforms allow access to legacy I/O port and ISA memory space on\n- * a per-bus basis.  This routine creates the files and ties them into\n- * their associated read, write and mmap files from pci-sysfs.c\n- *\n- * On error unwind, but don't propagate the error to the caller\n- * as it is ok to set up the PCI bus without these files.\n- */\n-void pci_create_legacy_files(struct pci_bus *b)\n+static umode_t pci_legacy_io_is_visible(struct kobject *kobj,\n+\t\t\t\t\tconst struct bin_attribute *a, int n)\n {\n-\tint error;\n-\n-\tif (!sysfs_initialized)\n-\t\treturn;\n-\n-\tb->legacy_io = kzalloc_objs(struct bin_attribute, 2, GFP_ATOMIC);\n-\tif (!b->legacy_io)\n-\t\tgoto kzalloc_err;\n-\n-\tsysfs_bin_attr_init(b->legacy_io);\n-\tb->legacy_io->attr.name = \"legacy_io\";\n-\tb->legacy_io->size = PCI_LEGACY_IO_SIZE;\n-\tb->legacy_io->attr.mode = 0600;\n-\tb->legacy_io->read = pci_read_legacy_io;\n-\tb->legacy_io->write = pci_write_legacy_io;\n-\t/* See pci_create_attr() for motivation */\n-\tb->legacy_io->llseek = pci_llseek_resource_legacy;\n-\tb->legacy_io->mmap = pci_mmap_legacy_io;\n-\tb->legacy_io->f_mapping = iomem_get_mapping;\n-\tpci_adjust_legacy_attr(b, pci_mmap_io);\n-\terror = device_create_bin_file(&b->dev, b->legacy_io);\n-\tif (error)\n-\t\tgoto legacy_io_err;\n-\n-\t/* Allocated above after the legacy_io struct */\n-\tb->legacy_mem = b->legacy_io + 1;\n-\tsysfs_bin_attr_init(b->legacy_mem);\n-\tb->legacy_mem->attr.name = \"legacy_mem\";\n-\tb->legacy_mem->size = PCI_LEGACY_MEM_SIZE;\n-\tb->legacy_mem->attr.mode = 0600;\n-\tb->legacy_mem->mmap = pci_mmap_legacy_mem;\n-\t/* See pci_create_attr() for motivation */\n-\tb->legacy_mem->llseek = pci_llseek_resource_legacy;\n-\tb->legacy_mem->f_mapping = iomem_get_mapping;\n-\tpci_adjust_legacy_attr(b, pci_mmap_mem);\n-\terror = device_create_bin_file(&b->dev, b->legacy_mem);\n-\tif (error)\n-\t\tgoto legacy_mem_err;\n-\n-\treturn;\n-\n-legacy_mem_err:\n-\tdevice_remove_bin_file(&b->dev, b->legacy_io);\n-legacy_io_err:\n-\tkfree(b->legacy_io);\n-\tb->legacy_io = NULL;\n-kzalloc_err:\n-\tdev_warn(&b->dev, \"could not create legacy I/O port and ISA memory resources in sysfs\\n\");\n+\treturn __pci_legacy_is_visible(kobj, a, pci_mmap_io, false);\n }\n \n-void pci_remove_legacy_files(struct pci_bus *b)\n+static umode_t pci_legacy_io_sparse_is_visible(struct kobject *kobj,\n+\t\t\t\t\t       const struct bin_attribute *a,\n+\t\t\t\t\t       int n)\n {\n-\tif (b->legacy_io) {\n-\t\tdevice_remove_bin_file(&b->dev, b->legacy_io);\n-\t\tdevice_remove_bin_file(&b->dev, b->legacy_mem);\n-\t\tkfree(b->legacy_io); /* both are allocated here */\n-\t}\n+\treturn __pci_legacy_is_visible(kobj, a, pci_mmap_io, true);\n }\n+\n+static umode_t pci_legacy_mem_is_visible(struct kobject *kobj,\n+\t\t\t\t\t const struct bin_attribute *a, int n)\n+{\n+\treturn __pci_legacy_is_visible(kobj, a, pci_mmap_mem, false);\n+}\n+\n+static umode_t pci_legacy_mem_sparse_is_visible(struct kobject *kobj,\n+\t\t\t\t\t\tconst struct bin_attribute *a,\n+\t\t\t\t\t\tint n)\n+{\n+\treturn __pci_legacy_is_visible(kobj, a, pci_mmap_mem, true);\n+}\n+\n+static loff_t pci_llseek_resource_legacy(struct file *filep,\n+\t\t\t\t\t struct kobject *kobj __always_unused,\n+\t\t\t\t\t const struct bin_attribute *attr,\n+\t\t\t\t\t loff_t offset, int whence)\n+{\n+\treturn fixed_size_llseek(filep, offset, whence, attr->size);\n+}\n+\n+static const struct bin_attribute pci_legacy_io_attr = {\n+\t.attr = { .name = \"legacy_io\", .mode = 0600 },\n+\t.size = PCI_LEGACY_IO_SIZE,\n+\t.read = pci_read_legacy_io,\n+\t.write = pci_write_legacy_io,\n+\t.mmap = pci_mmap_legacy_io,\n+\t.llseek = pci_llseek_resource_legacy,\n+\t.f_mapping = iomem_get_mapping,\n+};\n+\n+static const struct bin_attribute pci_legacy_io_sparse_attr = {\n+\t.attr = { .name = \"legacy_io_sparse\", .mode = 0600 },\n+\t.size = PCI_LEGACY_IO_SIZE << 5,\n+\t.read = pci_read_legacy_io,\n+\t.write = pci_write_legacy_io,\n+\t.mmap = pci_mmap_legacy_io,\n+\t.llseek = pci_llseek_resource_legacy,\n+\t.f_mapping = iomem_get_mapping,\n+};\n+\n+static const struct bin_attribute pci_legacy_mem_attr = {\n+\t.attr = { .name = \"legacy_mem\", .mode = 0600 },\n+\t.size = PCI_LEGACY_MEM_SIZE,\n+\t.mmap = pci_mmap_legacy_mem,\n+\t.llseek = pci_llseek_resource_legacy,\n+\t.f_mapping = iomem_get_mapping,\n+};\n+\n+static const struct bin_attribute pci_legacy_mem_sparse_attr = {\n+\t.attr = { .name = \"legacy_mem_sparse\", .mode = 0600 },\n+\t.size = PCI_LEGACY_MEM_SIZE << 5,\n+\t.mmap = pci_mmap_legacy_mem,\n+\t.llseek = pci_llseek_resource_legacy,\n+\t.f_mapping = iomem_get_mapping,\n+};\n+\n+static const struct bin_attribute *const pci_legacy_io_attrs[] = {\n+\t&pci_legacy_io_attr,\n+\tNULL,\n+};\n+\n+static const struct bin_attribute *const pci_legacy_io_sparse_attrs[] = {\n+\t&pci_legacy_io_sparse_attr,\n+\tNULL,\n+};\n+\n+static const struct bin_attribute *const pci_legacy_mem_attrs[] = {\n+\t&pci_legacy_mem_attr,\n+\tNULL,\n+};\n+\n+static const struct bin_attribute *const pci_legacy_mem_sparse_attrs[] = {\n+\t&pci_legacy_mem_sparse_attr,\n+\tNULL,\n+};\n+\n+static const struct attribute_group pci_legacy_io_group = {\n+\t.bin_attrs = pci_legacy_io_attrs,\n+\t.is_bin_visible = pci_legacy_io_is_visible,\n+};\n+\n+static const struct attribute_group pci_legacy_io_sparse_group = {\n+\t.bin_attrs = pci_legacy_io_sparse_attrs,\n+\t.is_bin_visible = pci_legacy_io_sparse_is_visible,\n+};\n+\n+static const struct attribute_group pci_legacy_mem_group = {\n+\t.bin_attrs = pci_legacy_mem_attrs,\n+\t.is_bin_visible = pci_legacy_mem_is_visible,\n+};\n+\n+static const struct attribute_group pci_legacy_mem_sparse_group = {\n+\t.bin_attrs = pci_legacy_mem_sparse_attrs,\n+\t.is_bin_visible = pci_legacy_mem_sparse_is_visible,\n+};\n+\n+void pci_create_legacy_files(struct pci_bus *b) { }\n+void pci_remove_legacy_files(struct pci_bus *b) { }\n #endif /* HAVE_PCI_LEGACY */\n \n+const struct attribute_group *pcibus_groups[] = {\n+\t&pcibus_group,\n+#ifdef HAVE_PCI_LEGACY\n+\t&pci_legacy_io_group,\n+\t&pci_legacy_io_sparse_group,\n+\t&pci_legacy_mem_group,\n+\t&pci_legacy_mem_sparse_group,\n+#endif\n+\tNULL,\n+};\n+\n #if defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)\n /**\n  * pci_mmap_resource - map a PCI resource into user memory space\n","prefixes":["v7","22/24"]}